From 463c4e42e114ea793e4262a23cd54ce5aedaf78a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sat, 6 Apr 2024 17:34:19 +0200 Subject: [PATCH 0001/1962] Add utilities to locate node from text position --- .../pmd/lang/document/NodeFindingUtil.java | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 pmd-core/src/main/java/net/sourceforge/pmd/lang/document/NodeFindingUtil.java diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/NodeFindingUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/NodeFindingUtil.java new file mode 100644 index 00000000000..747a609af1b --- /dev/null +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/NodeFindingUtil.java @@ -0,0 +1,94 @@ +package net.sourceforge.pmd.lang.document; + +import java.util.Optional; + +import net.sourceforge.pmd.annotation.Experimental; +import net.sourceforge.pmd.lang.ast.Node; + +/** + * Utilities to find a node at specific text coordinates. + */ +@Experimental +public class NodeFindingUtil { + + + /** + * Locates the innermost node in the subtree rooted in the given node + * that contains the given offset. + */ + public static Optional findNodeAt(Node root, int offset) { + return Optional.ofNullable(findNodeRec(root, offset)) + .filter(it -> it.getTextRegion().contains(offset)); + } + + + /** + * Simple recursive search algo. Assumes that the regions of siblings + * do not overlap and that parents contain regions of children entirely. + * - We only have to explore one node at each level of the tree, and we quickly + * hit the bottom (average depth of a Java AST ~20-25, with 6.x.x grammar). + * - At each level, the next node to explore is chosen via binary search. + */ + private static Node findNodeRec(Node subject, int offset) { + Node child = binarySearchInChildren(subject, offset); + return child == null ? subject : findNodeRec(child, offset); + } + + // returns the child of the [parent] that contains the target + // it's assumed to be unique + private static Node binarySearchInChildren(Node parent, int offset) { + + int low = 0; + int high = parent.getNumChildren() - 1; + + while (low <= high) { + int mid = (low + high) / 2; + Node child = parent.getChild(mid); + TextRegion childRegion = child.getTextRegion(); + int cmp = Integer.compare(childRegion.getStartOffset(), offset); + + if (cmp < 0) { + // node start is before target + low = mid + 1; + if (childRegion.getEndOffset() >= offset) { + // node end is after target + return child; + } + } else if (cmp > 0) { + high = mid - 1; + } else { + // target is node start position + return child; // key found + } + } + return null; // key not found + } + + /** + * Returns the innermost node that covers the entire given text range + * in the given tree. + * + * @param root Root of the tree + * @param range Range to find + * @param exact If true, will return the *outermost* node whose range + * is *exactly* the given text range, otherwise it may be larger. + */ + public static Optional findNodeCovering(Node root, TextRegion range, boolean exact) { + return findNodeAt(root, range.getStartOffset()).map(innermost -> { + for (Node parent : innermost.ancestorsOrSelf()) { + TextRegion parentRange = parent.getTextRegion(); + if (!exact && parentRange.contains(range)) { + return parent; + } else if (exact && parentRange.equals(range)) { + return parent; + } else if (exact && parentRange.contains(range)) { + // if it isn't the same, then we can't find better so better stop looking + return null; + } + } + return null; + }); + } + + +} From efbbb459ba3d60f05aadf9f287c4c6396209577e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sat, 6 Apr 2024 23:20:45 +0200 Subject: [PATCH 0002/1962] Make token document store reference to AstInfo --- .../pmd/lang/ast/impl/TokenDocument.java | 29 ++++++++++++++++++- .../ast/impl/javacc/JavaccTokenDocument.java | 7 +++++ .../ast/impl/javacc/JjtreeParserAdapter.java | 6 +++- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/TokenDocument.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/TokenDocument.java index a59c3e769a2..128c6458e4a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/TokenDocument.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/TokenDocument.java @@ -4,21 +4,48 @@ package net.sourceforge.pmd.lang.ast.impl; +import java.util.Objects; + +import org.checkerframework.checker.nullness.qual.NonNull; + +import net.sourceforge.pmd.lang.ast.AstInfo; import net.sourceforge.pmd.lang.ast.GenericToken; import net.sourceforge.pmd.lang.document.Chars; import net.sourceforge.pmd.lang.document.TextDocument; /** * Token layer of a parsed file. + * This object is used to store state global to all tokens of a single file, + * e.g. the text document. Not all languages currently have an implementation + * of a token document. + * + * @see net.sourceforge.pmd.lang.ast.impl.javacc.JavaccTokenDocument */ -public abstract class TokenDocument { +public abstract class TokenDocument> { private final TextDocument textDocument; + private AstInfo astInfo; public TokenDocument(TextDocument textDocument) { this.textDocument = textDocument; } + /** + * Returns the object holding information about the + * parse tree. Filled-in after parsing. + */ + public @NonNull AstInfo getAstInfo() { + return Objects.requireNonNull(astInfo); + } + + /** + * Set the ast info after parsing. Only meant to be used by a {@link Parser} + * implementation. + */ + protected void setAstInfo(AstInfo astInfo) { + this.astInfo = Objects.requireNonNull(astInfo); + } + /** Returns the original text of the file (without escaping). */ public Chars getFullText() { return textDocument.getText(); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccTokenDocument.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccTokenDocument.java index 4de99f4118d..096c63295a4 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccTokenDocument.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccTokenDocument.java @@ -10,6 +10,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import net.sourceforge.pmd.lang.ast.AstInfo; import net.sourceforge.pmd.lang.ast.impl.TokenDocument; import net.sourceforge.pmd.lang.document.TextDocument; @@ -29,6 +30,12 @@ public JavaccTokenDocument(TextDocument textDocument, TokenDocumentBehavior beha this.behavior = behavior; } + // override to make visible in this package + @Override + protected void setAstInfo(AstInfo astInfo) { + super.setAstInfo(astInfo); + } + /** * Overridable configuration of a token document. */ diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeParserAdapter.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeParserAdapter.java index 3838c48655a..e4b3374bb1d 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeParserAdapter.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeParserAdapter.java @@ -33,7 +33,11 @@ public final R parse(ParserTask task) throws ParseException { // Escapes are processed by CharStream#create task = task.withTextDocument(charStream.getTokenDocument().getTextDocument()); // Finally, do the parsing - return parseImpl(charStream, task); + R result = parseImpl(charStream, task); + // Make tokens have access to the parsed tree + charStream.getTokenDocument().setAstInfo(result.getAstInfo()); + // and return + return result; } catch (FileAnalysisException tme) { throw tme.setFileId(task.getTextDocument().getFileId()); } From cd2b448750ba36393bf3e4f2b2b1a6b9c670c67c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sat, 6 Apr 2024 23:54:27 +0200 Subject: [PATCH 0003/1962] Add test --- .../pmd/lang/document/NodeFindingUtil.java | 24 +++++-- .../pmd/lang/document/TextRegion.java | 6 +- .../pmd/lang/DummyLanguageModule.java | 2 +- .../lang/document/NodeFindingUtilTest.java | 67 +++++++++++++++++++ 4 files changed, 89 insertions(+), 10 deletions(-) create mode 100644 pmd-core/src/test/java/net/sourceforge/pmd/lang/document/NodeFindingUtilTest.java diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/NodeFindingUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/NodeFindingUtil.java index 747a609af1b..21e723bd08d 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/NodeFindingUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/NodeFindingUtil.java @@ -2,6 +2,8 @@ import java.util.Optional; +import org.checkerframework.checker.nullness.qual.Nullable; + import net.sourceforge.pmd.annotation.Experimental; import net.sourceforge.pmd.lang.ast.Node; @@ -17,8 +19,7 @@ public class NodeFindingUtil { * that contains the given offset. */ public static Optional findNodeAt(Node root, int offset) { - return Optional.ofNullable(findNodeRec(root, offset)) - .filter(it -> it.getTextRegion().contains(offset)); + return Optional.ofNullable(findNodeImpl(root, offset)); } @@ -29,9 +30,20 @@ public static Optional findNodeAt(Node root, int offset) { * hit the bottom (average depth of a Java AST ~20-25, with 6.x.x grammar). * - At each level, the next node to explore is chosen via binary search. */ - private static Node findNodeRec(Node subject, int offset) { - Node child = binarySearchInChildren(subject, offset); - return child == null ? subject : findNodeRec(child, offset); + private static @Nullable Node findNodeImpl(Node subject, int offset) { + // deepest node containing the target offset + Node deepestNode = subject; + if (!deepestNode.getTextRegion().contains(offset)) { + return null; + } + while (true) { + Node child = binarySearchInChildren(deepestNode, offset); + if (child == null) { + // no more specific child contains the node + return deepestNode; + } + deepestNode = child; + } } // returns the child of the [parent] that contains the target @@ -50,7 +62,7 @@ private static Node binarySearchInChildren(Node parent, int offset) { if (cmp < 0) { // node start is before target low = mid + 1; - if (childRegion.getEndOffset() >= offset) { + if (childRegion.getEndOffset() > offset) { // node end is after target return child; } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/TextRegion.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/TextRegion.java index 5b87b05386b..5a1e2d19c3f 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/TextRegion.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/TextRegion.java @@ -184,8 +184,8 @@ public static TextRegion fromOffsetLength(int startOffset, int length) { /** * Builds a new region from start and end offset. * - * @param startOffset Start offset - * @param endOffset End offset + * @param startOffset Start offset (inclusive) + * @param endOffset End offset (exclusive) * * @throws AssertionError If either offset is negative, or the two * offsets are not ordered @@ -230,7 +230,7 @@ public int compareTo(@NonNull TextRegion o) { @Override public String toString() { - return "Region(start=" + startOffset + ", len=" + length + ")"; + return "Region(start=" + startOffset + ", len=" + length + ", end=" + getEndOffset() + ")"; } @Override diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java index b252aaa145d..1d518c5eae2 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java @@ -127,7 +127,7 @@ public static DummyRootNode readLispNode(ParserTask task) { throw new ParseException("Unbalanced parentheses: " + text); } - top.setRegion(TextRegion.fromBothOffsets(top.getTextRegion().getStartOffset(), i)); + top.setRegion(TextRegion.fromBothOffsets(top.getTextRegion().getStartOffset(), i + 1)); if (top.getImage() == null) { // cut out image (if node doesn't have children it hasn't been populated yet) diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/NodeFindingUtilTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/NodeFindingUtilTest.java new file mode 100644 index 00000000000..a7d8989daef --- /dev/null +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/NodeFindingUtilTest.java @@ -0,0 +1,67 @@ +package net.sourceforge.pmd.lang.document; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Optional; + +import org.junit.jupiter.api.Test; + +import net.sourceforge.pmd.lang.DummyLanguageModule; +import net.sourceforge.pmd.lang.LanguageProcessor; +import net.sourceforge.pmd.lang.LanguageProcessorRegistry; +import net.sourceforge.pmd.lang.ast.DummyNode; +import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.ast.Parser; +import net.sourceforge.pmd.lang.ast.RootNode; +import net.sourceforge.pmd.lang.ast.SemanticErrorReporter; + +public class NodeFindingUtilTest { + + @Test + public void testFindNode() { + DummyNode.DummyRootNode root = parseLispish("(a(b)x(c))"); + + assertFinds("a", 1, root); + assertFinds("b", 2, root); + assertFinds("b", 3, root); + assertFinds("b", 4, root); + assertFinds("a", 5, root); + assertFinds("c", 6, root); + assertFinds("c", 7, root); + assertFinds("c", 8, root); + assertFinds("a", 9, root); + assertDoesNotFind(10, root); + } + + private static void assertDoesNotFind(int offset, DummyNode.DummyRootNode root) { + assertFalse(NodeFindingUtil.findNodeAt(root, offset).isPresent()); + } + + static void assertFinds(String nodeImage, int offset, Node root) { + Optional found = NodeFindingUtil.findNodeAt(root, offset); + + assertTrue(found.isPresent(), "Node not found: " + nodeImage + " at offset " + offset); + assertThat(found.get().getImage(), equalTo(nodeImage)); + } + + static DummyNode.DummyRootNode parseLispish(String source) { + + DummyLanguageModule lang = DummyLanguageModule.getInstance(); + try (LanguageProcessor processor = lang.createProcessor(lang.newPropertyBundle())) { + Parser.ParserTask task = new Parser.ParserTask( + TextDocument.readOnlyString(source, lang.getDefaultVersion()), + SemanticErrorReporter.noop(), + LanguageProcessorRegistry.singleton(processor) + ); + RootNode root = processor.services().getParser().parse(task); + + return (DummyNode.DummyRootNode) root; + } catch (Exception e) { + throw new RuntimeException(e); + } + + } +} From 94306434bbe0539ce93c13d26c1b08efea503bfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 7 Apr 2024 00:18:26 +0200 Subject: [PATCH 0004/1962] Try to wire this into RuleContext --- .../pmd/lang/ast/impl/javacc/JavaccToken.java | 6 +++ .../pmd/reporting/RuleContext.java | 49 ++++++++++++++++--- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccToken.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccToken.java index 957bb8ad144..ff120bb419a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccToken.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccToken.java @@ -4,6 +4,7 @@ package net.sourceforge.pmd.lang.ast.impl.javacc; +import net.sourceforge.pmd.lang.ast.AstInfo; import net.sourceforge.pmd.lang.ast.GenericToken; import net.sourceforge.pmd.lang.document.Chars; import net.sourceforge.pmd.lang.document.FileLocation; @@ -175,6 +176,11 @@ public String toString() { return document.describeKind(kind) + ": " + getImage(); } + /** Return the AST info object. Will fail if parsing is not finished. */ + public AstInfo getAstInfo() { + return document.getAstInfo(); + } + /** * Returns a new token with the same kind as this one, whose image * is replaced by the one marked on the char stream. diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java index 4f2674fe8bd..d459c8215f2 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java @@ -10,14 +10,18 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import org.apache.commons.lang3.StringUtils; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import net.sourceforge.pmd.lang.LanguageVersionHandler; +import net.sourceforge.pmd.lang.ast.AstInfo; import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken; import net.sourceforge.pmd.lang.document.FileLocation; +import net.sourceforge.pmd.lang.document.NodeFindingUtil; import net.sourceforge.pmd.lang.document.TextRange2d; import net.sourceforge.pmd.lang.rule.AbstractRule; import net.sourceforge.pmd.lang.rule.Rule; @@ -29,7 +33,7 @@ * This forwards events to a {@link FileAnalysisListener}. It implements * violation suppression by filtering some violations out, according to * the {@link ViolationSuppressor}s for the language. - * + *

* A RuleContext contains a Rule instance and violation reporting methods * implicitly report only for that rule. Contrary to PMD 6, RuleContext is * not unique throughout the analysis, a separate one is used per file and rule. @@ -130,22 +134,39 @@ public void addViolationWithMessage(Node location, String message, Object... for * @param formatArgs Format arguments for the message */ public void addViolationWithPosition(Node node, int beginLine, int endLine, String message, Object... formatArgs) { - Objects.requireNonNull(node, "Node was null"); + addViolationWithPosition(node, node.getAstInfo(), beginLine, endLine, message, formatArgs); + } + + /** + * Record a new violation of the contextual rule, at the given node. + * The position is refined using the given begin and end line numbers. + * The given violation message ({@link Rule#getMessage()}) is treated + * as a format string for a {@link MessageFormat} and should hence use + * appropriate escapes. The given formatting arguments are used. + * + * @param reportable Location of the violation (node or token) + * @param astInfo Info about the root of the tree ({@link Node#getAstInfo()}) + * @param message Violation message + * @param formatArgs Format arguments for the message + */ + public void addViolationWithPosition(Reportable reportable, AstInfo astInfo, int beginLine, int endLine, String message, Object... formatArgs) { + Objects.requireNonNull(reportable, "Node was null"); Objects.requireNonNull(message, "Message was null"); Objects.requireNonNull(formatArgs, "Format arguments were null, use an empty array"); - LanguageVersionHandler handler = node.getAstInfo().getLanguageProcessor().services(); + LanguageVersionHandler handler = astInfo.getLanguageProcessor().services(); - FileLocation location = node.getReportLocation(); + FileLocation location = reportable.getReportLocation(); if (beginLine != -1 && endLine != -1) { location = FileLocation.range(location.getFileId(), TextRange2d.range2d(beginLine, 1, endLine, 1)); } + Node suppressionNode = getNearestNode(reportable); - final Map extraVariables = ViolationDecorator.apply(handler.getViolationDecorator(), node); - final String description = makeMessage(message, formatArgs, extraVariables); - final RuleViolation violation = new ParametricRuleViolation(rule, location, description, extraVariables); + Map extraVariables = ViolationDecorator.apply(handler.getViolationDecorator(), suppressionNode); + String description = makeMessage(message, formatArgs, extraVariables); + RuleViolation violation = new ParametricRuleViolation(rule, location, description, extraVariables); - final SuppressedViolation suppressed = suppressOrNull(node, violation, handler); + SuppressedViolation suppressed = suppressOrNull(suppressionNode, violation, handler); if (suppressed != null) { listener.onSuppressedRuleViolation(suppressed); @@ -154,6 +175,18 @@ public void addViolationWithPosition(Node node, int beginLine, int endLine, Stri } } + // todo add this method on Reportable directly + private Node getNearestNode(Reportable reportable) { + if (reportable instanceof Node) { + return (Node) reportable; + } else if (reportable instanceof JavaccToken) { + AstInfo astInfo = ((JavaccToken) reportable).getAstInfo(); + Optional foundNode = NodeFindingUtil.findNodeAt(astInfo.getRootNode(), ((JavaccToken) reportable).getRegion().getStartOffset()); + return foundNode.orElse(astInfo.getRootNode()); + } + throw new IllegalArgumentException("Unsupported Reportable type: " + reportable); + } + private static @Nullable SuppressedViolation suppressOrNull(Node location, RuleViolation rv, LanguageVersionHandler handler) { SuppressedViolation suppressed = ViolationSuppressor.suppressOrNull(handler.getExtraViolationSuppressors(), rv, location); if (suppressed == null) { From f8b069b333a1d0432bec761f2db5ff15b083cc66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 7 Apr 2024 00:36:36 +0200 Subject: [PATCH 0005/1962] Make sure this works in CommentSize --- .../pmd/reporting/RuleContext.java | 40 +++++++++++------- .../rule/documentation/CommentSizeRule.java | 22 ++++++---- .../rule/documentation/xml/CommentSize.xml | 41 +++++++++++++++++++ 3 files changed, 79 insertions(+), 24 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java index d459c8215f2..962f05daf06 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java @@ -134,11 +134,18 @@ public void addViolationWithMessage(Node location, String message, Object... for * @param formatArgs Format arguments for the message */ public void addViolationWithPosition(Node node, int beginLine, int endLine, String message, Object... formatArgs) { - addViolationWithPosition(node, node.getAstInfo(), beginLine, endLine, message, formatArgs); + FileLocation location; + if (beginLine != -1 && endLine != -1) { + location = FileLocation.range(node.getTextDocument().getFileId(), + TextRange2d.range2d(beginLine, 1, endLine, 1)); + } else { + location = node.getReportLocation(); + } + addViolationWithPosition(node, node.getAstInfo(), location, message, formatArgs); } /** - * Record a new violation of the contextual rule, at the given node. + * Record a new violation of the contextual rule, at the given location (node or token). * The position is refined using the given begin and end line numbers. * The given violation message ({@link Rule#getMessage()}) is treated * as a format string for a {@link MessageFormat} and should hence use @@ -149,18 +156,15 @@ public void addViolationWithPosition(Node node, int beginLine, int endLine, Stri * @param message Violation message * @param formatArgs Format arguments for the message */ - public void addViolationWithPosition(Reportable reportable, AstInfo astInfo, int beginLine, int endLine, String message, Object... formatArgs) { + public void addViolationWithPosition(Reportable reportable, AstInfo astInfo, FileLocation location, + String message, Object... formatArgs) { Objects.requireNonNull(reportable, "Node was null"); Objects.requireNonNull(message, "Message was null"); Objects.requireNonNull(formatArgs, "Format arguments were null, use an empty array"); LanguageVersionHandler handler = astInfo.getLanguageProcessor().services(); - FileLocation location = reportable.getReportLocation(); - if (beginLine != -1 && endLine != -1) { - location = FileLocation.range(location.getFileId(), TextRange2d.range2d(beginLine, 1, endLine, 1)); - } - Node suppressionNode = getNearestNode(reportable); + Node suppressionNode = getNearestNode(reportable, astInfo); Map extraVariables = ViolationDecorator.apply(handler.getViolationDecorator(), suppressionNode); String description = makeMessage(message, formatArgs, extraVariables); @@ -175,16 +179,22 @@ public void addViolationWithPosition(Reportable reportable, AstInfo astInfo, } } - // todo add this method on Reportable directly - private Node getNearestNode(Reportable reportable) { + private Node getNearestNode(Reportable reportable, AstInfo astInfo) { if (reportable instanceof Node) { return (Node) reportable; - } else if (reportable instanceof JavaccToken) { - AstInfo astInfo = ((JavaccToken) reportable).getAstInfo(); - Optional foundNode = NodeFindingUtil.findNodeAt(astInfo.getRootNode(), ((JavaccToken) reportable).getRegion().getStartOffset()); - return foundNode.orElse(astInfo.getRootNode()); } - throw new IllegalArgumentException("Unsupported Reportable type: " + reportable); + int startOffset = getStartOffset(reportable, astInfo); + Optional foundNode = NodeFindingUtil.findNodeAt(astInfo.getRootNode(), startOffset); + // default to the root node + return foundNode.orElse(astInfo.getRootNode()); + } + + private static int getStartOffset(Reportable reportable, AstInfo astInfo) { + if (reportable instanceof JavaccToken) { + return ((JavaccToken) reportable).getRegion().getStartOffset(); + } + FileLocation loc = reportable.getReportLocation(); + return astInfo.getTextDocument().offsetAtLineColumn(loc.getStartPos()); } private static @Nullable SuppressedViolation suppressOrNull(Node location, RuleViolation rv, LanguageVersionHandler handler) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentSizeRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentSizeRule.java index d9820a1bf9a..21c1f3bb41a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentSizeRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentSizeRule.java @@ -7,6 +7,7 @@ import static net.sourceforge.pmd.properties.NumericConstraints.positive; import net.sourceforge.pmd.lang.document.Chars; +import net.sourceforge.pmd.lang.document.FileLocation; import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.ast.JavaComment; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; @@ -22,9 +23,9 @@ public class CommentSizeRule extends AbstractJavaRulechainRule { public static final PropertyDescriptor MAX_LINES - = PropertyFactory.intProperty("maxLines") - .desc("Maximum lines") - .require(positive()).defaultValue(6).build(); + = PropertyFactory.intProperty("maxLines") + .desc("Maximum lines") + .require(positive()).defaultValue(6).build(); public static final PropertyDescriptor MAX_LINE_LENGTH = PropertyFactory.intProperty("maxLineLength") @@ -43,9 +44,11 @@ public Object visit(ASTCompilationUnit cUnit, Object data) { for (JavaComment comment : cUnit.getComments()) { if (hasTooManyLines(comment)) { - asCtx(data).addViolationWithPosition(cUnit, - comment.getReportLocation().getStartLine(), comment.getReportLocation().getEndLine(), - getMessage() + ": Too many lines"); + asCtx(data).addViolationWithPosition( + comment.getToken(), + cUnit.getAstInfo(), + comment.getReportLocation(), + getMessage() + ": Too many lines"); } reportLinesTooLong(cUnit, asCtx(data), comment); @@ -86,9 +89,10 @@ private void reportLinesTooLong(ASTCompilationUnit acu, RuleContext ctx, JavaCom int lineNumber = comment.getReportLocation().getStartLine(); for (Chars line : comment.getFilteredLines(true)) { if (line.length() > maxLength) { - ctx.addViolationWithPosition(acu, - lineNumber, - lineNumber, + FileLocation location = FileLocation.caret(acu.getTextDocument().getFileId(), lineNumber, 1); + ctx.addViolationWithPosition(comment.getToken(), + acu.getAstInfo(), + location, getMessage() + ": Line too long"); } lineNumber++; diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentSize.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentSize.xml index 057b91d81eb..51b0e6d98d1 100755 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentSize.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentSize.xml @@ -46,6 +46,47 @@ public class Foo { public void doNothing() { } +} + ]]> + + + Suppression + 2 + 0 + + + + Not suppressed + 2 + 1 + From cd02335063bd222fd797b476225484d4a03f0561 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 7 Apr 2024 00:39:53 +0200 Subject: [PATCH 0006/1962] Remove AstInfo from tokens --- .../pmd/lang/ast/impl/TokenDocument.java | 22 ------------------- .../pmd/lang/ast/impl/javacc/JavaccToken.java | 6 ----- .../ast/impl/javacc/JavaccTokenDocument.java | 7 ------ .../ast/impl/javacc/JjtreeParserAdapter.java | 6 +---- 4 files changed, 1 insertion(+), 40 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/TokenDocument.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/TokenDocument.java index 128c6458e4a..4f2fb9dc802 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/TokenDocument.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/TokenDocument.java @@ -4,11 +4,6 @@ package net.sourceforge.pmd.lang.ast.impl; -import java.util.Objects; - -import org.checkerframework.checker.nullness.qual.NonNull; - -import net.sourceforge.pmd.lang.ast.AstInfo; import net.sourceforge.pmd.lang.ast.GenericToken; import net.sourceforge.pmd.lang.document.Chars; import net.sourceforge.pmd.lang.document.TextDocument; @@ -24,28 +19,11 @@ public abstract class TokenDocument> { private final TextDocument textDocument; - private AstInfo astInfo; public TokenDocument(TextDocument textDocument) { this.textDocument = textDocument; } - /** - * Returns the object holding information about the - * parse tree. Filled-in after parsing. - */ - public @NonNull AstInfo getAstInfo() { - return Objects.requireNonNull(astInfo); - } - - /** - * Set the ast info after parsing. Only meant to be used by a {@link Parser} - * implementation. - */ - protected void setAstInfo(AstInfo astInfo) { - this.astInfo = Objects.requireNonNull(astInfo); - } - /** Returns the original text of the file (without escaping). */ public Chars getFullText() { return textDocument.getText(); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccToken.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccToken.java index ff120bb419a..957bb8ad144 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccToken.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccToken.java @@ -4,7 +4,6 @@ package net.sourceforge.pmd.lang.ast.impl.javacc; -import net.sourceforge.pmd.lang.ast.AstInfo; import net.sourceforge.pmd.lang.ast.GenericToken; import net.sourceforge.pmd.lang.document.Chars; import net.sourceforge.pmd.lang.document.FileLocation; @@ -176,11 +175,6 @@ public String toString() { return document.describeKind(kind) + ": " + getImage(); } - /** Return the AST info object. Will fail if parsing is not finished. */ - public AstInfo getAstInfo() { - return document.getAstInfo(); - } - /** * Returns a new token with the same kind as this one, whose image * is replaced by the one marked on the char stream. diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccTokenDocument.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccTokenDocument.java index 096c63295a4..4de99f4118d 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccTokenDocument.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccTokenDocument.java @@ -10,7 +10,6 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; -import net.sourceforge.pmd.lang.ast.AstInfo; import net.sourceforge.pmd.lang.ast.impl.TokenDocument; import net.sourceforge.pmd.lang.document.TextDocument; @@ -30,12 +29,6 @@ public JavaccTokenDocument(TextDocument textDocument, TokenDocumentBehavior beha this.behavior = behavior; } - // override to make visible in this package - @Override - protected void setAstInfo(AstInfo astInfo) { - super.setAstInfo(astInfo); - } - /** * Overridable configuration of a token document. */ diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeParserAdapter.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeParserAdapter.java index e4b3374bb1d..3838c48655a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeParserAdapter.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeParserAdapter.java @@ -33,11 +33,7 @@ public final R parse(ParserTask task) throws ParseException { // Escapes are processed by CharStream#create task = task.withTextDocument(charStream.getTokenDocument().getTextDocument()); // Finally, do the parsing - R result = parseImpl(charStream, task); - // Make tokens have access to the parsed tree - charStream.getTokenDocument().setAstInfo(result.getAstInfo()); - // and return - return result; + return parseImpl(charStream, task); } catch (FileAnalysisException tme) { throw tme.setFileId(task.getTextDocument().getFileId()); } From fc477cbdb2237815a1eb799d01cc5b626f116fa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 7 Apr 2024 00:44:30 +0200 Subject: [PATCH 0007/1962] Make NodeFindingUtil internal for now --- .../internal}/NodeFindingUtil.java | 17 ++++++++++++----- .../sourceforge/pmd/reporting/RuleContext.java | 2 +- .../internal}/NodeFindingUtilTest.java | 7 ++++++- 3 files changed, 19 insertions(+), 7 deletions(-) rename pmd-core/src/main/java/net/sourceforge/pmd/lang/{document => ast/internal}/NodeFindingUtil.java (90%) rename pmd-core/src/test/java/net/sourceforge/pmd/lang/{document => ast/internal}/NodeFindingUtilTest.java (92%) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/NodeFindingUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/NodeFindingUtil.java similarity index 90% rename from pmd-core/src/main/java/net/sourceforge/pmd/lang/document/NodeFindingUtil.java rename to pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/NodeFindingUtil.java index 21e723bd08d..867b4f84511 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/NodeFindingUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/NodeFindingUtil.java @@ -1,17 +1,24 @@ -package net.sourceforge.pmd.lang.document; +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.ast.internal; import java.util.Optional; import org.checkerframework.checker.nullness.qual.Nullable; -import net.sourceforge.pmd.annotation.Experimental; import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.document.TextRegion; /** - * Utilities to find a node at specific text coordinates. + * Utilities to find a node at specific text coordinates in a tree. */ -@Experimental -public class NodeFindingUtil { +public final class NodeFindingUtil { + + private NodeFindingUtil() { + // utility class + } /** diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java index 962f05daf06..41d8a980727 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java @@ -20,8 +20,8 @@ import net.sourceforge.pmd.lang.ast.AstInfo; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken; +import net.sourceforge.pmd.lang.ast.internal.NodeFindingUtil; import net.sourceforge.pmd.lang.document.FileLocation; -import net.sourceforge.pmd.lang.document.NodeFindingUtil; import net.sourceforge.pmd.lang.document.TextRange2d; import net.sourceforge.pmd.lang.rule.AbstractRule; import net.sourceforge.pmd.lang.rule.Rule; diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/NodeFindingUtilTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/internal/NodeFindingUtilTest.java similarity index 92% rename from pmd-core/src/test/java/net/sourceforge/pmd/lang/document/NodeFindingUtilTest.java rename to pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/internal/NodeFindingUtilTest.java index a7d8989daef..9579dd26d89 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/NodeFindingUtilTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/internal/NodeFindingUtilTest.java @@ -1,4 +1,8 @@ -package net.sourceforge.pmd.lang.document; +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.ast.internal; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; @@ -17,6 +21,7 @@ import net.sourceforge.pmd.lang.ast.Parser; import net.sourceforge.pmd.lang.ast.RootNode; import net.sourceforge.pmd.lang.ast.SemanticErrorReporter; +import net.sourceforge.pmd.lang.document.TextDocument; public class NodeFindingUtilTest { From 5f9e4abf7d8c1f7399bacbdd7bf3db674f09768c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 9 Apr 2024 11:46:41 +0200 Subject: [PATCH 0008/1962] Fix pmd violation --- .../pmd/lang/ast/internal/NodeFindingUtilTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/internal/NodeFindingUtilTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/internal/NodeFindingUtilTest.java index 9579dd26d89..4bdf1d8a0f6 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/internal/NodeFindingUtilTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/internal/NodeFindingUtilTest.java @@ -23,10 +23,10 @@ import net.sourceforge.pmd.lang.ast.SemanticErrorReporter; import net.sourceforge.pmd.lang.document.TextDocument; -public class NodeFindingUtilTest { +class NodeFindingUtilTest { @Test - public void testFindNode() { + void testFindNode() { DummyNode.DummyRootNode root = parseLispish("(a(b)x(c))"); assertFinds("a", 1, root); From 1b9de011be19047aee522bcf69b24f9031f181f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 10 Apr 2024 18:51:16 +0200 Subject: [PATCH 0009/1962] Add permitted subclasses to ASM classbuilder --- .../pmd/lang/java/ast/JModifier.java | 7 +-- .../pmd/lang/java/symbols/JClassSymbol.java | 30 +++++++++++ .../java/symbols/internal/asm/ClassStub.java | 15 ++++++ .../internal/asm/ClassStubBuilder.java | 6 +++ .../symbols/internal/asm/AsmLoaderTest.kt | 47 +++++++++++++++++- .../lang/java/symbols/testdata/sealed/A.class | Bin 0 -> 329 bytes .../lang/java/symbols/testdata/sealed/B.class | Bin 0 -> 236 bytes .../lang/java/symbols/testdata/sealed/C.class | Bin 0 -> 329 bytes .../testdata/sealed/SealedTypesTestData.class | Bin 0 -> 392 bytes .../testdata/sealed/SealedTypesTestData.java | 22 ++++++++ .../lang/java/symbols/testdata/sealed/X.class | Bin 0 -> 311 bytes 11 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/A.class create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/B.class create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/C.class create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/SealedTypesTestData.class create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/SealedTypesTestData.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/X.class diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JModifier.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JModifier.java index 4bf5ac91624..66e71946f4d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JModifier.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JModifier.java @@ -11,6 +11,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; +import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; import net.sourceforge.pmd.lang.java.symbols.JMethodSymbol; /** @@ -25,9 +26,9 @@ public enum JModifier { PROTECTED(Modifier.PROTECTED), PRIVATE(Modifier.PRIVATE), - /** Modifier {@code "sealed"} (preview feature of JDK 15). */ + /** Modifier {@code "sealed"} (since Java 17). */ SEALED(0), - /** Modifier {@code "non-sealed"} (preview feature of JDK 15). */ + /** Modifier {@code "non-sealed"} (since Java 17). */ NON_SEALED("non-sealed", 0), ABSTRACT(Modifier.ABSTRACT), @@ -69,7 +70,7 @@ public enum JModifier { * A default method is a non-static non-abstract public method declared * in an interface ({@link JMethodSymbol#isDefaultMethod()}. *

  • {@link #SEALED}: a sealed class has an attribute {@code PermittedSubclasses} - * with a non-zero length (in the compiled class file) + * with a non-zero length (in the compiled class file). ({@link JClassSymbol#isSealed()}) *
  • {@link #NON_SEALED}: this doesn't exist at the class file level at all. * But a class must have the non-sealed modifier in source if it * is neither sealed, nor final, and appears in the {@code PermittedSubclasses} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JClassSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JClassSymbol.java index 62ab953a07c..49ca72df956 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JClassSymbol.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JClassSymbol.java @@ -227,6 +227,36 @@ default boolean isAbstract() { boolean isAnonymousClass(); + /** + * Return the list of permitted subclasses, as defined in the {@code permits} + * clause of a sealed class or interface. + * + * @see #isSealed() + */ + default List getPermittedSubclasses() { + return Collections.emptyList(); + } + + /** + * Return true if this type is sealed. Then it has a non-empty list of permitted + * subclasses. Note that there is no trace of the non-sealed modifier in class files. + * A class must have the {@code non-sealed} modifier if it is not sealed, not final, + * and has a sealed supertype. + * + * @see #getPermittedSubclasses() + */ + default boolean isSealed() { + return !getPermittedSubclasses().isEmpty(); + } + + /** + * Return true if this type is final, that is, does not admit subtypes. Note that + * array types have both modifiers final and abstract. + */ + default boolean isFinal() { + return Modifier.isFinal(getModifiers()); + } + /** * Return the simple names of all annotation attributes. If this * is not an annotation type, return an empty set. diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java index 581b5563991..3f7bd2c6ca1 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java @@ -62,6 +62,7 @@ final class ClassStub implements JClassSymbol, AsmStub, AnnotationOwner { private List methods = new ArrayList<>(); private List ctors = new ArrayList<>(); private List enumConstants = null; + private List permittedSubclasses = null; private PSet annotations = HashTreePSet.empty(); @@ -117,6 +118,7 @@ protected void finishParse(boolean failed) { fields = Collections.unmodifiableList(fields); memberClasses = Collections.unmodifiableList(memberClasses); enumConstants = CollectionUtil.makeUnmodifiableAndNonNull(enumConstants); + permittedSubclasses = CollectionUtil.makeUnmodifiableAndNonNull(permittedSubclasses); if (EnclosingInfo.NO_ENCLOSING.equals(enclosingInfo)) { if (names.canonicalName == null || names.simpleName == null) { @@ -259,6 +261,13 @@ void addCtor(CtorStub methodStub) { ctors.add(methodStub); } + void addPermittedSubclass(ClassStub permittedSubclass) { + if (this.permittedSubclasses == null) { + this.permittedSubclasses = new ArrayList<>(2); + } + this.permittedSubclasses.add(permittedSubclass); + } + @Override public void addAnnotation(SymAnnot annot) { annotations = annotations.plus(annot); @@ -376,6 +385,12 @@ public PSet getAnnotationAttributeNames() { return enumConstants; } + @Override + public List getPermittedSubclasses() { + parseLock.ensureParsed(); + return permittedSubclasses; + } + @Override public JTypeParameterOwnerSymbol getEnclosingTypeParameterOwner() { parseLock.ensureParsed(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStubBuilder.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStubBuilder.java index a48c70644f5..db2be360a03 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStubBuilder.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStubBuilder.java @@ -74,6 +74,12 @@ public AnnotationVisitor visitTypeAnnotation(int typeRef, @Nullable TypePath typ }; } + @Override + public void visitPermittedSubclass(String permittedSubclass) { + ClassStub permitted = resolver.resolveFromInternalNameCannotFail(permittedSubclass); + myStub.addPermittedSubclass(permitted); + } + /** * Visits information about an inner class. This inner class is not necessarily a member of the * class being visited. diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmLoaderTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmLoaderTest.kt index 4ffcc088cd4..47adf436682 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmLoaderTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmLoaderTest.kt @@ -7,6 +7,7 @@ package net.sourceforge.pmd.lang.java.symbols.internal.asm import io.kotest.core.spec.style.FunSpec import io.kotest.inspectors.forExactly import io.kotest.matchers.collections.shouldBeEmpty +import io.kotest.matchers.collections.shouldBeSingleton import io.kotest.matchers.collections.shouldContainExactlyInAnyOrder import io.kotest.matchers.collections.shouldHaveSize import io.kotest.matchers.nulls.shouldBeNull @@ -20,9 +21,11 @@ import javasymbols.testdata.deep.AClassWithLocals import javasymbols.testdata.deep.`Another$ClassWith$Dollar` import javasymbols.testdata.deep.OuterWithoutDollar import javasymbols.testdata.impls.GenericClass +import net.sourceforge.pmd.lang.java.symbols.JClassSymbol +import net.sourceforge.pmd.lang.java.types.testTypeSystem import net.sourceforge.pmd.lang.test.ast.IntelliMarker import net.sourceforge.pmd.lang.test.ast.shouldBe -import net.sourceforge.pmd.lang.java.types.testTypeSystem +import net.sourceforge.pmd.lang.test.ast.shouldBeA import org.objectweb.asm.Opcodes import kotlin.test.assertSame @@ -234,4 +237,46 @@ class AsmLoaderTest : IntelliMarker, FunSpec({ val notAnEnum = symLoader().resolveClassFromBinaryName(outerName)!! notAnEnum::getEnumConstants shouldBe emptyList() } + + test("Permitted subclasses") { + + val outerName = "net.sourceforge.pmd.lang.java.symbols.testdata.sealed.SealedTypesTestData" + + // Note here we are loading a .class file that is in the test/resources directory. + val sealedInterface = symLoader().resolveClassFromBinaryName(outerName)!! + // sealed interface SealedTypesTestData permits A, B, C + sealedInterface::getSimpleName shouldBe "SealedTypesTestData" + sealedInterface::isSealed shouldBe true + sealedInterface.permittedSubclasses.let { + it.shouldHaveSize(3) + it[0].shouldBeA { + // sealed interface A extends SealedTypesTestData permits X + it::getSimpleName shouldBe "A" + it::isSealed shouldBe true + it::isInterface shouldBe true + it::isFinal shouldBe false + it.permittedSubclasses.shouldBeSingleton { + // final class X implements A {} + it::getSimpleName shouldBe "X" + it::isFinal shouldBe true + } + } + it[1].shouldBeA { + // non-sealed interface B extends SealedTypesTestData + it::getSimpleName shouldBe "B" + it::isInterface shouldBe true + it::isSealed shouldBe false + it::isFinal shouldBe false + it::getPermittedSubclasses shouldBe emptyList() + } + it[2].shouldBeA { + // final class C implements SealedTypesTestData + it::getSimpleName shouldBe "C" + it::isInterface shouldBe false + it::isSealed shouldBe false + it::isFinal shouldBe true + it::getPermittedSubclasses shouldBe emptyList() + } + } + } }) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/A.class b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/A.class new file mode 100644 index 0000000000000000000000000000000000000000..9af79be3a4e9a20cf120c252ecd11b2971e44c49 GIT binary patch literal 329 zcmbVII|{-;5PchCR-=Vr<0;(I%0dvqN+Bt1H^~?hHXpJZAy>2T03J$Qx3)?#Gw^u4 z&%8g+7l1vM93I22CL?sycPZVQE+^4enNYIMMJXRr=%Gp)rG+7FGHEP8Qc)%j96rO! zaUA=Sl$08dfZ;q&GIGlC(2|a=+tIo)gprGODikqn{!q5R2n_2hbyZ;uWl^7`N@`7- aV==nlEdUrMcBb}OfCujO40C&Zi-%ufO=dX& literal 0 HcmV?d00001 diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/B.class b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/B.class new file mode 100644 index 0000000000000000000000000000000000000000..f6202a89ded4e4a297347e28c2fc0179ee07c8d7 GIT binary patch literal 236 zcmX^0Z`VEs1_oOOPId++Mh5e|)Dr#T{L-T2)U^Df^i=(V+!Xzs#JqI{gTw;l9a>}pg?M3PHKw26FUP7BZB}~4Oq2*QdVkm2|EKDBZDV-Mh1gT4yi0i xEe-+N<^r^hk%221>@>H`oK!{z2`ozVKu%y|U|?im24YsA&p>Q;Aj!nQ0RVPMNa+9o literal 0 HcmV?d00001 diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/C.class b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/C.class new file mode 100644 index 0000000000000000000000000000000000000000..3fb63a1a9d12820962fbcbeeb5c3805eca868bfa GIT binary patch literal 329 zcmbVIyKcfj5S#^q!6AS|LqkteaOu({G(<>92nsCvGu|L0KalT;#Al^KqR0pEQBl@M zOGU9e`_PPb=kj;{1@M86j|!?DYArmVPU!CRw^oVHwrUyfcw-6m_c)8~m{1))uRSyf zZy8%<@m0_K5q*fmMyTwyNZI(w&=zhf+&kt$H zMWDk(HvYnS`Hah Date: Wed, 10 Apr 2024 19:31:11 +0200 Subject: [PATCH 0010/1962] Add it to AST symbols --- .../pmd/lang/java/ast/ASTTypeDeclaration.java | 5 +++++ .../symbols/internal/ast/AstClassSym.java | 22 ++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeDeclaration.java index 1bc078f511e..213eff3b314 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeDeclaration.java @@ -279,4 +279,9 @@ default boolean isAnnotation() { return ASTList.orEmptyStream(isInterface() ? firstChild(ASTExtendsList.class) : firstChild(ASTImplementsList.class)); } + + /** Return the permits list if this is a sealed type, null otherwise. */ + default @Nullable ASTPermitsList getPermitsClause() { + return firstChild(ASTPermitsList.class); + } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstClassSym.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstClassSym.java index 647924c3abf..c28535d659d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstClassSym.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstClassSym.java @@ -22,6 +22,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTEnumConstant; import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTPermitsList; import net.sourceforge.pmd.lang.java.ast.ASTRecordComponent; import net.sourceforge.pmd.lang.java.ast.ASTRecordComponentList; import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration; @@ -54,6 +55,7 @@ final class AstClassSym private final List declaredCtors; private final List declaredFields; private final List enumConstants; // subset of declaredFields + private final List permittedSubclasses; private final PSet annotAttributes; AstClassSym(ASTTypeDeclaration node, @@ -99,6 +101,19 @@ final class AstClassSym } + ASTPermitsList permits = node.getPermitsClause(); + if (permits != null) { + this.permittedSubclasses = permits.toList().stream().map(it -> { + JTypeDeclSymbol symbol = it.getTypeMirror().getSymbol(); + if (symbol instanceof JClassSymbol) + return (JClassSymbol) symbol; + else return null; + }).filter(Objects::nonNull).collect(CollectionUtil.toUnmodifiableList()); + } else { + this.permittedSubclasses = Collections.emptyList(); + } + + for (ASTBodyDeclaration dnode : node.getDeclarations()) { if (dnode instanceof ASTTypeDeclaration) { @@ -216,7 +231,12 @@ public List getDeclaredFields() { public @NonNull List getEnumConstants() { return enumConstants; } - + + @Override + public List getPermittedSubclasses() { + return permittedSubclasses; + } + @Override public @Nullable JClassType getSuperclassType(Substitution substitution) { TypeSystem ts = getTypeSystem(); From 04e05891f0831413e0ea7d2b6ebc7a3bd15376a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 12 Apr 2024 14:39:06 +0200 Subject: [PATCH 0011/1962] Make variable naming conventions skip unnamed variables --- .../net/sourceforge/pmd/lang/java/ast/ASTVariableId.java | 9 +++++++++ .../codestyle/FormalParameterNamingConventionsRule.java | 4 ++++ .../codestyle/LocalVariableNamingConventionsRule.java | 4 ++++ 3 files changed, 17 insertions(+) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableId.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableId.java index e21de7a2b5b..01ea8e30758 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableId.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableId.java @@ -127,6 +127,15 @@ private ModifierOwner getModifierOwnerParent() { return (ModifierOwner) parent; } + /** + * Return true if this variable has no name. The name is then equal to {@code "_"}. + * A variable declaration with this name does not actually declare a variable in + * the current scope. + */ + public boolean isUnnamed() { + return "_".equals(name); + } + /** Returns the name of the variable. */ public String getName() { return name; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/FormalParameterNamingConventionsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/FormalParameterNamingConventionsRule.java index 6c81af4e234..57cd8ee6c80 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/FormalParameterNamingConventionsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/FormalParameterNamingConventionsRule.java @@ -39,6 +39,10 @@ public FormalParameterNamingConventionsRule() { @Override public Object visit(ASTVariableId node, Object data) { + if (node.isUnnamed()) { + // unnamed variables do not have to match the regexes. + return null; + } if (node.isLambdaParameter()) { checkMatches(node, node.isTypeInferred() ? lambdaParamRegex : explicitLambdaParamRegex, data); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableNamingConventionsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableNamingConventionsRule.java index eb5880b8c60..928ed24a475 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableNamingConventionsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableNamingConventionsRule.java @@ -38,6 +38,10 @@ public LocalVariableNamingConventionsRule() { @Override public Object visit(ASTVariableId node, Object data) { + if (node.isUnnamed()) { + // unnamed variables do not have to match the regexes. + return null; + } if (node.isExceptionBlockParameter()) { checkMatches(node, exceptionBlockParameterRegex, data); From 08ff78f1ce7c20cdcdd1094a50ab2b48a26097a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 12 Apr 2024 14:48:54 +0200 Subject: [PATCH 0012/1962] Don"t add unnamed variables to symtable --- .../table/internal/SymTableFactory.java | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymTableFactory.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymTableFactory.java index f531e1725e1..680679ba469 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymTableFactory.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymTableFactory.java @@ -23,6 +23,7 @@ import net.sourceforge.pmd.lang.ast.NodeStream; import net.sourceforge.pmd.lang.ast.SemanticErrorReporter; +import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter; import net.sourceforge.pmd.lang.java.ast.ASTFormalParameters; import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTList; @@ -365,9 +366,13 @@ JSymbolTable typeHeader(JSymbolTable parent, JClassSymbol sym) { * of fields by local variables and formals. */ JSymbolTable bodyDeclaration(JSymbolTable parent, JClassType enclosing, @Nullable ASTFormalParameters formals, @Nullable ASTTypeParameters tparams) { + NodeStream namedFormals = ASTList.orEmptyStream(formals).map(ASTFormalParameter::getVarId); + if (unnamedVariableIsSupported()) { + namedFormals = namedFormals.filterNot(ASTVariableId::isUnnamed); + } return new SymbolTableImpl( - VARS.shadow(varNode(parent), ScopeInfo.FORMAL_PARAM, VARS.groupByName(ASTList.orEmptyStream(formals), fp -> { - JVariableSymbol sym = fp.getVarId().getSymbol(); + VARS.shadow(varNode(parent), ScopeInfo.FORMAL_PARAM, VARS.groupByName(namedFormals, fp -> { + JVariableSymbol sym = fp.getSymbol(); return sym.getTypeSystem().sigOf(enclosing, (JFormalParamSymbol) sym); })), TYPES.shadow(typeNode(parent), ScopeInfo.TYPE_PARAM, TYPES.groupByName(ASTList.orEmptyStream(tparams), ASTTypeParameter::getTypeMirror)), @@ -386,15 +391,26 @@ JSymbolTable recordCtor(JSymbolTable parent, JClassType recordType, JConstructor JSymbolTable localVarSymTable(JSymbolTable parent, JClassType enclosing, Iterable ids) { List sigs = new ArrayList<>(); for (ASTVariableId id : ids) { + if (unnamedVariableIsSupported() && id.isUnnamed()) { + continue; + } sigs.add(id.getTypeSystem().sigOf(enclosing, (JLocalVariableSymbol) id.getSymbol())); } return SymbolTableImpl.withVars(parent, VARS.augment(varNode(parent), false, ScopeInfo.LOCAL, VARS.groupByName(sigs))); } JSymbolTable localVarSymTable(JSymbolTable parent, JClassType enclosing, JVariableSymbol id) { + if (unnamedVariableIsSupported() && "_".equals(id.getSimpleName())) { + // unnamed variable + return parent; + } return SymbolTableImpl.withVars(parent, VARS.augment(varNode(parent), false, ScopeInfo.LOCAL, id.getTypeSystem().sigOf(enclosing, (JLocalVariableSymbol) id))); } + private boolean unnamedVariableIsSupported() { + return processor.getJdkVersion() >= 22; + } + JSymbolTable localTypeSymTable(JSymbolTable parent, JClassType sym) { // TODO is this really not a shadow barrier? return SymbolTableImpl.withTypes(parent, TYPES.augment(typeNode(parent), false, ScopeInfo.LOCAL, sym)); From 55686dbef43bc0b87a48886b0fb9099eef674c49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Wed, 17 Apr 2024 15:57:23 -0300 Subject: [PATCH 0013/1962] Rename JUnit4TestShouldUseBeforeAnnotation - Call it JUnitTestShouldUseBeforeAnnotation as it applies to JUnit 4 and 5. - Improve the doc to clarify it's intended use. --- .../main/resources/category/java/bestpractices.xml | 13 +++++++++---- ... => JUnitTestShouldUseBeforeAnnotationTest.java} | 2 +- .../xml/JUnit4TestShouldUseAfterAnnotation.xml | 2 +- ...n.xml => JUnitTestShouldUseBeforeAnnotation.xml} | 2 +- 4 files changed, 12 insertions(+), 7 deletions(-) rename pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/{JUnit4TestShouldUseBeforeAnnotationTest.java => JUnitTestShouldUseBeforeAnnotationTest.java} (88%) rename pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/{JUnit4TestShouldUseBeforeAnnotation.xml => JUnitTestShouldUseBeforeAnnotation.xml} (97%) diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 31fc4fea2eb..20339ec32e6 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -710,15 +710,20 @@ public class MyTest2 { - + + + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junittestshouldusebeforeannotation"> -In JUnit 3, the setUp method was used to set up all data entities required in running tests. -JUnit 4 skips the setUp method and executes all methods annotated with @Before before all tests. +This rule detects methods called setUp() that are not properly annotated as a setup method. +This is primarily intended to assist in upgrading from JUnit 3, where setup methods were required to be called setUp(). +To a lesser extent, this may help detect omissions even under newer JUnit versions, as long as you are following this convention to name the methods. + +JUnit 4 will only execute methods annotated with @Before before all tests. JUnit 5 introduced @BeforeEach and @BeforeAll annotations to execute methods before each test or before all tests in the class, respectively. 3 diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnit4TestShouldUseBeforeAnnotationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestShouldUseBeforeAnnotationTest.java similarity index 88% rename from pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnit4TestShouldUseBeforeAnnotationTest.java rename to pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestShouldUseBeforeAnnotationTest.java index 6922491f02c..018d75b8551 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnit4TestShouldUseBeforeAnnotationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestShouldUseBeforeAnnotationTest.java @@ -9,7 +9,7 @@ import net.sourceforge.pmd.test.PmdRuleTst; -class JUnit4TestShouldUseBeforeAnnotationTest extends PmdRuleTst { +class JUnitTestShouldUseBeforeAnnotationTest extends PmdRuleTst { // no additional unit tests public static class BaseTest { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/JUnit4TestShouldUseAfterAnnotation.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/JUnit4TestShouldUseAfterAnnotation.xml index 69118826e1b..36d346b528c 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/JUnit4TestShouldUseAfterAnnotation.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/JUnit4TestShouldUseAfterAnnotation.xml @@ -136,7 +136,7 @@ public class Foo { [java] JUnit4TestShouldUseBeforeAnnotation false positive when overriding setUp #1592 0 [java] JUnit4TestShouldUseBeforeAnnotation false positive when overriding setUp #1592 0 Date: Wed, 17 Apr 2024 16:01:09 -0300 Subject: [PATCH 0014/1962] Rename JUnit4TestShouldUseAfterAnnotation - Call it JUnitTestShouldUseAfterAnnotation instead as it not only applies to JUnit4 - Improve the doc to further clarify it's usages --- .../main/resources/category/java/bestpractices.xml | 13 +++++++++---- ...a => JUnitTestShouldUseAfterAnnotationTest.java} | 2 +- ...on.xml => JUnitTestShouldUseAfterAnnotation.xml} | 0 3 files changed, 10 insertions(+), 5 deletions(-) rename pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/{JUnit4TestShouldUseAfterAnnotationTest.java => JUnitTestShouldUseAfterAnnotationTest.java} (88%) rename pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/{JUnit4TestShouldUseAfterAnnotation.xml => JUnitTestShouldUseAfterAnnotation.xml} (100%) diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 20339ec32e6..150725b5cbf 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -666,15 +666,20 @@ public class GoodTest { - + + + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junittestshoulduseafterannotation"> -In JUnit 3, the tearDown method was used to clean up all data entities required in running tests. -JUnit 4 skips the tearDown method and executes all methods annotated with @After after running each test. +This rule detects methods called tearDown() that are not properly annotated as a setup method. +This is primarily intended to assist in upgrading from JUnit 3, where tear down methods were required to be called tearDown(). +To a lesser extent, this may help detect omissions under newer JUnit versions, as long as you are following this convention to name the methods. + +JUnit 4 will only execute methods annotated with @After after running each test. JUnit 5 introduced @AfterEach and @AfterAll annotations to execute methods after each test or after all tests in the class, respectively. 3 diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnit4TestShouldUseAfterAnnotationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestShouldUseAfterAnnotationTest.java similarity index 88% rename from pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnit4TestShouldUseAfterAnnotationTest.java rename to pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestShouldUseAfterAnnotationTest.java index 2ea2b290d2d..272d7d9d886 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnit4TestShouldUseAfterAnnotationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestShouldUseAfterAnnotationTest.java @@ -9,7 +9,7 @@ import net.sourceforge.pmd.test.PmdRuleTst; -class JUnit4TestShouldUseAfterAnnotationTest extends PmdRuleTst { +class JUnitTestShouldUseAfterAnnotationTest extends PmdRuleTst { // no additional unit tests public static class BaseTest { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/JUnit4TestShouldUseAfterAnnotation.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/JUnitTestShouldUseAfterAnnotation.xml similarity index 100% rename from pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/JUnit4TestShouldUseAfterAnnotation.xml rename to pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/JUnitTestShouldUseAfterAnnotation.xml From 5301a8e852c839f4608b9efa5dbcc40df7d0463c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Wed, 17 Apr 2024 16:15:06 -0300 Subject: [PATCH 0015/1962] Rename JUnitAssertionsShouldIncludeMessageRule - The rule is now called UnitTestAssertionsShouldIncludeMessageRule as it applies to JUnit and TestNG. - The doc is updated to reflect this. --- ...TestAssertionsShouldIncludeMessageRule.java} | 4 ++-- .../resources/category/java/bestpractices.xml | 17 +++++++++++------ ...TestAssertionsShouldIncludeMessageTest.java} | 2 +- ... UnitTestAssertionsShouldIncludeMessage.xml} | 0 4 files changed, 14 insertions(+), 9 deletions(-) rename pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/{JUnitAssertionsShouldIncludeMessageRule.java => UnitTestAssertionsShouldIncludeMessageRule.java} (90%) rename pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/{JUnitAssertionsShouldIncludeMessageTest.java => UnitTestAssertionsShouldIncludeMessageTest.java} (76%) rename pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/{JUnitAssertionsShouldIncludeMessage.xml => UnitTestAssertionsShouldIncludeMessage.xml} (100%) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitAssertionsShouldIncludeMessageRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestAssertionsShouldIncludeMessageRule.java similarity index 90% rename from pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitAssertionsShouldIncludeMessageRule.java rename to pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestAssertionsShouldIncludeMessageRule.java index 915415a0a32..78be7c765e2 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitAssertionsShouldIncludeMessageRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestAssertionsShouldIncludeMessageRule.java @@ -10,7 +10,7 @@ import net.sourceforge.pmd.lang.java.types.InvocationMatcher; import net.sourceforge.pmd.lang.java.types.InvocationMatcher.CompoundInvocationMatcher; -public class JUnitAssertionsShouldIncludeMessageRule extends AbstractJavaRulechainRule { +public class UnitTestAssertionsShouldIncludeMessageRule extends AbstractJavaRulechainRule { private final CompoundInvocationMatcher checks = InvocationMatcher.parseAll( @@ -28,7 +28,7 @@ public class JUnitAssertionsShouldIncludeMessageRule extends AbstractJavaRulecha "_#assertEquals(double,double,double)" ); - public JUnitAssertionsShouldIncludeMessageRule() { + public UnitTestAssertionsShouldIncludeMessageRule() { super(ASTMethodCall.class); } diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 150725b5cbf..ce67924d9d2 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -885,20 +885,25 @@ class MyTest { // not public, that's fine - + + + message="Unit test assertions should include a message" + class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnitTestAssertionsShouldIncludeMessageRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unittestassertionsshouldincludemessage"> -JUnit assertions should include an informative message - i.e., use the three-argument version of +Unit assertions should include an informative message - i.e., use the three-argument version of assertEquals(), not the two-argument version. + +This rule supports tests using JUnit (3, 4 and 5) and TestNg. 3 Date: Wed, 17 Apr 2024 16:21:36 -0300 Subject: [PATCH 0016/1962] Rename JUnitTestContainsTooManyAssertsRule - The rule is now called UnitTestContainsTooManyAssertsRule as it checks for JUnit and TestNG. - This is further cleared up in the documentation. --- ...le.java => UnitTestContainsTooManyAssertsRule.java} | 4 ++-- .../src/main/resources/category/java/bestpractices.xml | 10 ++++++---- ...st.java => UnitTestContainsTooManyAssertsTest.java} | 2 +- ...yAsserts.xml => UnitTestContainsTooManyAsserts.xml} | 0 4 files changed, 9 insertions(+), 7 deletions(-) rename pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/{JUnitTestContainsTooManyAssertsRule.java => UnitTestContainsTooManyAssertsRule.java} (94%) rename pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/{JUnitTestContainsTooManyAssertsTest.java => UnitTestContainsTooManyAssertsTest.java} (78%) rename pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/{JUnitTestContainsTooManyAsserts.xml => UnitTestContainsTooManyAsserts.xml} (100%) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestContainsTooManyAssertsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestContainsTooManyAssertsRule.java similarity index 94% rename from pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestContainsTooManyAssertsRule.java rename to pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestContainsTooManyAssertsRule.java index e68ac3e9acc..42168a10b57 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestContainsTooManyAssertsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestContainsTooManyAssertsRule.java @@ -16,7 +16,7 @@ import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.properties.PropertyFactory; -public class JUnitTestContainsTooManyAssertsRule extends AbstractJavaRulechainRule { +public class UnitTestContainsTooManyAssertsRule extends AbstractJavaRulechainRule { private static final PropertyDescriptor MAX_ASSERTS = PropertyFactory.intProperty("maximumAsserts") @@ -33,7 +33,7 @@ public class JUnitTestContainsTooManyAssertsRule extends AbstractJavaRulechainRu .build(); - public JUnitTestContainsTooManyAssertsRule() { + public UnitTestContainsTooManyAssertsRule() { super(ASTMethodDeclaration.class); definePropertyDescriptor(MAX_ASSERTS); definePropertyDescriptor(EXTRA_ASSERT_METHOD_NAMES); diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index ce67924d9d2..fb8fb1d58e9 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -915,18 +915,20 @@ public class Foo { - + + + class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnitTestContainsTooManyAssertsRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unittestcontainstoomanyasserts"> Unit tests should not contain too many asserts. Many asserts are indicative of a complex test, for which it is harder to verify correctness. Consider breaking the test scenario into multiple, shorter test scenarios. Customize the maximum number of assertions used by this Rule to suit your needs. -This rule checks for JUnit4, JUnit5 and TestNG Tests, as well as methods starting with "test". +This rule checks for JUnit (3, 4 and 5) and TestNG Tests. 3 diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestContainsTooManyAssertsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestContainsTooManyAssertsTest.java similarity index 78% rename from pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestContainsTooManyAssertsTest.java rename to pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestContainsTooManyAssertsTest.java index 30404275d4e..e0d7780c956 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestContainsTooManyAssertsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestContainsTooManyAssertsTest.java @@ -6,6 +6,6 @@ import net.sourceforge.pmd.test.PmdRuleTst; -class JUnitTestContainsTooManyAssertsTest extends PmdRuleTst { +class UnitTestContainsTooManyAssertsTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/JUnitTestContainsTooManyAsserts.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestContainsTooManyAsserts.xml similarity index 100% rename from pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/JUnitTestContainsTooManyAsserts.xml rename to pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestContainsTooManyAsserts.xml From 9f1ab89d31e5f8936fe9c13b95c219b45031b012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Wed, 17 Apr 2024 16:25:03 -0300 Subject: [PATCH 0017/1962] Rename JUnitTestsShouldIncludeAssertRule - It's now called UnitTestsShouldIncludeAssertRule as it applies to JUnit and TestNG - The doc is updated to reflect this --- ... => UnitTestsShouldIncludeAssertRule.java} | 4 +-- .../resources/category/java/bestpractices.xml | 27 ++++++++++++------- ... => UnitTestsShouldIncludeAssertTest.java} | 2 +- ...t.xml => UnitTestsShouldIncludeAssert.xml} | 0 4 files changed, 20 insertions(+), 13 deletions(-) rename pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/{JUnitTestsShouldIncludeAssertRule.java => UnitTestsShouldIncludeAssertRule.java} (92%) rename pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/{JUnitTestsShouldIncludeAssertTest.java => UnitTestsShouldIncludeAssertTest.java} (78%) rename pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/{JUnitTestsShouldIncludeAssert.xml => UnitTestsShouldIncludeAssert.xml} (100%) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestsShouldIncludeAssertRule.java similarity index 92% rename from pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java rename to pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestsShouldIncludeAssertRule.java index b5bf29134b1..867ae525048 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestsShouldIncludeAssertRule.java @@ -15,7 +15,7 @@ import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.properties.PropertyFactory; -public class JUnitTestsShouldIncludeAssertRule extends AbstractJavaRulechainRule { +public class UnitTestsShouldIncludeAssertRule extends AbstractJavaRulechainRule { private static final PropertyDescriptor> EXTRA_ASSERT_METHOD_NAMES = PropertyFactory.stringProperty("extraAssertMethodNames") @@ -24,7 +24,7 @@ public class JUnitTestsShouldIncludeAssertRule extends AbstractJavaRulechainRule .emptyDefaultValue() .build(); - public JUnitTestsShouldIncludeAssertRule() { + public UnitTestsShouldIncludeAssertRule() { super(ASTMethodDeclaration.class); definePropertyDescriptor(EXTRA_ASSERT_METHOD_NAMES); } diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index fb8fb1d58e9..61489edcf9e 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -933,14 +933,16 @@ This rule checks for JUnit (3, 4 and 5) and TestNG Tests. 3 - + + + message="Unit tests should include assert() or fail()" + class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnitTestsShouldIncludeAssertRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unittestsshouldincludeassert"> -JUnit tests should include at least one assertion. This makes the tests more robust, and using assert +Unit tests should include at least one assertion. This makes the tests more robust, and using assert with messages provide the developer a clearer idea of what the test does. + +This rule checks for JUnit (3, 4 and 5) and TestNG Tests. 3 diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestsShouldIncludeAssertTest.java similarity index 78% rename from pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertTest.java rename to pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestsShouldIncludeAssertTest.java index 933f3f612c1..b76c92f6150 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestsShouldIncludeAssertTest.java @@ -6,6 +6,6 @@ import net.sourceforge.pmd.test.PmdRuleTst; -class JUnitTestsShouldIncludeAssertTest extends PmdRuleTst { +class UnitTestsShouldIncludeAssertTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/JUnitTestsShouldIncludeAssert.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestsShouldIncludeAssert.xml similarity index 100% rename from pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/JUnitTestsShouldIncludeAssert.xml rename to pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestsShouldIncludeAssert.xml From 77258973733e164e5fb40579dc8d1b15b6f8a0c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Wed, 17 Apr 2024 16:33:26 -0300 Subject: [PATCH 0018/1962] Rename JUnit4TestShouldUseTestAnnotation - The rule is now called UnitTestShouldUseTestAnnotation as it applies to both JUnit and TestNG. - The doc is further improved to reflect this. --- .../main/resources/category/java/bestpractices.xml | 11 +++++++---- ....java => UnitTestShouldUseTestAnnotationTest.java} | 2 +- ...tation.xml => UnitTestShouldUseTestAnnotation.xml} | 0 3 files changed, 8 insertions(+), 5 deletions(-) rename pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/{JUnit4TestShouldUseTestAnnotationTest.java => UnitTestShouldUseTestAnnotationTest.java} (77%) rename pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/{JUnit4TestShouldUseTestAnnotation.xml => UnitTestShouldUseTestAnnotation.xml} (100%) diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 61489edcf9e..24457e334d4 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -765,14 +765,17 @@ public class MyTest2 { - + + + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unittestshouldusetestannotation"> -In JUnit 3, the framework executed all methods which started with the word test as a unit test. +The rule will detect any test method starting with "test" that is not properly annotated, and will therefore not be run. + In JUnit 4, only methods annotated with the @Test annotation are executed. In JUnit 5, one of the following annotations should be used for tests: @Test, @RepeatedTest, @TestFactory, @TestTemplate or @ParameterizedTest. In TestNG, only methods annotated with the @Test annotation are executed. diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnit4TestShouldUseTestAnnotationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldUseTestAnnotationTest.java similarity index 77% rename from pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnit4TestShouldUseTestAnnotationTest.java rename to pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldUseTestAnnotationTest.java index 15b507dafb3..3f50bf341c1 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnit4TestShouldUseTestAnnotationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldUseTestAnnotationTest.java @@ -6,6 +6,6 @@ import net.sourceforge.pmd.test.PmdRuleTst; -class JUnit4TestShouldUseTestAnnotationTest extends PmdRuleTst { +class UnitTestShouldUseTestAnnotationTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/JUnit4TestShouldUseTestAnnotation.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldUseTestAnnotation.xml similarity index 100% rename from pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/JUnit4TestShouldUseTestAnnotation.xml rename to pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldUseTestAnnotation.xml From bd89f9185b636fa141b90b2ee3ae9d6bc04af4f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Wed, 17 Apr 2024 16:35:32 -0300 Subject: [PATCH 0019/1962] Typo --- pmd-java/src/main/resources/category/java/bestpractices.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 24457e334d4..629f0d8a369 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -900,7 +900,7 @@ class MyTest { // not public, that's fine Unit assertions should include an informative message - i.e., use the three-argument version of assertEquals(), not the two-argument version. -This rule supports tests using JUnit (3, 4 and 5) and TestNg. +This rule supports tests using JUnit (3, 4 and 5) and TestNG. 3 From 61a74592474c811d6e1607a500f482667ad520bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Wed, 17 Apr 2024 17:00:05 -0300 Subject: [PATCH 0020/1962] Update changelog --- docs/pages/release_notes.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 2df014843f7..59d5b924d05 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -16,7 +16,23 @@ This is a {{ site.pmd.release_type }} release. ### ๐ŸŒŸ Rule Changes -* {%rule java/bestpractices/JUnitTestsShouldIncludeAssert %} and {% rule java/bestpractices/JUnitTestContainsTooManyAsserts %} +Several rules for unit testing have been renamed to better reflect their actual scope. Lots of them were called after JUnit / JUnit 4, even when they applied to JUnit 5 and / or TestNG. + +* `java/bestpractices/JUnit4TestShouldUseAfterAnnotation` has been renamed to {% rule java/bestpractices/JUnitTestShouldUseAfterAnnotation %} + +* `java/bestpractices/JUnit4TestShouldUseBeforeAnnotation` has been renamed to {% rule java/bestpractices/JUnitTestShouldUseBeforeAnnotation %} + +* `java/bestpractices/JUnit4TestShouldUseTestAnnotation` has been renamed to {% rule java/bestpractices/UnitTestShouldUseTestAnnotation %} + +* `java/bestpractices/JUnitAssertionsShouldIncludeMessage` has been renamed to {% rule java/bestpractices/UnitTestAssertionsShouldIncludeMessage %} + +* `java/bestpractices/JUnitTestContainsTooManyAsserts` has been renamed to {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} + +* `java/bestpractices/JUnitTestsShouldIncludeAssert` has been renamed to {% rule java/bestpractices/UnitTestsShouldIncludeAssert %} + +Additionaly: + +* {%rule java/bestpractices/UnitTestsShouldIncludeAssert %} and {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} have a new property named `extraAssertMethodNames`. With this property, you can configure which additional static methods should be considered as valid verification methods. This allows to use custom mocking or assertion libraries. From 5b42381061440c94150b26a1c71ce3c8144415be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Sat, 27 Apr 2024 22:11:39 -0300 Subject: [PATCH 0021/1962] Reintroduce old class names - Don't break API compatibility, and set everything for removal in PMD 8 --- .../JUnitAssertionsShouldIncludeMessageRule.java | 13 +++++++++++++ .../JUnitTestContainsTooManyAssertsRule.java | 13 +++++++++++++ .../JUnitTestsShouldIncludeAssertRule.java | 13 +++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitAssertionsShouldIncludeMessageRule.java create mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestContainsTooManyAssertsRule.java create mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitAssertionsShouldIncludeMessageRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitAssertionsShouldIncludeMessageRule.java new file mode 100644 index 00000000000..4da48f44b07 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitAssertionsShouldIncludeMessageRule.java @@ -0,0 +1,13 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.bestpractices; + +/** + * @deprecated The rule was renamed {@link UnitTestAssertionsShouldIncludeMessageRule} + */ +@Deprecated +public class JUnitAssertionsShouldIncludeMessageRule extends UnitTestAssertionsShouldIncludeMessageRule { + +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestContainsTooManyAssertsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestContainsTooManyAssertsRule.java new file mode 100644 index 00000000000..13b9d247e13 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestContainsTooManyAssertsRule.java @@ -0,0 +1,13 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.bestpractices; + +/** + * @deprecated The rule was renamed {@link UnitTestContainsTooManyAssertsRule} + */ +@Deprecated +public class JUnitTestContainsTooManyAssertsRule extends UnitTestContainsTooManyAssertsRule { + +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java new file mode 100644 index 00000000000..ad20f3cca51 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java @@ -0,0 +1,13 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.bestpractices; + +/** + * @deprecated The rule was renamed {@link UnitTestsShouldIncludeAssertRule} + */ +@Deprecated +public class JUnitTestsShouldIncludeAssertRule extends UnitTestsShouldIncludeAssertRule { + +} From 89cba9bee1139fb1dea3ca4fbb060fa1007b7802 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 23 May 2024 21:24:21 +0200 Subject: [PATCH 0022/1962] Make new API experimental --- .../java/net/sourceforge/pmd/reporting/RuleContext.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java index 41d8a980727..ec4a714f718 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java @@ -16,6 +16,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import net.sourceforge.pmd.annotation.Experimental; import net.sourceforge.pmd.lang.LanguageVersionHandler; import net.sourceforge.pmd.lang.ast.AstInfo; import net.sourceforge.pmd.lang.ast.Node; @@ -155,7 +156,12 @@ public void addViolationWithPosition(Node node, int beginLine, int endLine, Stri * @param astInfo Info about the root of the tree ({@link Node#getAstInfo()}) * @param message Violation message * @param formatArgs Format arguments for the message + * + * @experimental This will probably never be stabilized, will instead be + * replaced by a fluent API or something to report violations. Do not use + * this outside of the PMD codebase. See https://github.com/pmd/pmd/issues/5039. */ + @Experimental public void addViolationWithPosition(Reportable reportable, AstInfo astInfo, FileLocation location, String message, Object... formatArgs) { Objects.requireNonNull(reportable, "Node was null"); From a8ed6cdc24516578b3fb6b84cf82950cea486f4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 23 May 2024 22:35:25 +0200 Subject: [PATCH 0023/1962] Make comment owners contain textually their comment --- .../ast/impl/javacc/AbstractJjtreeNode.java | 10 +++--- pmd-java/etc/grammar/Java.jjt | 8 ++--- .../ast/ASTCompactConstructorDeclaration.java | 21 ++++++++++++- .../java/ast/ASTConstructorDeclaration.java | 13 +++----- .../lang/java/ast/ASTMethodDeclaration.java | 21 ------------- .../ast/AbstractExecutableDeclaration.java | 17 ++++++++++ .../pmd/lang/java/ast/AbstractJavaNode.java | 5 +++ .../lang/java/ast/CommentAssignmentPass.java | 3 ++ .../documentation/CommentContentRule.java | 9 ++++-- .../rule/documentation/xml/CommentContent.xml | 31 +++++++++++++++++++ 10 files changed, 94 insertions(+), 44 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/AbstractJjtreeNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/AbstractJjtreeNode.java index 34859a89329..6c9394246dd 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/AbstractJjtreeNode.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/AbstractJjtreeNode.java @@ -90,25 +90,23 @@ protected void insertChild(B child, int index) { */ protected void fitTokensToChildren(int index) { if (index == 0) { - enlargeLeft((B) getChild(index)); + enlargeLeft(getChild(index).getFirstToken()); } if (index == getNumChildren()) { - enlargeRight((B) getChild(index)); + enlargeRight(getChild(index).getLastToken()); } } - private void enlargeLeft(B child) { + protected void enlargeLeft(JavaccToken childFst) { JavaccToken thisFst = this.getFirstToken(); - JavaccToken childFst = child.getFirstToken(); if (childFst.compareTo(thisFst) < 0) { this.setFirstToken(childFst); } } - private void enlargeRight(B child) { + private void enlargeRight(JavaccToken childLast) { JavaccToken thisLast = this.getLastToken(); - JavaccToken childLast = child.getLastToken(); if (childLast.compareTo(thisLast) > 0) { this.setLastToken(childLast); diff --git a/pmd-java/etc/grammar/Java.jjt b/pmd-java/etc/grammar/Java.jjt index a3fe7248018..511c1fdad7f 100644 --- a/pmd-java/etc/grammar/Java.jjt +++ b/pmd-java/etc/grammar/Java.jjt @@ -1318,7 +1318,7 @@ private void CompactConstructorDeclarationLookahead() #void: void CompactConstructorDeclaration(): {} { - { jjtThis.setImage(token.image); } + { jjtThis.setIdentToken(token); } Block() } @@ -1411,7 +1411,7 @@ void MethodDeclaration() : { [ TypeParameters() ] ResultType() - { jjtThis.setName(getToken(0).getImage()); } + { jjtThis.setIdentToken(getToken(0)); } FormalParameters() [ Dims() ] [ ThrowsList() ] @@ -1459,7 +1459,7 @@ void ConstructorDeclaration() : {} { [ TypeParameters() ] - {setLastTokenImage(jjtThis);} + {jjtThis.setIdentToken(token);} FormalParameters() [ ThrowsList() ] ConstructorBlock() @@ -2954,7 +2954,7 @@ void AnnotationMethodDeclaration() #MethodDeclaration: {} { Type() - { jjtThis.setName(getToken(0).getImage()); } + { jjtThis.setIdentToken(getToken(0)); } ("(" ")") #FormalParameters [ Dims() ] [ DefaultValue() ] ";" diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompactConstructorDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompactConstructorDeclaration.java index c7e86c64641..9aa392d8b02 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompactConstructorDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompactConstructorDeclaration.java @@ -5,6 +5,8 @@ package net.sourceforge.pmd.lang.java.ast; +import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken; +import net.sourceforge.pmd.lang.document.FileLocation; import net.sourceforge.pmd.lang.java.symbols.JConstructorSymbol; /** @@ -24,12 +26,29 @@ */ // TODO make implicit formal parameter node and implement ASTExecutableDeclaration. // This might help UnusedAssignmentRule / DataflowPass.ReachingDefsVisitor, see also #4603 -public final class ASTCompactConstructorDeclaration extends AbstractJavaNode implements ASTBodyDeclaration, SymbolDeclaratorNode, ModifierOwner { +public final class ASTCompactConstructorDeclaration extends AbstractJavaNode implements ASTBodyDeclaration, SymbolDeclaratorNode, ModifierOwner, JavadocCommentOwner { + + private JavaccToken identToken; ASTCompactConstructorDeclaration(int id) { super(id); } + + @Override + public FileLocation getReportLocation() { + return identToken.getReportLocation(); + } + + void setIdentToken(JavaccToken identToken) { + this.identToken = identToken; + } + + @Override + public String getImage() { + return identToken.getImage(); + } + @Override protected R acceptVisitor(JavaVisitor visitor, P data) { return visitor.visit(this, data); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclaration.java index 8747e35f743..4d52a92d860 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclaration.java @@ -6,7 +6,6 @@ import org.checkerframework.checker.nullness.qual.NonNull; -import net.sourceforge.pmd.lang.document.FileLocation; import net.sourceforge.pmd.lang.java.symbols.JConstructorSymbol; /** @@ -31,18 +30,14 @@ public final class ASTConstructorDeclaration extends AbstractExecutableDeclarati } @Override - public String getName() { - return getImage(); + protected R acceptVisitor(JavaVisitor visitor, P data) { + return visitor.visit(this, data); } - @Override - public FileLocation getReportLocation() { - return getModifiers().getLastToken().getNext().getReportLocation(); - } @Override - protected R acceptVisitor(JavaVisitor visitor, P data) { - return visitor.visit(this, data); + public String getImage() { + return getName(); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java index 2abc270355d..7e0f75f3547 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java @@ -7,8 +7,6 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; -import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken; -import net.sourceforge.pmd.lang.document.FileLocation; import net.sourceforge.pmd.lang.java.symbols.JMethodSymbol; import net.sourceforge.pmd.lang.java.types.JMethodSig; import net.sourceforge.pmd.lang.java.types.TypeSystem; @@ -43,8 +41,6 @@ */ public final class ASTMethodDeclaration extends AbstractExecutableDeclaration { - private String name; - /** * Populated by {@link OverrideResolutionPass}. */ @@ -83,23 +79,6 @@ void setOverriddenMethod(JMethodSig overriddenMethod) { this.overriddenMethod = overriddenMethod; } - @Override - public FileLocation getReportLocation() { - // the method identifier - JavaccToken ident = TokenUtils.nthPrevious(getModifiers().getLastToken(), getFormalParameters().getFirstToken(), 1); - return ident.getReportLocation(); - } - - /** Returns the simple name of the method. */ - @Override - public String getName() { - return name; - } - - void setName(String name) { - this.name = name; - } - /** * If this method declaration is an explicit record component accessor, * returns the corresponding record component. Otherwise returns null. diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractExecutableDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractExecutableDeclaration.java index 179bc077a19..cffa35765c8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractExecutableDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractExecutableDeclaration.java @@ -4,6 +4,8 @@ package net.sourceforge.pmd.lang.java.ast; +import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken; +import net.sourceforge.pmd.lang.document.FileLocation; import net.sourceforge.pmd.lang.java.symbols.JExecutableSymbol; import net.sourceforge.pmd.lang.java.types.JMethodSig; @@ -15,11 +17,15 @@ abstract class AbstractExecutableDeclaration private T symbol; private JMethodSig sig; + private JavaccToken identToken; AbstractExecutableDeclaration(int i) { super(i); } + void setIdentToken(JavaccToken identToken) { + this.identToken = identToken; + } void setSymbol(T symbol) { AbstractTypedSymbolDeclarator.assertSymbolNull(this.symbol, this); @@ -39,4 +45,15 @@ public JMethodSig getGenericSignature() { } return sig; } + + + @Override + public FileLocation getReportLocation() { + return identToken.getReportLocation(); + } + + @Override + public String getName() { + return identToken.getImage(); + } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaNode.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaNode.java index b8d971241af..b887549320b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaNode.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaNode.java @@ -75,6 +75,11 @@ protected void setLastToken(JavaccToken token) { super.setLastToken(token); } + @Override + protected void enlargeLeft(JavaccToken child) { + super.enlargeLeft(child); + } + @Override protected void setChild(AbstractJavaNode child, int index) { super.setChild(child, index); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/CommentAssignmentPass.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/CommentAssignmentPass.java index 7c63aaf9240..31affd0b17f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/CommentAssignmentPass.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/CommentAssignmentPass.java @@ -32,6 +32,9 @@ private CommentAssignmentPass() { private static void setComment(JavadocCommentOwner commentableNode, JavadocComment comment) { commentableNode.getUserMap().set(FORMAL_COMMENT_KEY, comment); comment.setOwner(commentableNode); + // This makes the node cover the comment too. + AbstractJavaNode node = (AbstractJavaNode) commentableNode; + node.enlargeLeft(comment.getToken()); } public static void assignCommentsToDeclarations(ASTCompilationUnit root) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentContentRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentContentRule.java index ec354ee05d0..1a3318d03e7 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentContentRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentContentRule.java @@ -10,6 +10,7 @@ import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.document.Chars; +import net.sourceforge.pmd.lang.document.FileLocation; import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.ast.JavaComment; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; @@ -51,10 +52,12 @@ private void reportIllegalTerms(RuleContext ctx, JavaComment comment, Pattern vi int lineNumber = comment.getReportLocation().getStartLine(); for (Chars line : comment.getFilteredLines(true)) { if (violationRegex.matcher(line).find()) { + + FileLocation location = FileLocation.caret(acu.getTextDocument().getFileId(), lineNumber, 1); ctx.addViolationWithPosition( - acu, - lineNumber, - lineNumber, + comment.getToken(), + acu.getAstInfo(), + location, "Line matches forbidden content regex ({0})", violationRegex.pattern() ); diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentContent.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentContent.xml index 8982d4916a7..b5db4316e45 100755 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentContent.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentContent.xml @@ -54,6 +54,37 @@ public class Foo { // doNothing public void doNothing() { } +} + ]]> + + + Suppression + idiot|jerk + 0 + From 2a7a80f927ece7fb35eaaeb49017acc56b750c33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 5 Jun 2024 11:06:09 +0200 Subject: [PATCH 0024/1962] Add custom experimental tag in javadoc --- pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pom.xml b/pom.xml index f78eeeb4049..69c93a7453b 100644 --- a/pom.xml +++ b/pom.xml @@ -412,6 +412,11 @@ a Implementation Note: + + experimental + a + Experimental Status: + param return throws From 0253b9d3cd2cfab4df08eb36dd48dd8a335e2171 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Sat, 14 Sep 2024 01:33:20 -0300 Subject: [PATCH 0025/1962] Ignore generated-sources in coverage reports - We don't test it directly, nor is it our job - A bad grammar won't be processed, or fail in subtle ways only detectable in specific tests on the AST (which is included) --- pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pom.xml b/pom.xml index 3c410ebe803..f2cb4d826c3 100644 --- a/pom.xml +++ b/pom.xml @@ -612,6 +612,11 @@ org.jacoco jacoco-maven-plugin 0.8.11 + + + **/target/generated-sources/** + + org.cyclonedx From 029130a478e1c4c585c965dca224961df18c7034 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Tue, 17 Sep 2024 17:00:42 -0300 Subject: [PATCH 0026/1962] Use a custom annotation to ignore javacc generated code --- javacc-wrapper.xml | 21 ++++++++++++----- .../sourceforge/pmd/annotation/Generated.java | 23 +++++++++++++++++++ pom.xml | 7 +----- 3 files changed, 39 insertions(+), 12 deletions(-) create mode 100644 pmd-core/src/main/java/net/sourceforge/pmd/annotation/Generated.java diff --git a/javacc-wrapper.xml b/javacc-wrapper.xml index 2c43e086d88..bbd50e21a4a 100644 --- a/javacc-wrapper.xml +++ b/javacc-wrapper.xml @@ -224,6 +224,11 @@ + + ${parser-name} + + @@ -262,7 +267,8 @@ - + @@ -272,7 +278,8 @@ - + @@ -385,11 +392,12 @@ - +'/> @@ -534,8 +542,9 @@ public final class ${token-constants-name} \{${line.separator} - + diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/annotation/Generated.java b/pmd-core/src/main/java/net/sourceforge/pmd/annotation/Generated.java new file mode 100644 index 00000000000..ab9b46f465b --- /dev/null +++ b/pmd-core/src/main/java/net/sourceforge/pmd/annotation/Generated.java @@ -0,0 +1,23 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Marks a class as generated code, and therefore to be ignored for code coverage purposes. + * + * @since 7.6.0 + */ +@Retention(RetentionPolicy.CLASS) +@Documented +public @interface Generated { + + /** The generator that produced this code */ + String value() default ""; + +} diff --git a/pom.xml b/pom.xml index f2cb4d826c3..216fad40565 100644 --- a/pom.xml +++ b/pom.xml @@ -611,12 +611,7 @@ org.jacoco jacoco-maven-plugin - 0.8.11 - - - **/target/generated-sources/** - - + 0.8.12 org.cyclonedx From cae71e7a5e72bba07867a38072b9e580aebfa97e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Tue, 17 Sep 2024 17:09:29 -0300 Subject: [PATCH 0027/1962] Be consistent in how we replace tokens --- javacc-wrapper.xml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/javacc-wrapper.xml b/javacc-wrapper.xml index bbd50e21a4a..05837e96ba7 100644 --- a/javacc-wrapper.xml +++ b/javacc-wrapper.xml @@ -224,9 +224,7 @@ - - ${parser-name} + From ddb1eb8dd8c9eada9a10ac112c7d3bcd9ad8988c Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Sat, 21 Sep 2024 16:03:36 +0200 Subject: [PATCH 0028/1962] [java] Fix #5067: CloseResource: False positive for FileSystems.getDefault() --- .../java/rule/errorprone/CloseResourceRule.java | 7 +++++++ .../java/rule/errorprone/xml/CloseResource.xml | 14 ++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceRule.java index c3aa18a4597..28c432a0753 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceRule.java @@ -204,6 +204,7 @@ private Map getResourceVariables(ASTExecutableDeclarati .filter(this::isVariableNotSpecifiedInTryWithResource) .filter(var -> isResourceTypeOrSubtype(var) || isNodeInstanceOfResourceType(getTypeOfVariable(var))) .filterNot(var -> var.isAnnotationPresent("lombok.Cleanup")) + .filterNot(this::isDefaultFileSystem) .toList(); for (ASTVariableId var : vars) { @@ -499,6 +500,12 @@ private boolean isVariableNotSpecifiedInTryWithResource(ASTVariableId varId) { return tryStatement == null || !isVariableSpecifiedInTryWithResource(varId, tryStatement); } + private boolean isDefaultFileSystem(ASTVariableId varId) { + @Nullable + ASTExpression initializer = varId.getInitializer(); + return initializer != null && initializer.getText().contentEquals("FileSystems.getDefault()"); + } + private boolean isVariableSpecifiedInTryWithResource(ASTVariableId varId, ASTTryStatement tryWithResource) { // skip own resources - these are definitively closed if (tryWithResource.getResources().descendants(ASTVariableId.class).toList().contains(varId)) { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml index f0e32dbfd4e..ac1c35d401b 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml @@ -2044,6 +2044,20 @@ public class CastedParameter { // doesn't need to be closed, it's still a paramterโ€ฆ } } +} + ]]> + + + #5067: FileSystems.getDefault() can't be closed + 0 + From 5fe19b2096348b8f321b96a7c936cff056463fed Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Sep 2024 11:43:22 +0200 Subject: [PATCH 0029/1962] [release] Prepare next development version [skip ci] --- docs/_config.yml | 6 +- docs/pages/release_notes.md | 87 +---------------- docs/pages/release_notes_old.md | 108 +++++++++++++++++++++ pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 4 +- 45 files changed, 156 insertions(+), 131 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index de55fdfd104..912d463cc10 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,9 +1,9 @@ repository: pmd/pmd pmd: - version: 7.6.0 - previous_version: 7.5.0 - date: 2024-09-27 + version: 7.7.0-SNAPSHOT + previous_version: 7.6.0 + date: 2024-10-25 # release types: major, minor, bugfix release_type: minor diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index d76aafb7a95..bc1a36ec7a8 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -14,94 +14,11 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy -#### New Git default branch - "main" - -We are joining the Git community and updating "master" to "main". Using the term "master" for the main -development branch can be offensive to some people. Existing versions of Git have been always capable of -working with any branch name and since 2.28.0 (July 2020) the default initial branch is configurable -(`init.defaultBranch`). Since October 2020, the default branch for new repositories on GitHub -is "main". Finally, PMD will also use this new name for the main branch in all our own repositories. - -Why "main"? PMD uses a very simple branching model - pull requests with feature branches and one main development -branch, from which releases are created. That's why "main" is currently the best fitting name. - -More information: -- -- - -What changes? -- We change the default branch on GitHub, so that pull requests are automatically created against `main` from - now on. -- If you have already a local clone of PMD's repository, you'll need to rename the old master branch locally: - ``` - git branch --move master main - git fetch origin - git branch --set-upstream-to=origin/main main - git remote set-head origin --auto - ``` - - More info: - and - -- If you created a fork on GitHub, you'll need to change the default branch in your fork to `main` as - well (Settings > Default Branch). -- Some time after this release, we'll delete the old master branch on GitHub. Then only `main` can be used. -- This change is expanded to the other PMD repositories as well, e.g. pmd-designer and pmd-regression-tester. - ### ๐Ÿ› Fixed Issues -* apex - * [#5138](https://github.com/pmd/pmd/issues/5138): \[apex] Various false-negatives since 7.3.0 when using triggers - (ApexCRUDViolation, CognitiveComplexity, OperationWithLimitsInLoop) - * [#5163](https://github.com/pmd/pmd/issues/5163): \[apex] Parser error when using toLabel in SOSL query - * [#5182](https://github.com/pmd/pmd/issues/5182): \[apex] Parser error when using GROUPING in a SOQL query - * [#5218](https://github.com/pmd/pmd/issues/5218): \[apex] Parser error when using nested subqueries in SOQL - * [#5228](https://github.com/pmd/pmd/issues/5228): \[apex] Parser error when using convertCurrency() in SOQL -* core - * [#5059](https://github.com/pmd/pmd/issues/5059): \[core] xml output doesn't escape CDATA inside its own CDATA - * [#5201](https://github.com/pmd/pmd/issues/5201): \[core] PMD sarif schema file points to nonexistent location - * [#5222](https://github.com/pmd/pmd/issues/5222): \[core] RuleReference/RuleSetWriter don't handle changed default property values correctly - * [#5229](https://github.com/pmd/pmd/issues/5229): \[doc] CLI flag `--show-suppressed` needs to mention xml, html, summaryhtml -* java - * [#5190](https://github.com/pmd/pmd/issues/5190): \[java] NPE in type inference -* java-codestyle - * [#5046](https://github.com/pmd/pmd/issues/5046): \[java] LocalVariableCouldBeFinal false positive with try/catch -* java-errorprone - * [#5068](https://github.com/pmd/pmd/issues/5068): \[java] MissingStaticMethodInNonInstantiatableClass: false positive with builder pattern - * [#5207](https://github.com/pmd/pmd/issues/5207): \[java] CheckSkipResult: false positve for a private method `void skip(int)` in a subclass of FilterInputStream ### ๐Ÿšจ API Changes -No changes. - -### โœจ Merged pull requests -* [#5186](https://github.com/pmd/pmd/pull/5186): \[java] Cleanup things about implicit classes - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5188](https://github.com/pmd/pmd/pull/5188): \[apex] Use new apex-parser 4.2.0 - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5191](https://github.com/pmd/pmd/pull/5191): \[java] Fix #5046 - FPs in LocalVariableCouldBeFinal - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5192](https://github.com/pmd/pmd/pull/5192): \[java] Fix #5190 - NPE in type inference caused by null type - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5195](https://github.com/pmd/pmd/pull/5195): \[apex] Fix various FNs when using triggers - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5202](https://github.com/pmd/pmd/pull/5202): \[core] Sarif format: refer to schemastore.org - [David Schach](https://github.com/dschach) (@dschach) -* [#5208](https://github.com/pmd/pmd/pull/5208): \[doc] Added Codety to "Tools / Integrations" - [Tony](https://github.com/random1223) (@random1223) -* [#5210](https://github.com/pmd/pmd/pull/5210): \[core] Fix PMD's XMLRenderer to escape CDATA - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5211](https://github.com/pmd/pmd/pull/5211): Change branch master to main - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5212](https://github.com/pmd/pmd/pull/5212): \[java] Adjust signature matching in CheckSkipResultRule - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) -* [#5223](https://github.com/pmd/pmd/pull/5223): \[core] Fix RuleReference / RuleSetWriter handling of properties - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5224](https://github.com/pmd/pmd/pull/5224): \[java] Fix #5068: Class incorrectly identified as non-instantiatable - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) -* [#5230](https://github.com/pmd/pmd/pull/5230): \[doc] Documentation update for --show-suppressed flag - [David Schach](https://github.com/dschach) (@dschach) -* [#5237](https://github.com/pmd/pmd/pull/5237): \[apex] Support convertCurrency() in SOQL/SOSL - [Andreas Dangel](https://github.com/adangel) (@adangel) - -### ๐Ÿ“ฆ Dependency updates -* [#5185](https://github.com/pmd/pmd/issues/5185): Bump checkstyle from 10.14.0 to 10.18.1 -* [#5187](https://github.com/pmd/pmd/issues/5187): Bump org.apache.maven.plugins:maven-install-plugin from 3.1.1 to 3.1.3 -* [#5199](https://github.com/pmd/pmd/issues/5199): Bump org.apache.maven.plugins:maven-deploy-plugin from 3.1.1 to 3.1.3 -* [#5216](https://github.com/pmd/pmd/issues/5216): Bump com.github.siom79.japicmp:japicmp-maven-plugin from 0.20.0 to 0.23.0 -* [#5226](https://github.com/pmd/pmd/issues/5226): Bump rouge from 4.3.0 to 4.4.0 in the all-gems group across 1 directory -* [#5227](https://github.com/pmd/pmd/issues/5227): Bump com.google.code.gson:gson from 2.10.1 to 2.11.0 -* [#5232](https://github.com/pmd/pmd/issues/5232): Bump com.google.protobuf:protobuf-java from 3.25.3 to 3.25.5 -* [#5233](https://github.com/pmd/pmd/issues/5233): Bump webrick from 1.8.1 to 1.8.2 in /docs - -### ๐Ÿ“ˆ Stats -* 60 commits -* 27 closed tickets & PRs -* Days since last release: 27 +### โœจ External Contributions {% endtocmaker %} + diff --git a/docs/pages/release_notes_old.md b/docs/pages/release_notes_old.md index 1dbd44da28b..6a7983db8b0 100644 --- a/docs/pages/release_notes_old.md +++ b/docs/pages/release_notes_old.md @@ -5,6 +5,114 @@ permalink: pmd_release_notes_old.html Previous versions of PMD can be downloaded here: [Releases - pmd/pmd (GitHub)](https://github.com/pmd/pmd/releases) +## 27-September-2024 - 7.6.0 + +The PMD team is pleased to announce PMD 7.6.0. + +This is a minor release. + +### Table Of Contents + +* [๐Ÿš€ New and noteworthy](#new-and-noteworthy) + * [New Git default branch - "main"](#new-git-default-branch---main) +* [๐Ÿ› Fixed Issues](#fixed-issues) +* [๐Ÿšจ API Changes](#api-changes) +* [โœจ Merged pull requests](#merged-pull-requests) +* [๐Ÿ“ฆ Dependency updates](#dependency-updates) +* [๐Ÿ“ˆ Stats](#stats) + +### ๐Ÿš€ New and noteworthy + +#### New Git default branch - "main" + +We are joining the Git community and updating "master" to "main". Using the term "master" for the main +development branch can be offensive to some people. Existing versions of Git have been always capable of +working with any branch name and since 2.28.0 (July 2020) the default initial branch is configurable +(`init.defaultBranch`). Since October 2020, the default branch for new repositories on GitHub +is "main". Finally, PMD will also use this new name for the main branch in all our own repositories. + +Why "main"? PMD uses a very simple branching model - pull requests with feature branches and one main development +branch, from which releases are created. That's why "main" is currently the best fitting name. + +More information: +- +- + +What changes? +- We change the default branch on GitHub, so that pull requests are automatically created against `main` from + now on. +- If you have already a local clone of PMD's repository, you'll need to rename the old master branch locally: + ``` + git branch --move master main + git fetch origin + git branch --set-upstream-to=origin/main main + git remote set-head origin --auto + ``` + + More info: + and + +- If you created a fork on GitHub, you'll need to change the default branch in your fork to `main` as + well (Settings > Default Branch). +- Some time after this release, we'll delete the old master branch on GitHub. Then only `main` can be used. +- This change is expanded to the other PMD repositories as well, e.g. pmd-designer and pmd-regression-tester. + +### ๐Ÿ› Fixed Issues +* apex + * [#5138](https://github.com/pmd/pmd/issues/5138): \[apex] Various false-negatives since 7.3.0 when using triggers + (ApexCRUDViolation, CognitiveComplexity, OperationWithLimitsInLoop) + * [#5163](https://github.com/pmd/pmd/issues/5163): \[apex] Parser error when using toLabel in SOSL query + * [#5182](https://github.com/pmd/pmd/issues/5182): \[apex] Parser error when using GROUPING in a SOQL query + * [#5218](https://github.com/pmd/pmd/issues/5218): \[apex] Parser error when using nested subqueries in SOQL + * [#5228](https://github.com/pmd/pmd/issues/5228): \[apex] Parser error when using convertCurrency() in SOQL +* core + * [#5059](https://github.com/pmd/pmd/issues/5059): \[core] xml output doesn't escape CDATA inside its own CDATA + * [#5201](https://github.com/pmd/pmd/issues/5201): \[core] PMD sarif schema file points to nonexistent location + * [#5222](https://github.com/pmd/pmd/issues/5222): \[core] RuleReference/RuleSetWriter don't handle changed default property values correctly + * [#5229](https://github.com/pmd/pmd/issues/5229): \[doc] CLI flag `--show-suppressed` needs to mention xml, html, summaryhtml +* java + * [#5190](https://github.com/pmd/pmd/issues/5190): \[java] NPE in type inference +* java-codestyle + * [#5046](https://github.com/pmd/pmd/issues/5046): \[java] LocalVariableCouldBeFinal false positive with try/catch +* java-errorprone + * [#5068](https://github.com/pmd/pmd/issues/5068): \[java] MissingStaticMethodInNonInstantiatableClass: false positive with builder pattern + * [#5207](https://github.com/pmd/pmd/issues/5207): \[java] CheckSkipResult: false positve for a private method `void skip(int)` in a subclass of FilterInputStream + +### ๐Ÿšจ API Changes + +No changes. + +### โœจ Merged pull requests +* [#5186](https://github.com/pmd/pmd/pull/5186): \[java] Cleanup things about implicit classes - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5188](https://github.com/pmd/pmd/pull/5188): \[apex] Use new apex-parser 4.2.0 - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5191](https://github.com/pmd/pmd/pull/5191): \[java] Fix #5046 - FPs in LocalVariableCouldBeFinal - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5192](https://github.com/pmd/pmd/pull/5192): \[java] Fix #5190 - NPE in type inference caused by null type - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5195](https://github.com/pmd/pmd/pull/5195): \[apex] Fix various FNs when using triggers - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5202](https://github.com/pmd/pmd/pull/5202): \[core] Sarif format: refer to schemastore.org - [David Schach](https://github.com/dschach) (@dschach) +* [#5208](https://github.com/pmd/pmd/pull/5208): \[doc] Added Codety to "Tools / Integrations" - [Tony](https://github.com/random1223) (@random1223) +* [#5210](https://github.com/pmd/pmd/pull/5210): \[core] Fix PMD's XMLRenderer to escape CDATA - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5211](https://github.com/pmd/pmd/pull/5211): Change branch master to main - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5212](https://github.com/pmd/pmd/pull/5212): \[java] Adjust signature matching in CheckSkipResultRule - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5223](https://github.com/pmd/pmd/pull/5223): \[core] Fix RuleReference / RuleSetWriter handling of properties - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5224](https://github.com/pmd/pmd/pull/5224): \[java] Fix #5068: Class incorrectly identified as non-instantiatable - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#5230](https://github.com/pmd/pmd/pull/5230): \[doc] Documentation update for --show-suppressed flag - [David Schach](https://github.com/dschach) (@dschach) +* [#5237](https://github.com/pmd/pmd/pull/5237): \[apex] Support convertCurrency() in SOQL/SOSL - [Andreas Dangel](https://github.com/adangel) (@adangel) + +### ๐Ÿ“ฆ Dependency updates +* [#5185](https://github.com/pmd/pmd/issues/5185): Bump checkstyle from 10.14.0 to 10.18.1 +* [#5187](https://github.com/pmd/pmd/issues/5187): Bump org.apache.maven.plugins:maven-install-plugin from 3.1.1 to 3.1.3 +* [#5199](https://github.com/pmd/pmd/issues/5199): Bump org.apache.maven.plugins:maven-deploy-plugin from 3.1.1 to 3.1.3 +* [#5216](https://github.com/pmd/pmd/issues/5216): Bump com.github.siom79.japicmp:japicmp-maven-plugin from 0.20.0 to 0.23.0 +* [#5226](https://github.com/pmd/pmd/issues/5226): Bump rouge from 4.3.0 to 4.4.0 in the all-gems group across 1 directory +* [#5227](https://github.com/pmd/pmd/issues/5227): Bump com.google.code.gson:gson from 2.10.1 to 2.11.0 +* [#5232](https://github.com/pmd/pmd/issues/5232): Bump com.google.protobuf:protobuf-java from 3.25.3 to 3.25.5 +* [#5233](https://github.com/pmd/pmd/issues/5233): Bump webrick from 1.8.1 to 1.8.2 in /docs + +### ๐Ÿ“ˆ Stats +* 60 commits +* 27 closed tickets & PRs +* Days since last release: 27 + ## 30-August-2024 - 7.5.0 The PMD team is pleased to announce PMD 7.5.0. diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index bd0347fa6a0..bc57065dc2d 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.6.0 + 7.7.0-SNAPSHOT 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 49c2d25fbae..1c1c8045feb 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index 33d02f304b2..adca9527bac 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index c039756ba63..147966f7b6b 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index ff1668a7643..531a06515f6 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index b8faafade02..adbfbd8e3cf 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index 9d1edb4a6ac..0eec39f809d 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index b637ed0a45d..496115127be 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index 2b826ac25b9..9ad286e9a43 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index 445646f2731..c0b7991017a 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index 7288b873878..94bc7d94bd2 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index ab6667c6a08..6aee2c1be5b 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index 1bf6a013e79..4df297ebc94 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index fd70a77b479..bf716ac77c7 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index cd95f899a94..86f19c7c014 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 388da224fea..d8131b8d658 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index bdbdd4e9608..5e4506efd46 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index c18a12730e2..9f1d3fb2230 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index cb677bb2e60..ac3ed6eed11 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index 24361d2a1d5..40f19513de1 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index 26f130e9788..49f8aade09a 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index 1548dbd5933..38f0d009e8a 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index f0c98321e01..f3a24be6d33 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index d3e3428a1f9..373fa78a8d0 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index ce1faf879d7..639c224e2c5 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index 14f408a8409..66818f1a479 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index 289745c71a7..3cb972b4036 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index eed7294d60b..88f09db7a43 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index 8f2db584e8d..2e6ad097a4f 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index 43652c6bd54..85b6643126f 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index 5c44ee002f2..9acaabbf96e 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index b1e58138062..80ad4da7bde 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index 9230660920b..3f73f1cbfb3 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.6.0 + 7.7.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index c58b97b2e5f..ee66fca93ab 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.6.0 + 7.7.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index 8f430c4ca71..023fa8dd390 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index a75bf296e12..43a990e8dc6 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index 99d3ec5354b..0fd57a44372 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index 2dab9d1d53e..e3a2489eff7 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index 7a281697bb1..6cb54b0cd5b 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index 5864669ea51..7ae874578d6 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index 38de0901f6f..1d19200b86a 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index c01c3e2b987..91354468869 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.6.0 + 7.7.0-SNAPSHOT pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - pmd_releases/7.6.0 + HEAD From 39b8bdf17103b3b01b0501778e48ba6b9554e110 Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Mon, 30 Sep 2024 20:13:01 +0200 Subject: [PATCH 0030/1962] Review Finding: Check for type java.nio.FileSystems --- .../pmd/lang/java/rule/errorprone/CloseResourceRule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceRule.java index 28c432a0753..440998cc8e7 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceRule.java @@ -503,7 +503,7 @@ private boolean isVariableNotSpecifiedInTryWithResource(ASTVariableId varId) { private boolean isDefaultFileSystem(ASTVariableId varId) { @Nullable ASTExpression initializer = varId.getInitializer(); - return initializer != null && initializer.getText().contentEquals("FileSystems.getDefault()"); + return initializer != null && InvocationMatcher.parse("java.nio.file.FileSystems#getDefault()").matchesCall(initializer); } private boolean isVariableSpecifiedInTryWithResource(ASTVariableId varId, ASTTryStatement tryWithResource) { From 7dcab3f189bb5b446c4ed97667907da2a24991c4 Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Mon, 30 Sep 2024 20:48:20 +0200 Subject: [PATCH 0031/1962] Fix static analysis findings --- .../pmd/lang/java/rule/errorprone/CloseResourceRule.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceRule.java index 440998cc8e7..f7caef91b68 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceRule.java @@ -108,6 +108,7 @@ public class CloseResourceRule extends AbstractJavaRule { .desc("Detect if 'close' (or other closeTargets) is called outside of a finally-block").defaultValue(false).build(); private static final InvocationMatcher OBJECTS_NON_NULL = InvocationMatcher.parse("java.util.Objects#nonNull(_)"); + private static final InvocationMatcher FILESYSTEMS_GET_DEFAULT = InvocationMatcher.parse("java.nio.file.FileSystems#getDefault()"); private final Set types = new HashSet<>(); private final Set simpleTypes = new HashSet<>(); @@ -503,7 +504,7 @@ private boolean isVariableNotSpecifiedInTryWithResource(ASTVariableId varId) { private boolean isDefaultFileSystem(ASTVariableId varId) { @Nullable ASTExpression initializer = varId.getInitializer(); - return initializer != null && InvocationMatcher.parse("java.nio.file.FileSystems#getDefault()").matchesCall(initializer); + return FILESYSTEMS_GET_DEFAULT.matchesCall(initializer); } private boolean isVariableSpecifiedInTryWithResource(ASTVariableId varId, ASTTryStatement tryWithResource) { From 4796da0fb22e9ec602e9f6576ad1e079273cd9ba Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 3 Oct 2024 19:48:54 +0200 Subject: [PATCH 0032/1962] Renamed JUnit4TestShouldUseBeforeAnnotation - call it UnitTest... to be agnostic to the testing framework --- docs/pages/release_notes.md | 2 +- .../resources/category/java/bestpractices.xml | 98 +++++++++---------- ...nitTestShouldUseBeforeAnnotationTest.java} | 2 +- .../xml/JUnitTestShouldUseAfterAnnotation.xml | 2 +- ... => UnitTestShouldUseBeforeAnnotation.xml} | 2 +- 5 files changed, 53 insertions(+), 53 deletions(-) rename pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/{JUnitTestShouldUseBeforeAnnotationTest.java => UnitTestShouldUseBeforeAnnotationTest.java} (88%) rename pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/{JUnitTestShouldUseBeforeAnnotation.xml => UnitTestShouldUseBeforeAnnotation.xml} (97%) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index a89a911d513..17ffdd2ccbc 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -20,7 +20,7 @@ Several rules for unit testing have been renamed to better reflect their actual * `java/bestpractices/JUnit4TestShouldUseAfterAnnotation` has been renamed to {% rule java/bestpractices/JUnitTestShouldUseAfterAnnotation %} -* `java/bestpractices/JUnit4TestShouldUseBeforeAnnotation` has been renamed to {% rule java/bestpractices/JUnitTestShouldUseBeforeAnnotation %} +* `java/bestpractices/JUnit4TestShouldUseBeforeAnnotation` has been renamed to {% rule java/bestpractices/UnitTestShouldUseBeforeAnnotation %} * `java/bestpractices/JUnit4TestShouldUseTestAnnotation` has been renamed to {% rule java/bestpractices/UnitTestShouldUseTestAnnotation %} diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 8356c31e491..efa61aed917 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -715,55 +715,7 @@ public class MyTest2 { - - - - -This rule detects methods called setUp() that are not properly annotated as a setup method. -This is primarily intended to assist in upgrading from JUnit 3, where setup methods were required to be called setUp(). -To a lesser extent, this may help detect omissions even under newer JUnit versions, as long as you are following this convention to name the methods. - -JUnit 4 will only execute methods annotated with @Before before all tests. -JUnit 5 introduced @BeforeEach and @BeforeAll annotations to execute methods before each test or before all tests in the class, respectively. - - 3 - - - - - - - - - - - + @@ -1462,6 +1414,54 @@ class Foo{ ]]> + + + + This rule detects methods called `setUp()` that are not properly annotated as a setup method. + This is primarily intended to assist in upgrading from JUnit 3, where setup methods were required to be called `setUp()`. + To a lesser extent, this may help detect omissions even under newer JUnit versions, as long as you are following this convention to name the methods. + + JUnit 4 will only execute methods annotated with `@Before` before all tests. + JUnit 5 introduced `@BeforeEach` and `@BeforeAll` annotations to execute methods before each test or before all tests in the class, respectively. + + 3 + + + + + + + + + + + + [java] JUnit4TestShouldUseBeforeAnnotation false positive when overriding setUp #1592 0 [java] JUnit4TestShouldUseBeforeAnnotation false positive when overriding setUp #1592 0 Date: Thu, 3 Oct 2024 19:52:56 +0200 Subject: [PATCH 0033/1962] Renamed JUnit4TestShouldUseAfterAnnotation - call it UnitTest... to be agnostic to the testing framework --- docs/pages/release_notes.md | 2 +- .../resources/category/java/bestpractices.xml | 96 +++++++++---------- ...UnitTestShouldUseAfterAnnotationTest.java} | 2 +- ...l => UnitTestShouldUseAfterAnnotation.xml} | 2 +- 4 files changed, 51 insertions(+), 51 deletions(-) rename pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/{JUnitTestShouldUseAfterAnnotationTest.java => UnitTestShouldUseAfterAnnotationTest.java} (88%) rename pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/{JUnitTestShouldUseAfterAnnotation.xml => UnitTestShouldUseAfterAnnotation.xml} (98%) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 17ffdd2ccbc..023cc34cc52 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -18,7 +18,7 @@ This is a {{ site.pmd.release_type }} release. Several rules for unit testing have been renamed to better reflect their actual scope. Lots of them were called after JUnit / JUnit 4, even when they applied to JUnit 5 and / or TestNG. -* `java/bestpractices/JUnit4TestShouldUseAfterAnnotation` has been renamed to {% rule java/bestpractices/JUnitTestShouldUseAfterAnnotation %} +* `java/bestpractices/JUnit4TestShouldUseAfterAnnotation` has been renamed to {% rule java/bestpractices/UnitTestShouldUseAfterAnnotation %} * `java/bestpractices/JUnit4TestShouldUseBeforeAnnotation` has been renamed to {% rule java/bestpractices/UnitTestShouldUseBeforeAnnotation %} diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index efa61aed917..684a2cf539e 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -666,54 +666,7 @@ public class GoodTest { - - - - -This rule detects methods called tearDown() that are not properly annotated as a setup method. -This is primarily intended to assist in upgrading from JUnit 3, where tear down methods were required to be called tearDown(). -To a lesser extent, this may help detect omissions under newer JUnit versions, as long as you are following this convention to name the methods. - -JUnit 4 will only execute methods annotated with @After after running each test. -JUnit 5 introduced @AfterEach and @AfterAll annotations to execute methods after each test or after all tests in the class, respectively. - - 3 - - - - - - - - - - - + @@ -1415,6 +1368,53 @@ class Foo{ + + + This rule detects methods called `tearDown()` that are not properly annotated as a cleanup method. + This is primarily intended to assist in upgrading from JUnit 3, where tear down methods were required to be called `tearDown()`. + To a lesser extent, this may help detect omissions under newer JUnit versions, as long as you are following this convention to name the methods. + + JUnit 4 will only execute methods annotated with `@After` after running each test. + JUnit 5 introduced `@AfterEach` and `@AfterAll` annotations to execute methods after each test or after all tests in the class, respectively. + + 3 + + + + + + + + + + + + [java] JUnit4TestShouldUseBeforeAnnotation false positive when overriding setUp #1592 0 Date: Thu, 3 Oct 2024 19:59:29 +0200 Subject: [PATCH 0034/1962] [java] Keep bestpractices.xml sorted alphabetically --- .../resources/category/java/bestpractices.xml | 294 +++++++++--------- 1 file changed, 147 insertions(+), 147 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 684a2cf539e..6e53d21ba48 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -672,61 +672,6 @@ public class GoodTest { - - -The rule will detect any test method starting with "test" that is not properly annotated, and will therefore not be run. - -In JUnit 4, only methods annotated with the @Test annotation are executed. -In JUnit 5, one of the following annotations should be used for tests: @Test, @RepeatedTest, @TestFactory, @TestTemplate or @ParameterizedTest. -In TestNG, only methods annotated with the @Test annotation are executed. - - 3 - - - - - - - - - - - - - - - -Unit assertions should include an informative message - i.e., use the three-argument version of -assertEquals(), not the two-argument version. - -This rule supports tests using JUnit (3, 4 and 5) and TestNG. - - 3 - - - - - - - -Unit tests should not contain too many asserts. Many asserts are indicative of a complex test, for which -it is harder to verify correctness. Consider breaking the test scenario into multiple, shorter test scenarios. -Customize the maximum number of assertions used by this Rule to suit your needs. - -This rule checks for JUnit (3, 4 and 5) and TestNG Tests. - - 3 - - - - - - - -Unit tests should include at least one assertion. This makes the tests more robust, and using assert -with messages provide the developer a clearer idea of what the test does. - -This rule checks for JUnit (3, 4 and 5) and TestNG Tests. - - 3 - - - - - + + +Unit assertions should include an informative message - i.e., use the three-argument version of +`assertEquals()`, not the two-argument version. + +This rule supports tests using JUnit (3, 4 and 5) and TestNG. + + 3 + + + + + + + + Unit tests should not contain too many asserts. Many asserts are indicative of a complex test, for which + it is harder to verify correctness. Consider breaking the test scenario into multiple, shorter test scenarios. + Customize the maximum number of assertions used by this Rule to suit your needs. + + This rule checks for JUnit (3, 4 and 5) and TestNG Tests. + + 3 + + + + + + + + The rule will detect any test method starting with "test" that is not properly annotated, and will therefore not be run. + + In JUnit 4, only methods annotated with the `@Test` annotation are executed. + In JUnit 5, one of the following annotations should be used for tests: `@Test`, `@RepeatedTest`, `@TestFactory`, `@TestTemplate` or `@ParameterizedTest`. + In TestNG, only methods annotated with the `@Test` annotation are executed. + + 3 + + + + + + + + + + + + + + + + Unit tests should include at least one assertion. This makes the tests more robust, and using assert + with messages provide the developer a clearer idea of what the test does. + + This rule checks for JUnit (3, 4 and 5) and TestNG Tests. + + 3 + + + + + Date: Thu, 3 Oct 2024 20:03:13 +0200 Subject: [PATCH 0035/1962] [doc] Update release notes (#4532, #4965) --- docs/pages/release_notes.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 023cc34cc52..6d8d727990d 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -16,29 +16,30 @@ This is a {{ site.pmd.release_type }} release. ### ๐ŸŒŸ Rule Changes -Several rules for unit testing have been renamed to better reflect their actual scope. Lots of them were called after JUnit / JUnit 4, even when they applied to JUnit 5 and / or TestNG. +#### Renamed Rules +Several rules for unit testing have been renamed to better reflect their actual scope. Lots of them were called +after JUnit / JUnit 4, even when they applied to JUnit 5 and / or TestNG. -* `java/bestpractices/JUnit4TestShouldUseAfterAnnotation` has been renamed to {% rule java/bestpractices/UnitTestShouldUseAfterAnnotation %} +* {% rule java/bestpractices/UnitTestShouldUseAfterAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseAfterAnnotation`. +* {% rule java/bestpractices/UnitTestShouldUseBeforeAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseBeforeAnnotation`. +* {% rule java/bestpractices/UnitTestShouldUseTestAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseTestAnnotation`. +* {% rule java/bestpractices/UnitTestAssertionsShouldIncludeMessage %} (Java Best Practices) has been renamed from `JUnitAssertionsShouldIncludeMessage`. +* {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} (Java Best Practices) has been renamed from `JUnitTestContainsTooManyAsserts`. +* {% rule java/bestpractices/UnitTestsShouldIncludeAssert %} (Java Best Practices) has been renamed from `JUnitTestsShouldIncludeAssert`. -* `java/bestpractices/JUnit4TestShouldUseBeforeAnnotation` has been renamed to {% rule java/bestpractices/UnitTestShouldUseBeforeAnnotation %} - -* `java/bestpractices/JUnit4TestShouldUseTestAnnotation` has been renamed to {% rule java/bestpractices/UnitTestShouldUseTestAnnotation %} - -* `java/bestpractices/JUnitAssertionsShouldIncludeMessage` has been renamed to {% rule java/bestpractices/UnitTestAssertionsShouldIncludeMessage %} - -* `java/bestpractices/JUnitTestContainsTooManyAsserts` has been renamed to {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} - -* `java/bestpractices/JUnitTestsShouldIncludeAssert` has been renamed to {% rule java/bestpractices/UnitTestsShouldIncludeAssert %} +The old rule names still work but are deprecated. ### ๐Ÿ› Fixed Issues - +* java + * [#4532](https://github.com/pmd/pmd/issues/4532): \[java] Rule misnomer for JUnit* rules * java-bestpractices * [#4278](https://github.com/pmd/pmd/issues/4278): \[java] UnusedPrivateMethod FP with Junit 5 @MethodSource and default factory method name * [#4975](https://github.com/pmd/pmd/issues/4975): \[java] UnusedPrivateMethod false positive when using @MethodSource on a @Nested test ### ๐Ÿšจ API Changes -### โœจ External Contributions +### โœจ Merged pull requests +* [#4965](https://github.com/pmd/pmd/pull/4965): \[java] Rename JUnit rules with overly restrictive names - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) {% endtocmaker %} From d77a63da952feebb53c01b8da45bca600b49f35e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 3 Oct 2024 20:29:53 +0200 Subject: [PATCH 0036/1962] [doc] Update release notes (#5241) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index a0bd73f9c68..978145ff2e0 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -29,6 +29,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ External Contributions * [#5208](https://github.com/pmd/pmd/pull/5208): \[doc] Added Codety to "Tools / Integrations" - [Tony](https://github.com/random1223) (@random1223) +* [#5241](https://github.com/pmd/pmd/pull/5241): \Ignore javacc code in coverage report - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) {% endtocmaker %} From 33c737718c0ff7a02739e8c7c2a1e026d17d0ec0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 3 Oct 2024 17:01:24 +0200 Subject: [PATCH 0037/1962] [java] UnitTestShouldUseBeforeAnnotation: Consider JUnit 5 and TestNG --- docs/pages/release_notes.md | 3 + .../resources/category/java/bestpractices.xml | 30 ++- .../xml/UnitTestShouldUseBeforeAnnotation.xml | 177 ++++++++++++------ 3 files changed, 142 insertions(+), 68 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 0068c0480de..645aa4f485e 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -16,6 +16,9 @@ This is a {{ site.pmd.release_type }} release. ### ๐ŸŒŸ Rule Changes +#### Changed Rules +* {% rule java/bestpractices/UnitTestShouldUseBeforeAnnotation %} (Java Best Practices) now also considers JUnit 5 and TestNG tests. + #### Renamed Rules Several rules for unit testing have been renamed to better reflect their actual scope. Lots of them were called after JUnit / JUnit 4, even when they applied to JUnit 5 and / or TestNG. diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 2698fbab739..6786399ceab 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -1342,16 +1342,20 @@ public class MyTest2 { - This rule detects methods called `setUp()` that are not properly annotated as a setup method. - This is primarily intended to assist in upgrading from JUnit 3, where setup methods were required to be called `setUp()`. - To a lesser extent, this may help detect omissions even under newer JUnit versions, as long as you are following this convention to name the methods. - - JUnit 4 will only execute methods annotated with `@Before` before all tests. - JUnit 5 introduced `@BeforeEach` and `@BeforeAll` annotations to execute methods before each test or before all tests in the class, respectively. +This rule detects methods called `setUp()` that are not properly annotated as a setup method. +This is primarily intended to assist in upgrading from JUnit 3, where setup methods were required to be called `setUp()`. +To a lesser extent, this may help detect omissions even under newer JUnit versions or under TestNG, +as long as you are following this convention to name the methods. + +* JUnit 4 will only execute methods annotated with `@Before` before all tests. +* JUnit 5 introduced `@BeforeEach` and `@BeforeAll` annotations to execute methods before each test or before all + tests in the class, respectively. +* TestNG provides the annotations `@BeforeMethod` and `@BeforeClass` to execute methods before each test or before + tests in the class, respectively. 3 @@ -1363,9 +1367,15 @@ public class MyTest2 { pmd-java:typeIs('org.junit.Before') or pmd-java:typeIs('org.junit.jupiter.api.BeforeEach') or pmd-java:typeIs('org.junit.jupiter.api.BeforeAll') - or pmd-java:typeIs('org.testng.annotations.BeforeMethod')])] - (: Make sure this is a junit 4 class :) - [../MethodDeclaration[pmd-java:hasAnnotation('org.junit.Test')]] + or pmd-java:typeIs('org.testng.annotations.BeforeMethod') + or pmd-java:typeIs('org.testng.annotations.BeforeClass') + ])] + (: Make sure this is a JUnit 4/5 or TestNG class :) + [../MethodDeclaration[ + pmd-java:hasAnnotation('org.junit.Test') + or pmd-java:hasAnnotation('org.junit.jupiter.api.Test') + or pmd-java:hasAnnotation('org.testng.annotations.Test') + ]] ]]> diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldUseBeforeAnnotation.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldUseBeforeAnnotation.xml index 10d6fbc5245..d9ae22cfd4c 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldUseBeforeAnnotation.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldUseBeforeAnnotation.xml @@ -5,8 +5,9 @@ xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests http://pmd.sourceforge.net/rule-tests_1_0_0.xsd"> - Contains setUp + JUnit4 Test class contains setUp 1 + 3 - Contains @setUp + JUnit4 Test class with Before is ok 0 - Renamed setup + JUnit4 Test class with renamed setup using Before is ok 0 - #1446 False positive with JUnit4TestShouldUseBeforeAnnotation when TestNG is used + Contains setUp, not a JUnit 4/5/TestNG test 0 + + + + JUnit4 Test class contains setUp with different signature is ok + 0 + +]]> - #940 False positive with JUnit4TestShouldUseBeforeAnnotation when JUnit5's 'BeforeEach' is used + [java] JUnit4TestShouldUseBeforeAnnotation false positive when overriding setUp #1592 0 - #940 False positive with JUnit4TestShouldUseBeforeAnnotation when JUnit5's 'BeforeAll' is used + TestNG class contains setUp + 1 + 4 + + + + + TestNG class contains setUp with different signature is ok (#1446) 0 +]]> + - Contains setUp, not a junit 4 test + TestNG with @BeforeMethod is ok (#1446) 0 +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class MyTestCase { + @BeforeMethod + public void setUp() {} + + @Test + public void myTest() {} +} +]]> + - Contains setUp with different signature + TestNG with @BeforeClass is ok 0 + - @Test - public void foo() { - } - } - ]]> + + JUnit5 Test class contains setUp + 1 + 4 + - [java] JUnit4TestShouldUseBeforeAnnotation false positive when overriding setUp #1592 + JUnit5 Test class with BeforeEach is ok (#940) 0 +]]> + + + + JUnit5 Test class with BeforeAll is ok (#940) + 0 + From 9337e5a7a21428f92d270c9309b141754e8b7f39 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 3 Oct 2024 17:18:04 +0200 Subject: [PATCH 0038/1962] [java] UnitTestShouldUseAfterAnnotation: Consider JUnit 5 and TestNG --- docs/pages/release_notes.md | 1 + .../resources/category/java/bestpractices.xml | 32 ++- .../xml/UnitTestShouldUseAfterAnnotation.xml | 197 +++++++++++------- 3 files changed, 148 insertions(+), 82 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 645aa4f485e..d5d1238fcc5 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -17,6 +17,7 @@ This is a {{ site.pmd.release_type }} release. ### ๐ŸŒŸ Rule Changes #### Changed Rules +* {% rule java/bestpractices/UnitTestShouldUseAfterAnnotation %} (Java Best Practices) now also considers JUnit 5 and TestNG tests. * {% rule java/bestpractices/UnitTestShouldUseBeforeAnnotation %} (Java Best Practices) now also considers JUnit 5 and TestNG tests. #### Renamed Rules diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 6786399ceab..cd51508131e 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -1295,36 +1295,46 @@ public class MyTestCase { - This rule detects methods called `tearDown()` that are not properly annotated as a cleanup method. - This is primarily intended to assist in upgrading from JUnit 3, where tear down methods were required to be called `tearDown()`. - To a lesser extent, this may help detect omissions under newer JUnit versions, as long as you are following this convention to name the methods. +This rule detects methods called `tearDown()` that are not properly annotated as a cleanup method. +This is primarily intended to assist in upgrading from JUnit 3, where tear down methods were required to be called `tearDown()`. +To a lesser extent, this may help detect omissions even under newer JUnit versions or under TestNG, +as long as you are following this convention to name the methods. - JUnit 4 will only execute methods annotated with `@After` after running each test. - JUnit 5 introduced `@AfterEach` and `@AfterAll` annotations to execute methods after each test or after all tests in the class, respectively. +* JUnit 4 will only execute methods annotated with `@After` after running each test. +* JUnit 5 introduced `@AfterEach` and `@AfterAll` annotations to execute methods after each test or after + all tests in the class, respectively. +* TestNG provides the annotations `@AfterMethod` and `@AfterClass` to execute methods after each test or after + tests in the class, respectively. 3 - - - Contains tearDown + JUnit4 test class contains tearDown 1 + 3 - Contains @After tearDown + JUnit4 test class contains tearDown with different signature is ok + 0 + + + + + JUnit4 test class contains @After tearDown is ok 0 - Renamed tearDown + JUnit4 test class contains renamed tearDown is ok 0 + + + + Contains tearDown, not a JUnit 4/5 or TestNG test is ok + 0 + + + + + [java] JUnit4TestShouldUseBeforeAnnotation false positive when overriding setUp #1592 + 0 + - #1446 False positive with JUnit4TestShouldUseBeforeAnnotation when TestNG is used + TestNG test contains tearDown + 1 + 4 + + + + + TestNG test contains tearDown with different signature is ok (#1446) 0 +]]> - #940 False positive with JUnit4TestShouldUseAfterAnnotation when JUnit5's 'AfterEach' is used + TestNG test contains tearDown with @AfterMethod is ok 0 +]]> - #940 False positive with JUnit4TestShouldUseAfterAnnotation when JUnit5's 'AfterAll' is used + TestNG test contains tearDown with @AfterClass is ok 0 +]]> + - Contains tearDown, not a junit 4 test - 0 + JUnit 5 test class contains tearDown + 1 + 4 +import org.junit.jupiter.api.Test; + +public class MyTestCase { + public void tearDown() {} // violation expected + + @Test + public void myTest() {} +} +]]> + - Contains tearDown with different signature + JUnit 5 test class contains tearDown with @AfterEach is ok (#940) 0 +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +public class MyTestCase { + @AfterEach + public void tearDown() {} + + @Test + public void myTest() {} +} +]]> - [java] JUnit4TestShouldUseBeforeAnnotation false positive when overriding setUp #1592 + JUnit 5 test class contains tearDown with @AfterAll is ok (#940) 0 +]]> From 7d4961f3033d65476f8a0fdf42101edf540c0c2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Thu, 3 Oct 2024 17:47:01 -0300 Subject: [PATCH 0039/1962] Update README.md Point coveralls to main branch --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7a4fde521ce..8d215b233af 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![Build Status](https://github.com/pmd/pmd/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/pmd/pmd/actions) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/net.sourceforge.pmd/pmd/badge.svg)](https://maven-badges.herokuapp.com/maven-central/net.sourceforge.pmd/pmd) [![Reproducible Builds](https://img.shields.io/badge/Reproducible_Builds-ok-green?labelColor=blue)](https://github.com/jvm-repo-rebuild/reproducible-central/tree/master/content/net/sourceforge/pmd#readme) -[![Coverage Status](https://coveralls.io/repos/github/pmd/pmd/badge.svg)](https://coveralls.io/github/pmd/pmd) +[![Coverage Status](https://coveralls.io/repos/github/pmd/pmd/badge.svg?branch=main)](https://coveralls.io/github/pmd/pmd?branch=main) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/ea550046a02344ec850553476c4aa2ca)](https://app.codacy.com/organizations/gh/pmd/dashboard) [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg)](code_of_conduct.md) [![Documentation (latest)](https://img.shields.io/badge/docs-latest-green)](https://docs.pmd-code.org/latest/) From 9fbaa4fbfb7f3d3cf32e82cefc61697995d46c27 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Oct 2024 09:25:21 +0200 Subject: [PATCH 0040/1962] [java] Update quickstart.xml with renamed UnitTest* rules --- .../src/main/resources/rulesets/java/quickstart.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pmd-java/src/main/resources/rulesets/java/quickstart.xml b/pmd-java/src/main/resources/rulesets/java/quickstart.xml index 97eb2742da4..8c8af377abd 100644 --- a/pmd-java/src/main/resources/rulesets/java/quickstart.xml +++ b/pmd-java/src/main/resources/rulesets/java/quickstart.xml @@ -24,13 +24,7 @@ - - - - - - @@ -45,6 +39,12 @@ + + + + + + From c0023dd94209513ec02459250bcdc16806f1a08c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Oct 2024 09:32:55 +0200 Subject: [PATCH 0041/1962] [java] Rename UnitTestShouldIncludeAssert again to make it consistent and always use singular "UnitTest" Follow-up on #4532 and #4965 --- docs/pages/release_notes.md | 6 +- .../JUnitTestsShouldIncludeAssertRule.java | 4 +- ...a => UnitTestShouldIncludeAssertRule.java} | 4 +- .../resources/category/java/bestpractices.xml | 58 +++++++++---------- .../resources/rulesets/java/quickstart.xml | 2 +- ...a => UnitTestShouldIncludeAssertTest.java} | 2 +- ...rt.xml => UnitTestShouldIncludeAssert.xml} | 0 7 files changed, 38 insertions(+), 38 deletions(-) rename pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/{UnitTestsShouldIncludeAssertRule.java => UnitTestShouldIncludeAssertRule.java} (93%) rename pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/{UnitTestsShouldIncludeAssertTest.java => UnitTestShouldIncludeAssertTest.java} (79%) rename pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/{UnitTestsShouldIncludeAssert.xml => UnitTestShouldIncludeAssert.xml} (100%) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 0068c0480de..7c5ba5a430b 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -20,12 +20,12 @@ This is a {{ site.pmd.release_type }} release. Several rules for unit testing have been renamed to better reflect their actual scope. Lots of them were called after JUnit / JUnit 4, even when they applied to JUnit 5 and / or TestNG. +* {% rule java/bestpractices/UnitTestAssertionsShouldIncludeMessage %} (Java Best Practices) has been renamed from `JUnitAssertionsShouldIncludeMessage`. +* {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} (Java Best Practices) has been renamed from `JUnitTestContainsTooManyAsserts`. +* {% rule java/bestpractices/UnitTestShouldIncludeAssert %} (Java Best Practices) has been renamed from `JUnitTestsShouldIncludeAssert`. * {% rule java/bestpractices/UnitTestShouldUseAfterAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseAfterAnnotation`. * {% rule java/bestpractices/UnitTestShouldUseBeforeAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseBeforeAnnotation`. * {% rule java/bestpractices/UnitTestShouldUseTestAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseTestAnnotation`. -* {% rule java/bestpractices/UnitTestAssertionsShouldIncludeMessage %} (Java Best Practices) has been renamed from `JUnitAssertionsShouldIncludeMessage`. -* {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} (Java Best Practices) has been renamed from `JUnitTestContainsTooManyAsserts`. -* {% rule java/bestpractices/UnitTestsShouldIncludeAssert %} (Java Best Practices) has been renamed from `JUnitTestsShouldIncludeAssert`. The old rule names still work but are deprecated. diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java index ad20f3cca51..452e67d033d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java @@ -5,9 +5,9 @@ package net.sourceforge.pmd.lang.java.rule.bestpractices; /** - * @deprecated The rule was renamed {@link UnitTestsShouldIncludeAssertRule} + * @deprecated The rule was renamed {@link UnitTestShouldIncludeAssertRule} */ @Deprecated -public class JUnitTestsShouldIncludeAssertRule extends UnitTestsShouldIncludeAssertRule { +public class JUnitTestsShouldIncludeAssertRule extends UnitTestShouldIncludeAssertRule { } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestsShouldIncludeAssertRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertRule.java similarity index 93% rename from pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestsShouldIncludeAssertRule.java rename to pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertRule.java index 867ae525048..dc21c4fb1ac 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestsShouldIncludeAssertRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertRule.java @@ -15,7 +15,7 @@ import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.properties.PropertyFactory; -public class UnitTestsShouldIncludeAssertRule extends AbstractJavaRulechainRule { +public class UnitTestShouldIncludeAssertRule extends AbstractJavaRulechainRule { private static final PropertyDescriptor> EXTRA_ASSERT_METHOD_NAMES = PropertyFactory.stringProperty("extraAssertMethodNames") @@ -24,7 +24,7 @@ public class UnitTestsShouldIncludeAssertRule extends AbstractJavaRulechainRule .emptyDefaultValue() .build(); - public UnitTestsShouldIncludeAssertRule() { + public UnitTestShouldIncludeAssertRule() { super(ASTMethodDeclaration.class); definePropertyDescriptor(EXTRA_ASSERT_METHOD_NAMES); } diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 2698fbab739..aa2f4e72557 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -748,7 +748,7 @@ class MyTest { // not public, that's fine - + + + + Unit tests should include at least one assertion. This makes the tests more robust, and using assert + with messages provide the developer a clearer idea of what the test does. + + This rule checks for JUnit (3, 4 and 5) and TestNG Tests. + + 3 + + + + + - - - Unit tests should include at least one assertion. This makes the tests more robust, and using assert - with messages provide the developer a clearer idea of what the test does. - - This rule checks for JUnit (3, 4 and 5) and TestNG Tests. - - 3 - - - - - --> + - diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestsShouldIncludeAssertTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertTest.java similarity index 79% rename from pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestsShouldIncludeAssertTest.java rename to pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertTest.java index b76c92f6150..bab5134261c 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestsShouldIncludeAssertTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertTest.java @@ -6,6 +6,6 @@ import net.sourceforge.pmd.test.PmdRuleTst; -class UnitTestsShouldIncludeAssertTest extends PmdRuleTst { +class UnitTestShouldIncludeAssertTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestsShouldIncludeAssert.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldIncludeAssert.xml similarity index 100% rename from pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestsShouldIncludeAssert.xml rename to pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldIncludeAssert.xml From 07cd250a74f196ca97dc479d2bca9321df95814e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Oct 2024 10:00:53 +0200 Subject: [PATCH 0042/1962] Fix release_notes.md --- docs/pages/release_notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 7c5ba5a430b..6f89cebd471 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -37,7 +37,7 @@ The old rule names still work but are deprecated. ### โœจ Merged pull requests * [#4965](https://github.com/pmd/pmd/pull/4965): \[java] Rename JUnit rules with overly restrictive names - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) -* [#5241](https://github.com/pmd/pmd/pull/5241): \Ignore javacc code in coverage report - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5241](https://github.com/pmd/pmd/pull/5241): Ignore javacc code in coverage report - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) {% endtocmaker %} From d2c42d24260ef43be9ff7228762c5d2baf04248a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Oct 2024 10:05:48 +0200 Subject: [PATCH 0043/1962] [doc] Update release notes (#5067, #5225) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 6f89cebd471..08ed81281f0 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -32,11 +32,14 @@ The old rule names still work but are deprecated. ### ๐Ÿ› Fixed Issues * java * [#4532](https://github.com/pmd/pmd/issues/4532): \[java] Rule misnomer for JUnit* rules +* java-errorprone + * [#5067](https://github.com/pmd/pmd/issues/5067): \[java] CloseResource: False positive for FileSystems.getDefault() ### ๐Ÿšจ API Changes ### โœจ Merged pull requests * [#4965](https://github.com/pmd/pmd/pull/4965): \[java] Rename JUnit rules with overly restrictive names - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5225](https://github.com/pmd/pmd/pull/5225): \[java] Fix #5067: CloseResource: False positive for FileSystems.getDefault() - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#5241](https://github.com/pmd/pmd/pull/5241): Ignore javacc code in coverage report - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) {% endtocmaker %} From a0818d5ab2669dfd7f6bf8ca9e0ec8d8e0148b5d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Oct 2024 15:54:21 +0200 Subject: [PATCH 0044/1962] [doc] Document renamed/old rule names --- docs/pages/release_notes.md | 8 ++++++++ .../main/resources/category/java/bestpractices.xml | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 08ed81281f0..197b7a4aec8 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -36,6 +36,14 @@ The old rule names still work but are deprecated. * [#5067](https://github.com/pmd/pmd/issues/5067): \[java] CloseResource: False positive for FileSystems.getDefault() ### ๐Ÿšจ API Changes +* java-bestpractices + * The old rule name `JUnit4TestShouldUseAfterAnnotation` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestShouldUseAfterAnnotation %} instead. + * The old rule name `JUnit4TestShouldUseBeforeAnnotation` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestShouldUseBeforeAnnotation %} instead. + * The old rule name `JUnit4TestShouldUseTestAnnotation` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestShouldUseTestAnnotation %} instead. + * The old rule name `JUnitAssertionsShouldIncludeMessage` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestAssertionsShouldIncludeMessage %} instead. + * The old rule name `JUnitTestContainsTooManyAsserts` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} instead. + * The old rule name `JUnitTestsShouldIncludeAssert` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestShouldIncludeAssert %} instead. + ### โœจ Merged pull requests * [#4965](https://github.com/pmd/pmd/pull/4965): \[java] Rename JUnit rules with overly restrictive names - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index aa2f4e72557..03b23ad1ca9 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -1239,6 +1239,8 @@ Unit assertions should include an informative message - i.e., use the three-argu `assertEquals()`, not the two-argument version. This rule supports tests using JUnit (3, 4 and 5) and TestNG. + +Note: This rule was named JUnitAssertionsShouldIncludeMessage before PMD 7.7.0. 3 @@ -1268,6 +1270,8 @@ public class Foo { Customize the maximum number of assertions used by this Rule to suit your needs. This rule checks for JUnit (3, 4 and 5) and TestNG Tests. + + Note: This rule was named JUnitTestContainsTooManyAsserts before PMD 7.7.0. 3 @@ -1303,6 +1307,8 @@ public class MyTestCase { with messages provide the developer a clearer idea of what the test does. This rule checks for JUnit (3, 4 and 5) and TestNG Tests. + + Note: This rule was named JUnitTestsShouldIncludeAssert before PMD 7.7.0. 3 @@ -1333,6 +1339,8 @@ public class Foo { JUnit 4 will only execute methods annotated with `@After` after running each test. JUnit 5 introduced `@AfterEach` and `@AfterAll` annotations to execute methods after each test or after all tests in the class, respectively. + + Note: This rule was named JUnit4TestShouldUseAfterAnnotation before PMD 7.7.0. 3 @@ -1380,6 +1388,8 @@ public class MyTest2 { JUnit 4 will only execute methods annotated with `@Before` before all tests. JUnit 5 introduced `@BeforeEach` and `@BeforeAll` annotations to execute methods before each test or before all tests in the class, respectively. + + Note: This rule was named JUnit4TestShouldUseBeforeAnnotation before PMD 7.7.0. 3 @@ -1426,6 +1436,8 @@ public class MyTest2 { In JUnit 4, only methods annotated with the `@Test` annotation are executed. In JUnit 5, one of the following annotations should be used for tests: `@Test`, `@RepeatedTest`, `@TestFactory`, `@TestTemplate` or `@ParameterizedTest`. In TestNG, only methods annotated with the `@Test` annotation are executed. + + Note: This rule was named JUnit4TestShouldUseTestAnnotation before PMD 7.7.0. 3 From 0c858b0a7bbbc051e428f7760701d736af592fdf Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Oct 2024 16:03:21 +0200 Subject: [PATCH 0045/1962] [java] SwitchStmtsShouldHaveDefault should ignore patterns Fixes #4813 --- docs/pages/release_notes.md | 2 + .../resources/category/java/bestpractices.xml | 6 ++ .../xml/SwitchStmtsShouldHaveDefault.xml | 75 +++++++++++++++++++ 3 files changed, 83 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 197b7a4aec8..154ac73a285 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -32,6 +32,8 @@ The old rule names still work but are deprecated. ### ๐Ÿ› Fixed Issues * java * [#4532](https://github.com/pmd/pmd/issues/4532): \[java] Rule misnomer for JUnit* rules +* java-bestpractices + * [#4813](https://github.com/pmd/pmd/issues/4813): \[java] SwitchStmtsShouldHaveDefault false positive with pattern matching * java-errorprone * [#5067](https://github.com/pmd/pmd/issues/5067): \[java] CloseResource: False positive for FileSystems.getDefault() diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 03b23ad1ca9..aa965d9f671 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -1168,12 +1168,18 @@ class SomeTestClass { easier to follow. This can be achieved by adding a `default` case, or, if the switch is on an enum type, by ensuring there is one switch branch for each enum constant. + + This rule doesn't consider Switch Statements, that use Pattern Matching, since for these the + compiler already ensures that all cases are covered. The same is true for Switch Expressions, + which are also not considered by this rule. 3 diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/SwitchStmtsShouldHaveDefault.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/SwitchStmtsShouldHaveDefault.xml index 758b97b43b8..e28cfe5b9d3 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/SwitchStmtsShouldHaveDefault.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/SwitchStmtsShouldHaveDefault.xml @@ -240,4 +240,79 @@ public enum GradeSystem { } ]]> + + + [java] SwitchStmtsShouldHaveDefault false positive with pattern matching #4813 + 0 + System.out.println("WARNING " + failure.message()); + case Success success -> System.out.println(success.message()); + } + } + public void test2(AcceptableResult result) { + switch (result) { + case ProviderWarning failure: System.out.println("Provider WARNING " + failure.message()); break; + case Warning failure: System.out.println("WARNING " + failure.message()); break; + case Success success: System.out.println(success.message()); break; + } + } + public void test3(AcceptableResult result) { + switch (result) { + case ProviderWarning failure -> System.out.println("Provider WARNING " + failure.message()); + case Success success -> System.out.println(success.message()); + default -> System.out.println("default case"); + } + } +} +]]> + + + + [java] SwitchStmtsShouldHaveDefault false positive with pattern matching #4813, example 2 + 0 + { return 1; } + case C c -> { return 2; } + case D d -> { return 3; } + // case B b -> { return 4; } // not explicitly necessary, but possible + } + } +} +]]> + From e5ff5532d4edc85e8662755369de500c10f5862b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Oct 2024 16:03:43 +0200 Subject: [PATCH 0046/1962] Update @emouty as a contributor --- .all-contributorsrc | 3 ++- docs/pages/pmd/projectdocs/credits.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 28d946f30a6..98aa4e2daa0 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7453,7 +7453,8 @@ "avatar_url": "https://avatars.githubusercontent.com/u/16755668?v=4", "profile": "https://github.com/emouty", "contributions": [ - "code" + "code", + "bug" ] }, { diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 4795947746b..77e7d0e94a2 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -916,7 +916,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d emersonmoura
    emersonmoura

    ๐Ÿ› - emouty
    emouty

    ๐Ÿ’ป + emouty
    emouty

    ๐Ÿ’ป ๐Ÿ› eugenepugach
    eugenepugach

    ๐Ÿ› fairy
    fairy

    ๐Ÿ› filiprafalowicz
    filiprafalowicz

    ๐Ÿ’ป From 312d8e46aef97e7514e71ec30f43808baabd322e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Oct 2024 16:45:29 +0200 Subject: [PATCH 0047/1962] [java] ImplicitSwitchFallThrough should consider switch expressions Fixes #3362 --- docs/pages/release_notes.md | 1 + .../ImplicitSwitchFallThroughRule.java | 28 +++++++++++++------ .../xml/ImplicitSwitchFallThrough.xml | 20 +++++++++++++ 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 197b7a4aec8..ea9d2b2f32a 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -33,6 +33,7 @@ The old rule names still work but are deprecated. * java * [#4532](https://github.com/pmd/pmd/issues/4532): \[java] Rule misnomer for JUnit* rules * java-errorprone + * [#3362](https://github.com/pmd/pmd/issues/3362): \[java] ImplicitSwitchFallThrough should consider switch expressions * [#5067](https://github.com/pmd/pmd/issues/5067): \[java] CloseResource: False positive for FileSystems.getDefault() ### ๐Ÿšจ API Changes diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ImplicitSwitchFallThroughRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ImplicitSwitchFallThroughRule.java index 29d91c111c2..fb0a9298f58 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ImplicitSwitchFallThroughRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ImplicitSwitchFallThroughRule.java @@ -9,28 +9,40 @@ import net.sourceforge.pmd.lang.ast.GenericToken; import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken; import net.sourceforge.pmd.lang.java.ast.ASTSwitchBranch; +import net.sourceforge.pmd.lang.java.ast.ASTSwitchExpression; import net.sourceforge.pmd.lang.java.ast.ASTSwitchFallthroughBranch; +import net.sourceforge.pmd.lang.java.ast.ASTSwitchLike; import net.sourceforge.pmd.lang.java.ast.ASTSwitchStatement; import net.sourceforge.pmd.lang.java.ast.JavaNode; import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; import net.sourceforge.pmd.lang.java.rule.internal.DataflowPass; import net.sourceforge.pmd.lang.java.rule.internal.DataflowPass.DataflowResult; +import net.sourceforge.pmd.reporting.RuleContext; import net.sourceforge.pmd.util.OptionalBool; public class ImplicitSwitchFallThroughRule extends AbstractJavaRulechainRule { - //todo should consider switch exprs - private static final Pattern IGNORED_COMMENT = Pattern.compile("/[/*].*\\bfalls?[ -]?thr(ough|u)\\b.*", Pattern.DOTALL | Pattern.CASE_INSENSITIVE); public ImplicitSwitchFallThroughRule() { - super(ASTSwitchStatement.class); + super(ASTSwitchStatement.class, ASTSwitchExpression.class); } @Override public Object visit(ASTSwitchStatement node, Object data) { + checkSwitchLike(node, asCtx(data)); + return null; + } + + @Override + public Object visit(ASTSwitchExpression node, Object data) { + checkSwitchLike(node, asCtx(data)); + return null; + } + + private void checkSwitchLike(ASTSwitchLike node, RuleContext ruleContext) { DataflowResult dataflow = DataflowPass.getDataflowResult(node.getRoot()); for (ASTSwitchBranch branch : node.getBranches()) { @@ -38,15 +50,14 @@ public Object visit(ASTSwitchStatement node, Object data) { ASTSwitchFallthroughBranch fallthrough = (ASTSwitchFallthroughBranch) branch; OptionalBool bool = dataflow.switchBranchFallsThrough(branch); if (bool != OptionalBool.NO - && fallthrough.getStatements().nonEmpty() - && !nextBranchHasComment(branch)) { - asCtx(data).addViolation(branch.getNextBranch().getLabel()); + && fallthrough.getStatements().nonEmpty() + && !nextBranchHasComment(branch)) { + ruleContext.addViolation(branch.getNextBranch().getLabel()); } } else { - return null; + return; } } - return null; } boolean nextBranchHasComment(ASTSwitchBranch branch) { @@ -62,5 +73,4 @@ boolean nextBranchHasComment(ASTSwitchBranch branch) { } return false; } - } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ImplicitSwitchFallThrough.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ImplicitSwitchFallThrough.xml index 6d86131b0d5..0ddd50e522e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ImplicitSwitchFallThrough.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ImplicitSwitchFallThrough.xml @@ -581,4 +581,24 @@ public class Test { } ]]> + + + switch expression with one case, which is not empty + 1 + 6 + + From 49deb8d4a03215295a45cc3cc8a76dde3b87aac9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Oct 2024 17:12:29 +0200 Subject: [PATCH 0048/1962] [java] SwitchDensity false positive with pattern matching Fixes #5030 --- docs/pages/release_notes.md | 2 ++ .../pmd/lang/java/ast/ASTSwitchLabel.java | 13 ++++++++-- .../java/rule/design/SwitchDensityRule.java | 2 +- .../java/rule/design/xml/SwitchDensity.xml | 26 +++++++++++++++++++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 197b7a4aec8..2ce3f37529f 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -32,6 +32,8 @@ The old rule names still work but are deprecated. ### ๐Ÿ› Fixed Issues * java * [#4532](https://github.com/pmd/pmd/issues/4532): \[java] Rule misnomer for JUnit* rules +* java-design + * [#5030](https://github.com/pmd/pmd/issues/5030): \[java] SwitchDensity false positive with pattern matching * java-errorprone * [#5067](https://github.com/pmd/pmd/issues/5067): \[java] CloseResource: False positive for FileSystems.getDefault() diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabel.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabel.java index 8391284ec8b..2b489d4fde4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabel.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabel.java @@ -50,8 +50,9 @@ public boolean isDefault() { /** * Returns the expressions of this label, or an empty list if this - * is the default label. This may contain {@linkplain ASTPatternExpression pattern expressions} - * to represent patterns. + * is the default label. This does neither contain {@linkplain ASTTypePattern TypePatterns} + * nor {@linkplain ASTRecordPattern RecordPatterns}. To check for this, + * use {@link #isPatternLabel()}. */ public NodeStream getExprList() { return children(ASTExpression.class); @@ -66,4 +67,12 @@ protected R acceptVisitor(JavaVisitor visitor, P public Iterator iterator() { return children(ASTExpression.class).iterator(); } + + /** + * Checks whether this label tests a {@link ASTTypePattern} or a {@link ASTRecordPattern}. + * @since 7.7.0 + */ + public boolean isPatternLabel() { + return children(ASTPattern.class).nonEmpty(); + } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SwitchDensityRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SwitchDensityRule.java index 1360d294587..a8a6fe6fbe4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SwitchDensityRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SwitchDensityRule.java @@ -55,7 +55,7 @@ public Void visitSwitchLike(ASTSwitchLike node, Object data) { int stmtCount = node.descendants(ASTStatement.class).count(); int labelCount = node.getBranches() .map(ASTSwitchBranch::getLabel) - .sumBy(label -> label.isDefault() ? 1 : label.getExprList().count()); + .sumBy(label -> label.isDefault() || label.isPatternLabel() ? 1 : label.getExprList().count()); // note: if labelCount is zero, double division will produce +Infinity or NaN, not ArithmeticException double density = stmtCount / (double) labelCount; diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SwitchDensity.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SwitchDensity.xml index 8af61b0af76..4216e0073ce 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SwitchDensity.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SwitchDensity.xml @@ -152,6 +152,32 @@ public class SwitchWithDefault { } } +} + ]]> + + + + [java] SwitchDensity false positive with pattern matching #5030 + 4 + 0 + 0 -> + { + System.err.println("I am a fish."); + } + case Integer i -> + { + System.err.println("I am not a fish."); + } + default -> + { + System.err.println("default"); + } + } + } } ]]> From 375fb72f3c99e19f7cab257b02a06f2e29dbf384 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Oct 2024 17:32:46 +0200 Subject: [PATCH 0049/1962] [java] Fix tree dump test New SwitchLabel#PatternLabel flag --- .../pmd/lang/java/ast/ParserCornerCases17.txt | 34 +++++----- .../pmd/lang/java/ast/SwitchStatements.txt | 8 +-- .../lang/java/ast/SwitchWithFallthrough.txt | 4 +- .../java14/MultipleCaseLabels.txt | 8 +-- .../java14/SimpleSwitchExpressions.txt | 10 +-- .../java14/SwitchExpressions.txt | 42 ++++++------ .../jdkversiontests/java14/SwitchRules.txt | 10 +-- .../java14/YieldStatements.txt | 4 +- .../java21/DealingWithNull.txt | 42 ++++++------ .../java21/EnhancedTypeCheckingSwitch.txt | 12 ++-- .../java21/ExhaustiveSwitch.txt | 26 ++++---- .../java21/GuardedPatterns.txt | 18 +++--- .../java21/Jep440_RecordPatterns.txt | 2 +- .../Jep441_PatternMatchingForSwitch.txt | 64 +++++++++---------- .../java21/PatternsInSwitchLabels.txt | 10 +-- .../java21/RecordPatternsExhaustiveSwitch.txt | 16 ++--- .../java21/RefiningPatternsInSwitch.txt | 20 +++--- .../ScopeOfPatternVariableDeclarations.txt | 14 ++-- .../Jep456_UnnamedPatternsAndVariables.txt | 16 ++--- .../java22p/Jep447_StatementsBeforeSuper.txt | 6 +- ...tiveTypesInPatternsInstanceofAndSwitch.txt | 12 ++-- .../Jep482_FlexibleConstructorBodies.txt | 6 +- 22 files changed, 192 insertions(+), 192 deletions(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.txt index 553f930c108..bea2307a185 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.txt @@ -107,39 +107,39 @@ | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "instruction", @Name = "instruction", @ParenthesisDepth = 0, @Parenthesized = false] | | +- NumericLiteral[@Base = 2, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0b11110000", @IntLiteral = true, @Integral = true, @LiteralText = "0b11110000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 240.0, @ValueAsFloat = 240.0, @ValueAsInt = 240, @ValueAsLong = 240] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 2, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0b00000000", @IntLiteral = true, @Integral = true, @LiteralText = "0b00000000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 2, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0b00010000", @IntLiteral = true, @Integral = true, @LiteralText = "0b00010000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 16.0, @ValueAsFloat = 16.0, @ValueAsInt = 16, @ValueAsLong = 16] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 2, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0b00100000", @IntLiteral = true, @Integral = true, @LiteralText = "0b00100000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 32.0, @ValueAsFloat = 32.0, @ValueAsInt = 32, @ValueAsLong = 32] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 2, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0b00110000", @IntLiteral = true, @Integral = true, @LiteralText = "0b00110000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 48.0, @ValueAsFloat = 48.0, @ValueAsInt = 48, @ValueAsLong = 48] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 2, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0b01000000", @IntLiteral = true, @Integral = true, @LiteralText = "0b01000000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 64.0, @ValueAsFloat = 64.0, @ValueAsInt = 64, @ValueAsLong = 64] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 2, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0b01010000", @IntLiteral = true, @Integral = true, @LiteralText = "0b01010000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 80.0, @ValueAsFloat = 80.0, @ValueAsInt = 80, @ValueAsLong = 80] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 2, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0b01100000", @IntLiteral = true, @Integral = true, @LiteralText = "0b01100000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 96.0, @ValueAsFloat = 96.0, @ValueAsInt = 96, @ValueAsLong = 96] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 2, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0b01110000", @IntLiteral = true, @Integral = true, @LiteralText = "0b01110000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 112.0, @ValueAsFloat = 112.0, @ValueAsInt = 112, @ValueAsLong = 112] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = true] - | +- SwitchLabel[@Default = true] + | +- SwitchLabel[@Default = true, @PatternLabel = false] | +- ThrowStatement[] | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "IllegalArgumentException"] @@ -258,7 +258,7 @@ | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "dayOfWeekArg", @Name = "dayOfWeekArg", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Monday", @Empty = false, @Image = "\"Monday\"", @Length = 6, @LiteralText = "\"Monday\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- ExpressionStatement[] | | | | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] @@ -266,13 +266,13 @@ | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Start of work week", @Empty = false, @Image = "\"Start of work week\"", @Length = 18, @LiteralText = "\"Start of work week\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- BreakStatement[@Label = null] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Tuesday", @Empty = false, @Image = "\"Tuesday\"", @Length = 7, @LiteralText = "\"Tuesday\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Wednesday", @Empty = false, @Image = "\"Wednesday\"", @Length = 9, @LiteralText = "\"Wednesday\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Thursday", @Empty = false, @Image = "\"Thursday\"", @Length = 8, @LiteralText = "\"Thursday\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- ExpressionStatement[] | | | | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] @@ -280,7 +280,7 @@ | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Midweek", @Empty = false, @Image = "\"Midweek\"", @Length = 7, @LiteralText = "\"Midweek\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- BreakStatement[@Label = null] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Friday", @Empty = false, @Image = "\"Friday\"", @Length = 6, @LiteralText = "\"Friday\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- ExpressionStatement[] | | | | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] @@ -288,10 +288,10 @@ | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "End of work week", @Empty = false, @Image = "\"End of work week\"", @Length = 16, @LiteralText = "\"End of work week\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- BreakStatement[@Label = null] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Saturday", @Empty = false, @Image = "\"Saturday\"", @Length = 8, @LiteralText = "\"Saturday\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Sunday", @Empty = false, @Image = "\"Sunday\"", @Length = 6, @LiteralText = "\"Sunday\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- ExpressionStatement[] | | | | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] @@ -299,7 +299,7 @@ | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Weekend", @Empty = false, @Image = "\"Weekend\"", @Length = 7, @LiteralText = "\"Weekend\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- BreakStatement[@Label = null] | | +- SwitchFallthroughBranch[@Default = true] - | | +- SwitchLabel[@Default = true] + | | +- SwitchLabel[@Default = true, @PatternLabel = false] | | +- ThrowStatement[] | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "IllegalArgumentException"] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchStatements.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchStatements.txt index 70874b10315..dbfa7a45099 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchStatements.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchStatements.txt @@ -16,16 +16,16 @@ +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "a", @Name = "a", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | +- SwitchFallthroughBranch[@Default = true] - | +- SwitchLabel[@Default = true] + | +- SwitchLabel[@Default = true, @PatternLabel = false] +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "a", @Name = "a", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "a", @Name = "a", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchFallthroughBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = false] | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | +- ExpressionStatement[] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] @@ -36,4 +36,4 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "1", @Empty = false, @Image = "\"1\"", @Length = 1, @LiteralText = "\"1\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- BreakStatement[@Label = null] +- SwitchFallthroughBranch[@Default = true] - +- SwitchLabel[@Default = true] + +- SwitchLabel[@Default = true, @PatternLabel = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchWithFallthrough.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchWithFallthrough.txt index 49574ca1a0a..5f16e3c6a77 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchWithFallthrough.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchWithFallthrough.txt @@ -16,7 +16,7 @@ +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "a", @Name = "a", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchFallthroughBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = false] | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] +- SwitchFallthroughBranch[@Default = true] - +- SwitchLabel[@Default = true] + +- SwitchLabel[@Default = true, @PatternLabel = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/MultipleCaseLabels.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/MultipleCaseLabels.txt index 5600a4c3d87..a9007b47873 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/MultipleCaseLabels.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/MultipleCaseLabels.txt @@ -65,7 +65,7 @@ +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "day", @Name = "day", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchFallthroughBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "MONDAY", @Name = "MONDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "FRIDAY", @Name = "FRIDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "SUNDAY", @Name = "SUNDAY", @ParenthesisDepth = 0, @Parenthesized = false] @@ -78,7 +78,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = " 6", @Empty = false, @Image = "\" 6\"", @Length = 3, @LiteralText = "\" 6\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- BreakStatement[@Label = null] +- SwitchFallthroughBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "TUESDAY", @Name = "TUESDAY", @ParenthesisDepth = 0, @Parenthesized = false] | +- ExpressionStatement[] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] @@ -89,7 +89,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = " 7", @Empty = false, @Image = "\" 7\"", @Length = 3, @LiteralText = "\" 7\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- BreakStatement[@Label = null] +- SwitchFallthroughBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "THURSDAY", @Name = "THURSDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "SATURDAY", @Name = "SATURDAY", @ParenthesisDepth = 0, @Parenthesized = false] | +- ExpressionStatement[] @@ -101,7 +101,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = " 8", @Empty = false, @Image = "\" 8\"", @Length = 3, @LiteralText = "\" 8\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- BreakStatement[@Label = null] +- SwitchFallthroughBranch[@Default = false] - +- SwitchLabel[@Default = false] + +- SwitchLabel[@Default = false, @PatternLabel = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "WEDNESDAY", @Name = "WEDNESDAY", @ParenthesisDepth = 0, @Parenthesized = false] +- ExpressionStatement[] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SimpleSwitchExpressions.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SimpleSwitchExpressions.txt index 7eb7d249f33..63cbacf6b46 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SimpleSwitchExpressions.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SimpleSwitchExpressions.txt @@ -69,26 +69,26 @@ | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "day", @Name = "day", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "MONDAY", @Name = "MONDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "FRIDAY", @Name = "FRIDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "SUNDAY", @Name = "SUNDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "6", @IntLiteral = true, @Integral = true, @LiteralText = "6", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 6.0, @ValueAsFloat = 6.0, @ValueAsInt = 6, @ValueAsLong = 6] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "TUESDAY", @Name = "TUESDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "7", @IntLiteral = true, @Integral = true, @LiteralText = "7", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 7.0, @ValueAsFloat = 7.0, @ValueAsInt = 7, @ValueAsLong = 7] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "THURSDAY", @Name = "THURSDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "SATURDAY", @Name = "SATURDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "8", @IntLiteral = true, @Integral = true, @LiteralText = "8", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 8.0, @ValueAsFloat = 8.0, @ValueAsInt = 8, @ValueAsLong = 8] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "WEDNESDAY", @Name = "WEDNESDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "9", @IntLiteral = true, @Integral = true, @LiteralText = "9", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 9.0, @ValueAsFloat = 9.0, @ValueAsInt = 9, @ValueAsLong = 9] | | +- SwitchArrowBranch[@Default = true] - | | +- SwitchLabel[@Default = true] + | | +- SwitchLabel[@Default = true, @PatternLabel = false] | | +- Block[@Empty = false, @Size = 3, @containsComment = false] | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchExpressions.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchExpressions.txt index 029dca3fd9f..72c512b8494 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchExpressions.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchExpressions.txt @@ -55,7 +55,7 @@ | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = true, @ExhaustiveEnumSwitch = true, @FallthroughSwitch = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "day", @Name = "day", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "MONDAY", @Name = "MONDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "FRIDAY", @Name = "FRIDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "SUNDAY", @Name = "SUNDAY", @ParenthesisDepth = 0, @Parenthesized = false] @@ -66,7 +66,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "6", @IntLiteral = true, @Integral = true, @LiteralText = "6", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 6.0, @ValueAsFloat = 6.0, @ValueAsInt = 6, @ValueAsLong = 6] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "TUESDAY", @Name = "TUESDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -75,7 +75,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "7", @IntLiteral = true, @Integral = true, @LiteralText = "7", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 7.0, @ValueAsFloat = 7.0, @ValueAsInt = 7, @ValueAsLong = 7] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "THURSDAY", @Name = "THURSDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "SATURDAY", @Name = "SATURDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] @@ -85,7 +85,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "8", @IntLiteral = true, @Integral = true, @LiteralText = "8", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 8.0, @ValueAsFloat = 8.0, @ValueAsInt = 8, @ValueAsLong = 8] | | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "WEDNESDAY", @Name = "WEDNESDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -101,22 +101,22 @@ | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = true, @ExhaustiveEnumSwitch = true, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "day", @Name = "day", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "MONDAY", @Name = "MONDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "FRIDAY", @Name = "FRIDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "SUNDAY", @Name = "SUNDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "6", @IntLiteral = true, @Integral = true, @LiteralText = "6", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 6.0, @ValueAsFloat = 6.0, @ValueAsInt = 6, @ValueAsLong = 6] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "TUESDAY", @Name = "TUESDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "7", @IntLiteral = true, @Integral = true, @LiteralText = "7", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 7.0, @ValueAsFloat = 7.0, @ValueAsInt = 7, @ValueAsLong = 7] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "THURSDAY", @Name = "THURSDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "SATURDAY", @Name = "SATURDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "8", @IntLiteral = true, @Integral = true, @LiteralText = "8", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 8.0, @ValueAsFloat = 8.0, @ValueAsInt = 8, @ValueAsLong = 8] | | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "WEDNESDAY", @Name = "WEDNESDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "9", @IntLiteral = true, @Integral = true, @LiteralText = "9", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 9.0, @ValueAsFloat = 9.0, @ValueAsInt = 9, @ValueAsLong = 9] | +- ExpressionStatement[] @@ -159,15 +159,15 @@ | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "day", @Name = "day", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "MONDAY", @Name = "MONDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "TUESDAY", @Name = "TUESDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | | +- SwitchArrowBranch[@Default = true] - | | +- SwitchLabel[@Default = true] + | | +- SwitchLabel[@Default = true, @PatternLabel = false] | | +- Block[@Empty = false, @Size = 3, @containsComment = false] | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] @@ -211,24 +211,24 @@ | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Foo", @Empty = false, @Image = "\"Foo\"", @Length = 3, @LiteralText = "\"Foo\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- YieldStatement[] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Bar", @Empty = false, @Image = "\"Bar\"", @Length = 3, @LiteralText = "\"Bar\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- YieldStatement[] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2", @IntLiteral = true, @Integral = true, @LiteralText = "2", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Baz", @Empty = false, @Image = "\"Baz\"", @Length = 3, @LiteralText = "\"Baz\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- YieldStatement[] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "BAZ", @Name = "BAZ", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "SwitchExpressions"] | | +- SwitchFallthroughBranch[@Default = true] - | | +- SwitchLabel[@Default = true] + | | +- SwitchLabel[@Default = true, @PatternLabel = false] | | +- ExpressionStatement[] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -258,7 +258,7 @@ | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "k", @Name = "k", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -267,7 +267,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "one", @Empty = false, @Image = "\"one\"", @Length = 3, @LiteralText = "\"one\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2", @IntLiteral = true, @Integral = true, @LiteralText = "2", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -276,7 +276,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "two", @Empty = false, @Image = "\"two\"", @Length = 3, @LiteralText = "\"two\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true] + | +- SwitchLabel[@Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] @@ -301,15 +301,15 @@ | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "k", @Name = "k", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "one", @Empty = false, @Image = "\"one\"", @Length = 3, @LiteralText = "\"one\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2", @IntLiteral = true, @Integral = true, @LiteralText = "2", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "two", @Empty = false, @Image = "\"two\"", @Length = 3, @LiteralText = "\"two\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true] + | +- SwitchLabel[@Default = true, @PatternLabel = false] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "many", @Empty = false, @Image = "\"many\"", @Length = 4, @LiteralText = "\"many\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] +- MethodDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PRIVATE, @Final = false, @Name = "f", @Overridden = false, @Static = true, @Varargs = false, @Visibility = Visibility.V_PRIVATE, @Void = false] +- ModifierList[@EffectiveModifiers = (JModifier.PRIVATE, JModifier.STATIC), @ExplicitModifiers = (JModifier.PRIVATE, JModifier.STATIC)] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchRules.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchRules.txt index 812fecf840d..4eb465db714 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchRules.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchRules.txt @@ -65,7 +65,7 @@ +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "day", @Name = "day", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "MONDAY", @Name = "MONDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "FRIDAY", @Name = "FRIDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "SUNDAY", @Name = "SUNDAY", @ParenthesisDepth = 0, @Parenthesized = false] @@ -76,7 +76,7 @@ | +- ArgumentList[@Empty = false, @Size = 1] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = " 6", @Empty = false, @Image = "\" 6\"", @Length = 3, @LiteralText = "\" 6\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "TUESDAY", @Name = "TUESDAY", @ParenthesisDepth = 0, @Parenthesized = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -85,7 +85,7 @@ | +- ArgumentList[@Empty = false, @Size = 1] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = " 7", @Empty = false, @Image = "\" 7\"", @Length = 3, @LiteralText = "\" 7\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "THURSDAY", @Name = "THURSDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "SATURDAY", @Name = "SATURDAY", @ParenthesisDepth = 0, @Parenthesized = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] @@ -95,7 +95,7 @@ | +- ArgumentList[@Empty = false, @Size = 1] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = " 8", @Empty = false, @Image = "\" 8\"", @Length = 3, @LiteralText = "\" 8\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "WEDNESDAY", @Name = "WEDNESDAY", @ParenthesisDepth = 0, @Parenthesized = false] | +- Block[@Empty = false, @Size = 1, @containsComment = false] | +- ExpressionStatement[] @@ -106,7 +106,7 @@ | +- ArgumentList[@Empty = false, @Size = 1] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = " 9", @Empty = false, @Image = "\" 9\"", @Length = 3, @LiteralText = "\" 9\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] +- SwitchArrowBranch[@Default = true] - +- SwitchLabel[@Default = true] + +- SwitchLabel[@Default = true, @PatternLabel = false] +- ThrowStatement[] +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "IllegalArgumentException"] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.txt index bbab68e1095..766c74cde24 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.txt @@ -29,7 +29,7 @@ +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "e", @Name = "e", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchArrowBranch[@Default = false] - +- SwitchLabel[@Default = false] + +- SwitchLabel[@Default = false, @PatternLabel = false] | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] +- Block[@Empty = false, @Size = 12, @containsComment = true] +- ExpressionStatement[] @@ -67,7 +67,7 @@ | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "foo", @Name = "foo", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = false] | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "4", @IntLiteral = true, @Integral = true, @LiteralText = "4", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 4.0, @ValueAsFloat = 4.0, @ValueAsInt = 4, @ValueAsLong = 4] | +- Block[@Empty = false, @Size = 1, @containsComment = false] | +- YieldStatement[] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/DealingWithNull.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/DealingWithNull.txt index fe8144121bd..1eb5bde018a 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/DealingWithNull.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/DealingWithNull.txt @@ -14,7 +14,7 @@ | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -23,7 +23,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Oops", @Empty = false, @Image = "\"Oops\"", @Length = 4, @LiteralText = "\"Oops\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Foo", @Empty = false, @Image = "\"Foo\"", @Length = 3, @LiteralText = "\"Foo\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Bar", @Empty = false, @Image = "\"Bar\"", @Length = 3, @LiteralText = "\"Bar\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] @@ -33,7 +33,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Great", @Empty = false, @Image = "\"Great\"", @Length = 5, @LiteralText = "\"Great\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true] + | +- SwitchLabel[@Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] @@ -52,7 +52,7 @@ | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -66,7 +66,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "String: ", @Empty = false, @Image = "\"String: \"", @Length = 8, @LiteralText = "\"String: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -75,7 +75,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "null", @Empty = false, @Image = "\"null\"", @Length = 4, @LiteralText = "\"null\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true] + | +- SwitchLabel[@Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] @@ -94,7 +94,7 @@ | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -108,7 +108,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "String: ", @Empty = false, @Image = "\"String: \"", @Length = 8, @LiteralText = "\"String: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true] + | +- SwitchLabel[@Default = true, @PatternLabel = false] | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -128,14 +128,14 @@ | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- ThrowStatement[] | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "NullPointerException"] | | +- ArgumentList[@Empty = true, @Size = 0] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -149,7 +149,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "String: ", @Empty = false, @Image = "\"String: \"", @Length = 8, @LiteralText = "\"String: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] @@ -161,7 +161,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Integer", @Empty = false, @Image = "\"Integer\"", @Length = 7, @LiteralText = "\"Integer\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true] + | +- SwitchLabel[@Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] @@ -180,7 +180,7 @@ | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ExpressionStatement[] | | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] @@ -191,7 +191,7 @@ | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "null", @Empty = false, @Image = "\"null\"", @Length = 4, @LiteralText = "\"null\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- BreakStatement[@Label = null] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -205,7 +205,7 @@ | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "String", @Empty = false, @Image = "\"String\"", @Length = 6, @LiteralText = "\"String\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- BreakStatement[@Label = null] | | +- SwitchFallthroughBranch[@Default = true] - | | +- SwitchLabel[@Default = true] + | | +- SwitchLabel[@Default = true, @PatternLabel = false] | | +- ExpressionStatement[] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -217,7 +217,7 @@ | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -226,7 +226,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "null", @Empty = false, @Image = "\"null\"", @Length = 4, @LiteralText = "\"null\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -238,7 +238,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "String", @Empty = false, @Image = "\"String\"", @Length = 6, @LiteralText = "\"String\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchArrowBranch[@Default = true] - | | +- SwitchLabel[@Default = true] + | | +- SwitchLabel[@Default = true, @PatternLabel = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] @@ -248,10 +248,10 @@ | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchFallthroughBranch[@Default = true] - | | +- SwitchLabel[@Default = true] + | | +- SwitchLabel[@Default = true, @PatternLabel = false] | | +- ExpressionStatement[] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -262,7 +262,7 @@ | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true] + | +- SwitchLabel[@Default = true, @PatternLabel = false] | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/EnhancedTypeCheckingSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/EnhancedTypeCheckingSwitch.txt index 71d642290ea..aec1b522244 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/EnhancedTypeCheckingSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/EnhancedTypeCheckingSwitch.txt @@ -38,7 +38,7 @@ | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "obj", @Name = "obj", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -47,7 +47,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "null", @Empty = false, @Image = "\"null\"", @Length = 4, @LiteralText = "\"null\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -59,7 +59,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "String", @Empty = false, @Image = "\"String\"", @Length = 6, @LiteralText = "\"String\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Color"] @@ -75,7 +75,7 @@ | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "c", @Name = "c", @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArgumentList[@Empty = true, @Size = 0] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Point"] @@ -91,7 +91,7 @@ | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "p", @Name = "p", @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArgumentList[@Empty = true, @Size = 0] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ArrayType[@ArrayDepth = 1] @@ -109,7 +109,7 @@ | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "length", @Name = "length", @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "ia", @Name = "ia", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true] + | +- SwitchLabel[@Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ExhaustiveSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ExhaustiveSwitch.txt index b43f4f1caf3..0690ebc5ba9 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ExhaustiveSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ExhaustiveSwitch.txt @@ -15,7 +15,7 @@ | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "obj", @Name = "obj", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -24,14 +24,14 @@ | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArgumentList[@Empty = true, @Size = 0] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "i", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true] + | +- SwitchLabel[@Default = true, @PatternLabel = false] | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] +- MethodDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "coverageStatement", @Overridden = false, @Static = true, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC), @ExplicitModifiers = (JModifier.STATIC)] @@ -45,7 +45,7 @@ | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -59,7 +59,7 @@ | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] @@ -73,7 +73,7 @@ | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Integer", @Empty = false, @Image = "\"Integer\"", @Length = 7, @LiteralText = "\"Integer\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = true] - | +- SwitchLabel[@Default = true] + | +- SwitchLabel[@Default = true, @PatternLabel = false] | +- BreakStatement[@Label = null] +- ClassDeclaration[@Abstract = true, @Annotation = false, @Anonymous = false, @BinaryName = "ExhaustiveSwitch$S", @CanonicalName = "ExhaustiveSwitch.S", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = true, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = true, @SimpleName = "S", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] | +- ModifierList[@EffectiveModifiers = (JModifier.SEALED, JModifier.ABSTRACT, JModifier.STATIC), @ExplicitModifiers = (JModifier.SEALED)] @@ -115,21 +115,21 @@ | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "A"] | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "a", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "B"] | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "b", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2", @IntLiteral = true, @Integral = true, @LiteralText = "2", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = true] | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "C"] @@ -147,7 +147,7 @@ | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "A"] @@ -161,7 +161,7 @@ | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "A", @Empty = false, @Image = "\"A\"", @Length = 1, @LiteralText = "\"A\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- BreakStatement[@Label = null] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "C"] @@ -175,7 +175,7 @@ | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "C", @Empty = false, @Image = "\"C\"", @Length = 1, @LiteralText = "\"C\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- BreakStatement[@Label = null] | | +- SwitchFallthroughBranch[@Default = true] - | | +- SwitchLabel[@Default = true] + | | +- SwitchLabel[@Default = true, @PatternLabel = false] | | +- ExpressionStatement[] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -226,7 +226,7 @@ | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = true] | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "F"] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/GuardedPatterns.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/GuardedPatterns.txt index 6e33db0bd76..e9ec43cda38 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/GuardedPatterns.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/GuardedPatterns.txt @@ -14,7 +14,7 @@ | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -32,7 +32,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "single char string", @Empty = false, @Image = "\"single char string\"", @Length = 18, @LiteralText = "\"single char string\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -44,7 +44,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "string", @Empty = false, @Image = "\"string\"", @Length = 6, @LiteralText = "\"string\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] @@ -62,7 +62,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "integer 1", @Empty = false, @Image = "\"integer 1\"", @Length = 9, @LiteralText = "\"integer 1\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true] + | +- SwitchLabel[@Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] @@ -118,7 +118,7 @@ | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -136,7 +136,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "single char string", @Empty = false, @Image = "\"single char string\"", @Length = 18, @LiteralText = "\"single char string\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -148,7 +148,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "string", @Empty = false, @Image = "\"string\"", @Length = 6, @LiteralText = "\"string\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] @@ -166,7 +166,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "integer 1", @Empty = false, @Image = "\"integer 1\"", @Length = 9, @LiteralText = "\"integer 1\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -175,7 +175,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "null!", @Empty = false, @Image = "\"null!\"", @Length = 5, @LiteralText = "\"null!\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true] + | +- SwitchLabel[@Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep440_RecordPatterns.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep440_RecordPatterns.txt index 84f45093b79..8756417a538 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep440_RecordPatterns.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep440_RecordPatterns.txt @@ -260,7 +260,7 @@ | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "pair", @Name = "pair", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = true] | | +- RecordPattern[] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "MyPair"] | | +- PatternList[@Empty = false, @Size = 2] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt index 97893e90d3b..fce6b81fdf1 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt @@ -15,7 +15,7 @@ | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "obj", @Name = "obj", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] @@ -27,7 +27,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "int %d", @Empty = false, @Image = "\"int %d\"", @Length = 6, @LiteralText = "\"int %d\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Long"] @@ -39,7 +39,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "long %d", @Empty = false, @Image = "\"long %d\"", @Length = 7, @LiteralText = "\"long %d\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "l", @Name = "l", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Double"] @@ -51,7 +51,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "double %f", @Empty = false, @Image = "\"double %f\"", @Length = 9, @LiteralText = "\"double %f\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -63,7 +63,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "String %s", @Empty = false, @Image = "\"String %s\"", @Length = 9, @LiteralText = "\"String %s\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true] + | +- SwitchLabel[@Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "toString", @MethodName = "toString", @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "obj", @Name = "obj", @ParenthesisDepth = 0, @Parenthesized = false] | +- ArgumentList[@Empty = true, @Size = 0] @@ -79,7 +79,7 @@ | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -88,7 +88,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Oops", @Empty = false, @Image = "\"Oops\"", @Length = 4, @LiteralText = "\"Oops\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Foo", @Empty = false, @Image = "\"Foo\"", @Length = 3, @LiteralText = "\"Foo\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Bar", @Empty = false, @Image = "\"Bar\"", @Length = 3, @LiteralText = "\"Bar\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] @@ -98,7 +98,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Great", @Empty = false, @Image = "\"Great\"", @Length = 5, @LiteralText = "\"Great\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true] + | +- SwitchLabel[@Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] @@ -117,11 +117,11 @@ | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "response", @Name = "response", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- Block[@Empty = true, @Size = 0, @containsComment = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -140,7 +140,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "You got it", @Empty = false, @Image = "\"You got it\"", @Length = 10, @LiteralText = "\"You got it\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -159,7 +159,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Shame", @Empty = false, @Image = "\"Shame\"", @Length = 5, @LiteralText = "\"Shame\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = true] | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -184,11 +184,11 @@ | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "response", @Name = "response", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- Block[@Empty = true, @Size = 0, @containsComment = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "y", @Empty = false, @Image = "\"y\"", @Length = 1, @LiteralText = "\"y\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Y", @Empty = false, @Image = "\"Y\"", @Length = 1, @LiteralText = "\"Y\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- Block[@Empty = false, @Size = 1, @containsComment = false] @@ -200,7 +200,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "You got it", @Empty = false, @Image = "\"You got it\"", @Length = 10, @LiteralText = "\"You got it\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "n", @Empty = false, @Image = "\"n\"", @Length = 1, @LiteralText = "\"n\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "N", @Empty = false, @Image = "\"N\"", @Length = 1, @LiteralText = "\"N\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- Block[@Empty = false, @Size = 1, @containsComment = false] @@ -212,7 +212,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Shame", @Empty = false, @Image = "\"Shame\"", @Length = 5, @LiteralText = "\"Shame\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -231,7 +231,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "You got it", @Empty = false, @Image = "\"You got it\"", @Length = 10, @LiteralText = "\"You got it\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -250,7 +250,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Shame", @Empty = false, @Image = "\"Shame\"", @Length = 5, @LiteralText = "\"Shame\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = true] | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -303,7 +303,7 @@ | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "c", @Name = "c", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Suit"] @@ -323,7 +323,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "It\'s clubs", @Empty = false, @Image = "\"It\'s clubs\"", @Length = 10, @LiteralText = "\"It\'s clubs\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Suit"] @@ -343,7 +343,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "It\'s diamonds", @Empty = false, @Image = "\"It\'s diamonds\"", @Length = 13, @LiteralText = "\"It\'s diamonds\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Suit"] @@ -363,7 +363,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "It\'s hearts", @Empty = false, @Image = "\"It\'s hearts\"", @Length = 11, @LiteralText = "\"It\'s hearts\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Suit"] @@ -377,7 +377,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "It\'s spades", @Empty = false, @Image = "\"It\'s spades\"", @Length = 11, @LiteralText = "\"It\'s spades\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = true] | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Tarot"] @@ -402,7 +402,7 @@ | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "c", @Name = "c", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "CLUBS", @Name = "CLUBS", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Suit"] @@ -415,7 +415,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "It\'s clubs", @Empty = false, @Image = "\"It\'s clubs\"", @Length = 10, @LiteralText = "\"It\'s clubs\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "DIAMONDS", @Name = "DIAMONDS", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Suit"] @@ -428,7 +428,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "It\'s diamonds", @Empty = false, @Image = "\"It\'s diamonds\"", @Length = 13, @LiteralText = "\"It\'s diamonds\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "HEARTS", @Name = "HEARTS", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Suit"] @@ -441,7 +441,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "It\'s hearts", @Empty = false, @Image = "\"It\'s hearts\"", @Length = 11, @LiteralText = "\"It\'s hearts\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "SPADES", @Name = "SPADES", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Suit"] @@ -454,7 +454,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "It\'s spades", @Empty = false, @Image = "\"It\'s spades\"", @Length = 11, @LiteralText = "\"It\'s spades\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = true] | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Tarot"] @@ -495,7 +495,7 @@ | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "c", @Name = "c", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "HEADS", @Name = "HEADS", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Coin"] @@ -508,7 +508,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Heads", @Empty = false, @Image = "\"Heads\"", @Length = 5, @LiteralText = "\"Heads\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = false] | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "TAILS", @Name = "TAILS", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Coin"] @@ -532,7 +532,7 @@ +- SwitchStatement[@DefaultCase = false, @EnumSwitch = true, @ExhaustiveEnumSwitch = true, @FallthroughSwitch = false] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "c", @Name = "c", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "HEADS", @Name = "HEADS", @ParenthesisDepth = 0, @Parenthesized = false] | +- Block[@Empty = false, @Size = 1, @containsComment = false] | +- ExpressionStatement[] @@ -543,7 +543,7 @@ | +- ArgumentList[@Empty = false, @Size = 1] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Heads", @Empty = false, @Image = "\"Heads\"", @Length = 5, @LiteralText = "\"Heads\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] +- SwitchArrowBranch[@Default = false] - +- SwitchLabel[@Default = false] + +- SwitchLabel[@Default = false, @PatternLabel = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "TAILS", @Name = "TAILS", @ParenthesisDepth = 0, @Parenthesized = false] | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Coin"] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/PatternsInSwitchLabels.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/PatternsInSwitchLabels.txt index c77d9dc1794..c78fee3b6ce 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/PatternsInSwitchLabels.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/PatternsInSwitchLabels.txt @@ -28,7 +28,7 @@ | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] @@ -40,7 +40,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "int %d", @Empty = false, @Image = "\"int %d\"", @Length = 6, @LiteralText = "\"int %d\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Long"] @@ -52,7 +52,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "long %d", @Empty = false, @Image = "\"long %d\"", @Length = 7, @LiteralText = "\"long %d\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "l", @Name = "l", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Double"] @@ -64,7 +64,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "double %f", @Empty = false, @Image = "\"double %f\"", @Length = 9, @LiteralText = "\"double %f\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -76,7 +76,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "String %s", @Empty = false, @Image = "\"String %s\"", @Length = 9, @LiteralText = "\"String %s\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true] + | +- SwitchLabel[@Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "toString", @MethodName = "toString", @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- ArgumentList[@Empty = true, @Size = 0] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatternsExhaustiveSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatternsExhaustiveSwitch.txt index ce5ef0f93d2..78a8d5d4955 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatternsExhaustiveSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatternsExhaustiveSwitch.txt @@ -64,7 +64,7 @@ +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "p1", @Name = "p1", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- RecordPattern[] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Pair"] | | | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] @@ -85,7 +85,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "a", @Empty = false, @Image = "\"a\"", @Length = 1, @LiteralText = "\"a\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- RecordPattern[] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Pair"] | | | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] @@ -106,7 +106,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "a", @Empty = false, @Image = "\"a\"", @Length = 1, @LiteralText = "\"a\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = true] | | +- RecordPattern[] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Pair"] | | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] @@ -129,7 +129,7 @@ +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "p2", @Name = "p2", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- RecordPattern[] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Pair"] | | | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] @@ -150,7 +150,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "a", @Empty = false, @Image = "\"a\"", @Length = 1, @LiteralText = "\"a\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = true] | | +- RecordPattern[] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Pair"] | | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] @@ -173,7 +173,7 @@ +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "p2", @Name = "p2", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = true] | | +- RecordPattern[] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Pair"] | | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] @@ -194,7 +194,7 @@ | +- ArgumentList[@Empty = false, @Size = 1] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "a", @Empty = false, @Image = "\"a\"", @Length = 1, @LiteralText = "\"a\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = true] | | +- RecordPattern[] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Pair"] | | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] @@ -215,7 +215,7 @@ | +- ArgumentList[@Empty = false, @Size = 1] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "a", @Empty = false, @Image = "\"a\"", @Length = 1, @LiteralText = "\"a\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] +- SwitchArrowBranch[@Default = false] - +- SwitchLabel[@Default = false] + +- SwitchLabel[@Default = false, @PatternLabel = true] | +- RecordPattern[] | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Pair"] | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RefiningPatternsInSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RefiningPatternsInSwitch.txt index 60f04062939..8090943eaf3 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RefiningPatternsInSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RefiningPatternsInSwitch.txt @@ -52,11 +52,11 @@ | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Triangle"] @@ -77,7 +77,7 @@ | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Large triangle", @Empty = false, @Image = "\"Large triangle\"", @Length = 14, @LiteralText = "\"Large triangle\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = true] - | +- SwitchLabel[@Default = true] + | +- SwitchLabel[@Default = true, @PatternLabel = false] | +- ExpressionStatement[] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -97,12 +97,12 @@ | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- Block[@Empty = false, @Size = 1, @containsComment = false] | | +- BreakStatement[@Label = null] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Triangle"] @@ -120,7 +120,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Large triangle", @Empty = false, @Image = "\"Large triangle\"", @Length = 14, @LiteralText = "\"Large triangle\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true] + | +- SwitchLabel[@Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] @@ -139,12 +139,12 @@ | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- Block[@Empty = false, @Size = 1, @containsComment = false] | | +- BreakStatement[@Label = null] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Triangle"] @@ -162,7 +162,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Large triangle", @Empty = false, @Image = "\"Large triangle\"", @Length = 14, @LiteralText = "\"Large triangle\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Triangle"] @@ -174,7 +174,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Small triangle", @Empty = false, @Image = "\"Small triangle\"", @Length = 14, @LiteralText = "\"Small triangle\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true] + | +- SwitchLabel[@Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ScopeOfPatternVariableDeclarations.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ScopeOfPatternVariableDeclarations.txt index 34fed8bb670..ee01695dd41 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ScopeOfPatternVariableDeclarations.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ScopeOfPatternVariableDeclarations.txt @@ -14,7 +14,7 @@ | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "obj", @Name = "obj", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Character"] @@ -34,7 +34,7 @@ | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Ding!", @Empty = false, @Image = "\"Ding!\"", @Length = 5, @LiteralText = "\"Ding!\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = true] - | +- SwitchLabel[@Default = true] + | +- SwitchLabel[@Default = true, @PatternLabel = false] | +- BreakStatement[@Label = null] +- MethodDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "testSwitchRule", @Overridden = false, @Static = true, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC), @ExplicitModifiers = (JModifier.STATIC)] @@ -48,7 +48,7 @@ | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Character"] @@ -76,7 +76,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Character", @Empty = false, @Image = "\"Character\"", @Length = 9, @LiteralText = "\"Character\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] @@ -91,7 +91,7 @@ | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArgumentList[@Empty = true, @Size = 0] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true] + | +- SwitchLabel[@Default = true, @PatternLabel = false] | +- Block[@Empty = false, @Size = 1, @containsComment = false] | +- BreakStatement[@Label = null] +- MethodDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "test2", @Overridden = false, @Static = true, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] @@ -106,7 +106,7 @@ | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Character"] @@ -147,7 +147,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "character", @Empty = false, @Image = "\"character\"", @Length = 9, @LiteralText = "\"character\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchFallthroughBranch[@Default = true] - | +- SwitchLabel[@Default = true] + | +- SwitchLabel[@Default = true, @PatternLabel = false] | +- ExpressionStatement[] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt index e77a4d2574e..06b6a2128c5 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt @@ -181,7 +181,7 @@ | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | | +- RecordPattern[] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] | | | | +- PatternList[@Empty = false, @Size = 1] @@ -193,7 +193,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | | +- RecordPattern[] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] | | | | +- PatternList[@Empty = false, @Size = 1] @@ -205,7 +205,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- RecordPattern[] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] | | | +- PatternList[@Empty = false, @Size = 1] @@ -218,7 +218,7 @@ | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | | +- RecordPattern[] | | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] | | | | | +- PatternList[@Empty = false, @Size = 1] @@ -237,7 +237,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | | +- RecordPattern[] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] | | | | +- PatternList[@Empty = false, @Size = 1] @@ -248,7 +248,7 @@ | | | +- MethodCall[@CompileTimeConstant = false, @Image = "stopProcessing", @MethodName = "stopProcessing", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ArgumentList[@Empty = true, @Size = 0] | | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- RecordPattern[] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] | | | +- PatternList[@Empty = false, @Size = 1] @@ -264,7 +264,7 @@ | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- RecordPattern[] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] | | | | +- PatternList[@Empty = false, @Size = 1] @@ -287,7 +287,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = true] | | +- RecordPattern[] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] | | +- PatternList[@Empty = false, @Size = 1] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22p/Jep447_StatementsBeforeSuper.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22p/Jep447_StatementsBeforeSuper.txt index 7490fc68a28..9fa3cd28107 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22p/Jep447_StatementsBeforeSuper.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22p/Jep447_StatementsBeforeSuper.txt @@ -105,7 +105,7 @@ | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "publicKey", @Name = "publicKey", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "RSAKey"] @@ -119,7 +119,7 @@ | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "StandardCharsets"] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "DSAPublicKey"] @@ -133,7 +133,7 @@ | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "StandardCharsets"] | | +- SwitchArrowBranch[@Default = true] - | | +- SwitchLabel[@Default = true] + | | +- SwitchLabel[@Default = true, @PatternLabel = false] | | +- ArrayAllocation[@ArrayDepth = 1, @CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArrayType[@ArrayDepth = 1] | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep455_PrimitiveTypesInPatternsInstanceofAndSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep455_PrimitiveTypesInPatternsInstanceofAndSwitch.txt index c80a09fff67..850597a25e3 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep455_PrimitiveTypesInPatternsInstanceofAndSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep455_PrimitiveTypesInPatternsInstanceofAndSwitch.txt @@ -347,7 +347,7 @@ | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchFallthroughBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = true] | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] @@ -381,11 +381,11 @@ | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "v", @Name = "v", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "0f", @IntLiteral = false, @Integral = false, @LiteralText = "0f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "5f", @IntLiteral = false, @Integral = false, @LiteralText = "5f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 5.0, @ValueAsFloat = 5.0, @ValueAsInt = 5, @ValueAsLong = 5] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] @@ -398,7 +398,7 @@ | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "6f", @IntLiteral = false, @Integral = false, @LiteralText = "6f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 6.0, @ValueAsFloat = 6.0, @ValueAsInt = 6, @ValueAsLong = 6] | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] @@ -424,7 +424,7 @@ | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | | +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "true", @ParenthesisDepth = 0, @Parenthesized = false, @True = true] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -433,7 +433,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "b was true", @Empty = false, @Image = "\"b was true\"", @Length = 10, @LiteralText = "\"b was true\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = false] | | +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "false", @ParenthesisDepth = 0, @Parenthesized = false, @True = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep482_FlexibleConstructorBodies.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep482_FlexibleConstructorBodies.txt index 549c591ecee..a796c0b5859 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep482_FlexibleConstructorBodies.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep482_FlexibleConstructorBodies.txt @@ -105,7 +105,7 @@ | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "publicKey", @Name = "publicKey", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "RSAKey"] @@ -119,7 +119,7 @@ | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "StandardCharsets"] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = true] | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "DSAPublicKey"] @@ -133,7 +133,7 @@ | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "StandardCharsets"] | | +- SwitchArrowBranch[@Default = true] - | | +- SwitchLabel[@Default = true] + | | +- SwitchLabel[@Default = true, @PatternLabel = false] | | +- ArrayAllocation[@ArrayDepth = 1, @CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArrayType[@ArrayDepth = 1] | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] From 90f436fd2861fc25b05fa6640be3579ad68f2170 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Oct 2024 16:17:27 +0200 Subject: [PATCH 0050/1962] [java] TooFewBranchesForSwitch should ignore Pattern Matching Fixes #5249 --- docs/pages/release_notes.md | 3 +++ .../resources/category/java/performance.xml | 2 ++ .../xml/TooFewBranchesForASwitchStatement.xml | 22 +++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 197b7a4aec8..f826710bdf1 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -34,6 +34,9 @@ The old rule names still work but are deprecated. * [#4532](https://github.com/pmd/pmd/issues/4532): \[java] Rule misnomer for JUnit* rules * java-errorprone * [#5067](https://github.com/pmd/pmd/issues/5067): \[java] CloseResource: False positive for FileSystems.getDefault() +* java-performance + * [#5249](https://github.com/pmd/pmd/issues/5249): \[java] TooFewBranchesForASwitchStatement false positive for Pattern Matching + * [#....](https://github.com/pmd/pmd/issues/....): \[java] TooFewBranchesForASwitchStatement should consider Switch Expressions ### ๐Ÿšจ API Changes * java-bestpractices diff --git a/pmd-java/src/main/resources/category/java/performance.xml b/pmd-java/src/main/resources/category/java/performance.xml index 376b5364998..22a2ec1c4fc 100644 --- a/pmd-java/src/main/resources/category/java/performance.xml +++ b/pmd-java/src/main/resources/category/java/performance.xml @@ -625,6 +625,8 @@ if-else statement to increase code readability. diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForASwitchStatement.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForASwitchStatement.xml index 006c56c1e52..bea0d83aa6d 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForASwitchStatement.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForASwitchStatement.xml @@ -69,4 +69,26 @@ public class ValidSwitch { } ]]> + + + [java] TooFewBranchesForASwitchStatement false positive for Pattern Matching + 0 + System.out.println("a"); + } + } + + public void simpleSwitchExpression(S s) { + String result = switch(s) { + case A a -> "a"; + }; + } +} +]]> + From b87944a565cd8c6e91eb22dc43dcae7ed3a1953e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Oct 2024 16:22:59 +0200 Subject: [PATCH 0051/1962] [java] TooFewBranchesForSwitch should consider Switch Expressions Fixes #5250 --- docs/pages/release_notes.md | 2 +- .../resources/category/java/performance.xml | 2 +- .../xml/TooFewBranchesForASwitchStatement.xml | 20 ++++++++++++++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index f826710bdf1..d0382529a67 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -36,7 +36,7 @@ The old rule names still work but are deprecated. * [#5067](https://github.com/pmd/pmd/issues/5067): \[java] CloseResource: False positive for FileSystems.getDefault() * java-performance * [#5249](https://github.com/pmd/pmd/issues/5249): \[java] TooFewBranchesForASwitchStatement false positive for Pattern Matching - * [#....](https://github.com/pmd/pmd/issues/....): \[java] TooFewBranchesForASwitchStatement should consider Switch Expressions + * [#5250](https://github.com/pmd/pmd/issues/5250): \[java] TooFewBranchesForASwitchStatement should consider Switch Expressions ### ๐Ÿšจ API Changes * java-bestpractices diff --git a/pmd-java/src/main/resources/category/java/performance.xml b/pmd-java/src/main/resources/category/java/performance.xml index 22a2ec1c4fc..bda8573382d 100644 --- a/pmd-java/src/main/resources/category/java/performance.xml +++ b/pmd-java/src/main/resources/category/java/performance.xml @@ -624,7 +624,7 @@ if-else statement to increase code readability. diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForASwitchStatement.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForASwitchStatement.xml index bea0d83aa6d..10dbb0081ff 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForASwitchStatement.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForASwitchStatement.xml @@ -5,7 +5,7 @@ xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests http://pmd.sourceforge.net/rule-tests_1_0_0.xsd"> - Only one case, this is useless + Switch Statement with only one case, not ok 3 1 + + Switch Expression with only one case, not ok + 3 + 1 + + + Even two branches is not enough for a switch statement 3 From 855e5175d48a68801a2dada88584e85fe847e3a8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Oct 2024 16:29:37 +0200 Subject: [PATCH 0052/1962] [java] Renamed rule TooFewBranchesForSwitch as it consider Switch Expressions now additionally to Switch Statements. --- docs/pages/release_notes.md | 21 +++++++++++-------- .../resources/category/java/performance.xml | 8 +++++-- ....java => TooFewBranchesForSwitchTest.java} | 2 +- ...tement.xml => TooFewBranchesForSwitch.xml} | 0 4 files changed, 19 insertions(+), 12 deletions(-) rename pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/{TooFewBranchesForASwitchStatementTest.java => TooFewBranchesForSwitchTest.java} (77%) rename pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/{TooFewBranchesForASwitchStatement.xml => TooFewBranchesForSwitch.xml} (100%) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index d0382529a67..3856b7640d6 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -17,15 +17,16 @@ This is a {{ site.pmd.release_type }} release. ### ๐ŸŒŸ Rule Changes #### Renamed Rules -Several rules for unit testing have been renamed to better reflect their actual scope. Lots of them were called -after JUnit / JUnit 4, even when they applied to JUnit 5 and / or TestNG. - -* {% rule java/bestpractices/UnitTestAssertionsShouldIncludeMessage %} (Java Best Practices) has been renamed from `JUnitAssertionsShouldIncludeMessage`. -* {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} (Java Best Practices) has been renamed from `JUnitTestContainsTooManyAsserts`. -* {% rule java/bestpractices/UnitTestShouldIncludeAssert %} (Java Best Practices) has been renamed from `JUnitTestsShouldIncludeAssert`. -* {% rule java/bestpractices/UnitTestShouldUseAfterAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseAfterAnnotation`. -* {% rule java/bestpractices/UnitTestShouldUseBeforeAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseBeforeAnnotation`. -* {% rule java/bestpractices/UnitTestShouldUseTestAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseTestAnnotation`. +* Several rules for unit testing have been renamed to better reflect their actual scope. Lots of them were called + after JUnit / JUnit 4, even when they applied to JUnit 5 and / or TestNG. + * {% rule java/bestpractices/UnitTestAssertionsShouldIncludeMessage %} (Java Best Practices) has been renamed from `JUnitAssertionsShouldIncludeMessage`. + * {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} (Java Best Practices) has been renamed from `JUnitTestContainsTooManyAsserts`. + * {% rule java/bestpractices/UnitTestShouldIncludeAssert %} (Java Best Practices) has been renamed from `JUnitTestsShouldIncludeAssert`. + * {% rule java/bestpractices/UnitTestShouldUseAfterAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseAfterAnnotation`. + * {% rule java/bestpractices/UnitTestShouldUseBeforeAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseBeforeAnnotation`. + * {% rule java/bestpractices/UnitTestShouldUseTestAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseTestAnnotation`. +* {% rule java/performance/TooFewBranchesForSwitch %} (Java Performance) has been renamed from `TooFewBranchesForASwitchStatement`, + as it now applies to Switch Expressions as well. The old rule names still work but are deprecated. @@ -46,6 +47,8 @@ The old rule names still work but are deprecated. * The old rule name `JUnitAssertionsShouldIncludeMessage` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestAssertionsShouldIncludeMessage %} instead. * The old rule name `JUnitTestContainsTooManyAsserts` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} instead. * The old rule name `JUnitTestsShouldIncludeAssert` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestShouldIncludeAssert %} instead. +* java-performance + * The old rule name `TooFewBranchesForASwitchStatement` has been deprecated. Use the new name {% rule java/performance/TooFewBranchesForSwitch %} instead. ### โœจ Merged pull requests diff --git a/pmd-java/src/main/resources/category/java/performance.xml b/pmd-java/src/main/resources/category/java/performance.xml index bda8573382d..4c0d2fe00c6 100644 --- a/pmd-java/src/main/resources/category/java/performance.xml +++ b/pmd-java/src/main/resources/category/java/performance.xml @@ -607,16 +607,20 @@ private String baz() {
    - + + + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#toofewbranchesforswitch"> Switch statements are intended to be used to support complex branching behaviour. Using a switch for only a few cases is ill-advised, since switches are not as easy to understand as if-else statements. In these cases use the if-else statement to increase code readability. + +Note: This rule was named TooFewBranchesForASwitchStatement before PMD 7.7.0. 3 diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/TooFewBranchesForASwitchStatementTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/TooFewBranchesForSwitchTest.java similarity index 77% rename from pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/TooFewBranchesForASwitchStatementTest.java rename to pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/TooFewBranchesForSwitchTest.java index 3916959a965..1787e14681e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/TooFewBranchesForASwitchStatementTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/TooFewBranchesForSwitchTest.java @@ -6,6 +6,6 @@ import net.sourceforge.pmd.test.PmdRuleTst; -class TooFewBranchesForASwitchStatementTest extends PmdRuleTst { +class TooFewBranchesForSwitchTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForASwitchStatement.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForSwitch.xml similarity index 100% rename from pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForASwitchStatement.xml rename to pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForSwitch.xml From d9db4dbcabebc8b4e3f7fbecb7a6a7b1ac4e45c2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 5 Oct 2024 10:19:03 +0200 Subject: [PATCH 0053/1962] [java] Rename TooFewBranchesForSwitch in quickstart.xml --- pmd-java/src/main/resources/rulesets/java/quickstart.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/main/resources/rulesets/java/quickstart.xml b/pmd-java/src/main/resources/rulesets/java/quickstart.xml index 3ac03a493cf..28bd28467c2 100644 --- a/pmd-java/src/main/resources/rulesets/java/quickstart.xml +++ b/pmd-java/src/main/resources/rulesets/java/quickstart.xml @@ -307,7 +307,7 @@ - + From 1f31f771ad14d8a89920a208995b10d9142bc201 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 5 Oct 2024 10:31:40 +0200 Subject: [PATCH 0054/1962] [java] SwitchDensity - more tests with (record) patterns --- .../java/rule/design/xml/SwitchDensity.xml | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SwitchDensity.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SwitchDensity.xml index 4216e0073ce..1c3c21bf4d4 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SwitchDensity.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SwitchDensity.xml @@ -181,4 +181,78 @@ public class SwitchDensityPattern { } ]]> + + + [java] SwitchDensity with pattern matching #5030 + 4 + 1 + 0 -> + { + System.err.println("I am a fish."); + System.err.println("I am a fish."); + System.err.println("I am a fish."); + System.err.println("I am a fish."); + System.err.println("I am a fish."); + } + case Integer i -> + { + System.err.println("I am not a fish."); + System.err.println("I am not a fish."); + System.err.println("I am not a fish."); + System.err.println("I am not a fish."); + System.err.println("I am not a fish."); + System.err.println("I am not a fish."); + } + default -> + { + System.err.println("default"); + } + } + } +} + ]]> + + + + Switch with Record Pattern, ok + 0 + System.out.println(a); + } + } +} +]]> + + + + Switch with Record Pattern, not ok + 4 + 1 + { + System.out.println(a); + System.out.println(a); + System.out.println(a); + System.out.println(a); + System.out.println(a); + } + } + } +} +]]> + From 13cc79af62d060bff491ff33cddf918cad0cb6ae Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 5 Oct 2024 10:36:39 +0200 Subject: [PATCH 0055/1962] [java] TooFewBranchesForSwitch - also ignore record pattern --- .../resources/category/java/performance.xml | 2 +- .../xml/TooFewBranchesForSwitch.xml | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/performance.xml b/pmd-java/src/main/resources/category/java/performance.xml index 4c0d2fe00c6..2a6d2183547 100644 --- a/pmd-java/src/main/resources/category/java/performance.xml +++ b/pmd-java/src/main/resources/category/java/performance.xml @@ -630,7 +630,7 @@ Note: This rule was named TooFewBranchesForASwitchStatement before PMD 7.7.0. diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForSwitch.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForSwitch.xml index 10dbb0081ff..2af77f0e740 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForSwitch.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForSwitch.xml @@ -89,7 +89,7 @@ public class ValidSwitch { - [java] TooFewBranchesForASwitchStatement false positive for Pattern Matching + [java] TooFewBranchesForASwitchStatement false positive for Pattern Matching #5249 0 + + + + Record patterns are ignored, too #5249 + 0 + System.out.println(a); + } + } +} ]]> From 59403fc9e145aac5c5c9a9d4fbf0474a725c0f3c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 5 Oct 2024 10:39:55 +0200 Subject: [PATCH 0056/1962] [java] SwitchStmtsShouldHaveDefault - also ignore record pattern --- .../resources/category/java/bestpractices.xml | 4 ++-- .../xml/SwitchStmtsShouldHaveDefault.xml | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index aa965d9f671..58fea8b30b9 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -1178,8 +1178,8 @@ class SomeTestClass { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/SwitchStmtsShouldHaveDefault.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/SwitchStmtsShouldHaveDefault.xml index e28cfe5b9d3..145739199e9 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/SwitchStmtsShouldHaveDefault.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/SwitchStmtsShouldHaveDefault.xml @@ -313,6 +313,22 @@ public class Example2 { } } } +]]> + + + + With Record Patterns #4813 + 0 + System.out.println(a); + } + } +} ]]> From 6f081e111a1eae05555d71e85a7b994cc3b643d8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 5 Oct 2024 10:41:10 +0200 Subject: [PATCH 0057/1962] Update pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForSwitch.xml --- .../lang/java/rule/performance/xml/TooFewBranchesForSwitch.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForSwitch.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForSwitch.xml index 2af77f0e740..502c470bc2d 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForSwitch.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForSwitch.xml @@ -23,7 +23,7 @@ public class DumbSwitch { - Switch Expression with only one case, not ok + Switch Expression with only one case, not ok #5250 3 1 Date: Sat, 5 Oct 2024 11:00:13 +0200 Subject: [PATCH 0058/1962] [java] Rename rule DefaultLabelNotLastInSwitch - as it applies to both switch statements and switch expressions - extend the test cases to cover new java syntax Note: For patterns in switch, the java compiler already makes sure, that default is the last case. --- docs/pages/release_notes.md | 21 +-- .../resources/category/java/bestpractices.xml | 12 +- .../resources/rulesets/java/quickstart.xml | 2 +- ...a => DefaultLabelNotLastInSwitchTest.java} | 2 +- .../xml/DefaultLabelNotLastInSwitch.xml | 136 ++++++++++++++++++ .../xml/DefaultLabelNotLastInSwitchStmt.xml | 59 -------- 6 files changed, 157 insertions(+), 75 deletions(-) rename pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/{DefaultLabelNotLastInSwitchStmtTest.java => DefaultLabelNotLastInSwitchTest.java} (78%) create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/DefaultLabelNotLastInSwitch.xml delete mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/DefaultLabelNotLastInSwitchStmt.xml diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 197b7a4aec8..00fa2977314 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -17,15 +17,16 @@ This is a {{ site.pmd.release_type }} release. ### ๐ŸŒŸ Rule Changes #### Renamed Rules -Several rules for unit testing have been renamed to better reflect their actual scope. Lots of them were called -after JUnit / JUnit 4, even when they applied to JUnit 5 and / or TestNG. - -* {% rule java/bestpractices/UnitTestAssertionsShouldIncludeMessage %} (Java Best Practices) has been renamed from `JUnitAssertionsShouldIncludeMessage`. -* {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} (Java Best Practices) has been renamed from `JUnitTestContainsTooManyAsserts`. -* {% rule java/bestpractices/UnitTestShouldIncludeAssert %} (Java Best Practices) has been renamed from `JUnitTestsShouldIncludeAssert`. -* {% rule java/bestpractices/UnitTestShouldUseAfterAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseAfterAnnotation`. -* {% rule java/bestpractices/UnitTestShouldUseBeforeAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseBeforeAnnotation`. -* {% rule java/bestpractices/UnitTestShouldUseTestAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseTestAnnotation`. +* Several rules for unit testing have been renamed to better reflect their actual scope. Lots of them were called + after JUnit / JUnit 4, even when they applied to JUnit 5 and / or TestNG. + * {% rule java/bestpractices/UnitTestAssertionsShouldIncludeMessage %} (Java Best Practices) has been renamed from `JUnitAssertionsShouldIncludeMessage`. + * {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} (Java Best Practices) has been renamed from `JUnitTestContainsTooManyAsserts`. + * {% rule java/bestpractices/UnitTestShouldIncludeAssert %} (Java Best Practices) has been renamed from `JUnitTestsShouldIncludeAssert`. + * {% rule java/bestpractices/UnitTestShouldUseAfterAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseAfterAnnotation`. + * {% rule java/bestpractices/UnitTestShouldUseBeforeAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseBeforeAnnotation`. + * {% rule java/bestpractices/UnitTestShouldUseTestAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseTestAnnotation`. +* {% rule java/bestpractices/DefaultLabelNotLastInSwitch %} (Java Best Practices) has been renamed from `DefaultLabelNotLastInSwitch`, as it also + applies to Switch Expressions. The old rule names still work but are deprecated. @@ -43,7 +44,7 @@ The old rule names still work but are deprecated. * The old rule name `JUnitAssertionsShouldIncludeMessage` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestAssertionsShouldIncludeMessage %} instead. * The old rule name `JUnitTestContainsTooManyAsserts` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} instead. * The old rule name `JUnitTestsShouldIncludeAssert` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestShouldIncludeAssert %} instead. - + * The old rule name `DefaultLabelNotLastInSwitch` has been deprecated. Use the new name {% rule java/bestpractices/DefaultLabelNotLastInSwitch %} instead. ### โœจ Merged pull requests * [#4965](https://github.com/pmd/pmd/pull/4965): \[java] Rename JUnit rules with overly restrictive names - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 03b23ad1ca9..834651971c6 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -457,14 +457,18 @@ public interface YetAnotherConstantInterface { - + + + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#defaultlabelnotlastinswitch"> -By convention, the default label should be the last label in a switch statement. +By convention, the default label should be the last label in a switch statement or switch expression. + +Note: This rule has been renamed from "DefaultLabelNotLastInSwitchStmt" with PMD 7.7.0. 3 diff --git a/pmd-java/src/main/resources/rulesets/java/quickstart.xml b/pmd-java/src/main/resources/rulesets/java/quickstart.xml index 3ac03a493cf..a1950908918 100644 --- a/pmd-java/src/main/resources/rulesets/java/quickstart.xml +++ b/pmd-java/src/main/resources/rulesets/java/quickstart.xml @@ -18,7 +18,7 @@ - + diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/DefaultLabelNotLastInSwitchStmtTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/DefaultLabelNotLastInSwitchTest.java similarity index 78% rename from pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/DefaultLabelNotLastInSwitchStmtTest.java rename to pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/DefaultLabelNotLastInSwitchTest.java index b316a1881f7..a012153e0e7 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/DefaultLabelNotLastInSwitchStmtTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/DefaultLabelNotLastInSwitchTest.java @@ -6,6 +6,6 @@ import net.sourceforge.pmd.test.PmdRuleTst; -class DefaultLabelNotLastInSwitchStmtTest extends PmdRuleTst { +class DefaultLabelNotLastInSwitchTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/DefaultLabelNotLastInSwitch.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/DefaultLabelNotLastInSwitch.xml new file mode 100644 index 00000000000..5212dbe022b --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/DefaultLabelNotLastInSwitch.xml @@ -0,0 +1,136 @@ + + + + + ok + 0 + + + + + bad + 1 + + + + + ok, no default + 0 + + + + + switch expression, ok + 0 + + + + + switch expression, not ok + 1 + + + + + switch arrow, ok + 0 + System.out.println("a"); + default -> System.out.println("default"); + } + } +} + ]]> + + + + switch arrow, not ok + 1 + System.out.println("a"); + default -> System.out.println("default"); + case 2 -> System.out.println("b"); + } + } +} + ]]> + + + + switch with pattern and default case, ok + 0 + + + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/DefaultLabelNotLastInSwitchStmt.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/DefaultLabelNotLastInSwitchStmt.xml deleted file mode 100644 index df892c6141b..00000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/DefaultLabelNotLastInSwitchStmt.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - - - ok - 0 - - - - - bad - 1 - - - - - ok, no default - 0 - - - From 079eb238b9bfbf90992b3cfae4860f34971478d8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 5 Oct 2024 11:19:53 +0200 Subject: [PATCH 0059/1962] [java] NonCaseLabelInSwitch - support switch expressions Rename rule from NonCaseLabelInSwitchStatement - as it applies to both switch statements and switch expressions - extend the test cases to cover new java syntax --- docs/pages/release_notes.md | 22 +-- .../resources/category/java/errorprone.xml | 13 +- .../resources/rulesets/java/quickstart.xml | 2 +- ...est.java => NonCaseLabelInSwitchTest.java} | 2 +- .../errorprone/xml/NonCaseLabelInSwitch.xml | 155 ++++++++++++++++++ .../xml/NonCaseLabelInSwitchStatement.xml | 43 ----- 6 files changed, 177 insertions(+), 60 deletions(-) rename pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/{NonCaseLabelInSwitchStatementTest.java => NonCaseLabelInSwitchTest.java} (78%) create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/NonCaseLabelInSwitch.xml delete mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/NonCaseLabelInSwitchStatement.xml diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 197b7a4aec8..16315bf5b22 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -17,15 +17,16 @@ This is a {{ site.pmd.release_type }} release. ### ๐ŸŒŸ Rule Changes #### Renamed Rules -Several rules for unit testing have been renamed to better reflect their actual scope. Lots of them were called -after JUnit / JUnit 4, even when they applied to JUnit 5 and / or TestNG. - -* {% rule java/bestpractices/UnitTestAssertionsShouldIncludeMessage %} (Java Best Practices) has been renamed from `JUnitAssertionsShouldIncludeMessage`. -* {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} (Java Best Practices) has been renamed from `JUnitTestContainsTooManyAsserts`. -* {% rule java/bestpractices/UnitTestShouldIncludeAssert %} (Java Best Practices) has been renamed from `JUnitTestsShouldIncludeAssert`. -* {% rule java/bestpractices/UnitTestShouldUseAfterAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseAfterAnnotation`. -* {% rule java/bestpractices/UnitTestShouldUseBeforeAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseBeforeAnnotation`. -* {% rule java/bestpractices/UnitTestShouldUseTestAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseTestAnnotation`. +* Several rules for unit testing have been renamed to better reflect their actual scope. Lots of them were called + after JUnit / JUnit 4, even when they applied to JUnit 5 and / or TestNG. + * {% rule java/bestpractices/UnitTestAssertionsShouldIncludeMessage %} (Java Best Practices) has been renamed from `JUnitAssertionsShouldIncludeMessage`. + * {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} (Java Best Practices) has been renamed from `JUnitTestContainsTooManyAsserts`. + * {% rule java/bestpractices/UnitTestShouldIncludeAssert %} (Java Best Practices) has been renamed from `JUnitTestsShouldIncludeAssert`. + * {% rule java/bestpractices/UnitTestShouldUseAfterAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseAfterAnnotation`. + * {% rule java/bestpractices/UnitTestShouldUseBeforeAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseBeforeAnnotation`. + * {% rule java/bestpractices/UnitTestShouldUseTestAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseTestAnnotation`. +* {% rule java/errorprone/NonCaseLabelInSwitch %} (Java Error Prone) has been renamed from `NonCaseLabelInSwitchStatement` as it also applies + to Switch Expressions. The old rule names still work but are deprecated. @@ -43,7 +44,8 @@ The old rule names still work but are deprecated. * The old rule name `JUnitAssertionsShouldIncludeMessage` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestAssertionsShouldIncludeMessage %} instead. * The old rule name `JUnitTestContainsTooManyAsserts` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} instead. * The old rule name `JUnitTestsShouldIncludeAssert` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestShouldIncludeAssert %} instead. - +* java-errorprone + * The old rule name `NonCaseLabelInSwitchStatement` has been deprecated. Use the new name {% rule java/errorprone/NonCaseLabelInSwitch %} instead. ### โœจ Merged pull requests * [#4965](https://github.com/pmd/pmd/pull/4965): \[java] Rename JUnit rules with overly restrictive names - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 1f9ed377655..875c5d81579 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -2185,20 +2185,24 @@ public class Foo { - + + -A non-case label (e.g. a named break/continue label) was present in a switch statement. +A non-case label (e.g. a named break/continue label) was present in a switch statement or switch expression. This is legal, but confusing. It is easy to mix up the case labels and the non-case labels. + +Note: This rule was renamed from `NonCaseLabelInSwitchStatement` with PMD 7.7.0. 3 - //SwitchStatement//LabeledStatement + //(SwitchStatement|SwitchExpression)//LabeledStatement @@ -2208,7 +2212,6 @@ public class Foo { switch (a) { case 1: // do something - break; mylabel: // this is legal, but confusing! break; default: diff --git a/pmd-java/src/main/resources/rulesets/java/quickstart.xml b/pmd-java/src/main/resources/rulesets/java/quickstart.xml index 3ac03a493cf..3f8b129015c 100644 --- a/pmd-java/src/main/resources/rulesets/java/quickstart.xml +++ b/pmd-java/src/main/resources/rulesets/java/quickstart.xml @@ -243,7 +243,7 @@ - + diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/NonCaseLabelInSwitchStatementTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/NonCaseLabelInSwitchTest.java similarity index 78% rename from pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/NonCaseLabelInSwitchStatementTest.java rename to pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/NonCaseLabelInSwitchTest.java index 9d914a95529..8644b8d91c8 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/NonCaseLabelInSwitchStatementTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/NonCaseLabelInSwitchTest.java @@ -6,6 +6,6 @@ import net.sourceforge.pmd.test.PmdRuleTst; -class NonCaseLabelInSwitchStatementTest extends PmdRuleTst { +class NonCaseLabelInSwitchTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/NonCaseLabelInSwitch.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/NonCaseLabelInSwitch.xml new file mode 100644 index 00000000000..d40af2f6c9c --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/NonCaseLabelInSwitch.xml @@ -0,0 +1,155 @@ + + + + + label inside switch statement, not ok + 1 + 5 + + + + + label inside switch expression, not ok + 1 + 5 + + + + + only cases in switch statement, ok + 0 + + + + + only cases in switch expression, ok + 0 + + + + + label in switch statement with arrow syntax, not ok + 1 + 6 + { + int y=8; + somelabel: + break; + } + default -> { + int j=8; + } + } + } +} +]]> + + + + label in switch expression with arrow syntax, not ok + 1 + 5 + { int y=8; + somelabel: + yield y; + } + default -> { + int j=8; + yield j; + } + }; + } +} +]]> + + + + only cases in switch stmt/expr with arrow syntax, ok + 0 + { + int y=8; + break; + } + default -> { + int j=8; + } + } + } + void barArrow(int x) { + x = switch (x) { + case 2 -> { int y=8; + yield y; + } + default -> { + int j=8; + yield j; + } + }; + } +} +]]> + + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/NonCaseLabelInSwitchStatement.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/NonCaseLabelInSwitchStatement.xml deleted file mode 100644 index b2ba4cecd08..00000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/NonCaseLabelInSwitchStatement.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - label inside switch - 1 - 6 - - - - - ok - 0 - - - From 5ecc29245beac565bc9708b89691cf7e60703916 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 5 Oct 2024 11:37:45 +0200 Subject: [PATCH 0060/1962] Fix externalInfoUrl after rename --- pmd-java/src/main/resources/category/java/errorprone.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 875c5d81579..98c35472e95 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -2192,7 +2192,7 @@ public class Foo { since="1.5" message="A non-case label was present in a switch statement or expression" class="net.sourceforge.pmd.lang.rule.xpath.XPathRule" - externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#noncaselabelinswitchstatement"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#noncaselabelinswitch"> A non-case label (e.g. a named break/continue label) was present in a switch statement or switch expression. This is legal, but confusing. It is easy to mix up the case labels and the non-case labels. From 377670f267a48108dda31f2f10a9b78bb2374f97 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 6 Oct 2024 18:48:47 +0200 Subject: [PATCH 0061/1962] [doc] Update release notes (#5257) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 16315bf5b22..85fa3914f0f 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -35,6 +35,7 @@ The old rule names still work but are deprecated. * [#4532](https://github.com/pmd/pmd/issues/4532): \[java] Rule misnomer for JUnit* rules * java-errorprone * [#5067](https://github.com/pmd/pmd/issues/5067): \[java] CloseResource: False positive for FileSystems.getDefault() + * [#5257](https://github.com/pmd/pmd/issues/5257): \[java] NonCaseLabelInSwitch should consider switch expressions ### ๐Ÿšจ API Changes * java-bestpractices From 00bf6fe2f7e67e75cd4db863378a50e0533952b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Sun, 6 Oct 2024 17:21:30 -0300 Subject: [PATCH 0062/1962] Fix @since for @Generated --- .../src/main/java/net/sourceforge/pmd/annotation/Generated.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/annotation/Generated.java b/pmd-core/src/main/java/net/sourceforge/pmd/annotation/Generated.java index ab9b46f465b..7dc0d2a253d 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/annotation/Generated.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/annotation/Generated.java @@ -11,7 +11,7 @@ /** * Marks a class as generated code, and therefore to be ignored for code coverage purposes. * - * @since 7.6.0 + * @since 7.7.0 */ @Retention(RetentionPolicy.CLASS) @Documented From 93a019765dd8031b3ee13b9f76c0a7af6afc3eb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Sun, 6 Oct 2024 17:24:42 -0300 Subject: [PATCH 0063/1962] Fix incorrect properties --- antlr4-wrapper.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/antlr4-wrapper.xml b/antlr4-wrapper.xml index 7a827340227..6153c751db6 100644 --- a/antlr4-wrapper.xml +++ b/antlr4-wrapper.xml @@ -32,10 +32,10 @@ - + - + From ca71d765538dc00d971050a504a4d2a72b458053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Sun, 6 Oct 2024 19:48:30 -0300 Subject: [PATCH 0064/1962] Include up-to-date-check to Antlr4 cpd - Prevent unnecessary re-runs --- antlr4-wrapper.xml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/antlr4-wrapper.xml b/antlr4-wrapper.xml index 6153c751db6..4036aa009a1 100644 --- a/antlr4-wrapper.xml +++ b/antlr4-wrapper.xml @@ -15,6 +15,7 @@ --> + @@ -40,6 +41,20 @@ + + + + + + + + + + + + + @@ -72,7 +87,9 @@ tofile="${parser-file}"/> - + + From e3cd599da22e039b282323af44a2d1775a337474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Sun, 6 Oct 2024 19:58:43 -0300 Subject: [PATCH 0065/1962] Add @Generated annotations to cpd Antlr languages --- antlr4-wrapper.xml | 78 +++++++++++++++++++++++++++++++++++++++++++++- pmd-cs/pom.xml | 1 + pmd-dart/pom.xml | 1 + pmd-go/pom.xml | 1 + pmd-lua/pom.xml | 1 + pom.xml | 8 +++++ 6 files changed, 89 insertions(+), 1 deletion(-) diff --git a/antlr4-wrapper.xml b/antlr4-wrapper.xml index 4036aa009a1..b17002f40ab 100644 --- a/antlr4-wrapper.xml +++ b/antlr4-wrapper.xml @@ -12,7 +12,14 @@ See AntlrGeneratedParserBase + It also uses the following maven properties: + - ant.contrib.jar: Location of the ant-contrib jar --> + + + + + @@ -55,6 +62,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -87,7 +163,7 @@ tofile="${parser-file}"/> - + diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index 0eec39f809d..f4879ed0e7b 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -30,6 +30,7 @@ + diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index 496115127be..f7727958328 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -30,6 +30,7 @@ + diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index 4df297ebc94..cf47e5217cc 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -30,6 +30,7 @@ + diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index f3a24be6d33..c8adda151f9 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -30,6 +30,7 @@ + diff --git a/pom.xml b/pom.xml index 8f0474ab59a..0f41e68e7db 100644 --- a/pom.xml +++ b/pom.xml @@ -122,6 +122,9 @@ ${project.build.directory}/generated-sources/javacc ${project.basedir}/../javacc-wrapper.xml + 1.0b3 + ${settings.localRepository}/ant-contrib/ant-contrib/${ant-contrib.version}/ant-contrib-${ant-contrib.version}.jar + ${project.build.directory}/generated-sources/antlr4 ${project.basedir}/../antlr4-wrapper.xml @@ -167,6 +170,11 @@ ant ${ant.version} + + ant-contrib + ant-contrib + ${ant-contrib.version} + From 31018611c65db4f699c0f745a5a65de540214e1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Sun, 6 Oct 2024 20:07:37 -0300 Subject: [PATCH 0066/1962] Add missing lexer properties --- antlr4-wrapper.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/antlr4-wrapper.xml b/antlr4-wrapper.xml index b17002f40ab..da0ed3799e9 100644 --- a/antlr4-wrapper.xml +++ b/antlr4-wrapper.xml @@ -48,6 +48,9 @@ + + + From f68130eaf9e95c836b682ef068736e9edd209cc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Sun, 6 Oct 2024 20:07:47 -0300 Subject: [PATCH 0067/1962] Annotate Antlr generated classes for PMD languages --- antlr4-wrapper.xml | 4 +++- pmd-kotlin/pom.xml | 1 + pmd-swift/pom.xml | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/antlr4-wrapper.xml b/antlr4-wrapper.xml index da0ed3799e9..0832bd9bc0e 100644 --- a/antlr4-wrapper.xml +++ b/antlr4-wrapper.xml @@ -179,7 +179,9 @@ public class ${lexer-name}'/> - + + diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index 40f19513de1..5e9dbf2e80e 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -43,6 +43,7 @@ + diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index 023fa8dd390..0c50cdc8181 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -42,6 +42,7 @@ + From ad27310a389a00ab5b2604a57b6656955ab6fafb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 7 Oct 2024 16:24:55 +0200 Subject: [PATCH 0068/1962] minimize --- .../java/symbols/table/internal/SymTableFactory.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymTableFactory.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymTableFactory.java index 14ee551a348..cd6240bc3b9 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymTableFactory.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymTableFactory.java @@ -26,7 +26,6 @@ import net.sourceforge.pmd.lang.ast.NodeStream; import net.sourceforge.pmd.lang.ast.SemanticErrorReporter; -import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter; import net.sourceforge.pmd.lang.java.ast.ASTFormalParameters; import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTList; @@ -435,10 +434,6 @@ JSymbolTable typeHeader(JSymbolTable parent, JClassSymbol sym) { * of fields by local variables and formals. */ JSymbolTable bodyDeclaration(JSymbolTable parent, JClassType enclosing, @Nullable ASTFormalParameters formals, @Nullable ASTTypeParameters tparams) { - NodeStream namedFormals = ASTList.orEmptyStream(formals).map(ASTFormalParameter::getVarId); - if (unnamedVariableIsSupported()) { - namedFormals = namedFormals.filterNot(ASTVariableId::isUnnamed); - } return new SymbolTableImpl( VARS.shadow(varNode(parent), ScopeInfo.FORMAL_PARAM, VARS.groupByName(ASTList.orEmptyStream(formals), fp -> { ASTVariableId varId = fp.getVarId(); @@ -480,10 +475,6 @@ JSymbolTable localVarSymTable(JSymbolTable parent, JClassType enclosing, ASTVari return SymbolTableImpl.withVars(parent, VARS.augment(varNode(parent), false, ScopeInfo.LOCAL, id.getTypeSystem().sigOf(enclosing, (JLocalVariableSymbol) id.getSymbol()))); } - private boolean unnamedVariableIsSupported() { - return processor.getJdkVersion() >= 22; - } - JSymbolTable localTypeSymTable(JSymbolTable parent, JClassType sym) { // TODO is this really not a shadow barrier? return SymbolTableImpl.withTypes(parent, TYPES.augment(typeNode(parent), false, ScopeInfo.LOCAL, sym)); From 2c1a7f026e6ba4d06d73118b44599b617445fccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 7 Oct 2024 16:40:37 +0200 Subject: [PATCH 0069/1962] Fix NPE with empty pattern list --- pmd-java/etc/grammar/Java.jjt | 4 +- .../java21/RecordPatterns.java | 9 ++ .../jdkversiontests/java21/RecordPatterns.txt | 104 ++++++++++++------ 3 files changed, 79 insertions(+), 38 deletions(-) diff --git a/pmd-java/etc/grammar/Java.jjt b/pmd-java/etc/grammar/Java.jjt index ef9406b9c3c..630520f4e71 100644 --- a/pmd-java/etc/grammar/Java.jjt +++ b/pmd-java/etc/grammar/Java.jjt @@ -1889,13 +1889,13 @@ void RecordPattern(): (Annotation())* ReferenceType() RecordStructurePattern() } -void RecordStructurePattern() #void: +void RecordStructurePattern() #PatternList: {} { "(" [ ComponentPatternList() ] ")" } -void ComponentPatternList() #PatternList : +void ComponentPatternList() #void : {} { ComponentPattern() ( "," ComponentPattern() )* diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatterns.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatterns.java index bf944eace8d..318c0e01344 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatterns.java +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatterns.java @@ -97,4 +97,13 @@ void test4(Box> bo) { System.out.println("String " + s); } } + + + record Empty(){} + void foo(Object o) { + boolean x = o instanceof Empty; + x = o instanceof Empty(); + } + + ; } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatterns.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatterns.txt index 04bed57df74..7c71e3a2b47 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatterns.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatterns.txt @@ -1,7 +1,7 @@ +- CompilationUnit[@PackageName = ""] +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "RecordPatterns", @CanonicalName = "RecordPatterns", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "RecordPatterns", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - +- ClassBody[@Empty = false, @Size = 18] + +- ClassBody[@Empty = false, @Size = 21] +- RecordDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "RecordPatterns$Point", @CanonicalName = "RecordPatterns.Point", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = true, @RegularClass = false, @RegularInterface = false, @SimpleName = "Point", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = ()] | +- RecordComponentList[@Empty = false, @Size = 2, @Varargs = false] @@ -512,38 +512,70 @@ | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "String ", @Empty = false, @Image = "\"String \"", @Length = 7, @LiteralText = "\"String \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] +- MethodDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "test4", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] - +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - +- VoidType[] - +- FormalParameters[@Empty = false, @Size = 1] - | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] - | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] - | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] - | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "bo", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - +- Block[@Empty = false, @Size = 1, @containsComment = false] - +- IfStatement[@Else = false] - +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "bo", @Name = "bo", @ParenthesisDepth = 0, @Parenthesized = false] - | +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | +- RecordPattern[] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] - | +- PatternList[@Empty = false, @Size = 1] - | +- RecordPattern[] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] - | +- PatternList[@Empty = false, @Size = 1] - | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - +- Block[@Empty = false, @Size = 1, @containsComment = false] - +- ExpressionStatement[] - +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - +- ArgumentList[@Empty = false, @Size = 1] - +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "String ", @Empty = false, @Image = "\"String \"", @Length = 7, @LiteralText = "\"String \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- VoidType[] + | +- FormalParameters[@Empty = false, @Size = 1] + | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] + | | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] + | | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "bo", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- Block[@Empty = false, @Size = 1, @containsComment = false] + | +- IfStatement[@Else = false] + | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "bo", @Name = "bo", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- RecordPattern[] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] + | | +- PatternList[@Empty = false, @Size = 1] + | | +- RecordPattern[] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] + | | +- PatternList[@Empty = false, @Size = 1] + | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- Block[@Empty = false, @Size = 1, @containsComment = false] + | +- ExpressionStatement[] + | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | +- ArgumentList[@Empty = false, @Size = 1] + | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] + | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "String ", @Empty = false, @Image = "\"String \"", @Length = 7, @LiteralText = "\"String \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] + +- RecordDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "RecordPatterns$Empty", @CanonicalName = "RecordPatterns.Empty", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = true, @RegularClass = false, @RegularInterface = false, @SimpleName = "Empty", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = ()] + | +- RecordComponentList[@Empty = true, @Size = 0, @Varargs = false] + | +- RecordBody[@Empty = true, @Size = 0] + +- MethodDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "foo", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- VoidType[] + | +- FormalParameters[@Empty = false, @Size = 1] + | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "o", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- Block[@Empty = false, @Size = 2, @containsComment = false] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BOOLEAN] + | | +- VariableDeclarator[@Initializer = true, @Name = "x"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Empty"] + | +- ExpressionStatement[] + | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] + | +- VariableAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] + | +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- RecordPattern[] + | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Empty"] + | +- PatternList[@Empty = true, @Size = 0] + +- EmptyDeclaration[] From b724b4dd33971ea0bdf45660c9107bd2e2ff95b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 7 Oct 2024 18:18:32 +0200 Subject: [PATCH 0070/1962] Fix DataflowPassTest --- .../java21/RecordPatterns.java | 5 ++- .../jdkversiontests/java21/RecordPatterns.txt | 41 ++++++++++--------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatterns.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatterns.java index 318c0e01344..36b02e94d87 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatterns.java +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatterns.java @@ -101,8 +101,9 @@ void test4(Box> bo) { record Empty(){} void foo(Object o) { - boolean x = o instanceof Empty; - x = o instanceof Empty(); + if (o instanceof Empty + || o instanceof Empty()) + System.out.println("Empty " + o); } ; diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatterns.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatterns.txt index 7c71e3a2b47..44dc24bba69 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatterns.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatterns.txt @@ -559,23 +559,26 @@ | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "o", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- Block[@Empty = false, @Size = 2, @containsComment = false] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BOOLEAN] - | | +- VariableDeclarator[@Initializer = true, @Name = "x"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Empty"] - | +- ExpressionStatement[] - | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] - | +- VariableAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] - | +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | +- RecordPattern[] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Empty"] - | +- PatternList[@Empty = true, @Size = 0] + | +- Block[@Empty = false, @Size = 1, @containsComment = false] + | +- IfStatement[@Else = false] + | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.CONDITIONAL_OR, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Empty"] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- RecordPattern[] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Empty"] + | | +- PatternList[@Empty = true, @Size = 0] + | +- ExpressionStatement[] + | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | +- ArgumentList[@Empty = false, @Size = 1] + | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] + | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Empty ", @Empty = false, @Image = "\"Empty \"", @Length = 6, @LiteralText = "\"Empty \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] +- EmptyDeclaration[] From ff1b9b2cdde7702f4df34bd55d5d7049a9e06b2a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 8 Oct 2024 17:15:18 +0200 Subject: [PATCH 0071/1962] [java] SwitchStmtsShouldHaveDefault - test for multiple case constants --- .../xml/SwitchStmtsShouldHaveDefault.xml | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/SwitchStmtsShouldHaveDefault.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/SwitchStmtsShouldHaveDefault.xml index 145739199e9..cd13ce5dc93 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/SwitchStmtsShouldHaveDefault.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/SwitchStmtsShouldHaveDefault.xml @@ -329,6 +329,39 @@ public class SwitchWithRecordPattern { } } } +]]> + + + + Multiple Case Constants + 0 + System.out.println("a or b"); + case C -> System.out.println("c"); + } + String s = switch(e) { + case A,B -> "a or b"; + case C -> "c"; + }; + System.out.println(s); + } +} ]]> From 07840cace2d8b375bbc22331d864d8a0b9375b27 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 8 Oct 2024 17:26:18 +0200 Subject: [PATCH 0072/1962] [java] Rename rule SwitchStmtsShouldHaveDefault to NonExhaustiveSwitch Fixes #4286 --- docs/pages/release_notes.md | 21 +++--- .../resources/category/java/bestpractices.xml | 68 ++++++++++--------- .../resources/rulesets/java/quickstart.xml | 2 +- ...Test.java => NonExhaustiveSwitchTest.java} | 2 +- ...aveDefault.xml => NonExhaustiveSwitch.xml} | 0 5 files changed, 49 insertions(+), 44 deletions(-) rename pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/{SwitchStmtsShouldHaveDefaultTest.java => NonExhaustiveSwitchTest.java} (79%) rename pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/{SwitchStmtsShouldHaveDefault.xml => NonExhaustiveSwitch.xml} (100%) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 197b7a4aec8..aac6ab68014 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -17,21 +17,23 @@ This is a {{ site.pmd.release_type }} release. ### ๐ŸŒŸ Rule Changes #### Renamed Rules -Several rules for unit testing have been renamed to better reflect their actual scope. Lots of them were called -after JUnit / JUnit 4, even when they applied to JUnit 5 and / or TestNG. - -* {% rule java/bestpractices/UnitTestAssertionsShouldIncludeMessage %} (Java Best Practices) has been renamed from `JUnitAssertionsShouldIncludeMessage`. -* {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} (Java Best Practices) has been renamed from `JUnitTestContainsTooManyAsserts`. -* {% rule java/bestpractices/UnitTestShouldIncludeAssert %} (Java Best Practices) has been renamed from `JUnitTestsShouldIncludeAssert`. -* {% rule java/bestpractices/UnitTestShouldUseAfterAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseAfterAnnotation`. -* {% rule java/bestpractices/UnitTestShouldUseBeforeAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseBeforeAnnotation`. -* {% rule java/bestpractices/UnitTestShouldUseTestAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseTestAnnotation`. +* Several rules for unit testing have been renamed to better reflect their actual scope. Lots of them were called + after JUnit / JUnit 4, even when they applied to JUnit 5 and / or TestNG. + * {% rule java/bestpractices/UnitTestAssertionsShouldIncludeMessage %} (Java Best Practices) has been renamed from `JUnitAssertionsShouldIncludeMessage`. + * {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} (Java Best Practices) has been renamed from `JUnitTestContainsTooManyAsserts`. + * {% rule java/bestpractices/UnitTestShouldIncludeAssert %} (Java Best Practices) has been renamed from `JUnitTestsShouldIncludeAssert`. + * {% rule java/bestpractices/UnitTestShouldUseAfterAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseAfterAnnotation`. + * {% rule java/bestpractices/UnitTestShouldUseBeforeAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseBeforeAnnotation`. + * {% rule java/bestpractices/UnitTestShouldUseTestAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseTestAnnotation`. +* {%rule java/bestpractices/NonExhaustiveSwitch %} (Java Best Practices) has been renamed from `SwitchStmtsShouldHaveDefault`. The old rule names still work but are deprecated. ### ๐Ÿ› Fixed Issues * java * [#4532](https://github.com/pmd/pmd/issues/4532): \[java] Rule misnomer for JUnit* rules +* java-bestpractices + * [#4286](https://github.com/pmd/pmd/issues/4286): \[java] Rename rule SwitchStmtsShouldHaveDefault to NonExhaustiveSwitch * java-errorprone * [#5067](https://github.com/pmd/pmd/issues/5067): \[java] CloseResource: False positive for FileSystems.getDefault() @@ -43,6 +45,7 @@ The old rule names still work but are deprecated. * The old rule name `JUnitAssertionsShouldIncludeMessage` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestAssertionsShouldIncludeMessage %} instead. * The old rule name `JUnitTestContainsTooManyAsserts` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} instead. * The old rule name `JUnitTestsShouldIncludeAssert` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestShouldIncludeAssert %} instead. + * The old rule name `SwitchStmtsShouldHaveDefault` has been deprecated. USe the new name {%rule java/bestpractices/NonExhaustiveSwitch %} instead. ### โœจ Merged pull requests diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 03b23ad1ca9..14ae96fcdc2 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -904,6 +904,40 @@ public class SecureSystem { + + + Switch statements should be exhaustive, to make their control flow + easier to follow. This can be achieved by adding a `default` case, or, + if the switch is on an enum type, by ensuring there is one switch branch + for each enum constant. + + 3 + + + + + + + + + + - - - Switch statements should be exhaustive, to make their control flow - easier to follow. This can be achieved by adding a `default` case, or, - if the switch is on an enum type, by ensuring there is one switch branch - for each enum constant. - - 3 - - - - - - - - - + + @@ -37,7 +38,6 @@ - diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/SwitchStmtsShouldHaveDefaultTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/NonExhaustiveSwitchTest.java similarity index 79% rename from pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/SwitchStmtsShouldHaveDefaultTest.java rename to pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/NonExhaustiveSwitchTest.java index 1e413f1bde3..2d7b18f754e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/SwitchStmtsShouldHaveDefaultTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/NonExhaustiveSwitchTest.java @@ -6,6 +6,6 @@ import net.sourceforge.pmd.test.PmdRuleTst; -class SwitchStmtsShouldHaveDefaultTest extends PmdRuleTst { +class NonExhaustiveSwitchTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/SwitchStmtsShouldHaveDefault.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/NonExhaustiveSwitch.xml similarity index 100% rename from pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/SwitchStmtsShouldHaveDefault.xml rename to pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/NonExhaustiveSwitch.xml From 54dfabea9bc70f22d8fe547e4993841d6a1cf739 Mon Sep 17 00:00:00 2001 From: Aryant Tripathi Date: Wed, 9 Oct 2024 10:00:02 +0530 Subject: [PATCH 0073/1962] Support Boolean wrapper class for BooleanGetMethodName rule (#5253) --- .../main/resources/category/java/codestyle.xml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml index d525b0df9cd..7f16e0177da 100644 --- a/pmd-java/src/main/resources/category/java/codestyle.xml +++ b/pmd-java/src/main/resources/category/java/codestyle.xml @@ -172,32 +172,33 @@ public class SomeJNIClass { -Methods that return boolean results should be named as predicate statements to denote this. -I.e, 'isReady()', 'hasValues()', 'canCommit()', 'willFail()', etc. Avoid the use of the 'get' -prefix for these methods. + Methods that return boolean or Boolean results should be named as predicate statements to denote this. + I.e., 'isReady()', 'hasValues()', 'canCommit()', 'willFail()', etc. Avoid the use of the 'get' prefix for these methods. 4 - - From 8b2af2db8a6b3e006a39d38b4f2538012f15f913 Mon Sep 17 00:00:00 2001 From: Aryant Tripathi Date: Thu, 10 Oct 2024 20:44:06 +0530 Subject: [PATCH 0074/1962] Support wrapper class in BooleanGetMethodName rule (#5253) - Updated XPath rule to include both primitive and wrapper class: (PrimitiveType[@Kind = 'boolean'] or ClassType[pmd-java:typeIs('java.lang.Boolean')]) - Added test cases to ensure that methods returning are also flagged correctly. - Ensured the rule enforces consistent method naming for both primitive and wrapper types. --- .../resources/category/java/codestyle.xml | 2 +- .../codestyle/xml/BooleanGetMethodName.xml | 60 +++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml index 7f16e0177da..5b382db9bca 100644 --- a/pmd-java/src/main/resources/category/java/codestyle.xml +++ b/pmd-java/src/main/resources/category/java/codestyle.xml @@ -187,7 +187,7 @@ public class SomeJNIClass { //MethodDeclaration [starts-with(@Name, 'get')] [@Arity = 0 or $checkParameterizedMethods = true()] - [ (PrimitiveType[@Kind = 'boolean'] or ReferenceType[@Type = 'Boolean']) and @Overridden = false() ] + [ (PrimitiveType[@Kind = 'boolean'] or ClassType[pmd-java:typeIs('java.lang.Boolean')]) and @Overridden = false() ] ]]> diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/BooleanGetMethodName.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/BooleanGetMethodName.xml index c0eee19a2f7..648afbf32bd 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/BooleanGetMethodName.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/BooleanGetMethodName.xml @@ -34,6 +34,16 @@ public class Foo { ]]> + + Should not match on multiple parameters by default + 0 + + + Should not match on methods annotated with @Override 0 @@ -60,4 +70,54 @@ public class Foo { } ]]> + + + Bad name + 1 + + + + + Good name + 0 + + + + + Should not match on methods annotated with @Override + 0 + + + + + + + Should match on multiple parameters when checkParameterizedMethods = true + true + 1 + + + From c595fea83f7c8f089ce9d550c93b152b41c95c3a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Oct 2024 11:57:10 +0200 Subject: [PATCH 0075/1962] [apex] AvoidNonRestrictiveQueries: Fix regex for detecting LIMIT clause Fixes #5270 --- docs/pages/release_notes.md | 2 ++ .../AvoidNonRestrictiveQueriesRule.java | 2 +- .../xml/AvoidNonRestrictiveQueries.xml | 30 +++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 197b7a4aec8..6da08b0c2c2 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -30,6 +30,8 @@ after JUnit / JUnit 4, even when they applied to JUnit 5 and / or TestNG. The old rule names still work but are deprecated. ### ๐Ÿ› Fixed Issues +* apex-performance + * [#5270](https://github.com/pmd/pmd/issues/5270): \[apex] AvoidNonRestrictiveQueries when LIMIT is followed by bind expression * java * [#4532](https://github.com/pmd/pmd/issues/4532): \[java] Rule misnomer for JUnit* rules * java-errorprone diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/performance/AvoidNonRestrictiveQueriesRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/performance/AvoidNonRestrictiveQueriesRule.java index e62363eb7e0..fd3c5bf392d 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/performance/AvoidNonRestrictiveQueriesRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/performance/AvoidNonRestrictiveQueriesRule.java @@ -24,7 +24,7 @@ import net.sourceforge.pmd.reporting.RuleContext; public class AvoidNonRestrictiveQueriesRule extends AbstractApexRule { - private static final Pattern RESTRICTIVE_PATTERN = Pattern.compile("(where\\s+)|(limit\\s+)", Pattern.CASE_INSENSITIVE); + private static final Pattern RESTRICTIVE_PATTERN = Pattern.compile("\\b(where|limit)\\b", Pattern.CASE_INSENSITIVE); private static final Pattern SELECT_OR_FIND_PATTERN = Pattern.compile("(select\\s+|find\\s+)", Pattern.CASE_INSENSITIVE); private static final Pattern SUB_QUERY_PATTERN = Pattern.compile("(?i)\\(\\s*select\\s+[^)]+\\)"); diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/performance/xml/AvoidNonRestrictiveQueries.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/performance/xml/AvoidNonRestrictiveQueries.xml index 289a0492611..c18ad9538ab 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/performance/xml/AvoidNonRestrictiveQueries.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/performance/xml/AvoidNonRestrictiveQueries.xml @@ -260,6 +260,36 @@ public class Something { .isEmpty(); } } +]]> + + + + [apex] AvoidNonRestrictiveQueries when LIMIT is followed by bind expression #5270 + 0 + getTwoAccounts() { + List result = [ + SELECT Id, Name FROM Account WITH SECURITY_ENFORCED + LIMIT:LIMIT_ACCOUNTS // note: no spaces... - false positive here + ]; + List result2 = [ + SELECT Id, Name FROM Account WITH SECURITY_ENFORCED + LIMIT :LIMIT_ACCOUNTS + ]; + List result3 = [ + SELECT Id, Name FROM Account WITH SECURITY_ENFORCED + LIMIT : LIMIT_ACCOUNTS + ]; + + // sosl: + List> searchList = [FIND 'map*' IN ALL FIELDS RETURNING Account (Id, Name), Contact, Opportunity, Lead LIMIT:LIMIT_ACCOUNTS]; + + return result; + } +} ]]> From 7ae31553257a5bf9bb9d31e40e9fcf86c5a33aad Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Oct 2024 11:57:39 +0200 Subject: [PATCH 0076/1962] Add @thesunlover as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 171 +++++++++++++------------- 2 files changed, 95 insertions(+), 85 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 28d946f30a6..6bde20ce777 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7819,6 +7819,15 @@ "contributions": [ "bug" ] + }, + { + "login": "thesunlover", + "name": "Iskren Stanislavov", + "avatar_url": "https://avatars.githubusercontent.com/u/6734600?v=4", + "profile": "https://interop.io/", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 4795947746b..6eb428996de 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -340,770 +340,771 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Ishan Srivastava
    Ishan Srivastava

    ๐Ÿ› + Iskren Stanislavov
    Iskren Stanislavov

    ๐Ÿ› Ivan Vakhrushev
    Ivan Vakhrushev

    ๐Ÿ› Ivano Guerini
    Ivano Guerini

    ๐Ÿ› Ivar Andreas Bonsaksen
    Ivar Andreas Bonsaksen

    ๐Ÿ› Ivo ล mรญd
    Ivo ล mรญd

    ๐Ÿ› JJengility
    JJengility

    ๐Ÿ› - Jake Hemmerle
    Jake Hemmerle

    ๐Ÿ› + Jake Hemmerle
    Jake Hemmerle

    ๐Ÿ› James Harrison
    James Harrison

    ๐Ÿ› ๐Ÿ’ป Jamie Bisotti
    Jamie Bisotti

    ๐Ÿ› Jan
    Jan

    ๐Ÿ› Jan Aertgeerts
    Jan Aertgeerts

    ๐Ÿ’ป ๐Ÿ› Jan Brรผmmer
    Jan Brรผmmer

    ๐Ÿ› Jan Tล™รญska
    Jan Tล™รญska

    ๐Ÿ› - Jan-Lukas Else
    Jan-Lukas Else

    ๐Ÿ› + Jan-Lukas Else
    Jan-Lukas Else

    ๐Ÿ› Jason Qiu
    Jason Qiu

    ๐Ÿ’ป ๐Ÿ“– Jason Williams
    Jason Williams

    ๐Ÿ› Jean-Paul Mayer
    Jean-Paul Mayer

    ๐Ÿ› Jean-Simon Larochelle
    Jean-Simon Larochelle

    ๐Ÿ› Jeff Bartolotta
    Jeff Bartolotta

    ๐Ÿ’ป ๐Ÿ› Jeff Hube
    Jeff Hube

    ๐Ÿ’ป ๐Ÿ› - Jeff Jensen
    Jeff Jensen

    ๐Ÿ› + Jeff Jensen
    Jeff Jensen

    ๐Ÿ› Jeff May
    Jeff May

    ๐Ÿ› Jens Gerdes
    Jens Gerdes

    ๐Ÿ› Jeroen Borgers
    Jeroen Borgers

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข Jeroen Meijer
    Jeroen Meijer

    ๐Ÿ› Jeroen van Wilgenburg
    Jeroen van Wilgenburg

    ๐Ÿ“– Jerome Russ
    Jerome Russ

    ๐Ÿ› - JerritEic
    JerritEic

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› + JerritEic
    JerritEic

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Jiri Pejchal
    Jiri Pejchal

    ๐Ÿ› Jithin Sunny
    Jithin Sunny

    ๐Ÿ› Jiล™รญ ล korpil
    Jiล™รญ ล korpil

    ๐Ÿ› Joao Machado
    Joao Machado

    ๐Ÿ› Jochen Krauss
    Jochen Krauss

    ๐Ÿ› Johan Hammar
    Johan Hammar

    ๐Ÿ› - John Karp
    John Karp

    ๐Ÿ› + John Karp
    John Karp

    ๐Ÿ› John Zhang
    John Zhang

    ๐Ÿ› John-Teng
    John-Teng

    ๐Ÿ’ป ๐Ÿ› Jon Moroney
    Jon Moroney

    ๐Ÿ’ป ๐Ÿ› Jonas Geiregat
    Jonas Geiregat

    ๐Ÿ› Jonas KeรŸler
    Jonas KeรŸler

    ๐Ÿ› Jonathan Wiesel
    Jonathan Wiesel

    ๐Ÿ’ป ๐Ÿ› - Jordan
    Jordan

    ๐Ÿ› + Jordan
    Jordan

    ๐Ÿ› Jordi Llach
    Jordi Llach

    ๐Ÿ› Jorge Solรณrzano
    Jorge Solรณrzano

    ๐Ÿ› JorneVL
    JorneVL

    ๐Ÿ› Jose Palafox
    Jose Palafox

    ๐Ÿ› Jose Stovall
    Jose Stovall

    ๐Ÿ› Joseph
    Joseph

    ๐Ÿ’ป - Joseph Heenan
    Joseph Heenan

    ๐Ÿ› + Joseph Heenan
    Joseph Heenan

    ๐Ÿ› Josh Feingold
    Josh Feingold

    ๐Ÿ’ป ๐Ÿ› Josh Holthaus
    Josh Holthaus

    ๐Ÿ› Joshua S Arquilevich
    Joshua S Arquilevich

    ๐Ÿ› Joรฃo Dinis Ferreira
    Joรฃo Dinis Ferreira

    ๐Ÿ“– Joรฃo Ferreira
    Joรฃo Ferreira

    ๐Ÿ’ป ๐Ÿ› Joรฃo Pedro Schmitt
    Joรฃo Pedro Schmitt

    ๐Ÿ› - Juan Martรญn Sotuyo Dodero
    Juan Martรญn Sotuyo Dodero

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง + Juan Martรญn Sotuyo Dodero
    Juan Martรญn Sotuyo Dodero

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง Juan Pablo Civile
    Juan Pablo Civile

    ๐Ÿ› Julian Voronetsky
    Julian Voronetsky

    ๐Ÿ› Julien
    Julien

    ๐Ÿ› Julius
    Julius

    ๐Ÿ› JustPRV
    JustPRV

    ๐Ÿ› Justin Stroud
    Justin Stroud

    ๐Ÿ’ป - Jรถrn Huxhorn
    Jรถrn Huxhorn

    ๐Ÿ› + Jรถrn Huxhorn
    Jรถrn Huxhorn

    ๐Ÿ› KThompso
    KThompso

    ๐Ÿ› Kai Amundsen
    Kai Amundsen

    ๐Ÿ› Karel Vervaeke
    Karel Vervaeke

    ๐Ÿ› Karl-Andero Mere
    Karl-Andero Mere

    ๐Ÿ› Karl-Philipp Richter
    Karl-Philipp Richter

    ๐Ÿ› Karsten Silz
    Karsten Silz

    ๐Ÿ› - Kazuma Watanabe
    Kazuma Watanabe

    ๐Ÿ› + Kazuma Watanabe
    Kazuma Watanabe

    ๐Ÿ› Kev
    Kev

    ๐Ÿ› Keve Mรผller
    Keve Mรผller

    ๐Ÿ› Kevin Guerra
    Kevin Guerra

    ๐Ÿ’ป Kevin Jones
    Kevin Jones

    ๐Ÿ› ๐Ÿ’ป Kevin Poorman
    Kevin Poorman

    ๐Ÿ› Kevin Wayne
    Kevin Wayne

    ๐Ÿ› - Kieran Black
    Kieran Black

    ๐Ÿ› + Kieran Black
    Kieran Black

    ๐Ÿ› Kirill Zubov
    Kirill Zubov

    ๐Ÿ› Kirk Clemens
    Kirk Clemens

    ๐Ÿ’ป ๐Ÿ› Klaus Hartl
    Klaus Hartl

    ๐Ÿ› Koen Van Looveren
    Koen Van Looveren

    ๐Ÿ› Kris Scheibe
    Kris Scheibe

    ๐Ÿ’ป ๐Ÿ› Krystian Dabrowski
    Krystian Dabrowski

    ๐Ÿ› ๐Ÿ’ป - Kunal Thanki
    Kunal Thanki

    ๐Ÿ› + Kunal Thanki
    Kunal Thanki

    ๐Ÿ› LaLucid
    LaLucid

    ๐Ÿ’ป Larry Diamond
    Larry Diamond

    ๐Ÿ’ป ๐Ÿ› Lars Knickrehm
    Lars Knickrehm

    ๐Ÿ› Laurent Bovet
    Laurent Bovet

    ๐Ÿ› ๐Ÿ’ป Leo Gutierrez
    Leo Gutierrez

    ๐Ÿ› LiGaOg
    LiGaOg

    ๐Ÿ’ป - Liam Sharp
    Liam Sharp

    ๐Ÿ› + Liam Sharp
    Liam Sharp

    ๐Ÿ› Lintsi
    Lintsi

    ๐Ÿ› Linus Fernandes
    Linus Fernandes

    ๐Ÿ› Lixon Lookose
    Lixon Lookose

    ๐Ÿ› Logesh
    Logesh

    ๐Ÿ› Lorenzo Gabriele
    Lorenzo Gabriele

    ๐Ÿ› Loรฏc Ledoyen
    Loรฏc Ledoyen

    ๐Ÿ› - Lucas
    Lucas

    ๐Ÿ› + Lucas
    Lucas

    ๐Ÿ› Lucas Silva
    Lucas Silva

    ๐Ÿ› Lucas Soncini
    Lucas Soncini

    ๐Ÿ’ป ๐Ÿ› Luis Alcantar
    Luis Alcantar

    ๐Ÿ’ป Lukas Grรคf
    Lukas Grรคf

    ๐Ÿ’ป Lukasz Slonina
    Lukasz Slonina

    ๐Ÿ› Lukebray
    Lukebray

    ๐Ÿ› - Lynn
    Lynn

    ๐Ÿ’ป ๐Ÿ› + Lynn
    Lynn

    ๐Ÿ’ป ๐Ÿ› Lyor Goldstein
    Lyor Goldstein

    ๐Ÿ› MCMicS
    MCMicS

    ๐Ÿ› Macarse
    Macarse

    ๐Ÿ› Machine account for PMD
    Machine account for PMD

    ๐Ÿ’ป Maciek Siemczyk
    Maciek Siemczyk

    ๐Ÿ› Maikel Steneker
    Maikel Steneker

    ๐Ÿ’ป ๐Ÿ› - Maksim Moiseikin
    Maksim Moiseikin

    ๐Ÿ› + Maksim Moiseikin
    Maksim Moiseikin

    ๐Ÿ› Manfred Koch
    Manfred Koch

    ๐Ÿ› Manuel Moya Ferrer
    Manuel Moya Ferrer

    ๐Ÿ’ป ๐Ÿ› Manuel Ryan
    Manuel Ryan

    ๐Ÿ› Marat Vyshegorodtsev
    Marat Vyshegorodtsev

    ๐Ÿ› Marcel Hรคrle
    Marcel Hรคrle

    ๐Ÿ› Marcello Fialho
    Marcello Fialho

    ๐Ÿ› - Marcin Dฤ…browski
    Marcin Dฤ…browski

    ๐Ÿ’ป + Marcin Dฤ…browski
    Marcin Dฤ…browski

    ๐Ÿ’ป Marcin Rataj
    Marcin Rataj

    ๐Ÿ› Marcono1234
    Marcono1234

    ๐Ÿ› Mark Adamcin
    Mark Adamcin

    ๐Ÿ› Mark Hall
    Mark Hall

    ๐Ÿ’ป ๐Ÿ› Mark Kolich
    Mark Kolich

    ๐Ÿ› Mark Pritchard
    Mark Pritchard

    ๐Ÿ› - Markus Rathgeb
    Markus Rathgeb

    ๐Ÿ› + Markus Rathgeb
    Markus Rathgeb

    ๐Ÿ› Marquis Wang
    Marquis Wang

    ๐Ÿ› MartGit
    MartGit

    ๐Ÿ› Martin Feldsztejn
    Martin Feldsztejn

    ๐Ÿ› Martin Lehmann
    Martin Lehmann

    ๐Ÿ› Martin Spamer
    Martin Spamer

    ๐Ÿ› Martin Tarjรกnyi
    Martin Tarjรกnyi

    ๐Ÿ› - MatFl
    MatFl

    ๐Ÿ› + MatFl
    MatFl

    ๐Ÿ› Mateusz Stefanski
    Mateusz Stefanski

    ๐Ÿ› Mathieu Gouin
    Mathieu Gouin

    ๐Ÿ› MatiasComercio
    MatiasComercio

    ๐Ÿ’ป ๐Ÿ› Matt Benson
    Matt Benson

    ๐Ÿ› Matt De Poorter
    Matt De Poorter

    ๐Ÿ› Matt Hargett
    Matt Hargett

    ๐Ÿ’ป ๐Ÿ’ต - Matt Harrah
    Matt Harrah

    ๐Ÿ› + Matt Harrah
    Matt Harrah

    ๐Ÿ› Matt Nelson
    Matt Nelson

    ๐Ÿ› Matthew Amos
    Matthew Amos

    ๐Ÿ› Matthew Duggan
    Matthew Duggan

    ๐Ÿ› Matthew Hall
    Matthew Hall

    ๐Ÿ› Matthew Rossner
    Matthew Rossner

    ๐Ÿ› Matรญas Fraga
    Matรญas Fraga

    ๐Ÿ’ป ๐Ÿ› - Maxime Robert
    Maxime Robert

    ๐Ÿ’ป ๐Ÿ› + Maxime Robert
    Maxime Robert

    ๐Ÿ’ป ๐Ÿ› MetaBF
    MetaBF

    ๐Ÿ› Metin Dagcilar
    Metin Dagcilar

    ๐Ÿ› Michael
    Michael

    ๐Ÿ› Michael Bell
    Michael Bell

    ๐Ÿ› Michael Bernstein
    Michael Bernstein

    ๐Ÿ› Michael Clay
    Michael Clay

    ๐Ÿ› - Michael Dombrowski
    Michael Dombrowski

    ๐Ÿ› + Michael Dombrowski
    Michael Dombrowski

    ๐Ÿ› Michael Hausegger
    Michael Hausegger

    ๐Ÿ› Michael Hoefer
    Michael Hoefer

    ๐Ÿ› Michael Kolesnikov
    Michael Kolesnikov

    ๐Ÿ› Michael Mรถbius
    Michael Mรถbius

    ๐Ÿ› Michael N. Lipp
    Michael N. Lipp

    ๐Ÿ› Michael Pellegrini
    Michael Pellegrini

    ๐Ÿ› - Michal Kordas
    Michal Kordas

    ๐Ÿ› + Michal Kordas
    Michal Kordas

    ๐Ÿ› Michaล‚ Borek
    Michaล‚ Borek

    ๐Ÿ› Michaล‚ Kuliล„ski
    Michaล‚ Kuliล„ski

    ๐Ÿ› Miguel Nรบรฑez Dรญaz-Montes
    Miguel Nรบรฑez Dรญaz-Montes

    ๐Ÿ› Mihai Ionut
    Mihai Ionut

    ๐Ÿ› Mikhail Kuchma
    Mikhail Kuchma

    ๐Ÿ› Mirek Hankus
    Mirek Hankus

    ๐Ÿ› - Mitch Spano
    Mitch Spano

    ๐Ÿ› + Mitch Spano
    Mitch Spano

    ๐Ÿ› Mladjan Gadzic
    Mladjan Gadzic

    ๐Ÿ› MrAngry52
    MrAngry52

    ๐Ÿ› Muminur Choudhury
    Muminur Choudhury

    ๐Ÿ› Mykhailo Palahuta
    Mykhailo Palahuta

    ๐Ÿ’ป ๐Ÿ› Nagendra Kumar Singh
    Nagendra Kumar Singh

    ๐Ÿ› Nahuel Barrios
    Nahuel Barrios

    ๐Ÿ› - Nakul Sharma
    Nakul Sharma

    ๐Ÿ› + Nakul Sharma
    Nakul Sharma

    ๐Ÿ› Nathan Braun
    Nathan Braun

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› Nathanaรซl
    Nathanaรซl

    ๐Ÿ› Naveen
    Naveen

    ๐Ÿ’ป Nazdravi
    Nazdravi

    ๐Ÿ› - Neha-Dhonde
    Neha-Dhonde

    ๐Ÿ› + Neha-Dhonde
    Neha-Dhonde

    ๐Ÿ› Nicholas Doyle
    Nicholas Doyle

    ๐Ÿ› Nick Butcher
    Nick Butcher

    ๐Ÿ› Nico Gallinal
    Nico Gallinal

    ๐Ÿ› Nicola Dal Maso
    Nicola Dal Maso

    ๐Ÿ› Nicolas Filotto
    Nicolas Filotto

    ๐Ÿ’ป Nicolas Vervelle
    Nicolas Vervelle

    ๐Ÿ› - Nicolas Vuillamy
    Nicolas Vuillamy

    ๐Ÿ“– + Nicolas Vuillamy
    Nicolas Vuillamy

    ๐Ÿ“– Nikita Chursin
    Nikita Chursin

    ๐Ÿ› Niklas Baudy
    Niklas Baudy

    ๐Ÿ› Nikolas Havrikov
    Nikolas Havrikov

    ๐Ÿ› Nilesh Virkar
    Nilesh Virkar

    ๐Ÿ› Nimit Patel
    Nimit Patel

    ๐Ÿ› Niranjan Harpale
    Niranjan Harpale

    ๐Ÿ› - Nirvik Patel
    Nirvik Patel

    ๐Ÿ’ป + Nirvik Patel
    Nirvik Patel

    ๐Ÿ’ป Noah Sussman
    Noah Sussman

    ๐Ÿ› Noah0120
    Noah0120

    ๐Ÿ› Noam Tamim
    Noam Tamim

    ๐Ÿ› Noel Grandin
    Noel Grandin

    ๐Ÿ› Olaf Haalstra
    Olaf Haalstra

    ๐Ÿ› Oleg Andreych
    Oleg Andreych

    ๐Ÿ’ป ๐Ÿ› - Oleg Pavlenko
    Oleg Pavlenko

    ๐Ÿ› + Oleg Pavlenko
    Oleg Pavlenko

    ๐Ÿ› Oleksii Dykov
    Oleksii Dykov

    ๐Ÿ’ป ๐Ÿ› Oliver Eikemeier
    Oliver Eikemeier

    ๐Ÿ› Oliver Siegmar
    Oliver Siegmar

    ๐Ÿ’ต Olivier Parent
    Olivier Parent

    ๐Ÿ’ป ๐Ÿ› Ollie Abbey
    Ollie Abbey

    ๐Ÿ’ป ๐Ÿ› Ondrej Kratochvil
    Ondrej Kratochvil

    ๐Ÿ› - OverDrone
    OverDrone

    ๐Ÿ› + OverDrone
    OverDrone

    ๐Ÿ› Ozan Gulle
    Ozan Gulle

    ๐Ÿ’ป ๐Ÿ› PUNEET JAIN
    PUNEET JAIN

    ๐Ÿ› Parbati Bose
    Parbati Bose

    ๐Ÿ› Paul Berg
    Paul Berg

    ๐Ÿ› Paul Guyot
    Paul Guyot

    ๐Ÿ’ป Pavel Bludov
    Pavel Bludov

    ๐Ÿ› - Pavel Miฤka
    Pavel Miฤka

    ๐Ÿ› + Pavel Miฤka
    Pavel Miฤka

    ๐Ÿ› Pedro Nuno Santos
    Pedro Nuno Santos

    ๐Ÿ› Pedro Rijo
    Pedro Rijo

    ๐Ÿ› Pelisse Romain
    Pelisse Romain

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Per Abich
    Per Abich

    ๐Ÿ’ป Pete Davids
    Pete Davids

    ๐Ÿ› Peter Bruin
    Peter Bruin

    ๐Ÿ› - Peter Chittum
    Peter Chittum

    ๐Ÿ’ป ๐Ÿ› + Peter Chittum
    Peter Chittum

    ๐Ÿ’ป ๐Ÿ› Peter Cudmore
    Peter Cudmore

    ๐Ÿ› Peter Kasson
    Peter Kasson

    ๐Ÿ› Peter Kofler
    Peter Kofler

    ๐Ÿ› Peter Paul Bakker
    Peter Paul Bakker

    ๐Ÿ’ป Peter Rader
    Peter Rader

    ๐Ÿ› Pham Hai Trung
    Pham Hai Trung

    ๐Ÿ› - Philip Graf
    Philip Graf

    ๐Ÿ’ป ๐Ÿ› + Philip Graf
    Philip Graf

    ๐Ÿ’ป ๐Ÿ› Philip Hachey
    Philip Hachey

    ๐Ÿ› Philippe Ozil
    Philippe Ozil

    ๐Ÿ› Phinehas Artemix
    Phinehas Artemix

    ๐Ÿ› Phokham Nonava
    Phokham Nonava

    ๐Ÿ› Pim van der Loos
    Pim van der Loos

    ๐Ÿ’ป โš ๏ธ Piotr Szymaล„ski
    Piotr Szymaล„ski

    ๐Ÿ› - Piotrek ลปygieล‚o
    Piotrek ลปygieล‚o

    ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– + Piotrek ลปygieล‚o
    Piotrek ลปygieล‚o

    ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– Pranay Jaiswal
    Pranay Jaiswal

    ๐Ÿ› Prasad Kamath
    Prasad Kamath

    ๐Ÿ› Prasanna
    Prasanna

    ๐Ÿ› Presh-AR
    Presh-AR

    ๐Ÿ› Puneet1726
    Puneet1726

    ๐Ÿ› RBRi
    RBRi

    ๐Ÿ› - Rafael Cortรชs
    Rafael Cortรชs

    ๐Ÿ› + Rafael Cortรชs
    Rafael Cortรชs

    ๐Ÿ› RaheemShaik999
    RaheemShaik999

    ๐Ÿ› RajeshR
    RajeshR

    ๐Ÿ’ป ๐Ÿ› Ramachandra Mohan
    Ramachandra Mohan

    ๐Ÿ› Ramel0921
    Ramel0921

    ๐Ÿ› Raquel Pau
    Raquel Pau

    ๐Ÿ› Ravikiran Janardhana
    Ravikiran Janardhana

    ๐Ÿ› - Reda Benhemmouche
    Reda Benhemmouche

    ๐Ÿ› + Reda Benhemmouche
    Reda Benhemmouche

    ๐Ÿ› Reinhard Schiedermeier
    Reinhard Schiedermeier

    ๐Ÿ› Renato Oliveira
    Renato Oliveira

    ๐Ÿ’ป ๐Ÿ› Rich DiCroce
    Rich DiCroce

    ๐Ÿ› Richard Corfield
    Richard Corfield

    ๐Ÿ’ป Richard Corfield
    Richard Corfield

    ๐Ÿ› ๐Ÿ’ป Riot R1cket
    Riot R1cket

    ๐Ÿ› - Rishabh Jain
    Rishabh Jain

    ๐Ÿ› + Rishabh Jain
    Rishabh Jain

    ๐Ÿ› RishabhDeep Singh
    RishabhDeep Singh

    ๐Ÿ› Rob Baillie
    Rob Baillie

    ๐Ÿ› Robbie Martinus
    Robbie Martinus

    ๐Ÿ’ป ๐Ÿ› Robert Henry
    Robert Henry

    ๐Ÿ› Robert Mihaly
    Robert Mihaly

    ๐Ÿ› Robert Painsi
    Robert Painsi

    ๐Ÿ› - Robert Russell
    Robert Russell

    ๐Ÿ› + Robert Russell
    Robert Russell

    ๐Ÿ› Robert Sรถsemann
    Robert Sรถsemann

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ› Robert Whitebit
    Robert Whitebit

    ๐Ÿ› Robin Richtsfeld
    Robin Richtsfeld

    ๐Ÿ› Robin Stocker
    Robin Stocker

    ๐Ÿ’ป ๐Ÿ› Robin Wils
    Robin Wils

    ๐Ÿ› RochusOest
    RochusOest

    ๐Ÿ› - Rodolfo Noviski
    Rodolfo Noviski

    ๐Ÿ› + Rodolfo Noviski
    Rodolfo Noviski

    ๐Ÿ› Rodrigo Casara
    Rodrigo Casara

    ๐Ÿ› Rodrigo Fernandes
    Rodrigo Fernandes

    ๐Ÿ› Roman Salvador
    Roman Salvador

    ๐Ÿ’ป ๐Ÿ› Ronald Blaschke
    Ronald Blaschke

    ๐Ÿ› Rรณbert Papp
    Rรณbert Papp

    ๐Ÿ› Saikat Sengupta
    Saikat Sengupta

    ๐Ÿ› - Saksham Handu
    Saksham Handu

    ๐Ÿ› + Saksham Handu
    Saksham Handu

    ๐Ÿ› Saladoc
    Saladoc

    ๐Ÿ› Salesforce Bob Lightning
    Salesforce Bob Lightning

    ๐Ÿ› Sam Carlberg
    Sam Carlberg

    ๐Ÿ› Sascha Riemer
    Sascha Riemer

    ๐Ÿ› Sashko
    Sashko

    ๐Ÿ’ป Satoshi Kubo
    Satoshi Kubo

    ๐Ÿ› - Scott Kennedy
    Scott Kennedy

    ๐Ÿ› + Scott Kennedy
    Scott Kennedy

    ๐Ÿ› Scott Wells
    Scott Wells

    ๐Ÿ› ๐Ÿ’ป Scrates1
    Scrates1

    ๐Ÿ› ๐Ÿ’ป Scrsloota
    Scrsloota

    ๐Ÿ’ป Sebastian Bรถgl
    Sebastian Bรถgl

    ๐Ÿ› Sebastian Davids
    Sebastian Davids

    ๐Ÿ› Sebastian Schuberth
    Sebastian Schuberth

    ๐Ÿ› - Sebastian Schwarz
    Sebastian Schwarz

    ๐Ÿ› + Sebastian Schwarz
    Sebastian Schwarz

    ๐Ÿ› Seren
    Seren

    ๐Ÿ› ๐Ÿ’ป Sergey Gorbaty
    Sergey Gorbaty

    ๐Ÿ› Sergey Kozlov
    Sergey Kozlov

    ๐Ÿ› Sergey Yanzin
    Sergey Yanzin

    ๐Ÿ’ป ๐Ÿ› Seth Wilcox
    Seth Wilcox

    ๐Ÿ’ป Shai Bennathan
    Shai Bennathan

    ๐Ÿ› ๐Ÿ’ป - Shubham
    Shubham

    ๐Ÿ’ป ๐Ÿ› + Shubham
    Shubham

    ๐Ÿ’ป ๐Ÿ› Simon Abykov
    Simon Abykov

    ๐Ÿ’ป ๐Ÿ› Simon Xiao
    Simon Xiao

    ๐Ÿ› Srinivasan Venkatachalam
    Srinivasan Venkatachalam

    ๐Ÿ› Stanislav Gromov
    Stanislav Gromov

    ๐Ÿ› Stanislav Myachenkov
    Stanislav Myachenkov

    ๐Ÿ’ป Stefan Birkner
    Stefan Birkner

    ๐Ÿ› - Stefan Bohn
    Stefan Bohn

    ๐Ÿ› + Stefan Bohn
    Stefan Bohn

    ๐Ÿ› Stefan Endrullis
    Stefan Endrullis

    ๐Ÿ› Stefan Klรถss-Schuster
    Stefan Klรถss-Schuster

    ๐Ÿ› Stefan Wolf
    Stefan Wolf

    ๐Ÿ› Stephan H. Wissel
    Stephan H. Wissel

    ๐Ÿ› Stephen
    Stephen

    ๐Ÿ› Stephen Carter
    Stephen Carter

    ๐Ÿ› - Stephen Friedrich
    Stephen Friedrich

    ๐Ÿ› + Stephen Friedrich
    Stephen Friedrich

    ๐Ÿ› Steve Babula
    Steve Babula

    ๐Ÿ’ป Steven Stearns
    Steven Stearns

    ๐Ÿ› ๐Ÿ’ป Stexxe
    Stexxe

    ๐Ÿ› Stian Lรฅgstad
    Stian Lรฅgstad

    ๐Ÿ› StuartClayton5
    StuartClayton5

    ๐Ÿ› Supun Arunoda
    Supun Arunoda

    ๐Ÿ› - Suren Abrahamyan
    Suren Abrahamyan

    ๐Ÿ› + Suren Abrahamyan
    Suren Abrahamyan

    ๐Ÿ› Suvashri
    Suvashri

    ๐Ÿ“– SwatiBGupta1110
    SwatiBGupta1110

    ๐Ÿ› SyedThoufich
    SyedThoufich

    ๐Ÿ› Szymon Sasin
    Szymon Sasin

    ๐Ÿ› T-chuangxin
    T-chuangxin

    ๐Ÿ› TERAI Atsuhiro
    TERAI Atsuhiro

    ๐Ÿ› - TIOBE Software
    TIOBE Software

    ๐Ÿ’ป ๐Ÿ› + TIOBE Software
    TIOBE Software

    ๐Ÿ’ป ๐Ÿ› Tarush Singh
    Tarush Singh

    ๐Ÿ’ป Taylor Smock
    Taylor Smock

    ๐Ÿ› Techeira Damiรกn
    Techeira Damiรกn

    ๐Ÿ’ป ๐Ÿ› Ted Husted
    Ted Husted

    ๐Ÿ› TehBakker
    TehBakker

    ๐Ÿ› The Gitter Badger
    The Gitter Badger

    ๐Ÿ› - Theodoor
    Theodoor

    ๐Ÿ› + Theodoor
    Theodoor

    ๐Ÿ› Thiago Henrique Hรผpner
    Thiago Henrique Hรผpner

    ๐Ÿ› Thibault Meyer
    Thibault Meyer

    ๐Ÿ› Thomas Gรผttler
    Thomas Gรผttler

    ๐Ÿ› Thomas Jones-Low
    Thomas Jones-Low

    ๐Ÿ› Thomas Smith
    Thomas Smith

    ๐Ÿ’ป ๐Ÿ› ThrawnCA
    ThrawnCA

    ๐Ÿ› - Thu Vo
    Thu Vo

    ๐Ÿ› + Thu Vo
    Thu Vo

    ๐Ÿ› Thunderforge
    Thunderforge

    ๐Ÿ’ป ๐Ÿ› Tim van der Lippe
    Tim van der Lippe

    ๐Ÿ› Tobias Weimer
    Tobias Weimer

    ๐Ÿ’ป ๐Ÿ› Tom Copeland
    Tom Copeland

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– Tom Daly
    Tom Daly

    ๐Ÿ› Tomas
    Tomas

    ๐Ÿ› - Tomer Figenblat
    Tomer Figenblat

    ๐Ÿ› + Tomer Figenblat
    Tomer Figenblat

    ๐Ÿ› Tomi De Lucca
    Tomi De Lucca

    ๐Ÿ’ป ๐Ÿ› Tony
    Tony

    ๐Ÿ“– Torsten Kleiber
    Torsten Kleiber

    ๐Ÿ› TrackerSB
    TrackerSB

    ๐Ÿ› Tyson Stewart
    Tyson Stewart

    ๐Ÿ› Ullrich Hafner
    Ullrich Hafner

    ๐Ÿ› - Utku Cuhadaroglu
    Utku Cuhadaroglu

    ๐Ÿ’ป ๐Ÿ› + Utku Cuhadaroglu
    Utku Cuhadaroglu

    ๐Ÿ’ป ๐Ÿ› Valentin Brandl
    Valentin Brandl

    ๐Ÿ› Valeria
    Valeria

    ๐Ÿ› Valery Yatsynovich
    Valery Yatsynovich

    ๐Ÿ“– Vasily Anisimov
    Vasily Anisimov

    ๐Ÿ› Vedant Chokshi
    Vedant Chokshi

    ๐Ÿ› Vibhor Goyal
    Vibhor Goyal

    ๐Ÿ› - Vickenty Fesunov
    Vickenty Fesunov

    ๐Ÿ› + Vickenty Fesunov
    Vickenty Fesunov

    ๐Ÿ› Victor Noรซl
    Victor Noรซl

    ๐Ÿ› Vincent Galloy
    Vincent Galloy

    ๐Ÿ’ป Vincent HUYNH
    Vincent HUYNH

    ๐Ÿ› Vincent Maurin
    Vincent Maurin

    ๐Ÿ› Vincent Privat
    Vincent Privat

    ๐Ÿ› Vishhwas
    Vishhwas

    ๐Ÿ› - Vishv_Android
    Vishv_Android

    ๐Ÿ› + Vishv_Android
    Vishv_Android

    ๐Ÿ› Vitaly
    Vitaly

    ๐Ÿ› Vitaly Polonetsky
    Vitaly Polonetsky

    ๐Ÿ› Vojtech Polivka
    Vojtech Polivka

    ๐Ÿ› Vsevolod Zholobov
    Vsevolod Zholobov

    ๐Ÿ› Vyom Yadav
    Vyom Yadav

    ๐Ÿ’ป Wang Shidong
    Wang Shidong

    ๐Ÿ› - Waqas Ahmed
    Waqas Ahmed

    ๐Ÿ› + Waqas Ahmed
    Waqas Ahmed

    ๐Ÿ› Wayne J. Earl
    Wayne J. Earl

    ๐Ÿ› Wchenghui
    Wchenghui

    ๐Ÿ› Wener
    Wener

    ๐Ÿ’ป Will Winder
    Will Winder

    ๐Ÿ› William Brockhus
    William Brockhus

    ๐Ÿ’ป ๐Ÿ› Wilson Kurniawan
    Wilson Kurniawan

    ๐Ÿ› - Wim Deblauwe
    Wim Deblauwe

    ๐Ÿ› + Wim Deblauwe
    Wim Deblauwe

    ๐Ÿ› Woongsik Choi
    Woongsik Choi

    ๐Ÿ› XenoAmess
    XenoAmess

    ๐Ÿ’ป ๐Ÿ› Yang
    Yang

    ๐Ÿ’ป YaroslavTER
    YaroslavTER

    ๐Ÿ› Yasar Shaikh
    Yasar Shaikh

    ๐Ÿ’ป Young Chan
    Young Chan

    ๐Ÿ’ป ๐Ÿ› - YuJin Kim
    YuJin Kim

    ๐Ÿ› + YuJin Kim
    YuJin Kim

    ๐Ÿ› Yuri Dolzhenko
    Yuri Dolzhenko

    ๐Ÿ› Yurii Dubinka
    Yurii Dubinka

    ๐Ÿ› Zoltan Farkas
    Zoltan Farkas

    ๐Ÿ› Zustin
    Zustin

    ๐Ÿ› aaronhurst-google
    aaronhurst-google

    ๐Ÿ› ๐Ÿ’ป alexmodis
    alexmodis

    ๐Ÿ› - andreoss
    andreoss

    ๐Ÿ› + andreoss
    andreoss

    ๐Ÿ› andrey81inmd
    andrey81inmd

    ๐Ÿ’ป ๐Ÿ› anicoara
    anicoara

    ๐Ÿ› arunprasathav
    arunprasathav

    ๐Ÿ› asiercamara
    asiercamara

    ๐Ÿ› astillich-igniti
    astillich-igniti

    ๐Ÿ’ป avesolovksyy
    avesolovksyy

    ๐Ÿ› - avishvat
    avishvat

    ๐Ÿ› + avishvat
    avishvat

    ๐Ÿ› avivmu
    avivmu

    ๐Ÿ› axelbarfod1
    axelbarfod1

    ๐Ÿ› b-3-n
    b-3-n

    ๐Ÿ› balbhadra9
    balbhadra9

    ๐Ÿ› base23de
    base23de

    ๐Ÿ› bergander
    bergander

    ๐Ÿ› ๐Ÿ’ป - berkam
    berkam

    ๐Ÿ’ป ๐Ÿ› + berkam
    berkam

    ๐Ÿ’ป ๐Ÿ› breizh31
    breizh31

    ๐Ÿ› caesarkim
    caesarkim

    ๐Ÿ› carolyujing
    carolyujing

    ๐Ÿ› cbfiddle
    cbfiddle

    ๐Ÿ› cesares-basilico
    cesares-basilico

    ๐Ÿ› chrite
    chrite

    ๐Ÿ› - ciufudean
    ciufudean

    ๐Ÿ“– + ciufudean
    ciufudean

    ๐Ÿ“– cobratbq
    cobratbq

    ๐Ÿ› coladict
    coladict

    ๐Ÿ› cosmoJFH
    cosmoJFH

    ๐Ÿ› cristalp
    cristalp

    ๐Ÿ› crunsk
    crunsk

    ๐Ÿ› cwholmes
    cwholmes

    ๐Ÿ› - cyberjj999
    cyberjj999

    ๐Ÿ› + cyberjj999
    cyberjj999

    ๐Ÿ› cyw3
    cyw3

    ๐Ÿ› ๐Ÿ“– d1ss0nanz
    d1ss0nanz

    ๐Ÿ› dague1
    dague1

    ๐Ÿ“– dalizi007
    dalizi007

    ๐Ÿ’ป danbrycefairsailcom
    danbrycefairsailcom

    ๐Ÿ› dariansanity
    dariansanity

    ๐Ÿ› - darrenmiliband
    darrenmiliband

    ๐Ÿ› + darrenmiliband
    darrenmiliband

    ๐Ÿ› davidburstrom
    davidburstrom

    ๐Ÿ› dbirkman-paloalto
    dbirkman-paloalto

    ๐Ÿ› deepak-patra
    deepak-patra

    ๐Ÿ› dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› dinesh150
    dinesh150

    ๐Ÿ› diziaq
    diziaq

    ๐Ÿ› - dreaminpast123
    dreaminpast123

    ๐Ÿ› + dreaminpast123
    dreaminpast123

    ๐Ÿ› duanyanan
    duanyanan

    ๐Ÿ› dutt-sanjay
    dutt-sanjay

    ๐Ÿ› duursma
    duursma

    ๐Ÿ’ป dylanleung
    dylanleung

    ๐Ÿ› dzeigler
    dzeigler

    ๐Ÿ› eant60
    eant60

    ๐Ÿ› - ekkirala
    ekkirala

    ๐Ÿ› + ekkirala
    ekkirala

    ๐Ÿ› emersonmoura
    emersonmoura

    ๐Ÿ› emouty
    emouty

    ๐Ÿ’ป eugenepugach
    eugenepugach

    ๐Ÿ› fairy
    fairy

    ๐Ÿ› filiprafalowicz
    filiprafalowicz

    ๐Ÿ’ป flxbl-io
    flxbl-io

    ๐Ÿ’ต - foxmason
    foxmason

    ๐Ÿ› + foxmason
    foxmason

    ๐Ÿ› frankegabor
    frankegabor

    ๐Ÿ› frankl
    frankl

    ๐Ÿ› freafrea
    freafrea

    ๐Ÿ› fsapatin
    fsapatin

    ๐Ÿ› gearsethenry
    gearsethenry

    ๐Ÿ› gracia19
    gracia19

    ๐Ÿ› - guo fei
    guo fei

    ๐Ÿ› + guo fei
    guo fei

    ๐Ÿ› gurmsc5
    gurmsc5

    ๐Ÿ› gwilymatgearset
    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ› haigsn
    haigsn

    ๐Ÿ› hemanshu070
    hemanshu070

    ๐Ÿ› henrik242
    henrik242

    ๐Ÿ› hongpuwu
    hongpuwu

    ๐Ÿ› - hvbtup
    hvbtup

    ๐Ÿ’ป ๐Ÿ› + hvbtup
    hvbtup

    ๐Ÿ’ป ๐Ÿ› igniti GmbH
    igniti GmbH

    ๐Ÿ› ilovezfs
    ilovezfs

    ๐Ÿ› imax-erik
    imax-erik

    ๐Ÿ› itaigilo
    itaigilo

    ๐Ÿ› jakivey32
    jakivey32

    ๐Ÿ› jbennett2091
    jbennett2091

    ๐Ÿ› - jcamerin
    jcamerin

    ๐Ÿ› + jcamerin
    jcamerin

    ๐Ÿ› jkeener1
    jkeener1

    ๐Ÿ› jmetertea
    jmetertea

    ๐Ÿ› johnra2
    johnra2

    ๐Ÿ’ป johnzhao9
    johnzhao9

    ๐Ÿ› josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ› kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ› - karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“– + karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“– karwer
    karwer

    ๐Ÿ› kaulonline
    kaulonline

    ๐Ÿ› kdaemonv
    kdaemonv

    ๐Ÿ› kdebski85
    kdebski85

    ๐Ÿ› ๐Ÿ’ป kenji21
    kenji21

    ๐Ÿ’ป ๐Ÿ› kfranic
    kfranic

    ๐Ÿ› - khalidkh
    khalidkh

    ๐Ÿ› + khalidkh
    khalidkh

    ๐Ÿ› koalalam
    koalalam

    ๐Ÿ› krzyk
    krzyk

    ๐Ÿ› lasselindqvist
    lasselindqvist

    ๐Ÿ› lgemeinhardt
    lgemeinhardt

    ๐Ÿ› lihuaib
    lihuaib

    ๐Ÿ› liqingjun123
    liqingjun123

    ๐Ÿ› - lonelyma1021
    lonelyma1021

    ๐Ÿ› + lonelyma1021
    lonelyma1021

    ๐Ÿ› lpeddy
    lpeddy

    ๐Ÿ› lujiefsi
    lujiefsi

    ๐Ÿ’ป lukelukes
    lukelukes

    ๐Ÿ’ป lyriccoder
    lyriccoder

    ๐Ÿ› marcelmore
    marcelmore

    ๐Ÿ› matchbox
    matchbox

    ๐Ÿ› - matthiaskraaz
    matthiaskraaz

    ๐Ÿ› + matthiaskraaz
    matthiaskraaz

    ๐Ÿ› meandonlyme
    meandonlyme

    ๐Ÿ› mikesive
    mikesive

    ๐Ÿ› milossesic
    milossesic

    ๐Ÿ› mluckam
    mluckam

    ๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
    mohan-chinnappan-n

    ๐Ÿ’ป mriddell95
    mriddell95

    ๐Ÿ› - mrlzh
    mrlzh

    ๐Ÿ› + mrlzh
    mrlzh

    ๐Ÿ› msloan
    msloan

    ๐Ÿ› mucharlaravalika
    mucharlaravalika

    ๐Ÿ› mvenneman
    mvenneman

    ๐Ÿ› nareshl119
    nareshl119

    ๐Ÿ› nicolas-harraudeau-sonarsource
    nicolas-harraudeau-sonarsource

    ๐Ÿ› noerremark
    noerremark

    ๐Ÿ› - novsirion
    novsirion

    ๐Ÿ› + novsirion
    novsirion

    ๐Ÿ› nwcm
    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
    oggboy

    ๐Ÿ› oinume
    oinume

    ๐Ÿ› orimarko
    orimarko

    ๐Ÿ’ป ๐Ÿ› pablogomez2197
    pablogomez2197

    ๐Ÿ› pacvz
    pacvz

    ๐Ÿ’ป - pallavi agarwal
    pallavi agarwal

    ๐Ÿ› + pallavi agarwal
    pallavi agarwal

    ๐Ÿ› parksungrin
    parksungrin

    ๐Ÿ› patpatpat123
    patpatpat123

    ๐Ÿ› patriksevallius
    patriksevallius

    ๐Ÿ› pbrajesh1
    pbrajesh1

    ๐Ÿ› phoenix384
    phoenix384

    ๐Ÿ› piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป - plan3d
    plan3d

    ๐Ÿ› + plan3d
    plan3d

    ๐Ÿ› poojasix
    poojasix

    ๐Ÿ› prabhushrikant
    prabhushrikant

    ๐Ÿ› pujitha8783
    pujitha8783

    ๐Ÿ› r-r-a-j
    r-r-a-j

    ๐Ÿ› raghujayjunk
    raghujayjunk

    ๐Ÿ› rajeshveera
    rajeshveera

    ๐Ÿ› - rajeswarreddy88
    rajeswarreddy88

    ๐Ÿ› + rajeswarreddy88
    rajeswarreddy88

    ๐Ÿ› recdevs
    recdevs

    ๐Ÿ› reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ› rijkt
    rijkt

    ๐Ÿ› rillig-tk
    rillig-tk

    ๐Ÿ› rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ› rnveach
    rnveach

    ๐Ÿ› - rxmicro
    rxmicro

    ๐Ÿ› + rxmicro
    rxmicro

    ๐Ÿ› ryan-gustafson
    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ› sabi0
    sabi0

    ๐Ÿ› scais
    scais

    ๐Ÿ› schosin
    schosin

    ๐Ÿ› screamingfrog
    screamingfrog

    ๐Ÿ’ต sebbASF
    sebbASF

    ๐Ÿ› - sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป + sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป shilko2013
    shilko2013

    ๐Ÿ› shiomiyan
    shiomiyan

    ๐Ÿ“– simeonKondr
    simeonKondr

    ๐Ÿ› snajberk
    snajberk

    ๐Ÿ› sniperrifle2004
    sniperrifle2004

    ๐Ÿ› snuyanzin
    snuyanzin

    ๐Ÿ› ๐Ÿ’ป - soloturn
    soloturn

    ๐Ÿ› + soloturn
    soloturn

    ๐Ÿ› soyodream
    soyodream

    ๐Ÿ› sratz
    sratz

    ๐Ÿ› stonio
    stonio

    ๐Ÿ› sturton
    sturton

    ๐Ÿ’ป ๐Ÿ› sudharmohan
    sudharmohan

    ๐Ÿ› suruchidawar
    suruchidawar

    ๐Ÿ› - svenfinitiv
    svenfinitiv

    ๐Ÿ› + svenfinitiv
    svenfinitiv

    ๐Ÿ› szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป tashiscool
    tashiscool

    ๐Ÿ› test-git-hook
    test-git-hook

    ๐Ÿ› testation21
    testation21

    ๐Ÿ’ป ๐Ÿ› thanosa
    thanosa

    ๐Ÿ› tiandiyixian
    tiandiyixian

    ๐Ÿ› - tobwoerk
    tobwoerk

    ๐Ÿ› + tobwoerk
    tobwoerk

    ๐Ÿ› tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป trentchilders
    trentchilders

    ๐Ÿ› triandicAnt
    triandicAnt

    ๐Ÿ› trishul14
    trishul14

    ๐Ÿ› tsui
    tsui

    ๐Ÿ› wangzitom12306
    wangzitom12306

    ๐Ÿ› - winhkey
    winhkey

    ๐Ÿ› + winhkey
    winhkey

    ๐Ÿ› witherspore
    witherspore

    ๐Ÿ› wjljack
    wjljack

    ๐Ÿ› wuchiuwong
    wuchiuwong

    ๐Ÿ› xingsong
    xingsong

    ๐Ÿ› xioayuge
    xioayuge

    ๐Ÿ› xnYi9wRezm
    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ› - xuanuy
    xuanuy

    ๐Ÿ› + xuanuy
    xuanuy

    ๐Ÿ› xyf0921
    xyf0921

    ๐Ÿ› yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› yasuharu-sato
    yasuharu-sato

    ๐Ÿ› zenglian
    zenglian

    ๐Ÿ› zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› zh3ng
    zh3ng

    ๐Ÿ› - zt_soft
    zt_soft

    ๐Ÿ› + zt_soft
    zt_soft

    ๐Ÿ› ztt79
    ztt79

    ๐Ÿ› zzzzfeng
    zzzzfeng

    ๐Ÿ› รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› From fbde9b967f2194975546141a78ffa9df726ea5d3 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Oct 2024 12:35:19 +0200 Subject: [PATCH 0077/1962] [doc] Update release notes (#5261, #5264) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 197b7a4aec8..4b87f9bfae6 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -32,6 +32,7 @@ The old rule names still work but are deprecated. ### ๐Ÿ› Fixed Issues * java * [#4532](https://github.com/pmd/pmd/issues/4532): \[java] Rule misnomer for JUnit* rules + * [#5261](https://github.com/pmd/pmd/issues/5261): \[java] Record patterns with empty deconstructor lists lead to NPE * java-errorprone * [#5067](https://github.com/pmd/pmd/issues/5067): \[java] CloseResource: False positive for FileSystems.getDefault() @@ -49,6 +50,7 @@ The old rule names still work but are deprecated. * [#4965](https://github.com/pmd/pmd/pull/4965): \[java] Rename JUnit rules with overly restrictive names - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) * [#5225](https://github.com/pmd/pmd/pull/5225): \[java] Fix #5067: CloseResource: False positive for FileSystems.getDefault() - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#5241](https://github.com/pmd/pmd/pull/5241): Ignore javacc code in coverage report - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5264](https://github.com/pmd/pmd/pull/5264): \[java] Fix NPE with empty pattern list - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) {% endtocmaker %} From 7655cfc63bb1b7dfdea2298beec0ae30215bb5e5 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Oct 2024 12:35:45 +0200 Subject: [PATCH 0078/1962] Add @gudzpoz as a contributor --- .all-contributorsrc | 9 ++++++ docs/pages/pmd/projectdocs/credits.md | 41 ++++++++++++++------------- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 28d946f30a6..e04c9b717bd 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7819,6 +7819,15 @@ "contributions": [ "bug" ] + }, + { + "login": "gudzpoz", + "name": "gudzpoz", + "avatar_url": "https://avatars.githubusercontent.com/u/14026120?v=4", + "profile": "https://kyo.iroiro.party/", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 4795947746b..04fbc8f37ae 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -930,180 +930,181 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d fsapatin
    fsapatin

    ๐Ÿ› gearsethenry
    gearsethenry

    ๐Ÿ› gracia19
    gracia19

    ๐Ÿ› - guo fei
    guo fei

    ๐Ÿ› + gudzpoz
    gudzpoz

    ๐Ÿ› + guo fei
    guo fei

    ๐Ÿ› gurmsc5
    gurmsc5

    ๐Ÿ› gwilymatgearset
    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ› haigsn
    haigsn

    ๐Ÿ› hemanshu070
    hemanshu070

    ๐Ÿ› henrik242
    henrik242

    ๐Ÿ› hongpuwu
    hongpuwu

    ๐Ÿ› - hvbtup
    hvbtup

    ๐Ÿ’ป ๐Ÿ› + hvbtup
    hvbtup

    ๐Ÿ’ป ๐Ÿ› igniti GmbH
    igniti GmbH

    ๐Ÿ› ilovezfs
    ilovezfs

    ๐Ÿ› imax-erik
    imax-erik

    ๐Ÿ› itaigilo
    itaigilo

    ๐Ÿ› jakivey32
    jakivey32

    ๐Ÿ› jbennett2091
    jbennett2091

    ๐Ÿ› - jcamerin
    jcamerin

    ๐Ÿ› + jcamerin
    jcamerin

    ๐Ÿ› jkeener1
    jkeener1

    ๐Ÿ› jmetertea
    jmetertea

    ๐Ÿ› johnra2
    johnra2

    ๐Ÿ’ป johnzhao9
    johnzhao9

    ๐Ÿ› josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ› kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ› - karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“– + karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“– karwer
    karwer

    ๐Ÿ› kaulonline
    kaulonline

    ๐Ÿ› kdaemonv
    kdaemonv

    ๐Ÿ› kdebski85
    kdebski85

    ๐Ÿ› ๐Ÿ’ป kenji21
    kenji21

    ๐Ÿ’ป ๐Ÿ› kfranic
    kfranic

    ๐Ÿ› - khalidkh
    khalidkh

    ๐Ÿ› + khalidkh
    khalidkh

    ๐Ÿ› koalalam
    koalalam

    ๐Ÿ› krzyk
    krzyk

    ๐Ÿ› lasselindqvist
    lasselindqvist

    ๐Ÿ› lgemeinhardt
    lgemeinhardt

    ๐Ÿ› lihuaib
    lihuaib

    ๐Ÿ› liqingjun123
    liqingjun123

    ๐Ÿ› - lonelyma1021
    lonelyma1021

    ๐Ÿ› + lonelyma1021
    lonelyma1021

    ๐Ÿ› lpeddy
    lpeddy

    ๐Ÿ› lujiefsi
    lujiefsi

    ๐Ÿ’ป lukelukes
    lukelukes

    ๐Ÿ’ป lyriccoder
    lyriccoder

    ๐Ÿ› marcelmore
    marcelmore

    ๐Ÿ› matchbox
    matchbox

    ๐Ÿ› - matthiaskraaz
    matthiaskraaz

    ๐Ÿ› + matthiaskraaz
    matthiaskraaz

    ๐Ÿ› meandonlyme
    meandonlyme

    ๐Ÿ› mikesive
    mikesive

    ๐Ÿ› milossesic
    milossesic

    ๐Ÿ› mluckam
    mluckam

    ๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
    mohan-chinnappan-n

    ๐Ÿ’ป mriddell95
    mriddell95

    ๐Ÿ› - mrlzh
    mrlzh

    ๐Ÿ› + mrlzh
    mrlzh

    ๐Ÿ› msloan
    msloan

    ๐Ÿ› mucharlaravalika
    mucharlaravalika

    ๐Ÿ› mvenneman
    mvenneman

    ๐Ÿ› nareshl119
    nareshl119

    ๐Ÿ› nicolas-harraudeau-sonarsource
    nicolas-harraudeau-sonarsource

    ๐Ÿ› noerremark
    noerremark

    ๐Ÿ› - novsirion
    novsirion

    ๐Ÿ› + novsirion
    novsirion

    ๐Ÿ› nwcm
    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
    oggboy

    ๐Ÿ› oinume
    oinume

    ๐Ÿ› orimarko
    orimarko

    ๐Ÿ’ป ๐Ÿ› pablogomez2197
    pablogomez2197

    ๐Ÿ› pacvz
    pacvz

    ๐Ÿ’ป - pallavi agarwal
    pallavi agarwal

    ๐Ÿ› + pallavi agarwal
    pallavi agarwal

    ๐Ÿ› parksungrin
    parksungrin

    ๐Ÿ› patpatpat123
    patpatpat123

    ๐Ÿ› patriksevallius
    patriksevallius

    ๐Ÿ› pbrajesh1
    pbrajesh1

    ๐Ÿ› phoenix384
    phoenix384

    ๐Ÿ› piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป - plan3d
    plan3d

    ๐Ÿ› + plan3d
    plan3d

    ๐Ÿ› poojasix
    poojasix

    ๐Ÿ› prabhushrikant
    prabhushrikant

    ๐Ÿ› pujitha8783
    pujitha8783

    ๐Ÿ› r-r-a-j
    r-r-a-j

    ๐Ÿ› raghujayjunk
    raghujayjunk

    ๐Ÿ› rajeshveera
    rajeshveera

    ๐Ÿ› - rajeswarreddy88
    rajeswarreddy88

    ๐Ÿ› + rajeswarreddy88
    rajeswarreddy88

    ๐Ÿ› recdevs
    recdevs

    ๐Ÿ› reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ› rijkt
    rijkt

    ๐Ÿ› rillig-tk
    rillig-tk

    ๐Ÿ› rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ› rnveach
    rnveach

    ๐Ÿ› - rxmicro
    rxmicro

    ๐Ÿ› + rxmicro
    rxmicro

    ๐Ÿ› ryan-gustafson
    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ› sabi0
    sabi0

    ๐Ÿ› scais
    scais

    ๐Ÿ› schosin
    schosin

    ๐Ÿ› screamingfrog
    screamingfrog

    ๐Ÿ’ต sebbASF
    sebbASF

    ๐Ÿ› - sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป + sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป shilko2013
    shilko2013

    ๐Ÿ› shiomiyan
    shiomiyan

    ๐Ÿ“– simeonKondr
    simeonKondr

    ๐Ÿ› snajberk
    snajberk

    ๐Ÿ› sniperrifle2004
    sniperrifle2004

    ๐Ÿ› snuyanzin
    snuyanzin

    ๐Ÿ› ๐Ÿ’ป - soloturn
    soloturn

    ๐Ÿ› + soloturn
    soloturn

    ๐Ÿ› soyodream
    soyodream

    ๐Ÿ› sratz
    sratz

    ๐Ÿ› stonio
    stonio

    ๐Ÿ› sturton
    sturton

    ๐Ÿ’ป ๐Ÿ› sudharmohan
    sudharmohan

    ๐Ÿ› suruchidawar
    suruchidawar

    ๐Ÿ› - svenfinitiv
    svenfinitiv

    ๐Ÿ› + svenfinitiv
    svenfinitiv

    ๐Ÿ› szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป tashiscool
    tashiscool

    ๐Ÿ› test-git-hook
    test-git-hook

    ๐Ÿ› testation21
    testation21

    ๐Ÿ’ป ๐Ÿ› thanosa
    thanosa

    ๐Ÿ› tiandiyixian
    tiandiyixian

    ๐Ÿ› - tobwoerk
    tobwoerk

    ๐Ÿ› + tobwoerk
    tobwoerk

    ๐Ÿ› tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป trentchilders
    trentchilders

    ๐Ÿ› triandicAnt
    triandicAnt

    ๐Ÿ› trishul14
    trishul14

    ๐Ÿ› tsui
    tsui

    ๐Ÿ› wangzitom12306
    wangzitom12306

    ๐Ÿ› - winhkey
    winhkey

    ๐Ÿ› + winhkey
    winhkey

    ๐Ÿ› witherspore
    witherspore

    ๐Ÿ› wjljack
    wjljack

    ๐Ÿ› wuchiuwong
    wuchiuwong

    ๐Ÿ› xingsong
    xingsong

    ๐Ÿ› xioayuge
    xioayuge

    ๐Ÿ› xnYi9wRezm
    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ› - xuanuy
    xuanuy

    ๐Ÿ› + xuanuy
    xuanuy

    ๐Ÿ› xyf0921
    xyf0921

    ๐Ÿ› yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› yasuharu-sato
    yasuharu-sato

    ๐Ÿ› zenglian
    zenglian

    ๐Ÿ› zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› zh3ng
    zh3ng

    ๐Ÿ› - zt_soft
    zt_soft

    ๐Ÿ› + zt_soft
    zt_soft

    ๐Ÿ› ztt79
    ztt79

    ๐Ÿ› zzzzfeng
    zzzzfeng

    ๐Ÿ› รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› From 8ac55e7ad706d6095653e5a0e168e5eb4a822411 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Oct 2024 16:42:42 +0200 Subject: [PATCH 0079/1962] Bump org.junit from 5.8.2 to 5.11.2 (#5274) Also update junit-platform from 1.10.2 to 1.11.2 - Supersedes and closes #5260 - Supersedes and closes #5259 --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 8f0474ab59a..9d4e2061ab0 100644 --- a/pom.xml +++ b/pom.xml @@ -94,7 +94,7 @@ ${maven.compiler.test.target} 1.9.24 5.9.1 - 5.8.2 + 5.11.2 1.9.20 5.0 @@ -963,7 +963,7 @@ org.junit.platform junit-platform-suite - 1.10.2 + 1.11.2 test @@ -1092,13 +1092,13 @@ 3.25.5 - org.junit.platform junit-platform-commons - 1.8.2 + 1.11.2 test From ed6312e3baa48e783cd8e0891b0243af13dc1fd4 Mon Sep 17 00:00:00 2001 From: Aryant Tripathi Date: Fri, 11 Oct 2024 22:29:42 +0530 Subject: [PATCH 0080/1962] Support wrapper class in BooleanGetMethodName rule (#5253)\n \n - Updated XPath rule to include both primitive and wrapper class:\n (PrimitiveType[@Kind = 'boolean'] or ClassType[pmd-java:typeIs('java.lang.Boolean')])\n - Added test cases to ensure that methods returning are also flagged correctly.\n - Ensured the rule enforces consistent method naming for both primitive and wrapper types. --- .../codestyle/xml/BooleanGetMethodName.xml | 59 ++++++++++++++++--- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/BooleanGetMethodName.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/BooleanGetMethodName.xml index 648afbf32bd..09e067a2715 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/BooleanGetMethodName.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/BooleanGetMethodName.xml @@ -35,11 +35,13 @@ public class Foo { - Should not match on multiple parameters by default + Should not match for boxed Boolean on multiple parameters by default (#5253) 0 @@ -72,11 +74,13 @@ public class Foo { - Bad name + Bad name with boxed Boolean (#5253) 1 @@ -86,13 +90,15 @@ public class Foo { 0 - Should not match on methods annotated with @Override + Should not match for boxed Boolean on methods annotated with @Override (#5253) 0 - - - Should match on multiple parameters when checkParameterizedMethods = true + Should match for boxed Boolean on multiple parameters when checkParameterizedMethods = true (#5253) true 1 + + Should match for boxed Boolean on multiple parameters when checkParameterizedMethods = true (#5253) + true + 1 + + + + + Custom Boolean type (#5253) + 0 + + + + + Custom Boolean type with returning value (#5253) + 0 + + + From 9077c6a71f14946285aafaaa81d93dff85000d39 Mon Sep 17 00:00:00 2001 From: Aryant Tripathi Date: Fri, 11 Oct 2024 22:34:07 +0530 Subject: [PATCH 0081/1962] Support wrapper class in BooleanGetMethodName rule (#5253)\n \n - Updated XPath rule to include both primitive and wrapper class:\n (PrimitiveType[@Kind = 'boolean'] or ClassType[pmd-java:typeIs('java.lang.Boolean')])\n - Added test cases to ensure that methods returning are also flagged correctly.\n - Ensured the rule enforces consistent method naming for both primitive and wrapper types. --- .../pmd/lang/java/rule/codestyle/xml/BooleanGetMethodName.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/BooleanGetMethodName.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/BooleanGetMethodName.xml index 09e067a2715..6231601d6df 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/BooleanGetMethodName.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/BooleanGetMethodName.xml @@ -86,7 +86,7 @@ public class Foo { - Good name + Good name with boxed Boolean (#5253) 0 Date: Sat, 12 Oct 2024 18:01:21 +0200 Subject: [PATCH 0082/1962] [doc] Update release notes (#5253, #5269) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 4b87f9bfae6..e6c419b789b 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -33,6 +33,8 @@ The old rule names still work but are deprecated. * java * [#4532](https://github.com/pmd/pmd/issues/4532): \[java] Rule misnomer for JUnit* rules * [#5261](https://github.com/pmd/pmd/issues/5261): \[java] Record patterns with empty deconstructor lists lead to NPE +* java-codestyle + * [#5253](https://github.com/pmd/pmd/issues/5253): \[java] BooleanGetMethodName: False-negatives with `Boolean` wrapper * java-errorprone * [#5067](https://github.com/pmd/pmd/issues/5067): \[java] CloseResource: False positive for FileSystems.getDefault() @@ -51,6 +53,7 @@ The old rule names still work but are deprecated. * [#5225](https://github.com/pmd/pmd/pull/5225): \[java] Fix #5067: CloseResource: False positive for FileSystems.getDefault() - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#5241](https://github.com/pmd/pmd/pull/5241): Ignore javacc code in coverage report - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) * [#5264](https://github.com/pmd/pmd/pull/5264): \[java] Fix NPE with empty pattern list - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5269](https://github.com/pmd/pmd/pull/5269): \[java] Fix #5253: Support Boolean wrapper class for BooleanGetMethodName rule - [Aryant Tripathi](https://github.com/Aryant-Tripathi) (@Aryant-Tripathi) {% endtocmaker %} From 47a59b1810d73572108d0e34e89ae8dccc5fbe16 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 12 Oct 2024 18:01:45 +0200 Subject: [PATCH 0083/1962] Add @phansys as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 167 +++++++++++++------------- 2 files changed, 93 insertions(+), 83 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index e04c9b717bd..24f01443b12 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7828,6 +7828,15 @@ "contributions": [ "bug" ] + }, + { + "login": "phansys", + "name": "Javier Spagnoletti", + "avatar_url": "https://avatars.githubusercontent.com/u/1231441?v=4", + "profile": "https://github.com/phansys", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 04fbc8f37ae..2ea476a44a8 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -359,751 +359,752 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Jason Qiu
    Jason Qiu

    ๐Ÿ’ป ๐Ÿ“– Jason Williams
    Jason Williams

    ๐Ÿ› + Javier Spagnoletti
    Javier Spagnoletti

    ๐Ÿ› Jean-Paul Mayer
    Jean-Paul Mayer

    ๐Ÿ› Jean-Simon Larochelle
    Jean-Simon Larochelle

    ๐Ÿ› Jeff Bartolotta
    Jeff Bartolotta

    ๐Ÿ’ป ๐Ÿ› Jeff Hube
    Jeff Hube

    ๐Ÿ’ป ๐Ÿ› - Jeff Jensen
    Jeff Jensen

    ๐Ÿ› + Jeff Jensen
    Jeff Jensen

    ๐Ÿ› Jeff May
    Jeff May

    ๐Ÿ› Jens Gerdes
    Jens Gerdes

    ๐Ÿ› Jeroen Borgers
    Jeroen Borgers

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข Jeroen Meijer
    Jeroen Meijer

    ๐Ÿ› Jeroen van Wilgenburg
    Jeroen van Wilgenburg

    ๐Ÿ“– Jerome Russ
    Jerome Russ

    ๐Ÿ› - JerritEic
    JerritEic

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› + JerritEic
    JerritEic

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Jiri Pejchal
    Jiri Pejchal

    ๐Ÿ› Jithin Sunny
    Jithin Sunny

    ๐Ÿ› Jiล™รญ ล korpil
    Jiล™รญ ล korpil

    ๐Ÿ› Joao Machado
    Joao Machado

    ๐Ÿ› Jochen Krauss
    Jochen Krauss

    ๐Ÿ› Johan Hammar
    Johan Hammar

    ๐Ÿ› - John Karp
    John Karp

    ๐Ÿ› + John Karp
    John Karp

    ๐Ÿ› John Zhang
    John Zhang

    ๐Ÿ› John-Teng
    John-Teng

    ๐Ÿ’ป ๐Ÿ› Jon Moroney
    Jon Moroney

    ๐Ÿ’ป ๐Ÿ› Jonas Geiregat
    Jonas Geiregat

    ๐Ÿ› Jonas KeรŸler
    Jonas KeรŸler

    ๐Ÿ› Jonathan Wiesel
    Jonathan Wiesel

    ๐Ÿ’ป ๐Ÿ› - Jordan
    Jordan

    ๐Ÿ› + Jordan
    Jordan

    ๐Ÿ› Jordi Llach
    Jordi Llach

    ๐Ÿ› Jorge Solรณrzano
    Jorge Solรณrzano

    ๐Ÿ› JorneVL
    JorneVL

    ๐Ÿ› Jose Palafox
    Jose Palafox

    ๐Ÿ› Jose Stovall
    Jose Stovall

    ๐Ÿ› Joseph
    Joseph

    ๐Ÿ’ป - Joseph Heenan
    Joseph Heenan

    ๐Ÿ› + Joseph Heenan
    Joseph Heenan

    ๐Ÿ› Josh Feingold
    Josh Feingold

    ๐Ÿ’ป ๐Ÿ› Josh Holthaus
    Josh Holthaus

    ๐Ÿ› Joshua S Arquilevich
    Joshua S Arquilevich

    ๐Ÿ› Joรฃo Dinis Ferreira
    Joรฃo Dinis Ferreira

    ๐Ÿ“– Joรฃo Ferreira
    Joรฃo Ferreira

    ๐Ÿ’ป ๐Ÿ› Joรฃo Pedro Schmitt
    Joรฃo Pedro Schmitt

    ๐Ÿ› - Juan Martรญn Sotuyo Dodero
    Juan Martรญn Sotuyo Dodero

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง + Juan Martรญn Sotuyo Dodero
    Juan Martรญn Sotuyo Dodero

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง Juan Pablo Civile
    Juan Pablo Civile

    ๐Ÿ› Julian Voronetsky
    Julian Voronetsky

    ๐Ÿ› Julien
    Julien

    ๐Ÿ› Julius
    Julius

    ๐Ÿ› JustPRV
    JustPRV

    ๐Ÿ› Justin Stroud
    Justin Stroud

    ๐Ÿ’ป - Jรถrn Huxhorn
    Jรถrn Huxhorn

    ๐Ÿ› + Jรถrn Huxhorn
    Jรถrn Huxhorn

    ๐Ÿ› KThompso
    KThompso

    ๐Ÿ› Kai Amundsen
    Kai Amundsen

    ๐Ÿ› Karel Vervaeke
    Karel Vervaeke

    ๐Ÿ› Karl-Andero Mere
    Karl-Andero Mere

    ๐Ÿ› Karl-Philipp Richter
    Karl-Philipp Richter

    ๐Ÿ› Karsten Silz
    Karsten Silz

    ๐Ÿ› - Kazuma Watanabe
    Kazuma Watanabe

    ๐Ÿ› + Kazuma Watanabe
    Kazuma Watanabe

    ๐Ÿ› Kev
    Kev

    ๐Ÿ› Keve Mรผller
    Keve Mรผller

    ๐Ÿ› Kevin Guerra
    Kevin Guerra

    ๐Ÿ’ป Kevin Jones
    Kevin Jones

    ๐Ÿ› ๐Ÿ’ป Kevin Poorman
    Kevin Poorman

    ๐Ÿ› Kevin Wayne
    Kevin Wayne

    ๐Ÿ› - Kieran Black
    Kieran Black

    ๐Ÿ› + Kieran Black
    Kieran Black

    ๐Ÿ› Kirill Zubov
    Kirill Zubov

    ๐Ÿ› Kirk Clemens
    Kirk Clemens

    ๐Ÿ’ป ๐Ÿ› Klaus Hartl
    Klaus Hartl

    ๐Ÿ› Koen Van Looveren
    Koen Van Looveren

    ๐Ÿ› Kris Scheibe
    Kris Scheibe

    ๐Ÿ’ป ๐Ÿ› Krystian Dabrowski
    Krystian Dabrowski

    ๐Ÿ› ๐Ÿ’ป - Kunal Thanki
    Kunal Thanki

    ๐Ÿ› + Kunal Thanki
    Kunal Thanki

    ๐Ÿ› LaLucid
    LaLucid

    ๐Ÿ’ป Larry Diamond
    Larry Diamond

    ๐Ÿ’ป ๐Ÿ› Lars Knickrehm
    Lars Knickrehm

    ๐Ÿ› Laurent Bovet
    Laurent Bovet

    ๐Ÿ› ๐Ÿ’ป Leo Gutierrez
    Leo Gutierrez

    ๐Ÿ› LiGaOg
    LiGaOg

    ๐Ÿ’ป - Liam Sharp
    Liam Sharp

    ๐Ÿ› + Liam Sharp
    Liam Sharp

    ๐Ÿ› Lintsi
    Lintsi

    ๐Ÿ› Linus Fernandes
    Linus Fernandes

    ๐Ÿ› Lixon Lookose
    Lixon Lookose

    ๐Ÿ› Logesh
    Logesh

    ๐Ÿ› Lorenzo Gabriele
    Lorenzo Gabriele

    ๐Ÿ› Loรฏc Ledoyen
    Loรฏc Ledoyen

    ๐Ÿ› - Lucas
    Lucas

    ๐Ÿ› + Lucas
    Lucas

    ๐Ÿ› Lucas Silva
    Lucas Silva

    ๐Ÿ› Lucas Soncini
    Lucas Soncini

    ๐Ÿ’ป ๐Ÿ› Luis Alcantar
    Luis Alcantar

    ๐Ÿ’ป Lukas Grรคf
    Lukas Grรคf

    ๐Ÿ’ป Lukasz Slonina
    Lukasz Slonina

    ๐Ÿ› Lukebray
    Lukebray

    ๐Ÿ› - Lynn
    Lynn

    ๐Ÿ’ป ๐Ÿ› + Lynn
    Lynn

    ๐Ÿ’ป ๐Ÿ› Lyor Goldstein
    Lyor Goldstein

    ๐Ÿ› MCMicS
    MCMicS

    ๐Ÿ› Macarse
    Macarse

    ๐Ÿ› Machine account for PMD
    Machine account for PMD

    ๐Ÿ’ป Maciek Siemczyk
    Maciek Siemczyk

    ๐Ÿ› Maikel Steneker
    Maikel Steneker

    ๐Ÿ’ป ๐Ÿ› - Maksim Moiseikin
    Maksim Moiseikin

    ๐Ÿ› + Maksim Moiseikin
    Maksim Moiseikin

    ๐Ÿ› Manfred Koch
    Manfred Koch

    ๐Ÿ› Manuel Moya Ferrer
    Manuel Moya Ferrer

    ๐Ÿ’ป ๐Ÿ› Manuel Ryan
    Manuel Ryan

    ๐Ÿ› Marat Vyshegorodtsev
    Marat Vyshegorodtsev

    ๐Ÿ› Marcel Hรคrle
    Marcel Hรคrle

    ๐Ÿ› Marcello Fialho
    Marcello Fialho

    ๐Ÿ› - Marcin Dฤ…browski
    Marcin Dฤ…browski

    ๐Ÿ’ป + Marcin Dฤ…browski
    Marcin Dฤ…browski

    ๐Ÿ’ป Marcin Rataj
    Marcin Rataj

    ๐Ÿ› Marcono1234
    Marcono1234

    ๐Ÿ› Mark Adamcin
    Mark Adamcin

    ๐Ÿ› Mark Hall
    Mark Hall

    ๐Ÿ’ป ๐Ÿ› Mark Kolich
    Mark Kolich

    ๐Ÿ› Mark Pritchard
    Mark Pritchard

    ๐Ÿ› - Markus Rathgeb
    Markus Rathgeb

    ๐Ÿ› + Markus Rathgeb
    Markus Rathgeb

    ๐Ÿ› Marquis Wang
    Marquis Wang

    ๐Ÿ› MartGit
    MartGit

    ๐Ÿ› Martin Feldsztejn
    Martin Feldsztejn

    ๐Ÿ› Martin Lehmann
    Martin Lehmann

    ๐Ÿ› Martin Spamer
    Martin Spamer

    ๐Ÿ› Martin Tarjรกnyi
    Martin Tarjรกnyi

    ๐Ÿ› - MatFl
    MatFl

    ๐Ÿ› + MatFl
    MatFl

    ๐Ÿ› Mateusz Stefanski
    Mateusz Stefanski

    ๐Ÿ› Mathieu Gouin
    Mathieu Gouin

    ๐Ÿ› MatiasComercio
    MatiasComercio

    ๐Ÿ’ป ๐Ÿ› Matt Benson
    Matt Benson

    ๐Ÿ› Matt De Poorter
    Matt De Poorter

    ๐Ÿ› Matt Hargett
    Matt Hargett

    ๐Ÿ’ป ๐Ÿ’ต - Matt Harrah
    Matt Harrah

    ๐Ÿ› + Matt Harrah
    Matt Harrah

    ๐Ÿ› Matt Nelson
    Matt Nelson

    ๐Ÿ› Matthew Amos
    Matthew Amos

    ๐Ÿ› Matthew Duggan
    Matthew Duggan

    ๐Ÿ› Matthew Hall
    Matthew Hall

    ๐Ÿ› Matthew Rossner
    Matthew Rossner

    ๐Ÿ› Matรญas Fraga
    Matรญas Fraga

    ๐Ÿ’ป ๐Ÿ› - Maxime Robert
    Maxime Robert

    ๐Ÿ’ป ๐Ÿ› + Maxime Robert
    Maxime Robert

    ๐Ÿ’ป ๐Ÿ› MetaBF
    MetaBF

    ๐Ÿ› Metin Dagcilar
    Metin Dagcilar

    ๐Ÿ› Michael
    Michael

    ๐Ÿ› Michael Bell
    Michael Bell

    ๐Ÿ› Michael Bernstein
    Michael Bernstein

    ๐Ÿ› Michael Clay
    Michael Clay

    ๐Ÿ› - Michael Dombrowski
    Michael Dombrowski

    ๐Ÿ› + Michael Dombrowski
    Michael Dombrowski

    ๐Ÿ› Michael Hausegger
    Michael Hausegger

    ๐Ÿ› Michael Hoefer
    Michael Hoefer

    ๐Ÿ› Michael Kolesnikov
    Michael Kolesnikov

    ๐Ÿ› Michael Mรถbius
    Michael Mรถbius

    ๐Ÿ› Michael N. Lipp
    Michael N. Lipp

    ๐Ÿ› Michael Pellegrini
    Michael Pellegrini

    ๐Ÿ› - Michal Kordas
    Michal Kordas

    ๐Ÿ› + Michal Kordas
    Michal Kordas

    ๐Ÿ› Michaล‚ Borek
    Michaล‚ Borek

    ๐Ÿ› Michaล‚ Kuliล„ski
    Michaล‚ Kuliล„ski

    ๐Ÿ› Miguel Nรบรฑez Dรญaz-Montes
    Miguel Nรบรฑez Dรญaz-Montes

    ๐Ÿ› Mihai Ionut
    Mihai Ionut

    ๐Ÿ› Mikhail Kuchma
    Mikhail Kuchma

    ๐Ÿ› Mirek Hankus
    Mirek Hankus

    ๐Ÿ› - Mitch Spano
    Mitch Spano

    ๐Ÿ› + Mitch Spano
    Mitch Spano

    ๐Ÿ› Mladjan Gadzic
    Mladjan Gadzic

    ๐Ÿ› MrAngry52
    MrAngry52

    ๐Ÿ› Muminur Choudhury
    Muminur Choudhury

    ๐Ÿ› Mykhailo Palahuta
    Mykhailo Palahuta

    ๐Ÿ’ป ๐Ÿ› Nagendra Kumar Singh
    Nagendra Kumar Singh

    ๐Ÿ› Nahuel Barrios
    Nahuel Barrios

    ๐Ÿ› - Nakul Sharma
    Nakul Sharma

    ๐Ÿ› + Nakul Sharma
    Nakul Sharma

    ๐Ÿ› Nathan Braun
    Nathan Braun

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› Nathanaรซl
    Nathanaรซl

    ๐Ÿ› Naveen
    Naveen

    ๐Ÿ’ป Nazdravi
    Nazdravi

    ๐Ÿ› - Neha-Dhonde
    Neha-Dhonde

    ๐Ÿ› + Neha-Dhonde
    Neha-Dhonde

    ๐Ÿ› Nicholas Doyle
    Nicholas Doyle

    ๐Ÿ› Nick Butcher
    Nick Butcher

    ๐Ÿ› Nico Gallinal
    Nico Gallinal

    ๐Ÿ› Nicola Dal Maso
    Nicola Dal Maso

    ๐Ÿ› Nicolas Filotto
    Nicolas Filotto

    ๐Ÿ’ป Nicolas Vervelle
    Nicolas Vervelle

    ๐Ÿ› - Nicolas Vuillamy
    Nicolas Vuillamy

    ๐Ÿ“– + Nicolas Vuillamy
    Nicolas Vuillamy

    ๐Ÿ“– Nikita Chursin
    Nikita Chursin

    ๐Ÿ› Niklas Baudy
    Niklas Baudy

    ๐Ÿ› Nikolas Havrikov
    Nikolas Havrikov

    ๐Ÿ› Nilesh Virkar
    Nilesh Virkar

    ๐Ÿ› Nimit Patel
    Nimit Patel

    ๐Ÿ› Niranjan Harpale
    Niranjan Harpale

    ๐Ÿ› - Nirvik Patel
    Nirvik Patel

    ๐Ÿ’ป + Nirvik Patel
    Nirvik Patel

    ๐Ÿ’ป Noah Sussman
    Noah Sussman

    ๐Ÿ› Noah0120
    Noah0120

    ๐Ÿ› Noam Tamim
    Noam Tamim

    ๐Ÿ› Noel Grandin
    Noel Grandin

    ๐Ÿ› Olaf Haalstra
    Olaf Haalstra

    ๐Ÿ› Oleg Andreych
    Oleg Andreych

    ๐Ÿ’ป ๐Ÿ› - Oleg Pavlenko
    Oleg Pavlenko

    ๐Ÿ› + Oleg Pavlenko
    Oleg Pavlenko

    ๐Ÿ› Oleksii Dykov
    Oleksii Dykov

    ๐Ÿ’ป ๐Ÿ› Oliver Eikemeier
    Oliver Eikemeier

    ๐Ÿ› Oliver Siegmar
    Oliver Siegmar

    ๐Ÿ’ต Olivier Parent
    Olivier Parent

    ๐Ÿ’ป ๐Ÿ› Ollie Abbey
    Ollie Abbey

    ๐Ÿ’ป ๐Ÿ› Ondrej Kratochvil
    Ondrej Kratochvil

    ๐Ÿ› - OverDrone
    OverDrone

    ๐Ÿ› + OverDrone
    OverDrone

    ๐Ÿ› Ozan Gulle
    Ozan Gulle

    ๐Ÿ’ป ๐Ÿ› PUNEET JAIN
    PUNEET JAIN

    ๐Ÿ› Parbati Bose
    Parbati Bose

    ๐Ÿ› Paul Berg
    Paul Berg

    ๐Ÿ› Paul Guyot
    Paul Guyot

    ๐Ÿ’ป Pavel Bludov
    Pavel Bludov

    ๐Ÿ› - Pavel Miฤka
    Pavel Miฤka

    ๐Ÿ› + Pavel Miฤka
    Pavel Miฤka

    ๐Ÿ› Pedro Nuno Santos
    Pedro Nuno Santos

    ๐Ÿ› Pedro Rijo
    Pedro Rijo

    ๐Ÿ› Pelisse Romain
    Pelisse Romain

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Per Abich
    Per Abich

    ๐Ÿ’ป Pete Davids
    Pete Davids

    ๐Ÿ› Peter Bruin
    Peter Bruin

    ๐Ÿ› - Peter Chittum
    Peter Chittum

    ๐Ÿ’ป ๐Ÿ› + Peter Chittum
    Peter Chittum

    ๐Ÿ’ป ๐Ÿ› Peter Cudmore
    Peter Cudmore

    ๐Ÿ› Peter Kasson
    Peter Kasson

    ๐Ÿ› Peter Kofler
    Peter Kofler

    ๐Ÿ› Peter Paul Bakker
    Peter Paul Bakker

    ๐Ÿ’ป Peter Rader
    Peter Rader

    ๐Ÿ› Pham Hai Trung
    Pham Hai Trung

    ๐Ÿ› - Philip Graf
    Philip Graf

    ๐Ÿ’ป ๐Ÿ› + Philip Graf
    Philip Graf

    ๐Ÿ’ป ๐Ÿ› Philip Hachey
    Philip Hachey

    ๐Ÿ› Philippe Ozil
    Philippe Ozil

    ๐Ÿ› Phinehas Artemix
    Phinehas Artemix

    ๐Ÿ› Phokham Nonava
    Phokham Nonava

    ๐Ÿ› Pim van der Loos
    Pim van der Loos

    ๐Ÿ’ป โš ๏ธ Piotr Szymaล„ski
    Piotr Szymaล„ski

    ๐Ÿ› - Piotrek ลปygieล‚o
    Piotrek ลปygieล‚o

    ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– + Piotrek ลปygieล‚o
    Piotrek ลปygieล‚o

    ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– Pranay Jaiswal
    Pranay Jaiswal

    ๐Ÿ› Prasad Kamath
    Prasad Kamath

    ๐Ÿ› Prasanna
    Prasanna

    ๐Ÿ› Presh-AR
    Presh-AR

    ๐Ÿ› Puneet1726
    Puneet1726

    ๐Ÿ› RBRi
    RBRi

    ๐Ÿ› - Rafael Cortรชs
    Rafael Cortรชs

    ๐Ÿ› + Rafael Cortรชs
    Rafael Cortรชs

    ๐Ÿ› RaheemShaik999
    RaheemShaik999

    ๐Ÿ› RajeshR
    RajeshR

    ๐Ÿ’ป ๐Ÿ› Ramachandra Mohan
    Ramachandra Mohan

    ๐Ÿ› Ramel0921
    Ramel0921

    ๐Ÿ› Raquel Pau
    Raquel Pau

    ๐Ÿ› Ravikiran Janardhana
    Ravikiran Janardhana

    ๐Ÿ› - Reda Benhemmouche
    Reda Benhemmouche

    ๐Ÿ› + Reda Benhemmouche
    Reda Benhemmouche

    ๐Ÿ› Reinhard Schiedermeier
    Reinhard Schiedermeier

    ๐Ÿ› Renato Oliveira
    Renato Oliveira

    ๐Ÿ’ป ๐Ÿ› Rich DiCroce
    Rich DiCroce

    ๐Ÿ› Richard Corfield
    Richard Corfield

    ๐Ÿ’ป Richard Corfield
    Richard Corfield

    ๐Ÿ› ๐Ÿ’ป Riot R1cket
    Riot R1cket

    ๐Ÿ› - Rishabh Jain
    Rishabh Jain

    ๐Ÿ› + Rishabh Jain
    Rishabh Jain

    ๐Ÿ› RishabhDeep Singh
    RishabhDeep Singh

    ๐Ÿ› Rob Baillie
    Rob Baillie

    ๐Ÿ› Robbie Martinus
    Robbie Martinus

    ๐Ÿ’ป ๐Ÿ› Robert Henry
    Robert Henry

    ๐Ÿ› Robert Mihaly
    Robert Mihaly

    ๐Ÿ› Robert Painsi
    Robert Painsi

    ๐Ÿ› - Robert Russell
    Robert Russell

    ๐Ÿ› + Robert Russell
    Robert Russell

    ๐Ÿ› Robert Sรถsemann
    Robert Sรถsemann

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ› Robert Whitebit
    Robert Whitebit

    ๐Ÿ› Robin Richtsfeld
    Robin Richtsfeld

    ๐Ÿ› Robin Stocker
    Robin Stocker

    ๐Ÿ’ป ๐Ÿ› Robin Wils
    Robin Wils

    ๐Ÿ› RochusOest
    RochusOest

    ๐Ÿ› - Rodolfo Noviski
    Rodolfo Noviski

    ๐Ÿ› + Rodolfo Noviski
    Rodolfo Noviski

    ๐Ÿ› Rodrigo Casara
    Rodrigo Casara

    ๐Ÿ› Rodrigo Fernandes
    Rodrigo Fernandes

    ๐Ÿ› Roman Salvador
    Roman Salvador

    ๐Ÿ’ป ๐Ÿ› Ronald Blaschke
    Ronald Blaschke

    ๐Ÿ› Rรณbert Papp
    Rรณbert Papp

    ๐Ÿ› Saikat Sengupta
    Saikat Sengupta

    ๐Ÿ› - Saksham Handu
    Saksham Handu

    ๐Ÿ› + Saksham Handu
    Saksham Handu

    ๐Ÿ› Saladoc
    Saladoc

    ๐Ÿ› Salesforce Bob Lightning
    Salesforce Bob Lightning

    ๐Ÿ› Sam Carlberg
    Sam Carlberg

    ๐Ÿ› Sascha Riemer
    Sascha Riemer

    ๐Ÿ› Sashko
    Sashko

    ๐Ÿ’ป Satoshi Kubo
    Satoshi Kubo

    ๐Ÿ› - Scott Kennedy
    Scott Kennedy

    ๐Ÿ› + Scott Kennedy
    Scott Kennedy

    ๐Ÿ› Scott Wells
    Scott Wells

    ๐Ÿ› ๐Ÿ’ป Scrates1
    Scrates1

    ๐Ÿ› ๐Ÿ’ป Scrsloota
    Scrsloota

    ๐Ÿ’ป Sebastian Bรถgl
    Sebastian Bรถgl

    ๐Ÿ› Sebastian Davids
    Sebastian Davids

    ๐Ÿ› Sebastian Schuberth
    Sebastian Schuberth

    ๐Ÿ› - Sebastian Schwarz
    Sebastian Schwarz

    ๐Ÿ› + Sebastian Schwarz
    Sebastian Schwarz

    ๐Ÿ› Seren
    Seren

    ๐Ÿ› ๐Ÿ’ป Sergey Gorbaty
    Sergey Gorbaty

    ๐Ÿ› Sergey Kozlov
    Sergey Kozlov

    ๐Ÿ› Sergey Yanzin
    Sergey Yanzin

    ๐Ÿ’ป ๐Ÿ› Seth Wilcox
    Seth Wilcox

    ๐Ÿ’ป Shai Bennathan
    Shai Bennathan

    ๐Ÿ› ๐Ÿ’ป - Shubham
    Shubham

    ๐Ÿ’ป ๐Ÿ› + Shubham
    Shubham

    ๐Ÿ’ป ๐Ÿ› Simon Abykov
    Simon Abykov

    ๐Ÿ’ป ๐Ÿ› Simon Xiao
    Simon Xiao

    ๐Ÿ› Srinivasan Venkatachalam
    Srinivasan Venkatachalam

    ๐Ÿ› Stanislav Gromov
    Stanislav Gromov

    ๐Ÿ› Stanislav Myachenkov
    Stanislav Myachenkov

    ๐Ÿ’ป Stefan Birkner
    Stefan Birkner

    ๐Ÿ› - Stefan Bohn
    Stefan Bohn

    ๐Ÿ› + Stefan Bohn
    Stefan Bohn

    ๐Ÿ› Stefan Endrullis
    Stefan Endrullis

    ๐Ÿ› Stefan Klรถss-Schuster
    Stefan Klรถss-Schuster

    ๐Ÿ› Stefan Wolf
    Stefan Wolf

    ๐Ÿ› Stephan H. Wissel
    Stephan H. Wissel

    ๐Ÿ› Stephen
    Stephen

    ๐Ÿ› Stephen Carter
    Stephen Carter

    ๐Ÿ› - Stephen Friedrich
    Stephen Friedrich

    ๐Ÿ› + Stephen Friedrich
    Stephen Friedrich

    ๐Ÿ› Steve Babula
    Steve Babula

    ๐Ÿ’ป Steven Stearns
    Steven Stearns

    ๐Ÿ› ๐Ÿ’ป Stexxe
    Stexxe

    ๐Ÿ› Stian Lรฅgstad
    Stian Lรฅgstad

    ๐Ÿ› StuartClayton5
    StuartClayton5

    ๐Ÿ› Supun Arunoda
    Supun Arunoda

    ๐Ÿ› - Suren Abrahamyan
    Suren Abrahamyan

    ๐Ÿ› + Suren Abrahamyan
    Suren Abrahamyan

    ๐Ÿ› Suvashri
    Suvashri

    ๐Ÿ“– SwatiBGupta1110
    SwatiBGupta1110

    ๐Ÿ› SyedThoufich
    SyedThoufich

    ๐Ÿ› Szymon Sasin
    Szymon Sasin

    ๐Ÿ› T-chuangxin
    T-chuangxin

    ๐Ÿ› TERAI Atsuhiro
    TERAI Atsuhiro

    ๐Ÿ› - TIOBE Software
    TIOBE Software

    ๐Ÿ’ป ๐Ÿ› + TIOBE Software
    TIOBE Software

    ๐Ÿ’ป ๐Ÿ› Tarush Singh
    Tarush Singh

    ๐Ÿ’ป Taylor Smock
    Taylor Smock

    ๐Ÿ› Techeira Damiรกn
    Techeira Damiรกn

    ๐Ÿ’ป ๐Ÿ› Ted Husted
    Ted Husted

    ๐Ÿ› TehBakker
    TehBakker

    ๐Ÿ› The Gitter Badger
    The Gitter Badger

    ๐Ÿ› - Theodoor
    Theodoor

    ๐Ÿ› + Theodoor
    Theodoor

    ๐Ÿ› Thiago Henrique Hรผpner
    Thiago Henrique Hรผpner

    ๐Ÿ› Thibault Meyer
    Thibault Meyer

    ๐Ÿ› Thomas Gรผttler
    Thomas Gรผttler

    ๐Ÿ› Thomas Jones-Low
    Thomas Jones-Low

    ๐Ÿ› Thomas Smith
    Thomas Smith

    ๐Ÿ’ป ๐Ÿ› ThrawnCA
    ThrawnCA

    ๐Ÿ› - Thu Vo
    Thu Vo

    ๐Ÿ› + Thu Vo
    Thu Vo

    ๐Ÿ› Thunderforge
    Thunderforge

    ๐Ÿ’ป ๐Ÿ› Tim van der Lippe
    Tim van der Lippe

    ๐Ÿ› Tobias Weimer
    Tobias Weimer

    ๐Ÿ’ป ๐Ÿ› Tom Copeland
    Tom Copeland

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– Tom Daly
    Tom Daly

    ๐Ÿ› Tomas
    Tomas

    ๐Ÿ› - Tomer Figenblat
    Tomer Figenblat

    ๐Ÿ› + Tomer Figenblat
    Tomer Figenblat

    ๐Ÿ› Tomi De Lucca
    Tomi De Lucca

    ๐Ÿ’ป ๐Ÿ› Tony
    Tony

    ๐Ÿ“– Torsten Kleiber
    Torsten Kleiber

    ๐Ÿ› TrackerSB
    TrackerSB

    ๐Ÿ› Tyson Stewart
    Tyson Stewart

    ๐Ÿ› Ullrich Hafner
    Ullrich Hafner

    ๐Ÿ› - Utku Cuhadaroglu
    Utku Cuhadaroglu

    ๐Ÿ’ป ๐Ÿ› + Utku Cuhadaroglu
    Utku Cuhadaroglu

    ๐Ÿ’ป ๐Ÿ› Valentin Brandl
    Valentin Brandl

    ๐Ÿ› Valeria
    Valeria

    ๐Ÿ› Valery Yatsynovich
    Valery Yatsynovich

    ๐Ÿ“– Vasily Anisimov
    Vasily Anisimov

    ๐Ÿ› Vedant Chokshi
    Vedant Chokshi

    ๐Ÿ› Vibhor Goyal
    Vibhor Goyal

    ๐Ÿ› - Vickenty Fesunov
    Vickenty Fesunov

    ๐Ÿ› + Vickenty Fesunov
    Vickenty Fesunov

    ๐Ÿ› Victor Noรซl
    Victor Noรซl

    ๐Ÿ› Vincent Galloy
    Vincent Galloy

    ๐Ÿ’ป Vincent HUYNH
    Vincent HUYNH

    ๐Ÿ› Vincent Maurin
    Vincent Maurin

    ๐Ÿ› Vincent Privat
    Vincent Privat

    ๐Ÿ› Vishhwas
    Vishhwas

    ๐Ÿ› - Vishv_Android
    Vishv_Android

    ๐Ÿ› + Vishv_Android
    Vishv_Android

    ๐Ÿ› Vitaly
    Vitaly

    ๐Ÿ› Vitaly Polonetsky
    Vitaly Polonetsky

    ๐Ÿ› Vojtech Polivka
    Vojtech Polivka

    ๐Ÿ› Vsevolod Zholobov
    Vsevolod Zholobov

    ๐Ÿ› Vyom Yadav
    Vyom Yadav

    ๐Ÿ’ป Wang Shidong
    Wang Shidong

    ๐Ÿ› - Waqas Ahmed
    Waqas Ahmed

    ๐Ÿ› + Waqas Ahmed
    Waqas Ahmed

    ๐Ÿ› Wayne J. Earl
    Wayne J. Earl

    ๐Ÿ› Wchenghui
    Wchenghui

    ๐Ÿ› Wener
    Wener

    ๐Ÿ’ป Will Winder
    Will Winder

    ๐Ÿ› William Brockhus
    William Brockhus

    ๐Ÿ’ป ๐Ÿ› Wilson Kurniawan
    Wilson Kurniawan

    ๐Ÿ› - Wim Deblauwe
    Wim Deblauwe

    ๐Ÿ› + Wim Deblauwe
    Wim Deblauwe

    ๐Ÿ› Woongsik Choi
    Woongsik Choi

    ๐Ÿ› XenoAmess
    XenoAmess

    ๐Ÿ’ป ๐Ÿ› Yang
    Yang

    ๐Ÿ’ป YaroslavTER
    YaroslavTER

    ๐Ÿ› Yasar Shaikh
    Yasar Shaikh

    ๐Ÿ’ป Young Chan
    Young Chan

    ๐Ÿ’ป ๐Ÿ› - YuJin Kim
    YuJin Kim

    ๐Ÿ› + YuJin Kim
    YuJin Kim

    ๐Ÿ› Yuri Dolzhenko
    Yuri Dolzhenko

    ๐Ÿ› Yurii Dubinka
    Yurii Dubinka

    ๐Ÿ› Zoltan Farkas
    Zoltan Farkas

    ๐Ÿ› Zustin
    Zustin

    ๐Ÿ› aaronhurst-google
    aaronhurst-google

    ๐Ÿ› ๐Ÿ’ป alexmodis
    alexmodis

    ๐Ÿ› - andreoss
    andreoss

    ๐Ÿ› + andreoss
    andreoss

    ๐Ÿ› andrey81inmd
    andrey81inmd

    ๐Ÿ’ป ๐Ÿ› anicoara
    anicoara

    ๐Ÿ› arunprasathav
    arunprasathav

    ๐Ÿ› asiercamara
    asiercamara

    ๐Ÿ› astillich-igniti
    astillich-igniti

    ๐Ÿ’ป avesolovksyy
    avesolovksyy

    ๐Ÿ› - avishvat
    avishvat

    ๐Ÿ› + avishvat
    avishvat

    ๐Ÿ› avivmu
    avivmu

    ๐Ÿ› axelbarfod1
    axelbarfod1

    ๐Ÿ› b-3-n
    b-3-n

    ๐Ÿ› balbhadra9
    balbhadra9

    ๐Ÿ› base23de
    base23de

    ๐Ÿ› bergander
    bergander

    ๐Ÿ› ๐Ÿ’ป - berkam
    berkam

    ๐Ÿ’ป ๐Ÿ› + berkam
    berkam

    ๐Ÿ’ป ๐Ÿ› breizh31
    breizh31

    ๐Ÿ› caesarkim
    caesarkim

    ๐Ÿ› carolyujing
    carolyujing

    ๐Ÿ› cbfiddle
    cbfiddle

    ๐Ÿ› cesares-basilico
    cesares-basilico

    ๐Ÿ› chrite
    chrite

    ๐Ÿ› - ciufudean
    ciufudean

    ๐Ÿ“– + ciufudean
    ciufudean

    ๐Ÿ“– cobratbq
    cobratbq

    ๐Ÿ› coladict
    coladict

    ๐Ÿ› cosmoJFH
    cosmoJFH

    ๐Ÿ› cristalp
    cristalp

    ๐Ÿ› crunsk
    crunsk

    ๐Ÿ› cwholmes
    cwholmes

    ๐Ÿ› - cyberjj999
    cyberjj999

    ๐Ÿ› + cyberjj999
    cyberjj999

    ๐Ÿ› cyw3
    cyw3

    ๐Ÿ› ๐Ÿ“– d1ss0nanz
    d1ss0nanz

    ๐Ÿ› dague1
    dague1

    ๐Ÿ“– dalizi007
    dalizi007

    ๐Ÿ’ป danbrycefairsailcom
    danbrycefairsailcom

    ๐Ÿ› dariansanity
    dariansanity

    ๐Ÿ› - darrenmiliband
    darrenmiliband

    ๐Ÿ› + darrenmiliband
    darrenmiliband

    ๐Ÿ› davidburstrom
    davidburstrom

    ๐Ÿ› dbirkman-paloalto
    dbirkman-paloalto

    ๐Ÿ› deepak-patra
    deepak-patra

    ๐Ÿ› dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› dinesh150
    dinesh150

    ๐Ÿ› diziaq
    diziaq

    ๐Ÿ› - dreaminpast123
    dreaminpast123

    ๐Ÿ› + dreaminpast123
    dreaminpast123

    ๐Ÿ› duanyanan
    duanyanan

    ๐Ÿ› dutt-sanjay
    dutt-sanjay

    ๐Ÿ› duursma
    duursma

    ๐Ÿ’ป dylanleung
    dylanleung

    ๐Ÿ› dzeigler
    dzeigler

    ๐Ÿ› eant60
    eant60

    ๐Ÿ› - ekkirala
    ekkirala

    ๐Ÿ› + ekkirala
    ekkirala

    ๐Ÿ› emersonmoura
    emersonmoura

    ๐Ÿ› emouty
    emouty

    ๐Ÿ’ป eugenepugach
    eugenepugach

    ๐Ÿ› fairy
    fairy

    ๐Ÿ› filiprafalowicz
    filiprafalowicz

    ๐Ÿ’ป flxbl-io
    flxbl-io

    ๐Ÿ’ต - foxmason
    foxmason

    ๐Ÿ› + foxmason
    foxmason

    ๐Ÿ› frankegabor
    frankegabor

    ๐Ÿ› frankl
    frankl

    ๐Ÿ› freafrea
    freafrea

    ๐Ÿ› fsapatin
    fsapatin

    ๐Ÿ› gearsethenry
    gearsethenry

    ๐Ÿ› gracia19
    gracia19

    ๐Ÿ› - gudzpoz
    gudzpoz

    ๐Ÿ› + gudzpoz
    gudzpoz

    ๐Ÿ› guo fei
    guo fei

    ๐Ÿ› gurmsc5
    gurmsc5

    ๐Ÿ› gwilymatgearset
    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ› haigsn
    haigsn

    ๐Ÿ› hemanshu070
    hemanshu070

    ๐Ÿ› henrik242
    henrik242

    ๐Ÿ› - hongpuwu
    hongpuwu

    ๐Ÿ› + hongpuwu
    hongpuwu

    ๐Ÿ› hvbtup
    hvbtup

    ๐Ÿ’ป ๐Ÿ› igniti GmbH
    igniti GmbH

    ๐Ÿ› ilovezfs
    ilovezfs

    ๐Ÿ› imax-erik
    imax-erik

    ๐Ÿ› itaigilo
    itaigilo

    ๐Ÿ› jakivey32
    jakivey32

    ๐Ÿ› - jbennett2091
    jbennett2091

    ๐Ÿ› + jbennett2091
    jbennett2091

    ๐Ÿ› jcamerin
    jcamerin

    ๐Ÿ› jkeener1
    jkeener1

    ๐Ÿ› jmetertea
    jmetertea

    ๐Ÿ› johnra2
    johnra2

    ๐Ÿ’ป johnzhao9
    johnzhao9

    ๐Ÿ› josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ› - kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ› + kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ› karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“– karwer
    karwer

    ๐Ÿ› kaulonline
    kaulonline

    ๐Ÿ› kdaemonv
    kdaemonv

    ๐Ÿ› kdebski85
    kdebski85

    ๐Ÿ› ๐Ÿ’ป kenji21
    kenji21

    ๐Ÿ’ป ๐Ÿ› - kfranic
    kfranic

    ๐Ÿ› + kfranic
    kfranic

    ๐Ÿ› khalidkh
    khalidkh

    ๐Ÿ› koalalam
    koalalam

    ๐Ÿ› krzyk
    krzyk

    ๐Ÿ› lasselindqvist
    lasselindqvist

    ๐Ÿ› lgemeinhardt
    lgemeinhardt

    ๐Ÿ› lihuaib
    lihuaib

    ๐Ÿ› - liqingjun123
    liqingjun123

    ๐Ÿ› + liqingjun123
    liqingjun123

    ๐Ÿ› lonelyma1021
    lonelyma1021

    ๐Ÿ› lpeddy
    lpeddy

    ๐Ÿ› lujiefsi
    lujiefsi

    ๐Ÿ’ป lukelukes
    lukelukes

    ๐Ÿ’ป lyriccoder
    lyriccoder

    ๐Ÿ› marcelmore
    marcelmore

    ๐Ÿ› - matchbox
    matchbox

    ๐Ÿ› + matchbox
    matchbox

    ๐Ÿ› matthiaskraaz
    matthiaskraaz

    ๐Ÿ› meandonlyme
    meandonlyme

    ๐Ÿ› mikesive
    mikesive

    ๐Ÿ› milossesic
    milossesic

    ๐Ÿ› mluckam
    mluckam

    ๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
    mohan-chinnappan-n

    ๐Ÿ’ป - mriddell95
    mriddell95

    ๐Ÿ› + mriddell95
    mriddell95

    ๐Ÿ› mrlzh
    mrlzh

    ๐Ÿ› msloan
    msloan

    ๐Ÿ› mucharlaravalika
    mucharlaravalika

    ๐Ÿ› mvenneman
    mvenneman

    ๐Ÿ› nareshl119
    nareshl119

    ๐Ÿ› nicolas-harraudeau-sonarsource
    nicolas-harraudeau-sonarsource

    ๐Ÿ› - noerremark
    noerremark

    ๐Ÿ› + noerremark
    noerremark

    ๐Ÿ› novsirion
    novsirion

    ๐Ÿ› nwcm
    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
    oggboy

    ๐Ÿ› oinume
    oinume

    ๐Ÿ› orimarko
    orimarko

    ๐Ÿ’ป ๐Ÿ› pablogomez2197
    pablogomez2197

    ๐Ÿ› - pacvz
    pacvz

    ๐Ÿ’ป + pacvz
    pacvz

    ๐Ÿ’ป pallavi agarwal
    pallavi agarwal

    ๐Ÿ› parksungrin
    parksungrin

    ๐Ÿ› patpatpat123
    patpatpat123

    ๐Ÿ› patriksevallius
    patriksevallius

    ๐Ÿ› pbrajesh1
    pbrajesh1

    ๐Ÿ› phoenix384
    phoenix384

    ๐Ÿ› - piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป + piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป plan3d
    plan3d

    ๐Ÿ› poojasix
    poojasix

    ๐Ÿ› prabhushrikant
    prabhushrikant

    ๐Ÿ› pujitha8783
    pujitha8783

    ๐Ÿ› r-r-a-j
    r-r-a-j

    ๐Ÿ› raghujayjunk
    raghujayjunk

    ๐Ÿ› - rajeshveera
    rajeshveera

    ๐Ÿ› + rajeshveera
    rajeshveera

    ๐Ÿ› rajeswarreddy88
    rajeswarreddy88

    ๐Ÿ› recdevs
    recdevs

    ๐Ÿ› reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ› rijkt
    rijkt

    ๐Ÿ› rillig-tk
    rillig-tk

    ๐Ÿ› rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ› - rnveach
    rnveach

    ๐Ÿ› + rnveach
    rnveach

    ๐Ÿ› rxmicro
    rxmicro

    ๐Ÿ› ryan-gustafson
    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ› sabi0
    sabi0

    ๐Ÿ› scais
    scais

    ๐Ÿ› schosin
    schosin

    ๐Ÿ› screamingfrog
    screamingfrog

    ๐Ÿ’ต - sebbASF
    sebbASF

    ๐Ÿ› + sebbASF
    sebbASF

    ๐Ÿ› sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป shilko2013
    shilko2013

    ๐Ÿ› shiomiyan
    shiomiyan

    ๐Ÿ“– simeonKondr
    simeonKondr

    ๐Ÿ› snajberk
    snajberk

    ๐Ÿ› sniperrifle2004
    sniperrifle2004

    ๐Ÿ› - snuyanzin
    snuyanzin

    ๐Ÿ› ๐Ÿ’ป + snuyanzin
    snuyanzin

    ๐Ÿ› ๐Ÿ’ป soloturn
    soloturn

    ๐Ÿ› soyodream
    soyodream

    ๐Ÿ› sratz
    sratz

    ๐Ÿ› stonio
    stonio

    ๐Ÿ› sturton
    sturton

    ๐Ÿ’ป ๐Ÿ› sudharmohan
    sudharmohan

    ๐Ÿ› - suruchidawar
    suruchidawar

    ๐Ÿ› + suruchidawar
    suruchidawar

    ๐Ÿ› svenfinitiv
    svenfinitiv

    ๐Ÿ› szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป tashiscool
    tashiscool

    ๐Ÿ› test-git-hook
    test-git-hook

    ๐Ÿ› testation21
    testation21

    ๐Ÿ’ป ๐Ÿ› thanosa
    thanosa

    ๐Ÿ› - tiandiyixian
    tiandiyixian

    ๐Ÿ› + tiandiyixian
    tiandiyixian

    ๐Ÿ› tobwoerk
    tobwoerk

    ๐Ÿ› tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป trentchilders
    trentchilders

    ๐Ÿ› triandicAnt
    triandicAnt

    ๐Ÿ› trishul14
    trishul14

    ๐Ÿ› tsui
    tsui

    ๐Ÿ› - wangzitom12306
    wangzitom12306

    ๐Ÿ› + wangzitom12306
    wangzitom12306

    ๐Ÿ› winhkey
    winhkey

    ๐Ÿ› witherspore
    witherspore

    ๐Ÿ› wjljack
    wjljack

    ๐Ÿ› wuchiuwong
    wuchiuwong

    ๐Ÿ› xingsong
    xingsong

    ๐Ÿ› xioayuge
    xioayuge

    ๐Ÿ› - xnYi9wRezm
    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ› + xnYi9wRezm
    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ› xuanuy
    xuanuy

    ๐Ÿ› xyf0921
    xyf0921

    ๐Ÿ› yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› yasuharu-sato
    yasuharu-sato

    ๐Ÿ› zenglian
    zenglian

    ๐Ÿ› zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› - zh3ng
    zh3ng

    ๐Ÿ› + zh3ng
    zh3ng

    ๐Ÿ› zt_soft
    zt_soft

    ๐Ÿ› ztt79
    ztt79

    ๐Ÿ› zzzzfeng
    zzzzfeng

    ๐Ÿ› From 85e0695ca608d35cb2112c9d374add5674b5710b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 12 Oct 2024 18:02:07 +0200 Subject: [PATCH 0084/1962] Add @Aryant-Tripathi as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 225 +++++++++++++------------- 2 files changed, 123 insertions(+), 111 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 24f01443b12..8d11a3745ae 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7837,6 +7837,15 @@ "contributions": [ "bug" ] + }, + { + "login": "Aryant-Tripathi", + "name": "Aryant Tripathi", + "avatar_url": "https://avatars.githubusercontent.com/u/60316716?v=4", + "profile": "https://github.com/Aryant-Tripathi", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 2ea476a44a8..0a1cd02cb00 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -110,1006 +110,1009 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Artur Bosch
    Artur Bosch

    ๐Ÿ› Artur Dryomov
    Artur Dryomov

    ๐Ÿ› Artur Ossowski
    Artur Ossowski

    ๐Ÿ› + Aryant Tripathi
    Aryant Tripathi

    ๐Ÿ’ป AshTheMash
    AshTheMash

    ๐Ÿ› - Ashish Rana
    Ashish Rana

    ๐Ÿ› + Ashish Rana
    Ashish Rana

    ๐Ÿ› Atul Kaushal
    Atul Kaushal

    ๐Ÿ› August Boland
    August Boland

    ๐Ÿ› Aurel Hudec
    Aurel Hudec

    ๐Ÿ› Austin
    Austin

    ๐Ÿ› Austin Shalit
    Austin Shalit

    ๐Ÿ› Austin Tice
    Austin Tice

    ๐Ÿ› - Ayoub Kaanich
    Ayoub Kaanich

    ๐Ÿ› + Ayoub Kaanich
    Ayoub Kaanich

    ๐Ÿ› BBG
    BBG

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Bailey Tjiong
    Bailey Tjiong

    ๐Ÿ’ป Barthรฉlemy L.
    Barthรฉlemy L.

    ๐Ÿ› Basavaraj K N
    Basavaraj K N

    ๐Ÿ› Basil Peace
    Basil Peace

    ๐Ÿ› Belle
    Belle

    ๐Ÿ› - Ben Lerner
    Ben Lerner

    ๐Ÿ› + Ben Lerner
    Ben Lerner

    ๐Ÿ› Ben Manes
    Ben Manes

    ๐Ÿ› Ben McCann
    Ben McCann

    ๐Ÿ› Bendegรบz Nagy
    Bendegรบz Nagy

    ๐Ÿ› Bennet S Yee
    Bennet S Yee

    ๐Ÿ› Benoit Lacelle
    Benoit Lacelle

    ๐Ÿ› Bernardo Macรชdo
    Bernardo Macรชdo

    ๐Ÿ› - Bernd Farka
    Bernd Farka

    ๐Ÿ› + Bernd Farka
    Bernd Farka

    ๐Ÿ› Betina Cynthia Mamani
    Betina Cynthia Mamani

    ๐Ÿ› Bhanu Prakash Pamidi
    Bhanu Prakash Pamidi

    ๐Ÿ’ป ๐Ÿ› Bhargav Thanki
    Bhargav Thanki

    ๐Ÿ› Binu R J
    Binu R J

    ๐Ÿ› Bjรถrn Kautler
    Bjรถrn Kautler

    ๐Ÿ’ป ๐Ÿ› Blightbuster
    Blightbuster

    ๐Ÿ› - Bo Zhang
    Bo Zhang

    ๐Ÿ› + Bo Zhang
    Bo Zhang

    ๐Ÿ› Bob "Wombat" Hogg
    Bob "Wombat" Hogg

    ๐Ÿ› Bobby Wertman
    Bobby Wertman

    ๐Ÿ› Bolarinwa Saheed Olayemi
    Bolarinwa Saheed Olayemi

    ๐Ÿ’ป ๐Ÿ› Boris Petrov
    Boris Petrov

    ๐Ÿ› Brad Kent
    Brad Kent

    ๐Ÿ› Brandon Mikeska
    Brandon Mikeska

    ๐Ÿ› - Brian Batronis
    Brian Batronis

    ๐Ÿ› + Brian Batronis
    Brian Batronis

    ๐Ÿ› Brian Johnson
    Brian Johnson

    ๐Ÿ› Brice Dutheil
    Brice Dutheil

    ๐Ÿ’ป ๐Ÿ› Bruno Ferreira
    Bruno Ferreira

    ๐Ÿ› Bruno Harbulot
    Bruno Harbulot

    ๐Ÿ› Bruno Ritz
    Bruno Ritz

    ๐Ÿ› BurovnikovEvgeniy
    BurovnikovEvgeniy

    ๐Ÿ› - Cameron Donaldson
    Cameron Donaldson

    ๐Ÿ› + Cameron Donaldson
    Cameron Donaldson

    ๐Ÿ› Carlos Macasaet
    Carlos Macasaet

    ๐Ÿ› Carsten Otto
    Carsten Otto

    ๐Ÿ› Charlie Housh
    Charlie Housh

    ๐Ÿ› Charlie Jonas
    Charlie Jonas

    ๐Ÿ› Chas Honton
    Chas Honton

    ๐Ÿ› ๐Ÿ’ป Chen Yang
    Chen Yang

    ๐Ÿ› - Chotu
    Chotu

    ๐Ÿ› + Chotu
    Chotu

    ๐Ÿ› Chris Smith
    Chris Smith

    ๐Ÿ› Chris Toomey
    Chris Toomey

    ๐Ÿ› Christian Hujer
    Christian Hujer

    ๐Ÿ› Christian Pontesegger
    Christian Pontesegger

    ๐Ÿ› ChristianWulf
    ChristianWulf

    ๐Ÿ› Christofer Dutz
    Christofer Dutz

    ๐Ÿ’ป - Christoffer Anselm
    Christoffer Anselm

    ๐Ÿ› + Christoffer Anselm
    Christoffer Anselm

    ๐Ÿ› Christophe Vidal
    Christophe Vidal

    ๐Ÿ› Christopher Dancy
    Christopher Dancy

    ๐Ÿ› Clemens Prill
    Clemens Prill

    ๐Ÿ› Clint Chester
    Clint Chester

    ๐Ÿ’ป ๐Ÿ› Clรฉment Fournier
    Clรฉment Fournier

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง Codacy Badger
    Codacy Badger

    ๐Ÿ› - Code-Nil
    Code-Nil

    ๐Ÿ› + Code-Nil
    Code-Nil

    ๐Ÿ› ColColonCleaner
    ColColonCleaner

    ๐Ÿ› Colin Ingarfield
    Colin Ingarfield

    ๐Ÿ› Craig Andrews
    Craig Andrews

    ๐Ÿ› Craig Muchinsky
    Craig Muchinsky

    ๐Ÿ› Cyril
    Cyril

    ๐Ÿ’ป ๐Ÿ› Dale
    Dale

    ๐Ÿ’ป - Damien Jiang
    Damien Jiang

    ๐Ÿ› + Damien Jiang
    Damien Jiang

    ๐Ÿ› Dan Berindei
    Dan Berindei

    ๐Ÿ› Dan Rollo
    Dan Rollo

    ๐Ÿ› Dan Ziemba
    Dan Ziemba

    ๐Ÿ› Daniel Gredler
    Daniel Gredler

    ๐Ÿ’ป ๐Ÿ› Daniel Jipa
    Daniel Jipa

    ๐Ÿ› Daniel Paul Searles
    Daniel Paul Searles

    ๐Ÿ’ป - Daniel Reigada
    Daniel Reigada

    ๐Ÿ› + Daniel Reigada
    Daniel Reigada

    ๐Ÿ› Danilo Pianini
    Danilo Pianini

    ๐Ÿ› Darko
    Darko

    ๐Ÿ› David
    David

    ๐Ÿ› David Atkinson
    David Atkinson

    ๐Ÿ› David Burstrรถm
    David Burstrรถm

    ๐Ÿ’ป ๐Ÿ› David Goatรฉ
    David Goatรฉ

    ๐Ÿ› - David Golpira
    David Golpira

    ๐Ÿ› + David Golpira
    David Golpira

    ๐Ÿ› David Kovaล™รญk
    David Kovaล™รญk

    ๐Ÿ› David M. Karr (fullname at gmail.com)
    David M. Karr (fullname at gmail.com)

    ๐Ÿ› David Renz
    David Renz

    ๐Ÿ’ป ๐Ÿ› David Renz
    David Renz

    ๐Ÿ› David Schach
    David Schach

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– Dawid Ciok
    Dawid Ciok

    ๐Ÿ› ๐Ÿ’ป - Debamoy Datta
    Debamoy Datta

    ๐Ÿ’ป + Debamoy Datta
    Debamoy Datta

    ๐Ÿ’ป Deleted user
    Deleted user

    ๐Ÿ› Dell Green
    Dell Green

    ๐Ÿ› Dem Pilafian
    Dem Pilafian

    ๐Ÿ› Den
    Den

    ๐Ÿ› Denis Borovikov
    Denis Borovikov

    ๐Ÿ’ป ๐Ÿ› Dennie Reniers
    Dennie Reniers

    ๐Ÿ’ป ๐Ÿ› - Dennis Kieselhorst
    Dennis Kieselhorst

    ๐Ÿ› + Dennis Kieselhorst
    Dennis Kieselhorst

    ๐Ÿ› Derek P. Moore
    Derek P. Moore

    ๐Ÿ› Dichotomia
    Dichotomia

    ๐Ÿ› Dionisio Cortรฉs Fernรกndez
    Dionisio Cortรฉs Fernรกndez

    ๐Ÿ’ป ๐Ÿ› Dmitri Bourlatchkov
    Dmitri Bourlatchkov

    ๐Ÿ› Dmitriy Kuzmin
    Dmitriy Kuzmin

    ๐Ÿ› Dmytro Dashenkov
    Dmytro Dashenkov

    ๐Ÿ› - Dr. Christian Kohlschรผtter
    Dr. Christian Kohlschรผtter

    ๐Ÿ› + Dr. Christian Kohlschรผtter
    Dr. Christian Kohlschรผtter

    ๐Ÿ› Drew Hall
    Drew Hall

    ๐Ÿ› Dumitru Postoronca
    Dumitru Postoronca

    ๐Ÿ› Dylan Adams
    Dylan Adams

    ๐Ÿ› Eden Hao
    Eden Hao

    ๐Ÿ› Edward Klimoshenko
    Edward Klimoshenko

    ๐Ÿ› ๐Ÿ’ป Egor Bredikhin
    Egor Bredikhin

    ๐Ÿ› - Elan P. Kugelmass
    Elan P. Kugelmass

    ๐Ÿ› + Elan P. Kugelmass
    Elan P. Kugelmass

    ๐Ÿ› Elder S.
    Elder S.

    ๐Ÿ› Eldrick Wega
    Eldrick Wega

    ๐Ÿ“– Emile
    Emile

    ๐Ÿ› Eric
    Eric

    ๐Ÿ› Eric Kintzer
    Eric Kintzer

    ๐Ÿ› Eric Perret
    Eric Perret

    ๐Ÿ› - Eric Squires
    Eric Squires

    ๐Ÿ› + Eric Squires
    Eric Squires

    ๐Ÿ› Erich L Foster
    Erich L Foster

    ๐Ÿ› Erik Bleske
    Erik Bleske

    ๐Ÿ› Erik C. Thauvin
    Erik C. Thauvin

    ๐Ÿ“– Ernst Reissner
    Ernst Reissner

    ๐Ÿ› Ethan Sargent
    Ethan Sargent

    ๐Ÿ› Ewan Tempero
    Ewan Tempero

    ๐Ÿ› - F.W. Dekker
    F.W. Dekker

    ๐Ÿ› + F.W. Dekker
    F.W. Dekker

    ๐Ÿ› FSchliephacke
    FSchliephacke

    ๐Ÿ› Facundo
    Facundo

    ๐Ÿ› Federico Giust
    Federico Giust

    ๐Ÿ› Fedor Sherstobitov
    Fedor Sherstobitov

    ๐Ÿ› Felix Lampe
    Felix Lampe

    ๐Ÿ› Filip Golonka
    Filip Golonka

    ๐Ÿ› - Filipe Esperandio
    Filipe Esperandio

    ๐Ÿ’ป ๐Ÿ› + Filipe Esperandio
    Filipe Esperandio

    ๐Ÿ’ป ๐Ÿ› Filippo Nova
    Filippo Nova

    ๐Ÿ› Francesco la Torre
    Francesco la Torre

    ๐Ÿ› Francisco Duarte
    Francisco Duarte

    ๐Ÿ› Frieder Bluemle
    Frieder Bluemle

    ๐Ÿ› Frits Jalvingh
    Frits Jalvingh

    ๐Ÿ’ป ๐Ÿ› G. Bazior
    G. Bazior

    ๐Ÿ› - Gabe Henkes
    Gabe Henkes

    ๐Ÿ› + Gabe Henkes
    Gabe Henkes

    ๐Ÿ› Gary Gregory
    Gary Gregory

    ๐Ÿ› Genoud Magloire
    Genoud Magloire

    ๐Ÿ› Geoffrey555
    Geoffrey555

    ๐Ÿ› Georg Romstorfer
    Georg Romstorfer

    ๐Ÿ› Gili Tzabari
    Gili Tzabari

    ๐Ÿ› Gio
    Gio

    ๐Ÿ› - Gol
    Gol

    ๐Ÿ› + Gol
    Gol

    ๐Ÿ› Gold856
    Gold856

    ๐Ÿ› ๐Ÿ’ป Gonzalo Exequiel Ibars Ingman
    Gonzalo Exequiel Ibars Ingman

    ๐Ÿ’ป ๐Ÿ› GooDer
    GooDer

    ๐Ÿ› Gregor Riegler
    Gregor Riegler

    ๐Ÿ› Grzegorz Olszewski
    Grzegorz Olszewski

    ๐Ÿ› Gunther Schrijvers
    Gunther Schrijvers

    ๐Ÿ’ป ๐Ÿ› - Gustavo Krieger
    Gustavo Krieger

    ๐Ÿ› + Gustavo Krieger
    Gustavo Krieger

    ๐Ÿ› Guy Elsmore-Paddock
    Guy Elsmore-Paddock

    ๐Ÿ› Gรถrkem Mรผlayim
    Gรถrkem Mรผlayim

    ๐Ÿ› Hanzel Godinez
    Hanzel Godinez

    ๐Ÿ› Haoliang Chen
    Haoliang Chen

    ๐Ÿ› Harsh Kukreja
    Harsh Kukreja

    ๐Ÿ› Hassan ALAMI
    Hassan ALAMI

    ๐Ÿ› - Heber
    Heber

    ๐Ÿ› + Heber
    Heber

    ๐Ÿ› Henning Schmiedehausen
    Henning Schmiedehausen

    ๐Ÿ’ป ๐Ÿ› Henning von Bargen
    Henning von Bargen

    ๐Ÿ’ป Hervรฉ Boutemy
    Hervรฉ Boutemy

    ๐Ÿ› Himanshu Pandey
    Himanshu Pandey

    ๐Ÿ› Hokwang Lee
    Hokwang Lee

    ๐Ÿ› Hooperbloob
    Hooperbloob

    ๐Ÿ’ป - Hung PHAN
    Hung PHAN

    ๐Ÿ› + Hung PHAN
    Hung PHAN

    ๐Ÿ› IDoCodingStuffs
    IDoCodingStuffs

    ๐Ÿ’ป ๐Ÿ› Iccen Gan
    Iccen Gan

    ๐Ÿ› Ignacio Mariano Tirabasso
    Ignacio Mariano Tirabasso

    ๐Ÿ› Igor Melnichenko
    Igor Melnichenko

    ๐Ÿ› Igor Moreno
    Igor Moreno

    ๐Ÿ› Intelesis-MS
    Intelesis-MS

    ๐Ÿ› - Iroha_
    Iroha_

    ๐Ÿ› + Iroha_
    Iroha_

    ๐Ÿ› Ishan Srivastava
    Ishan Srivastava

    ๐Ÿ› Ivan Vakhrushev
    Ivan Vakhrushev

    ๐Ÿ› Ivano Guerini
    Ivano Guerini

    ๐Ÿ› Ivar Andreas Bonsaksen
    Ivar Andreas Bonsaksen

    ๐Ÿ› Ivo ล mรญd
    Ivo ล mรญd

    ๐Ÿ› JJengility
    JJengility

    ๐Ÿ› - Jake Hemmerle
    Jake Hemmerle

    ๐Ÿ› + Jake Hemmerle
    Jake Hemmerle

    ๐Ÿ› James Harrison
    James Harrison

    ๐Ÿ› ๐Ÿ’ป Jamie Bisotti
    Jamie Bisotti

    ๐Ÿ› Jan
    Jan

    ๐Ÿ› Jan Aertgeerts
    Jan Aertgeerts

    ๐Ÿ’ป ๐Ÿ› Jan Brรผmmer
    Jan Brรผmmer

    ๐Ÿ› Jan Tล™รญska
    Jan Tล™รญska

    ๐Ÿ› - Jan-Lukas Else
    Jan-Lukas Else

    ๐Ÿ› + Jan-Lukas Else
    Jan-Lukas Else

    ๐Ÿ› Jason Qiu
    Jason Qiu

    ๐Ÿ’ป ๐Ÿ“– Jason Williams
    Jason Williams

    ๐Ÿ› Javier Spagnoletti
    Javier Spagnoletti

    ๐Ÿ› Jean-Paul Mayer
    Jean-Paul Mayer

    ๐Ÿ› Jean-Simon Larochelle
    Jean-Simon Larochelle

    ๐Ÿ› Jeff Bartolotta
    Jeff Bartolotta

    ๐Ÿ’ป ๐Ÿ› - Jeff Hube
    Jeff Hube

    ๐Ÿ’ป ๐Ÿ› + Jeff Hube
    Jeff Hube

    ๐Ÿ’ป ๐Ÿ› Jeff Jensen
    Jeff Jensen

    ๐Ÿ› Jeff May
    Jeff May

    ๐Ÿ› Jens Gerdes
    Jens Gerdes

    ๐Ÿ› Jeroen Borgers
    Jeroen Borgers

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข Jeroen Meijer
    Jeroen Meijer

    ๐Ÿ› Jeroen van Wilgenburg
    Jeroen van Wilgenburg

    ๐Ÿ“– - Jerome Russ
    Jerome Russ

    ๐Ÿ› + Jerome Russ
    Jerome Russ

    ๐Ÿ› JerritEic
    JerritEic

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Jiri Pejchal
    Jiri Pejchal

    ๐Ÿ› Jithin Sunny
    Jithin Sunny

    ๐Ÿ› Jiล™รญ ล korpil
    Jiล™รญ ล korpil

    ๐Ÿ› Joao Machado
    Joao Machado

    ๐Ÿ› Jochen Krauss
    Jochen Krauss

    ๐Ÿ› - Johan Hammar
    Johan Hammar

    ๐Ÿ› + Johan Hammar
    Johan Hammar

    ๐Ÿ› John Karp
    John Karp

    ๐Ÿ› John Zhang
    John Zhang

    ๐Ÿ› John-Teng
    John-Teng

    ๐Ÿ’ป ๐Ÿ› Jon Moroney
    Jon Moroney

    ๐Ÿ’ป ๐Ÿ› Jonas Geiregat
    Jonas Geiregat

    ๐Ÿ› Jonas KeรŸler
    Jonas KeรŸler

    ๐Ÿ› - Jonathan Wiesel
    Jonathan Wiesel

    ๐Ÿ’ป ๐Ÿ› + Jonathan Wiesel
    Jonathan Wiesel

    ๐Ÿ’ป ๐Ÿ› Jordan
    Jordan

    ๐Ÿ› Jordi Llach
    Jordi Llach

    ๐Ÿ› Jorge Solรณrzano
    Jorge Solรณrzano

    ๐Ÿ› JorneVL
    JorneVL

    ๐Ÿ› Jose Palafox
    Jose Palafox

    ๐Ÿ› Jose Stovall
    Jose Stovall

    ๐Ÿ› - Joseph
    Joseph

    ๐Ÿ’ป + Joseph
    Joseph

    ๐Ÿ’ป Joseph Heenan
    Joseph Heenan

    ๐Ÿ› Josh Feingold
    Josh Feingold

    ๐Ÿ’ป ๐Ÿ› Josh Holthaus
    Josh Holthaus

    ๐Ÿ› Joshua S Arquilevich
    Joshua S Arquilevich

    ๐Ÿ› Joรฃo Dinis Ferreira
    Joรฃo Dinis Ferreira

    ๐Ÿ“– Joรฃo Ferreira
    Joรฃo Ferreira

    ๐Ÿ’ป ๐Ÿ› - Joรฃo Pedro Schmitt
    Joรฃo Pedro Schmitt

    ๐Ÿ› + Joรฃo Pedro Schmitt
    Joรฃo Pedro Schmitt

    ๐Ÿ› Juan Martรญn Sotuyo Dodero
    Juan Martรญn Sotuyo Dodero

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง Juan Pablo Civile
    Juan Pablo Civile

    ๐Ÿ› Julian Voronetsky
    Julian Voronetsky

    ๐Ÿ› Julien
    Julien

    ๐Ÿ› Julius
    Julius

    ๐Ÿ› JustPRV
    JustPRV

    ๐Ÿ› - Justin Stroud
    Justin Stroud

    ๐Ÿ’ป + Justin Stroud
    Justin Stroud

    ๐Ÿ’ป Jรถrn Huxhorn
    Jรถrn Huxhorn

    ๐Ÿ› KThompso
    KThompso

    ๐Ÿ› Kai Amundsen
    Kai Amundsen

    ๐Ÿ› Karel Vervaeke
    Karel Vervaeke

    ๐Ÿ› Karl-Andero Mere
    Karl-Andero Mere

    ๐Ÿ› Karl-Philipp Richter
    Karl-Philipp Richter

    ๐Ÿ› - Karsten Silz
    Karsten Silz

    ๐Ÿ› + Karsten Silz
    Karsten Silz

    ๐Ÿ› Kazuma Watanabe
    Kazuma Watanabe

    ๐Ÿ› Kev
    Kev

    ๐Ÿ› Keve Mรผller
    Keve Mรผller

    ๐Ÿ› Kevin Guerra
    Kevin Guerra

    ๐Ÿ’ป Kevin Jones
    Kevin Jones

    ๐Ÿ› ๐Ÿ’ป Kevin Poorman
    Kevin Poorman

    ๐Ÿ› - Kevin Wayne
    Kevin Wayne

    ๐Ÿ› + Kevin Wayne
    Kevin Wayne

    ๐Ÿ› Kieran Black
    Kieran Black

    ๐Ÿ› Kirill Zubov
    Kirill Zubov

    ๐Ÿ› Kirk Clemens
    Kirk Clemens

    ๐Ÿ’ป ๐Ÿ› Klaus Hartl
    Klaus Hartl

    ๐Ÿ› Koen Van Looveren
    Koen Van Looveren

    ๐Ÿ› Kris Scheibe
    Kris Scheibe

    ๐Ÿ’ป ๐Ÿ› - Krystian Dabrowski
    Krystian Dabrowski

    ๐Ÿ› ๐Ÿ’ป + Krystian Dabrowski
    Krystian Dabrowski

    ๐Ÿ› ๐Ÿ’ป Kunal Thanki
    Kunal Thanki

    ๐Ÿ› LaLucid
    LaLucid

    ๐Ÿ’ป Larry Diamond
    Larry Diamond

    ๐Ÿ’ป ๐Ÿ› Lars Knickrehm
    Lars Knickrehm

    ๐Ÿ› Laurent Bovet
    Laurent Bovet

    ๐Ÿ› ๐Ÿ’ป Leo Gutierrez
    Leo Gutierrez

    ๐Ÿ› - LiGaOg
    LiGaOg

    ๐Ÿ’ป + LiGaOg
    LiGaOg

    ๐Ÿ’ป Liam Sharp
    Liam Sharp

    ๐Ÿ› Lintsi
    Lintsi

    ๐Ÿ› Linus Fernandes
    Linus Fernandes

    ๐Ÿ› Lixon Lookose
    Lixon Lookose

    ๐Ÿ› Logesh
    Logesh

    ๐Ÿ› Lorenzo Gabriele
    Lorenzo Gabriele

    ๐Ÿ› - Loรฏc Ledoyen
    Loรฏc Ledoyen

    ๐Ÿ› + Loรฏc Ledoyen
    Loรฏc Ledoyen

    ๐Ÿ› Lucas
    Lucas

    ๐Ÿ› Lucas Silva
    Lucas Silva

    ๐Ÿ› Lucas Soncini
    Lucas Soncini

    ๐Ÿ’ป ๐Ÿ› Luis Alcantar
    Luis Alcantar

    ๐Ÿ’ป Lukas Grรคf
    Lukas Grรคf

    ๐Ÿ’ป Lukasz Slonina
    Lukasz Slonina

    ๐Ÿ› - Lukebray
    Lukebray

    ๐Ÿ› + Lukebray
    Lukebray

    ๐Ÿ› Lynn
    Lynn

    ๐Ÿ’ป ๐Ÿ› Lyor Goldstein
    Lyor Goldstein

    ๐Ÿ› MCMicS
    MCMicS

    ๐Ÿ› Macarse
    Macarse

    ๐Ÿ› Machine account for PMD
    Machine account for PMD

    ๐Ÿ’ป Maciek Siemczyk
    Maciek Siemczyk

    ๐Ÿ› - Maikel Steneker
    Maikel Steneker

    ๐Ÿ’ป ๐Ÿ› + Maikel Steneker
    Maikel Steneker

    ๐Ÿ’ป ๐Ÿ› Maksim Moiseikin
    Maksim Moiseikin

    ๐Ÿ› Manfred Koch
    Manfred Koch

    ๐Ÿ› Manuel Moya Ferrer
    Manuel Moya Ferrer

    ๐Ÿ’ป ๐Ÿ› Manuel Ryan
    Manuel Ryan

    ๐Ÿ› Marat Vyshegorodtsev
    Marat Vyshegorodtsev

    ๐Ÿ› Marcel Hรคrle
    Marcel Hรคrle

    ๐Ÿ› - Marcello Fialho
    Marcello Fialho

    ๐Ÿ› + Marcello Fialho
    Marcello Fialho

    ๐Ÿ› Marcin Dฤ…browski
    Marcin Dฤ…browski

    ๐Ÿ’ป Marcin Rataj
    Marcin Rataj

    ๐Ÿ› Marcono1234
    Marcono1234

    ๐Ÿ› Mark Adamcin
    Mark Adamcin

    ๐Ÿ› Mark Hall
    Mark Hall

    ๐Ÿ’ป ๐Ÿ› Mark Kolich
    Mark Kolich

    ๐Ÿ› - Mark Pritchard
    Mark Pritchard

    ๐Ÿ› + Mark Pritchard
    Mark Pritchard

    ๐Ÿ› Markus Rathgeb
    Markus Rathgeb

    ๐Ÿ› Marquis Wang
    Marquis Wang

    ๐Ÿ› MartGit
    MartGit

    ๐Ÿ› Martin Feldsztejn
    Martin Feldsztejn

    ๐Ÿ› Martin Lehmann
    Martin Lehmann

    ๐Ÿ› Martin Spamer
    Martin Spamer

    ๐Ÿ› - Martin Tarjรกnyi
    Martin Tarjรกnyi

    ๐Ÿ› + Martin Tarjรกnyi
    Martin Tarjรกnyi

    ๐Ÿ› MatFl
    MatFl

    ๐Ÿ› Mateusz Stefanski
    Mateusz Stefanski

    ๐Ÿ› Mathieu Gouin
    Mathieu Gouin

    ๐Ÿ› MatiasComercio
    MatiasComercio

    ๐Ÿ’ป ๐Ÿ› Matt Benson
    Matt Benson

    ๐Ÿ› Matt De Poorter
    Matt De Poorter

    ๐Ÿ› - Matt Hargett
    Matt Hargett

    ๐Ÿ’ป ๐Ÿ’ต + Matt Hargett
    Matt Hargett

    ๐Ÿ’ป ๐Ÿ’ต Matt Harrah
    Matt Harrah

    ๐Ÿ› Matt Nelson
    Matt Nelson

    ๐Ÿ› Matthew Amos
    Matthew Amos

    ๐Ÿ› Matthew Duggan
    Matthew Duggan

    ๐Ÿ› Matthew Hall
    Matthew Hall

    ๐Ÿ› Matthew Rossner
    Matthew Rossner

    ๐Ÿ› - Matรญas Fraga
    Matรญas Fraga

    ๐Ÿ’ป ๐Ÿ› + Matรญas Fraga
    Matรญas Fraga

    ๐Ÿ’ป ๐Ÿ› Maxime Robert
    Maxime Robert

    ๐Ÿ’ป ๐Ÿ› MetaBF
    MetaBF

    ๐Ÿ› Metin Dagcilar
    Metin Dagcilar

    ๐Ÿ› Michael
    Michael

    ๐Ÿ› Michael Bell
    Michael Bell

    ๐Ÿ› Michael Bernstein
    Michael Bernstein

    ๐Ÿ› - Michael Clay
    Michael Clay

    ๐Ÿ› + Michael Clay
    Michael Clay

    ๐Ÿ› Michael Dombrowski
    Michael Dombrowski

    ๐Ÿ› Michael Hausegger
    Michael Hausegger

    ๐Ÿ› Michael Hoefer
    Michael Hoefer

    ๐Ÿ› Michael Kolesnikov
    Michael Kolesnikov

    ๐Ÿ› Michael Mรถbius
    Michael Mรถbius

    ๐Ÿ› Michael N. Lipp
    Michael N. Lipp

    ๐Ÿ› - Michael Pellegrini
    Michael Pellegrini

    ๐Ÿ› + Michael Pellegrini
    Michael Pellegrini

    ๐Ÿ› Michal Kordas
    Michal Kordas

    ๐Ÿ› Michaล‚ Borek
    Michaล‚ Borek

    ๐Ÿ› Michaล‚ Kuliล„ski
    Michaล‚ Kuliล„ski

    ๐Ÿ› Miguel Nรบรฑez Dรญaz-Montes
    Miguel Nรบรฑez Dรญaz-Montes

    ๐Ÿ› Mihai Ionut
    Mihai Ionut

    ๐Ÿ› Mikhail Kuchma
    Mikhail Kuchma

    ๐Ÿ› - Mirek Hankus
    Mirek Hankus

    ๐Ÿ› + Mirek Hankus
    Mirek Hankus

    ๐Ÿ› Mitch Spano
    Mitch Spano

    ๐Ÿ› Mladjan Gadzic
    Mladjan Gadzic

    ๐Ÿ› MrAngry52
    MrAngry52

    ๐Ÿ› Muminur Choudhury
    Muminur Choudhury

    ๐Ÿ› Mykhailo Palahuta
    Mykhailo Palahuta

    ๐Ÿ’ป ๐Ÿ› Nagendra Kumar Singh
    Nagendra Kumar Singh

    ๐Ÿ› - Nahuel Barrios
    Nahuel Barrios

    ๐Ÿ› + Nahuel Barrios
    Nahuel Barrios

    ๐Ÿ› Nakul Sharma
    Nakul Sharma

    ๐Ÿ› Nathan Braun
    Nathan Braun

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› Nathanaรซl
    Nathanaรซl

    ๐Ÿ› Naveen
    Naveen

    ๐Ÿ’ป - Nazdravi
    Nazdravi

    ๐Ÿ› + Nazdravi
    Nazdravi

    ๐Ÿ› Neha-Dhonde
    Neha-Dhonde

    ๐Ÿ› Nicholas Doyle
    Nicholas Doyle

    ๐Ÿ› Nick Butcher
    Nick Butcher

    ๐Ÿ› Nico Gallinal
    Nico Gallinal

    ๐Ÿ› Nicola Dal Maso
    Nicola Dal Maso

    ๐Ÿ› Nicolas Filotto
    Nicolas Filotto

    ๐Ÿ’ป - Nicolas Vervelle
    Nicolas Vervelle

    ๐Ÿ› + Nicolas Vervelle
    Nicolas Vervelle

    ๐Ÿ› Nicolas Vuillamy
    Nicolas Vuillamy

    ๐Ÿ“– Nikita Chursin
    Nikita Chursin

    ๐Ÿ› Niklas Baudy
    Niklas Baudy

    ๐Ÿ› Nikolas Havrikov
    Nikolas Havrikov

    ๐Ÿ› Nilesh Virkar
    Nilesh Virkar

    ๐Ÿ› Nimit Patel
    Nimit Patel

    ๐Ÿ› - Niranjan Harpale
    Niranjan Harpale

    ๐Ÿ› + Niranjan Harpale
    Niranjan Harpale

    ๐Ÿ› Nirvik Patel
    Nirvik Patel

    ๐Ÿ’ป Noah Sussman
    Noah Sussman

    ๐Ÿ› Noah0120
    Noah0120

    ๐Ÿ› Noam Tamim
    Noam Tamim

    ๐Ÿ› Noel Grandin
    Noel Grandin

    ๐Ÿ› Olaf Haalstra
    Olaf Haalstra

    ๐Ÿ› - Oleg Andreych
    Oleg Andreych

    ๐Ÿ’ป ๐Ÿ› + Oleg Andreych
    Oleg Andreych

    ๐Ÿ’ป ๐Ÿ› Oleg Pavlenko
    Oleg Pavlenko

    ๐Ÿ› Oleksii Dykov
    Oleksii Dykov

    ๐Ÿ’ป ๐Ÿ› Oliver Eikemeier
    Oliver Eikemeier

    ๐Ÿ› Oliver Siegmar
    Oliver Siegmar

    ๐Ÿ’ต Olivier Parent
    Olivier Parent

    ๐Ÿ’ป ๐Ÿ› Ollie Abbey
    Ollie Abbey

    ๐Ÿ’ป ๐Ÿ› - Ondrej Kratochvil
    Ondrej Kratochvil

    ๐Ÿ› + Ondrej Kratochvil
    Ondrej Kratochvil

    ๐Ÿ› OverDrone
    OverDrone

    ๐Ÿ› Ozan Gulle
    Ozan Gulle

    ๐Ÿ’ป ๐Ÿ› PUNEET JAIN
    PUNEET JAIN

    ๐Ÿ› Parbati Bose
    Parbati Bose

    ๐Ÿ› Paul Berg
    Paul Berg

    ๐Ÿ› Paul Guyot
    Paul Guyot

    ๐Ÿ’ป - Pavel Bludov
    Pavel Bludov

    ๐Ÿ› + Pavel Bludov
    Pavel Bludov

    ๐Ÿ› Pavel Miฤka
    Pavel Miฤka

    ๐Ÿ› Pedro Nuno Santos
    Pedro Nuno Santos

    ๐Ÿ› Pedro Rijo
    Pedro Rijo

    ๐Ÿ› Pelisse Romain
    Pelisse Romain

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Per Abich
    Per Abich

    ๐Ÿ’ป Pete Davids
    Pete Davids

    ๐Ÿ› - Peter Bruin
    Peter Bruin

    ๐Ÿ› + Peter Bruin
    Peter Bruin

    ๐Ÿ› Peter Chittum
    Peter Chittum

    ๐Ÿ’ป ๐Ÿ› Peter Cudmore
    Peter Cudmore

    ๐Ÿ› Peter Kasson
    Peter Kasson

    ๐Ÿ› Peter Kofler
    Peter Kofler

    ๐Ÿ› Peter Paul Bakker
    Peter Paul Bakker

    ๐Ÿ’ป Peter Rader
    Peter Rader

    ๐Ÿ› - Pham Hai Trung
    Pham Hai Trung

    ๐Ÿ› + Pham Hai Trung
    Pham Hai Trung

    ๐Ÿ› Philip Graf
    Philip Graf

    ๐Ÿ’ป ๐Ÿ› Philip Hachey
    Philip Hachey

    ๐Ÿ› Philippe Ozil
    Philippe Ozil

    ๐Ÿ› Phinehas Artemix
    Phinehas Artemix

    ๐Ÿ› Phokham Nonava
    Phokham Nonava

    ๐Ÿ› Pim van der Loos
    Pim van der Loos

    ๐Ÿ’ป โš ๏ธ - Piotr Szymaล„ski
    Piotr Szymaล„ski

    ๐Ÿ› + Piotr Szymaล„ski
    Piotr Szymaล„ski

    ๐Ÿ› Piotrek ลปygieล‚o
    Piotrek ลปygieล‚o

    ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– Pranay Jaiswal
    Pranay Jaiswal

    ๐Ÿ› Prasad Kamath
    Prasad Kamath

    ๐Ÿ› Prasanna
    Prasanna

    ๐Ÿ› Presh-AR
    Presh-AR

    ๐Ÿ› Puneet1726
    Puneet1726

    ๐Ÿ› - RBRi
    RBRi

    ๐Ÿ› + RBRi
    RBRi

    ๐Ÿ› Rafael Cortรชs
    Rafael Cortรชs

    ๐Ÿ› RaheemShaik999
    RaheemShaik999

    ๐Ÿ› RajeshR
    RajeshR

    ๐Ÿ’ป ๐Ÿ› Ramachandra Mohan
    Ramachandra Mohan

    ๐Ÿ› Ramel0921
    Ramel0921

    ๐Ÿ› Raquel Pau
    Raquel Pau

    ๐Ÿ› - Ravikiran Janardhana
    Ravikiran Janardhana

    ๐Ÿ› + Ravikiran Janardhana
    Ravikiran Janardhana

    ๐Ÿ› Reda Benhemmouche
    Reda Benhemmouche

    ๐Ÿ› Reinhard Schiedermeier
    Reinhard Schiedermeier

    ๐Ÿ› Renato Oliveira
    Renato Oliveira

    ๐Ÿ’ป ๐Ÿ› Rich DiCroce
    Rich DiCroce

    ๐Ÿ› Richard Corfield
    Richard Corfield

    ๐Ÿ’ป Richard Corfield
    Richard Corfield

    ๐Ÿ› ๐Ÿ’ป - Riot R1cket
    Riot R1cket

    ๐Ÿ› + Riot R1cket
    Riot R1cket

    ๐Ÿ› Rishabh Jain
    Rishabh Jain

    ๐Ÿ› RishabhDeep Singh
    RishabhDeep Singh

    ๐Ÿ› Rob Baillie
    Rob Baillie

    ๐Ÿ› Robbie Martinus
    Robbie Martinus

    ๐Ÿ’ป ๐Ÿ› Robert Henry
    Robert Henry

    ๐Ÿ› Robert Mihaly
    Robert Mihaly

    ๐Ÿ› - Robert Painsi
    Robert Painsi

    ๐Ÿ› + Robert Painsi
    Robert Painsi

    ๐Ÿ› Robert Russell
    Robert Russell

    ๐Ÿ› Robert Sรถsemann
    Robert Sรถsemann

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ› Robert Whitebit
    Robert Whitebit

    ๐Ÿ› Robin Richtsfeld
    Robin Richtsfeld

    ๐Ÿ› Robin Stocker
    Robin Stocker

    ๐Ÿ’ป ๐Ÿ› Robin Wils
    Robin Wils

    ๐Ÿ› - RochusOest
    RochusOest

    ๐Ÿ› + RochusOest
    RochusOest

    ๐Ÿ› Rodolfo Noviski
    Rodolfo Noviski

    ๐Ÿ› Rodrigo Casara
    Rodrigo Casara

    ๐Ÿ› Rodrigo Fernandes
    Rodrigo Fernandes

    ๐Ÿ› Roman Salvador
    Roman Salvador

    ๐Ÿ’ป ๐Ÿ› Ronald Blaschke
    Ronald Blaschke

    ๐Ÿ› Rรณbert Papp
    Rรณbert Papp

    ๐Ÿ› - Saikat Sengupta
    Saikat Sengupta

    ๐Ÿ› + Saikat Sengupta
    Saikat Sengupta

    ๐Ÿ› Saksham Handu
    Saksham Handu

    ๐Ÿ› Saladoc
    Saladoc

    ๐Ÿ› Salesforce Bob Lightning
    Salesforce Bob Lightning

    ๐Ÿ› Sam Carlberg
    Sam Carlberg

    ๐Ÿ› Sascha Riemer
    Sascha Riemer

    ๐Ÿ› Sashko
    Sashko

    ๐Ÿ’ป - Satoshi Kubo
    Satoshi Kubo

    ๐Ÿ› + Satoshi Kubo
    Satoshi Kubo

    ๐Ÿ› Scott Kennedy
    Scott Kennedy

    ๐Ÿ› Scott Wells
    Scott Wells

    ๐Ÿ› ๐Ÿ’ป Scrates1
    Scrates1

    ๐Ÿ› ๐Ÿ’ป Scrsloota
    Scrsloota

    ๐Ÿ’ป Sebastian Bรถgl
    Sebastian Bรถgl

    ๐Ÿ› Sebastian Davids
    Sebastian Davids

    ๐Ÿ› - Sebastian Schuberth
    Sebastian Schuberth

    ๐Ÿ› + Sebastian Schuberth
    Sebastian Schuberth

    ๐Ÿ› Sebastian Schwarz
    Sebastian Schwarz

    ๐Ÿ› Seren
    Seren

    ๐Ÿ› ๐Ÿ’ป Sergey Gorbaty
    Sergey Gorbaty

    ๐Ÿ› Sergey Kozlov
    Sergey Kozlov

    ๐Ÿ› Sergey Yanzin
    Sergey Yanzin

    ๐Ÿ’ป ๐Ÿ› Seth Wilcox
    Seth Wilcox

    ๐Ÿ’ป - Shai Bennathan
    Shai Bennathan

    ๐Ÿ› ๐Ÿ’ป + Shai Bennathan
    Shai Bennathan

    ๐Ÿ› ๐Ÿ’ป Shubham
    Shubham

    ๐Ÿ’ป ๐Ÿ› Simon Abykov
    Simon Abykov

    ๐Ÿ’ป ๐Ÿ› Simon Xiao
    Simon Xiao

    ๐Ÿ› Srinivasan Venkatachalam
    Srinivasan Venkatachalam

    ๐Ÿ› Stanislav Gromov
    Stanislav Gromov

    ๐Ÿ› Stanislav Myachenkov
    Stanislav Myachenkov

    ๐Ÿ’ป - Stefan Birkner
    Stefan Birkner

    ๐Ÿ› + Stefan Birkner
    Stefan Birkner

    ๐Ÿ› Stefan Bohn
    Stefan Bohn

    ๐Ÿ› Stefan Endrullis
    Stefan Endrullis

    ๐Ÿ› Stefan Klรถss-Schuster
    Stefan Klรถss-Schuster

    ๐Ÿ› Stefan Wolf
    Stefan Wolf

    ๐Ÿ› Stephan H. Wissel
    Stephan H. Wissel

    ๐Ÿ› Stephen
    Stephen

    ๐Ÿ› - Stephen Carter
    Stephen Carter

    ๐Ÿ› + Stephen Carter
    Stephen Carter

    ๐Ÿ› Stephen Friedrich
    Stephen Friedrich

    ๐Ÿ› Steve Babula
    Steve Babula

    ๐Ÿ’ป Steven Stearns
    Steven Stearns

    ๐Ÿ› ๐Ÿ’ป Stexxe
    Stexxe

    ๐Ÿ› Stian Lรฅgstad
    Stian Lรฅgstad

    ๐Ÿ› StuartClayton5
    StuartClayton5

    ๐Ÿ› - Supun Arunoda
    Supun Arunoda

    ๐Ÿ› + Supun Arunoda
    Supun Arunoda

    ๐Ÿ› Suren Abrahamyan
    Suren Abrahamyan

    ๐Ÿ› Suvashri
    Suvashri

    ๐Ÿ“– SwatiBGupta1110
    SwatiBGupta1110

    ๐Ÿ› SyedThoufich
    SyedThoufich

    ๐Ÿ› Szymon Sasin
    Szymon Sasin

    ๐Ÿ› T-chuangxin
    T-chuangxin

    ๐Ÿ› - TERAI Atsuhiro
    TERAI Atsuhiro

    ๐Ÿ› + TERAI Atsuhiro
    TERAI Atsuhiro

    ๐Ÿ› TIOBE Software
    TIOBE Software

    ๐Ÿ’ป ๐Ÿ› Tarush Singh
    Tarush Singh

    ๐Ÿ’ป Taylor Smock
    Taylor Smock

    ๐Ÿ› Techeira Damiรกn
    Techeira Damiรกn

    ๐Ÿ’ป ๐Ÿ› Ted Husted
    Ted Husted

    ๐Ÿ› TehBakker
    TehBakker

    ๐Ÿ› - The Gitter Badger
    The Gitter Badger

    ๐Ÿ› + The Gitter Badger
    The Gitter Badger

    ๐Ÿ› Theodoor
    Theodoor

    ๐Ÿ› Thiago Henrique Hรผpner
    Thiago Henrique Hรผpner

    ๐Ÿ› Thibault Meyer
    Thibault Meyer

    ๐Ÿ› Thomas Gรผttler
    Thomas Gรผttler

    ๐Ÿ› Thomas Jones-Low
    Thomas Jones-Low

    ๐Ÿ› Thomas Smith
    Thomas Smith

    ๐Ÿ’ป ๐Ÿ› - ThrawnCA
    ThrawnCA

    ๐Ÿ› + ThrawnCA
    ThrawnCA

    ๐Ÿ› Thu Vo
    Thu Vo

    ๐Ÿ› Thunderforge
    Thunderforge

    ๐Ÿ’ป ๐Ÿ› Tim van der Lippe
    Tim van der Lippe

    ๐Ÿ› Tobias Weimer
    Tobias Weimer

    ๐Ÿ’ป ๐Ÿ› Tom Copeland
    Tom Copeland

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– Tom Daly
    Tom Daly

    ๐Ÿ› - Tomas
    Tomas

    ๐Ÿ› + Tomas
    Tomas

    ๐Ÿ› Tomer Figenblat
    Tomer Figenblat

    ๐Ÿ› Tomi De Lucca
    Tomi De Lucca

    ๐Ÿ’ป ๐Ÿ› Tony
    Tony

    ๐Ÿ“– Torsten Kleiber
    Torsten Kleiber

    ๐Ÿ› TrackerSB
    TrackerSB

    ๐Ÿ› Tyson Stewart
    Tyson Stewart

    ๐Ÿ› - Ullrich Hafner
    Ullrich Hafner

    ๐Ÿ› + Ullrich Hafner
    Ullrich Hafner

    ๐Ÿ› Utku Cuhadaroglu
    Utku Cuhadaroglu

    ๐Ÿ’ป ๐Ÿ› Valentin Brandl
    Valentin Brandl

    ๐Ÿ› Valeria
    Valeria

    ๐Ÿ› Valery Yatsynovich
    Valery Yatsynovich

    ๐Ÿ“– Vasily Anisimov
    Vasily Anisimov

    ๐Ÿ› Vedant Chokshi
    Vedant Chokshi

    ๐Ÿ› - Vibhor Goyal
    Vibhor Goyal

    ๐Ÿ› + Vibhor Goyal
    Vibhor Goyal

    ๐Ÿ› Vickenty Fesunov
    Vickenty Fesunov

    ๐Ÿ› Victor Noรซl
    Victor Noรซl

    ๐Ÿ› Vincent Galloy
    Vincent Galloy

    ๐Ÿ’ป Vincent HUYNH
    Vincent HUYNH

    ๐Ÿ› Vincent Maurin
    Vincent Maurin

    ๐Ÿ› Vincent Privat
    Vincent Privat

    ๐Ÿ› - Vishhwas
    Vishhwas

    ๐Ÿ› + Vishhwas
    Vishhwas

    ๐Ÿ› Vishv_Android
    Vishv_Android

    ๐Ÿ› Vitaly
    Vitaly

    ๐Ÿ› Vitaly Polonetsky
    Vitaly Polonetsky

    ๐Ÿ› Vojtech Polivka
    Vojtech Polivka

    ๐Ÿ› Vsevolod Zholobov
    Vsevolod Zholobov

    ๐Ÿ› Vyom Yadav
    Vyom Yadav

    ๐Ÿ’ป - Wang Shidong
    Wang Shidong

    ๐Ÿ› + Wang Shidong
    Wang Shidong

    ๐Ÿ› Waqas Ahmed
    Waqas Ahmed

    ๐Ÿ› Wayne J. Earl
    Wayne J. Earl

    ๐Ÿ› Wchenghui
    Wchenghui

    ๐Ÿ› Wener
    Wener

    ๐Ÿ’ป Will Winder
    Will Winder

    ๐Ÿ› William Brockhus
    William Brockhus

    ๐Ÿ’ป ๐Ÿ› - Wilson Kurniawan
    Wilson Kurniawan

    ๐Ÿ› + Wilson Kurniawan
    Wilson Kurniawan

    ๐Ÿ› Wim Deblauwe
    Wim Deblauwe

    ๐Ÿ› Woongsik Choi
    Woongsik Choi

    ๐Ÿ› XenoAmess
    XenoAmess

    ๐Ÿ’ป ๐Ÿ› Yang
    Yang

    ๐Ÿ’ป YaroslavTER
    YaroslavTER

    ๐Ÿ› Yasar Shaikh
    Yasar Shaikh

    ๐Ÿ’ป - Young Chan
    Young Chan

    ๐Ÿ’ป ๐Ÿ› + Young Chan
    Young Chan

    ๐Ÿ’ป ๐Ÿ› YuJin Kim
    YuJin Kim

    ๐Ÿ› Yuri Dolzhenko
    Yuri Dolzhenko

    ๐Ÿ› Yurii Dubinka
    Yurii Dubinka

    ๐Ÿ› Zoltan Farkas
    Zoltan Farkas

    ๐Ÿ› Zustin
    Zustin

    ๐Ÿ› aaronhurst-google
    aaronhurst-google

    ๐Ÿ› ๐Ÿ’ป - alexmodis
    alexmodis

    ๐Ÿ› + alexmodis
    alexmodis

    ๐Ÿ› andreoss
    andreoss

    ๐Ÿ› andrey81inmd
    andrey81inmd

    ๐Ÿ’ป ๐Ÿ› anicoara
    anicoara

    ๐Ÿ› arunprasathav
    arunprasathav

    ๐Ÿ› asiercamara
    asiercamara

    ๐Ÿ› astillich-igniti
    astillich-igniti

    ๐Ÿ’ป - avesolovksyy
    avesolovksyy

    ๐Ÿ› + avesolovksyy
    avesolovksyy

    ๐Ÿ› avishvat
    avishvat

    ๐Ÿ› avivmu
    avivmu

    ๐Ÿ› axelbarfod1
    axelbarfod1

    ๐Ÿ› b-3-n
    b-3-n

    ๐Ÿ› balbhadra9
    balbhadra9

    ๐Ÿ› base23de
    base23de

    ๐Ÿ› - bergander
    bergander

    ๐Ÿ› ๐Ÿ’ป + bergander
    bergander

    ๐Ÿ› ๐Ÿ’ป berkam
    berkam

    ๐Ÿ’ป ๐Ÿ› breizh31
    breizh31

    ๐Ÿ› caesarkim
    caesarkim

    ๐Ÿ› carolyujing
    carolyujing

    ๐Ÿ› cbfiddle
    cbfiddle

    ๐Ÿ› cesares-basilico
    cesares-basilico

    ๐Ÿ› - chrite
    chrite

    ๐Ÿ› + chrite
    chrite

    ๐Ÿ› ciufudean
    ciufudean

    ๐Ÿ“– cobratbq
    cobratbq

    ๐Ÿ› coladict
    coladict

    ๐Ÿ› cosmoJFH
    cosmoJFH

    ๐Ÿ› cristalp
    cristalp

    ๐Ÿ› crunsk
    crunsk

    ๐Ÿ› - cwholmes
    cwholmes

    ๐Ÿ› + cwholmes
    cwholmes

    ๐Ÿ› cyberjj999
    cyberjj999

    ๐Ÿ› cyw3
    cyw3

    ๐Ÿ› ๐Ÿ“– d1ss0nanz
    d1ss0nanz

    ๐Ÿ› dague1
    dague1

    ๐Ÿ“– dalizi007
    dalizi007

    ๐Ÿ’ป danbrycefairsailcom
    danbrycefairsailcom

    ๐Ÿ› - dariansanity
    dariansanity

    ๐Ÿ› + dariansanity
    dariansanity

    ๐Ÿ› darrenmiliband
    darrenmiliband

    ๐Ÿ› davidburstrom
    davidburstrom

    ๐Ÿ› dbirkman-paloalto
    dbirkman-paloalto

    ๐Ÿ› deepak-patra
    deepak-patra

    ๐Ÿ› dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› dinesh150
    dinesh150

    ๐Ÿ› - diziaq
    diziaq

    ๐Ÿ› + diziaq
    diziaq

    ๐Ÿ› dreaminpast123
    dreaminpast123

    ๐Ÿ› duanyanan
    duanyanan

    ๐Ÿ› dutt-sanjay
    dutt-sanjay

    ๐Ÿ› duursma
    duursma

    ๐Ÿ’ป dylanleung
    dylanleung

    ๐Ÿ› dzeigler
    dzeigler

    ๐Ÿ› - eant60
    eant60

    ๐Ÿ› + eant60
    eant60

    ๐Ÿ› ekkirala
    ekkirala

    ๐Ÿ› emersonmoura
    emersonmoura

    ๐Ÿ› emouty
    emouty

    ๐Ÿ’ป eugenepugach
    eugenepugach

    ๐Ÿ› fairy
    fairy

    ๐Ÿ› filiprafalowicz
    filiprafalowicz

    ๐Ÿ’ป - flxbl-io
    flxbl-io

    ๐Ÿ’ต + flxbl-io
    flxbl-io

    ๐Ÿ’ต foxmason
    foxmason

    ๐Ÿ› frankegabor
    frankegabor

    ๐Ÿ› frankl
    frankl

    ๐Ÿ› freafrea
    freafrea

    ๐Ÿ› fsapatin
    fsapatin

    ๐Ÿ› gearsethenry
    gearsethenry

    ๐Ÿ› - gracia19
    gracia19

    ๐Ÿ› + gracia19
    gracia19

    ๐Ÿ› gudzpoz
    gudzpoz

    ๐Ÿ› guo fei
    guo fei

    ๐Ÿ› gurmsc5
    gurmsc5

    ๐Ÿ› gwilymatgearset
    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ› haigsn
    haigsn

    ๐Ÿ› hemanshu070
    hemanshu070

    ๐Ÿ› - henrik242
    henrik242

    ๐Ÿ› + henrik242
    henrik242

    ๐Ÿ› hongpuwu
    hongpuwu

    ๐Ÿ› hvbtup
    hvbtup

    ๐Ÿ’ป ๐Ÿ› igniti GmbH
    igniti GmbH

    ๐Ÿ› ilovezfs
    ilovezfs

    ๐Ÿ› imax-erik
    imax-erik

    ๐Ÿ› itaigilo
    itaigilo

    ๐Ÿ› - jakivey32
    jakivey32

    ๐Ÿ› + jakivey32
    jakivey32

    ๐Ÿ› jbennett2091
    jbennett2091

    ๐Ÿ› jcamerin
    jcamerin

    ๐Ÿ› jkeener1
    jkeener1

    ๐Ÿ› jmetertea
    jmetertea

    ๐Ÿ› johnra2
    johnra2

    ๐Ÿ’ป johnzhao9
    johnzhao9

    ๐Ÿ› - josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ› + josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ› kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ› karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“– karwer
    karwer

    ๐Ÿ› kaulonline
    kaulonline

    ๐Ÿ› kdaemonv
    kdaemonv

    ๐Ÿ› kdebski85
    kdebski85

    ๐Ÿ› ๐Ÿ’ป - kenji21
    kenji21

    ๐Ÿ’ป ๐Ÿ› + kenji21
    kenji21

    ๐Ÿ’ป ๐Ÿ› kfranic
    kfranic

    ๐Ÿ› khalidkh
    khalidkh

    ๐Ÿ› koalalam
    koalalam

    ๐Ÿ› krzyk
    krzyk

    ๐Ÿ› lasselindqvist
    lasselindqvist

    ๐Ÿ› lgemeinhardt
    lgemeinhardt

    ๐Ÿ› - lihuaib
    lihuaib

    ๐Ÿ› + lihuaib
    lihuaib

    ๐Ÿ› liqingjun123
    liqingjun123

    ๐Ÿ› lonelyma1021
    lonelyma1021

    ๐Ÿ› lpeddy
    lpeddy

    ๐Ÿ› lujiefsi
    lujiefsi

    ๐Ÿ’ป lukelukes
    lukelukes

    ๐Ÿ’ป lyriccoder
    lyriccoder

    ๐Ÿ› - marcelmore
    marcelmore

    ๐Ÿ› + marcelmore
    marcelmore

    ๐Ÿ› matchbox
    matchbox

    ๐Ÿ› matthiaskraaz
    matthiaskraaz

    ๐Ÿ› meandonlyme
    meandonlyme

    ๐Ÿ› mikesive
    mikesive

    ๐Ÿ› milossesic
    milossesic

    ๐Ÿ› mluckam
    mluckam

    ๐Ÿ’ป ๐Ÿ› - mohan-chinnappan-n
    mohan-chinnappan-n

    ๐Ÿ’ป + mohan-chinnappan-n
    mohan-chinnappan-n

    ๐Ÿ’ป mriddell95
    mriddell95

    ๐Ÿ› mrlzh
    mrlzh

    ๐Ÿ› msloan
    msloan

    ๐Ÿ› mucharlaravalika
    mucharlaravalika

    ๐Ÿ› mvenneman
    mvenneman

    ๐Ÿ› nareshl119
    nareshl119

    ๐Ÿ› - nicolas-harraudeau-sonarsource
    nicolas-harraudeau-sonarsource

    ๐Ÿ› + nicolas-harraudeau-sonarsource
    nicolas-harraudeau-sonarsource

    ๐Ÿ› noerremark
    noerremark

    ๐Ÿ› novsirion
    novsirion

    ๐Ÿ› nwcm
    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
    oggboy

    ๐Ÿ› oinume
    oinume

    ๐Ÿ› orimarko
    orimarko

    ๐Ÿ’ป ๐Ÿ› - pablogomez2197
    pablogomez2197

    ๐Ÿ› + pablogomez2197
    pablogomez2197

    ๐Ÿ› pacvz
    pacvz

    ๐Ÿ’ป pallavi agarwal
    pallavi agarwal

    ๐Ÿ› parksungrin
    parksungrin

    ๐Ÿ› patpatpat123
    patpatpat123

    ๐Ÿ› patriksevallius
    patriksevallius

    ๐Ÿ› pbrajesh1
    pbrajesh1

    ๐Ÿ› - phoenix384
    phoenix384

    ๐Ÿ› + phoenix384
    phoenix384

    ๐Ÿ› piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป plan3d
    plan3d

    ๐Ÿ› poojasix
    poojasix

    ๐Ÿ› prabhushrikant
    prabhushrikant

    ๐Ÿ› pujitha8783
    pujitha8783

    ๐Ÿ› r-r-a-j
    r-r-a-j

    ๐Ÿ› - raghujayjunk
    raghujayjunk

    ๐Ÿ› + raghujayjunk
    raghujayjunk

    ๐Ÿ› rajeshveera
    rajeshveera

    ๐Ÿ› rajeswarreddy88
    rajeswarreddy88

    ๐Ÿ› recdevs
    recdevs

    ๐Ÿ› reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ› rijkt
    rijkt

    ๐Ÿ› rillig-tk
    rillig-tk

    ๐Ÿ› - rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ› + rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ› rnveach
    rnveach

    ๐Ÿ› rxmicro
    rxmicro

    ๐Ÿ› ryan-gustafson
    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ› sabi0
    sabi0

    ๐Ÿ› scais
    scais

    ๐Ÿ› schosin
    schosin

    ๐Ÿ› - screamingfrog
    screamingfrog

    ๐Ÿ’ต + screamingfrog
    screamingfrog

    ๐Ÿ’ต sebbASF
    sebbASF

    ๐Ÿ› sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป shilko2013
    shilko2013

    ๐Ÿ› shiomiyan
    shiomiyan

    ๐Ÿ“– simeonKondr
    simeonKondr

    ๐Ÿ› snajberk
    snajberk

    ๐Ÿ› - sniperrifle2004
    sniperrifle2004

    ๐Ÿ› + sniperrifle2004
    sniperrifle2004

    ๐Ÿ› snuyanzin
    snuyanzin

    ๐Ÿ› ๐Ÿ’ป soloturn
    soloturn

    ๐Ÿ› soyodream
    soyodream

    ๐Ÿ› sratz
    sratz

    ๐Ÿ› stonio
    stonio

    ๐Ÿ› sturton
    sturton

    ๐Ÿ’ป ๐Ÿ› - sudharmohan
    sudharmohan

    ๐Ÿ› + sudharmohan
    sudharmohan

    ๐Ÿ› suruchidawar
    suruchidawar

    ๐Ÿ› svenfinitiv
    svenfinitiv

    ๐Ÿ› szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป tashiscool
    tashiscool

    ๐Ÿ› test-git-hook
    test-git-hook

    ๐Ÿ› testation21
    testation21

    ๐Ÿ’ป ๐Ÿ› - thanosa
    thanosa

    ๐Ÿ› + thanosa
    thanosa

    ๐Ÿ› tiandiyixian
    tiandiyixian

    ๐Ÿ› tobwoerk
    tobwoerk

    ๐Ÿ› tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป trentchilders
    trentchilders

    ๐Ÿ› triandicAnt
    triandicAnt

    ๐Ÿ› trishul14
    trishul14

    ๐Ÿ› - tsui
    tsui

    ๐Ÿ› + tsui
    tsui

    ๐Ÿ› wangzitom12306
    wangzitom12306

    ๐Ÿ› winhkey
    winhkey

    ๐Ÿ› witherspore
    witherspore

    ๐Ÿ› wjljack
    wjljack

    ๐Ÿ› wuchiuwong
    wuchiuwong

    ๐Ÿ› xingsong
    xingsong

    ๐Ÿ› - xioayuge
    xioayuge

    ๐Ÿ› + xioayuge
    xioayuge

    ๐Ÿ› xnYi9wRezm
    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ› xuanuy
    xuanuy

    ๐Ÿ› xyf0921
    xyf0921

    ๐Ÿ› yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› yasuharu-sato
    yasuharu-sato

    ๐Ÿ› zenglian
    zenglian

    ๐Ÿ› - zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› + zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› zh3ng
    zh3ng

    ๐Ÿ› zt_soft
    zt_soft

    ๐Ÿ› ztt79
    ztt79

    ๐Ÿ› zzzzfeng
    zzzzfeng

    ๐Ÿ› รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› ไปป่ดตๆฐ
    ไปป่ดตๆฐ

    ๐Ÿ› + + ่Œ…ๅปถๅฎ‰
    ่Œ…ๅปถๅฎ‰

    ๐Ÿ’ป From ab1976382af7be6b424a5500a2ce5dc84e645238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Sat, 12 Oct 2024 17:28:18 -0300 Subject: [PATCH 0085/1962] Remove ant.contrib.jar property --- antlr4-wrapper.xml | 9 +-------- pmd-cs/pom.xml | 1 - pmd-dart/pom.xml | 1 - pmd-go/pom.xml | 1 - pmd-kotlin/pom.xml | 1 - pmd-lua/pom.xml | 1 - pmd-swift/pom.xml | 1 - pom.xml | 1 - 8 files changed, 1 insertion(+), 15 deletions(-) diff --git a/antlr4-wrapper.xml b/antlr4-wrapper.xml index 0832bd9bc0e..c3e4527f9fb 100644 --- a/antlr4-wrapper.xml +++ b/antlr4-wrapper.xml @@ -11,15 +11,8 @@ - root-node-name: name of the root node without prefix (eg "TopLevel"), will be made to implement RootNode See AntlrGeneratedParserBase - - It also uses the following maven properties: - - ant.contrib.jar: Location of the ant-contrib jar --> - - - - - + diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index f4879ed0e7b..0eec39f809d 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -30,7 +30,6 @@ - diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index f7727958328..496115127be 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -30,7 +30,6 @@ - diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index cf47e5217cc..4df297ebc94 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -30,7 +30,6 @@ - diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index 5e9dbf2e80e..40f19513de1 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -43,7 +43,6 @@ - diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index c8adda151f9..f3a24be6d33 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -30,7 +30,6 @@ - diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index 0c50cdc8181..023fa8dd390 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -42,7 +42,6 @@ - diff --git a/pom.xml b/pom.xml index 0f41e68e7db..871775ff545 100644 --- a/pom.xml +++ b/pom.xml @@ -123,7 +123,6 @@ ${project.basedir}/../javacc-wrapper.xml 1.0b3 - ${settings.localRepository}/ant-contrib/ant-contrib/${ant-contrib.version}/ant-contrib-${ant-contrib.version}.jar ${project.build.directory}/generated-sources/antlr4 ${project.basedir}/../antlr4-wrapper.xml From f834b8744de723ec38a41de0f73990521b79abf4 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 13 Oct 2024 12:26:31 +0200 Subject: [PATCH 0086/1962] [doc] Update release notes (#5258) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 197b7a4aec8..98d61841ae2 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -49,6 +49,7 @@ The old rule names still work but are deprecated. * [#4965](https://github.com/pmd/pmd/pull/4965): \[java] Rename JUnit rules with overly restrictive names - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) * [#5225](https://github.com/pmd/pmd/pull/5225): \[java] Fix #5067: CloseResource: False positive for FileSystems.getDefault() - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#5241](https://github.com/pmd/pmd/pull/5241): Ignore javacc code in coverage report - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5258](https://github.com/pmd/pmd/pull/5258): Ignore generated antlr classes in coverage reports - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) {% endtocmaker %} From 867b142ee4dfe47115fc5658266be5761c71d315 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 13 Oct 2024 12:03:17 +0200 Subject: [PATCH 0087/1962] Use plugin-classpath to simplify javacc-wrapper.xml javacc is on the antrun plugin's classpath. The javacc jar file doesn't need to be copied explicitly. --- javacc-wrapper.xml | 20 +++++--------------- pmd-cpp/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pom.xml | 2 +- 13 files changed, 17 insertions(+), 27 deletions(-) diff --git a/javacc-wrapper.xml b/javacc-wrapper.xml index 05837e96ba7..cde14d0ae19 100644 --- a/javacc-wrapper.xml +++ b/javacc-wrapper.xml @@ -25,9 +25,9 @@ It also uses the following maven properties: - javacc.outputDirectory: Directory in which to root the generated package tree - - javacc.jar: JAR of JavaCC in the local maven repository + - plugin-classpath: The classpath of maven-antrun-plugin with javacc.jar dependency + Provided by maven via "" - some properties of project.build - --> @@ -40,8 +40,6 @@ - - @@ -84,7 +82,7 @@ + depends="checkUpToDate,init,jjtree,jjtree-ersatz,javacc,adapt-generated,default-visitor" /> @@ -104,9 +102,6 @@ - - - @@ -117,11 +112,6 @@ - - - - - + classpath="${plugin-classpath}"> @@ -148,7 +138,7 @@ + classpath="${plugin-classpath}"> diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index adbfbd8e3cf..a42c4f850aa 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -34,10 +34,10 @@ + - diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index d8131b8d658..2d82829d151 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -105,7 +105,7 @@ - + diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index 5e4506efd46..ea4d55938d1 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -47,10 +47,10 @@ + - diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index 9f1d3fb2230..790d5353f82 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -40,7 +40,7 @@ - + diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index 373fa78a8d0..42a69e24975 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -34,10 +34,10 @@ + - diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index 639c224e2c5..d551bc25a14 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -64,7 +64,7 @@ - + diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index 66818f1a479..197c6dac58e 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -34,10 +34,10 @@ + - diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index 2e6ad097a4f..26a56142552 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -40,7 +40,7 @@ - + diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index 85b6643126f..30326faeeb3 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -34,10 +34,10 @@ + - diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index 6cb54b0cd5b..905cd6b41c5 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -43,7 +43,7 @@ - + diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index 7ae874578d6..164795a6232 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -47,7 +47,7 @@ - + diff --git a/pom.xml b/pom.xml index 67269e26ad2..fd7181a3489 100644 --- a/pom.xml +++ b/pom.xml @@ -118,7 +118,7 @@ 27 7.2.0 - ${settings.localRepository}/net/java/dev/javacc/javacc/${javacc.version}/javacc-${javacc.version}.jar + ${project.build.directory}/generated-sources/javacc ${project.basedir}/../javacc-wrapper.xml From 5ffb9531917fbc83344c98a9921b3fb340c633de Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Oct 2024 09:40:02 +0200 Subject: [PATCH 0088/1962] [java] CouplingBetweenObjects: improve violation message When we add the actual count to the message, we can more easily verify that the rule works as expected. --- .../lang/java/rule/design/CouplingBetweenObjectsRule.java | 6 +++--- pmd-java/src/main/resources/category/java/design.xml | 2 +- .../lang/java/rule/design/xml/CouplingBetweenObjects.xml | 6 ++++++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CouplingBetweenObjectsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CouplingBetweenObjectsRule.java index 527477529ce..230e0861c77 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CouplingBetweenObjectsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CouplingBetweenObjectsRule.java @@ -52,9 +52,9 @@ public CouplingBetweenObjectsRule() { public Object visit(ASTCompilationUnit cu, Object data) { super.visit(cu, data); - if (couplingCount > getProperty(THRESHOLD_DESCRIPTOR)) { - asCtx(data).addViolation(cu, - "A value of " + couplingCount + " may denote a high amount of coupling within the class"); + Integer threshold = getProperty(THRESHOLD_DESCRIPTOR); + if (couplingCount > threshold) { + asCtx(data).addViolation(cu, couplingCount, threshold); } couplingCount = 0; diff --git a/pmd-java/src/main/resources/category/java/design.xml b/pmd-java/src/main/resources/category/java/design.xml index 37ca5dc3cd2..d235d4239bd 100644 --- a/pmd-java/src/main/resources/category/java/design.xml +++ b/pmd-java/src/main/resources/category/java/design.xml @@ -377,7 +377,7 @@ class Foo { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/CouplingBetweenObjects.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/CouplingBetweenObjects.xml index 28b2e0abaf0..49a39332f1a 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/CouplingBetweenObjects.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/CouplingBetweenObjects.xml @@ -9,6 +9,9 @@ 2 1 1 + + A value of 3 may denote a high amount of coupling within the class (threshold: 2) + 2 1 1 + + A value of 3 may denote a high amount of coupling within the class (threshold: 2) + Date: Fri, 18 Oct 2024 15:36:28 +0200 Subject: [PATCH 0089/1962] [doc] Update release notes --- docs/pages/release_notes.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index c80d7c0cc25..83abd066f17 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -17,15 +17,14 @@ This is a {{ site.pmd.release_type }} release. ### ๐ŸŒŸ Rule Changes #### Renamed Rules -Several rules for unit testing have been renamed to better reflect their actual scope. Lots of them were called -after JUnit / JUnit 4, even when they applied to JUnit 5 and / or TestNG. - -* {% rule java/bestpractices/UnitTestAssertionsShouldIncludeMessage %} (Java Best Practices) has been renamed from `JUnitAssertionsShouldIncludeMessage`. -* {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} (Java Best Practices) has been renamed from `JUnitTestContainsTooManyAsserts`. -* {% rule java/bestpractices/UnitTestShouldIncludeAssert %} (Java Best Practices) has been renamed from `JUnitTestsShouldIncludeAssert`. -* {% rule java/bestpractices/UnitTestShouldUseAfterAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseAfterAnnotation`. -* {% rule java/bestpractices/UnitTestShouldUseBeforeAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseBeforeAnnotation`. -* {% rule java/bestpractices/UnitTestShouldUseTestAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseTestAnnotation`. +* Several rules for unit testing have been renamed to better reflect their actual scope. Lots of them were called + after JUnit / JUnit 4, even when they applied to JUnit 5 and / or TestNG. + * {% rule java/bestpractices/UnitTestAssertionsShouldIncludeMessage %} (Java Best Practices) has been renamed from `JUnitAssertionsShouldIncludeMessage`. + * {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} (Java Best Practices) has been renamed from `JUnitTestContainsTooManyAsserts`. + * {% rule java/bestpractices/UnitTestShouldIncludeAssert %} (Java Best Practices) has been renamed from `JUnitTestsShouldIncludeAssert`. + * {% rule java/bestpractices/UnitTestShouldUseAfterAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseAfterAnnotation`. + * {% rule java/bestpractices/UnitTestShouldUseBeforeAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseBeforeAnnotation`. + * {% rule java/bestpractices/UnitTestShouldUseTestAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseTestAnnotation`. The old rule names still work but are deprecated. @@ -49,12 +48,13 @@ The old rule names still work but are deprecated. ### โœจ Merged pull requests -* [#4965](https://github.com/pmd/pmd/pull/4965): \[java] Rename JUnit rules with overly restrictive names - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) -* [#5225](https://github.com/pmd/pmd/pull/5225): \[java] Fix #5067: CloseResource: False positive for FileSystems.getDefault() - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#4965](https://github.com/pmd/pmd/pull/4965): Fix #4532: \[java] Rename JUnit rules with overly restrictive names - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5225](https://github.com/pmd/pmd/pull/5225): Fix #5067: \[java] CloseResource: False positive for FileSystems.getDefault() - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#5241](https://github.com/pmd/pmd/pull/5241): Ignore javacc code in coverage report - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) * [#5258](https://github.com/pmd/pmd/pull/5258): Ignore generated antlr classes in coverage reports - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) -* [#5264](https://github.com/pmd/pmd/pull/5264): \[java] Fix NPE with empty pattern list - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5269](https://github.com/pmd/pmd/pull/5269): \[java] Fix #5253: Support Boolean wrapper class for BooleanGetMethodName rule - [Aryant Tripathi](https://github.com/Aryant-Tripathi) (@Aryant-Tripathi) +* [#5264](https://github.com/pmd/pmd/pull/5264): Fix #5261: \[java] Fix NPE with empty pattern list - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5269](https://github.com/pmd/pmd/pull/5269): Fix #5253: \[java] Support Boolean wrapper class for BooleanGetMethodName rule - [Aryant Tripathi](https://github.com/Aryant-Tripathi) (@Aryant-Tripathi) +* [#5275](https://github.com/pmd/pmd/pull/5275): Use plugin-classpath to simplify javacc-wrapper.xml - [Andreas Dangel](https://github.com/adangel) (@adangel) {% endtocmaker %} From f0375d61dd8987eada67ae7d584a3e1dcc3b680a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Oct 2024 15:39:52 +0200 Subject: [PATCH 0090/1962] [doc] Update release notes (#5278) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index c80d7c0cc25..a160b83a888 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -55,6 +55,7 @@ The old rule names still work but are deprecated. * [#5258](https://github.com/pmd/pmd/pull/5258): Ignore generated antlr classes in coverage reports - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) * [#5264](https://github.com/pmd/pmd/pull/5264): \[java] Fix NPE with empty pattern list - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5269](https://github.com/pmd/pmd/pull/5269): \[java] Fix #5253: Support Boolean wrapper class for BooleanGetMethodName rule - [Aryant Tripathi](https://github.com/Aryant-Tripathi) (@Aryant-Tripathi) +* [#5278](https://github.com/pmd/pmd/pull/5278): \[java] CouplingBetweenObjects: improve violation message - [Andreas Dangel](https://github.com/adangel) (@adangel) {% endtocmaker %} From 99f4c9c044478534d24c38431eb00f8dbd7cf8d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Oct 2024 16:04:35 +0200 Subject: [PATCH 0091/1962] Bump org.checkerframework:checker-qual from 2.11.1 to 3.48.1 (#5276) Bumps [org.checkerframework:checker-qual](https://github.com/typetools/checker-framework) from 2.11.1 to 3.48.1. - [Release notes](https://github.com/typetools/checker-framework/releases) - [Changelog](https://github.com/typetools/checker-framework/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/typetools/checker-framework/compare/checker-framework-2.11.1...checker-framework-3.48.1) --- updated-dependencies: - dependency-name: org.checkerframework:checker-qual dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fd7181a3489..d6535a613b4 100644 --- a/pom.xml +++ b/pom.xml @@ -853,7 +853,7 @@ org.checkerframework checker-qual - 2.11.1 + 3.48.1 net.sf.saxon From a0d4b38b5349d27bd4762080131e0362d2fe26da Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Oct 2024 16:16:54 +0200 Subject: [PATCH 0092/1962] [doc] Update release notes (#5245) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 5c5329437e8..088b0f9d061 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -55,6 +55,7 @@ The old rule names still work but are deprecated. * [#4965](https://github.com/pmd/pmd/pull/4965): Fix #4532: \[java] Rename JUnit rules with overly restrictive names - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) * [#5225](https://github.com/pmd/pmd/pull/5225): Fix #5067: \[java] CloseResource: False positive for FileSystems.getDefault() - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#5241](https://github.com/pmd/pmd/pull/5241): Ignore javacc code in coverage report - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5245](https://github.com/pmd/pmd/pull/5245): \[java] Improve UnitTestShouldUse{After,Before}Annotation rules to support JUnit5 and TestNG - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5258](https://github.com/pmd/pmd/pull/5258): Ignore generated antlr classes in coverage reports - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) * [#5264](https://github.com/pmd/pmd/pull/5264): Fix #5261: \[java] Fix NPE with empty pattern list - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5269](https://github.com/pmd/pmd/pull/5269): Fix #5253: \[java] Support Boolean wrapper class for BooleanGetMethodName rule - [Aryant Tripathi](https://github.com/Aryant-Tripathi) (@Aryant-Tripathi) From 81429a46288a8a119988d5acbf94ffcf1819423e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Oct 2024 16:21:02 +0200 Subject: [PATCH 0093/1962] [doc] Update release notes (#5247) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 5f7705b6916..6c8174d2411 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -53,6 +53,7 @@ The old rule names still work but are deprecated. * [#4965](https://github.com/pmd/pmd/pull/4965): Fix #4532: \[java] Rename JUnit rules with overly restrictive names - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) * [#5225](https://github.com/pmd/pmd/pull/5225): Fix #5067: \[java] CloseResource: False positive for FileSystems.getDefault() - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#5241](https://github.com/pmd/pmd/pull/5241): Ignore javacc code in coverage report - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5247](https://github.com/pmd/pmd/pull/5247): Fix #5030: \[java] SwitchDensity false positive with pattern matching - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5258](https://github.com/pmd/pmd/pull/5258): Ignore generated antlr classes in coverage reports - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) * [#5264](https://github.com/pmd/pmd/pull/5264): Fix #5261: \[java] Fix NPE with empty pattern list - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5269](https://github.com/pmd/pmd/pull/5269): Fix #5253: \[java] Support Boolean wrapper class for BooleanGetMethodName rule - [Aryant Tripathi](https://github.com/Aryant-Tripathi) (@Aryant-Tripathi) From fd8fcd67d66a181e6362305bcbe19a19d1b793fd Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Oct 2024 16:23:17 +0200 Subject: [PATCH 0094/1962] [doc] Update release notes (#5248) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index c0c6fea785d..85a758234cb 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -52,6 +52,7 @@ The old rule names still work but are deprecated. * [#4965](https://github.com/pmd/pmd/pull/4965): Fix #4532: \[java] Rename JUnit rules with overly restrictive names - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) * [#5225](https://github.com/pmd/pmd/pull/5225): Fix #5067: \[java] CloseResource: False positive for FileSystems.getDefault() - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#5241](https://github.com/pmd/pmd/pull/5241): Ignore javacc code in coverage report - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5248](https://github.com/pmd/pmd/pull/5248): Fix #3362: \[java] ImplicitSwitchFallThrough should consider switch expressions - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5258](https://github.com/pmd/pmd/pull/5258): Ignore generated antlr classes in coverage reports - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) * [#5264](https://github.com/pmd/pmd/pull/5264): Fix #5261: \[java] Fix NPE with empty pattern list - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5269](https://github.com/pmd/pmd/pull/5269): Fix #5253: \[java] Support Boolean wrapper class for BooleanGetMethodName rule - [Aryant Tripathi](https://github.com/Aryant-Tripathi) (@Aryant-Tripathi) From 665504decc34d037b674afe3fcf9ea13bc819484 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Oct 2024 16:30:41 +0200 Subject: [PATCH 0095/1962] [doc] Update release notes (#5251) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index f01329a652f..217f0640caf 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -58,6 +58,7 @@ The old rule names still work but are deprecated. * [#4965](https://github.com/pmd/pmd/pull/4965): Fix #4532: \[java] Rename JUnit rules with overly restrictive names - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) * [#5225](https://github.com/pmd/pmd/pull/5225): Fix #5067: \[java] CloseResource: False positive for FileSystems.getDefault() - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#5241](https://github.com/pmd/pmd/pull/5241): Ignore javacc code in coverage report - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5251](https://github.com/pmd/pmd/pull/5251): Fix #5249 and #5250: \[java] TooFewBranchesForSwitch ignore pattern matching and support switch expressions - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5258](https://github.com/pmd/pmd/pull/5258): Ignore generated antlr classes in coverage reports - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) * [#5264](https://github.com/pmd/pmd/pull/5264): Fix #5261: \[java] Fix NPE with empty pattern list - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5269](https://github.com/pmd/pmd/pull/5269): Fix #5253: \[java] Support Boolean wrapper class for BooleanGetMethodName rule - [Aryant Tripathi](https://github.com/Aryant-Tripathi) (@Aryant-Tripathi) From 5df7dccfb637ed83ba170723b7931adfe35c4752 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Oct 2024 16:40:27 +0200 Subject: [PATCH 0096/1962] [doc] Update release notes (#5255) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index c33b211b8aa..3290251f559 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -53,6 +53,7 @@ The old rule names still work but are deprecated. * [#4965](https://github.com/pmd/pmd/pull/4965): Fix #4532: \[java] Rename JUnit rules with overly restrictive names - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) * [#5225](https://github.com/pmd/pmd/pull/5225): Fix #5067: \[java] CloseResource: False positive for FileSystems.getDefault() - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#5241](https://github.com/pmd/pmd/pull/5241): Ignore javacc code in coverage report - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5255](https://github.com/pmd/pmd/pull/5255): \[java] Rename rule DefaultLabelNotLastInSwitch - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5258](https://github.com/pmd/pmd/pull/5258): Ignore generated antlr classes in coverage reports - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) * [#5264](https://github.com/pmd/pmd/pull/5264): Fix #5261: \[java] Fix NPE with empty pattern list - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5269](https://github.com/pmd/pmd/pull/5269): Fix #5253: \[java] Support Boolean wrapper class for BooleanGetMethodName rule - [Aryant Tripathi](https://github.com/Aryant-Tripathi) (@Aryant-Tripathi) From b60b4d8a682a0815566374c95cfac3bd2beaecb9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Oct 2024 16:42:52 +0200 Subject: [PATCH 0097/1962] Bump com.google.protobuf:protobuf-java from 3.25.3 to 4.28.2 (#5234) * Bump com.google.protobuf:protobuf-java from 3.25.3 to 4.28.2 Bumps [com.google.protobuf:protobuf-java](https://github.com/protocolbuffers/protobuf) from 3.25.3 to 4.28.2. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl) - [Commits](https://github.com/protocolbuffers/protobuf/commits) --- updated-dependencies: - dependency-name: com.google.protobuf:protobuf-java dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Cleanup comment about protobuf dependency --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andreas Dangel --- pom.xml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index d6535a613b4..87bf5c36419 100644 --- a/pom.xml +++ b/pom.xml @@ -1087,16 +1087,11 @@ test - + com.google.protobuf protobuf-java - 3.25.5 + 4.28.2 - 27 + 28-SNAPSHOT 7.2.0 @@ -569,22 +569,22 @@ net.sourceforge.pmd pmd-core - 7.5.0 + 7.7.0 net.sourceforge.pmd pmd-java - 7.5.0 + 7.7.0 net.sourceforge.pmd pmd-jsp - 7.5.0 + 7.7.0 net.sourceforge.pmd pmd-javascript - 7.5.0 + 7.7.0 From d68d6c57efa0d9e8d9613955b27a56662f6629cc Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 27 Oct 2024 15:53:00 +0100 Subject: [PATCH 0122/1962] Bump asm from 9.7 to 9.7.1 This enables support for Java 24 Refs #5154 --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index e429008001d..d91edae2cc9 100644 --- a/pom.xml +++ b/pom.xml @@ -592,11 +592,11 @@ pmd-build-tools-config ${pmd.build-tools.version} - + org.ow2.asm asm - 9.7 + 9.7.1 @@ -828,7 +828,7 @@ org.ow2.asm asm - 9.7 + 9.7.1 org.pcollections From 16eafc89c2cdf8c0a370ab98d979d41d5d799540 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 27 Oct 2024 16:24:05 +0100 Subject: [PATCH 0123/1962] [java] TooFewBranchesForSwitch - allow list of case constants Fixes #5287 --- docs/pages/release_notes.md | 2 + .../resources/category/java/performance.xml | 2 +- .../xml/TooFewBranchesForSwitch.xml | 42 +++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index bc1a36ec7a8..68f3742003e 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -15,6 +15,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* java-performance + * [#5287](https://github.com/pmd/pmd/issues/5287): \[java] TooFewBranchesForSwitch false-positive with switch using list of case constants ### ๐Ÿšจ API Changes diff --git a/pmd-java/src/main/resources/category/java/performance.xml b/pmd-java/src/main/resources/category/java/performance.xml index a8e4c37142b..8b2d4e20c5a 100644 --- a/pmd-java/src/main/resources/category/java/performance.xml +++ b/pmd-java/src/main/resources/category/java/performance.xml @@ -629,7 +629,7 @@ Note: This rule was named TooFewBranchesForASwitchStatement before PMD 7.7.0. diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForSwitch.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForSwitch.xml index e603390ec65..2da0d99a82d 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForSwitch.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForSwitch.xml @@ -136,6 +136,48 @@ public class SwitchWithRecordPattern { } } } +]]> +
    + + + #5287 [java] TooFewBranchesForSwitch false-positive with switch using list of case constants + 3 + 0 + 1; + default -> 0; + }; + } + + int checkSwitchStatement(SomeEnum someEnumValue) { + int result; + switch(someEnumValue) { + case A, B, C -> { result = 1; } + default -> { result = 0; } + } + return result; + } + + int checkSwitchExpressionGroup(SomeEnum someEnumValue) { + return switch(someEnumValue) { + case A, B, C: yield 1; + default: yield 0; + }; + } + + int checkSwitchStatementGroup(SomeEnum someEnumValue) { + int result; + switch(someEnumValue) { + case A, B, C: result = 1; break; + default: result = 0; break; + } + return result; + } +} ]]> From c81cd1d5203114ee42c781ce243ad044ff242944 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 03:31:36 +0000 Subject: [PATCH 0124/1962] Bump org.apache.maven.plugins:maven-assembly-plugin from 3.6.0 to 3.7.1 Bumps [org.apache.maven.plugins:maven-assembly-plugin](https://github.com/apache/maven-assembly-plugin) from 3.6.0 to 3.7.1. - [Release notes](https://github.com/apache/maven-assembly-plugin/releases) - [Commits](https://github.com/apache/maven-assembly-plugin/compare/maven-assembly-plugin-3.6.0...maven-assembly-plugin-3.7.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-assembly-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d91edae2cc9..d09220f92bf 100644 --- a/pom.xml +++ b/pom.xml @@ -179,7 +179,7 @@ org.apache.maven.plugins maven-assembly-plugin - 3.6.0 + 3.7.1 org.apache.maven.plugins From 69a92de52dddd720270f1a76ff27a9ccc5e8050c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Mon, 28 Oct 2024 22:10:21 -0300 Subject: [PATCH 0125/1962] Have pmd-xml Lexer in line with other antlr grammars - The package is no longer antlr4, but ast, as is in all other modules - We keep a deprecated proxy for backwards compatibility - We annotate the generated classes as such to ignore them from coverage reports --- pmd-xml/pom.xml | 22 +++++++++++++++++++ .../pmd/lang/xml/{antlr4 => ast}/XMLLexer.g4 | 0 .../pmd/lang/xml/antlr4/XMLLexer.java | 17 ++++++++++++++ .../pmd/lang/xml/cpd/XmlCpdLexer.java | 2 +- 4 files changed, 40 insertions(+), 1 deletion(-) rename pmd-xml/src/main/antlr4/net/sourceforge/pmd/lang/xml/{antlr4 => ast}/XMLLexer.g4 (100%) create mode 100644 pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index 1d19200b86a..676ba39759a 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -45,6 +45,28 @@ + + + org.apache.maven.plugins + maven-antrun-plugin + + + antlr-cleanup + generate-sources + + run + + + + + + + + + + + + diff --git a/pmd-xml/src/main/antlr4/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.g4 b/pmd-xml/src/main/antlr4/net/sourceforge/pmd/lang/xml/ast/XMLLexer.g4 similarity index 100% rename from pmd-xml/src/main/antlr4/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.g4 rename to pmd-xml/src/main/antlr4/net/sourceforge/pmd/lang/xml/ast/XMLLexer.g4 diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java new file mode 100644 index 00000000000..2425c51b9f3 --- /dev/null +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java @@ -0,0 +1,17 @@ +package net.sourceforge.pmd.lang.xml.antlr4; + +import org.antlr.v4.runtime.CharStream; + +/** + * Backwards compatible bridge. The XMLLexer was moved to align it with other PMD modules. + * This class will be removed in PMD 8.0.0. + * Use {@link net.sourceforge.pmd.lang.xml.ast.XMLLexer} directly instead. + * + * @deprecated + */ +@Deprecated +public class XMLLexer extends net.sourceforge.pmd.lang.xml.ast.XMLLexer { + public XMLLexer(CharStream input) { + super(input); + } +} diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/cpd/XmlCpdLexer.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/cpd/XmlCpdLexer.java index 62b077ab4b6..bf52b3d5591 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/cpd/XmlCpdLexer.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/cpd/XmlCpdLexer.java @@ -8,7 +8,7 @@ import org.antlr.v4.runtime.Lexer; import net.sourceforge.pmd.cpd.impl.AntlrCpdLexer; -import net.sourceforge.pmd.lang.xml.antlr4.XMLLexer; +import net.sourceforge.pmd.lang.xml.ast.XMLLexer; /** *

    Note: This class has been called XmlTokenizer in PMD 6

    . From 7119424d963ecc91dcfcb8c89c23e673754a6659 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Tue, 29 Oct 2024 16:56:30 -0300 Subject: [PATCH 0126/1962] Add license header --- .../java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java index 2425c51b9f3..23221fe7ccf 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java @@ -1,3 +1,6 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ package net.sourceforge.pmd.lang.xml.antlr4; import org.antlr.v4.runtime.CharStream; From 94095df8720322eb40fa9c7417cbbaea08af230d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Tue, 29 Oct 2024 17:21:24 -0300 Subject: [PATCH 0127/1962] Fix style issues --- .../main/java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java | 1 + 1 file changed, 1 insertion(+) diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java index 23221fe7ccf..e86b9cb58e9 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java @@ -1,6 +1,7 @@ /** * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ + package net.sourceforge.pmd.lang.xml.antlr4; import org.antlr.v4.runtime.CharStream; From 8a9e5eb0114410b16bd72508d9f19de265e6d827 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 13 Jun 2024 11:14:50 +0200 Subject: [PATCH 0128/1962] [java] Add test case for #2001 --- .../codestyle/unnecessaryimport/Issue2001.java | 11 +++++++++++ .../java/rule/codestyle/xml/UnnecessaryImport.xml | 14 ++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/unnecessaryimport/Issue2001.java diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/unnecessaryimport/Issue2001.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/unnecessaryimport/Issue2001.java new file mode 100644 index 00000000000..f90fd8a223b --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/unnecessaryimport/Issue2001.java @@ -0,0 +1,11 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryimport; + +public class Issue2001 { + public interface B { + // empty + } +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml index eb7b1c853b5..5f4ec7f3096 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml @@ -1317,4 +1317,18 @@ public class Foo { ]]>
    java 23-preview + + + [java] UnusedImports: False positive if nested interface is referenced in javadoc #2001 + 0 + + From dfb6817343a205068f2c09a7f4525ebb3a93f51d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 14 Jun 2024 20:41:18 +0200 Subject: [PATCH 0129/1962] [java] Add test case for #819 --- .../bestpractices/xml/UnusedPrivateMethod.xml | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index e81d963fcb5..479f90aa147 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2134,4 +2134,28 @@ public class ObtainViaTest { } ]]>
    + + + [java] UnusedPrivateMethod false positive when .class files missing from classpath #819 + 0 + + From a8c9aad093a0e52b595f33ec15f880e7da06295f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 21 Jun 2024 18:48:44 +0200 Subject: [PATCH 0130/1962] [java] Add test case for #913 --- .../testdata/ClassInDifferentPackage.java | 14 ++++++++++++++ .../testdata/deep/ClassInDifferentPackage.java | 15 +++++++++++++++ .../symbols/table/internal/HeaderScopesTest.kt | 10 ++++++++++ 3 files changed, 39 insertions(+) create mode 100644 pmd-java/src/test/java/javasymbols/testdata/ClassInDifferentPackage.java create mode 100644 pmd-java/src/test/java/javasymbols/testdata/deep/ClassInDifferentPackage.java diff --git a/pmd-java/src/test/java/javasymbols/testdata/ClassInDifferentPackage.java b/pmd-java/src/test/java/javasymbols/testdata/ClassInDifferentPackage.java new file mode 100644 index 00000000000..83070d42396 --- /dev/null +++ b/pmd-java/src/test/java/javasymbols/testdata/ClassInDifferentPackage.java @@ -0,0 +1,14 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package javasymbols.testdata; + +/** + * This class in this package shouldn't be confused by the class + * with the same name in sub-package {@code deep}. + * + * @see [java] Incorrect type resolution with classes having the same name #913 + */ +public class ClassInDifferentPackage { +} diff --git a/pmd-java/src/test/java/javasymbols/testdata/deep/ClassInDifferentPackage.java b/pmd-java/src/test/java/javasymbols/testdata/deep/ClassInDifferentPackage.java new file mode 100644 index 00000000000..1d3d5aa8d73 --- /dev/null +++ b/pmd-java/src/test/java/javasymbols/testdata/deep/ClassInDifferentPackage.java @@ -0,0 +1,15 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package javasymbols.testdata.deep; + +/** + * This class is in sub-package {@code deep} + * and shouldn't be confused by the class with the same name + * in parent package. + * + * @see [java] Incorrect type resolution with classes having the same name #913 + */ +public class ClassInDifferentPackage { +} diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/HeaderScopesTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/HeaderScopesTest.kt index ffa4b7efa1c..b5428ae72fb 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/HeaderScopesTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/HeaderScopesTest.kt @@ -373,4 +373,14 @@ class HeaderScopesTest : ProcessorTestSpec({ val block = acu.descendants(ASTBlock::class.java).firstOrThrow() block.symbolTable.types().shouldResolveToClass("List", "java.util.List") } + + parserTest("[java] Incorrect type resolution with classes having the same name #913") { + val acu1 = parser.parseClass(javasymbols.testdata.deep.ClassInDifferentPackage::class.java) + acu1.symbolTable.types().shouldResolveToClass("ClassInDifferentPackage", "javasymbols.testdata.deep.ClassInDifferentPackage") + TypeTestUtil.isExactlyA("javasymbols.testdata.deep.ClassInDifferentPackage", acu1.typeDeclarations.first()) + + val acu2 = parser.parseClass(javasymbols.testdata.ClassInDifferentPackage::class.java) + acu2.symbolTable.types().shouldResolveToClass("ClassInDifferentPackage", "javasymbols.testdata.ClassInDifferentPackage") + TypeTestUtil.isExactlyA("javasymbols.testdata.ClassInDifferentPackage", acu2.typeDeclarations.first()) + } }) From fa28b78e61905343ea8efecf74aedb9930a5e297 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 21 Jun 2024 18:52:05 +0200 Subject: [PATCH 0131/1962] [java] Add test case for #2206 --- .../xml/UnnecessaryLocalBeforeReturn.xml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryLocalBeforeReturn.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryLocalBeforeReturn.xml index 5f227de94a0..aebaa0f006f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryLocalBeforeReturn.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryLocalBeforeReturn.xml @@ -337,6 +337,23 @@ public class Example { } } } +]]> + + + + [java] UnnecessaryLocalBeforeReturn false positive when negating variable #2206 + 0 + From 7c0fd45a55048b5eb6c9810f82ee24bc3b5a49a0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 21 Jun 2024 18:57:05 +0200 Subject: [PATCH 0132/1962] [java] Comment existing test case for #2458 (#4201) --- .../java/rule/codestyle/xml/CommentDefaultAccessModifier.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/CommentDefaultAccessModifier.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/CommentDefaultAccessModifier.xml index 6375c33a895..b3c02a841e5 100755 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/CommentDefaultAccessModifier.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/CommentDefaultAccessModifier.xml @@ -490,11 +490,11 @@ class SomeTest { - [java] CommentDefaultAccessModifier should consider lombok's @Value #4201 + [java] CommentDefaultAccessModifier should consider lombok's @Value #4201 #2458 0 Date: Fri, 21 Jun 2024 19:05:11 +0200 Subject: [PATCH 0133/1962] [java] Add test case for #2540 --- .../ReturnEmptyCollectionRatherThanNull.xml | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ReturnEmptyCollectionRatherThanNull.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ReturnEmptyCollectionRatherThanNull.xml index effc4e57d1c..8b7500f3321 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ReturnEmptyCollectionRatherThanNull.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ReturnEmptyCollectionRatherThanNull.xml @@ -232,4 +232,43 @@ public class Foo { } ]]> + + + [java] Array: ReturnEmptyArrayRatherThanNull can not detect return null surrounded by if statement #2540 + 1 + 7 + + + + + [java] Collection: ReturnEmptyArrayRatherThanNull can not detect return null surrounded by if statement #2540 + 1 + 9 + readBytes() throws IOException { + int tag = is.read(); + if (tag == 'N') + return null; // violation + return new ArrayList<>(); + } +} +]]> + + From da0294e0464dbc3bf6e355c0dc49c3a9d526363a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 21 Jun 2024 19:08:36 +0200 Subject: [PATCH 0134/1962] [java] Add test case for #2535 --- .../xml/ClassCastExceptionWithToArray.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ClassCastExceptionWithToArray.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ClassCastExceptionWithToArray.xml index f8e9793738a..24608dd2766 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ClassCastExceptionWithToArray.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ClassCastExceptionWithToArray.xml @@ -109,4 +109,20 @@ public class Test { } ]]> + + + [java] ClassCastExceptionWithToArray can't detect the case that call toArray() in this.foo.toArray() #2535 + 1 + 6 + labels; + public String[] extractKey() { + return (String[]) this.labels.toArray(); + } +} +]]> + From e5739db90b1c399c6a6a2131dfbbe82d2210e59f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 12 Jul 2024 10:16:58 +0200 Subject: [PATCH 0135/1962] [java] Add test case for #2541 --- .../rule/design/xml/SimplifyConditional.xml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SimplifyConditional.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SimplifyConditional.xml index ad2f14df162..2e567fd481f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SimplifyConditional.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SimplifyConditional.xml @@ -128,4 +128,21 @@ public class Foo { } ]]> + + + [java] SimplifyConditional can not detect the case if(foo != null && (foo instanceof Bar)) #2541 + 4 + )) {} + if (temp != null && temp instanceof List) {} + + if (temp != null && (temp instanceof List)) {} + if (temp != null && temp instanceof List) {} + } +} +]]> + From 68eb546809e14f7e79f62b4c5223ce7be266f26d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 12 Jul 2024 10:21:27 +0200 Subject: [PATCH 0136/1962] [java] Add test case for #2718 --- .../xml/InvalidLogMessageFormat.xml | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml index bd9543b2c1b..31a4805cabb 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml @@ -1229,6 +1229,34 @@ public class MessageFormatWithThrowable { LOGGER.error("Uncaught exception - {}", thread.getName(), exception)); } } +]]> + + + + [java] InvalidLogMessageFormat rule : False positive for lambda parameter #2718 + 0 + LOG.warn( + "Failed on {}", + 1, + e.getLastThrowable())); + } +} ]]> From cfa80c7f86b849cc47afa1a9879ff935e6b355e2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 12 Jul 2024 10:30:25 +0200 Subject: [PATCH 0137/1962] [java] Add test case for #2743 --- .../switchstmtsshouldhavedefault/Animal.java | 11 +++++ .../bestpractices/xml/NonExhaustiveSwitch.xml | 46 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/switchstmtsshouldhavedefault/Animal.java diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/switchstmtsshouldhavedefault/Animal.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/switchstmtsshouldhavedefault/Animal.java new file mode 100644 index 00000000000..7450ce2c18d --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/switchstmtsshouldhavedefault/Animal.java @@ -0,0 +1,11 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.bestpractices.switchstmtsshouldhavedefault; + +public class Animal { + public SimpleEnum getType() { + return null; + } +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/NonExhaustiveSwitch.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/NonExhaustiveSwitch.xml index eba1aef0018..5f47c9b0305 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/NonExhaustiveSwitch.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/NonExhaustiveSwitch.xml @@ -375,6 +375,52 @@ public class SwitchMultipleCaseConstants { System.out.println(s); } } +]]> + + + + [java] False positive violation of SwitchStmtsShouldHaveDefault when using local variable inference #2743 + 0 + getAnimals() { return null; } + + void check() { + for (var animal : getAnimals()) { + switch (animal.getType()) { // false violation + case FOO: + // do something + break; + case BAR: + // do something + break; + case BZAZ: + // do something + break; + } + } + } + + void setValue(List list) { + list.forEach(eIn -> { + switch (eIn) { + case FOO: + // do something + break; + case BAR: + // do something + break; + case BZAZ: + // do something + break; + } + }); + } +} ]]> From 705e1d82f7fb5532aecb15cd9dbf5bd11c10180c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 19 Jul 2024 16:42:23 +0200 Subject: [PATCH 0138/1962] [java] Add test case for #2835 --- .../rule/errorprone/xml/CloseResource.xml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml index ac1c35d401b..102b4e23400 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml @@ -1317,6 +1317,27 @@ public class CloseResourceStream { ]]> + + #2835 [java] CloseResource false positive with Stream and ternary + 0 + getContainers() { + return null; + } + + public void bar() { + Foo foo = new Foo(); + final Stream containers = foo.getContainers() != null ? foo.getContainers().stream() : Stream.empty(); + System.out.println("count: " + containers.count()); + } +} +]]> + + #2402 [java] CloseResource possible false positive with primitive Streams 0 From 2a6cc059c882062c3948d82a345f172f4757d056 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 19 Jul 2024 16:50:53 +0200 Subject: [PATCH 0139/1962] [java] Add test case for #3080 --- .../AvoidDecimalLiteralsInBigDecimalConstructor.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AvoidDecimalLiteralsInBigDecimalConstructor.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AvoidDecimalLiteralsInBigDecimalConstructor.xml index 240559a14a0..9212ce01dd7 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AvoidDecimalLiteralsInBigDecimalConstructor.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AvoidDecimalLiteralsInBigDecimalConstructor.xml @@ -113,4 +113,16 @@ public class Foo { } ]]> + + #3080 [java] AvoidDecimalLiteralsInBigDecimalConstructor FP with PMD 6.30.0 + 0 + + From 54fea526a37660ce365901fd41cfa9bec3ac65b0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 19 Jul 2024 16:53:23 +0200 Subject: [PATCH 0140/1962] [java] Add test case for #3250 --- .../xml/InvalidLogMessageFormat.xml | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml index 31a4805cabb..d0b5d4e14ba 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml @@ -1259,4 +1259,44 @@ public class Foo { } ]]> + + + #3250 [java] InvalidLogMessageFormat detection failing when another %-parameter is used + 0 + + + + + #3250 [java] InvalidLogMessageFormat detection failing when another %-parameter is used in a variable + 0 + + From 09f500d9ee26e58f99e601224c6ae2fcf3003670 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 19 Jul 2024 17:02:58 +0200 Subject: [PATCH 0141/1962] [apex] Add test case for #4897 --- .../rule/security/xml/ApexCRUDViolation.xml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/security/xml/ApexCRUDViolation.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/security/xml/ApexCRUDViolation.xml index 9be853be4a9..ef3dbb3681f 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/security/xml/ApexCRUDViolation.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/security/xml/ApexCRUDViolation.xml @@ -1860,6 +1860,24 @@ trigger WidgetTrigger on Widget__c (before insert) { String test = Label.Test; Type c = MyTest.class; } +]]> + + + + #4897 [apex] ApexCRUDViolation incorrectly cleared when WITH SECURITY_ENFORCED is commented out + 1 + myMethod2() + { + List accounts = [ + SELECT Id, Name + FROM Account + // WITH SECURITY_ENFORCED + ]; + return accounts; + } +} ]]> From 0f3a5b41498a46166b3271d61aa10d3b5b18db4e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 6 Oct 2024 19:02:50 +0200 Subject: [PATCH 0142/1962] [java] Add test case for #3456 #3803 --- .../rule/security/xml/InsecureCryptoIv.xml | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/security/xml/InsecureCryptoIv.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/security/xml/InsecureCryptoIv.xml index 376f9de4b3f..374a0d4fd35 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/security/xml/InsecureCryptoIv.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/security/xml/InsecureCryptoIv.xml @@ -152,4 +152,39 @@ public class Foo { } ]]> + + + #3456 #3803 [java] A false negative about InsecureCryptoIv + 2 + 8,19 + + From 1e0b9a8413cc34f3b28b39bafa111275e27aa0f1 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 6 Oct 2024 19:13:56 +0200 Subject: [PATCH 0143/1962] [java] Add test case for #3632 --- .../bestpractices/xml/UnusedPrivateField.xml | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml index 7324803a06e..65c6b0cf801 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml @@ -828,6 +828,34 @@ public class Tester { private int x = 2021; // Unused, should report a warning }; } +]]> + + + + #3632 [java] Make UnusedPrivateField consider enum classes + 1 + 5 + + + + + #3632 [java] Make UnusedPrivateField consider enum classes (top-level) + 1 + 4 + From 7686431c50ce3e33557b72e7e33d216beed99309 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 6 Oct 2024 19:17:45 +0200 Subject: [PATCH 0144/1962] [java] Add test case for #3633 --- .../bestpractices/xml/UnusedPrivateMethod.xml | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index 479f90aa147..240c78b4f5e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2156,6 +2156,34 @@ class Engine { private void loadFromActiveResources(Key key, boolean isMemoryCacheable) { // false positive: not unused } } +]]> + + + + #3633 [java] Make UnusedPrivateMethod consider enum classes + 1 + 5 + + + + + #3633 [java] Make UnusedPrivateMethod consider enum classes (top-level) + 1 + 4 + From 10cb3692b16d388e5cf802c03ce2df6e14fade4f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 6 Oct 2024 19:21:31 +0200 Subject: [PATCH 0145/1962] [java] Add test case for #3685 --- .../xml/UseCollectionIsEmpty.xml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UseCollectionIsEmpty.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UseCollectionIsEmpty.xml index c3c449ea2f1..b2347b3cc11 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UseCollectionIsEmpty.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UseCollectionIsEmpty.xml @@ -566,6 +566,25 @@ public class Example { return new ArrayList<>(); } } +]]> + + + + #3685 [java] Make UseCollectionIsEmpty can detect collection of other class + 1 + 9 + list1 = new ArrayList<>(); +} +class Class2 { + public void foo() { + if(Class1.list1.size() == 0) {} // should report a warning here, but no warning + } +} ]]> From 55deef355cdceefee830bab6fea258a920f20875 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Oct 2024 16:10:10 +0200 Subject: [PATCH 0146/1962] [java] Add test case for #3432 --- .../xml/UnusedNullCheckInEquals.xml | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UnusedNullCheckInEquals.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UnusedNullCheckInEquals.xml index 78562a00081..424670d20b3 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UnusedNullCheckInEquals.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UnusedNullCheckInEquals.xml @@ -157,4 +157,63 @@ public class Foo { } ]]> + + + [java] UnusedNullCheckInEquals: various false positives #3432 + 1 + 22 + 0 && Bytes.equals(startRow,stopRow)); + } + + // overridden equals() that has more than two arguments - actual false positive, should not be reported + void case3a(HashingStrategy hashingStrategy, String k1, String k2) { + if (k1 == k2 || (k1 != null && hashingStrategy.equals(k1, k2))); + } + void case3b(String passthroughNsPrefix, Attribute attribute) { + if (passthroughNsPrefix != null && LexerUtils.equals(passthroughNsPrefix, attribute.namespacePrefix(), true, true)); + } + + // .class.getName() cannot return null - this should be reported, as the null check is indeed unused + void case4(String driverDelegate) { + if (driverDelegate != null && StdJDBCDelegate.class.getName().equals(driverDelegate)); // line 22 + if (driverDelegate != null && driverDelegate.equals(StdJDBCDelegate.class.getName())); // corrected version + } + + // null checked in condition of conditional expression + private int start; + private int length; + private String file; + void case5(UnusedNullCheckInEquals other) { + if (this.start == other.start && this.length == other.length && + (this.file == null ? other.file == null : (other.file != null && this.file.equals(other.file)))); + // note: the last check "other.file != null" is actually unnecessary, as we use this.file.equals(...) + // to compare with and this.file we already verified, cannot be null + } +} +class Other { + char[] name; +} +interface HashingStrategy { + boolean equals(String s1, String s2); +} +interface Attribute { + String namespacePrefix(); +} +class LexerUtils { + static boolean equals(String prefix1, String prefix2, boolean flag1, boolean flag2) { + return false; + } +} +class StdJDBCDelegate {} +]]> + From 21e5443c190c66a0c56ba5780302a3dad9ab1db9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Oct 2024 16:13:12 +0200 Subject: [PATCH 0147/1962] [java] Add test case for #3684 --- .../performance/xml/RedundantFieldInitializer.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/RedundantFieldInitializer.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/RedundantFieldInitializer.xml index 279f98007a1..a5aa7b1c35b 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/RedundantFieldInitializer.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/RedundantFieldInitializer.xml @@ -1493,4 +1493,16 @@ public class Test { } ]]> + + + [java] RedundantFieldInitializer FN with constant expressions #3684 + 2 + 2,3 + + From ed36b173dc89a6cd19212c15b15f6a6fb0d25c39 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Oct 2024 16:15:22 +0200 Subject: [PATCH 0148/1962] [java] Add test case for #3743 --- .../rule/performance/xml/RedundantFieldInitializer.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/RedundantFieldInitializer.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/RedundantFieldInitializer.xml index a5aa7b1c35b..1baeb0ce7be 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/RedundantFieldInitializer.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/RedundantFieldInitializer.xml @@ -1503,6 +1503,16 @@ class Impl { int a = 1 + 0 - 1; // should report a warning int b = 0 + 1 - 1; // can be detected } +]]> + + + + [java] RedundantFieldInitializer FP with expressions that start with zero #3743 + 0 + From bf9244826fdfda96f997f7c89cf7ab45bd291cb9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Oct 2024 16:17:28 +0200 Subject: [PATCH 0149/1962] [java] Add test case for #3628 --- .../bestpractices/xml/UnusedFormalParameter.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedFormalParameter.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedFormalParameter.xml index b595b408586..bf317468337 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedFormalParameter.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedFormalParameter.xml @@ -379,4 +379,19 @@ class ChildOfInner extends Outer.Inner { } ]]> + + + [java] Make UnusedFormalParameter consider enum classes #3628 + 1 + 5 + + From e6e54329be132719689a889b90cf4166ec3f289a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Oct 2024 16:19:18 +0200 Subject: [PATCH 0150/1962] [java] Add test case for #3629 --- .../lang/java/rule/design/xml/SingularField.xml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SingularField.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SingularField.xml index e1557165e39..38c438bc64d 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SingularField.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SingularField.xml @@ -1116,5 +1116,20 @@ public class AFTIPCTopologyWatcher { ]]> - + + [java] Make SingularField consider nested classes by default #3629 + 1 + 3 + + From 27b9421f83d67af9b7e1b6837190c79a46e78cd7 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Oct 2024 16:21:24 +0200 Subject: [PATCH 0151/1962] [java] Add test case for #3959 --- .../java/rule/errorprone/xml/NullAssignment.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/NullAssignment.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/NullAssignment.xml index 8798c3586f5..ea4d9807854 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/NullAssignment.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/NullAssignment.xml @@ -286,6 +286,22 @@ public class NullAssignmentConstructorCall { (discordClient == null) ? null : discordClient.getClass())); } } +]]> + + + + [java] A false negative for NullAssignment #3959 + 1 + 6 + From 567138afaaf8d02f8f5db347da848e99de195661 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Oct 2024 16:29:14 +0200 Subject: [PATCH 0152/1962] [java] Add test case for #3352 --- .../xml/LiteralsFirstInComparisons.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/LiteralsFirstInComparisons.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/LiteralsFirstInComparisons.xml index 0f4d38308f5..3d716d3b6f7 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/LiteralsFirstInComparisons.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/LiteralsFirstInComparisons.xml @@ -479,4 +479,17 @@ public class LiteralsFirstInComparisonBigInteger { } ]]> + + + [java] Regression with LiteralsFirstInComparisons in 6.35.0 #3352 + 0 + , Object, Boolean> ARG_CLASS_HAS_TOSTRING, Object arg, Object ctx) { + if (Boolean.TRUE.equals(ARG_CLASS_HAS_TOSTRING.apply(arg.getClass(), ctx))); + } +} +]]> + From 1bb7b5741a8300c0e248d42c46c6f6a928d92508 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Oct 2024 16:35:24 +0200 Subject: [PATCH 0153/1962] [java] Add test case for #3438 --- .../AvoidBranchingStatementAsLastInLoop.xml | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AvoidBranchingStatementAsLastInLoop.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AvoidBranchingStatementAsLastInLoop.xml index 420f6b2d6b1..8f63e047410 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AvoidBranchingStatementAsLastInLoop.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AvoidBranchingStatementAsLastInLoop.xml @@ -376,6 +376,40 @@ class A { } } } +]]> + + + + [java] A false positive negative by AvoidBranchingStatementAsLastInLoop when in a nested switch #3438 + 0 + From 7359fef88fc5c551a9ea336ec25990743303cf4a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Oct 2024 16:37:29 +0200 Subject: [PATCH 0154/1962] [java] Add test case for #3852 --- .../rule/design/xml/SimplifyBooleanReturns.xml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SimplifyBooleanReturns.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SimplifyBooleanReturns.xml index 9ef56b3eaa6..55d87688a00 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SimplifyBooleanReturns.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SimplifyBooleanReturns.xml @@ -265,4 +265,21 @@ public class SimplifyBooleanReturns { } ]]> + + + [java] SimplifyBooleanReturns should consider literal expression #3852 + 1 + 3 + + From 8204040e66647376f82d565400306e08ce2f500b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Oct 2024 16:39:13 +0200 Subject: [PATCH 0155/1962] [java] Add test case for #3933 --- .../bestpractices/xml/ArrayIsStoredDirectly.xml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/ArrayIsStoredDirectly.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/ArrayIsStoredDirectly.xml index 302c04bb121..8fee0dbfda9 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/ArrayIsStoredDirectly.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/ArrayIsStoredDirectly.xml @@ -345,6 +345,20 @@ public enum DemoEnum { this.values = values; } } +]]> + + + + [java] ArrayIsStoredDirectly false negative when parenthesized #3933 + 1 + 4 + From 3017a12b5164e86604837013332e1c0a5119d41b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Oct 2024 16:41:17 +0200 Subject: [PATCH 0156/1962] [java] Add test case for #3947 --- .../xml/CompareObjectsWithEquals.xml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CompareObjectsWithEquals.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CompareObjectsWithEquals.xml index 304865ca362..cab7acc80dd 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CompareObjectsWithEquals.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CompareObjectsWithEquals.xml @@ -499,4 +499,22 @@ public class EnumTest { ]]> + + [java] A false negative about the rule CompareObjectsWithEquals #3947 + 2 + 6,9 + + From 78cb3b7636e6e0d949bc69b6b0657b28e211d8b7 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Oct 2024 16:49:18 +0200 Subject: [PATCH 0157/1962] [java] Add test case for #4127 --- .../bestpractices/xml/UnusedAssignment.xml | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedAssignment.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedAssignment.xml index 5893fc117f0..f94cf73c5d7 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedAssignment.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedAssignment.xml @@ -3928,6 +3928,29 @@ public class Main { return r; } } +]]> + + + + [java] UnusedAssignment false-positive with try-with-resources #4127 + 0 + locks; + public static void foo() { + Lock lock; + synchronized (locks) { + lock = locks.get(0); + } + try (lock) { + // ... + } + } +} ]]> From d8f90d8979d34a272af0d8f26785fc2a742a23e3 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 12 Oct 2024 18:29:39 +0200 Subject: [PATCH 0158/1962] [java] Add test case for #4711 --- .../errorprone/xml/UseProperClassLoader.xml | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UseProperClassLoader.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UseProperClassLoader.xml index 416e1c72aec..997531cacb3 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UseProperClassLoader.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UseProperClassLoader.xml @@ -56,4 +56,24 @@ public class UseProperClassLoaderFP { } ]]> + + + [java] False-positive UseProperClassLoader #4711 + 0 + + From a145b0f29bc04a525fca4a71873bf54c8e531c40 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 12 Oct 2024 18:31:32 +0200 Subject: [PATCH 0159/1962] [java] Add test case for #3956 --- .../lang/java/rule/design/xml/ImmutableField.xml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml index 17cece9399a..8b78b34e062 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml @@ -924,4 +924,18 @@ class Foo { } ]]> + + + [java] ImmutableField should consider fields in anonymous classes #3956 + 2 + 2,4 + + From b2a4e6bf37814ec49baed0a949152cc293f0bbcb Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 12 Oct 2024 18:32:58 +0200 Subject: [PATCH 0160/1962] [java] Add test case for #3957 --- .../lang/java/rule/design/xml/ImmutableField.xml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml index 8b78b34e062..897a56146ef 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml @@ -924,7 +924,7 @@ class Foo { } ]]> - + [java] ImmutableField should consider fields in anonymous classes #3956 2 @@ -936,6 +936,20 @@ public class C { private int f = 0; // should report a warning in this line }; } +]]> + + + + [java] ImmutableField should consider enum class #3957 + 1 + 4 + From 79926c6b9ba7ca145cabd4a6b063e573eb99fff4 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 12 Oct 2024 18:44:03 +0200 Subject: [PATCH 0161/1962] [java] Comment test case for #3975 --- .../rule/bestpractices/xml/UnusedAssignment.xml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedAssignment.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedAssignment.xml index f94cf73c5d7..eb78a510b82 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedAssignment.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedAssignment.xml @@ -1198,22 +1198,23 @@ public class Foo { - Definitions in try block reach catch blocks through method calls + Definitions in try block reach catch blocks through method calls (#3975) 1 4 + The initializer for variable 'halfway' is never used (overwritten on line 7) - + - Definitions in try block reach catch blocks through method calls 2 + Definitions in try block reach catch blocks through method calls 2 (#3975) 1 4 @@ -1251,8 +1252,8 @@ public class Foo { ]]> - Definitions in try block reach catch blocks through method calls 3 - + Definitions in try block reach catch blocks through method calls 3 (#3975) + 0 From 84355d6375de0413bf16c525181a825d7ed0949f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 12 Oct 2024 18:46:13 +0200 Subject: [PATCH 0162/1962] [java] Add test case for #4013 --- .../xml/InefficientEmptyStringCheck.xml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InefficientEmptyStringCheck.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InefficientEmptyStringCheck.xml index c9a32ebc1cd..9a7db9f41d1 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InefficientEmptyStringCheck.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InefficientEmptyStringCheck.xml @@ -320,4 +320,23 @@ public class StringTrimMethodArgument { } ]]> + + + [java] InefficientEmptyStringCheck false negatives #4013 + 2 + 3,7 + 0 ) { // false negative + config.set( var, true ); + var = token; + } + if( var != null && var.trim().length() > 0 ) { // false negative + config.set( var, true ); + } + } +} +]]> + From 290a6f573ac5babc6b5764e9d1b189a054777ad1 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Oct 2024 09:42:04 +0200 Subject: [PATCH 0163/1962] [java] Add test case for #2818 --- .../design/xml/CouplingBetweenObjects.xml | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/CouplingBetweenObjects.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/CouplingBetweenObjects.xml index 49a39332f1a..9c172b92dde 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/CouplingBetweenObjects.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/CouplingBetweenObjects.xml @@ -68,4 +68,32 @@ public interface Foo { } ]]> + + + [java] CouplingBetweenObjectsRule does not count attribute and local variable couplings properly #2818 + 2 + 1 + 1 + + A value of 4 may denote a high amount of coupling within the class (threshold: 2) + + + From 2b7cb4de395c7ee52a89884207a4262717e48767 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Oct 2024 09:52:16 +0200 Subject: [PATCH 0164/1962] [java] Add test case for #3083 --- .../xml/UnnecessaryFullyQualifiedName.xml | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml index 056c77453e1..97c76278955 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml @@ -1123,6 +1123,114 @@ public class Foo { } }; } +]]> + + + + [java] UnnecessaryFullyQualifiedName: False positive with shadowed static method import #3083 + 0 + > implements Tree { + private TreeNode root; + + public BinaryTree() { + root = null; + } + + @Override + public void add(E obj) { + requireNonNull(obj); + if (isNull(root)) + root = new TreeNode<>(obj, null, null); + else + root.insert(obj); + } + + @Override + public boolean contains(E obj) { + requireNonNull(obj); + return nonNull(root) ? nonNull(root.find(obj)) : false; + } + + @Override + public void remove(E obj) { + if (nonNull(root)) + root = root.remove(obj, root); + } + + @Override + public Iterator iterator(TraversalOrder order) { + return null; + } + + private static class TreeNode> { + T val; + TreeNode left; + TreeNode right; + + TreeNode(T val, TreeNode left, TreeNode right) { + this.val = val; + this.left = left; + this.right = right; + } + + public void insert(T obj) { + requireNonNull(obj); + if (val.compareTo(obj) < 0) { + if (isNull(right)) right = new TreeNode<>(obj, null, null); + else right.insert(obj); + } + else { + if (isNull(left)) + left = new TreeNode<>(obj, null, null); + else left.insert(obj); + } + } + + public TreeNode find(T obj) { + int temp = val.compareTo(obj); + if (temp == 0) return this; + if (temp < 0) return isNull(right) ? null : right.find(obj); + return isNull(left) ? null : left.find(obj); + } + + private TreeNode remove(T obj, TreeNode node) { + requireNonNull(obj); + TreeNode t = node; + if (isNull(t)) return t; + if (obj.compareTo(t.val) < 0) t.left = remove(obj, t.left); + else if (obj.compareTo(t.val) > 0) t.right = remove(obj, t.right); + else if (isNull(t.left) || isNull(t.right)) t = isNull(t.left) ? t.right : t.left; + else { + t.val = findMin(t.right).val; t.right = remove(t.val, t.right); + } + return t; + } + + private TreeNode findMin(TreeNode node) { + TreeNode t = node; + if (isNull(t)) return null; + while (nonNull(t.left)) + t = t.left; + return t; + } + + @Override + public String toString() { + return Objects.toString(val); // False-positive here for UnnecessaryFullyQualifiedName + } + } +} ]]> From de31dccc57d7a4ebf2bb7d575b08442b009b8151 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Oct 2024 09:55:28 +0200 Subject: [PATCH 0165/1962] [java] Add test case for #3292 --- .../bestpractices/xml/UnusedPrivateMethod.xml | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index 240c78b4f5e..93f093e31b6 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2184,6 +2184,50 @@ enum EnumClass { EnumClass() {} private void func(){}; // should report a warning here } +]]> + + + + [java] UnusedPrivateMethod: false positive with inner class instance method passed as a function reference parameter #3292 + 0 + combiner) { + return combiner.apply(new Holder("t1"), new Holder("t2")).value; + } + + private class Holder { + + private final String value; + + public Holder(String value) { + this.value = value; + } + + private Holder combine(Holder other) { // false positive - not unused, used as Holder::combine + return new Holder(value + separator + other.value); + } + } +} ]]> From 9fc7e4d59a7f7c4bcde099d92bcd49cfe3327ff0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Oct 2024 10:01:07 +0200 Subject: [PATCH 0166/1962] [java] Add test case for #3346 --- .../bestpractices/xml/NonExhaustiveSwitch.xml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/NonExhaustiveSwitch.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/NonExhaustiveSwitch.xml index 5f47c9b0305..4531e2695d5 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/NonExhaustiveSwitch.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/NonExhaustiveSwitch.xml @@ -421,6 +421,25 @@ public class Foo { }); } } +]]> + + + + [java] SwitchStmtsShouldHaveDefault and implicit default #3346 + 0 + From af1de670dfab63e99cc0dc88b4ef56de82e76fbe Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Oct 2024 10:10:09 +0200 Subject: [PATCH 0167/1962] [java] Add test case for #3350 --- .../UnitTestAssertionsShouldIncludeMessage.xml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestAssertionsShouldIncludeMessage.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestAssertionsShouldIncludeMessage.xml index 7081b82c701..987e97caf45 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestAssertionsShouldIncludeMessage.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestAssertionsShouldIncludeMessage.xml @@ -506,6 +506,24 @@ public class AssertionMessageTest { ]]> + + [java] JUnitAssertionsShouldIncludeMessage - False positive with AssertJ assertThat and JUnit5 #3350 + 0 + + + Assert calls should be considered in the whole file that contains at least one test case 1 From f5048e81dc155ba364265311d0c23fed909a023a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Oct 2024 10:15:32 +0200 Subject: [PATCH 0168/1962] [java] Add test case for #3370 --- .../xml/WhileLoopWithLiteralBoolean.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/WhileLoopWithLiteralBoolean.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/WhileLoopWithLiteralBoolean.xml index 8aeb255db33..5e9e86fac64 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/WhileLoopWithLiteralBoolean.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/WhileLoopWithLiteralBoolean.xml @@ -79,6 +79,22 @@ class Foo { ]]> + + [java] WhileLoopWithLiteralBoolean misses constant expression #3370 + 1 + 4 + + + do while false & false 8 From 726ba29756039f0eb6a011f82c67edb301870a80 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Oct 2024 10:17:22 +0200 Subject: [PATCH 0169/1962] [java] Add test case for #3433 --- .../errorprone/xml/InvalidLogMessageFormat.xml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml index d0b5d4e14ba..a25d5b28240 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml @@ -1299,4 +1299,21 @@ class TestInvalidLogMessageFormat { } ]]> + + + [java] False Positives in InvalidLogMessageFormat rule #3433 + 0 + + From e3471fa66b3a0a286f4b436263406d643f8af881 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Oct 2024 10:27:01 +0200 Subject: [PATCH 0170/1962] [java] Add test case for #4016 --- .../bestpractices/xml/UnusedPrivateMethod.xml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index 93f093e31b6..9526aabda56 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2228,6 +2228,25 @@ public class TestUnusedPrivateMethodWithFunctionReference { } } } +]]> + + + + [java] UnusedPrivateMethod false-positive when a private method defined in an inner private class is called. #4016 + 0 + From 1542861eaf0e8a8b15aa14bbaf818160fc73f2c1 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Oct 2024 10:30:22 +0200 Subject: [PATCH 0171/1962] [java] Add test case for #4043 --- .../xml/NonThreadSafeSingleton.xml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/multithreading/xml/NonThreadSafeSingleton.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/multithreading/xml/NonThreadSafeSingleton.xml index 9a177239f39..ae3e78a73df 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/multithreading/xml/NonThreadSafeSingleton.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/multithreading/xml/NonThreadSafeSingleton.xml @@ -194,4 +194,22 @@ public class Foo { } ]]> + + + [java] A false positive about the rule NonThreadSafeSingleton #4043 + 1 + 5 + + From 8d2f8f7e6247324bc4530b0e4d48632c7c299936 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Oct 2024 10:33:13 +0200 Subject: [PATCH 0172/1962] [java] Add test case for #3940 --- .../rule/bestpractices/xml/LooseCoupling.xml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/LooseCoupling.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/LooseCoupling.xml index f9680e117d0..2f20751204f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/LooseCoupling.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/LooseCoupling.xml @@ -327,4 +327,23 @@ public final class Foo> { } ]]> + + + [java] LooseCoupling FP with class literal #3940 + 0 + getCountriesDictionary() throws IOException { + final Map out = objectMapper.readValue(".....", HashMap.class); + return HashBiMap.create(out); + } +} +]]> + From 890ee3dd98aeea5e206149e4f702e016addf7f84 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Oct 2024 15:11:17 +0200 Subject: [PATCH 0173/1962] [java] Add test case for #2192 --- .../java/rule/design/xml/LawOfDemeter.xml | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/LawOfDemeter.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/LawOfDemeter.xml index 1e93cbc8451..3e9ecf78925 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/LawOfDemeter.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/LawOfDemeter.xml @@ -1253,6 +1253,65 @@ class MyObjectProvider { return new MyObject(); } } +]]> + + + + #2192 [java] LawOfDemeter: False negative with Try-resource block treated as function call by rule + 0 + "); + out.println(""); + out.println(results.getString("Surname")); + out.println(""); + out.println(""); + out.println(results.getString("Forenames")); + out.println(""); + out.println(""); + out.println(results.getString("PhoneNum")); + out.println(""); + out.println(""); + } + out.println(""); + } catch (SQLException sqlEx) { + printHtmlSelectError(out); + return; + } + out.println(""); + out.println(""); + out.flush(); + } +} ]]> From 1792bd85d7fcf34ed024077ba2a0a3ddb1731d43 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Oct 2024 15:18:20 +0200 Subject: [PATCH 0174/1962] [java] Add test case for #3801 --- .../java/rule/design/xml/LawOfDemeter.xml | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/LawOfDemeter.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/LawOfDemeter.xml index 3e9ecf78925..b17e617bc7e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/LawOfDemeter.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/LawOfDemeter.xml @@ -1312,6 +1312,47 @@ public class DbServlet extends HttpServlet { out.flush(); } } +]]> + + + + #3801 [java] LawOfDemeter - false negative with braces + 2 + 11,15 + From ad301cbc8da0bbfbfd47a1934a0d829d0bc6d9f3 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Oct 2024 15:29:52 +0200 Subject: [PATCH 0175/1962] [java] Add test case for #3820 --- .../xml/SimplifiableTestAssertion.xml | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/SimplifiableTestAssertion.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/SimplifiableTestAssertion.xml index 5aaee41acac..a0cc2ac38eb 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/SimplifiableTestAssertion.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/SimplifiableTestAssertion.xml @@ -659,5 +659,48 @@ public class Foo { ]]> + + #3820 [java] SimplifiableTestAssertion has a tendency to report false positives + 1 + 13 + + Assertion may be simplified using assertFalse + + + From 04e968407c7e9141e27a899583456fe252d12d53 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Oct 2024 15:32:31 +0200 Subject: [PATCH 0176/1962] [java] Add test case for #3860 --- .../rule/errorprone/xml/MoreThanOneLogger.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/MoreThanOneLogger.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/MoreThanOneLogger.xml index 85b61f00e43..a29904f9e7d 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/MoreThanOneLogger.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/MoreThanOneLogger.xml @@ -117,4 +117,19 @@ public record Reproducer(List smsIds) { } ]]> + + + #3860 [java] MoreThanOneLogger is reported on mocked Logger field + 0 + + From 963f54d7633e93bee6de213de716f28766f556c1 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Oct 2024 15:50:28 +0200 Subject: [PATCH 0177/1962] [java] Add test case for #3899 --- .../unusedprivatemethod/issue3899/Child.java | 8 +++++ .../unusedprivatemethod/issue3899/Parent.java | 8 +++++ .../issue3899/PmdTestCase.java | 22 ++++++++++++++ .../bestpractices/xml/UnusedPrivateMethod.xml | 29 +++++++++++++++++++ 4 files changed, 67 insertions(+) create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/issue3899/Child.java create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/issue3899/Parent.java create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/issue3899/PmdTestCase.java diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/issue3899/Child.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/issue3899/Child.java new file mode 100644 index 00000000000..dda3ec01b7e --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/issue3899/Child.java @@ -0,0 +1,8 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.bestpractices.unusedprivatemethod.issue3899; + +public class Child implements Parent { +} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/issue3899/Parent.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/issue3899/Parent.java new file mode 100644 index 00000000000..35298d43cbf --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/issue3899/Parent.java @@ -0,0 +1,8 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.bestpractices.unusedprivatemethod.issue3899; + +public interface Parent { +} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/issue3899/PmdTestCase.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/issue3899/PmdTestCase.java new file mode 100644 index 00000000000..63cc8b93f1b --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/issue3899/PmdTestCase.java @@ -0,0 +1,22 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.bestpractices.unusedprivatemethod.issue3899; + +public class PmdTestCase { + public void check() { + Child child = new Child(); + + checkChild(child); + checkParent(child); + } + + // OK + private void checkChild(Child child) { + } + + // This method results in "UnusedPrivateMethod: Avoid unused private methods such as 'checkParent(Parent)'" + private void checkParent(Parent parent) { // false positive + } +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index 9526aabda56..da7c0fa3fe8 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2247,6 +2247,35 @@ class OuterClass { return line; } } +]]> + + + + #3899 [java] UnusedPrivateMethod - false positive with JDK 17 + 0 + From d6043cd429325f35329b308afdb2472889fc9ae0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Oct 2024 15:54:41 +0200 Subject: [PATCH 0178/1962] [java] Add test case for #4046 --- .../java/rule/design/xml/ImmutableField.xml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml index 897a56146ef..0947ab4ef35 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml @@ -950,6 +950,27 @@ public class D { private int y = 42; // should have a warning in this line } } +]]> + + + + #4046 [java] Incorrect ImmutableField error on field with both declaration and constructor initializer + 0 + From ab6dcfb8ab2c9a2a1d4d01bceb827d0b72e50edf Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Oct 2024 19:54:34 +0200 Subject: [PATCH 0179/1962] [java] Add test case for #4062 --- .../xml/SimplifiableTestAssertion.xml | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/SimplifiableTestAssertion.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/SimplifiableTestAssertion.xml index a0cc2ac38eb..c604a9c830e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/SimplifiableTestAssertion.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/SimplifiableTestAssertion.xml @@ -701,6 +701,26 @@ class Envelope { public boolean equals(Envelope env, double eps, boolean epsIsRelative) { return true; } public Envelope getOriginalEnvelope() { return this; } } +]]> + + + + #4062 [java] A false negative about the rule SimplifiableTestAssertion + 1 + 9 + From c0ca2431dd13b086e3be6208d1ed2db61e377ea0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Oct 2024 19:59:25 +0200 Subject: [PATCH 0180/1962] [java] Add test case for #4078 --- .../xml/UseStringBufferForStringAppends.xml | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseStringBufferForStringAppends.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseStringBufferForStringAppends.xml index c07bc1c1fb8..b03fedc9dcd 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseStringBufferForStringAppends.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseStringBufferForStringAppends.xml @@ -665,4 +665,27 @@ public class UseStringBufferForStringAppendsFP { } ]]> + + + #4078 [java] False positive about the rule UseStringBufferForStringAppends + 4 + 4,6,12,13 + + From 3436001f73bd9b9fc978ca78803ea3947e06ffa5 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Oct 2024 20:02:57 +0200 Subject: [PATCH 0181/1962] [java] Add test case for #4703 --- .../bestpractices/xml/GuardLogStatement.xml | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/GuardLogStatement.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/GuardLogStatement.xml index 4c8970291da..5d53dbfa1d2 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/GuardLogStatement.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/GuardLogStatement.xml @@ -771,4 +771,24 @@ public class MyClass { } ]]> + + + #4703 [java] GuardLogStatement reports violation for Log4j parameterized logs + 1 + 8 + + From 04fd7b599feb3da869cd31cfb262a38dbf5dc365 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Oct 2024 20:07:48 +0200 Subject: [PATCH 0182/1962] [java] Add test case for #4765 --- .../xml/UnitTestShouldIncludeAssert.xml | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldIncludeAssert.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldIncludeAssert.xml index fa6a664f3cb..4b9426fc0f0 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldIncludeAssert.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldIncludeAssert.xml @@ -804,6 +804,26 @@ class ShouldIncludeAssertTest { } } +]]> + + + + #4765 [java] JUnitTestsShouldIncludeAssert does not detect assertThat() when saving in variable + 0 + jaxb = null; + final var dataArea = assertThat(jaxb).isNotNull() + .extracting(JAXBElement::getValue) + .isNotNull(); + } +} ]]> From 65eea8b5bb7f8d5d3f2de650206bba14e200eccd Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Oct 2024 20:10:41 +0200 Subject: [PATCH 0183/1962] [java] Add test case for #1433 --- .../bestpractices/xml/UnusedPrivateField.xml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml index 65c6b0cf801..30ed1b84508 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml @@ -856,6 +856,25 @@ enum EnumClass { EnumClass() {} private int a; // should report a warning here } +]]> + + + + #1433 [java] UnusedPrivateField: false positive when field has the same name as the class + 0 + From 3dcddba2768d84ac36d39244e83ab23c7ed92c6e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Oct 2024 20:17:48 +0200 Subject: [PATCH 0184/1962] [javascript] Add test case for #4055 --- .../rule/codestyle/xml/UnnecessaryBlock.xml | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/xml/UnnecessaryBlock.xml b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/xml/UnnecessaryBlock.xml index c5ed56228d0..241d5ea9489 100644 --- a/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/xml/UnnecessaryBlock.xml +++ b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/xml/UnnecessaryBlock.xml @@ -299,4 +299,43 @@ import { foo2 } from './someScript2.js'; const { isLoggedIn2 } = useAuth2() // ]]> + + + #4055 [javascript] UnnecessaryBlock FP for try/catch + 0 + + From ec8aa188c054b6ab1705e12210c970be61227c6b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Oct 2024 20:25:00 +0200 Subject: [PATCH 0185/1962] [javascript] Add test case for #4129 --- .../rule/codestyle/xml/UnnecessaryBlock.xml | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/xml/UnnecessaryBlock.xml b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/xml/UnnecessaryBlock.xml index 241d5ea9489..b30bcdf92fc 100644 --- a/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/xml/UnnecessaryBlock.xml +++ b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/xml/UnnecessaryBlock.xml @@ -336,6 +336,49 @@ async function run2(){ await client.close() } } +]]> + + + + #4129 [javascript] UnnecessaryBlock FP for function declaration + 0 + { + const action = isAdditionalTagsAndSlicerAbTest + ? `TagShown${tracking}` + : ADDITIONAL_TAG_NOT_SHOWN_ACTION; + return { // unnecessary block false positive here + gaCat: SEARCH_PAGE_TRACKING_CATEGORY, + gaActImp: action, + gaLblImp: `profileId=${profileId}|Cityname=${cityName}`, + once: true, + trackImpression: true, + }; +}; + +/* export is not supported by rhino and produces a syntax error/empty statement */ +export const getAdditionalTagTrackingImpressionObj = ( + profileId, + cityName, + tracking, + isAdditionalTagsAndSlicerAbTest +) => { + const action = isAdditionalTagsAndSlicerAbTest + ? `TagShown${tracking}` + : ADDITIONAL_TAG_NOT_SHOWN_ACTION; + return { // unnecessary block false positive here + gaCat: SEARCH_PAGE_TRACKING_CATEGORY, + gaActImp: action, + gaLblImp: `profileId=${profileId}|Cityname=${cityName}`, + once: true, + trackImpression: true, + }; +}; ]]> From 6cbb7e206a3602a2a0f79233d9c5dea0d392fcb4 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Oct 2024 20:48:34 +0200 Subject: [PATCH 0186/1962] [java] Add test case for #4620 --- .../rule/codestyle/xml/UnnecessaryCast.xml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml index 53072694c5b..b9d8381d875 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml @@ -888,4 +888,25 @@ class MyClass { } ]]> + + + #4620 [java] UnnecessaryCast reports false-positive for ByteBuffer methods when targeting Java 8 + 2 + 5,9 + + From ae3ebff8b1617a5adaebae662361f0b97f6c09f6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 25 Oct 2024 12:56:09 +0200 Subject: [PATCH 0187/1962] [swift] Add test case for #2698 --- .../pmd/lang/swift/cpd/SwiftCpdLexerTest.java | 5 +++++ .../swift/cpd/testdata/Issue2698_Emoji.swift | 8 +++++++ .../swift/cpd/testdata/Issue2698_Emoji.txt | 21 +++++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Issue2698_Emoji.swift create mode 100644 pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Issue2698_Emoji.txt diff --git a/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/cpd/SwiftCpdLexerTest.java b/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/cpd/SwiftCpdLexerTest.java index 03385bf1364..88c3c7bbf0b 100644 --- a/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/cpd/SwiftCpdLexerTest.java +++ b/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/cpd/SwiftCpdLexerTest.java @@ -64,4 +64,9 @@ void testStackoverflowOnLongLiteral() { void testTabWidth() { doTest("tabWidth"); } + + @Test + void emojiParsingError() { + doTest("Issue2698_Emoji"); + } } diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Issue2698_Emoji.swift b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Issue2698_Emoji.swift new file mode 100644 index 00000000000..9a74745b320 --- /dev/null +++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Issue2698_Emoji.swift @@ -0,0 +1,8 @@ +// see https://github.com/pmd/pmd/issues/2698 + +if let userToken = userToken { + print("๐Ÿ‘ค | User > Token: \(userToken)") +} + +var baseCommand = #"curl "\#(url.absoluteURL)""# + diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Issue2698_Emoji.txt b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Issue2698_Emoji.txt new file mode 100644 index 00000000000..df2ca58cd9a --- /dev/null +++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/Issue2698_Emoji.txt @@ -0,0 +1,21 @@ + [Image] or [Truncated image[ Bcol Ecol +L3 + [if] 1 3 + [let] 4 7 + [userToken] 8 17 + [=] 18 19 + [userToken] 20 29 + [{] 30 31 +L4 + [print] 6 11 + [(] 11 12 + ["๐Ÿ‘ค | User > Token: \\(userToken)"] 12 44 + [)] 44 45 + [}] 46 47 +L6 + [var] 1 3 +L7 + [baseCommand] 4 15 + [=] 16 17 + [#"curl "\\#(url.absoluteURL)""#] 18 48 +EOF From ee1b5990dae07885993f5e6858e5bdc9a7bc9cf1 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 25 Oct 2024 20:20:20 +0200 Subject: [PATCH 0188/1962] [apex] Add test case for #4678 --- .../pmd/lang/apex/AntlrVersionTest.java | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/AntlrVersionTest.java diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/AntlrVersionTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/AntlrVersionTest.java new file mode 100644 index 00000000000..f55f98f4f4b --- /dev/null +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/AntlrVersionTest.java @@ -0,0 +1,88 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.apex; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.IOException; +import java.util.Deque; +import java.util.LinkedList; + +import org.antlr.v4.runtime.RuntimeMetaData; +import org.junit.jupiter.api.Test; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +import com.github.stefanbirkner.systemlambda.SystemLambda; +import io.github.apexdevtools.apexparser.ApexParser; + +class AntlrVersionTest { + /** + *

    In PMD, we provide the antlr4-runtime dependency on our own and overwrite the version that would + * be inherited transitively. This might cause problems for parsers that are not generated by us, + * like apex-dev-tools:apex-parser. This might be generated with a different version, which results + * in stderr messages created by {@link org.antlr.v4.runtime.RuntimeMetaData#checkVersion(String, String)}. + *

    + *

    + * Sample failure messages are: + *

    +     *     ANTLR Tool version 4.9.1 used for code generation does not match the current runtime version 4.13.2
    +     *     ANTLR Runtime version 4.9.1 used for parser compilation does not match the current runtime version 4.13.2
    +     * 
    + *

    + *

    + * This test serves as a safety guard, in case we update our own antlr dependency to some + * incompatible version. + *

    + * + * @see [apex] Warning messages about ANTLR version mismatch #4678 + */ + @Test + void antlrVersionIsCompatible() throws IOException { + ClassReader classReader = new ClassReader(ApexParser.class.getName()); + classReader.accept(new ClassVisitor(Opcodes.ASM9) { + @Override + public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { + if ("".equals(name)) { + return new MethodVisitor(Opcodes.ASM9) { + private final Deque versions = new LinkedList<>(); + + @Override + public void visitLdcInsn(Object value) { + if (value instanceof String) { + versions.addLast((String) value); + if (versions.size() > 2) { + versions.removeFirst(); + } + } + } + + @Override + public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) { + if ("org/antlr/v4/runtime/RuntimeMetaData".equals(owner) && "checkVersion".equals(name)) { + assertEquals(2, versions.size()); + String checkResult = executeCheckVersion(versions.getFirst(), versions.getLast()); + assertEquals("", checkResult, "no incompatibility message expected"); + } + } + }; + } + return null; + } + }, 0); + } + + private String executeCheckVersion(String generatingToolVersion, String compileTimeVersion) { + try { + return SystemLambda.tapSystemErr(() -> { + RuntimeMetaData.checkVersion(generatingToolVersion, compileTimeVersion); + }); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} From 6ae7404941cbe24d0309c37ad0b87e7f7e7ff68a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 31 Oct 2024 12:17:27 +0100 Subject: [PATCH 0189/1962] [xml] XMLLexer - Update deprecation notice --- .../main/java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java index e86b9cb58e9..ca52185930e 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java @@ -11,7 +11,7 @@ * This class will be removed in PMD 8.0.0. * Use {@link net.sourceforge.pmd.lang.xml.ast.XMLLexer} directly instead. * - * @deprecated + * @deprecated since 7.8.0. Use {@link net.sourceforge.pmd.lang.xml.ast.XMLLexer} directly instead. */ @Deprecated public class XMLLexer extends net.sourceforge.pmd.lang.xml.ast.XMLLexer { From c079d8c544b94de5bff8b15c5cd72e62f7912037 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 31 Oct 2024 12:22:59 +0100 Subject: [PATCH 0190/1962] [doc] Update release notes (#5296) --- docs/pages/release_notes.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index bc1a36ec7a8..53a0f49b5df 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -18,6 +18,11 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿšจ API Changes +#### Deprecations +* pmd-xml + * {%jdoc xml::lang.xml.antlr4.XMLLexer %} is deprecated for removal. Use {%jdoc !!xml::lang.xml.ast.XMLLexer %} + instead (note different package `ast` instead of `antlr4`). + ### โœจ External Contributions {% endtocmaker %} From 5eaefd2841a20c9992a736ba69ae689b9d8533da Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 31 Oct 2024 15:06:32 +0100 Subject: [PATCH 0191/1962] [doc] Update release notes (#1860) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 53a0f49b5df..3c146742174 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -15,6 +15,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* ant + * [#1860](https://github.com/pmd/pmd/issues/1860): \[ant] Reflective access warnings on java > 9 and java < 17 ### ๐Ÿšจ API Changes From 3ed370f61d0579e33cf50852c2c59eeb9e94ae34 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 31 Oct 2024 15:07:25 +0100 Subject: [PATCH 0192/1962] Bump gems and bundler (#5301) - Bump bundler from 2.5.3 to 2.5.22 - Bump activesupport from 7.2.1 to 7.2.2 - Bump execjs from 2.9.1 to 2.10.0 - Bump faraday from 2.11.0 to 2.12.0 - Bump i18n from 1.14.5 to 1.14.6 - Bump json from 2.7.2 to 2.7.5 - Bump logger from 1.6.0 to 1.6.1 - Bump rexml from 3.3.6/3.3.8 to 3.3.9 - Bump rufus-scheduler from 3.9.2 to 3.9.2 - Fixes https://github.com/pmd/pmd/security/dependabot/69 - Fixes https://github.com/pmd/pmd/security/dependabot/70 --- Gemfile.lock | 10 +++++----- docs/Gemfile.lock | 20 +++++++++++--------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 0ed3a0fa5fd..1f7805ea501 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -45,7 +45,7 @@ GEM git (1.19.1) addressable (~> 2.8) rchardet (~> 1.8) - json (2.7.2) + json (2.7.5) kramdown (2.4.0) rexml kramdown-parser-gfm (1.1.0) @@ -74,10 +74,10 @@ GEM raabro (1.4.0) racc (1.8.1) rchardet (1.8.0) - rexml (3.3.8) + rexml (3.3.9) rouge (4.4.0) - rufus-scheduler (3.9.1) - fugit (~> 1.1, >= 1.1.6) + rufus-scheduler (3.9.2) + fugit (~> 1.1, >= 1.11.1) safe_yaml (1.0.5) sawyer (0.9.2) addressable (>= 2.3.5) @@ -102,4 +102,4 @@ DEPENDENCIES safe_yaml BUNDLED WITH - 2.5.3 + 2.5.22 diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index a8439253e33..85d32da6ff0 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -1,8 +1,9 @@ GEM remote: https://rubygems.org/ specs: - activesupport (7.2.1) + activesupport (7.2.2) base64 + benchmark (>= 0.3) bigdecimal concurrent-ruby (~> 1.0, >= 1.3.1) connection_pool (>= 2.2.5) @@ -15,6 +16,7 @@ GEM addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) base64 (0.2.0) + benchmark (0.3.0) bigdecimal (3.1.8) coffee-script (2.4.1) coffee-script-source @@ -34,9 +36,10 @@ GEM ethon (0.16.0) ffi (>= 1.15.0) eventmachine (1.2.7) - execjs (2.9.1) - faraday (2.11.0) + execjs (2.10.0) + faraday (2.12.0) faraday-net_http (>= 2.0, < 3.4) + json logger faraday-net_http (3.3.0) net-http @@ -99,7 +102,7 @@ GEM activesupport (>= 2) nokogiri (>= 1.4) http_parser.rb (0.8.0) - i18n (1.14.5) + i18n (1.14.6) concurrent-ruby (~> 1.0) jekyll (3.10.0) addressable (~> 2.4) @@ -211,6 +214,7 @@ GEM gemoji (>= 3, < 5) html-pipeline (~> 2.2) jekyll (>= 3.0, < 5.0) + json (2.7.5) kramdown (2.4.0) rexml kramdown-parser-gfm (1.1.0) @@ -219,7 +223,7 @@ GEM listen (3.9.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) - logger (1.6.0) + logger (1.6.1) mercenary (0.3.6) minima (2.5.1) jekyll (>= 3.5, < 5.0) @@ -240,8 +244,7 @@ GEM rb-fsevent (0.11.2) rb-inotify (0.11.1) ffi (~> 1.0) - rexml (3.3.6) - strscan + rexml (3.3.9) rouge (3.30.0) rubyzip (2.3.2) safe_yaml (1.0.5) @@ -255,7 +258,6 @@ GEM faraday (>= 0.17.3, < 3) securerandom (0.3.1) simpleidn (0.2.3) - strscan (3.1.0) terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) typhoeus (1.4.1) @@ -276,4 +278,4 @@ DEPENDENCIES webrick BUNDLED WITH - 2.5.3 + 2.5.22 From 93929deef65d523e45f6697b6098bd1fa8654127 Mon Sep 17 00:00:00 2001 From: mitchspano Date: Fri, 1 Nov 2024 17:09:51 +0000 Subject: [PATCH 0193/1962] Update @mitchspano as a contributor --- .all-contributorsrc | 3 +- docs/pages/pmd/projectdocs/credits.md | 2207 ++++++++++++------------- 2 files changed, 1105 insertions(+), 1105 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 95ebc05d6e1..929528f6149 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7517,7 +7517,8 @@ "avatar_url": "https://avatars.githubusercontent.com/u/18402464?v=4", "profile": "https://github.com/mitchspano", "contributions": [ - "bug" + "bug", + "code" ] }, { diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 9497ea73780..0213cced3c8 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -13,1110 +13,1109 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    0xflotus
    0xflotus

    ๐Ÿ’ป ๐Ÿ›
    1henni
    1henni

    ๐Ÿ›
    219sansim
    219sansim

    ๐Ÿ’ป
    ALiNew
    ALiNew

    ๐Ÿ›
    ASBrouwers
    ASBrouwers

    ๐Ÿ’ป
    Abhijit Sarkar
    Abhijit Sarkar

    ๐Ÿ›
    Abhishek Kumar
    Abhishek Kumar

    ๐Ÿ›
    Adam
    Adam

    ๐Ÿ›
    Adam Carroll
    Adam Carroll

    ๐Ÿ›
    Adam Obuchowicz
    Adam Obuchowicz

    ๐Ÿ›
    Adrian Price
    Adrian Price

    ๐Ÿ›
    Adrien Lecharpentier
    Adrien Lecharpentier

    ๐Ÿ›
    Aidan Harding
    Aidan Harding

    ๐Ÿ›
    Akshat Bahety
    Akshat Bahety

    ๐Ÿ’ป ๐Ÿ›
    Akshay Thapa
    Akshay Thapa

    ๐Ÿ›
    Alan Buttars
    Alan Buttars

    ๐Ÿ›
    Alan Hohn
    Alan Hohn

    ๐Ÿ›
    Alberto Fernรกndez
    Alberto Fernรกndez

    ๐Ÿ’ป ๐Ÿ›
    Alex
    Alex

    ๐Ÿ’ป
    Alex
    Alex

    ๐Ÿ›
    Alex B
    Alex B

    ๐Ÿ›
    Alex Rentz
    Alex Rentz

    ๐Ÿ›
    Alex Saveau
    Alex Saveau

    ๐Ÿ›
    Alex Shesterov
    Alex Shesterov

    ๐Ÿ’ป ๐Ÿ›
    Alexey Markevich
    Alexey Markevich

    ๐Ÿ›
    Alexey Naumov
    Alexey Naumov

    ๐Ÿ›
    Alexey Yudichev
    Alexey Yudichev

    ๐Ÿ›
    Alix
    Alix

    ๐Ÿ›
    Alix
    Alix

    ๐Ÿ›
    Amish Shah
    Amish Shah

    ๐Ÿ›
    Amit Prasad
    Amit Prasad

    ๐Ÿ›
    Amitosh Swain Mahapatra
    Amitosh Swain Mahapatra

    ๐Ÿ›
    Anand Subramanian
    Anand Subramanian

    ๐Ÿ’ป ๐Ÿ›
    Anastasiia Koba
    Anastasiia Koba

    ๐Ÿ’ป
    Anatoly Trosinenko
    Anatoly Trosinenko

    ๐Ÿ’ป ๐Ÿ›
    Andi Pabst
    Andi Pabst

    ๐Ÿ’ป ๐Ÿ›
    Andrea
    Andrea

    ๐Ÿ›
    Andrea Aime
    Andrea Aime

    ๐Ÿ›
    Andreas Dangel
    Andreas Dangel

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง
    Andreas Deininger
    Andreas Deininger

    ๐Ÿ“–
    Andreas Markussen
    Andreas Markussen

    ๐Ÿ›
    Andreas Schmid
    Andreas Schmid

    ๐Ÿ›
    Andreas Turban
    Andreas Turban

    ๐Ÿ›
    Andrei Paikin
    Andrei Paikin

    ๐Ÿ›
    Andrew
    Andrew

    ๐Ÿ›
    Andrew Green
    Andrew Green

    ๐Ÿ›
    Andrey Bozhko
    Andrey Bozhko

    ๐Ÿ“–
    Andrey Fomin
    Andrey Fomin

    ๐Ÿ›
    Andrey Hitrin
    Andrey Hitrin

    ๐Ÿ›
    Andrey Mochalov
    Andrey Mochalov

    ๐Ÿ’ป ๐Ÿ›
    Andro72
    Andro72

    ๐Ÿ›
    Andrwyw
    Andrwyw

    ๐Ÿ›
    Andrรฉs Catalรกn
    Andrรฉs Catalรกn

    ๐Ÿ›
    Andy Goossens
    Andy Goossens

    ๐Ÿ›
    Andy Pattenden
    Andy Pattenden

    ๐Ÿ›
    Andy Ray
    Andy Ray

    ๐Ÿ›
    Andy Robinson
    Andy Robinson

    ๐Ÿ›
    Andy-2639
    Andy-2639

    ๐Ÿ›
    Ankush Somani
    Ankush Somani

    ๐Ÿ›
    Anmol Kumar
    Anmol Kumar

    ๐Ÿ›
    Anthony Whitford
    Anthony Whitford

    ๐Ÿ›
    AnthonyKot
    AnthonyKot

    ๐Ÿ›
    Anurag Agarwal
    Anurag Agarwal

    ๐Ÿ›
    Aravind Hegde
    Aravind Hegde

    ๐Ÿ›
    Arda Aslan
    Arda Aslan

    ๐Ÿ›
    Ari Fogel
    Ari Fogel

    ๐Ÿ›
    Arnaud Jeansen
    Arnaud Jeansen

    ๐Ÿ’ป ๐Ÿ›
    Arpit Koolwal
    Arpit Koolwal

    ๐Ÿ›
    Artem
    Artem

    ๐Ÿ’ป ๐Ÿ›
    Artem
    Artem

    ๐Ÿ›
    Artem Sheremet
    Artem Sheremet

    ๐Ÿ›
    Artur
    Artur

    ๐Ÿ›
    Artur Bosch
    Artur Bosch

    ๐Ÿ›
    Artur Dryomov
    Artur Dryomov

    ๐Ÿ›
    Artur Ossowski
    Artur Ossowski

    ๐Ÿ›
    Aryant Tripathi
    Aryant Tripathi

    ๐Ÿ’ป
    AshTheMash
    AshTheMash

    ๐Ÿ›
    Ashish Rana
    Ashish Rana

    ๐Ÿ›
    Atul Kaushal
    Atul Kaushal

    ๐Ÿ›
    August Boland
    August Boland

    ๐Ÿ›
    Aurel Hudec
    Aurel Hudec

    ๐Ÿ›
    Austin
    Austin

    ๐Ÿ›
    Austin Shalit
    Austin Shalit

    ๐Ÿ›
    Austin Tice
    Austin Tice

    ๐Ÿ›
    Ayoub Kaanich
    Ayoub Kaanich

    ๐Ÿ›
    BBG
    BBG

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
    Bailey Tjiong
    Bailey Tjiong

    ๐Ÿ’ป
    Barthรฉlemy L.
    Barthรฉlemy L.

    ๐Ÿ›
    Basavaraj K N
    Basavaraj K N

    ๐Ÿ›
    Basil Peace
    Basil Peace

    ๐Ÿ›
    Belle
    Belle

    ๐Ÿ›
    Ben Lerner
    Ben Lerner

    ๐Ÿ›
    Ben Manes
    Ben Manes

    ๐Ÿ›
    Ben McCann
    Ben McCann

    ๐Ÿ›
    Bendegรบz Nagy
    Bendegรบz Nagy

    ๐Ÿ›
    Bennet S Yee
    Bennet S Yee

    ๐Ÿ›
    Benoit Lacelle
    Benoit Lacelle

    ๐Ÿ›
    Bernardo Macรชdo
    Bernardo Macรชdo

    ๐Ÿ›
    Bernd Farka
    Bernd Farka

    ๐Ÿ›
    Betina Cynthia Mamani
    Betina Cynthia Mamani

    ๐Ÿ›
    Bhanu Prakash Pamidi
    Bhanu Prakash Pamidi

    ๐Ÿ’ป ๐Ÿ›
    Bhargav Thanki
    Bhargav Thanki

    ๐Ÿ›
    Binu R J
    Binu R J

    ๐Ÿ›
    Bjรถrn Kautler
    Bjรถrn Kautler

    ๐Ÿ’ป ๐Ÿ›
    Blightbuster
    Blightbuster

    ๐Ÿ›
    Bo Zhang
    Bo Zhang

    ๐Ÿ›
    Bob "Wombat" Hogg
    Bob "Wombat" Hogg

    ๐Ÿ›
    Bobby Wertman
    Bobby Wertman

    ๐Ÿ›
    Bolarinwa Saheed Olayemi
    Bolarinwa Saheed Olayemi

    ๐Ÿ’ป ๐Ÿ›
    Boris Petrov
    Boris Petrov

    ๐Ÿ›
    Brad Kent
    Brad Kent

    ๐Ÿ›
    Brandon Mikeska
    Brandon Mikeska

    ๐Ÿ›
    Brian Batronis
    Brian Batronis

    ๐Ÿ›
    Brian Johnson
    Brian Johnson

    ๐Ÿ›
    Brice Dutheil
    Brice Dutheil

    ๐Ÿ’ป ๐Ÿ›
    Bruno Ferreira
    Bruno Ferreira

    ๐Ÿ›
    Bruno Harbulot
    Bruno Harbulot

    ๐Ÿ›
    Bruno Ritz
    Bruno Ritz

    ๐Ÿ›
    BurovnikovEvgeniy
    BurovnikovEvgeniy

    ๐Ÿ›
    Cameron Donaldson
    Cameron Donaldson

    ๐Ÿ›
    Carlos Macasaet
    Carlos Macasaet

    ๐Ÿ›
    Carsten Otto
    Carsten Otto

    ๐Ÿ›
    Charlie Housh
    Charlie Housh

    ๐Ÿ›
    Charlie Jonas
    Charlie Jonas

    ๐Ÿ›
    Chas Honton
    Chas Honton

    ๐Ÿ› ๐Ÿ’ป
    Chen Yang
    Chen Yang

    ๐Ÿ›
    Chotu
    Chotu

    ๐Ÿ›
    Chris Smith
    Chris Smith

    ๐Ÿ›
    Chris Toomey
    Chris Toomey

    ๐Ÿ›
    Christian Hujer
    Christian Hujer

    ๐Ÿ›
    Christian Pontesegger
    Christian Pontesegger

    ๐Ÿ›
    ChristianWulf
    ChristianWulf

    ๐Ÿ›
    Christofer Dutz
    Christofer Dutz

    ๐Ÿ’ป
    Christoffer Anselm
    Christoffer Anselm

    ๐Ÿ›
    Christophe Vidal
    Christophe Vidal

    ๐Ÿ›
    Christopher Dancy
    Christopher Dancy

    ๐Ÿ›
    Clemens Prill
    Clemens Prill

    ๐Ÿ›
    Clint Chester
    Clint Chester

    ๐Ÿ’ป ๐Ÿ›
    Clรฉment Fournier
    Clรฉment Fournier

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง
    Codacy Badger
    Codacy Badger

    ๐Ÿ›
    Code-Nil
    Code-Nil

    ๐Ÿ›
    ColColonCleaner
    ColColonCleaner

    ๐Ÿ›
    Colin Ingarfield
    Colin Ingarfield

    ๐Ÿ›
    Craig Andrews
    Craig Andrews

    ๐Ÿ›
    Craig Muchinsky
    Craig Muchinsky

    ๐Ÿ›
    Cyril
    Cyril

    ๐Ÿ’ป ๐Ÿ›
    Dale
    Dale

    ๐Ÿ’ป
    Damien Jiang
    Damien Jiang

    ๐Ÿ›
    Dan Berindei
    Dan Berindei

    ๐Ÿ›
    Dan Rollo
    Dan Rollo

    ๐Ÿ›
    Dan Ziemba
    Dan Ziemba

    ๐Ÿ›
    Daniel Gredler
    Daniel Gredler

    ๐Ÿ’ป ๐Ÿ›
    Daniel Jipa
    Daniel Jipa

    ๐Ÿ›
    Daniel Paul Searles
    Daniel Paul Searles

    ๐Ÿ’ป
    Daniel Reigada
    Daniel Reigada

    ๐Ÿ›
    Danilo Pianini
    Danilo Pianini

    ๐Ÿ›
    Darko
    Darko

    ๐Ÿ›
    David
    David

    ๐Ÿ›
    David Atkinson
    David Atkinson

    ๐Ÿ›
    David Burstrรถm
    David Burstrรถm

    ๐Ÿ’ป ๐Ÿ›
    David Goatรฉ
    David Goatรฉ

    ๐Ÿ›
    David Golpira
    David Golpira

    ๐Ÿ›
    David Kovaล™รญk
    David Kovaล™รญk

    ๐Ÿ›
    David M. Karr (fullname at gmail.com)
    David M. Karr (fullname at gmail.com)

    ๐Ÿ›
    David Renz
    David Renz

    ๐Ÿ’ป ๐Ÿ›
    David Renz
    David Renz

    ๐Ÿ›
    David Schach
    David Schach

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–
    Dawid Ciok
    Dawid Ciok

    ๐Ÿ› ๐Ÿ’ป
    Debamoy Datta
    Debamoy Datta

    ๐Ÿ’ป
    Deleted user
    Deleted user

    ๐Ÿ›
    Dell Green
    Dell Green

    ๐Ÿ›
    Dem Pilafian
    Dem Pilafian

    ๐Ÿ›
    Den
    Den

    ๐Ÿ›
    Denis Borovikov
    Denis Borovikov

    ๐Ÿ’ป ๐Ÿ›
    Dennie Reniers
    Dennie Reniers

    ๐Ÿ’ป ๐Ÿ›
    Dennis Kieselhorst
    Dennis Kieselhorst

    ๐Ÿ›
    Derek P. Moore
    Derek P. Moore

    ๐Ÿ›
    Dichotomia
    Dichotomia

    ๐Ÿ›
    Dionisio Cortรฉs Fernรกndez
    Dionisio Cortรฉs Fernรกndez

    ๐Ÿ’ป ๐Ÿ›
    Dmitri Bourlatchkov
    Dmitri Bourlatchkov

    ๐Ÿ›
    Dmitriy Kuzmin
    Dmitriy Kuzmin

    ๐Ÿ›
    Dmytro Dashenkov
    Dmytro Dashenkov

    ๐Ÿ›
    Dr. Christian Kohlschรผtter
    Dr. Christian Kohlschรผtter

    ๐Ÿ›
    Drew Hall
    Drew Hall

    ๐Ÿ›
    Dumitru Postoronca
    Dumitru Postoronca

    ๐Ÿ›
    Dylan Adams
    Dylan Adams

    ๐Ÿ›
    Eden Hao
    Eden Hao

    ๐Ÿ›
    Edward Klimoshenko
    Edward Klimoshenko

    ๐Ÿ› ๐Ÿ’ป
    Egor Bredikhin
    Egor Bredikhin

    ๐Ÿ›
    Elan P. Kugelmass
    Elan P. Kugelmass

    ๐Ÿ›
    Elder S.
    Elder S.

    ๐Ÿ›
    Eldrick Wega
    Eldrick Wega

    ๐Ÿ“–
    Emile
    Emile

    ๐Ÿ›
    Eric
    Eric

    ๐Ÿ›
    Eric Kintzer
    Eric Kintzer

    ๐Ÿ›
    Eric Perret
    Eric Perret

    ๐Ÿ›
    Eric Squires
    Eric Squires

    ๐Ÿ›
    Erich L Foster
    Erich L Foster

    ๐Ÿ›
    Erik Bleske
    Erik Bleske

    ๐Ÿ›
    Erik C. Thauvin
    Erik C. Thauvin

    ๐Ÿ“–
    Ernst Reissner
    Ernst Reissner

    ๐Ÿ›
    Ethan Sargent
    Ethan Sargent

    ๐Ÿ›
    Ewan Tempero
    Ewan Tempero

    ๐Ÿ›
    F.W. Dekker
    F.W. Dekker

    ๐Ÿ›
    FSchliephacke
    FSchliephacke

    ๐Ÿ›
    Facundo
    Facundo

    ๐Ÿ›
    Federico Giust
    Federico Giust

    ๐Ÿ›
    Fedor Sherstobitov
    Fedor Sherstobitov

    ๐Ÿ›
    Felix Lampe
    Felix Lampe

    ๐Ÿ›
    Filip Golonka
    Filip Golonka

    ๐Ÿ›
    Filipe Esperandio
    Filipe Esperandio

    ๐Ÿ’ป ๐Ÿ›
    Filippo Nova
    Filippo Nova

    ๐Ÿ›
    Francesco la Torre
    Francesco la Torre

    ๐Ÿ›
    Francisco Duarte
    Francisco Duarte

    ๐Ÿ›
    Frieder Bluemle
    Frieder Bluemle

    ๐Ÿ›
    Frits Jalvingh
    Frits Jalvingh

    ๐Ÿ’ป ๐Ÿ›
    G. Bazior
    G. Bazior

    ๐Ÿ›
    Gabe Henkes
    Gabe Henkes

    ๐Ÿ›
    Gary Gregory
    Gary Gregory

    ๐Ÿ›
    Genoud Magloire
    Genoud Magloire

    ๐Ÿ›
    Geoffrey555
    Geoffrey555

    ๐Ÿ›
    Georg Romstorfer
    Georg Romstorfer

    ๐Ÿ›
    Gili Tzabari
    Gili Tzabari

    ๐Ÿ›
    Gio
    Gio

    ๐Ÿ›
    Gol
    Gol

    ๐Ÿ›
    Gold856
    Gold856

    ๐Ÿ› ๐Ÿ’ป
    Gonzalo Exequiel Ibars Ingman
    Gonzalo Exequiel Ibars Ingman

    ๐Ÿ’ป ๐Ÿ›
    GooDer
    GooDer

    ๐Ÿ›
    Gregor Riegler
    Gregor Riegler

    ๐Ÿ›
    Grzegorz Olszewski
    Grzegorz Olszewski

    ๐Ÿ›
    Gunther Schrijvers
    Gunther Schrijvers

    ๐Ÿ’ป ๐Ÿ›
    Gustavo Krieger
    Gustavo Krieger

    ๐Ÿ›
    Guy Elsmore-Paddock
    Guy Elsmore-Paddock

    ๐Ÿ›
    Gรถrkem Mรผlayim
    Gรถrkem Mรผlayim

    ๐Ÿ›
    Hanzel Godinez
    Hanzel Godinez

    ๐Ÿ›
    Haoliang Chen
    Haoliang Chen

    ๐Ÿ›
    Harsh Kukreja
    Harsh Kukreja

    ๐Ÿ›
    Hassan ALAMI
    Hassan ALAMI

    ๐Ÿ›
    Heber
    Heber

    ๐Ÿ›
    Henning Schmiedehausen
    Henning Schmiedehausen

    ๐Ÿ’ป ๐Ÿ›
    Henning von Bargen
    Henning von Bargen

    ๐Ÿ’ป
    Hervรฉ Boutemy
    Hervรฉ Boutemy

    ๐Ÿ›
    Himanshu Pandey
    Himanshu Pandey

    ๐Ÿ›
    Hokwang Lee
    Hokwang Lee

    ๐Ÿ›
    Hooperbloob
    Hooperbloob

    ๐Ÿ’ป
    Hung PHAN
    Hung PHAN

    ๐Ÿ›
    IDoCodingStuffs
    IDoCodingStuffs

    ๐Ÿ’ป ๐Ÿ›
    Iccen Gan
    Iccen Gan

    ๐Ÿ›
    Ignacio Mariano Tirabasso
    Ignacio Mariano Tirabasso

    ๐Ÿ›
    Igor Melnichenko
    Igor Melnichenko

    ๐Ÿ›
    Igor Moreno
    Igor Moreno

    ๐Ÿ›
    Intelesis-MS
    Intelesis-MS

    ๐Ÿ›
    Iroha_
    Iroha_

    ๐Ÿ›
    Ishan Srivastava
    Ishan Srivastava

    ๐Ÿ›
    Iskren Stanislavov
    Iskren Stanislavov

    ๐Ÿ›
    Ivan Vakhrushev
    Ivan Vakhrushev

    ๐Ÿ›
    Ivano Guerini
    Ivano Guerini

    ๐Ÿ›
    Ivar Andreas Bonsaksen
    Ivar Andreas Bonsaksen

    ๐Ÿ›
    Ivo ล mรญd
    Ivo ล mรญd

    ๐Ÿ›
    JJengility
    JJengility

    ๐Ÿ›
    Jake Hemmerle
    Jake Hemmerle

    ๐Ÿ›
    James Harrison
    James Harrison

    ๐Ÿ› ๐Ÿ’ป
    Jamie Bisotti
    Jamie Bisotti

    ๐Ÿ›
    Jan
    Jan

    ๐Ÿ›
    Jan Aertgeerts
    Jan Aertgeerts

    ๐Ÿ’ป ๐Ÿ›
    Jan Brรผmmer
    Jan Brรผmmer

    ๐Ÿ›
    Jan Tล™รญska
    Jan Tล™รญska

    ๐Ÿ›
    Jan-Lukas Else
    Jan-Lukas Else

    ๐Ÿ›
    Jason Qiu
    Jason Qiu

    ๐Ÿ’ป ๐Ÿ“–
    Jason Williams
    Jason Williams

    ๐Ÿ›
    Javier Spagnoletti
    Javier Spagnoletti

    ๐Ÿ›
    Jean-Paul Mayer
    Jean-Paul Mayer

    ๐Ÿ›
    Jean-Simon Larochelle
    Jean-Simon Larochelle

    ๐Ÿ›
    Jeff Bartolotta
    Jeff Bartolotta

    ๐Ÿ’ป ๐Ÿ›
    Jeff Hube
    Jeff Hube

    ๐Ÿ’ป ๐Ÿ›
    Jeff Jensen
    Jeff Jensen

    ๐Ÿ›
    Jeff May
    Jeff May

    ๐Ÿ›
    Jens Gerdes
    Jens Gerdes

    ๐Ÿ›
    Jeroen Borgers
    Jeroen Borgers

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข
    Jeroen Meijer
    Jeroen Meijer

    ๐Ÿ›
    Jeroen van Wilgenburg
    Jeroen van Wilgenburg

    ๐Ÿ“–
    Jerome Russ
    Jerome Russ

    ๐Ÿ›
    JerritEic
    JerritEic

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
    Jiri Pejchal
    Jiri Pejchal

    ๐Ÿ›
    Jithin Sunny
    Jithin Sunny

    ๐Ÿ›
    Jiล™รญ ล korpil
    Jiล™รญ ล korpil

    ๐Ÿ›
    Joao Machado
    Joao Machado

    ๐Ÿ›
    Jochen Krauss
    Jochen Krauss

    ๐Ÿ›
    Johan Hammar
    Johan Hammar

    ๐Ÿ›
    John Karp
    John Karp

    ๐Ÿ›
    John Zhang
    John Zhang

    ๐Ÿ›
    John-Teng
    John-Teng

    ๐Ÿ’ป ๐Ÿ›
    Jon Moroney
    Jon Moroney

    ๐Ÿ’ป ๐Ÿ›
    Jonas Geiregat
    Jonas Geiregat

    ๐Ÿ›
    Jonas KeรŸler
    Jonas KeรŸler

    ๐Ÿ›
    Jonathan Wiesel
    Jonathan Wiesel

    ๐Ÿ’ป ๐Ÿ›
    Jordan
    Jordan

    ๐Ÿ›
    Jordi Llach
    Jordi Llach

    ๐Ÿ›
    Jorge Solรณrzano
    Jorge Solรณrzano

    ๐Ÿ›
    JorneVL
    JorneVL

    ๐Ÿ›
    Jose Palafox
    Jose Palafox

    ๐Ÿ›
    Jose Stovall
    Jose Stovall

    ๐Ÿ›
    Joseph
    Joseph

    ๐Ÿ’ป
    Joseph Heenan
    Joseph Heenan

    ๐Ÿ›
    Josh Feingold
    Josh Feingold

    ๐Ÿ’ป ๐Ÿ›
    Josh Holthaus
    Josh Holthaus

    ๐Ÿ›
    Joshua S Arquilevich
    Joshua S Arquilevich

    ๐Ÿ›
    Joรฃo Dinis Ferreira
    Joรฃo Dinis Ferreira

    ๐Ÿ“–
    Joรฃo Ferreira
    Joรฃo Ferreira

    ๐Ÿ’ป ๐Ÿ›
    Joรฃo Pedro Schmitt
    Joรฃo Pedro Schmitt

    ๐Ÿ›
    Juan Martรญn Sotuyo Dodero
    Juan Martรญn Sotuyo Dodero

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง
    Juan Pablo Civile
    Juan Pablo Civile

    ๐Ÿ›
    Julian Voronetsky
    Julian Voronetsky

    ๐Ÿ›
    Julien
    Julien

    ๐Ÿ›
    Julius
    Julius

    ๐Ÿ›
    JustPRV
    JustPRV

    ๐Ÿ›
    Justin Stroud
    Justin Stroud

    ๐Ÿ’ป
    Jรถrn Huxhorn
    Jรถrn Huxhorn

    ๐Ÿ›
    KThompso
    KThompso

    ๐Ÿ›
    Kai Amundsen
    Kai Amundsen

    ๐Ÿ›
    Karel Vervaeke
    Karel Vervaeke

    ๐Ÿ›
    Karl-Andero Mere
    Karl-Andero Mere

    ๐Ÿ›
    Karl-Philipp Richter
    Karl-Philipp Richter

    ๐Ÿ›
    Karsten Silz
    Karsten Silz

    ๐Ÿ›
    Kazuma Watanabe
    Kazuma Watanabe

    ๐Ÿ›
    Kev
    Kev

    ๐Ÿ›
    Keve Mรผller
    Keve Mรผller

    ๐Ÿ›
    Kevin Guerra
    Kevin Guerra

    ๐Ÿ’ป
    Kevin Jones
    Kevin Jones

    ๐Ÿ› ๐Ÿ’ป
    Kevin Poorman
    Kevin Poorman

    ๐Ÿ›
    Kevin Wayne
    Kevin Wayne

    ๐Ÿ›
    Kieran Black
    Kieran Black

    ๐Ÿ›
    Kirill Zubov
    Kirill Zubov

    ๐Ÿ›
    Kirk Clemens
    Kirk Clemens

    ๐Ÿ’ป ๐Ÿ›
    Klaus Hartl
    Klaus Hartl

    ๐Ÿ›
    Koen Van Looveren
    Koen Van Looveren

    ๐Ÿ›
    Kris Scheibe
    Kris Scheibe

    ๐Ÿ’ป ๐Ÿ›
    Krystian Dabrowski
    Krystian Dabrowski

    ๐Ÿ› ๐Ÿ’ป
    Kunal Thanki
    Kunal Thanki

    ๐Ÿ›
    LaLucid
    LaLucid

    ๐Ÿ’ป
    Larry Diamond
    Larry Diamond

    ๐Ÿ’ป ๐Ÿ›
    Lars Knickrehm
    Lars Knickrehm

    ๐Ÿ›
    Laurent Bovet
    Laurent Bovet

    ๐Ÿ› ๐Ÿ’ป
    Leo Gutierrez
    Leo Gutierrez

    ๐Ÿ›
    LiGaOg
    LiGaOg

    ๐Ÿ’ป
    Liam Sharp
    Liam Sharp

    ๐Ÿ›
    Lintsi
    Lintsi

    ๐Ÿ›
    Linus Fernandes
    Linus Fernandes

    ๐Ÿ›
    Lixon Lookose
    Lixon Lookose

    ๐Ÿ›
    Logesh
    Logesh

    ๐Ÿ›
    Lorenzo Gabriele
    Lorenzo Gabriele

    ๐Ÿ›
    Loรฏc Ledoyen
    Loรฏc Ledoyen

    ๐Ÿ›
    Lucas
    Lucas

    ๐Ÿ›
    Lucas Silva
    Lucas Silva

    ๐Ÿ›
    Lucas Soncini
    Lucas Soncini

    ๐Ÿ’ป ๐Ÿ›
    Luis Alcantar
    Luis Alcantar

    ๐Ÿ’ป
    Lukas Grรคf
    Lukas Grรคf

    ๐Ÿ’ป
    Lukasz Slonina
    Lukasz Slonina

    ๐Ÿ›
    Lukebray
    Lukebray

    ๐Ÿ›
    Lynn
    Lynn

    ๐Ÿ’ป ๐Ÿ›
    Lyor Goldstein
    Lyor Goldstein

    ๐Ÿ›
    MCMicS
    MCMicS

    ๐Ÿ›
    Macarse
    Macarse

    ๐Ÿ›
    Machine account for PMD
    Machine account for PMD

    ๐Ÿ’ป
    Maciek Siemczyk
    Maciek Siemczyk

    ๐Ÿ›
    Maikel Steneker
    Maikel Steneker

    ๐Ÿ’ป ๐Ÿ›
    Maksim Moiseikin
    Maksim Moiseikin

    ๐Ÿ›
    Manfred Koch
    Manfred Koch

    ๐Ÿ›
    Manuel Moya Ferrer
    Manuel Moya Ferrer

    ๐Ÿ’ป ๐Ÿ›
    Manuel Ryan
    Manuel Ryan

    ๐Ÿ›
    Marat Vyshegorodtsev
    Marat Vyshegorodtsev

    ๐Ÿ›
    Marcel Hรคrle
    Marcel Hรคrle

    ๐Ÿ›
    Marcello Fialho
    Marcello Fialho

    ๐Ÿ›
    Marcin Dฤ…browski
    Marcin Dฤ…browski

    ๐Ÿ’ป
    Marcin Rataj
    Marcin Rataj

    ๐Ÿ›
    Marcono1234
    Marcono1234

    ๐Ÿ›
    Mark Adamcin
    Mark Adamcin

    ๐Ÿ›
    Mark Hall
    Mark Hall

    ๐Ÿ’ป ๐Ÿ›
    Mark Kolich
    Mark Kolich

    ๐Ÿ›
    Mark Pritchard
    Mark Pritchard

    ๐Ÿ›
    Markus Rathgeb
    Markus Rathgeb

    ๐Ÿ›
    Marquis Wang
    Marquis Wang

    ๐Ÿ›
    MartGit
    MartGit

    ๐Ÿ›
    Martin Feldsztejn
    Martin Feldsztejn

    ๐Ÿ›
    Martin Lehmann
    Martin Lehmann

    ๐Ÿ›
    Martin Spamer
    Martin Spamer

    ๐Ÿ›
    Martin Tarjรกnyi
    Martin Tarjรกnyi

    ๐Ÿ›
    MatFl
    MatFl

    ๐Ÿ›
    Mateusz Stefanski
    Mateusz Stefanski

    ๐Ÿ›
    Mathieu Gouin
    Mathieu Gouin

    ๐Ÿ›
    MatiasComercio
    MatiasComercio

    ๐Ÿ’ป ๐Ÿ›
    Matt Benson
    Matt Benson

    ๐Ÿ›
    Matt De Poorter
    Matt De Poorter

    ๐Ÿ›
    Matt Hargett
    Matt Hargett

    ๐Ÿ’ป ๐Ÿ’ต
    Matt Harrah
    Matt Harrah

    ๐Ÿ›
    Matt Nelson
    Matt Nelson

    ๐Ÿ›
    Matthew Amos
    Matthew Amos

    ๐Ÿ›
    Matthew Duggan
    Matthew Duggan

    ๐Ÿ›
    Matthew Hall
    Matthew Hall

    ๐Ÿ›
    Matthew Rossner
    Matthew Rossner

    ๐Ÿ›
    Matรญas Fraga
    Matรญas Fraga

    ๐Ÿ’ป ๐Ÿ›
    Maxime Robert
    Maxime Robert

    ๐Ÿ’ป ๐Ÿ›
    MetaBF
    MetaBF

    ๐Ÿ›
    Metin Dagcilar
    Metin Dagcilar

    ๐Ÿ›
    Michael
    Michael

    ๐Ÿ›
    Michael Bell
    Michael Bell

    ๐Ÿ›
    Michael Bernstein
    Michael Bernstein

    ๐Ÿ›
    Michael Clay
    Michael Clay

    ๐Ÿ›
    Michael Dombrowski
    Michael Dombrowski

    ๐Ÿ›
    Michael Hausegger
    Michael Hausegger

    ๐Ÿ›
    Michael Hoefer
    Michael Hoefer

    ๐Ÿ›
    Michael Kolesnikov
    Michael Kolesnikov

    ๐Ÿ›
    Michael Mรถbius
    Michael Mรถbius

    ๐Ÿ›
    Michael N. Lipp
    Michael N. Lipp

    ๐Ÿ›
    Michael Pellegrini
    Michael Pellegrini

    ๐Ÿ›
    Michal Kordas
    Michal Kordas

    ๐Ÿ›
    Michaล‚ Borek
    Michaล‚ Borek

    ๐Ÿ›
    Michaล‚ Kuliล„ski
    Michaล‚ Kuliล„ski

    ๐Ÿ›
    Miguel Nรบรฑez Dรญaz-Montes
    Miguel Nรบรฑez Dรญaz-Montes

    ๐Ÿ›
    Mihai Ionut
    Mihai Ionut

    ๐Ÿ›
    Mikhail Kuchma
    Mikhail Kuchma

    ๐Ÿ›
    Mirek Hankus
    Mirek Hankus

    ๐Ÿ›
    Mitch Spano
    Mitch Spano

    ๐Ÿ›
    Mladjan Gadzic
    Mladjan Gadzic

    ๐Ÿ›
    MrAngry52
    MrAngry52

    ๐Ÿ›
    Muminur Choudhury
    Muminur Choudhury

    ๐Ÿ›
    Mykhailo Palahuta
    Mykhailo Palahuta

    ๐Ÿ’ป ๐Ÿ›
    Nagendra Kumar Singh
    Nagendra Kumar Singh

    ๐Ÿ›
    Nahuel Barrios
    Nahuel Barrios

    ๐Ÿ›
    Nakul Sharma
    Nakul Sharma

    ๐Ÿ›
    Nathan Braun
    Nathan Braun

    ๐Ÿ›
    Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ›
    Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ›
    Nathanaรซl
    Nathanaรซl

    ๐Ÿ›
    Naveen
    Naveen

    ๐Ÿ’ป
    Nazdravi
    Nazdravi

    ๐Ÿ›
    Neha-Dhonde
    Neha-Dhonde

    ๐Ÿ›
    Nicholas Doyle
    Nicholas Doyle

    ๐Ÿ›
    Nick Butcher
    Nick Butcher

    ๐Ÿ›
    Nico Gallinal
    Nico Gallinal

    ๐Ÿ›
    Nicola Dal Maso
    Nicola Dal Maso

    ๐Ÿ›
    Nicolas Filotto
    Nicolas Filotto

    ๐Ÿ’ป
    Nicolas Vervelle
    Nicolas Vervelle

    ๐Ÿ›
    Nicolas Vuillamy
    Nicolas Vuillamy

    ๐Ÿ“–
    Nikita Chursin
    Nikita Chursin

    ๐Ÿ›
    Niklas Baudy
    Niklas Baudy

    ๐Ÿ›
    Nikolas Havrikov
    Nikolas Havrikov

    ๐Ÿ›
    Nilesh Virkar
    Nilesh Virkar

    ๐Ÿ›
    Nimit Patel
    Nimit Patel

    ๐Ÿ›
    Niranjan Harpale
    Niranjan Harpale

    ๐Ÿ›
    Nirvik Patel
    Nirvik Patel

    ๐Ÿ’ป
    Noah Sussman
    Noah Sussman

    ๐Ÿ›
    Noah0120
    Noah0120

    ๐Ÿ›
    Noam Tamim
    Noam Tamim

    ๐Ÿ›
    Noel Grandin
    Noel Grandin

    ๐Ÿ›
    Olaf Haalstra
    Olaf Haalstra

    ๐Ÿ›
    Oleg Andreych
    Oleg Andreych

    ๐Ÿ’ป ๐Ÿ›
    Oleg Pavlenko
    Oleg Pavlenko

    ๐Ÿ›
    Oleksii Dykov
    Oleksii Dykov

    ๐Ÿ’ป ๐Ÿ›
    Oliver Eikemeier
    Oliver Eikemeier

    ๐Ÿ›
    Oliver Siegmar
    Oliver Siegmar

    ๐Ÿ’ต
    Olivier Parent
    Olivier Parent

    ๐Ÿ’ป ๐Ÿ›
    Ollie Abbey
    Ollie Abbey

    ๐Ÿ’ป ๐Ÿ›
    Ondrej Kratochvil
    Ondrej Kratochvil

    ๐Ÿ›
    OverDrone
    OverDrone

    ๐Ÿ›
    Ozan Gulle
    Ozan Gulle

    ๐Ÿ’ป ๐Ÿ›
    PUNEET JAIN
    PUNEET JAIN

    ๐Ÿ›
    Parbati Bose
    Parbati Bose

    ๐Ÿ›
    Paul Berg
    Paul Berg

    ๐Ÿ›
    Paul Guyot
    Paul Guyot

    ๐Ÿ’ป
    Pavel Bludov
    Pavel Bludov

    ๐Ÿ›
    Pavel Miฤka
    Pavel Miฤka

    ๐Ÿ›
    Pedro Nuno Santos
    Pedro Nuno Santos

    ๐Ÿ›
    Pedro Rijo
    Pedro Rijo

    ๐Ÿ›
    Pelisse Romain
    Pelisse Romain

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
    Per Abich
    Per Abich

    ๐Ÿ’ป
    Pete Davids
    Pete Davids

    ๐Ÿ›
    Peter Bruin
    Peter Bruin

    ๐Ÿ›
    Peter Chittum
    Peter Chittum

    ๐Ÿ’ป ๐Ÿ›
    Peter Cudmore
    Peter Cudmore

    ๐Ÿ›
    Peter Kasson
    Peter Kasson

    ๐Ÿ›
    Peter Kofler
    Peter Kofler

    ๐Ÿ›
    Peter Paul Bakker
    Peter Paul Bakker

    ๐Ÿ’ป
    Peter Rader
    Peter Rader

    ๐Ÿ›
    Pham Hai Trung
    Pham Hai Trung

    ๐Ÿ›
    Philip Graf
    Philip Graf

    ๐Ÿ’ป ๐Ÿ›
    Philip Hachey
    Philip Hachey

    ๐Ÿ›
    Philippe Ozil
    Philippe Ozil

    ๐Ÿ›
    Phinehas Artemix
    Phinehas Artemix

    ๐Ÿ›
    Phokham Nonava
    Phokham Nonava

    ๐Ÿ›
    Pim van der Loos
    Pim van der Loos

    ๐Ÿ’ป โš ๏ธ
    Piotr Szymaล„ski
    Piotr Szymaล„ski

    ๐Ÿ›
    Piotrek ลปygieล‚o
    Piotrek ลปygieล‚o

    ๐Ÿ’ป ๐Ÿ› ๐Ÿ“–
    Pranay Jaiswal
    Pranay Jaiswal

    ๐Ÿ›
    Prasad Kamath
    Prasad Kamath

    ๐Ÿ›
    Prasanna
    Prasanna

    ๐Ÿ›
    Presh-AR
    Presh-AR

    ๐Ÿ›
    Puneet1726
    Puneet1726

    ๐Ÿ›
    RBRi
    RBRi

    ๐Ÿ›
    Rafael Cortรชs
    Rafael Cortรชs

    ๐Ÿ›
    RaheemShaik999
    RaheemShaik999

    ๐Ÿ›
    RajeshR
    RajeshR

    ๐Ÿ’ป ๐Ÿ›
    Ramachandra Mohan
    Ramachandra Mohan

    ๐Ÿ›
    Ramel0921
    Ramel0921

    ๐Ÿ›
    Raquel Pau
    Raquel Pau

    ๐Ÿ›
    Ravikiran Janardhana
    Ravikiran Janardhana

    ๐Ÿ›
    Reda Benhemmouche
    Reda Benhemmouche

    ๐Ÿ›
    Reinhard Schiedermeier
    Reinhard Schiedermeier

    ๐Ÿ›
    Renato Oliveira
    Renato Oliveira

    ๐Ÿ’ป ๐Ÿ›
    Rich DiCroce
    Rich DiCroce

    ๐Ÿ›
    Richard Corfield
    Richard Corfield

    ๐Ÿ’ป
    Richard Corfield
    Richard Corfield

    ๐Ÿ› ๐Ÿ’ป
    Riot R1cket
    Riot R1cket

    ๐Ÿ›
    Rishabh Jain
    Rishabh Jain

    ๐Ÿ›
    RishabhDeep Singh
    RishabhDeep Singh

    ๐Ÿ›
    Rob Baillie
    Rob Baillie

    ๐Ÿ›
    Robbie Martinus
    Robbie Martinus

    ๐Ÿ’ป ๐Ÿ›
    Robert Henry
    Robert Henry

    ๐Ÿ›
    Robert Mihaly
    Robert Mihaly

    ๐Ÿ›
    Robert Painsi
    Robert Painsi

    ๐Ÿ›
    Robert Russell
    Robert Russell

    ๐Ÿ›
    Robert Sรถsemann
    Robert Sรถsemann

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ›
    Robert Whitebit
    Robert Whitebit

    ๐Ÿ›
    Robin Richtsfeld
    Robin Richtsfeld

    ๐Ÿ›
    Robin Stocker
    Robin Stocker

    ๐Ÿ’ป ๐Ÿ›
    Robin Wils
    Robin Wils

    ๐Ÿ›
    RochusOest
    RochusOest

    ๐Ÿ›
    Rodolfo Noviski
    Rodolfo Noviski

    ๐Ÿ›
    Rodrigo Casara
    Rodrigo Casara

    ๐Ÿ›
    Rodrigo Fernandes
    Rodrigo Fernandes

    ๐Ÿ›
    Roman Salvador
    Roman Salvador

    ๐Ÿ’ป ๐Ÿ›
    Ronald Blaschke
    Ronald Blaschke

    ๐Ÿ›
    Rรณbert Papp
    Rรณbert Papp

    ๐Ÿ›
    Saikat Sengupta
    Saikat Sengupta

    ๐Ÿ›
    Saksham Handu
    Saksham Handu

    ๐Ÿ›
    Saladoc
    Saladoc

    ๐Ÿ›
    Salesforce Bob Lightning
    Salesforce Bob Lightning

    ๐Ÿ›
    Sam Carlberg
    Sam Carlberg

    ๐Ÿ›
    Sascha Riemer
    Sascha Riemer

    ๐Ÿ›
    Sashko
    Sashko

    ๐Ÿ’ป
    Satoshi Kubo
    Satoshi Kubo

    ๐Ÿ›
    Scott Kennedy
    Scott Kennedy

    ๐Ÿ›
    Scott Wells
    Scott Wells

    ๐Ÿ› ๐Ÿ’ป
    Scrates1
    Scrates1

    ๐Ÿ› ๐Ÿ’ป
    Scrsloota
    Scrsloota

    ๐Ÿ’ป
    Sebastian Bรถgl
    Sebastian Bรถgl

    ๐Ÿ›
    Sebastian Davids
    Sebastian Davids

    ๐Ÿ›
    Sebastian Schuberth
    Sebastian Schuberth

    ๐Ÿ›
    Sebastian Schwarz
    Sebastian Schwarz

    ๐Ÿ›
    Seren
    Seren

    ๐Ÿ› ๐Ÿ’ป
    Sergey Gorbaty
    Sergey Gorbaty

    ๐Ÿ›
    Sergey Kozlov
    Sergey Kozlov

    ๐Ÿ›
    Sergey Yanzin
    Sergey Yanzin

    ๐Ÿ’ป ๐Ÿ›
    Seth Wilcox
    Seth Wilcox

    ๐Ÿ’ป
    Shai Bennathan
    Shai Bennathan

    ๐Ÿ› ๐Ÿ’ป
    Shubham
    Shubham

    ๐Ÿ’ป ๐Ÿ›
    Simon Abykov
    Simon Abykov

    ๐Ÿ’ป ๐Ÿ›
    Simon Xiao
    Simon Xiao

    ๐Ÿ›
    Srinivasan Venkatachalam
    Srinivasan Venkatachalam

    ๐Ÿ›
    Stanislav Gromov
    Stanislav Gromov

    ๐Ÿ›
    Stanislav Myachenkov
    Stanislav Myachenkov

    ๐Ÿ’ป
    Stefan Birkner
    Stefan Birkner

    ๐Ÿ›
    Stefan Bohn
    Stefan Bohn

    ๐Ÿ›
    Stefan Endrullis
    Stefan Endrullis

    ๐Ÿ›
    Stefan Klรถss-Schuster
    Stefan Klรถss-Schuster

    ๐Ÿ›
    Stefan Wolf
    Stefan Wolf

    ๐Ÿ›
    Stephan H. Wissel
    Stephan H. Wissel

    ๐Ÿ›
    Stephen
    Stephen

    ๐Ÿ›
    Stephen Carter
    Stephen Carter

    ๐Ÿ›
    Stephen Friedrich
    Stephen Friedrich

    ๐Ÿ›
    Steve Babula
    Steve Babula

    ๐Ÿ’ป
    Steven Stearns
    Steven Stearns

    ๐Ÿ› ๐Ÿ’ป
    Stexxe
    Stexxe

    ๐Ÿ›
    Stian Lรฅgstad
    Stian Lรฅgstad

    ๐Ÿ›
    StuartClayton5
    StuartClayton5

    ๐Ÿ›
    Supun Arunoda
    Supun Arunoda

    ๐Ÿ›
    Suren Abrahamyan
    Suren Abrahamyan

    ๐Ÿ›
    Suvashri
    Suvashri

    ๐Ÿ“–
    SwatiBGupta1110
    SwatiBGupta1110

    ๐Ÿ›
    SyedThoufich
    SyedThoufich

    ๐Ÿ›
    Szymon Sasin
    Szymon Sasin

    ๐Ÿ›
    T-chuangxin
    T-chuangxin

    ๐Ÿ›
    TERAI Atsuhiro
    TERAI Atsuhiro

    ๐Ÿ›
    TIOBE Software
    TIOBE Software

    ๐Ÿ’ป ๐Ÿ›
    Tarush Singh
    Tarush Singh

    ๐Ÿ’ป
    Taylor Smock
    Taylor Smock

    ๐Ÿ›
    Techeira Damiรกn
    Techeira Damiรกn

    ๐Ÿ’ป ๐Ÿ›
    Ted Husted
    Ted Husted

    ๐Ÿ›
    TehBakker
    TehBakker

    ๐Ÿ›
    The Gitter Badger
    The Gitter Badger

    ๐Ÿ›
    Theodoor
    Theodoor

    ๐Ÿ›
    Thiago Henrique Hรผpner
    Thiago Henrique Hรผpner

    ๐Ÿ›
    Thibault Meyer
    Thibault Meyer

    ๐Ÿ›
    Thomas Gรผttler
    Thomas Gรผttler

    ๐Ÿ›
    Thomas Jones-Low
    Thomas Jones-Low

    ๐Ÿ›
    Thomas Smith
    Thomas Smith

    ๐Ÿ’ป ๐Ÿ›
    ThrawnCA
    ThrawnCA

    ๐Ÿ›
    Thu Vo
    Thu Vo

    ๐Ÿ›
    Thunderforge
    Thunderforge

    ๐Ÿ’ป ๐Ÿ›
    Tim van der Lippe
    Tim van der Lippe

    ๐Ÿ›
    Tobias Weimer
    Tobias Weimer

    ๐Ÿ’ป ๐Ÿ›
    Tom Copeland
    Tom Copeland

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–
    Tom Daly
    Tom Daly

    ๐Ÿ›
    Tomas
    Tomas

    ๐Ÿ›
    Tomer Figenblat
    Tomer Figenblat

    ๐Ÿ›
    Tomi De Lucca
    Tomi De Lucca

    ๐Ÿ’ป ๐Ÿ›
    Tony
    Tony

    ๐Ÿ“–
    Torsten Kleiber
    Torsten Kleiber

    ๐Ÿ›
    TrackerSB
    TrackerSB

    ๐Ÿ›
    Tyson Stewart
    Tyson Stewart

    ๐Ÿ›
    Ullrich Hafner
    Ullrich Hafner

    ๐Ÿ›
    Utku Cuhadaroglu
    Utku Cuhadaroglu

    ๐Ÿ’ป ๐Ÿ›
    Valentin Brandl
    Valentin Brandl

    ๐Ÿ›
    Valeria
    Valeria

    ๐Ÿ›
    Valery Yatsynovich
    Valery Yatsynovich

    ๐Ÿ“–
    Vasily Anisimov
    Vasily Anisimov

    ๐Ÿ›
    Vedant Chokshi
    Vedant Chokshi

    ๐Ÿ›
    Vibhor Goyal
    Vibhor Goyal

    ๐Ÿ›
    Vickenty Fesunov
    Vickenty Fesunov

    ๐Ÿ›
    Victor Noรซl
    Victor Noรซl

    ๐Ÿ›
    Vincent Galloy
    Vincent Galloy

    ๐Ÿ’ป
    Vincent HUYNH
    Vincent HUYNH

    ๐Ÿ›
    Vincent Maurin
    Vincent Maurin

    ๐Ÿ›
    Vincent Privat
    Vincent Privat

    ๐Ÿ›
    Vishhwas
    Vishhwas

    ๐Ÿ›
    Vishv_Android
    Vishv_Android

    ๐Ÿ›
    Vitaly
    Vitaly

    ๐Ÿ›
    Vitaly Polonetsky
    Vitaly Polonetsky

    ๐Ÿ›
    Vojtech Polivka
    Vojtech Polivka

    ๐Ÿ›
    Vsevolod Zholobov
    Vsevolod Zholobov

    ๐Ÿ›
    Vyom Yadav
    Vyom Yadav

    ๐Ÿ’ป
    Wang Shidong
    Wang Shidong

    ๐Ÿ›
    Waqas Ahmed
    Waqas Ahmed

    ๐Ÿ›
    Wayne J. Earl
    Wayne J. Earl

    ๐Ÿ›
    Wchenghui
    Wchenghui

    ๐Ÿ›
    Wener
    Wener

    ๐Ÿ’ป
    Will Winder
    Will Winder

    ๐Ÿ›
    William Brockhus
    William Brockhus

    ๐Ÿ’ป ๐Ÿ›
    Wilson Kurniawan
    Wilson Kurniawan

    ๐Ÿ›
    Wim Deblauwe
    Wim Deblauwe

    ๐Ÿ›
    Woongsik Choi
    Woongsik Choi

    ๐Ÿ›
    XenoAmess
    XenoAmess

    ๐Ÿ’ป ๐Ÿ›
    Yang
    Yang

    ๐Ÿ’ป
    YaroslavTER
    YaroslavTER

    ๐Ÿ›
    Yasar Shaikh
    Yasar Shaikh

    ๐Ÿ’ป
    Young Chan
    Young Chan

    ๐Ÿ’ป ๐Ÿ›
    YuJin Kim
    YuJin Kim

    ๐Ÿ›
    Yuri Dolzhenko
    Yuri Dolzhenko

    ๐Ÿ›
    Yurii Dubinka
    Yurii Dubinka

    ๐Ÿ›
    Zoltan Farkas
    Zoltan Farkas

    ๐Ÿ›
    Zustin
    Zustin

    ๐Ÿ›
    aaronhurst-google
    aaronhurst-google

    ๐Ÿ› ๐Ÿ’ป
    alexmodis
    alexmodis

    ๐Ÿ›
    andreoss
    andreoss

    ๐Ÿ›
    andrey81inmd
    andrey81inmd

    ๐Ÿ’ป ๐Ÿ›
    anicoara
    anicoara

    ๐Ÿ›
    arunprasathav
    arunprasathav

    ๐Ÿ›
    asiercamara
    asiercamara

    ๐Ÿ›
    astillich-igniti
    astillich-igniti

    ๐Ÿ’ป
    avesolovksyy
    avesolovksyy

    ๐Ÿ›
    avishvat
    avishvat

    ๐Ÿ›
    avivmu
    avivmu

    ๐Ÿ›
    axelbarfod1
    axelbarfod1

    ๐Ÿ›
    b-3-n
    b-3-n

    ๐Ÿ›
    balbhadra9
    balbhadra9

    ๐Ÿ›
    base23de
    base23de

    ๐Ÿ›
    bergander
    bergander

    ๐Ÿ› ๐Ÿ’ป
    berkam
    berkam

    ๐Ÿ’ป ๐Ÿ›
    breizh31
    breizh31

    ๐Ÿ›
    caesarkim
    caesarkim

    ๐Ÿ›
    carolyujing
    carolyujing

    ๐Ÿ›
    cbfiddle
    cbfiddle

    ๐Ÿ›
    cesares-basilico
    cesares-basilico

    ๐Ÿ›
    chrite
    chrite

    ๐Ÿ›
    ciufudean
    ciufudean

    ๐Ÿ“–
    cobratbq
    cobratbq

    ๐Ÿ›
    coladict
    coladict

    ๐Ÿ›
    cosmoJFH
    cosmoJFH

    ๐Ÿ›
    cristalp
    cristalp

    ๐Ÿ›
    crunsk
    crunsk

    ๐Ÿ›
    cwholmes
    cwholmes

    ๐Ÿ›
    cyberjj999
    cyberjj999

    ๐Ÿ›
    cyw3
    cyw3

    ๐Ÿ› ๐Ÿ“–
    d1ss0nanz
    d1ss0nanz

    ๐Ÿ›
    dague1
    dague1

    ๐Ÿ“–
    dalizi007
    dalizi007

    ๐Ÿ’ป
    danbrycefairsailcom
    danbrycefairsailcom

    ๐Ÿ›
    dariansanity
    dariansanity

    ๐Ÿ›
    darrenmiliband
    darrenmiliband

    ๐Ÿ›
    davidburstrom
    davidburstrom

    ๐Ÿ›
    dbirkman-paloalto
    dbirkman-paloalto

    ๐Ÿ›
    deepak-patra
    deepak-patra

    ๐Ÿ›
    dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ›
    dinesh150
    dinesh150

    ๐Ÿ›
    diziaq
    diziaq

    ๐Ÿ›
    dreaminpast123
    dreaminpast123

    ๐Ÿ›
    duanyanan
    duanyanan

    ๐Ÿ›
    dutt-sanjay
    dutt-sanjay

    ๐Ÿ›
    duursma
    duursma

    ๐Ÿ’ป
    dylanleung
    dylanleung

    ๐Ÿ›
    dzeigler
    dzeigler

    ๐Ÿ›
    eant60
    eant60

    ๐Ÿ›
    ekkirala
    ekkirala

    ๐Ÿ›
    emersonmoura
    emersonmoura

    ๐Ÿ›
    emouty
    emouty

    ๐Ÿ’ป ๐Ÿ›
    eugenepugach
    eugenepugach

    ๐Ÿ›
    fairy
    fairy

    ๐Ÿ›
    filiprafalowicz
    filiprafalowicz

    ๐Ÿ’ป
    flxbl-io
    flxbl-io

    ๐Ÿ’ต
    foxmason
    foxmason

    ๐Ÿ›
    frankegabor
    frankegabor

    ๐Ÿ›
    frankl
    frankl

    ๐Ÿ›
    freafrea
    freafrea

    ๐Ÿ›
    fsapatin
    fsapatin

    ๐Ÿ›
    gearsethenry
    gearsethenry

    ๐Ÿ›
    gracia19
    gracia19

    ๐Ÿ›
    gudzpoz
    gudzpoz

    ๐Ÿ›
    guo fei
    guo fei

    ๐Ÿ›
    gurmsc5
    gurmsc5

    ๐Ÿ›
    gwilymatgearset
    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ›
    haigsn
    haigsn

    ๐Ÿ›
    hemanshu070
    hemanshu070

    ๐Ÿ›
    henrik242
    henrik242

    ๐Ÿ›
    hongpuwu
    hongpuwu

    ๐Ÿ›
    hvbtup
    hvbtup

    ๐Ÿ’ป ๐Ÿ›
    igniti GmbH
    igniti GmbH

    ๐Ÿ›
    ilovezfs
    ilovezfs

    ๐Ÿ›
    imax-erik
    imax-erik

    ๐Ÿ›
    itaigilo
    itaigilo

    ๐Ÿ›
    jakivey32
    jakivey32

    ๐Ÿ›
    jbennett2091
    jbennett2091

    ๐Ÿ›
    jcamerin
    jcamerin

    ๐Ÿ›
    jkeener1
    jkeener1

    ๐Ÿ›
    jmetertea
    jmetertea

    ๐Ÿ›
    johnra2
    johnra2

    ๐Ÿ’ป
    johnzhao9
    johnzhao9

    ๐Ÿ›
    josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ›
    kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ›
    karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“–
    karwer
    karwer

    ๐Ÿ›
    kaulonline
    kaulonline

    ๐Ÿ›
    kdaemonv
    kdaemonv

    ๐Ÿ›
    kdebski85
    kdebski85

    ๐Ÿ› ๐Ÿ’ป
    kenji21
    kenji21

    ๐Ÿ’ป ๐Ÿ›
    kfranic
    kfranic

    ๐Ÿ›
    khalidkh
    khalidkh

    ๐Ÿ›
    koalalam
    koalalam

    ๐Ÿ›
    krzyk
    krzyk

    ๐Ÿ›
    lasselindqvist
    lasselindqvist

    ๐Ÿ›
    lgemeinhardt
    lgemeinhardt

    ๐Ÿ›
    lihuaib
    lihuaib

    ๐Ÿ›
    liqingjun123
    liqingjun123

    ๐Ÿ›
    lonelyma1021
    lonelyma1021

    ๐Ÿ›
    lpeddy
    lpeddy

    ๐Ÿ›
    lujiefsi
    lujiefsi

    ๐Ÿ’ป
    lukelukes
    lukelukes

    ๐Ÿ’ป
    lyriccoder
    lyriccoder

    ๐Ÿ›
    marcelmore
    marcelmore

    ๐Ÿ›
    matchbox
    matchbox

    ๐Ÿ›
    matthiaskraaz
    matthiaskraaz

    ๐Ÿ›
    meandonlyme
    meandonlyme

    ๐Ÿ›
    mikesive
    mikesive

    ๐Ÿ›
    milossesic
    milossesic

    ๐Ÿ›
    mluckam
    mluckam

    ๐Ÿ’ป ๐Ÿ›
    mohan-chinnappan-n
    mohan-chinnappan-n

    ๐Ÿ’ป
    mriddell95
    mriddell95

    ๐Ÿ›
    mrlzh
    mrlzh

    ๐Ÿ›
    msloan
    msloan

    ๐Ÿ›
    mucharlaravalika
    mucharlaravalika

    ๐Ÿ›
    mvenneman
    mvenneman

    ๐Ÿ›
    nareshl119
    nareshl119

    ๐Ÿ›
    nicolas-harraudeau-sonarsource
    nicolas-harraudeau-sonarsource

    ๐Ÿ›
    noerremark
    noerremark

    ๐Ÿ›
    novsirion
    novsirion

    ๐Ÿ›
    nwcm
    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป
    oggboy
    oggboy

    ๐Ÿ›
    oinume
    oinume

    ๐Ÿ›
    orimarko
    orimarko

    ๐Ÿ’ป ๐Ÿ›
    pablogomez2197
    pablogomez2197

    ๐Ÿ›
    pacvz
    pacvz

    ๐Ÿ’ป
    pallavi agarwal
    pallavi agarwal

    ๐Ÿ›
    parksungrin
    parksungrin

    ๐Ÿ›
    patpatpat123
    patpatpat123

    ๐Ÿ›
    patriksevallius
    patriksevallius

    ๐Ÿ›
    pbrajesh1
    pbrajesh1

    ๐Ÿ›
    phoenix384
    phoenix384

    ๐Ÿ›
    piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป
    plan3d
    plan3d

    ๐Ÿ›
    poojasix
    poojasix

    ๐Ÿ›
    prabhushrikant
    prabhushrikant

    ๐Ÿ›
    pujitha8783
    pujitha8783

    ๐Ÿ›
    r-r-a-j
    r-r-a-j

    ๐Ÿ›
    raghujayjunk
    raghujayjunk

    ๐Ÿ›
    rajeshveera
    rajeshveera

    ๐Ÿ›
    rajeswarreddy88
    rajeswarreddy88

    ๐Ÿ›
    recdevs
    recdevs

    ๐Ÿ›
    reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ›
    rijkt
    rijkt

    ๐Ÿ›
    rillig-tk
    rillig-tk

    ๐Ÿ›
    rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ›
    rnveach
    rnveach

    ๐Ÿ›
    rxmicro
    rxmicro

    ๐Ÿ›
    ryan-gustafson
    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ›
    sabi0
    sabi0

    ๐Ÿ›
    scais
    scais

    ๐Ÿ›
    schosin
    schosin

    ๐Ÿ›
    screamingfrog
    screamingfrog

    ๐Ÿ’ต
    sebbASF
    sebbASF

    ๐Ÿ›
    sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป
    shilko2013
    shilko2013

    ๐Ÿ›
    shiomiyan
    shiomiyan

    ๐Ÿ“–
    simeonKondr
    simeonKondr

    ๐Ÿ›
    snajberk
    snajberk

    ๐Ÿ›
    sniperrifle2004
    sniperrifle2004

    ๐Ÿ›
    snuyanzin
    snuyanzin

    ๐Ÿ› ๐Ÿ’ป
    soloturn
    soloturn

    ๐Ÿ›
    soyodream
    soyodream

    ๐Ÿ›
    sratz
    sratz

    ๐Ÿ›
    stonio
    stonio

    ๐Ÿ›
    sturton
    sturton

    ๐Ÿ’ป ๐Ÿ›
    sudharmohan
    sudharmohan

    ๐Ÿ›
    suruchidawar
    suruchidawar

    ๐Ÿ›
    svenfinitiv
    svenfinitiv

    ๐Ÿ›
    szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป
    tashiscool
    tashiscool

    ๐Ÿ›
    test-git-hook
    test-git-hook

    ๐Ÿ›
    testation21
    testation21

    ๐Ÿ’ป ๐Ÿ›
    thanosa
    thanosa

    ๐Ÿ›
    tiandiyixian
    tiandiyixian

    ๐Ÿ›
    tobwoerk
    tobwoerk

    ๐Ÿ›
    tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป
    trentchilders
    trentchilders

    ๐Ÿ›
    triandicAnt
    triandicAnt

    ๐Ÿ›
    trishul14
    trishul14

    ๐Ÿ›
    tsui
    tsui

    ๐Ÿ›
    wangzitom12306
    wangzitom12306

    ๐Ÿ›
    winhkey
    winhkey

    ๐Ÿ›
    witherspore
    witherspore

    ๐Ÿ›
    wjljack
    wjljack

    ๐Ÿ›
    wuchiuwong
    wuchiuwong

    ๐Ÿ›
    xingsong
    xingsong

    ๐Ÿ›
    xioayuge
    xioayuge

    ๐Ÿ›
    xnYi9wRezm
    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ›
    xuanuy
    xuanuy

    ๐Ÿ›
    xyf0921
    xyf0921

    ๐Ÿ›
    yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ›
    yasuharu-sato
    yasuharu-sato

    ๐Ÿ›
    zenglian
    zenglian

    ๐Ÿ›
    zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ›
    zh3ng
    zh3ng

    ๐Ÿ›
    zt_soft
    zt_soft

    ๐Ÿ›
    ztt79
    ztt79

    ๐Ÿ›
    zzzzfeng
    zzzzfeng

    ๐Ÿ›
    รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ›
    ไปป่ดตๆฐ
    ไปป่ดตๆฐ

    ๐Ÿ›
    ่Œ…ๅปถๅฎ‰
    ่Œ…ๅปถๅฎ‰

    ๐Ÿ’ป

    0xflotus

    ๐Ÿ’ป ๐Ÿ›

    1henni

    ๐Ÿ›

    219sansim

    ๐Ÿ’ป

    ALiNew

    ๐Ÿ›

    ASBrouwers

    ๐Ÿ’ป

    Abhijit Sarkar

    ๐Ÿ›

    Abhishek Kumar

    ๐Ÿ›

    Adam

    ๐Ÿ›

    Adam Carroll

    ๐Ÿ›

    Adam Obuchowicz

    ๐Ÿ›

    Adrian Price

    ๐Ÿ›

    Adrien Lecharpentier

    ๐Ÿ›

    Aidan Harding

    ๐Ÿ›

    Akshat Bahety

    ๐Ÿ’ป ๐Ÿ›

    Akshay Thapa

    ๐Ÿ›

    Alan Buttars

    ๐Ÿ›

    Alan Hohn

    ๐Ÿ›

    Alberto Fernรกndez

    ๐Ÿ’ป ๐Ÿ›

    Alex

    ๐Ÿ’ป

    Alex

    ๐Ÿ›

    Alex B

    ๐Ÿ›

    Alex Rentz

    ๐Ÿ›

    Alex Saveau

    ๐Ÿ›

    Alex Shesterov

    ๐Ÿ’ป ๐Ÿ›

    Alexey Markevich

    ๐Ÿ›

    Alexey Naumov

    ๐Ÿ›

    Alexey Yudichev

    ๐Ÿ›

    Alix

    ๐Ÿ›

    Alix

    ๐Ÿ›

    Amish Shah

    ๐Ÿ›

    Amit Prasad

    ๐Ÿ›

    Amitosh Swain Mahapatra

    ๐Ÿ›

    Anand Subramanian

    ๐Ÿ’ป ๐Ÿ›

    Anastasiia Koba

    ๐Ÿ’ป

    Anatoly Trosinenko

    ๐Ÿ’ป ๐Ÿ›

    Andi Pabst

    ๐Ÿ’ป ๐Ÿ›

    Andrea

    ๐Ÿ›

    Andrea Aime

    ๐Ÿ›

    Andreas Dangel

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง

    Andreas Deininger

    ๐Ÿ“–

    Andreas Markussen

    ๐Ÿ›

    Andreas Schmid

    ๐Ÿ›

    Andreas Turban

    ๐Ÿ›

    Andrei Paikin

    ๐Ÿ›

    Andrew

    ๐Ÿ›

    Andrew Green

    ๐Ÿ›

    Andrey Bozhko

    ๐Ÿ“–

    Andrey Fomin

    ๐Ÿ›

    Andrey Hitrin

    ๐Ÿ›

    Andrey Mochalov

    ๐Ÿ’ป ๐Ÿ›

    Andro72

    ๐Ÿ›

    Andrwyw

    ๐Ÿ›

    Andrรฉs Catalรกn

    ๐Ÿ›

    Andy Goossens

    ๐Ÿ›

    Andy Pattenden

    ๐Ÿ›

    Andy Ray

    ๐Ÿ›

    Andy Robinson

    ๐Ÿ›

    Andy-2639

    ๐Ÿ›

    Ankush Somani

    ๐Ÿ›

    Anmol Kumar

    ๐Ÿ›

    Anthony Whitford

    ๐Ÿ›

    AnthonyKot

    ๐Ÿ›

    Anurag Agarwal

    ๐Ÿ›

    Aravind Hegde

    ๐Ÿ›

    Arda Aslan

    ๐Ÿ›

    Ari Fogel

    ๐Ÿ›

    Arnaud Jeansen

    ๐Ÿ’ป ๐Ÿ›

    Arpit Koolwal

    ๐Ÿ›

    Artem

    ๐Ÿ’ป ๐Ÿ›

    Artem

    ๐Ÿ›

    Artem Sheremet

    ๐Ÿ›

    Artur

    ๐Ÿ›

    Artur Bosch

    ๐Ÿ›

    Artur Dryomov

    ๐Ÿ›

    Artur Ossowski

    ๐Ÿ›

    Aryant Tripathi

    ๐Ÿ’ป

    AshTheMash

    ๐Ÿ›

    Ashish Rana

    ๐Ÿ›

    Atul Kaushal

    ๐Ÿ›

    August Boland

    ๐Ÿ›

    Aurel Hudec

    ๐Ÿ›

    Austin

    ๐Ÿ›

    Austin Shalit

    ๐Ÿ›

    Austin Tice

    ๐Ÿ›

    Ayoub Kaanich

    ๐Ÿ›

    BBG

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›

    Bailey Tjiong

    ๐Ÿ’ป

    Barthรฉlemy L.

    ๐Ÿ›

    Basavaraj K N

    ๐Ÿ›

    Basil Peace

    ๐Ÿ›

    Belle

    ๐Ÿ›

    Ben Lerner

    ๐Ÿ›

    Ben Manes

    ๐Ÿ›

    Ben McCann

    ๐Ÿ›

    Bendegรบz Nagy

    ๐Ÿ›

    Bennet S Yee

    ๐Ÿ›

    Benoit Lacelle

    ๐Ÿ›

    Bernardo Macรชdo

    ๐Ÿ›

    Bernd Farka

    ๐Ÿ›

    Betina Cynthia Mamani

    ๐Ÿ›

    Bhanu Prakash Pamidi

    ๐Ÿ’ป ๐Ÿ›

    Bhargav Thanki

    ๐Ÿ›

    Binu R J

    ๐Ÿ›

    Bjรถrn Kautler

    ๐Ÿ’ป ๐Ÿ›

    Blightbuster

    ๐Ÿ›

    Bo Zhang

    ๐Ÿ›

    Bob "Wombat" Hogg

    ๐Ÿ›

    Bobby Wertman

    ๐Ÿ›

    Bolarinwa Saheed Olayemi

    ๐Ÿ’ป ๐Ÿ›

    Boris Petrov

    ๐Ÿ›

    Brad Kent

    ๐Ÿ›

    Brandon Mikeska

    ๐Ÿ›

    Brian Batronis

    ๐Ÿ›

    Brian Johnson

    ๐Ÿ›

    Brice Dutheil

    ๐Ÿ’ป ๐Ÿ›

    Bruno Ferreira

    ๐Ÿ›

    Bruno Harbulot

    ๐Ÿ›

    Bruno Ritz

    ๐Ÿ›

    BurovnikovEvgeniy

    ๐Ÿ›

    Cameron Donaldson

    ๐Ÿ›

    Carlos Macasaet

    ๐Ÿ›

    Carsten Otto

    ๐Ÿ›

    Charlie Housh

    ๐Ÿ›

    Charlie Jonas

    ๐Ÿ›

    Chas Honton

    ๐Ÿ› ๐Ÿ’ป

    Chen Yang

    ๐Ÿ›

    Chotu

    ๐Ÿ›

    Chris Smith

    ๐Ÿ›

    Chris Toomey

    ๐Ÿ›

    Christian Hujer

    ๐Ÿ›

    Christian Pontesegger

    ๐Ÿ›

    ChristianWulf

    ๐Ÿ›

    Christofer Dutz

    ๐Ÿ’ป

    Christoffer Anselm

    ๐Ÿ›

    Christophe Vidal

    ๐Ÿ›

    Christopher Dancy

    ๐Ÿ›

    Clemens Prill

    ๐Ÿ›

    Clint Chester

    ๐Ÿ’ป ๐Ÿ›

    Clรฉment Fournier

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง

    Codacy Badger

    ๐Ÿ›

    Code-Nil

    ๐Ÿ›

    ColColonCleaner

    ๐Ÿ›

    Colin Ingarfield

    ๐Ÿ›

    Craig Andrews

    ๐Ÿ›

    Craig Muchinsky

    ๐Ÿ›

    Cyril

    ๐Ÿ’ป ๐Ÿ›

    Dale

    ๐Ÿ’ป

    Damien Jiang

    ๐Ÿ›

    Dan Berindei

    ๐Ÿ›

    Dan Rollo

    ๐Ÿ›

    Dan Ziemba

    ๐Ÿ›

    Daniel Gredler

    ๐Ÿ’ป ๐Ÿ›

    Daniel Jipa

    ๐Ÿ›

    Daniel Paul Searles

    ๐Ÿ’ป

    Daniel Reigada

    ๐Ÿ›

    Danilo Pianini

    ๐Ÿ›

    Darko

    ๐Ÿ›

    David

    ๐Ÿ›

    David Atkinson

    ๐Ÿ›

    David Burstrรถm

    ๐Ÿ’ป ๐Ÿ›

    David Goatรฉ

    ๐Ÿ›

    David Golpira

    ๐Ÿ›

    David Kovaล™รญk

    ๐Ÿ›

    David M. Karr (fullname at gmail.com)

    ๐Ÿ›

    David Renz

    ๐Ÿ’ป ๐Ÿ›

    David Renz

    ๐Ÿ›

    David Schach

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–

    Dawid Ciok

    ๐Ÿ› ๐Ÿ’ป

    Debamoy Datta

    ๐Ÿ’ป

    Deleted user

    ๐Ÿ›

    Dell Green

    ๐Ÿ›

    Dem Pilafian

    ๐Ÿ›

    Den

    ๐Ÿ›

    Denis Borovikov

    ๐Ÿ’ป ๐Ÿ›

    Dennie Reniers

    ๐Ÿ’ป ๐Ÿ›

    Dennis Kieselhorst

    ๐Ÿ›

    Derek P. Moore

    ๐Ÿ›

    Dichotomia

    ๐Ÿ›

    Dionisio Cortรฉs Fernรกndez

    ๐Ÿ’ป ๐Ÿ›

    Dmitri Bourlatchkov

    ๐Ÿ›

    Dmitriy Kuzmin

    ๐Ÿ›

    Dmytro Dashenkov

    ๐Ÿ›

    Dr. Christian Kohlschรผtter

    ๐Ÿ›

    Drew Hall

    ๐Ÿ›

    Dumitru Postoronca

    ๐Ÿ›

    Dylan Adams

    ๐Ÿ›

    Eden Hao

    ๐Ÿ›

    Edward Klimoshenko

    ๐Ÿ› ๐Ÿ’ป

    Egor Bredikhin

    ๐Ÿ›

    Elan P. Kugelmass

    ๐Ÿ›

    Elder S.

    ๐Ÿ›

    Eldrick Wega

    ๐Ÿ“–

    Emile

    ๐Ÿ›

    Eric

    ๐Ÿ›

    Eric Kintzer

    ๐Ÿ›

    Eric Perret

    ๐Ÿ›

    Eric Squires

    ๐Ÿ›

    Erich L Foster

    ๐Ÿ›

    Erik Bleske

    ๐Ÿ›

    Erik C. Thauvin

    ๐Ÿ“–

    Ernst Reissner

    ๐Ÿ›

    Ethan Sargent

    ๐Ÿ›

    Ewan Tempero

    ๐Ÿ›

    F.W. Dekker

    ๐Ÿ›

    FSchliephacke

    ๐Ÿ›

    Facundo

    ๐Ÿ›

    Federico Giust

    ๐Ÿ›

    Fedor Sherstobitov

    ๐Ÿ›

    Felix Lampe

    ๐Ÿ›

    Filip Golonka

    ๐Ÿ›

    Filipe Esperandio

    ๐Ÿ’ป ๐Ÿ›

    Filippo Nova

    ๐Ÿ›

    Francesco la Torre

    ๐Ÿ›

    Francisco Duarte

    ๐Ÿ›

    Frieder Bluemle

    ๐Ÿ›

    Frits Jalvingh

    ๐Ÿ’ป ๐Ÿ›

    G. Bazior

    ๐Ÿ›

    Gabe Henkes

    ๐Ÿ›

    Gary Gregory

    ๐Ÿ›

    Genoud Magloire

    ๐Ÿ›

    Geoffrey555

    ๐Ÿ›

    Georg Romstorfer

    ๐Ÿ›

    Gili Tzabari

    ๐Ÿ›

    Gio

    ๐Ÿ›

    Gol

    ๐Ÿ›

    Gold856

    ๐Ÿ› ๐Ÿ’ป

    Gonzalo Exequiel Ibars Ingman

    ๐Ÿ’ป ๐Ÿ›

    GooDer

    ๐Ÿ›

    Gregor Riegler

    ๐Ÿ›

    Grzegorz Olszewski

    ๐Ÿ›

    Gunther Schrijvers

    ๐Ÿ’ป ๐Ÿ›

    Gustavo Krieger

    ๐Ÿ›

    Guy Elsmore-Paddock

    ๐Ÿ›

    Gรถrkem Mรผlayim

    ๐Ÿ›

    Hanzel Godinez

    ๐Ÿ›

    Haoliang Chen

    ๐Ÿ›

    Harsh Kukreja

    ๐Ÿ›

    Hassan ALAMI

    ๐Ÿ›

    Heber

    ๐Ÿ›

    Henning Schmiedehausen

    ๐Ÿ’ป ๐Ÿ›

    Henning von Bargen

    ๐Ÿ’ป

    Hervรฉ Boutemy

    ๐Ÿ›

    Himanshu Pandey

    ๐Ÿ›

    Hokwang Lee

    ๐Ÿ›

    Hooperbloob

    ๐Ÿ’ป

    Hung PHAN

    ๐Ÿ›

    IDoCodingStuffs

    ๐Ÿ’ป ๐Ÿ›

    Iccen Gan

    ๐Ÿ›

    Ignacio Mariano Tirabasso

    ๐Ÿ›

    Igor Melnichenko

    ๐Ÿ›

    Igor Moreno

    ๐Ÿ›

    Intelesis-MS

    ๐Ÿ›

    Iroha_

    ๐Ÿ›

    Ishan Srivastava

    ๐Ÿ›

    Iskren Stanislavov

    ๐Ÿ›

    Ivan Vakhrushev

    ๐Ÿ›

    Ivano Guerini

    ๐Ÿ›

    Ivar Andreas Bonsaksen

    ๐Ÿ›

    Ivo ล mรญd

    ๐Ÿ›

    JJengility

    ๐Ÿ›

    Jake Hemmerle

    ๐Ÿ›

    Jakub Dupak

    ๐Ÿ’ป

    James Harrison

    ๐Ÿ› ๐Ÿ’ป

    Jamie Bisotti

    ๐Ÿ›

    Jan

    ๐Ÿ›

    Jan Aertgeerts

    ๐Ÿ’ป ๐Ÿ›

    Jan Brรผmmer

    ๐Ÿ›

    Jan Tล™รญska

    ๐Ÿ›

    Jan-Lukas Else

    ๐Ÿ›

    Jason Qiu

    ๐Ÿ’ป ๐Ÿ“–

    Jason Williams

    ๐Ÿ›

    Javier Spagnoletti

    ๐Ÿ›

    Jean-Paul Mayer

    ๐Ÿ›

    Jean-Simon Larochelle

    ๐Ÿ›

    Jeff Bartolotta

    ๐Ÿ’ป ๐Ÿ›

    Jeff Hube

    ๐Ÿ’ป ๐Ÿ›

    Jeff Jensen

    ๐Ÿ›

    Jeff May

    ๐Ÿ›

    Jens Gerdes

    ๐Ÿ›

    Jeroen Borgers

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข

    Jeroen Meijer

    ๐Ÿ›

    Jeroen van Wilgenburg

    ๐Ÿ“–

    Jerome Russ

    ๐Ÿ›

    JerritEic

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›

    Jiri Pejchal

    ๐Ÿ›

    Jithin Sunny

    ๐Ÿ›

    Jiล™รญ ล korpil

    ๐Ÿ›

    Joao Machado

    ๐Ÿ›

    Jochen Krauss

    ๐Ÿ›

    Johan Hammar

    ๐Ÿ›

    John Karp

    ๐Ÿ›

    John Zhang

    ๐Ÿ›

    John-Teng

    ๐Ÿ’ป ๐Ÿ›

    Jon Moroney

    ๐Ÿ’ป ๐Ÿ›

    Jonas Geiregat

    ๐Ÿ›

    Jonas KeรŸler

    ๐Ÿ›

    Jonathan Wiesel

    ๐Ÿ’ป ๐Ÿ›

    Jordan

    ๐Ÿ›

    Jordi Llach

    ๐Ÿ›

    Jorge Solรณrzano

    ๐Ÿ›

    JorneVL

    ๐Ÿ›

    Jose Palafox

    ๐Ÿ›

    Jose Stovall

    ๐Ÿ›

    Joseph

    ๐Ÿ’ป

    Joseph Heenan

    ๐Ÿ›

    Josh Feingold

    ๐Ÿ’ป ๐Ÿ›

    Josh Holthaus

    ๐Ÿ›

    Joshua S Arquilevich

    ๐Ÿ›

    Joรฃo Dinis Ferreira

    ๐Ÿ“–

    Joรฃo Ferreira

    ๐Ÿ’ป ๐Ÿ›

    Joรฃo Pedro Schmitt

    ๐Ÿ›

    Juan Martรญn Sotuyo Dodero

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง

    Juan Pablo Civile

    ๐Ÿ›

    Julian Voronetsky

    ๐Ÿ›

    Julien

    ๐Ÿ›

    Julius

    ๐Ÿ›

    JustPRV

    ๐Ÿ›

    Justin Stroud

    ๐Ÿ’ป

    Jรถrn Huxhorn

    ๐Ÿ›

    KThompso

    ๐Ÿ›

    Kai Amundsen

    ๐Ÿ›

    Karel Vervaeke

    ๐Ÿ›

    Karl-Andero Mere

    ๐Ÿ›

    Karl-Philipp Richter

    ๐Ÿ›

    Karsten Silz

    ๐Ÿ›

    Kazuma Watanabe

    ๐Ÿ›

    Kev

    ๐Ÿ›

    Keve Mรผller

    ๐Ÿ›

    Kevin Guerra

    ๐Ÿ’ป

    Kevin Jones

    ๐Ÿ› ๐Ÿ’ป

    Kevin Poorman

    ๐Ÿ›

    Kevin Wayne

    ๐Ÿ›

    Kieran Black

    ๐Ÿ›

    Kirill Zubov

    ๐Ÿ›

    Kirk Clemens

    ๐Ÿ’ป ๐Ÿ›

    Klaus Hartl

    ๐Ÿ›

    Koen Van Looveren

    ๐Ÿ›

    Kris Scheibe

    ๐Ÿ’ป ๐Ÿ›

    Krystian Dabrowski

    ๐Ÿ› ๐Ÿ’ป

    Kunal Thanki

    ๐Ÿ›

    LaLucid

    ๐Ÿ’ป

    Larry Diamond

    ๐Ÿ’ป ๐Ÿ›

    Lars Knickrehm

    ๐Ÿ›

    Laurent Bovet

    ๐Ÿ› ๐Ÿ’ป

    Leo Gutierrez

    ๐Ÿ›

    LiGaOg

    ๐Ÿ’ป

    Liam Sharp

    ๐Ÿ›

    Lintsi

    ๐Ÿ›

    Linus Fernandes

    ๐Ÿ›

    Lixon Lookose

    ๐Ÿ›

    Logesh

    ๐Ÿ›

    Lorenzo Gabriele

    ๐Ÿ›

    Loรฏc Ledoyen

    ๐Ÿ›

    Lucas

    ๐Ÿ›

    Lucas Silva

    ๐Ÿ›

    Lucas Soncini

    ๐Ÿ’ป ๐Ÿ›

    Luis Alcantar

    ๐Ÿ’ป

    Lukas Grรคf

    ๐Ÿ’ป

    Lukasz Slonina

    ๐Ÿ›

    Lukebray

    ๐Ÿ›

    Lynn

    ๐Ÿ’ป ๐Ÿ›

    Lyor Goldstein

    ๐Ÿ›

    MCMicS

    ๐Ÿ›

    Macarse

    ๐Ÿ›

    Machine account for PMD

    ๐Ÿ’ป

    Maciek Siemczyk

    ๐Ÿ›

    Maikel Steneker

    ๐Ÿ’ป ๐Ÿ›

    Maksim Moiseikin

    ๐Ÿ›

    Manfred Koch

    ๐Ÿ›

    Manuel Moya Ferrer

    ๐Ÿ’ป ๐Ÿ›

    Manuel Ryan

    ๐Ÿ›

    Marat Vyshegorodtsev

    ๐Ÿ›

    Marcel Hรคrle

    ๐Ÿ›

    Marcello Fialho

    ๐Ÿ›

    Marcin Dฤ…browski

    ๐Ÿ’ป

    Marcin Rataj

    ๐Ÿ›

    Marcono1234

    ๐Ÿ›

    Mark Adamcin

    ๐Ÿ›

    Mark Hall

    ๐Ÿ’ป ๐Ÿ›

    Mark Kolich

    ๐Ÿ›

    Mark Pritchard

    ๐Ÿ›

    Markus Rathgeb

    ๐Ÿ›

    Marquis Wang

    ๐Ÿ›

    MartGit

    ๐Ÿ›

    Martin Feldsztejn

    ๐Ÿ›

    Martin Lehmann

    ๐Ÿ›

    Martin Spamer

    ๐Ÿ›

    Martin Tarjรกnyi

    ๐Ÿ›

    MatFl

    ๐Ÿ›

    Mateusz Stefanski

    ๐Ÿ›

    Mathieu Gouin

    ๐Ÿ›

    MatiasComercio

    ๐Ÿ’ป ๐Ÿ›

    Matt Benson

    ๐Ÿ›

    Matt De Poorter

    ๐Ÿ›

    Matt Hargett

    ๐Ÿ’ป ๐Ÿ’ต

    Matt Harrah

    ๐Ÿ›

    Matt Nelson

    ๐Ÿ›

    Matthew Amos

    ๐Ÿ›

    Matthew Duggan

    ๐Ÿ›

    Matthew Hall

    ๐Ÿ›

    Matthew Rossner

    ๐Ÿ›

    Matรญas Fraga

    ๐Ÿ’ป ๐Ÿ›

    Maxime Robert

    ๐Ÿ’ป ๐Ÿ›

    MetaBF

    ๐Ÿ›

    Metin Dagcilar

    ๐Ÿ›

    Michael

    ๐Ÿ›

    Michael Bell

    ๐Ÿ›

    Michael Bernstein

    ๐Ÿ›

    Michael Clay

    ๐Ÿ›

    Michael Dombrowski

    ๐Ÿ›

    Michael Hausegger

    ๐Ÿ›

    Michael Hoefer

    ๐Ÿ›

    Michael Kolesnikov

    ๐Ÿ›

    Michael Mรถbius

    ๐Ÿ›

    Michael N. Lipp

    ๐Ÿ›

    Michael Pellegrini

    ๐Ÿ›

    Michal Kordas

    ๐Ÿ›

    Michaล‚ Borek

    ๐Ÿ›

    Michaล‚ Kuliล„ski

    ๐Ÿ›

    Miguel Nรบรฑez Dรญaz-Montes

    ๐Ÿ›

    Mihai Ionut

    ๐Ÿ›

    Mikhail Kuchma

    ๐Ÿ›

    Mirek Hankus

    ๐Ÿ›

    Mitch Spano

    ๐Ÿ› ๐Ÿ’ป

    Mladjan Gadzic

    ๐Ÿ›

    MrAngry52

    ๐Ÿ›

    Muminur Choudhury

    ๐Ÿ›

    Mykhailo Palahuta

    ๐Ÿ’ป ๐Ÿ›

    Nagendra Kumar Singh

    ๐Ÿ›

    Nahuel Barrios

    ๐Ÿ›

    Nakul Sharma

    ๐Ÿ›

    Nathan Braun

    ๐Ÿ›

    Nathan Reynolds

    ๐Ÿ›

    Nathan Reynolds

    ๐Ÿ›

    Nathanaรซl

    ๐Ÿ›

    Naveen

    ๐Ÿ’ป

    Nazdravi

    ๐Ÿ›

    Neha-Dhonde

    ๐Ÿ›

    Nicholas Doyle

    ๐Ÿ›

    Nick Butcher

    ๐Ÿ›

    Nico Gallinal

    ๐Ÿ›

    Nicola Dal Maso

    ๐Ÿ›

    Nicolas Filotto

    ๐Ÿ’ป

    Nicolas Vervelle

    ๐Ÿ›

    Nicolas Vuillamy

    ๐Ÿ“–

    Nikita Chursin

    ๐Ÿ›

    Niklas Baudy

    ๐Ÿ›

    Nikolas Havrikov

    ๐Ÿ›

    Nilesh Virkar

    ๐Ÿ›

    Nimit Patel

    ๐Ÿ›

    Niranjan Harpale

    ๐Ÿ›

    Nirvik Patel

    ๐Ÿ’ป

    Noah Sussman

    ๐Ÿ›

    Noah0120

    ๐Ÿ›

    Noam Tamim

    ๐Ÿ›

    Noel Grandin

    ๐Ÿ›

    Olaf Haalstra

    ๐Ÿ›

    Oleg Andreych

    ๐Ÿ’ป ๐Ÿ›

    Oleg Pavlenko

    ๐Ÿ›

    Oleksii Dykov

    ๐Ÿ’ป ๐Ÿ›

    Oliver Eikemeier

    ๐Ÿ›

    Oliver Siegmar

    ๐Ÿ’ต

    Olivier Parent

    ๐Ÿ’ป ๐Ÿ›

    Ollie Abbey

    ๐Ÿ’ป ๐Ÿ›

    Ondrej Kratochvil

    ๐Ÿ›

    OverDrone

    ๐Ÿ›

    Ozan Gulle

    ๐Ÿ’ป ๐Ÿ›

    PUNEET JAIN

    ๐Ÿ›

    Parbati Bose

    ๐Ÿ›

    Paul Berg

    ๐Ÿ›

    Paul Guyot

    ๐Ÿ’ป

    Pavel Bludov

    ๐Ÿ›

    Pavel Miฤka

    ๐Ÿ›

    Pedro Nuno Santos

    ๐Ÿ›

    Pedro Rijo

    ๐Ÿ›

    Pelisse Romain

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›

    Per Abich

    ๐Ÿ’ป

    Pete Davids

    ๐Ÿ›

    Peter Bruin

    ๐Ÿ›

    Peter Chittum

    ๐Ÿ’ป ๐Ÿ›

    Peter Cudmore

    ๐Ÿ›

    Peter Kasson

    ๐Ÿ›

    Peter Kofler

    ๐Ÿ›

    Peter Paul Bakker

    ๐Ÿ’ป

    Peter Rader

    ๐Ÿ›

    Pham Hai Trung

    ๐Ÿ›

    Philip Graf

    ๐Ÿ’ป ๐Ÿ›

    Philip Hachey

    ๐Ÿ›

    Philippe Ozil

    ๐Ÿ›

    Phinehas Artemix

    ๐Ÿ›

    Phokham Nonava

    ๐Ÿ›

    Pim van der Loos

    ๐Ÿ’ป โš ๏ธ

    Piotr Szymaล„ski

    ๐Ÿ›

    Piotrek ลปygieล‚o

    ๐Ÿ’ป ๐Ÿ› ๐Ÿ“–

    Pranay Jaiswal

    ๐Ÿ›

    Prasad Kamath

    ๐Ÿ›

    Prasanna

    ๐Ÿ›

    Presh-AR

    ๐Ÿ›

    Puneet1726

    ๐Ÿ›

    RBRi

    ๐Ÿ›

    Rafael Cortรชs

    ๐Ÿ›

    RaheemShaik999

    ๐Ÿ›

    RajeshR

    ๐Ÿ’ป ๐Ÿ›

    Ramachandra Mohan

    ๐Ÿ›

    Ramel0921

    ๐Ÿ›

    Raquel Pau

    ๐Ÿ›

    Ravikiran Janardhana

    ๐Ÿ›

    Reda Benhemmouche

    ๐Ÿ›

    Reinhard Schiedermeier

    ๐Ÿ›

    Renato Oliveira

    ๐Ÿ’ป ๐Ÿ›

    Rich DiCroce

    ๐Ÿ›

    Richard Corfield

    ๐Ÿ’ป

    Richard Corfield

    ๐Ÿ› ๐Ÿ’ป

    Riot R1cket

    ๐Ÿ›

    Rishabh Jain

    ๐Ÿ›

    RishabhDeep Singh

    ๐Ÿ›

    Rob Baillie

    ๐Ÿ›

    Robbie Martinus

    ๐Ÿ’ป ๐Ÿ›

    Robert Henry

    ๐Ÿ›

    Robert Mihaly

    ๐Ÿ›

    Robert Painsi

    ๐Ÿ›

    Robert Russell

    ๐Ÿ›

    Robert Sรถsemann

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ›

    Robert Whitebit

    ๐Ÿ›

    Robin Richtsfeld

    ๐Ÿ›

    Robin Stocker

    ๐Ÿ’ป ๐Ÿ›

    Robin Wils

    ๐Ÿ›

    RochusOest

    ๐Ÿ›

    Rodolfo Noviski

    ๐Ÿ›

    Rodrigo Casara

    ๐Ÿ›

    Rodrigo Fernandes

    ๐Ÿ›

    Roman Salvador

    ๐Ÿ’ป ๐Ÿ›

    Ronald Blaschke

    ๐Ÿ›

    Rรณbert Papp

    ๐Ÿ›

    Saikat Sengupta

    ๐Ÿ›

    Saksham Handu

    ๐Ÿ›

    Saladoc

    ๐Ÿ›

    Salesforce Bob Lightning

    ๐Ÿ›

    Sam Carlberg

    ๐Ÿ›

    Sascha Riemer

    ๐Ÿ›

    Sashko

    ๐Ÿ’ป

    Satoshi Kubo

    ๐Ÿ›

    Scott Kennedy

    ๐Ÿ›

    Scott Wells

    ๐Ÿ› ๐Ÿ’ป

    Scrates1

    ๐Ÿ› ๐Ÿ’ป

    Scrsloota

    ๐Ÿ’ป

    Sebastian Bรถgl

    ๐Ÿ›

    Sebastian Davids

    ๐Ÿ›

    Sebastian Schuberth

    ๐Ÿ›

    Sebastian Schwarz

    ๐Ÿ›

    Seren

    ๐Ÿ› ๐Ÿ’ป

    Sergey Gorbaty

    ๐Ÿ›

    Sergey Kozlov

    ๐Ÿ›

    Sergey Yanzin

    ๐Ÿ’ป ๐Ÿ›

    Seth Wilcox

    ๐Ÿ’ป

    Shai Bennathan

    ๐Ÿ› ๐Ÿ’ป

    Shubham

    ๐Ÿ’ป ๐Ÿ›

    Simon Abykov

    ๐Ÿ’ป ๐Ÿ›

    Simon Xiao

    ๐Ÿ›

    Srinivasan Venkatachalam

    ๐Ÿ›

    Stanislav Gromov

    ๐Ÿ›

    Stanislav Myachenkov

    ๐Ÿ’ป

    Stefan Birkner

    ๐Ÿ›

    Stefan Bohn

    ๐Ÿ›

    Stefan Endrullis

    ๐Ÿ›

    Stefan Klรถss-Schuster

    ๐Ÿ›

    Stefan Wolf

    ๐Ÿ›

    Stephan H. Wissel

    ๐Ÿ›

    Stephen

    ๐Ÿ›

    Stephen Carter

    ๐Ÿ›

    Stephen Friedrich

    ๐Ÿ›

    Steve Babula

    ๐Ÿ’ป

    Steven Stearns

    ๐Ÿ› ๐Ÿ’ป

    Stexxe

    ๐Ÿ›

    Stian Lรฅgstad

    ๐Ÿ›

    StuartClayton5

    ๐Ÿ›

    Supun Arunoda

    ๐Ÿ›

    Suren Abrahamyan

    ๐Ÿ›

    Suvashri

    ๐Ÿ“–

    SwatiBGupta1110

    ๐Ÿ›

    SyedThoufich

    ๐Ÿ›

    Szymon Sasin

    ๐Ÿ›

    T-chuangxin

    ๐Ÿ›

    TERAI Atsuhiro

    ๐Ÿ›

    TIOBE Software

    ๐Ÿ’ป ๐Ÿ›

    Tarush Singh

    ๐Ÿ’ป

    Taylor Smock

    ๐Ÿ›

    Techeira Damiรกn

    ๐Ÿ’ป ๐Ÿ›

    Ted Husted

    ๐Ÿ›

    TehBakker

    ๐Ÿ›

    The Gitter Badger

    ๐Ÿ›

    Theodoor

    ๐Ÿ›

    Thiago Henrique Hรผpner

    ๐Ÿ›

    Thibault Meyer

    ๐Ÿ›

    Thomas Gรผttler

    ๐Ÿ›

    Thomas Jones-Low

    ๐Ÿ›

    Thomas Smith

    ๐Ÿ’ป ๐Ÿ›

    ThrawnCA

    ๐Ÿ›

    Thu Vo

    ๐Ÿ›

    Thunderforge

    ๐Ÿ’ป ๐Ÿ›

    Tim van der Lippe

    ๐Ÿ›

    Tobias Weimer

    ๐Ÿ’ป ๐Ÿ›

    Tom Copeland

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–

    Tom Daly

    ๐Ÿ›

    Tomas

    ๐Ÿ›

    Tomer Figenblat

    ๐Ÿ›

    Tomi De Lucca

    ๐Ÿ’ป ๐Ÿ›

    Tony

    ๐Ÿ“–

    Torsten Kleiber

    ๐Ÿ›

    TrackerSB

    ๐Ÿ›

    Tyson Stewart

    ๐Ÿ›

    Ullrich Hafner

    ๐Ÿ›

    Utku Cuhadaroglu

    ๐Ÿ’ป ๐Ÿ›

    Valentin Brandl

    ๐Ÿ›

    Valeria

    ๐Ÿ›

    Valery Yatsynovich

    ๐Ÿ“–

    Vasily Anisimov

    ๐Ÿ›

    Vedant Chokshi

    ๐Ÿ›

    Vibhor Goyal

    ๐Ÿ›

    Vickenty Fesunov

    ๐Ÿ›

    Victor Noรซl

    ๐Ÿ›

    Vincent Galloy

    ๐Ÿ’ป

    Vincent HUYNH

    ๐Ÿ›

    Vincent Maurin

    ๐Ÿ›

    Vincent Privat

    ๐Ÿ›

    Vishhwas

    ๐Ÿ›

    Vishv_Android

    ๐Ÿ›

    Vitaly

    ๐Ÿ›

    Vitaly Polonetsky

    ๐Ÿ›

    Vojtech Polivka

    ๐Ÿ›

    Vsevolod Zholobov

    ๐Ÿ›

    Vyom Yadav

    ๐Ÿ’ป

    Wang Shidong

    ๐Ÿ›

    Waqas Ahmed

    ๐Ÿ›

    Wayne J. Earl

    ๐Ÿ›

    Wchenghui

    ๐Ÿ›

    Wener

    ๐Ÿ’ป

    Will Winder

    ๐Ÿ›

    William Brockhus

    ๐Ÿ’ป ๐Ÿ›

    Wilson Kurniawan

    ๐Ÿ›

    Wim Deblauwe

    ๐Ÿ›

    Woongsik Choi

    ๐Ÿ›

    XenoAmess

    ๐Ÿ’ป ๐Ÿ›

    Yang

    ๐Ÿ’ป

    YaroslavTER

    ๐Ÿ›

    Yasar Shaikh

    ๐Ÿ’ป

    Young Chan

    ๐Ÿ’ป ๐Ÿ›

    YuJin Kim

    ๐Ÿ›

    Yuri Dolzhenko

    ๐Ÿ›

    Yurii Dubinka

    ๐Ÿ›

    Zoltan Farkas

    ๐Ÿ›

    Zustin

    ๐Ÿ›

    aaronhurst-google

    ๐Ÿ› ๐Ÿ’ป

    alexmodis

    ๐Ÿ›

    andreoss

    ๐Ÿ›

    andrey81inmd

    ๐Ÿ’ป ๐Ÿ›

    anicoara

    ๐Ÿ›

    arunprasathav

    ๐Ÿ›

    asiercamara

    ๐Ÿ›

    astillich-igniti

    ๐Ÿ’ป

    avesolovksyy

    ๐Ÿ›

    avishvat

    ๐Ÿ›

    avivmu

    ๐Ÿ›

    axelbarfod1

    ๐Ÿ›

    b-3-n

    ๐Ÿ›

    balbhadra9

    ๐Ÿ›

    base23de

    ๐Ÿ›

    bergander

    ๐Ÿ› ๐Ÿ’ป

    berkam

    ๐Ÿ’ป ๐Ÿ›

    breizh31

    ๐Ÿ›

    caesarkim

    ๐Ÿ›

    carolyujing

    ๐Ÿ›

    cbfiddle

    ๐Ÿ›

    cesares-basilico

    ๐Ÿ›

    chrite

    ๐Ÿ›

    ciufudean

    ๐Ÿ“–

    cobratbq

    ๐Ÿ›

    coladict

    ๐Ÿ›

    cosmoJFH

    ๐Ÿ›

    cristalp

    ๐Ÿ›

    crunsk

    ๐Ÿ›

    cwholmes

    ๐Ÿ›

    cyberjj999

    ๐Ÿ›

    cyw3

    ๐Ÿ› ๐Ÿ“–

    d1ss0nanz

    ๐Ÿ›

    dague1

    ๐Ÿ“–

    dalizi007

    ๐Ÿ’ป

    danbrycefairsailcom

    ๐Ÿ›

    dariansanity

    ๐Ÿ›

    darrenmiliband

    ๐Ÿ›

    davidburstrom

    ๐Ÿ›

    dbirkman-paloalto

    ๐Ÿ›

    deepak-patra

    ๐Ÿ›

    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ›

    dinesh150

    ๐Ÿ›

    diziaq

    ๐Ÿ›

    dreaminpast123

    ๐Ÿ›

    duanyanan

    ๐Ÿ›

    dutt-sanjay

    ๐Ÿ›

    duursma

    ๐Ÿ’ป

    dylanleung

    ๐Ÿ›

    dzeigler

    ๐Ÿ›

    eant60

    ๐Ÿ›

    ekkirala

    ๐Ÿ›

    emersonmoura

    ๐Ÿ›

    emouty

    ๐Ÿ’ป ๐Ÿ›

    eugenepugach

    ๐Ÿ›

    fairy

    ๐Ÿ›

    filiprafalowicz

    ๐Ÿ’ป

    flxbl-io

    ๐Ÿ’ต

    foxmason

    ๐Ÿ›

    frankegabor

    ๐Ÿ›

    frankl

    ๐Ÿ›

    freafrea

    ๐Ÿ›

    fsapatin

    ๐Ÿ›

    gearsethenry

    ๐Ÿ›

    gracia19

    ๐Ÿ›

    gudzpoz

    ๐Ÿ›

    guo fei

    ๐Ÿ›

    gurmsc5

    ๐Ÿ›

    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ›

    haigsn

    ๐Ÿ›

    hemanshu070

    ๐Ÿ›

    henrik242

    ๐Ÿ›

    hongpuwu

    ๐Ÿ›

    hvbtup

    ๐Ÿ’ป ๐Ÿ›

    igniti GmbH

    ๐Ÿ›

    ilovezfs

    ๐Ÿ›

    imax-erik

    ๐Ÿ›

    itaigilo

    ๐Ÿ›

    jakivey32

    ๐Ÿ›

    jbennett2091

    ๐Ÿ›

    jcamerin

    ๐Ÿ›

    jkeener1

    ๐Ÿ›

    jmetertea

    ๐Ÿ›

    johnra2

    ๐Ÿ’ป

    johnzhao9

    ๐Ÿ›

    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ›

    kabroxiko

    ๐Ÿ’ป ๐Ÿ›

    karthikaiyasamy

    ๐Ÿ“–

    karwer

    ๐Ÿ›

    kaulonline

    ๐Ÿ›

    kdaemonv

    ๐Ÿ›

    kdebski85

    ๐Ÿ› ๐Ÿ’ป

    kenji21

    ๐Ÿ’ป ๐Ÿ›

    kfranic

    ๐Ÿ›

    khalidkh

    ๐Ÿ›

    koalalam

    ๐Ÿ›

    krzyk

    ๐Ÿ›

    lasselindqvist

    ๐Ÿ›

    lgemeinhardt

    ๐Ÿ›

    lihuaib

    ๐Ÿ›

    liqingjun123

    ๐Ÿ›

    lonelyma1021

    ๐Ÿ›

    lpeddy

    ๐Ÿ›

    lujiefsi

    ๐Ÿ’ป

    lukelukes

    ๐Ÿ’ป

    lyriccoder

    ๐Ÿ›

    marcelmore

    ๐Ÿ›

    matchbox

    ๐Ÿ›

    matthiaskraaz

    ๐Ÿ›

    meandonlyme

    ๐Ÿ›

    mikesive

    ๐Ÿ›

    milossesic

    ๐Ÿ›

    mluckam

    ๐Ÿ’ป ๐Ÿ›

    mohan-chinnappan-n

    ๐Ÿ’ป

    mriddell95

    ๐Ÿ›

    mrlzh

    ๐Ÿ›

    msloan

    ๐Ÿ›

    mucharlaravalika

    ๐Ÿ›

    mvenneman

    ๐Ÿ›

    nareshl119

    ๐Ÿ›

    nicolas-harraudeau-sonarsource

    ๐Ÿ›

    noerremark

    ๐Ÿ›

    novsirion

    ๐Ÿ›

    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป

    oggboy

    ๐Ÿ›

    oinume

    ๐Ÿ›

    orimarko

    ๐Ÿ’ป ๐Ÿ›

    pablogomez2197

    ๐Ÿ›

    pacvz

    ๐Ÿ’ป

    pallavi agarwal

    ๐Ÿ›

    parksungrin

    ๐Ÿ›

    patpatpat123

    ๐Ÿ›

    patriksevallius

    ๐Ÿ›

    pbrajesh1

    ๐Ÿ›

    phoenix384

    ๐Ÿ›

    piotrszymanski-sc

    ๐Ÿ’ป

    plan3d

    ๐Ÿ›

    poojasix

    ๐Ÿ›

    prabhushrikant

    ๐Ÿ›

    pujitha8783

    ๐Ÿ›

    r-r-a-j

    ๐Ÿ›

    raghujayjunk

    ๐Ÿ›

    rajeshveera

    ๐Ÿ›

    rajeswarreddy88

    ๐Ÿ›

    recdevs

    ๐Ÿ›

    reudismam

    ๐Ÿ’ป ๐Ÿ›

    rijkt

    ๐Ÿ›

    rillig-tk

    ๐Ÿ›

    rmohan20

    ๐Ÿ’ป ๐Ÿ›

    rnveach

    ๐Ÿ›

    rxmicro

    ๐Ÿ›

    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ›

    sabi0

    ๐Ÿ›

    scais

    ๐Ÿ›

    schosin

    ๐Ÿ›

    screamingfrog

    ๐Ÿ’ต

    sebbASF

    ๐Ÿ›

    sergeygorbaty

    ๐Ÿ’ป

    shilko2013

    ๐Ÿ›

    shiomiyan

    ๐Ÿ“–

    simeonKondr

    ๐Ÿ›

    snajberk

    ๐Ÿ›

    sniperrifle2004

    ๐Ÿ›

    snuyanzin

    ๐Ÿ› ๐Ÿ’ป

    soloturn

    ๐Ÿ›

    soyodream

    ๐Ÿ›

    sratz

    ๐Ÿ›

    stonio

    ๐Ÿ›

    sturton

    ๐Ÿ’ป ๐Ÿ›

    sudharmohan

    ๐Ÿ›

    suruchidawar

    ๐Ÿ›

    svenfinitiv

    ๐Ÿ›

    szymanp23

    ๐Ÿ› ๐Ÿ’ป

    tashiscool

    ๐Ÿ›

    test-git-hook

    ๐Ÿ›

    testation21

    ๐Ÿ’ป ๐Ÿ›

    thanosa

    ๐Ÿ›

    tiandiyixian

    ๐Ÿ›

    tobwoerk

    ๐Ÿ›

    tprouvot

    ๐Ÿ› ๐Ÿ’ป

    trentchilders

    ๐Ÿ›

    triandicAnt

    ๐Ÿ›

    trishul14

    ๐Ÿ›

    tsui

    ๐Ÿ›

    wangzitom12306

    ๐Ÿ›

    winhkey

    ๐Ÿ›

    witherspore

    ๐Ÿ›

    wjljack

    ๐Ÿ›

    wuchiuwong

    ๐Ÿ›

    xingsong

    ๐Ÿ›

    xioayuge

    ๐Ÿ›

    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ›

    xuanuy

    ๐Ÿ›

    xyf0921

    ๐Ÿ›

    yalechen-cyw3

    ๐Ÿ›

    yasuharu-sato

    ๐Ÿ›

    zenglian

    ๐Ÿ›

    zgrzyt93

    ๐Ÿ’ป ๐Ÿ›

    zh3ng

    ๐Ÿ›

    zt_soft

    ๐Ÿ›

    ztt79

    ๐Ÿ›

    zzzzfeng

    ๐Ÿ›

    รrpรกd Magosรกnyi

    ๐Ÿ›

    ไปป่ดตๆฐ

    ๐Ÿ›

    ่Œ…ๅปถๅฎ‰

    ๐Ÿ’ป
    From 52fb6c814bafd47315e92453337dcd4ff5d22784 Mon Sep 17 00:00:00 2001 From: mitchspano Date: Fri, 1 Nov 2024 21:17:53 +0000 Subject: [PATCH 0194/1962] Queueable Should Attach Finalizer --- .../QueueableShouldAttachFinalizerRule.java | 87 +++++++++++++++++++ .../resources/category/apex/bestpractices.xml | 26 ++++++ .../QueueableShouldAttachFinalizerTest.java | 11 +++ .../xml/QueueableShouldAttachFinalizer.xml | 51 +++++++++++ 4 files changed, 175 insertions(+) create mode 100644 pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableShouldAttachFinalizerRule.java create mode 100644 pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableShouldAttachFinalizerTest.java create mode 100644 pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/bestpractices/xml/QueueableShouldAttachFinalizer.xml diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableShouldAttachFinalizerRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableShouldAttachFinalizerRule.java new file mode 100644 index 00000000000..dad3ebfc942 --- /dev/null +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableShouldAttachFinalizerRule.java @@ -0,0 +1,87 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.apex.rule.bestpractices; + +import java.util.List; +import net.sourceforge.pmd.lang.apex.ast.ASTMethod; +import net.sourceforge.pmd.lang.apex.ast.ASTMethodCallExpression; +import net.sourceforge.pmd.lang.apex.ast.ASTParameter; +import net.sourceforge.pmd.lang.apex.ast.ASTUserClass; +import net.sourceforge.pmd.lang.apex.rule.AbstractApexRule; + +/** + * Scans classes which implement the `Queueable` interface. If the `public void + * execute(QueueableContext context)` method does not call the `System.attachFinalizer(Finalizer f)` + * method, then a violation will be added to the `execute` method. + * + * @author mitchspano + */ +public class QueueableShouldAttachFinalizerRule extends AbstractApexRule { + + private static final String EXECUTE = "execute"; + private static final String QUEUEABLE = "queueable"; + private static final String QUEUEABLE_CONTEXT = "queueablecontext"; + private static final String SYSTEM_ATTACH_FINALIZER = "system.attachfinalizer"; + + /** Scans the top level class and all inner classes. */ + @Override + public Object visit(ASTUserClass topLevelClass, Object data) { + scanClassForViolation(topLevelClass, data); + for (ASTUserClass innerClass : topLevelClass.descendants(ASTUserClass.class).toList()) { + scanClassForViolation(innerClass, data); + } + return data; + } + + /** + * If the class implements the `Queueable` interface and the `execute(QueueableContext context)` + * does not call the `System.attachFinalizer(Finalizer f)` method, then add a violation. + */ + private void scanClassForViolation(ASTUserClass theClass, Object data) { + if (!implementsTheQueueableInterface(theClass)) { + return; + } + for (ASTMethod theMethod : theClass.descendants(ASTMethod.class).toList()) { + if (isTheExecuteMethodOfTheQueueableInterface(theMethod) + && !callsTheSystemAttachFinalizerMethod(theMethod)) { + asCtx(data).addViolation(theMethod); + } + } + } + + /** Determines if the class implements the Queueable interface. */ + private boolean implementsTheQueueableInterface(ASTUserClass theClass) { + for (String interfaceName : theClass.getInterfaceNames()) { + if (interfaceName.equalsIgnoreCase(QUEUEABLE)) { + return true; + } + } + return false; + } + + /** + * Determines if the method is the `execute(QueueableContext context)` method. Parameter count is + * checked to account for method overloading. + */ + private boolean isTheExecuteMethodOfTheQueueableInterface(ASTMethod theMethod) { + if (!theMethod.getCanonicalName().equalsIgnoreCase(EXECUTE)) { + return false; + } + List parameters = theMethod.descendants(ASTParameter.class).toList(); + return parameters.size() == 1 + && parameters.get(0).getType().equalsIgnoreCase(QUEUEABLE_CONTEXT); + } + + /** Determines if the method calls the `System.attachFinalizer(Finalizer f)` method. */ + private boolean callsTheSystemAttachFinalizerMethod(ASTMethod theMethod) { + for (ASTMethodCallExpression methodCallExpression : + theMethod.descendants(ASTMethodCallExpression.class).toList()) { + if (methodCallExpression.getFullMethodName().equalsIgnoreCase(SYSTEM_ATTACH_FINALIZER)) { + return true; + } + } + return false; + } +} diff --git a/pmd-apex/src/main/resources/category/apex/bestpractices.xml b/pmd-apex/src/main/resources/category/apex/bestpractices.xml index f2d723cb8c8..7a023c169b7 100644 --- a/pmd-apex/src/main/resources/category/apex/bestpractices.xml +++ b/pmd-apex/src/main/resources/category/apex/bestpractices.xml @@ -285,4 +285,30 @@ Detects when a local variable is declared and/or assigned but not used.
    + + +Detects when the Queueable interface is used but a Finalizer is not attached. + + + usersToUpdate; + + public UserUpdater(List usersToUpdate) { + this.usersToUpdate = usersToUpdate; + } + + public void execute(QueueableContext context) { // no Finalizer is attached + update usersToUpdate; + } + } +]]> + + + diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableShouldAttachFinalizerTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableShouldAttachFinalizerTest.java new file mode 100644 index 00000000000..f24a3d94f54 --- /dev/null +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableShouldAttachFinalizerTest.java @@ -0,0 +1,11 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.apex.rule.bestpractices; + +import net.sourceforge.pmd.test.PmdRuleTst; + +class QueueableShouldAttachFinalizerTest extends PmdRuleTst { + // no additional unit tests +} diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/bestpractices/xml/QueueableShouldAttachFinalizer.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/bestpractices/xml/QueueableShouldAttachFinalizer.xml new file mode 100644 index 00000000000..207b2bb5cc2 --- /dev/null +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/bestpractices/xml/QueueableShouldAttachFinalizer.xml @@ -0,0 +1,51 @@ + + + + + [apex] Queueable Should Attach Finalizer - positive test case #5302 + 1 + 8 + usersToUpdate; + + public UserUpdater(List usersToUpdate) { + this.usersToUpdate = usersToUpdate; + } + + public void execute(QueueableContext context) { + update usersToUpdate; + } +} + ]]> + + + [apex] Queueable Should Attach Finalizer - negative test case #5302 + 0 + usersToUpdate; + + public UserUpdater(List usersToUpdate) { + this.usersToUpdate = usersToUpdate; + } + + public void execute(QueueableContext context) { + System.attachFinalizer(this); + update usersToUpdate; + } + + public void execute(FinalizerContext ctx) { + if (ctx.getResult() == ParentJobResult.SUCCESS) { + // Handle success + } else { + // Handle failure + } + } +} + ]]> + + \ No newline at end of file From be3c34fe1ad34a4e3e317d20778a7531b4ea7c59 Mon Sep 17 00:00:00 2001 From: mitchspano Date: Fri, 1 Nov 2024 21:29:30 +0000 Subject: [PATCH 0195/1962] Add priority definition. --- .../resources/category/apex/bestpractices.xml | 128 +++++++++--------- 1 file changed, 65 insertions(+), 63 deletions(-) diff --git a/pmd-apex/src/main/resources/category/apex/bestpractices.xml b/pmd-apex/src/main/resources/category/apex/bestpractices.xml index 7a023c169b7..784b9f99b1f 100644 --- a/pmd-apex/src/main/resources/category/apex/bestpractices.xml +++ b/pmd-apex/src/main/resources/category/apex/bestpractices.xml @@ -1,20 +1,20 @@ + xmlns="http://pmd.sourceforge.net/ruleset/2.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd"> Rules which enforce generally accepted best practices. + language="apex" + since="6.13.0" + message="Apex test assert statement should make use of the message parameter." + class="net.sourceforge.pmd.lang.apex.rule.bestpractices.ApexAssertionsShouldIncludeMessageRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_bestpractices.html#apexassertionsshouldincludemessage"> The second parameter of System.assert/third parameter of System.assertEquals/System.assertNotEquals is a message. Having a second/third parameter provides more information and makes it easier to debug the test failure and @@ -38,11 +38,11 @@ public class Foo { + language="apex" + since="5.5.1" + message="Apex unit tests should System.assert() or assertEquals() or assertNotEquals()" + class="net.sourceforge.pmd.lang.apex.rule.bestpractices.ApexUnitTestClassShouldHaveAssertsRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_bestpractices.html#apexunittestclassshouldhaveasserts"> Apex unit tests should include at least one assertion. This makes the tests more robust, and using assert with messages provide the developer a clearer idea of what the test does. Custom assert method invocation @@ -65,11 +65,11 @@ public class Foo { + language="apex" + since="6.51.0" + message="Apex unit test classes should have at least one System.runAs() call" + class="net.sourceforge.pmd.lang.apex.rule.bestpractices.ApexUnitTestClassShouldHaveRunAsRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_bestpractices.html#apexunittestclassshouldhaverunas"> Apex unit tests should include at least one runAs method. This makes the tests more robust, and independent from the user running it. @@ -103,11 +103,11 @@ private class TestRunAs { + since="6.13.0" + language="apex" + message="Apex test methods should have @isTest annotation." + class="net.sourceforge.pmd.lang.rule.xpath.XPathRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_bestpractices.html#apexunittestmethodshouldhaveistestannotation"> Apex test methods should have `@isTest` annotation instead of the `testMethod` keyword, as `testMethod` is deprecated. @@ -148,11 +148,11 @@ private class ATest { + language="apex" + since="5.5.1" + message="Apex unit tests should not use @isTest(seeAllData = true)" + class="net.sourceforge.pmd.lang.apex.rule.bestpractices.ApexUnitTestShouldNotUseSeeAllDataTrueRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_bestpractices.html#apexunittestshouldnotuseseealldatatrue"> Apex unit tests should not use @isTest(seeAllData=true) because it opens up the existing database data for unexpected modification by tests. @@ -173,11 +173,11 @@ public class Foo { + language="apex" + since="5.5.0" + message="Avoid using global modifier" + class="net.sourceforge.pmd.lang.apex.rule.bestpractices.AvoidGlobalModifierRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_bestpractices.html#avoidglobalmodifier"> Global classes should be avoided (especially in managed packages) as they can never be deleted or changed in signature. Always check twice if something needs to be global. Many interfaces (e.g. Batch) required global modifiers in the past but don't require this anymore. Don't lock yourself in. @@ -195,11 +195,11 @@ global class Unchangeable { + language="apex" + since="5.5.0" + message="Avoid logic in triggers" + class="net.sourceforge.pmd.lang.apex.rule.bestpractices.AvoidLogicInTriggerRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_bestpractices.html#avoidlogicintrigger"> As triggers do not allow methods like regular classes they are less flexible and suited to apply good encapsulation style. Therefore delegate the triggers work to a regular class (often called Trigger handler class). @@ -227,29 +227,30 @@ trigger Accounts on Account (before insert, before update, before delete, after - + since="6.18.0" + language="apex" + message="Calls to System.debug should specify a logging level." + class="net.sourceforge.pmd.lang.rule.xpath.XPathRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_bestpractices.html#debugsshoulduselogginglevel"> + The first parameter of System.debug, when using the signature with two parameters, is a LoggingLevel enum. Having the Logging Level specified provides a cleaner log, and improves readability of it. - 3 - - - - + 3 + + + + - - - + + + + since="6.23.0" + language="apex" + message="Variable ''{0}'' defined but not used" + class="net.sourceforge.pmd.lang.apex.rule.bestpractices.UnusedLocalVariableRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_bestpractices.html#unusedlocalvariable"> Detects when a local variable is declared and/or assigned but not used. + 5 + since="7.8.0" + language="apex" + message="It is best practice to call the `System.attachFinalizer(Finalizer f)` method within the `execute` method of a class which implements the `Queueable` interface." + class="net.sourceforge.pmd.lang.apex.rule.bestpractices.QueueableShouldAttachFinalizerRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_bestpractices.html#queueableshouldattachfinalizer"> Detects when the Queueable interface is used but a Finalizer is not attached. @@ -311,4 +313,4 @@ Detects when the Queueable interface is used but a Finalizer is not attached. - + \ No newline at end of file From 83d8ca0169167638151ccb98030c72300bb91a3a Mon Sep 17 00:00:00 2001 From: mitchspano Date: Fri, 1 Nov 2024 21:59:13 +0000 Subject: [PATCH 0196/1962] Fix `bestPractices.xml` formatting and priority definition. --- .../resources/category/apex/bestpractices.xml | 129 +++++++++--------- 1 file changed, 64 insertions(+), 65 deletions(-) diff --git a/pmd-apex/src/main/resources/category/apex/bestpractices.xml b/pmd-apex/src/main/resources/category/apex/bestpractices.xml index 784b9f99b1f..f69949af4a7 100644 --- a/pmd-apex/src/main/resources/category/apex/bestpractices.xml +++ b/pmd-apex/src/main/resources/category/apex/bestpractices.xml @@ -1,20 +1,20 @@ + xmlns="http://pmd.sourceforge.net/ruleset/2.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd"> Rules which enforce generally accepted best practices. + language="apex" + since="6.13.0" + message="Apex test assert statement should make use of the message parameter." + class="net.sourceforge.pmd.lang.apex.rule.bestpractices.ApexAssertionsShouldIncludeMessageRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_bestpractices.html#apexassertionsshouldincludemessage"> The second parameter of System.assert/third parameter of System.assertEquals/System.assertNotEquals is a message. Having a second/third parameter provides more information and makes it easier to debug the test failure and @@ -38,11 +38,11 @@ public class Foo { + language="apex" + since="5.5.1" + message="Apex unit tests should System.assert() or assertEquals() or assertNotEquals()" + class="net.sourceforge.pmd.lang.apex.rule.bestpractices.ApexUnitTestClassShouldHaveAssertsRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_bestpractices.html#apexunittestclassshouldhaveasserts"> Apex unit tests should include at least one assertion. This makes the tests more robust, and using assert with messages provide the developer a clearer idea of what the test does. Custom assert method invocation @@ -65,11 +65,11 @@ public class Foo { + language="apex" + since="6.51.0" + message="Apex unit test classes should have at least one System.runAs() call" + class="net.sourceforge.pmd.lang.apex.rule.bestpractices.ApexUnitTestClassShouldHaveRunAsRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_bestpractices.html#apexunittestclassshouldhaverunas"> Apex unit tests should include at least one runAs method. This makes the tests more robust, and independent from the user running it. @@ -103,11 +103,11 @@ private class TestRunAs { + since="6.13.0" + language="apex" + message="Apex test methods should have @isTest annotation." + class="net.sourceforge.pmd.lang.rule.xpath.XPathRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_bestpractices.html#apexunittestmethodshouldhaveistestannotation"> Apex test methods should have `@isTest` annotation instead of the `testMethod` keyword, as `testMethod` is deprecated. @@ -148,11 +148,11 @@ private class ATest { + language="apex" + since="5.5.1" + message="Apex unit tests should not use @isTest(seeAllData = true)" + class="net.sourceforge.pmd.lang.apex.rule.bestpractices.ApexUnitTestShouldNotUseSeeAllDataTrueRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_bestpractices.html#apexunittestshouldnotuseseealldatatrue"> Apex unit tests should not use @isTest(seeAllData=true) because it opens up the existing database data for unexpected modification by tests. @@ -173,11 +173,11 @@ public class Foo { + language="apex" + since="5.5.0" + message="Avoid using global modifier" + class="net.sourceforge.pmd.lang.apex.rule.bestpractices.AvoidGlobalModifierRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_bestpractices.html#avoidglobalmodifier"> Global classes should be avoided (especially in managed packages) as they can never be deleted or changed in signature. Always check twice if something needs to be global. Many interfaces (e.g. Batch) required global modifiers in the past but don't require this anymore. Don't lock yourself in. @@ -195,11 +195,11 @@ global class Unchangeable { + language="apex" + since="5.5.0" + message="Avoid logic in triggers" + class="net.sourceforge.pmd.lang.apex.rule.bestpractices.AvoidLogicInTriggerRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_bestpractices.html#avoidlogicintrigger"> As triggers do not allow methods like regular classes they are less flexible and suited to apply good encapsulation style. Therefore delegate the triggers work to a regular class (often called Trigger handler class). @@ -227,30 +227,29 @@ trigger Accounts on Account (before insert, before update, before delete, after - + since="6.18.0" + language="apex" + message="Calls to System.debug should specify a logging level." + class="net.sourceforge.pmd.lang.rule.xpath.XPathRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_bestpractices.html#debugsshoulduselogginglevel"> + The first parameter of System.debug, when using the signature with two parameters, is a LoggingLevel enum. Having the Logging Level specified provides a cleaner log, and improves readability of it. - 3 - - - - + 3 + + + + - - - + + + + since="6.23.0" + language="apex" + message="Variable ''{0}'' defined but not used" + class="net.sourceforge.pmd.lang.apex.rule.bestpractices.UnusedLocalVariableRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_bestpractices.html#unusedlocalvariable"> Detects when a local variable is declared and/or assigned but not used. - 5 + since="7.8.0" + language="apex" + message="It is best practice to call the `System.attachFinalizer(Finalizer f)` method within the `execute` method of a class which implements the `Queueable` interface." + class="net.sourceforge.pmd.lang.apex.rule.bestpractices.QueueableShouldAttachFinalizerRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_bestpractices.html#queueableshouldattachfinalizer"> Detects when the Queueable interface is used but a Finalizer is not attached. + 5 - \ No newline at end of file + From 36dfcf82112044442d083c15c778658a988fa949 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 03:08:41 +0000 Subject: [PATCH 0197/1962] Bump org.apache.maven.plugins:maven-clean-plugin from 3.3.2 to 3.4.0 Bumps [org.apache.maven.plugins:maven-clean-plugin](https://github.com/apache/maven-clean-plugin) from 3.3.2 to 3.4.0. - [Release notes](https://github.com/apache/maven-clean-plugin/releases) - [Commits](https://github.com/apache/maven-clean-plugin/compare/maven-clean-plugin-3.3.2...maven-clean-plugin-3.4.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-clean-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d09220f92bf..915bd9c00e9 100644 --- a/pom.xml +++ b/pom.xml @@ -202,7 +202,7 @@ org.apache.maven.plugins maven-clean-plugin - 3.3.2 + 3.4.0 From e15c05721eb1b202f41a8fa03db835becababff5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 09:23:58 +0100 Subject: [PATCH 0198/1962] Bump webrick from 1.8.2 to 1.9.0 in /docs in the all-gems group across 1 directory (#5308) Bump webrick in /docs in the all-gems group across 1 directory Bumps the all-gems group with 1 update in the /docs directory: [webrick](https://github.com/ruby/webrick). Updates `webrick` from 1.8.2 to 1.9.0 - [Release notes](https://github.com/ruby/webrick/releases) - [Commits](https://github.com/ruby/webrick/compare/v1.8.2...v1.9.0) --- updated-dependencies: - dependency-name: webrick dependency-type: direct:production update-type: version-update:semver-minor dependency-group: all-gems ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index 85d32da6ff0..c65178abcd7 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -266,7 +266,7 @@ GEM concurrent-ruby (~> 1.0) unicode-display_width (1.8.0) uri (0.13.1) - webrick (1.8.2) + webrick (1.9.0) PLATFORMS x86_64-linux From a1996554d88d8a9109a44d31af9d62746f2e02ef Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 31 Oct 2024 17:04:19 +0100 Subject: [PATCH 0199/1962] [java] Add DeadlockTest for verifying #5293 - Improve logging for Parselock Refs #5293 --- .../java/symbols/internal/asm/ClassStub.java | 7 +- .../symbols/internal/asm/GenericSigBase.java | 8 +- .../java/symbols/internal/asm/ModuleStub.java | 2 +- .../java/symbols/internal/asm/ParseLock.java | 18 +++- .../pmd/lang/java/symbols/DeadlockTest.java | 86 +++++++++++++++++++ .../test/resources/simplelogger.properties | 5 ++ 6 files changed, 114 insertions(+), 12 deletions(-) create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/DeadlockTest.java create mode 100644 pmd-java/src/test/resources/simplelogger.properties diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java index 6a050ca5b3d..c5337cf773e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java @@ -84,12 +84,7 @@ private static boolean isValidInternalName(String internalName) { this.resolver = resolver; this.names = new Names(internalName); - this.parseLock = new ParseLock() { - // note to devs: to debug the parsing logic you might have - // to replace the implementation of toString temporarily, - // otherwise an IDE could call toString just to show the item - // in the debugger view (which could cause parsing of the class file). - + this.parseLock = new ParseLock("ClassStub:" + internalName) { @Override protected boolean doParse() throws IOException { try (InputStream instream = loader.getInputStream()) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java index 67844686466..8ee5f39aaad 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java @@ -46,9 +46,9 @@ abstract class GenericSigBase { protected List typeParameters; private final ParseLock lock; - protected GenericSigBase(T ctx) { + protected GenericSigBase(T ctx, String parseLockName) { this.ctx = ctx; - this.lock = new ParseLock() { + this.lock = new ParseLock(parseLockName) { @Override protected boolean doParse() { GenericSigBase.this.doParse(); @@ -116,7 +116,7 @@ static class LazyClassSignature extends GenericSigBase { @Nullable String signature, // null if doesn't use generics in header @Nullable String superInternalName, // null if this is the Object class String[] interfaces) { - super(ctx); + super(ctx, "LazyClassSignature:" + ctx.getInternalName() + "[" + signature + "]"); this.signature = signature; this.rawItfs = CollectionUtil.map(interfaces, ctx.getResolver()::resolveFromInternalNameCannotFail); @@ -233,7 +233,7 @@ static class LazyMethodType extends GenericSigBase implements Ty @Nullable String genericSig, @Nullable String[] exceptions, boolean skipFirstParam) { - super(ctx); + super(ctx, "LazyMethodType:" + (genericSig != null ? genericSig : descriptor)); this.signature = genericSig != null ? genericSig : descriptor; // generic signatures already omit the synthetic param this.skipFirstParam = skipFirstParam && genericSig == null; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ModuleStub.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ModuleStub.java index 3db93664d3c..1c0b33b0d2d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ModuleStub.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ModuleStub.java @@ -35,7 +35,7 @@ class ModuleStub implements JModuleSymbol, AsmStub, AnnotationOwner { this.resolver = resolver; this.moduleName = moduleName; - this.parseLock = new ParseLock() { + this.parseLock = new ParseLock("ModuleStub:" + moduleName) { @Override protected boolean doParse() throws IOException { try (InputStream instream = loader.getInputStream()) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java index a7bfada5ea9..a0150e00fe7 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java @@ -17,15 +17,30 @@ abstract class ParseLock { private static final Logger LOG = LoggerFactory.getLogger(ParseLock.class); private volatile ParseStatus status = ParseStatus.NOT_PARSED; + private final String name; + + protected ParseLock(String name) { + this.name = name; + } public void ensureParsed() { getFinalStatus(); } + private void logParseLockTrace(String prefix) { + if (LOG.isTraceEnabled()) { + LOG.trace("{} {}: {}", Thread.currentThread().getName(), String.format("%-15s", prefix), this); + } + } + private ParseStatus getFinalStatus() { ParseStatus status = this.status; if (!status.isFinished) { + logParseLockTrace("waiting on"); + synchronized (this) { + logParseLockTrace("locked"); + status = this.status; if (status == ParseStatus.NOT_PARSED) { this.status = ParseStatus.BEING_PARSED; @@ -54,6 +69,7 @@ private ParseStatus getFinalStatus() { throw new IllegalStateException("Thread is reentering the parse lock"); } } + logParseLockTrace("released"); } return status; } @@ -85,7 +101,7 @@ protected boolean postCondition() { @Override public String toString() { - return "ParseLock{status=" + status + '}'; + return "ParseLock{name=" + name + ",status=" + status + '}'; } private enum ParseStatus { diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/DeadlockTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/DeadlockTest.java new file mode 100644 index 00000000000..25e3de1948b --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/DeadlockTest.java @@ -0,0 +1,86 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.symbols; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; + +import net.sourceforge.pmd.lang.java.JavaParsingHelper; +import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; + +/** + * Tests to help analyze [java] Deadlock when executing PMD in multiple threads #5293. + * + * @see [java] Deadlock when executing PMD in multiple threads #5293 + */ +class DeadlockTest { + + abstract static class Outer implements GenericInterface, GenericClass> { + // must be a nested class, that is reusing the type param T of the outer class + abstract static class Inner { + Inner(Outer grid) { } + } + } + + static class GenericBaseClass { } + + interface GenericInterface { } + + abstract static class GenericClass extends GenericBaseClass> { } + + @Test + @Timeout(2) + void parseWithoutDeadlock() throws InterruptedException { + /* + Deadlock: + t1 -> locks parse for Outer.Inner and waits for parse lock for Outer + t2 -> locks parse for Outer, locks parse for GenericInterface and then waits for parse lock for Outer.Inner + + + In order to reproduce the deadlock reliably, add the following piece into ParseLock, just at the beginning + of the synchronized block (line 42): + + // t1 needs to wait after having the lock, so that t2 can go on and wait on the same lock + if (Thread.currentThread().getName().equals("t1") && this.toString().contains("LazyClassSignature:net/sourceforge/pmd/lang/java/symbols/DeadlockTest$Outer$Inner[ { + ASTCompilationUnit class1 = JavaParsingHelper.DEFAULT.parse( + "package net.sourceforge.pmd.lang.java.symbols;\n" + + "import net.sourceforge.pmd.lang.java.symbols.DeadlockTest.Outer;\n" + + " class Class1 {\n" + + " public static Outer.Inner newInner(Outer grid) {\n" + + " return null;\n" + + " }\n" + + " }\n" + ); + assertNotNull(class1); + }, "t1"); + + Thread t2 = new Thread(() -> { + ASTCompilationUnit class2 = JavaParsingHelper.DEFAULT.parse( + "package net.sourceforge.pmd.lang.java.symbols;\n" + + "import net.sourceforge.pmd.lang.java.symbols.DeadlockTest.Outer;\n" + + " class Class2 {\n" + + " protected Outer theOuter;\n" + + " }\n" + ); + assertNotNull(class2); + }, "t2"); + + t1.start(); + t2.start(); + + t1.join(); + t2.join(); + } +} diff --git a/pmd-java/src/test/resources/simplelogger.properties b/pmd-java/src/test/resources/simplelogger.properties new file mode 100644 index 00000000000..8a4eafe283c --- /dev/null +++ b/pmd-java/src/test/resources/simplelogger.properties @@ -0,0 +1,5 @@ +# +# BSD-style license; for more info see http://pmd.sourceforge.net/license.html +# + +#org.slf4j.simpleLogger.log.net.sourceforge.pmd.lang.java.symbols.internal.asm.ParseLock=trace From 1ee649442914de12f06de12f586cc647ad9a27a6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 4 Nov 2024 10:40:32 +0100 Subject: [PATCH 0200/1962] [java] Fix #5293: Parse number of type parameters eagerly When creating a LazyClassSignature or LazyMethodType, make sure to parse the number of type parameters eagerly, so that AstDisambiguationPass can get this number without triggering additional parsing. --- .../java/symbols/internal/asm/ClassStub.java | 4 +-- .../symbols/internal/asm/GenericSigBase.java | 20 ++++++++--- .../asm/GenericTypeParameterCounter.java | 36 +++++++++++++++++++ 3 files changed, 53 insertions(+), 7 deletions(-) create mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericTypeParameterCounter.java diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java index c5337cf773e..15ae7b0535d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java @@ -310,9 +310,9 @@ public List getTypeParameters() { } @Override - public boolean isGeneric() { + public int getTypeParameterCount() { parseLock.ensureParsed(); - return signature.isGeneric(); + return signature.getTypeParameterCount(); } @Override diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java index 8ee5f39aaad..eabeb13c5af 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java @@ -81,7 +81,11 @@ protected final void ensureParsed() { protected abstract boolean postCondition(); - protected abstract boolean isGeneric(); + protected abstract int getTypeParameterCount(); + + protected boolean isGeneric() { + return getTypeParameterCount() > 0; + } public void setTypeParams(List tvars) { assert this.typeParameters == null : "Type params were already parsed for " + this; @@ -105,6 +109,7 @@ static class LazyClassSignature extends GenericSigBase { private static final String OBJECT_BOUND = ":" + OBJECT_SIG; private final @Nullable String signature; + private final int typeParameterCount; private @Nullable JClassType superType; private List superItfs; @@ -118,6 +123,7 @@ static class LazyClassSignature extends GenericSigBase { String[] interfaces) { super(ctx, "LazyClassSignature:" + ctx.getInternalName() + "[" + signature + "]"); this.signature = signature; + this.typeParameterCount = GenericTypeParameterCounter.determineTypeParameterCount(this.signature); this.rawItfs = CollectionUtil.map(interfaces, ctx.getResolver()::resolveFromInternalNameCannotFail); this.rawSuper = ctx.getResolver().resolveFromInternalNameCannotFail(superInternalName); @@ -157,8 +163,9 @@ protected void doParse() { } @Override - protected boolean isGeneric() { - return signature != null && TypeParamsParser.hasTypeParams(signature); + protected int getTypeParameterCount() { + // note: no ensureParsed() needed, the type parameters are counted eagerly + return typeParameterCount; } @Override @@ -206,6 +213,7 @@ public String toString() { static class LazyMethodType extends GenericSigBase implements TypeAnnotationReceiver { private final @NonNull String signature; + private final int typeParameterCount; private @Nullable TypeAnnotationSet receiverAnnotations; private List parameterTypes; @@ -235,6 +243,7 @@ static class LazyMethodType extends GenericSigBase implements Ty boolean skipFirstParam) { super(ctx, "LazyMethodType:" + (genericSig != null ? genericSig : descriptor)); this.signature = genericSig != null ? genericSig : descriptor; + this.typeParameterCount = GenericTypeParameterCounter.determineTypeParameterCount(genericSig); // generic signatures already omit the synthetic param this.skipFirstParam = skipFirstParam && genericSig == null; this.rawExceptions = exceptions; @@ -288,8 +297,9 @@ protected boolean postCondition() { @Override - protected boolean isGeneric() { - return TypeParamsParser.hasTypeParams(signature); + protected int getTypeParameterCount() { + // note: no ensureParsed() needed, the type parameters are counted eagerly + return typeParameterCount; } void setParameterTypes(List params) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericTypeParameterCounter.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericTypeParameterCounter.java new file mode 100644 index 00000000000..28f309c43bd --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericTypeParameterCounter.java @@ -0,0 +1,36 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.symbols.internal.asm; + +import org.objectweb.asm.signature.SignatureReader; +import org.objectweb.asm.signature.SignatureVisitor; + +class GenericTypeParameterCounter extends SignatureVisitor { + private int count; + + GenericTypeParameterCounter() { + super(AsmSymbolResolver.ASM_API_V); + } + + @Override + public void visitFormalTypeParameter(String name) { + count++; + } + + public int getCount() { + return count; + } + + static int determineTypeParameterCount(String signature) { + if (signature == null) { + return 0; + } + + SignatureReader signatureReader = new SignatureReader(signature); + GenericTypeParameterCounter counter = new GenericTypeParameterCounter(); + signatureReader.accept(counter); + return counter.getCount(); + } +} From 733ac4bba04520af86097047c56bba1e9b8b5900 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 4 Nov 2024 11:21:25 +0100 Subject: [PATCH 0201/1962] [doc] Update release notes (#5293) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 3c146742174..3e50f0fc867 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -17,6 +17,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿ› Fixed Issues * ant * [#1860](https://github.com/pmd/pmd/issues/1860): \[ant] Reflective access warnings on java > 9 and java < 17 +* java + * [#5293](https://github.com/pmd/pmd/issues/5293): \[java] Deadlock when executing PMD in multiple threads ### ๐Ÿšจ API Changes From 9dcb697f13549dab1bce1dac0d4c9b7fa5cfe215 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 7 Nov 2024 12:38:11 +0100 Subject: [PATCH 0202/1962] Improve DeadlockTest --- .../pmd/lang/java/symbols/DeadlockTest.java | 73 ++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/DeadlockTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/DeadlockTest.java index 25e3de1948b..15358be481e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/DeadlockTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/DeadlockTest.java @@ -4,12 +4,19 @@ package net.sourceforge.pmd.lang.java.symbols; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +import java.util.ArrayList; +import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; import net.sourceforge.pmd.lang.java.JavaParsingHelper; +import net.sourceforge.pmd.lang.java.ast.ASTClassType; import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; /** @@ -38,7 +45,21 @@ void parseWithoutDeadlock() throws InterruptedException { /* Deadlock: t1 -> locks parse for Outer.Inner and waits for parse lock for Outer + โ”œโ”€ t1 waiting on : ParseLock{name=LazyClassSignature:net/sourceforge/pmd/lang/java/symbols/DeadlockTest$Outer$Inner[Ljava/lang/Object;],status=NOT_PARSED} + โ””โ”€ t1 locked : ParseLock{name=LazyClassSignature:net/sourceforge/pmd/lang/java/symbols/DeadlockTest$Outer$Inner[Ljava/lang/Object;],status=NOT_PARSED} + โ””โ”€ t1 waiting on : ParseLock{name=LazyClassSignature:net/sourceforge/pmd/lang/java/symbols/DeadlockTest$Outer[Ljava/lang/Object;Lnet/sourceforge/pmd/lang/java/symbols/DeadlockTest$GenericInterface;Lnet/sourceforge/pmd/lang/java/symbols/DeadlockTest$GenericClass;>;],status=BEING_PARSED} t2 -> locks parse for Outer, locks parse for GenericInterface and then waits for parse lock for Outer.Inner + โ”œโ”€ t2 waiting on : ParseLock{name=LazyClassSignature:net/sourceforge/pmd/lang/java/symbols/DeadlockTest$Outer[Ljava/lang/Object;Lnet/sourceforge/pmd/lang/java/symbols/DeadlockTest$GenericInterface;Lnet/sourceforge/pmd/lang/java/symbols/DeadlockTest$GenericClass;>;],status=NOT_PARSED} + โ””โ”€ t2 locked : ParseLock{name=LazyClassSignature:net/sourceforge/pmd/lang/java/symbols/DeadlockTest$Outer[Ljava/lang/Object;Lnet/sourceforge/pmd/lang/java/symbols/DeadlockTest$GenericInterface;Lnet/sourceforge/pmd/lang/java/symbols/DeadlockTest$GenericClass;>;],status=NOT_PARSED} + โ”œโ”€ t2 waiting on : ParseLock{name=LazyClassSignature:net/sourceforge/pmd/lang/java/symbols/DeadlockTest[null],status=NOT_PARSED} + โ”œโ”€ t2 locked : ParseLock{name=LazyClassSignature:net/sourceforge/pmd/lang/java/symbols/DeadlockTest[null],status=NOT_PARSED} + โ”œโ”€ t2 released : ParseLock{name=LazyClassSignature:net/sourceforge/pmd/lang/java/symbols/DeadlockTest[null],status=FULL} + โ”œโ”€ t2 waiting on : ParseLock{name=LazyClassSignature:net/sourceforge/pmd/lang/java/symbols/DeadlockTest$Outer[Ljava/lang/Object;Lnet/sourceforge/pmd/lang/java/symbols/DeadlockTest$GenericInterface;Lnet/sourceforge/pmd/lang/java/symbols/DeadlockTest$GenericClass;>;],status=BEING_PARSED} + โ”œโ”€ t2 locked : ParseLock{name=LazyClassSignature:net/sourceforge/pmd/lang/java/symbols/DeadlockTest$Outer[Ljava/lang/Object;Lnet/sourceforge/pmd/lang/java/symbols/DeadlockTest$GenericInterface;Lnet/sourceforge/pmd/lang/java/symbols/DeadlockTest$GenericClass;>;],status=BEING_PARSED} + โ”œโ”€ t2 released : ParseLock{name=LazyClassSignature:net/sourceforge/pmd/lang/java/symbols/DeadlockTest$Outer[Ljava/lang/Object;Lnet/sourceforge/pmd/lang/java/symbols/DeadlockTest$GenericInterface;Lnet/sourceforge/pmd/lang/java/symbols/DeadlockTest$GenericClass;>;],status=BEING_PARSED} + โ””โ”€ t2 waiting on : ParseLock{name=LazyClassSignature:net/sourceforge/pmd/lang/java/symbols/DeadlockTest$GenericClass[Lnet/sourceforge/pmd/lang/java/symbols/DeadlockTest$GenericBaseClass;>;],status=NOT_PARSED} + โ”œโ”€ t2 locked : ParseLock{name=LazyClassSignature:net/sourceforge/pmd/lang/java/symbols/DeadlockTest$GenericClass[Lnet/sourceforge/pmd/lang/java/symbols/DeadlockTest$GenericBaseClass;>;],status=NOT_PARSED} + โ””โ”€ t2 waiting on : ParseLock{name=LazyClassSignature:net/sourceforge/pmd/lang/java/symbols/DeadlockTest$Outer$Inner[Ljava/lang/Object;],status=NOT_PARSED} In order to reproduce the deadlock reliably, add the following piece into ParseLock, just at the beginning @@ -51,20 +72,50 @@ of the synchronized block (line 42): } catch (InterruptedException ignored) { } } + + And then, introduce a bug again. One way to make the test fail is: + Comment out the method "public int getTypeParameterCount()", so that it is inherited again. + Add the following method: + @Override + public boolean isGeneric() { + parseLock.ensureParsed(); + return signature.isGeneric(); + } */ + List exceptions = new ArrayList<>(); + Thread.UncaughtExceptionHandler exceptionHandler = (t, e) -> { + exceptions.add(e); + e.printStackTrace(); + }; + Thread t1 = new Thread(() -> { ASTCompilationUnit class1 = JavaParsingHelper.DEFAULT.parse( "package net.sourceforge.pmd.lang.java.symbols;\n" + "import net.sourceforge.pmd.lang.java.symbols.DeadlockTest.Outer;\n" + " class Class1 {\n" - + " public static Outer.Inner newInner(Outer grid) {\n" + + " public static Outer.Inner newInner(Outer grid) {\n" + " return null;\n" + " }\n" + " }\n" ); assertNotNull(class1); + + // Outer.Inner = return type of method "newInner" + List classTypes = class1.descendants(ASTClassType.class).toList(); + ASTClassType outerInner = classTypes.get(0); + assertGenericClassType(outerInner, "Inner", "X", "T"); + + // Outer = qualifier of Outer.Inner + ASTClassType outer = classTypes.get(1); + assertEquals("Outer", outer.getSimpleName()); + assertNull(outer.getTypeArguments()); + + // Outer = formal parameter type of method newInner + ASTClassType outerFormalParam = classTypes.get(3); + assertGenericClassType(outerFormalParam, "Outer", "X", "T"); }, "t1"); + t1.setUncaughtExceptionHandler(exceptionHandler); Thread t2 = new Thread(() -> { ASTCompilationUnit class2 = JavaParsingHelper.DEFAULT.parse( @@ -75,12 +126,32 @@ of the synchronized block (line 42): + " }\n" ); assertNotNull(class2); + + // Outer = type of field "theOuter" + ASTClassType firstClassType = class2.descendants(ASTClassType.class).first(); + assertNotNull(firstClassType); + assertGenericClassType(firstClassType, "Outer", "M", "T"); }, "t2"); + t2.setUncaughtExceptionHandler(exceptionHandler); t1.start(); t2.start(); t1.join(); t2.join(); + + assertAll(exceptions.stream() + .map(e -> () -> { + throw e; + })); + } + + private static void assertGenericClassType(ASTClassType classType, String simpleName, String actualTypeParamName, String originalTypeParamName) { + assertEquals(simpleName, classType.getSimpleName()); + assertEquals(1, classType.getTypeArguments().size()); + assertEquals(actualTypeParamName, ((ASTClassType) classType.getTypeArguments().get(0)).getSimpleName()); + JTypeParameterOwnerSymbol symbol = (JTypeParameterOwnerSymbol) classType.getTypeMirror().getSymbol(); + assertEquals(1, symbol.getTypeParameterCount()); + assertEquals(originalTypeParamName, symbol.getTypeParameters().get(0).getName()); } } From ca208d22416dc2abec528208347fca1de34e3de9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 7 Nov 2024 12:40:18 +0100 Subject: [PATCH 0203/1962] Bump maven-pmd-plugin from 3.24.0 to 3.26.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 915bd9c00e9..dec91f16ef1 100644 --- a/pom.xml +++ b/pom.xml @@ -101,7 +101,7 @@ 3.2.5 10.18.1 3.5.0 - 3.24.0 + 3.26.0 1.10.14 3.6.3 4.9.3 From ee7d6fed3e4795f4fcb8827d8fc6a6851bf191dc Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 7 Nov 2024 19:50:29 +0100 Subject: [PATCH 0204/1962] [java] TooFewBranchesForSwitch - add test case from comment on #5311 --- .../xml/TooFewBranchesForSwitch.xml | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForSwitch.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForSwitch.xml index 2da0d99a82d..4cbc9893c77 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForSwitch.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/TooFewBranchesForSwitch.xml @@ -178,6 +178,26 @@ class Tester { return result; } } +]]> + + + + From #5311: Another example for list of case constants + 0 + "Hello"; + case E, F, G -> "World"; + }; + } + + enum Bar { + A, B, C, D, E, F, G + } +} ]]> From 07de5559bcb39ab3e4908735d16c4954f005596e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 03:35:46 +0000 Subject: [PATCH 0205/1962] Bump org.apache.commons:commons-compress from 1.26.0 to 1.27.1 Bumps org.apache.commons:commons-compress from 1.26.0 to 1.27.1. --- updated-dependencies: - dependency-name: org.apache.commons:commons-compress dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pmd-dist/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index 7bfaf114e5c..5a40e514e2f 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -178,7 +178,7 @@ org.apache.commons commons-compress - 1.26.0 + 1.27.1 test From 4e4ca6bb70d2406155666312a8fa6220ebb5aae0 Mon Sep 17 00:00:00 2001 From: mitchspano Date: Tue, 12 Nov 2024 19:46:58 +0000 Subject: [PATCH 0206/1962] Incorporate code review feedback. - Renames the rule to `QueueableWithoutFinalizer` to be more neutral. - Provides a more robust description. - Provides a more succinct error message. - Provides a positive sample for the documentation . --- ...ava => QueueableWithoutFinalizerRule.java} | 2 +- .../resources/category/apex/bestpractices.xml | 47 ++++++++++++++----- ...ava => QueueableWithoutFinalizerTest.java} | 2 +- ...izer.xml => QueueableWithoutFinalizer.xml} | 4 +- 4 files changed, 40 insertions(+), 15 deletions(-) rename pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/{QueueableShouldAttachFinalizerRule.java => QueueableWithoutFinalizerRule.java} (97%) rename pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/{QueueableShouldAttachFinalizerTest.java => QueueableWithoutFinalizerTest.java} (78%) rename pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/bestpractices/xml/{QueueableShouldAttachFinalizer.xml => QueueableWithoutFinalizer.xml} (87%) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableShouldAttachFinalizerRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableWithoutFinalizerRule.java similarity index 97% rename from pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableShouldAttachFinalizerRule.java rename to pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableWithoutFinalizerRule.java index dad3ebfc942..a3f349615f8 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableShouldAttachFinalizerRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableWithoutFinalizerRule.java @@ -18,7 +18,7 @@ * * @author mitchspano */ -public class QueueableShouldAttachFinalizerRule extends AbstractApexRule { +public class QueueableWithoutFinalizerRule extends AbstractApexRule { private static final String EXECUTE = "execute"; private static final String QUEUEABLE = "queueable"; diff --git a/pmd-apex/src/main/resources/category/apex/bestpractices.xml b/pmd-apex/src/main/resources/category/apex/bestpractices.xml index f69949af4a7..836894f3b5a 100644 --- a/pmd-apex/src/main/resources/category/apex/bestpractices.xml +++ b/pmd-apex/src/main/resources/category/apex/bestpractices.xml @@ -285,29 +285,54 @@ Detects when a local variable is declared and/or assigned but not used.
    - + message="This Queueable doesn't attach a Finalizer" + class="net.sourceforge.pmd.lang.apex.rule.bestpractices.QueueableWithoutFinalizerRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_bestpractices.html#queueablewithoutfinalizer"> Detects when the Queueable interface is used but a Finalizer is not attached. +It is best practice to call the `System.attachFinalizer(Finalizer f)` method within the `execute` method of a class which implements the `Queueable` interface. +Without attaching a Finalizer, there is no way of designing error recovery actions should the Queueable action fail. 5 usersToUpdate; +// Incorrect code, does not attach a finalizer. +public class UserUpdater implements Queueable { + public List usersToUpdate; - public UserUpdater(List usersToUpdate) { - this.usersToUpdate = usersToUpdate; - } + public UserUpdater(List usersToUpdate) { + this.usersToUpdate = usersToUpdate; + } + + public void execute(QueueableContext context) { // no Finalizer is attached + update usersToUpdate; + } +} + +// Proper code, attaches a finalizer. +public class UserUpdater implements Queueable, Finalizer { + public List usersToUpdate; - public void execute(QueueableContext context) { // no Finalizer is attached - update usersToUpdate; + public UserUpdater(List usersToUpdate) { + this.usersToUpdate = usersToUpdate; + } + + public void execute(QueueableContext context) { + System.attachFinalizer(this); + update usersToUpdate; + } + + public void execute(FinalizerContext ctx) { + if (ctx.getResult() == ParentJobResult.SUCCESS) { + // Handle success + } else { + // Handle failure } } +} ]]> diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableShouldAttachFinalizerTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableWithoutFinalizerTest.java similarity index 78% rename from pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableShouldAttachFinalizerTest.java rename to pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableWithoutFinalizerTest.java index f24a3d94f54..35d20e8d9cf 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableShouldAttachFinalizerTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableWithoutFinalizerTest.java @@ -6,6 +6,6 @@ import net.sourceforge.pmd.test.PmdRuleTst; -class QueueableShouldAttachFinalizerTest extends PmdRuleTst { +class QueueableWithoutFinalizerTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/bestpractices/xml/QueueableShouldAttachFinalizer.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/bestpractices/xml/QueueableWithoutFinalizer.xml similarity index 87% rename from pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/bestpractices/xml/QueueableShouldAttachFinalizer.xml rename to pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/bestpractices/xml/QueueableWithoutFinalizer.xml index 207b2bb5cc2..41145ef9665 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/bestpractices/xml/QueueableShouldAttachFinalizer.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/bestpractices/xml/QueueableWithoutFinalizer.xml @@ -5,7 +5,7 @@ xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests http://pmd.sourceforge.net/rule-tests_1_0_0.xsd"> - [apex] Queueable Should Attach Finalizer - positive test case #5302 + [apex] Queueable Without Finalizer - positive test case #5302 1 8 - [apex] Queueable Should Attach Finalizer - negative test case #5302 + [apex] Queueable Without Finalizer - negative test case #5302 0 Date: Tue, 12 Nov 2024 21:59:02 +0000 Subject: [PATCH 0207/1962] Implements the `RuleChain` within the `QueueableWithoutFinalizerRule`. Implements the [`RuleChain`](https://docs.pmd-code.org/latest/pmd_userdocs_extending_writing_java_rules.html#economic-traversal-the-rulechain) to traverse all classes within the file. --- .../QueueableWithoutFinalizerRule.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableWithoutFinalizerRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableWithoutFinalizerRule.java index a3f349615f8..bae5f2ef854 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableWithoutFinalizerRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableWithoutFinalizerRule.java @@ -10,6 +10,8 @@ import net.sourceforge.pmd.lang.apex.ast.ASTParameter; import net.sourceforge.pmd.lang.apex.ast.ASTUserClass; import net.sourceforge.pmd.lang.apex.rule.AbstractApexRule; +import net.sourceforge.pmd.lang.rule.RuleTargetSelector; +import org.checkerframework.checker.nullness.qual.NonNull; /** * Scans classes which implement the `Queueable` interface. If the `public void @@ -25,23 +27,19 @@ public class QueueableWithoutFinalizerRule extends AbstractApexRule { private static final String QUEUEABLE_CONTEXT = "queueablecontext"; private static final String SYSTEM_ATTACH_FINALIZER = "system.attachfinalizer"; - /** Scans the top level class and all inner classes. */ @Override - public Object visit(ASTUserClass topLevelClass, Object data) { - scanClassForViolation(topLevelClass, data); - for (ASTUserClass innerClass : topLevelClass.descendants(ASTUserClass.class).toList()) { - scanClassForViolation(innerClass, data); - } - return data; + protected @NonNull RuleTargetSelector buildTargetSelector() { + return RuleTargetSelector.forTypes(ASTUserClass.class); } /** * If the class implements the `Queueable` interface and the `execute(QueueableContext context)` * does not call the `System.attachFinalizer(Finalizer f)` method, then add a violation. */ - private void scanClassForViolation(ASTUserClass theClass, Object data) { + @Override + public Object visit(ASTUserClass theClass, Object data) { if (!implementsTheQueueableInterface(theClass)) { - return; + return data; } for (ASTMethod theMethod : theClass.descendants(ASTMethod.class).toList()) { if (isTheExecuteMethodOfTheQueueableInterface(theMethod) @@ -49,6 +47,7 @@ private void scanClassForViolation(ASTUserClass theClass, Object data) { asCtx(data).addViolation(theMethod); } } + return data; } /** Determines if the class implements the Queueable interface. */ From 529693c916ebca6226ae501c1ceaf53eb88f95ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 13 Nov 2024 22:27:51 +0100 Subject: [PATCH 0208/1962] [java] fix inference dependency issue Reported in #5324 I improved the verbose logging output a bit so some of the changes are not directly relevant. --- .../types/internal/infer/ExprCheckHelper.java | 18 +- .../lang/java/types/internal/infer/Infer.java | 13 +- .../internal/infer/InferenceContext.java | 87 +++++++- .../internal/infer/TypeInferenceLogger.java | 74 +++++-- .../types/internal/infer/VarWalkStrategy.java | 8 + .../lang/java/types/TypesTreeDumpTest.java | 5 + .../bestpractices/xml/UnusedPrivateMethod.xml | 43 ++++ .../NestedLambdasAndMethodCalls.java | 38 ++++ .../dumptests/NestedLambdasAndMethodCalls.txt | 194 ++++++++++++++++++ .../java/types/dumptests/UnnamedPatterns.txt | 6 +- 10 files changed, 448 insertions(+), 38 deletions(-) create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/NestedLambdasAndMethodCalls.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/NestedLambdasAndMethodCalls.txt diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java index c5c20caec96..dc8955fcb09 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java @@ -552,8 +552,15 @@ private boolean isLambdaCongruent(@NonNull JClassType functionalItf, // finally, add bounds if (result != ts.NO_TYPE) { + Set inputIvars = infCtx.freeVarsIn(groundFun.getFormalParameters()); + // The free vars of the return type depend on the free vars of the parameters. + // This explicit dependency is there to prevent solving the variables in the + // return type before solving those of the parameters. That is because the variables + // mentioned in the return type may be further constrained by adding the return constraints + // below (in the listener), which is only triggered when the input ivars have been instantiated. + infCtx.addInstantiationDependencies(infCtx.freeVarsIn(groundFun.getReturnType()), inputIvars); infCtx.addInstantiationListener( - infCtx.freeVarsIn(groundFun.getFormalParameters()), + inputIvars, solvedCtx -> { if (mayMutateExpr()) { lambda.setInferredType(solvedCtx.ground(groundTargetType)); @@ -562,8 +569,15 @@ private boolean isLambdaCongruent(@NonNull JClassType functionalItf, lambda.updateTypingContext(solvedGroundFun); } JTypeMirror groundResult = solvedCtx.ground(result); + // We need to build another checker that uses the solved context. + // This is because the free vars may have been adopted by a parent + // context, so the solvedCtx may be that parent context. The checks + // must use that context so that constraints and listeners are added + // to the parent context, since that one is responsible for solving + // the variables. + ExprCheckHelper newChecker = new ExprCheckHelper(solvedCtx, phase, this.checker, site, infer); for (ExprMirror expr : lambda.getResultExpressions()) { - if (!isCompatible(groundResult, expr)) { + if (!newChecker.isCompatible(groundResult, expr)) { return; } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java index 02f16611d5b..79823042103 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java @@ -602,17 +602,20 @@ private JMethodSig instantiateImpl(JMethodSig m, MethodCallSite site, MethodReso // see: https://docs.oracle.com/javase/specs/jls/se9/html/jls-18.html#jls-18.5.1 // as per https://docs.oracle.com/javase/specs/jls/se9/html/jls-18.html#jls-18.5.2 // we only test it can reduce, we don't commit inferred types at this stage - InferenceContext ctxCopy = infCtx.copy(); - LOG.applicabilityTest(ctxCopy, m); - ctxCopy.solve(/*onlyBoundedVars:*/isPreJava8()); - + InferenceContext ctxCopy = infCtx.shallowCopy(); + LOG.applicabilityTest(ctxCopy); + try { + ctxCopy.solve(/*onlyBoundedVars:*/isPreJava8()); + } finally { + LOG.finishApplicabilityTest(); + } // if unchecked conversion was needed, update the site for invocation pass if (ctxCopy.needsUncheckedConversion()) { site.setNeedsUncheckedConversion(); } // don't commit any types - return m; + return infCtx.mapToIVars(m); } } finally { // Note that even if solve succeeded, listeners checking deferred diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/InferenceContext.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/InferenceContext.java index ba3a78640e1..73b843439fd 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/InferenceContext.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/InferenceContext.java @@ -13,11 +13,13 @@ import java.util.Collections; import java.util.Deque; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.function.Supplier; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -38,6 +40,7 @@ import net.sourceforge.pmd.lang.java.types.internal.infer.IncorporationAction.SubstituteInst; import net.sourceforge.pmd.lang.java.types.internal.infer.InferenceVar.BoundKind; import net.sourceforge.pmd.lang.java.types.internal.infer.VarWalkStrategy.GraphWalk; +import net.sourceforge.pmd.util.CollectionUtil; /** * Context of a type inference process. This object maintains a set of @@ -51,6 +54,13 @@ final class InferenceContext { private static int ctxId = 0; private final Map> instantiationListeners = new HashMap<>(); + // explicit dependencies between variables for graph building + private final Map> instantiationConstraints = new HashMap<>(); + // This flag is set to true when the explicit dependencies are changed, + // or when this context adopted new ivars. This means we should interrupt + // resolution and recompute the dependency graph between ivars, because + // the new variables may have dependencies on existing variables, and vice versa. + private boolean graphWasChanged = false; private final Set freeVars = new LinkedHashSet<>(); private final Set inferenceVars = new LinkedHashSet<>(); @@ -127,18 +137,19 @@ void addPrimaryBounds() { } } - public InferenceContext copy() { + /** + * Performs a shallow copy of this context, which would allow solving + * the variables without executing listeners. Instantiation listeners + * are not copied, and parent contexts are not copied. + */ + public InferenceContext shallowCopy() { final InferenceContext copy = new InferenceContext(ts, supertypeCheckCache, Collections.emptyList(), logger); copy.freeVars.addAll(this.freeVars); copy.inferenceVars.addAll(this.inferenceVars); copy.incorporationActions.addAll(this.incorporationActions); + copy.instantiationConstraints.putAll(this.instantiationConstraints); copy.mapping = mapping; // mapping is immutable, so we can share it safely - // recursively copy parentsโ€ฆ - if (this.parent != null) { - copy.parent = this.parent.copy(); - } - return copy; } @@ -310,10 +321,20 @@ static JTypeMirror groundOrWildcard(JTypeMirror t) { * Copy variable in this inference context to the given context */ void duplicateInto(final InferenceContext that) { + boolean changedGraph = !that.freeVars.containsAll(this.freeVars) + || !this.instantiationConstraints.isEmpty(); + that.graphWasChanged |= changedGraph; that.inferenceVars.addAll(this.inferenceVars); that.freeVars.addAll(this.freeVars); that.incorporationActions.addAll(this.incorporationActions); that.instantiationListeners.putAll(this.instantiationListeners); + CollectionUtil.mergeMaps( + that.instantiationConstraints, + this.instantiationConstraints, + (set1, set2) -> { + set1.addAll(set2); + return set1; + }); this.parent = that; @@ -324,6 +345,30 @@ void duplicateInto(final InferenceContext that) { } + // The `from` ivars depend on the `dependencies` ivars for resolution. + void addInstantiationDependencies(Set from, Set dependencies) { + if (from.isEmpty()) { + return; + } + Set outputVars = new HashSet<>(dependencies); + outputVars.removeAll(from); + if (outputVars.isEmpty()) { + return; + } + for (InferenceVar inputVar : from) { + logger.ivarDependencyRegistered(this, inputVar, outputVars); + instantiationConstraints.merge(inputVar, outputVars, (o1, o2) -> { + o2 = new LinkedHashSet<>(o2); + o2.addAll(o1); + return o2; + }); + } + } + + Map> getInstantiationDependencies() { + return instantiationConstraints; + } + void addInstantiationListener(Set relevantTypes, InstantiationListener listener) { Set free = freeVarsIn(relevantTypes); if (free.isEmpty()) { @@ -448,7 +493,7 @@ void solve() { } boolean solve(boolean onlyBoundedVars) { - return solve(new GraphWalk(this, onlyBoundedVars)); + return solve(() -> new GraphWalk(this, onlyBoundedVars)); } /** @@ -459,6 +504,26 @@ void solve(InferenceVar var) { solve(new GraphWalk(var)); } + + private boolean solve(Supplier newWalker) { + VarWalkStrategy strategy = newWalker.get(); + while (strategy != null) { + if (solve(strategy)) { + break; + } + strategy = newWalker.get(); + } + return freeVars.isEmpty(); + } + + + /** + * This returns true if solving the VarWalkStrategy succeeded entirely. + * Resolution can be interrupted early to account for new ivars and dependencies, + * which may change the graph dependencies. In this case this method returns + * false, we recompute the graph with the new ivars and dependencies, and + * we try again to make progress. + */ private boolean solve(VarWalkStrategy walker) { incorporate(); @@ -470,6 +535,12 @@ private boolean solve(VarWalkStrategy walker) { //repeat until all variables are solved outer: while (!intersect(freeVars, varsToSolve).isEmpty() && progress) { + if (graphWasChanged) { + graphWasChanged = false; + logger.contextDependenciesChanged(this); + return false; + } + progress = false; for (List wave : ReductionStep.WAVES) { if (solveBatchProgressed(varsToSolve, wave)) { @@ -481,7 +552,7 @@ private boolean solve(VarWalkStrategy walker) { } } } - return freeVars.isEmpty(); + return true; } /** diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java index 023e422a494..2c9cfff9efa 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java @@ -12,6 +12,7 @@ import java.util.Deque; import java.util.Iterator; import java.util.List; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -61,7 +62,10 @@ default void ambiguityError(MethodCallSite site, @Nullable MethodCtDecl selected default void ctxInitialization(InferenceContext ctx, JMethodSig sig) { } - default void applicabilityTest(InferenceContext ctx, JMethodSig sig) { } + default void applicabilityTest(InferenceContext ctx) { } + + default void finishApplicabilityTest() { + } default void startArgsChecks() { } @@ -81,6 +85,8 @@ default void endReturnChecks() { } default void propagateAndAbort(InferenceContext context, InferenceContext parent) { } + default void contextDependenciesChanged(InferenceContext ctx) { } + // ivar events @@ -90,6 +96,8 @@ default void ivarMerged(InferenceContext ctx, InferenceVar var, InferenceVar del default void ivarInstantiated(InferenceContext ctx, InferenceVar var, JTypeMirror inst) { } + default void ivarDependencyRegistered(InferenceContext ctx, InferenceVar var, Set deps) { } + /** * Log that the instantiation of the method type m for the given @@ -136,9 +144,11 @@ public TypeInferenceLogger newInstance() { protected final PrintStream out; - protected static final int LEVEL_INCREMENT = 4; - private int level; private String indent; + /** + * Four spaces. + */ + protected static final String BASE_INDENT = " "; protected static final String ANSI_RESET = "\u001B[0m"; protected static final String ANSI_BLUE = "\u001B[34m"; @@ -177,16 +187,24 @@ protected static String doColor(Object str, Pattern pattern, String replacement) public SimpleLogger(PrintStream out) { this.out = out; - updateLevel(0); + this.indent = ""; } - protected int getLevel() { - return level; + protected void addIndentSegment(String segment) { + indent += segment; } - protected void updateLevel(int increment) { - level += increment; - indent = StringUtils.repeat(' ', level); + protected void removeIndentSegment(String segment) { + assert indent.endsWith(segment) : "mismatched end section!"; + indent = StringUtils.removeEnd(indent, segment); + } + + protected void setIndent(String indent) { + this.indent = indent; + } + + protected String getIndent() { + return indent; } protected void println(String str) { @@ -196,13 +214,13 @@ protected void println(String str) { protected void endSection(String footer) { - updateLevel(-LEVEL_INCREMENT); + removeIndentSegment(BASE_INDENT); println(footer); } protected void startSection(String header) { println(header); - updateLevel(+LEVEL_INCREMENT); + addIndentSegment(BASE_INDENT); } @Override @@ -335,7 +353,7 @@ public TypeInferenceLogger newInstance() { class VerboseLogger extends SimpleLogger { - private final Deque marks = new ArrayDeque<>(); + private final Deque marks = new ArrayDeque<>(); public VerboseLogger(PrintStream out) { super(out); @@ -343,16 +361,16 @@ public VerboseLogger(PrintStream out) { } void mark() { - marks.push(getLevel()); + marks.push(getIndent()); } void rollback(String lastWords) { - int pop = marks.pop(); - updateLevel(pop - getLevel()); // back to normal + final String savedIndent = marks.pop(); + setIndent(savedIndent); // back to normal if (!lastWords.isEmpty()) { - updateLevel(+LEVEL_INCREMENT); + addIndentSegment(BASE_INDENT); println(lastWords); - updateLevel(-LEVEL_INCREMENT); + setIndent(savedIndent); } } @@ -369,8 +387,14 @@ public void ctxInitialization(InferenceContext ctx, JMethodSig sig) { } @Override - public void applicabilityTest(InferenceContext ctx, JMethodSig sig) { - println(String.format("Applicability testing with Context %-11d%s", ctx.getId(), ppHighlight(ctx.mapToIVars(sig)))); + public void applicabilityTest(InferenceContext ctx) { + println(String.format("Solving with context %d for applicability testing", ctx.getId())); + addIndentSegment("| "); + } + + @Override + public void finishApplicabilityTest() { + removeIndentSegment("| "); } @Override @@ -404,7 +428,7 @@ public void propagateAndAbort(InferenceContext context, InferenceContext parent) @Override public void startArg(int i, ExprMirror expr, JTypeMirror formalType) { - startSection("Checking arg " + i + " against " + formalType); + startSection("Checking arg " + i + " against " + colorIvars(formalType)); printExpr(expr); } @@ -452,6 +476,16 @@ public void ivarInstantiated(InferenceContext ctx, InferenceVar var, JTypeMirror println(addCtxInfo(ctx, "Ivar instantiated") + color(var + " := ", ANSI_BLUE) + colorIvars(inst)); } + @Override + public void ivarDependencyRegistered(InferenceContext ctx, InferenceVar var, Set deps) { + println(addCtxInfo(ctx, "Ivar dependency registered: ") + color(var + " -> ", ANSI_BLUE) + colorIvars(deps)); + } + + @Override + public void contextDependenciesChanged(InferenceContext ctx) { + println("Recomputing dependency graph (ctx " + ctx.getId() + ")"); + } + private @NonNull String addCtxInfo(InferenceContext ctx, String event) { return String.format("%-20s(ctx %d): ", event, ctx.getId()); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/VarWalkStrategy.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/VarWalkStrategy.java index 2177a1cf927..19774ca49ec 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/VarWalkStrategy.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/VarWalkStrategy.java @@ -90,6 +90,14 @@ Iterator> buildGraphIterator(InferenceContext ctx, boolean onl } } + ctx.getInstantiationDependencies().forEach((ivar, deps) -> { + Vertex vertex = graph.addLeaf(ivar); + for (InferenceVar dep : deps) { + Vertex target = graph.addLeaf(dep); + graph.addEdge(vertex, target); + } + }); + // Here, "ฮฑ depends on ฮฒ" is modelled by an edge ฮฑ -> ฮฒ // Merge strongly connected components into a "super node". diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/TypesTreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/TypesTreeDumpTest.java index f69b79479c6..9b8baaeca66 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/TypesTreeDumpTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/TypesTreeDumpTest.java @@ -50,6 +50,11 @@ void testUnnamedPatterns() { doTest("UnnamedPatterns"); } + @Test + void testNestedLambdasAndMethodCalls() { + doTest("NestedLambdasAndMethodCalls"); + } + @Override protected @NonNull String normalize(@NonNull String str) { return super.normalize(str) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index e81d963fcb5..2679f0a8c5c 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2134,4 +2134,47 @@ public class ObtainViaTest { } ]]> + + UnusedPrivateMethod with method reference + 0 + > map = new Main().run(library); + System.out.println(map); + } + + private Map> run(Library library) { + return library + .books() + .stream() + .map(book -> book.lenders().stream().collect(Collectors.toMap(Lender::name, lender -> Map.of(book.title(), lender.status())))) + .reduce(this::reduceBooksAndLenderStatusByLender) + .orElse(null); + } + + private Map> reduceBooksAndLenderStatusByLender( + Map> previousMap, + Map> nextMap + ) { + previousMap.putAll(nextMap); + return previousMap; + } + } + + + record Lender(String name, String status) {} + record Book(String title, Collection lenders) {} + record Library(Collection books) {} + ]]> + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/NestedLambdasAndMethodCalls.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/NestedLambdasAndMethodCalls.java new file mode 100644 index 00000000000..33914e0a684 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/NestedLambdasAndMethodCalls.java @@ -0,0 +1,38 @@ +package org.example.unusedPrivateMethod; + +import static java.util.Collections.emptySet; + +import java.util.Collection; +import java.util.Map; +import java.util.stream.Collectors; + +public class NestedLambdasAndMethodCalls { + + public static void main(String[] args) { + Library library = new Library(emptySet()); + Map> map = new Main().run(library); + System.out.println(map); + } + + private Map> run(Library library) { + return library + .books() + .stream() + .map(book -> book.lenders().stream().collect(Collectors.toMap(Lender::name, lender -> Map.of(book.title(), lender.status())))) + .reduce(this::reduceBooksAndLenderStatusByLender) + .orElse(null); + } + + private Map> reduceBooksAndLenderStatusByLender( + Map> previousMap, + Map> nextMap + ) { + previousMap.putAll(nextMap); + return previousMap; + } +} + + +record Lender(String name, String status) {} +record Book(String title, Collection lenders) {} +record Library(Collection books) {} \ No newline at end of file diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/NestedLambdasAndMethodCalls.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/NestedLambdasAndMethodCalls.txt new file mode 100644 index 00000000000..9099296ff86 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/NestedLambdasAndMethodCalls.txt @@ -0,0 +1,194 @@ ++- CompilationUnit[] + +- PackageDeclaration[] + | +- ModifierList[] + +- ImportDeclaration[] + +- ImportDeclaration[] + +- ImportDeclaration[] + +- ImportDeclaration[] + +- ClassDeclaration[@TypeMirror = "org.example.unusedPrivateMethod.NestedLambdasAndMethodCalls"] + | +- ModifierList[] + | +- ClassBody[] + | +- MethodDeclaration[@Name = "main"] + | | +- ModifierList[] + | | +- VoidType[@TypeMirror = "void"] + | | +- FormalParameters[] + | | | +- FormalParameter[@TypeMirror = "java.lang.String[]"] + | | | +- ModifierList[] + | | | +- ArrayType[@TypeMirror = "java.lang.String[]"] + | | | | +- ClassType[@TypeMirror = "java.lang.String"] + | | | | +- ArrayDimensions[] + | | | | +- ArrayTypeDim[] + | | | +- VariableId[@Name = "args", @TypeMirror = "java.lang.String[]"] + | | +- Block[] + | | +- LocalVariableDeclaration[] + | | | +- ModifierList[] + | | | +- ClassType[@TypeMirror = "org.example.unusedPrivateMethod.Library"] + | | | +- VariableDeclarator[] + | | | +- VariableId[@Name = "library", @TypeMirror = "org.example.unusedPrivateMethod.Library"] + | | | +- ConstructorCall[@Failed = false, @Function = "org.example.unusedPrivateMethod.Library.new(java.util.Collection) -> org.example.unusedPrivateMethod.Library", @MethodName = "new", @TypeMirror = "org.example.unusedPrivateMethod.Library", @Unchecked = false, @VarargsCall = false] + | | | +- ClassType[@TypeMirror = "org.example.unusedPrivateMethod.Library"] + | | | +- ArgumentList[] + | | | +- MethodCall[@Failed = false, @Function = "java.util.Collections. emptySet() -> java.util.Set", @MethodName = "emptySet", @TypeMirror = "java.util.Set", @Unchecked = false, @VarargsCall = false] + | | | +- ArgumentList[] + | | +- LocalVariableDeclaration[] + | | | +- ModifierList[] + | | | +- ClassType[@TypeMirror = "java.util.Map>"] + | | | | +- TypeArguments[] + | | | | +- ClassType[@TypeMirror = "java.lang.String"] + | | | | +- ClassType[@TypeMirror = "java.util.Map"] + | | | | +- TypeArguments[] + | | | | +- ClassType[@TypeMirror = "java.lang.String"] + | | | | +- ClassType[@TypeMirror = "java.lang.String"] + | | | +- VariableDeclarator[] + | | | +- VariableId[@Name = "map", @TypeMirror = "java.util.Map>"] + | | | +- MethodCall[@Failed = true, @Function = "(*unknown*).(*unknown method*)() -> (*unknown*)", @MethodName = "run", @TypeMirror = "(*unknown*)", @Unchecked = false, @VarargsCall = false] + | | | +- ConstructorCall[@Failed = true, @Function = "(*unknown*).(*unknown method*)() -> (*unknown*)", @MethodName = "new", @TypeMirror = "*Main", @Unchecked = false, @VarargsCall = false] + | | | | +- ClassType[@TypeMirror = "*Main"] + | | | | +- ArgumentList[] + | | | +- ArgumentList[] + | | | +- VariableAccess[@Name = "library", @TypeMirror = "org.example.unusedPrivateMethod.Library"] + | | +- ExpressionStatement[] + | | +- MethodCall[@Failed = false, @Function = "java.io.PrintStream.println(java.lang.Object) -> void", @MethodName = "println", @TypeMirror = "void", @Unchecked = false, @VarargsCall = false] + | | +- FieldAccess[@Name = "out", @TypeMirror = "java.io.PrintStream"] + | | | +- TypeExpression[@TypeMirror = "java.lang.System"] + | | | +- ClassType[@TypeMirror = "java.lang.System"] + | | +- ArgumentList[] + | | +- VariableAccess[@Name = "map", @TypeMirror = "java.util.Map>"] + | +- MethodDeclaration[@Name = "run"] + | | +- ModifierList[] + | | +- ClassType[@TypeMirror = "java.util.Map>"] + | | | +- TypeArguments[] + | | | +- ClassType[@TypeMirror = "java.lang.String"] + | | | +- ClassType[@TypeMirror = "java.util.Map"] + | | | +- TypeArguments[] + | | | +- ClassType[@TypeMirror = "java.lang.String"] + | | | +- ClassType[@TypeMirror = "java.lang.String"] + | | +- FormalParameters[] + | | | +- FormalParameter[@TypeMirror = "org.example.unusedPrivateMethod.Library"] + | | | +- ModifierList[] + | | | +- ClassType[@TypeMirror = "org.example.unusedPrivateMethod.Library"] + | | | +- VariableId[@Name = "library", @TypeMirror = "org.example.unusedPrivateMethod.Library"] + | | +- Block[] + | | +- ReturnStatement[] + | | +- MethodCall[@Failed = false, @Function = "java.util.Optional>>.orElse(java.util.Map>) -> java.util.Map>", @MethodName = "orElse", @TypeMirror = "java.util.Map>", @Unchecked = false, @VarargsCall = false] + | | +- MethodCall[@Failed = false, @Function = "java.util.stream.Stream>>.reduce(java.util.function.BinaryOperator>>) -> java.util.Optional>>", @MethodName = "reduce", @TypeMirror = "java.util.Optional>>", @Unchecked = false, @VarargsCall = false] + | | | +- MethodCall[@Failed = false, @Function = "java.util.stream.Stream. map(java.util.function.Function>>) -> java.util.stream.Stream>>", @MethodName = "map", @TypeMirror = "java.util.stream.Stream>>", @Unchecked = false, @VarargsCall = false] + | | | | +- MethodCall[@Failed = false, @Function = "java.util.Collection.stream() -> java.util.stream.Stream", @MethodName = "stream", @TypeMirror = "java.util.stream.Stream", @Unchecked = false, @VarargsCall = false] + | | | | | +- MethodCall[@Failed = false, @Function = "org.example.unusedPrivateMethod.Library.books() -> java.util.Collection", @MethodName = "books", @TypeMirror = "java.util.Collection", @Unchecked = false, @VarargsCall = false] + | | | | | | +- VariableAccess[@Name = "library", @TypeMirror = "org.example.unusedPrivateMethod.Library"] + | | | | | | +- ArgumentList[] + | | | | | +- ArgumentList[] + | | | | +- ArgumentList[] + | | | | +- LambdaExpression[@TypeMirror = "java.util.function.Function>>"] + | | | | +- LambdaParameterList[] + | | | | | +- LambdaParameter[@TypeMirror = "org.example.unusedPrivateMethod.Book"] + | | | | | +- ModifierList[] + | | | | | +- VariableId[@Name = "book", @TypeMirror = "org.example.unusedPrivateMethod.Book"] + | | | | +- MethodCall[@Failed = false, @Function = "java.util.stream.Stream. collect(java.util.stream.Collector>>) -> java.util.Map>", @MethodName = "collect", @TypeMirror = "java.util.Map>", @Unchecked = false, @VarargsCall = false] + | | | | +- MethodCall[@Failed = false, @Function = "java.util.Collection.stream() -> java.util.stream.Stream", @MethodName = "stream", @TypeMirror = "java.util.stream.Stream", @Unchecked = false, @VarargsCall = false] + | | | | | +- MethodCall[@Failed = false, @Function = "org.example.unusedPrivateMethod.Book.lenders() -> java.util.Collection", @MethodName = "lenders", @TypeMirror = "java.util.Collection", @Unchecked = false, @VarargsCall = false] + | | | | | | +- VariableAccess[@Name = "book", @TypeMirror = "org.example.unusedPrivateMethod.Book"] + | | | | | | +- ArgumentList[] + | | | | | +- ArgumentList[] + | | | | +- ArgumentList[] + | | | | +- MethodCall[@Failed = false, @Function = "java.util.stream.Collectors. toMap(java.util.function.Function, java.util.function.Function>) -> java.util.stream.Collector>>", @MethodName = "toMap", @TypeMirror = "java.util.stream.Collector>>", @Unchecked = false, @VarargsCall = false] + | | | | +- TypeExpression[@TypeMirror = "java.util.stream.Collectors"] + | | | | | +- ClassType[@TypeMirror = "java.util.stream.Collectors"] + | | | | +- ArgumentList[] + | | | | +- MethodReference[@TypeMirror = "java.util.function.Function"] + | | | | | +- TypeExpression[@TypeMirror = "org.example.unusedPrivateMethod.Lender"] + | | | | | +- ClassType[@TypeMirror = "org.example.unusedPrivateMethod.Lender"] + | | | | +- LambdaExpression[@TypeMirror = "java.util.function.Function>"] + | | | | +- LambdaParameterList[] + | | | | | +- LambdaParameter[@TypeMirror = "org.example.unusedPrivateMethod.Lender"] + | | | | | +- ModifierList[] + | | | | | +- VariableId[@Name = "lender", @TypeMirror = "org.example.unusedPrivateMethod.Lender"] + | | | | +- MethodCall[@Failed = false, @Function = "java.util.Map. of(java.lang.String, java.lang.String) -> java.util.Map", @MethodName = "of", @TypeMirror = "java.util.Map", @Unchecked = false, @VarargsCall = false] + | | | | +- TypeExpression[@TypeMirror = "java.util.Map"] + | | | | | +- ClassType[@TypeMirror = "java.util.Map"] + | | | | +- ArgumentList[] + | | | | +- MethodCall[@Failed = false, @Function = "org.example.unusedPrivateMethod.Book.title() -> java.lang.String", @MethodName = "title", @TypeMirror = "java.lang.String", @Unchecked = false, @VarargsCall = false] + | | | | | +- VariableAccess[@Name = "book", @TypeMirror = "org.example.unusedPrivateMethod.Book"] + | | | | | +- ArgumentList[] + | | | | +- MethodCall[@Failed = false, @Function = "org.example.unusedPrivateMethod.Lender.status() -> java.lang.String", @MethodName = "status", @TypeMirror = "java.lang.String", @Unchecked = false, @VarargsCall = false] + | | | | +- VariableAccess[@Name = "lender", @TypeMirror = "org.example.unusedPrivateMethod.Lender"] + | | | | +- ArgumentList[] + | | | +- ArgumentList[] + | | | +- MethodReference[@TypeMirror = "java.util.function.BinaryOperator>>"] + | | | +- ThisExpression[@TypeMirror = "org.example.unusedPrivateMethod.NestedLambdasAndMethodCalls"] + | | +- ArgumentList[] + | | +- NullLiteral[@TypeMirror = "null"] + | +- MethodDeclaration[@Name = "reduceBooksAndLenderStatusByLender"] + | +- ModifierList[] + | +- ClassType[@TypeMirror = "java.util.Map>"] + | | +- TypeArguments[] + | | +- ClassType[@TypeMirror = "java.lang.String"] + | | +- ClassType[@TypeMirror = "java.util.Map"] + | | +- TypeArguments[] + | | +- ClassType[@TypeMirror = "java.lang.String"] + | | +- ClassType[@TypeMirror = "java.lang.String"] + | +- FormalParameters[] + | | +- FormalParameter[@TypeMirror = "java.util.Map>"] + | | | +- ModifierList[] + | | | +- ClassType[@TypeMirror = "java.util.Map>"] + | | | | +- TypeArguments[] + | | | | +- ClassType[@TypeMirror = "java.lang.String"] + | | | | +- ClassType[@TypeMirror = "java.util.Map"] + | | | | +- TypeArguments[] + | | | | +- ClassType[@TypeMirror = "java.lang.String"] + | | | | +- ClassType[@TypeMirror = "java.lang.String"] + | | | +- VariableId[@Name = "previousMap", @TypeMirror = "java.util.Map>"] + | | +- FormalParameter[@TypeMirror = "java.util.Map>"] + | | +- ModifierList[] + | | +- ClassType[@TypeMirror = "java.util.Map>"] + | | | +- TypeArguments[] + | | | +- ClassType[@TypeMirror = "java.lang.String"] + | | | +- ClassType[@TypeMirror = "java.util.Map"] + | | | +- TypeArguments[] + | | | +- ClassType[@TypeMirror = "java.lang.String"] + | | | +- ClassType[@TypeMirror = "java.lang.String"] + | | +- VariableId[@Name = "nextMap", @TypeMirror = "java.util.Map>"] + | +- Block[] + | +- ExpressionStatement[] + | | +- MethodCall[@Failed = false, @Function = "java.util.Map>.putAll(java.util.Map>) -> void", @MethodName = "putAll", @TypeMirror = "void", @Unchecked = false, @VarargsCall = false] + | | +- VariableAccess[@Name = "previousMap", @TypeMirror = "java.util.Map>"] + | | +- ArgumentList[] + | | +- VariableAccess[@Name = "nextMap", @TypeMirror = "java.util.Map>"] + | +- ReturnStatement[] + | +- VariableAccess[@Name = "previousMap", @TypeMirror = "java.util.Map>"] + +- RecordDeclaration[@TypeMirror = "org.example.unusedPrivateMethod.Lender"] + | +- ModifierList[] + | +- RecordComponentList[] + | | +- RecordComponent[@TypeMirror = "java.lang.String"] + | | | +- ModifierList[] + | | | +- ClassType[@TypeMirror = "java.lang.String"] + | | | +- VariableId[@Name = "name", @TypeMirror = "java.lang.String"] + | | +- RecordComponent[@TypeMirror = "java.lang.String"] + | | +- ModifierList[] + | | +- ClassType[@TypeMirror = "java.lang.String"] + | | +- VariableId[@Name = "status", @TypeMirror = "java.lang.String"] + | +- RecordBody[] + +- RecordDeclaration[@TypeMirror = "org.example.unusedPrivateMethod.Book"] + | +- ModifierList[] + | +- RecordComponentList[] + | | +- RecordComponent[@TypeMirror = "java.lang.String"] + | | | +- ModifierList[] + | | | +- ClassType[@TypeMirror = "java.lang.String"] + | | | +- VariableId[@Name = "title", @TypeMirror = "java.lang.String"] + | | +- RecordComponent[@TypeMirror = "java.util.Collection"] + | | +- ModifierList[] + | | +- ClassType[@TypeMirror = "java.util.Collection"] + | | | +- TypeArguments[] + | | | +- ClassType[@TypeMirror = "org.example.unusedPrivateMethod.Lender"] + | | +- VariableId[@Name = "lenders", @TypeMirror = "java.util.Collection"] + | +- RecordBody[] + +- RecordDeclaration[@TypeMirror = "org.example.unusedPrivateMethod.Library"] + +- ModifierList[] + +- RecordComponentList[] + | +- RecordComponent[@TypeMirror = "java.util.Collection"] + | +- ModifierList[] + | +- ClassType[@TypeMirror = "java.util.Collection"] + | | +- TypeArguments[] + | | +- ClassType[@TypeMirror = "org.example.unusedPrivateMethod.Book"] + | +- VariableId[@Name = "books", @TypeMirror = "java.util.Collection"] + +- RecordBody[] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/UnnamedPatterns.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/UnnamedPatterns.txt index 25eb7dd0d72..e1fa78ded18 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/UnnamedPatterns.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/UnnamedPatterns.txt @@ -583,7 +583,7 @@ | +- ArgumentList[] | +- StringLiteral[@TypeMirror = "java.lang.String"] +- ExpressionStatement[] - +- MethodCall[@Failed = false, @Function = "java.util.stream.Stream. collect(java.util.stream.Collector>) -> java.util.Map", @MethodName = "collect", @TypeMirror = "java.util.Map", @Unchecked = false, @VarargsCall = false] + +- MethodCall[@Failed = false, @Function = "java.util.stream.Stream. collect(java.util.stream.Collector>) -> java.util.Map", @MethodName = "collect", @TypeMirror = "java.util.Map", @Unchecked = false, @VarargsCall = false] +- MethodCall[@Failed = false, @Function = "java.util.Collection.stream() -> java.util.stream.Stream", @MethodName = "stream", @TypeMirror = "java.util.stream.Stream", @Unchecked = false, @VarargsCall = false] | +- MethodCall[@Failed = false, @Function = "java.util.List. of(java.lang.String, java.lang.String) -> java.util.List", @MethodName = "of", @TypeMirror = "java.util.List", @Unchecked = false, @VarargsCall = false] | | +- TypeExpression[@TypeMirror = "java.util.List"] @@ -593,14 +593,14 @@ | | +- StringLiteral[@TypeMirror = "java.lang.String"] | +- ArgumentList[] +- ArgumentList[] - +- MethodCall[@Failed = false, @Function = "java.util.stream.Collectors. toMap(java.util.function.Function, java.util.function.Function) -> java.util.stream.Collector>", @MethodName = "toMap", @TypeMirror = "java.util.stream.Collector>", @Unchecked = false, @VarargsCall = false] + +- MethodCall[@Failed = false, @Function = "java.util.stream.Collectors. toMap(java.util.function.Function, java.util.function.Function) -> java.util.stream.Collector>", @MethodName = "toMap", @TypeMirror = "java.util.stream.Collector>", @Unchecked = false, @VarargsCall = false] +- TypeExpression[@TypeMirror = "java.util.stream.Collectors"] | +- ClassType[@TypeMirror = "java.util.stream.Collectors"] +- ArgumentList[] +- MethodReference[@TypeMirror = "java.util.function.Function"] | +- TypeExpression[@TypeMirror = "java.lang.String"] | +- ClassType[@TypeMirror = "java.lang.String"] - +- LambdaExpression[@TypeMirror = "java.util.function.Function"] + +- LambdaExpression[@TypeMirror = "java.util.function.Function"] +- LambdaParameterList[] | +- LambdaParameter[@TypeMirror = "java.lang.String"] | +- ModifierList[] From ed5e862aa384301a9e3c99f037930342cb6d23c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 15:14:44 +0100 Subject: [PATCH 0209/1962] Bump rouge from 4.4.0 to 4.5.0 in the all-gems group across 1 directory (#5316) Bumps the all-gems group with 1 update in the / directory: [rouge](https://github.com/rouge-ruby/rouge). Updates `rouge` from 4.4.0 to 4.5.0 - [Release notes](https://github.com/rouge-ruby/rouge/releases) - [Changelog](https://github.com/rouge-ruby/rouge/blob/master/CHANGELOG.md) - [Commits](https://github.com/rouge-ruby/rouge/compare/v4.4.0...v4.5.0) --- updated-dependencies: - dependency-name: rouge dependency-type: direct:development update-type: version-update:semver-minor dependency-group: all-gems ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1f7805ea501..41dfc5878a2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -75,7 +75,7 @@ GEM racc (1.8.1) rchardet (1.8.0) rexml (3.3.9) - rouge (4.4.0) + rouge (4.5.0) rufus-scheduler (3.9.2) fugit (~> 1.1, >= 1.11.1) safe_yaml (1.0.5) From e29bb926dfb59be006a3546de4b0412e82a83b65 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Sep 2024 17:11:33 +0200 Subject: [PATCH 0210/1962] Update default release notes sections --- do-release.sh | 9 ++++++++- docs/pages/pmd/projectdocs/committers/releasing.md | 9 ++++++++- docs/pages/release_notes.md | 9 ++++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/do-release.sh b/do-release.sh index 3440db6fc50..10a10687b3a 100755 --- a/do-release.sh +++ b/do-release.sh @@ -290,7 +290,14 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿšจ API Changes -### โœจ External Contributions +### โœจ Merged pull requests + + +### ๐Ÿ“ฆ Dependency updates + + +### ๐Ÿ“ˆ Stats + {% endtocmaker %} diff --git a/docs/pages/pmd/projectdocs/committers/releasing.md b/docs/pages/pmd/projectdocs/committers/releasing.md index 11365d7333b..9feba99d644 100644 --- a/docs/pages/pmd/projectdocs/committers/releasing.md +++ b/docs/pages/pmd/projectdocs/committers/releasing.md @@ -363,7 +363,14 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿšจ API Changes -### โœจ External Contributions +### โœจ Merged pull requests + + +### ๐Ÿ“ฆ Dependency updates + + +### ๐Ÿ“ˆ Stats + {% endtocmaker %} diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 3e50f0fc867..b22bd467204 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -27,7 +27,14 @@ This is a {{ site.pmd.release_type }} release. * {%jdoc xml::lang.xml.antlr4.XMLLexer %} is deprecated for removal. Use {%jdoc !!xml::lang.xml.ast.XMLLexer %} instead (note different package `ast` instead of `antlr4`). -### โœจ External Contributions +### โœจ Merged pull requests + + +### ๐Ÿ“ฆ Dependency updates + + +### ๐Ÿ“ˆ Stats + {% endtocmaker %} From 12d48e5493fe46532b5bab399665de75d339d612 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Sep 2024 18:49:28 +0200 Subject: [PATCH 0211/1962] Add release-notes scripts --- .ci/tools/release-notes-add-pr.sh | 46 +++++ .ci/tools/release-notes-generate.sh | 161 ++++++++++++++++++ do-release.sh | 41 +---- .../pmd/projectdocs/committers/releasing.md | 45 ++--- 4 files changed, 224 insertions(+), 69 deletions(-) create mode 100755 .ci/tools/release-notes-add-pr.sh create mode 100755 .ci/tools/release-notes-generate.sh diff --git a/.ci/tools/release-notes-add-pr.sh b/.ci/tools/release-notes-add-pr.sh new file mode 100755 index 00000000000..dbc34dd4bd2 --- /dev/null +++ b/.ci/tools/release-notes-add-pr.sh @@ -0,0 +1,46 @@ +#!/bin/bash +set -e + +if [ -z "$1" ]; then + echo "$0 " + exit 1 +fi + +BASEDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +PULL_NUMBER="$1" + +CURL_API_HEADER=(--header "X-GitHub-Api-Version: 2022-11-28") +CURL_AUTH_HEADER=() +if [ -n "$GITHUB_TOKEN" ]; then + echo "Will use env var GITHUB_TOKEN for github REST API" + CURL_AUTH_HEADER=(--header "Authorization: Bearer $GITHUB_TOKEN") +fi + + +PULL_JSON=$(curl "${CURL_API_HEADER[@]}" "${CURL_AUTH_HEADER[@]}" -s "https://api.github.com/repos/pmd/pmd/pulls/$PULL_NUMBER") +#echo "$PULL_JSON" > pull-response-$PULL_NUMBER.txt +#DEBUG ONLY +#PULL_JSON=$(cat pull-response-$PULL_NUMBER.txt) +#DEBUG ONLY + +PULL_ITEM="$(echo "$PULL_JSON" | jq --raw-output '"* [#\(.number)](https://github.com/pmd/pmd/pull/\(.number)): \(.title | gsub("@"; "@") | gsub("\\["; "\\[")) - @\(.user.login)"')" + +USER="$(echo "$PULL_JSON" | jq --raw-output .user.login)" +USER_JSON="$(curl "${CURL_API_HEADER[@]}" "${CURL_AUTH_HEADER[@]}" -s "https://api.github.com/users/$USER")" +#DEBUG ONLY +#USER_JSON="{\"login\": \"$USER\", \"name\": \"foo $USER\"}" +#DEBUG_ONLY +USER_NAME="$(echo "$USER_JSON" | jq --raw-output .name)" +search=" - \@$USER" +replacement=" - [$USER_NAME](https://github.com/$USER) (@$USER)" +PULL_ITEM="${PULL_ITEM//${search}/${replacement}}" + +RELEASE_NOTES_FILE="${BASEDIR}/docs/pages/release_notes.md" +RELEASE_NOTES=$(cat "$RELEASE_NOTES_FILE") + +line="$(echo "$RELEASE_NOTES" | grep -n "### ๐Ÿ“ฆ Dependency updates" | cut -d ":" -f 1)" +RELEASE_NOTES="$(echo "$RELEASE_NOTES" | head -n "$((line - 1))") +$PULL_ITEM +$(echo "$RELEASE_NOTES" | tail -n "+$((line - 1))") +" +echo "$RELEASE_NOTES" > "$RELEASE_NOTES_FILE" diff --git a/.ci/tools/release-notes-generate.sh b/.ci/tools/release-notes-generate.sh new file mode 100755 index 00000000000..f15a26aad39 --- /dev/null +++ b/.ci/tools/release-notes-generate.sh @@ -0,0 +1,161 @@ +#!/bin/bash +set -e + +if [ -z "$1" ] || [ -z "$2" ]; then + echo "$0 " + exit 1 +fi + +BASEDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +LAST_VERSION="$1" +RELEASE_VERSION="$2" + +CURL_API_HEADER=(--header "X-GitHub-Api-Version: 2022-11-28") +CURL_AUTH_HEADER=() +if [ -n "$GITHUB_TOKEN" ]; then + echo "Will use env var GITHUB_TOKEN for github REST API" + CURL_AUTH_HEADER=(--header "Authorization: Bearer $GITHUB_TOKEN") +fi + +# determine current milestone +MILESTONE_JSON=$(curl "${CURL_API_HEADER[@]}" "${CURL_AUTH_HEADER[@]}" -s "https://api.github.com/repos/pmd/pmd/milestones?state=all&direction=desc&per_page=10&page=1"|jq ".[] | select(.title == \"$RELEASE_VERSION\")") +#DEBUG ONLY +#MILESTONE_JSON='{"number":80,"closed_issues":40}' +#DEBUG ONLY +MILESTONE=$(echo "$MILESTONE_JSON" | jq .number) + +PAGE="1" +HAS_NEXT="true" +ISSUES_JSON="" +while [ "$HAS_NEXT" = "true" ]; do + echo "Fetching issues for milestone ${MILESTONE} page ${PAGE}..." + URL="https://api.github.com/repos/pmd/pmd/issues?state=closed&sort=created&direction=asc&per_page=30&page=${PAGE}&milestone=${MILESTONE}" + RESPONSE="$(curl "${CURL_API_HEADER[@]}" "${CURL_AUTH_HEADER[@]}" -s -w "\n%header{link}" "$URL")" + + #DEBUG ONLY + #echo "$RESPONSE" > issues-response-${PAGE}.txt + #RESPONSE="$(cat issues-response-${PAGE}.txt)" + #DEBUG ONLY + + LINK_HEADER="$(echo "$RESPONSE" | tail -1)" + BODY="$(echo "$RESPONSE" | head -n -1)" + + #DEBUG ONLY + #echo "$BODY" > "issues-response-page-${PAGE}.txt" + #BODY="$(cat "issues-response-page-${PAGE}.txt")" + #DEBUG ONLY + + COMMA="," + if [ "$PAGE" -eq 1 ]; then + COMMA="" + fi + ISSUES_JSON="${ISSUES_JSON}${COMMA}${BODY}" + + if [[ $LINK_HEADER == *"; rel=\"next\""* ]]; then + HAS_NEXT="true" + else + HAS_NEXT="false" + fi + PAGE=$((PAGE + 1)) + + #DEBUG ONLY + #HAS_NEXT="true" + #if [ "$PAGE" -gt 2 ]; then break; fi + #DEBUG ONLY + + # stop after 10 pages + if [ "$PAGE" -gt 10 ]; then + echo + echo + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + echo "!!!!!!!!!!!!!! reached page 10, stopping now !!!!!!!!!!!!!" + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + echo + echo + break; + fi +done + + +ISSUES_JSON="$(echo "[ $ISSUES_JSON ]" | jq 'flatten(1)')" +echo "Found $(echo "$ISSUES_JSON" | jq length) issues/pull requests" +#DEBUG ONLY +#echo "$ISSUES_JSON" > issues-all.txt +#DEBUG ONLY + +FIXED_ISSUES_JSON="$(echo "$ISSUES_JSON" | jq 'map(select(has("pull_request") | not))')" +FIXED_ISSUES="$(echo "$FIXED_ISSUES_JSON" | jq --raw-output '.[] | "* [#\(.number)](https://github.com/pmd/pmd/issues/\(.number)): \(.title | gsub("@"; "@") | gsub("\\["; "\\["))"')" +FIXED_ISSUES="### ๐Ÿ› Fixed Issues + +$FIXED_ISSUES +" + +PULL_REQUESTS_JSON="$(echo "$ISSUES_JSON" | jq 'map(select(has("pull_request"))) | map(select(contains({labels: [{name: "dependencies"}]}) | not))')" +PULL_REQUESTS="$(echo "$PULL_REQUESTS_JSON" | jq --raw-output '.[] | "* [#\(.number)](https://github.com/pmd/pmd/pull/\(.number)): \(.title | gsub("@"; "@") | gsub("\\["; "\\[")) - @\(.user.login)"')" + +AUTHORS="$(echo "$PULL_REQUESTS_JSON" | jq --raw-output '.[].user.login' | sort | uniq)" +echo "Resolving $(echo "$AUTHORS" | wc -l) author names in pull requests..." +for login in $AUTHORS; do + USER_JSON="$(curl "${CURL_API_HEADER[@]}" "${CURL_AUTH_HEADER[@]}" -s "https://api.github.com/users/$login")" + #DEBUG ONLY + #USER_JSON="{\"login\": \"$login\", \"name\": \"foo $login\"}" + #DEBUG_ONLY + USER_NAME="$(echo "$USER_JSON" | jq --raw-output .name)" + search=" - \@$login" + replacement=" - [$USER_NAME](https://github.com/$login) (@$login)" + PULL_REQUESTS="${PULL_REQUESTS//${search}/${replacement}}" +done + +PULL_REQUESTS="### โœจ Merged pull requests + +$PULL_REQUESTS +" + +DEPENDENCY_UPDATES_JSON="$(echo "$ISSUES_JSON" | jq 'map(select(has("pull_request"))) | map(select(contains({labels: [{name: "dependencies"}]})))')" +DEPENDENCY_UPDATES="$(echo "$DEPENDENCY_UPDATES_JSON" | jq --raw-output '.[] | "* [#\(.number)](https://github.com/pmd/pmd/pull/\(.number)): \(.title | gsub("@"; "@") | gsub("\\["; "\\["))"')" +DEPENDENCY_UPDATES_COUNT=$(echo "$DEPENDENCY_UPDATES_JSON" | jq length) +if [ -z "$DEPENDENCY_UPDATES" ]; then DEPENDENCY_UPDATES="No dependency updates."; fi +DEPENDENCY_UPDATES="### ๐Ÿ“ฆ Dependency updates + +$DEPENDENCY_UPDATES +" + +# calculating stats for release notes (excluding dependency updates) +STATS_CLOSED_ISSUES=$(echo "$MILESTONE_JSON" | jq .closed_issues) +STATS=$( +echo "### ๐Ÿ“ˆ Stats" +echo "" +echo "* $(git log pmd_releases/"${LAST_VERSION}"..HEAD --oneline --no-merges |wc -l) commits" +echo "* $((STATS_CLOSED_ISSUES - DEPENDENCY_UPDATES_COUNT)) closed tickets & PRs" +echo "* Days since last release: $(( ( $(date +%s) - $(git log --max-count=1 --format="%at" pmd_releases/"${LAST_VERSION}") ) / 86400))" +echo +) + +function insert() { + local FULL_TEXT="$1" + local FROM_MARKER="$2" + local END_MARKER="$3" + local INSERTION="$4" + local fromLine + local endLine + local headText + local tailText + fromLine="$(echo "$FULL_TEXT" | grep -n "$FROM_MARKER" | cut -d ":" -f 1)" + endLine="$(echo "$FULL_TEXT" | grep -n "$END_MARKER" | cut -d ":" -f 1)" + headText="$(echo "$FULL_TEXT" | head -n "$((fromLine - 1))")" + tailText="$(echo "$FULL_TEXT" | tail -n "+$endLine")" + echo "$headText + +$INSERTION + +$tailText" +} + +RELEASE_NOTES_FILE="${BASEDIR}/docs/pages/release_notes.md" +RELEASE_NOTES=$(cat "$RELEASE_NOTES_FILE") +#RELEASE_NOTES="$(insert "$RELEASE_NOTES" "### ๐Ÿ› Fixed Issues" "### โœจ Merged pull requests" "$FIXED_ISSUES")" +RELEASE_NOTES="$(insert "$RELEASE_NOTES" "### โœจ Merged pull requests" "### ๐Ÿ“ฆ Dependency updates" "$PULL_REQUESTS")" +RELEASE_NOTES="$(insert "$RELEASE_NOTES" "### ๐Ÿ“ฆ Dependency updates" "### ๐Ÿ“ˆ Stats" "$DEPENDENCY_UPDATES")" +RELEASE_NOTES="$(insert "$RELEASE_NOTES" "### ๐Ÿ“ˆ Stats" "{% endtocmaker %}" "$STATS")" + +echo "$RELEASE_NOTES" > "$RELEASE_NOTES_FILE" diff --git a/do-release.sh b/do-release.sh index 10a10687b3a..786139c7211 100755 --- a/do-release.sh +++ b/do-release.sh @@ -125,46 +125,11 @@ echo echo "Press enter to continue..." read -r +# updating release notes +.ci/tools/release-notes-generate.sh "$LAST_VERSION" "$RELEASE_VERSION" -# determine current milestone -MILESTONE_JSON=$(curl -s "https://api.github.com/repos/pmd/pmd/milestones?state=all&direction=desc&per_page=5"|jq ".[] | select(.title == \"$RELEASE_VERSION\")") -MILESTONE=$(echo "$MILESTONE_JSON" | jq .number) - -# determine dependency updates -DEPENDENCIES_JSON=$(curl -s "https://api.github.com/repos/pmd/pmd/issues?labels=dependencies&state=closed&direction=asc&per_page=50&page=1&milestone=${MILESTONE}") -DEPENDENCIES_COUNT=$(echo "$DEPENDENCIES_JSON" | jq length) -DEPENDENCIES="" -if [ $DEPENDENCIES_COUNT -gt 0 ]; then - DEPENDENCIES=$( - echo "### ๐Ÿ“ฆ Dependency updates" - echo "$DEPENDENCIES_JSON" | jq --raw-output '.[] | "* [#\(.number)](https://github.com/pmd/pmd/issues/\(.number)): \(.title)"' - ) -else - DEPENDENCIES=$( - echo "### ๐Ÿ“ฆ Dependency updates" - echo "No dependency updates" - ) -fi - -# calculating stats for release notes (excluding dependency updates) -STATS_CLOSED_ISSUES=$(echo "$MILESTONE_JSON" | jq .closed_issues) -STATS=$( -echo "### ๐Ÿ“ˆ Stats" -echo "* $(git log pmd_releases/"${LAST_VERSION}"..HEAD --oneline --no-merges |wc -l) commits" -echo "* $(($STATS_CLOSED_ISSUES - $DEPENDENCIES_COUNT)) closed tickets & PRs" -echo "* Days since last release: $(( ( $(date +%s) - $(git log --max-count=1 --format="%at" pmd_releases/"${LAST_VERSION}") ) / 86400))" -) - - -TEMP_RELEASE_NOTES=$(cat docs/pages/release_notes.md) -TEMP_RELEASE_NOTES=${TEMP_RELEASE_NOTES/\{\% endtocmaker \%\}/${DEPENDENCIES//\&/\\\&}$'\n'$'\n'${STATS//\&/\\\&}$'\n'$'\n'\{\% endtocmaker \%\}} -echo "${TEMP_RELEASE_NOTES}" > docs/pages/release_notes.md - -echo -echo "Updated dependencies and stats in release notes:" -echo "$DEPENDENCIES" -echo "$STATS" echo +echo "Updated merged pull requests, dependency updates and stats in release notes:" echo "Please verify docs/pages/release_notes.md" echo echo "Press enter to continue..." diff --git a/docs/pages/pmd/projectdocs/committers/releasing.md b/docs/pages/pmd/projectdocs/committers/releasing.md index 9feba99d644..a32c23e3d98 100644 --- a/docs/pages/pmd/projectdocs/committers/releasing.md +++ b/docs/pages/pmd/projectdocs/committers/releasing.md @@ -99,46 +99,29 @@ Starting with PMD 7.5.0 we use Dependabot to update dependencies. Dependabot wil labeled with `dependencies`. When we merge such a pull request, we should assign it to the correct milestone. It is important, that the due date of the milestone is set correctly, otherwise the query won't find the milestone number. -Then we can query which PRs have been merged and generate a section for the release notes: +Then we can query which PRs have been merged and generate automatically a section for the release notes. +This is done by the script `.ci/tools/release-notes-generate.sh`. It needs to be called with the +LAST_VERSION and RELEASE_VERSION as parameters, e.g. ```shell -NEW_VERSION=7.2.0 -MILESTONE_JSON=$(curl -s "https://api.github.com/repos/pmd/pmd/milestones?state=all&direction=desc&per_page=5"|jq ".[] | select(.title == \"$NEW_VERSION\")") -MILESTONE=$(echo "$MILESTONE_JSON" | jq .number) - -# determine dependency updates -DEPENDENCIES_JSON=$(curl -s "https://api.github.com/repos/pmd/pmd/issues?labels=dependencies&state=closed&direction=asc&per_page=50&page=1&milestone=${MILESTONE}") -DEPENDENCIES_COUNT=$(echo "$DEPENDENCIES_JSON" | jq length) -if [ $DEPENDENCIES_COUNT -gt 0 ]; then - echo "### ๐Ÿ“ฆ Dependency updates" - echo "$DEPENDENCIES_JSON" | jq --raw-output '.[] | "* [#\(.number)](https://github.com/pmd/pmd/issues/\(.number)): \(.title)"' -else - echo "### ๐Ÿ“ฆ Dependency updates" - echo "No dependency updates" -fi +.ci/tool/release-notes-generate.sh 7.5.0 7.6.0 ``` -This section needs to be added to the release notes at the end. + +This script will directly modify the file `docs/pages/release_notes.md`. It can be called multiple times +without issues. However, there is active +[rate limiting](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2022-11-28) +of the GitHub API, which might cause issues. If that happens, you need to set the env var `GITHUB_TOKEN` with +your personal access token. The script will pick it up automatically. +A fine-grained token with onl "Public Repositories (read-only)" access is enough. Starting with PMD 6.23.0 we'll provide small statistics for every release. This needs to be added to the release notes as the last section (after "Dependency updates"). To count the closed issues and pull requests, the milestone on GitHub with the title of the new release is searched. It is important, that the due date of the milestone is correctly set, as the returned milestones in the API call are sorted by due date. -Make sure, there is such a milestone on . The following snippet will -create the numbers, that can be attached to the release notes as a last section. Note: It uses part of the -above code snippet (e.g. NEW_VERSION, MILESTONE, DEPENDENCIES_COUNT): - -```shell -LAST_VERSION=7.1.0 -NEW_VERSION_COMMITISH=HEAD -STATS_CLOSED_ISSUES=$(echo "$MILESTONE_JSON" | jq .closed_issues) - -echo "### Stats" -echo "* $(git log pmd_releases/${LAST_VERSION}..${NEW_VERSION_COMMITISH} --oneline --no-merges |wc -l) commits" -echo "* $(($STATS_CLOSED_ISSUES - $DEPENDENCIES_COUNT)) closed tickets & PRs" -echo "* Days since last release: $(( ( $(date +%s) - $(git log --max-count=1 --format="%at" pmd_releases/${LAST_VERSION}) ) / 86400))" -``` +Make sure, there is such a milestone on . +This section is updated automatically by `.ci/tools/release-notes-generate.sh` as well. -Note: both shell snippets are also integrated into `do-release.sh`. +Note: the call to "release-notes-generate.sh" is also integrated into `do-release.sh`. Check in all (version) changes to branch main or any other branch, from which the release takes place: From 2f5d7f4292acd2cd1e6f2561c044ec167b5fb719 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Sep 2024 18:57:20 +0200 Subject: [PATCH 0212/1962] Update merging PR doc --- docs/pages/pmd/projectdocs/committers/merging_pull_requests.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/pages/pmd/projectdocs/committers/merging_pull_requests.md b/docs/pages/pmd/projectdocs/committers/merging_pull_requests.md index ebd8779f362..af1391c586d 100644 --- a/docs/pages/pmd/projectdocs/committers/merging_pull_requests.md +++ b/docs/pages/pmd/projectdocs/committers/merging_pull_requests.md @@ -39,7 +39,8 @@ author: Andreas Dangel * If the PR fixes a bug, make sure, it is listed under the section "Fixed Issues". Also make sure, that the PR description mentions this (e.g. "- fixes #issue-number") and the this PR is linked with the issue. Merging this PR will then automatically close the issue. - * In any case, add the PR to the section "External Contributions". + * In any case, add the PR to the section "Merged pull requests". You can add it by calling + `.ci/tools/release-notes-add-pr.sh prnumber`. * Commit these changes with the message: ``` From a1ceee7403e415d3a5348fd5a68c5d403d3979f1 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 14 Nov 2024 15:19:44 +0100 Subject: [PATCH 0213/1962] Handle missing link header when paging with curl --- .ci/tools/release-notes-generate.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.ci/tools/release-notes-generate.sh b/.ci/tools/release-notes-generate.sh index f15a26aad39..2bce824ba3b 100755 --- a/.ci/tools/release-notes-generate.sh +++ b/.ci/tools/release-notes-generate.sh @@ -30,7 +30,7 @@ ISSUES_JSON="" while [ "$HAS_NEXT" = "true" ]; do echo "Fetching issues for milestone ${MILESTONE} page ${PAGE}..." URL="https://api.github.com/repos/pmd/pmd/issues?state=closed&sort=created&direction=asc&per_page=30&page=${PAGE}&milestone=${MILESTONE}" - RESPONSE="$(curl "${CURL_API_HEADER[@]}" "${CURL_AUTH_HEADER[@]}" -s -w "\n%header{link}" "$URL")" + RESPONSE="$(curl "${CURL_API_HEADER[@]}" "${CURL_AUTH_HEADER[@]}" -s -w "\nLink: %header{link}" "$URL")" #DEBUG ONLY #echo "$RESPONSE" > issues-response-${PAGE}.txt @@ -152,6 +152,8 @@ $tailText" } RELEASE_NOTES_FILE="${BASEDIR}/docs/pages/release_notes.md" +echo "Updating $RELEASE_NOTES_FILE now..." + RELEASE_NOTES=$(cat "$RELEASE_NOTES_FILE") #RELEASE_NOTES="$(insert "$RELEASE_NOTES" "### ๐Ÿ› Fixed Issues" "### โœจ Merged pull requests" "$FIXED_ISSUES")" RELEASE_NOTES="$(insert "$RELEASE_NOTES" "### โœจ Merged pull requests" "### ๐Ÿ“ฆ Dependency updates" "$PULL_REQUESTS")" From e5a123698144993b6cf8808e6206fae3b4ff5d88 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 14 Nov 2024 15:48:47 +0100 Subject: [PATCH 0214/1962] Update pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml --- .../lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index 2679f0a8c5c..2a743036a69 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2135,7 +2135,7 @@ public class ObtainViaTest { ]]> - UnusedPrivateMethod with method reference + #5324 UnusedPrivateMethod with method reference 0 Date: Thu, 14 Nov 2024 15:50:35 +0100 Subject: [PATCH 0215/1962] [doc] Update release notes (#5324) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 3e50f0fc867..5fa3ac04b69 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -19,6 +19,7 @@ This is a {{ site.pmd.release_type }} release. * [#1860](https://github.com/pmd/pmd/issues/1860): \[ant] Reflective access warnings on java > 9 and java < 17 * java * [#5293](https://github.com/pmd/pmd/issues/5293): \[java] Deadlock when executing PMD in multiple threads + * [#5324](https://github.com/pmd/pmd/issues/5324): \[java] Issue with type inference of nested lambdas ### ๐Ÿšจ API Changes From a79d3e6557381cdad139d1ab2ee5d7921f78a081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 14 Nov 2024 16:13:30 +0100 Subject: [PATCH 0216/1962] Add unit tests --- .../java/internal/JavaLanguageProperties.java | 2 +- .../internal/infer/InferenceContext.java | 1 + .../internal/infer/TypeInferenceLogger.java | 10 +- .../internal/infer/InferenceCtxUnitTests.java | 93 +++++++++++++++++++ 4 files changed, 103 insertions(+), 3 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProperties.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProperties.java index 7fafea029ef..7590d48f6fd 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProperties.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProperties.java @@ -22,7 +22,7 @@ public class JavaLanguageProperties extends JvmLanguagePropertyBundle { PropertyFactory.enumProperty("xTypeInferenceLogging", EnumUtils.getEnumMap(InferenceLoggingVerbosity.class)) .desc("Verbosity of the type inference logging") - .defaultValue(InferenceLoggingVerbosity.DISABLED) + .defaultValue(InferenceLoggingVerbosity.VERBOSE) .build(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/InferenceContext.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/InferenceContext.java index 73b843439fd..8cc251fa0ef 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/InferenceContext.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/InferenceContext.java @@ -525,6 +525,7 @@ private boolean solve(Supplier newWalker) { * we try again to make progress. */ private boolean solve(VarWalkStrategy walker) { + graphWasChanged = false; incorporate(); while (walker.hasNext()) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java index 2c9cfff9efa..cb7fe3e6d3b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java @@ -22,6 +22,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import net.sourceforge.pmd.lang.java.ast.JavaNode; +import net.sourceforge.pmd.lang.java.internal.JavaLanguageProperties; import net.sourceforge.pmd.lang.java.symbols.JTypeDeclSymbol; import net.sourceforge.pmd.lang.java.types.JMethodSig; import net.sourceforge.pmd.lang.java.types.JTypeMirror; @@ -34,6 +35,12 @@ /** * A strategy to log the execution traces of {@link Infer}. + * The default does nothing, so the logger calls can be optimized out + * at runtime, while not having to check that logging is enabled at the + * call sites. + * + *

    To enable logging for the CLI, use the language property ({@link JavaLanguageProperties}) + * {@code xTypeInferenceLogging}. From tests, see {@code JavaParsingHelper#logTypeInferenceVerbose()}. */ @SuppressWarnings("PMD.UncommentedEmptyMethodBody") public interface TypeInferenceLogger { @@ -64,8 +71,7 @@ default void ctxInitialization(InferenceContext ctx, JMethodSig sig) { } default void applicabilityTest(InferenceContext ctx) { } - default void finishApplicabilityTest() { - } + default void finishApplicabilityTest() { } default void startArgsChecks() { } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/internal/infer/InferenceCtxUnitTests.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/internal/infer/InferenceCtxUnitTests.java index 5e33c6dd018..ba1d8342618 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/internal/infer/InferenceCtxUnitTests.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/internal/infer/InferenceCtxUnitTests.java @@ -8,7 +8,10 @@ import static net.sourceforge.pmd.lang.java.types.internal.infer.BaseTypeInferenceUnitTest.Bound.eqBound; import static net.sourceforge.pmd.lang.java.types.internal.infer.BaseTypeInferenceUnitTest.Bound.lower; import static net.sourceforge.pmd.lang.java.types.internal.infer.BaseTypeInferenceUnitTest.Bound.upper; +import static net.sourceforge.pmd.util.CollectionUtil.setOf; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsInAnyOrder; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -19,11 +22,17 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import java.util.List; +import java.util.Set; + +import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Test; import net.sourceforge.pmd.lang.java.types.JTypeMirror; import net.sourceforge.pmd.lang.java.types.TypeOps; import net.sourceforge.pmd.lang.java.types.internal.infer.InferenceVar.BoundKind; +import net.sourceforge.pmd.lang.java.types.internal.infer.VarWalkStrategy.GraphWalk; +import net.sourceforge.pmd.util.IteratorUtil; /** * @@ -331,4 +340,88 @@ void testArrayUpper() { assertThat(a, hasBoundsExactly(upper(ts.BOOLEAN.box()))); } + + private static @NotNull List> createBatchSetsFromGraph(InferenceContext ctx) { + GraphWalk graphWalk = new GraphWalk(ctx, false); + List> batches = IteratorUtil.toList(graphWalk); + return batches; + } + + @Test + void testGraphBuilding() { + InferenceContext ctx = emptyCtx(); + InferenceVar a = newIvar(ctx); + InferenceVar b = newIvar(ctx); + + List> batches = createBatchSetsFromGraph(ctx); + // no dependency: unordered + assertThat(batches, containsInAnyOrder(setOf(a), setOf(b))); + } + + @Test + void testGraphBuildingWithDependency() { + InferenceContext ctx = emptyCtx(); + InferenceVar a = newIvar(ctx); + InferenceVar b = newIvar(ctx); + + // a -> b + addSubtypeConstraint(ctx, a, ts.arrayType(b)); + + List> batches = createBatchSetsFromGraph(ctx); + + assertThat(batches, contains(setOf(b), setOf(a))); + } + + @Test + void testGraphBuildingWithDependency2() { + InferenceContext ctx = emptyCtx(); + InferenceVar a = newIvar(ctx); + InferenceVar b = newIvar(ctx); + + // a -> b + // b -> a (because of propagation) + addSubtypeConstraint(ctx, a, b); + + List> batches = createBatchSetsFromGraph(ctx); + + assertThat(batches, contains(setOf(b, a))); + } + + + + + @Test + void testGraphBuildingWithExtraDependency() { + InferenceContext ctx = emptyCtx(); + InferenceVar a = newIvar(ctx); + InferenceVar b = newIvar(ctx); + + // b -> a + ctx.addInstantiationDependencies(setOf(b), setOf(a)); + + List> batches = createBatchSetsFromGraph(ctx); + + assertThat(batches, contains(setOf(a), setOf(b))); + } + + @Test + void testGraphBuildingWithDependencyCycle() { + InferenceContext ctx = emptyCtx(); + InferenceVar a = newIvar(ctx); + InferenceVar b = newIvar(ctx); + InferenceVar c = newIvar(ctx); + + // a -> b, b -> a, + // a -> c, b -> c + a.addBound(BoundKind.UPPER, b); + a.addBound(BoundKind.EQ, listType(c)); + b.addBound(BoundKind.LOWER, a); + b.addBound(BoundKind.LOWER, listType(c)); + + + List> batches = createBatchSetsFromGraph(ctx); + + assertThat(batches, contains(setOf(c), setOf(b, a))); + } + } From bd9a975908fd09d8e58518a236b572fec571abec Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 14 Nov 2024 16:31:56 +0100 Subject: [PATCH 0217/1962] [java] UseStringBufferLength - consider sb.toString().equals("") Fixes #5320 --- docs/pages/release_notes.md | 2 ++ .../resources/category/java/performance.xml | 5 ++++ .../performance/xml/UseStringBufferLength.xml | 25 ++++++++++++++++--- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 5fa3ac04b69..122a371db2f 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -20,6 +20,8 @@ This is a {{ site.pmd.release_type }} release. * java * [#5293](https://github.com/pmd/pmd/issues/5293): \[java] Deadlock when executing PMD in multiple threads * [#5324](https://github.com/pmd/pmd/issues/5324): \[java] Issue with type inference of nested lambdas +* java-performance + * [#5320](https://github.com/pmd/pmd/issues/5320): \[java] UseStringBufferLength: false-negative on StringBuffer of sb.toString().equals("") ### ๐Ÿšจ API Changes diff --git a/pmd-java/src/main/resources/category/java/performance.xml b/pmd-java/src/main/resources/category/java/performance.xml index a8e4c37142b..87487db1587 100644 --- a/pmd-java/src/main/resources/category/java/performance.xml +++ b/pmd-java/src/main/resources/category/java/performance.xml @@ -901,6 +901,11 @@ or StringBuffer.toString().length() == ... and MethodCall[pmd-java:matchesSig('java.lang.AbstractStringBuilder#toString()')] and ArgumentList/VariableAccess[@Name = //VariableDeclarator[StringLiteral[@Image='""']] /VariableId[pmd-java:modifiers() = 'final']/@Name]] +| +(: finds sb.toString().equals("") :) +//MethodCall[pmd-java:matchesSig('_#equals(_)') + and MethodCall[pmd-java:matchesSig('java.lang.AbstractStringBuilder#toString()')] + and ArgumentList/StringLiteral[@Image='""']] ]]> diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseStringBufferLength.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseStringBufferLength.xml index 0f47697896e..37b7c6cab08 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseStringBufferLength.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseStringBufferLength.xml @@ -28,9 +28,8 @@ public class Foo { - - StringBuffer.toString.equals(""), bad - 0 + #5320 StringBuffer.toString.equals(""), bad + 2 + + + #5320 [java] UseStringBufferLength: false-negative on StringBuffer of sb.toString().equals("") + 3 + 6,7,9 + + From 2df68ed16888ce9945dfc960d5b51c2547d4c833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 14 Nov 2024 16:32:09 +0100 Subject: [PATCH 0218/1962] Disable type inf logging by default --- .../pmd/lang/java/internal/JavaLanguageProperties.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProperties.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProperties.java index 7590d48f6fd..7fafea029ef 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProperties.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProperties.java @@ -22,7 +22,7 @@ public class JavaLanguageProperties extends JvmLanguagePropertyBundle { PropertyFactory.enumProperty("xTypeInferenceLogging", EnumUtils.getEnumMap(InferenceLoggingVerbosity.class)) .desc("Verbosity of the type inference logging") - .defaultValue(InferenceLoggingVerbosity.VERBOSE) + .defaultValue(InferenceLoggingVerbosity.DISABLED) .build(); From af13f1bfa1b9d587fb262f27fd4511dc9c7b018b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 14 Nov 2024 16:32:25 +0100 Subject: [PATCH 0219/1962] Add @chenguangqi as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 172 +++++++++++++------------- 2 files changed, 96 insertions(+), 85 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 95ebc05d6e1..1d4a930f383 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7865,6 +7865,15 @@ "contributions": [ "code" ] + }, + { + "login": "chenguangqi", + "name": "ๅคฉ็ƒญๅƒ่ฅฟ็“œ", + "avatar_url": "https://avatars.githubusercontent.com/u/6231010?v=4", + "profile": "http://chenguangqi.github.io/", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 9497ea73780..7b6a55aec62 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -350,770 +350,772 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d JJengility
    JJengility

    ๐Ÿ› Jake Hemmerle
    Jake Hemmerle

    ๐Ÿ› + Jakub Dupak
    Jakub Dupak

    ๐Ÿ’ป James Harrison
    James Harrison

    ๐Ÿ› ๐Ÿ’ป Jamie Bisotti
    Jamie Bisotti

    ๐Ÿ› Jan
    Jan

    ๐Ÿ› Jan Aertgeerts
    Jan Aertgeerts

    ๐Ÿ’ป ๐Ÿ› - Jan Brรผmmer
    Jan Brรผmmer

    ๐Ÿ› + Jan Brรผmmer
    Jan Brรผmmer

    ๐Ÿ› Jan Tล™รญska
    Jan Tล™รญska

    ๐Ÿ› Jan-Lukas Else
    Jan-Lukas Else

    ๐Ÿ› Jason Qiu
    Jason Qiu

    ๐Ÿ’ป ๐Ÿ“– Jason Williams
    Jason Williams

    ๐Ÿ› Javier Spagnoletti
    Javier Spagnoletti

    ๐Ÿ› Jean-Paul Mayer
    Jean-Paul Mayer

    ๐Ÿ› - Jean-Simon Larochelle
    Jean-Simon Larochelle

    ๐Ÿ› + Jean-Simon Larochelle
    Jean-Simon Larochelle

    ๐Ÿ› Jeff Bartolotta
    Jeff Bartolotta

    ๐Ÿ’ป ๐Ÿ› Jeff Hube
    Jeff Hube

    ๐Ÿ’ป ๐Ÿ› Jeff Jensen
    Jeff Jensen

    ๐Ÿ› Jeff May
    Jeff May

    ๐Ÿ› Jens Gerdes
    Jens Gerdes

    ๐Ÿ› Jeroen Borgers
    Jeroen Borgers

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข - Jeroen Meijer
    Jeroen Meijer

    ๐Ÿ› + Jeroen Meijer
    Jeroen Meijer

    ๐Ÿ› Jeroen van Wilgenburg
    Jeroen van Wilgenburg

    ๐Ÿ“– Jerome Russ
    Jerome Russ

    ๐Ÿ› JerritEic
    JerritEic

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Jiri Pejchal
    Jiri Pejchal

    ๐Ÿ› Jithin Sunny
    Jithin Sunny

    ๐Ÿ› Jiล™รญ ล korpil
    Jiล™รญ ล korpil

    ๐Ÿ› - Joao Machado
    Joao Machado

    ๐Ÿ› + Joao Machado
    Joao Machado

    ๐Ÿ› Jochen Krauss
    Jochen Krauss

    ๐Ÿ› Johan Hammar
    Johan Hammar

    ๐Ÿ› John Karp
    John Karp

    ๐Ÿ› John Zhang
    John Zhang

    ๐Ÿ› John-Teng
    John-Teng

    ๐Ÿ’ป ๐Ÿ› Jon Moroney
    Jon Moroney

    ๐Ÿ’ป ๐Ÿ› - Jonas Geiregat
    Jonas Geiregat

    ๐Ÿ› + Jonas Geiregat
    Jonas Geiregat

    ๐Ÿ› Jonas KeรŸler
    Jonas KeรŸler

    ๐Ÿ› Jonathan Wiesel
    Jonathan Wiesel

    ๐Ÿ’ป ๐Ÿ› Jordan
    Jordan

    ๐Ÿ› Jordi Llach
    Jordi Llach

    ๐Ÿ› Jorge Solรณrzano
    Jorge Solรณrzano

    ๐Ÿ› JorneVL
    JorneVL

    ๐Ÿ› - Jose Palafox
    Jose Palafox

    ๐Ÿ› + Jose Palafox
    Jose Palafox

    ๐Ÿ› Jose Stovall
    Jose Stovall

    ๐Ÿ› Joseph
    Joseph

    ๐Ÿ’ป Joseph Heenan
    Joseph Heenan

    ๐Ÿ› Josh Feingold
    Josh Feingold

    ๐Ÿ’ป ๐Ÿ› Josh Holthaus
    Josh Holthaus

    ๐Ÿ› Joshua S Arquilevich
    Joshua S Arquilevich

    ๐Ÿ› - Joรฃo Dinis Ferreira
    Joรฃo Dinis Ferreira

    ๐Ÿ“– + Joรฃo Dinis Ferreira
    Joรฃo Dinis Ferreira

    ๐Ÿ“– Joรฃo Ferreira
    Joรฃo Ferreira

    ๐Ÿ’ป ๐Ÿ› Joรฃo Pedro Schmitt
    Joรฃo Pedro Schmitt

    ๐Ÿ› Juan Martรญn Sotuyo Dodero
    Juan Martรญn Sotuyo Dodero

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง Juan Pablo Civile
    Juan Pablo Civile

    ๐Ÿ› Julian Voronetsky
    Julian Voronetsky

    ๐Ÿ› Julien
    Julien

    ๐Ÿ› - Julius
    Julius

    ๐Ÿ› + Julius
    Julius

    ๐Ÿ› JustPRV
    JustPRV

    ๐Ÿ› Justin Stroud
    Justin Stroud

    ๐Ÿ’ป Jรถrn Huxhorn
    Jรถrn Huxhorn

    ๐Ÿ› KThompso
    KThompso

    ๐Ÿ› Kai Amundsen
    Kai Amundsen

    ๐Ÿ› Karel Vervaeke
    Karel Vervaeke

    ๐Ÿ› - Karl-Andero Mere
    Karl-Andero Mere

    ๐Ÿ› + Karl-Andero Mere
    Karl-Andero Mere

    ๐Ÿ› Karl-Philipp Richter
    Karl-Philipp Richter

    ๐Ÿ› Karsten Silz
    Karsten Silz

    ๐Ÿ› Kazuma Watanabe
    Kazuma Watanabe

    ๐Ÿ› Kev
    Kev

    ๐Ÿ› Keve Mรผller
    Keve Mรผller

    ๐Ÿ› Kevin Guerra
    Kevin Guerra

    ๐Ÿ’ป - Kevin Jones
    Kevin Jones

    ๐Ÿ› ๐Ÿ’ป + Kevin Jones
    Kevin Jones

    ๐Ÿ› ๐Ÿ’ป Kevin Poorman
    Kevin Poorman

    ๐Ÿ› Kevin Wayne
    Kevin Wayne

    ๐Ÿ› Kieran Black
    Kieran Black

    ๐Ÿ› Kirill Zubov
    Kirill Zubov

    ๐Ÿ› Kirk Clemens
    Kirk Clemens

    ๐Ÿ’ป ๐Ÿ› Klaus Hartl
    Klaus Hartl

    ๐Ÿ› - Koen Van Looveren
    Koen Van Looveren

    ๐Ÿ› + Koen Van Looveren
    Koen Van Looveren

    ๐Ÿ› Kris Scheibe
    Kris Scheibe

    ๐Ÿ’ป ๐Ÿ› Krystian Dabrowski
    Krystian Dabrowski

    ๐Ÿ› ๐Ÿ’ป Kunal Thanki
    Kunal Thanki

    ๐Ÿ› LaLucid
    LaLucid

    ๐Ÿ’ป Larry Diamond
    Larry Diamond

    ๐Ÿ’ป ๐Ÿ› Lars Knickrehm
    Lars Knickrehm

    ๐Ÿ› - Laurent Bovet
    Laurent Bovet

    ๐Ÿ› ๐Ÿ’ป + Laurent Bovet
    Laurent Bovet

    ๐Ÿ› ๐Ÿ’ป Leo Gutierrez
    Leo Gutierrez

    ๐Ÿ› LiGaOg
    LiGaOg

    ๐Ÿ’ป Liam Sharp
    Liam Sharp

    ๐Ÿ› Lintsi
    Lintsi

    ๐Ÿ› Linus Fernandes
    Linus Fernandes

    ๐Ÿ› Lixon Lookose
    Lixon Lookose

    ๐Ÿ› - Logesh
    Logesh

    ๐Ÿ› + Logesh
    Logesh

    ๐Ÿ› Lorenzo Gabriele
    Lorenzo Gabriele

    ๐Ÿ› Loรฏc Ledoyen
    Loรฏc Ledoyen

    ๐Ÿ› Lucas
    Lucas

    ๐Ÿ› Lucas Silva
    Lucas Silva

    ๐Ÿ› Lucas Soncini
    Lucas Soncini

    ๐Ÿ’ป ๐Ÿ› Luis Alcantar
    Luis Alcantar

    ๐Ÿ’ป - Lukas Grรคf
    Lukas Grรคf

    ๐Ÿ’ป + Lukas Grรคf
    Lukas Grรคf

    ๐Ÿ’ป Lukasz Slonina
    Lukasz Slonina

    ๐Ÿ› Lukebray
    Lukebray

    ๐Ÿ› Lynn
    Lynn

    ๐Ÿ’ป ๐Ÿ› Lyor Goldstein
    Lyor Goldstein

    ๐Ÿ› MCMicS
    MCMicS

    ๐Ÿ› Macarse
    Macarse

    ๐Ÿ› - Machine account for PMD
    Machine account for PMD

    ๐Ÿ’ป + Machine account for PMD
    Machine account for PMD

    ๐Ÿ’ป Maciek Siemczyk
    Maciek Siemczyk

    ๐Ÿ› Maikel Steneker
    Maikel Steneker

    ๐Ÿ’ป ๐Ÿ› Maksim Moiseikin
    Maksim Moiseikin

    ๐Ÿ› Manfred Koch
    Manfred Koch

    ๐Ÿ› Manuel Moya Ferrer
    Manuel Moya Ferrer

    ๐Ÿ’ป ๐Ÿ› Manuel Ryan
    Manuel Ryan

    ๐Ÿ› - Marat Vyshegorodtsev
    Marat Vyshegorodtsev

    ๐Ÿ› + Marat Vyshegorodtsev
    Marat Vyshegorodtsev

    ๐Ÿ› Marcel Hรคrle
    Marcel Hรคrle

    ๐Ÿ› Marcello Fialho
    Marcello Fialho

    ๐Ÿ› Marcin Dฤ…browski
    Marcin Dฤ…browski

    ๐Ÿ’ป Marcin Rataj
    Marcin Rataj

    ๐Ÿ› Marcono1234
    Marcono1234

    ๐Ÿ› Mark Adamcin
    Mark Adamcin

    ๐Ÿ› - Mark Hall
    Mark Hall

    ๐Ÿ’ป ๐Ÿ› + Mark Hall
    Mark Hall

    ๐Ÿ’ป ๐Ÿ› Mark Kolich
    Mark Kolich

    ๐Ÿ› Mark Pritchard
    Mark Pritchard

    ๐Ÿ› Markus Rathgeb
    Markus Rathgeb

    ๐Ÿ› Marquis Wang
    Marquis Wang

    ๐Ÿ› MartGit
    MartGit

    ๐Ÿ› Martin Feldsztejn
    Martin Feldsztejn

    ๐Ÿ› - Martin Lehmann
    Martin Lehmann

    ๐Ÿ› + Martin Lehmann
    Martin Lehmann

    ๐Ÿ› Martin Spamer
    Martin Spamer

    ๐Ÿ› Martin Tarjรกnyi
    Martin Tarjรกnyi

    ๐Ÿ› MatFl
    MatFl

    ๐Ÿ› Mateusz Stefanski
    Mateusz Stefanski

    ๐Ÿ› Mathieu Gouin
    Mathieu Gouin

    ๐Ÿ› MatiasComercio
    MatiasComercio

    ๐Ÿ’ป ๐Ÿ› - Matt Benson
    Matt Benson

    ๐Ÿ› + Matt Benson
    Matt Benson

    ๐Ÿ› Matt De Poorter
    Matt De Poorter

    ๐Ÿ› Matt Hargett
    Matt Hargett

    ๐Ÿ’ป ๐Ÿ’ต Matt Harrah
    Matt Harrah

    ๐Ÿ› Matt Nelson
    Matt Nelson

    ๐Ÿ› Matthew Amos
    Matthew Amos

    ๐Ÿ› Matthew Duggan
    Matthew Duggan

    ๐Ÿ› - Matthew Hall
    Matthew Hall

    ๐Ÿ› + Matthew Hall
    Matthew Hall

    ๐Ÿ› Matthew Rossner
    Matthew Rossner

    ๐Ÿ› Matรญas Fraga
    Matรญas Fraga

    ๐Ÿ’ป ๐Ÿ› Maxime Robert
    Maxime Robert

    ๐Ÿ’ป ๐Ÿ› MetaBF
    MetaBF

    ๐Ÿ› Metin Dagcilar
    Metin Dagcilar

    ๐Ÿ› Michael
    Michael

    ๐Ÿ› - Michael Bell
    Michael Bell

    ๐Ÿ› + Michael Bell
    Michael Bell

    ๐Ÿ› Michael Bernstein
    Michael Bernstein

    ๐Ÿ› Michael Clay
    Michael Clay

    ๐Ÿ› Michael Dombrowski
    Michael Dombrowski

    ๐Ÿ› Michael Hausegger
    Michael Hausegger

    ๐Ÿ› Michael Hoefer
    Michael Hoefer

    ๐Ÿ› Michael Kolesnikov
    Michael Kolesnikov

    ๐Ÿ› - Michael Mรถbius
    Michael Mรถbius

    ๐Ÿ› + Michael Mรถbius
    Michael Mรถbius

    ๐Ÿ› Michael N. Lipp
    Michael N. Lipp

    ๐Ÿ› Michael Pellegrini
    Michael Pellegrini

    ๐Ÿ› Michal Kordas
    Michal Kordas

    ๐Ÿ› Michaล‚ Borek
    Michaล‚ Borek

    ๐Ÿ› Michaล‚ Kuliล„ski
    Michaล‚ Kuliล„ski

    ๐Ÿ› Miguel Nรบรฑez Dรญaz-Montes
    Miguel Nรบรฑez Dรญaz-Montes

    ๐Ÿ› - Mihai Ionut
    Mihai Ionut

    ๐Ÿ› + Mihai Ionut
    Mihai Ionut

    ๐Ÿ› Mikhail Kuchma
    Mikhail Kuchma

    ๐Ÿ› Mirek Hankus
    Mirek Hankus

    ๐Ÿ› Mitch Spano
    Mitch Spano

    ๐Ÿ› Mladjan Gadzic
    Mladjan Gadzic

    ๐Ÿ› MrAngry52
    MrAngry52

    ๐Ÿ› Muminur Choudhury
    Muminur Choudhury

    ๐Ÿ› - Mykhailo Palahuta
    Mykhailo Palahuta

    ๐Ÿ’ป ๐Ÿ› + Mykhailo Palahuta
    Mykhailo Palahuta

    ๐Ÿ’ป ๐Ÿ› Nagendra Kumar Singh
    Nagendra Kumar Singh

    ๐Ÿ› Nahuel Barrios
    Nahuel Barrios

    ๐Ÿ› Nakul Sharma
    Nakul Sharma

    ๐Ÿ› Nathan Braun
    Nathan Braun

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› - Nathanaรซl
    Nathanaรซl

    ๐Ÿ› + Nathanaรซl
    Nathanaรซl

    ๐Ÿ› Naveen
    Naveen

    ๐Ÿ’ป Nazdravi
    Nazdravi

    ๐Ÿ› Neha-Dhonde
    Neha-Dhonde

    ๐Ÿ› Nicholas Doyle
    Nicholas Doyle

    ๐Ÿ› Nick Butcher
    Nick Butcher

    ๐Ÿ› Nico Gallinal
    Nico Gallinal

    ๐Ÿ› - Nicola Dal Maso
    Nicola Dal Maso

    ๐Ÿ› + Nicola Dal Maso
    Nicola Dal Maso

    ๐Ÿ› Nicolas Filotto
    Nicolas Filotto

    ๐Ÿ’ป Nicolas Vervelle
    Nicolas Vervelle

    ๐Ÿ› Nicolas Vuillamy
    Nicolas Vuillamy

    ๐Ÿ“– Nikita Chursin
    Nikita Chursin

    ๐Ÿ› Niklas Baudy
    Niklas Baudy

    ๐Ÿ› Nikolas Havrikov
    Nikolas Havrikov

    ๐Ÿ› - Nilesh Virkar
    Nilesh Virkar

    ๐Ÿ› + Nilesh Virkar
    Nilesh Virkar

    ๐Ÿ› Nimit Patel
    Nimit Patel

    ๐Ÿ› Niranjan Harpale
    Niranjan Harpale

    ๐Ÿ› Nirvik Patel
    Nirvik Patel

    ๐Ÿ’ป Noah Sussman
    Noah Sussman

    ๐Ÿ› Noah0120
    Noah0120

    ๐Ÿ› Noam Tamim
    Noam Tamim

    ๐Ÿ› - Noel Grandin
    Noel Grandin

    ๐Ÿ› + Noel Grandin
    Noel Grandin

    ๐Ÿ› Olaf Haalstra
    Olaf Haalstra

    ๐Ÿ› Oleg Andreych
    Oleg Andreych

    ๐Ÿ’ป ๐Ÿ› Oleg Pavlenko
    Oleg Pavlenko

    ๐Ÿ› Oleksii Dykov
    Oleksii Dykov

    ๐Ÿ’ป ๐Ÿ› Oliver Eikemeier
    Oliver Eikemeier

    ๐Ÿ› Oliver Siegmar
    Oliver Siegmar

    ๐Ÿ’ต - Olivier Parent
    Olivier Parent

    ๐Ÿ’ป ๐Ÿ› + Olivier Parent
    Olivier Parent

    ๐Ÿ’ป ๐Ÿ› Ollie Abbey
    Ollie Abbey

    ๐Ÿ’ป ๐Ÿ› Ondrej Kratochvil
    Ondrej Kratochvil

    ๐Ÿ› OverDrone
    OverDrone

    ๐Ÿ› Ozan Gulle
    Ozan Gulle

    ๐Ÿ’ป ๐Ÿ› PUNEET JAIN
    PUNEET JAIN

    ๐Ÿ› Parbati Bose
    Parbati Bose

    ๐Ÿ› - Paul Berg
    Paul Berg

    ๐Ÿ› + Paul Berg
    Paul Berg

    ๐Ÿ› Paul Guyot
    Paul Guyot

    ๐Ÿ’ป Pavel Bludov
    Pavel Bludov

    ๐Ÿ› Pavel Miฤka
    Pavel Miฤka

    ๐Ÿ› Pedro Nuno Santos
    Pedro Nuno Santos

    ๐Ÿ› Pedro Rijo
    Pedro Rijo

    ๐Ÿ› Pelisse Romain
    Pelisse Romain

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› - Per Abich
    Per Abich

    ๐Ÿ’ป + Per Abich
    Per Abich

    ๐Ÿ’ป Pete Davids
    Pete Davids

    ๐Ÿ› Peter Bruin
    Peter Bruin

    ๐Ÿ› Peter Chittum
    Peter Chittum

    ๐Ÿ’ป ๐Ÿ› Peter Cudmore
    Peter Cudmore

    ๐Ÿ› Peter Kasson
    Peter Kasson

    ๐Ÿ› Peter Kofler
    Peter Kofler

    ๐Ÿ› - Peter Paul Bakker
    Peter Paul Bakker

    ๐Ÿ’ป + Peter Paul Bakker
    Peter Paul Bakker

    ๐Ÿ’ป Peter Rader
    Peter Rader

    ๐Ÿ› Pham Hai Trung
    Pham Hai Trung

    ๐Ÿ› Philip Graf
    Philip Graf

    ๐Ÿ’ป ๐Ÿ› Philip Hachey
    Philip Hachey

    ๐Ÿ› Philippe Ozil
    Philippe Ozil

    ๐Ÿ› Phinehas Artemix
    Phinehas Artemix

    ๐Ÿ› - Phokham Nonava
    Phokham Nonava

    ๐Ÿ› + Phokham Nonava
    Phokham Nonava

    ๐Ÿ› Pim van der Loos
    Pim van der Loos

    ๐Ÿ’ป โš ๏ธ Piotr Szymaล„ski
    Piotr Szymaล„ski

    ๐Ÿ› Piotrek ลปygieล‚o
    Piotrek ลปygieล‚o

    ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– Pranay Jaiswal
    Pranay Jaiswal

    ๐Ÿ› Prasad Kamath
    Prasad Kamath

    ๐Ÿ› Prasanna
    Prasanna

    ๐Ÿ› - Presh-AR
    Presh-AR

    ๐Ÿ› + Presh-AR
    Presh-AR

    ๐Ÿ› Puneet1726
    Puneet1726

    ๐Ÿ› RBRi
    RBRi

    ๐Ÿ› Rafael Cortรชs
    Rafael Cortรชs

    ๐Ÿ› RaheemShaik999
    RaheemShaik999

    ๐Ÿ› RajeshR
    RajeshR

    ๐Ÿ’ป ๐Ÿ› Ramachandra Mohan
    Ramachandra Mohan

    ๐Ÿ› - Ramel0921
    Ramel0921

    ๐Ÿ› + Ramel0921
    Ramel0921

    ๐Ÿ› Raquel Pau
    Raquel Pau

    ๐Ÿ› Ravikiran Janardhana
    Ravikiran Janardhana

    ๐Ÿ› Reda Benhemmouche
    Reda Benhemmouche

    ๐Ÿ› Reinhard Schiedermeier
    Reinhard Schiedermeier

    ๐Ÿ› Renato Oliveira
    Renato Oliveira

    ๐Ÿ’ป ๐Ÿ› Rich DiCroce
    Rich DiCroce

    ๐Ÿ› - Richard Corfield
    Richard Corfield

    ๐Ÿ’ป + Richard Corfield
    Richard Corfield

    ๐Ÿ’ป Richard Corfield
    Richard Corfield

    ๐Ÿ› ๐Ÿ’ป Riot R1cket
    Riot R1cket

    ๐Ÿ› Rishabh Jain
    Rishabh Jain

    ๐Ÿ› RishabhDeep Singh
    RishabhDeep Singh

    ๐Ÿ› Rob Baillie
    Rob Baillie

    ๐Ÿ› Robbie Martinus
    Robbie Martinus

    ๐Ÿ’ป ๐Ÿ› - Robert Henry
    Robert Henry

    ๐Ÿ› + Robert Henry
    Robert Henry

    ๐Ÿ› Robert Mihaly
    Robert Mihaly

    ๐Ÿ› Robert Painsi
    Robert Painsi

    ๐Ÿ› Robert Russell
    Robert Russell

    ๐Ÿ› Robert Sรถsemann
    Robert Sรถsemann

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ› Robert Whitebit
    Robert Whitebit

    ๐Ÿ› Robin Richtsfeld
    Robin Richtsfeld

    ๐Ÿ› - Robin Stocker
    Robin Stocker

    ๐Ÿ’ป ๐Ÿ› + Robin Stocker
    Robin Stocker

    ๐Ÿ’ป ๐Ÿ› Robin Wils
    Robin Wils

    ๐Ÿ› RochusOest
    RochusOest

    ๐Ÿ› Rodolfo Noviski
    Rodolfo Noviski

    ๐Ÿ› Rodrigo Casara
    Rodrigo Casara

    ๐Ÿ› Rodrigo Fernandes
    Rodrigo Fernandes

    ๐Ÿ› Roman Salvador
    Roman Salvador

    ๐Ÿ’ป ๐Ÿ› - Ronald Blaschke
    Ronald Blaschke

    ๐Ÿ› + Ronald Blaschke
    Ronald Blaschke

    ๐Ÿ› Rรณbert Papp
    Rรณbert Papp

    ๐Ÿ› Saikat Sengupta
    Saikat Sengupta

    ๐Ÿ› Saksham Handu
    Saksham Handu

    ๐Ÿ› Saladoc
    Saladoc

    ๐Ÿ› Salesforce Bob Lightning
    Salesforce Bob Lightning

    ๐Ÿ› Sam Carlberg
    Sam Carlberg

    ๐Ÿ› - Sascha Riemer
    Sascha Riemer

    ๐Ÿ› + Sascha Riemer
    Sascha Riemer

    ๐Ÿ› Sashko
    Sashko

    ๐Ÿ’ป Satoshi Kubo
    Satoshi Kubo

    ๐Ÿ› Scott Kennedy
    Scott Kennedy

    ๐Ÿ› Scott Wells
    Scott Wells

    ๐Ÿ› ๐Ÿ’ป Scrates1
    Scrates1

    ๐Ÿ› ๐Ÿ’ป Scrsloota
    Scrsloota

    ๐Ÿ’ป - Sebastian Bรถgl
    Sebastian Bรถgl

    ๐Ÿ› + Sebastian Bรถgl
    Sebastian Bรถgl

    ๐Ÿ› Sebastian Davids
    Sebastian Davids

    ๐Ÿ› Sebastian Schuberth
    Sebastian Schuberth

    ๐Ÿ› Sebastian Schwarz
    Sebastian Schwarz

    ๐Ÿ› Seren
    Seren

    ๐Ÿ› ๐Ÿ’ป Sergey Gorbaty
    Sergey Gorbaty

    ๐Ÿ› Sergey Kozlov
    Sergey Kozlov

    ๐Ÿ› - Sergey Yanzin
    Sergey Yanzin

    ๐Ÿ’ป ๐Ÿ› + Sergey Yanzin
    Sergey Yanzin

    ๐Ÿ’ป ๐Ÿ› Seth Wilcox
    Seth Wilcox

    ๐Ÿ’ป Shai Bennathan
    Shai Bennathan

    ๐Ÿ› ๐Ÿ’ป Shubham
    Shubham

    ๐Ÿ’ป ๐Ÿ› Simon Abykov
    Simon Abykov

    ๐Ÿ’ป ๐Ÿ› Simon Xiao
    Simon Xiao

    ๐Ÿ› Srinivasan Venkatachalam
    Srinivasan Venkatachalam

    ๐Ÿ› - Stanislav Gromov
    Stanislav Gromov

    ๐Ÿ› + Stanislav Gromov
    Stanislav Gromov

    ๐Ÿ› Stanislav Myachenkov
    Stanislav Myachenkov

    ๐Ÿ’ป Stefan Birkner
    Stefan Birkner

    ๐Ÿ› Stefan Bohn
    Stefan Bohn

    ๐Ÿ› Stefan Endrullis
    Stefan Endrullis

    ๐Ÿ› Stefan Klรถss-Schuster
    Stefan Klรถss-Schuster

    ๐Ÿ› Stefan Wolf
    Stefan Wolf

    ๐Ÿ› - Stephan H. Wissel
    Stephan H. Wissel

    ๐Ÿ› + Stephan H. Wissel
    Stephan H. Wissel

    ๐Ÿ› Stephen
    Stephen

    ๐Ÿ› Stephen Carter
    Stephen Carter

    ๐Ÿ› Stephen Friedrich
    Stephen Friedrich

    ๐Ÿ› Steve Babula
    Steve Babula

    ๐Ÿ’ป Steven Stearns
    Steven Stearns

    ๐Ÿ› ๐Ÿ’ป Stexxe
    Stexxe

    ๐Ÿ› - Stian Lรฅgstad
    Stian Lรฅgstad

    ๐Ÿ› + Stian Lรฅgstad
    Stian Lรฅgstad

    ๐Ÿ› StuartClayton5
    StuartClayton5

    ๐Ÿ› Supun Arunoda
    Supun Arunoda

    ๐Ÿ› Suren Abrahamyan
    Suren Abrahamyan

    ๐Ÿ› Suvashri
    Suvashri

    ๐Ÿ“– SwatiBGupta1110
    SwatiBGupta1110

    ๐Ÿ› SyedThoufich
    SyedThoufich

    ๐Ÿ› - Szymon Sasin
    Szymon Sasin

    ๐Ÿ› + Szymon Sasin
    Szymon Sasin

    ๐Ÿ› T-chuangxin
    T-chuangxin

    ๐Ÿ› TERAI Atsuhiro
    TERAI Atsuhiro

    ๐Ÿ› TIOBE Software
    TIOBE Software

    ๐Ÿ’ป ๐Ÿ› Tarush Singh
    Tarush Singh

    ๐Ÿ’ป Taylor Smock
    Taylor Smock

    ๐Ÿ› Techeira Damiรกn
    Techeira Damiรกn

    ๐Ÿ’ป ๐Ÿ› - Ted Husted
    Ted Husted

    ๐Ÿ› + Ted Husted
    Ted Husted

    ๐Ÿ› TehBakker
    TehBakker

    ๐Ÿ› The Gitter Badger
    The Gitter Badger

    ๐Ÿ› Theodoor
    Theodoor

    ๐Ÿ› Thiago Henrique Hรผpner
    Thiago Henrique Hรผpner

    ๐Ÿ› Thibault Meyer
    Thibault Meyer

    ๐Ÿ› Thomas Gรผttler
    Thomas Gรผttler

    ๐Ÿ› - Thomas Jones-Low
    Thomas Jones-Low

    ๐Ÿ› + Thomas Jones-Low
    Thomas Jones-Low

    ๐Ÿ› Thomas Smith
    Thomas Smith

    ๐Ÿ’ป ๐Ÿ› ThrawnCA
    ThrawnCA

    ๐Ÿ› Thu Vo
    Thu Vo

    ๐Ÿ› Thunderforge
    Thunderforge

    ๐Ÿ’ป ๐Ÿ› Tim van der Lippe
    Tim van der Lippe

    ๐Ÿ› Tobias Weimer
    Tobias Weimer

    ๐Ÿ’ป ๐Ÿ› - Tom Copeland
    Tom Copeland

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– + Tom Copeland
    Tom Copeland

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– Tom Daly
    Tom Daly

    ๐Ÿ› Tomas
    Tomas

    ๐Ÿ› Tomer Figenblat
    Tomer Figenblat

    ๐Ÿ› Tomi De Lucca
    Tomi De Lucca

    ๐Ÿ’ป ๐Ÿ› Tony
    Tony

    ๐Ÿ“– Torsten Kleiber
    Torsten Kleiber

    ๐Ÿ› - TrackerSB
    TrackerSB

    ๐Ÿ› + TrackerSB
    TrackerSB

    ๐Ÿ› Tyson Stewart
    Tyson Stewart

    ๐Ÿ› Ullrich Hafner
    Ullrich Hafner

    ๐Ÿ› Utku Cuhadaroglu
    Utku Cuhadaroglu

    ๐Ÿ’ป ๐Ÿ› Valentin Brandl
    Valentin Brandl

    ๐Ÿ› Valeria
    Valeria

    ๐Ÿ› Valery Yatsynovich
    Valery Yatsynovich

    ๐Ÿ“– - Vasily Anisimov
    Vasily Anisimov

    ๐Ÿ› + Vasily Anisimov
    Vasily Anisimov

    ๐Ÿ› Vedant Chokshi
    Vedant Chokshi

    ๐Ÿ› Vibhor Goyal
    Vibhor Goyal

    ๐Ÿ› Vickenty Fesunov
    Vickenty Fesunov

    ๐Ÿ› Victor Noรซl
    Victor Noรซl

    ๐Ÿ› Vincent Galloy
    Vincent Galloy

    ๐Ÿ’ป Vincent HUYNH
    Vincent HUYNH

    ๐Ÿ› - Vincent Maurin
    Vincent Maurin

    ๐Ÿ› + Vincent Maurin
    Vincent Maurin

    ๐Ÿ› Vincent Privat
    Vincent Privat

    ๐Ÿ› Vishhwas
    Vishhwas

    ๐Ÿ› Vishv_Android
    Vishv_Android

    ๐Ÿ› Vitaly
    Vitaly

    ๐Ÿ› Vitaly Polonetsky
    Vitaly Polonetsky

    ๐Ÿ› Vojtech Polivka
    Vojtech Polivka

    ๐Ÿ› - Vsevolod Zholobov
    Vsevolod Zholobov

    ๐Ÿ› + Vsevolod Zholobov
    Vsevolod Zholobov

    ๐Ÿ› Vyom Yadav
    Vyom Yadav

    ๐Ÿ’ป Wang Shidong
    Wang Shidong

    ๐Ÿ› Waqas Ahmed
    Waqas Ahmed

    ๐Ÿ› Wayne J. Earl
    Wayne J. Earl

    ๐Ÿ› Wchenghui
    Wchenghui

    ๐Ÿ› Wener
    Wener

    ๐Ÿ’ป - Will Winder
    Will Winder

    ๐Ÿ› + Will Winder
    Will Winder

    ๐Ÿ› William Brockhus
    William Brockhus

    ๐Ÿ’ป ๐Ÿ› Wilson Kurniawan
    Wilson Kurniawan

    ๐Ÿ› Wim Deblauwe
    Wim Deblauwe

    ๐Ÿ› Woongsik Choi
    Woongsik Choi

    ๐Ÿ› XenoAmess
    XenoAmess

    ๐Ÿ’ป ๐Ÿ› Yang
    Yang

    ๐Ÿ’ป - YaroslavTER
    YaroslavTER

    ๐Ÿ› + YaroslavTER
    YaroslavTER

    ๐Ÿ› Yasar Shaikh
    Yasar Shaikh

    ๐Ÿ’ป Young Chan
    Young Chan

    ๐Ÿ’ป ๐Ÿ› YuJin Kim
    YuJin Kim

    ๐Ÿ› Yuri Dolzhenko
    Yuri Dolzhenko

    ๐Ÿ› Yurii Dubinka
    Yurii Dubinka

    ๐Ÿ› Zoltan Farkas
    Zoltan Farkas

    ๐Ÿ› - Zustin
    Zustin

    ๐Ÿ› + Zustin
    Zustin

    ๐Ÿ› aaronhurst-google
    aaronhurst-google

    ๐Ÿ› ๐Ÿ’ป alexmodis
    alexmodis

    ๐Ÿ› andreoss
    andreoss

    ๐Ÿ› andrey81inmd
    andrey81inmd

    ๐Ÿ’ป ๐Ÿ› anicoara
    anicoara

    ๐Ÿ› arunprasathav
    arunprasathav

    ๐Ÿ› - asiercamara
    asiercamara

    ๐Ÿ› + asiercamara
    asiercamara

    ๐Ÿ› astillich-igniti
    astillich-igniti

    ๐Ÿ’ป avesolovksyy
    avesolovksyy

    ๐Ÿ› avishvat
    avishvat

    ๐Ÿ› avivmu
    avivmu

    ๐Ÿ› axelbarfod1
    axelbarfod1

    ๐Ÿ› b-3-n
    b-3-n

    ๐Ÿ› - balbhadra9
    balbhadra9

    ๐Ÿ› + balbhadra9
    balbhadra9

    ๐Ÿ› base23de
    base23de

    ๐Ÿ› bergander
    bergander

    ๐Ÿ› ๐Ÿ’ป berkam
    berkam

    ๐Ÿ’ป ๐Ÿ› breizh31
    breizh31

    ๐Ÿ› caesarkim
    caesarkim

    ๐Ÿ› carolyujing
    carolyujing

    ๐Ÿ› - cbfiddle
    cbfiddle

    ๐Ÿ› + cbfiddle
    cbfiddle

    ๐Ÿ› cesares-basilico
    cesares-basilico

    ๐Ÿ› chrite
    chrite

    ๐Ÿ› ciufudean
    ciufudean

    ๐Ÿ“– cobratbq
    cobratbq

    ๐Ÿ› coladict
    coladict

    ๐Ÿ› cosmoJFH
    cosmoJFH

    ๐Ÿ› - cristalp
    cristalp

    ๐Ÿ› + cristalp
    cristalp

    ๐Ÿ› crunsk
    crunsk

    ๐Ÿ› cwholmes
    cwholmes

    ๐Ÿ› cyberjj999
    cyberjj999

    ๐Ÿ› cyw3
    cyw3

    ๐Ÿ› ๐Ÿ“– d1ss0nanz
    d1ss0nanz

    ๐Ÿ› dague1
    dague1

    ๐Ÿ“– - dalizi007
    dalizi007

    ๐Ÿ’ป + dalizi007
    dalizi007

    ๐Ÿ’ป danbrycefairsailcom
    danbrycefairsailcom

    ๐Ÿ› dariansanity
    dariansanity

    ๐Ÿ› darrenmiliband
    darrenmiliband

    ๐Ÿ› davidburstrom
    davidburstrom

    ๐Ÿ› dbirkman-paloalto
    dbirkman-paloalto

    ๐Ÿ› deepak-patra
    deepak-patra

    ๐Ÿ› - dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› + dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› dinesh150
    dinesh150

    ๐Ÿ› diziaq
    diziaq

    ๐Ÿ› dreaminpast123
    dreaminpast123

    ๐Ÿ› duanyanan
    duanyanan

    ๐Ÿ› dutt-sanjay
    dutt-sanjay

    ๐Ÿ› duursma
    duursma

    ๐Ÿ’ป - dylanleung
    dylanleung

    ๐Ÿ› + dylanleung
    dylanleung

    ๐Ÿ› dzeigler
    dzeigler

    ๐Ÿ› eant60
    eant60

    ๐Ÿ› ekkirala
    ekkirala

    ๐Ÿ› emersonmoura
    emersonmoura

    ๐Ÿ› emouty
    emouty

    ๐Ÿ’ป ๐Ÿ› eugenepugach
    eugenepugach

    ๐Ÿ› - fairy
    fairy

    ๐Ÿ› + fairy
    fairy

    ๐Ÿ› filiprafalowicz
    filiprafalowicz

    ๐Ÿ’ป flxbl-io
    flxbl-io

    ๐Ÿ’ต foxmason
    foxmason

    ๐Ÿ› frankegabor
    frankegabor

    ๐Ÿ› frankl
    frankl

    ๐Ÿ› freafrea
    freafrea

    ๐Ÿ› - fsapatin
    fsapatin

    ๐Ÿ› + fsapatin
    fsapatin

    ๐Ÿ› gearsethenry
    gearsethenry

    ๐Ÿ› gracia19
    gracia19

    ๐Ÿ› gudzpoz
    gudzpoz

    ๐Ÿ› guo fei
    guo fei

    ๐Ÿ› gurmsc5
    gurmsc5

    ๐Ÿ› gwilymatgearset
    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ› - haigsn
    haigsn

    ๐Ÿ› + haigsn
    haigsn

    ๐Ÿ› hemanshu070
    hemanshu070

    ๐Ÿ› henrik242
    henrik242

    ๐Ÿ› hongpuwu
    hongpuwu

    ๐Ÿ› hvbtup
    hvbtup

    ๐Ÿ’ป ๐Ÿ› igniti GmbH
    igniti GmbH

    ๐Ÿ› ilovezfs
    ilovezfs

    ๐Ÿ› - imax-erik
    imax-erik

    ๐Ÿ› + imax-erik
    imax-erik

    ๐Ÿ› itaigilo
    itaigilo

    ๐Ÿ› jakivey32
    jakivey32

    ๐Ÿ› jbennett2091
    jbennett2091

    ๐Ÿ› jcamerin
    jcamerin

    ๐Ÿ› jkeener1
    jkeener1

    ๐Ÿ› jmetertea
    jmetertea

    ๐Ÿ› - johnra2
    johnra2

    ๐Ÿ’ป + johnra2
    johnra2

    ๐Ÿ’ป johnzhao9
    johnzhao9

    ๐Ÿ› josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ› kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ› karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“– karwer
    karwer

    ๐Ÿ› kaulonline
    kaulonline

    ๐Ÿ› - kdaemonv
    kdaemonv

    ๐Ÿ› + kdaemonv
    kdaemonv

    ๐Ÿ› kdebski85
    kdebski85

    ๐Ÿ› ๐Ÿ’ป kenji21
    kenji21

    ๐Ÿ’ป ๐Ÿ› kfranic
    kfranic

    ๐Ÿ› khalidkh
    khalidkh

    ๐Ÿ› koalalam
    koalalam

    ๐Ÿ› krzyk
    krzyk

    ๐Ÿ› - lasselindqvist
    lasselindqvist

    ๐Ÿ› + lasselindqvist
    lasselindqvist

    ๐Ÿ› lgemeinhardt
    lgemeinhardt

    ๐Ÿ› lihuaib
    lihuaib

    ๐Ÿ› liqingjun123
    liqingjun123

    ๐Ÿ› lonelyma1021
    lonelyma1021

    ๐Ÿ› lpeddy
    lpeddy

    ๐Ÿ› lujiefsi
    lujiefsi

    ๐Ÿ’ป - lukelukes
    lukelukes

    ๐Ÿ’ป + lukelukes
    lukelukes

    ๐Ÿ’ป lyriccoder
    lyriccoder

    ๐Ÿ› marcelmore
    marcelmore

    ๐Ÿ› matchbox
    matchbox

    ๐Ÿ› matthiaskraaz
    matthiaskraaz

    ๐Ÿ› meandonlyme
    meandonlyme

    ๐Ÿ› mikesive
    mikesive

    ๐Ÿ› - milossesic
    milossesic

    ๐Ÿ› + milossesic
    milossesic

    ๐Ÿ› mluckam
    mluckam

    ๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
    mohan-chinnappan-n

    ๐Ÿ’ป mriddell95
    mriddell95

    ๐Ÿ› mrlzh
    mrlzh

    ๐Ÿ› msloan
    msloan

    ๐Ÿ› mucharlaravalika
    mucharlaravalika

    ๐Ÿ› - mvenneman
    mvenneman

    ๐Ÿ› + mvenneman
    mvenneman

    ๐Ÿ› nareshl119
    nareshl119

    ๐Ÿ› nicolas-harraudeau-sonarsource
    nicolas-harraudeau-sonarsource

    ๐Ÿ› noerremark
    noerremark

    ๐Ÿ› novsirion
    novsirion

    ๐Ÿ› nwcm
    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
    oggboy

    ๐Ÿ› - oinume
    oinume

    ๐Ÿ› + oinume
    oinume

    ๐Ÿ› orimarko
    orimarko

    ๐Ÿ’ป ๐Ÿ› pablogomez2197
    pablogomez2197

    ๐Ÿ› pacvz
    pacvz

    ๐Ÿ’ป pallavi agarwal
    pallavi agarwal

    ๐Ÿ› parksungrin
    parksungrin

    ๐Ÿ› patpatpat123
    patpatpat123

    ๐Ÿ› - patriksevallius
    patriksevallius

    ๐Ÿ› + patriksevallius
    patriksevallius

    ๐Ÿ› pbrajesh1
    pbrajesh1

    ๐Ÿ› phoenix384
    phoenix384

    ๐Ÿ› piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป plan3d
    plan3d

    ๐Ÿ› poojasix
    poojasix

    ๐Ÿ› prabhushrikant
    prabhushrikant

    ๐Ÿ› - pujitha8783
    pujitha8783

    ๐Ÿ› + pujitha8783
    pujitha8783

    ๐Ÿ› r-r-a-j
    r-r-a-j

    ๐Ÿ› raghujayjunk
    raghujayjunk

    ๐Ÿ› rajeshveera
    rajeshveera

    ๐Ÿ› rajeswarreddy88
    rajeswarreddy88

    ๐Ÿ› recdevs
    recdevs

    ๐Ÿ› reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ› - rijkt
    rijkt

    ๐Ÿ› + rijkt
    rijkt

    ๐Ÿ› rillig-tk
    rillig-tk

    ๐Ÿ› rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ› rnveach
    rnveach

    ๐Ÿ› rxmicro
    rxmicro

    ๐Ÿ› ryan-gustafson
    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ› sabi0
    sabi0

    ๐Ÿ› - scais
    scais

    ๐Ÿ› + scais
    scais

    ๐Ÿ› schosin
    schosin

    ๐Ÿ› screamingfrog
    screamingfrog

    ๐Ÿ’ต sebbASF
    sebbASF

    ๐Ÿ› sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป shilko2013
    shilko2013

    ๐Ÿ› shiomiyan
    shiomiyan

    ๐Ÿ“– - simeonKondr
    simeonKondr

    ๐Ÿ› + simeonKondr
    simeonKondr

    ๐Ÿ› snajberk
    snajberk

    ๐Ÿ› sniperrifle2004
    sniperrifle2004

    ๐Ÿ› snuyanzin
    snuyanzin

    ๐Ÿ› ๐Ÿ’ป soloturn
    soloturn

    ๐Ÿ› soyodream
    soyodream

    ๐Ÿ› sratz
    sratz

    ๐Ÿ› - stonio
    stonio

    ๐Ÿ› + stonio
    stonio

    ๐Ÿ› sturton
    sturton

    ๐Ÿ’ป ๐Ÿ› sudharmohan
    sudharmohan

    ๐Ÿ› suruchidawar
    suruchidawar

    ๐Ÿ› svenfinitiv
    svenfinitiv

    ๐Ÿ› szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป tashiscool
    tashiscool

    ๐Ÿ› - test-git-hook
    test-git-hook

    ๐Ÿ› + test-git-hook
    test-git-hook

    ๐Ÿ› testation21
    testation21

    ๐Ÿ’ป ๐Ÿ› thanosa
    thanosa

    ๐Ÿ› tiandiyixian
    tiandiyixian

    ๐Ÿ› tobwoerk
    tobwoerk

    ๐Ÿ› tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป trentchilders
    trentchilders

    ๐Ÿ› - triandicAnt
    triandicAnt

    ๐Ÿ› + triandicAnt
    triandicAnt

    ๐Ÿ› trishul14
    trishul14

    ๐Ÿ› tsui
    tsui

    ๐Ÿ› wangzitom12306
    wangzitom12306

    ๐Ÿ› winhkey
    winhkey

    ๐Ÿ› witherspore
    witherspore

    ๐Ÿ› wjljack
    wjljack

    ๐Ÿ› - wuchiuwong
    wuchiuwong

    ๐Ÿ› + wuchiuwong
    wuchiuwong

    ๐Ÿ› xingsong
    xingsong

    ๐Ÿ› xioayuge
    xioayuge

    ๐Ÿ› xnYi9wRezm
    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ› xuanuy
    xuanuy

    ๐Ÿ› xyf0921
    xyf0921

    ๐Ÿ› yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› - yasuharu-sato
    yasuharu-sato

    ๐Ÿ› + yasuharu-sato
    yasuharu-sato

    ๐Ÿ› zenglian
    zenglian

    ๐Ÿ› zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› zh3ng
    zh3ng

    ๐Ÿ› zt_soft
    zt_soft

    ๐Ÿ› ztt79
    ztt79

    ๐Ÿ› zzzzfeng
    zzzzfeng

    ๐Ÿ› - รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› + รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› ไปป่ดตๆฐ
    ไปป่ดตๆฐ

    ๐Ÿ› + ๅคฉ็ƒญๅƒ่ฅฟ็“œ
    ๅคฉ็ƒญๅƒ่ฅฟ็“œ

    ๐Ÿ› ่Œ…ๅปถๅฎ‰
    ่Œ…ๅปถๅฎ‰

    ๐Ÿ’ป From 634a5252860d7e966109eef62ae3cb0973c6b491 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 14 Nov 2024 17:07:37 +0100 Subject: [PATCH 0220/1962] [html] Test for a closing tag when determining node positions Fixes #5322 --- docs/pages/release_notes.md | 2 ++ .../pmd/lang/html/ast/LineNumbers.java | 11 ++++---- .../pmd/lang/html/cpd/HtmlCpdLexerTest.java | 9 +++++++ .../lang/html/cpd/testdata/InvalidHtml.html | 7 +++++ .../lang/html/cpd/testdata/InvalidHtml.txt | 22 +++++++++++++++ .../pmd/lang/html/cpd/testdata/MetaTag.html | 9 +++++++ .../pmd/lang/html/cpd/testdata/MetaTag.txt | 27 +++++++++++++++++++ 7 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 pmd-html/src/test/resources/net/sourceforge/pmd/lang/html/cpd/testdata/InvalidHtml.html create mode 100644 pmd-html/src/test/resources/net/sourceforge/pmd/lang/html/cpd/testdata/InvalidHtml.txt create mode 100644 pmd-html/src/test/resources/net/sourceforge/pmd/lang/html/cpd/testdata/MetaTag.html create mode 100644 pmd-html/src/test/resources/net/sourceforge/pmd/lang/html/cpd/testdata/MetaTag.txt diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 5fa3ac04b69..3a1b90322b9 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -20,6 +20,8 @@ This is a {{ site.pmd.release_type }} release. * java * [#5293](https://github.com/pmd/pmd/issues/5293): \[java] Deadlock when executing PMD in multiple threads * [#5324](https://github.com/pmd/pmd/issues/5324): \[java] Issue with type inference of nested lambdas +* html + * [5322](https://github.com/pmd/pmd/issues/5322): \[html] CPD throws exception on when HTML file is missing closing tag ### ๐Ÿšจ API Changes diff --git a/pmd-html/src/main/java/net/sourceforge/pmd/lang/html/ast/LineNumbers.java b/pmd-html/src/main/java/net/sourceforge/pmd/lang/html/ast/LineNumbers.java index 423b2772fba..5419b30e3a4 100644 --- a/pmd-html/src/main/java/net/sourceforge/pmd/lang/html/ast/LineNumbers.java +++ b/pmd-html/src/main/java/net/sourceforge/pmd/lang/html/ast/LineNumbers.java @@ -50,15 +50,14 @@ private int determineLocation(AbstractHtmlNode n, int index) { nextIndex = determineLocation((AbstractHtmlNode) child, nextIndex); } - // autoclosing element, eg - boolean isAutoClose = n.getNumChildren() == 0 - && n instanceof ASTHtmlElement - // nextIndex is up to the closing > at this point - && htmlString.startsWith("/>", nextIndex - 2); + // explicitly closing element, eg. + boolean hasCloseElement = n instanceof ASTHtmlElement + // nextIndex is up to the closing tag at this point + && htmlString.startsWith("", nextIndex); if (n instanceof ASTHtmlDocument) { nextIndex = htmlString.length(); - } else if (n instanceof ASTHtmlElement && !isAutoClose) { + } else if (n instanceof ASTHtmlElement && hasCloseElement) { nextIndex += 2 + n.getXPathNodeName().length() + 1; // } else if (n instanceof ASTHtmlComment) { nextIndex += 4 + 3; // diff --git a/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/cpd/HtmlCpdLexerTest.java b/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/cpd/HtmlCpdLexerTest.java index 04db5c6152d..088837d2ce0 100644 --- a/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/cpd/HtmlCpdLexerTest.java +++ b/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/cpd/HtmlCpdLexerTest.java @@ -21,4 +21,13 @@ void testSimpleHtmlFile() { doTest("SimpleHtmlFile"); } + @Test + void invalidHtml() { + doTest("InvalidHtml"); + } + + @Test + void metaTag() { + doTest("MetaTag"); + } } diff --git a/pmd-html/src/test/resources/net/sourceforge/pmd/lang/html/cpd/testdata/InvalidHtml.html b/pmd-html/src/test/resources/net/sourceforge/pmd/lang/html/cpd/testdata/InvalidHtml.html new file mode 100644 index 00000000000..73acc68e1df --- /dev/null +++ b/pmd-html/src/test/resources/net/sourceforge/pmd/lang/html/cpd/testdata/InvalidHtml.html @@ -0,0 +1,7 @@ + + + + +

    + + diff --git a/pmd-html/src/test/resources/net/sourceforge/pmd/lang/html/cpd/testdata/InvalidHtml.txt b/pmd-html/src/test/resources/net/sourceforge/pmd/lang/html/cpd/testdata/InvalidHtml.txt new file mode 100644 index 00000000000..2cc097ffd22 --- /dev/null +++ b/pmd-html/src/test/resources/net/sourceforge/pmd/lang/html/cpd/testdata/InvalidHtml.txt @@ -0,0 +1,22 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [#document] 1 8 + [#doctype] 1 15 + [\n] 16 16 +L2 + [html] 1 7 + [\n] 17 17 +L3 + [body] 1 7 + [\n] 7 7 +L4 + [#comment] 1 36 + [\n] 37 37 +L5 + [div] 1 22 + [\n] 22 22 +L6 + [\n] 8 8 +L7 + [\n] 8 8 +EOF diff --git a/pmd-html/src/test/resources/net/sourceforge/pmd/lang/html/cpd/testdata/MetaTag.html b/pmd-html/src/test/resources/net/sourceforge/pmd/lang/html/cpd/testdata/MetaTag.html new file mode 100644 index 00000000000..d8a96810a88 --- /dev/null +++ b/pmd-html/src/test/resources/net/sourceforge/pmd/lang/html/cpd/testdata/MetaTag.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/pmd-html/src/test/resources/net/sourceforge/pmd/lang/html/cpd/testdata/MetaTag.txt b/pmd-html/src/test/resources/net/sourceforge/pmd/lang/html/cpd/testdata/MetaTag.txt new file mode 100644 index 00000000000..0547e117b80 --- /dev/null +++ b/pmd-html/src/test/resources/net/sourceforge/pmd/lang/html/cpd/testdata/MetaTag.txt @@ -0,0 +1,27 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [#document] 1 8 + [#doctype] 1 15 + [\n] 16 16 +L2 + [html] 1 7 + [\n] 17 17 +L3 + [head] 1 7 + [\n ] 7 4 +L4 + [#comment] 5 66 + [\n ] 67 4 +L5 + [meta] 5 27 + [\n] 27 27 +L6 + [\n] 8 8 +L7 + [body] 1 7 + [\n] 7 7 +L8 + [\n] 8 8 +L9 + [\n] 8 8 +EOF From 61eb116833573ce78ca3d1eb6bdf1fb1892f8685 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 14 Nov 2024 17:39:07 +0100 Subject: [PATCH 0221/1962] [java] PreserveStackTrace - consider instance type patterns Fixes #5318 --- docs/pages/release_notes.md | 2 + .../bestpractices/PreserveStackTraceRule.java | 73 ++++++++++++------- .../bestpractices/xml/PreserveStackTrace.xml | 31 ++++++++ 3 files changed, 78 insertions(+), 28 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 5fa3ac04b69..ea37011a0fa 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -20,6 +20,8 @@ This is a {{ site.pmd.release_type }} release. * java * [#5293](https://github.com/pmd/pmd/issues/5293): \[java] Deadlock when executing PMD in multiple threads * [#5324](https://github.com/pmd/pmd/issues/5324): \[java] Issue with type inference of nested lambdas +* java-bestpractices + * [#5318](https://github.com/pmd/pmd/issues/5318): \[java] PreserveStackTraceRule: false-positive on Pattern Matching with instanceof ### ๐Ÿšจ API Changes diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/PreserveStackTraceRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/PreserveStackTraceRule.java index 03d0d9faea2..229e8a5da03 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/PreserveStackTraceRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/PreserveStackTraceRule.java @@ -4,11 +4,10 @@ package net.sourceforge.pmd.lang.java.rule.bestpractices; +import java.util.Collections; import java.util.HashSet; import java.util.Set; -import org.checkerframework.checker.nullness.qual.NonNull; - import net.sourceforge.pmd.lang.ast.NodeStream; import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr.ASTNamedReferenceExpr; import net.sourceforge.pmd.lang.java.ast.ASTCastExpression; @@ -17,13 +16,17 @@ import net.sourceforge.pmd.lang.java.ast.ASTConstructorCall; import net.sourceforge.pmd.lang.java.ast.ASTExpression; import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTInfixExpression; import net.sourceforge.pmd.lang.java.ast.ASTInitializer; import net.sourceforge.pmd.lang.java.ast.ASTList; import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; +import net.sourceforge.pmd.lang.java.ast.ASTPatternExpression; import net.sourceforge.pmd.lang.java.ast.ASTThrowStatement; import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTTypePattern; import net.sourceforge.pmd.lang.java.ast.ASTVariableAccess; import net.sourceforge.pmd.lang.java.ast.ASTVariableId; +import net.sourceforge.pmd.lang.java.ast.BinaryOp; import net.sourceforge.pmd.lang.java.ast.InvocationNode; import net.sourceforge.pmd.lang.java.ast.JavaNode; import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; @@ -64,7 +67,7 @@ public Object visit(ASTCatchClause catchStmt, Object data) { for (ASTThrowStatement throwStatement : catchStmt.getBody().descendants(ASTThrowStatement.class)) { ASTExpression thrownExpr = throwStatement.getExpr(); - if (!exprConsumesException(exceptionParam, thrownExpr, true)) { + if (!exprConsumesException(Collections.singleton(exceptionParam), thrownExpr, true)) { asCtx(data).addViolation(thrownExpr, exceptionParam.getName()); } } @@ -72,25 +75,39 @@ public Object visit(ASTCatchClause catchStmt, Object data) { return null; } - private boolean exprConsumesException(ASTVariableId exceptionParam, ASTExpression expr, boolean mayBeSelf) { + private boolean exprConsumesException(Set exceptionParams, ASTExpression expr, boolean mayBeSelf) { if (expr instanceof ASTConstructorCall) { // new Exception(e) - return ctorConsumesException(exceptionParam, (ASTConstructorCall) expr); + return ctorConsumesException(exceptionParams, (ASTConstructorCall) expr); } else if (expr instanceof ASTMethodCall) { - return methodConsumesException(exceptionParam, (ASTMethodCall) expr); + return methodConsumesException(exceptionParams, (ASTMethodCall) expr); } else if (expr instanceof ASTCastExpression) { ASTExpression innermost = JavaAstUtils.peelCasts(expr); - return exprConsumesException(exceptionParam, innermost, mayBeSelf); + return exprConsumesException(exceptionParams, innermost, mayBeSelf); } else if (expr instanceof ASTConditionalExpression) { ASTConditionalExpression ternary = (ASTConditionalExpression) expr; - return exprConsumesException(exceptionParam, ternary.getThenBranch(), mayBeSelf) - && exprConsumesException(exceptionParam, ternary.getElseBranch(), mayBeSelf); + Set possibleExceptionParams = new HashSet<>(exceptionParams); + + // Peel out a type pattern variable in case this conditional is an instanceof pattern + NodeStream.of(ternary.getCondition()) + .filterIs(ASTInfixExpression.class) + .filterMatching(ASTInfixExpression::getOperator, BinaryOp.INSTANCEOF) + .map(ASTInfixExpression::getRightOperand) + .filterIs(ASTPatternExpression.class) + .map(ASTPatternExpression::getPattern) + .filterIs(ASTTypePattern.class) + .map(ASTTypePattern::getVarId) + .firstOpt() + .ifPresent(possibleExceptionParams::add); + + return exprConsumesException(possibleExceptionParams, ternary.getThenBranch(), mayBeSelf) + && exprConsumesException(possibleExceptionParams, ternary.getElseBranch(), mayBeSelf); } else if (expr instanceof ASTVariableAccess) { JVariableSymbol referencedSym = ((ASTVariableAccess) expr).getReferencedSym(); @@ -99,7 +116,7 @@ private boolean exprConsumesException(ASTVariableId exceptionParam, ASTExpressio } ASTVariableId decl = referencedSym.tryGetNode(); - if (decl == exceptionParam) { + if (exceptionParams.contains(decl)) { return mayBeSelf; } else if (decl == null || decl.isFormalParameter() || decl.isField()) { return false; @@ -113,16 +130,16 @@ private boolean exprConsumesException(ASTVariableId exceptionParam, ASTExpressio // if any of the initializer and usages consumes the variable, // answer true. - if (exprConsumesException(exceptionParam, decl.getInitializer(), mayBeSelf)) { + if (exprConsumesException(exceptionParams, decl.getInitializer(), mayBeSelf)) { return true; } for (ASTNamedReferenceExpr usage : decl.getLocalUsages()) { - if (assignmentRhsConsumesException(exceptionParam, decl, usage)) { + if (assignmentRhsConsumesException(exceptionParams, decl, usage)) { return true; } - if (JavaAstUtils.followingCallChain(usage).any(it -> consumesExceptionNonRecursive(exceptionParam, it))) { + if (JavaAstUtils.followingCallChain(usage).any(it -> consumesExceptionNonRecursive(exceptionParams, it))) { return true; } } @@ -134,7 +151,7 @@ private boolean exprConsumesException(ASTVariableId exceptionParam, ASTExpressio } } - private boolean assignmentRhsConsumesException(ASTVariableId exceptionParam, ASTVariableId lhsVariable, ASTNamedReferenceExpr usage) { + private boolean assignmentRhsConsumesException(Set exceptionParams, ASTVariableId lhsVariable, ASTNamedReferenceExpr usage) { if (usage.getIndexInParent() == 0) { ASTExpression assignmentRhs = JavaAstUtils.getOtherOperandIfInAssignmentExpr(usage); boolean rhsIsSelfReferential = @@ -142,25 +159,25 @@ private boolean assignmentRhsConsumesException(ASTVariableId exceptionParam, AST .descendantsOrSelf() .filterIs(ASTVariableAccess.class) .any(it -> JavaAstUtils.isReferenceToVar(it, lhsVariable.getSymbol())); - return !rhsIsSelfReferential && exprConsumesException(exceptionParam, assignmentRhs, true); + return !rhsIsSelfReferential && exprConsumesException(exceptionParams, assignmentRhs, true); } return false; } - private boolean ctorConsumesException(ASTVariableId exceptionParam, ASTConstructorCall ctorCall) { - return ctorCall.isAnonymousClass() && callsInitCauseInAnonInitializer(exceptionParam, ctorCall) - || anArgumentConsumesException(exceptionParam, ctorCall); + private boolean ctorConsumesException(Set exceptionParams, ASTConstructorCall ctorCall) { + return ctorCall.isAnonymousClass() && callsInitCauseInAnonInitializer(exceptionParams, ctorCall) + || anArgumentConsumesException(exceptionParams, ctorCall); } - private boolean consumesExceptionNonRecursive(ASTVariableId exceptionParam, ASTExpression expr) { + private boolean consumesExceptionNonRecursive(Set exceptionParam, ASTExpression expr) { if (expr instanceof ASTConstructorCall) { return ctorConsumesException(exceptionParam, (ASTConstructorCall) expr); } return expr instanceof InvocationNode && anArgumentConsumesException(exceptionParam, (InvocationNode) expr); } - private boolean methodConsumesException(ASTVariableId exceptionParam, ASTMethodCall call) { - if (anArgumentConsumesException(exceptionParam, call)) { + private boolean methodConsumesException(Set exceptionParams, ASTMethodCall call) { + if (anArgumentConsumesException(exceptionParams, call)) { return true; } ASTExpression qualifier = call.getQualifier(); @@ -168,24 +185,24 @@ private boolean methodConsumesException(ASTVariableId exceptionParam, ASTMethodC return false; } boolean mayBeSelf = ALLOWED_GETTERS.anyMatch(call); - return exprConsumesException(exceptionParam, qualifier, mayBeSelf); + return exprConsumesException(exceptionParams, qualifier, mayBeSelf); } - private boolean callsInitCauseInAnonInitializer(ASTVariableId exceptionParam, ASTConstructorCall ctorCall) { + private boolean callsInitCauseInAnonInitializer(Set exceptionParams, ASTConstructorCall ctorCall) { return NodeStream.of(ctorCall.getAnonymousClassDeclaration()) .flatMap(ASTTypeDeclaration::getDeclarations) .map(NodeStream.asInstanceOf(ASTFieldDeclaration.class, ASTInitializer.class)) .descendants().filterIs(ASTMethodCall.class) - .any(it -> isInitCauseWithTargetInArg(exceptionParam, it)); + .any(it -> isInitCauseWithTargetInArg(exceptionParams, it)); } - private boolean isInitCauseWithTargetInArg(ASTVariableId exceptionSym, JavaNode expr) { - return INIT_CAUSE.matchesCall(expr) && anArgumentConsumesException(exceptionSym, (ASTMethodCall) expr); + private boolean isInitCauseWithTargetInArg(Set exceptionParams, JavaNode expr) { + return INIT_CAUSE.matchesCall(expr) && anArgumentConsumesException(exceptionParams, (ASTMethodCall) expr); } - private boolean anArgumentConsumesException(@NonNull ASTVariableId exceptionParam, InvocationNode thrownExpr) { + private boolean anArgumentConsumesException(Set exceptionParams, InvocationNode thrownExpr) { for (ASTExpression arg : ASTList.orEmptyStream(thrownExpr.getArguments())) { - if (exprConsumesException(exceptionParam, arg, true)) { + if (exprConsumesException(exceptionParams, arg, true)) { return true; } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/PreserveStackTrace.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/PreserveStackTrace.xml index 5292c61d647..637b6dffa6e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/PreserveStackTrace.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/PreserveStackTrace.xml @@ -1168,4 +1168,35 @@ public class Foo { ]]> + + #5318 [java] PreserveStackTraceRule: false-positive on Pattern Matching with instanceof + 0 + formatExceptionHandler = e -> { e.printStackTrace(); }; +} +]]> + From bf388d7fd059aec33d38f6b2088470c04ea1aea6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 14 Nov 2024 17:27:45 +0100 Subject: [PATCH 0222/1962] Propagate unknown type better when mref is unresolved --- .../types/internal/infer/ExprCheckHelper.java | 7 ++ .../java/types/internal/infer/ExprOps.java | 1 - .../lang/java/types/TypesTreeDumpTest.java | 5 ++ .../pmd/lang/java/types/AstTestUtil.kt | 1 + .../infer/UnresolvedTypesRecoveryTest.kt | 38 +++++++++ .../bestpractices/xml/UnusedPrivateMethod.xml | 41 ++++++++++ .../types/dumptests/UnresolvedThings.java | 16 ++++ .../java/types/dumptests/UnresolvedThings.txt | 80 +++++++++++++++++++ 8 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/UnresolvedThings.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/UnresolvedThings.txt diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java index dc8955fcb09..f6521426e2b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java @@ -335,6 +335,13 @@ private boolean isMethodRefCompatible(@NonNull JClassType functionalItf, MethodR checker.checkExprConstraint(infCtx, capture(r2), r); } completeMethodRefInference(mref, nonWildcard, fun, exactMethod, true); + } else if (TypeOps.isUnresolved(mref.getTypeToSearch())) { + // Then this is neither an exact nor inexact method ref, + // we just don't know what it is. + + // The return values of the mref are assimilated to an (*unknown*) type. + checker.checkExprConstraint(infCtx, ts.UNKNOWN, fun.getReturnType()); + completeMethodRefInference(mref, nonWildcard, fun, ts.UNRESOLVED_METHOD, false); } else { // Otherwise, the method reference is inexact, and: diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java index 8ea1cee3da4..a04c91c55fd 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java @@ -227,7 +227,6 @@ static boolean isPertinentToApplicability(ExprMirror arg, JMethodSig m, JTypeMir } } else { JClassType enclosing = mref.getEnclosingType(); - accessible = mref.getTypeToSearch() .streamMethods(TypeOps.accessibleMethodFilter(mref.getMethodName(), enclosing.getSymbol())) .collect(OverloadSet.collectMostSpecific(enclosing)); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/TypesTreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/TypesTreeDumpTest.java index 9b8baaeca66..50d22c663d2 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/TypesTreeDumpTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/TypesTreeDumpTest.java @@ -55,6 +55,11 @@ void testNestedLambdasAndMethodCalls() { doTest("NestedLambdasAndMethodCalls"); } + @Test + void testUnresolvedThings() { + doTest("UnresolvedThings"); + } + @Override protected @NonNull String normalize(@NonNull String str) { return super.normalize(str) diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/AstTestUtil.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/AstTestUtil.kt index 1545c93f7ea..e5c04d1ac59 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/AstTestUtil.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/AstTestUtil.kt @@ -21,6 +21,7 @@ fun JavaNode.declaredMethodSignatures(): List = methodDeclarations() fun JavaNode.methodCalls(): DescendantNodeStream = descendants(ASTMethodCall::class.java) fun JavaNode.firstMethodCall() = methodCalls().crossFindBoundaries().firstOrThrow() +fun JavaNode.firstMethodCall(name: String) = methodCalls().crossFindBoundaries().filter { it.methodName == name }.firstOrThrow() fun JavaNode.ctorCalls(): DescendantNodeStream = descendants(ASTConstructorCall::class.java) fun JavaNode.firstCtorCall() = ctorCalls().crossFindBoundaries().firstOrThrow() diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt index 24d7ec3c04e..45c13cf5691 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt @@ -664,4 +664,42 @@ class C { fooToInt.referencedMethod.symbol shouldBe toIntFun } } + + parserTest("Type inference should not resolve UNKNOWN bounded types to Object #5329") { + + val (acu, _) = parser.parseWithTypeInferenceSpy( + """ + import java.util.ArrayList; + import java.util.List; + import java.util.stream.Stream; + import java.util.stream.Collectors; + + class Foo { + public Item methodA(List loads) { + List items = new ArrayList<>(); + loads.stream() + // Here this collect call should have type + // Map<(*unknown*), List<*Item>> + // ie, key is unknown, not Object. + .collect(Collectors.groupingBy(Item::getValue)) + .forEach((a, b) -> items.add(buildItem(a, b))); + } + + private SummaryDto.ItemDto buildItem(BigDecimal a, List b) { + return SummaryDto.ItemDto.builder().build(); + } + } + """ + ) + + val collect = acu.firstMethodCall("collect") + val buildItem = acu.firstMethodCall("buildItem") + val (_, buildItemDecl) = acu.methodDeclarations().toList { it.symbol } + val (itemT) = acu.descendants(ASTClassType::class.java).toList { it.typeMirror } + + acu.withTypeDsl { + collect shouldHaveType java.util.Map::class[ts.UNKNOWN, java.util.List::class[itemT]] + buildItem.methodType.symbol shouldBe buildItemDecl + } + } }) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index 2a743036a69..1a6dd1488dd 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2177,4 +2177,45 @@ public class ObtainViaTest { record Library(Collection books) {} ]]> + + #5324 UnusedPrivateMethod with unresolved types + 0 + { + try { + return registerUser(email, firstName, lastName); + } catch (Exception e) { + throw new IllegalStateException("Failed to register user for " + email, e); + } + }); + // ... + return user; + } + + private User registerUser(String email, String firstName, String lastName) throws Exception { + // register user logic here... + } + } + ]]> + + + #5329 UnusedPrivateMethod with unresolved types + 0 + items = new ArrayList<>(); + loads.stream() + .collect(Collectors.groupingBy(Item::getValue)) + .forEach((a, b) -> items.add(buildItem(a, b))); + } + + private SummaryDto.ItemDto buildItem(BigDecimal a, List b) { + return SummaryDto.ItemDto.builder().build(); + } + } + ]]> + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/UnresolvedThings.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/UnresolvedThings.java new file mode 100644 index 00000000000..83eb9d62b4d --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/UnresolvedThings.java @@ -0,0 +1,16 @@ +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; +import java.util.stream.Collectors; +class Foo { + public User methodA(List loads) { + List items = new ArrayList<>(); + loads.stream() + .collect(Collectors.groupingBy(Item::getValue)) + .forEach((a, b) -> items.add(buildItem(a, b))); + } + + private SummaryDto.ItemDto buildItem(BigDecimal a, List b) { + return SummaryDto.ItemDto.builder().build(); + } +} \ No newline at end of file diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/UnresolvedThings.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/UnresolvedThings.txt new file mode 100644 index 00000000000..32f1f2643e5 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/UnresolvedThings.txt @@ -0,0 +1,80 @@ ++- CompilationUnit[] + +- ImportDeclaration[] + +- ImportDeclaration[] + +- ImportDeclaration[] + +- ImportDeclaration[] + +- ClassDeclaration[@TypeMirror = "Foo"] + +- ModifierList[] + +- ClassBody[] + +- MethodDeclaration[@Name = "methodA"] + | +- ModifierList[] + | +- ClassType[@TypeMirror = "*User"] + | +- FormalParameters[] + | | +- FormalParameter[@TypeMirror = "java.util.List<*Item>"] + | | +- ModifierList[] + | | +- ClassType[@TypeMirror = "java.util.List<*Item>"] + | | | +- TypeArguments[] + | | | +- ClassType[@TypeMirror = "*Item"] + | | +- VariableId[@Name = "loads", @TypeMirror = "java.util.List<*Item>"] + | +- Block[] + | +- LocalVariableDeclaration[] + | | +- ModifierList[] + | | +- ClassType[@TypeMirror = "java.util.List<*SummaryDto.ItemDto>"] + | | | +- TypeArguments[] + | | | +- ClassType[@TypeMirror = "*SummaryDto.ItemDto"] + | | +- VariableDeclarator[] + | | +- VariableId[@Name = "items", @TypeMirror = "java.util.List<*SummaryDto.ItemDto>"] + | | +- ConstructorCall[@Failed = false, @Function = "java.util.ArrayList<*SummaryDto.ItemDto>.new() -> java.util.ArrayList<*SummaryDto.ItemDto>", @MethodName = "new", @TypeMirror = "java.util.ArrayList<*SummaryDto.ItemDto>", @Unchecked = false, @VarargsCall = false] + | | +- ClassType[@TypeMirror = "java.util.ArrayList"] + | | | +- TypeArguments[] + | | +- ArgumentList[] + | +- ExpressionStatement[] + | +- MethodCall[@Failed = false, @Function = "java.util.Map<(*unknown*), java.util.List<*Item>>.forEach(java.util.function.BiConsumer>) -> void", @MethodName = "forEach", @TypeMirror = "void", @Unchecked = false, @VarargsCall = false] + | +- MethodCall[@Failed = false, @Function = "java.util.stream.Stream<*Item>. collect(java.util.stream.Collector>>) -> java.util.Map<(*unknown*), java.util.List<*Item>>", @MethodName = "collect", @TypeMirror = "java.util.Map<(*unknown*), java.util.List<*Item>>", @Unchecked = false, @VarargsCall = false] + | | +- MethodCall[@Failed = false, @Function = "java.util.Collection<*Item>.stream() -> java.util.stream.Stream<*Item>", @MethodName = "stream", @TypeMirror = "java.util.stream.Stream<*Item>", @Unchecked = false, @VarargsCall = false] + | | | +- VariableAccess[@Name = "loads", @TypeMirror = "java.util.List<*Item>"] + | | | +- ArgumentList[] + | | +- ArgumentList[] + | | +- MethodCall[@Failed = false, @Function = "java.util.stream.Collectors. groupingBy(java.util.function.Function) -> java.util.stream.Collector<*Item, java.lang.Object, java.util.Map<(*unknown*), java.util.List<*Item>>>", @MethodName = "groupingBy", @TypeMirror = "java.util.stream.Collector<*Item, java.lang.Object, java.util.Map<(*unknown*), java.util.List<*Item>>>", @Unchecked = false, @VarargsCall = false] + | | +- TypeExpression[@TypeMirror = "java.util.stream.Collectors"] + | | | +- ClassType[@TypeMirror = "java.util.stream.Collectors"] + | | +- ArgumentList[] + | | +- MethodReference[@TypeMirror = "java.util.function.Function<*Item, (*unknown*)>"] + | | +- AmbiguousName[@TypeMirror = "(*unknown*)"] + | +- ArgumentList[] + | +- LambdaExpression[@TypeMirror = "java.util.function.BiConsumer<(*unknown*), java.util.List<*Item>>"] + | +- LambdaParameterList[] + | | +- LambdaParameter[@TypeMirror = "(*unknown*)"] + | | | +- ModifierList[] + | | | +- VariableId[@Name = "a", @TypeMirror = "(*unknown*)"] + | | +- LambdaParameter[@TypeMirror = "java.util.List<*Item>"] + | | +- ModifierList[] + | | +- VariableId[@Name = "b", @TypeMirror = "java.util.List<*Item>"] + | +- MethodCall[@Failed = false, @Function = "java.util.List<*SummaryDto.ItemDto>.add(*SummaryDto.ItemDto) -> boolean", @MethodName = "add", @TypeMirror = "boolean", @Unchecked = false, @VarargsCall = false] + | +- VariableAccess[@Name = "items", @TypeMirror = "java.util.List<*SummaryDto.ItemDto>"] + | +- ArgumentList[] + | +- MethodCall[@Failed = false, @Function = "Foo.buildItem(*BigDecimal, java.util.List<*Item>) -> *SummaryDto.ItemDto", @MethodName = "buildItem", @TypeMirror = "*SummaryDto.ItemDto", @Unchecked = false, @VarargsCall = false] + | +- ArgumentList[] + | +- VariableAccess[@Name = "a", @TypeMirror = "(*unknown*)"] + | +- VariableAccess[@Name = "b", @TypeMirror = "java.util.List<*Item>"] + +- MethodDeclaration[@Name = "buildItem"] + +- ModifierList[] + +- ClassType[@TypeMirror = "*SummaryDto.ItemDto"] + +- FormalParameters[] + | +- FormalParameter[@TypeMirror = "*BigDecimal"] + | | +- ModifierList[] + | | +- ClassType[@TypeMirror = "*BigDecimal"] + | | +- VariableId[@Name = "a", @TypeMirror = "*BigDecimal"] + | +- FormalParameter[@TypeMirror = "java.util.List<*Item>"] + | +- ModifierList[] + | +- ClassType[@TypeMirror = "java.util.List<*Item>"] + | | +- TypeArguments[] + | | +- ClassType[@TypeMirror = "*Item"] + | +- VariableId[@Name = "b", @TypeMirror = "java.util.List<*Item>"] + +- Block[] + +- ReturnStatement[] + +- MethodCall[@Failed = true, @Function = "(*unknown*).(*unknown method*)() -> (*unknown*)", @MethodName = "build", @TypeMirror = "(*unknown*)", @Unchecked = false, @VarargsCall = false] + +- MethodCall[@Failed = true, @Function = "(*unknown*).(*unknown method*)() -> (*unknown*)", @MethodName = "builder", @TypeMirror = "(*unknown*)", @Unchecked = false, @VarargsCall = false] + | +- AmbiguousName[@TypeMirror = "(*unknown*)"] + | +- ArgumentList[] + +- ArgumentList[] From bb729e02f4a6f472fb732688024cf941f2c32908 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 14 Nov 2024 17:39:32 +0100 Subject: [PATCH 0223/1962] Add @VitaliiIevtushenko as a contributor --- .all-contributorsrc | 9 + docs/pages/pmd/projectdocs/credits.md | 238 +++++++++++++------------- 2 files changed, 129 insertions(+), 118 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 95ebc05d6e1..171741bf0bc 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7865,6 +7865,15 @@ "contributions": [ "code" ] + }, + { + "login": "VitaliiIevtushenko", + "name": "Vitalii Yevtushenko", + "avatar_url": "https://avatars.githubusercontent.com/u/11145125?v=4", + "profile": "https://github.com/VitaliiIevtushenko", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 9497ea73780..6f7d9255aae 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -350,769 +350,771 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d JJengility
    JJengility

    ๐Ÿ› Jake Hemmerle
    Jake Hemmerle

    ๐Ÿ› + Jakub Dupak
    Jakub Dupak

    ๐Ÿ’ป James Harrison
    James Harrison

    ๐Ÿ› ๐Ÿ’ป Jamie Bisotti
    Jamie Bisotti

    ๐Ÿ› Jan
    Jan

    ๐Ÿ› Jan Aertgeerts
    Jan Aertgeerts

    ๐Ÿ’ป ๐Ÿ› - Jan Brรผmmer
    Jan Brรผmmer

    ๐Ÿ› + Jan Brรผmmer
    Jan Brรผmmer

    ๐Ÿ› Jan Tล™รญska
    Jan Tล™รญska

    ๐Ÿ› Jan-Lukas Else
    Jan-Lukas Else

    ๐Ÿ› Jason Qiu
    Jason Qiu

    ๐Ÿ’ป ๐Ÿ“– Jason Williams
    Jason Williams

    ๐Ÿ› Javier Spagnoletti
    Javier Spagnoletti

    ๐Ÿ› Jean-Paul Mayer
    Jean-Paul Mayer

    ๐Ÿ› - Jean-Simon Larochelle
    Jean-Simon Larochelle

    ๐Ÿ› + Jean-Simon Larochelle
    Jean-Simon Larochelle

    ๐Ÿ› Jeff Bartolotta
    Jeff Bartolotta

    ๐Ÿ’ป ๐Ÿ› Jeff Hube
    Jeff Hube

    ๐Ÿ’ป ๐Ÿ› Jeff Jensen
    Jeff Jensen

    ๐Ÿ› Jeff May
    Jeff May

    ๐Ÿ› Jens Gerdes
    Jens Gerdes

    ๐Ÿ› Jeroen Borgers
    Jeroen Borgers

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข - Jeroen Meijer
    Jeroen Meijer

    ๐Ÿ› + Jeroen Meijer
    Jeroen Meijer

    ๐Ÿ› Jeroen van Wilgenburg
    Jeroen van Wilgenburg

    ๐Ÿ“– Jerome Russ
    Jerome Russ

    ๐Ÿ› JerritEic
    JerritEic

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Jiri Pejchal
    Jiri Pejchal

    ๐Ÿ› Jithin Sunny
    Jithin Sunny

    ๐Ÿ› Jiล™รญ ล korpil
    Jiล™รญ ล korpil

    ๐Ÿ› - Joao Machado
    Joao Machado

    ๐Ÿ› + Joao Machado
    Joao Machado

    ๐Ÿ› Jochen Krauss
    Jochen Krauss

    ๐Ÿ› Johan Hammar
    Johan Hammar

    ๐Ÿ› John Karp
    John Karp

    ๐Ÿ› John Zhang
    John Zhang

    ๐Ÿ› John-Teng
    John-Teng

    ๐Ÿ’ป ๐Ÿ› Jon Moroney
    Jon Moroney

    ๐Ÿ’ป ๐Ÿ› - Jonas Geiregat
    Jonas Geiregat

    ๐Ÿ› + Jonas Geiregat
    Jonas Geiregat

    ๐Ÿ› Jonas KeรŸler
    Jonas KeรŸler

    ๐Ÿ› Jonathan Wiesel
    Jonathan Wiesel

    ๐Ÿ’ป ๐Ÿ› Jordan
    Jordan

    ๐Ÿ› Jordi Llach
    Jordi Llach

    ๐Ÿ› Jorge Solรณrzano
    Jorge Solรณrzano

    ๐Ÿ› JorneVL
    JorneVL

    ๐Ÿ› - Jose Palafox
    Jose Palafox

    ๐Ÿ› + Jose Palafox
    Jose Palafox

    ๐Ÿ› Jose Stovall
    Jose Stovall

    ๐Ÿ› Joseph
    Joseph

    ๐Ÿ’ป Joseph Heenan
    Joseph Heenan

    ๐Ÿ› Josh Feingold
    Josh Feingold

    ๐Ÿ’ป ๐Ÿ› Josh Holthaus
    Josh Holthaus

    ๐Ÿ› Joshua S Arquilevich
    Joshua S Arquilevich

    ๐Ÿ› - Joรฃo Dinis Ferreira
    Joรฃo Dinis Ferreira

    ๐Ÿ“– + Joรฃo Dinis Ferreira
    Joรฃo Dinis Ferreira

    ๐Ÿ“– Joรฃo Ferreira
    Joรฃo Ferreira

    ๐Ÿ’ป ๐Ÿ› Joรฃo Pedro Schmitt
    Joรฃo Pedro Schmitt

    ๐Ÿ› Juan Martรญn Sotuyo Dodero
    Juan Martรญn Sotuyo Dodero

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง Juan Pablo Civile
    Juan Pablo Civile

    ๐Ÿ› Julian Voronetsky
    Julian Voronetsky

    ๐Ÿ› Julien
    Julien

    ๐Ÿ› - Julius
    Julius

    ๐Ÿ› + Julius
    Julius

    ๐Ÿ› JustPRV
    JustPRV

    ๐Ÿ› Justin Stroud
    Justin Stroud

    ๐Ÿ’ป Jรถrn Huxhorn
    Jรถrn Huxhorn

    ๐Ÿ› KThompso
    KThompso

    ๐Ÿ› Kai Amundsen
    Kai Amundsen

    ๐Ÿ› Karel Vervaeke
    Karel Vervaeke

    ๐Ÿ› - Karl-Andero Mere
    Karl-Andero Mere

    ๐Ÿ› + Karl-Andero Mere
    Karl-Andero Mere

    ๐Ÿ› Karl-Philipp Richter
    Karl-Philipp Richter

    ๐Ÿ› Karsten Silz
    Karsten Silz

    ๐Ÿ› Kazuma Watanabe
    Kazuma Watanabe

    ๐Ÿ› Kev
    Kev

    ๐Ÿ› Keve Mรผller
    Keve Mรผller

    ๐Ÿ› Kevin Guerra
    Kevin Guerra

    ๐Ÿ’ป - Kevin Jones
    Kevin Jones

    ๐Ÿ› ๐Ÿ’ป + Kevin Jones
    Kevin Jones

    ๐Ÿ› ๐Ÿ’ป Kevin Poorman
    Kevin Poorman

    ๐Ÿ› Kevin Wayne
    Kevin Wayne

    ๐Ÿ› Kieran Black
    Kieran Black

    ๐Ÿ› Kirill Zubov
    Kirill Zubov

    ๐Ÿ› Kirk Clemens
    Kirk Clemens

    ๐Ÿ’ป ๐Ÿ› Klaus Hartl
    Klaus Hartl

    ๐Ÿ› - Koen Van Looveren
    Koen Van Looveren

    ๐Ÿ› + Koen Van Looveren
    Koen Van Looveren

    ๐Ÿ› Kris Scheibe
    Kris Scheibe

    ๐Ÿ’ป ๐Ÿ› Krystian Dabrowski
    Krystian Dabrowski

    ๐Ÿ› ๐Ÿ’ป Kunal Thanki
    Kunal Thanki

    ๐Ÿ› LaLucid
    LaLucid

    ๐Ÿ’ป Larry Diamond
    Larry Diamond

    ๐Ÿ’ป ๐Ÿ› Lars Knickrehm
    Lars Knickrehm

    ๐Ÿ› - Laurent Bovet
    Laurent Bovet

    ๐Ÿ› ๐Ÿ’ป + Laurent Bovet
    Laurent Bovet

    ๐Ÿ› ๐Ÿ’ป Leo Gutierrez
    Leo Gutierrez

    ๐Ÿ› LiGaOg
    LiGaOg

    ๐Ÿ’ป Liam Sharp
    Liam Sharp

    ๐Ÿ› Lintsi
    Lintsi

    ๐Ÿ› Linus Fernandes
    Linus Fernandes

    ๐Ÿ› Lixon Lookose
    Lixon Lookose

    ๐Ÿ› - Logesh
    Logesh

    ๐Ÿ› + Logesh
    Logesh

    ๐Ÿ› Lorenzo Gabriele
    Lorenzo Gabriele

    ๐Ÿ› Loรฏc Ledoyen
    Loรฏc Ledoyen

    ๐Ÿ› Lucas
    Lucas

    ๐Ÿ› Lucas Silva
    Lucas Silva

    ๐Ÿ› Lucas Soncini
    Lucas Soncini

    ๐Ÿ’ป ๐Ÿ› Luis Alcantar
    Luis Alcantar

    ๐Ÿ’ป - Lukas Grรคf
    Lukas Grรคf

    ๐Ÿ’ป + Lukas Grรคf
    Lukas Grรคf

    ๐Ÿ’ป Lukasz Slonina
    Lukasz Slonina

    ๐Ÿ› Lukebray
    Lukebray

    ๐Ÿ› Lynn
    Lynn

    ๐Ÿ’ป ๐Ÿ› Lyor Goldstein
    Lyor Goldstein

    ๐Ÿ› MCMicS
    MCMicS

    ๐Ÿ› Macarse
    Macarse

    ๐Ÿ› - Machine account for PMD
    Machine account for PMD

    ๐Ÿ’ป + Machine account for PMD
    Machine account for PMD

    ๐Ÿ’ป Maciek Siemczyk
    Maciek Siemczyk

    ๐Ÿ› Maikel Steneker
    Maikel Steneker

    ๐Ÿ’ป ๐Ÿ› Maksim Moiseikin
    Maksim Moiseikin

    ๐Ÿ› Manfred Koch
    Manfred Koch

    ๐Ÿ› Manuel Moya Ferrer
    Manuel Moya Ferrer

    ๐Ÿ’ป ๐Ÿ› Manuel Ryan
    Manuel Ryan

    ๐Ÿ› - Marat Vyshegorodtsev
    Marat Vyshegorodtsev

    ๐Ÿ› + Marat Vyshegorodtsev
    Marat Vyshegorodtsev

    ๐Ÿ› Marcel Hรคrle
    Marcel Hรคrle

    ๐Ÿ› Marcello Fialho
    Marcello Fialho

    ๐Ÿ› Marcin Dฤ…browski
    Marcin Dฤ…browski

    ๐Ÿ’ป Marcin Rataj
    Marcin Rataj

    ๐Ÿ› Marcono1234
    Marcono1234

    ๐Ÿ› Mark Adamcin
    Mark Adamcin

    ๐Ÿ› - Mark Hall
    Mark Hall

    ๐Ÿ’ป ๐Ÿ› + Mark Hall
    Mark Hall

    ๐Ÿ’ป ๐Ÿ› Mark Kolich
    Mark Kolich

    ๐Ÿ› Mark Pritchard
    Mark Pritchard

    ๐Ÿ› Markus Rathgeb
    Markus Rathgeb

    ๐Ÿ› Marquis Wang
    Marquis Wang

    ๐Ÿ› MartGit
    MartGit

    ๐Ÿ› Martin Feldsztejn
    Martin Feldsztejn

    ๐Ÿ› - Martin Lehmann
    Martin Lehmann

    ๐Ÿ› + Martin Lehmann
    Martin Lehmann

    ๐Ÿ› Martin Spamer
    Martin Spamer

    ๐Ÿ› Martin Tarjรกnyi
    Martin Tarjรกnyi

    ๐Ÿ› MatFl
    MatFl

    ๐Ÿ› Mateusz Stefanski
    Mateusz Stefanski

    ๐Ÿ› Mathieu Gouin
    Mathieu Gouin

    ๐Ÿ› MatiasComercio
    MatiasComercio

    ๐Ÿ’ป ๐Ÿ› - Matt Benson
    Matt Benson

    ๐Ÿ› + Matt Benson
    Matt Benson

    ๐Ÿ› Matt De Poorter
    Matt De Poorter

    ๐Ÿ› Matt Hargett
    Matt Hargett

    ๐Ÿ’ป ๐Ÿ’ต Matt Harrah
    Matt Harrah

    ๐Ÿ› Matt Nelson
    Matt Nelson

    ๐Ÿ› Matthew Amos
    Matthew Amos

    ๐Ÿ› Matthew Duggan
    Matthew Duggan

    ๐Ÿ› - Matthew Hall
    Matthew Hall

    ๐Ÿ› + Matthew Hall
    Matthew Hall

    ๐Ÿ› Matthew Rossner
    Matthew Rossner

    ๐Ÿ› Matรญas Fraga
    Matรญas Fraga

    ๐Ÿ’ป ๐Ÿ› Maxime Robert
    Maxime Robert

    ๐Ÿ’ป ๐Ÿ› MetaBF
    MetaBF

    ๐Ÿ› Metin Dagcilar
    Metin Dagcilar

    ๐Ÿ› Michael
    Michael

    ๐Ÿ› - Michael Bell
    Michael Bell

    ๐Ÿ› + Michael Bell
    Michael Bell

    ๐Ÿ› Michael Bernstein
    Michael Bernstein

    ๐Ÿ› Michael Clay
    Michael Clay

    ๐Ÿ› Michael Dombrowski
    Michael Dombrowski

    ๐Ÿ› Michael Hausegger
    Michael Hausegger

    ๐Ÿ› Michael Hoefer
    Michael Hoefer

    ๐Ÿ› Michael Kolesnikov
    Michael Kolesnikov

    ๐Ÿ› - Michael Mรถbius
    Michael Mรถbius

    ๐Ÿ› + Michael Mรถbius
    Michael Mรถbius

    ๐Ÿ› Michael N. Lipp
    Michael N. Lipp

    ๐Ÿ› Michael Pellegrini
    Michael Pellegrini

    ๐Ÿ› Michal Kordas
    Michal Kordas

    ๐Ÿ› Michaล‚ Borek
    Michaล‚ Borek

    ๐Ÿ› Michaล‚ Kuliล„ski
    Michaล‚ Kuliล„ski

    ๐Ÿ› Miguel Nรบรฑez Dรญaz-Montes
    Miguel Nรบรฑez Dรญaz-Montes

    ๐Ÿ› - Mihai Ionut
    Mihai Ionut

    ๐Ÿ› + Mihai Ionut
    Mihai Ionut

    ๐Ÿ› Mikhail Kuchma
    Mikhail Kuchma

    ๐Ÿ› Mirek Hankus
    Mirek Hankus

    ๐Ÿ› Mitch Spano
    Mitch Spano

    ๐Ÿ› Mladjan Gadzic
    Mladjan Gadzic

    ๐Ÿ› MrAngry52
    MrAngry52

    ๐Ÿ› Muminur Choudhury
    Muminur Choudhury

    ๐Ÿ› - Mykhailo Palahuta
    Mykhailo Palahuta

    ๐Ÿ’ป ๐Ÿ› + Mykhailo Palahuta
    Mykhailo Palahuta

    ๐Ÿ’ป ๐Ÿ› Nagendra Kumar Singh
    Nagendra Kumar Singh

    ๐Ÿ› Nahuel Barrios
    Nahuel Barrios

    ๐Ÿ› Nakul Sharma
    Nakul Sharma

    ๐Ÿ› Nathan Braun
    Nathan Braun

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› - Nathanaรซl
    Nathanaรซl

    ๐Ÿ› + Nathanaรซl
    Nathanaรซl

    ๐Ÿ› Naveen
    Naveen

    ๐Ÿ’ป Nazdravi
    Nazdravi

    ๐Ÿ› Neha-Dhonde
    Neha-Dhonde

    ๐Ÿ› Nicholas Doyle
    Nicholas Doyle

    ๐Ÿ› Nick Butcher
    Nick Butcher

    ๐Ÿ› Nico Gallinal
    Nico Gallinal

    ๐Ÿ› - Nicola Dal Maso
    Nicola Dal Maso

    ๐Ÿ› + Nicola Dal Maso
    Nicola Dal Maso

    ๐Ÿ› Nicolas Filotto
    Nicolas Filotto

    ๐Ÿ’ป Nicolas Vervelle
    Nicolas Vervelle

    ๐Ÿ› Nicolas Vuillamy
    Nicolas Vuillamy

    ๐Ÿ“– Nikita Chursin
    Nikita Chursin

    ๐Ÿ› Niklas Baudy
    Niklas Baudy

    ๐Ÿ› Nikolas Havrikov
    Nikolas Havrikov

    ๐Ÿ› - Nilesh Virkar
    Nilesh Virkar

    ๐Ÿ› + Nilesh Virkar
    Nilesh Virkar

    ๐Ÿ› Nimit Patel
    Nimit Patel

    ๐Ÿ› Niranjan Harpale
    Niranjan Harpale

    ๐Ÿ› Nirvik Patel
    Nirvik Patel

    ๐Ÿ’ป Noah Sussman
    Noah Sussman

    ๐Ÿ› Noah0120
    Noah0120

    ๐Ÿ› Noam Tamim
    Noam Tamim

    ๐Ÿ› - Noel Grandin
    Noel Grandin

    ๐Ÿ› + Noel Grandin
    Noel Grandin

    ๐Ÿ› Olaf Haalstra
    Olaf Haalstra

    ๐Ÿ› Oleg Andreych
    Oleg Andreych

    ๐Ÿ’ป ๐Ÿ› Oleg Pavlenko
    Oleg Pavlenko

    ๐Ÿ› Oleksii Dykov
    Oleksii Dykov

    ๐Ÿ’ป ๐Ÿ› Oliver Eikemeier
    Oliver Eikemeier

    ๐Ÿ› Oliver Siegmar
    Oliver Siegmar

    ๐Ÿ’ต - Olivier Parent
    Olivier Parent

    ๐Ÿ’ป ๐Ÿ› + Olivier Parent
    Olivier Parent

    ๐Ÿ’ป ๐Ÿ› Ollie Abbey
    Ollie Abbey

    ๐Ÿ’ป ๐Ÿ› Ondrej Kratochvil
    Ondrej Kratochvil

    ๐Ÿ› OverDrone
    OverDrone

    ๐Ÿ› Ozan Gulle
    Ozan Gulle

    ๐Ÿ’ป ๐Ÿ› PUNEET JAIN
    PUNEET JAIN

    ๐Ÿ› Parbati Bose
    Parbati Bose

    ๐Ÿ› - Paul Berg
    Paul Berg

    ๐Ÿ› + Paul Berg
    Paul Berg

    ๐Ÿ› Paul Guyot
    Paul Guyot

    ๐Ÿ’ป Pavel Bludov
    Pavel Bludov

    ๐Ÿ› Pavel Miฤka
    Pavel Miฤka

    ๐Ÿ› Pedro Nuno Santos
    Pedro Nuno Santos

    ๐Ÿ› Pedro Rijo
    Pedro Rijo

    ๐Ÿ› Pelisse Romain
    Pelisse Romain

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› - Per Abich
    Per Abich

    ๐Ÿ’ป + Per Abich
    Per Abich

    ๐Ÿ’ป Pete Davids
    Pete Davids

    ๐Ÿ› Peter Bruin
    Peter Bruin

    ๐Ÿ› Peter Chittum
    Peter Chittum

    ๐Ÿ’ป ๐Ÿ› Peter Cudmore
    Peter Cudmore

    ๐Ÿ› Peter Kasson
    Peter Kasson

    ๐Ÿ› Peter Kofler
    Peter Kofler

    ๐Ÿ› - Peter Paul Bakker
    Peter Paul Bakker

    ๐Ÿ’ป + Peter Paul Bakker
    Peter Paul Bakker

    ๐Ÿ’ป Peter Rader
    Peter Rader

    ๐Ÿ› Pham Hai Trung
    Pham Hai Trung

    ๐Ÿ› Philip Graf
    Philip Graf

    ๐Ÿ’ป ๐Ÿ› Philip Hachey
    Philip Hachey

    ๐Ÿ› Philippe Ozil
    Philippe Ozil

    ๐Ÿ› Phinehas Artemix
    Phinehas Artemix

    ๐Ÿ› - Phokham Nonava
    Phokham Nonava

    ๐Ÿ› + Phokham Nonava
    Phokham Nonava

    ๐Ÿ› Pim van der Loos
    Pim van der Loos

    ๐Ÿ’ป โš ๏ธ Piotr Szymaล„ski
    Piotr Szymaล„ski

    ๐Ÿ› Piotrek ลปygieล‚o
    Piotrek ลปygieล‚o

    ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– Pranay Jaiswal
    Pranay Jaiswal

    ๐Ÿ› Prasad Kamath
    Prasad Kamath

    ๐Ÿ› Prasanna
    Prasanna

    ๐Ÿ› - Presh-AR
    Presh-AR

    ๐Ÿ› + Presh-AR
    Presh-AR

    ๐Ÿ› Puneet1726
    Puneet1726

    ๐Ÿ› RBRi
    RBRi

    ๐Ÿ› Rafael Cortรชs
    Rafael Cortรชs

    ๐Ÿ› RaheemShaik999
    RaheemShaik999

    ๐Ÿ› RajeshR
    RajeshR

    ๐Ÿ’ป ๐Ÿ› Ramachandra Mohan
    Ramachandra Mohan

    ๐Ÿ› - Ramel0921
    Ramel0921

    ๐Ÿ› + Ramel0921
    Ramel0921

    ๐Ÿ› Raquel Pau
    Raquel Pau

    ๐Ÿ› Ravikiran Janardhana
    Ravikiran Janardhana

    ๐Ÿ› Reda Benhemmouche
    Reda Benhemmouche

    ๐Ÿ› Reinhard Schiedermeier
    Reinhard Schiedermeier

    ๐Ÿ› Renato Oliveira
    Renato Oliveira

    ๐Ÿ’ป ๐Ÿ› Rich DiCroce
    Rich DiCroce

    ๐Ÿ› - Richard Corfield
    Richard Corfield

    ๐Ÿ’ป + Richard Corfield
    Richard Corfield

    ๐Ÿ’ป Richard Corfield
    Richard Corfield

    ๐Ÿ› ๐Ÿ’ป Riot R1cket
    Riot R1cket

    ๐Ÿ› Rishabh Jain
    Rishabh Jain

    ๐Ÿ› RishabhDeep Singh
    RishabhDeep Singh

    ๐Ÿ› Rob Baillie
    Rob Baillie

    ๐Ÿ› Robbie Martinus
    Robbie Martinus

    ๐Ÿ’ป ๐Ÿ› - Robert Henry
    Robert Henry

    ๐Ÿ› + Robert Henry
    Robert Henry

    ๐Ÿ› Robert Mihaly
    Robert Mihaly

    ๐Ÿ› Robert Painsi
    Robert Painsi

    ๐Ÿ› Robert Russell
    Robert Russell

    ๐Ÿ› Robert Sรถsemann
    Robert Sรถsemann

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ› Robert Whitebit
    Robert Whitebit

    ๐Ÿ› Robin Richtsfeld
    Robin Richtsfeld

    ๐Ÿ› - Robin Stocker
    Robin Stocker

    ๐Ÿ’ป ๐Ÿ› + Robin Stocker
    Robin Stocker

    ๐Ÿ’ป ๐Ÿ› Robin Wils
    Robin Wils

    ๐Ÿ› RochusOest
    RochusOest

    ๐Ÿ› Rodolfo Noviski
    Rodolfo Noviski

    ๐Ÿ› Rodrigo Casara
    Rodrigo Casara

    ๐Ÿ› Rodrigo Fernandes
    Rodrigo Fernandes

    ๐Ÿ› Roman Salvador
    Roman Salvador

    ๐Ÿ’ป ๐Ÿ› - Ronald Blaschke
    Ronald Blaschke

    ๐Ÿ› + Ronald Blaschke
    Ronald Blaschke

    ๐Ÿ› Rรณbert Papp
    Rรณbert Papp

    ๐Ÿ› Saikat Sengupta
    Saikat Sengupta

    ๐Ÿ› Saksham Handu
    Saksham Handu

    ๐Ÿ› Saladoc
    Saladoc

    ๐Ÿ› Salesforce Bob Lightning
    Salesforce Bob Lightning

    ๐Ÿ› Sam Carlberg
    Sam Carlberg

    ๐Ÿ› - Sascha Riemer
    Sascha Riemer

    ๐Ÿ› + Sascha Riemer
    Sascha Riemer

    ๐Ÿ› Sashko
    Sashko

    ๐Ÿ’ป Satoshi Kubo
    Satoshi Kubo

    ๐Ÿ› Scott Kennedy
    Scott Kennedy

    ๐Ÿ› Scott Wells
    Scott Wells

    ๐Ÿ› ๐Ÿ’ป Scrates1
    Scrates1

    ๐Ÿ› ๐Ÿ’ป Scrsloota
    Scrsloota

    ๐Ÿ’ป - Sebastian Bรถgl
    Sebastian Bรถgl

    ๐Ÿ› + Sebastian Bรถgl
    Sebastian Bรถgl

    ๐Ÿ› Sebastian Davids
    Sebastian Davids

    ๐Ÿ› Sebastian Schuberth
    Sebastian Schuberth

    ๐Ÿ› Sebastian Schwarz
    Sebastian Schwarz

    ๐Ÿ› Seren
    Seren

    ๐Ÿ› ๐Ÿ’ป Sergey Gorbaty
    Sergey Gorbaty

    ๐Ÿ› Sergey Kozlov
    Sergey Kozlov

    ๐Ÿ› - Sergey Yanzin
    Sergey Yanzin

    ๐Ÿ’ป ๐Ÿ› + Sergey Yanzin
    Sergey Yanzin

    ๐Ÿ’ป ๐Ÿ› Seth Wilcox
    Seth Wilcox

    ๐Ÿ’ป Shai Bennathan
    Shai Bennathan

    ๐Ÿ› ๐Ÿ’ป Shubham
    Shubham

    ๐Ÿ’ป ๐Ÿ› Simon Abykov
    Simon Abykov

    ๐Ÿ’ป ๐Ÿ› Simon Xiao
    Simon Xiao

    ๐Ÿ› Srinivasan Venkatachalam
    Srinivasan Venkatachalam

    ๐Ÿ› - Stanislav Gromov
    Stanislav Gromov

    ๐Ÿ› + Stanislav Gromov
    Stanislav Gromov

    ๐Ÿ› Stanislav Myachenkov
    Stanislav Myachenkov

    ๐Ÿ’ป Stefan Birkner
    Stefan Birkner

    ๐Ÿ› Stefan Bohn
    Stefan Bohn

    ๐Ÿ› Stefan Endrullis
    Stefan Endrullis

    ๐Ÿ› Stefan Klรถss-Schuster
    Stefan Klรถss-Schuster

    ๐Ÿ› Stefan Wolf
    Stefan Wolf

    ๐Ÿ› - Stephan H. Wissel
    Stephan H. Wissel

    ๐Ÿ› + Stephan H. Wissel
    Stephan H. Wissel

    ๐Ÿ› Stephen
    Stephen

    ๐Ÿ› Stephen Carter
    Stephen Carter

    ๐Ÿ› Stephen Friedrich
    Stephen Friedrich

    ๐Ÿ› Steve Babula
    Steve Babula

    ๐Ÿ’ป Steven Stearns
    Steven Stearns

    ๐Ÿ› ๐Ÿ’ป Stexxe
    Stexxe

    ๐Ÿ› - Stian Lรฅgstad
    Stian Lรฅgstad

    ๐Ÿ› + Stian Lรฅgstad
    Stian Lรฅgstad

    ๐Ÿ› StuartClayton5
    StuartClayton5

    ๐Ÿ› Supun Arunoda
    Supun Arunoda

    ๐Ÿ› Suren Abrahamyan
    Suren Abrahamyan

    ๐Ÿ› Suvashri
    Suvashri

    ๐Ÿ“– SwatiBGupta1110
    SwatiBGupta1110

    ๐Ÿ› SyedThoufich
    SyedThoufich

    ๐Ÿ› - Szymon Sasin
    Szymon Sasin

    ๐Ÿ› + Szymon Sasin
    Szymon Sasin

    ๐Ÿ› T-chuangxin
    T-chuangxin

    ๐Ÿ› TERAI Atsuhiro
    TERAI Atsuhiro

    ๐Ÿ› TIOBE Software
    TIOBE Software

    ๐Ÿ’ป ๐Ÿ› Tarush Singh
    Tarush Singh

    ๐Ÿ’ป Taylor Smock
    Taylor Smock

    ๐Ÿ› Techeira Damiรกn
    Techeira Damiรกn

    ๐Ÿ’ป ๐Ÿ› - Ted Husted
    Ted Husted

    ๐Ÿ› + Ted Husted
    Ted Husted

    ๐Ÿ› TehBakker
    TehBakker

    ๐Ÿ› The Gitter Badger
    The Gitter Badger

    ๐Ÿ› Theodoor
    Theodoor

    ๐Ÿ› Thiago Henrique Hรผpner
    Thiago Henrique Hรผpner

    ๐Ÿ› Thibault Meyer
    Thibault Meyer

    ๐Ÿ› Thomas Gรผttler
    Thomas Gรผttler

    ๐Ÿ› - Thomas Jones-Low
    Thomas Jones-Low

    ๐Ÿ› + Thomas Jones-Low
    Thomas Jones-Low

    ๐Ÿ› Thomas Smith
    Thomas Smith

    ๐Ÿ’ป ๐Ÿ› ThrawnCA
    ThrawnCA

    ๐Ÿ› Thu Vo
    Thu Vo

    ๐Ÿ› Thunderforge
    Thunderforge

    ๐Ÿ’ป ๐Ÿ› Tim van der Lippe
    Tim van der Lippe

    ๐Ÿ› Tobias Weimer
    Tobias Weimer

    ๐Ÿ’ป ๐Ÿ› - Tom Copeland
    Tom Copeland

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– + Tom Copeland
    Tom Copeland

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– Tom Daly
    Tom Daly

    ๐Ÿ› Tomas
    Tomas

    ๐Ÿ› Tomer Figenblat
    Tomer Figenblat

    ๐Ÿ› Tomi De Lucca
    Tomi De Lucca

    ๐Ÿ’ป ๐Ÿ› Tony
    Tony

    ๐Ÿ“– Torsten Kleiber
    Torsten Kleiber

    ๐Ÿ› - TrackerSB
    TrackerSB

    ๐Ÿ› + TrackerSB
    TrackerSB

    ๐Ÿ› Tyson Stewart
    Tyson Stewart

    ๐Ÿ› Ullrich Hafner
    Ullrich Hafner

    ๐Ÿ› Utku Cuhadaroglu
    Utku Cuhadaroglu

    ๐Ÿ’ป ๐Ÿ› Valentin Brandl
    Valentin Brandl

    ๐Ÿ› Valeria
    Valeria

    ๐Ÿ› Valery Yatsynovich
    Valery Yatsynovich

    ๐Ÿ“– - Vasily Anisimov
    Vasily Anisimov

    ๐Ÿ› + Vasily Anisimov
    Vasily Anisimov

    ๐Ÿ› Vedant Chokshi
    Vedant Chokshi

    ๐Ÿ› Vibhor Goyal
    Vibhor Goyal

    ๐Ÿ› Vickenty Fesunov
    Vickenty Fesunov

    ๐Ÿ› Victor Noรซl
    Victor Noรซl

    ๐Ÿ› Vincent Galloy
    Vincent Galloy

    ๐Ÿ’ป Vincent HUYNH
    Vincent HUYNH

    ๐Ÿ› - Vincent Maurin
    Vincent Maurin

    ๐Ÿ› + Vincent Maurin
    Vincent Maurin

    ๐Ÿ› Vincent Privat
    Vincent Privat

    ๐Ÿ› Vishhwas
    Vishhwas

    ๐Ÿ› Vishv_Android
    Vishv_Android

    ๐Ÿ› + Vitalii Yevtushenko
    Vitalii Yevtushenko

    ๐Ÿ› Vitaly
    Vitaly

    ๐Ÿ› Vitaly Polonetsky
    Vitaly Polonetsky

    ๐Ÿ› - Vojtech Polivka
    Vojtech Polivka

    ๐Ÿ› - Vsevolod Zholobov
    Vsevolod Zholobov

    ๐Ÿ› + Vojtech Polivka
    Vojtech Polivka

    ๐Ÿ› + Vsevolod Zholobov
    Vsevolod Zholobov

    ๐Ÿ› Vyom Yadav
    Vyom Yadav

    ๐Ÿ’ป Wang Shidong
    Wang Shidong

    ๐Ÿ› Waqas Ahmed
    Waqas Ahmed

    ๐Ÿ› Wayne J. Earl
    Wayne J. Earl

    ๐Ÿ› Wchenghui
    Wchenghui

    ๐Ÿ› - Wener
    Wener

    ๐Ÿ’ป - Will Winder
    Will Winder

    ๐Ÿ› + Wener
    Wener

    ๐Ÿ’ป + Will Winder
    Will Winder

    ๐Ÿ› William Brockhus
    William Brockhus

    ๐Ÿ’ป ๐Ÿ› Wilson Kurniawan
    Wilson Kurniawan

    ๐Ÿ› Wim Deblauwe
    Wim Deblauwe

    ๐Ÿ› Woongsik Choi
    Woongsik Choi

    ๐Ÿ› XenoAmess
    XenoAmess

    ๐Ÿ’ป ๐Ÿ› - Yang
    Yang

    ๐Ÿ’ป - YaroslavTER
    YaroslavTER

    ๐Ÿ› + Yang
    Yang

    ๐Ÿ’ป + YaroslavTER
    YaroslavTER

    ๐Ÿ› Yasar Shaikh
    Yasar Shaikh

    ๐Ÿ’ป Young Chan
    Young Chan

    ๐Ÿ’ป ๐Ÿ› YuJin Kim
    YuJin Kim

    ๐Ÿ› Yuri Dolzhenko
    Yuri Dolzhenko

    ๐Ÿ› Yurii Dubinka
    Yurii Dubinka

    ๐Ÿ› - Zoltan Farkas
    Zoltan Farkas

    ๐Ÿ› - Zustin
    Zustin

    ๐Ÿ› + Zoltan Farkas
    Zoltan Farkas

    ๐Ÿ› + Zustin
    Zustin

    ๐Ÿ› aaronhurst-google
    aaronhurst-google

    ๐Ÿ› ๐Ÿ’ป alexmodis
    alexmodis

    ๐Ÿ› andreoss
    andreoss

    ๐Ÿ› andrey81inmd
    andrey81inmd

    ๐Ÿ’ป ๐Ÿ› anicoara
    anicoara

    ๐Ÿ› - arunprasathav
    arunprasathav

    ๐Ÿ› - asiercamara
    asiercamara

    ๐Ÿ› + arunprasathav
    arunprasathav

    ๐Ÿ› + asiercamara
    asiercamara

    ๐Ÿ› astillich-igniti
    astillich-igniti

    ๐Ÿ’ป avesolovksyy
    avesolovksyy

    ๐Ÿ› avishvat
    avishvat

    ๐Ÿ› avivmu
    avivmu

    ๐Ÿ› axelbarfod1
    axelbarfod1

    ๐Ÿ› - b-3-n
    b-3-n

    ๐Ÿ› - balbhadra9
    balbhadra9

    ๐Ÿ› + b-3-n
    b-3-n

    ๐Ÿ› + balbhadra9
    balbhadra9

    ๐Ÿ› base23de
    base23de

    ๐Ÿ› bergander
    bergander

    ๐Ÿ› ๐Ÿ’ป berkam
    berkam

    ๐Ÿ’ป ๐Ÿ› breizh31
    breizh31

    ๐Ÿ› caesarkim
    caesarkim

    ๐Ÿ› - carolyujing
    carolyujing

    ๐Ÿ› - cbfiddle
    cbfiddle

    ๐Ÿ› + carolyujing
    carolyujing

    ๐Ÿ› + cbfiddle
    cbfiddle

    ๐Ÿ› cesares-basilico
    cesares-basilico

    ๐Ÿ› chrite
    chrite

    ๐Ÿ› ciufudean
    ciufudean

    ๐Ÿ“– cobratbq
    cobratbq

    ๐Ÿ› coladict
    coladict

    ๐Ÿ› - cosmoJFH
    cosmoJFH

    ๐Ÿ› - cristalp
    cristalp

    ๐Ÿ› + cosmoJFH
    cosmoJFH

    ๐Ÿ› + cristalp
    cristalp

    ๐Ÿ› crunsk
    crunsk

    ๐Ÿ› cwholmes
    cwholmes

    ๐Ÿ› cyberjj999
    cyberjj999

    ๐Ÿ› cyw3
    cyw3

    ๐Ÿ› ๐Ÿ“– d1ss0nanz
    d1ss0nanz

    ๐Ÿ› - dague1
    dague1

    ๐Ÿ“– - dalizi007
    dalizi007

    ๐Ÿ’ป + dague1
    dague1

    ๐Ÿ“– + dalizi007
    dalizi007

    ๐Ÿ’ป danbrycefairsailcom
    danbrycefairsailcom

    ๐Ÿ› dariansanity
    dariansanity

    ๐Ÿ› darrenmiliband
    darrenmiliband

    ๐Ÿ› davidburstrom
    davidburstrom

    ๐Ÿ› dbirkman-paloalto
    dbirkman-paloalto

    ๐Ÿ› - deepak-patra
    deepak-patra

    ๐Ÿ› - dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› + deepak-patra
    deepak-patra

    ๐Ÿ› + dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› dinesh150
    dinesh150

    ๐Ÿ› diziaq
    diziaq

    ๐Ÿ› dreaminpast123
    dreaminpast123

    ๐Ÿ› duanyanan
    duanyanan

    ๐Ÿ› dutt-sanjay
    dutt-sanjay

    ๐Ÿ› - duursma
    duursma

    ๐Ÿ’ป - dylanleung
    dylanleung

    ๐Ÿ› + duursma
    duursma

    ๐Ÿ’ป + dylanleung
    dylanleung

    ๐Ÿ› dzeigler
    dzeigler

    ๐Ÿ› eant60
    eant60

    ๐Ÿ› ekkirala
    ekkirala

    ๐Ÿ› emersonmoura
    emersonmoura

    ๐Ÿ› emouty
    emouty

    ๐Ÿ’ป ๐Ÿ› - eugenepugach
    eugenepugach

    ๐Ÿ› - fairy
    fairy

    ๐Ÿ› + eugenepugach
    eugenepugach

    ๐Ÿ› + fairy
    fairy

    ๐Ÿ› filiprafalowicz
    filiprafalowicz

    ๐Ÿ’ป flxbl-io
    flxbl-io

    ๐Ÿ’ต foxmason
    foxmason

    ๐Ÿ› frankegabor
    frankegabor

    ๐Ÿ› frankl
    frankl

    ๐Ÿ› - freafrea
    freafrea

    ๐Ÿ› - fsapatin
    fsapatin

    ๐Ÿ› + freafrea
    freafrea

    ๐Ÿ› + fsapatin
    fsapatin

    ๐Ÿ› gearsethenry
    gearsethenry

    ๐Ÿ› gracia19
    gracia19

    ๐Ÿ› gudzpoz
    gudzpoz

    ๐Ÿ› guo fei
    guo fei

    ๐Ÿ› gurmsc5
    gurmsc5

    ๐Ÿ› - gwilymatgearset
    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ› - haigsn
    haigsn

    ๐Ÿ› + gwilymatgearset
    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ› + haigsn
    haigsn

    ๐Ÿ› hemanshu070
    hemanshu070

    ๐Ÿ› henrik242
    henrik242

    ๐Ÿ› hongpuwu
    hongpuwu

    ๐Ÿ› hvbtup
    hvbtup

    ๐Ÿ’ป ๐Ÿ› igniti GmbH
    igniti GmbH

    ๐Ÿ› - ilovezfs
    ilovezfs

    ๐Ÿ› - imax-erik
    imax-erik

    ๐Ÿ› + ilovezfs
    ilovezfs

    ๐Ÿ› + imax-erik
    imax-erik

    ๐Ÿ› itaigilo
    itaigilo

    ๐Ÿ› jakivey32
    jakivey32

    ๐Ÿ› jbennett2091
    jbennett2091

    ๐Ÿ› jcamerin
    jcamerin

    ๐Ÿ› jkeener1
    jkeener1

    ๐Ÿ› - jmetertea
    jmetertea

    ๐Ÿ› - johnra2
    johnra2

    ๐Ÿ’ป + jmetertea
    jmetertea

    ๐Ÿ› + johnra2
    johnra2

    ๐Ÿ’ป johnzhao9
    johnzhao9

    ๐Ÿ› josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ› kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ› karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“– karwer
    karwer

    ๐Ÿ› - kaulonline
    kaulonline

    ๐Ÿ› - kdaemonv
    kdaemonv

    ๐Ÿ› + kaulonline
    kaulonline

    ๐Ÿ› + kdaemonv
    kdaemonv

    ๐Ÿ› kdebski85
    kdebski85

    ๐Ÿ› ๐Ÿ’ป kenji21
    kenji21

    ๐Ÿ’ป ๐Ÿ› kfranic
    kfranic

    ๐Ÿ› khalidkh
    khalidkh

    ๐Ÿ› koalalam
    koalalam

    ๐Ÿ› - krzyk
    krzyk

    ๐Ÿ› - lasselindqvist
    lasselindqvist

    ๐Ÿ› + krzyk
    krzyk

    ๐Ÿ› + lasselindqvist
    lasselindqvist

    ๐Ÿ› lgemeinhardt
    lgemeinhardt

    ๐Ÿ› lihuaib
    lihuaib

    ๐Ÿ› liqingjun123
    liqingjun123

    ๐Ÿ› lonelyma1021
    lonelyma1021

    ๐Ÿ› lpeddy
    lpeddy

    ๐Ÿ› - lujiefsi
    lujiefsi

    ๐Ÿ’ป - lukelukes
    lukelukes

    ๐Ÿ’ป + lujiefsi
    lujiefsi

    ๐Ÿ’ป + lukelukes
    lukelukes

    ๐Ÿ’ป lyriccoder
    lyriccoder

    ๐Ÿ› marcelmore
    marcelmore

    ๐Ÿ› matchbox
    matchbox

    ๐Ÿ› matthiaskraaz
    matthiaskraaz

    ๐Ÿ› meandonlyme
    meandonlyme

    ๐Ÿ› - mikesive
    mikesive

    ๐Ÿ› - milossesic
    milossesic

    ๐Ÿ› + mikesive
    mikesive

    ๐Ÿ› + milossesic
    milossesic

    ๐Ÿ› mluckam
    mluckam

    ๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
    mohan-chinnappan-n

    ๐Ÿ’ป mriddell95
    mriddell95

    ๐Ÿ› mrlzh
    mrlzh

    ๐Ÿ› msloan
    msloan

    ๐Ÿ› - mucharlaravalika
    mucharlaravalika

    ๐Ÿ› - mvenneman
    mvenneman

    ๐Ÿ› + mucharlaravalika
    mucharlaravalika

    ๐Ÿ› + mvenneman
    mvenneman

    ๐Ÿ› nareshl119
    nareshl119

    ๐Ÿ› nicolas-harraudeau-sonarsource
    nicolas-harraudeau-sonarsource

    ๐Ÿ› noerremark
    noerremark

    ๐Ÿ› novsirion
    novsirion

    ๐Ÿ› nwcm
    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป - oggboy
    oggboy

    ๐Ÿ› - oinume
    oinume

    ๐Ÿ› + oggboy
    oggboy

    ๐Ÿ› + oinume
    oinume

    ๐Ÿ› orimarko
    orimarko

    ๐Ÿ’ป ๐Ÿ› pablogomez2197
    pablogomez2197

    ๐Ÿ› pacvz
    pacvz

    ๐Ÿ’ป pallavi agarwal
    pallavi agarwal

    ๐Ÿ› parksungrin
    parksungrin

    ๐Ÿ› - patpatpat123
    patpatpat123

    ๐Ÿ› - patriksevallius
    patriksevallius

    ๐Ÿ› + patpatpat123
    patpatpat123

    ๐Ÿ› + patriksevallius
    patriksevallius

    ๐Ÿ› pbrajesh1
    pbrajesh1

    ๐Ÿ› phoenix384
    phoenix384

    ๐Ÿ› piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป plan3d
    plan3d

    ๐Ÿ› poojasix
    poojasix

    ๐Ÿ› - prabhushrikant
    prabhushrikant

    ๐Ÿ› - pujitha8783
    pujitha8783

    ๐Ÿ› + prabhushrikant
    prabhushrikant

    ๐Ÿ› + pujitha8783
    pujitha8783

    ๐Ÿ› r-r-a-j
    r-r-a-j

    ๐Ÿ› raghujayjunk
    raghujayjunk

    ๐Ÿ› rajeshveera
    rajeshveera

    ๐Ÿ› rajeswarreddy88
    rajeswarreddy88

    ๐Ÿ› recdevs
    recdevs

    ๐Ÿ› - reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ› - rijkt
    rijkt

    ๐Ÿ› + reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ› + rijkt
    rijkt

    ๐Ÿ› rillig-tk
    rillig-tk

    ๐Ÿ› rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ› rnveach
    rnveach

    ๐Ÿ› rxmicro
    rxmicro

    ๐Ÿ› ryan-gustafson
    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ› - sabi0
    sabi0

    ๐Ÿ› - scais
    scais

    ๐Ÿ› + sabi0
    sabi0

    ๐Ÿ› + scais
    scais

    ๐Ÿ› schosin
    schosin

    ๐Ÿ› screamingfrog
    screamingfrog

    ๐Ÿ’ต sebbASF
    sebbASF

    ๐Ÿ› sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป shilko2013
    shilko2013

    ๐Ÿ› - shiomiyan
    shiomiyan

    ๐Ÿ“– - simeonKondr
    simeonKondr

    ๐Ÿ› + shiomiyan
    shiomiyan

    ๐Ÿ“– + simeonKondr
    simeonKondr

    ๐Ÿ› snajberk
    snajberk

    ๐Ÿ› sniperrifle2004
    sniperrifle2004

    ๐Ÿ› snuyanzin
    snuyanzin

    ๐Ÿ› ๐Ÿ’ป soloturn
    soloturn

    ๐Ÿ› soyodream
    soyodream

    ๐Ÿ› - sratz
    sratz

    ๐Ÿ› - stonio
    stonio

    ๐Ÿ› + sratz
    sratz

    ๐Ÿ› + stonio
    stonio

    ๐Ÿ› sturton
    sturton

    ๐Ÿ’ป ๐Ÿ› sudharmohan
    sudharmohan

    ๐Ÿ› suruchidawar
    suruchidawar

    ๐Ÿ› svenfinitiv
    svenfinitiv

    ๐Ÿ› szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป - tashiscool
    tashiscool

    ๐Ÿ› - test-git-hook
    test-git-hook

    ๐Ÿ› + tashiscool
    tashiscool

    ๐Ÿ› + test-git-hook
    test-git-hook

    ๐Ÿ› testation21
    testation21

    ๐Ÿ’ป ๐Ÿ› thanosa
    thanosa

    ๐Ÿ› tiandiyixian
    tiandiyixian

    ๐Ÿ› tobwoerk
    tobwoerk

    ๐Ÿ› tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป - trentchilders
    trentchilders

    ๐Ÿ› - triandicAnt
    triandicAnt

    ๐Ÿ› + trentchilders
    trentchilders

    ๐Ÿ› + triandicAnt
    triandicAnt

    ๐Ÿ› trishul14
    trishul14

    ๐Ÿ› tsui
    tsui

    ๐Ÿ› wangzitom12306
    wangzitom12306

    ๐Ÿ› winhkey
    winhkey

    ๐Ÿ› witherspore
    witherspore

    ๐Ÿ› - wjljack
    wjljack

    ๐Ÿ› - wuchiuwong
    wuchiuwong

    ๐Ÿ› + wjljack
    wjljack

    ๐Ÿ› + wuchiuwong
    wuchiuwong

    ๐Ÿ› xingsong
    xingsong

    ๐Ÿ› xioayuge
    xioayuge

    ๐Ÿ› xnYi9wRezm
    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ› xuanuy
    xuanuy

    ๐Ÿ› xyf0921
    xyf0921

    ๐Ÿ› - yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› - yasuharu-sato
    yasuharu-sato

    ๐Ÿ› + yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› + yasuharu-sato
    yasuharu-sato

    ๐Ÿ› zenglian
    zenglian

    ๐Ÿ› zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› zh3ng
    zh3ng

    ๐Ÿ› zt_soft
    zt_soft

    ๐Ÿ› ztt79
    ztt79

    ๐Ÿ› - zzzzfeng
    zzzzfeng

    ๐Ÿ› - รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› + zzzzfeng
    zzzzfeng

    ๐Ÿ› + รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› ไปป่ดตๆฐ
    ไปป่ดตๆฐ

    ๐Ÿ› ่Œ…ๅปถๅฎ‰
    ่Œ…ๅปถๅฎ‰

    ๐Ÿ’ป From 3fdbf7d6cbaaa78f2edc2f48922beeb5c2e4a9ce Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 14 Nov 2024 17:48:08 +0100 Subject: [PATCH 0224/1962] [java] InsufficientStringBufferDeclaration: Fix CCE for Character Fixes #5314 --- docs/pages/release_notes.md | 2 ++ ...sufficientStringBufferDeclarationRule.java | 8 +++++++- .../InsufficientStringBufferDeclaration.xml | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 5fa3ac04b69..3893f1a8201 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -20,6 +20,8 @@ This is a {{ site.pmd.release_type }} release. * java * [#5293](https://github.com/pmd/pmd/issues/5293): \[java] Deadlock when executing PMD in multiple threads * [#5324](https://github.com/pmd/pmd/issues/5324): \[java] Issue with type inference of nested lambdas +* java-performance + * [#5314](https://github.com/pmd/pmd/issues/5314): \[java] InsufficientStringBufferDeclarationRule: Lack of handling for char type parameters ### ๐Ÿšจ API Changes diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java index a6fabf91a26..5acd063c154 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java @@ -240,6 +240,12 @@ private State getConstructorCapacity(ASTVariableId variable, ASTExpression node) private int calculateExpression(ASTExpression expression) { Object value = expression.getConstValue(); - return value == null ? State.UNKNOWN_CAPACITY : (Integer) value; + if (value == null) { + return State.UNKNOWN_CAPACITY; + } + if (value instanceof Character) { + return (Character) value; + } + return (Integer) value; } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml index ec267fcfccc..bd5d364eb1d 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml @@ -1419,4 +1419,23 @@ public class LiteralExpression { } ]]> + + + #5314 [java] InsufficientStringBufferDeclarationRule: Lack of handling for char type parameters + 0 + + From 01b8ca765bc16a57bac3bb8a14f2c13839ae2dd7 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 14 Nov 2024 17:48:26 +0100 Subject: [PATCH 0225/1962] Add @chenguangqi as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 172 +++++++++++++------------- 2 files changed, 96 insertions(+), 85 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 95ebc05d6e1..1d4a930f383 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7865,6 +7865,15 @@ "contributions": [ "code" ] + }, + { + "login": "chenguangqi", + "name": "ๅคฉ็ƒญๅƒ่ฅฟ็“œ", + "avatar_url": "https://avatars.githubusercontent.com/u/6231010?v=4", + "profile": "http://chenguangqi.github.io/", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 9497ea73780..7b6a55aec62 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -350,770 +350,772 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d JJengility
    JJengility

    ๐Ÿ› Jake Hemmerle
    Jake Hemmerle

    ๐Ÿ› + Jakub Dupak
    Jakub Dupak

    ๐Ÿ’ป James Harrison
    James Harrison

    ๐Ÿ› ๐Ÿ’ป Jamie Bisotti
    Jamie Bisotti

    ๐Ÿ› Jan
    Jan

    ๐Ÿ› Jan Aertgeerts
    Jan Aertgeerts

    ๐Ÿ’ป ๐Ÿ› - Jan Brรผmmer
    Jan Brรผmmer

    ๐Ÿ› + Jan Brรผmmer
    Jan Brรผmmer

    ๐Ÿ› Jan Tล™รญska
    Jan Tล™รญska

    ๐Ÿ› Jan-Lukas Else
    Jan-Lukas Else

    ๐Ÿ› Jason Qiu
    Jason Qiu

    ๐Ÿ’ป ๐Ÿ“– Jason Williams
    Jason Williams

    ๐Ÿ› Javier Spagnoletti
    Javier Spagnoletti

    ๐Ÿ› Jean-Paul Mayer
    Jean-Paul Mayer

    ๐Ÿ› - Jean-Simon Larochelle
    Jean-Simon Larochelle

    ๐Ÿ› + Jean-Simon Larochelle
    Jean-Simon Larochelle

    ๐Ÿ› Jeff Bartolotta
    Jeff Bartolotta

    ๐Ÿ’ป ๐Ÿ› Jeff Hube
    Jeff Hube

    ๐Ÿ’ป ๐Ÿ› Jeff Jensen
    Jeff Jensen

    ๐Ÿ› Jeff May
    Jeff May

    ๐Ÿ› Jens Gerdes
    Jens Gerdes

    ๐Ÿ› Jeroen Borgers
    Jeroen Borgers

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข - Jeroen Meijer
    Jeroen Meijer

    ๐Ÿ› + Jeroen Meijer
    Jeroen Meijer

    ๐Ÿ› Jeroen van Wilgenburg
    Jeroen van Wilgenburg

    ๐Ÿ“– Jerome Russ
    Jerome Russ

    ๐Ÿ› JerritEic
    JerritEic

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Jiri Pejchal
    Jiri Pejchal

    ๐Ÿ› Jithin Sunny
    Jithin Sunny

    ๐Ÿ› Jiล™รญ ล korpil
    Jiล™รญ ล korpil

    ๐Ÿ› - Joao Machado
    Joao Machado

    ๐Ÿ› + Joao Machado
    Joao Machado

    ๐Ÿ› Jochen Krauss
    Jochen Krauss

    ๐Ÿ› Johan Hammar
    Johan Hammar

    ๐Ÿ› John Karp
    John Karp

    ๐Ÿ› John Zhang
    John Zhang

    ๐Ÿ› John-Teng
    John-Teng

    ๐Ÿ’ป ๐Ÿ› Jon Moroney
    Jon Moroney

    ๐Ÿ’ป ๐Ÿ› - Jonas Geiregat
    Jonas Geiregat

    ๐Ÿ› + Jonas Geiregat
    Jonas Geiregat

    ๐Ÿ› Jonas KeรŸler
    Jonas KeรŸler

    ๐Ÿ› Jonathan Wiesel
    Jonathan Wiesel

    ๐Ÿ’ป ๐Ÿ› Jordan
    Jordan

    ๐Ÿ› Jordi Llach
    Jordi Llach

    ๐Ÿ› Jorge Solรณrzano
    Jorge Solรณrzano

    ๐Ÿ› JorneVL
    JorneVL

    ๐Ÿ› - Jose Palafox
    Jose Palafox

    ๐Ÿ› + Jose Palafox
    Jose Palafox

    ๐Ÿ› Jose Stovall
    Jose Stovall

    ๐Ÿ› Joseph
    Joseph

    ๐Ÿ’ป Joseph Heenan
    Joseph Heenan

    ๐Ÿ› Josh Feingold
    Josh Feingold

    ๐Ÿ’ป ๐Ÿ› Josh Holthaus
    Josh Holthaus

    ๐Ÿ› Joshua S Arquilevich
    Joshua S Arquilevich

    ๐Ÿ› - Joรฃo Dinis Ferreira
    Joรฃo Dinis Ferreira

    ๐Ÿ“– + Joรฃo Dinis Ferreira
    Joรฃo Dinis Ferreira

    ๐Ÿ“– Joรฃo Ferreira
    Joรฃo Ferreira

    ๐Ÿ’ป ๐Ÿ› Joรฃo Pedro Schmitt
    Joรฃo Pedro Schmitt

    ๐Ÿ› Juan Martรญn Sotuyo Dodero
    Juan Martรญn Sotuyo Dodero

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง Juan Pablo Civile
    Juan Pablo Civile

    ๐Ÿ› Julian Voronetsky
    Julian Voronetsky

    ๐Ÿ› Julien
    Julien

    ๐Ÿ› - Julius
    Julius

    ๐Ÿ› + Julius
    Julius

    ๐Ÿ› JustPRV
    JustPRV

    ๐Ÿ› Justin Stroud
    Justin Stroud

    ๐Ÿ’ป Jรถrn Huxhorn
    Jรถrn Huxhorn

    ๐Ÿ› KThompso
    KThompso

    ๐Ÿ› Kai Amundsen
    Kai Amundsen

    ๐Ÿ› Karel Vervaeke
    Karel Vervaeke

    ๐Ÿ› - Karl-Andero Mere
    Karl-Andero Mere

    ๐Ÿ› + Karl-Andero Mere
    Karl-Andero Mere

    ๐Ÿ› Karl-Philipp Richter
    Karl-Philipp Richter

    ๐Ÿ› Karsten Silz
    Karsten Silz

    ๐Ÿ› Kazuma Watanabe
    Kazuma Watanabe

    ๐Ÿ› Kev
    Kev

    ๐Ÿ› Keve Mรผller
    Keve Mรผller

    ๐Ÿ› Kevin Guerra
    Kevin Guerra

    ๐Ÿ’ป - Kevin Jones
    Kevin Jones

    ๐Ÿ› ๐Ÿ’ป + Kevin Jones
    Kevin Jones

    ๐Ÿ› ๐Ÿ’ป Kevin Poorman
    Kevin Poorman

    ๐Ÿ› Kevin Wayne
    Kevin Wayne

    ๐Ÿ› Kieran Black
    Kieran Black

    ๐Ÿ› Kirill Zubov
    Kirill Zubov

    ๐Ÿ› Kirk Clemens
    Kirk Clemens

    ๐Ÿ’ป ๐Ÿ› Klaus Hartl
    Klaus Hartl

    ๐Ÿ› - Koen Van Looveren
    Koen Van Looveren

    ๐Ÿ› + Koen Van Looveren
    Koen Van Looveren

    ๐Ÿ› Kris Scheibe
    Kris Scheibe

    ๐Ÿ’ป ๐Ÿ› Krystian Dabrowski
    Krystian Dabrowski

    ๐Ÿ› ๐Ÿ’ป Kunal Thanki
    Kunal Thanki

    ๐Ÿ› LaLucid
    LaLucid

    ๐Ÿ’ป Larry Diamond
    Larry Diamond

    ๐Ÿ’ป ๐Ÿ› Lars Knickrehm
    Lars Knickrehm

    ๐Ÿ› - Laurent Bovet
    Laurent Bovet

    ๐Ÿ› ๐Ÿ’ป + Laurent Bovet
    Laurent Bovet

    ๐Ÿ› ๐Ÿ’ป Leo Gutierrez
    Leo Gutierrez

    ๐Ÿ› LiGaOg
    LiGaOg

    ๐Ÿ’ป Liam Sharp
    Liam Sharp

    ๐Ÿ› Lintsi
    Lintsi

    ๐Ÿ› Linus Fernandes
    Linus Fernandes

    ๐Ÿ› Lixon Lookose
    Lixon Lookose

    ๐Ÿ› - Logesh
    Logesh

    ๐Ÿ› + Logesh
    Logesh

    ๐Ÿ› Lorenzo Gabriele
    Lorenzo Gabriele

    ๐Ÿ› Loรฏc Ledoyen
    Loรฏc Ledoyen

    ๐Ÿ› Lucas
    Lucas

    ๐Ÿ› Lucas Silva
    Lucas Silva

    ๐Ÿ› Lucas Soncini
    Lucas Soncini

    ๐Ÿ’ป ๐Ÿ› Luis Alcantar
    Luis Alcantar

    ๐Ÿ’ป - Lukas Grรคf
    Lukas Grรคf

    ๐Ÿ’ป + Lukas Grรคf
    Lukas Grรคf

    ๐Ÿ’ป Lukasz Slonina
    Lukasz Slonina

    ๐Ÿ› Lukebray
    Lukebray

    ๐Ÿ› Lynn
    Lynn

    ๐Ÿ’ป ๐Ÿ› Lyor Goldstein
    Lyor Goldstein

    ๐Ÿ› MCMicS
    MCMicS

    ๐Ÿ› Macarse
    Macarse

    ๐Ÿ› - Machine account for PMD
    Machine account for PMD

    ๐Ÿ’ป + Machine account for PMD
    Machine account for PMD

    ๐Ÿ’ป Maciek Siemczyk
    Maciek Siemczyk

    ๐Ÿ› Maikel Steneker
    Maikel Steneker

    ๐Ÿ’ป ๐Ÿ› Maksim Moiseikin
    Maksim Moiseikin

    ๐Ÿ› Manfred Koch
    Manfred Koch

    ๐Ÿ› Manuel Moya Ferrer
    Manuel Moya Ferrer

    ๐Ÿ’ป ๐Ÿ› Manuel Ryan
    Manuel Ryan

    ๐Ÿ› - Marat Vyshegorodtsev
    Marat Vyshegorodtsev

    ๐Ÿ› + Marat Vyshegorodtsev
    Marat Vyshegorodtsev

    ๐Ÿ› Marcel Hรคrle
    Marcel Hรคrle

    ๐Ÿ› Marcello Fialho
    Marcello Fialho

    ๐Ÿ› Marcin Dฤ…browski
    Marcin Dฤ…browski

    ๐Ÿ’ป Marcin Rataj
    Marcin Rataj

    ๐Ÿ› Marcono1234
    Marcono1234

    ๐Ÿ› Mark Adamcin
    Mark Adamcin

    ๐Ÿ› - Mark Hall
    Mark Hall

    ๐Ÿ’ป ๐Ÿ› + Mark Hall
    Mark Hall

    ๐Ÿ’ป ๐Ÿ› Mark Kolich
    Mark Kolich

    ๐Ÿ› Mark Pritchard
    Mark Pritchard

    ๐Ÿ› Markus Rathgeb
    Markus Rathgeb

    ๐Ÿ› Marquis Wang
    Marquis Wang

    ๐Ÿ› MartGit
    MartGit

    ๐Ÿ› Martin Feldsztejn
    Martin Feldsztejn

    ๐Ÿ› - Martin Lehmann
    Martin Lehmann

    ๐Ÿ› + Martin Lehmann
    Martin Lehmann

    ๐Ÿ› Martin Spamer
    Martin Spamer

    ๐Ÿ› Martin Tarjรกnyi
    Martin Tarjรกnyi

    ๐Ÿ› MatFl
    MatFl

    ๐Ÿ› Mateusz Stefanski
    Mateusz Stefanski

    ๐Ÿ› Mathieu Gouin
    Mathieu Gouin

    ๐Ÿ› MatiasComercio
    MatiasComercio

    ๐Ÿ’ป ๐Ÿ› - Matt Benson
    Matt Benson

    ๐Ÿ› + Matt Benson
    Matt Benson

    ๐Ÿ› Matt De Poorter
    Matt De Poorter

    ๐Ÿ› Matt Hargett
    Matt Hargett

    ๐Ÿ’ป ๐Ÿ’ต Matt Harrah
    Matt Harrah

    ๐Ÿ› Matt Nelson
    Matt Nelson

    ๐Ÿ› Matthew Amos
    Matthew Amos

    ๐Ÿ› Matthew Duggan
    Matthew Duggan

    ๐Ÿ› - Matthew Hall
    Matthew Hall

    ๐Ÿ› + Matthew Hall
    Matthew Hall

    ๐Ÿ› Matthew Rossner
    Matthew Rossner

    ๐Ÿ› Matรญas Fraga
    Matรญas Fraga

    ๐Ÿ’ป ๐Ÿ› Maxime Robert
    Maxime Robert

    ๐Ÿ’ป ๐Ÿ› MetaBF
    MetaBF

    ๐Ÿ› Metin Dagcilar
    Metin Dagcilar

    ๐Ÿ› Michael
    Michael

    ๐Ÿ› - Michael Bell
    Michael Bell

    ๐Ÿ› + Michael Bell
    Michael Bell

    ๐Ÿ› Michael Bernstein
    Michael Bernstein

    ๐Ÿ› Michael Clay
    Michael Clay

    ๐Ÿ› Michael Dombrowski
    Michael Dombrowski

    ๐Ÿ› Michael Hausegger
    Michael Hausegger

    ๐Ÿ› Michael Hoefer
    Michael Hoefer

    ๐Ÿ› Michael Kolesnikov
    Michael Kolesnikov

    ๐Ÿ› - Michael Mรถbius
    Michael Mรถbius

    ๐Ÿ› + Michael Mรถbius
    Michael Mรถbius

    ๐Ÿ› Michael N. Lipp
    Michael N. Lipp

    ๐Ÿ› Michael Pellegrini
    Michael Pellegrini

    ๐Ÿ› Michal Kordas
    Michal Kordas

    ๐Ÿ› Michaล‚ Borek
    Michaล‚ Borek

    ๐Ÿ› Michaล‚ Kuliล„ski
    Michaล‚ Kuliล„ski

    ๐Ÿ› Miguel Nรบรฑez Dรญaz-Montes
    Miguel Nรบรฑez Dรญaz-Montes

    ๐Ÿ› - Mihai Ionut
    Mihai Ionut

    ๐Ÿ› + Mihai Ionut
    Mihai Ionut

    ๐Ÿ› Mikhail Kuchma
    Mikhail Kuchma

    ๐Ÿ› Mirek Hankus
    Mirek Hankus

    ๐Ÿ› Mitch Spano
    Mitch Spano

    ๐Ÿ› Mladjan Gadzic
    Mladjan Gadzic

    ๐Ÿ› MrAngry52
    MrAngry52

    ๐Ÿ› Muminur Choudhury
    Muminur Choudhury

    ๐Ÿ› - Mykhailo Palahuta
    Mykhailo Palahuta

    ๐Ÿ’ป ๐Ÿ› + Mykhailo Palahuta
    Mykhailo Palahuta

    ๐Ÿ’ป ๐Ÿ› Nagendra Kumar Singh
    Nagendra Kumar Singh

    ๐Ÿ› Nahuel Barrios
    Nahuel Barrios

    ๐Ÿ› Nakul Sharma
    Nakul Sharma

    ๐Ÿ› Nathan Braun
    Nathan Braun

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› - Nathanaรซl
    Nathanaรซl

    ๐Ÿ› + Nathanaรซl
    Nathanaรซl

    ๐Ÿ› Naveen
    Naveen

    ๐Ÿ’ป Nazdravi
    Nazdravi

    ๐Ÿ› Neha-Dhonde
    Neha-Dhonde

    ๐Ÿ› Nicholas Doyle
    Nicholas Doyle

    ๐Ÿ› Nick Butcher
    Nick Butcher

    ๐Ÿ› Nico Gallinal
    Nico Gallinal

    ๐Ÿ› - Nicola Dal Maso
    Nicola Dal Maso

    ๐Ÿ› + Nicola Dal Maso
    Nicola Dal Maso

    ๐Ÿ› Nicolas Filotto
    Nicolas Filotto

    ๐Ÿ’ป Nicolas Vervelle
    Nicolas Vervelle

    ๐Ÿ› Nicolas Vuillamy
    Nicolas Vuillamy

    ๐Ÿ“– Nikita Chursin
    Nikita Chursin

    ๐Ÿ› Niklas Baudy
    Niklas Baudy

    ๐Ÿ› Nikolas Havrikov
    Nikolas Havrikov

    ๐Ÿ› - Nilesh Virkar
    Nilesh Virkar

    ๐Ÿ› + Nilesh Virkar
    Nilesh Virkar

    ๐Ÿ› Nimit Patel
    Nimit Patel

    ๐Ÿ› Niranjan Harpale
    Niranjan Harpale

    ๐Ÿ› Nirvik Patel
    Nirvik Patel

    ๐Ÿ’ป Noah Sussman
    Noah Sussman

    ๐Ÿ› Noah0120
    Noah0120

    ๐Ÿ› Noam Tamim
    Noam Tamim

    ๐Ÿ› - Noel Grandin
    Noel Grandin

    ๐Ÿ› + Noel Grandin
    Noel Grandin

    ๐Ÿ› Olaf Haalstra
    Olaf Haalstra

    ๐Ÿ› Oleg Andreych
    Oleg Andreych

    ๐Ÿ’ป ๐Ÿ› Oleg Pavlenko
    Oleg Pavlenko

    ๐Ÿ› Oleksii Dykov
    Oleksii Dykov

    ๐Ÿ’ป ๐Ÿ› Oliver Eikemeier
    Oliver Eikemeier

    ๐Ÿ› Oliver Siegmar
    Oliver Siegmar

    ๐Ÿ’ต - Olivier Parent
    Olivier Parent

    ๐Ÿ’ป ๐Ÿ› + Olivier Parent
    Olivier Parent

    ๐Ÿ’ป ๐Ÿ› Ollie Abbey
    Ollie Abbey

    ๐Ÿ’ป ๐Ÿ› Ondrej Kratochvil
    Ondrej Kratochvil

    ๐Ÿ› OverDrone
    OverDrone

    ๐Ÿ› Ozan Gulle
    Ozan Gulle

    ๐Ÿ’ป ๐Ÿ› PUNEET JAIN
    PUNEET JAIN

    ๐Ÿ› Parbati Bose
    Parbati Bose

    ๐Ÿ› - Paul Berg
    Paul Berg

    ๐Ÿ› + Paul Berg
    Paul Berg

    ๐Ÿ› Paul Guyot
    Paul Guyot

    ๐Ÿ’ป Pavel Bludov
    Pavel Bludov

    ๐Ÿ› Pavel Miฤka
    Pavel Miฤka

    ๐Ÿ› Pedro Nuno Santos
    Pedro Nuno Santos

    ๐Ÿ› Pedro Rijo
    Pedro Rijo

    ๐Ÿ› Pelisse Romain
    Pelisse Romain

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› - Per Abich
    Per Abich

    ๐Ÿ’ป + Per Abich
    Per Abich

    ๐Ÿ’ป Pete Davids
    Pete Davids

    ๐Ÿ› Peter Bruin
    Peter Bruin

    ๐Ÿ› Peter Chittum
    Peter Chittum

    ๐Ÿ’ป ๐Ÿ› Peter Cudmore
    Peter Cudmore

    ๐Ÿ› Peter Kasson
    Peter Kasson

    ๐Ÿ› Peter Kofler
    Peter Kofler

    ๐Ÿ› - Peter Paul Bakker
    Peter Paul Bakker

    ๐Ÿ’ป + Peter Paul Bakker
    Peter Paul Bakker

    ๐Ÿ’ป Peter Rader
    Peter Rader

    ๐Ÿ› Pham Hai Trung
    Pham Hai Trung

    ๐Ÿ› Philip Graf
    Philip Graf

    ๐Ÿ’ป ๐Ÿ› Philip Hachey
    Philip Hachey

    ๐Ÿ› Philippe Ozil
    Philippe Ozil

    ๐Ÿ› Phinehas Artemix
    Phinehas Artemix

    ๐Ÿ› - Phokham Nonava
    Phokham Nonava

    ๐Ÿ› + Phokham Nonava
    Phokham Nonava

    ๐Ÿ› Pim van der Loos
    Pim van der Loos

    ๐Ÿ’ป โš ๏ธ Piotr Szymaล„ski
    Piotr Szymaล„ski

    ๐Ÿ› Piotrek ลปygieล‚o
    Piotrek ลปygieล‚o

    ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– Pranay Jaiswal
    Pranay Jaiswal

    ๐Ÿ› Prasad Kamath
    Prasad Kamath

    ๐Ÿ› Prasanna
    Prasanna

    ๐Ÿ› - Presh-AR
    Presh-AR

    ๐Ÿ› + Presh-AR
    Presh-AR

    ๐Ÿ› Puneet1726
    Puneet1726

    ๐Ÿ› RBRi
    RBRi

    ๐Ÿ› Rafael Cortรชs
    Rafael Cortรชs

    ๐Ÿ› RaheemShaik999
    RaheemShaik999

    ๐Ÿ› RajeshR
    RajeshR

    ๐Ÿ’ป ๐Ÿ› Ramachandra Mohan
    Ramachandra Mohan

    ๐Ÿ› - Ramel0921
    Ramel0921

    ๐Ÿ› + Ramel0921
    Ramel0921

    ๐Ÿ› Raquel Pau
    Raquel Pau

    ๐Ÿ› Ravikiran Janardhana
    Ravikiran Janardhana

    ๐Ÿ› Reda Benhemmouche
    Reda Benhemmouche

    ๐Ÿ› Reinhard Schiedermeier
    Reinhard Schiedermeier

    ๐Ÿ› Renato Oliveira
    Renato Oliveira

    ๐Ÿ’ป ๐Ÿ› Rich DiCroce
    Rich DiCroce

    ๐Ÿ› - Richard Corfield
    Richard Corfield

    ๐Ÿ’ป + Richard Corfield
    Richard Corfield

    ๐Ÿ’ป Richard Corfield
    Richard Corfield

    ๐Ÿ› ๐Ÿ’ป Riot R1cket
    Riot R1cket

    ๐Ÿ› Rishabh Jain
    Rishabh Jain

    ๐Ÿ› RishabhDeep Singh
    RishabhDeep Singh

    ๐Ÿ› Rob Baillie
    Rob Baillie

    ๐Ÿ› Robbie Martinus
    Robbie Martinus

    ๐Ÿ’ป ๐Ÿ› - Robert Henry
    Robert Henry

    ๐Ÿ› + Robert Henry
    Robert Henry

    ๐Ÿ› Robert Mihaly
    Robert Mihaly

    ๐Ÿ› Robert Painsi
    Robert Painsi

    ๐Ÿ› Robert Russell
    Robert Russell

    ๐Ÿ› Robert Sรถsemann
    Robert Sรถsemann

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ› Robert Whitebit
    Robert Whitebit

    ๐Ÿ› Robin Richtsfeld
    Robin Richtsfeld

    ๐Ÿ› - Robin Stocker
    Robin Stocker

    ๐Ÿ’ป ๐Ÿ› + Robin Stocker
    Robin Stocker

    ๐Ÿ’ป ๐Ÿ› Robin Wils
    Robin Wils

    ๐Ÿ› RochusOest
    RochusOest

    ๐Ÿ› Rodolfo Noviski
    Rodolfo Noviski

    ๐Ÿ› Rodrigo Casara
    Rodrigo Casara

    ๐Ÿ› Rodrigo Fernandes
    Rodrigo Fernandes

    ๐Ÿ› Roman Salvador
    Roman Salvador

    ๐Ÿ’ป ๐Ÿ› - Ronald Blaschke
    Ronald Blaschke

    ๐Ÿ› + Ronald Blaschke
    Ronald Blaschke

    ๐Ÿ› Rรณbert Papp
    Rรณbert Papp

    ๐Ÿ› Saikat Sengupta
    Saikat Sengupta

    ๐Ÿ› Saksham Handu
    Saksham Handu

    ๐Ÿ› Saladoc
    Saladoc

    ๐Ÿ› Salesforce Bob Lightning
    Salesforce Bob Lightning

    ๐Ÿ› Sam Carlberg
    Sam Carlberg

    ๐Ÿ› - Sascha Riemer
    Sascha Riemer

    ๐Ÿ› + Sascha Riemer
    Sascha Riemer

    ๐Ÿ› Sashko
    Sashko

    ๐Ÿ’ป Satoshi Kubo
    Satoshi Kubo

    ๐Ÿ› Scott Kennedy
    Scott Kennedy

    ๐Ÿ› Scott Wells
    Scott Wells

    ๐Ÿ› ๐Ÿ’ป Scrates1
    Scrates1

    ๐Ÿ› ๐Ÿ’ป Scrsloota
    Scrsloota

    ๐Ÿ’ป - Sebastian Bรถgl
    Sebastian Bรถgl

    ๐Ÿ› + Sebastian Bรถgl
    Sebastian Bรถgl

    ๐Ÿ› Sebastian Davids
    Sebastian Davids

    ๐Ÿ› Sebastian Schuberth
    Sebastian Schuberth

    ๐Ÿ› Sebastian Schwarz
    Sebastian Schwarz

    ๐Ÿ› Seren
    Seren

    ๐Ÿ› ๐Ÿ’ป Sergey Gorbaty
    Sergey Gorbaty

    ๐Ÿ› Sergey Kozlov
    Sergey Kozlov

    ๐Ÿ› - Sergey Yanzin
    Sergey Yanzin

    ๐Ÿ’ป ๐Ÿ› + Sergey Yanzin
    Sergey Yanzin

    ๐Ÿ’ป ๐Ÿ› Seth Wilcox
    Seth Wilcox

    ๐Ÿ’ป Shai Bennathan
    Shai Bennathan

    ๐Ÿ› ๐Ÿ’ป Shubham
    Shubham

    ๐Ÿ’ป ๐Ÿ› Simon Abykov
    Simon Abykov

    ๐Ÿ’ป ๐Ÿ› Simon Xiao
    Simon Xiao

    ๐Ÿ› Srinivasan Venkatachalam
    Srinivasan Venkatachalam

    ๐Ÿ› - Stanislav Gromov
    Stanislav Gromov

    ๐Ÿ› + Stanislav Gromov
    Stanislav Gromov

    ๐Ÿ› Stanislav Myachenkov
    Stanislav Myachenkov

    ๐Ÿ’ป Stefan Birkner
    Stefan Birkner

    ๐Ÿ› Stefan Bohn
    Stefan Bohn

    ๐Ÿ› Stefan Endrullis
    Stefan Endrullis

    ๐Ÿ› Stefan Klรถss-Schuster
    Stefan Klรถss-Schuster

    ๐Ÿ› Stefan Wolf
    Stefan Wolf

    ๐Ÿ› - Stephan H. Wissel
    Stephan H. Wissel

    ๐Ÿ› + Stephan H. Wissel
    Stephan H. Wissel

    ๐Ÿ› Stephen
    Stephen

    ๐Ÿ› Stephen Carter
    Stephen Carter

    ๐Ÿ› Stephen Friedrich
    Stephen Friedrich

    ๐Ÿ› Steve Babula
    Steve Babula

    ๐Ÿ’ป Steven Stearns
    Steven Stearns

    ๐Ÿ› ๐Ÿ’ป Stexxe
    Stexxe

    ๐Ÿ› - Stian Lรฅgstad
    Stian Lรฅgstad

    ๐Ÿ› + Stian Lรฅgstad
    Stian Lรฅgstad

    ๐Ÿ› StuartClayton5
    StuartClayton5

    ๐Ÿ› Supun Arunoda
    Supun Arunoda

    ๐Ÿ› Suren Abrahamyan
    Suren Abrahamyan

    ๐Ÿ› Suvashri
    Suvashri

    ๐Ÿ“– SwatiBGupta1110
    SwatiBGupta1110

    ๐Ÿ› SyedThoufich
    SyedThoufich

    ๐Ÿ› - Szymon Sasin
    Szymon Sasin

    ๐Ÿ› + Szymon Sasin
    Szymon Sasin

    ๐Ÿ› T-chuangxin
    T-chuangxin

    ๐Ÿ› TERAI Atsuhiro
    TERAI Atsuhiro

    ๐Ÿ› TIOBE Software
    TIOBE Software

    ๐Ÿ’ป ๐Ÿ› Tarush Singh
    Tarush Singh

    ๐Ÿ’ป Taylor Smock
    Taylor Smock

    ๐Ÿ› Techeira Damiรกn
    Techeira Damiรกn

    ๐Ÿ’ป ๐Ÿ› - Ted Husted
    Ted Husted

    ๐Ÿ› + Ted Husted
    Ted Husted

    ๐Ÿ› TehBakker
    TehBakker

    ๐Ÿ› The Gitter Badger
    The Gitter Badger

    ๐Ÿ› Theodoor
    Theodoor

    ๐Ÿ› Thiago Henrique Hรผpner
    Thiago Henrique Hรผpner

    ๐Ÿ› Thibault Meyer
    Thibault Meyer

    ๐Ÿ› Thomas Gรผttler
    Thomas Gรผttler

    ๐Ÿ› - Thomas Jones-Low
    Thomas Jones-Low

    ๐Ÿ› + Thomas Jones-Low
    Thomas Jones-Low

    ๐Ÿ› Thomas Smith
    Thomas Smith

    ๐Ÿ’ป ๐Ÿ› ThrawnCA
    ThrawnCA

    ๐Ÿ› Thu Vo
    Thu Vo

    ๐Ÿ› Thunderforge
    Thunderforge

    ๐Ÿ’ป ๐Ÿ› Tim van der Lippe
    Tim van der Lippe

    ๐Ÿ› Tobias Weimer
    Tobias Weimer

    ๐Ÿ’ป ๐Ÿ› - Tom Copeland
    Tom Copeland

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– + Tom Copeland
    Tom Copeland

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– Tom Daly
    Tom Daly

    ๐Ÿ› Tomas
    Tomas

    ๐Ÿ› Tomer Figenblat
    Tomer Figenblat

    ๐Ÿ› Tomi De Lucca
    Tomi De Lucca

    ๐Ÿ’ป ๐Ÿ› Tony
    Tony

    ๐Ÿ“– Torsten Kleiber
    Torsten Kleiber

    ๐Ÿ› - TrackerSB
    TrackerSB

    ๐Ÿ› + TrackerSB
    TrackerSB

    ๐Ÿ› Tyson Stewart
    Tyson Stewart

    ๐Ÿ› Ullrich Hafner
    Ullrich Hafner

    ๐Ÿ› Utku Cuhadaroglu
    Utku Cuhadaroglu

    ๐Ÿ’ป ๐Ÿ› Valentin Brandl
    Valentin Brandl

    ๐Ÿ› Valeria
    Valeria

    ๐Ÿ› Valery Yatsynovich
    Valery Yatsynovich

    ๐Ÿ“– - Vasily Anisimov
    Vasily Anisimov

    ๐Ÿ› + Vasily Anisimov
    Vasily Anisimov

    ๐Ÿ› Vedant Chokshi
    Vedant Chokshi

    ๐Ÿ› Vibhor Goyal
    Vibhor Goyal

    ๐Ÿ› Vickenty Fesunov
    Vickenty Fesunov

    ๐Ÿ› Victor Noรซl
    Victor Noรซl

    ๐Ÿ› Vincent Galloy
    Vincent Galloy

    ๐Ÿ’ป Vincent HUYNH
    Vincent HUYNH

    ๐Ÿ› - Vincent Maurin
    Vincent Maurin

    ๐Ÿ› + Vincent Maurin
    Vincent Maurin

    ๐Ÿ› Vincent Privat
    Vincent Privat

    ๐Ÿ› Vishhwas
    Vishhwas

    ๐Ÿ› Vishv_Android
    Vishv_Android

    ๐Ÿ› Vitaly
    Vitaly

    ๐Ÿ› Vitaly Polonetsky
    Vitaly Polonetsky

    ๐Ÿ› Vojtech Polivka
    Vojtech Polivka

    ๐Ÿ› - Vsevolod Zholobov
    Vsevolod Zholobov

    ๐Ÿ› + Vsevolod Zholobov
    Vsevolod Zholobov

    ๐Ÿ› Vyom Yadav
    Vyom Yadav

    ๐Ÿ’ป Wang Shidong
    Wang Shidong

    ๐Ÿ› Waqas Ahmed
    Waqas Ahmed

    ๐Ÿ› Wayne J. Earl
    Wayne J. Earl

    ๐Ÿ› Wchenghui
    Wchenghui

    ๐Ÿ› Wener
    Wener

    ๐Ÿ’ป - Will Winder
    Will Winder

    ๐Ÿ› + Will Winder
    Will Winder

    ๐Ÿ› William Brockhus
    William Brockhus

    ๐Ÿ’ป ๐Ÿ› Wilson Kurniawan
    Wilson Kurniawan

    ๐Ÿ› Wim Deblauwe
    Wim Deblauwe

    ๐Ÿ› Woongsik Choi
    Woongsik Choi

    ๐Ÿ› XenoAmess
    XenoAmess

    ๐Ÿ’ป ๐Ÿ› Yang
    Yang

    ๐Ÿ’ป - YaroslavTER
    YaroslavTER

    ๐Ÿ› + YaroslavTER
    YaroslavTER

    ๐Ÿ› Yasar Shaikh
    Yasar Shaikh

    ๐Ÿ’ป Young Chan
    Young Chan

    ๐Ÿ’ป ๐Ÿ› YuJin Kim
    YuJin Kim

    ๐Ÿ› Yuri Dolzhenko
    Yuri Dolzhenko

    ๐Ÿ› Yurii Dubinka
    Yurii Dubinka

    ๐Ÿ› Zoltan Farkas
    Zoltan Farkas

    ๐Ÿ› - Zustin
    Zustin

    ๐Ÿ› + Zustin
    Zustin

    ๐Ÿ› aaronhurst-google
    aaronhurst-google

    ๐Ÿ› ๐Ÿ’ป alexmodis
    alexmodis

    ๐Ÿ› andreoss
    andreoss

    ๐Ÿ› andrey81inmd
    andrey81inmd

    ๐Ÿ’ป ๐Ÿ› anicoara
    anicoara

    ๐Ÿ› arunprasathav
    arunprasathav

    ๐Ÿ› - asiercamara
    asiercamara

    ๐Ÿ› + asiercamara
    asiercamara

    ๐Ÿ› astillich-igniti
    astillich-igniti

    ๐Ÿ’ป avesolovksyy
    avesolovksyy

    ๐Ÿ› avishvat
    avishvat

    ๐Ÿ› avivmu
    avivmu

    ๐Ÿ› axelbarfod1
    axelbarfod1

    ๐Ÿ› b-3-n
    b-3-n

    ๐Ÿ› - balbhadra9
    balbhadra9

    ๐Ÿ› + balbhadra9
    balbhadra9

    ๐Ÿ› base23de
    base23de

    ๐Ÿ› bergander
    bergander

    ๐Ÿ› ๐Ÿ’ป berkam
    berkam

    ๐Ÿ’ป ๐Ÿ› breizh31
    breizh31

    ๐Ÿ› caesarkim
    caesarkim

    ๐Ÿ› carolyujing
    carolyujing

    ๐Ÿ› - cbfiddle
    cbfiddle

    ๐Ÿ› + cbfiddle
    cbfiddle

    ๐Ÿ› cesares-basilico
    cesares-basilico

    ๐Ÿ› chrite
    chrite

    ๐Ÿ› ciufudean
    ciufudean

    ๐Ÿ“– cobratbq
    cobratbq

    ๐Ÿ› coladict
    coladict

    ๐Ÿ› cosmoJFH
    cosmoJFH

    ๐Ÿ› - cristalp
    cristalp

    ๐Ÿ› + cristalp
    cristalp

    ๐Ÿ› crunsk
    crunsk

    ๐Ÿ› cwholmes
    cwholmes

    ๐Ÿ› cyberjj999
    cyberjj999

    ๐Ÿ› cyw3
    cyw3

    ๐Ÿ› ๐Ÿ“– d1ss0nanz
    d1ss0nanz

    ๐Ÿ› dague1
    dague1

    ๐Ÿ“– - dalizi007
    dalizi007

    ๐Ÿ’ป + dalizi007
    dalizi007

    ๐Ÿ’ป danbrycefairsailcom
    danbrycefairsailcom

    ๐Ÿ› dariansanity
    dariansanity

    ๐Ÿ› darrenmiliband
    darrenmiliband

    ๐Ÿ› davidburstrom
    davidburstrom

    ๐Ÿ› dbirkman-paloalto
    dbirkman-paloalto

    ๐Ÿ› deepak-patra
    deepak-patra

    ๐Ÿ› - dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› + dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› dinesh150
    dinesh150

    ๐Ÿ› diziaq
    diziaq

    ๐Ÿ› dreaminpast123
    dreaminpast123

    ๐Ÿ› duanyanan
    duanyanan

    ๐Ÿ› dutt-sanjay
    dutt-sanjay

    ๐Ÿ› duursma
    duursma

    ๐Ÿ’ป - dylanleung
    dylanleung

    ๐Ÿ› + dylanleung
    dylanleung

    ๐Ÿ› dzeigler
    dzeigler

    ๐Ÿ› eant60
    eant60

    ๐Ÿ› ekkirala
    ekkirala

    ๐Ÿ› emersonmoura
    emersonmoura

    ๐Ÿ› emouty
    emouty

    ๐Ÿ’ป ๐Ÿ› eugenepugach
    eugenepugach

    ๐Ÿ› - fairy
    fairy

    ๐Ÿ› + fairy
    fairy

    ๐Ÿ› filiprafalowicz
    filiprafalowicz

    ๐Ÿ’ป flxbl-io
    flxbl-io

    ๐Ÿ’ต foxmason
    foxmason

    ๐Ÿ› frankegabor
    frankegabor

    ๐Ÿ› frankl
    frankl

    ๐Ÿ› freafrea
    freafrea

    ๐Ÿ› - fsapatin
    fsapatin

    ๐Ÿ› + fsapatin
    fsapatin

    ๐Ÿ› gearsethenry
    gearsethenry

    ๐Ÿ› gracia19
    gracia19

    ๐Ÿ› gudzpoz
    gudzpoz

    ๐Ÿ› guo fei
    guo fei

    ๐Ÿ› gurmsc5
    gurmsc5

    ๐Ÿ› gwilymatgearset
    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ› - haigsn
    haigsn

    ๐Ÿ› + haigsn
    haigsn

    ๐Ÿ› hemanshu070
    hemanshu070

    ๐Ÿ› henrik242
    henrik242

    ๐Ÿ› hongpuwu
    hongpuwu

    ๐Ÿ› hvbtup
    hvbtup

    ๐Ÿ’ป ๐Ÿ› igniti GmbH
    igniti GmbH

    ๐Ÿ› ilovezfs
    ilovezfs

    ๐Ÿ› - imax-erik
    imax-erik

    ๐Ÿ› + imax-erik
    imax-erik

    ๐Ÿ› itaigilo
    itaigilo

    ๐Ÿ› jakivey32
    jakivey32

    ๐Ÿ› jbennett2091
    jbennett2091

    ๐Ÿ› jcamerin
    jcamerin

    ๐Ÿ› jkeener1
    jkeener1

    ๐Ÿ› jmetertea
    jmetertea

    ๐Ÿ› - johnra2
    johnra2

    ๐Ÿ’ป + johnra2
    johnra2

    ๐Ÿ’ป johnzhao9
    johnzhao9

    ๐Ÿ› josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ› kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ› karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“– karwer
    karwer

    ๐Ÿ› kaulonline
    kaulonline

    ๐Ÿ› - kdaemonv
    kdaemonv

    ๐Ÿ› + kdaemonv
    kdaemonv

    ๐Ÿ› kdebski85
    kdebski85

    ๐Ÿ› ๐Ÿ’ป kenji21
    kenji21

    ๐Ÿ’ป ๐Ÿ› kfranic
    kfranic

    ๐Ÿ› khalidkh
    khalidkh

    ๐Ÿ› koalalam
    koalalam

    ๐Ÿ› krzyk
    krzyk

    ๐Ÿ› - lasselindqvist
    lasselindqvist

    ๐Ÿ› + lasselindqvist
    lasselindqvist

    ๐Ÿ› lgemeinhardt
    lgemeinhardt

    ๐Ÿ› lihuaib
    lihuaib

    ๐Ÿ› liqingjun123
    liqingjun123

    ๐Ÿ› lonelyma1021
    lonelyma1021

    ๐Ÿ› lpeddy
    lpeddy

    ๐Ÿ› lujiefsi
    lujiefsi

    ๐Ÿ’ป - lukelukes
    lukelukes

    ๐Ÿ’ป + lukelukes
    lukelukes

    ๐Ÿ’ป lyriccoder
    lyriccoder

    ๐Ÿ› marcelmore
    marcelmore

    ๐Ÿ› matchbox
    matchbox

    ๐Ÿ› matthiaskraaz
    matthiaskraaz

    ๐Ÿ› meandonlyme
    meandonlyme

    ๐Ÿ› mikesive
    mikesive

    ๐Ÿ› - milossesic
    milossesic

    ๐Ÿ› + milossesic
    milossesic

    ๐Ÿ› mluckam
    mluckam

    ๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
    mohan-chinnappan-n

    ๐Ÿ’ป mriddell95
    mriddell95

    ๐Ÿ› mrlzh
    mrlzh

    ๐Ÿ› msloan
    msloan

    ๐Ÿ› mucharlaravalika
    mucharlaravalika

    ๐Ÿ› - mvenneman
    mvenneman

    ๐Ÿ› + mvenneman
    mvenneman

    ๐Ÿ› nareshl119
    nareshl119

    ๐Ÿ› nicolas-harraudeau-sonarsource
    nicolas-harraudeau-sonarsource

    ๐Ÿ› noerremark
    noerremark

    ๐Ÿ› novsirion
    novsirion

    ๐Ÿ› nwcm
    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
    oggboy

    ๐Ÿ› - oinume
    oinume

    ๐Ÿ› + oinume
    oinume

    ๐Ÿ› orimarko
    orimarko

    ๐Ÿ’ป ๐Ÿ› pablogomez2197
    pablogomez2197

    ๐Ÿ› pacvz
    pacvz

    ๐Ÿ’ป pallavi agarwal
    pallavi agarwal

    ๐Ÿ› parksungrin
    parksungrin

    ๐Ÿ› patpatpat123
    patpatpat123

    ๐Ÿ› - patriksevallius
    patriksevallius

    ๐Ÿ› + patriksevallius
    patriksevallius

    ๐Ÿ› pbrajesh1
    pbrajesh1

    ๐Ÿ› phoenix384
    phoenix384

    ๐Ÿ› piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป plan3d
    plan3d

    ๐Ÿ› poojasix
    poojasix

    ๐Ÿ› prabhushrikant
    prabhushrikant

    ๐Ÿ› - pujitha8783
    pujitha8783

    ๐Ÿ› + pujitha8783
    pujitha8783

    ๐Ÿ› r-r-a-j
    r-r-a-j

    ๐Ÿ› raghujayjunk
    raghujayjunk

    ๐Ÿ› rajeshveera
    rajeshveera

    ๐Ÿ› rajeswarreddy88
    rajeswarreddy88

    ๐Ÿ› recdevs
    recdevs

    ๐Ÿ› reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ› - rijkt
    rijkt

    ๐Ÿ› + rijkt
    rijkt

    ๐Ÿ› rillig-tk
    rillig-tk

    ๐Ÿ› rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ› rnveach
    rnveach

    ๐Ÿ› rxmicro
    rxmicro

    ๐Ÿ› ryan-gustafson
    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ› sabi0
    sabi0

    ๐Ÿ› - scais
    scais

    ๐Ÿ› + scais
    scais

    ๐Ÿ› schosin
    schosin

    ๐Ÿ› screamingfrog
    screamingfrog

    ๐Ÿ’ต sebbASF
    sebbASF

    ๐Ÿ› sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป shilko2013
    shilko2013

    ๐Ÿ› shiomiyan
    shiomiyan

    ๐Ÿ“– - simeonKondr
    simeonKondr

    ๐Ÿ› + simeonKondr
    simeonKondr

    ๐Ÿ› snajberk
    snajberk

    ๐Ÿ› sniperrifle2004
    sniperrifle2004

    ๐Ÿ› snuyanzin
    snuyanzin

    ๐Ÿ› ๐Ÿ’ป soloturn
    soloturn

    ๐Ÿ› soyodream
    soyodream

    ๐Ÿ› sratz
    sratz

    ๐Ÿ› - stonio
    stonio

    ๐Ÿ› + stonio
    stonio

    ๐Ÿ› sturton
    sturton

    ๐Ÿ’ป ๐Ÿ› sudharmohan
    sudharmohan

    ๐Ÿ› suruchidawar
    suruchidawar

    ๐Ÿ› svenfinitiv
    svenfinitiv

    ๐Ÿ› szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป tashiscool
    tashiscool

    ๐Ÿ› - test-git-hook
    test-git-hook

    ๐Ÿ› + test-git-hook
    test-git-hook

    ๐Ÿ› testation21
    testation21

    ๐Ÿ’ป ๐Ÿ› thanosa
    thanosa

    ๐Ÿ› tiandiyixian
    tiandiyixian

    ๐Ÿ› tobwoerk
    tobwoerk

    ๐Ÿ› tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป trentchilders
    trentchilders

    ๐Ÿ› - triandicAnt
    triandicAnt

    ๐Ÿ› + triandicAnt
    triandicAnt

    ๐Ÿ› trishul14
    trishul14

    ๐Ÿ› tsui
    tsui

    ๐Ÿ› wangzitom12306
    wangzitom12306

    ๐Ÿ› winhkey
    winhkey

    ๐Ÿ› witherspore
    witherspore

    ๐Ÿ› wjljack
    wjljack

    ๐Ÿ› - wuchiuwong
    wuchiuwong

    ๐Ÿ› + wuchiuwong
    wuchiuwong

    ๐Ÿ› xingsong
    xingsong

    ๐Ÿ› xioayuge
    xioayuge

    ๐Ÿ› xnYi9wRezm
    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ› xuanuy
    xuanuy

    ๐Ÿ› xyf0921
    xyf0921

    ๐Ÿ› yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› - yasuharu-sato
    yasuharu-sato

    ๐Ÿ› + yasuharu-sato
    yasuharu-sato

    ๐Ÿ› zenglian
    zenglian

    ๐Ÿ› zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› zh3ng
    zh3ng

    ๐Ÿ› zt_soft
    zt_soft

    ๐Ÿ› ztt79
    ztt79

    ๐Ÿ› zzzzfeng
    zzzzfeng

    ๐Ÿ› - รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› + รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› ไปป่ดตๆฐ
    ไปป่ดตๆฐ

    ๐Ÿ› + ๅคฉ็ƒญๅƒ่ฅฟ็“œ
    ๅคฉ็ƒญๅƒ่ฅฟ็“œ

    ๐Ÿ› ่Œ…ๅปถๅฎ‰
    ่Œ…ๅปถๅฎ‰

    ๐Ÿ’ป From 991bc2c41d92de4f9b18cfe67d63870fb9428a2e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 14 Nov 2024 18:12:13 +0100 Subject: [PATCH 0226/1962] [apex] Report LexException when extracting comments --- .../pmd/lang/apex/ast/ApexCommentBuilder.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexCommentBuilder.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexCommentBuilder.java index 48d41f0faa8..7cc9e23f8da 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexCommentBuilder.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexCommentBuilder.java @@ -14,10 +14,14 @@ import java.util.Map; import java.util.RandomAccess; +import org.antlr.v4.runtime.BaseErrorListener; import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.Recognizer; import org.antlr.v4.runtime.Token; import net.sourceforge.pmd.annotation.InternalApi; +import net.sourceforge.pmd.lang.ast.LexException; import net.sourceforge.pmd.lang.document.TextDocument; import net.sourceforge.pmd.lang.document.TextRegion; @@ -106,6 +110,13 @@ public void buildFormalComment(AbstractApexNode node) { private static CommentInformation extractInformationFromComments(TextDocument sourceCode, String suppressMarker) { String source = sourceCode.getText().toString(); ApexLexer lexer = new ApexLexer(new CaseInsensitiveInputStream(CharStreams.fromString(source))); + lexer.removeErrorListeners(); + lexer.addErrorListener(new BaseErrorListener() { + @Override + public void syntaxError(Recognizer recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) { + throw new LexException(line, charPositionInLine, sourceCode.getFileId(), msg, e); + } + }); List allCommentTokens = new ArrayList<>(); Map suppressMap = new HashMap<>(); From 509452577def03f1ae357722204424d0ff53591d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 14 Nov 2024 18:16:06 +0100 Subject: [PATCH 0227/1962] [apex] Add test case for #5333 --- .../sourceforge/pmd/lang/apex/ast/ApexCommentTest.java | 8 ++++++++ .../net/sourceforge/pmd/lang/apex/ast/ApexLexerTest.java | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexCommentTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexCommentTest.java index 728cce62531..6e847170bfe 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexCommentTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexCommentTest.java @@ -66,4 +66,12 @@ void classHasFormalComment() { ASTFormalComment comment = file.descendants(ASTUserClass.class).children(ASTFormalComment.class).first(); assertEquals(FORMAL_COMMENT_CONTENT, comment.getImage()); } + + @Test + void fileWithUnicodeEscapes() { + ASTApexFile file = apex.parse(FORMAL_COMMENT_CONTENT + "\n" + + "class MyClass { String s = 'Fran\\u00E7ois'; }"); + ASTFormalComment comment = file.descendants(ASTUserClass.class).children(ASTFormalComment.class).first(); + assertEquals(FORMAL_COMMENT_CONTENT, comment.getImage()); + } } diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexLexerTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexLexerTest.java index b0751603705..22104ac4010 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexLexerTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexLexerTest.java @@ -57,6 +57,7 @@ void testParser() { @Test void testLexerUnicodeEscapes() { String s = "'Fran\\u00E7ois'"; + // note: with apex-parser 4.3.1, no errors are reported anymore assertEquals(2, getLexingErrors(CharStreams.fromString(s))); assertEquals(0, getLexingErrors(new CaseInsensitiveInputStream(CharStreams.fromString(s)))); } @@ -71,7 +72,7 @@ private int getLexingErrors(CharStream stream) { return errorListener.getErrorCount(); } - static class ErrorListener extends BaseErrorListener { + private static class ErrorListener extends BaseErrorListener { private int errorCount = 0; @Override From 093683bc592e968ae629f7087655575efd394c92 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 14 Nov 2024 18:17:49 +0100 Subject: [PATCH 0228/1962] [doc] Update release notes (#5284, #5333) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 5fa3ac04b69..4a522f95325 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -17,6 +17,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿ› Fixed Issues * ant * [#1860](https://github.com/pmd/pmd/issues/1860): \[ant] Reflective access warnings on java > 9 and java < 17 +* apex + * [#5333](https://github.com/pmd/pmd/issues/5333): \[apex] Token recognition errors for string containing unicode escape sequence * java * [#5293](https://github.com/pmd/pmd/issues/5293): \[java] Deadlock when executing PMD in multiple threads * [#5324](https://github.com/pmd/pmd/issues/5324): \[java] Issue with type inference of nested lambdas @@ -29,6 +31,7 @@ This is a {{ site.pmd.release_type }} release. instead (note different package `ast` instead of `antlr4`). ### โœจ External Contributions +* [#5284](https://github.com/pmd/pmd/pull/5284): \[apex] Use case-insensitive input stream to avoid choking on Unicode escape sequences - [Willem A. Hajenius](https://github.com/wahajenius) (@wahajenius) {% endtocmaker %} From e1d4f27e198beba891a3b4d20e112956229c6e4a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 14 Nov 2024 18:18:06 +0100 Subject: [PATCH 0229/1962] Add @wahajenius as a contributor --- .all-contributorsrc | 9 + docs/pages/pmd/projectdocs/credits.md | 234 +++++++++++++------------- 2 files changed, 127 insertions(+), 116 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 95ebc05d6e1..3ccf2e8784b 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7865,6 +7865,15 @@ "contributions": [ "code" ] + }, + { + "login": "wahajenius", + "name": "Willem A. Hajenius", + "avatar_url": "https://avatars.githubusercontent.com/u/7836322?v=4", + "profile": "https://github.com/wahajenius", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 9497ea73780..8bedbc0f630 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -350,769 +350,771 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d JJengility
    JJengility

    ๐Ÿ› Jake Hemmerle
    Jake Hemmerle

    ๐Ÿ› + Jakub Dupak
    Jakub Dupak

    ๐Ÿ’ป James Harrison
    James Harrison

    ๐Ÿ› ๐Ÿ’ป Jamie Bisotti
    Jamie Bisotti

    ๐Ÿ› Jan
    Jan

    ๐Ÿ› Jan Aertgeerts
    Jan Aertgeerts

    ๐Ÿ’ป ๐Ÿ› - Jan Brรผmmer
    Jan Brรผmmer

    ๐Ÿ› + Jan Brรผmmer
    Jan Brรผmmer

    ๐Ÿ› Jan Tล™รญska
    Jan Tล™รญska

    ๐Ÿ› Jan-Lukas Else
    Jan-Lukas Else

    ๐Ÿ› Jason Qiu
    Jason Qiu

    ๐Ÿ’ป ๐Ÿ“– Jason Williams
    Jason Williams

    ๐Ÿ› Javier Spagnoletti
    Javier Spagnoletti

    ๐Ÿ› Jean-Paul Mayer
    Jean-Paul Mayer

    ๐Ÿ› - Jean-Simon Larochelle
    Jean-Simon Larochelle

    ๐Ÿ› + Jean-Simon Larochelle
    Jean-Simon Larochelle

    ๐Ÿ› Jeff Bartolotta
    Jeff Bartolotta

    ๐Ÿ’ป ๐Ÿ› Jeff Hube
    Jeff Hube

    ๐Ÿ’ป ๐Ÿ› Jeff Jensen
    Jeff Jensen

    ๐Ÿ› Jeff May
    Jeff May

    ๐Ÿ› Jens Gerdes
    Jens Gerdes

    ๐Ÿ› Jeroen Borgers
    Jeroen Borgers

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข - Jeroen Meijer
    Jeroen Meijer

    ๐Ÿ› + Jeroen Meijer
    Jeroen Meijer

    ๐Ÿ› Jeroen van Wilgenburg
    Jeroen van Wilgenburg

    ๐Ÿ“– Jerome Russ
    Jerome Russ

    ๐Ÿ› JerritEic
    JerritEic

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Jiri Pejchal
    Jiri Pejchal

    ๐Ÿ› Jithin Sunny
    Jithin Sunny

    ๐Ÿ› Jiล™รญ ล korpil
    Jiล™รญ ล korpil

    ๐Ÿ› - Joao Machado
    Joao Machado

    ๐Ÿ› + Joao Machado
    Joao Machado

    ๐Ÿ› Jochen Krauss
    Jochen Krauss

    ๐Ÿ› Johan Hammar
    Johan Hammar

    ๐Ÿ› John Karp
    John Karp

    ๐Ÿ› John Zhang
    John Zhang

    ๐Ÿ› John-Teng
    John-Teng

    ๐Ÿ’ป ๐Ÿ› Jon Moroney
    Jon Moroney

    ๐Ÿ’ป ๐Ÿ› - Jonas Geiregat
    Jonas Geiregat

    ๐Ÿ› + Jonas Geiregat
    Jonas Geiregat

    ๐Ÿ› Jonas KeรŸler
    Jonas KeรŸler

    ๐Ÿ› Jonathan Wiesel
    Jonathan Wiesel

    ๐Ÿ’ป ๐Ÿ› Jordan
    Jordan

    ๐Ÿ› Jordi Llach
    Jordi Llach

    ๐Ÿ› Jorge Solรณrzano
    Jorge Solรณrzano

    ๐Ÿ› JorneVL
    JorneVL

    ๐Ÿ› - Jose Palafox
    Jose Palafox

    ๐Ÿ› + Jose Palafox
    Jose Palafox

    ๐Ÿ› Jose Stovall
    Jose Stovall

    ๐Ÿ› Joseph
    Joseph

    ๐Ÿ’ป Joseph Heenan
    Joseph Heenan

    ๐Ÿ› Josh Feingold
    Josh Feingold

    ๐Ÿ’ป ๐Ÿ› Josh Holthaus
    Josh Holthaus

    ๐Ÿ› Joshua S Arquilevich
    Joshua S Arquilevich

    ๐Ÿ› - Joรฃo Dinis Ferreira
    Joรฃo Dinis Ferreira

    ๐Ÿ“– + Joรฃo Dinis Ferreira
    Joรฃo Dinis Ferreira

    ๐Ÿ“– Joรฃo Ferreira
    Joรฃo Ferreira

    ๐Ÿ’ป ๐Ÿ› Joรฃo Pedro Schmitt
    Joรฃo Pedro Schmitt

    ๐Ÿ› Juan Martรญn Sotuyo Dodero
    Juan Martรญn Sotuyo Dodero

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง Juan Pablo Civile
    Juan Pablo Civile

    ๐Ÿ› Julian Voronetsky
    Julian Voronetsky

    ๐Ÿ› Julien
    Julien

    ๐Ÿ› - Julius
    Julius

    ๐Ÿ› + Julius
    Julius

    ๐Ÿ› JustPRV
    JustPRV

    ๐Ÿ› Justin Stroud
    Justin Stroud

    ๐Ÿ’ป Jรถrn Huxhorn
    Jรถrn Huxhorn

    ๐Ÿ› KThompso
    KThompso

    ๐Ÿ› Kai Amundsen
    Kai Amundsen

    ๐Ÿ› Karel Vervaeke
    Karel Vervaeke

    ๐Ÿ› - Karl-Andero Mere
    Karl-Andero Mere

    ๐Ÿ› + Karl-Andero Mere
    Karl-Andero Mere

    ๐Ÿ› Karl-Philipp Richter
    Karl-Philipp Richter

    ๐Ÿ› Karsten Silz
    Karsten Silz

    ๐Ÿ› Kazuma Watanabe
    Kazuma Watanabe

    ๐Ÿ› Kev
    Kev

    ๐Ÿ› Keve Mรผller
    Keve Mรผller

    ๐Ÿ› Kevin Guerra
    Kevin Guerra

    ๐Ÿ’ป - Kevin Jones
    Kevin Jones

    ๐Ÿ› ๐Ÿ’ป + Kevin Jones
    Kevin Jones

    ๐Ÿ› ๐Ÿ’ป Kevin Poorman
    Kevin Poorman

    ๐Ÿ› Kevin Wayne
    Kevin Wayne

    ๐Ÿ› Kieran Black
    Kieran Black

    ๐Ÿ› Kirill Zubov
    Kirill Zubov

    ๐Ÿ› Kirk Clemens
    Kirk Clemens

    ๐Ÿ’ป ๐Ÿ› Klaus Hartl
    Klaus Hartl

    ๐Ÿ› - Koen Van Looveren
    Koen Van Looveren

    ๐Ÿ› + Koen Van Looveren
    Koen Van Looveren

    ๐Ÿ› Kris Scheibe
    Kris Scheibe

    ๐Ÿ’ป ๐Ÿ› Krystian Dabrowski
    Krystian Dabrowski

    ๐Ÿ› ๐Ÿ’ป Kunal Thanki
    Kunal Thanki

    ๐Ÿ› LaLucid
    LaLucid

    ๐Ÿ’ป Larry Diamond
    Larry Diamond

    ๐Ÿ’ป ๐Ÿ› Lars Knickrehm
    Lars Knickrehm

    ๐Ÿ› - Laurent Bovet
    Laurent Bovet

    ๐Ÿ› ๐Ÿ’ป + Laurent Bovet
    Laurent Bovet

    ๐Ÿ› ๐Ÿ’ป Leo Gutierrez
    Leo Gutierrez

    ๐Ÿ› LiGaOg
    LiGaOg

    ๐Ÿ’ป Liam Sharp
    Liam Sharp

    ๐Ÿ› Lintsi
    Lintsi

    ๐Ÿ› Linus Fernandes
    Linus Fernandes

    ๐Ÿ› Lixon Lookose
    Lixon Lookose

    ๐Ÿ› - Logesh
    Logesh

    ๐Ÿ› + Logesh
    Logesh

    ๐Ÿ› Lorenzo Gabriele
    Lorenzo Gabriele

    ๐Ÿ› Loรฏc Ledoyen
    Loรฏc Ledoyen

    ๐Ÿ› Lucas
    Lucas

    ๐Ÿ› Lucas Silva
    Lucas Silva

    ๐Ÿ› Lucas Soncini
    Lucas Soncini

    ๐Ÿ’ป ๐Ÿ› Luis Alcantar
    Luis Alcantar

    ๐Ÿ’ป - Lukas Grรคf
    Lukas Grรคf

    ๐Ÿ’ป + Lukas Grรคf
    Lukas Grรคf

    ๐Ÿ’ป Lukasz Slonina
    Lukasz Slonina

    ๐Ÿ› Lukebray
    Lukebray

    ๐Ÿ› Lynn
    Lynn

    ๐Ÿ’ป ๐Ÿ› Lyor Goldstein
    Lyor Goldstein

    ๐Ÿ› MCMicS
    MCMicS

    ๐Ÿ› Macarse
    Macarse

    ๐Ÿ› - Machine account for PMD
    Machine account for PMD

    ๐Ÿ’ป + Machine account for PMD
    Machine account for PMD

    ๐Ÿ’ป Maciek Siemczyk
    Maciek Siemczyk

    ๐Ÿ› Maikel Steneker
    Maikel Steneker

    ๐Ÿ’ป ๐Ÿ› Maksim Moiseikin
    Maksim Moiseikin

    ๐Ÿ› Manfred Koch
    Manfred Koch

    ๐Ÿ› Manuel Moya Ferrer
    Manuel Moya Ferrer

    ๐Ÿ’ป ๐Ÿ› Manuel Ryan
    Manuel Ryan

    ๐Ÿ› - Marat Vyshegorodtsev
    Marat Vyshegorodtsev

    ๐Ÿ› + Marat Vyshegorodtsev
    Marat Vyshegorodtsev

    ๐Ÿ› Marcel Hรคrle
    Marcel Hรคrle

    ๐Ÿ› Marcello Fialho
    Marcello Fialho

    ๐Ÿ› Marcin Dฤ…browski
    Marcin Dฤ…browski

    ๐Ÿ’ป Marcin Rataj
    Marcin Rataj

    ๐Ÿ› Marcono1234
    Marcono1234

    ๐Ÿ› Mark Adamcin
    Mark Adamcin

    ๐Ÿ› - Mark Hall
    Mark Hall

    ๐Ÿ’ป ๐Ÿ› + Mark Hall
    Mark Hall

    ๐Ÿ’ป ๐Ÿ› Mark Kolich
    Mark Kolich

    ๐Ÿ› Mark Pritchard
    Mark Pritchard

    ๐Ÿ› Markus Rathgeb
    Markus Rathgeb

    ๐Ÿ› Marquis Wang
    Marquis Wang

    ๐Ÿ› MartGit
    MartGit

    ๐Ÿ› Martin Feldsztejn
    Martin Feldsztejn

    ๐Ÿ› - Martin Lehmann
    Martin Lehmann

    ๐Ÿ› + Martin Lehmann
    Martin Lehmann

    ๐Ÿ› Martin Spamer
    Martin Spamer

    ๐Ÿ› Martin Tarjรกnyi
    Martin Tarjรกnyi

    ๐Ÿ› MatFl
    MatFl

    ๐Ÿ› Mateusz Stefanski
    Mateusz Stefanski

    ๐Ÿ› Mathieu Gouin
    Mathieu Gouin

    ๐Ÿ› MatiasComercio
    MatiasComercio

    ๐Ÿ’ป ๐Ÿ› - Matt Benson
    Matt Benson

    ๐Ÿ› + Matt Benson
    Matt Benson

    ๐Ÿ› Matt De Poorter
    Matt De Poorter

    ๐Ÿ› Matt Hargett
    Matt Hargett

    ๐Ÿ’ป ๐Ÿ’ต Matt Harrah
    Matt Harrah

    ๐Ÿ› Matt Nelson
    Matt Nelson

    ๐Ÿ› Matthew Amos
    Matthew Amos

    ๐Ÿ› Matthew Duggan
    Matthew Duggan

    ๐Ÿ› - Matthew Hall
    Matthew Hall

    ๐Ÿ› + Matthew Hall
    Matthew Hall

    ๐Ÿ› Matthew Rossner
    Matthew Rossner

    ๐Ÿ› Matรญas Fraga
    Matรญas Fraga

    ๐Ÿ’ป ๐Ÿ› Maxime Robert
    Maxime Robert

    ๐Ÿ’ป ๐Ÿ› MetaBF
    MetaBF

    ๐Ÿ› Metin Dagcilar
    Metin Dagcilar

    ๐Ÿ› Michael
    Michael

    ๐Ÿ› - Michael Bell
    Michael Bell

    ๐Ÿ› + Michael Bell
    Michael Bell

    ๐Ÿ› Michael Bernstein
    Michael Bernstein

    ๐Ÿ› Michael Clay
    Michael Clay

    ๐Ÿ› Michael Dombrowski
    Michael Dombrowski

    ๐Ÿ› Michael Hausegger
    Michael Hausegger

    ๐Ÿ› Michael Hoefer
    Michael Hoefer

    ๐Ÿ› Michael Kolesnikov
    Michael Kolesnikov

    ๐Ÿ› - Michael Mรถbius
    Michael Mรถbius

    ๐Ÿ› + Michael Mรถbius
    Michael Mรถbius

    ๐Ÿ› Michael N. Lipp
    Michael N. Lipp

    ๐Ÿ› Michael Pellegrini
    Michael Pellegrini

    ๐Ÿ› Michal Kordas
    Michal Kordas

    ๐Ÿ› Michaล‚ Borek
    Michaล‚ Borek

    ๐Ÿ› Michaล‚ Kuliล„ski
    Michaล‚ Kuliล„ski

    ๐Ÿ› Miguel Nรบรฑez Dรญaz-Montes
    Miguel Nรบรฑez Dรญaz-Montes

    ๐Ÿ› - Mihai Ionut
    Mihai Ionut

    ๐Ÿ› + Mihai Ionut
    Mihai Ionut

    ๐Ÿ› Mikhail Kuchma
    Mikhail Kuchma

    ๐Ÿ› Mirek Hankus
    Mirek Hankus

    ๐Ÿ› Mitch Spano
    Mitch Spano

    ๐Ÿ› Mladjan Gadzic
    Mladjan Gadzic

    ๐Ÿ› MrAngry52
    MrAngry52

    ๐Ÿ› Muminur Choudhury
    Muminur Choudhury

    ๐Ÿ› - Mykhailo Palahuta
    Mykhailo Palahuta

    ๐Ÿ’ป ๐Ÿ› + Mykhailo Palahuta
    Mykhailo Palahuta

    ๐Ÿ’ป ๐Ÿ› Nagendra Kumar Singh
    Nagendra Kumar Singh

    ๐Ÿ› Nahuel Barrios
    Nahuel Barrios

    ๐Ÿ› Nakul Sharma
    Nakul Sharma

    ๐Ÿ› Nathan Braun
    Nathan Braun

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› - Nathanaรซl
    Nathanaรซl

    ๐Ÿ› + Nathanaรซl
    Nathanaรซl

    ๐Ÿ› Naveen
    Naveen

    ๐Ÿ’ป Nazdravi
    Nazdravi

    ๐Ÿ› Neha-Dhonde
    Neha-Dhonde

    ๐Ÿ› Nicholas Doyle
    Nicholas Doyle

    ๐Ÿ› Nick Butcher
    Nick Butcher

    ๐Ÿ› Nico Gallinal
    Nico Gallinal

    ๐Ÿ› - Nicola Dal Maso
    Nicola Dal Maso

    ๐Ÿ› + Nicola Dal Maso
    Nicola Dal Maso

    ๐Ÿ› Nicolas Filotto
    Nicolas Filotto

    ๐Ÿ’ป Nicolas Vervelle
    Nicolas Vervelle

    ๐Ÿ› Nicolas Vuillamy
    Nicolas Vuillamy

    ๐Ÿ“– Nikita Chursin
    Nikita Chursin

    ๐Ÿ› Niklas Baudy
    Niklas Baudy

    ๐Ÿ› Nikolas Havrikov
    Nikolas Havrikov

    ๐Ÿ› - Nilesh Virkar
    Nilesh Virkar

    ๐Ÿ› + Nilesh Virkar
    Nilesh Virkar

    ๐Ÿ› Nimit Patel
    Nimit Patel

    ๐Ÿ› Niranjan Harpale
    Niranjan Harpale

    ๐Ÿ› Nirvik Patel
    Nirvik Patel

    ๐Ÿ’ป Noah Sussman
    Noah Sussman

    ๐Ÿ› Noah0120
    Noah0120

    ๐Ÿ› Noam Tamim
    Noam Tamim

    ๐Ÿ› - Noel Grandin
    Noel Grandin

    ๐Ÿ› + Noel Grandin
    Noel Grandin

    ๐Ÿ› Olaf Haalstra
    Olaf Haalstra

    ๐Ÿ› Oleg Andreych
    Oleg Andreych

    ๐Ÿ’ป ๐Ÿ› Oleg Pavlenko
    Oleg Pavlenko

    ๐Ÿ› Oleksii Dykov
    Oleksii Dykov

    ๐Ÿ’ป ๐Ÿ› Oliver Eikemeier
    Oliver Eikemeier

    ๐Ÿ› Oliver Siegmar
    Oliver Siegmar

    ๐Ÿ’ต - Olivier Parent
    Olivier Parent

    ๐Ÿ’ป ๐Ÿ› + Olivier Parent
    Olivier Parent

    ๐Ÿ’ป ๐Ÿ› Ollie Abbey
    Ollie Abbey

    ๐Ÿ’ป ๐Ÿ› Ondrej Kratochvil
    Ondrej Kratochvil

    ๐Ÿ› OverDrone
    OverDrone

    ๐Ÿ› Ozan Gulle
    Ozan Gulle

    ๐Ÿ’ป ๐Ÿ› PUNEET JAIN
    PUNEET JAIN

    ๐Ÿ› Parbati Bose
    Parbati Bose

    ๐Ÿ› - Paul Berg
    Paul Berg

    ๐Ÿ› + Paul Berg
    Paul Berg

    ๐Ÿ› Paul Guyot
    Paul Guyot

    ๐Ÿ’ป Pavel Bludov
    Pavel Bludov

    ๐Ÿ› Pavel Miฤka
    Pavel Miฤka

    ๐Ÿ› Pedro Nuno Santos
    Pedro Nuno Santos

    ๐Ÿ› Pedro Rijo
    Pedro Rijo

    ๐Ÿ› Pelisse Romain
    Pelisse Romain

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› - Per Abich
    Per Abich

    ๐Ÿ’ป + Per Abich
    Per Abich

    ๐Ÿ’ป Pete Davids
    Pete Davids

    ๐Ÿ› Peter Bruin
    Peter Bruin

    ๐Ÿ› Peter Chittum
    Peter Chittum

    ๐Ÿ’ป ๐Ÿ› Peter Cudmore
    Peter Cudmore

    ๐Ÿ› Peter Kasson
    Peter Kasson

    ๐Ÿ› Peter Kofler
    Peter Kofler

    ๐Ÿ› - Peter Paul Bakker
    Peter Paul Bakker

    ๐Ÿ’ป + Peter Paul Bakker
    Peter Paul Bakker

    ๐Ÿ’ป Peter Rader
    Peter Rader

    ๐Ÿ› Pham Hai Trung
    Pham Hai Trung

    ๐Ÿ› Philip Graf
    Philip Graf

    ๐Ÿ’ป ๐Ÿ› Philip Hachey
    Philip Hachey

    ๐Ÿ› Philippe Ozil
    Philippe Ozil

    ๐Ÿ› Phinehas Artemix
    Phinehas Artemix

    ๐Ÿ› - Phokham Nonava
    Phokham Nonava

    ๐Ÿ› + Phokham Nonava
    Phokham Nonava

    ๐Ÿ› Pim van der Loos
    Pim van der Loos

    ๐Ÿ’ป โš ๏ธ Piotr Szymaล„ski
    Piotr Szymaล„ski

    ๐Ÿ› Piotrek ลปygieล‚o
    Piotrek ลปygieล‚o

    ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– Pranay Jaiswal
    Pranay Jaiswal

    ๐Ÿ› Prasad Kamath
    Prasad Kamath

    ๐Ÿ› Prasanna
    Prasanna

    ๐Ÿ› - Presh-AR
    Presh-AR

    ๐Ÿ› + Presh-AR
    Presh-AR

    ๐Ÿ› Puneet1726
    Puneet1726

    ๐Ÿ› RBRi
    RBRi

    ๐Ÿ› Rafael Cortรชs
    Rafael Cortรชs

    ๐Ÿ› RaheemShaik999
    RaheemShaik999

    ๐Ÿ› RajeshR
    RajeshR

    ๐Ÿ’ป ๐Ÿ› Ramachandra Mohan
    Ramachandra Mohan

    ๐Ÿ› - Ramel0921
    Ramel0921

    ๐Ÿ› + Ramel0921
    Ramel0921

    ๐Ÿ› Raquel Pau
    Raquel Pau

    ๐Ÿ› Ravikiran Janardhana
    Ravikiran Janardhana

    ๐Ÿ› Reda Benhemmouche
    Reda Benhemmouche

    ๐Ÿ› Reinhard Schiedermeier
    Reinhard Schiedermeier

    ๐Ÿ› Renato Oliveira
    Renato Oliveira

    ๐Ÿ’ป ๐Ÿ› Rich DiCroce
    Rich DiCroce

    ๐Ÿ› - Richard Corfield
    Richard Corfield

    ๐Ÿ’ป + Richard Corfield
    Richard Corfield

    ๐Ÿ’ป Richard Corfield
    Richard Corfield

    ๐Ÿ› ๐Ÿ’ป Riot R1cket
    Riot R1cket

    ๐Ÿ› Rishabh Jain
    Rishabh Jain

    ๐Ÿ› RishabhDeep Singh
    RishabhDeep Singh

    ๐Ÿ› Rob Baillie
    Rob Baillie

    ๐Ÿ› Robbie Martinus
    Robbie Martinus

    ๐Ÿ’ป ๐Ÿ› - Robert Henry
    Robert Henry

    ๐Ÿ› + Robert Henry
    Robert Henry

    ๐Ÿ› Robert Mihaly
    Robert Mihaly

    ๐Ÿ› Robert Painsi
    Robert Painsi

    ๐Ÿ› Robert Russell
    Robert Russell

    ๐Ÿ› Robert Sรถsemann
    Robert Sรถsemann

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ› Robert Whitebit
    Robert Whitebit

    ๐Ÿ› Robin Richtsfeld
    Robin Richtsfeld

    ๐Ÿ› - Robin Stocker
    Robin Stocker

    ๐Ÿ’ป ๐Ÿ› + Robin Stocker
    Robin Stocker

    ๐Ÿ’ป ๐Ÿ› Robin Wils
    Robin Wils

    ๐Ÿ› RochusOest
    RochusOest

    ๐Ÿ› Rodolfo Noviski
    Rodolfo Noviski

    ๐Ÿ› Rodrigo Casara
    Rodrigo Casara

    ๐Ÿ› Rodrigo Fernandes
    Rodrigo Fernandes

    ๐Ÿ› Roman Salvador
    Roman Salvador

    ๐Ÿ’ป ๐Ÿ› - Ronald Blaschke
    Ronald Blaschke

    ๐Ÿ› + Ronald Blaschke
    Ronald Blaschke

    ๐Ÿ› Rรณbert Papp
    Rรณbert Papp

    ๐Ÿ› Saikat Sengupta
    Saikat Sengupta

    ๐Ÿ› Saksham Handu
    Saksham Handu

    ๐Ÿ› Saladoc
    Saladoc

    ๐Ÿ› Salesforce Bob Lightning
    Salesforce Bob Lightning

    ๐Ÿ› Sam Carlberg
    Sam Carlberg

    ๐Ÿ› - Sascha Riemer
    Sascha Riemer

    ๐Ÿ› + Sascha Riemer
    Sascha Riemer

    ๐Ÿ› Sashko
    Sashko

    ๐Ÿ’ป Satoshi Kubo
    Satoshi Kubo

    ๐Ÿ› Scott Kennedy
    Scott Kennedy

    ๐Ÿ› Scott Wells
    Scott Wells

    ๐Ÿ› ๐Ÿ’ป Scrates1
    Scrates1

    ๐Ÿ› ๐Ÿ’ป Scrsloota
    Scrsloota

    ๐Ÿ’ป - Sebastian Bรถgl
    Sebastian Bรถgl

    ๐Ÿ› + Sebastian Bรถgl
    Sebastian Bรถgl

    ๐Ÿ› Sebastian Davids
    Sebastian Davids

    ๐Ÿ› Sebastian Schuberth
    Sebastian Schuberth

    ๐Ÿ› Sebastian Schwarz
    Sebastian Schwarz

    ๐Ÿ› Seren
    Seren

    ๐Ÿ› ๐Ÿ’ป Sergey Gorbaty
    Sergey Gorbaty

    ๐Ÿ› Sergey Kozlov
    Sergey Kozlov

    ๐Ÿ› - Sergey Yanzin
    Sergey Yanzin

    ๐Ÿ’ป ๐Ÿ› + Sergey Yanzin
    Sergey Yanzin

    ๐Ÿ’ป ๐Ÿ› Seth Wilcox
    Seth Wilcox

    ๐Ÿ’ป Shai Bennathan
    Shai Bennathan

    ๐Ÿ› ๐Ÿ’ป Shubham
    Shubham

    ๐Ÿ’ป ๐Ÿ› Simon Abykov
    Simon Abykov

    ๐Ÿ’ป ๐Ÿ› Simon Xiao
    Simon Xiao

    ๐Ÿ› Srinivasan Venkatachalam
    Srinivasan Venkatachalam

    ๐Ÿ› - Stanislav Gromov
    Stanislav Gromov

    ๐Ÿ› + Stanislav Gromov
    Stanislav Gromov

    ๐Ÿ› Stanislav Myachenkov
    Stanislav Myachenkov

    ๐Ÿ’ป Stefan Birkner
    Stefan Birkner

    ๐Ÿ› Stefan Bohn
    Stefan Bohn

    ๐Ÿ› Stefan Endrullis
    Stefan Endrullis

    ๐Ÿ› Stefan Klรถss-Schuster
    Stefan Klรถss-Schuster

    ๐Ÿ› Stefan Wolf
    Stefan Wolf

    ๐Ÿ› - Stephan H. Wissel
    Stephan H. Wissel

    ๐Ÿ› + Stephan H. Wissel
    Stephan H. Wissel

    ๐Ÿ› Stephen
    Stephen

    ๐Ÿ› Stephen Carter
    Stephen Carter

    ๐Ÿ› Stephen Friedrich
    Stephen Friedrich

    ๐Ÿ› Steve Babula
    Steve Babula

    ๐Ÿ’ป Steven Stearns
    Steven Stearns

    ๐Ÿ› ๐Ÿ’ป Stexxe
    Stexxe

    ๐Ÿ› - Stian Lรฅgstad
    Stian Lรฅgstad

    ๐Ÿ› + Stian Lรฅgstad
    Stian Lรฅgstad

    ๐Ÿ› StuartClayton5
    StuartClayton5

    ๐Ÿ› Supun Arunoda
    Supun Arunoda

    ๐Ÿ› Suren Abrahamyan
    Suren Abrahamyan

    ๐Ÿ› Suvashri
    Suvashri

    ๐Ÿ“– SwatiBGupta1110
    SwatiBGupta1110

    ๐Ÿ› SyedThoufich
    SyedThoufich

    ๐Ÿ› - Szymon Sasin
    Szymon Sasin

    ๐Ÿ› + Szymon Sasin
    Szymon Sasin

    ๐Ÿ› T-chuangxin
    T-chuangxin

    ๐Ÿ› TERAI Atsuhiro
    TERAI Atsuhiro

    ๐Ÿ› TIOBE Software
    TIOBE Software

    ๐Ÿ’ป ๐Ÿ› Tarush Singh
    Tarush Singh

    ๐Ÿ’ป Taylor Smock
    Taylor Smock

    ๐Ÿ› Techeira Damiรกn
    Techeira Damiรกn

    ๐Ÿ’ป ๐Ÿ› - Ted Husted
    Ted Husted

    ๐Ÿ› + Ted Husted
    Ted Husted

    ๐Ÿ› TehBakker
    TehBakker

    ๐Ÿ› The Gitter Badger
    The Gitter Badger

    ๐Ÿ› Theodoor
    Theodoor

    ๐Ÿ› Thiago Henrique Hรผpner
    Thiago Henrique Hรผpner

    ๐Ÿ› Thibault Meyer
    Thibault Meyer

    ๐Ÿ› Thomas Gรผttler
    Thomas Gรผttler

    ๐Ÿ› - Thomas Jones-Low
    Thomas Jones-Low

    ๐Ÿ› + Thomas Jones-Low
    Thomas Jones-Low

    ๐Ÿ› Thomas Smith
    Thomas Smith

    ๐Ÿ’ป ๐Ÿ› ThrawnCA
    ThrawnCA

    ๐Ÿ› Thu Vo
    Thu Vo

    ๐Ÿ› Thunderforge
    Thunderforge

    ๐Ÿ’ป ๐Ÿ› Tim van der Lippe
    Tim van der Lippe

    ๐Ÿ› Tobias Weimer
    Tobias Weimer

    ๐Ÿ’ป ๐Ÿ› - Tom Copeland
    Tom Copeland

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– + Tom Copeland
    Tom Copeland

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– Tom Daly
    Tom Daly

    ๐Ÿ› Tomas
    Tomas

    ๐Ÿ› Tomer Figenblat
    Tomer Figenblat

    ๐Ÿ› Tomi De Lucca
    Tomi De Lucca

    ๐Ÿ’ป ๐Ÿ› Tony
    Tony

    ๐Ÿ“– Torsten Kleiber
    Torsten Kleiber

    ๐Ÿ› - TrackerSB
    TrackerSB

    ๐Ÿ› + TrackerSB
    TrackerSB

    ๐Ÿ› Tyson Stewart
    Tyson Stewart

    ๐Ÿ› Ullrich Hafner
    Ullrich Hafner

    ๐Ÿ› Utku Cuhadaroglu
    Utku Cuhadaroglu

    ๐Ÿ’ป ๐Ÿ› Valentin Brandl
    Valentin Brandl

    ๐Ÿ› Valeria
    Valeria

    ๐Ÿ› Valery Yatsynovich
    Valery Yatsynovich

    ๐Ÿ“– - Vasily Anisimov
    Vasily Anisimov

    ๐Ÿ› + Vasily Anisimov
    Vasily Anisimov

    ๐Ÿ› Vedant Chokshi
    Vedant Chokshi

    ๐Ÿ› Vibhor Goyal
    Vibhor Goyal

    ๐Ÿ› Vickenty Fesunov
    Vickenty Fesunov

    ๐Ÿ› Victor Noรซl
    Victor Noรซl

    ๐Ÿ› Vincent Galloy
    Vincent Galloy

    ๐Ÿ’ป Vincent HUYNH
    Vincent HUYNH

    ๐Ÿ› - Vincent Maurin
    Vincent Maurin

    ๐Ÿ› + Vincent Maurin
    Vincent Maurin

    ๐Ÿ› Vincent Privat
    Vincent Privat

    ๐Ÿ› Vishhwas
    Vishhwas

    ๐Ÿ› Vishv_Android
    Vishv_Android

    ๐Ÿ› Vitaly
    Vitaly

    ๐Ÿ› Vitaly Polonetsky
    Vitaly Polonetsky

    ๐Ÿ› Vojtech Polivka
    Vojtech Polivka

    ๐Ÿ› - Vsevolod Zholobov
    Vsevolod Zholobov

    ๐Ÿ› + Vsevolod Zholobov
    Vsevolod Zholobov

    ๐Ÿ› Vyom Yadav
    Vyom Yadav

    ๐Ÿ’ป Wang Shidong
    Wang Shidong

    ๐Ÿ› Waqas Ahmed
    Waqas Ahmed

    ๐Ÿ› Wayne J. Earl
    Wayne J. Earl

    ๐Ÿ› Wchenghui
    Wchenghui

    ๐Ÿ› Wener
    Wener

    ๐Ÿ’ป - Will Winder
    Will Winder

    ๐Ÿ› + Will Winder
    Will Winder

    ๐Ÿ› + Willem A. Hajenius
    Willem A. Hajenius

    ๐Ÿ’ป William Brockhus
    William Brockhus

    ๐Ÿ’ป ๐Ÿ› Wilson Kurniawan
    Wilson Kurniawan

    ๐Ÿ› Wim Deblauwe
    Wim Deblauwe

    ๐Ÿ› Woongsik Choi
    Woongsik Choi

    ๐Ÿ› XenoAmess
    XenoAmess

    ๐Ÿ’ป ๐Ÿ› - Yang
    Yang

    ๐Ÿ’ป - YaroslavTER
    YaroslavTER

    ๐Ÿ› + Yang
    Yang

    ๐Ÿ’ป + YaroslavTER
    YaroslavTER

    ๐Ÿ› Yasar Shaikh
    Yasar Shaikh

    ๐Ÿ’ป Young Chan
    Young Chan

    ๐Ÿ’ป ๐Ÿ› YuJin Kim
    YuJin Kim

    ๐Ÿ› Yuri Dolzhenko
    Yuri Dolzhenko

    ๐Ÿ› Yurii Dubinka
    Yurii Dubinka

    ๐Ÿ› - Zoltan Farkas
    Zoltan Farkas

    ๐Ÿ› - Zustin
    Zustin

    ๐Ÿ› + Zoltan Farkas
    Zoltan Farkas

    ๐Ÿ› + Zustin
    Zustin

    ๐Ÿ› aaronhurst-google
    aaronhurst-google

    ๐Ÿ› ๐Ÿ’ป alexmodis
    alexmodis

    ๐Ÿ› andreoss
    andreoss

    ๐Ÿ› andrey81inmd
    andrey81inmd

    ๐Ÿ’ป ๐Ÿ› anicoara
    anicoara

    ๐Ÿ› - arunprasathav
    arunprasathav

    ๐Ÿ› - asiercamara
    asiercamara

    ๐Ÿ› + arunprasathav
    arunprasathav

    ๐Ÿ› + asiercamara
    asiercamara

    ๐Ÿ› astillich-igniti
    astillich-igniti

    ๐Ÿ’ป avesolovksyy
    avesolovksyy

    ๐Ÿ› avishvat
    avishvat

    ๐Ÿ› avivmu
    avivmu

    ๐Ÿ› axelbarfod1
    axelbarfod1

    ๐Ÿ› - b-3-n
    b-3-n

    ๐Ÿ› - balbhadra9
    balbhadra9

    ๐Ÿ› + b-3-n
    b-3-n

    ๐Ÿ› + balbhadra9
    balbhadra9

    ๐Ÿ› base23de
    base23de

    ๐Ÿ› bergander
    bergander

    ๐Ÿ› ๐Ÿ’ป berkam
    berkam

    ๐Ÿ’ป ๐Ÿ› breizh31
    breizh31

    ๐Ÿ› caesarkim
    caesarkim

    ๐Ÿ› - carolyujing
    carolyujing

    ๐Ÿ› - cbfiddle
    cbfiddle

    ๐Ÿ› + carolyujing
    carolyujing

    ๐Ÿ› + cbfiddle
    cbfiddle

    ๐Ÿ› cesares-basilico
    cesares-basilico

    ๐Ÿ› chrite
    chrite

    ๐Ÿ› ciufudean
    ciufudean

    ๐Ÿ“– cobratbq
    cobratbq

    ๐Ÿ› coladict
    coladict

    ๐Ÿ› - cosmoJFH
    cosmoJFH

    ๐Ÿ› - cristalp
    cristalp

    ๐Ÿ› + cosmoJFH
    cosmoJFH

    ๐Ÿ› + cristalp
    cristalp

    ๐Ÿ› crunsk
    crunsk

    ๐Ÿ› cwholmes
    cwholmes

    ๐Ÿ› cyberjj999
    cyberjj999

    ๐Ÿ› cyw3
    cyw3

    ๐Ÿ› ๐Ÿ“– d1ss0nanz
    d1ss0nanz

    ๐Ÿ› - dague1
    dague1

    ๐Ÿ“– - dalizi007
    dalizi007

    ๐Ÿ’ป + dague1
    dague1

    ๐Ÿ“– + dalizi007
    dalizi007

    ๐Ÿ’ป danbrycefairsailcom
    danbrycefairsailcom

    ๐Ÿ› dariansanity
    dariansanity

    ๐Ÿ› darrenmiliband
    darrenmiliband

    ๐Ÿ› davidburstrom
    davidburstrom

    ๐Ÿ› dbirkman-paloalto
    dbirkman-paloalto

    ๐Ÿ› - deepak-patra
    deepak-patra

    ๐Ÿ› - dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› + deepak-patra
    deepak-patra

    ๐Ÿ› + dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› dinesh150
    dinesh150

    ๐Ÿ› diziaq
    diziaq

    ๐Ÿ› dreaminpast123
    dreaminpast123

    ๐Ÿ› duanyanan
    duanyanan

    ๐Ÿ› dutt-sanjay
    dutt-sanjay

    ๐Ÿ› - duursma
    duursma

    ๐Ÿ’ป - dylanleung
    dylanleung

    ๐Ÿ› + duursma
    duursma

    ๐Ÿ’ป + dylanleung
    dylanleung

    ๐Ÿ› dzeigler
    dzeigler

    ๐Ÿ› eant60
    eant60

    ๐Ÿ› ekkirala
    ekkirala

    ๐Ÿ› emersonmoura
    emersonmoura

    ๐Ÿ› emouty
    emouty

    ๐Ÿ’ป ๐Ÿ› - eugenepugach
    eugenepugach

    ๐Ÿ› - fairy
    fairy

    ๐Ÿ› + eugenepugach
    eugenepugach

    ๐Ÿ› + fairy
    fairy

    ๐Ÿ› filiprafalowicz
    filiprafalowicz

    ๐Ÿ’ป flxbl-io
    flxbl-io

    ๐Ÿ’ต foxmason
    foxmason

    ๐Ÿ› frankegabor
    frankegabor

    ๐Ÿ› frankl
    frankl

    ๐Ÿ› - freafrea
    freafrea

    ๐Ÿ› - fsapatin
    fsapatin

    ๐Ÿ› + freafrea
    freafrea

    ๐Ÿ› + fsapatin
    fsapatin

    ๐Ÿ› gearsethenry
    gearsethenry

    ๐Ÿ› gracia19
    gracia19

    ๐Ÿ› gudzpoz
    gudzpoz

    ๐Ÿ› guo fei
    guo fei

    ๐Ÿ› gurmsc5
    gurmsc5

    ๐Ÿ› - gwilymatgearset
    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ› - haigsn
    haigsn

    ๐Ÿ› + gwilymatgearset
    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ› + haigsn
    haigsn

    ๐Ÿ› hemanshu070
    hemanshu070

    ๐Ÿ› henrik242
    henrik242

    ๐Ÿ› hongpuwu
    hongpuwu

    ๐Ÿ› hvbtup
    hvbtup

    ๐Ÿ’ป ๐Ÿ› igniti GmbH
    igniti GmbH

    ๐Ÿ› - ilovezfs
    ilovezfs

    ๐Ÿ› - imax-erik
    imax-erik

    ๐Ÿ› + ilovezfs
    ilovezfs

    ๐Ÿ› + imax-erik
    imax-erik

    ๐Ÿ› itaigilo
    itaigilo

    ๐Ÿ› jakivey32
    jakivey32

    ๐Ÿ› jbennett2091
    jbennett2091

    ๐Ÿ› jcamerin
    jcamerin

    ๐Ÿ› jkeener1
    jkeener1

    ๐Ÿ› - jmetertea
    jmetertea

    ๐Ÿ› - johnra2
    johnra2

    ๐Ÿ’ป + jmetertea
    jmetertea

    ๐Ÿ› + johnra2
    johnra2

    ๐Ÿ’ป johnzhao9
    johnzhao9

    ๐Ÿ› josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ› kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ› karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“– karwer
    karwer

    ๐Ÿ› - kaulonline
    kaulonline

    ๐Ÿ› - kdaemonv
    kdaemonv

    ๐Ÿ› + kaulonline
    kaulonline

    ๐Ÿ› + kdaemonv
    kdaemonv

    ๐Ÿ› kdebski85
    kdebski85

    ๐Ÿ› ๐Ÿ’ป kenji21
    kenji21

    ๐Ÿ’ป ๐Ÿ› kfranic
    kfranic

    ๐Ÿ› khalidkh
    khalidkh

    ๐Ÿ› koalalam
    koalalam

    ๐Ÿ› - krzyk
    krzyk

    ๐Ÿ› - lasselindqvist
    lasselindqvist

    ๐Ÿ› + krzyk
    krzyk

    ๐Ÿ› + lasselindqvist
    lasselindqvist

    ๐Ÿ› lgemeinhardt
    lgemeinhardt

    ๐Ÿ› lihuaib
    lihuaib

    ๐Ÿ› liqingjun123
    liqingjun123

    ๐Ÿ› lonelyma1021
    lonelyma1021

    ๐Ÿ› lpeddy
    lpeddy

    ๐Ÿ› - lujiefsi
    lujiefsi

    ๐Ÿ’ป - lukelukes
    lukelukes

    ๐Ÿ’ป + lujiefsi
    lujiefsi

    ๐Ÿ’ป + lukelukes
    lukelukes

    ๐Ÿ’ป lyriccoder
    lyriccoder

    ๐Ÿ› marcelmore
    marcelmore

    ๐Ÿ› matchbox
    matchbox

    ๐Ÿ› matthiaskraaz
    matthiaskraaz

    ๐Ÿ› meandonlyme
    meandonlyme

    ๐Ÿ› - mikesive
    mikesive

    ๐Ÿ› - milossesic
    milossesic

    ๐Ÿ› + mikesive
    mikesive

    ๐Ÿ› + milossesic
    milossesic

    ๐Ÿ› mluckam
    mluckam

    ๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
    mohan-chinnappan-n

    ๐Ÿ’ป mriddell95
    mriddell95

    ๐Ÿ› mrlzh
    mrlzh

    ๐Ÿ› msloan
    msloan

    ๐Ÿ› - mucharlaravalika
    mucharlaravalika

    ๐Ÿ› - mvenneman
    mvenneman

    ๐Ÿ› + mucharlaravalika
    mucharlaravalika

    ๐Ÿ› + mvenneman
    mvenneman

    ๐Ÿ› nareshl119
    nareshl119

    ๐Ÿ› nicolas-harraudeau-sonarsource
    nicolas-harraudeau-sonarsource

    ๐Ÿ› noerremark
    noerremark

    ๐Ÿ› novsirion
    novsirion

    ๐Ÿ› nwcm
    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป - oggboy
    oggboy

    ๐Ÿ› - oinume
    oinume

    ๐Ÿ› + oggboy
    oggboy

    ๐Ÿ› + oinume
    oinume

    ๐Ÿ› orimarko
    orimarko

    ๐Ÿ’ป ๐Ÿ› pablogomez2197
    pablogomez2197

    ๐Ÿ› pacvz
    pacvz

    ๐Ÿ’ป pallavi agarwal
    pallavi agarwal

    ๐Ÿ› parksungrin
    parksungrin

    ๐Ÿ› - patpatpat123
    patpatpat123

    ๐Ÿ› - patriksevallius
    patriksevallius

    ๐Ÿ› + patpatpat123
    patpatpat123

    ๐Ÿ› + patriksevallius
    patriksevallius

    ๐Ÿ› pbrajesh1
    pbrajesh1

    ๐Ÿ› phoenix384
    phoenix384

    ๐Ÿ› piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป plan3d
    plan3d

    ๐Ÿ› poojasix
    poojasix

    ๐Ÿ› - prabhushrikant
    prabhushrikant

    ๐Ÿ› - pujitha8783
    pujitha8783

    ๐Ÿ› + prabhushrikant
    prabhushrikant

    ๐Ÿ› + pujitha8783
    pujitha8783

    ๐Ÿ› r-r-a-j
    r-r-a-j

    ๐Ÿ› raghujayjunk
    raghujayjunk

    ๐Ÿ› rajeshveera
    rajeshveera

    ๐Ÿ› rajeswarreddy88
    rajeswarreddy88

    ๐Ÿ› recdevs
    recdevs

    ๐Ÿ› - reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ› - rijkt
    rijkt

    ๐Ÿ› + reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ› + rijkt
    rijkt

    ๐Ÿ› rillig-tk
    rillig-tk

    ๐Ÿ› rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ› rnveach
    rnveach

    ๐Ÿ› rxmicro
    rxmicro

    ๐Ÿ› ryan-gustafson
    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ› - sabi0
    sabi0

    ๐Ÿ› - scais
    scais

    ๐Ÿ› + sabi0
    sabi0

    ๐Ÿ› + scais
    scais

    ๐Ÿ› schosin
    schosin

    ๐Ÿ› screamingfrog
    screamingfrog

    ๐Ÿ’ต sebbASF
    sebbASF

    ๐Ÿ› sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป shilko2013
    shilko2013

    ๐Ÿ› - shiomiyan
    shiomiyan

    ๐Ÿ“– - simeonKondr
    simeonKondr

    ๐Ÿ› + shiomiyan
    shiomiyan

    ๐Ÿ“– + simeonKondr
    simeonKondr

    ๐Ÿ› snajberk
    snajberk

    ๐Ÿ› sniperrifle2004
    sniperrifle2004

    ๐Ÿ› snuyanzin
    snuyanzin

    ๐Ÿ› ๐Ÿ’ป soloturn
    soloturn

    ๐Ÿ› soyodream
    soyodream

    ๐Ÿ› - sratz
    sratz

    ๐Ÿ› - stonio
    stonio

    ๐Ÿ› + sratz
    sratz

    ๐Ÿ› + stonio
    stonio

    ๐Ÿ› sturton
    sturton

    ๐Ÿ’ป ๐Ÿ› sudharmohan
    sudharmohan

    ๐Ÿ› suruchidawar
    suruchidawar

    ๐Ÿ› svenfinitiv
    svenfinitiv

    ๐Ÿ› szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป - tashiscool
    tashiscool

    ๐Ÿ› - test-git-hook
    test-git-hook

    ๐Ÿ› + tashiscool
    tashiscool

    ๐Ÿ› + test-git-hook
    test-git-hook

    ๐Ÿ› testation21
    testation21

    ๐Ÿ’ป ๐Ÿ› thanosa
    thanosa

    ๐Ÿ› tiandiyixian
    tiandiyixian

    ๐Ÿ› tobwoerk
    tobwoerk

    ๐Ÿ› tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป - trentchilders
    trentchilders

    ๐Ÿ› - triandicAnt
    triandicAnt

    ๐Ÿ› + trentchilders
    trentchilders

    ๐Ÿ› + triandicAnt
    triandicAnt

    ๐Ÿ› trishul14
    trishul14

    ๐Ÿ› tsui
    tsui

    ๐Ÿ› wangzitom12306
    wangzitom12306

    ๐Ÿ› winhkey
    winhkey

    ๐Ÿ› witherspore
    witherspore

    ๐Ÿ› - wjljack
    wjljack

    ๐Ÿ› - wuchiuwong
    wuchiuwong

    ๐Ÿ› + wjljack
    wjljack

    ๐Ÿ› + wuchiuwong
    wuchiuwong

    ๐Ÿ› xingsong
    xingsong

    ๐Ÿ› xioayuge
    xioayuge

    ๐Ÿ› xnYi9wRezm
    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ› xuanuy
    xuanuy

    ๐Ÿ› xyf0921
    xyf0921

    ๐Ÿ› - yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› - yasuharu-sato
    yasuharu-sato

    ๐Ÿ› + yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› + yasuharu-sato
    yasuharu-sato

    ๐Ÿ› zenglian
    zenglian

    ๐Ÿ› zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› zh3ng
    zh3ng

    ๐Ÿ› zt_soft
    zt_soft

    ๐Ÿ› ztt79
    ztt79

    ๐Ÿ› - zzzzfeng
    zzzzfeng

    ๐Ÿ› - รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› + zzzzfeng
    zzzzfeng

    ๐Ÿ› + รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› ไปป่ดตๆฐ
    ไปป่ดตๆฐ

    ๐Ÿ› ่Œ…ๅปถๅฎ‰
    ่Œ…ๅปถๅฎ‰

    ๐Ÿ’ป From 6d19bd97f75f6ef0c3c33b99a874374b856aaf47 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 14 Nov 2024 19:02:33 +0100 Subject: [PATCH 0230/1962] [java] UnitTestShouldIncludeAssert - consider SoftAssertionsExtension Fixes #4113 --- docs/pages/release_notes.md | 2 + .../UnitTestShouldIncludeAssertRule.java | 27 +++++++++++-- .../rule/internal/TestFrameworksUtil.java | 2 +- .../xml/UnitTestShouldIncludeAssert.xml | 38 +++++++++++++++++++ 4 files changed, 65 insertions(+), 4 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 4a522f95325..957b4717eed 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -22,6 +22,8 @@ This is a {{ site.pmd.release_type }} release. * java * [#5293](https://github.com/pmd/pmd/issues/5293): \[java] Deadlock when executing PMD in multiple threads * [#5324](https://github.com/pmd/pmd/issues/5324): \[java] Issue with type inference of nested lambdas +* java-bestpractices + * [#4113](https://github.com/pmd/pmd/issues/4113): \[java] JUnitTestsShouldIncludeAssert - false positive with SoftAssertionsExtension ### ๐Ÿšจ API Changes diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertRule.java index dc21c4fb1ac..f2e860682a8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertRule.java @@ -5,13 +5,18 @@ package net.sourceforge.pmd.lang.java.rule.bestpractices; import java.util.Set; +import java.util.function.Predicate; import java.util.stream.Collectors; +import net.sourceforge.pmd.lang.java.ast.ASTAnnotation; import net.sourceforge.pmd.lang.java.ast.ASTBlock; +import net.sourceforge.pmd.lang.java.ast.ASTClassLiteral; import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; import net.sourceforge.pmd.lang.java.rule.internal.TestFrameworksUtil; +import net.sourceforge.pmd.lang.java.types.TypeTestUtil; import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.properties.PropertyFactory; @@ -31,16 +36,32 @@ public UnitTestShouldIncludeAssertRule() { @Override public Object visit(ASTMethodDeclaration method, Object data) { - ASTBlock body = method.getBody(); + boolean usesSoftAssertExtension = usesSoftAssertExtension(method.getEnclosingType()); Set extraAsserts = getProperty(EXTRA_ASSERT_METHOD_NAMES); + Predicate isAssertCall = usesSoftAssertExtension + ? TestFrameworksUtil::isSoftAssert + : TestFrameworksUtil::isProbableAssertCall; + + ASTBlock body = method.getBody(); if (body != null && TestFrameworksUtil.isTestMethod(method) && !TestFrameworksUtil.isExpectAnnotated(method) && body.descendants(ASTMethodCall.class) - .none(call -> TestFrameworksUtil.isProbableAssertCall(call) - || extraAsserts.contains(call.getMethodName()))) { + .none(isAssertCall + .or(call -> extraAsserts.contains(call.getMethodName())))) { asCtx(data).addViolation(method); } return data; } + + private boolean usesSoftAssertExtension(ASTTypeDeclaration typeDeclaration) { + ASTAnnotation extendWith = typeDeclaration.getAnnotation("org.junit.jupiter.api.extension.ExtendWith"); + if (extendWith == null) { + return false; + } + return extendWith.getFlatValue("value") + .filterIs(ASTClassLiteral.class) + .map(ASTClassLiteral::getTypeNode) + .any(c -> TypeTestUtil.isA("org.assertj.core.api.junit.jupiter.SoftAssertionsExtension", c)); + } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java index cbb4c83810b..95e2f9777d8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java @@ -180,7 +180,7 @@ public static boolean isProbableAssertCall(ASTMethodCall call) { || isExpectExceptionCall(call); } - private static boolean isSoftAssert(ASTMethodCall call) { + public static boolean isSoftAssert(ASTMethodCall call) { JTypeMirror declaringType = call.getMethodType().getDeclaringType(); return (TypeTestUtil.isA("org.assertj.core.api.StandardSoftAssertionsProvider", declaringType) || TypeTestUtil.isA("org.assertj.core.api.Java6StandardSoftAssertionsProvider", declaringType) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldIncludeAssert.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldIncludeAssert.xml index fa6a664f3cb..2d0de33aa64 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldIncludeAssert.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldIncludeAssert.xml @@ -804,6 +804,44 @@ class ShouldIncludeAssertTest { } } +]]> + + + + #4113 [java] JUnitTestsShouldIncludeAssert - false positive with SoftAssertionsExtension + 1 + 27 + { + softly2.assertThat(false).isTrue(); + softly2.assertThat(true).isFalse(); + }); + } + + @Test + void falseNegative() { + // no assertion at all + } +} ]]> From 32f55e22e3df43e3442b8077752d404b2f18eea2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 14 Nov 2024 19:18:11 +0100 Subject: [PATCH 0231/1962] [doc] Update release notes (#5329, #5330) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 5fa3ac04b69..44f31cb3cc8 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -20,6 +20,7 @@ This is a {{ site.pmd.release_type }} release. * java * [#5293](https://github.com/pmd/pmd/issues/5293): \[java] Deadlock when executing PMD in multiple threads * [#5324](https://github.com/pmd/pmd/issues/5324): \[java] Issue with type inference of nested lambdas + * [#5329](https://github.com/pmd/pmd/issues/5329): \[java] Type inference issue with unknown method ref in call chain ### ๐Ÿšจ API Changes From c1cdf4ec02fc160e0d20af7bc187f1a6119fb260 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 14 Nov 2024 19:45:27 +0100 Subject: [PATCH 0232/1962] Simplify if statement --- .../UnitTestShouldIncludeAssertRule.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertRule.java index f2e860682a8..755fb02b003 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertRule.java @@ -56,12 +56,9 @@ public Object visit(ASTMethodDeclaration method, Object data) { private boolean usesSoftAssertExtension(ASTTypeDeclaration typeDeclaration) { ASTAnnotation extendWith = typeDeclaration.getAnnotation("org.junit.jupiter.api.extension.ExtendWith"); - if (extendWith == null) { - return false; - } - return extendWith.getFlatValue("value") - .filterIs(ASTClassLiteral.class) - .map(ASTClassLiteral::getTypeNode) - .any(c -> TypeTestUtil.isA("org.assertj.core.api.junit.jupiter.SoftAssertionsExtension", c)); + return extendWith != null && extendWith.getFlatValue("value") + .filterIs(ASTClassLiteral.class) + .map(ASTClassLiteral::getTypeNode) + .any(c -> TypeTestUtil.isA("org.assertj.core.api.junit.jupiter.SoftAssertionsExtension", c)); } } From 0d606a7122a4eeb7952e689391ef81ac4d4f631d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Thu, 14 Nov 2024 16:39:09 -0300 Subject: [PATCH 0233/1962] Prevent auxiliary grammars from generating lexers - A misconfiguration of Antlr4 produced an auxiliary gramma (UnicodeClasses), that was imported into the main kotlin grammar, to produce it's own Lexer, which was never used. - We no longer produce that Lexer, properly moving imports to the standard directory for that. - We manually copy a generated version for API compatibility, flagging it as both Generated and Deprecated for removal in PMD 8 --- pmd-kotlin/pom.xml | 3 - .../kotlin/ast => imports}/UnicodeClasses.g4 | 0 .../ast => imports}/UnicodeClasses.tokens | 0 .../pmd/lang/kotlin/ast/UnicodeClasses.java | 393 ++++++++++++++++++ 4 files changed, 393 insertions(+), 3 deletions(-) rename pmd-kotlin/src/main/antlr4/{net/sourceforge/pmd/lang/kotlin/ast => imports}/UnicodeClasses.g4 (100%) rename pmd-kotlin/src/main/antlr4/{net/sourceforge/pmd/lang/kotlin/ast => imports}/UnicodeClasses.tokens (100%) create mode 100644 pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index db57e025849..85a26cf1d7c 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -26,9 +26,6 @@ org.antlr antlr4-maven-plugin - - src/main/antlr4/net/sourceforge/pmd/lang/kotlin/ast - org.apache.maven.plugins diff --git a/pmd-kotlin/src/main/antlr4/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.g4 b/pmd-kotlin/src/main/antlr4/imports/UnicodeClasses.g4 similarity index 100% rename from pmd-kotlin/src/main/antlr4/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.g4 rename to pmd-kotlin/src/main/antlr4/imports/UnicodeClasses.g4 diff --git a/pmd-kotlin/src/main/antlr4/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.tokens b/pmd-kotlin/src/main/antlr4/imports/UnicodeClasses.tokens similarity index 100% rename from pmd-kotlin/src/main/antlr4/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.tokens rename to pmd-kotlin/src/main/antlr4/imports/UnicodeClasses.tokens diff --git a/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java b/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java new file mode 100644 index 00000000000..14066ae367b --- /dev/null +++ b/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java @@ -0,0 +1,393 @@ +// Generated from net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.g4 by ANTLR 4.9.3 +package net.sourceforge.pmd.lang.kotlin.ast; + +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.RuntimeMetaData; +import org.antlr.v4.runtime.Vocabulary; +import org.antlr.v4.runtime.VocabularyImpl; +import org.antlr.v4.runtime.atn.ATN; +import org.antlr.v4.runtime.atn.ATNDeserializer; +import org.antlr.v4.runtime.atn.LexerATNSimulator; +import org.antlr.v4.runtime.atn.PredictionContextCache; +import org.antlr.v4.runtime.dfa.DFA; + +/** + * @deprecated This class was never intended to be generated. It will be removed with no replacement. + */ + +@Deprecated +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) +@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") +public class UnicodeClasses extends Lexer { + static { RuntimeMetaData.checkVersion("4.9.3", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + UNICODE_CLASS_LL=1, UNICODE_CLASS_LM=2, UNICODE_CLASS_LO=3, UNICODE_CLASS_LT=4, + UNICODE_CLASS_LU=5, UNICODE_CLASS_ND=6, UNICODE_CLASS_NL=7; + public static String[] channelNames = { + "DEFAULT_TOKEN_CHANNEL", "HIDDEN" + }; + + public static String[] modeNames = { + "DEFAULT_MODE" + }; + + private static String[] makeRuleNames() { + return new String[] { + "UNICODE_CLASS_LL", "UNICODE_CLASS_LM", "UNICODE_CLASS_LO", "UNICODE_CLASS_LT", + "UNICODE_CLASS_LU", "UNICODE_CLASS_ND", "UNICODE_CLASS_NL" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, "UNICODE_CLASS_LL", "UNICODE_CLASS_LM", "UNICODE_CLASS_LO", "UNICODE_CLASS_LT", + "UNICODE_CLASS_LU", "UNICODE_CLASS_ND", "UNICODE_CLASS_NL" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + + public UnicodeClasses(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @Override + public String getGrammarFileName() { return "UnicodeClasses.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public String[] getChannelNames() { return channelNames; } + + @Override + public String[] getModeNames() { return modeNames; } + + @Override + public ATN getATN() { return _ATN; } + + public static final String _serializedATN = + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\t\37\b\1\4\2\t\2"+ + "\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\3\2\3\2\3\3\3\3\3\4\3"+ + "\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\2\2\t\3\3\5\4\7\5\t\6\13\7\r\b\17\t"+ + "\3\2\t\u0248\2c|\u00b7\u00b7\u00e1\u00f8\u00fa\u0101\u0103\u0103\u0105"+ + "\u0105\u0107\u0107\u0109\u0109\u010b\u010b\u010d\u010d\u010f\u010f\u0111"+ + "\u0111\u0113\u0113\u0115\u0115\u0117\u0117\u0119\u0119\u011b\u011b\u011d"+ + "\u011d\u011f\u011f\u0121\u0121\u0123\u0123\u0125\u0125\u0127\u0127\u0129"+ + "\u0129\u012b\u012b\u012d\u012d\u012f\u012f\u0131\u0131\u0133\u0133\u0135"+ + "\u0135\u0137\u0137\u0139\u013a\u013c\u013c\u013e\u013e\u0140\u0140\u0142"+ + "\u0142\u0144\u0144\u0146\u0146\u0148\u0148\u014a\u014b\u014d\u014d\u014f"+ + "\u014f\u0151\u0151\u0153\u0153\u0155\u0155\u0157\u0157\u0159\u0159\u015b"+ + "\u015b\u015d\u015d\u015f\u015f\u0161\u0161\u0163\u0163\u0165\u0165\u0167"+ + "\u0167\u0169\u0169\u016b\u016b\u016d\u016d\u016f\u016f\u0171\u0171\u0173"+ + "\u0173\u0175\u0175\u0177\u0177\u0179\u0179\u017c\u017c\u017e\u017e\u0180"+ + "\u0182\u0185\u0185\u0187\u0187\u018a\u018a\u018e\u018f\u0194\u0194\u0197"+ + "\u0197\u019b\u019d\u01a0\u01a0\u01a3\u01a3\u01a5\u01a5\u01a7\u01a7\u01aa"+ + "\u01aa\u01ac\u01ad\u01af\u01af\u01b2\u01b2\u01b6\u01b6\u01b8\u01b8\u01bb"+ + "\u01bc\u01bf\u01c1\u01c8\u01c8\u01cb\u01cb\u01ce\u01ce\u01d0\u01d0\u01d2"+ + "\u01d2\u01d4\u01d4\u01d6\u01d6\u01d8\u01d8\u01da\u01da\u01dc\u01dc\u01de"+ + "\u01df\u01e1\u01e1\u01e3\u01e3\u01e5\u01e5\u01e7\u01e7\u01e9\u01e9\u01eb"+ + "\u01eb\u01ed\u01ed\u01ef\u01ef\u01f1\u01f2\u01f5\u01f5\u01f7\u01f7\u01fb"+ + "\u01fb\u01fd\u01fd\u01ff\u01ff\u0201\u0201\u0203\u0203\u0205\u0205\u0207"+ + "\u0207\u0209\u0209\u020b\u020b\u020d\u020d\u020f\u020f\u0211\u0211\u0213"+ + "\u0213\u0215\u0215\u0217\u0217\u0219\u0219\u021b\u021b\u021d\u021d\u021f"+ + "\u021f\u0221\u0221\u0223\u0223\u0225\u0225\u0227\u0227\u0229\u0229\u022b"+ + "\u022b\u022d\u022d\u022f\u022f\u0231\u0231\u0233\u0233\u0235\u023b\u023e"+ + "\u023e\u0241\u0242\u0244\u0244\u0249\u0249\u024b\u024b\u024d\u024d\u024f"+ + "\u024f\u0251\u0295\u0297\u02b1\u0373\u0373\u0375\u0375\u0379\u0379\u037d"+ + "\u037f\u0392\u0392\u03ae\u03d0\u03d2\u03d3\u03d7\u03d9\u03db\u03db\u03dd"+ + "\u03dd\u03df\u03df\u03e1\u03e1\u03e3\u03e3\u03e5\u03e5\u03e7\u03e7\u03e9"+ + "\u03e9\u03eb\u03eb\u03ed\u03ed\u03ef\u03ef\u03f1\u03f5\u03f7\u03f7\u03fa"+ + "\u03fa\u03fd\u03fe\u0432\u0461\u0463\u0463\u0465\u0465\u0467\u0467\u0469"+ + "\u0469\u046b\u046b\u046d\u046d\u046f\u046f\u0471\u0471\u0473\u0473\u0475"+ + "\u0475\u0477\u0477\u0479\u0479\u047b\u047b\u047d\u047d\u047f\u047f\u0481"+ + "\u0481\u0483\u0483\u048d\u048d\u048f\u048f\u0491\u0491\u0493\u0493\u0495"+ + "\u0495\u0497\u0497\u0499\u0499\u049b\u049b\u049d\u049d\u049f\u049f\u04a1"+ + "\u04a1\u04a3\u04a3\u04a5\u04a5\u04a7\u04a7\u04a9\u04a9\u04ab\u04ab\u04ad"+ + "\u04ad\u04af\u04af\u04b1\u04b1\u04b3\u04b3\u04b5\u04b5\u04b7\u04b7\u04b9"+ + "\u04b9\u04bb\u04bb\u04bd\u04bd\u04bf\u04bf\u04c1\u04c1\u04c4\u04c4\u04c6"+ + "\u04c6\u04c8\u04c8\u04ca\u04ca\u04cc\u04cc\u04ce\u04ce\u04d0\u04d1\u04d3"+ + "\u04d3\u04d5\u04d5\u04d7\u04d7\u04d9\u04d9\u04db\u04db\u04dd\u04dd\u04df"+ + "\u04df\u04e1\u04e1\u04e3\u04e3\u04e5\u04e5\u04e7\u04e7\u04e9\u04e9\u04eb"+ + "\u04eb\u04ed\u04ed\u04ef\u04ef\u04f1\u04f1\u04f3\u04f3\u04f5\u04f5\u04f7"+ + "\u04f7\u04f9\u04f9\u04fb\u04fb\u04fd\u04fd\u04ff\u04ff\u0501\u0501\u0503"+ + "\u0503\u0505\u0505\u0507\u0507\u0509\u0509\u050b\u050b\u050d\u050d\u050f"+ + "\u050f\u0511\u0511\u0513\u0513\u0515\u0515\u0517\u0517\u0519\u0519\u051b"+ + "\u051b\u051d\u051d\u051f\u051f\u0521\u0521\u0523\u0523\u0525\u0525\u0527"+ + "\u0527\u0529\u0529\u0563\u0589\u1d02\u1d2d\u1d6d\u1d79\u1d7b\u1d9c\u1e03"+ + "\u1e03\u1e05\u1e05\u1e07\u1e07\u1e09\u1e09\u1e0b\u1e0b\u1e0d\u1e0d\u1e0f"+ + "\u1e0f\u1e11\u1e11\u1e13\u1e13\u1e15\u1e15\u1e17\u1e17\u1e19\u1e19\u1e1b"+ + "\u1e1b\u1e1d\u1e1d\u1e1f\u1e1f\u1e21\u1e21\u1e23\u1e23\u1e25\u1e25\u1e27"+ + "\u1e27\u1e29\u1e29\u1e2b\u1e2b\u1e2d\u1e2d\u1e2f\u1e2f\u1e31\u1e31\u1e33"+ + "\u1e33\u1e35\u1e35\u1e37\u1e37\u1e39\u1e39\u1e3b\u1e3b\u1e3d\u1e3d\u1e3f"+ + "\u1e3f\u1e41\u1e41\u1e43\u1e43\u1e45\u1e45\u1e47\u1e47\u1e49\u1e49\u1e4b"+ + "\u1e4b\u1e4d\u1e4d\u1e4f\u1e4f\u1e51\u1e51\u1e53\u1e53\u1e55\u1e55\u1e57"+ + "\u1e57\u1e59\u1e59\u1e5b\u1e5b\u1e5d\u1e5d\u1e5f\u1e5f\u1e61\u1e61\u1e63"+ + "\u1e63\u1e65\u1e65\u1e67\u1e67\u1e69\u1e69\u1e6b\u1e6b\u1e6d\u1e6d\u1e6f"+ + "\u1e6f\u1e71\u1e71\u1e73\u1e73\u1e75\u1e75\u1e77\u1e77\u1e79\u1e79\u1e7b"+ + "\u1e7b\u1e7d\u1e7d\u1e7f\u1e7f\u1e81\u1e81\u1e83\u1e83\u1e85\u1e85\u1e87"+ + "\u1e87\u1e89\u1e89\u1e8b\u1e8b\u1e8d\u1e8d\u1e8f\u1e8f\u1e91\u1e91\u1e93"+ + "\u1e93\u1e95\u1e95\u1e97\u1e9f\u1ea1\u1ea1\u1ea3\u1ea3\u1ea5\u1ea5\u1ea7"+ + "\u1ea7\u1ea9\u1ea9\u1eab\u1eab\u1ead\u1ead\u1eaf\u1eaf\u1eb1\u1eb1\u1eb3"+ + "\u1eb3\u1eb5\u1eb5\u1eb7\u1eb7\u1eb9\u1eb9\u1ebb\u1ebb\u1ebd\u1ebd\u1ebf"+ + "\u1ebf\u1ec1\u1ec1\u1ec3\u1ec3\u1ec5\u1ec5\u1ec7\u1ec7\u1ec9\u1ec9\u1ecb"+ + "\u1ecb\u1ecd\u1ecd\u1ecf\u1ecf\u1ed1\u1ed1\u1ed3\u1ed3\u1ed5\u1ed5\u1ed7"+ + "\u1ed7\u1ed9\u1ed9\u1edb\u1edb\u1edd\u1edd\u1edf\u1edf\u1ee1\u1ee1\u1ee3"+ + "\u1ee3\u1ee5\u1ee5\u1ee7\u1ee7\u1ee9\u1ee9\u1eeb\u1eeb\u1eed\u1eed\u1eef"+ + "\u1eef\u1ef1\u1ef1\u1ef3\u1ef3\u1ef5\u1ef5\u1ef7\u1ef7\u1ef9\u1ef9\u1efb"+ + "\u1efb\u1efd\u1efd\u1eff\u1eff\u1f01\u1f09\u1f12\u1f17\u1f22\u1f29\u1f32"+ + "\u1f39\u1f42\u1f47\u1f52\u1f59\u1f62\u1f69\u1f72\u1f7f\u1f82\u1f89\u1f92"+ + "\u1f99\u1fa2\u1fa9\u1fb2\u1fb6\u1fb8\u1fb9\u1fc0\u1fc0\u1fc4\u1fc6\u1fc8"+ + "\u1fc9\u1fd2\u1fd5\u1fd8\u1fd9\u1fe2\u1fe9\u1ff4\u1ff6\u1ff8\u1ff9\u210c"+ + "\u210c\u2110\u2111\u2115\u2115\u2131\u2131\u2136\u2136\u213b\u213b\u213e"+ + "\u213f\u2148\u214b\u2150\u2150\u2186\u2186\u2c32\u2c60\u2c63\u2c63\u2c67"+ + "\u2c68\u2c6a\u2c6a\u2c6c\u2c6c\u2c6e\u2c6e\u2c73\u2c73\u2c75\u2c76\u2c78"+ + "\u2c7d\u2c83\u2c83\u2c85\u2c85\u2c87\u2c87\u2c89\u2c89\u2c8b\u2c8b\u2c8d"+ + "\u2c8d\u2c8f\u2c8f\u2c91\u2c91\u2c93\u2c93\u2c95\u2c95\u2c97\u2c97\u2c99"+ + "\u2c99\u2c9b\u2c9b\u2c9d\u2c9d\u2c9f\u2c9f\u2ca1\u2ca1\u2ca3\u2ca3\u2ca5"+ + "\u2ca5\u2ca7\u2ca7\u2ca9\u2ca9\u2cab\u2cab\u2cad\u2cad\u2caf\u2caf\u2cb1"+ + "\u2cb1\u2cb3\u2cb3\u2cb5\u2cb5\u2cb7\u2cb7\u2cb9\u2cb9\u2cbb\u2cbb\u2cbd"+ + "\u2cbd\u2cbf\u2cbf\u2cc1\u2cc1\u2cc3\u2cc3\u2cc5\u2cc5\u2cc7\u2cc7\u2cc9"+ + "\u2cc9\u2ccb\u2ccb\u2ccd\u2ccd\u2ccf\u2ccf\u2cd1\u2cd1\u2cd3\u2cd3\u2cd5"+ + "\u2cd5\u2cd7\u2cd7\u2cd9\u2cd9\u2cdb\u2cdb\u2cdd\u2cdd\u2cdf\u2cdf\u2ce1"+ + "\u2ce1\u2ce3\u2ce3\u2ce5\u2ce6\u2cee\u2cee\u2cf0\u2cf0\u2cf5\u2cf5\u2d02"+ + "\u2d27\u2d29\u2d29\u2d2f\u2d2f\ua643\ua643\ua645\ua645\ua647\ua647\ua649"+ + "\ua649\ua64b\ua64b\ua64d\ua64d\ua64f\ua64f\ua651\ua651\ua653\ua653\ua655"+ + "\ua655\ua657\ua657\ua659\ua659\ua65b\ua65b\ua65d\ua65d\ua65f\ua65f\ua661"+ + "\ua661\ua663\ua663\ua665\ua665\ua667\ua667\ua669\ua669\ua66b\ua66b\ua66d"+ + "\ua66d\ua66f\ua66f\ua683\ua683\ua685\ua685\ua687\ua687\ua689\ua689\ua68b"+ + "\ua68b\ua68d\ua68d\ua68f\ua68f\ua691\ua691\ua693\ua693\ua695\ua695\ua697"+ + "\ua697\ua699\ua699\ua725\ua725\ua727\ua727\ua729\ua729\ua72b\ua72b\ua72d"+ + "\ua72d\ua72f\ua72f\ua731\ua733\ua735\ua735\ua737\ua737\ua739\ua739\ua73b"+ + "\ua73b\ua73d\ua73d\ua73f\ua73f\ua741\ua741\ua743\ua743\ua745\ua745\ua747"+ + "\ua747\ua749\ua749\ua74b\ua74b\ua74d\ua74d\ua74f\ua74f\ua751\ua751\ua753"+ + "\ua753\ua755\ua755\ua757\ua757\ua759\ua759\ua75b\ua75b\ua75d\ua75d\ua75f"+ + "\ua75f\ua761\ua761\ua763\ua763\ua765\ua765\ua767\ua767\ua769\ua769\ua76b"+ + "\ua76b\ua76d\ua76d\ua76f\ua76f\ua771\ua771\ua773\ua77a\ua77c\ua77c\ua77e"+ + "\ua77e\ua781\ua781\ua783\ua783\ua785\ua785\ua787\ua787\ua789\ua789\ua78e"+ + "\ua78e\ua790\ua790\ua793\ua793\ua795\ua795\ua7a3\ua7a3\ua7a5\ua7a5\ua7a7"+ + "\ua7a7\ua7a9\ua7a9\ua7ab\ua7ab\ua7fc\ua7fc\ufb02\ufb08\ufb15\ufb19\uff43"+ + "\uff5c\65\2\u02b2\u02c3\u02c8\u02d3\u02e2\u02e6\u02ee\u02ee\u02f0\u02f0"+ + "\u0376\u0376\u037c\u037c\u055b\u055b\u0642\u0642\u06e7\u06e8\u07f6\u07f7"+ + "\u07fc\u07fc\u081c\u081c\u0826\u0826\u082a\u082a\u0973\u0973\u0e48\u0e48"+ + "\u0ec8\u0ec8\u10fe\u10fe\u17d9\u17d9\u1845\u1845\u1aa9\u1aa9\u1c7a\u1c7f"+ + "\u1d2e\u1d6c\u1d7a\u1d7a\u1d9d\u1dc1\u2073\u2073\u2081\u2081\u2092\u209e"+ + "\u2c7e\u2c7f\u2d71\u2d71\u2e31\u2e31\u3007\u3007\u3033\u3037\u303d\u303d"+ + "\u309f\u30a0\u30fe\u3100\ua017\ua017\ua4fa\ua4ff\ua60e\ua60e\ua681\ua681"+ + "\ua719\ua721\ua772\ua772\ua78a\ua78a\ua7fa\ua7fb\ua9d1\ua9d1\uaa72\uaa72"+ + "\uaadf\uaadf\uaaf5\uaaf6\uff72\uff72\uffa0\uffa1\u0123\2\u00ac\u00ac\u00bc"+ + "\u00bc\u01bd\u01bd\u01c2\u01c5\u0296\u0296\u05d2\u05ec\u05f2\u05f4\u0622"+ + "\u0641\u0643\u064c\u0670\u0671\u0673\u06d5\u06d7\u06d7\u06f0\u06f1\u06fc"+ + "\u06fe\u0701\u0701\u0712\u0712\u0714\u0731\u074f\u07a7\u07b3\u07b3\u07cc"+ + "\u07ec\u0802\u0817\u0842\u085a\u08a2\u08a2\u08a4\u08ae\u0906\u093b\u093f"+ + "\u093f\u0952\u0952\u095a\u0963\u0974\u0979\u097b\u0981\u0987\u098e\u0991"+ + "\u0992\u0995\u09aa\u09ac\u09b2\u09b4\u09b4\u09b8\u09bb\u09bf\u09bf\u09d0"+ + "\u09d0\u09de\u09df\u09e1\u09e3\u09f2\u09f3\u0a07\u0a0c\u0a11\u0a12\u0a15"+ + "\u0a2a\u0a2c\u0a32\u0a34\u0a35\u0a37\u0a38\u0a3a\u0a3b\u0a5b\u0a5e\u0a60"+ + "\u0a60\u0a74\u0a76\u0a87\u0a8f\u0a91\u0a93\u0a95\u0aaa\u0aac\u0ab2\u0ab4"+ + "\u0ab5\u0ab7\u0abb\u0abf\u0abf\u0ad2\u0ad2\u0ae2\u0ae3\u0b07\u0b0e\u0b11"+ + "\u0b12\u0b15\u0b2a\u0b2c\u0b32\u0b34\u0b35\u0b37\u0b3b\u0b3f\u0b3f\u0b5e"+ + "\u0b5f\u0b61\u0b63\u0b73\u0b73\u0b85\u0b85\u0b87\u0b8c\u0b90\u0b92\u0b94"+ + "\u0b97\u0b9b\u0b9c\u0b9e\u0b9e\u0ba0\u0ba1\u0ba5\u0ba6\u0baa\u0bac\u0bb0"+ + "\u0bbb\u0bd2\u0bd2\u0c07\u0c0e\u0c10\u0c12\u0c14\u0c2a\u0c2c\u0c35\u0c37"+ + "\u0c3b\u0c3f\u0c3f\u0c5a\u0c5b\u0c62\u0c63\u0c87\u0c8e\u0c90\u0c92\u0c94"+ + "\u0caa\u0cac\u0cb5\u0cb7\u0cbb\u0cbf\u0cbf\u0ce0\u0ce0\u0ce2\u0ce3\u0cf3"+ + "\u0cf4\u0d07\u0d0e\u0d10\u0d12\u0d14\u0d3c\u0d3f\u0d3f\u0d50\u0d50\u0d62"+ + "\u0d63\u0d7c\u0d81\u0d87\u0d98\u0d9c\u0db3\u0db5\u0dbd\u0dbf\u0dbf\u0dc2"+ + "\u0dc8\u0e03\u0e32\u0e34\u0e35\u0e42\u0e47\u0e83\u0e84\u0e86\u0e86\u0e89"+ + "\u0e8a\u0e8c\u0e8c\u0e8f\u0e8f\u0e96\u0e99\u0e9b\u0ea1\u0ea3\u0ea5\u0ea7"+ + "\u0ea7\u0ea9\u0ea9\u0eac\u0ead\u0eaf\u0eb2\u0eb4\u0eb5\u0ebf\u0ebf\u0ec2"+ + "\u0ec6\u0ede\u0ee1\u0f02\u0f02\u0f42\u0f49\u0f4b\u0f6e\u0f8a\u0f8e\u1002"+ + "\u102c\u1041\u1041\u1052\u1057\u105c\u105f\u1063\u1063\u1067\u1068\u1070"+ + "\u1072\u1077\u1083\u1090\u1090\u10d2\u10fc\u10ff\u124a\u124c\u124f\u1252"+ + "\u1258\u125a\u125a\u125c\u125f\u1262\u128a\u128c\u128f\u1292\u12b2\u12b4"+ + "\u12b7\u12ba\u12c0\u12c2\u12c2\u12c4\u12c7\u12ca\u12d8\u12da\u1312\u1314"+ + "\u1317\u131a\u135c\u1382\u1391\u13a2\u13f6\u1403\u166e\u1671\u1681\u1683"+ + "\u169c\u16a2\u16ec\u1702\u170e\u1710\u1713\u1722\u1733\u1742\u1753\u1762"+ + "\u176e\u1770\u1772\u1782\u17b5\u17de\u17de\u1822\u1844\u1846\u1879\u1882"+ + "\u18aa\u18ac\u18ac\u18b2\u18f7\u1902\u191e\u1952\u196f\u1972\u1976\u1982"+ + "\u19ad\u19c3\u19c9\u1a02\u1a18\u1a22\u1a56\u1b07\u1b35\u1b47\u1b4d\u1b85"+ + "\u1ba2\u1bb0\u1bb1\u1bbc\u1be7\u1c02\u1c25\u1c4f\u1c51\u1c5c\u1c79\u1ceb"+ + "\u1cee\u1cf0\u1cf3\u1cf7\u1cf8\u2137\u213a\u2d32\u2d69\u2d82\u2d98\u2da2"+ + "\u2da8\u2daa\u2db0\u2db2\u2db8\u2dba\u2dc0\u2dc2\u2dc8\u2dca\u2dd0\u2dd2"+ + "\u2dd8\u2dda\u2de0\u3008\u3008\u303e\u303e\u3043\u3098\u30a1\u30a1\u30a3"+ + "\u30fc\u3101\u3101\u3107\u312f\u3133\u3190\u31a2\u31bc\u31f2\u3201\u3402"+ + "\u3402\u4db7\u4db7\u4e02\u4e02\u9fce\u9fce\ua002\ua016\ua018\ua48e\ua4d2"+ + "\ua4f9\ua502\ua60d\ua612\ua621\ua62c\ua62d\ua670\ua670\ua6a2\ua6e7\ua7fd"+ + "\ua803\ua805\ua807\ua809\ua80c\ua80e\ua824\ua842\ua875\ua884\ua8b5\ua8f4"+ + "\ua8f9\ua8fd\ua8fd\ua90c\ua927\ua932\ua948\ua962\ua97e\ua986\ua9b4\uaa02"+ + "\uaa2a\uaa42\uaa44\uaa46\uaa4d\uaa62\uaa71\uaa73\uaa78\uaa7c\uaa7c\uaa82"+ + "\uaab1\uaab3\uaab3\uaab7\uaab8\uaabb\uaabf\uaac2\uaac2\uaac4\uaac4\uaadd"+ + "\uaade\uaae2\uaaec\uaaf4\uaaf4\uab03\uab08\uab0b\uab10\uab13\uab18\uab22"+ + "\uab28\uab2a\uab30\uabc2\uabe4\uac02\uac02\ud7a5\ud7a5\ud7b2\ud7c8\ud7cd"+ + "\ud7fd\uf902\ufa6f\ufa72\ufadb\ufb1f\ufb1f\ufb21\ufb2a\ufb2c\ufb38\ufb3a"+ + "\ufb3e\ufb40\ufb40\ufb42\ufb43\ufb45\ufb46\ufb48\ufbb3\ufbd5\ufd3f\ufd52"+ + "\ufd91\ufd94\ufdc9\ufdf2\ufdfd\ufe72\ufe76\ufe78\ufefe\uff68\uff71\uff73"+ + "\uff9f\uffa2\uffc0\uffc4\uffc9\uffcc\uffd1\uffd4\uffd9\uffdc\uffde\f\2"+ + "\u01c7\u01c7\u01ca\u01ca\u01cd\u01cd\u01f4\u01f4\u1f8a\u1f91\u1f9a\u1fa1"+ + "\u1faa\u1fb1\u1fbe\u1fbe\u1fce\u1fce\u1ffe\u1ffe\u0242\2C\\\u00c2\u00d8"+ + "\u00da\u00e0\u0102\u0102\u0104\u0104\u0106\u0106\u0108\u0108\u010a\u010a"+ + "\u010c\u010c\u010e\u010e\u0110\u0110\u0112\u0112\u0114\u0114\u0116\u0116"+ + "\u0118\u0118\u011a\u011a\u011c\u011c\u011e\u011e\u0120\u0120\u0122\u0122"+ + "\u0124\u0124\u0126\u0126\u0128\u0128\u012a\u012a\u012c\u012c\u012e\u012e"+ + "\u0130\u0130\u0132\u0132\u0134\u0134\u0136\u0136\u0138\u0138\u013b\u013b"+ + "\u013d\u013d\u013f\u013f\u0141\u0141\u0143\u0143\u0145\u0145\u0147\u0147"+ + "\u0149\u0149\u014c\u014c\u014e\u014e\u0150\u0150\u0152\u0152\u0154\u0154"+ + "\u0156\u0156\u0158\u0158\u015a\u015a\u015c\u015c\u015e\u015e\u0160\u0160"+ + "\u0162\u0162\u0164\u0164\u0166\u0166\u0168\u0168\u016a\u016a\u016c\u016c"+ + "\u016e\u016e\u0170\u0170\u0172\u0172\u0174\u0174\u0176\u0176\u0178\u0178"+ + "\u017a\u017b\u017d\u017d\u017f\u017f\u0183\u0184\u0186\u0186\u0188\u0189"+ + "\u018b\u018d\u0190\u0193\u0195\u0196\u0198\u019a\u019e\u019f\u01a1\u01a2"+ + "\u01a4\u01a4\u01a6\u01a6\u01a8\u01a9\u01ab\u01ab\u01ae\u01ae\u01b0\u01b1"+ + "\u01b3\u01b5\u01b7\u01b7\u01b9\u01ba\u01be\u01be\u01c6\u01c6\u01c9\u01c9"+ + "\u01cc\u01cc\u01cf\u01cf\u01d1\u01d1\u01d3\u01d3\u01d5\u01d5\u01d7\u01d7"+ + "\u01d9\u01d9\u01db\u01db\u01dd\u01dd\u01e0\u01e0\u01e2\u01e2\u01e4\u01e4"+ + "\u01e6\u01e6\u01e8\u01e8\u01ea\u01ea\u01ec\u01ec\u01ee\u01ee\u01f0\u01f0"+ + "\u01f3\u01f3\u01f6\u01f6\u01f8\u01fa\u01fc\u01fc\u01fe\u01fe\u0200\u0200"+ + "\u0202\u0202\u0204\u0204\u0206\u0206\u0208\u0208\u020a\u020a\u020c\u020c"+ + "\u020e\u020e\u0210\u0210\u0212\u0212\u0214\u0214\u0216\u0216\u0218\u0218"+ + "\u021a\u021a\u021c\u021c\u021e\u021e\u0220\u0220\u0222\u0222\u0224\u0224"+ + "\u0226\u0226\u0228\u0228\u022a\u022a\u022c\u022c\u022e\u022e\u0230\u0230"+ + "\u0232\u0232\u0234\u0234\u023c\u023d\u023f\u0240\u0243\u0243\u0245\u0248"+ + "\u024a\u024a\u024c\u024c\u024e\u024e\u0250\u0250\u0372\u0372\u0374\u0374"+ + "\u0378\u0378\u0388\u0388\u038a\u038c\u038e\u038e\u0390\u0391\u0393\u03a3"+ + "\u03a5\u03ad\u03d1\u03d1\u03d4\u03d6\u03da\u03da\u03dc\u03dc\u03de\u03de"+ + "\u03e0\u03e0\u03e2\u03e2\u03e4\u03e4\u03e6\u03e6\u03e8\u03e8\u03ea\u03ea"+ + "\u03ec\u03ec\u03ee\u03ee\u03f0\u03f0\u03f6\u03f6\u03f9\u03f9\u03fb\u03fc"+ + "\u03ff\u0431\u0462\u0462\u0464\u0464\u0466\u0466\u0468\u0468\u046a\u046a"+ + "\u046c\u046c\u046e\u046e\u0470\u0470\u0472\u0472\u0474\u0474\u0476\u0476"+ + "\u0478\u0478\u047a\u047a\u047c\u047c\u047e\u047e\u0480\u0480\u0482\u0482"+ + "\u048c\u048c\u048e\u048e\u0490\u0490\u0492\u0492\u0494\u0494\u0496\u0496"+ + "\u0498\u0498\u049a\u049a\u049c\u049c\u049e\u049e\u04a0\u04a0\u04a2\u04a2"+ + "\u04a4\u04a4\u04a6\u04a6\u04a8\u04a8\u04aa\u04aa\u04ac\u04ac\u04ae\u04ae"+ + "\u04b0\u04b0\u04b2\u04b2\u04b4\u04b4\u04b6\u04b6\u04b8\u04b8\u04ba\u04ba"+ + "\u04bc\u04bc\u04be\u04be\u04c0\u04c0\u04c2\u04c3\u04c5\u04c5\u04c7\u04c7"+ + "\u04c9\u04c9\u04cb\u04cb\u04cd\u04cd\u04cf\u04cf\u04d2\u04d2\u04d4\u04d4"+ + "\u04d6\u04d6\u04d8\u04d8\u04da\u04da\u04dc\u04dc\u04de\u04de\u04e0\u04e0"+ + "\u04e2\u04e2\u04e4\u04e4\u04e6\u04e6\u04e8\u04e8\u04ea\u04ea\u04ec\u04ec"+ + "\u04ee\u04ee\u04f0\u04f0\u04f2\u04f2\u04f4\u04f4\u04f6\u04f6\u04f8\u04f8"+ + "\u04fa\u04fa\u04fc\u04fc\u04fe\u04fe\u0500\u0500\u0502\u0502\u0504\u0504"+ + "\u0506\u0506\u0508\u0508\u050a\u050a\u050c\u050c\u050e\u050e\u0510\u0510"+ + "\u0512\u0512\u0514\u0514\u0516\u0516\u0518\u0518\u051a\u051a\u051c\u051c"+ + "\u051e\u051e\u0520\u0520\u0522\u0522\u0524\u0524\u0526\u0526\u0528\u0528"+ + "\u0533\u0558\u10a2\u10c7\u10c9\u10c9\u10cf\u10cf\u1e02\u1e02\u1e04\u1e04"+ + "\u1e06\u1e06\u1e08\u1e08\u1e0a\u1e0a\u1e0c\u1e0c\u1e0e\u1e0e\u1e10\u1e10"+ + "\u1e12\u1e12\u1e14\u1e14\u1e16\u1e16\u1e18\u1e18\u1e1a\u1e1a\u1e1c\u1e1c"+ + "\u1e1e\u1e1e\u1e20\u1e20\u1e22\u1e22\u1e24\u1e24\u1e26\u1e26\u1e28\u1e28"+ + "\u1e2a\u1e2a\u1e2c\u1e2c\u1e2e\u1e2e\u1e30\u1e30\u1e32\u1e32\u1e34\u1e34"+ + "\u1e36\u1e36\u1e38\u1e38\u1e3a\u1e3a\u1e3c\u1e3c\u1e3e\u1e3e\u1e40\u1e40"+ + "\u1e42\u1e42\u1e44\u1e44\u1e46\u1e46\u1e48\u1e48\u1e4a\u1e4a\u1e4c\u1e4c"+ + "\u1e4e\u1e4e\u1e50\u1e50\u1e52\u1e52\u1e54\u1e54\u1e56\u1e56\u1e58\u1e58"+ + "\u1e5a\u1e5a\u1e5c\u1e5c\u1e5e\u1e5e\u1e60\u1e60\u1e62\u1e62\u1e64\u1e64"+ + "\u1e66\u1e66\u1e68\u1e68\u1e6a\u1e6a\u1e6c\u1e6c\u1e6e\u1e6e\u1e70\u1e70"+ + "\u1e72\u1e72\u1e74\u1e74\u1e76\u1e76\u1e78\u1e78\u1e7a\u1e7a\u1e7c\u1e7c"+ + "\u1e7e\u1e7e\u1e80\u1e80\u1e82\u1e82\u1e84\u1e84\u1e86\u1e86\u1e88\u1e88"+ + "\u1e8a\u1e8a\u1e8c\u1e8c\u1e8e\u1e8e\u1e90\u1e90\u1e92\u1e92\u1e94\u1e94"+ + "\u1e96\u1e96\u1ea0\u1ea0\u1ea2\u1ea2\u1ea4\u1ea4\u1ea6\u1ea6\u1ea8\u1ea8"+ + "\u1eaa\u1eaa\u1eac\u1eac\u1eae\u1eae\u1eb0\u1eb0\u1eb2\u1eb2\u1eb4\u1eb4"+ + "\u1eb6\u1eb6\u1eb8\u1eb8\u1eba\u1eba\u1ebc\u1ebc\u1ebe\u1ebe\u1ec0\u1ec0"+ + "\u1ec2\u1ec2\u1ec4\u1ec4\u1ec6\u1ec6\u1ec8\u1ec8\u1eca\u1eca\u1ecc\u1ecc"+ + "\u1ece\u1ece\u1ed0\u1ed0\u1ed2\u1ed2\u1ed4\u1ed4\u1ed6\u1ed6\u1ed8\u1ed8"+ + "\u1eda\u1eda\u1edc\u1edc\u1ede\u1ede\u1ee0\u1ee0\u1ee2\u1ee2\u1ee4\u1ee4"+ + "\u1ee6\u1ee6\u1ee8\u1ee8\u1eea\u1eea\u1eec\u1eec\u1eee\u1eee\u1ef0\u1ef0"+ + "\u1ef2\u1ef2\u1ef4\u1ef4\u1ef6\u1ef6\u1ef8\u1ef8\u1efa\u1efa\u1efc\u1efc"+ + "\u1efe\u1efe\u1f00\u1f00\u1f0a\u1f11\u1f1a\u1f1f\u1f2a\u1f31\u1f3a\u1f41"+ + "\u1f4a\u1f4f\u1f5b\u1f5b\u1f5d\u1f5d\u1f5f\u1f5f\u1f61\u1f61\u1f6a\u1f71"+ + "\u1fba\u1fbd\u1fca\u1fcd\u1fda\u1fdd\u1fea\u1fee\u1ffa\u1ffd\u2104\u2104"+ + "\u2109\u2109\u210d\u210f\u2112\u2114\u2117\u2117\u211b\u211f\u2126\u2126"+ + "\u2128\u2128\u212a\u212a\u212c\u212f\u2132\u2135\u2140\u2141\u2147\u2147"+ + "\u2185\u2185\u2c02\u2c30\u2c62\u2c62\u2c64\u2c66\u2c69\u2c69\u2c6b\u2c6b"+ + "\u2c6d\u2c6d\u2c6f\u2c72\u2c74\u2c74\u2c77\u2c77\u2c80\u2c82\u2c84\u2c84"+ + "\u2c86\u2c86\u2c88\u2c88\u2c8a\u2c8a\u2c8c\u2c8c\u2c8e\u2c8e\u2c90\u2c90"+ + "\u2c92\u2c92\u2c94\u2c94\u2c96\u2c96\u2c98\u2c98\u2c9a\u2c9a\u2c9c\u2c9c"+ + "\u2c9e\u2c9e\u2ca0\u2ca0\u2ca2\u2ca2\u2ca4\u2ca4\u2ca6\u2ca6\u2ca8\u2ca8"+ + "\u2caa\u2caa\u2cac\u2cac\u2cae\u2cae\u2cb0\u2cb0\u2cb2\u2cb2\u2cb4\u2cb4"+ + "\u2cb6\u2cb6\u2cb8\u2cb8\u2cba\u2cba\u2cbc\u2cbc\u2cbe\u2cbe\u2cc0\u2cc0"+ + "\u2cc2\u2cc2\u2cc4\u2cc4\u2cc6\u2cc6\u2cc8\u2cc8\u2cca\u2cca\u2ccc\u2ccc"+ + "\u2cce\u2cce\u2cd0\u2cd0\u2cd2\u2cd2\u2cd4\u2cd4\u2cd6\u2cd6\u2cd8\u2cd8"+ + "\u2cda\u2cda\u2cdc\u2cdc\u2cde\u2cde\u2ce0\u2ce0\u2ce2\u2ce2\u2ce4\u2ce4"+ + "\u2ced\u2ced\u2cef\u2cef\u2cf4\u2cf4\ua642\ua642\ua644\ua644\ua646\ua646"+ + "\ua648\ua648\ua64a\ua64a\ua64c\ua64c\ua64e\ua64e\ua650\ua650\ua652\ua652"+ + "\ua654\ua654\ua656\ua656\ua658\ua658\ua65a\ua65a\ua65c\ua65c\ua65e\ua65e"+ + "\ua660\ua660\ua662\ua662\ua664\ua664\ua666\ua666\ua668\ua668\ua66a\ua66a"+ + "\ua66c\ua66c\ua66e\ua66e\ua682\ua682\ua684\ua684\ua686\ua686\ua688\ua688"+ + "\ua68a\ua68a\ua68c\ua68c\ua68e\ua68e\ua690\ua690\ua692\ua692\ua694\ua694"+ + "\ua696\ua696\ua698\ua698\ua724\ua724\ua726\ua726\ua728\ua728\ua72a\ua72a"+ + "\ua72c\ua72c\ua72e\ua72e\ua730\ua730\ua734\ua734\ua736\ua736\ua738\ua738"+ + "\ua73a\ua73a\ua73c\ua73c\ua73e\ua73e\ua740\ua740\ua742\ua742\ua744\ua744"+ + "\ua746\ua746\ua748\ua748\ua74a\ua74a\ua74c\ua74c\ua74e\ua74e\ua750\ua750"+ + "\ua752\ua752\ua754\ua754\ua756\ua756\ua758\ua758\ua75a\ua75a\ua75c\ua75c"+ + "\ua75e\ua75e\ua760\ua760\ua762\ua762\ua764\ua764\ua766\ua766\ua768\ua768"+ + "\ua76a\ua76a\ua76c\ua76c\ua76e\ua76e\ua770\ua770\ua77b\ua77b\ua77d\ua77d"+ + "\ua77f\ua780\ua782\ua782\ua784\ua784\ua786\ua786\ua788\ua788\ua78d\ua78d"+ + "\ua78f\ua78f\ua792\ua792\ua794\ua794\ua7a2\ua7a2\ua7a4\ua7a4\ua7a6\ua7a6"+ + "\ua7a8\ua7a8\ua7aa\ua7aa\ua7ac\ua7ac\uff23\uff3c%\2\62;\u0662\u066b\u06f2"+ + "\u06fb\u07c2\u07cb\u0968\u0971\u09e8\u09f1\u0a68\u0a71\u0ae8\u0af1\u0b68"+ + "\u0b71\u0be8\u0bf1\u0c68\u0c71\u0ce8\u0cf1\u0d68\u0d71\u0e52\u0e5b\u0ed2"+ + "\u0edb\u0f22\u0f2b\u1042\u104b\u1092\u109b\u17e2\u17eb\u1812\u181b\u1948"+ + "\u1951\u19d2\u19db\u1a82\u1a8b\u1a92\u1a9b\u1b52\u1b5b\u1bb2\u1bbb\u1c42"+ + "\u1c4b\u1c52\u1c5b\ua622\ua62b\ua8d2\ua8db\ua902\ua90b\ua9d2\ua9db\uaa52"+ + "\uaa5b\uabf2\uabfb\uff12\uff1b\t\2\u16f0\u16f2\u2162\u2184\u2187\u218a"+ + "\u3009\u3009\u3023\u302b\u303a\u303c\ua6e8\ua6f1\2\36\2\3\3\2\2\2\2\5"+ + "\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2"+ + "\3\21\3\2\2\2\5\23\3\2\2\2\7\25\3\2\2\2\t\27\3\2\2\2\13\31\3\2\2\2\r\33"+ + "\3\2\2\2\17\35\3\2\2\2\21\22\t\2\2\2\22\4\3\2\2\2\23\24\t\3\2\2\24\6\3"+ + "\2\2\2\25\26\t\4\2\2\26\b\3\2\2\2\27\30\t\5\2\2\30\n\3\2\2\2\31\32\t\6"+ + "\2\2\32\f\3\2\2\2\33\34\t\7\2\2\34\16\3\2\2\2\35\36\t\b\2\2\36\20\3\2"+ + "\2\2\3\2\2"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file From 0e0f347f51ed98b31cf48c5a962dba8438031379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Thu, 14 Nov 2024 16:47:20 -0300 Subject: [PATCH 0234/1962] Rename parser before annotating to ensure files are found --- antlr4-wrapper.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/antlr4-wrapper.xml b/antlr4-wrapper.xml index c3e4527f9fb..bf6bc88ee67 100644 --- a/antlr4-wrapper.xml +++ b/antlr4-wrapper.xml @@ -172,8 +172,8 @@ public class ${lexer-name}'/> - - + From 79026f98c93c1aa7fab269ed4a6caf1de1b5311e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Thu, 14 Nov 2024 16:49:45 -0300 Subject: [PATCH 0235/1962] Add licence header --- .../net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java b/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java index 14066ae367b..20ac9047188 100644 --- a/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java +++ b/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java @@ -1,3 +1,7 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + // Generated from net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.g4 by ANTLR 4.9.3 package net.sourceforge.pmd.lang.kotlin.ast; From 178f9541e25028939bb05c9c62188e22deaabcc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Thu, 14 Nov 2024 16:51:04 -0300 Subject: [PATCH 0236/1962] Add since to deprecation notice --- .../net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java b/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java index 20ac9047188..de3a2151155 100644 --- a/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java +++ b/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java @@ -17,7 +17,7 @@ import org.antlr.v4.runtime.dfa.DFA; /** - * @deprecated This class was never intended to be generated. It will be removed with no replacement. + * @deprecated Since 7.8.0. This class was never intended to be generated. It will be removed with no replacement. */ @Deprecated From 0cf8f2c18bc19c53f355e83b56af36a4e7485644 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Thu, 14 Nov 2024 16:55:55 -0300 Subject: [PATCH 0237/1962] Suppress style warnings on generated file --- .../net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java b/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java index de3a2151155..ed8c4339828 100644 --- a/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java +++ b/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java @@ -2,6 +2,7 @@ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ +// CHECKSTYLE:OFF // Generated from net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.g4 by ANTLR 4.9.3 package net.sourceforge.pmd.lang.kotlin.ast; @@ -394,4 +395,4 @@ public UnicodeClasses(CharStream input) { _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); } } -} \ No newline at end of file +} From ef3a4cc15ec0a95f9ac3873e186c234e2fef272d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Thu, 14 Nov 2024 18:10:59 -0300 Subject: [PATCH 0238/1962] Remove generated gherkin code from coverage report - Take the chance to remove / deprecate autogenerated classes that are not needed and were not used. --- pmd-gherkin/pom.xml | 22 + .../lang/gherkin/ast/GherkinBaseListener.java | 337 +++ .../lang/gherkin/ast/GherkinBaseVisitor.java | 192 ++ .../pmd/lang/gherkin/ast/GherkinListener.java | 260 ++ .../pmd/lang/gherkin/ast/GherkinParser.java | 2100 +++++++++++++++++ .../pmd/lang/gherkin/ast/GherkinVisitor.java | 167 ++ 6 files changed, 3078 insertions(+) create mode 100644 pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinBaseListener.java create mode 100644 pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinBaseVisitor.java create mode 100644 pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinListener.java create mode 100644 pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinParser.java create mode 100644 pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinVisitor.java diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index 2c796714902..58343201395 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -18,6 +18,28 @@ antlr4-maven-plugin + + org.apache.maven.plugins + maven-antrun-plugin + + + antlr-cleanup + generate-sources + + run + + + + + + + + + + + + + maven-resources-plugin diff --git a/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinBaseListener.java b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinBaseListener.java new file mode 100644 index 00000000000..ddbeb87d8db --- /dev/null +++ b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinBaseListener.java @@ -0,0 +1,337 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +// CHECKSTYLE:OFF +// Generated from net/sourceforge/pmd/lang/gherkin/ast/Gherkin.g4 by ANTLR 4.9.3 +package net.sourceforge.pmd.lang.gherkin.ast; + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.tree.ErrorNode; +import org.antlr.v4.runtime.tree.TerminalNode; + +/** + * This class provides an empty implementation of {@link GherkinListener}, + * which can be extended to create a listener which only needs to handle a subset + * of the available methods. + * + * @deprecated Since 7.8.0. This class was never intended to be generated. It will be removed with no replacement. + */ + +@Deprecated +@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public class GherkinBaseListener implements GherkinListener { + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterMain(GherkinParser.MainContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitMain(GherkinParser.MainContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterFeature(GherkinParser.FeatureContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitFeature(GherkinParser.FeatureContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterInstructionLine(GherkinParser.InstructionLineContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitInstructionLine(GherkinParser.InstructionLineContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterInstruction(GherkinParser.InstructionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitInstruction(GherkinParser.InstructionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterStepInstruction(GherkinParser.StepInstructionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitStepInstruction(GherkinParser.StepInstructionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterBackground(GherkinParser.BackgroundContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitBackground(GherkinParser.BackgroundContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterRulex(GherkinParser.RulexContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitRulex(GherkinParser.RulexContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterScenario(GherkinParser.ScenarioContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitScenario(GherkinParser.ScenarioContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterScenarioOutline(GherkinParser.ScenarioOutlineContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitScenarioOutline(GherkinParser.ScenarioOutlineContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterStep(GherkinParser.StepContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitStep(GherkinParser.StepContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterStepItem(GherkinParser.StepItemContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitStepItem(GherkinParser.StepItemContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterTagline(GherkinParser.TaglineContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitTagline(GherkinParser.TaglineContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterAnd(GherkinParser.AndContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitAnd(GherkinParser.AndContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterAnystep(GherkinParser.AnystepContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitAnystep(GherkinParser.AnystepContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterBut(GherkinParser.ButContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitBut(GherkinParser.ButContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterDatatable(GherkinParser.DatatableContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitDatatable(GherkinParser.DatatableContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterGiven(GherkinParser.GivenContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitGiven(GherkinParser.GivenContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterThen(GherkinParser.ThenContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitThen(GherkinParser.ThenContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterWhen(GherkinParser.WhenContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitWhen(GherkinParser.WhenContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterExamples(GherkinParser.ExamplesContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitExamples(GherkinParser.ExamplesContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterInstructionDescription(GherkinParser.InstructionDescriptionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitInstructionDescription(GherkinParser.InstructionDescriptionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterStepDescription(GherkinParser.StepDescriptionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitStepDescription(GherkinParser.StepDescriptionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterDescription(GherkinParser.DescriptionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitDescription(GherkinParser.DescriptionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterText(GherkinParser.TextContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitText(GherkinParser.TextContext ctx) { } + + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void visitTerminal(TerminalNode node) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void visitErrorNode(ErrorNode node) { } +} \ No newline at end of file diff --git a/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinBaseVisitor.java b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinBaseVisitor.java new file mode 100644 index 00000000000..90c6480261c --- /dev/null +++ b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinBaseVisitor.java @@ -0,0 +1,192 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +// CHECKSTYLE:OFF +// Generated from net/sourceforge/pmd/lang/gherkin/ast/Gherkin.g4 by ANTLR 4.9.3 +package net.sourceforge.pmd.lang.gherkin.ast; +import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor; + +/** + * This class provides an empty implementation of {@link GherkinVisitor}, + * which can be extended to create a visitor which only needs to handle a subset + * of the available methods. + * + * @param The return type of the visit operation. Use {@link Void} for + * operations with no return type. + * + * @deprecated Since 7.8.0. This class was never intended to be generated. It will be removed with no replacement. + */ + +@Deprecated +@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public class GherkinBaseVisitor extends AbstractParseTreeVisitor implements GherkinVisitor { + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitMain(GherkinParser.MainContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitFeature(GherkinParser.FeatureContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitInstructionLine(GherkinParser.InstructionLineContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitInstruction(GherkinParser.InstructionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitStepInstruction(GherkinParser.StepInstructionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitBackground(GherkinParser.BackgroundContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitRulex(GherkinParser.RulexContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitScenario(GherkinParser.ScenarioContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitScenarioOutline(GherkinParser.ScenarioOutlineContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitStep(GherkinParser.StepContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitStepItem(GherkinParser.StepItemContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitTagline(GherkinParser.TaglineContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitAnd(GherkinParser.AndContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitAnystep(GherkinParser.AnystepContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitBut(GherkinParser.ButContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitDatatable(GherkinParser.DatatableContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitGiven(GherkinParser.GivenContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitThen(GherkinParser.ThenContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitWhen(GherkinParser.WhenContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitExamples(GherkinParser.ExamplesContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitInstructionDescription(GherkinParser.InstructionDescriptionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitStepDescription(GherkinParser.StepDescriptionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitDescription(GherkinParser.DescriptionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitText(GherkinParser.TextContext ctx) { return visitChildren(ctx); } +} \ No newline at end of file diff --git a/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinListener.java b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinListener.java new file mode 100644 index 00000000000..5976505f6ff --- /dev/null +++ b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinListener.java @@ -0,0 +1,260 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +// CHECKSTYLE:OFF +// Generated from net/sourceforge/pmd/lang/gherkin/ast/Gherkin.g4 by ANTLR 4.9.3 +package net.sourceforge.pmd.lang.gherkin.ast; +import org.antlr.v4.runtime.tree.ParseTreeListener; + +/** + * This interface defines a complete listener for a parse tree produced by + * {@link GherkinParser}. + * + * @deprecated Since 7.8.0. This class was never intended to be generated. It will be removed with no replacement. + */ + +@Deprecated +@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public interface GherkinListener extends ParseTreeListener { + /** + * Enter a parse tree produced by {@link GherkinParser#main}. + * @param ctx the parse tree + */ + void enterMain(GherkinParser.MainContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#main}. + * @param ctx the parse tree + */ + void exitMain(GherkinParser.MainContext ctx); + /** + * Enter a parse tree produced by {@link GherkinParser#feature}. + * @param ctx the parse tree + */ + void enterFeature(GherkinParser.FeatureContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#feature}. + * @param ctx the parse tree + */ + void exitFeature(GherkinParser.FeatureContext ctx); + /** + * Enter a parse tree produced by {@link GherkinParser#instructionLine}. + * @param ctx the parse tree + */ + void enterInstructionLine(GherkinParser.InstructionLineContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#instructionLine}. + * @param ctx the parse tree + */ + void exitInstructionLine(GherkinParser.InstructionLineContext ctx); + /** + * Enter a parse tree produced by {@link GherkinParser#instruction}. + * @param ctx the parse tree + */ + void enterInstruction(GherkinParser.InstructionContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#instruction}. + * @param ctx the parse tree + */ + void exitInstruction(GherkinParser.InstructionContext ctx); + /** + * Enter a parse tree produced by {@link GherkinParser#stepInstruction}. + * @param ctx the parse tree + */ + void enterStepInstruction(GherkinParser.StepInstructionContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#stepInstruction}. + * @param ctx the parse tree + */ + void exitStepInstruction(GherkinParser.StepInstructionContext ctx); + /** + * Enter a parse tree produced by {@link GherkinParser#background}. + * @param ctx the parse tree + */ + void enterBackground(GherkinParser.BackgroundContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#background}. + * @param ctx the parse tree + */ + void exitBackground(GherkinParser.BackgroundContext ctx); + /** + * Enter a parse tree produced by {@link GherkinParser#rulex}. + * @param ctx the parse tree + */ + void enterRulex(GherkinParser.RulexContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#rulex}. + * @param ctx the parse tree + */ + void exitRulex(GherkinParser.RulexContext ctx); + /** + * Enter a parse tree produced by {@link GherkinParser#scenario}. + * @param ctx the parse tree + */ + void enterScenario(GherkinParser.ScenarioContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#scenario}. + * @param ctx the parse tree + */ + void exitScenario(GherkinParser.ScenarioContext ctx); + /** + * Enter a parse tree produced by {@link GherkinParser#scenarioOutline}. + * @param ctx the parse tree + */ + void enterScenarioOutline(GherkinParser.ScenarioOutlineContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#scenarioOutline}. + * @param ctx the parse tree + */ + void exitScenarioOutline(GherkinParser.ScenarioOutlineContext ctx); + /** + * Enter a parse tree produced by {@link GherkinParser#step}. + * @param ctx the parse tree + */ + void enterStep(GherkinParser.StepContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#step}. + * @param ctx the parse tree + */ + void exitStep(GherkinParser.StepContext ctx); + /** + * Enter a parse tree produced by {@link GherkinParser#stepItem}. + * @param ctx the parse tree + */ + void enterStepItem(GherkinParser.StepItemContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#stepItem}. + * @param ctx the parse tree + */ + void exitStepItem(GherkinParser.StepItemContext ctx); + /** + * Enter a parse tree produced by {@link GherkinParser#tagline}. + * @param ctx the parse tree + */ + void enterTagline(GherkinParser.TaglineContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#tagline}. + * @param ctx the parse tree + */ + void exitTagline(GherkinParser.TaglineContext ctx); + /** + * Enter a parse tree produced by {@link GherkinParser#and}. + * @param ctx the parse tree + */ + void enterAnd(GherkinParser.AndContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#and}. + * @param ctx the parse tree + */ + void exitAnd(GherkinParser.AndContext ctx); + /** + * Enter a parse tree produced by {@link GherkinParser#anystep}. + * @param ctx the parse tree + */ + void enterAnystep(GherkinParser.AnystepContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#anystep}. + * @param ctx the parse tree + */ + void exitAnystep(GherkinParser.AnystepContext ctx); + /** + * Enter a parse tree produced by {@link GherkinParser#but}. + * @param ctx the parse tree + */ + void enterBut(GherkinParser.ButContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#but}. + * @param ctx the parse tree + */ + void exitBut(GherkinParser.ButContext ctx); + /** + * Enter a parse tree produced by {@link GherkinParser#datatable}. + * @param ctx the parse tree + */ + void enterDatatable(GherkinParser.DatatableContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#datatable}. + * @param ctx the parse tree + */ + void exitDatatable(GherkinParser.DatatableContext ctx); + /** + * Enter a parse tree produced by {@link GherkinParser#given}. + * @param ctx the parse tree + */ + void enterGiven(GherkinParser.GivenContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#given}. + * @param ctx the parse tree + */ + void exitGiven(GherkinParser.GivenContext ctx); + /** + * Enter a parse tree produced by {@link GherkinParser#then}. + * @param ctx the parse tree + */ + void enterThen(GherkinParser.ThenContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#then}. + * @param ctx the parse tree + */ + void exitThen(GherkinParser.ThenContext ctx); + /** + * Enter a parse tree produced by {@link GherkinParser#when}. + * @param ctx the parse tree + */ + void enterWhen(GherkinParser.WhenContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#when}. + * @param ctx the parse tree + */ + void exitWhen(GherkinParser.WhenContext ctx); + /** + * Enter a parse tree produced by {@link GherkinParser#examples}. + * @param ctx the parse tree + */ + void enterExamples(GherkinParser.ExamplesContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#examples}. + * @param ctx the parse tree + */ + void exitExamples(GherkinParser.ExamplesContext ctx); + /** + * Enter a parse tree produced by {@link GherkinParser#instructionDescription}. + * @param ctx the parse tree + */ + void enterInstructionDescription(GherkinParser.InstructionDescriptionContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#instructionDescription}. + * @param ctx the parse tree + */ + void exitInstructionDescription(GherkinParser.InstructionDescriptionContext ctx); + /** + * Enter a parse tree produced by {@link GherkinParser#stepDescription}. + * @param ctx the parse tree + */ + void enterStepDescription(GherkinParser.StepDescriptionContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#stepDescription}. + * @param ctx the parse tree + */ + void exitStepDescription(GherkinParser.StepDescriptionContext ctx); + /** + * Enter a parse tree produced by {@link GherkinParser#description}. + * @param ctx the parse tree + */ + void enterDescription(GherkinParser.DescriptionContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#description}. + * @param ctx the parse tree + */ + void exitDescription(GherkinParser.DescriptionContext ctx); + /** + * Enter a parse tree produced by {@link GherkinParser#text}. + * @param ctx the parse tree + */ + void enterText(GherkinParser.TextContext ctx); + /** + * Exit a parse tree produced by {@link GherkinParser#text}. + * @param ctx the parse tree + */ + void exitText(GherkinParser.TextContext ctx); +} \ No newline at end of file diff --git a/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinParser.java b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinParser.java new file mode 100644 index 00000000000..e8388f2309b --- /dev/null +++ b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinParser.java @@ -0,0 +1,2100 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +// CHECKSTYLE:OFF +// Generated from net/sourceforge/pmd/lang/gherkin/ast/Gherkin.g4 by ANTLR 4.9.3 +package net.sourceforge.pmd.lang.gherkin.ast; + +import java.util.List; + +import org.antlr.v4.runtime.NoViableAltException; +import org.antlr.v4.runtime.Parser; +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.RuntimeMetaData; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.Vocabulary; +import org.antlr.v4.runtime.VocabularyImpl; +import org.antlr.v4.runtime.atn.ATN; +import org.antlr.v4.runtime.atn.ATNDeserializer; +import org.antlr.v4.runtime.atn.ParserATNSimulator; +import org.antlr.v4.runtime.atn.PredictionContextCache; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.tree.ParseTreeListener; +import org.antlr.v4.runtime.tree.ParseTreeVisitor; +import org.antlr.v4.runtime.tree.TerminalNode; + +/** + * @deprecated Since 7.8.0. This class was never intended to be generated. It will be removed with no replacement. + */ + +@Deprecated +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) +@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public class GherkinParser extends Parser { + static { RuntimeMetaData.checkVersion("4.9.3", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + BOMUTF8=1, BOMUTF16=2, WHITESPACE=3, COMMENT=4, STARTCOMMENT=5, DOCSTRING1=6, + DOCSTRING2=7, BACKGROUND=8, EXAMPLES=9, FEATURE=10, RULEX=11, SCENARIO=12, + SCENARIOOUTLINE=13, AND=14, ANYSTEP=15, BUT=16, DATATABLE=17, GIVEN=18, + THEN=19, WHEN=20, TAG=21, PARAMETER=22, NL=23, TOKEN=24; + public static final int + RULE_main = 0, RULE_feature = 1, RULE_instructionLine = 2, RULE_instruction = 3, + RULE_stepInstruction = 4, RULE_background = 5, RULE_rulex = 6, RULE_scenario = 7, + RULE_scenarioOutline = 8, RULE_step = 9, RULE_stepItem = 10, RULE_tagline = 11, + RULE_and = 12, RULE_anystep = 13, RULE_but = 14, RULE_datatable = 15, + RULE_given = 16, RULE_then = 17, RULE_when = 18, RULE_examples = 19, RULE_instructionDescription = 20, + RULE_stepDescription = 21, RULE_description = 22, RULE_text = 23; + private static String[] makeRuleNames() { + return new String[] { + "main", "feature", "instructionLine", "instruction", "stepInstruction", + "background", "rulex", "scenario", "scenarioOutline", "step", "stepItem", + "tagline", "and", "anystep", "but", "datatable", "given", "then", "when", + "examples", "instructionDescription", "stepDescription", "description", + "text" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, "'\u00EF\u00BB\u00BF'", "'\uFEFF'", null, null, null, null, null, + "'Background:'", null, "'Feature:'", "'Rule:'", null, null, "'And'", + "'*'", "'But'", null, "'Given'", "'Then'", "'When'" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, "BOMUTF8", "BOMUTF16", "WHITESPACE", "COMMENT", "STARTCOMMENT", + "DOCSTRING1", "DOCSTRING2", "BACKGROUND", "EXAMPLES", "FEATURE", "RULEX", + "SCENARIO", "SCENARIOOUTLINE", "AND", "ANYSTEP", "BUT", "DATATABLE", + "GIVEN", "THEN", "WHEN", "TAG", "PARAMETER", "NL", "TOKEN" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + @Override + public String getGrammarFileName() { return "Gherkin.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public ATN getATN() { return _ATN; } + + public GherkinParser(TokenStream input) { + super(input); + _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class MainContext extends ParserRuleContext { + public FeatureContext feature() { + return getRuleContext(FeatureContext.class,0); + } + public TerminalNode EOF() { return getToken(GherkinParser.EOF, 0); } + public TerminalNode STARTCOMMENT() { return getToken(GherkinParser.STARTCOMMENT, 0); } + public List description() { + return getRuleContexts(DescriptionContext.class); + } + public DescriptionContext description(int i) { + return getRuleContext(DescriptionContext.class,i); + } + public List instructionLine() { + return getRuleContexts(InstructionLineContext.class); + } + public InstructionLineContext instructionLine(int i) { + return getRuleContext(InstructionLineContext.class,i); + } + public List NL() { return getTokens(GherkinParser.NL); } + public TerminalNode NL(int i) { + return getToken(GherkinParser.NL, i); + } + public MainContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_main; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterMain(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitMain(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitMain(this); + else return visitor.visitChildren(this); + } + } + + public final MainContext main() throws RecognitionException { + MainContext _localctx = new MainContext(_ctx, getState()); + enterRule(_localctx, 0, RULE_main); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(49); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,0,_ctx) ) { + case 1: + { + setState(48); + match(STARTCOMMENT); + } + break; + } + setState(51); + feature(); + setState(55); + _errHandler.sync(this); + _la = _input.LA(1); + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << STARTCOMMENT) | (1L << SCENARIO) | (1L << SCENARIOOUTLINE) | (1L << AND) | (1L << ANYSTEP) | (1L << BUT) | (1L << DATATABLE) | (1L << GIVEN) | (1L << THEN) | (1L << WHEN) | (1L << TAG) | (1L << PARAMETER) | (1L << TOKEN))) != 0)) { + { + { + setState(52); + description(); + } + } + setState(57); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(61); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,2,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(58); + instructionLine(); + } + } + } + setState(63); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,2,_ctx); + } + setState(67); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==NL) { + { + { + setState(64); + match(NL); + } + } + setState(69); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(70); + match(EOF); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class FeatureContext extends ParserRuleContext { + public List tagline() { + return getRuleContexts(TaglineContext.class); + } + public TaglineContext tagline(int i) { + return getRuleContext(TaglineContext.class,i); + } + public List NL() { return getTokens(GherkinParser.NL); } + public TerminalNode NL(int i) { + return getToken(GherkinParser.NL, i); + } + public TerminalNode FEATURE() { return getToken(GherkinParser.FEATURE, 0); } + public FeatureContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_feature; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterFeature(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitFeature(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitFeature(this); + else return visitor.visitChildren(this); + } + } + + public final FeatureContext feature() throws RecognitionException { + FeatureContext _localctx = new FeatureContext(_ctx, getState()); + enterRule(_localctx, 2, RULE_feature); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(81); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,5,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(75); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==NL) { + { + { + setState(72); + match(NL); + } + } + setState(77); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(78); + tagline(); + } + } + } + setState(83); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,5,_ctx); + } + setState(87); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,6,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(84); + match(NL); + } + } + } + setState(89); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,6,_ctx); + } + setState(91); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==FEATURE) { + { + setState(90); + match(FEATURE); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class InstructionLineContext extends ParserRuleContext { + public InstructionContext instruction() { + return getRuleContext(InstructionContext.class,0); + } + public DatatableContext datatable() { + return getRuleContext(DatatableContext.class,0); + } + public List NL() { return getTokens(GherkinParser.NL); } + public TerminalNode NL(int i) { + return getToken(GherkinParser.NL, i); + } + public InstructionLineContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_instructionLine; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterInstructionLine(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitInstructionLine(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitInstructionLine(this); + else return visitor.visitChildren(this); + } + } + + public final InstructionLineContext instructionLine() throws RecognitionException { + InstructionLineContext _localctx = new InstructionLineContext(_ctx, getState()); + enterRule(_localctx, 4, RULE_instructionLine); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(94); + _errHandler.sync(this); + _la = _input.LA(1); + do { + { + { + setState(93); + match(NL); + } + } + setState(96); + _errHandler.sync(this); + _la = _input.LA(1); + } while ( _la==NL ); + setState(100); + _errHandler.sync(this); + switch (_input.LA(1)) { + case BACKGROUND: + case RULEX: + case SCENARIO: + case SCENARIOOUTLINE: + case AND: + case ANYSTEP: + case BUT: + case GIVEN: + case THEN: + case WHEN: + case TAG: + case PARAMETER: + case TOKEN: + { + setState(98); + instruction(); + } + break; + case DATATABLE: + { + setState(99); + datatable(); + } + break; + default: + throw new NoViableAltException(this); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class InstructionContext extends ParserRuleContext { + public RulexContext rulex() { + return getRuleContext(RulexContext.class,0); + } + public List description() { + return getRuleContexts(DescriptionContext.class); + } + public DescriptionContext description(int i) { + return getRuleContext(DescriptionContext.class,i); + } + public StepInstructionContext stepInstruction() { + return getRuleContext(StepInstructionContext.class,0); + } + public List stepDescription() { + return getRuleContexts(StepDescriptionContext.class); + } + public StepDescriptionContext stepDescription(int i) { + return getRuleContext(StepDescriptionContext.class,i); + } + public List step() { + return getRuleContexts(StepContext.class); + } + public StepContext step(int i) { + return getRuleContext(StepContext.class,i); + } + public List NL() { return getTokens(GherkinParser.NL); } + public TerminalNode NL(int i) { + return getToken(GherkinParser.NL, i); + } + public TaglineContext tagline() { + return getRuleContext(TaglineContext.class,0); + } + public InstructionDescriptionContext instructionDescription() { + return getRuleContext(InstructionDescriptionContext.class,0); + } + public InstructionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_instruction; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterInstruction(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitInstruction(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitInstruction(this); + else return visitor.visitChildren(this); + } + } + + public final InstructionContext instruction() throws RecognitionException { + InstructionContext _localctx = new InstructionContext(_ctx, getState()); + enterRule(_localctx, 6, RULE_instruction); + int _la; + try { + int _alt; + setState(152); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,18,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(102); + rulex(); + setState(106); + _errHandler.sync(this); + _la = _input.LA(1); + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << STARTCOMMENT) | (1L << SCENARIO) | (1L << SCENARIOOUTLINE) | (1L << AND) | (1L << ANYSTEP) | (1L << BUT) | (1L << DATATABLE) | (1L << GIVEN) | (1L << THEN) | (1L << WHEN) | (1L << TAG) | (1L << PARAMETER) | (1L << TOKEN))) != 0)) { + { + { + setState(103); + description(); + } + } + setState(108); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(109); + stepInstruction(); + setState(113); + _errHandler.sync(this); + _la = _input.LA(1); + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << STARTCOMMENT) | (1L << SCENARIO) | (1L << SCENARIOOUTLINE) | (1L << AND) | (1L << ANYSTEP) | (1L << BUT) | (1L << DATATABLE) | (1L << GIVEN) | (1L << THEN) | (1L << WHEN) | (1L << TAG) | (1L << PARAMETER) | (1L << TOKEN))) != 0)) { + { + { + setState(110); + description(); + } + } + setState(115); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(130); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,14,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(117); + _errHandler.sync(this); + _la = _input.LA(1); + do { + { + { + setState(116); + match(NL); + } + } + setState(119); + _errHandler.sync(this); + _la = _input.LA(1); + } while ( _la==NL ); + setState(121); + stepDescription(); + setState(125); + _errHandler.sync(this); + _la = _input.LA(1); + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << STARTCOMMENT) | (1L << SCENARIO) | (1L << SCENARIOOUTLINE) | (1L << AND) | (1L << ANYSTEP) | (1L << BUT) | (1L << DATATABLE) | (1L << GIVEN) | (1L << THEN) | (1L << WHEN) | (1L << TAG) | (1L << PARAMETER) | (1L << TOKEN))) != 0)) { + { + { + setState(122); + description(); + } + } + setState(127); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + } + } + setState(132); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,14,_ctx); + } + setState(141); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,16,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(134); + _errHandler.sync(this); + _alt = 1; + do { + switch (_alt) { + case 1: + { + { + setState(133); + match(NL); + } + } + break; + default: + throw new NoViableAltException(this); + } + setState(136); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,15,_ctx); + } while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); + setState(138); + step(); + } + } + } + setState(143); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,16,_ctx); + } + } + break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(144); + tagline(); + } + break; + case 4: + enterOuterAlt(_localctx, 4); + { + setState(145); + instructionDescription(); + setState(149); + _errHandler.sync(this); + _la = _input.LA(1); + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << STARTCOMMENT) | (1L << SCENARIO) | (1L << SCENARIOOUTLINE) | (1L << AND) | (1L << ANYSTEP) | (1L << BUT) | (1L << DATATABLE) | (1L << GIVEN) | (1L << THEN) | (1L << WHEN) | (1L << TAG) | (1L << PARAMETER) | (1L << TOKEN))) != 0)) { + { + { + setState(146); + description(); + } + } + setState(151); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class StepInstructionContext extends ParserRuleContext { + public BackgroundContext background() { + return getRuleContext(BackgroundContext.class,0); + } + public ScenarioContext scenario() { + return getRuleContext(ScenarioContext.class,0); + } + public ScenarioOutlineContext scenarioOutline() { + return getRuleContext(ScenarioOutlineContext.class,0); + } + public StepInstructionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_stepInstruction; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterStepInstruction(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitStepInstruction(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitStepInstruction(this); + else return visitor.visitChildren(this); + } + } + + public final StepInstructionContext stepInstruction() throws RecognitionException { + StepInstructionContext _localctx = new StepInstructionContext(_ctx, getState()); + enterRule(_localctx, 8, RULE_stepInstruction); + try { + setState(157); + _errHandler.sync(this); + switch (_input.LA(1)) { + case BACKGROUND: + enterOuterAlt(_localctx, 1); + { + setState(154); + background(); + } + break; + case SCENARIO: + enterOuterAlt(_localctx, 2); + { + setState(155); + scenario(); + } + break; + case SCENARIOOUTLINE: + enterOuterAlt(_localctx, 3); + { + setState(156); + scenarioOutline(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class BackgroundContext extends ParserRuleContext { + public TerminalNode BACKGROUND() { return getToken(GherkinParser.BACKGROUND, 0); } + public BackgroundContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_background; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterBackground(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitBackground(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitBackground(this); + else return visitor.visitChildren(this); + } + } + + public final BackgroundContext background() throws RecognitionException { + BackgroundContext _localctx = new BackgroundContext(_ctx, getState()); + enterRule(_localctx, 10, RULE_background); + try { + enterOuterAlt(_localctx, 1); + { + setState(159); + match(BACKGROUND); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class RulexContext extends ParserRuleContext { + public TerminalNode RULEX() { return getToken(GherkinParser.RULEX, 0); } + public RulexContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_rulex; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterRulex(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitRulex(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitRulex(this); + else return visitor.visitChildren(this); + } + } + + public final RulexContext rulex() throws RecognitionException { + RulexContext _localctx = new RulexContext(_ctx, getState()); + enterRule(_localctx, 12, RULE_rulex); + try { + enterOuterAlt(_localctx, 1); + { + setState(161); + match(RULEX); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ScenarioContext extends ParserRuleContext { + public TerminalNode SCENARIO() { return getToken(GherkinParser.SCENARIO, 0); } + public ScenarioContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_scenario; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterScenario(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitScenario(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitScenario(this); + else return visitor.visitChildren(this); + } + } + + public final ScenarioContext scenario() throws RecognitionException { + ScenarioContext _localctx = new ScenarioContext(_ctx, getState()); + enterRule(_localctx, 14, RULE_scenario); + try { + enterOuterAlt(_localctx, 1); + { + setState(163); + match(SCENARIO); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ScenarioOutlineContext extends ParserRuleContext { + public TerminalNode SCENARIOOUTLINE() { return getToken(GherkinParser.SCENARIOOUTLINE, 0); } + public ScenarioOutlineContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_scenarioOutline; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterScenarioOutline(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitScenarioOutline(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitScenarioOutline(this); + else return visitor.visitChildren(this); + } + } + + public final ScenarioOutlineContext scenarioOutline() throws RecognitionException { + ScenarioOutlineContext _localctx = new ScenarioOutlineContext(_ctx, getState()); + enterRule(_localctx, 16, RULE_scenarioOutline); + try { + enterOuterAlt(_localctx, 1); + { + setState(165); + match(SCENARIOOUTLINE); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class StepContext extends ParserRuleContext { + public StepItemContext stepItem() { + return getRuleContext(StepItemContext.class,0); + } + public List description() { + return getRuleContexts(DescriptionContext.class); + } + public DescriptionContext description(int i) { + return getRuleContext(DescriptionContext.class,i); + } + public StepContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_step; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterStep(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitStep(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitStep(this); + else return visitor.visitChildren(this); + } + } + + public final StepContext step() throws RecognitionException { + StepContext _localctx = new StepContext(_ctx, getState()); + enterRule(_localctx, 18, RULE_step); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(167); + stepItem(); + setState(171); + _errHandler.sync(this); + _la = _input.LA(1); + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << STARTCOMMENT) | (1L << SCENARIO) | (1L << SCENARIOOUTLINE) | (1L << AND) | (1L << ANYSTEP) | (1L << BUT) | (1L << DATATABLE) | (1L << GIVEN) | (1L << THEN) | (1L << WHEN) | (1L << TAG) | (1L << PARAMETER) | (1L << TOKEN))) != 0)) { + { + { + setState(168); + description(); + } + } + setState(173); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class StepItemContext extends ParserRuleContext { + public AndContext and() { + return getRuleContext(AndContext.class,0); + } + public AnystepContext anystep() { + return getRuleContext(AnystepContext.class,0); + } + public ButContext but() { + return getRuleContext(ButContext.class,0); + } + public DatatableContext datatable() { + return getRuleContext(DatatableContext.class,0); + } + public GivenContext given() { + return getRuleContext(GivenContext.class,0); + } + public ThenContext then() { + return getRuleContext(ThenContext.class,0); + } + public WhenContext when() { + return getRuleContext(WhenContext.class,0); + } + public ExamplesContext examples() { + return getRuleContext(ExamplesContext.class,0); + } + public List tagline() { + return getRuleContexts(TaglineContext.class); + } + public TaglineContext tagline(int i) { + return getRuleContext(TaglineContext.class,i); + } + public List NL() { return getTokens(GherkinParser.NL); } + public TerminalNode NL(int i) { + return getToken(GherkinParser.NL, i); + } + public StepItemContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_stepItem; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterStepItem(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitStepItem(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitStepItem(this); + else return visitor.visitChildren(this); + } + } + + public final StepItemContext stepItem() throws RecognitionException { + StepItemContext _localctx = new StepItemContext(_ctx, getState()); + enterRule(_localctx, 20, RULE_stepItem); + int _la; + try { + int _alt; + setState(200); + _errHandler.sync(this); + switch (_input.LA(1)) { + case AND: + enterOuterAlt(_localctx, 1); + { + setState(174); + and(); + } + break; + case ANYSTEP: + enterOuterAlt(_localctx, 2); + { + setState(175); + anystep(); + } + break; + case BUT: + enterOuterAlt(_localctx, 3); + { + setState(176); + but(); + } + break; + case DATATABLE: + enterOuterAlt(_localctx, 4); + { + setState(177); + datatable(); + } + break; + case GIVEN: + enterOuterAlt(_localctx, 5); + { + setState(178); + given(); + } + break; + case THEN: + enterOuterAlt(_localctx, 6); + { + setState(179); + then(); + } + break; + case WHEN: + enterOuterAlt(_localctx, 7); + { + setState(180); + when(); + } + break; + case EXAMPLES: + case TAG: + case NL: + enterOuterAlt(_localctx, 8); + { + setState(190); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,22,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(184); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==NL) { + { + { + setState(181); + match(NL); + } + } + setState(186); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(187); + tagline(); + } + } + } + setState(192); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,22,_ctx); + } + setState(196); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==NL) { + { + { + setState(193); + match(NL); + } + } + setState(198); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(199); + examples(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class TaglineContext extends ParserRuleContext { + public List TAG() { return getTokens(GherkinParser.TAG); } + public TerminalNode TAG(int i) { + return getToken(GherkinParser.TAG, i); + } + public TaglineContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_tagline; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterTagline(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitTagline(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitTagline(this); + else return visitor.visitChildren(this); + } + } + + public final TaglineContext tagline() throws RecognitionException { + TaglineContext _localctx = new TaglineContext(_ctx, getState()); + enterRule(_localctx, 22, RULE_tagline); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(203); + _errHandler.sync(this); + _alt = 1; + do { + switch (_alt) { + case 1: + { + { + setState(202); + match(TAG); + } + } + break; + default: + throw new NoViableAltException(this); + } + setState(205); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,25,_ctx); + } while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class AndContext extends ParserRuleContext { + public TerminalNode AND() { return getToken(GherkinParser.AND, 0); } + public AndContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_and; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterAnd(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitAnd(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitAnd(this); + else return visitor.visitChildren(this); + } + } + + public final AndContext and() throws RecognitionException { + AndContext _localctx = new AndContext(_ctx, getState()); + enterRule(_localctx, 24, RULE_and); + try { + enterOuterAlt(_localctx, 1); + { + setState(207); + match(AND); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class AnystepContext extends ParserRuleContext { + public TerminalNode ANYSTEP() { return getToken(GherkinParser.ANYSTEP, 0); } + public AnystepContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_anystep; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterAnystep(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitAnystep(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitAnystep(this); + else return visitor.visitChildren(this); + } + } + + public final AnystepContext anystep() throws RecognitionException { + AnystepContext _localctx = new AnystepContext(_ctx, getState()); + enterRule(_localctx, 26, RULE_anystep); + try { + enterOuterAlt(_localctx, 1); + { + setState(209); + match(ANYSTEP); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ButContext extends ParserRuleContext { + public TerminalNode BUT() { return getToken(GherkinParser.BUT, 0); } + public ButContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_but; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterBut(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitBut(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitBut(this); + else return visitor.visitChildren(this); + } + } + + public final ButContext but() throws RecognitionException { + ButContext _localctx = new ButContext(_ctx, getState()); + enterRule(_localctx, 28, RULE_but); + try { + enterOuterAlt(_localctx, 1); + { + setState(211); + match(BUT); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class DatatableContext extends ParserRuleContext { + public List DATATABLE() { return getTokens(GherkinParser.DATATABLE); } + public TerminalNode DATATABLE(int i) { + return getToken(GherkinParser.DATATABLE, i); + } + public DatatableContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_datatable; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterDatatable(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitDatatable(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitDatatable(this); + else return visitor.visitChildren(this); + } + } + + public final DatatableContext datatable() throws RecognitionException { + DatatableContext _localctx = new DatatableContext(_ctx, getState()); + enterRule(_localctx, 30, RULE_datatable); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(214); + _errHandler.sync(this); + _alt = 1; + do { + switch (_alt) { + case 1: + { + { + setState(213); + match(DATATABLE); + } + } + break; + default: + throw new NoViableAltException(this); + } + setState(216); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,26,_ctx); + } while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class GivenContext extends ParserRuleContext { + public TerminalNode GIVEN() { return getToken(GherkinParser.GIVEN, 0); } + public GivenContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_given; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterGiven(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitGiven(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitGiven(this); + else return visitor.visitChildren(this); + } + } + + public final GivenContext given() throws RecognitionException { + GivenContext _localctx = new GivenContext(_ctx, getState()); + enterRule(_localctx, 32, RULE_given); + try { + enterOuterAlt(_localctx, 1); + { + setState(218); + match(GIVEN); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ThenContext extends ParserRuleContext { + public TerminalNode THEN() { return getToken(GherkinParser.THEN, 0); } + public ThenContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_then; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterThen(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitThen(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitThen(this); + else return visitor.visitChildren(this); + } + } + + public final ThenContext then() throws RecognitionException { + ThenContext _localctx = new ThenContext(_ctx, getState()); + enterRule(_localctx, 34, RULE_then); + try { + enterOuterAlt(_localctx, 1); + { + setState(220); + match(THEN); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class WhenContext extends ParserRuleContext { + public TerminalNode WHEN() { return getToken(GherkinParser.WHEN, 0); } + public WhenContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_when; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterWhen(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitWhen(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitWhen(this); + else return visitor.visitChildren(this); + } + } + + public final WhenContext when() throws RecognitionException { + WhenContext _localctx = new WhenContext(_ctx, getState()); + enterRule(_localctx, 36, RULE_when); + try { + enterOuterAlt(_localctx, 1); + { + setState(222); + match(WHEN); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ExamplesContext extends ParserRuleContext { + public TerminalNode EXAMPLES() { return getToken(GherkinParser.EXAMPLES, 0); } + public ExamplesContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_examples; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterExamples(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitExamples(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitExamples(this); + else return visitor.visitChildren(this); + } + } + + public final ExamplesContext examples() throws RecognitionException { + ExamplesContext _localctx = new ExamplesContext(_ctx, getState()); + enterRule(_localctx, 38, RULE_examples); + try { + enterOuterAlt(_localctx, 1); + { + setState(224); + match(EXAMPLES); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class InstructionDescriptionContext extends ParserRuleContext { + public TextContext text() { + return getRuleContext(TextContext.class,0); + } + public TerminalNode PARAMETER() { return getToken(GherkinParser.PARAMETER, 0); } + public TerminalNode AND() { return getToken(GherkinParser.AND, 0); } + public TerminalNode ANYSTEP() { return getToken(GherkinParser.ANYSTEP, 0); } + public TerminalNode BUT() { return getToken(GherkinParser.BUT, 0); } + public TerminalNode GIVEN() { return getToken(GherkinParser.GIVEN, 0); } + public TerminalNode THEN() { return getToken(GherkinParser.THEN, 0); } + public TerminalNode WHEN() { return getToken(GherkinParser.WHEN, 0); } + public TerminalNode SCENARIO() { return getToken(GherkinParser.SCENARIO, 0); } + public InstructionDescriptionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_instructionDescription; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterInstructionDescription(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitInstructionDescription(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitInstructionDescription(this); + else return visitor.visitChildren(this); + } + } + + public final InstructionDescriptionContext instructionDescription() throws RecognitionException { + InstructionDescriptionContext _localctx = new InstructionDescriptionContext(_ctx, getState()); + enterRule(_localctx, 40, RULE_instructionDescription); + try { + setState(235); + _errHandler.sync(this); + switch (_input.LA(1)) { + case TOKEN: + enterOuterAlt(_localctx, 1); + { + setState(226); + text(); + } + break; + case PARAMETER: + enterOuterAlt(_localctx, 2); + { + setState(227); + match(PARAMETER); + } + break; + case AND: + enterOuterAlt(_localctx, 3); + { + setState(228); + match(AND); + } + break; + case ANYSTEP: + enterOuterAlt(_localctx, 4); + { + setState(229); + match(ANYSTEP); + } + break; + case BUT: + enterOuterAlt(_localctx, 5); + { + setState(230); + match(BUT); + } + break; + case GIVEN: + enterOuterAlt(_localctx, 6); + { + setState(231); + match(GIVEN); + } + break; + case THEN: + enterOuterAlt(_localctx, 7); + { + setState(232); + match(THEN); + } + break; + case WHEN: + enterOuterAlt(_localctx, 8); + { + setState(233); + match(WHEN); + } + break; + case SCENARIO: + enterOuterAlt(_localctx, 9); + { + setState(234); + match(SCENARIO); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class StepDescriptionContext extends ParserRuleContext { + public TextContext text() { + return getRuleContext(TextContext.class,0); + } + public TerminalNode PARAMETER() { return getToken(GherkinParser.PARAMETER, 0); } + public StepDescriptionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_stepDescription; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterStepDescription(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitStepDescription(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitStepDescription(this); + else return visitor.visitChildren(this); + } + } + + public final StepDescriptionContext stepDescription() throws RecognitionException { + StepDescriptionContext _localctx = new StepDescriptionContext(_ctx, getState()); + enterRule(_localctx, 42, RULE_stepDescription); + try { + setState(239); + _errHandler.sync(this); + switch (_input.LA(1)) { + case TOKEN: + enterOuterAlt(_localctx, 1); + { + setState(237); + text(); + } + break; + case PARAMETER: + enterOuterAlt(_localctx, 2); + { + setState(238); + match(PARAMETER); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class DescriptionContext extends ParserRuleContext { + public TextContext text() { + return getRuleContext(TextContext.class,0); + } + public TerminalNode PARAMETER() { return getToken(GherkinParser.PARAMETER, 0); } + public TerminalNode TAG() { return getToken(GherkinParser.TAG, 0); } + public TerminalNode AND() { return getToken(GherkinParser.AND, 0); } + public TerminalNode ANYSTEP() { return getToken(GherkinParser.ANYSTEP, 0); } + public TerminalNode BUT() { return getToken(GherkinParser.BUT, 0); } + public TerminalNode DATATABLE() { return getToken(GherkinParser.DATATABLE, 0); } + public TerminalNode GIVEN() { return getToken(GherkinParser.GIVEN, 0); } + public TerminalNode THEN() { return getToken(GherkinParser.THEN, 0); } + public TerminalNode WHEN() { return getToken(GherkinParser.WHEN, 0); } + public TerminalNode SCENARIO() { return getToken(GherkinParser.SCENARIO, 0); } + public TerminalNode SCENARIOOUTLINE() { return getToken(GherkinParser.SCENARIOOUTLINE, 0); } + public TerminalNode STARTCOMMENT() { return getToken(GherkinParser.STARTCOMMENT, 0); } + public DescriptionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_description; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterDescription(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitDescription(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitDescription(this); + else return visitor.visitChildren(this); + } + } + + public final DescriptionContext description() throws RecognitionException { + DescriptionContext _localctx = new DescriptionContext(_ctx, getState()); + enterRule(_localctx, 44, RULE_description); + try { + setState(254); + _errHandler.sync(this); + switch (_input.LA(1)) { + case TOKEN: + enterOuterAlt(_localctx, 1); + { + setState(241); + text(); + } + break; + case PARAMETER: + enterOuterAlt(_localctx, 2); + { + setState(242); + match(PARAMETER); + } + break; + case TAG: + enterOuterAlt(_localctx, 3); + { + setState(243); + match(TAG); + } + break; + case AND: + enterOuterAlt(_localctx, 4); + { + setState(244); + match(AND); + } + break; + case ANYSTEP: + enterOuterAlt(_localctx, 5); + { + setState(245); + match(ANYSTEP); + } + break; + case BUT: + enterOuterAlt(_localctx, 6); + { + setState(246); + match(BUT); + } + break; + case DATATABLE: + enterOuterAlt(_localctx, 7); + { + setState(247); + match(DATATABLE); + } + break; + case GIVEN: + enterOuterAlt(_localctx, 8); + { + setState(248); + match(GIVEN); + } + break; + case THEN: + enterOuterAlt(_localctx, 9); + { + setState(249); + match(THEN); + } + break; + case WHEN: + enterOuterAlt(_localctx, 10); + { + setState(250); + match(WHEN); + } + break; + case SCENARIO: + enterOuterAlt(_localctx, 11); + { + setState(251); + match(SCENARIO); + } + break; + case SCENARIOOUTLINE: + enterOuterAlt(_localctx, 12); + { + setState(252); + match(SCENARIOOUTLINE); + } + break; + case STARTCOMMENT: + enterOuterAlt(_localctx, 13); + { + setState(253); + match(STARTCOMMENT); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class TextContext extends ParserRuleContext { + public List TOKEN() { return getTokens(GherkinParser.TOKEN); } + public TerminalNode TOKEN(int i) { + return getToken(GherkinParser.TOKEN, i); + } + public TextContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_text; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).enterText(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GherkinListener ) ((GherkinListener)listener).exitText(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof GherkinVisitor ) return ((GherkinVisitor)visitor).visitText(this); + else return visitor.visitChildren(this); + } + } + + public final TextContext text() throws RecognitionException { + TextContext _localctx = new TextContext(_ctx, getState()); + enterRule(_localctx, 46, RULE_text); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(257); + _errHandler.sync(this); + _alt = 1; + do { + switch (_alt) { + case 1: + { + { + setState(256); + match(TOKEN); + } + } + break; + default: + throw new NoViableAltException(this); + } + setState(259); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,30,_ctx); + } while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static final String _serializedATN = + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\32\u0108\4\2\t\2"+ + "\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+ + "\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ + "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+ + "\3\2\5\2\64\n\2\3\2\3\2\7\28\n\2\f\2\16\2;\13\2\3\2\7\2>\n\2\f\2\16\2"+ + "A\13\2\3\2\7\2D\n\2\f\2\16\2G\13\2\3\2\3\2\3\3\7\3L\n\3\f\3\16\3O\13\3"+ + "\3\3\7\3R\n\3\f\3\16\3U\13\3\3\3\7\3X\n\3\f\3\16\3[\13\3\3\3\5\3^\n\3"+ + "\3\4\6\4a\n\4\r\4\16\4b\3\4\3\4\5\4g\n\4\3\5\3\5\7\5k\n\5\f\5\16\5n\13"+ + "\5\3\5\3\5\7\5r\n\5\f\5\16\5u\13\5\3\5\6\5x\n\5\r\5\16\5y\3\5\3\5\7\5"+ + "~\n\5\f\5\16\5\u0081\13\5\7\5\u0083\n\5\f\5\16\5\u0086\13\5\3\5\6\5\u0089"+ + "\n\5\r\5\16\5\u008a\3\5\7\5\u008e\n\5\f\5\16\5\u0091\13\5\3\5\3\5\3\5"+ + "\7\5\u0096\n\5\f\5\16\5\u0099\13\5\5\5\u009b\n\5\3\6\3\6\3\6\5\6\u00a0"+ + "\n\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n\3\13\3\13\7\13\u00ac\n\13\f\13\16"+ + "\13\u00af\13\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\7\f\u00b9\n\f\f\f\16\f"+ + "\u00bc\13\f\3\f\7\f\u00bf\n\f\f\f\16\f\u00c2\13\f\3\f\7\f\u00c5\n\f\f"+ + "\f\16\f\u00c8\13\f\3\f\5\f\u00cb\n\f\3\r\6\r\u00ce\n\r\r\r\16\r\u00cf"+ + "\3\16\3\16\3\17\3\17\3\20\3\20\3\21\6\21\u00d9\n\21\r\21\16\21\u00da\3"+ + "\22\3\22\3\23\3\23\3\24\3\24\3\25\3\25\3\26\3\26\3\26\3\26\3\26\3\26\3"+ + "\26\3\26\3\26\5\26\u00ee\n\26\3\27\3\27\5\27\u00f2\n\27\3\30\3\30\3\30"+ + "\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\5\30\u0101\n\30\3\31"+ + "\6\31\u0104\n\31\r\31\16\31\u0105\3\31\2\2\32\2\4\6\b\n\f\16\20\22\24"+ + "\26\30\32\34\36 \"$&(*,.\60\2\2\2\u0129\2\63\3\2\2\2\4S\3\2\2\2\6`\3\2"+ + "\2\2\b\u009a\3\2\2\2\n\u009f\3\2\2\2\f\u00a1\3\2\2\2\16\u00a3\3\2\2\2"+ + "\20\u00a5\3\2\2\2\22\u00a7\3\2\2\2\24\u00a9\3\2\2\2\26\u00ca\3\2\2\2\30"+ + "\u00cd\3\2\2\2\32\u00d1\3\2\2\2\34\u00d3\3\2\2\2\36\u00d5\3\2\2\2 \u00d8"+ + "\3\2\2\2\"\u00dc\3\2\2\2$\u00de\3\2\2\2&\u00e0\3\2\2\2(\u00e2\3\2\2\2"+ + "*\u00ed\3\2\2\2,\u00f1\3\2\2\2.\u0100\3\2\2\2\60\u0103\3\2\2\2\62\64\7"+ + "\7\2\2\63\62\3\2\2\2\63\64\3\2\2\2\64\65\3\2\2\2\659\5\4\3\2\668\5.\30"+ + "\2\67\66\3\2\2\28;\3\2\2\29\67\3\2\2\29:\3\2\2\2:?\3\2\2\2;9\3\2\2\2<"+ + ">\5\6\4\2=<\3\2\2\2>A\3\2\2\2?=\3\2\2\2?@\3\2\2\2@E\3\2\2\2A?\3\2\2\2"+ + "BD\7\31\2\2CB\3\2\2\2DG\3\2\2\2EC\3\2\2\2EF\3\2\2\2FH\3\2\2\2GE\3\2\2"+ + "\2HI\7\2\2\3I\3\3\2\2\2JL\7\31\2\2KJ\3\2\2\2LO\3\2\2\2MK\3\2\2\2MN\3\2"+ + "\2\2NP\3\2\2\2OM\3\2\2\2PR\5\30\r\2QM\3\2\2\2RU\3\2\2\2SQ\3\2\2\2ST\3"+ + "\2\2\2TY\3\2\2\2US\3\2\2\2VX\7\31\2\2WV\3\2\2\2X[\3\2\2\2YW\3\2\2\2YZ"+ + "\3\2\2\2Z]\3\2\2\2[Y\3\2\2\2\\^\7\f\2\2]\\\3\2\2\2]^\3\2\2\2^\5\3\2\2"+ + "\2_a\7\31\2\2`_\3\2\2\2ab\3\2\2\2b`\3\2\2\2bc\3\2\2\2cf\3\2\2\2dg\5\b"+ + "\5\2eg\5 \21\2fd\3\2\2\2fe\3\2\2\2g\7\3\2\2\2hl\5\16\b\2ik\5.\30\2ji\3"+ + "\2\2\2kn\3\2\2\2lj\3\2\2\2lm\3\2\2\2m\u009b\3\2\2\2nl\3\2\2\2os\5\n\6"+ + "\2pr\5.\30\2qp\3\2\2\2ru\3\2\2\2sq\3\2\2\2st\3\2\2\2t\u0084\3\2\2\2us"+ + "\3\2\2\2vx\7\31\2\2wv\3\2\2\2xy\3\2\2\2yw\3\2\2\2yz\3\2\2\2z{\3\2\2\2"+ + "{\177\5,\27\2|~\5.\30\2}|\3\2\2\2~\u0081\3\2\2\2\177}\3\2\2\2\177\u0080"+ + "\3\2\2\2\u0080\u0083\3\2\2\2\u0081\177\3\2\2\2\u0082w\3\2\2\2\u0083\u0086"+ + "\3\2\2\2\u0084\u0082\3\2\2\2\u0084\u0085\3\2\2\2\u0085\u008f\3\2\2\2\u0086"+ + "\u0084\3\2\2\2\u0087\u0089\7\31\2\2\u0088\u0087\3\2\2\2\u0089\u008a\3"+ + "\2\2\2\u008a\u0088\3\2\2\2\u008a\u008b\3\2\2\2\u008b\u008c\3\2\2\2\u008c"+ + "\u008e\5\24\13\2\u008d\u0088\3\2\2\2\u008e\u0091\3\2\2\2\u008f\u008d\3"+ + "\2\2\2\u008f\u0090\3\2\2\2\u0090\u009b\3\2\2\2\u0091\u008f\3\2\2\2\u0092"+ + "\u009b\5\30\r\2\u0093\u0097\5*\26\2\u0094\u0096\5.\30\2\u0095\u0094\3"+ + "\2\2\2\u0096\u0099\3\2\2\2\u0097\u0095\3\2\2\2\u0097\u0098\3\2\2\2\u0098"+ + "\u009b\3\2\2\2\u0099\u0097\3\2\2\2\u009ah\3\2\2\2\u009ao\3\2\2\2\u009a"+ + "\u0092\3\2\2\2\u009a\u0093\3\2\2\2\u009b\t\3\2\2\2\u009c\u00a0\5\f\7\2"+ + "\u009d\u00a0\5\20\t\2\u009e\u00a0\5\22\n\2\u009f\u009c\3\2\2\2\u009f\u009d"+ + "\3\2\2\2\u009f\u009e\3\2\2\2\u00a0\13\3\2\2\2\u00a1\u00a2\7\n\2\2\u00a2"+ + "\r\3\2\2\2\u00a3\u00a4\7\r\2\2\u00a4\17\3\2\2\2\u00a5\u00a6\7\16\2\2\u00a6"+ + "\21\3\2\2\2\u00a7\u00a8\7\17\2\2\u00a8\23\3\2\2\2\u00a9\u00ad\5\26\f\2"+ + "\u00aa\u00ac\5.\30\2\u00ab\u00aa\3\2\2\2\u00ac\u00af\3\2\2\2\u00ad\u00ab"+ + "\3\2\2\2\u00ad\u00ae\3\2\2\2\u00ae\25\3\2\2\2\u00af\u00ad\3\2\2\2\u00b0"+ + "\u00cb\5\32\16\2\u00b1\u00cb\5\34\17\2\u00b2\u00cb\5\36\20\2\u00b3\u00cb"+ + "\5 \21\2\u00b4\u00cb\5\"\22\2\u00b5\u00cb\5$\23\2\u00b6\u00cb\5&\24\2"+ + "\u00b7\u00b9\7\31\2\2\u00b8\u00b7\3\2\2\2\u00b9\u00bc\3\2\2\2\u00ba\u00b8"+ + "\3\2\2\2\u00ba\u00bb\3\2\2\2\u00bb\u00bd\3\2\2\2\u00bc\u00ba\3\2\2\2\u00bd"+ + "\u00bf\5\30\r\2\u00be\u00ba\3\2\2\2\u00bf\u00c2\3\2\2\2\u00c0\u00be\3"+ + "\2\2\2\u00c0\u00c1\3\2\2\2\u00c1\u00c6\3\2\2\2\u00c2\u00c0\3\2\2\2\u00c3"+ + "\u00c5\7\31\2\2\u00c4\u00c3\3\2\2\2\u00c5\u00c8\3\2\2\2\u00c6\u00c4\3"+ + "\2\2\2\u00c6\u00c7\3\2\2\2\u00c7\u00c9\3\2\2\2\u00c8\u00c6\3\2\2\2\u00c9"+ + "\u00cb\5(\25\2\u00ca\u00b0\3\2\2\2\u00ca\u00b1\3\2\2\2\u00ca\u00b2\3\2"+ + "\2\2\u00ca\u00b3\3\2\2\2\u00ca\u00b4\3\2\2\2\u00ca\u00b5\3\2\2\2\u00ca"+ + "\u00b6\3\2\2\2\u00ca\u00c0\3\2\2\2\u00cb\27\3\2\2\2\u00cc\u00ce\7\27\2"+ + "\2\u00cd\u00cc\3\2\2\2\u00ce\u00cf\3\2\2\2\u00cf\u00cd\3\2\2\2\u00cf\u00d0"+ + "\3\2\2\2\u00d0\31\3\2\2\2\u00d1\u00d2\7\20\2\2\u00d2\33\3\2\2\2\u00d3"+ + "\u00d4\7\21\2\2\u00d4\35\3\2\2\2\u00d5\u00d6\7\22\2\2\u00d6\37\3\2\2\2"+ + "\u00d7\u00d9\7\23\2\2\u00d8\u00d7\3\2\2\2\u00d9\u00da\3\2\2\2\u00da\u00d8"+ + "\3\2\2\2\u00da\u00db\3\2\2\2\u00db!\3\2\2\2\u00dc\u00dd\7\24\2\2\u00dd"+ + "#\3\2\2\2\u00de\u00df\7\25\2\2\u00df%\3\2\2\2\u00e0\u00e1\7\26\2\2\u00e1"+ + "\'\3\2\2\2\u00e2\u00e3\7\13\2\2\u00e3)\3\2\2\2\u00e4\u00ee\5\60\31\2\u00e5"+ + "\u00ee\7\30\2\2\u00e6\u00ee\7\20\2\2\u00e7\u00ee\7\21\2\2\u00e8\u00ee"+ + "\7\22\2\2\u00e9\u00ee\7\24\2\2\u00ea\u00ee\7\25\2\2\u00eb\u00ee\7\26\2"+ + "\2\u00ec\u00ee\7\16\2\2\u00ed\u00e4\3\2\2\2\u00ed\u00e5\3\2\2\2\u00ed"+ + "\u00e6\3\2\2\2\u00ed\u00e7\3\2\2\2\u00ed\u00e8\3\2\2\2\u00ed\u00e9\3\2"+ + "\2\2\u00ed\u00ea\3\2\2\2\u00ed\u00eb\3\2\2\2\u00ed\u00ec\3\2\2\2\u00ee"+ + "+\3\2\2\2\u00ef\u00f2\5\60\31\2\u00f0\u00f2\7\30\2\2\u00f1\u00ef\3\2\2"+ + "\2\u00f1\u00f0\3\2\2\2\u00f2-\3\2\2\2\u00f3\u0101\5\60\31\2\u00f4\u0101"+ + "\7\30\2\2\u00f5\u0101\7\27\2\2\u00f6\u0101\7\20\2\2\u00f7\u0101\7\21\2"+ + "\2\u00f8\u0101\7\22\2\2\u00f9\u0101\7\23\2\2\u00fa\u0101\7\24\2\2\u00fb"+ + "\u0101\7\25\2\2\u00fc\u0101\7\26\2\2\u00fd\u0101\7\16\2\2\u00fe\u0101"+ + "\7\17\2\2\u00ff\u0101\7\7\2\2\u0100\u00f3\3\2\2\2\u0100\u00f4\3\2\2\2"+ + "\u0100\u00f5\3\2\2\2\u0100\u00f6\3\2\2\2\u0100\u00f7\3\2\2\2\u0100\u00f8"+ + "\3\2\2\2\u0100\u00f9\3\2\2\2\u0100\u00fa\3\2\2\2\u0100\u00fb\3\2\2\2\u0100"+ + "\u00fc\3\2\2\2\u0100\u00fd\3\2\2\2\u0100\u00fe\3\2\2\2\u0100\u00ff\3\2"+ + "\2\2\u0101/\3\2\2\2\u0102\u0104\7\32\2\2\u0103\u0102\3\2\2\2\u0104\u0105"+ + "\3\2\2\2\u0105\u0103\3\2\2\2\u0105\u0106\3\2\2\2\u0106\61\3\2\2\2!\63"+ + "9?EMSY]bflsy\177\u0084\u008a\u008f\u0097\u009a\u009f\u00ad\u00ba\u00c0"+ + "\u00c6\u00ca\u00cf\u00da\u00ed\u00f1\u0100\u0105"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinVisitor.java b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinVisitor.java new file mode 100644 index 00000000000..e08c47c7825 --- /dev/null +++ b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinVisitor.java @@ -0,0 +1,167 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +// CHECKSTYLE:OFF +// Generated from net/sourceforge/pmd/lang/gherkin/ast/Gherkin.g4 by ANTLR 4.9.3 +package net.sourceforge.pmd.lang.gherkin.ast; +import org.antlr.v4.runtime.tree.ParseTreeVisitor; + +/** + * This interface defines a complete generic visitor for a parse tree produced + * by {@link GherkinParser}. + * + * @param The return type of the visit operation. Use {@link Void} for + * operations with no return type. + * + * @deprecated Since 7.8.0. This class was never intended to be generated. It will be removed with no replacement. + */ + +@Deprecated +@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public interface GherkinVisitor extends ParseTreeVisitor { + /** + * Visit a parse tree produced by {@link GherkinParser#main}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitMain(GherkinParser.MainContext ctx); + /** + * Visit a parse tree produced by {@link GherkinParser#feature}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitFeature(GherkinParser.FeatureContext ctx); + /** + * Visit a parse tree produced by {@link GherkinParser#instructionLine}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInstructionLine(GherkinParser.InstructionLineContext ctx); + /** + * Visit a parse tree produced by {@link GherkinParser#instruction}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInstruction(GherkinParser.InstructionContext ctx); + /** + * Visit a parse tree produced by {@link GherkinParser#stepInstruction}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStepInstruction(GherkinParser.StepInstructionContext ctx); + /** + * Visit a parse tree produced by {@link GherkinParser#background}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitBackground(GherkinParser.BackgroundContext ctx); + /** + * Visit a parse tree produced by {@link GherkinParser#rulex}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitRulex(GherkinParser.RulexContext ctx); + /** + * Visit a parse tree produced by {@link GherkinParser#scenario}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitScenario(GherkinParser.ScenarioContext ctx); + /** + * Visit a parse tree produced by {@link GherkinParser#scenarioOutline}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitScenarioOutline(GherkinParser.ScenarioOutlineContext ctx); + /** + * Visit a parse tree produced by {@link GherkinParser#step}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStep(GherkinParser.StepContext ctx); + /** + * Visit a parse tree produced by {@link GherkinParser#stepItem}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStepItem(GherkinParser.StepItemContext ctx); + /** + * Visit a parse tree produced by {@link GherkinParser#tagline}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTagline(GherkinParser.TaglineContext ctx); + /** + * Visit a parse tree produced by {@link GherkinParser#and}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitAnd(GherkinParser.AndContext ctx); + /** + * Visit a parse tree produced by {@link GherkinParser#anystep}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitAnystep(GherkinParser.AnystepContext ctx); + /** + * Visit a parse tree produced by {@link GherkinParser#but}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitBut(GherkinParser.ButContext ctx); + /** + * Visit a parse tree produced by {@link GherkinParser#datatable}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitDatatable(GherkinParser.DatatableContext ctx); + /** + * Visit a parse tree produced by {@link GherkinParser#given}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitGiven(GherkinParser.GivenContext ctx); + /** + * Visit a parse tree produced by {@link GherkinParser#then}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitThen(GherkinParser.ThenContext ctx); + /** + * Visit a parse tree produced by {@link GherkinParser#when}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitWhen(GherkinParser.WhenContext ctx); + /** + * Visit a parse tree produced by {@link GherkinParser#examples}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExamples(GherkinParser.ExamplesContext ctx); + /** + * Visit a parse tree produced by {@link GherkinParser#instructionDescription}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInstructionDescription(GherkinParser.InstructionDescriptionContext ctx); + /** + * Visit a parse tree produced by {@link GherkinParser#stepDescription}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStepDescription(GherkinParser.StepDescriptionContext ctx); + /** + * Visit a parse tree produced by {@link GherkinParser#description}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitDescription(GherkinParser.DescriptionContext ctx); + /** + * Visit a parse tree produced by {@link GherkinParser#text}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitText(GherkinParser.TextContext ctx); +} \ No newline at end of file From e201b5261db6e0f7792c622df40e08164d261868 Mon Sep 17 00:00:00 2001 From: Kursat Aktas Date: Fri, 15 Nov 2024 00:11:12 +0300 Subject: [PATCH 0239/1962] Introducing PMD Guru on Gurubase.io Signed-off-by: Kursat Aktas --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8d215b233af..22e830efb83 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ [![Codacy Badge](https://app.codacy.com/project/badge/Grade/ea550046a02344ec850553476c4aa2ca)](https://app.codacy.com/organizations/gh/pmd/dashboard) [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg)](code_of_conduct.md) [![Documentation (latest)](https://img.shields.io/badge/docs-latest-green)](https://docs.pmd-code.org/latest/) +[![Gurubase](https://img.shields.io/badge/Gurubase-Ask%20PMD%20Guru-006BFF)](https://gurubase.io/g/pmd) **PMD** is an extensible multilanguage static code analyzer. It finds common programming flaws like unused variables, empty catch blocks, unnecessary object creation, and so forth. It's mainly concerned with **Java and From 69a24126f7ae12c153bda1ce30fb169114a0fa91 Mon Sep 17 00:00:00 2001 From: mitchspano Date: Thu, 14 Nov 2024 23:29:44 +0000 Subject: [PATCH 0240/1962] Fix formatting and static code analysis findings. --- .../QueueableWithoutFinalizerRule.java | 116 +++++++++--------- .../QueueableWithoutFinalizerTest.java | 2 +- 2 files changed, 62 insertions(+), 56 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableWithoutFinalizerRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableWithoutFinalizerRule.java index bae5f2ef854..9acb39e07d1 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableWithoutFinalizerRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableWithoutFinalizerRule.java @@ -5,82 +5,88 @@ package net.sourceforge.pmd.lang.apex.rule.bestpractices; import java.util.List; + +import org.checkerframework.checker.nullness.qual.NonNull; + import net.sourceforge.pmd.lang.apex.ast.ASTMethod; import net.sourceforge.pmd.lang.apex.ast.ASTMethodCallExpression; import net.sourceforge.pmd.lang.apex.ast.ASTParameter; import net.sourceforge.pmd.lang.apex.ast.ASTUserClass; import net.sourceforge.pmd.lang.apex.rule.AbstractApexRule; import net.sourceforge.pmd.lang.rule.RuleTargetSelector; -import org.checkerframework.checker.nullness.qual.NonNull; /** * Scans classes which implement the `Queueable` interface. If the `public void - * execute(QueueableContext context)` method does not call the `System.attachFinalizer(Finalizer f)` - * method, then a violation will be added to the `execute` method. + * execute(QueueableContext context)` method does not call the + * `System.attachFinalizer(Finalizer f)` method, then a violation will be added + * to the `execute` method. * * @author mitchspano */ public class QueueableWithoutFinalizerRule extends AbstractApexRule { - private static final String EXECUTE = "execute"; - private static final String QUEUEABLE = "queueable"; - private static final String QUEUEABLE_CONTEXT = "queueablecontext"; - private static final String SYSTEM_ATTACH_FINALIZER = "system.attachfinalizer"; - - @Override - protected @NonNull RuleTargetSelector buildTargetSelector() { - return RuleTargetSelector.forTypes(ASTUserClass.class); - } + private static final String EXECUTE = "execute"; + private static final String QUEUEABLE = "queueable"; + private static final String QUEUEABLE_CONTEXT = "queueablecontext"; + private static final String SYSTEM_ATTACH_FINALIZER = "system.attachfinalizer"; - /** - * If the class implements the `Queueable` interface and the `execute(QueueableContext context)` - * does not call the `System.attachFinalizer(Finalizer f)` method, then add a violation. - */ - @Override - public Object visit(ASTUserClass theClass, Object data) { - if (!implementsTheQueueableInterface(theClass)) { - return data; + @Override + protected @NonNull RuleTargetSelector buildTargetSelector() { + return RuleTargetSelector.forTypes(ASTUserClass.class); } - for (ASTMethod theMethod : theClass.descendants(ASTMethod.class).toList()) { - if (isTheExecuteMethodOfTheQueueableInterface(theMethod) - && !callsTheSystemAttachFinalizerMethod(theMethod)) { - asCtx(data).addViolation(theMethod); - } + + /** + * If the class implements the `Queueable` interface and the + * `execute(QueueableContext context)` does not call the + * `System.attachFinalizer(Finalizer f)` method, then add a violation. + */ + @Override + public Object visit(ASTUserClass theClass, Object data) { + if (!implementsTheQueueableInterface(theClass)) { + return data; + } + for (ASTMethod theMethod : theClass.descendants(ASTMethod.class).toList()) { + if (isTheExecuteMethodOfTheQueueableInterface(theMethod) + && !callsTheSystemAttachFinalizerMethod(theMethod)) { + asCtx(data).addViolation(theMethod); + } + } + return data; } - return data; - } - /** Determines if the class implements the Queueable interface. */ - private boolean implementsTheQueueableInterface(ASTUserClass theClass) { - for (String interfaceName : theClass.getInterfaceNames()) { - if (interfaceName.equalsIgnoreCase(QUEUEABLE)) { - return true; - } + /** Determines if the class implements the Queueable interface. */ + private boolean implementsTheQueueableInterface(ASTUserClass theClass) { + for (String interfaceName : theClass.getInterfaceNames()) { + if (QUEUEABLE.equalsIgnoreCase(interfaceName)) { + return true; + } + } + return false; } - return false; - } - /** - * Determines if the method is the `execute(QueueableContext context)` method. Parameter count is - * checked to account for method overloading. - */ - private boolean isTheExecuteMethodOfTheQueueableInterface(ASTMethod theMethod) { - if (!theMethod.getCanonicalName().equalsIgnoreCase(EXECUTE)) { - return false; + /** + * Determines if the method is the `execute(QueueableContext context)` + * method. Parameter count is checked to account for method overloading. + */ + private boolean isTheExecuteMethodOfTheQueueableInterface(ASTMethod theMethod) { + if (!EXECUTE.equalsIgnoreCase(theMethod.getCanonicalName())) { + return false; + } + List parameters = theMethod.descendants(ASTParameter.class).toList(); + return parameters.size() == 1 && QUEUEABLE_CONTEXT.equalsIgnoreCase(parameters.get(0).getType()); } - List parameters = theMethod.descendants(ASTParameter.class).toList(); - return parameters.size() == 1 - && parameters.get(0).getType().equalsIgnoreCase(QUEUEABLE_CONTEXT); - } - /** Determines if the method calls the `System.attachFinalizer(Finalizer f)` method. */ - private boolean callsTheSystemAttachFinalizerMethod(ASTMethod theMethod) { - for (ASTMethodCallExpression methodCallExpression : - theMethod.descendants(ASTMethodCallExpression.class).toList()) { - if (methodCallExpression.getFullMethodName().equalsIgnoreCase(SYSTEM_ATTACH_FINALIZER)) { - return true; - } + /** + * Determines if the method calls the `System.attachFinalizer(Finalizer f)` + * method. + */ + private boolean callsTheSystemAttachFinalizerMethod(ASTMethod theMethod) { + for (ASTMethodCallExpression methodCallExpression : theMethod.descendants(ASTMethodCallExpression.class) + .toList()) { + if (SYSTEM_ATTACH_FINALIZER.equalsIgnoreCase(methodCallExpression.getFullMethodName())) { + return true; + } + } + return false; } - return false; - } } diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableWithoutFinalizerTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableWithoutFinalizerTest.java index 35d20e8d9cf..7daa72c1696 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableWithoutFinalizerTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/QueueableWithoutFinalizerTest.java @@ -7,5 +7,5 @@ import net.sourceforge.pmd.test.PmdRuleTst; class QueueableWithoutFinalizerTest extends PmdRuleTst { - // no additional unit tests + // no additional unit tests } From e4b91f65d7f6d6d490c7e718fde9d0cdebdfddd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 15 Nov 2024 11:50:45 +0100 Subject: [PATCH 0241/1962] Allow lambdas with unresolved target types to succeed inference This prevents failures in code that uses lambdas --- .../pmd/lang/java/types/TypingContext.java | 2 +- .../types/internal/infer/ExprCheckHelper.java | 36 ++++++++++++-- .../java/types/internal/infer/ExprMirror.java | 13 ++++- .../java/types/internal/infer/ExprOps.java | 5 ++ .../internal/infer/ast/LambdaMirrorImpl.java | 25 ++++++---- .../infer/UnresolvedTypesRecoveryTest.kt | 48 +++++++++++++++++++ 6 files changed, 114 insertions(+), 15 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypingContext.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypingContext.java index fc55e155a6c..4721218ebba 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypingContext.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypingContext.java @@ -49,7 +49,7 @@ public TypingContext andThen(Map map) { return new TypingContext(this, map); } - public TypingContext andThenZip(List symbols, List types) { + public TypingContext andThenZip(List symbols, List types) { AssertionUtil.requireParamNotNull("symbols", symbols); AssertionUtil.requireParamNotNull("types", types); if (symbols.size() != types.size()) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java index f6521426e2b..a01d285be0e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java @@ -17,6 +17,7 @@ import static net.sourceforge.pmd.lang.java.types.internal.infer.InferenceVar.BoundKind.UPPER; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Set; @@ -115,7 +116,8 @@ boolean isCompatible(JTypeMirror targetType, ExprMirror expr) { } if (expr instanceof FunctionalExprMirror) { // those are never standalone - JClassType funType = getProbablyFunctItfType(targetType, expr); + + JClassType funType = getProbablyFunctItfType(targetType, (FunctionalExprMirror) expr); if (funType == null) { /* * The functional expression has an inference variable as a target type, @@ -160,6 +162,23 @@ boolean isCompatible(JTypeMirror targetType, ExprMirror expr) { return false; } + private void handleFunctionalExprWithoutTargetType(FunctionalExprMirror expr, JTypeMirror targetType) { + if (expr instanceof LambdaExprMirror) { + LambdaExprMirror lambda = (LambdaExprMirror) expr; + List paramTypes; + List explicit = lambda.getExplicitParameterTypes(); + paramTypes = explicit != null + ? explicit : Collections.nCopies(lambda.getParamCount(), ts.UNKNOWN); + lambda.updateTypingContext(paramTypes); + // checker.checkExprConstraint(infCtx, ts.UNKNOWN, fun.getReturnType()); + } + // todo method ref + infCtx.addInstantiationListener(infCtx.freeVarsIn(targetType), ctx -> { + expr.setInferredType(ctx.ground(targetType)); + expr.setFunctionalMethod(ts.UNRESOLVED_METHOD); + }); + } + private boolean isInvocationCompatible(JTypeMirror targetType, InvocationMirror invoc, boolean isStandalone) { MethodCallSite nestedSite = infer.newCallSite(invoc, targetType, this.site, this.infCtx, isSpecificityCheck()); @@ -210,7 +229,7 @@ private boolean isInvocationCompatible(JTypeMirror targetType, InvocationMirror return true; } - private @Nullable JClassType getProbablyFunctItfType(final JTypeMirror targetType, ExprMirror expr) { + private @Nullable JClassType getProbablyFunctItfType(final JTypeMirror targetType, FunctionalExprMirror expr) { JClassType asClass; if (targetType instanceof InferenceVar && site != null) { if (site.isInFinalInvocation()) { @@ -222,6 +241,15 @@ private boolean isInvocationCompatible(JTypeMirror targetType, InvocationMirror asClass = asClassType(targetType); } + if (asClass == null && TypeOps.isUnresolved(targetType) + || asClass != null && TypeOps.isUnresolved(asClass)) { + // Then the whole thing will fail because we cannot find + // a functional method/ it is not a proper functional interface. + JTypeMirror target = asClass != null ? asClass : targetType; + handleFunctionalExprWithoutTargetType(expr, target); + // We consider it as matching though, just as if the lambda had an (*unknown*) type. + return null; + } if (asClass == null) { throw ResolutionFailedException.notAFunctionalInterface(infer.LOG, targetType, expr); } @@ -573,7 +601,7 @@ private boolean isLambdaCongruent(@NonNull JClassType functionalItf, lambda.setInferredType(solvedCtx.ground(groundTargetType)); JMethodSig solvedGroundFun = solvedCtx.ground(groundFun); lambda.setFunctionalMethod(solvedGroundFun); - lambda.updateTypingContext(solvedGroundFun); + lambda.updateTypingContext(solvedGroundFun.getFormalParameters()); } JTypeMirror groundResult = solvedCtx.ground(result); // We need to build another checker that uses the solved context. @@ -592,7 +620,7 @@ private boolean isLambdaCongruent(@NonNull JClassType functionalItf, } if (mayMutateExpr()) { // we know that the lambda matches now - lambda.updateTypingContext(groundFun); + lambda.updateTypingContext(groundFun.getFormalParameters()); } return true; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java index 6d1038427b8..4f814bd6459 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java @@ -298,7 +298,8 @@ interface LambdaExprMirror extends FunctionalExprMirror { /** * Returns the types of the explicit parameters. If the lambda - * is implicitly typed, then returns null. + * is implicitly typed, then returns null. If some parameters + * have a var type, returns {@link TypeSystem#UNKNOWN} for those. * *

    Note that a degenerate case of explicitly typed lambda * expression is a lambda with zero formal parameters. @@ -346,7 +347,15 @@ default boolean isExplicitlyTyped() { */ boolean isVoidCompatible(); - void updateTypingContext(JMethodSig groundFun); + /** + * Set the currently considered type of the parameters. + * This may change depending on which target type we are currently + * considering. The type of parameters (and therefore the typing context) + * may influence the type of the return values of the lambda. + * + * @param formalParameters formal parameter types of the lambda + */ + void updateTypingContext(List formalParameters); } /** diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java index a04c91c55fd..7629ca4b65e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java @@ -78,6 +78,11 @@ boolean isPotentiallyCompatible(JMethodSig m, ExprMirror e, JTypeMirror t) { // a type variable if the type variable is a type parameter of the candidate method. return m.getTypeParameters().contains(t); } + if (TypeOps.isUnresolved(t)) { + // Then we will not find a functional interface method. + // Treat the argument as potentially compatible though. + return true; + } JMethodSig fun = TypeOps.findFunctionalInterfaceMethod(t); if (fun == null) { // t is not a functional interface diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/LambdaMirrorImpl.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/LambdaMirrorImpl.java index d354acb4e4b..05c0b5c0bf0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/LambdaMirrorImpl.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/LambdaMirrorImpl.java @@ -19,8 +19,8 @@ import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement; import net.sourceforge.pmd.lang.java.ast.ASTThrowStatement; +import net.sourceforge.pmd.lang.java.ast.ASTType; import net.sourceforge.pmd.lang.java.ast.ASTUnaryExpression; -import net.sourceforge.pmd.lang.java.ast.TypeNode; import net.sourceforge.pmd.lang.java.symbols.JVariableSymbol; import net.sourceforge.pmd.lang.java.types.JMethodSig; import net.sourceforge.pmd.lang.java.types.JTypeMirror; @@ -74,14 +74,23 @@ public boolean isEquivalentToUnderlyingAst() { @Override public @Nullable List getExplicitParameterTypes() { ASTLambdaParameterList parameters = myNode.getParameters(); - if (parameters.size() == 0) { + if (parameters.isEmpty()) { return Collections.emptyList(); } - List types = parameters.toStream() - .map(ASTLambdaParameter::getTypeNode) - .toList(TypeNode::getTypeMirror); - return types.isEmpty() ? null : types; + if (parameters.toStream().all(ASTLambdaParameter::isTypeInferred)) { + return null; + } + + return parameters.toStream() + .toList(e -> { + ASTType typeNode = e.getTypeNode(); + if (typeNode == null) { + // var type + return factory.ts.UNKNOWN; + } + return typeNode.getTypeMirror(); + }); } @Override @@ -102,10 +111,10 @@ public List getResultExpressions() { } @Override - public void updateTypingContext(JMethodSig groundFun) { + public void updateTypingContext(List formalTypes) { if (!isExplicitlyTyped()) { // update bindings - setTypingContext(getTypingContext().andThenZip(formalSymbols, groundFun.getFormalParameters())); + setTypingContext(getTypingContext().andThenZip(formalSymbols, formalTypes)); } } diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt index 45c13cf5691..d7c366d48ad 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt @@ -702,4 +702,52 @@ class C { buildItem.methodType.symbol shouldBe buildItemDecl } } + + parserTest("Type inference should treat lambda with unresolved target type as UNKNOWN") { + + // here the FunctionalItf is the target type for the lambda + // but it is unresolved. It should not prevent type inference from + // resolving foo and bar to their respective overloads + val (acu, _) = parser.parseWithTypeInferenceSpy( + """ + class Foo { + public void methodA() { + foo(() -> "auie"); + foo(1, () -> "auie"); + var x = bar(() -> ""); + } + + private void foo(int y, FunctionalItf x) { + } + private void foo(FunctionalItf x) { + return SummaryDto.ItemDto.builder().build(); + } + private T bar(T x) { + return SummaryDto.ItemDto.builder().build(); + } + // interface FunctionalItf { String x(); } + } + """ + ) + + val (foo1, foo2, bar) = acu.methodCalls().toList() + val functItfT = acu.descendants(ASTClassType::class.java) + .filter { it.simpleName == "FunctionalItf" } + .firstOrThrow().typeMirror + val (_, foo2Decl, fooDecl, barDecl) = acu.methodDeclarations().toList { it.symbol } + val lambdas = acu.descendants(ASTLambdaExpression::class.java).toList() + + acu.withTypeDsl { + foo1.methodType.symbol shouldBe fooDecl + foo2.methodType.symbol shouldBe foo2Decl + bar.methodType.symbol shouldBe barDecl + + for (lambda in lambdas) { + lambda shouldHaveType functItfT + lambda.functionalMethod shouldBe ts.UNRESOLVED_METHOD + } + + bar shouldHaveType functItfT + } + } }) From b1c08e92a4281b4bc271e58cc88f7423f5cf6416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 15 Nov 2024 14:21:07 +0100 Subject: [PATCH 0242/1962] Support more situations --- .../pmd/lang/java/types/TypeOps.java | 34 ++++-- .../types/internal/infer/ExprCheckHelper.java | 65 ++++++----- .../internal/infer/TypeInferenceLogger.java | 10 ++ .../lang/java/types/TypeTestMockingUtil.kt | 6 + .../infer/UnresolvedTypesRecoveryTest.kt | 107 +++++++++++++++++- 5 files changed, 180 insertions(+), 42 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java index a6ac8828196..2b736d5b518 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java @@ -634,14 +634,6 @@ Convertibility isConvertible(@NonNull JTypeMirror t, @NonNull JTypeMirror s, boo return isConvertible(t, lower); } // otherwise fallthrough - } else if (isSpecialUnresolved(t)) { - // error type or unresolved type is subtype of everything - if (s instanceof JArrayType) { - // In case the array has an ivar 'a as element type, a bound will be added 'a >: (*unknown*) - // This helps inference recover in call chains and propagate the (*unknown*) types gracefully. - return TypeOps.isConvertible(t, ((JArrayType) s).getElementType()); - } - return Convertibility.SUBTYPING; } else if (hasUnresolvedSymbol(t) && t instanceof JClassType) { // This also considers types with an unresolved symbol // subtypes of (nearly) anything. This allows them to @@ -817,9 +809,17 @@ public Convertibility visitNullType(JTypeMirror t, JTypeMirror s) { @Override public Convertibility visitSentinel(JTypeMirror t, JTypeMirror s) { + // t may be (*unknown*), (*error*) or void // we know t != s - return t.isVoid() ? Convertibility.NEVER - : Convertibility.SUBTYPING; + if (t.isVoid()) { + return Convertibility.NEVER; + } + // unknown and error are subtypes of everything. + // however we want them to add constrains on unknown + if (!pure && !(s instanceof SentinelType)) { + s.acceptVisitor(this, t); + } + return Convertibility.SUBTYPING; } @Override @@ -842,6 +842,14 @@ public Convertibility visitWildcard(JWildcardType t, JTypeMirror s) { @Override public Convertibility visitClass(JClassType t, JTypeMirror s) { + if (isSpecialUnresolved(s)) { + if (!pure) { + for (JTypeMirror arg : t.getTypeArgs()) { + typeArgContains(arg, s); + } + } + return Convertibility.SUBTYPING; + } if (!(s instanceof JClassType)) { // note, that this ignores wildcard types, // because they're only compared through @@ -892,6 +900,12 @@ public Convertibility visitArray(JArrayType t, JTypeMirror s) { if (s == ts.OBJECT || s.equals(ts.CLONEABLE) || s.equals(ts.SERIALIZABLE)) { return Convertibility.SUBTYPING; } + if (isSpecialUnresolved(s)) { + if (!pure) { + t.getElementType().acceptVisitor(this, s); + } + return Convertibility.SUBTYPING; + } if (!(s instanceof JArrayType)) { // not comparable to any other type diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java index a01d285be0e..959614a860e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java @@ -119,15 +119,6 @@ boolean isCompatible(JTypeMirror targetType, ExprMirror expr) { JClassType funType = getProbablyFunctItfType(targetType, (FunctionalExprMirror) expr); if (funType == null) { - /* - * The functional expression has an inference variable as a target type, - * and that ivar does not have enough bounds to be resolved to a functional interface type yet. - * - *

    This should not prevent ctdecl resolution to proceed. The additional - * bounds may be contributed by the invocation constraints of an enclosing - * inference process. - */ - infer.LOG.functionalExprNeedsInvocationCtx(targetType, expr); return true; // deferred to invocation } @@ -162,22 +153,6 @@ boolean isCompatible(JTypeMirror targetType, ExprMirror expr) { return false; } - private void handleFunctionalExprWithoutTargetType(FunctionalExprMirror expr, JTypeMirror targetType) { - if (expr instanceof LambdaExprMirror) { - LambdaExprMirror lambda = (LambdaExprMirror) expr; - List paramTypes; - List explicit = lambda.getExplicitParameterTypes(); - paramTypes = explicit != null - ? explicit : Collections.nCopies(lambda.getParamCount(), ts.UNKNOWN); - lambda.updateTypingContext(paramTypes); - // checker.checkExprConstraint(infCtx, ts.UNKNOWN, fun.getReturnType()); - } - // todo method ref - infCtx.addInstantiationListener(infCtx.freeVarsIn(targetType), ctx -> { - expr.setInferredType(ctx.ground(targetType)); - expr.setFunctionalMethod(ts.UNRESOLVED_METHOD); - }); - } private boolean isInvocationCompatible(JTypeMirror targetType, InvocationMirror invoc, boolean isStandalone) { MethodCallSite nestedSite = infer.newCallSite(invoc, targetType, this.site, this.infCtx, isSpecificityCheck()); @@ -235,6 +210,15 @@ private boolean isInvocationCompatible(JTypeMirror targetType, InvocationMirror if (site.isInFinalInvocation()) { asClass = asClassType(softSolve(targetType)); // null if not funct itf } else { + /* + * The functional expression has an inference variable as a target type, + * and that ivar does not have enough bounds to be resolved to a functional interface type yet. + * + *

    This should not prevent ctdecl resolution to proceed. The additional + * bounds may be contributed by the invocation constraints of an enclosing + * inference process. + */ + infer.LOG.functionalExprNeedsInvocationCtx(targetType, expr); return null; // defer } } else { @@ -243,11 +227,13 @@ private boolean isInvocationCompatible(JTypeMirror targetType, InvocationMirror if (asClass == null && TypeOps.isUnresolved(targetType) || asClass != null && TypeOps.isUnresolved(asClass)) { - // Then the whole thing will fail because we cannot find - // a functional method/ it is not a proper functional interface. + // The type is unresolved, meaning classpath is incomplete. + // We will treat the lambda/mref as if it is compatible with this + // unresolved type. This is usually the right thing to do but + // the types of lambda parameters may be unresolved. JTypeMirror target = asClass != null ? asClass : targetType; handleFunctionalExprWithoutTargetType(expr, target); - // We consider it as matching though, just as if the lambda had an (*unknown*) type. + infer.LOG.functionalExprHasUnresolvedTargetType(targetType, expr); return null; } if (asClass == null) { @@ -256,6 +242,29 @@ private boolean isInvocationCompatible(JTypeMirror targetType, InvocationMirror return asClass; } + private void handleFunctionalExprWithoutTargetType(FunctionalExprMirror expr, JTypeMirror targetType) { + if (expr instanceof LambdaExprMirror) { + LambdaExprMirror lambda = (LambdaExprMirror) expr; + List paramTypes; + List explicit = lambda.getExplicitParameterTypes(); + paramTypes = explicit != null + ? explicit : Collections.nCopies(lambda.getParamCount(), ts.UNKNOWN); + // we need to set the parameter types + lambda.updateTypingContext(paramTypes); + // And add a constraint on the free variables in the target type. + // These free variables may be inferrable when the classpath is complete + // through the lambda adding constraints on those variables. Since + // we do not know the signature of the function, we should allow for + // the variables mentioned in this type to resolve to (*unknown*) and not + // Object. + checker.checkExprConstraint(infCtx, ts.UNKNOWN, targetType); + } + infCtx.addInstantiationListener(infCtx.freeVarsIn(targetType), ctx -> { + expr.setInferredType(ctx.ground(targetType)); + expr.setFunctionalMethod(ts.UNRESOLVED_METHOD); + }); + } + // we can't ask the infctx to solve the ivar, as that would require all bounds to be ground // We want however to be able to add constraints on the functional interface type's inference variables // This is useful to infer lambdas generic in their return type diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java index cb7fe3e6d3b..ee0a2340ecc 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java @@ -29,6 +29,7 @@ import net.sourceforge.pmd.lang.java.types.TypePrettyPrint; import net.sourceforge.pmd.lang.java.types.TypePrettyPrint.TypePrettyPrinter; import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.CtorInvocationMirror; +import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.FunctionalExprMirror; import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.InvocationMirror.MethodCtDecl; import net.sourceforge.pmd.lang.java.types.internal.infer.InferenceVar.BoundKind; import net.sourceforge.pmd.util.StringUtil; @@ -81,6 +82,8 @@ default void skipArgAsNonPertinent(int i, ExprMirror expr) { } default void functionalExprNeedsInvocationCtx(JTypeMirror targetT, ExprMirror expr) { } + default void functionalExprHasUnresolvedTargetType(JTypeMirror targetT, FunctionalExprMirror expr) { } + default void endArg() { } default void endArgsChecks() { } @@ -303,6 +306,12 @@ public void fallbackInvocation(JMethodSig ctdecl, MethodCallSite site) { endSection(""); } + @Override + public void functionalExprHasUnresolvedTargetType(JTypeMirror targetT, FunctionalExprMirror expr) { + println("[WARNING] Target type for functional expression is unresolved: " + targetT); + println("Will treat the expression as matching (this may cause future mistakes)"); + } + @Override public void ambiguityError(MethodCallSite site, @Nullable MethodCtDecl selected, List methods) { println(""); @@ -451,6 +460,7 @@ public void functionalExprNeedsInvocationCtx(JTypeMirror targetT, ExprMirror exp println("Will wait for invocation phase before discarding."); } + @Override public void endArgsChecks() { endSection(""); diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TypeTestMockingUtil.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TypeTestMockingUtil.kt index dc7c5141254..fcb7fc40d50 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TypeTestMockingUtil.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TypeTestMockingUtil.kt @@ -54,6 +54,12 @@ data class TypeInferenceSpy(private val spy: TypeInferenceLogger, val ts: TypeSy }) } + + fun shouldHaveUnresolvedLambdaCtx(lambdaOrMref: FunctionalExpression) { + verify(spy, times(1)) + .functionalExprHasUnresolvedTargetType(any(), argThat { it.location == lambdaOrMref }) + } + fun shouldHaveNoLambdaCtx(lambdaOrMref: FunctionalExpression) { verify(spy, times(1)) .logResolutionFail(argThat { diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt index d7c366d48ad..c777ab4c7ff 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt @@ -530,17 +530,21 @@ class C { val (mref) = acu.descendants(ASTMethodReference::class.java).toList() val (lambdaCall, mrefCall) = acu.descendants(ASTMethodCall::class.java).toList() + val fooDecl = acu.methodDeclarations()[0]!! + val targetTy = acu.descendants(ASTClassType::class.java).firstOrThrow().typeMirror - spy.shouldHaveNoApplicableMethods(lambdaCall) - spy.shouldHaveNoApplicableMethods(mrefCall) + spy.shouldHaveUnresolvedLambdaCtx(lambda) + spy.shouldHaveUnresolvedLambdaCtx(mref) acu.withTypeDsl { - lambda shouldHaveType ts.UNKNOWN + lambda shouldHaveType targetTy lambda.functionalMethod shouldBe ts.UNRESOLVED_METHOD - mref shouldHaveType ts.UNKNOWN + mref shouldHaveType targetTy mref.functionalMethod shouldBe ts.UNRESOLVED_METHOD mref.referencedMethod shouldBe ts.UNRESOLVED_METHOD + lambdaCall.methodType.symbol shouldBe fooDecl.symbol + mrefCall.methodType.symbol shouldBe fooDecl.symbol } } @@ -750,4 +754,99 @@ class C { bar shouldHaveType functItfT } } + + parserTest("Lambda with unresolved target type that has parameters") { + + // here the FunctionalItf is the target type for the lambda + // but it is unresolved. It should not prevent type inference from + // resolving foo and bar to their respective overloads + val (acu, _) = parser.parseWithTypeInferenceSpy( + """ + class Foo { + public void methodA() { + foo((a, b) -> a + b); + foo(1, (var a, int b) -> a + b); + var x = bar((int a, int b) -> a + b); + } + + private void foo(int y, FunctionalItf x) { + } + private void foo(FunctionalItf x) { + return SummaryDto.ItemDto.builder().build(); + } + private T bar(T x) { + return SummaryDto.ItemDto.builder().build(); + } + // interface FunctionalItf { String x(int x, int y); } + } + """ + ) + + val (foo1, foo2, bar) = acu.methodCalls().toList() + val functItfT = acu.descendants(ASTClassType::class.java) + .filter { it.simpleName == "FunctionalItf" } + .firstOrThrow().typeMirror + val (_, foo2Decl, fooDecl, barDecl) = acu.methodDeclarations().toList { it.symbol } + val lambdas = acu.descendants(ASTLambdaExpression::class.java).toList() + val (la, lb, lc) = lambdas + + acu.withTypeDsl { + foo1.methodType.symbol shouldBe fooDecl + foo2.methodType.symbol shouldBe foo2Decl + bar.methodType.symbol shouldBe barDecl + + for (lambda in lambdas) { + lambda shouldHaveType functItfT + lambda.functionalMethod shouldBe ts.UNRESOLVED_METHOD + } + + bar shouldHaveType functItfT + la.varAccesses("a").forEach { it shouldHaveType ts.UNKNOWN } + lb.varAccesses("a").forEach { it shouldHaveType ts.UNKNOWN } + lc.varAccesses("a").forEach { it shouldHaveType int } + + la.varAccesses("b").forEach { it shouldHaveType ts.UNKNOWN } + lb.varAccesses("b").forEach { it shouldHaveType int } + lc.varAccesses("b").forEach { it shouldHaveType int } + } + } + + parserTest("Lambda with unresolved target type return type should be unknown") { + + val (acu, _) = parser.logTypeInferenceVerbose().parseWithTypeInferenceSpy( + """ + class Foo { + public void methodA() { + // here the type of result is which is an + // argument for the unresolved functional + // interface. result should be unknown, not Object. + var result = foo(2, (a, b) -> a + b); + } + + private T foo(int y, FunctionalItf x) {} + + // interface FunctionalItf { A fun(int x, B y); } + } + """ + ) + + val (foo1) = acu.methodCalls().toList() + val functItfT = acu.descendants(ASTClassType::class.java) + .filter { it.simpleName == "FunctionalItf" } + .firstOrThrow().typeMirror.symbol as JClassSymbol + val (_, fooDecl) = acu.methodDeclarations().toList { it.symbol } + val (lambda) = acu.descendants(ASTLambdaExpression::class.java).toList() + + acu.withTypeDsl { + foo1.methodType.symbol shouldBe fooDecl + + lambda shouldHaveType functItfT[ts.UNKNOWN, int.box()] + lambda.functionalMethod shouldBe ts.UNRESOLVED_METHOD + + lambda.varAccesses("a").forEach { it shouldHaveType ts.UNKNOWN } + lambda.varAccesses("b").forEach { it shouldHaveType ts.UNKNOWN } + + acu.varId("result") shouldHaveType ts.UNKNOWN + } + } }) From 858850e4ce0aadd576763baa5e300fcb1550804e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 15 Nov 2024 14:52:54 +0100 Subject: [PATCH 0243/1962] Add test for #5338 --- .../bestpractices/xml/UnusedPrivateMethod.xml | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index 1a6dd1488dd..5331d424a8b 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2218,4 +2218,29 @@ public class ObtainViaTest { } ]]> + + #5338 UnusedPrivateMethod with unresolved target for lambda + 0 + CompletableFuture.completedFuture("HI!") + ); + Assertions.assertNotNull(listener.onRecord(new byte[0])); + } + + private static BytesListener createListener( + BytesParser parser + ) { + return bytes -> parser + .parse(bytes) + .thenAccept(System.out::println); + } + } + ]]> + From 9d15c900dbecea3beda88564443edabd0e3450e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Fri, 15 Nov 2024 11:27:07 -0300 Subject: [PATCH 0244/1962] Pass linters in generated code --- .../sourceforge/pmd/lang/gherkin/ast/GherkinBaseListener.java | 3 ++- .../sourceforge/pmd/lang/gherkin/ast/GherkinBaseVisitor.java | 2 +- .../net/sourceforge/pmd/lang/gherkin/ast/GherkinListener.java | 2 +- .../net/sourceforge/pmd/lang/gherkin/ast/GherkinParser.java | 4 +++- .../net/sourceforge/pmd/lang/gherkin/ast/GherkinVisitor.java | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinBaseListener.java b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinBaseListener.java index ddbeb87d8db..d1b7e781053 100644 --- a/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinBaseListener.java +++ b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinBaseListener.java @@ -18,6 +18,7 @@ * @deprecated Since 7.8.0. This class was never intended to be generated. It will be removed with no replacement. */ +@SuppressWarnings("PMD.UncommentedEmptyMethodBody") @Deprecated @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") public class GherkinBaseListener implements GherkinListener { @@ -334,4 +335,4 @@ public class GherkinBaseListener implements GherkinListener { *

    The default implementation does nothing.

    */ @Override public void visitErrorNode(ErrorNode node) { } -} \ No newline at end of file +} diff --git a/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinBaseVisitor.java b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinBaseVisitor.java index 90c6480261c..d6e8410f7ee 100644 --- a/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinBaseVisitor.java +++ b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinBaseVisitor.java @@ -189,4 +189,4 @@ public class GherkinBaseVisitor extends AbstractParseTreeVisitor implement * {@link #visitChildren} on {@code ctx}.

    */ @Override public T visitText(GherkinParser.TextContext ctx) { return visitChildren(ctx); } -} \ No newline at end of file +} diff --git a/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinListener.java b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinListener.java index 5976505f6ff..2f8167188e2 100644 --- a/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinListener.java +++ b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinListener.java @@ -257,4 +257,4 @@ public interface GherkinListener extends ParseTreeListener { * @param ctx the parse tree */ void exitText(GherkinParser.TextContext ctx); -} \ No newline at end of file +} diff --git a/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinParser.java b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinParser.java index e8388f2309b..1db84c9d0c8 100644 --- a/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinParser.java +++ b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinParser.java @@ -6,6 +6,8 @@ // Generated from net/sourceforge/pmd/lang/gherkin/ast/Gherkin.g4 by ANTLR 4.9.3 package net.sourceforge.pmd.lang.gherkin.ast; +// CPD-OFF + import java.util.List; import org.antlr.v4.runtime.NoViableAltException; @@ -2097,4 +2099,4 @@ public final TextContext text() throws RecognitionException { _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); } } -} \ No newline at end of file +} diff --git a/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinVisitor.java b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinVisitor.java index e08c47c7825..9ac69e5fe02 100644 --- a/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinVisitor.java +++ b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/ast/GherkinVisitor.java @@ -164,4 +164,4 @@ public interface GherkinVisitor extends ParseTreeVisitor { * @return the visitor result */ T visitText(GherkinParser.TextContext ctx); -} \ No newline at end of file +} From 5931b6601cc14d245c01cedf7f24eed045a6d31a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 15 Nov 2024 15:23:52 +0100 Subject: [PATCH 0245/1962] [java] Fix #5097 - problem with unchecked conversion --- .../pmd/lang/java/types/TypeOps.java | 6 ++++ .../pmd/lang/java/types/SubtypingTest.kt | 9 +++-- .../infer/UnresolvedTypesRecoveryTest.kt | 35 +++++++++++++++++++ .../bestpractices/xml/UnusedPrivateMethod.xml | 32 +++++++++++++++++ 4 files changed, 79 insertions(+), 3 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java index a6ac8828196..7f976967d84 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java @@ -717,6 +717,12 @@ Convertibility typeArgsAreContained(JClassType t, JClassType s) { // no unchecked warning. return allArgsAreUnboundedWildcards(sargs) ? Convertibility.UNCHECKED_NO_WARNING : Convertibility.UNCHECKED_WARNING; + } else if (sargs.isEmpty()) { + // C <: |C| + // JLS 4.10.2 + // unchecked conversion converts a raw type to a generic type + // subtyping converts a generic type to its raw type + return Convertibility.SUBTYPING; } if (targs.size() != sargs.size()) { diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/SubtypingTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/SubtypingTest.kt index 03cfcddb4ae..d3b3ba18c62 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/SubtypingTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/SubtypingTest.kt @@ -13,14 +13,14 @@ import io.kotest.property.Exhaustive import io.kotest.property.checkAll import io.kotest.property.exhaustive.ints import io.kotest.property.forAll -import net.sourceforge.pmd.lang.test.ast.shouldBeA import net.sourceforge.pmd.lang.java.ast.ParserTestCtx import net.sourceforge.pmd.lang.java.symbols.internal.UnresolvedClassStore import net.sourceforge.pmd.lang.java.symbols.internal.asm.createUnresolvedAsmSymbol -import net.sourceforge.pmd.lang.java.types.TypeConversion.* -import net.sourceforge.pmd.lang.java.types.TypeOps.Convertibility.* +import net.sourceforge.pmd.lang.java.types.TypeConversion.capture +import net.sourceforge.pmd.lang.java.types.TypeOps.Convertibility.UNCHECKED_NO_WARNING import net.sourceforge.pmd.lang.java.types.testdata.ComparableList import net.sourceforge.pmd.lang.java.types.testdata.SomeEnum +import net.sourceforge.pmd.lang.test.ast.shouldBeA import kotlin.test.assertTrue /** @@ -187,6 +187,9 @@ class SubtypingTest : FunSpec({ Class shouldBeUncheckedSubtypeOf `Class{String}` ts.STRING shouldBeSubtypeOf `Comparable{Wildcard}` + + val unresolvedT = ts.createUnresolvedAsmSymbol("foo") + unresolvedT[`?`] shouldBeSubtypeOf ts.rawType(unresolvedT) } test("Test wildcard subtyping") { diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt index 45c13cf5691..82fdf359cd3 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt @@ -702,4 +702,39 @@ class C { buildItem.methodType.symbol shouldBe buildItemDecl } } + + parserTest("Unresolved type should also allow unchecked conversion") { + // The problem here is that ConstraintViolation is not convertible to ConstraintViolation, + // because ConstraintViolation is not on the classpath. + + val (acu, _) = parser.parseWithTypeInferenceSpy( + """ + import java.util.Set; + class Foo { + private void foo(ConstraintViolation constraintViolation) { + constraintViolation.toString(); + } + + public void foos(Set> constraintViolations) { + constraintViolations.forEach(this::foo); + } + + } + """ + ) + +// val (foreach) = acu.methodCalls().toList() + val constraintViolationT = acu.descendants(ASTClassType::class.java) + .filter { it.simpleName == "ConstraintViolation" } + .firstOrThrow().typeMirror.symbol as JClassSymbol + val (fooDecl) = acu.methodDeclarations().toList { it.symbol } + val (mref) = acu.descendants(ASTMethodReference::class.java).toList() + + acu.withTypeDsl { + mref.referencedMethod.symbol shouldBe fooDecl + + mref shouldHaveType java.util.function.Consumer::class[constraintViolationT[`?`]] + + } + } }) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index 1a6dd1488dd..87f89cd75b9 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2218,4 +2218,36 @@ public class ObtainViaTest { } ]]> + + #5097 UnusedPrivateMethod with unresolved target for method reference + 0 + > listOfLists) { + listOfLists.forEach(this::doWork); + } + + //BUT this does??? + //UnusedPrivateMethod - this as a false positive - but what is different? + private void addValidationError(ConstraintViolation constraintViolation) { + constraintViolation.toString(); + } + + public void addValidationErrors(Set> constraintViolations) { + constraintViolations.forEach(this::addValidationError); + } + + } + ]]> + From f2610e0aca18cf7f8ccf1f2dfdd5427d5c01ba88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 15 Nov 2024 15:44:26 +0100 Subject: [PATCH 0246/1962] Suppress warning --- .../lang/java/types/internal/infer/ast/LambdaMirrorImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/LambdaMirrorImpl.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/LambdaMirrorImpl.java index 05c0b5c0bf0..2cbd0cb3990 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/LambdaMirrorImpl.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/LambdaMirrorImpl.java @@ -79,7 +79,7 @@ public boolean isEquivalentToUnderlyingAst() { } if (parameters.toStream().all(ASTLambdaParameter::isTypeInferred)) { - return null; + return null; // NOPMD ReturnEmptyCollectionRatherThanNull } return parameters.toStream() From a72ac5845b20f26552327d090ffd468a498298c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 15 Nov 2024 16:14:09 +0100 Subject: [PATCH 0247/1962] Add test for #5113 --- .../bestpractices/xml/UnusedPrivateMethod.xml | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index 1a6dd1488dd..ae0fc5e242c 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2218,4 +2218,24 @@ public class ObtainViaTest { } ]]> + + + UnusedPrivateMethod #5113 + 0 + foo(int param) { + var optional = param == 0 ? Optional.of(true) : Optional.of(false); + return optional.flatMap(this::dummy); + } + + private Optional dummy(boolean foo) { + return Optional.of(foo); + } + } + ]]> + + From b264fa14e15f8db96b6bee4ffc0f2e91444f6d16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 15 Nov 2024 16:28:08 +0100 Subject: [PATCH 0248/1962] Fix #5083 - mref without target type but with exact method has compile time decl --- .../lang/java/types/internal/infer/Infer.java | 15 +++-- .../internal/infer/MethodRefInferenceTest.kt | 41 ++++++++++++- .../infer/UnresolvedTypesRecoveryTest.kt | 6 +- .../bestpractices/xml/UnusedPrivateMethod.xml | 59 +++++++++++++++++++ 4 files changed, 111 insertions(+), 10 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java index 79823042103..e51ef905f22 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java @@ -36,7 +36,6 @@ import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.FunctionalExprMirror; import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.InvocationMirror; import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.InvocationMirror.MethodCtDecl; -import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.LambdaExprMirror; import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.MethodRefMirror; import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.PolyExprMirror; import net.sourceforge.pmd.lang.java.types.internal.infer.InferenceVar.BoundKind; @@ -145,13 +144,19 @@ public void inferFunctionalExprInUnambiguousContext(PolySite + + UnusedPrivateMethod #5083 - method reference without target type + 0 + predicate; + + private static boolean isAppleType(String data) { + return "apple".equals(data); + } + + private static boolean isRokuType(String data) { + return "roku".equals(data); + } + + private static boolean isSamsungType(String data) { + return "samsung".equals(data); + } + + private static boolean isAmazonType(String data) { + return "amazon".equals(data); + } + + private static boolean isAndroidType(String data) { + return "android".equals(data); + } + } + ]]> + + + + UnusedPrivateMethod #5083 - method reference without target type (2) + 0 + + From 3356dd949db9b8868bba5e6b5b622509596ab2c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Fri, 15 Nov 2024 15:42:35 -0300 Subject: [PATCH 0249/1962] Ignore generated code in Julia module --- pmd-julia/pom.xml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index 2dae0d4d57b..e4235671694 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -18,6 +18,28 @@ antlr4-maven-plugin
    + + org.apache.maven.plugins + maven-antrun-plugin + + + antlr-cleanup + generate-sources + + run + + + + + + + + + + + + + maven-resources-plugin From 3bb943e0e54c07730f302905ff119b1ce37ebb23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Fri, 15 Nov 2024 16:01:45 -0300 Subject: [PATCH 0250/1962] Add deprecated code for backwards compatibility --- .../pmd/lang/julia/ast/JuliaBaseListener.java | 277 ++ .../pmd/lang/julia/ast/JuliaBaseVisitor.java | 156 ++ .../pmd/lang/julia/ast/JuliaListener.java | 209 ++ .../pmd/lang/julia/ast/JuliaParser.java | 2220 +++++++++++++++++ .../pmd/lang/julia/ast/JuliaVisitor.java | 137 + 5 files changed, 2999 insertions(+) create mode 100644 pmd-julia/src/main/java/net/sourceforge/pmd/lang/julia/ast/JuliaBaseListener.java create mode 100644 pmd-julia/src/main/java/net/sourceforge/pmd/lang/julia/ast/JuliaBaseVisitor.java create mode 100644 pmd-julia/src/main/java/net/sourceforge/pmd/lang/julia/ast/JuliaListener.java create mode 100644 pmd-julia/src/main/java/net/sourceforge/pmd/lang/julia/ast/JuliaParser.java create mode 100644 pmd-julia/src/main/java/net/sourceforge/pmd/lang/julia/ast/JuliaVisitor.java diff --git a/pmd-julia/src/main/java/net/sourceforge/pmd/lang/julia/ast/JuliaBaseListener.java b/pmd-julia/src/main/java/net/sourceforge/pmd/lang/julia/ast/JuliaBaseListener.java new file mode 100644 index 00000000000..50f62d17558 --- /dev/null +++ b/pmd-julia/src/main/java/net/sourceforge/pmd/lang/julia/ast/JuliaBaseListener.java @@ -0,0 +1,277 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +// CHECKSTYLE:OFF +// Generated from net/sourceforge/pmd/lang/julia/ast/Julia.g4 by ANTLR 4.9.3 +package net.sourceforge.pmd.lang.julia.ast; + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.tree.ErrorNode; +import org.antlr.v4.runtime.tree.TerminalNode; + +/** + * This class provides an empty implementation of {@link JuliaListener}, + * which can be extended to create a listener which only needs to handle a subset + * of the available methods. + * + * @deprecated Since 7.8.0. This class was never intended to be generated. It will be removed with no replacement. + */ +@SuppressWarnings("PMD.UncommentedEmptyMethodBody") +@Deprecated +@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public class JuliaBaseListener implements JuliaListener { + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterMain(JuliaParser.MainContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitMain(JuliaParser.MainContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterFunctionDefinition(JuliaParser.FunctionDefinitionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitFunctionDefinition(JuliaParser.FunctionDefinitionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterFunctionDefinition1(JuliaParser.FunctionDefinition1Context ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitFunctionDefinition1(JuliaParser.FunctionDefinition1Context ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterFunctionDefinition2(JuliaParser.FunctionDefinition2Context ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitFunctionDefinition2(JuliaParser.FunctionDefinition2Context ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterFunctionIdentifier(JuliaParser.FunctionIdentifierContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitFunctionIdentifier(JuliaParser.FunctionIdentifierContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterWhereClause(JuliaParser.WhereClauseContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitWhereClause(JuliaParser.WhereClauseContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterFunctionBody(JuliaParser.FunctionBodyContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitFunctionBody(JuliaParser.FunctionBodyContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterStatement(JuliaParser.StatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitStatement(JuliaParser.StatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterBeginStatement(JuliaParser.BeginStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitBeginStatement(JuliaParser.BeginStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterDoStatement(JuliaParser.DoStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitDoStatement(JuliaParser.DoStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterForStatement(JuliaParser.ForStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitForStatement(JuliaParser.ForStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterIfStatement(JuliaParser.IfStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitIfStatement(JuliaParser.IfStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterLetStatement(JuliaParser.LetStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitLetStatement(JuliaParser.LetStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterMacroStatement(JuliaParser.MacroStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitMacroStatement(JuliaParser.MacroStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterStructStatement(JuliaParser.StructStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitStructStatement(JuliaParser.StructStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterTryCatchStatement(JuliaParser.TryCatchStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitTryCatchStatement(JuliaParser.TryCatchStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterTypeStatement(JuliaParser.TypeStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitTypeStatement(JuliaParser.TypeStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterWhileStatement(JuliaParser.WhileStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitWhileStatement(JuliaParser.WhileStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterAnyToken(JuliaParser.AnyTokenContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitAnyToken(JuliaParser.AnyTokenContext ctx) { } + + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void visitTerminal(TerminalNode node) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void visitErrorNode(ErrorNode node) { } +} diff --git a/pmd-julia/src/main/java/net/sourceforge/pmd/lang/julia/ast/JuliaBaseVisitor.java b/pmd-julia/src/main/java/net/sourceforge/pmd/lang/julia/ast/JuliaBaseVisitor.java new file mode 100644 index 00000000000..36b3a0ecef9 --- /dev/null +++ b/pmd-julia/src/main/java/net/sourceforge/pmd/lang/julia/ast/JuliaBaseVisitor.java @@ -0,0 +1,156 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +// CHECKSTYLE:OFF +// Generated from net/sourceforge/pmd/lang/julia/ast/Julia.g4 by ANTLR 4.9.3 +package net.sourceforge.pmd.lang.julia.ast; +import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor; + +/** + * This class provides an empty implementation of {@link JuliaVisitor}, + * which can be extended to create a visitor which only needs to handle a subset + * of the available methods. + * + * @param The return type of the visit operation. Use {@link Void} for + * operations with no return type. + * + * @deprecated Since 7.8.0. This class was never intended to be generated. It will be removed with no replacement. + */ +@Deprecated +@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public class JuliaBaseVisitor extends AbstractParseTreeVisitor implements JuliaVisitor { + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitMain(JuliaParser.MainContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitFunctionDefinition(JuliaParser.FunctionDefinitionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitFunctionDefinition1(JuliaParser.FunctionDefinition1Context ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitFunctionDefinition2(JuliaParser.FunctionDefinition2Context ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitFunctionIdentifier(JuliaParser.FunctionIdentifierContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitWhereClause(JuliaParser.WhereClauseContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitFunctionBody(JuliaParser.FunctionBodyContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitStatement(JuliaParser.StatementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitBeginStatement(JuliaParser.BeginStatementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitDoStatement(JuliaParser.DoStatementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitForStatement(JuliaParser.ForStatementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitIfStatement(JuliaParser.IfStatementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitLetStatement(JuliaParser.LetStatementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitMacroStatement(JuliaParser.MacroStatementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitStructStatement(JuliaParser.StructStatementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitTryCatchStatement(JuliaParser.TryCatchStatementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitTypeStatement(JuliaParser.TypeStatementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitWhileStatement(JuliaParser.WhileStatementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitAnyToken(JuliaParser.AnyTokenContext ctx) { return visitChildren(ctx); } +} diff --git a/pmd-julia/src/main/java/net/sourceforge/pmd/lang/julia/ast/JuliaListener.java b/pmd-julia/src/main/java/net/sourceforge/pmd/lang/julia/ast/JuliaListener.java new file mode 100644 index 00000000000..dfb10fb6b76 --- /dev/null +++ b/pmd-julia/src/main/java/net/sourceforge/pmd/lang/julia/ast/JuliaListener.java @@ -0,0 +1,209 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +// CHECKSTYLE:OFF +// Generated from net/sourceforge/pmd/lang/julia/ast/Julia.g4 by ANTLR 4.9.3 +package net.sourceforge.pmd.lang.julia.ast; +import org.antlr.v4.runtime.tree.ParseTreeListener; + +/** + * This interface defines a complete listener for a parse tree produced by + * {@link JuliaParser}. + * + * @deprecated Since 7.8.0. This class was never intended to be generated. It will be removed with no replacement. + */ +@Deprecated +@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public interface JuliaListener extends ParseTreeListener { + /** + * Enter a parse tree produced by {@link JuliaParser#main}. + * @param ctx the parse tree + */ + void enterMain(JuliaParser.MainContext ctx); + /** + * Exit a parse tree produced by {@link JuliaParser#main}. + * @param ctx the parse tree + */ + void exitMain(JuliaParser.MainContext ctx); + /** + * Enter a parse tree produced by {@link JuliaParser#functionDefinition}. + * @param ctx the parse tree + */ + void enterFunctionDefinition(JuliaParser.FunctionDefinitionContext ctx); + /** + * Exit a parse tree produced by {@link JuliaParser#functionDefinition}. + * @param ctx the parse tree + */ + void exitFunctionDefinition(JuliaParser.FunctionDefinitionContext ctx); + /** + * Enter a parse tree produced by {@link JuliaParser#functionDefinition1}. + * @param ctx the parse tree + */ + void enterFunctionDefinition1(JuliaParser.FunctionDefinition1Context ctx); + /** + * Exit a parse tree produced by {@link JuliaParser#functionDefinition1}. + * @param ctx the parse tree + */ + void exitFunctionDefinition1(JuliaParser.FunctionDefinition1Context ctx); + /** + * Enter a parse tree produced by {@link JuliaParser#functionDefinition2}. + * @param ctx the parse tree + */ + void enterFunctionDefinition2(JuliaParser.FunctionDefinition2Context ctx); + /** + * Exit a parse tree produced by {@link JuliaParser#functionDefinition2}. + * @param ctx the parse tree + */ + void exitFunctionDefinition2(JuliaParser.FunctionDefinition2Context ctx); + /** + * Enter a parse tree produced by {@link JuliaParser#functionIdentifier}. + * @param ctx the parse tree + */ + void enterFunctionIdentifier(JuliaParser.FunctionIdentifierContext ctx); + /** + * Exit a parse tree produced by {@link JuliaParser#functionIdentifier}. + * @param ctx the parse tree + */ + void exitFunctionIdentifier(JuliaParser.FunctionIdentifierContext ctx); + /** + * Enter a parse tree produced by {@link JuliaParser#whereClause}. + * @param ctx the parse tree + */ + void enterWhereClause(JuliaParser.WhereClauseContext ctx); + /** + * Exit a parse tree produced by {@link JuliaParser#whereClause}. + * @param ctx the parse tree + */ + void exitWhereClause(JuliaParser.WhereClauseContext ctx); + /** + * Enter a parse tree produced by {@link JuliaParser#functionBody}. + * @param ctx the parse tree + */ + void enterFunctionBody(JuliaParser.FunctionBodyContext ctx); + /** + * Exit a parse tree produced by {@link JuliaParser#functionBody}. + * @param ctx the parse tree + */ + void exitFunctionBody(JuliaParser.FunctionBodyContext ctx); + /** + * Enter a parse tree produced by {@link JuliaParser#statement}. + * @param ctx the parse tree + */ + void enterStatement(JuliaParser.StatementContext ctx); + /** + * Exit a parse tree produced by {@link JuliaParser#statement}. + * @param ctx the parse tree + */ + void exitStatement(JuliaParser.StatementContext ctx); + /** + * Enter a parse tree produced by {@link JuliaParser#beginStatement}. + * @param ctx the parse tree + */ + void enterBeginStatement(JuliaParser.BeginStatementContext ctx); + /** + * Exit a parse tree produced by {@link JuliaParser#beginStatement}. + * @param ctx the parse tree + */ + void exitBeginStatement(JuliaParser.BeginStatementContext ctx); + /** + * Enter a parse tree produced by {@link JuliaParser#doStatement}. + * @param ctx the parse tree + */ + void enterDoStatement(JuliaParser.DoStatementContext ctx); + /** + * Exit a parse tree produced by {@link JuliaParser#doStatement}. + * @param ctx the parse tree + */ + void exitDoStatement(JuliaParser.DoStatementContext ctx); + /** + * Enter a parse tree produced by {@link JuliaParser#forStatement}. + * @param ctx the parse tree + */ + void enterForStatement(JuliaParser.ForStatementContext ctx); + /** + * Exit a parse tree produced by {@link JuliaParser#forStatement}. + * @param ctx the parse tree + */ + void exitForStatement(JuliaParser.ForStatementContext ctx); + /** + * Enter a parse tree produced by {@link JuliaParser#ifStatement}. + * @param ctx the parse tree + */ + void enterIfStatement(JuliaParser.IfStatementContext ctx); + /** + * Exit a parse tree produced by {@link JuliaParser#ifStatement}. + * @param ctx the parse tree + */ + void exitIfStatement(JuliaParser.IfStatementContext ctx); + /** + * Enter a parse tree produced by {@link JuliaParser#letStatement}. + * @param ctx the parse tree + */ + void enterLetStatement(JuliaParser.LetStatementContext ctx); + /** + * Exit a parse tree produced by {@link JuliaParser#letStatement}. + * @param ctx the parse tree + */ + void exitLetStatement(JuliaParser.LetStatementContext ctx); + /** + * Enter a parse tree produced by {@link JuliaParser#macroStatement}. + * @param ctx the parse tree + */ + void enterMacroStatement(JuliaParser.MacroStatementContext ctx); + /** + * Exit a parse tree produced by {@link JuliaParser#macroStatement}. + * @param ctx the parse tree + */ + void exitMacroStatement(JuliaParser.MacroStatementContext ctx); + /** + * Enter a parse tree produced by {@link JuliaParser#structStatement}. + * @param ctx the parse tree + */ + void enterStructStatement(JuliaParser.StructStatementContext ctx); + /** + * Exit a parse tree produced by {@link JuliaParser#structStatement}. + * @param ctx the parse tree + */ + void exitStructStatement(JuliaParser.StructStatementContext ctx); + /** + * Enter a parse tree produced by {@link JuliaParser#tryCatchStatement}. + * @param ctx the parse tree + */ + void enterTryCatchStatement(JuliaParser.TryCatchStatementContext ctx); + /** + * Exit a parse tree produced by {@link JuliaParser#tryCatchStatement}. + * @param ctx the parse tree + */ + void exitTryCatchStatement(JuliaParser.TryCatchStatementContext ctx); + /** + * Enter a parse tree produced by {@link JuliaParser#typeStatement}. + * @param ctx the parse tree + */ + void enterTypeStatement(JuliaParser.TypeStatementContext ctx); + /** + * Exit a parse tree produced by {@link JuliaParser#typeStatement}. + * @param ctx the parse tree + */ + void exitTypeStatement(JuliaParser.TypeStatementContext ctx); + /** + * Enter a parse tree produced by {@link JuliaParser#whileStatement}. + * @param ctx the parse tree + */ + void enterWhileStatement(JuliaParser.WhileStatementContext ctx); + /** + * Exit a parse tree produced by {@link JuliaParser#whileStatement}. + * @param ctx the parse tree + */ + void exitWhileStatement(JuliaParser.WhileStatementContext ctx); + /** + * Enter a parse tree produced by {@link JuliaParser#anyToken}. + * @param ctx the parse tree + */ + void enterAnyToken(JuliaParser.AnyTokenContext ctx); + /** + * Exit a parse tree produced by {@link JuliaParser#anyToken}. + * @param ctx the parse tree + */ + void exitAnyToken(JuliaParser.AnyTokenContext ctx); +} diff --git a/pmd-julia/src/main/java/net/sourceforge/pmd/lang/julia/ast/JuliaParser.java b/pmd-julia/src/main/java/net/sourceforge/pmd/lang/julia/ast/JuliaParser.java new file mode 100644 index 00000000000..e43900e48cb --- /dev/null +++ b/pmd-julia/src/main/java/net/sourceforge/pmd/lang/julia/ast/JuliaParser.java @@ -0,0 +1,2220 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +// CHECKSTYLE:OFF +// Generated from net/sourceforge/pmd/lang/julia/ast/Julia.g4 by ANTLR 4.9.3 +package net.sourceforge.pmd.lang.julia.ast; + +import java.util.List; + +import org.antlr.v4.runtime.NoViableAltException; +import org.antlr.v4.runtime.Parser; +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.RuntimeMetaData; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.Vocabulary; +import org.antlr.v4.runtime.VocabularyImpl; +import org.antlr.v4.runtime.atn.ATN; +import org.antlr.v4.runtime.atn.ATNDeserializer; +import org.antlr.v4.runtime.atn.ParserATNSimulator; +import org.antlr.v4.runtime.atn.PredictionContextCache; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.tree.ParseTreeListener; +import org.antlr.v4.runtime.tree.ParseTreeVisitor; +import org.antlr.v4.runtime.tree.TerminalNode; + +/** + * @deprecated Since 7.8.0. This class was never intended to be generated. It will be removed with no replacement. + */ + +@Deprecated +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) +@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public class JuliaParser extends Parser { + static { RuntimeMetaData.checkVersion("4.9.3", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9, + T__9=10, T__10=11, T__11=12, T__12=13, T__13=14, T__14=15, T__15=16, T__16=17, + COMMENTS=18, MULTILINECOMMENTS1=19, MULTILINECOMMENTS2=20, MULTILINESTRING=21, + NL=22, WHITESPACE=23, ABSTRACT=24, ARROWOPERATOR=25, ASSIGNMENTOPERATOR=26, + BAREMODULE=27, BEGIN=28, BITSHIFTOPERATOR=29, BITSTYPE=30, BREAK=31, CATCH=32, + CCALL=33, CHAR=34, CONST=35, CONTINUE=36, DO=37, ELSE=38, ELSIF=39, END=40, + EXPORT=41, EXTERNALCOMMAND=42, FINALLY=43, FOR=44, FUNCTION=45, GLOBAL=46, + IF=47, IMMUTABLE=48, IMPORT=49, IMPORTALL=50, INSTANCEOF=51, LET=52, LOCAL=53, + MACRO=54, MODULE=55, PIPEOPERATOR=56, QUOTE=57, RETURN=58, STAGEDFUNCTION=59, + STRING=60, STRUCT=61, TRY=62, TYPE=63, TYPEALIAS=64, USING=65, WHERE=66, + WHILE=67, NUMERICAL=68, INT_LITERAL=69, BINARY=70, OCTAL=71, HEX=72, FLOAT32_LITERAL=73, + FLOAT64_LITERAL=74, HEX_FLOAT=75, IDENTIFIER=76, ANY=77, STAGED_FUNCTION=78; + public static final int + RULE_main = 0, RULE_functionDefinition = 1, RULE_functionDefinition1 = 2, + RULE_functionDefinition2 = 3, RULE_functionIdentifier = 4, RULE_whereClause = 5, + RULE_functionBody = 6, RULE_statement = 7, RULE_beginStatement = 8, RULE_doStatement = 9, + RULE_forStatement = 10, RULE_ifStatement = 11, RULE_letStatement = 12, + RULE_macroStatement = 13, RULE_structStatement = 14, RULE_tryCatchStatement = 15, + RULE_typeStatement = 16, RULE_whileStatement = 17, RULE_anyToken = 18; + private static String[] makeRuleNames() { + return new String[] { + "main", "functionDefinition", "functionDefinition1", "functionDefinition2", + "functionIdentifier", "whereClause", "functionBody", "statement", "beginStatement", + "doStatement", "forStatement", "ifStatement", "letStatement", "macroStatement", + "structStatement", "tryCatchStatement", "typeStatement", "whileStatement", + "anyToken" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, "'('", "')'", "'='", "'['", "']'", "'{'", "'}'", "'=>'", "'&&'", + "'||'", "'=='", "'>='", "'<='", "'<'", "'<:'", "'>'", "'...'", null, + null, null, null, null, null, "'abstract'", null, null, "'baremodule'", + "'begin'", null, "'bitstype'", "'break'", "'catch'", "'ccall'", null, + "'const'", "'continue'", "'do'", "'else'", "'elsif'", "'end'", "'export'", + null, "'finally'", "'for'", "'function'", "'global'", "'if'", "'immutable'", + "'import'", "'importall'", "'::'", "'let'", "'local'", "'macro'", "'module'", + null, "'quote'", "'return'", "'stagedfunction'", null, "'struct'", "'try'", + "'type'", "'typealias'", "'using'", "'where'", "'while'" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, "COMMENTS", "MULTILINECOMMENTS1", + "MULTILINECOMMENTS2", "MULTILINESTRING", "NL", "WHITESPACE", "ABSTRACT", + "ARROWOPERATOR", "ASSIGNMENTOPERATOR", "BAREMODULE", "BEGIN", "BITSHIFTOPERATOR", + "BITSTYPE", "BREAK", "CATCH", "CCALL", "CHAR", "CONST", "CONTINUE", "DO", + "ELSE", "ELSIF", "END", "EXPORT", "EXTERNALCOMMAND", "FINALLY", "FOR", + "FUNCTION", "GLOBAL", "IF", "IMMUTABLE", "IMPORT", "IMPORTALL", "INSTANCEOF", + "LET", "LOCAL", "MACRO", "MODULE", "PIPEOPERATOR", "QUOTE", "RETURN", + "STAGEDFUNCTION", "STRING", "STRUCT", "TRY", "TYPE", "TYPEALIAS", "USING", + "WHERE", "WHILE", "NUMERICAL", "INT_LITERAL", "BINARY", "OCTAL", "HEX", + "FLOAT32_LITERAL", "FLOAT64_LITERAL", "HEX_FLOAT", "IDENTIFIER", "ANY", + "STAGED_FUNCTION" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + @Override + public String getGrammarFileName() { return "Julia.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public ATN getATN() { return _ATN; } + + public JuliaParser(TokenStream input) { + super(input); + _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class MainContext extends ParserRuleContext { + public List functionBody() { + return getRuleContexts(FunctionBodyContext.class); + } + public FunctionBodyContext functionBody(int i) { + return getRuleContext(FunctionBodyContext.class,i); + } + public TerminalNode EOF() { return getToken(JuliaParser.EOF, 0); } + public List functionDefinition() { + return getRuleContexts(FunctionDefinitionContext.class); + } + public FunctionDefinitionContext functionDefinition(int i) { + return getRuleContext(FunctionDefinitionContext.class,i); + } + public TerminalNode END() { return getToken(JuliaParser.END, 0); } + public MainContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_main; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).enterMain(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).exitMain(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JuliaVisitor ) return ((JuliaVisitor)visitor).visitMain(this); + else return visitor.visitChildren(this); + } + } + + public final MainContext main() throws RecognitionException { + MainContext _localctx = new MainContext(_ctx, getState()); + enterRule(_localctx, 0, RULE_main); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(38); + functionBody(); + setState(44); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==T__0 || _la==FUNCTION || _la==IDENTIFIER) { + { + { + setState(39); + functionDefinition(); + setState(40); + functionBody(); + } + } + setState(46); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(48); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==END) { + { + setState(47); + match(END); + } + } + + setState(50); + match(EOF); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class FunctionDefinitionContext extends ParserRuleContext { + public FunctionDefinition1Context functionDefinition1() { + return getRuleContext(FunctionDefinition1Context.class,0); + } + public FunctionDefinition2Context functionDefinition2() { + return getRuleContext(FunctionDefinition2Context.class,0); + } + public FunctionDefinitionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_functionDefinition; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).enterFunctionDefinition(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).exitFunctionDefinition(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JuliaVisitor ) return ((JuliaVisitor)visitor).visitFunctionDefinition(this); + else return visitor.visitChildren(this); + } + } + + public final FunctionDefinitionContext functionDefinition() throws RecognitionException { + FunctionDefinitionContext _localctx = new FunctionDefinitionContext(_ctx, getState()); + enterRule(_localctx, 2, RULE_functionDefinition); + try { + setState(54); + _errHandler.sync(this); + switch (_input.LA(1)) { + case FUNCTION: + enterOuterAlt(_localctx, 1); + { + setState(52); + functionDefinition1(); + } + break; + case T__0: + case IDENTIFIER: + enterOuterAlt(_localctx, 2); + { + setState(53); + functionDefinition2(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class FunctionDefinition1Context extends ParserRuleContext { + public TerminalNode FUNCTION() { return getToken(JuliaParser.FUNCTION, 0); } + public TerminalNode END() { return getToken(JuliaParser.END, 0); } + public TerminalNode IDENTIFIER() { return getToken(JuliaParser.IDENTIFIER, 0); } + public List anyToken() { + return getRuleContexts(AnyTokenContext.class); + } + public AnyTokenContext anyToken(int i) { + return getRuleContext(AnyTokenContext.class,i); + } + public FunctionBodyContext functionBody() { + return getRuleContext(FunctionBodyContext.class,0); + } + public List whereClause() { + return getRuleContexts(WhereClauseContext.class); + } + public WhereClauseContext whereClause(int i) { + return getRuleContext(WhereClauseContext.class,i); + } + public FunctionDefinition1Context(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_functionDefinition1; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).enterFunctionDefinition1(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).exitFunctionDefinition1(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JuliaVisitor ) return ((JuliaVisitor)visitor).visitFunctionDefinition1(this); + else return visitor.visitChildren(this); + } + } + + public final FunctionDefinition1Context functionDefinition1() throws RecognitionException { + FunctionDefinition1Context _localctx = new FunctionDefinition1Context(_ctx, getState()); + enterRule(_localctx, 4, RULE_functionDefinition1); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(56); + match(FUNCTION); + setState(58); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,3,_ctx) ) { + case 1: + { + setState(57); + match(IDENTIFIER); + } + break; + } + setState(63); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,4,_ctx); + while ( _alt!=1 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1+1 ) { + { + { + setState(60); + anyToken(); + } + } + } + setState(65); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,4,_ctx); + } + setState(81); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==T__0) { + { + setState(66); + match(T__0); + setState(70); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,5,_ctx); + while ( _alt!=1 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1+1 ) { + { + { + setState(67); + anyToken(); + } + } + } + setState(72); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,5,_ctx); + } + setState(73); + match(T__1); + setState(77); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,6,_ctx); + while ( _alt!=1 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1+1 ) { + { + { + setState(74); + whereClause(); + } + } + } + setState(79); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,6,_ctx); + } + setState(80); + functionBody(); + } + } + + setState(83); + match(END); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class FunctionDefinition2Context extends ParserRuleContext { + public FunctionIdentifierContext functionIdentifier() { + return getRuleContext(FunctionIdentifierContext.class,0); + } + public FunctionBodyContext functionBody() { + return getRuleContext(FunctionBodyContext.class,0); + } + public List anyToken() { + return getRuleContexts(AnyTokenContext.class); + } + public AnyTokenContext anyToken(int i) { + return getRuleContext(AnyTokenContext.class,i); + } + public List whereClause() { + return getRuleContexts(WhereClauseContext.class); + } + public WhereClauseContext whereClause(int i) { + return getRuleContext(WhereClauseContext.class,i); + } + public FunctionDefinition2Context(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_functionDefinition2; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).enterFunctionDefinition2(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).exitFunctionDefinition2(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JuliaVisitor ) return ((JuliaVisitor)visitor).visitFunctionDefinition2(this); + else return visitor.visitChildren(this); + } + } + + public final FunctionDefinition2Context functionDefinition2() throws RecognitionException { + FunctionDefinition2Context _localctx = new FunctionDefinition2Context(_ctx, getState()); + enterRule(_localctx, 6, RULE_functionDefinition2); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(85); + functionIdentifier(); + setState(86); + match(T__0); + setState(90); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,8,_ctx); + while ( _alt!=1 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1+1 ) { + { + { + setState(87); + anyToken(); + } + } + } + setState(92); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,8,_ctx); + } + setState(93); + match(T__1); + setState(97); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,9,_ctx); + while ( _alt!=1 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1+1 ) { + { + { + setState(94); + whereClause(); + } + } + } + setState(99); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,9,_ctx); + } + setState(100); + match(T__2); + setState(101); + functionBody(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class FunctionIdentifierContext extends ParserRuleContext { + public TerminalNode IDENTIFIER() { return getToken(JuliaParser.IDENTIFIER, 0); } + public List anyToken() { + return getRuleContexts(AnyTokenContext.class); + } + public AnyTokenContext anyToken(int i) { + return getRuleContext(AnyTokenContext.class,i); + } + public FunctionIdentifierContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_functionIdentifier; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).enterFunctionIdentifier(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).exitFunctionIdentifier(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JuliaVisitor ) return ((JuliaVisitor)visitor).visitFunctionIdentifier(this); + else return visitor.visitChildren(this); + } + } + + public final FunctionIdentifierContext functionIdentifier() throws RecognitionException { + FunctionIdentifierContext _localctx = new FunctionIdentifierContext(_ctx, getState()); + enterRule(_localctx, 8, RULE_functionIdentifier); + try { + int _alt; + setState(112); + _errHandler.sync(this); + switch (_input.LA(1)) { + case IDENTIFIER: + enterOuterAlt(_localctx, 1); + { + setState(103); + match(IDENTIFIER); + } + break; + case T__0: + enterOuterAlt(_localctx, 2); + { + setState(104); + match(T__0); + setState(108); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,10,_ctx); + while ( _alt!=1 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1+1 ) { + { + { + setState(105); + anyToken(); + } + } + } + setState(110); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,10,_ctx); + } + setState(111); + match(T__1); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class WhereClauseContext extends ParserRuleContext { + public TerminalNode WHERE() { return getToken(JuliaParser.WHERE, 0); } + public List anyToken() { + return getRuleContexts(AnyTokenContext.class); + } + public AnyTokenContext anyToken(int i) { + return getRuleContext(AnyTokenContext.class,i); + } + public WhereClauseContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_whereClause; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).enterWhereClause(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).exitWhereClause(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JuliaVisitor ) return ((JuliaVisitor)visitor).visitWhereClause(this); + else return visitor.visitChildren(this); + } + } + + public final WhereClauseContext whereClause() throws RecognitionException { + WhereClauseContext _localctx = new WhereClauseContext(_ctx, getState()); + enterRule(_localctx, 10, RULE_whereClause); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(114); + match(WHERE); + setState(118); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,12,_ctx); + while ( _alt!=1 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1+1 ) { + { + { + setState(115); + anyToken(); + } + } + } + setState(120); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,12,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class FunctionBodyContext extends ParserRuleContext { + public List anyToken() { + return getRuleContexts(AnyTokenContext.class); + } + public AnyTokenContext anyToken(int i) { + return getRuleContext(AnyTokenContext.class,i); + } + public List statement() { + return getRuleContexts(StatementContext.class); + } + public StatementContext statement(int i) { + return getRuleContext(StatementContext.class,i); + } + public FunctionBodyContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_functionBody; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).enterFunctionBody(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).exitFunctionBody(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JuliaVisitor ) return ((JuliaVisitor)visitor).visitFunctionBody(this); + else return visitor.visitChildren(this); + } + } + + public final FunctionBodyContext functionBody() throws RecognitionException { + FunctionBodyContext _localctx = new FunctionBodyContext(_ctx, getState()); + enterRule(_localctx, 12, RULE_functionBody); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(124); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,13,_ctx); + while ( _alt!=1 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1+1 ) { + { + { + setState(121); + anyToken(); + } + } + } + setState(126); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,13,_ctx); + } + setState(136); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,15,_ctx); + while ( _alt!=1 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1+1 ) { + { + { + setState(127); + statement(); + setState(131); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,14,_ctx); + while ( _alt!=1 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1+1 ) { + { + { + setState(128); + anyToken(); + } + } + } + setState(133); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,14,_ctx); + } + } + } + } + setState(138); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,15,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class StatementContext extends ParserRuleContext { + public BeginStatementContext beginStatement() { + return getRuleContext(BeginStatementContext.class,0); + } + public DoStatementContext doStatement() { + return getRuleContext(DoStatementContext.class,0); + } + public ForStatementContext forStatement() { + return getRuleContext(ForStatementContext.class,0); + } + public FunctionDefinition1Context functionDefinition1() { + return getRuleContext(FunctionDefinition1Context.class,0); + } + public IfStatementContext ifStatement() { + return getRuleContext(IfStatementContext.class,0); + } + public LetStatementContext letStatement() { + return getRuleContext(LetStatementContext.class,0); + } + public MacroStatementContext macroStatement() { + return getRuleContext(MacroStatementContext.class,0); + } + public StructStatementContext structStatement() { + return getRuleContext(StructStatementContext.class,0); + } + public TryCatchStatementContext tryCatchStatement() { + return getRuleContext(TryCatchStatementContext.class,0); + } + public TypeStatementContext typeStatement() { + return getRuleContext(TypeStatementContext.class,0); + } + public WhileStatementContext whileStatement() { + return getRuleContext(WhileStatementContext.class,0); + } + public StatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_statement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).enterStatement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).exitStatement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JuliaVisitor ) return ((JuliaVisitor)visitor).visitStatement(this); + else return visitor.visitChildren(this); + } + } + + public final StatementContext statement() throws RecognitionException { + StatementContext _localctx = new StatementContext(_ctx, getState()); + enterRule(_localctx, 14, RULE_statement); + try { + setState(150); + _errHandler.sync(this); + switch (_input.LA(1)) { + case BEGIN: + enterOuterAlt(_localctx, 1); + { + setState(139); + beginStatement(); + } + break; + case DO: + enterOuterAlt(_localctx, 2); + { + setState(140); + doStatement(); + } + break; + case FOR: + enterOuterAlt(_localctx, 3); + { + setState(141); + forStatement(); + } + break; + case FUNCTION: + enterOuterAlt(_localctx, 4); + { + setState(142); + functionDefinition1(); + } + break; + case IF: + enterOuterAlt(_localctx, 5); + { + setState(143); + ifStatement(); + } + break; + case LET: + enterOuterAlt(_localctx, 6); + { + setState(144); + letStatement(); + } + break; + case MACRO: + enterOuterAlt(_localctx, 7); + { + setState(145); + macroStatement(); + } + break; + case STRUCT: + enterOuterAlt(_localctx, 8); + { + setState(146); + structStatement(); + } + break; + case TRY: + enterOuterAlt(_localctx, 9); + { + setState(147); + tryCatchStatement(); + } + break; + case TYPE: + enterOuterAlt(_localctx, 10); + { + setState(148); + typeStatement(); + } + break; + case WHILE: + enterOuterAlt(_localctx, 11); + { + setState(149); + whileStatement(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class BeginStatementContext extends ParserRuleContext { + public TerminalNode BEGIN() { return getToken(JuliaParser.BEGIN, 0); } + public FunctionBodyContext functionBody() { + return getRuleContext(FunctionBodyContext.class,0); + } + public TerminalNode END() { return getToken(JuliaParser.END, 0); } + public BeginStatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_beginStatement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).enterBeginStatement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).exitBeginStatement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JuliaVisitor ) return ((JuliaVisitor)visitor).visitBeginStatement(this); + else return visitor.visitChildren(this); + } + } + + public final BeginStatementContext beginStatement() throws RecognitionException { + BeginStatementContext _localctx = new BeginStatementContext(_ctx, getState()); + enterRule(_localctx, 16, RULE_beginStatement); + try { + enterOuterAlt(_localctx, 1); + { + setState(152); + match(BEGIN); + setState(153); + functionBody(); + setState(154); + match(END); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class DoStatementContext extends ParserRuleContext { + public TerminalNode DO() { return getToken(JuliaParser.DO, 0); } + public FunctionBodyContext functionBody() { + return getRuleContext(FunctionBodyContext.class,0); + } + public TerminalNode END() { return getToken(JuliaParser.END, 0); } + public DoStatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_doStatement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).enterDoStatement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).exitDoStatement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JuliaVisitor ) return ((JuliaVisitor)visitor).visitDoStatement(this); + else return visitor.visitChildren(this); + } + } + + public final DoStatementContext doStatement() throws RecognitionException { + DoStatementContext _localctx = new DoStatementContext(_ctx, getState()); + enterRule(_localctx, 18, RULE_doStatement); + try { + enterOuterAlt(_localctx, 1); + { + setState(156); + match(DO); + setState(157); + functionBody(); + setState(158); + match(END); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ForStatementContext extends ParserRuleContext { + public TerminalNode FOR() { return getToken(JuliaParser.FOR, 0); } + public FunctionBodyContext functionBody() { + return getRuleContext(FunctionBodyContext.class,0); + } + public TerminalNode END() { return getToken(JuliaParser.END, 0); } + public ForStatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_forStatement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).enterForStatement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).exitForStatement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JuliaVisitor ) return ((JuliaVisitor)visitor).visitForStatement(this); + else return visitor.visitChildren(this); + } + } + + public final ForStatementContext forStatement() throws RecognitionException { + ForStatementContext _localctx = new ForStatementContext(_ctx, getState()); + enterRule(_localctx, 20, RULE_forStatement); + try { + enterOuterAlt(_localctx, 1); + { + setState(160); + match(FOR); + setState(161); + functionBody(); + setState(162); + match(END); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class IfStatementContext extends ParserRuleContext { + public TerminalNode IF() { return getToken(JuliaParser.IF, 0); } + public List functionBody() { + return getRuleContexts(FunctionBodyContext.class); + } + public FunctionBodyContext functionBody(int i) { + return getRuleContext(FunctionBodyContext.class,i); + } + public TerminalNode END() { return getToken(JuliaParser.END, 0); } + public List ELSIF() { return getTokens(JuliaParser.ELSIF); } + public TerminalNode ELSIF(int i) { + return getToken(JuliaParser.ELSIF, i); + } + public TerminalNode ELSE() { return getToken(JuliaParser.ELSE, 0); } + public IfStatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_ifStatement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).enterIfStatement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).exitIfStatement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JuliaVisitor ) return ((JuliaVisitor)visitor).visitIfStatement(this); + else return visitor.visitChildren(this); + } + } + + public final IfStatementContext ifStatement() throws RecognitionException { + IfStatementContext _localctx = new IfStatementContext(_ctx, getState()); + enterRule(_localctx, 22, RULE_ifStatement); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(164); + match(IF); + setState(165); + functionBody(); + setState(170); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==ELSIF) { + { + { + setState(166); + match(ELSIF); + setState(167); + functionBody(); + } + } + setState(172); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(175); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==ELSE) { + { + setState(173); + match(ELSE); + setState(174); + functionBody(); + } + } + + setState(177); + match(END); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class LetStatementContext extends ParserRuleContext { + public TerminalNode LET() { return getToken(JuliaParser.LET, 0); } + public FunctionBodyContext functionBody() { + return getRuleContext(FunctionBodyContext.class,0); + } + public TerminalNode END() { return getToken(JuliaParser.END, 0); } + public LetStatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_letStatement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).enterLetStatement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).exitLetStatement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JuliaVisitor ) return ((JuliaVisitor)visitor).visitLetStatement(this); + else return visitor.visitChildren(this); + } + } + + public final LetStatementContext letStatement() throws RecognitionException { + LetStatementContext _localctx = new LetStatementContext(_ctx, getState()); + enterRule(_localctx, 24, RULE_letStatement); + try { + enterOuterAlt(_localctx, 1); + { + setState(179); + match(LET); + setState(180); + functionBody(); + setState(181); + match(END); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class MacroStatementContext extends ParserRuleContext { + public TerminalNode MACRO() { return getToken(JuliaParser.MACRO, 0); } + public FunctionBodyContext functionBody() { + return getRuleContext(FunctionBodyContext.class,0); + } + public TerminalNode END() { return getToken(JuliaParser.END, 0); } + public MacroStatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_macroStatement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).enterMacroStatement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).exitMacroStatement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JuliaVisitor ) return ((JuliaVisitor)visitor).visitMacroStatement(this); + else return visitor.visitChildren(this); + } + } + + public final MacroStatementContext macroStatement() throws RecognitionException { + MacroStatementContext _localctx = new MacroStatementContext(_ctx, getState()); + enterRule(_localctx, 26, RULE_macroStatement); + try { + enterOuterAlt(_localctx, 1); + { + setState(183); + match(MACRO); + setState(184); + functionBody(); + setState(185); + match(END); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class StructStatementContext extends ParserRuleContext { + public TerminalNode STRUCT() { return getToken(JuliaParser.STRUCT, 0); } + public FunctionBodyContext functionBody() { + return getRuleContext(FunctionBodyContext.class,0); + } + public TerminalNode END() { return getToken(JuliaParser.END, 0); } + public StructStatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_structStatement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).enterStructStatement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).exitStructStatement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JuliaVisitor ) return ((JuliaVisitor)visitor).visitStructStatement(this); + else return visitor.visitChildren(this); + } + } + + public final StructStatementContext structStatement() throws RecognitionException { + StructStatementContext _localctx = new StructStatementContext(_ctx, getState()); + enterRule(_localctx, 28, RULE_structStatement); + try { + enterOuterAlt(_localctx, 1); + { + setState(187); + match(STRUCT); + setState(188); + functionBody(); + setState(189); + match(END); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class TryCatchStatementContext extends ParserRuleContext { + public TerminalNode TRY() { return getToken(JuliaParser.TRY, 0); } + public List functionBody() { + return getRuleContexts(FunctionBodyContext.class); + } + public FunctionBodyContext functionBody(int i) { + return getRuleContext(FunctionBodyContext.class,i); + } + public TerminalNode END() { return getToken(JuliaParser.END, 0); } + public TerminalNode CATCH() { return getToken(JuliaParser.CATCH, 0); } + public TerminalNode FINALLY() { return getToken(JuliaParser.FINALLY, 0); } + public TryCatchStatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_tryCatchStatement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).enterTryCatchStatement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).exitTryCatchStatement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JuliaVisitor ) return ((JuliaVisitor)visitor).visitTryCatchStatement(this); + else return visitor.visitChildren(this); + } + } + + public final TryCatchStatementContext tryCatchStatement() throws RecognitionException { + TryCatchStatementContext _localctx = new TryCatchStatementContext(_ctx, getState()); + enterRule(_localctx, 30, RULE_tryCatchStatement); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(191); + match(TRY); + setState(192); + functionBody(); + setState(195); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==CATCH) { + { + setState(193); + match(CATCH); + setState(194); + functionBody(); + } + } + + setState(199); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==FINALLY) { + { + setState(197); + match(FINALLY); + setState(198); + functionBody(); + } + } + + setState(201); + match(END); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class TypeStatementContext extends ParserRuleContext { + public TerminalNode TYPE() { return getToken(JuliaParser.TYPE, 0); } + public FunctionBodyContext functionBody() { + return getRuleContext(FunctionBodyContext.class,0); + } + public TerminalNode END() { return getToken(JuliaParser.END, 0); } + public TypeStatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_typeStatement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).enterTypeStatement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).exitTypeStatement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JuliaVisitor ) return ((JuliaVisitor)visitor).visitTypeStatement(this); + else return visitor.visitChildren(this); + } + } + + public final TypeStatementContext typeStatement() throws RecognitionException { + TypeStatementContext _localctx = new TypeStatementContext(_ctx, getState()); + enterRule(_localctx, 32, RULE_typeStatement); + try { + enterOuterAlt(_localctx, 1); + { + setState(203); + match(TYPE); + setState(204); + functionBody(); + setState(205); + match(END); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class WhileStatementContext extends ParserRuleContext { + public TerminalNode WHILE() { return getToken(JuliaParser.WHILE, 0); } + public FunctionBodyContext functionBody() { + return getRuleContext(FunctionBodyContext.class,0); + } + public TerminalNode END() { return getToken(JuliaParser.END, 0); } + public WhileStatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_whileStatement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).enterWhileStatement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).exitWhileStatement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JuliaVisitor ) return ((JuliaVisitor)visitor).visitWhileStatement(this); + else return visitor.visitChildren(this); + } + } + + public final WhileStatementContext whileStatement() throws RecognitionException { + WhileStatementContext _localctx = new WhileStatementContext(_ctx, getState()); + enterRule(_localctx, 34, RULE_whileStatement); + try { + enterOuterAlt(_localctx, 1); + { + setState(207); + match(WHILE); + setState(208); + functionBody(); + setState(209); + match(END); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class AnyTokenContext extends ParserRuleContext { + public TerminalNode ABSTRACT() { return getToken(JuliaParser.ABSTRACT, 0); } + public TerminalNode ANY() { return getToken(JuliaParser.ANY, 0); } + public TerminalNode ARROWOPERATOR() { return getToken(JuliaParser.ARROWOPERATOR, 0); } + public TerminalNode ASSIGNMENTOPERATOR() { return getToken(JuliaParser.ASSIGNMENTOPERATOR, 0); } + public TerminalNode BAREMODULE() { return getToken(JuliaParser.BAREMODULE, 0); } + public TerminalNode BEGIN() { return getToken(JuliaParser.BEGIN, 0); } + public TerminalNode BITSHIFTOPERATOR() { return getToken(JuliaParser.BITSHIFTOPERATOR, 0); } + public TerminalNode BITSTYPE() { return getToken(JuliaParser.BITSTYPE, 0); } + public TerminalNode BREAK() { return getToken(JuliaParser.BREAK, 0); } + public TerminalNode CATCH() { return getToken(JuliaParser.CATCH, 0); } + public TerminalNode CCALL() { return getToken(JuliaParser.CCALL, 0); } + public TerminalNode CHAR() { return getToken(JuliaParser.CHAR, 0); } + public TerminalNode CONST() { return getToken(JuliaParser.CONST, 0); } + public TerminalNode CONTINUE() { return getToken(JuliaParser.CONTINUE, 0); } + public TerminalNode DO() { return getToken(JuliaParser.DO, 0); } + public TerminalNode ELSE() { return getToken(JuliaParser.ELSE, 0); } + public TerminalNode ELSIF() { return getToken(JuliaParser.ELSIF, 0); } + public TerminalNode END() { return getToken(JuliaParser.END, 0); } + public TerminalNode EXPORT() { return getToken(JuliaParser.EXPORT, 0); } + public TerminalNode EXTERNALCOMMAND() { return getToken(JuliaParser.EXTERNALCOMMAND, 0); } + public TerminalNode FINALLY() { return getToken(JuliaParser.FINALLY, 0); } + public TerminalNode FOR() { return getToken(JuliaParser.FOR, 0); } + public TerminalNode FUNCTION() { return getToken(JuliaParser.FUNCTION, 0); } + public TerminalNode GLOBAL() { return getToken(JuliaParser.GLOBAL, 0); } + public TerminalNode IDENTIFIER() { return getToken(JuliaParser.IDENTIFIER, 0); } + public TerminalNode IF() { return getToken(JuliaParser.IF, 0); } + public TerminalNode IMMUTABLE() { return getToken(JuliaParser.IMMUTABLE, 0); } + public TerminalNode IMPORT() { return getToken(JuliaParser.IMPORT, 0); } + public TerminalNode IMPORTALL() { return getToken(JuliaParser.IMPORTALL, 0); } + public TerminalNode INSTANCEOF() { return getToken(JuliaParser.INSTANCEOF, 0); } + public TerminalNode LET() { return getToken(JuliaParser.LET, 0); } + public TerminalNode LOCAL() { return getToken(JuliaParser.LOCAL, 0); } + public TerminalNode MACRO() { return getToken(JuliaParser.MACRO, 0); } + public TerminalNode MODULE() { return getToken(JuliaParser.MODULE, 0); } + public TerminalNode NUMERICAL() { return getToken(JuliaParser.NUMERICAL, 0); } + public TerminalNode PIPEOPERATOR() { return getToken(JuliaParser.PIPEOPERATOR, 0); } + public TerminalNode QUOTE() { return getToken(JuliaParser.QUOTE, 0); } + public TerminalNode RETURN() { return getToken(JuliaParser.RETURN, 0); } + public TerminalNode STAGED_FUNCTION() { return getToken(JuliaParser.STAGED_FUNCTION, 0); } + public TerminalNode STRING() { return getToken(JuliaParser.STRING, 0); } + public TerminalNode STRUCT() { return getToken(JuliaParser.STRUCT, 0); } + public TerminalNode TRY() { return getToken(JuliaParser.TRY, 0); } + public TerminalNode TYPE() { return getToken(JuliaParser.TYPE, 0); } + public TerminalNode TYPEALIAS() { return getToken(JuliaParser.TYPEALIAS, 0); } + public TerminalNode USING() { return getToken(JuliaParser.USING, 0); } + public TerminalNode WHERE() { return getToken(JuliaParser.WHERE, 0); } + public TerminalNode WHILE() { return getToken(JuliaParser.WHILE, 0); } + public List anyToken() { + return getRuleContexts(AnyTokenContext.class); + } + public AnyTokenContext anyToken(int i) { + return getRuleContext(AnyTokenContext.class,i); + } + public AnyTokenContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_anyToken; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).enterAnyToken(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof JuliaListener ) ((JuliaListener)listener).exitAnyToken(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JuliaVisitor ) return ((JuliaVisitor)visitor).visitAnyToken(this); + else return visitor.visitChildren(this); + } + } + + public final AnyTokenContext anyToken() throws RecognitionException { + AnyTokenContext _localctx = new AnyTokenContext(_ctx, getState()); + enterRule(_localctx, 36, RULE_anyToken); + try { + int _alt; + setState(293); + _errHandler.sync(this); + switch (_input.LA(1)) { + case ABSTRACT: + enterOuterAlt(_localctx, 1); + { + setState(211); + match(ABSTRACT); + } + break; + case ANY: + enterOuterAlt(_localctx, 2); + { + setState(212); + match(ANY); + } + break; + case ARROWOPERATOR: + enterOuterAlt(_localctx, 3); + { + setState(213); + match(ARROWOPERATOR); + } + break; + case ASSIGNMENTOPERATOR: + enterOuterAlt(_localctx, 4); + { + setState(214); + match(ASSIGNMENTOPERATOR); + } + break; + case BAREMODULE: + enterOuterAlt(_localctx, 5); + { + setState(215); + match(BAREMODULE); + } + break; + case BEGIN: + enterOuterAlt(_localctx, 6); + { + setState(216); + match(BEGIN); + } + break; + case BITSHIFTOPERATOR: + enterOuterAlt(_localctx, 7); + { + setState(217); + match(BITSHIFTOPERATOR); + } + break; + case BITSTYPE: + enterOuterAlt(_localctx, 8); + { + setState(218); + match(BITSTYPE); + } + break; + case BREAK: + enterOuterAlt(_localctx, 9); + { + setState(219); + match(BREAK); + } + break; + case CATCH: + enterOuterAlt(_localctx, 10); + { + setState(220); + match(CATCH); + } + break; + case CCALL: + enterOuterAlt(_localctx, 11); + { + setState(221); + match(CCALL); + } + break; + case CHAR: + enterOuterAlt(_localctx, 12); + { + setState(222); + match(CHAR); + } + break; + case CONST: + enterOuterAlt(_localctx, 13); + { + setState(223); + match(CONST); + } + break; + case CONTINUE: + enterOuterAlt(_localctx, 14); + { + setState(224); + match(CONTINUE); + } + break; + case DO: + enterOuterAlt(_localctx, 15); + { + setState(225); + match(DO); + } + break; + case ELSE: + enterOuterAlt(_localctx, 16); + { + setState(226); + match(ELSE); + } + break; + case ELSIF: + enterOuterAlt(_localctx, 17); + { + setState(227); + match(ELSIF); + } + break; + case END: + enterOuterAlt(_localctx, 18); + { + setState(228); + match(END); + } + break; + case EXPORT: + enterOuterAlt(_localctx, 19); + { + setState(229); + match(EXPORT); + } + break; + case EXTERNALCOMMAND: + enterOuterAlt(_localctx, 20); + { + setState(230); + match(EXTERNALCOMMAND); + } + break; + case FINALLY: + enterOuterAlt(_localctx, 21); + { + setState(231); + match(FINALLY); + } + break; + case FOR: + enterOuterAlt(_localctx, 22); + { + setState(232); + match(FOR); + } + break; + case FUNCTION: + enterOuterAlt(_localctx, 23); + { + setState(233); + match(FUNCTION); + } + break; + case GLOBAL: + enterOuterAlt(_localctx, 24); + { + setState(234); + match(GLOBAL); + } + break; + case IDENTIFIER: + enterOuterAlt(_localctx, 25); + { + setState(235); + match(IDENTIFIER); + } + break; + case IF: + enterOuterAlt(_localctx, 26); + { + setState(236); + match(IF); + } + break; + case IMMUTABLE: + enterOuterAlt(_localctx, 27); + { + setState(237); + match(IMMUTABLE); + } + break; + case IMPORT: + enterOuterAlt(_localctx, 28); + { + setState(238); + match(IMPORT); + } + break; + case IMPORTALL: + enterOuterAlt(_localctx, 29); + { + setState(239); + match(IMPORTALL); + } + break; + case INSTANCEOF: + enterOuterAlt(_localctx, 30); + { + setState(240); + match(INSTANCEOF); + } + break; + case LET: + enterOuterAlt(_localctx, 31); + { + setState(241); + match(LET); + } + break; + case LOCAL: + enterOuterAlt(_localctx, 32); + { + setState(242); + match(LOCAL); + } + break; + case MACRO: + enterOuterAlt(_localctx, 33); + { + setState(243); + match(MACRO); + } + break; + case MODULE: + enterOuterAlt(_localctx, 34); + { + setState(244); + match(MODULE); + } + break; + case NUMERICAL: + enterOuterAlt(_localctx, 35); + { + setState(245); + match(NUMERICAL); + } + break; + case PIPEOPERATOR: + enterOuterAlt(_localctx, 36); + { + setState(246); + match(PIPEOPERATOR); + } + break; + case QUOTE: + enterOuterAlt(_localctx, 37); + { + setState(247); + match(QUOTE); + } + break; + case RETURN: + enterOuterAlt(_localctx, 38); + { + setState(248); + match(RETURN); + } + break; + case STAGED_FUNCTION: + enterOuterAlt(_localctx, 39); + { + setState(249); + match(STAGED_FUNCTION); + } + break; + case STRING: + enterOuterAlt(_localctx, 40); + { + setState(250); + match(STRING); + } + break; + case STRUCT: + enterOuterAlt(_localctx, 41); + { + setState(251); + match(STRUCT); + } + break; + case TRY: + enterOuterAlt(_localctx, 42); + { + setState(252); + match(TRY); + } + break; + case TYPE: + enterOuterAlt(_localctx, 43); + { + setState(253); + match(TYPE); + } + break; + case TYPEALIAS: + enterOuterAlt(_localctx, 44); + { + setState(254); + match(TYPEALIAS); + } + break; + case USING: + enterOuterAlt(_localctx, 45); + { + setState(255); + match(USING); + } + break; + case WHERE: + enterOuterAlt(_localctx, 46); + { + setState(256); + match(WHERE); + } + break; + case WHILE: + enterOuterAlt(_localctx, 47); + { + setState(257); + match(WHILE); + } + break; + case T__0: + enterOuterAlt(_localctx, 48); + { + setState(258); + match(T__0); + setState(262); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,21,_ctx); + while ( _alt!=1 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1+1 ) { + { + { + setState(259); + anyToken(); + } + } + } + setState(264); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,21,_ctx); + } + setState(265); + match(T__1); + } + break; + case T__3: + enterOuterAlt(_localctx, 49); + { + setState(266); + match(T__3); + setState(270); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,22,_ctx); + while ( _alt!=1 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1+1 ) { + { + { + setState(267); + anyToken(); + } + } + } + setState(272); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,22,_ctx); + } + setState(273); + match(T__4); + } + break; + case T__5: + enterOuterAlt(_localctx, 50); + { + setState(274); + match(T__5); + setState(278); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,23,_ctx); + while ( _alt!=1 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1+1 ) { + { + { + setState(275); + anyToken(); + } + } + } + setState(280); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,23,_ctx); + } + setState(281); + match(T__6); + } + break; + case T__2: + enterOuterAlt(_localctx, 51); + { + setState(282); + match(T__2); + } + break; + case T__7: + enterOuterAlt(_localctx, 52); + { + setState(283); + match(T__7); + } + break; + case T__8: + enterOuterAlt(_localctx, 53); + { + setState(284); + match(T__8); + } + break; + case T__9: + enterOuterAlt(_localctx, 54); + { + setState(285); + match(T__9); + } + break; + case T__10: + enterOuterAlt(_localctx, 55); + { + setState(286); + match(T__10); + } + break; + case T__11: + enterOuterAlt(_localctx, 56); + { + setState(287); + match(T__11); + } + break; + case T__12: + enterOuterAlt(_localctx, 57); + { + setState(288); + match(T__12); + } + break; + case T__13: + enterOuterAlt(_localctx, 58); + { + setState(289); + match(T__13); + } + break; + case T__14: + enterOuterAlt(_localctx, 59); + { + setState(290); + match(T__14); + } + break; + case T__15: + enterOuterAlt(_localctx, 60); + { + setState(291); + match(T__15); + } + break; + case T__16: + enterOuterAlt(_localctx, 61); + { + setState(292); + match(T__16); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static final String _serializedATN = + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3P\u012a\4\2\t\2\4"+ + "\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t"+ + "\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ + "\4\23\t\23\4\24\t\24\3\2\3\2\3\2\3\2\7\2-\n\2\f\2\16\2\60\13\2\3\2\5\2"+ + "\63\n\2\3\2\3\2\3\3\3\3\5\39\n\3\3\4\3\4\5\4=\n\4\3\4\7\4@\n\4\f\4\16"+ + "\4C\13\4\3\4\3\4\7\4G\n\4\f\4\16\4J\13\4\3\4\3\4\7\4N\n\4\f\4\16\4Q\13"+ + "\4\3\4\5\4T\n\4\3\4\3\4\3\5\3\5\3\5\7\5[\n\5\f\5\16\5^\13\5\3\5\3\5\7"+ + "\5b\n\5\f\5\16\5e\13\5\3\5\3\5\3\5\3\6\3\6\3\6\7\6m\n\6\f\6\16\6p\13\6"+ + "\3\6\5\6s\n\6\3\7\3\7\7\7w\n\7\f\7\16\7z\13\7\3\b\7\b}\n\b\f\b\16\b\u0080"+ + "\13\b\3\b\3\b\7\b\u0084\n\b\f\b\16\b\u0087\13\b\7\b\u0089\n\b\f\b\16\b"+ + "\u008c\13\b\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3\t\5\t\u0099\n\t"+ + "\3\n\3\n\3\n\3\n\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3\r\7"+ + "\r\u00ab\n\r\f\r\16\r\u00ae\13\r\3\r\3\r\5\r\u00b2\n\r\3\r\3\r\3\16\3"+ + "\16\3\16\3\16\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3"+ + "\21\5\21\u00c6\n\21\3\21\3\21\5\21\u00ca\n\21\3\21\3\21\3\22\3\22\3\22"+ + "\3\22\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24"+ + "\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24"+ + "\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24"+ + "\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\7\24\u0107"+ + "\n\24\f\24\16\24\u010a\13\24\3\24\3\24\3\24\7\24\u010f\n\24\f\24\16\24"+ + "\u0112\13\24\3\24\3\24\3\24\7\24\u0117\n\24\f\24\16\24\u011a\13\24\3\24"+ + "\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\5\24\u0128\n\24"+ + "\3\24\17AHO\\cnx~\u0085\u008a\u0108\u0110\u0118\2\25\2\4\6\b\n\f\16\20"+ + "\22\24\26\30\32\34\36 \"$&\2\2\2\u0173\2(\3\2\2\2\48\3\2\2\2\6:\3\2\2"+ + "\2\bW\3\2\2\2\nr\3\2\2\2\ft\3\2\2\2\16~\3\2\2\2\20\u0098\3\2\2\2\22\u009a"+ + "\3\2\2\2\24\u009e\3\2\2\2\26\u00a2\3\2\2\2\30\u00a6\3\2\2\2\32\u00b5\3"+ + "\2\2\2\34\u00b9\3\2\2\2\36\u00bd\3\2\2\2 \u00c1\3\2\2\2\"\u00cd\3\2\2"+ + "\2$\u00d1\3\2\2\2&\u0127\3\2\2\2(.\5\16\b\2)*\5\4\3\2*+\5\16\b\2+-\3\2"+ + "\2\2,)\3\2\2\2-\60\3\2\2\2.,\3\2\2\2./\3\2\2\2/\62\3\2\2\2\60.\3\2\2\2"+ + "\61\63\7*\2\2\62\61\3\2\2\2\62\63\3\2\2\2\63\64\3\2\2\2\64\65\7\2\2\3"+ + "\65\3\3\2\2\2\669\5\6\4\2\679\5\b\5\28\66\3\2\2\28\67\3\2\2\29\5\3\2\2"+ + "\2:<\7/\2\2;=\7N\2\2<;\3\2\2\2<=\3\2\2\2=A\3\2\2\2>@\5&\24\2?>\3\2\2\2"+ + "@C\3\2\2\2AB\3\2\2\2A?\3\2\2\2BS\3\2\2\2CA\3\2\2\2DH\7\3\2\2EG\5&\24\2"+ + "FE\3\2\2\2GJ\3\2\2\2HI\3\2\2\2HF\3\2\2\2IK\3\2\2\2JH\3\2\2\2KO\7\4\2\2"+ + "LN\5\f\7\2ML\3\2\2\2NQ\3\2\2\2OP\3\2\2\2OM\3\2\2\2PR\3\2\2\2QO\3\2\2\2"+ + "RT\5\16\b\2SD\3\2\2\2ST\3\2\2\2TU\3\2\2\2UV\7*\2\2V\7\3\2\2\2WX\5\n\6"+ + "\2X\\\7\3\2\2Y[\5&\24\2ZY\3\2\2\2[^\3\2\2\2\\]\3\2\2\2\\Z\3\2\2\2]_\3"+ + "\2\2\2^\\\3\2\2\2_c\7\4\2\2`b\5\f\7\2a`\3\2\2\2be\3\2\2\2cd\3\2\2\2ca"+ + "\3\2\2\2df\3\2\2\2ec\3\2\2\2fg\7\5\2\2gh\5\16\b\2h\t\3\2\2\2is\7N\2\2"+ + "jn\7\3\2\2km\5&\24\2lk\3\2\2\2mp\3\2\2\2no\3\2\2\2nl\3\2\2\2oq\3\2\2\2"+ + "pn\3\2\2\2qs\7\4\2\2ri\3\2\2\2rj\3\2\2\2s\13\3\2\2\2tx\7D\2\2uw\5&\24"+ + "\2vu\3\2\2\2wz\3\2\2\2xy\3\2\2\2xv\3\2\2\2y\r\3\2\2\2zx\3\2\2\2{}\5&\24"+ + "\2|{\3\2\2\2}\u0080\3\2\2\2~\177\3\2\2\2~|\3\2\2\2\177\u008a\3\2\2\2\u0080"+ + "~\3\2\2\2\u0081\u0085\5\20\t\2\u0082\u0084\5&\24\2\u0083\u0082\3\2\2\2"+ + "\u0084\u0087\3\2\2\2\u0085\u0086\3\2\2\2\u0085\u0083\3\2\2\2\u0086\u0089"+ + "\3\2\2\2\u0087\u0085\3\2\2\2\u0088\u0081\3\2\2\2\u0089\u008c\3\2\2\2\u008a"+ + "\u008b\3\2\2\2\u008a\u0088\3\2\2\2\u008b\17\3\2\2\2\u008c\u008a\3\2\2"+ + "\2\u008d\u0099\5\22\n\2\u008e\u0099\5\24\13\2\u008f\u0099\5\26\f\2\u0090"+ + "\u0099\5\6\4\2\u0091\u0099\5\30\r\2\u0092\u0099\5\32\16\2\u0093\u0099"+ + "\5\34\17\2\u0094\u0099\5\36\20\2\u0095\u0099\5 \21\2\u0096\u0099\5\"\22"+ + "\2\u0097\u0099\5$\23\2\u0098\u008d\3\2\2\2\u0098\u008e\3\2\2\2\u0098\u008f"+ + "\3\2\2\2\u0098\u0090\3\2\2\2\u0098\u0091\3\2\2\2\u0098\u0092\3\2\2\2\u0098"+ + "\u0093\3\2\2\2\u0098\u0094\3\2\2\2\u0098\u0095\3\2\2\2\u0098\u0096\3\2"+ + "\2\2\u0098\u0097\3\2\2\2\u0099\21\3\2\2\2\u009a\u009b\7\36\2\2\u009b\u009c"+ + "\5\16\b\2\u009c\u009d\7*\2\2\u009d\23\3\2\2\2\u009e\u009f\7\'\2\2\u009f"+ + "\u00a0\5\16\b\2\u00a0\u00a1\7*\2\2\u00a1\25\3\2\2\2\u00a2\u00a3\7.\2\2"+ + "\u00a3\u00a4\5\16\b\2\u00a4\u00a5\7*\2\2\u00a5\27\3\2\2\2\u00a6\u00a7"+ + "\7\61\2\2\u00a7\u00ac\5\16\b\2\u00a8\u00a9\7)\2\2\u00a9\u00ab\5\16\b\2"+ + "\u00aa\u00a8\3\2\2\2\u00ab\u00ae\3\2\2\2\u00ac\u00aa\3\2\2\2\u00ac\u00ad"+ + "\3\2\2\2\u00ad\u00b1\3\2\2\2\u00ae\u00ac\3\2\2\2\u00af\u00b0\7(\2\2\u00b0"+ + "\u00b2\5\16\b\2\u00b1\u00af\3\2\2\2\u00b1\u00b2\3\2\2\2\u00b2\u00b3\3"+ + "\2\2\2\u00b3\u00b4\7*\2\2\u00b4\31\3\2\2\2\u00b5\u00b6\7\66\2\2\u00b6"+ + "\u00b7\5\16\b\2\u00b7\u00b8\7*\2\2\u00b8\33\3\2\2\2\u00b9\u00ba\78\2\2"+ + "\u00ba\u00bb\5\16\b\2\u00bb\u00bc\7*\2\2\u00bc\35\3\2\2\2\u00bd\u00be"+ + "\7?\2\2\u00be\u00bf\5\16\b\2\u00bf\u00c0\7*\2\2\u00c0\37\3\2\2\2\u00c1"+ + "\u00c2\7@\2\2\u00c2\u00c5\5\16\b\2\u00c3\u00c4\7\"\2\2\u00c4\u00c6\5\16"+ + "\b\2\u00c5\u00c3\3\2\2\2\u00c5\u00c6\3\2\2\2\u00c6\u00c9\3\2\2\2\u00c7"+ + "\u00c8\7-\2\2\u00c8\u00ca\5\16\b\2\u00c9\u00c7\3\2\2\2\u00c9\u00ca\3\2"+ + "\2\2\u00ca\u00cb\3\2\2\2\u00cb\u00cc\7*\2\2\u00cc!\3\2\2\2\u00cd\u00ce"+ + "\7A\2\2\u00ce\u00cf\5\16\b\2\u00cf\u00d0\7*\2\2\u00d0#\3\2\2\2\u00d1\u00d2"+ + "\7E\2\2\u00d2\u00d3\5\16\b\2\u00d3\u00d4\7*\2\2\u00d4%\3\2\2\2\u00d5\u0128"+ + "\7\32\2\2\u00d6\u0128\7O\2\2\u00d7\u0128\7\33\2\2\u00d8\u0128\7\34\2\2"+ + "\u00d9\u0128\7\35\2\2\u00da\u0128\7\36\2\2\u00db\u0128\7\37\2\2\u00dc"+ + "\u0128\7 \2\2\u00dd\u0128\7!\2\2\u00de\u0128\7\"\2\2\u00df\u0128\7#\2"+ + "\2\u00e0\u0128\7$\2\2\u00e1\u0128\7%\2\2\u00e2\u0128\7&\2\2\u00e3\u0128"+ + "\7\'\2\2\u00e4\u0128\7(\2\2\u00e5\u0128\7)\2\2\u00e6\u0128\7*\2\2\u00e7"+ + "\u0128\7+\2\2\u00e8\u0128\7,\2\2\u00e9\u0128\7-\2\2\u00ea\u0128\7.\2\2"+ + "\u00eb\u0128\7/\2\2\u00ec\u0128\7\60\2\2\u00ed\u0128\7N\2\2\u00ee\u0128"+ + "\7\61\2\2\u00ef\u0128\7\62\2\2\u00f0\u0128\7\63\2\2\u00f1\u0128\7\64\2"+ + "\2\u00f2\u0128\7\65\2\2\u00f3\u0128\7\66\2\2\u00f4\u0128\7\67\2\2\u00f5"+ + "\u0128\78\2\2\u00f6\u0128\79\2\2\u00f7\u0128\7F\2\2\u00f8\u0128\7:\2\2"+ + "\u00f9\u0128\7;\2\2\u00fa\u0128\7<\2\2\u00fb\u0128\7P\2\2\u00fc\u0128"+ + "\7>\2\2\u00fd\u0128\7?\2\2\u00fe\u0128\7@\2\2\u00ff\u0128\7A\2\2\u0100"+ + "\u0128\7B\2\2\u0101\u0128\7C\2\2\u0102\u0128\7D\2\2\u0103\u0128\7E\2\2"+ + "\u0104\u0108\7\3\2\2\u0105\u0107\5&\24\2\u0106\u0105\3\2\2\2\u0107\u010a"+ + "\3\2\2\2\u0108\u0109\3\2\2\2\u0108\u0106\3\2\2\2\u0109\u010b\3\2\2\2\u010a"+ + "\u0108\3\2\2\2\u010b\u0128\7\4\2\2\u010c\u0110\7\6\2\2\u010d\u010f\5&"+ + "\24\2\u010e\u010d\3\2\2\2\u010f\u0112\3\2\2\2\u0110\u0111\3\2\2\2\u0110"+ + "\u010e\3\2\2\2\u0111\u0113\3\2\2\2\u0112\u0110\3\2\2\2\u0113\u0128\7\7"+ + "\2\2\u0114\u0118\7\b\2\2\u0115\u0117\5&\24\2\u0116\u0115\3\2\2\2\u0117"+ + "\u011a\3\2\2\2\u0118\u0119\3\2\2\2\u0118\u0116\3\2\2\2\u0119\u011b\3\2"+ + "\2\2\u011a\u0118\3\2\2\2\u011b\u0128\7\t\2\2\u011c\u0128\7\5\2\2\u011d"+ + "\u0128\7\n\2\2\u011e\u0128\7\13\2\2\u011f\u0128\7\f\2\2\u0120\u0128\7"+ + "\r\2\2\u0121\u0128\7\16\2\2\u0122\u0128\7\17\2\2\u0123\u0128\7\20\2\2"+ + "\u0124\u0128\7\21\2\2\u0125\u0128\7\22\2\2\u0126\u0128\7\23\2\2\u0127"+ + "\u00d5\3\2\2\2\u0127\u00d6\3\2\2\2\u0127\u00d7\3\2\2\2\u0127\u00d8\3\2"+ + "\2\2\u0127\u00d9\3\2\2\2\u0127\u00da\3\2\2\2\u0127\u00db\3\2\2\2\u0127"+ + "\u00dc\3\2\2\2\u0127\u00dd\3\2\2\2\u0127\u00de\3\2\2\2\u0127\u00df\3\2"+ + "\2\2\u0127\u00e0\3\2\2\2\u0127\u00e1\3\2\2\2\u0127\u00e2\3\2\2\2\u0127"+ + "\u00e3\3\2\2\2\u0127\u00e4\3\2\2\2\u0127\u00e5\3\2\2\2\u0127\u00e6\3\2"+ + "\2\2\u0127\u00e7\3\2\2\2\u0127\u00e8\3\2\2\2\u0127\u00e9\3\2\2\2\u0127"+ + "\u00ea\3\2\2\2\u0127\u00eb\3\2\2\2\u0127\u00ec\3\2\2\2\u0127\u00ed\3\2"+ + "\2\2\u0127\u00ee\3\2\2\2\u0127\u00ef\3\2\2\2\u0127\u00f0\3\2\2\2\u0127"+ + "\u00f1\3\2\2\2\u0127\u00f2\3\2\2\2\u0127\u00f3\3\2\2\2\u0127\u00f4\3\2"+ + "\2\2\u0127\u00f5\3\2\2\2\u0127\u00f6\3\2\2\2\u0127\u00f7\3\2\2\2\u0127"+ + "\u00f8\3\2\2\2\u0127\u00f9\3\2\2\2\u0127\u00fa\3\2\2\2\u0127\u00fb\3\2"+ + "\2\2\u0127\u00fc\3\2\2\2\u0127\u00fd\3\2\2\2\u0127\u00fe\3\2\2\2\u0127"+ + "\u00ff\3\2\2\2\u0127\u0100\3\2\2\2\u0127\u0101\3\2\2\2\u0127\u0102\3\2"+ + "\2\2\u0127\u0103\3\2\2\2\u0127\u0104\3\2\2\2\u0127\u010c\3\2\2\2\u0127"+ + "\u0114\3\2\2\2\u0127\u011c\3\2\2\2\u0127\u011d\3\2\2\2\u0127\u011e\3\2"+ + "\2\2\u0127\u011f\3\2\2\2\u0127\u0120\3\2\2\2\u0127\u0121\3\2\2\2\u0127"+ + "\u0122\3\2\2\2\u0127\u0123\3\2\2\2\u0127\u0124\3\2\2\2\u0127\u0125\3\2"+ + "\2\2\u0127\u0126\3\2\2\2\u0128\'\3\2\2\2\33.\628 The return type of the visit operation. Use {@link Void} for + * operations with no return type. + * + * @deprecated Since 7.8.0. This class was never intended to be generated. It will be removed with no replacement. + */ + +@Deprecated +@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public interface JuliaVisitor extends ParseTreeVisitor { + /** + * Visit a parse tree produced by {@link JuliaParser#main}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitMain(JuliaParser.MainContext ctx); + /** + * Visit a parse tree produced by {@link JuliaParser#functionDefinition}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitFunctionDefinition(JuliaParser.FunctionDefinitionContext ctx); + /** + * Visit a parse tree produced by {@link JuliaParser#functionDefinition1}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitFunctionDefinition1(JuliaParser.FunctionDefinition1Context ctx); + /** + * Visit a parse tree produced by {@link JuliaParser#functionDefinition2}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitFunctionDefinition2(JuliaParser.FunctionDefinition2Context ctx); + /** + * Visit a parse tree produced by {@link JuliaParser#functionIdentifier}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitFunctionIdentifier(JuliaParser.FunctionIdentifierContext ctx); + /** + * Visit a parse tree produced by {@link JuliaParser#whereClause}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitWhereClause(JuliaParser.WhereClauseContext ctx); + /** + * Visit a parse tree produced by {@link JuliaParser#functionBody}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitFunctionBody(JuliaParser.FunctionBodyContext ctx); + /** + * Visit a parse tree produced by {@link JuliaParser#statement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStatement(JuliaParser.StatementContext ctx); + /** + * Visit a parse tree produced by {@link JuliaParser#beginStatement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitBeginStatement(JuliaParser.BeginStatementContext ctx); + /** + * Visit a parse tree produced by {@link JuliaParser#doStatement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitDoStatement(JuliaParser.DoStatementContext ctx); + /** + * Visit a parse tree produced by {@link JuliaParser#forStatement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitForStatement(JuliaParser.ForStatementContext ctx); + /** + * Visit a parse tree produced by {@link JuliaParser#ifStatement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitIfStatement(JuliaParser.IfStatementContext ctx); + /** + * Visit a parse tree produced by {@link JuliaParser#letStatement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitLetStatement(JuliaParser.LetStatementContext ctx); + /** + * Visit a parse tree produced by {@link JuliaParser#macroStatement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitMacroStatement(JuliaParser.MacroStatementContext ctx); + /** + * Visit a parse tree produced by {@link JuliaParser#structStatement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStructStatement(JuliaParser.StructStatementContext ctx); + /** + * Visit a parse tree produced by {@link JuliaParser#tryCatchStatement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTryCatchStatement(JuliaParser.TryCatchStatementContext ctx); + /** + * Visit a parse tree produced by {@link JuliaParser#typeStatement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTypeStatement(JuliaParser.TypeStatementContext ctx); + /** + * Visit a parse tree produced by {@link JuliaParser#whileStatement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitWhileStatement(JuliaParser.WhileStatementContext ctx); + /** + * Visit a parse tree produced by {@link JuliaParser#anyToken}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitAnyToken(JuliaParser.AnyTokenContext ctx); +} From aad8e93a2f71ed5daa53c892e24eb63ea06a8418 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Fri, 15 Nov 2024 16:13:44 -0300 Subject: [PATCH 0251/1962] Add test case ensuring we don't incur in FNs --- .../bestpractices/xml/UnusedPrivateMethod.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index 5f38fdcf2e2..12b92436d9f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2297,4 +2297,20 @@ public class ObtainViaTest { ]]> + + UnusedPrivateMethod #5083 - method reference without target type (3) + 2 + s) { + s.forEach(this::foo); // Not being able to resolve UnresolvedType and AnotherUnresolvedType means we can't tell which foo is being used hereโ€ฆ + } +} + ]]> + + From a6746fcffaf28ce5e477134618c845ac2b48f491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Fri, 15 Nov 2024 16:14:53 -0300 Subject: [PATCH 0252/1962] Update changelog, refs #5083 --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index e64354df241..c1d07eb0284 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,6 +25,8 @@ This is a {{ site.pmd.release_type }} release. * [#5293](https://github.com/pmd/pmd/issues/5293): \[java] Deadlock when executing PMD in multiple threads * [#5324](https://github.com/pmd/pmd/issues/5324): \[java] Issue with type inference of nested lambdas * [#5329](https://github.com/pmd/pmd/issues/5329): \[java] Type inference issue with unknown method ref in call chain +* java-bestpractices + * [#5083](https://github.com/pmd/pmd/issues/5083): \[java] UnusedPrivateMethod false positive when method reference has no target type * java-performance * [#5314](https://github.com/pmd/pmd/issues/5314): \[java] InsufficientStringBufferDeclarationRule: Lack of handling for char type parameters From b6f45ed6187bebdefc4a51f058d6655d5cfdffc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Fri, 15 Nov 2024 17:54:35 -0300 Subject: [PATCH 0253/1962] Ensure types don't match --- .../lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index 12b92436d9f..329eaaf54b6 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2306,7 +2306,7 @@ import java.util.Set; public class Foo { private void foo(AnotherUnresolvedType baz) {} private void foo(UnresolvedType baz) {} - public void bar(Set s) { + public void bar(Set s) { s.forEach(this::foo); // Not being able to resolve UnresolvedType and AnotherUnresolvedType means we can't tell which foo is being used hereโ€ฆ } } From 15cab177d237d838fcc4da6a7ca8a0617c43a74a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Fri, 15 Nov 2024 18:30:03 -0300 Subject: [PATCH 0254/1962] Remove added test --- .../bestpractices/xml/UnusedPrivateMethod.xml | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index 329eaaf54b6..548b16a1612 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2296,21 +2296,4 @@ public class ObtainViaTest { } ]]> - - - UnusedPrivateMethod #5083 - method reference without target type (3) - 2 - s) { - s.forEach(this::foo); // Not being able to resolve UnresolvedType and AnotherUnresolvedType means we can't tell which foo is being used hereโ€ฆ - } -} - ]]> - - From ee1ab976bc41fe307397975eddfa63056e33d314 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Fri, 15 Nov 2024 18:39:39 -0300 Subject: [PATCH 0255/1962] update changelog, refs #5097 --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index e64354df241..60fdbc6a45d 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,6 +25,8 @@ This is a {{ site.pmd.release_type }} release. * [#5293](https://github.com/pmd/pmd/issues/5293): \[java] Deadlock when executing PMD in multiple threads * [#5324](https://github.com/pmd/pmd/issues/5324): \[java] Issue with type inference of nested lambdas * [#5329](https://github.com/pmd/pmd/issues/5329): \[java] Type inference issue with unknown method ref in call chain +* java-bestpractices + * [#5097](https://github.com/pmd/pmd/issues/5097): \[java] UnusedPrivateMethod FP with raw type missing from the classpath * java-performance * [#5314](https://github.com/pmd/pmd/issues/5314): \[java] InsufficientStringBufferDeclarationRule: Lack of handling for char type parameters From 1ee0f53608e5c3f0ec6d62e4ffbb218d45132a12 Mon Sep 17 00:00:00 2001 From: mitchspano Date: Fri, 15 Nov 2024 22:07:44 +0000 Subject: [PATCH 0256/1962] Update @mitchspano as a contributor --- .all-contributorsrc | 4 ++-- docs/pages/pmd/projectdocs/credits.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 929528f6149..0af52570b4a 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7517,8 +7517,8 @@ "avatar_url": "https://avatars.githubusercontent.com/u/18402464?v=4", "profile": "https://github.com/mitchspano", "contributions": [ - "bug", - "code" + "code", + "bug" ] }, { diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 0213cced3c8..eb1dcc1f530 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -557,7 +557,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
    Mihai Ionut

    ๐Ÿ›
    Mikhail Kuchma

    ๐Ÿ›
    Mirek Hankus

    ๐Ÿ› -
    Mitch Spano

    ๐Ÿ› ๐Ÿ’ป +
    Mitch Spano

    ๐Ÿ’ป ๐Ÿ›
    Mladjan Gadzic

    ๐Ÿ›
    MrAngry52

    ๐Ÿ›
    Muminur Choudhury

    ๐Ÿ› From c4563969318c80f668c4d7d6e715ded25437a431 Mon Sep 17 00:00:00 2001 From: mitchspano Date: Fri, 15 Nov 2024 22:14:20 +0000 Subject: [PATCH 0257/1962] Reset credits.md to pmd main HEAD. --- docs/pages/pmd/projectdocs/credits.md | 2211 +++++++++++++------------ 1 file changed, 1108 insertions(+), 1103 deletions(-) diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index eb1dcc1f530..81690f91dc9 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -13,1109 +13,1114 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    0xflotus

    ๐Ÿ’ป ๐Ÿ›

    1henni

    ๐Ÿ›

    219sansim

    ๐Ÿ’ป

    ALiNew

    ๐Ÿ›

    ASBrouwers

    ๐Ÿ’ป

    Abhijit Sarkar

    ๐Ÿ›

    Abhishek Kumar

    ๐Ÿ›

    Adam

    ๐Ÿ›

    Adam Carroll

    ๐Ÿ›

    Adam Obuchowicz

    ๐Ÿ›

    Adrian Price

    ๐Ÿ›

    Adrien Lecharpentier

    ๐Ÿ›

    Aidan Harding

    ๐Ÿ›

    Akshat Bahety

    ๐Ÿ’ป ๐Ÿ›

    Akshay Thapa

    ๐Ÿ›

    Alan Buttars

    ๐Ÿ›

    Alan Hohn

    ๐Ÿ›

    Alberto Fernรกndez

    ๐Ÿ’ป ๐Ÿ›

    Alex

    ๐Ÿ’ป

    Alex

    ๐Ÿ›

    Alex B

    ๐Ÿ›

    Alex Rentz

    ๐Ÿ›

    Alex Saveau

    ๐Ÿ›

    Alex Shesterov

    ๐Ÿ’ป ๐Ÿ›

    Alexey Markevich

    ๐Ÿ›

    Alexey Naumov

    ๐Ÿ›

    Alexey Yudichev

    ๐Ÿ›

    Alix

    ๐Ÿ›

    Alix

    ๐Ÿ›

    Amish Shah

    ๐Ÿ›

    Amit Prasad

    ๐Ÿ›

    Amitosh Swain Mahapatra

    ๐Ÿ›

    Anand Subramanian

    ๐Ÿ’ป ๐Ÿ›

    Anastasiia Koba

    ๐Ÿ’ป

    Anatoly Trosinenko

    ๐Ÿ’ป ๐Ÿ›

    Andi Pabst

    ๐Ÿ’ป ๐Ÿ›

    Andrea

    ๐Ÿ›

    Andrea Aime

    ๐Ÿ›

    Andreas Dangel

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง

    Andreas Deininger

    ๐Ÿ“–

    Andreas Markussen

    ๐Ÿ›

    Andreas Schmid

    ๐Ÿ›

    Andreas Turban

    ๐Ÿ›

    Andrei Paikin

    ๐Ÿ›

    Andrew

    ๐Ÿ›

    Andrew Green

    ๐Ÿ›

    Andrey Bozhko

    ๐Ÿ“–

    Andrey Fomin

    ๐Ÿ›

    Andrey Hitrin

    ๐Ÿ›

    Andrey Mochalov

    ๐Ÿ’ป ๐Ÿ›

    Andro72

    ๐Ÿ›

    Andrwyw

    ๐Ÿ›

    Andrรฉs Catalรกn

    ๐Ÿ›

    Andy Goossens

    ๐Ÿ›

    Andy Pattenden

    ๐Ÿ›

    Andy Ray

    ๐Ÿ›

    Andy Robinson

    ๐Ÿ›

    Andy-2639

    ๐Ÿ›

    Ankush Somani

    ๐Ÿ›

    Anmol Kumar

    ๐Ÿ›

    Anthony Whitford

    ๐Ÿ›

    AnthonyKot

    ๐Ÿ›

    Anurag Agarwal

    ๐Ÿ›

    Aravind Hegde

    ๐Ÿ›

    Arda Aslan

    ๐Ÿ›

    Ari Fogel

    ๐Ÿ›

    Arnaud Jeansen

    ๐Ÿ’ป ๐Ÿ›

    Arpit Koolwal

    ๐Ÿ›

    Artem

    ๐Ÿ’ป ๐Ÿ›

    Artem

    ๐Ÿ›

    Artem Sheremet

    ๐Ÿ›

    Artur

    ๐Ÿ›

    Artur Bosch

    ๐Ÿ›

    Artur Dryomov

    ๐Ÿ›

    Artur Ossowski

    ๐Ÿ›

    Aryant Tripathi

    ๐Ÿ’ป

    AshTheMash

    ๐Ÿ›

    Ashish Rana

    ๐Ÿ›

    Atul Kaushal

    ๐Ÿ›

    August Boland

    ๐Ÿ›

    Aurel Hudec

    ๐Ÿ›

    Austin

    ๐Ÿ›

    Austin Shalit

    ๐Ÿ›

    Austin Tice

    ๐Ÿ›

    Ayoub Kaanich

    ๐Ÿ›

    BBG

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›

    Bailey Tjiong

    ๐Ÿ’ป

    Barthรฉlemy L.

    ๐Ÿ›

    Basavaraj K N

    ๐Ÿ›

    Basil Peace

    ๐Ÿ›

    Belle

    ๐Ÿ›

    Ben Lerner

    ๐Ÿ›

    Ben Manes

    ๐Ÿ›

    Ben McCann

    ๐Ÿ›

    Bendegรบz Nagy

    ๐Ÿ›

    Bennet S Yee

    ๐Ÿ›

    Benoit Lacelle

    ๐Ÿ›

    Bernardo Macรชdo

    ๐Ÿ›

    Bernd Farka

    ๐Ÿ›

    Betina Cynthia Mamani

    ๐Ÿ›

    Bhanu Prakash Pamidi

    ๐Ÿ’ป ๐Ÿ›

    Bhargav Thanki

    ๐Ÿ›

    Binu R J

    ๐Ÿ›

    Bjรถrn Kautler

    ๐Ÿ’ป ๐Ÿ›

    Blightbuster

    ๐Ÿ›

    Bo Zhang

    ๐Ÿ›

    Bob "Wombat" Hogg

    ๐Ÿ›

    Bobby Wertman

    ๐Ÿ›

    Bolarinwa Saheed Olayemi

    ๐Ÿ’ป ๐Ÿ›

    Boris Petrov

    ๐Ÿ›

    Brad Kent

    ๐Ÿ›

    Brandon Mikeska

    ๐Ÿ›

    Brian Batronis

    ๐Ÿ›

    Brian Johnson

    ๐Ÿ›

    Brice Dutheil

    ๐Ÿ’ป ๐Ÿ›

    Bruno Ferreira

    ๐Ÿ›

    Bruno Harbulot

    ๐Ÿ›

    Bruno Ritz

    ๐Ÿ›

    BurovnikovEvgeniy

    ๐Ÿ›

    Cameron Donaldson

    ๐Ÿ›

    Carlos Macasaet

    ๐Ÿ›

    Carsten Otto

    ๐Ÿ›

    Charlie Housh

    ๐Ÿ›

    Charlie Jonas

    ๐Ÿ›

    Chas Honton

    ๐Ÿ› ๐Ÿ’ป

    Chen Yang

    ๐Ÿ›

    Chotu

    ๐Ÿ›

    Chris Smith

    ๐Ÿ›

    Chris Toomey

    ๐Ÿ›

    Christian Hujer

    ๐Ÿ›

    Christian Pontesegger

    ๐Ÿ›

    ChristianWulf

    ๐Ÿ›

    Christofer Dutz

    ๐Ÿ’ป

    Christoffer Anselm

    ๐Ÿ›

    Christophe Vidal

    ๐Ÿ›

    Christopher Dancy

    ๐Ÿ›

    Clemens Prill

    ๐Ÿ›

    Clint Chester

    ๐Ÿ’ป ๐Ÿ›

    Clรฉment Fournier

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง

    Codacy Badger

    ๐Ÿ›

    Code-Nil

    ๐Ÿ›

    ColColonCleaner

    ๐Ÿ›

    Colin Ingarfield

    ๐Ÿ›

    Craig Andrews

    ๐Ÿ›

    Craig Muchinsky

    ๐Ÿ›

    Cyril

    ๐Ÿ’ป ๐Ÿ›

    Dale

    ๐Ÿ’ป

    Damien Jiang

    ๐Ÿ›

    Dan Berindei

    ๐Ÿ›

    Dan Rollo

    ๐Ÿ›

    Dan Ziemba

    ๐Ÿ›

    Daniel Gredler

    ๐Ÿ’ป ๐Ÿ›

    Daniel Jipa

    ๐Ÿ›

    Daniel Paul Searles

    ๐Ÿ’ป

    Daniel Reigada

    ๐Ÿ›

    Danilo Pianini

    ๐Ÿ›

    Darko

    ๐Ÿ›

    David

    ๐Ÿ›

    David Atkinson

    ๐Ÿ›

    David Burstrรถm

    ๐Ÿ’ป ๐Ÿ›

    David Goatรฉ

    ๐Ÿ›

    David Golpira

    ๐Ÿ›

    David Kovaล™รญk

    ๐Ÿ›

    David M. Karr (fullname at gmail.com)

    ๐Ÿ›

    David Renz

    ๐Ÿ’ป ๐Ÿ›

    David Renz

    ๐Ÿ›

    David Schach

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–

    Dawid Ciok

    ๐Ÿ› ๐Ÿ’ป

    Debamoy Datta

    ๐Ÿ’ป

    Deleted user

    ๐Ÿ›

    Dell Green

    ๐Ÿ›

    Dem Pilafian

    ๐Ÿ›

    Den

    ๐Ÿ›

    Denis Borovikov

    ๐Ÿ’ป ๐Ÿ›

    Dennie Reniers

    ๐Ÿ’ป ๐Ÿ›

    Dennis Kieselhorst

    ๐Ÿ›

    Derek P. Moore

    ๐Ÿ›

    Dichotomia

    ๐Ÿ›

    Dionisio Cortรฉs Fernรกndez

    ๐Ÿ’ป ๐Ÿ›

    Dmitri Bourlatchkov

    ๐Ÿ›

    Dmitriy Kuzmin

    ๐Ÿ›

    Dmytro Dashenkov

    ๐Ÿ›

    Dr. Christian Kohlschรผtter

    ๐Ÿ›

    Drew Hall

    ๐Ÿ›

    Dumitru Postoronca

    ๐Ÿ›

    Dylan Adams

    ๐Ÿ›

    Eden Hao

    ๐Ÿ›

    Edward Klimoshenko

    ๐Ÿ› ๐Ÿ’ป

    Egor Bredikhin

    ๐Ÿ›

    Elan P. Kugelmass

    ๐Ÿ›

    Elder S.

    ๐Ÿ›

    Eldrick Wega

    ๐Ÿ“–

    Emile

    ๐Ÿ›

    Eric

    ๐Ÿ›

    Eric Kintzer

    ๐Ÿ›

    Eric Perret

    ๐Ÿ›

    Eric Squires

    ๐Ÿ›

    Erich L Foster

    ๐Ÿ›

    Erik Bleske

    ๐Ÿ›

    Erik C. Thauvin

    ๐Ÿ“–

    Ernst Reissner

    ๐Ÿ›

    Ethan Sargent

    ๐Ÿ›

    Ewan Tempero

    ๐Ÿ›

    F.W. Dekker

    ๐Ÿ›

    FSchliephacke

    ๐Ÿ›

    Facundo

    ๐Ÿ›

    Federico Giust

    ๐Ÿ›

    Fedor Sherstobitov

    ๐Ÿ›

    Felix Lampe

    ๐Ÿ›

    Filip Golonka

    ๐Ÿ›

    Filipe Esperandio

    ๐Ÿ’ป ๐Ÿ›

    Filippo Nova

    ๐Ÿ›

    Francesco la Torre

    ๐Ÿ›

    Francisco Duarte

    ๐Ÿ›

    Frieder Bluemle

    ๐Ÿ›

    Frits Jalvingh

    ๐Ÿ’ป ๐Ÿ›

    G. Bazior

    ๐Ÿ›

    Gabe Henkes

    ๐Ÿ›

    Gary Gregory

    ๐Ÿ›

    Genoud Magloire

    ๐Ÿ›

    Geoffrey555

    ๐Ÿ›

    Georg Romstorfer

    ๐Ÿ›

    Gili Tzabari

    ๐Ÿ›

    Gio

    ๐Ÿ›

    Gol

    ๐Ÿ›

    Gold856

    ๐Ÿ› ๐Ÿ’ป

    Gonzalo Exequiel Ibars Ingman

    ๐Ÿ’ป ๐Ÿ›

    GooDer

    ๐Ÿ›

    Gregor Riegler

    ๐Ÿ›

    Grzegorz Olszewski

    ๐Ÿ›

    Gunther Schrijvers

    ๐Ÿ’ป ๐Ÿ›

    Gustavo Krieger

    ๐Ÿ›

    Guy Elsmore-Paddock

    ๐Ÿ›

    Gรถrkem Mรผlayim

    ๐Ÿ›

    Hanzel Godinez

    ๐Ÿ›

    Haoliang Chen

    ๐Ÿ›

    Harsh Kukreja

    ๐Ÿ›

    Hassan ALAMI

    ๐Ÿ›

    Heber

    ๐Ÿ›

    Henning Schmiedehausen

    ๐Ÿ’ป ๐Ÿ›

    Henning von Bargen

    ๐Ÿ’ป

    Hervรฉ Boutemy

    ๐Ÿ›

    Himanshu Pandey

    ๐Ÿ›

    Hokwang Lee

    ๐Ÿ›

    Hooperbloob

    ๐Ÿ’ป

    Hung PHAN

    ๐Ÿ›

    IDoCodingStuffs

    ๐Ÿ’ป ๐Ÿ›

    Iccen Gan

    ๐Ÿ›

    Ignacio Mariano Tirabasso

    ๐Ÿ›

    Igor Melnichenko

    ๐Ÿ›

    Igor Moreno

    ๐Ÿ›

    Intelesis-MS

    ๐Ÿ›

    Iroha_

    ๐Ÿ›

    Ishan Srivastava

    ๐Ÿ›

    Iskren Stanislavov

    ๐Ÿ›

    Ivan Vakhrushev

    ๐Ÿ›

    Ivano Guerini

    ๐Ÿ›

    Ivar Andreas Bonsaksen

    ๐Ÿ›

    Ivo ล mรญd

    ๐Ÿ›

    JJengility

    ๐Ÿ›

    Jake Hemmerle

    ๐Ÿ›

    Jakub Dupak

    ๐Ÿ’ป

    James Harrison

    ๐Ÿ› ๐Ÿ’ป

    Jamie Bisotti

    ๐Ÿ›

    Jan

    ๐Ÿ›

    Jan Aertgeerts

    ๐Ÿ’ป ๐Ÿ›

    Jan Brรผmmer

    ๐Ÿ›

    Jan Tล™รญska

    ๐Ÿ›

    Jan-Lukas Else

    ๐Ÿ›

    Jason Qiu

    ๐Ÿ’ป ๐Ÿ“–

    Jason Williams

    ๐Ÿ›

    Javier Spagnoletti

    ๐Ÿ›

    Jean-Paul Mayer

    ๐Ÿ›

    Jean-Simon Larochelle

    ๐Ÿ›

    Jeff Bartolotta

    ๐Ÿ’ป ๐Ÿ›

    Jeff Hube

    ๐Ÿ’ป ๐Ÿ›

    Jeff Jensen

    ๐Ÿ›

    Jeff May

    ๐Ÿ›

    Jens Gerdes

    ๐Ÿ›

    Jeroen Borgers

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข

    Jeroen Meijer

    ๐Ÿ›

    Jeroen van Wilgenburg

    ๐Ÿ“–

    Jerome Russ

    ๐Ÿ›

    JerritEic

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›

    Jiri Pejchal

    ๐Ÿ›

    Jithin Sunny

    ๐Ÿ›

    Jiล™รญ ล korpil

    ๐Ÿ›

    Joao Machado

    ๐Ÿ›

    Jochen Krauss

    ๐Ÿ›

    Johan Hammar

    ๐Ÿ›

    John Karp

    ๐Ÿ›

    John Zhang

    ๐Ÿ›

    John-Teng

    ๐Ÿ’ป ๐Ÿ›

    Jon Moroney

    ๐Ÿ’ป ๐Ÿ›

    Jonas Geiregat

    ๐Ÿ›

    Jonas KeรŸler

    ๐Ÿ›

    Jonathan Wiesel

    ๐Ÿ’ป ๐Ÿ›

    Jordan

    ๐Ÿ›

    Jordi Llach

    ๐Ÿ›

    Jorge Solรณrzano

    ๐Ÿ›

    JorneVL

    ๐Ÿ›

    Jose Palafox

    ๐Ÿ›

    Jose Stovall

    ๐Ÿ›

    Joseph

    ๐Ÿ’ป

    Joseph Heenan

    ๐Ÿ›

    Josh Feingold

    ๐Ÿ’ป ๐Ÿ›

    Josh Holthaus

    ๐Ÿ›

    Joshua S Arquilevich

    ๐Ÿ›

    Joรฃo Dinis Ferreira

    ๐Ÿ“–

    Joรฃo Ferreira

    ๐Ÿ’ป ๐Ÿ›

    Joรฃo Pedro Schmitt

    ๐Ÿ›

    Juan Martรญn Sotuyo Dodero

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง

    Juan Pablo Civile

    ๐Ÿ›

    Julian Voronetsky

    ๐Ÿ›

    Julien

    ๐Ÿ›

    Julius

    ๐Ÿ›

    JustPRV

    ๐Ÿ›

    Justin Stroud

    ๐Ÿ’ป

    Jรถrn Huxhorn

    ๐Ÿ›

    KThompso

    ๐Ÿ›

    Kai Amundsen

    ๐Ÿ›

    Karel Vervaeke

    ๐Ÿ›

    Karl-Andero Mere

    ๐Ÿ›

    Karl-Philipp Richter

    ๐Ÿ›

    Karsten Silz

    ๐Ÿ›

    Kazuma Watanabe

    ๐Ÿ›

    Kev

    ๐Ÿ›

    Keve Mรผller

    ๐Ÿ›

    Kevin Guerra

    ๐Ÿ’ป

    Kevin Jones

    ๐Ÿ› ๐Ÿ’ป

    Kevin Poorman

    ๐Ÿ›

    Kevin Wayne

    ๐Ÿ›

    Kieran Black

    ๐Ÿ›

    Kirill Zubov

    ๐Ÿ›

    Kirk Clemens

    ๐Ÿ’ป ๐Ÿ›

    Klaus Hartl

    ๐Ÿ›

    Koen Van Looveren

    ๐Ÿ›

    Kris Scheibe

    ๐Ÿ’ป ๐Ÿ›

    Krystian Dabrowski

    ๐Ÿ› ๐Ÿ’ป

    Kunal Thanki

    ๐Ÿ›

    LaLucid

    ๐Ÿ’ป

    Larry Diamond

    ๐Ÿ’ป ๐Ÿ›

    Lars Knickrehm

    ๐Ÿ›

    Laurent Bovet

    ๐Ÿ› ๐Ÿ’ป

    Leo Gutierrez

    ๐Ÿ›

    LiGaOg

    ๐Ÿ’ป

    Liam Sharp

    ๐Ÿ›

    Lintsi

    ๐Ÿ›

    Linus Fernandes

    ๐Ÿ›

    Lixon Lookose

    ๐Ÿ›

    Logesh

    ๐Ÿ›

    Lorenzo Gabriele

    ๐Ÿ›

    Loรฏc Ledoyen

    ๐Ÿ›

    Lucas

    ๐Ÿ›

    Lucas Silva

    ๐Ÿ›

    Lucas Soncini

    ๐Ÿ’ป ๐Ÿ›

    Luis Alcantar

    ๐Ÿ’ป

    Lukas Grรคf

    ๐Ÿ’ป

    Lukasz Slonina

    ๐Ÿ›

    Lukebray

    ๐Ÿ›

    Lynn

    ๐Ÿ’ป ๐Ÿ›

    Lyor Goldstein

    ๐Ÿ›

    MCMicS

    ๐Ÿ›

    Macarse

    ๐Ÿ›

    Machine account for PMD

    ๐Ÿ’ป

    Maciek Siemczyk

    ๐Ÿ›

    Maikel Steneker

    ๐Ÿ’ป ๐Ÿ›

    Maksim Moiseikin

    ๐Ÿ›

    Manfred Koch

    ๐Ÿ›

    Manuel Moya Ferrer

    ๐Ÿ’ป ๐Ÿ›

    Manuel Ryan

    ๐Ÿ›

    Marat Vyshegorodtsev

    ๐Ÿ›

    Marcel Hรคrle

    ๐Ÿ›

    Marcello Fialho

    ๐Ÿ›

    Marcin Dฤ…browski

    ๐Ÿ’ป

    Marcin Rataj

    ๐Ÿ›

    Marcono1234

    ๐Ÿ›

    Mark Adamcin

    ๐Ÿ›

    Mark Hall

    ๐Ÿ’ป ๐Ÿ›

    Mark Kolich

    ๐Ÿ›

    Mark Pritchard

    ๐Ÿ›

    Markus Rathgeb

    ๐Ÿ›

    Marquis Wang

    ๐Ÿ›

    MartGit

    ๐Ÿ›

    Martin Feldsztejn

    ๐Ÿ›

    Martin Lehmann

    ๐Ÿ›

    Martin Spamer

    ๐Ÿ›

    Martin Tarjรกnyi

    ๐Ÿ›

    MatFl

    ๐Ÿ›

    Mateusz Stefanski

    ๐Ÿ›

    Mathieu Gouin

    ๐Ÿ›

    MatiasComercio

    ๐Ÿ’ป ๐Ÿ›

    Matt Benson

    ๐Ÿ›

    Matt De Poorter

    ๐Ÿ›

    Matt Hargett

    ๐Ÿ’ป ๐Ÿ’ต

    Matt Harrah

    ๐Ÿ›

    Matt Nelson

    ๐Ÿ›

    Matthew Amos

    ๐Ÿ›

    Matthew Duggan

    ๐Ÿ›

    Matthew Hall

    ๐Ÿ›

    Matthew Rossner

    ๐Ÿ›

    Matรญas Fraga

    ๐Ÿ’ป ๐Ÿ›

    Maxime Robert

    ๐Ÿ’ป ๐Ÿ›

    MetaBF

    ๐Ÿ›

    Metin Dagcilar

    ๐Ÿ›

    Michael

    ๐Ÿ›

    Michael Bell

    ๐Ÿ›

    Michael Bernstein

    ๐Ÿ›

    Michael Clay

    ๐Ÿ›

    Michael Dombrowski

    ๐Ÿ›

    Michael Hausegger

    ๐Ÿ›

    Michael Hoefer

    ๐Ÿ›

    Michael Kolesnikov

    ๐Ÿ›

    Michael Mรถbius

    ๐Ÿ›

    Michael N. Lipp

    ๐Ÿ›

    Michael Pellegrini

    ๐Ÿ›

    Michal Kordas

    ๐Ÿ›

    Michaล‚ Borek

    ๐Ÿ›

    Michaล‚ Kuliล„ski

    ๐Ÿ›

    Miguel Nรบรฑez Dรญaz-Montes

    ๐Ÿ›

    Mihai Ionut

    ๐Ÿ›

    Mikhail Kuchma

    ๐Ÿ›

    Mirek Hankus

    ๐Ÿ›

    Mitch Spano

    ๐Ÿ’ป ๐Ÿ›

    Mladjan Gadzic

    ๐Ÿ›

    MrAngry52

    ๐Ÿ›

    Muminur Choudhury

    ๐Ÿ›

    Mykhailo Palahuta

    ๐Ÿ’ป ๐Ÿ›

    Nagendra Kumar Singh

    ๐Ÿ›

    Nahuel Barrios

    ๐Ÿ›

    Nakul Sharma

    ๐Ÿ›

    Nathan Braun

    ๐Ÿ›

    Nathan Reynolds

    ๐Ÿ›

    Nathan Reynolds

    ๐Ÿ›

    Nathanaรซl

    ๐Ÿ›

    Naveen

    ๐Ÿ’ป

    Nazdravi

    ๐Ÿ›

    Neha-Dhonde

    ๐Ÿ›

    Nicholas Doyle

    ๐Ÿ›

    Nick Butcher

    ๐Ÿ›

    Nico Gallinal

    ๐Ÿ›

    Nicola Dal Maso

    ๐Ÿ›

    Nicolas Filotto

    ๐Ÿ’ป

    Nicolas Vervelle

    ๐Ÿ›

    Nicolas Vuillamy

    ๐Ÿ“–

    Nikita Chursin

    ๐Ÿ›

    Niklas Baudy

    ๐Ÿ›

    Nikolas Havrikov

    ๐Ÿ›

    Nilesh Virkar

    ๐Ÿ›

    Nimit Patel

    ๐Ÿ›

    Niranjan Harpale

    ๐Ÿ›

    Nirvik Patel

    ๐Ÿ’ป

    Noah Sussman

    ๐Ÿ›

    Noah0120

    ๐Ÿ›

    Noam Tamim

    ๐Ÿ›

    Noel Grandin

    ๐Ÿ›

    Olaf Haalstra

    ๐Ÿ›

    Oleg Andreych

    ๐Ÿ’ป ๐Ÿ›

    Oleg Pavlenko

    ๐Ÿ›

    Oleksii Dykov

    ๐Ÿ’ป ๐Ÿ›

    Oliver Eikemeier

    ๐Ÿ›

    Oliver Siegmar

    ๐Ÿ’ต

    Olivier Parent

    ๐Ÿ’ป ๐Ÿ›

    Ollie Abbey

    ๐Ÿ’ป ๐Ÿ›

    Ondrej Kratochvil

    ๐Ÿ›

    OverDrone

    ๐Ÿ›

    Ozan Gulle

    ๐Ÿ’ป ๐Ÿ›

    PUNEET JAIN

    ๐Ÿ›

    Parbati Bose

    ๐Ÿ›

    Paul Berg

    ๐Ÿ›

    Paul Guyot

    ๐Ÿ’ป

    Pavel Bludov

    ๐Ÿ›

    Pavel Miฤka

    ๐Ÿ›

    Pedro Nuno Santos

    ๐Ÿ›

    Pedro Rijo

    ๐Ÿ›

    Pelisse Romain

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›

    Per Abich

    ๐Ÿ’ป

    Pete Davids

    ๐Ÿ›

    Peter Bruin

    ๐Ÿ›

    Peter Chittum

    ๐Ÿ’ป ๐Ÿ›

    Peter Cudmore

    ๐Ÿ›

    Peter Kasson

    ๐Ÿ›

    Peter Kofler

    ๐Ÿ›

    Peter Paul Bakker

    ๐Ÿ’ป

    Peter Rader

    ๐Ÿ›

    Pham Hai Trung

    ๐Ÿ›

    Philip Graf

    ๐Ÿ’ป ๐Ÿ›

    Philip Hachey

    ๐Ÿ›

    Philippe Ozil

    ๐Ÿ›

    Phinehas Artemix

    ๐Ÿ›

    Phokham Nonava

    ๐Ÿ›

    Pim van der Loos

    ๐Ÿ’ป โš ๏ธ

    Piotr Szymaล„ski

    ๐Ÿ›

    Piotrek ลปygieล‚o

    ๐Ÿ’ป ๐Ÿ› ๐Ÿ“–

    Pranay Jaiswal

    ๐Ÿ›

    Prasad Kamath

    ๐Ÿ›

    Prasanna

    ๐Ÿ›

    Presh-AR

    ๐Ÿ›

    Puneet1726

    ๐Ÿ›

    RBRi

    ๐Ÿ›

    Rafael Cortรชs

    ๐Ÿ›

    RaheemShaik999

    ๐Ÿ›

    RajeshR

    ๐Ÿ’ป ๐Ÿ›

    Ramachandra Mohan

    ๐Ÿ›

    Ramel0921

    ๐Ÿ›

    Raquel Pau

    ๐Ÿ›

    Ravikiran Janardhana

    ๐Ÿ›

    Reda Benhemmouche

    ๐Ÿ›

    Reinhard Schiedermeier

    ๐Ÿ›

    Renato Oliveira

    ๐Ÿ’ป ๐Ÿ›

    Rich DiCroce

    ๐Ÿ›

    Richard Corfield

    ๐Ÿ’ป

    Richard Corfield

    ๐Ÿ› ๐Ÿ’ป

    Riot R1cket

    ๐Ÿ›

    Rishabh Jain

    ๐Ÿ›

    RishabhDeep Singh

    ๐Ÿ›

    Rob Baillie

    ๐Ÿ›

    Robbie Martinus

    ๐Ÿ’ป ๐Ÿ›

    Robert Henry

    ๐Ÿ›

    Robert Mihaly

    ๐Ÿ›

    Robert Painsi

    ๐Ÿ›

    Robert Russell

    ๐Ÿ›

    Robert Sรถsemann

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ›

    Robert Whitebit

    ๐Ÿ›

    Robin Richtsfeld

    ๐Ÿ›

    Robin Stocker

    ๐Ÿ’ป ๐Ÿ›

    Robin Wils

    ๐Ÿ›

    RochusOest

    ๐Ÿ›

    Rodolfo Noviski

    ๐Ÿ›

    Rodrigo Casara

    ๐Ÿ›

    Rodrigo Fernandes

    ๐Ÿ›

    Roman Salvador

    ๐Ÿ’ป ๐Ÿ›

    Ronald Blaschke

    ๐Ÿ›

    Rรณbert Papp

    ๐Ÿ›

    Saikat Sengupta

    ๐Ÿ›

    Saksham Handu

    ๐Ÿ›

    Saladoc

    ๐Ÿ›

    Salesforce Bob Lightning

    ๐Ÿ›

    Sam Carlberg

    ๐Ÿ›

    Sascha Riemer

    ๐Ÿ›

    Sashko

    ๐Ÿ’ป

    Satoshi Kubo

    ๐Ÿ›

    Scott Kennedy

    ๐Ÿ›

    Scott Wells

    ๐Ÿ› ๐Ÿ’ป

    Scrates1

    ๐Ÿ› ๐Ÿ’ป

    Scrsloota

    ๐Ÿ’ป

    Sebastian Bรถgl

    ๐Ÿ›

    Sebastian Davids

    ๐Ÿ›

    Sebastian Schuberth

    ๐Ÿ›

    Sebastian Schwarz

    ๐Ÿ›

    Seren

    ๐Ÿ› ๐Ÿ’ป

    Sergey Gorbaty

    ๐Ÿ›

    Sergey Kozlov

    ๐Ÿ›

    Sergey Yanzin

    ๐Ÿ’ป ๐Ÿ›

    Seth Wilcox

    ๐Ÿ’ป

    Shai Bennathan

    ๐Ÿ› ๐Ÿ’ป

    Shubham

    ๐Ÿ’ป ๐Ÿ›

    Simon Abykov

    ๐Ÿ’ป ๐Ÿ›

    Simon Xiao

    ๐Ÿ›

    Srinivasan Venkatachalam

    ๐Ÿ›

    Stanislav Gromov

    ๐Ÿ›

    Stanislav Myachenkov

    ๐Ÿ’ป

    Stefan Birkner

    ๐Ÿ›

    Stefan Bohn

    ๐Ÿ›

    Stefan Endrullis

    ๐Ÿ›

    Stefan Klรถss-Schuster

    ๐Ÿ›

    Stefan Wolf

    ๐Ÿ›

    Stephan H. Wissel

    ๐Ÿ›

    Stephen

    ๐Ÿ›

    Stephen Carter

    ๐Ÿ›

    Stephen Friedrich

    ๐Ÿ›

    Steve Babula

    ๐Ÿ’ป

    Steven Stearns

    ๐Ÿ› ๐Ÿ’ป

    Stexxe

    ๐Ÿ›

    Stian Lรฅgstad

    ๐Ÿ›

    StuartClayton5

    ๐Ÿ›

    Supun Arunoda

    ๐Ÿ›

    Suren Abrahamyan

    ๐Ÿ›

    Suvashri

    ๐Ÿ“–

    SwatiBGupta1110

    ๐Ÿ›

    SyedThoufich

    ๐Ÿ›

    Szymon Sasin

    ๐Ÿ›

    T-chuangxin

    ๐Ÿ›

    TERAI Atsuhiro

    ๐Ÿ›

    TIOBE Software

    ๐Ÿ’ป ๐Ÿ›

    Tarush Singh

    ๐Ÿ’ป

    Taylor Smock

    ๐Ÿ›

    Techeira Damiรกn

    ๐Ÿ’ป ๐Ÿ›

    Ted Husted

    ๐Ÿ›

    TehBakker

    ๐Ÿ›

    The Gitter Badger

    ๐Ÿ›

    Theodoor

    ๐Ÿ›

    Thiago Henrique Hรผpner

    ๐Ÿ›

    Thibault Meyer

    ๐Ÿ›

    Thomas Gรผttler

    ๐Ÿ›

    Thomas Jones-Low

    ๐Ÿ›

    Thomas Smith

    ๐Ÿ’ป ๐Ÿ›

    ThrawnCA

    ๐Ÿ›

    Thu Vo

    ๐Ÿ›

    Thunderforge

    ๐Ÿ’ป ๐Ÿ›

    Tim van der Lippe

    ๐Ÿ›

    Tobias Weimer

    ๐Ÿ’ป ๐Ÿ›

    Tom Copeland

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–

    Tom Daly

    ๐Ÿ›

    Tomas

    ๐Ÿ›

    Tomer Figenblat

    ๐Ÿ›

    Tomi De Lucca

    ๐Ÿ’ป ๐Ÿ›

    Tony

    ๐Ÿ“–

    Torsten Kleiber

    ๐Ÿ›

    TrackerSB

    ๐Ÿ›

    Tyson Stewart

    ๐Ÿ›

    Ullrich Hafner

    ๐Ÿ›

    Utku Cuhadaroglu

    ๐Ÿ’ป ๐Ÿ›

    Valentin Brandl

    ๐Ÿ›

    Valeria

    ๐Ÿ›

    Valery Yatsynovich

    ๐Ÿ“–

    Vasily Anisimov

    ๐Ÿ›

    Vedant Chokshi

    ๐Ÿ›

    Vibhor Goyal

    ๐Ÿ›

    Vickenty Fesunov

    ๐Ÿ›

    Victor Noรซl

    ๐Ÿ›

    Vincent Galloy

    ๐Ÿ’ป

    Vincent HUYNH

    ๐Ÿ›

    Vincent Maurin

    ๐Ÿ›

    Vincent Privat

    ๐Ÿ›

    Vishhwas

    ๐Ÿ›

    Vishv_Android

    ๐Ÿ›

    Vitaly

    ๐Ÿ›

    Vitaly Polonetsky

    ๐Ÿ›

    Vojtech Polivka

    ๐Ÿ›

    Vsevolod Zholobov

    ๐Ÿ›

    Vyom Yadav

    ๐Ÿ’ป

    Wang Shidong

    ๐Ÿ›

    Waqas Ahmed

    ๐Ÿ›

    Wayne J. Earl

    ๐Ÿ›

    Wchenghui

    ๐Ÿ›

    Wener

    ๐Ÿ’ป

    Will Winder

    ๐Ÿ›

    William Brockhus

    ๐Ÿ’ป ๐Ÿ›

    Wilson Kurniawan

    ๐Ÿ›

    Wim Deblauwe

    ๐Ÿ›

    Woongsik Choi

    ๐Ÿ›

    XenoAmess

    ๐Ÿ’ป ๐Ÿ›

    Yang

    ๐Ÿ’ป

    YaroslavTER

    ๐Ÿ›

    Yasar Shaikh

    ๐Ÿ’ป

    Young Chan

    ๐Ÿ’ป ๐Ÿ›

    YuJin Kim

    ๐Ÿ›

    Yuri Dolzhenko

    ๐Ÿ›

    Yurii Dubinka

    ๐Ÿ›

    Zoltan Farkas

    ๐Ÿ›

    Zustin

    ๐Ÿ›

    aaronhurst-google

    ๐Ÿ› ๐Ÿ’ป

    alexmodis

    ๐Ÿ›

    andreoss

    ๐Ÿ›

    andrey81inmd

    ๐Ÿ’ป ๐Ÿ›

    anicoara

    ๐Ÿ›

    arunprasathav

    ๐Ÿ›

    asiercamara

    ๐Ÿ›

    astillich-igniti

    ๐Ÿ’ป

    avesolovksyy

    ๐Ÿ›

    avishvat

    ๐Ÿ›

    avivmu

    ๐Ÿ›

    axelbarfod1

    ๐Ÿ›

    b-3-n

    ๐Ÿ›

    balbhadra9

    ๐Ÿ›

    base23de

    ๐Ÿ›

    bergander

    ๐Ÿ› ๐Ÿ’ป

    berkam

    ๐Ÿ’ป ๐Ÿ›

    breizh31

    ๐Ÿ›

    caesarkim

    ๐Ÿ›

    carolyujing

    ๐Ÿ›

    cbfiddle

    ๐Ÿ›

    cesares-basilico

    ๐Ÿ›

    chrite

    ๐Ÿ›

    ciufudean

    ๐Ÿ“–

    cobratbq

    ๐Ÿ›

    coladict

    ๐Ÿ›

    cosmoJFH

    ๐Ÿ›

    cristalp

    ๐Ÿ›

    crunsk

    ๐Ÿ›

    cwholmes

    ๐Ÿ›

    cyberjj999

    ๐Ÿ›

    cyw3

    ๐Ÿ› ๐Ÿ“–

    d1ss0nanz

    ๐Ÿ›

    dague1

    ๐Ÿ“–

    dalizi007

    ๐Ÿ’ป

    danbrycefairsailcom

    ๐Ÿ›

    dariansanity

    ๐Ÿ›

    darrenmiliband

    ๐Ÿ›

    davidburstrom

    ๐Ÿ›

    dbirkman-paloalto

    ๐Ÿ›

    deepak-patra

    ๐Ÿ›

    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ›

    dinesh150

    ๐Ÿ›

    diziaq

    ๐Ÿ›

    dreaminpast123

    ๐Ÿ›

    duanyanan

    ๐Ÿ›

    dutt-sanjay

    ๐Ÿ›

    duursma

    ๐Ÿ’ป

    dylanleung

    ๐Ÿ›

    dzeigler

    ๐Ÿ›

    eant60

    ๐Ÿ›

    ekkirala

    ๐Ÿ›

    emersonmoura

    ๐Ÿ›

    emouty

    ๐Ÿ’ป ๐Ÿ›

    eugenepugach

    ๐Ÿ›

    fairy

    ๐Ÿ›

    filiprafalowicz

    ๐Ÿ’ป

    flxbl-io

    ๐Ÿ’ต

    foxmason

    ๐Ÿ›

    frankegabor

    ๐Ÿ›

    frankl

    ๐Ÿ›

    freafrea

    ๐Ÿ›

    fsapatin

    ๐Ÿ›

    gearsethenry

    ๐Ÿ›

    gracia19

    ๐Ÿ›

    gudzpoz

    ๐Ÿ›

    guo fei

    ๐Ÿ›

    gurmsc5

    ๐Ÿ›

    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ›

    haigsn

    ๐Ÿ›

    hemanshu070

    ๐Ÿ›

    henrik242

    ๐Ÿ›

    hongpuwu

    ๐Ÿ›

    hvbtup

    ๐Ÿ’ป ๐Ÿ›

    igniti GmbH

    ๐Ÿ›

    ilovezfs

    ๐Ÿ›

    imax-erik

    ๐Ÿ›

    itaigilo

    ๐Ÿ›

    jakivey32

    ๐Ÿ›

    jbennett2091

    ๐Ÿ›

    jcamerin

    ๐Ÿ›

    jkeener1

    ๐Ÿ›

    jmetertea

    ๐Ÿ›

    johnra2

    ๐Ÿ’ป

    johnzhao9

    ๐Ÿ›

    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ›

    kabroxiko

    ๐Ÿ’ป ๐Ÿ›

    karthikaiyasamy

    ๐Ÿ“–

    karwer

    ๐Ÿ›

    kaulonline

    ๐Ÿ›

    kdaemonv

    ๐Ÿ›

    kdebski85

    ๐Ÿ› ๐Ÿ’ป

    kenji21

    ๐Ÿ’ป ๐Ÿ›

    kfranic

    ๐Ÿ›

    khalidkh

    ๐Ÿ›

    koalalam

    ๐Ÿ›

    krzyk

    ๐Ÿ›

    lasselindqvist

    ๐Ÿ›

    lgemeinhardt

    ๐Ÿ›

    lihuaib

    ๐Ÿ›

    liqingjun123

    ๐Ÿ›

    lonelyma1021

    ๐Ÿ›

    lpeddy

    ๐Ÿ›

    lujiefsi

    ๐Ÿ’ป

    lukelukes

    ๐Ÿ’ป

    lyriccoder

    ๐Ÿ›

    marcelmore

    ๐Ÿ›

    matchbox

    ๐Ÿ›

    matthiaskraaz

    ๐Ÿ›

    meandonlyme

    ๐Ÿ›

    mikesive

    ๐Ÿ›

    milossesic

    ๐Ÿ›

    mluckam

    ๐Ÿ’ป ๐Ÿ›

    mohan-chinnappan-n

    ๐Ÿ’ป

    mriddell95

    ๐Ÿ›

    mrlzh

    ๐Ÿ›

    msloan

    ๐Ÿ›

    mucharlaravalika

    ๐Ÿ›

    mvenneman

    ๐Ÿ›

    nareshl119

    ๐Ÿ›

    nicolas-harraudeau-sonarsource

    ๐Ÿ›

    noerremark

    ๐Ÿ›

    novsirion

    ๐Ÿ›

    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป

    oggboy

    ๐Ÿ›

    oinume

    ๐Ÿ›

    orimarko

    ๐Ÿ’ป ๐Ÿ›

    pablogomez2197

    ๐Ÿ›

    pacvz

    ๐Ÿ’ป

    pallavi agarwal

    ๐Ÿ›

    parksungrin

    ๐Ÿ›

    patpatpat123

    ๐Ÿ›

    patriksevallius

    ๐Ÿ›

    pbrajesh1

    ๐Ÿ›

    phoenix384

    ๐Ÿ›

    piotrszymanski-sc

    ๐Ÿ’ป

    plan3d

    ๐Ÿ›

    poojasix

    ๐Ÿ›

    prabhushrikant

    ๐Ÿ›

    pujitha8783

    ๐Ÿ›

    r-r-a-j

    ๐Ÿ›

    raghujayjunk

    ๐Ÿ›

    rajeshveera

    ๐Ÿ›

    rajeswarreddy88

    ๐Ÿ›

    recdevs

    ๐Ÿ›

    reudismam

    ๐Ÿ’ป ๐Ÿ›

    rijkt

    ๐Ÿ›

    rillig-tk

    ๐Ÿ›

    rmohan20

    ๐Ÿ’ป ๐Ÿ›

    rnveach

    ๐Ÿ›

    rxmicro

    ๐Ÿ›

    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ›

    sabi0

    ๐Ÿ›

    scais

    ๐Ÿ›

    schosin

    ๐Ÿ›

    screamingfrog

    ๐Ÿ’ต

    sebbASF

    ๐Ÿ›

    sergeygorbaty

    ๐Ÿ’ป

    shilko2013

    ๐Ÿ›

    shiomiyan

    ๐Ÿ“–

    simeonKondr

    ๐Ÿ›

    snajberk

    ๐Ÿ›

    sniperrifle2004

    ๐Ÿ›

    snuyanzin

    ๐Ÿ› ๐Ÿ’ป

    soloturn

    ๐Ÿ›

    soyodream

    ๐Ÿ›

    sratz

    ๐Ÿ›

    stonio

    ๐Ÿ›

    sturton

    ๐Ÿ’ป ๐Ÿ›

    sudharmohan

    ๐Ÿ›

    suruchidawar

    ๐Ÿ›

    svenfinitiv

    ๐Ÿ›

    szymanp23

    ๐Ÿ› ๐Ÿ’ป

    tashiscool

    ๐Ÿ›

    test-git-hook

    ๐Ÿ›

    testation21

    ๐Ÿ’ป ๐Ÿ›

    thanosa

    ๐Ÿ›

    tiandiyixian

    ๐Ÿ›

    tobwoerk

    ๐Ÿ›

    tprouvot

    ๐Ÿ› ๐Ÿ’ป

    trentchilders

    ๐Ÿ›

    triandicAnt

    ๐Ÿ›

    trishul14

    ๐Ÿ›

    tsui

    ๐Ÿ›

    wangzitom12306

    ๐Ÿ›

    winhkey

    ๐Ÿ›

    witherspore

    ๐Ÿ›

    wjljack

    ๐Ÿ›

    wuchiuwong

    ๐Ÿ›

    xingsong

    ๐Ÿ›

    xioayuge

    ๐Ÿ›

    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ›

    xuanuy

    ๐Ÿ›

    xyf0921

    ๐Ÿ›

    yalechen-cyw3

    ๐Ÿ›

    yasuharu-sato

    ๐Ÿ›

    zenglian

    ๐Ÿ›

    zgrzyt93

    ๐Ÿ’ป ๐Ÿ›

    zh3ng

    ๐Ÿ›

    zt_soft

    ๐Ÿ›

    ztt79

    ๐Ÿ›

    zzzzfeng

    ๐Ÿ›

    รrpรกd Magosรกnyi

    ๐Ÿ›

    ไปป่ดตๆฐ

    ๐Ÿ›

    ่Œ…ๅปถๅฎ‰

    ๐Ÿ’ป
    0xflotus
    0xflotus

    ๐Ÿ’ป ๐Ÿ›
    1henni
    1henni

    ๐Ÿ›
    219sansim
    219sansim

    ๐Ÿ’ป
    ALiNew
    ALiNew

    ๐Ÿ›
    ASBrouwers
    ASBrouwers

    ๐Ÿ’ป
    Abhijit Sarkar
    Abhijit Sarkar

    ๐Ÿ›
    Abhishek Kumar
    Abhishek Kumar

    ๐Ÿ›
    Adam
    Adam

    ๐Ÿ›
    Adam Carroll
    Adam Carroll

    ๐Ÿ›
    Adam Obuchowicz
    Adam Obuchowicz

    ๐Ÿ›
    Adrian Price
    Adrian Price

    ๐Ÿ›
    Adrien Lecharpentier
    Adrien Lecharpentier

    ๐Ÿ›
    Aidan Harding
    Aidan Harding

    ๐Ÿ›
    Akshat Bahety
    Akshat Bahety

    ๐Ÿ’ป ๐Ÿ›
    Akshay Thapa
    Akshay Thapa

    ๐Ÿ›
    Alan Buttars
    Alan Buttars

    ๐Ÿ›
    Alan Hohn
    Alan Hohn

    ๐Ÿ›
    Alberto Fernรกndez
    Alberto Fernรกndez

    ๐Ÿ’ป ๐Ÿ›
    Alex
    Alex

    ๐Ÿ’ป
    Alex
    Alex

    ๐Ÿ›
    Alex B
    Alex B

    ๐Ÿ›
    Alex Rentz
    Alex Rentz

    ๐Ÿ›
    Alex Saveau
    Alex Saveau

    ๐Ÿ›
    Alex Shesterov
    Alex Shesterov

    ๐Ÿ’ป ๐Ÿ›
    Alexey Markevich
    Alexey Markevich

    ๐Ÿ›
    Alexey Naumov
    Alexey Naumov

    ๐Ÿ›
    Alexey Yudichev
    Alexey Yudichev

    ๐Ÿ›
    Alix
    Alix

    ๐Ÿ›
    Alix
    Alix

    ๐Ÿ›
    Amish Shah
    Amish Shah

    ๐Ÿ›
    Amit Prasad
    Amit Prasad

    ๐Ÿ›
    Amitosh Swain Mahapatra
    Amitosh Swain Mahapatra

    ๐Ÿ›
    Anand Subramanian
    Anand Subramanian

    ๐Ÿ’ป ๐Ÿ›
    Anastasiia Koba
    Anastasiia Koba

    ๐Ÿ’ป
    Anatoly Trosinenko
    Anatoly Trosinenko

    ๐Ÿ’ป ๐Ÿ›
    Andi Pabst
    Andi Pabst

    ๐Ÿ’ป ๐Ÿ›
    Andrea
    Andrea

    ๐Ÿ›
    Andrea Aime
    Andrea Aime

    ๐Ÿ›
    Andreas Dangel
    Andreas Dangel

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง
    Andreas Deininger
    Andreas Deininger

    ๐Ÿ“–
    Andreas Markussen
    Andreas Markussen

    ๐Ÿ›
    Andreas Schmid
    Andreas Schmid

    ๐Ÿ›
    Andreas Turban
    Andreas Turban

    ๐Ÿ›
    Andrei Paikin
    Andrei Paikin

    ๐Ÿ›
    Andrew
    Andrew

    ๐Ÿ›
    Andrew Green
    Andrew Green

    ๐Ÿ›
    Andrey Bozhko
    Andrey Bozhko

    ๐Ÿ“–
    Andrey Fomin
    Andrey Fomin

    ๐Ÿ›
    Andrey Hitrin
    Andrey Hitrin

    ๐Ÿ›
    Andrey Mochalov
    Andrey Mochalov

    ๐Ÿ’ป ๐Ÿ›
    Andro72
    Andro72

    ๐Ÿ›
    Andrwyw
    Andrwyw

    ๐Ÿ›
    Andrรฉs Catalรกn
    Andrรฉs Catalรกn

    ๐Ÿ›
    Andy Goossens
    Andy Goossens

    ๐Ÿ›
    Andy Pattenden
    Andy Pattenden

    ๐Ÿ›
    Andy Ray
    Andy Ray

    ๐Ÿ›
    Andy Robinson
    Andy Robinson

    ๐Ÿ›
    Andy-2639
    Andy-2639

    ๐Ÿ›
    Ankush Somani
    Ankush Somani

    ๐Ÿ›
    Anmol Kumar
    Anmol Kumar

    ๐Ÿ›
    Anthony Whitford
    Anthony Whitford

    ๐Ÿ›
    AnthonyKot
    AnthonyKot

    ๐Ÿ›
    Anurag Agarwal
    Anurag Agarwal

    ๐Ÿ›
    Aravind Hegde
    Aravind Hegde

    ๐Ÿ›
    Arda Aslan
    Arda Aslan

    ๐Ÿ›
    Ari Fogel
    Ari Fogel

    ๐Ÿ›
    Arnaud Jeansen
    Arnaud Jeansen

    ๐Ÿ’ป ๐Ÿ›
    Arpit Koolwal
    Arpit Koolwal

    ๐Ÿ›
    Artem
    Artem

    ๐Ÿ’ป ๐Ÿ›
    Artem
    Artem

    ๐Ÿ›
    Artem Sheremet
    Artem Sheremet

    ๐Ÿ›
    Artur
    Artur

    ๐Ÿ›
    Artur Bosch
    Artur Bosch

    ๐Ÿ›
    Artur Dryomov
    Artur Dryomov

    ๐Ÿ›
    Artur Ossowski
    Artur Ossowski

    ๐Ÿ›
    Aryant Tripathi
    Aryant Tripathi

    ๐Ÿ’ป
    AshTheMash
    AshTheMash

    ๐Ÿ›
    Ashish Rana
    Ashish Rana

    ๐Ÿ›
    Atul Kaushal
    Atul Kaushal

    ๐Ÿ›
    August Boland
    August Boland

    ๐Ÿ›
    Aurel Hudec
    Aurel Hudec

    ๐Ÿ›
    Austin
    Austin

    ๐Ÿ›
    Austin Shalit
    Austin Shalit

    ๐Ÿ›
    Austin Tice
    Austin Tice

    ๐Ÿ›
    Ayoub Kaanich
    Ayoub Kaanich

    ๐Ÿ›
    BBG
    BBG

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
    Bailey Tjiong
    Bailey Tjiong

    ๐Ÿ’ป
    Barthรฉlemy L.
    Barthรฉlemy L.

    ๐Ÿ›
    Basavaraj K N
    Basavaraj K N

    ๐Ÿ›
    Basil Peace
    Basil Peace

    ๐Ÿ›
    Belle
    Belle

    ๐Ÿ›
    Ben Lerner
    Ben Lerner

    ๐Ÿ›
    Ben Manes
    Ben Manes

    ๐Ÿ›
    Ben McCann
    Ben McCann

    ๐Ÿ›
    Bendegรบz Nagy
    Bendegรบz Nagy

    ๐Ÿ›
    Bennet S Yee
    Bennet S Yee

    ๐Ÿ›
    Benoit Lacelle
    Benoit Lacelle

    ๐Ÿ›
    Bernardo Macรชdo
    Bernardo Macรชdo

    ๐Ÿ›
    Bernd Farka
    Bernd Farka

    ๐Ÿ›
    Betina Cynthia Mamani
    Betina Cynthia Mamani

    ๐Ÿ›
    Bhanu Prakash Pamidi
    Bhanu Prakash Pamidi

    ๐Ÿ’ป ๐Ÿ›
    Bhargav Thanki
    Bhargav Thanki

    ๐Ÿ›
    Binu R J
    Binu R J

    ๐Ÿ›
    Bjรถrn Kautler
    Bjรถrn Kautler

    ๐Ÿ’ป ๐Ÿ›
    Blightbuster
    Blightbuster

    ๐Ÿ›
    Bo Zhang
    Bo Zhang

    ๐Ÿ›
    Bob "Wombat" Hogg
    Bob "Wombat" Hogg

    ๐Ÿ›
    Bobby Wertman
    Bobby Wertman

    ๐Ÿ›
    Bolarinwa Saheed Olayemi
    Bolarinwa Saheed Olayemi

    ๐Ÿ’ป ๐Ÿ›
    Boris Petrov
    Boris Petrov

    ๐Ÿ›
    Brad Kent
    Brad Kent

    ๐Ÿ›
    Brandon Mikeska
    Brandon Mikeska

    ๐Ÿ›
    Brian Batronis
    Brian Batronis

    ๐Ÿ›
    Brian Johnson
    Brian Johnson

    ๐Ÿ›
    Brice Dutheil
    Brice Dutheil

    ๐Ÿ’ป ๐Ÿ›
    Bruno Ferreira
    Bruno Ferreira

    ๐Ÿ›
    Bruno Harbulot
    Bruno Harbulot

    ๐Ÿ›
    Bruno Ritz
    Bruno Ritz

    ๐Ÿ›
    BurovnikovEvgeniy
    BurovnikovEvgeniy

    ๐Ÿ›
    Cameron Donaldson
    Cameron Donaldson

    ๐Ÿ›
    Carlos Macasaet
    Carlos Macasaet

    ๐Ÿ›
    Carsten Otto
    Carsten Otto

    ๐Ÿ›
    Charlie Housh
    Charlie Housh

    ๐Ÿ›
    Charlie Jonas
    Charlie Jonas

    ๐Ÿ›
    Chas Honton
    Chas Honton

    ๐Ÿ› ๐Ÿ’ป
    Chen Yang
    Chen Yang

    ๐Ÿ›
    Chotu
    Chotu

    ๐Ÿ›
    Chris Smith
    Chris Smith

    ๐Ÿ›
    Chris Toomey
    Chris Toomey

    ๐Ÿ›
    Christian Hujer
    Christian Hujer

    ๐Ÿ›
    Christian Pontesegger
    Christian Pontesegger

    ๐Ÿ›
    ChristianWulf
    ChristianWulf

    ๐Ÿ›
    Christofer Dutz
    Christofer Dutz

    ๐Ÿ’ป
    Christoffer Anselm
    Christoffer Anselm

    ๐Ÿ›
    Christophe Vidal
    Christophe Vidal

    ๐Ÿ›
    Christopher Dancy
    Christopher Dancy

    ๐Ÿ›
    Clemens Prill
    Clemens Prill

    ๐Ÿ›
    Clint Chester
    Clint Chester

    ๐Ÿ’ป ๐Ÿ›
    Clรฉment Fournier
    Clรฉment Fournier

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง
    Codacy Badger
    Codacy Badger

    ๐Ÿ›
    Code-Nil
    Code-Nil

    ๐Ÿ›
    ColColonCleaner
    ColColonCleaner

    ๐Ÿ›
    Colin Ingarfield
    Colin Ingarfield

    ๐Ÿ›
    Craig Andrews
    Craig Andrews

    ๐Ÿ›
    Craig Muchinsky
    Craig Muchinsky

    ๐Ÿ›
    Cyril
    Cyril

    ๐Ÿ’ป ๐Ÿ›
    Dale
    Dale

    ๐Ÿ’ป
    Damien Jiang
    Damien Jiang

    ๐Ÿ›
    Dan Berindei
    Dan Berindei

    ๐Ÿ›
    Dan Rollo
    Dan Rollo

    ๐Ÿ›
    Dan Ziemba
    Dan Ziemba

    ๐Ÿ›
    Daniel Gredler
    Daniel Gredler

    ๐Ÿ’ป ๐Ÿ›
    Daniel Jipa
    Daniel Jipa

    ๐Ÿ›
    Daniel Paul Searles
    Daniel Paul Searles

    ๐Ÿ’ป
    Daniel Reigada
    Daniel Reigada

    ๐Ÿ›
    Danilo Pianini
    Danilo Pianini

    ๐Ÿ›
    Darko
    Darko

    ๐Ÿ›
    David
    David

    ๐Ÿ›
    David Atkinson
    David Atkinson

    ๐Ÿ›
    David Burstrรถm
    David Burstrรถm

    ๐Ÿ’ป ๐Ÿ›
    David Goatรฉ
    David Goatรฉ

    ๐Ÿ›
    David Golpira
    David Golpira

    ๐Ÿ›
    David Kovaล™รญk
    David Kovaล™รญk

    ๐Ÿ›
    David M. Karr (fullname at gmail.com)
    David M. Karr (fullname at gmail.com)

    ๐Ÿ›
    David Renz
    David Renz

    ๐Ÿ’ป ๐Ÿ›
    David Renz
    David Renz

    ๐Ÿ›
    David Schach
    David Schach

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–
    Dawid Ciok
    Dawid Ciok

    ๐Ÿ› ๐Ÿ’ป
    Debamoy Datta
    Debamoy Datta

    ๐Ÿ’ป
    Deleted user
    Deleted user

    ๐Ÿ›
    Dell Green
    Dell Green

    ๐Ÿ›
    Dem Pilafian
    Dem Pilafian

    ๐Ÿ›
    Den
    Den

    ๐Ÿ›
    Denis Borovikov
    Denis Borovikov

    ๐Ÿ’ป ๐Ÿ›
    Dennie Reniers
    Dennie Reniers

    ๐Ÿ’ป ๐Ÿ›
    Dennis Kieselhorst
    Dennis Kieselhorst

    ๐Ÿ›
    Derek P. Moore
    Derek P. Moore

    ๐Ÿ›
    Dichotomia
    Dichotomia

    ๐Ÿ›
    Dionisio Cortรฉs Fernรกndez
    Dionisio Cortรฉs Fernรกndez

    ๐Ÿ’ป ๐Ÿ›
    Dmitri Bourlatchkov
    Dmitri Bourlatchkov

    ๐Ÿ›
    Dmitriy Kuzmin
    Dmitriy Kuzmin

    ๐Ÿ›
    Dmytro Dashenkov
    Dmytro Dashenkov

    ๐Ÿ›
    Dr. Christian Kohlschรผtter
    Dr. Christian Kohlschรผtter

    ๐Ÿ›
    Drew Hall
    Drew Hall

    ๐Ÿ›
    Dumitru Postoronca
    Dumitru Postoronca

    ๐Ÿ›
    Dylan Adams
    Dylan Adams

    ๐Ÿ›
    Eden Hao
    Eden Hao

    ๐Ÿ›
    Edward Klimoshenko
    Edward Klimoshenko

    ๐Ÿ› ๐Ÿ’ป
    Egor Bredikhin
    Egor Bredikhin

    ๐Ÿ›
    Elan P. Kugelmass
    Elan P. Kugelmass

    ๐Ÿ›
    Elder S.
    Elder S.

    ๐Ÿ›
    Eldrick Wega
    Eldrick Wega

    ๐Ÿ“–
    Emile
    Emile

    ๐Ÿ›
    Eric
    Eric

    ๐Ÿ›
    Eric Kintzer
    Eric Kintzer

    ๐Ÿ›
    Eric Perret
    Eric Perret

    ๐Ÿ›
    Eric Squires
    Eric Squires

    ๐Ÿ›
    Erich L Foster
    Erich L Foster

    ๐Ÿ›
    Erik Bleske
    Erik Bleske

    ๐Ÿ›
    Erik C. Thauvin
    Erik C. Thauvin

    ๐Ÿ“–
    Ernst Reissner
    Ernst Reissner

    ๐Ÿ›
    Ethan Sargent
    Ethan Sargent

    ๐Ÿ›
    Ewan Tempero
    Ewan Tempero

    ๐Ÿ›
    F.W. Dekker
    F.W. Dekker

    ๐Ÿ›
    FSchliephacke
    FSchliephacke

    ๐Ÿ›
    Facundo
    Facundo

    ๐Ÿ›
    Federico Giust
    Federico Giust

    ๐Ÿ›
    Fedor Sherstobitov
    Fedor Sherstobitov

    ๐Ÿ›
    Felix Lampe
    Felix Lampe

    ๐Ÿ›
    Filip Golonka
    Filip Golonka

    ๐Ÿ›
    Filipe Esperandio
    Filipe Esperandio

    ๐Ÿ’ป ๐Ÿ›
    Filippo Nova
    Filippo Nova

    ๐Ÿ›
    Francesco la Torre
    Francesco la Torre

    ๐Ÿ›
    Francisco Duarte
    Francisco Duarte

    ๐Ÿ›
    Frieder Bluemle
    Frieder Bluemle

    ๐Ÿ›
    Frits Jalvingh
    Frits Jalvingh

    ๐Ÿ’ป ๐Ÿ›
    G. Bazior
    G. Bazior

    ๐Ÿ›
    Gabe Henkes
    Gabe Henkes

    ๐Ÿ›
    Gary Gregory
    Gary Gregory

    ๐Ÿ›
    Genoud Magloire
    Genoud Magloire

    ๐Ÿ›
    Geoffrey555
    Geoffrey555

    ๐Ÿ›
    Georg Romstorfer
    Georg Romstorfer

    ๐Ÿ›
    Gili Tzabari
    Gili Tzabari

    ๐Ÿ›
    Gio
    Gio

    ๐Ÿ›
    Gol
    Gol

    ๐Ÿ›
    Gold856
    Gold856

    ๐Ÿ› ๐Ÿ’ป
    Gonzalo Exequiel Ibars Ingman
    Gonzalo Exequiel Ibars Ingman

    ๐Ÿ’ป ๐Ÿ›
    GooDer
    GooDer

    ๐Ÿ›
    Gregor Riegler
    Gregor Riegler

    ๐Ÿ›
    Grzegorz Olszewski
    Grzegorz Olszewski

    ๐Ÿ›
    Gunther Schrijvers
    Gunther Schrijvers

    ๐Ÿ’ป ๐Ÿ›
    Gustavo Krieger
    Gustavo Krieger

    ๐Ÿ›
    Guy Elsmore-Paddock
    Guy Elsmore-Paddock

    ๐Ÿ›
    Gรถrkem Mรผlayim
    Gรถrkem Mรผlayim

    ๐Ÿ›
    Hanzel Godinez
    Hanzel Godinez

    ๐Ÿ›
    Haoliang Chen
    Haoliang Chen

    ๐Ÿ›
    Harsh Kukreja
    Harsh Kukreja

    ๐Ÿ›
    Hassan ALAMI
    Hassan ALAMI

    ๐Ÿ›
    Heber
    Heber

    ๐Ÿ›
    Henning Schmiedehausen
    Henning Schmiedehausen

    ๐Ÿ’ป ๐Ÿ›
    Henning von Bargen
    Henning von Bargen

    ๐Ÿ’ป
    Hervรฉ Boutemy
    Hervรฉ Boutemy

    ๐Ÿ›
    Himanshu Pandey
    Himanshu Pandey

    ๐Ÿ›
    Hokwang Lee
    Hokwang Lee

    ๐Ÿ›
    Hooperbloob
    Hooperbloob

    ๐Ÿ’ป
    Hung PHAN
    Hung PHAN

    ๐Ÿ›
    IDoCodingStuffs
    IDoCodingStuffs

    ๐Ÿ’ป ๐Ÿ›
    Iccen Gan
    Iccen Gan

    ๐Ÿ›
    Ignacio Mariano Tirabasso
    Ignacio Mariano Tirabasso

    ๐Ÿ›
    Igor Melnichenko
    Igor Melnichenko

    ๐Ÿ›
    Igor Moreno
    Igor Moreno

    ๐Ÿ›
    Intelesis-MS
    Intelesis-MS

    ๐Ÿ›
    Iroha_
    Iroha_

    ๐Ÿ›
    Ishan Srivastava
    Ishan Srivastava

    ๐Ÿ›
    Iskren Stanislavov
    Iskren Stanislavov

    ๐Ÿ›
    Ivan Vakhrushev
    Ivan Vakhrushev

    ๐Ÿ›
    Ivano Guerini
    Ivano Guerini

    ๐Ÿ›
    Ivar Andreas Bonsaksen
    Ivar Andreas Bonsaksen

    ๐Ÿ›
    Ivo ล mรญd
    Ivo ล mรญd

    ๐Ÿ›
    JJengility
    JJengility

    ๐Ÿ›
    Jake Hemmerle
    Jake Hemmerle

    ๐Ÿ›
    Jakub Dupak
    Jakub Dupak

    ๐Ÿ’ป
    James Harrison
    James Harrison

    ๐Ÿ› ๐Ÿ’ป
    Jamie Bisotti
    Jamie Bisotti

    ๐Ÿ›
    Jan
    Jan

    ๐Ÿ›
    Jan Aertgeerts
    Jan Aertgeerts

    ๐Ÿ’ป ๐Ÿ›
    Jan Brรผmmer
    Jan Brรผmmer

    ๐Ÿ›
    Jan Tล™รญska
    Jan Tล™รญska

    ๐Ÿ›
    Jan-Lukas Else
    Jan-Lukas Else

    ๐Ÿ›
    Jason Qiu
    Jason Qiu

    ๐Ÿ’ป ๐Ÿ“–
    Jason Williams
    Jason Williams

    ๐Ÿ›
    Javier Spagnoletti
    Javier Spagnoletti

    ๐Ÿ›
    Jean-Paul Mayer
    Jean-Paul Mayer

    ๐Ÿ›
    Jean-Simon Larochelle
    Jean-Simon Larochelle

    ๐Ÿ›
    Jeff Bartolotta
    Jeff Bartolotta

    ๐Ÿ’ป ๐Ÿ›
    Jeff Hube
    Jeff Hube

    ๐Ÿ’ป ๐Ÿ›
    Jeff Jensen
    Jeff Jensen

    ๐Ÿ›
    Jeff May
    Jeff May

    ๐Ÿ›
    Jens Gerdes
    Jens Gerdes

    ๐Ÿ›
    Jeroen Borgers
    Jeroen Borgers

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข
    Jeroen Meijer
    Jeroen Meijer

    ๐Ÿ›
    Jeroen van Wilgenburg
    Jeroen van Wilgenburg

    ๐Ÿ“–
    Jerome Russ
    Jerome Russ

    ๐Ÿ›
    JerritEic
    JerritEic

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
    Jiri Pejchal
    Jiri Pejchal

    ๐Ÿ›
    Jithin Sunny
    Jithin Sunny

    ๐Ÿ›
    Jiล™รญ ล korpil
    Jiล™รญ ล korpil

    ๐Ÿ›
    Joao Machado
    Joao Machado

    ๐Ÿ›
    Jochen Krauss
    Jochen Krauss

    ๐Ÿ›
    Johan Hammar
    Johan Hammar

    ๐Ÿ›
    John Karp
    John Karp

    ๐Ÿ›
    John Zhang
    John Zhang

    ๐Ÿ›
    John-Teng
    John-Teng

    ๐Ÿ’ป ๐Ÿ›
    Jon Moroney
    Jon Moroney

    ๐Ÿ’ป ๐Ÿ›
    Jonas Geiregat
    Jonas Geiregat

    ๐Ÿ›
    Jonas KeรŸler
    Jonas KeรŸler

    ๐Ÿ›
    Jonathan Wiesel
    Jonathan Wiesel

    ๐Ÿ’ป ๐Ÿ›
    Jordan
    Jordan

    ๐Ÿ›
    Jordi Llach
    Jordi Llach

    ๐Ÿ›
    Jorge Solรณrzano
    Jorge Solรณrzano

    ๐Ÿ›
    JorneVL
    JorneVL

    ๐Ÿ›
    Jose Palafox
    Jose Palafox

    ๐Ÿ›
    Jose Stovall
    Jose Stovall

    ๐Ÿ›
    Joseph
    Joseph

    ๐Ÿ’ป
    Joseph Heenan
    Joseph Heenan

    ๐Ÿ›
    Josh Feingold
    Josh Feingold

    ๐Ÿ’ป ๐Ÿ›
    Josh Holthaus
    Josh Holthaus

    ๐Ÿ›
    Joshua S Arquilevich
    Joshua S Arquilevich

    ๐Ÿ›
    Joรฃo Dinis Ferreira
    Joรฃo Dinis Ferreira

    ๐Ÿ“–
    Joรฃo Ferreira
    Joรฃo Ferreira

    ๐Ÿ’ป ๐Ÿ›
    Joรฃo Pedro Schmitt
    Joรฃo Pedro Schmitt

    ๐Ÿ›
    Juan Martรญn Sotuyo Dodero
    Juan Martรญn Sotuyo Dodero

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง
    Juan Pablo Civile
    Juan Pablo Civile

    ๐Ÿ›
    Julian Voronetsky
    Julian Voronetsky

    ๐Ÿ›
    Julien
    Julien

    ๐Ÿ›
    Julius
    Julius

    ๐Ÿ›
    JustPRV
    JustPRV

    ๐Ÿ›
    Justin Stroud
    Justin Stroud

    ๐Ÿ’ป
    Jรถrn Huxhorn
    Jรถrn Huxhorn

    ๐Ÿ›
    KThompso
    KThompso

    ๐Ÿ›
    Kai Amundsen
    Kai Amundsen

    ๐Ÿ›
    Karel Vervaeke
    Karel Vervaeke

    ๐Ÿ›
    Karl-Andero Mere
    Karl-Andero Mere

    ๐Ÿ›
    Karl-Philipp Richter
    Karl-Philipp Richter

    ๐Ÿ›
    Karsten Silz
    Karsten Silz

    ๐Ÿ›
    Kazuma Watanabe
    Kazuma Watanabe

    ๐Ÿ›
    Kev
    Kev

    ๐Ÿ›
    Keve Mรผller
    Keve Mรผller

    ๐Ÿ›
    Kevin Guerra
    Kevin Guerra

    ๐Ÿ’ป
    Kevin Jones
    Kevin Jones

    ๐Ÿ› ๐Ÿ’ป
    Kevin Poorman
    Kevin Poorman

    ๐Ÿ›
    Kevin Wayne
    Kevin Wayne

    ๐Ÿ›
    Kieran Black
    Kieran Black

    ๐Ÿ›
    Kirill Zubov
    Kirill Zubov

    ๐Ÿ›
    Kirk Clemens
    Kirk Clemens

    ๐Ÿ’ป ๐Ÿ›
    Klaus Hartl
    Klaus Hartl

    ๐Ÿ›
    Koen Van Looveren
    Koen Van Looveren

    ๐Ÿ›
    Kris Scheibe
    Kris Scheibe

    ๐Ÿ’ป ๐Ÿ›
    Krystian Dabrowski
    Krystian Dabrowski

    ๐Ÿ› ๐Ÿ’ป
    Kunal Thanki
    Kunal Thanki

    ๐Ÿ›
    LaLucid
    LaLucid

    ๐Ÿ’ป
    Larry Diamond
    Larry Diamond

    ๐Ÿ’ป ๐Ÿ›
    Lars Knickrehm
    Lars Knickrehm

    ๐Ÿ›
    Laurent Bovet
    Laurent Bovet

    ๐Ÿ› ๐Ÿ’ป
    Leo Gutierrez
    Leo Gutierrez

    ๐Ÿ›
    LiGaOg
    LiGaOg

    ๐Ÿ’ป
    Liam Sharp
    Liam Sharp

    ๐Ÿ›
    Lintsi
    Lintsi

    ๐Ÿ›
    Linus Fernandes
    Linus Fernandes

    ๐Ÿ›
    Lixon Lookose
    Lixon Lookose

    ๐Ÿ›
    Logesh
    Logesh

    ๐Ÿ›
    Lorenzo Gabriele
    Lorenzo Gabriele

    ๐Ÿ›
    Loรฏc Ledoyen
    Loรฏc Ledoyen

    ๐Ÿ›
    Lucas
    Lucas

    ๐Ÿ›
    Lucas Silva
    Lucas Silva

    ๐Ÿ›
    Lucas Soncini
    Lucas Soncini

    ๐Ÿ’ป ๐Ÿ›
    Luis Alcantar
    Luis Alcantar

    ๐Ÿ’ป
    Lukas Grรคf
    Lukas Grรคf

    ๐Ÿ’ป
    Lukasz Slonina
    Lukasz Slonina

    ๐Ÿ›
    Lukebray
    Lukebray

    ๐Ÿ›
    Lynn
    Lynn

    ๐Ÿ’ป ๐Ÿ›
    Lyor Goldstein
    Lyor Goldstein

    ๐Ÿ›
    MCMicS
    MCMicS

    ๐Ÿ›
    Macarse
    Macarse

    ๐Ÿ›
    Machine account for PMD
    Machine account for PMD

    ๐Ÿ’ป
    Maciek Siemczyk
    Maciek Siemczyk

    ๐Ÿ›
    Maikel Steneker
    Maikel Steneker

    ๐Ÿ’ป ๐Ÿ›
    Maksim Moiseikin
    Maksim Moiseikin

    ๐Ÿ›
    Manfred Koch
    Manfred Koch

    ๐Ÿ›
    Manuel Moya Ferrer
    Manuel Moya Ferrer

    ๐Ÿ’ป ๐Ÿ›
    Manuel Ryan
    Manuel Ryan

    ๐Ÿ›
    Marat Vyshegorodtsev
    Marat Vyshegorodtsev

    ๐Ÿ›
    Marcel Hรคrle
    Marcel Hรคrle

    ๐Ÿ›
    Marcello Fialho
    Marcello Fialho

    ๐Ÿ›
    Marcin Dฤ…browski
    Marcin Dฤ…browski

    ๐Ÿ’ป
    Marcin Rataj
    Marcin Rataj

    ๐Ÿ›
    Marcono1234
    Marcono1234

    ๐Ÿ›
    Mark Adamcin
    Mark Adamcin

    ๐Ÿ›
    Mark Hall
    Mark Hall

    ๐Ÿ’ป ๐Ÿ›
    Mark Kolich
    Mark Kolich

    ๐Ÿ›
    Mark Pritchard
    Mark Pritchard

    ๐Ÿ›
    Markus Rathgeb
    Markus Rathgeb

    ๐Ÿ›
    Marquis Wang
    Marquis Wang

    ๐Ÿ›
    MartGit
    MartGit

    ๐Ÿ›
    Martin Feldsztejn
    Martin Feldsztejn

    ๐Ÿ›
    Martin Lehmann
    Martin Lehmann

    ๐Ÿ›
    Martin Spamer
    Martin Spamer

    ๐Ÿ›
    Martin Tarjรกnyi
    Martin Tarjรกnyi

    ๐Ÿ›
    MatFl
    MatFl

    ๐Ÿ›
    Mateusz Stefanski
    Mateusz Stefanski

    ๐Ÿ›
    Mathieu Gouin
    Mathieu Gouin

    ๐Ÿ›
    MatiasComercio
    MatiasComercio

    ๐Ÿ’ป ๐Ÿ›
    Matt Benson
    Matt Benson

    ๐Ÿ›
    Matt De Poorter
    Matt De Poorter

    ๐Ÿ›
    Matt Hargett
    Matt Hargett

    ๐Ÿ’ป ๐Ÿ’ต
    Matt Harrah
    Matt Harrah

    ๐Ÿ›
    Matt Nelson
    Matt Nelson

    ๐Ÿ›
    Matthew Amos
    Matthew Amos

    ๐Ÿ›
    Matthew Duggan
    Matthew Duggan

    ๐Ÿ›
    Matthew Hall
    Matthew Hall

    ๐Ÿ›
    Matthew Rossner
    Matthew Rossner

    ๐Ÿ›
    Matรญas Fraga
    Matรญas Fraga

    ๐Ÿ’ป ๐Ÿ›
    Maxime Robert
    Maxime Robert

    ๐Ÿ’ป ๐Ÿ›
    MetaBF
    MetaBF

    ๐Ÿ›
    Metin Dagcilar
    Metin Dagcilar

    ๐Ÿ›
    Michael
    Michael

    ๐Ÿ›
    Michael Bell
    Michael Bell

    ๐Ÿ›
    Michael Bernstein
    Michael Bernstein

    ๐Ÿ›
    Michael Clay
    Michael Clay

    ๐Ÿ›
    Michael Dombrowski
    Michael Dombrowski

    ๐Ÿ›
    Michael Hausegger
    Michael Hausegger

    ๐Ÿ›
    Michael Hoefer
    Michael Hoefer

    ๐Ÿ›
    Michael Kolesnikov
    Michael Kolesnikov

    ๐Ÿ›
    Michael Mรถbius
    Michael Mรถbius

    ๐Ÿ›
    Michael N. Lipp
    Michael N. Lipp

    ๐Ÿ›
    Michael Pellegrini
    Michael Pellegrini

    ๐Ÿ›
    Michal Kordas
    Michal Kordas

    ๐Ÿ›
    Michaล‚ Borek
    Michaล‚ Borek

    ๐Ÿ›
    Michaล‚ Kuliล„ski
    Michaล‚ Kuliล„ski

    ๐Ÿ›
    Miguel Nรบรฑez Dรญaz-Montes
    Miguel Nรบรฑez Dรญaz-Montes

    ๐Ÿ›
    Mihai Ionut
    Mihai Ionut

    ๐Ÿ›
    Mikhail Kuchma
    Mikhail Kuchma

    ๐Ÿ›
    Mirek Hankus
    Mirek Hankus

    ๐Ÿ›
    Mitch Spano
    Mitch Spano

    ๐Ÿ›
    Mladjan Gadzic
    Mladjan Gadzic

    ๐Ÿ›
    MrAngry52
    MrAngry52

    ๐Ÿ›
    Muminur Choudhury
    Muminur Choudhury

    ๐Ÿ›
    Mykhailo Palahuta
    Mykhailo Palahuta

    ๐Ÿ’ป ๐Ÿ›
    Nagendra Kumar Singh
    Nagendra Kumar Singh

    ๐Ÿ›
    Nahuel Barrios
    Nahuel Barrios

    ๐Ÿ›
    Nakul Sharma
    Nakul Sharma

    ๐Ÿ›
    Nathan Braun
    Nathan Braun

    ๐Ÿ›
    Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ›
    Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ›
    Nathanaรซl
    Nathanaรซl

    ๐Ÿ›
    Naveen
    Naveen

    ๐Ÿ’ป
    Nazdravi
    Nazdravi

    ๐Ÿ›
    Neha-Dhonde
    Neha-Dhonde

    ๐Ÿ›
    Nicholas Doyle
    Nicholas Doyle

    ๐Ÿ›
    Nick Butcher
    Nick Butcher

    ๐Ÿ›
    Nico Gallinal
    Nico Gallinal

    ๐Ÿ›
    Nicola Dal Maso
    Nicola Dal Maso

    ๐Ÿ›
    Nicolas Filotto
    Nicolas Filotto

    ๐Ÿ’ป
    Nicolas Vervelle
    Nicolas Vervelle

    ๐Ÿ›
    Nicolas Vuillamy
    Nicolas Vuillamy

    ๐Ÿ“–
    Nikita Chursin
    Nikita Chursin

    ๐Ÿ›
    Niklas Baudy
    Niklas Baudy

    ๐Ÿ›
    Nikolas Havrikov
    Nikolas Havrikov

    ๐Ÿ›
    Nilesh Virkar
    Nilesh Virkar

    ๐Ÿ›
    Nimit Patel
    Nimit Patel

    ๐Ÿ›
    Niranjan Harpale
    Niranjan Harpale

    ๐Ÿ›
    Nirvik Patel
    Nirvik Patel

    ๐Ÿ’ป
    Noah Sussman
    Noah Sussman

    ๐Ÿ›
    Noah0120
    Noah0120

    ๐Ÿ›
    Noam Tamim
    Noam Tamim

    ๐Ÿ›
    Noel Grandin
    Noel Grandin

    ๐Ÿ›
    Olaf Haalstra
    Olaf Haalstra

    ๐Ÿ›
    Oleg Andreych
    Oleg Andreych

    ๐Ÿ’ป ๐Ÿ›
    Oleg Pavlenko
    Oleg Pavlenko

    ๐Ÿ›
    Oleksii Dykov
    Oleksii Dykov

    ๐Ÿ’ป ๐Ÿ›
    Oliver Eikemeier
    Oliver Eikemeier

    ๐Ÿ›
    Oliver Siegmar
    Oliver Siegmar

    ๐Ÿ’ต
    Olivier Parent
    Olivier Parent

    ๐Ÿ’ป ๐Ÿ›
    Ollie Abbey
    Ollie Abbey

    ๐Ÿ’ป ๐Ÿ›
    Ondrej Kratochvil
    Ondrej Kratochvil

    ๐Ÿ›
    OverDrone
    OverDrone

    ๐Ÿ›
    Ozan Gulle
    Ozan Gulle

    ๐Ÿ’ป ๐Ÿ›
    PUNEET JAIN
    PUNEET JAIN

    ๐Ÿ›
    Parbati Bose
    Parbati Bose

    ๐Ÿ›
    Paul Berg
    Paul Berg

    ๐Ÿ›
    Paul Guyot
    Paul Guyot

    ๐Ÿ’ป
    Pavel Bludov
    Pavel Bludov

    ๐Ÿ›
    Pavel Miฤka
    Pavel Miฤka

    ๐Ÿ›
    Pedro Nuno Santos
    Pedro Nuno Santos

    ๐Ÿ›
    Pedro Rijo
    Pedro Rijo

    ๐Ÿ›
    Pelisse Romain
    Pelisse Romain

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
    Per Abich
    Per Abich

    ๐Ÿ’ป
    Pete Davids
    Pete Davids

    ๐Ÿ›
    Peter Bruin
    Peter Bruin

    ๐Ÿ›
    Peter Chittum
    Peter Chittum

    ๐Ÿ’ป ๐Ÿ›
    Peter Cudmore
    Peter Cudmore

    ๐Ÿ›
    Peter Kasson
    Peter Kasson

    ๐Ÿ›
    Peter Kofler
    Peter Kofler

    ๐Ÿ›
    Peter Paul Bakker
    Peter Paul Bakker

    ๐Ÿ’ป
    Peter Rader
    Peter Rader

    ๐Ÿ›
    Pham Hai Trung
    Pham Hai Trung

    ๐Ÿ›
    Philip Graf
    Philip Graf

    ๐Ÿ’ป ๐Ÿ›
    Philip Hachey
    Philip Hachey

    ๐Ÿ›
    Philippe Ozil
    Philippe Ozil

    ๐Ÿ›
    Phinehas Artemix
    Phinehas Artemix

    ๐Ÿ›
    Phokham Nonava
    Phokham Nonava

    ๐Ÿ›
    Pim van der Loos
    Pim van der Loos

    ๐Ÿ’ป โš ๏ธ
    Piotr Szymaล„ski
    Piotr Szymaล„ski

    ๐Ÿ›
    Piotrek ลปygieล‚o
    Piotrek ลปygieล‚o

    ๐Ÿ’ป ๐Ÿ› ๐Ÿ“–
    Pranay Jaiswal
    Pranay Jaiswal

    ๐Ÿ›
    Prasad Kamath
    Prasad Kamath

    ๐Ÿ›
    Prasanna
    Prasanna

    ๐Ÿ›
    Presh-AR
    Presh-AR

    ๐Ÿ›
    Puneet1726
    Puneet1726

    ๐Ÿ›
    RBRi
    RBRi

    ๐Ÿ›
    Rafael Cortรชs
    Rafael Cortรชs

    ๐Ÿ›
    RaheemShaik999
    RaheemShaik999

    ๐Ÿ›
    RajeshR
    RajeshR

    ๐Ÿ’ป ๐Ÿ›
    Ramachandra Mohan
    Ramachandra Mohan

    ๐Ÿ›
    Ramel0921
    Ramel0921

    ๐Ÿ›
    Raquel Pau
    Raquel Pau

    ๐Ÿ›
    Ravikiran Janardhana
    Ravikiran Janardhana

    ๐Ÿ›
    Reda Benhemmouche
    Reda Benhemmouche

    ๐Ÿ›
    Reinhard Schiedermeier
    Reinhard Schiedermeier

    ๐Ÿ›
    Renato Oliveira
    Renato Oliveira

    ๐Ÿ’ป ๐Ÿ›
    Rich DiCroce
    Rich DiCroce

    ๐Ÿ›
    Richard Corfield
    Richard Corfield

    ๐Ÿ’ป
    Richard Corfield
    Richard Corfield

    ๐Ÿ› ๐Ÿ’ป
    Riot R1cket
    Riot R1cket

    ๐Ÿ›
    Rishabh Jain
    Rishabh Jain

    ๐Ÿ›
    RishabhDeep Singh
    RishabhDeep Singh

    ๐Ÿ›
    Rob Baillie
    Rob Baillie

    ๐Ÿ›
    Robbie Martinus
    Robbie Martinus

    ๐Ÿ’ป ๐Ÿ›
    Robert Henry
    Robert Henry

    ๐Ÿ›
    Robert Mihaly
    Robert Mihaly

    ๐Ÿ›
    Robert Painsi
    Robert Painsi

    ๐Ÿ›
    Robert Russell
    Robert Russell

    ๐Ÿ›
    Robert Sรถsemann
    Robert Sรถsemann

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ›
    Robert Whitebit
    Robert Whitebit

    ๐Ÿ›
    Robin Richtsfeld
    Robin Richtsfeld

    ๐Ÿ›
    Robin Stocker
    Robin Stocker

    ๐Ÿ’ป ๐Ÿ›
    Robin Wils
    Robin Wils

    ๐Ÿ›
    RochusOest
    RochusOest

    ๐Ÿ›
    Rodolfo Noviski
    Rodolfo Noviski

    ๐Ÿ›
    Rodrigo Casara
    Rodrigo Casara

    ๐Ÿ›
    Rodrigo Fernandes
    Rodrigo Fernandes

    ๐Ÿ›
    Roman Salvador
    Roman Salvador

    ๐Ÿ’ป ๐Ÿ›
    Ronald Blaschke
    Ronald Blaschke

    ๐Ÿ›
    Rรณbert Papp
    Rรณbert Papp

    ๐Ÿ›
    Saikat Sengupta
    Saikat Sengupta

    ๐Ÿ›
    Saksham Handu
    Saksham Handu

    ๐Ÿ›
    Saladoc
    Saladoc

    ๐Ÿ›
    Salesforce Bob Lightning
    Salesforce Bob Lightning

    ๐Ÿ›
    Sam Carlberg
    Sam Carlberg

    ๐Ÿ›
    Sascha Riemer
    Sascha Riemer

    ๐Ÿ›
    Sashko
    Sashko

    ๐Ÿ’ป
    Satoshi Kubo
    Satoshi Kubo

    ๐Ÿ›
    Scott Kennedy
    Scott Kennedy

    ๐Ÿ›
    Scott Wells
    Scott Wells

    ๐Ÿ› ๐Ÿ’ป
    Scrates1
    Scrates1

    ๐Ÿ› ๐Ÿ’ป
    Scrsloota
    Scrsloota

    ๐Ÿ’ป
    Sebastian Bรถgl
    Sebastian Bรถgl

    ๐Ÿ›
    Sebastian Davids
    Sebastian Davids

    ๐Ÿ›
    Sebastian Schuberth
    Sebastian Schuberth

    ๐Ÿ›
    Sebastian Schwarz
    Sebastian Schwarz

    ๐Ÿ›
    Seren
    Seren

    ๐Ÿ› ๐Ÿ’ป
    Sergey Gorbaty
    Sergey Gorbaty

    ๐Ÿ›
    Sergey Kozlov
    Sergey Kozlov

    ๐Ÿ›
    Sergey Yanzin
    Sergey Yanzin

    ๐Ÿ’ป ๐Ÿ›
    Seth Wilcox
    Seth Wilcox

    ๐Ÿ’ป
    Shai Bennathan
    Shai Bennathan

    ๐Ÿ› ๐Ÿ’ป
    Shubham
    Shubham

    ๐Ÿ’ป ๐Ÿ›
    Simon Abykov
    Simon Abykov

    ๐Ÿ’ป ๐Ÿ›
    Simon Xiao
    Simon Xiao

    ๐Ÿ›
    Srinivasan Venkatachalam
    Srinivasan Venkatachalam

    ๐Ÿ›
    Stanislav Gromov
    Stanislav Gromov

    ๐Ÿ›
    Stanislav Myachenkov
    Stanislav Myachenkov

    ๐Ÿ’ป
    Stefan Birkner
    Stefan Birkner

    ๐Ÿ›
    Stefan Bohn
    Stefan Bohn

    ๐Ÿ›
    Stefan Endrullis
    Stefan Endrullis

    ๐Ÿ›
    Stefan Klรถss-Schuster
    Stefan Klรถss-Schuster

    ๐Ÿ›
    Stefan Wolf
    Stefan Wolf

    ๐Ÿ›
    Stephan H. Wissel
    Stephan H. Wissel

    ๐Ÿ›
    Stephen
    Stephen

    ๐Ÿ›
    Stephen Carter
    Stephen Carter

    ๐Ÿ›
    Stephen Friedrich
    Stephen Friedrich

    ๐Ÿ›
    Steve Babula
    Steve Babula

    ๐Ÿ’ป
    Steven Stearns
    Steven Stearns

    ๐Ÿ› ๐Ÿ’ป
    Stexxe
    Stexxe

    ๐Ÿ›
    Stian Lรฅgstad
    Stian Lรฅgstad

    ๐Ÿ›
    StuartClayton5
    StuartClayton5

    ๐Ÿ›
    Supun Arunoda
    Supun Arunoda

    ๐Ÿ›
    Suren Abrahamyan
    Suren Abrahamyan

    ๐Ÿ›
    Suvashri
    Suvashri

    ๐Ÿ“–
    SwatiBGupta1110
    SwatiBGupta1110

    ๐Ÿ›
    SyedThoufich
    SyedThoufich

    ๐Ÿ›
    Szymon Sasin
    Szymon Sasin

    ๐Ÿ›
    T-chuangxin
    T-chuangxin

    ๐Ÿ›
    TERAI Atsuhiro
    TERAI Atsuhiro

    ๐Ÿ›
    TIOBE Software
    TIOBE Software

    ๐Ÿ’ป ๐Ÿ›
    Tarush Singh
    Tarush Singh

    ๐Ÿ’ป
    Taylor Smock
    Taylor Smock

    ๐Ÿ›
    Techeira Damiรกn
    Techeira Damiรกn

    ๐Ÿ’ป ๐Ÿ›
    Ted Husted
    Ted Husted

    ๐Ÿ›
    TehBakker
    TehBakker

    ๐Ÿ›
    The Gitter Badger
    The Gitter Badger

    ๐Ÿ›
    Theodoor
    Theodoor

    ๐Ÿ›
    Thiago Henrique Hรผpner
    Thiago Henrique Hรผpner

    ๐Ÿ›
    Thibault Meyer
    Thibault Meyer

    ๐Ÿ›
    Thomas Gรผttler
    Thomas Gรผttler

    ๐Ÿ›
    Thomas Jones-Low
    Thomas Jones-Low

    ๐Ÿ›
    Thomas Smith
    Thomas Smith

    ๐Ÿ’ป ๐Ÿ›
    ThrawnCA
    ThrawnCA

    ๐Ÿ›
    Thu Vo
    Thu Vo

    ๐Ÿ›
    Thunderforge
    Thunderforge

    ๐Ÿ’ป ๐Ÿ›
    Tim van der Lippe
    Tim van der Lippe

    ๐Ÿ›
    Tobias Weimer
    Tobias Weimer

    ๐Ÿ’ป ๐Ÿ›
    Tom Copeland
    Tom Copeland

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–
    Tom Daly
    Tom Daly

    ๐Ÿ›
    Tomas
    Tomas

    ๐Ÿ›
    Tomer Figenblat
    Tomer Figenblat

    ๐Ÿ›
    Tomi De Lucca
    Tomi De Lucca

    ๐Ÿ’ป ๐Ÿ›
    Tony
    Tony

    ๐Ÿ“–
    Torsten Kleiber
    Torsten Kleiber

    ๐Ÿ›
    TrackerSB
    TrackerSB

    ๐Ÿ›
    Tyson Stewart
    Tyson Stewart

    ๐Ÿ›
    Ullrich Hafner
    Ullrich Hafner

    ๐Ÿ›
    Utku Cuhadaroglu
    Utku Cuhadaroglu

    ๐Ÿ’ป ๐Ÿ›
    Valentin Brandl
    Valentin Brandl

    ๐Ÿ›
    Valeria
    Valeria

    ๐Ÿ›
    Valery Yatsynovich
    Valery Yatsynovich

    ๐Ÿ“–
    Vasily Anisimov
    Vasily Anisimov

    ๐Ÿ›
    Vedant Chokshi
    Vedant Chokshi

    ๐Ÿ›
    Vibhor Goyal
    Vibhor Goyal

    ๐Ÿ›
    Vickenty Fesunov
    Vickenty Fesunov

    ๐Ÿ›
    Victor Noรซl
    Victor Noรซl

    ๐Ÿ›
    Vincent Galloy
    Vincent Galloy

    ๐Ÿ’ป
    Vincent HUYNH
    Vincent HUYNH

    ๐Ÿ›
    Vincent Maurin
    Vincent Maurin

    ๐Ÿ›
    Vincent Privat
    Vincent Privat

    ๐Ÿ›
    Vishhwas
    Vishhwas

    ๐Ÿ›
    Vishv_Android
    Vishv_Android

    ๐Ÿ›
    Vitalii Yevtushenko
    Vitalii Yevtushenko

    ๐Ÿ›
    Vitaly
    Vitaly

    ๐Ÿ›
    Vitaly Polonetsky
    Vitaly Polonetsky

    ๐Ÿ›
    Vojtech Polivka
    Vojtech Polivka

    ๐Ÿ›
    Vsevolod Zholobov
    Vsevolod Zholobov

    ๐Ÿ›
    Vyom Yadav
    Vyom Yadav

    ๐Ÿ’ป
    Wang Shidong
    Wang Shidong

    ๐Ÿ›
    Waqas Ahmed
    Waqas Ahmed

    ๐Ÿ›
    Wayne J. Earl
    Wayne J. Earl

    ๐Ÿ›
    Wchenghui
    Wchenghui

    ๐Ÿ›
    Wener
    Wener

    ๐Ÿ’ป
    Will Winder
    Will Winder

    ๐Ÿ›
    Willem A. Hajenius
    Willem A. Hajenius

    ๐Ÿ’ป
    William Brockhus
    William Brockhus

    ๐Ÿ’ป ๐Ÿ›
    Wilson Kurniawan
    Wilson Kurniawan

    ๐Ÿ›
    Wim Deblauwe
    Wim Deblauwe

    ๐Ÿ›
    Woongsik Choi
    Woongsik Choi

    ๐Ÿ›
    XenoAmess
    XenoAmess

    ๐Ÿ’ป ๐Ÿ›
    Yang
    Yang

    ๐Ÿ’ป
    YaroslavTER
    YaroslavTER

    ๐Ÿ›
    Yasar Shaikh
    Yasar Shaikh

    ๐Ÿ’ป
    Young Chan
    Young Chan

    ๐Ÿ’ป ๐Ÿ›
    YuJin Kim
    YuJin Kim

    ๐Ÿ›
    Yuri Dolzhenko
    Yuri Dolzhenko

    ๐Ÿ›
    Yurii Dubinka
    Yurii Dubinka

    ๐Ÿ›
    Zoltan Farkas
    Zoltan Farkas

    ๐Ÿ›
    Zustin
    Zustin

    ๐Ÿ›
    aaronhurst-google
    aaronhurst-google

    ๐Ÿ› ๐Ÿ’ป
    alexmodis
    alexmodis

    ๐Ÿ›
    andreoss
    andreoss

    ๐Ÿ›
    andrey81inmd
    andrey81inmd

    ๐Ÿ’ป ๐Ÿ›
    anicoara
    anicoara

    ๐Ÿ›
    arunprasathav
    arunprasathav

    ๐Ÿ›
    asiercamara
    asiercamara

    ๐Ÿ›
    astillich-igniti
    astillich-igniti

    ๐Ÿ’ป
    avesolovksyy
    avesolovksyy

    ๐Ÿ›
    avishvat
    avishvat

    ๐Ÿ›
    avivmu
    avivmu

    ๐Ÿ›
    axelbarfod1
    axelbarfod1

    ๐Ÿ›
    b-3-n
    b-3-n

    ๐Ÿ›
    balbhadra9
    balbhadra9

    ๐Ÿ›
    base23de
    base23de

    ๐Ÿ›
    bergander
    bergander

    ๐Ÿ› ๐Ÿ’ป
    berkam
    berkam

    ๐Ÿ’ป ๐Ÿ›
    breizh31
    breizh31

    ๐Ÿ›
    caesarkim
    caesarkim

    ๐Ÿ›
    carolyujing
    carolyujing

    ๐Ÿ›
    cbfiddle
    cbfiddle

    ๐Ÿ›
    cesares-basilico
    cesares-basilico

    ๐Ÿ›
    chrite
    chrite

    ๐Ÿ›
    ciufudean
    ciufudean

    ๐Ÿ“–
    cobratbq
    cobratbq

    ๐Ÿ›
    coladict
    coladict

    ๐Ÿ›
    cosmoJFH
    cosmoJFH

    ๐Ÿ›
    cristalp
    cristalp

    ๐Ÿ›
    crunsk
    crunsk

    ๐Ÿ›
    cwholmes
    cwholmes

    ๐Ÿ›
    cyberjj999
    cyberjj999

    ๐Ÿ›
    cyw3
    cyw3

    ๐Ÿ› ๐Ÿ“–
    d1ss0nanz
    d1ss0nanz

    ๐Ÿ›
    dague1
    dague1

    ๐Ÿ“–
    dalizi007
    dalizi007

    ๐Ÿ’ป
    danbrycefairsailcom
    danbrycefairsailcom

    ๐Ÿ›
    dariansanity
    dariansanity

    ๐Ÿ›
    darrenmiliband
    darrenmiliband

    ๐Ÿ›
    davidburstrom
    davidburstrom

    ๐Ÿ›
    dbirkman-paloalto
    dbirkman-paloalto

    ๐Ÿ›
    deepak-patra
    deepak-patra

    ๐Ÿ›
    dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ›
    dinesh150
    dinesh150

    ๐Ÿ›
    diziaq
    diziaq

    ๐Ÿ›
    dreaminpast123
    dreaminpast123

    ๐Ÿ›
    duanyanan
    duanyanan

    ๐Ÿ›
    dutt-sanjay
    dutt-sanjay

    ๐Ÿ›
    duursma
    duursma

    ๐Ÿ’ป
    dylanleung
    dylanleung

    ๐Ÿ›
    dzeigler
    dzeigler

    ๐Ÿ›
    eant60
    eant60

    ๐Ÿ›
    ekkirala
    ekkirala

    ๐Ÿ›
    emersonmoura
    emersonmoura

    ๐Ÿ›
    emouty
    emouty

    ๐Ÿ’ป ๐Ÿ›
    eugenepugach
    eugenepugach

    ๐Ÿ›
    fairy
    fairy

    ๐Ÿ›
    filiprafalowicz
    filiprafalowicz

    ๐Ÿ’ป
    flxbl-io
    flxbl-io

    ๐Ÿ’ต
    foxmason
    foxmason

    ๐Ÿ›
    frankegabor
    frankegabor

    ๐Ÿ›
    frankl
    frankl

    ๐Ÿ›
    freafrea
    freafrea

    ๐Ÿ›
    fsapatin
    fsapatin

    ๐Ÿ›
    gearsethenry
    gearsethenry

    ๐Ÿ›
    gracia19
    gracia19

    ๐Ÿ›
    gudzpoz
    gudzpoz

    ๐Ÿ›
    guo fei
    guo fei

    ๐Ÿ›
    gurmsc5
    gurmsc5

    ๐Ÿ›
    gwilymatgearset
    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ›
    haigsn
    haigsn

    ๐Ÿ›
    hemanshu070
    hemanshu070

    ๐Ÿ›
    henrik242
    henrik242

    ๐Ÿ›
    hongpuwu
    hongpuwu

    ๐Ÿ›
    hvbtup
    hvbtup

    ๐Ÿ’ป ๐Ÿ›
    igniti GmbH
    igniti GmbH

    ๐Ÿ›
    ilovezfs
    ilovezfs

    ๐Ÿ›
    imax-erik
    imax-erik

    ๐Ÿ›
    itaigilo
    itaigilo

    ๐Ÿ›
    jakivey32
    jakivey32

    ๐Ÿ›
    jbennett2091
    jbennett2091

    ๐Ÿ›
    jcamerin
    jcamerin

    ๐Ÿ›
    jkeener1
    jkeener1

    ๐Ÿ›
    jmetertea
    jmetertea

    ๐Ÿ›
    johnra2
    johnra2

    ๐Ÿ’ป
    johnzhao9
    johnzhao9

    ๐Ÿ›
    josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ›
    kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ›
    karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“–
    karwer
    karwer

    ๐Ÿ›
    kaulonline
    kaulonline

    ๐Ÿ›
    kdaemonv
    kdaemonv

    ๐Ÿ›
    kdebski85
    kdebski85

    ๐Ÿ› ๐Ÿ’ป
    kenji21
    kenji21

    ๐Ÿ’ป ๐Ÿ›
    kfranic
    kfranic

    ๐Ÿ›
    khalidkh
    khalidkh

    ๐Ÿ›
    koalalam
    koalalam

    ๐Ÿ›
    krzyk
    krzyk

    ๐Ÿ›
    lasselindqvist
    lasselindqvist

    ๐Ÿ›
    lgemeinhardt
    lgemeinhardt

    ๐Ÿ›
    lihuaib
    lihuaib

    ๐Ÿ›
    liqingjun123
    liqingjun123

    ๐Ÿ›
    lonelyma1021
    lonelyma1021

    ๐Ÿ›
    lpeddy
    lpeddy

    ๐Ÿ›
    lujiefsi
    lujiefsi

    ๐Ÿ’ป
    lukelukes
    lukelukes

    ๐Ÿ’ป
    lyriccoder
    lyriccoder

    ๐Ÿ›
    marcelmore
    marcelmore

    ๐Ÿ›
    matchbox
    matchbox

    ๐Ÿ›
    matthiaskraaz
    matthiaskraaz

    ๐Ÿ›
    meandonlyme
    meandonlyme

    ๐Ÿ›
    mikesive
    mikesive

    ๐Ÿ›
    milossesic
    milossesic

    ๐Ÿ›
    mluckam
    mluckam

    ๐Ÿ’ป ๐Ÿ›
    mohan-chinnappan-n
    mohan-chinnappan-n

    ๐Ÿ’ป
    mriddell95
    mriddell95

    ๐Ÿ›
    mrlzh
    mrlzh

    ๐Ÿ›
    msloan
    msloan

    ๐Ÿ›
    mucharlaravalika
    mucharlaravalika

    ๐Ÿ›
    mvenneman
    mvenneman

    ๐Ÿ›
    nareshl119
    nareshl119

    ๐Ÿ›
    nicolas-harraudeau-sonarsource
    nicolas-harraudeau-sonarsource

    ๐Ÿ›
    noerremark
    noerremark

    ๐Ÿ›
    novsirion
    novsirion

    ๐Ÿ›
    nwcm
    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป
    oggboy
    oggboy

    ๐Ÿ›
    oinume
    oinume

    ๐Ÿ›
    orimarko
    orimarko

    ๐Ÿ’ป ๐Ÿ›
    pablogomez2197
    pablogomez2197

    ๐Ÿ›
    pacvz
    pacvz

    ๐Ÿ’ป
    pallavi agarwal
    pallavi agarwal

    ๐Ÿ›
    parksungrin
    parksungrin

    ๐Ÿ›
    patpatpat123
    patpatpat123

    ๐Ÿ›
    patriksevallius
    patriksevallius

    ๐Ÿ›
    pbrajesh1
    pbrajesh1

    ๐Ÿ›
    phoenix384
    phoenix384

    ๐Ÿ›
    piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป
    plan3d
    plan3d

    ๐Ÿ›
    poojasix
    poojasix

    ๐Ÿ›
    prabhushrikant
    prabhushrikant

    ๐Ÿ›
    pujitha8783
    pujitha8783

    ๐Ÿ›
    r-r-a-j
    r-r-a-j

    ๐Ÿ›
    raghujayjunk
    raghujayjunk

    ๐Ÿ›
    rajeshveera
    rajeshveera

    ๐Ÿ›
    rajeswarreddy88
    rajeswarreddy88

    ๐Ÿ›
    recdevs
    recdevs

    ๐Ÿ›
    reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ›
    rijkt
    rijkt

    ๐Ÿ›
    rillig-tk
    rillig-tk

    ๐Ÿ›
    rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ›
    rnveach
    rnveach

    ๐Ÿ›
    rxmicro
    rxmicro

    ๐Ÿ›
    ryan-gustafson
    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ›
    sabi0
    sabi0

    ๐Ÿ›
    scais
    scais

    ๐Ÿ›
    schosin
    schosin

    ๐Ÿ›
    screamingfrog
    screamingfrog

    ๐Ÿ’ต
    sebbASF
    sebbASF

    ๐Ÿ›
    sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป
    shilko2013
    shilko2013

    ๐Ÿ›
    shiomiyan
    shiomiyan

    ๐Ÿ“–
    simeonKondr
    simeonKondr

    ๐Ÿ›
    snajberk
    snajberk

    ๐Ÿ›
    sniperrifle2004
    sniperrifle2004

    ๐Ÿ›
    snuyanzin
    snuyanzin

    ๐Ÿ› ๐Ÿ’ป
    soloturn
    soloturn

    ๐Ÿ›
    soyodream
    soyodream

    ๐Ÿ›
    sratz
    sratz

    ๐Ÿ›
    stonio
    stonio

    ๐Ÿ›
    sturton
    sturton

    ๐Ÿ’ป ๐Ÿ›
    sudharmohan
    sudharmohan

    ๐Ÿ›
    suruchidawar
    suruchidawar

    ๐Ÿ›
    svenfinitiv
    svenfinitiv

    ๐Ÿ›
    szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป
    tashiscool
    tashiscool

    ๐Ÿ›
    test-git-hook
    test-git-hook

    ๐Ÿ›
    testation21
    testation21

    ๐Ÿ’ป ๐Ÿ›
    thanosa
    thanosa

    ๐Ÿ›
    tiandiyixian
    tiandiyixian

    ๐Ÿ›
    tobwoerk
    tobwoerk

    ๐Ÿ›
    tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป
    trentchilders
    trentchilders

    ๐Ÿ›
    triandicAnt
    triandicAnt

    ๐Ÿ›
    trishul14
    trishul14

    ๐Ÿ›
    tsui
    tsui

    ๐Ÿ›
    wangzitom12306
    wangzitom12306

    ๐Ÿ›
    winhkey
    winhkey

    ๐Ÿ›
    witherspore
    witherspore

    ๐Ÿ›
    wjljack
    wjljack

    ๐Ÿ›
    wuchiuwong
    wuchiuwong

    ๐Ÿ›
    xingsong
    xingsong

    ๐Ÿ›
    xioayuge
    xioayuge

    ๐Ÿ›
    xnYi9wRezm
    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ›
    xuanuy
    xuanuy

    ๐Ÿ›
    xyf0921
    xyf0921

    ๐Ÿ›
    yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ›
    yasuharu-sato
    yasuharu-sato

    ๐Ÿ›
    zenglian
    zenglian

    ๐Ÿ›
    zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ›
    zh3ng
    zh3ng

    ๐Ÿ›
    zt_soft
    zt_soft

    ๐Ÿ›
    ztt79
    ztt79

    ๐Ÿ›
    zzzzfeng
    zzzzfeng

    ๐Ÿ›
    รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ›
    ไปป่ดตๆฐ
    ไปป่ดตๆฐ

    ๐Ÿ›
    ๅคฉ็ƒญๅƒ่ฅฟ็“œ
    ๅคฉ็ƒญๅƒ่ฅฟ็“œ

    ๐Ÿ›
    ่Œ…ๅปถๅฎ‰
    ่Œ…ๅปถๅฎ‰

    ๐Ÿ’ป
    From a5925eb5ea6dc2ed4b980d1d0a2276977b1ae184 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 17 Nov 2024 15:24:49 +0100 Subject: [PATCH 0258/1962] [doc] Fix typo in release notes --- docs/pages/release_notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 4469d3528bc..496f8a26cb0 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -20,7 +20,7 @@ This is a {{ site.pmd.release_type }} release. * apex * [#5333](https://github.com/pmd/pmd/issues/5333): \[apex] Token recognition errors for string containing unicode escape sequence * html - * [5322](https://github.com/pmd/pmd/issues/5322): \[html] CPD throws exception on when HTML file is missing closing tag + * [#5322](https://github.com/pmd/pmd/issues/5322): \[html] CPD throws exception on when HTML file is missing closing tag * java * [#5293](https://github.com/pmd/pmd/issues/5293): \[java] Deadlock when executing PMD in multiple threads * [#5324](https://github.com/pmd/pmd/issues/5324): \[java] Issue with type inference of nested lambdas From 44c15aae6d929c4e6e05a6c347592f45d634f0f8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 17 Nov 2024 15:30:59 +0100 Subject: [PATCH 0259/1962] [doc] Update release notes (#5303, #5302) --- docs/pages/release_notes.md | 9 +++++++++ pmd-apex/src/main/resources/rulesets/apex/quickstart.xml | 1 + 2 files changed, 10 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 496f8a26cb0..c6576be2417 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -14,10 +14,18 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy +### ๐ŸŒŸ New and changed rules + +#### New Rules +* The new Apex rule {% rule apex/bestpractices/QueueableWithoutFinalizer %} detects when the Queueable interface + is used but a Finalizer is not attached. Without attaching a Finalizer, there is no way of designing error + recovery actions should the Queueable action fail. + ### ๐Ÿ› Fixed Issues * ant * [#1860](https://github.com/pmd/pmd/issues/1860): \[ant] Reflective access warnings on java > 9 and java < 17 * apex + * [#5302](https://github.com/pmd/pmd/issues/5302): \[apex] New Rule: Queueable Should Attach Finalizer * [#5333](https://github.com/pmd/pmd/issues/5333): \[apex] Token recognition errors for string containing unicode escape sequence * html * [#5322](https://github.com/pmd/pmd/issues/5322): \[html] CPD throws exception on when HTML file is missing closing tag @@ -42,6 +50,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ External Contributions * [#5284](https://github.com/pmd/pmd/pull/5284): \[apex] Use case-insensitive input stream to avoid choking on Unicode escape sequences - [Willem A. Hajenius](https://github.com/wahajenius) (@wahajenius) +* [#5303](https://github.com/pmd/pmd/pull/5303): \[apex] New Rule: Queueable Should Attach Finalizer - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) {% endtocmaker %} diff --git a/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml b/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml index 83774146c1b..53c63c7546f 100644 --- a/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml +++ b/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml @@ -209,6 +209,7 @@ 3 + From bc4a49deacdf8100097a31af5aa22477a19a16ed Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 17 Nov 2024 15:49:32 +0100 Subject: [PATCH 0260/1962] [doc] Update docs/pages/pmd/projectdocs/credits.md [skip ci] --- docs/pages/pmd/projectdocs/credits.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 81690f91dc9..8fc171d45be 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -558,7 +558,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Mihai Ionut
    Mihai Ionut

    ๐Ÿ› Mikhail Kuchma
    Mikhail Kuchma

    ๐Ÿ› Mirek Hankus
    Mirek Hankus

    ๐Ÿ› - Mitch Spano
    Mitch Spano

    ๐Ÿ› + Mitch Spano
    Mitch Spano

    ๐Ÿ’ป ๐Ÿ› Mladjan Gadzic
    Mladjan Gadzic

    ๐Ÿ› MrAngry52
    MrAngry52

    ๐Ÿ› Muminur Choudhury
    Muminur Choudhury

    ๐Ÿ› From 5a0220da2e1641e779838b9b3c4fea3f16ae39c2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 17 Nov 2024 15:58:05 +0100 Subject: [PATCH 0261/1962] [doc] Update release notes (#5335) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index f9967dcfc36..bea75362779 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -30,6 +30,9 @@ This is a {{ site.pmd.release_type }} release. * pmd-xml * {%jdoc xml::lang.xml.antlr4.XMLLexer %} is deprecated for removal. Use {%jdoc !!xml::lang.xml.ast.XMLLexer %} instead (note different package `ast` instead of `antlr4`). +* pmd-kotlin + * {%jdoc kotlin::lang.kotlin.ast.UnicodeClasses %} is deprecated for removal. This class was never intended to + be generated. It will be removed with no replacement. ### โœจ External Contributions * [#5284](https://github.com/pmd/pmd/pull/5284): \[apex] Use case-insensitive input stream to avoid choking on Unicode escape sequences - [Willem A. Hajenius](https://github.com/wahajenius) (@wahajenius) From a9b6c946b4392aac8113db14a330625240cfe67c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 17 Nov 2024 16:12:46 +0100 Subject: [PATCH 0262/1962] [doc] Update release notes (#5336) --- docs/pages/release_notes.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index b7ab311cb17..b882fa65165 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -29,6 +29,17 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿšจ API Changes #### Deprecations +* pmd-gherkin + * {%jdoc gherkin::lang.gherkin.ast.GherkinBaseListener %} is deprecated for removal. This class was never intended + to be generated. It will be removed with no replacement. + * {%jdoc gherkin::lang.gherkin.ast.GherkinBaseVisitor %} is deprecated for removal. This class was never intended + to be generated. It will be removed with no replacement. + * {%jdoc gherkin::lang.gherkin.ast.GherkinListener %} is deprecated for removal. This class was never intended + to be generated. It will be removed with no replacement. + * {%jdoc gherkin::lang.gherkin.ast.GherkinParser %} is deprecated for removal. This class was never intended + to be generated. It will be removed with no replacement. + * {%jdoc gherkin::lang.gherkin.ast.GherkinVisitor %} is deprecated for removal. This class was never intended + to be generated. It will be removed with no replacement. * pmd-xml * {%jdoc xml::lang.xml.antlr4.XMLLexer %} is deprecated for removal. Use {%jdoc !!xml::lang.xml.ast.XMLLexer %} instead (note different package `ast` instead of `antlr4`). From 8fdfd369b076f90698fbb2040667a84be07d93ab Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 17 Nov 2024 16:15:55 +0100 Subject: [PATCH 0263/1962] [doc] Update release notes (#5342) --- docs/pages/release_notes.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index e64354df241..76fc7fbc707 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -31,6 +31,17 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿšจ API Changes #### Deprecations +* pmd-julia + * {%jdoc julia::lang.julia.ast.JuliaBaseListener %} is deprecated for removal. This class was never intended to + be generated. It will be removed with no replacement. + * {%jdoc julia::lang.julia.ast.JuliaBaseVisitor %} is deprecated for removal. This class was never intended to + be generated. It will be removed with no replacement. + * {%jdoc julia::lang.julia.ast.JuliaListener %} is deprecated for removal. This class was never intended to + be generated. It will be removed with no replacement. + * {%jdoc julia::lang.julia.ast.JuliaParser %} is deprecated for removal. This class was never intended to + be generated. It will be removed with no replacement. + * {%jdoc julia::lang.julia.ast.JuliaVisitor %} is deprecated for removal. This class was never intended to + be generated. It will be removed with no replacement. * pmd-xml * {%jdoc xml::lang.xml.antlr4.XMLLexer %} is deprecated for removal. Use {%jdoc !!xml::lang.xml.ast.XMLLexer %} instead (note different package `ast` instead of `antlr4`). From e513b85b21028a62f2b02bc367d2f99500fa3cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Sun, 17 Nov 2024 16:10:34 -0300 Subject: [PATCH 0264/1962] Remvoegenerated coco files form coverage - Remove / deprecate unused generated code - Flag everything as Generated --- pmd-coco/pom.xml | 22 + .../pmd/lang/coco/ast/CocoBaseListener.java | 1369 +++ .../pmd/lang/coco/ast/CocoBaseVisitor.java | 793 ++ .../pmd/lang/coco/ast/CocoListener.java | 1177 +++ .../pmd/lang/coco/ast/CocoParser.java | 8678 +++++++++++++++++ .../pmd/lang/coco/ast/CocoVisitor.java | 712 ++ 6 files changed, 12751 insertions(+) create mode 100644 pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoBaseListener.java create mode 100644 pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoBaseVisitor.java create mode 100644 pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoListener.java create mode 100644 pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoParser.java create mode 100644 pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoVisitor.java diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index c060429a452..5d9270a0ac3 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -18,6 +18,28 @@ antlr4-maven-plugin
    + + org.apache.maven.plugins + maven-antrun-plugin + + + antlr-cleanup + generate-sources + + run + + + + + + + + + + + + + maven-resources-plugin diff --git a/pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoBaseListener.java b/pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoBaseListener.java new file mode 100644 index 00000000000..f2792e56902 --- /dev/null +++ b/pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoBaseListener.java @@ -0,0 +1,1369 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +// CHECKSTYLE:OFF +// Generated from net/sourceforge/pmd/lang/coco/ast/Coco.g4 by ANTLR 4.9.3 +package net.sourceforge.pmd.lang.coco.ast; + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.tree.ErrorNode; +import org.antlr.v4.runtime.tree.TerminalNode; + +/** + * This class provides an empty implementation of {@link CocoListener}, + * which can be extended to create a listener which only needs to handle a subset + * of the available methods. + * + * @deprecated Since 7.8.0. This class was never intended to be generated. It will be removed with no replacement. + */ +@SuppressWarnings("PMD.UncommentedEmptyMethodBody") +@Deprecated +@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public class CocoBaseListener implements CocoListener { + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterModule(CocoParser.ModuleContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitModule(CocoParser.ModuleContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterDeclaration(CocoParser.DeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitDeclaration(CocoParser.DeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterAttribute(CocoParser.AttributeContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitAttribute(CocoParser.AttributeContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterAttributeDeclaration(CocoParser.AttributeDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitAttributeDeclaration(CocoParser.AttributeDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterImportDeclaration(CocoParser.ImportDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitImportDeclaration(CocoParser.ImportDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterVariableDeclaration(CocoParser.VariableDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitVariableDeclaration(CocoParser.VariableDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterEnumDeclaration(CocoParser.EnumDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitEnumDeclaration(CocoParser.EnumDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterStructDeclaration(CocoParser.StructDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitStructDeclaration(CocoParser.StructDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterTypeAliasDeclaration(CocoParser.TypeAliasDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitTypeAliasDeclaration(CocoParser.TypeAliasDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterFunctionDeclaration(CocoParser.FunctionDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitFunctionDeclaration(CocoParser.FunctionDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterInstanceDeclaration(CocoParser.InstanceDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitInstanceDeclaration(CocoParser.InstanceDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterPortDeclaration(CocoParser.PortDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitPortDeclaration(CocoParser.PortDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterComponentDeclaration(CocoParser.ComponentDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitComponentDeclaration(CocoParser.ComponentDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterExternalConstantDeclaration(CocoParser.ExternalConstantDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitExternalConstantDeclaration(CocoParser.ExternalConstantDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterExternalTypeDeclaration(CocoParser.ExternalTypeDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitExternalTypeDeclaration(CocoParser.ExternalTypeDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterExternalTypeElement(CocoParser.ExternalTypeElementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitExternalTypeElement(CocoParser.ExternalTypeElementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterExternalFunctionDeclaration(CocoParser.ExternalFunctionDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitExternalFunctionDeclaration(CocoParser.ExternalFunctionDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterGenericTypeDeclaration(CocoParser.GenericTypeDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitGenericTypeDeclaration(CocoParser.GenericTypeDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterGenericTypes(CocoParser.GenericTypesContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitGenericTypes(CocoParser.GenericTypesContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterGenericType(CocoParser.GenericTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitGenericType(CocoParser.GenericTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterEnumElement(CocoParser.EnumElementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitEnumElement(CocoParser.EnumElementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterEnumCase(CocoParser.EnumCaseContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitEnumCase(CocoParser.EnumCaseContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterCaseParameters(CocoParser.CaseParametersContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitCaseParameters(CocoParser.CaseParametersContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterCaseParameter(CocoParser.CaseParameterContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitCaseParameter(CocoParser.CaseParameterContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterStructElement(CocoParser.StructElementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitStructElement(CocoParser.StructElementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterFieldDeclaration(CocoParser.FieldDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitFieldDeclaration(CocoParser.FieldDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterComponentElement(CocoParser.ComponentElementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitComponentElement(CocoParser.ComponentElementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterStaticMemberDeclaration(CocoParser.StaticMemberDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitStaticMemberDeclaration(CocoParser.StaticMemberDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterConstructorDeclaration(CocoParser.ConstructorDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitConstructorDeclaration(CocoParser.ConstructorDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterIfExpression(CocoParser.IfExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitIfExpression(CocoParser.IfExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterTryOperatorExpression(CocoParser.TryOperatorExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitTryOperatorExpression(CocoParser.TryOperatorExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterUnaryOperatorExpression(CocoParser.UnaryOperatorExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitUnaryOperatorExpression(CocoParser.UnaryOperatorExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterOptionalExpression(CocoParser.OptionalExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitOptionalExpression(CocoParser.OptionalExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterArithmicOrLogicalExpression(CocoParser.ArithmicOrLogicalExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitArithmicOrLogicalExpression(CocoParser.ArithmicOrLogicalExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterLiteralExpression(CocoParser.LiteralExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitLiteralExpression(CocoParser.LiteralExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterArrayLiteralExpression(CocoParser.ArrayLiteralExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitArrayLiteralExpression(CocoParser.ArrayLiteralExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterNondetExpression(CocoParser.NondetExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitNondetExpression(CocoParser.NondetExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterGroupedExpression(CocoParser.GroupedExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitGroupedExpression(CocoParser.GroupedExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterBlockExpression(CocoParser.BlockExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitBlockExpression(CocoParser.BlockExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterMatchExpression(CocoParser.MatchExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitMatchExpression(CocoParser.MatchExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterStructLiteralExpression(CocoParser.StructLiteralExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitStructLiteralExpression(CocoParser.StructLiteralExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterMemberReferenceExpression(CocoParser.MemberReferenceExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitMemberReferenceExpression(CocoParser.MemberReferenceExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterAssignmentExpression(CocoParser.AssignmentExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitAssignmentExpression(CocoParser.AssignmentExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterVariableReferenceExpression(CocoParser.VariableReferenceExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitVariableReferenceExpression(CocoParser.VariableReferenceExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterImplicitMemberExpression(CocoParser.ImplicitMemberExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitImplicitMemberExpression(CocoParser.ImplicitMemberExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterExternalFunction(CocoParser.ExternalFunctionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitExternalFunction(CocoParser.ExternalFunctionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterCastExpression(CocoParser.CastExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitCastExpression(CocoParser.CastExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterStateInvariantExpression(CocoParser.StateInvariantExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitStateInvariantExpression(CocoParser.StateInvariantExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterCallExpression(CocoParser.CallExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitCallExpression(CocoParser.CallExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterExternalLiteral(CocoParser.ExternalLiteralContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitExternalLiteral(CocoParser.ExternalLiteralContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterArraySubscriptExpression(CocoParser.ArraySubscriptExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitArraySubscriptExpression(CocoParser.ArraySubscriptExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterBlockExpression_(CocoParser.BlockExpression_Context ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitBlockExpression_(CocoParser.BlockExpression_Context ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterIfExpression_(CocoParser.IfExpression_Context ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitIfExpression_(CocoParser.IfExpression_Context ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterMatchExpression_(CocoParser.MatchExpression_Context ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitMatchExpression_(CocoParser.MatchExpression_Context ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterNondetExpression_(CocoParser.NondetExpression_Context ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitNondetExpression_(CocoParser.NondetExpression_Context ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterFieldAssignments(CocoParser.FieldAssignmentsContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitFieldAssignments(CocoParser.FieldAssignmentsContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterFieldAssignment(CocoParser.FieldAssignmentContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitFieldAssignment(CocoParser.FieldAssignmentContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterNondetClauses(CocoParser.NondetClausesContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitNondetClauses(CocoParser.NondetClausesContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterNondetClause(CocoParser.NondetClauseContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitNondetClause(CocoParser.NondetClauseContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterMatchClauses(CocoParser.MatchClausesContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitMatchClauses(CocoParser.MatchClausesContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterMatchClause(CocoParser.MatchClauseContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitMatchClause(CocoParser.MatchClauseContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterPattern(CocoParser.PatternContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitPattern(CocoParser.PatternContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterEnumCasePattern(CocoParser.EnumCasePatternContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitEnumCasePattern(CocoParser.EnumCasePatternContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterIdParameterPatterns(CocoParser.IdParameterPatternsContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitIdParameterPatterns(CocoParser.IdParameterPatternsContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterIdParameterPattern(CocoParser.IdParameterPatternContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitIdParameterPattern(CocoParser.IdParameterPatternContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterVariableDeclarationPattern(CocoParser.VariableDeclarationPatternContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitVariableDeclarationPattern(CocoParser.VariableDeclarationPatternContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterParameterPatterns(CocoParser.ParameterPatternsContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitParameterPatterns(CocoParser.ParameterPatternsContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterParameterPattern(CocoParser.ParameterPatternContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitParameterPattern(CocoParser.ParameterPatternContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterExpressions(CocoParser.ExpressionsContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitExpressions(CocoParser.ExpressionsContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterStatement(CocoParser.StatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitStatement(CocoParser.StatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterDeclarationStatement(CocoParser.DeclarationStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitDeclarationStatement(CocoParser.DeclarationStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterReturnStatement(CocoParser.ReturnStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitReturnStatement(CocoParser.ReturnStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterBecomeStatement(CocoParser.BecomeStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitBecomeStatement(CocoParser.BecomeStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterWhileStatement(CocoParser.WhileStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitWhileStatement(CocoParser.WhileStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterForStatement(CocoParser.ForStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitForStatement(CocoParser.ForStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterBreakStatement(CocoParser.BreakStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitBreakStatement(CocoParser.BreakStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterContinueStatement(CocoParser.ContinueStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitContinueStatement(CocoParser.ContinueStatementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterPortElement(CocoParser.PortElementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitPortElement(CocoParser.PortElementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterFunctionInterfaceDeclaration(CocoParser.FunctionInterfaceDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitFunctionInterfaceDeclaration(CocoParser.FunctionInterfaceDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterSignalDeclaration(CocoParser.SignalDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitSignalDeclaration(CocoParser.SignalDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterStateMachineDeclaration(CocoParser.StateMachineDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitStateMachineDeclaration(CocoParser.StateMachineDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterStateMachineElement(CocoParser.StateMachineElementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitStateMachineElement(CocoParser.StateMachineElementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterStateDeclaration(CocoParser.StateDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitStateDeclaration(CocoParser.StateDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterEventStateDeclaration(CocoParser.EventStateDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitEventStateDeclaration(CocoParser.EventStateDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterExecutionStateDeclaration(CocoParser.ExecutionStateDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitExecutionStateDeclaration(CocoParser.ExecutionStateDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterEventStateElement(CocoParser.EventStateElementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitEventStateElement(CocoParser.EventStateElementContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterEntryFunctionDeclaration(CocoParser.EntryFunctionDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitEntryFunctionDeclaration(CocoParser.EntryFunctionDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterExitFunctionDeclaration(CocoParser.ExitFunctionDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitExitFunctionDeclaration(CocoParser.ExitFunctionDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterStateInvariant(CocoParser.StateInvariantContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitStateInvariant(CocoParser.StateInvariantContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterTransitionDeclaration(CocoParser.TransitionDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitTransitionDeclaration(CocoParser.TransitionDeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterEventTransition(CocoParser.EventTransitionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitEventTransition(CocoParser.EventTransitionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterEventSource(CocoParser.EventSourceContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitEventSource(CocoParser.EventSourceContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterSpontaneousTransition(CocoParser.SpontaneousTransitionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitSpontaneousTransition(CocoParser.SpontaneousTransitionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterTimerTransition(CocoParser.TimerTransitionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitTimerTransition(CocoParser.TimerTransitionContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterEventHandler(CocoParser.EventHandlerContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitEventHandler(CocoParser.EventHandlerContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterOffer(CocoParser.OfferContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitOffer(CocoParser.OfferContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterOfferClauses(CocoParser.OfferClausesContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitOfferClauses(CocoParser.OfferClausesContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterOfferClause(CocoParser.OfferClauseContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitOfferClause(CocoParser.OfferClauseContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterParameters(CocoParser.ParametersContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitParameters(CocoParser.ParametersContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterParameter(CocoParser.ParameterContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitParameter(CocoParser.ParameterContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterLiteralExpression_(CocoParser.LiteralExpression_Context ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitLiteralExpression_(CocoParser.LiteralExpression_Context ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterBinaryType(CocoParser.BinaryTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitBinaryType(CocoParser.BinaryTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterGroupType(CocoParser.GroupTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitGroupType(CocoParser.GroupTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterFunctionType(CocoParser.FunctionTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitFunctionType(CocoParser.FunctionTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterUnaryType(CocoParser.UnaryTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitUnaryType(CocoParser.UnaryTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterLiteralType(CocoParser.LiteralTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitLiteralType(CocoParser.LiteralTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterTypeReference(CocoParser.TypeReferenceContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitTypeReference(CocoParser.TypeReferenceContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterReferenceType(CocoParser.ReferenceTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitReferenceType(CocoParser.ReferenceTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterTypes(CocoParser.TypesContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitTypes(CocoParser.TypesContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterDotIdentifierList(CocoParser.DotIdentifierListContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitDotIdentifierList(CocoParser.DotIdentifierListContext ctx) { } + + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void enterEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void exitEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void visitTerminal(TerminalNode node) { } + /** + * {@inheritDoc} + * + *

    The default implementation does nothing.

    + */ + @Override public void visitErrorNode(ErrorNode node) { } +} diff --git a/pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoBaseVisitor.java b/pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoBaseVisitor.java new file mode 100644 index 00000000000..ec60e5c0488 --- /dev/null +++ b/pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoBaseVisitor.java @@ -0,0 +1,793 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +// CHECKSTYLE:OFF +// Generated from net/sourceforge/pmd/lang/coco/ast/Coco.g4 by ANTLR 4.9.3 +package net.sourceforge.pmd.lang.coco.ast; +import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor; + +/** + * This class provides an empty implementation of {@link CocoVisitor}, + * which can be extended to create a visitor which only needs to handle a subset + * of the available methods. + * + * @param The return type of the visit operation. Use {@link Void} for + * operations with no return type. + * + * @deprecated Since 7.8.0. This class was never intended to be generated. It will be removed with no replacement. + */ +@Deprecated +@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public class CocoBaseVisitor extends AbstractParseTreeVisitor implements CocoVisitor { + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitModule(CocoParser.ModuleContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitDeclaration(CocoParser.DeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitAttribute(CocoParser.AttributeContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitAttributeDeclaration(CocoParser.AttributeDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitImportDeclaration(CocoParser.ImportDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitVariableDeclaration(CocoParser.VariableDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitEnumDeclaration(CocoParser.EnumDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitStructDeclaration(CocoParser.StructDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitTypeAliasDeclaration(CocoParser.TypeAliasDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitFunctionDeclaration(CocoParser.FunctionDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitInstanceDeclaration(CocoParser.InstanceDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitPortDeclaration(CocoParser.PortDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitComponentDeclaration(CocoParser.ComponentDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitExternalConstantDeclaration(CocoParser.ExternalConstantDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitExternalTypeDeclaration(CocoParser.ExternalTypeDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitExternalTypeElement(CocoParser.ExternalTypeElementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitExternalFunctionDeclaration(CocoParser.ExternalFunctionDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitGenericTypeDeclaration(CocoParser.GenericTypeDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitGenericTypes(CocoParser.GenericTypesContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitGenericType(CocoParser.GenericTypeContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitEnumElement(CocoParser.EnumElementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitEnumCase(CocoParser.EnumCaseContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitCaseParameters(CocoParser.CaseParametersContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitCaseParameter(CocoParser.CaseParameterContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitStructElement(CocoParser.StructElementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitFieldDeclaration(CocoParser.FieldDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitComponentElement(CocoParser.ComponentElementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitStaticMemberDeclaration(CocoParser.StaticMemberDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitConstructorDeclaration(CocoParser.ConstructorDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitIfExpression(CocoParser.IfExpressionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitTryOperatorExpression(CocoParser.TryOperatorExpressionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitUnaryOperatorExpression(CocoParser.UnaryOperatorExpressionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitOptionalExpression(CocoParser.OptionalExpressionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitArithmicOrLogicalExpression(CocoParser.ArithmicOrLogicalExpressionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitLiteralExpression(CocoParser.LiteralExpressionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitArrayLiteralExpression(CocoParser.ArrayLiteralExpressionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitNondetExpression(CocoParser.NondetExpressionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitGroupedExpression(CocoParser.GroupedExpressionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitBlockExpression(CocoParser.BlockExpressionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitMatchExpression(CocoParser.MatchExpressionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitStructLiteralExpression(CocoParser.StructLiteralExpressionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitMemberReferenceExpression(CocoParser.MemberReferenceExpressionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitAssignmentExpression(CocoParser.AssignmentExpressionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitVariableReferenceExpression(CocoParser.VariableReferenceExpressionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitImplicitMemberExpression(CocoParser.ImplicitMemberExpressionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitExternalFunction(CocoParser.ExternalFunctionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitCastExpression(CocoParser.CastExpressionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitStateInvariantExpression(CocoParser.StateInvariantExpressionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitCallExpression(CocoParser.CallExpressionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitExternalLiteral(CocoParser.ExternalLiteralContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitArraySubscriptExpression(CocoParser.ArraySubscriptExpressionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitBlockExpression_(CocoParser.BlockExpression_Context ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitIfExpression_(CocoParser.IfExpression_Context ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitMatchExpression_(CocoParser.MatchExpression_Context ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitNondetExpression_(CocoParser.NondetExpression_Context ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitFieldAssignments(CocoParser.FieldAssignmentsContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitFieldAssignment(CocoParser.FieldAssignmentContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitNondetClauses(CocoParser.NondetClausesContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitNondetClause(CocoParser.NondetClauseContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitMatchClauses(CocoParser.MatchClausesContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitMatchClause(CocoParser.MatchClauseContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitPattern(CocoParser.PatternContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitEnumCasePattern(CocoParser.EnumCasePatternContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitIdParameterPatterns(CocoParser.IdParameterPatternsContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitIdParameterPattern(CocoParser.IdParameterPatternContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitVariableDeclarationPattern(CocoParser.VariableDeclarationPatternContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitParameterPatterns(CocoParser.ParameterPatternsContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitParameterPattern(CocoParser.ParameterPatternContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitExpressions(CocoParser.ExpressionsContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitStatement(CocoParser.StatementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitDeclarationStatement(CocoParser.DeclarationStatementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitReturnStatement(CocoParser.ReturnStatementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitBecomeStatement(CocoParser.BecomeStatementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitWhileStatement(CocoParser.WhileStatementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitForStatement(CocoParser.ForStatementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitBreakStatement(CocoParser.BreakStatementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitContinueStatement(CocoParser.ContinueStatementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitPortElement(CocoParser.PortElementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitFunctionInterfaceDeclaration(CocoParser.FunctionInterfaceDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitSignalDeclaration(CocoParser.SignalDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitStateMachineDeclaration(CocoParser.StateMachineDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitStateMachineElement(CocoParser.StateMachineElementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitStateDeclaration(CocoParser.StateDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitEventStateDeclaration(CocoParser.EventStateDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitExecutionStateDeclaration(CocoParser.ExecutionStateDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitEventStateElement(CocoParser.EventStateElementContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitEntryFunctionDeclaration(CocoParser.EntryFunctionDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitExitFunctionDeclaration(CocoParser.ExitFunctionDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitStateInvariant(CocoParser.StateInvariantContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitTransitionDeclaration(CocoParser.TransitionDeclarationContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitEventTransition(CocoParser.EventTransitionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitEventSource(CocoParser.EventSourceContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitSpontaneousTransition(CocoParser.SpontaneousTransitionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitTimerTransition(CocoParser.TimerTransitionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitEventHandler(CocoParser.EventHandlerContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitOffer(CocoParser.OfferContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitOfferClauses(CocoParser.OfferClausesContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitOfferClause(CocoParser.OfferClauseContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitParameters(CocoParser.ParametersContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitParameter(CocoParser.ParameterContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitLiteralExpression_(CocoParser.LiteralExpression_Context ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitBinaryType(CocoParser.BinaryTypeContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitGroupType(CocoParser.GroupTypeContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitFunctionType(CocoParser.FunctionTypeContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitUnaryType(CocoParser.UnaryTypeContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitLiteralType(CocoParser.LiteralTypeContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitTypeReference(CocoParser.TypeReferenceContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitReferenceType(CocoParser.ReferenceTypeContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitTypes(CocoParser.TypesContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

    The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

    + */ + @Override public T visitDotIdentifierList(CocoParser.DotIdentifierListContext ctx) { return visitChildren(ctx); } +} diff --git a/pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoListener.java b/pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoListener.java new file mode 100644 index 00000000000..bef3fbacbd1 --- /dev/null +++ b/pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoListener.java @@ -0,0 +1,1177 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +// CHECKSTYLE:OFF +// Generated from net/sourceforge/pmd/lang/coco/ast/Coco.g4 by ANTLR 4.9.3 +package net.sourceforge.pmd.lang.coco.ast; +import org.antlr.v4.runtime.tree.ParseTreeListener; + +/** + * This interface defines a complete listener for a parse tree produced by + * {@link CocoParser}. + * + * @deprecated Since 7.8.0. This class was never intended to be generated. It will be removed with no replacement. + */ +@Deprecated +@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public interface CocoListener extends ParseTreeListener { + /** + * Enter a parse tree produced by {@link CocoParser#module}. + * @param ctx the parse tree + */ + void enterModule(CocoParser.ModuleContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#module}. + * @param ctx the parse tree + */ + void exitModule(CocoParser.ModuleContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#declaration}. + * @param ctx the parse tree + */ + void enterDeclaration(CocoParser.DeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#declaration}. + * @param ctx the parse tree + */ + void exitDeclaration(CocoParser.DeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#attribute}. + * @param ctx the parse tree + */ + void enterAttribute(CocoParser.AttributeContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#attribute}. + * @param ctx the parse tree + */ + void exitAttribute(CocoParser.AttributeContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#attributeDeclaration}. + * @param ctx the parse tree + */ + void enterAttributeDeclaration(CocoParser.AttributeDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#attributeDeclaration}. + * @param ctx the parse tree + */ + void exitAttributeDeclaration(CocoParser.AttributeDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#importDeclaration}. + * @param ctx the parse tree + */ + void enterImportDeclaration(CocoParser.ImportDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#importDeclaration}. + * @param ctx the parse tree + */ + void exitImportDeclaration(CocoParser.ImportDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#variableDeclaration}. + * @param ctx the parse tree + */ + void enterVariableDeclaration(CocoParser.VariableDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#variableDeclaration}. + * @param ctx the parse tree + */ + void exitVariableDeclaration(CocoParser.VariableDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#enumDeclaration}. + * @param ctx the parse tree + */ + void enterEnumDeclaration(CocoParser.EnumDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#enumDeclaration}. + * @param ctx the parse tree + */ + void exitEnumDeclaration(CocoParser.EnumDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#structDeclaration}. + * @param ctx the parse tree + */ + void enterStructDeclaration(CocoParser.StructDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#structDeclaration}. + * @param ctx the parse tree + */ + void exitStructDeclaration(CocoParser.StructDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#typeAliasDeclaration}. + * @param ctx the parse tree + */ + void enterTypeAliasDeclaration(CocoParser.TypeAliasDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#typeAliasDeclaration}. + * @param ctx the parse tree + */ + void exitTypeAliasDeclaration(CocoParser.TypeAliasDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#functionDeclaration}. + * @param ctx the parse tree + */ + void enterFunctionDeclaration(CocoParser.FunctionDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#functionDeclaration}. + * @param ctx the parse tree + */ + void exitFunctionDeclaration(CocoParser.FunctionDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#instanceDeclaration}. + * @param ctx the parse tree + */ + void enterInstanceDeclaration(CocoParser.InstanceDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#instanceDeclaration}. + * @param ctx the parse tree + */ + void exitInstanceDeclaration(CocoParser.InstanceDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#portDeclaration}. + * @param ctx the parse tree + */ + void enterPortDeclaration(CocoParser.PortDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#portDeclaration}. + * @param ctx the parse tree + */ + void exitPortDeclaration(CocoParser.PortDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#componentDeclaration}. + * @param ctx the parse tree + */ + void enterComponentDeclaration(CocoParser.ComponentDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#componentDeclaration}. + * @param ctx the parse tree + */ + void exitComponentDeclaration(CocoParser.ComponentDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#externalConstantDeclaration}. + * @param ctx the parse tree + */ + void enterExternalConstantDeclaration(CocoParser.ExternalConstantDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#externalConstantDeclaration}. + * @param ctx the parse tree + */ + void exitExternalConstantDeclaration(CocoParser.ExternalConstantDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#externalTypeDeclaration}. + * @param ctx the parse tree + */ + void enterExternalTypeDeclaration(CocoParser.ExternalTypeDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#externalTypeDeclaration}. + * @param ctx the parse tree + */ + void exitExternalTypeDeclaration(CocoParser.ExternalTypeDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#externalTypeElement}. + * @param ctx the parse tree + */ + void enterExternalTypeElement(CocoParser.ExternalTypeElementContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#externalTypeElement}. + * @param ctx the parse tree + */ + void exitExternalTypeElement(CocoParser.ExternalTypeElementContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#externalFunctionDeclaration}. + * @param ctx the parse tree + */ + void enterExternalFunctionDeclaration(CocoParser.ExternalFunctionDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#externalFunctionDeclaration}. + * @param ctx the parse tree + */ + void exitExternalFunctionDeclaration(CocoParser.ExternalFunctionDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#genericTypeDeclaration}. + * @param ctx the parse tree + */ + void enterGenericTypeDeclaration(CocoParser.GenericTypeDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#genericTypeDeclaration}. + * @param ctx the parse tree + */ + void exitGenericTypeDeclaration(CocoParser.GenericTypeDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#genericTypes}. + * @param ctx the parse tree + */ + void enterGenericTypes(CocoParser.GenericTypesContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#genericTypes}. + * @param ctx the parse tree + */ + void exitGenericTypes(CocoParser.GenericTypesContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#genericType}. + * @param ctx the parse tree + */ + void enterGenericType(CocoParser.GenericTypeContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#genericType}. + * @param ctx the parse tree + */ + void exitGenericType(CocoParser.GenericTypeContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#enumElement}. + * @param ctx the parse tree + */ + void enterEnumElement(CocoParser.EnumElementContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#enumElement}. + * @param ctx the parse tree + */ + void exitEnumElement(CocoParser.EnumElementContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#enumCase}. + * @param ctx the parse tree + */ + void enterEnumCase(CocoParser.EnumCaseContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#enumCase}. + * @param ctx the parse tree + */ + void exitEnumCase(CocoParser.EnumCaseContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#caseParameters}. + * @param ctx the parse tree + */ + void enterCaseParameters(CocoParser.CaseParametersContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#caseParameters}. + * @param ctx the parse tree + */ + void exitCaseParameters(CocoParser.CaseParametersContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#caseParameter}. + * @param ctx the parse tree + */ + void enterCaseParameter(CocoParser.CaseParameterContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#caseParameter}. + * @param ctx the parse tree + */ + void exitCaseParameter(CocoParser.CaseParameterContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#structElement}. + * @param ctx the parse tree + */ + void enterStructElement(CocoParser.StructElementContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#structElement}. + * @param ctx the parse tree + */ + void exitStructElement(CocoParser.StructElementContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#fieldDeclaration}. + * @param ctx the parse tree + */ + void enterFieldDeclaration(CocoParser.FieldDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#fieldDeclaration}. + * @param ctx the parse tree + */ + void exitFieldDeclaration(CocoParser.FieldDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#componentElement}. + * @param ctx the parse tree + */ + void enterComponentElement(CocoParser.ComponentElementContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#componentElement}. + * @param ctx the parse tree + */ + void exitComponentElement(CocoParser.ComponentElementContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#staticMemberDeclaration}. + * @param ctx the parse tree + */ + void enterStaticMemberDeclaration(CocoParser.StaticMemberDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#staticMemberDeclaration}. + * @param ctx the parse tree + */ + void exitStaticMemberDeclaration(CocoParser.StaticMemberDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#constructorDeclaration}. + * @param ctx the parse tree + */ + void enterConstructorDeclaration(CocoParser.ConstructorDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#constructorDeclaration}. + * @param ctx the parse tree + */ + void exitConstructorDeclaration(CocoParser.ConstructorDeclarationContext ctx); + /** + * Enter a parse tree produced by the {@code IfExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void enterIfExpression(CocoParser.IfExpressionContext ctx); + /** + * Exit a parse tree produced by the {@code IfExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void exitIfExpression(CocoParser.IfExpressionContext ctx); + /** + * Enter a parse tree produced by the {@code TryOperatorExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void enterTryOperatorExpression(CocoParser.TryOperatorExpressionContext ctx); + /** + * Exit a parse tree produced by the {@code TryOperatorExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void exitTryOperatorExpression(CocoParser.TryOperatorExpressionContext ctx); + /** + * Enter a parse tree produced by the {@code UnaryOperatorExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void enterUnaryOperatorExpression(CocoParser.UnaryOperatorExpressionContext ctx); + /** + * Exit a parse tree produced by the {@code UnaryOperatorExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void exitUnaryOperatorExpression(CocoParser.UnaryOperatorExpressionContext ctx); + /** + * Enter a parse tree produced by the {@code OptionalExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void enterOptionalExpression(CocoParser.OptionalExpressionContext ctx); + /** + * Exit a parse tree produced by the {@code OptionalExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void exitOptionalExpression(CocoParser.OptionalExpressionContext ctx); + /** + * Enter a parse tree produced by the {@code ArithmicOrLogicalExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void enterArithmicOrLogicalExpression(CocoParser.ArithmicOrLogicalExpressionContext ctx); + /** + * Exit a parse tree produced by the {@code ArithmicOrLogicalExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void exitArithmicOrLogicalExpression(CocoParser.ArithmicOrLogicalExpressionContext ctx); + /** + * Enter a parse tree produced by the {@code LiteralExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void enterLiteralExpression(CocoParser.LiteralExpressionContext ctx); + /** + * Exit a parse tree produced by the {@code LiteralExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void exitLiteralExpression(CocoParser.LiteralExpressionContext ctx); + /** + * Enter a parse tree produced by the {@code ArrayLiteralExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void enterArrayLiteralExpression(CocoParser.ArrayLiteralExpressionContext ctx); + /** + * Exit a parse tree produced by the {@code ArrayLiteralExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void exitArrayLiteralExpression(CocoParser.ArrayLiteralExpressionContext ctx); + /** + * Enter a parse tree produced by the {@code NondetExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void enterNondetExpression(CocoParser.NondetExpressionContext ctx); + /** + * Exit a parse tree produced by the {@code NondetExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void exitNondetExpression(CocoParser.NondetExpressionContext ctx); + /** + * Enter a parse tree produced by the {@code GroupedExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void enterGroupedExpression(CocoParser.GroupedExpressionContext ctx); + /** + * Exit a parse tree produced by the {@code GroupedExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void exitGroupedExpression(CocoParser.GroupedExpressionContext ctx); + /** + * Enter a parse tree produced by the {@code BlockExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void enterBlockExpression(CocoParser.BlockExpressionContext ctx); + /** + * Exit a parse tree produced by the {@code BlockExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void exitBlockExpression(CocoParser.BlockExpressionContext ctx); + /** + * Enter a parse tree produced by the {@code MatchExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void enterMatchExpression(CocoParser.MatchExpressionContext ctx); + /** + * Exit a parse tree produced by the {@code MatchExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void exitMatchExpression(CocoParser.MatchExpressionContext ctx); + /** + * Enter a parse tree produced by the {@code StructLiteralExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void enterStructLiteralExpression(CocoParser.StructLiteralExpressionContext ctx); + /** + * Exit a parse tree produced by the {@code StructLiteralExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void exitStructLiteralExpression(CocoParser.StructLiteralExpressionContext ctx); + /** + * Enter a parse tree produced by the {@code MemberReferenceExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void enterMemberReferenceExpression(CocoParser.MemberReferenceExpressionContext ctx); + /** + * Exit a parse tree produced by the {@code MemberReferenceExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void exitMemberReferenceExpression(CocoParser.MemberReferenceExpressionContext ctx); + /** + * Enter a parse tree produced by the {@code AssignmentExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void enterAssignmentExpression(CocoParser.AssignmentExpressionContext ctx); + /** + * Exit a parse tree produced by the {@code AssignmentExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void exitAssignmentExpression(CocoParser.AssignmentExpressionContext ctx); + /** + * Enter a parse tree produced by the {@code VariableReferenceExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void enterVariableReferenceExpression(CocoParser.VariableReferenceExpressionContext ctx); + /** + * Exit a parse tree produced by the {@code VariableReferenceExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void exitVariableReferenceExpression(CocoParser.VariableReferenceExpressionContext ctx); + /** + * Enter a parse tree produced by the {@code ImplicitMemberExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void enterImplicitMemberExpression(CocoParser.ImplicitMemberExpressionContext ctx); + /** + * Exit a parse tree produced by the {@code ImplicitMemberExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void exitImplicitMemberExpression(CocoParser.ImplicitMemberExpressionContext ctx); + /** + * Enter a parse tree produced by the {@code ExternalFunction} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void enterExternalFunction(CocoParser.ExternalFunctionContext ctx); + /** + * Exit a parse tree produced by the {@code ExternalFunction} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void exitExternalFunction(CocoParser.ExternalFunctionContext ctx); + /** + * Enter a parse tree produced by the {@code CastExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void enterCastExpression(CocoParser.CastExpressionContext ctx); + /** + * Exit a parse tree produced by the {@code CastExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void exitCastExpression(CocoParser.CastExpressionContext ctx); + /** + * Enter a parse tree produced by the {@code StateInvariantExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void enterStateInvariantExpression(CocoParser.StateInvariantExpressionContext ctx); + /** + * Exit a parse tree produced by the {@code StateInvariantExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void exitStateInvariantExpression(CocoParser.StateInvariantExpressionContext ctx); + /** + * Enter a parse tree produced by the {@code CallExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void enterCallExpression(CocoParser.CallExpressionContext ctx); + /** + * Exit a parse tree produced by the {@code CallExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void exitCallExpression(CocoParser.CallExpressionContext ctx); + /** + * Enter a parse tree produced by the {@code ExternalLiteral} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void enterExternalLiteral(CocoParser.ExternalLiteralContext ctx); + /** + * Exit a parse tree produced by the {@code ExternalLiteral} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void exitExternalLiteral(CocoParser.ExternalLiteralContext ctx); + /** + * Enter a parse tree produced by the {@code ArraySubscriptExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void enterArraySubscriptExpression(CocoParser.ArraySubscriptExpressionContext ctx); + /** + * Exit a parse tree produced by the {@code ArraySubscriptExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + */ + void exitArraySubscriptExpression(CocoParser.ArraySubscriptExpressionContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#blockExpression_}. + * @param ctx the parse tree + */ + void enterBlockExpression_(CocoParser.BlockExpression_Context ctx); + /** + * Exit a parse tree produced by {@link CocoParser#blockExpression_}. + * @param ctx the parse tree + */ + void exitBlockExpression_(CocoParser.BlockExpression_Context ctx); + /** + * Enter a parse tree produced by {@link CocoParser#ifExpression_}. + * @param ctx the parse tree + */ + void enterIfExpression_(CocoParser.IfExpression_Context ctx); + /** + * Exit a parse tree produced by {@link CocoParser#ifExpression_}. + * @param ctx the parse tree + */ + void exitIfExpression_(CocoParser.IfExpression_Context ctx); + /** + * Enter a parse tree produced by {@link CocoParser#matchExpression_}. + * @param ctx the parse tree + */ + void enterMatchExpression_(CocoParser.MatchExpression_Context ctx); + /** + * Exit a parse tree produced by {@link CocoParser#matchExpression_}. + * @param ctx the parse tree + */ + void exitMatchExpression_(CocoParser.MatchExpression_Context ctx); + /** + * Enter a parse tree produced by {@link CocoParser#nondetExpression_}. + * @param ctx the parse tree + */ + void enterNondetExpression_(CocoParser.NondetExpression_Context ctx); + /** + * Exit a parse tree produced by {@link CocoParser#nondetExpression_}. + * @param ctx the parse tree + */ + void exitNondetExpression_(CocoParser.NondetExpression_Context ctx); + /** + * Enter a parse tree produced by {@link CocoParser#fieldAssignments}. + * @param ctx the parse tree + */ + void enterFieldAssignments(CocoParser.FieldAssignmentsContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#fieldAssignments}. + * @param ctx the parse tree + */ + void exitFieldAssignments(CocoParser.FieldAssignmentsContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#fieldAssignment}. + * @param ctx the parse tree + */ + void enterFieldAssignment(CocoParser.FieldAssignmentContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#fieldAssignment}. + * @param ctx the parse tree + */ + void exitFieldAssignment(CocoParser.FieldAssignmentContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#nondetClauses}. + * @param ctx the parse tree + */ + void enterNondetClauses(CocoParser.NondetClausesContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#nondetClauses}. + * @param ctx the parse tree + */ + void exitNondetClauses(CocoParser.NondetClausesContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#nondetClause}. + * @param ctx the parse tree + */ + void enterNondetClause(CocoParser.NondetClauseContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#nondetClause}. + * @param ctx the parse tree + */ + void exitNondetClause(CocoParser.NondetClauseContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#matchClauses}. + * @param ctx the parse tree + */ + void enterMatchClauses(CocoParser.MatchClausesContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#matchClauses}. + * @param ctx the parse tree + */ + void exitMatchClauses(CocoParser.MatchClausesContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#matchClause}. + * @param ctx the parse tree + */ + void enterMatchClause(CocoParser.MatchClauseContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#matchClause}. + * @param ctx the parse tree + */ + void exitMatchClause(CocoParser.MatchClauseContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#pattern}. + * @param ctx the parse tree + */ + void enterPattern(CocoParser.PatternContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#pattern}. + * @param ctx the parse tree + */ + void exitPattern(CocoParser.PatternContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#enumCasePattern}. + * @param ctx the parse tree + */ + void enterEnumCasePattern(CocoParser.EnumCasePatternContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#enumCasePattern}. + * @param ctx the parse tree + */ + void exitEnumCasePattern(CocoParser.EnumCasePatternContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#idParameterPatterns}. + * @param ctx the parse tree + */ + void enterIdParameterPatterns(CocoParser.IdParameterPatternsContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#idParameterPatterns}. + * @param ctx the parse tree + */ + void exitIdParameterPatterns(CocoParser.IdParameterPatternsContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#idParameterPattern}. + * @param ctx the parse tree + */ + void enterIdParameterPattern(CocoParser.IdParameterPatternContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#idParameterPattern}. + * @param ctx the parse tree + */ + void exitIdParameterPattern(CocoParser.IdParameterPatternContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#variableDeclarationPattern}. + * @param ctx the parse tree + */ + void enterVariableDeclarationPattern(CocoParser.VariableDeclarationPatternContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#variableDeclarationPattern}. + * @param ctx the parse tree + */ + void exitVariableDeclarationPattern(CocoParser.VariableDeclarationPatternContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#parameterPatterns}. + * @param ctx the parse tree + */ + void enterParameterPatterns(CocoParser.ParameterPatternsContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#parameterPatterns}. + * @param ctx the parse tree + */ + void exitParameterPatterns(CocoParser.ParameterPatternsContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#parameterPattern}. + * @param ctx the parse tree + */ + void enterParameterPattern(CocoParser.ParameterPatternContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#parameterPattern}. + * @param ctx the parse tree + */ + void exitParameterPattern(CocoParser.ParameterPatternContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#expressions}. + * @param ctx the parse tree + */ + void enterExpressions(CocoParser.ExpressionsContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#expressions}. + * @param ctx the parse tree + */ + void exitExpressions(CocoParser.ExpressionsContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#statement}. + * @param ctx the parse tree + */ + void enterStatement(CocoParser.StatementContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#statement}. + * @param ctx the parse tree + */ + void exitStatement(CocoParser.StatementContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#declarationStatement}. + * @param ctx the parse tree + */ + void enterDeclarationStatement(CocoParser.DeclarationStatementContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#declarationStatement}. + * @param ctx the parse tree + */ + void exitDeclarationStatement(CocoParser.DeclarationStatementContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#returnStatement}. + * @param ctx the parse tree + */ + void enterReturnStatement(CocoParser.ReturnStatementContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#returnStatement}. + * @param ctx the parse tree + */ + void exitReturnStatement(CocoParser.ReturnStatementContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#becomeStatement}. + * @param ctx the parse tree + */ + void enterBecomeStatement(CocoParser.BecomeStatementContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#becomeStatement}. + * @param ctx the parse tree + */ + void exitBecomeStatement(CocoParser.BecomeStatementContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#whileStatement}. + * @param ctx the parse tree + */ + void enterWhileStatement(CocoParser.WhileStatementContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#whileStatement}. + * @param ctx the parse tree + */ + void exitWhileStatement(CocoParser.WhileStatementContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#forStatement}. + * @param ctx the parse tree + */ + void enterForStatement(CocoParser.ForStatementContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#forStatement}. + * @param ctx the parse tree + */ + void exitForStatement(CocoParser.ForStatementContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#breakStatement}. + * @param ctx the parse tree + */ + void enterBreakStatement(CocoParser.BreakStatementContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#breakStatement}. + * @param ctx the parse tree + */ + void exitBreakStatement(CocoParser.BreakStatementContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#continueStatement}. + * @param ctx the parse tree + */ + void enterContinueStatement(CocoParser.ContinueStatementContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#continueStatement}. + * @param ctx the parse tree + */ + void exitContinueStatement(CocoParser.ContinueStatementContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#portElement}. + * @param ctx the parse tree + */ + void enterPortElement(CocoParser.PortElementContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#portElement}. + * @param ctx the parse tree + */ + void exitPortElement(CocoParser.PortElementContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#functionInterfaceDeclaration}. + * @param ctx the parse tree + */ + void enterFunctionInterfaceDeclaration(CocoParser.FunctionInterfaceDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#functionInterfaceDeclaration}. + * @param ctx the parse tree + */ + void exitFunctionInterfaceDeclaration(CocoParser.FunctionInterfaceDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#signalDeclaration}. + * @param ctx the parse tree + */ + void enterSignalDeclaration(CocoParser.SignalDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#signalDeclaration}. + * @param ctx the parse tree + */ + void exitSignalDeclaration(CocoParser.SignalDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#stateMachineDeclaration}. + * @param ctx the parse tree + */ + void enterStateMachineDeclaration(CocoParser.StateMachineDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#stateMachineDeclaration}. + * @param ctx the parse tree + */ + void exitStateMachineDeclaration(CocoParser.StateMachineDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#stateMachineElement}. + * @param ctx the parse tree + */ + void enterStateMachineElement(CocoParser.StateMachineElementContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#stateMachineElement}. + * @param ctx the parse tree + */ + void exitStateMachineElement(CocoParser.StateMachineElementContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#stateDeclaration}. + * @param ctx the parse tree + */ + void enterStateDeclaration(CocoParser.StateDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#stateDeclaration}. + * @param ctx the parse tree + */ + void exitStateDeclaration(CocoParser.StateDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#eventStateDeclaration}. + * @param ctx the parse tree + */ + void enterEventStateDeclaration(CocoParser.EventStateDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#eventStateDeclaration}. + * @param ctx the parse tree + */ + void exitEventStateDeclaration(CocoParser.EventStateDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#executionStateDeclaration}. + * @param ctx the parse tree + */ + void enterExecutionStateDeclaration(CocoParser.ExecutionStateDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#executionStateDeclaration}. + * @param ctx the parse tree + */ + void exitExecutionStateDeclaration(CocoParser.ExecutionStateDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#eventStateElement}. + * @param ctx the parse tree + */ + void enterEventStateElement(CocoParser.EventStateElementContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#eventStateElement}. + * @param ctx the parse tree + */ + void exitEventStateElement(CocoParser.EventStateElementContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#entryFunctionDeclaration}. + * @param ctx the parse tree + */ + void enterEntryFunctionDeclaration(CocoParser.EntryFunctionDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#entryFunctionDeclaration}. + * @param ctx the parse tree + */ + void exitEntryFunctionDeclaration(CocoParser.EntryFunctionDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#exitFunctionDeclaration}. + * @param ctx the parse tree + */ + void enterExitFunctionDeclaration(CocoParser.ExitFunctionDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#exitFunctionDeclaration}. + * @param ctx the parse tree + */ + void exitExitFunctionDeclaration(CocoParser.ExitFunctionDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#stateInvariant}. + * @param ctx the parse tree + */ + void enterStateInvariant(CocoParser.StateInvariantContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#stateInvariant}. + * @param ctx the parse tree + */ + void exitStateInvariant(CocoParser.StateInvariantContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#transitionDeclaration}. + * @param ctx the parse tree + */ + void enterTransitionDeclaration(CocoParser.TransitionDeclarationContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#transitionDeclaration}. + * @param ctx the parse tree + */ + void exitTransitionDeclaration(CocoParser.TransitionDeclarationContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#eventTransition}. + * @param ctx the parse tree + */ + void enterEventTransition(CocoParser.EventTransitionContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#eventTransition}. + * @param ctx the parse tree + */ + void exitEventTransition(CocoParser.EventTransitionContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#eventSource}. + * @param ctx the parse tree + */ + void enterEventSource(CocoParser.EventSourceContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#eventSource}. + * @param ctx the parse tree + */ + void exitEventSource(CocoParser.EventSourceContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#spontaneousTransition}. + * @param ctx the parse tree + */ + void enterSpontaneousTransition(CocoParser.SpontaneousTransitionContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#spontaneousTransition}. + * @param ctx the parse tree + */ + void exitSpontaneousTransition(CocoParser.SpontaneousTransitionContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#timerTransition}. + * @param ctx the parse tree + */ + void enterTimerTransition(CocoParser.TimerTransitionContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#timerTransition}. + * @param ctx the parse tree + */ + void exitTimerTransition(CocoParser.TimerTransitionContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#eventHandler}. + * @param ctx the parse tree + */ + void enterEventHandler(CocoParser.EventHandlerContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#eventHandler}. + * @param ctx the parse tree + */ + void exitEventHandler(CocoParser.EventHandlerContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#offer}. + * @param ctx the parse tree + */ + void enterOffer(CocoParser.OfferContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#offer}. + * @param ctx the parse tree + */ + void exitOffer(CocoParser.OfferContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#offerClauses}. + * @param ctx the parse tree + */ + void enterOfferClauses(CocoParser.OfferClausesContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#offerClauses}. + * @param ctx the parse tree + */ + void exitOfferClauses(CocoParser.OfferClausesContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#offerClause}. + * @param ctx the parse tree + */ + void enterOfferClause(CocoParser.OfferClauseContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#offerClause}. + * @param ctx the parse tree + */ + void exitOfferClause(CocoParser.OfferClauseContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#parameters}. + * @param ctx the parse tree + */ + void enterParameters(CocoParser.ParametersContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#parameters}. + * @param ctx the parse tree + */ + void exitParameters(CocoParser.ParametersContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#parameter}. + * @param ctx the parse tree + */ + void enterParameter(CocoParser.ParameterContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#parameter}. + * @param ctx the parse tree + */ + void exitParameter(CocoParser.ParameterContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#literalExpression_}. + * @param ctx the parse tree + */ + void enterLiteralExpression_(CocoParser.LiteralExpression_Context ctx); + /** + * Exit a parse tree produced by {@link CocoParser#literalExpression_}. + * @param ctx the parse tree + */ + void exitLiteralExpression_(CocoParser.LiteralExpression_Context ctx); + /** + * Enter a parse tree produced by the {@code BinaryType} + * labeled alternative in {@link CocoParser#type}. + * @param ctx the parse tree + */ + void enterBinaryType(CocoParser.BinaryTypeContext ctx); + /** + * Exit a parse tree produced by the {@code BinaryType} + * labeled alternative in {@link CocoParser#type}. + * @param ctx the parse tree + */ + void exitBinaryType(CocoParser.BinaryTypeContext ctx); + /** + * Enter a parse tree produced by the {@code GroupType} + * labeled alternative in {@link CocoParser#type}. + * @param ctx the parse tree + */ + void enterGroupType(CocoParser.GroupTypeContext ctx); + /** + * Exit a parse tree produced by the {@code GroupType} + * labeled alternative in {@link CocoParser#type}. + * @param ctx the parse tree + */ + void exitGroupType(CocoParser.GroupTypeContext ctx); + /** + * Enter a parse tree produced by the {@code FunctionType} + * labeled alternative in {@link CocoParser#type}. + * @param ctx the parse tree + */ + void enterFunctionType(CocoParser.FunctionTypeContext ctx); + /** + * Exit a parse tree produced by the {@code FunctionType} + * labeled alternative in {@link CocoParser#type}. + * @param ctx the parse tree + */ + void exitFunctionType(CocoParser.FunctionTypeContext ctx); + /** + * Enter a parse tree produced by the {@code UnaryType} + * labeled alternative in {@link CocoParser#type}. + * @param ctx the parse tree + */ + void enterUnaryType(CocoParser.UnaryTypeContext ctx); + /** + * Exit a parse tree produced by the {@code UnaryType} + * labeled alternative in {@link CocoParser#type}. + * @param ctx the parse tree + */ + void exitUnaryType(CocoParser.UnaryTypeContext ctx); + /** + * Enter a parse tree produced by the {@code LiteralType} + * labeled alternative in {@link CocoParser#type}. + * @param ctx the parse tree + */ + void enterLiteralType(CocoParser.LiteralTypeContext ctx); + /** + * Exit a parse tree produced by the {@code LiteralType} + * labeled alternative in {@link CocoParser#type}. + * @param ctx the parse tree + */ + void exitLiteralType(CocoParser.LiteralTypeContext ctx); + /** + * Enter a parse tree produced by the {@code TypeReference} + * labeled alternative in {@link CocoParser#type}. + * @param ctx the parse tree + */ + void enterTypeReference(CocoParser.TypeReferenceContext ctx); + /** + * Exit a parse tree produced by the {@code TypeReference} + * labeled alternative in {@link CocoParser#type}. + * @param ctx the parse tree + */ + void exitTypeReference(CocoParser.TypeReferenceContext ctx); + /** + * Enter a parse tree produced by the {@code ReferenceType} + * labeled alternative in {@link CocoParser#type}. + * @param ctx the parse tree + */ + void enterReferenceType(CocoParser.ReferenceTypeContext ctx); + /** + * Exit a parse tree produced by the {@code ReferenceType} + * labeled alternative in {@link CocoParser#type}. + * @param ctx the parse tree + */ + void exitReferenceType(CocoParser.ReferenceTypeContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#types}. + * @param ctx the parse tree + */ + void enterTypes(CocoParser.TypesContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#types}. + * @param ctx the parse tree + */ + void exitTypes(CocoParser.TypesContext ctx); + /** + * Enter a parse tree produced by {@link CocoParser#dotIdentifierList}. + * @param ctx the parse tree + */ + void enterDotIdentifierList(CocoParser.DotIdentifierListContext ctx); + /** + * Exit a parse tree produced by {@link CocoParser#dotIdentifierList}. + * @param ctx the parse tree + */ + void exitDotIdentifierList(CocoParser.DotIdentifierListContext ctx); +} diff --git a/pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoParser.java b/pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoParser.java new file mode 100644 index 00000000000..a091be9d24b --- /dev/null +++ b/pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoParser.java @@ -0,0 +1,8678 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +// CHECKSTYLE:OFF +// Generated from net/sourceforge/pmd/lang/coco/ast/Coco.g4 by ANTLR 4.9.3 +package net.sourceforge.pmd.lang.coco.ast; + +import java.util.List; + +import org.antlr.v4.runtime.FailedPredicateException; +import org.antlr.v4.runtime.NoViableAltException; +import org.antlr.v4.runtime.Parser; +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.RuleContext; +import org.antlr.v4.runtime.RuntimeMetaData; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.Vocabulary; +import org.antlr.v4.runtime.VocabularyImpl; +import org.antlr.v4.runtime.atn.ATN; +import org.antlr.v4.runtime.atn.ATNDeserializer; +import org.antlr.v4.runtime.atn.ParserATNSimulator; +import org.antlr.v4.runtime.atn.PredictionContextCache; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.tree.ParseTreeListener; +import org.antlr.v4.runtime.tree.ParseTreeVisitor; +import org.antlr.v4.runtime.tree.TerminalNode; + +/** + * @deprecated Since 7.8.0. This class was never intended to be generated. It will be removed with no replacement. + */ +@Deprecated +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) +@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public class CocoParser extends Parser { + static { RuntimeMetaData.checkVersion("4.9.3", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + AFTER=1, AS=2, ASSERT=3, ATTRIBUTE=4, BECOME=5, BREAK=6, CASE=7, COMPONENT=8, + CONTINUE=9, ELSE=10, ENUM=11, ENTRY=12, EXECUTION=13, EXIT=14, EXTERNAL=15, + FINAL=16, FOR=17, FUNCTION=18, IF=19, ILLEGAL=20, IMPORT=21, IN=22, INIT=23, + INSTANCE=24, MACHINE=25, MATCH=26, MUT=27, MUTATING=28, NONDET=29, OFFER=30, + OPTIONAL=31, OTHERWISE=32, OUT=33, OUTGOING=34, PERIODIC=35, PORT=36, + PRIVATE=37, RETURN=38, SIGNAL=39, SPONTANEOUS=40, STATE=41, STATIC=42, + STRUCT=43, TYPE=44, UNQUALIFIED=45, VAL=46, VAR=47, WHERE=48, WHILE=49, + IDENTIFIER=50, AT=51, ASSIGN=52, COLON=53, LP=54, RP=55, LC=56, RC=57, + LB=58, RB=59, COMMA=60, SEMI=61, DOT=62, LT=63, GT=64, MUL=65, DIV=66, + MINUS=67, MOD=68, PLUS=69, IMPL=70, ARROW=71, AMP=72, QM=73, PIPE=74, + EXCL=75, ELLIP=76, EQ=77, NE=78, OR=79, AND=80, LE=81, GE=82, WHITESPACE=83, + NEWLINE=84, LINE_COMMENT=85, BLOCK_COMMENT=86, INTEGER=87, BACKTICK_LITERAL=88, + CHAR_LITERAL=89, STRING_LITERAL=90; + public static final int + RULE_module = 0, RULE_declaration = 1, RULE_attribute = 2, RULE_attributeDeclaration = 3, + RULE_importDeclaration = 4, RULE_variableDeclaration = 5, RULE_enumDeclaration = 6, + RULE_structDeclaration = 7, RULE_typeAliasDeclaration = 8, RULE_functionDeclaration = 9, + RULE_instanceDeclaration = 10, RULE_portDeclaration = 11, RULE_componentDeclaration = 12, + RULE_externalConstantDeclaration = 13, RULE_externalTypeDeclaration = 14, + RULE_externalTypeElement = 15, RULE_externalFunctionDeclaration = 16, + RULE_genericTypeDeclaration = 17, RULE_genericTypes = 18, RULE_genericType = 19, + RULE_enumElement = 20, RULE_enumCase = 21, RULE_caseParameters = 22, RULE_caseParameter = 23, + RULE_structElement = 24, RULE_fieldDeclaration = 25, RULE_componentElement = 26, + RULE_staticMemberDeclaration = 27, RULE_constructorDeclaration = 28, RULE_expression = 29, + RULE_blockExpression_ = 30, RULE_ifExpression_ = 31, RULE_matchExpression_ = 32, + RULE_nondetExpression_ = 33, RULE_fieldAssignments = 34, RULE_fieldAssignment = 35, + RULE_nondetClauses = 36, RULE_nondetClause = 37, RULE_matchClauses = 38, + RULE_matchClause = 39, RULE_pattern = 40, RULE_enumCasePattern = 41, RULE_idParameterPatterns = 42, + RULE_idParameterPattern = 43, RULE_variableDeclarationPattern = 44, RULE_parameterPatterns = 45, + RULE_parameterPattern = 46, RULE_expressions = 47, RULE_statement = 48, + RULE_declarationStatement = 49, RULE_returnStatement = 50, RULE_becomeStatement = 51, + RULE_whileStatement = 52, RULE_forStatement = 53, RULE_breakStatement = 54, + RULE_continueStatement = 55, RULE_portElement = 56, RULE_functionInterfaceDeclaration = 57, + RULE_signalDeclaration = 58, RULE_stateMachineDeclaration = 59, RULE_stateMachineElement = 60, + RULE_stateDeclaration = 61, RULE_eventStateDeclaration = 62, RULE_executionStateDeclaration = 63, + RULE_eventStateElement = 64, RULE_entryFunctionDeclaration = 65, RULE_exitFunctionDeclaration = 66, + RULE_stateInvariant = 67, RULE_transitionDeclaration = 68, RULE_eventTransition = 69, + RULE_eventSource = 70, RULE_spontaneousTransition = 71, RULE_timerTransition = 72, + RULE_eventHandler = 73, RULE_offer = 74, RULE_offerClauses = 75, RULE_offerClause = 76, + RULE_parameters = 77, RULE_parameter = 78, RULE_literalExpression_ = 79, + RULE_type = 80, RULE_types = 81, RULE_dotIdentifierList = 82; + private static String[] makeRuleNames() { + return new String[] { + "module", "declaration", "attribute", "attributeDeclaration", "importDeclaration", + "variableDeclaration", "enumDeclaration", "structDeclaration", "typeAliasDeclaration", + "functionDeclaration", "instanceDeclaration", "portDeclaration", "componentDeclaration", + "externalConstantDeclaration", "externalTypeDeclaration", "externalTypeElement", + "externalFunctionDeclaration", "genericTypeDeclaration", "genericTypes", + "genericType", "enumElement", "enumCase", "caseParameters", "caseParameter", + "structElement", "fieldDeclaration", "componentElement", "staticMemberDeclaration", + "constructorDeclaration", "expression", "blockExpression_", "ifExpression_", + "matchExpression_", "nondetExpression_", "fieldAssignments", "fieldAssignment", + "nondetClauses", "nondetClause", "matchClauses", "matchClause", "pattern", + "enumCasePattern", "idParameterPatterns", "idParameterPattern", "variableDeclarationPattern", + "parameterPatterns", "parameterPattern", "expressions", "statement", + "declarationStatement", "returnStatement", "becomeStatement", "whileStatement", + "forStatement", "breakStatement", "continueStatement", "portElement", + "functionInterfaceDeclaration", "signalDeclaration", "stateMachineDeclaration", + "stateMachineElement", "stateDeclaration", "eventStateDeclaration", "executionStateDeclaration", + "eventStateElement", "entryFunctionDeclaration", "exitFunctionDeclaration", + "stateInvariant", "transitionDeclaration", "eventTransition", "eventSource", + "spontaneousTransition", "timerTransition", "eventHandler", "offer", + "offerClauses", "offerClause", "parameters", "parameter", "literalExpression_", + "type", "types", "dotIdentifierList" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, "'after'", "'as'", "'assert'", "'attribute'", "'become'", "'break'", + "'case'", "'component'", "'continue'", "'else'", "'enum'", "'entry'", + "'execution'", "'exit'", "'external'", "'final'", "'for'", "'function'", + "'if'", "'illegal'", "'import'", "'in'", "'init'", "'instance'", "'machine'", + "'match'", "'mut'", "'mutating'", "'nondet'", "'offer'", "'optional'", + "'otherwise'", "'out'", "'outgoing'", "'periodic'", "'port'", "'private'", + "'return'", "'signal'", "'spontaneous'", "'state'", "'static'", "'struct'", + "'type'", "'unqualified'", "'val'", "'var'", "'where'", "'while'", null, + "'@'", "'='", "':'", "'('", "')'", "'{'", "'}'", "'['", "']'", "','", + "';'", "'.'", "'<'", "'>'", "'*'", "'/'", "'-'", "'%'", "'+'", "'=>'", + "'->'", "'&'", "'?'", "'|'", "'!'", "'...'", "'=='", "'!='", "'||'", + "'&&'", "'<='", "'>='" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, "AFTER", "AS", "ASSERT", "ATTRIBUTE", "BECOME", "BREAK", "CASE", + "COMPONENT", "CONTINUE", "ELSE", "ENUM", "ENTRY", "EXECUTION", "EXIT", + "EXTERNAL", "FINAL", "FOR", "FUNCTION", "IF", "ILLEGAL", "IMPORT", "IN", + "INIT", "INSTANCE", "MACHINE", "MATCH", "MUT", "MUTATING", "NONDET", + "OFFER", "OPTIONAL", "OTHERWISE", "OUT", "OUTGOING", "PERIODIC", "PORT", + "PRIVATE", "RETURN", "SIGNAL", "SPONTANEOUS", "STATE", "STATIC", "STRUCT", + "TYPE", "UNQUALIFIED", "VAL", "VAR", "WHERE", "WHILE", "IDENTIFIER", + "AT", "ASSIGN", "COLON", "LP", "RP", "LC", "RC", "LB", "RB", "COMMA", + "SEMI", "DOT", "LT", "GT", "MUL", "DIV", "MINUS", "MOD", "PLUS", "IMPL", + "ARROW", "AMP", "QM", "PIPE", "EXCL", "ELLIP", "EQ", "NE", "OR", "AND", + "LE", "GE", "WHITESPACE", "NEWLINE", "LINE_COMMENT", "BLOCK_COMMENT", + "INTEGER", "BACKTICK_LITERAL", "CHAR_LITERAL", "STRING_LITERAL" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + @Override + public String getGrammarFileName() { return "Coco.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public ATN getATN() { return _ATN; } + + public CocoParser(TokenStream input) { + super(input); + _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ModuleContext extends ParserRuleContext { + public TerminalNode EOF() { return getToken(CocoParser.EOF, 0); } + public List declaration() { + return getRuleContexts(DeclarationContext.class); + } + public DeclarationContext declaration(int i) { + return getRuleContext(DeclarationContext.class,i); + } + public ModuleContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_module; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterModule(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitModule(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitModule(this); + else return visitor.visitChildren(this); + } + } + + public final ModuleContext module() throws RecognitionException { + ModuleContext _localctx = new ModuleContext(_ctx, getState()); + enterRule(_localctx, 0, RULE_module); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(169); + _errHandler.sync(this); + _la = _input.LA(1); + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ATTRIBUTE) | (1L << COMPONENT) | (1L << ENUM) | (1L << EXTERNAL) | (1L << FUNCTION) | (1L << IMPORT) | (1L << INSTANCE) | (1L << PORT) | (1L << PRIVATE) | (1L << STRUCT) | (1L << TYPE) | (1L << VAL) | (1L << VAR) | (1L << AT))) != 0)) { + { + { + setState(166); + declaration(); + } + } + setState(171); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(172); + match(EOF); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class DeclarationContext extends ParserRuleContext { + public ImportDeclarationContext importDeclaration() { + return getRuleContext(ImportDeclarationContext.class,0); + } + public VariableDeclarationContext variableDeclaration() { + return getRuleContext(VariableDeclarationContext.class,0); + } + public EnumDeclarationContext enumDeclaration() { + return getRuleContext(EnumDeclarationContext.class,0); + } + public StructDeclarationContext structDeclaration() { + return getRuleContext(StructDeclarationContext.class,0); + } + public TypeAliasDeclarationContext typeAliasDeclaration() { + return getRuleContext(TypeAliasDeclarationContext.class,0); + } + public FunctionDeclarationContext functionDeclaration() { + return getRuleContext(FunctionDeclarationContext.class,0); + } + public InstanceDeclarationContext instanceDeclaration() { + return getRuleContext(InstanceDeclarationContext.class,0); + } + public PortDeclarationContext portDeclaration() { + return getRuleContext(PortDeclarationContext.class,0); + } + public ComponentDeclarationContext componentDeclaration() { + return getRuleContext(ComponentDeclarationContext.class,0); + } + public ExternalConstantDeclarationContext externalConstantDeclaration() { + return getRuleContext(ExternalConstantDeclarationContext.class,0); + } + public ExternalFunctionDeclarationContext externalFunctionDeclaration() { + return getRuleContext(ExternalFunctionDeclarationContext.class,0); + } + public ExternalTypeDeclarationContext externalTypeDeclaration() { + return getRuleContext(ExternalTypeDeclarationContext.class,0); + } + public AttributeDeclarationContext attributeDeclaration() { + return getRuleContext(AttributeDeclarationContext.class,0); + } + public List attribute() { + return getRuleContexts(AttributeContext.class); + } + public AttributeContext attribute(int i) { + return getRuleContext(AttributeContext.class,i); + } + public DeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_declaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final DeclarationContext declaration() throws RecognitionException { + DeclarationContext _localctx = new DeclarationContext(_ctx, getState()); + enterRule(_localctx, 2, RULE_declaration); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(177); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==AT) { + { + { + setState(174); + attribute(); + } + } + setState(179); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(193); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,2,_ctx) ) { + case 1: + { + setState(180); + importDeclaration(); + } + break; + case 2: + { + setState(181); + variableDeclaration(); + } + break; + case 3: + { + setState(182); + enumDeclaration(); + } + break; + case 4: + { + setState(183); + structDeclaration(); + } + break; + case 5: + { + setState(184); + typeAliasDeclaration(); + } + break; + case 6: + { + setState(185); + functionDeclaration(); + } + break; + case 7: + { + setState(186); + instanceDeclaration(); + } + break; + case 8: + { + setState(187); + portDeclaration(); + } + break; + case 9: + { + setState(188); + componentDeclaration(); + } + break; + case 10: + { + setState(189); + externalConstantDeclaration(); + } + break; + case 11: + { + setState(190); + externalFunctionDeclaration(); + } + break; + case 12: + { + setState(191); + externalTypeDeclaration(); + } + break; + case 13: + { + setState(192); + attributeDeclaration(); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class AttributeContext extends ParserRuleContext { + public TerminalNode AT() { return getToken(CocoParser.AT, 0); } + public DotIdentifierListContext dotIdentifierList() { + return getRuleContext(DotIdentifierListContext.class,0); + } + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public ExpressionsContext expressions() { + return getRuleContext(ExpressionsContext.class,0); + } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public AttributeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_attribute; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterAttribute(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitAttribute(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitAttribute(this); + else return visitor.visitChildren(this); + } + } + + public final AttributeContext attribute() throws RecognitionException { + AttributeContext _localctx = new AttributeContext(_ctx, getState()); + enterRule(_localctx, 4, RULE_attribute); + try { + enterOuterAlt(_localctx, 1); + { + setState(195); + match(AT); + setState(196); + dotIdentifierList(); + setState(201); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,3,_ctx) ) { + case 1: + { + setState(197); + match(LP); + setState(198); + expressions(); + setState(199); + match(RP); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class AttributeDeclarationContext extends ParserRuleContext { + public TerminalNode ATTRIBUTE() { return getToken(CocoParser.ATTRIBUTE, 0); } + public TerminalNode AT() { return getToken(CocoParser.AT, 0); } + public DotIdentifierListContext dotIdentifierList() { + return getRuleContext(DotIdentifierListContext.class,0); + } + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public ParametersContext parameters() { + return getRuleContext(ParametersContext.class,0); + } + public AttributeDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_attributeDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterAttributeDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitAttributeDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitAttributeDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final AttributeDeclarationContext attributeDeclaration() throws RecognitionException { + AttributeDeclarationContext _localctx = new AttributeDeclarationContext(_ctx, getState()); + enterRule(_localctx, 6, RULE_attributeDeclaration); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(203); + match(ATTRIBUTE); + setState(204); + match(AT); + setState(205); + dotIdentifierList(); + setState(211); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==LP) { + { + setState(206); + match(LP); + setState(208); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==VAR || _la==IDENTIFIER) { + { + setState(207); + parameters(); + } + } + + setState(210); + match(RP); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ImportDeclarationContext extends ParserRuleContext { + public TerminalNode IMPORT() { return getToken(CocoParser.IMPORT, 0); } + public DotIdentifierListContext dotIdentifierList() { + return getRuleContext(DotIdentifierListContext.class,0); + } + public TerminalNode UNQUALIFIED() { return getToken(CocoParser.UNQUALIFIED, 0); } + public TerminalNode AS() { return getToken(CocoParser.AS, 0); } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public ImportDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_importDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterImportDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitImportDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitImportDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final ImportDeclarationContext importDeclaration() throws RecognitionException { + ImportDeclarationContext _localctx = new ImportDeclarationContext(_ctx, getState()); + enterRule(_localctx, 8, RULE_importDeclaration); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(213); + match(IMPORT); + setState(215); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==UNQUALIFIED) { + { + setState(214); + match(UNQUALIFIED); + } + } + + setState(217); + dotIdentifierList(); + setState(220); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==AS) { + { + setState(218); + match(AS); + setState(219); + match(IDENTIFIER); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class VariableDeclarationContext extends ParserRuleContext { + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode VAR() { return getToken(CocoParser.VAR, 0); } + public TerminalNode VAL() { return getToken(CocoParser.VAL, 0); } + public TerminalNode PRIVATE() { return getToken(CocoParser.PRIVATE, 0); } + public GenericTypeDeclarationContext genericTypeDeclaration() { + return getRuleContext(GenericTypeDeclarationContext.class,0); + } + public TerminalNode COLON() { return getToken(CocoParser.COLON, 0); } + public TypeContext type() { + return getRuleContext(TypeContext.class,0); + } + public TerminalNode ASSIGN() { return getToken(CocoParser.ASSIGN, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public VariableDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_variableDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterVariableDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitVariableDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitVariableDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final VariableDeclarationContext variableDeclaration() throws RecognitionException { + VariableDeclarationContext _localctx = new VariableDeclarationContext(_ctx, getState()); + enterRule(_localctx, 10, RULE_variableDeclaration); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(223); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==PRIVATE) { + { + setState(222); + match(PRIVATE); + } + } + + setState(225); + _la = _input.LA(1); + if ( !(_la==VAL || _la==VAR) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(226); + match(IDENTIFIER); + setState(228); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==LT) { + { + setState(227); + genericTypeDeclaration(); + } + } + + setState(232); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COLON) { + { + setState(230); + match(COLON); + setState(231); + type(0); + } + } + + setState(236); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==ASSIGN) { + { + setState(234); + match(ASSIGN); + setState(235); + expression(0); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class EnumDeclarationContext extends ParserRuleContext { + public TerminalNode ENUM() { return getToken(CocoParser.ENUM, 0); } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode LC() { return getToken(CocoParser.LC, 0); } + public TerminalNode RC() { return getToken(CocoParser.RC, 0); } + public GenericTypeDeclarationContext genericTypeDeclaration() { + return getRuleContext(GenericTypeDeclarationContext.class,0); + } + public List enumElement() { + return getRuleContexts(EnumElementContext.class); + } + public EnumElementContext enumElement(int i) { + return getRuleContext(EnumElementContext.class,i); + } + public EnumDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_enumDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterEnumDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitEnumDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitEnumDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final EnumDeclarationContext enumDeclaration() throws RecognitionException { + EnumDeclarationContext _localctx = new EnumDeclarationContext(_ctx, getState()); + enterRule(_localctx, 12, RULE_enumDeclaration); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(238); + match(ENUM); + setState(239); + match(IDENTIFIER); + setState(241); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==LT) { + { + setState(240); + genericTypeDeclaration(); + } + } + + setState(243); + match(LC); + setState(247); + _errHandler.sync(this); + _la = _input.LA(1); + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << CASE) | (1L << FUNCTION) | (1L << MUT) | (1L << MUTATING) | (1L << STATIC))) != 0)) { + { + { + setState(244); + enumElement(); + } + } + setState(249); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(250); + match(RC); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class StructDeclarationContext extends ParserRuleContext { + public TerminalNode STRUCT() { return getToken(CocoParser.STRUCT, 0); } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode LC() { return getToken(CocoParser.LC, 0); } + public TerminalNode RC() { return getToken(CocoParser.RC, 0); } + public GenericTypeDeclarationContext genericTypeDeclaration() { + return getRuleContext(GenericTypeDeclarationContext.class,0); + } + public List structElement() { + return getRuleContexts(StructElementContext.class); + } + public StructElementContext structElement(int i) { + return getRuleContext(StructElementContext.class,i); + } + public StructDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_structDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterStructDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitStructDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitStructDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final StructDeclarationContext structDeclaration() throws RecognitionException { + StructDeclarationContext _localctx = new StructDeclarationContext(_ctx, getState()); + enterRule(_localctx, 14, RULE_structDeclaration); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(252); + match(STRUCT); + setState(253); + match(IDENTIFIER); + setState(255); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==LT) { + { + setState(254); + genericTypeDeclaration(); + } + } + + setState(257); + match(LC); + setState(261); + _errHandler.sync(this); + _la = _input.LA(1); + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << FUNCTION) | (1L << MUT) | (1L << MUTATING) | (1L << STATIC) | (1L << VAL) | (1L << VAR) | (1L << IDENTIFIER))) != 0)) { + { + { + setState(258); + structElement(); + } + } + setState(263); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(264); + match(RC); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class TypeAliasDeclarationContext extends ParserRuleContext { + public TerminalNode TYPE() { return getToken(CocoParser.TYPE, 0); } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode ASSIGN() { return getToken(CocoParser.ASSIGN, 0); } + public TypeContext type() { + return getRuleContext(TypeContext.class,0); + } + public GenericTypeDeclarationContext genericTypeDeclaration() { + return getRuleContext(GenericTypeDeclarationContext.class,0); + } + public TypeAliasDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_typeAliasDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterTypeAliasDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitTypeAliasDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitTypeAliasDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final TypeAliasDeclarationContext typeAliasDeclaration() throws RecognitionException { + TypeAliasDeclarationContext _localctx = new TypeAliasDeclarationContext(_ctx, getState()); + enterRule(_localctx, 16, RULE_typeAliasDeclaration); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(266); + match(TYPE); + setState(267); + match(IDENTIFIER); + setState(269); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==LT) { + { + setState(268); + genericTypeDeclaration(); + } + } + + setState(271); + match(ASSIGN); + setState(272); + type(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class FunctionDeclarationContext extends ParserRuleContext { + public TerminalNode FUNCTION() { return getToken(CocoParser.FUNCTION, 0); } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public TerminalNode COLON() { return getToken(CocoParser.COLON, 0); } + public TypeContext type() { + return getRuleContext(TypeContext.class,0); + } + public TerminalNode ASSIGN() { return getToken(CocoParser.ASSIGN, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public GenericTypeDeclarationContext genericTypeDeclaration() { + return getRuleContext(GenericTypeDeclarationContext.class,0); + } + public ParametersContext parameters() { + return getRuleContext(ParametersContext.class,0); + } + public FunctionDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_functionDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterFunctionDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitFunctionDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitFunctionDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final FunctionDeclarationContext functionDeclaration() throws RecognitionException { + FunctionDeclarationContext _localctx = new FunctionDeclarationContext(_ctx, getState()); + enterRule(_localctx, 18, RULE_functionDeclaration); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(274); + match(FUNCTION); + setState(275); + match(IDENTIFIER); + setState(277); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==LT) { + { + setState(276); + genericTypeDeclaration(); + } + } + + setState(279); + match(LP); + setState(281); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==VAR || _la==IDENTIFIER) { + { + setState(280); + parameters(); + } + } + + setState(283); + match(RP); + setState(284); + match(COLON); + setState(285); + type(0); + setState(286); + match(ASSIGN); + setState(287); + expression(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class InstanceDeclarationContext extends ParserRuleContext { + public TerminalNode INSTANCE() { return getToken(CocoParser.INSTANCE, 0); } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public ParametersContext parameters() { + return getRuleContext(ParametersContext.class,0); + } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public BlockExpression_Context blockExpression_() { + return getRuleContext(BlockExpression_Context.class,0); + } + public GenericTypeDeclarationContext genericTypeDeclaration() { + return getRuleContext(GenericTypeDeclarationContext.class,0); + } + public InstanceDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_instanceDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterInstanceDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitInstanceDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitInstanceDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final InstanceDeclarationContext instanceDeclaration() throws RecognitionException { + InstanceDeclarationContext _localctx = new InstanceDeclarationContext(_ctx, getState()); + enterRule(_localctx, 20, RULE_instanceDeclaration); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(289); + match(INSTANCE); + setState(290); + match(IDENTIFIER); + setState(292); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==LT) { + { + setState(291); + genericTypeDeclaration(); + } + } + + setState(294); + match(LP); + setState(295); + parameters(); + setState(296); + match(RP); + setState(297); + blockExpression_(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class PortDeclarationContext extends ParserRuleContext { + public TerminalNode PORT() { return getToken(CocoParser.PORT, 0); } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode LC() { return getToken(CocoParser.LC, 0); } + public TerminalNode RC() { return getToken(CocoParser.RC, 0); } + public TerminalNode COLON() { return getToken(CocoParser.COLON, 0); } + public TypesContext types() { + return getRuleContext(TypesContext.class,0); + } + public TerminalNode FINAL() { return getToken(CocoParser.FINAL, 0); } + public List portElement() { + return getRuleContexts(PortElementContext.class); + } + public PortElementContext portElement(int i) { + return getRuleContext(PortElementContext.class,i); + } + public PortDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_portDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterPortDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitPortDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitPortDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final PortDeclarationContext portDeclaration() throws RecognitionException { + PortDeclarationContext _localctx = new PortDeclarationContext(_ctx, getState()); + enterRule(_localctx, 22, RULE_portDeclaration); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(299); + match(PORT); + setState(300); + match(IDENTIFIER); + setState(303); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COLON) { + { + setState(301); + match(COLON); + setState(302); + types(); + } + } + + setState(306); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==FINAL) { + { + setState(305); + match(FINAL); + } + } + + setState(308); + match(LC); + setState(312); + _errHandler.sync(this); + _la = _input.LA(1); + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ENUM) | (1L << EXTERNAL) | (1L << FUNCTION) | (1L << MACHINE) | (1L << OUTGOING) | (1L << PORT) | (1L << STATIC) | (1L << STRUCT) | (1L << TYPE) | (1L << VAL) | (1L << VAR) | (1L << IDENTIFIER) | (1L << AT))) != 0)) { + { + { + setState(309); + portElement(); + } + } + setState(314); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(315); + match(RC); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ComponentDeclarationContext extends ParserRuleContext { + public TerminalNode COMPONENT() { return getToken(CocoParser.COMPONENT, 0); } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode LC() { return getToken(CocoParser.LC, 0); } + public TerminalNode RC() { return getToken(CocoParser.RC, 0); } + public TerminalNode EXTERNAL() { return getToken(CocoParser.EXTERNAL, 0); } + public TerminalNode COLON() { return getToken(CocoParser.COLON, 0); } + public TypeContext type() { + return getRuleContext(TypeContext.class,0); + } + public List componentElement() { + return getRuleContexts(ComponentElementContext.class); + } + public ComponentElementContext componentElement(int i) { + return getRuleContext(ComponentElementContext.class,i); + } + public ComponentDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_componentDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterComponentDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitComponentDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitComponentDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final ComponentDeclarationContext componentDeclaration() throws RecognitionException { + ComponentDeclarationContext _localctx = new ComponentDeclarationContext(_ctx, getState()); + enterRule(_localctx, 24, RULE_componentDeclaration); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(318); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==EXTERNAL) { + { + setState(317); + match(EXTERNAL); + } + } + + setState(320); + match(COMPONENT); + setState(321); + match(IDENTIFIER); + setState(324); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COLON) { + { + setState(322); + match(COLON); + setState(323); + type(0); + } + } + + setState(326); + match(LC); + setState(330); + _errHandler.sync(this); + _la = _input.LA(1); + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << INIT) | (1L << MACHINE) | (1L << PRIVATE) | (1L << STATIC) | (1L << VAL) | (1L << VAR) | (1L << IDENTIFIER) | (1L << AT))) != 0)) { + { + { + setState(327); + componentElement(); + } + } + setState(332); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(333); + match(RC); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ExternalConstantDeclarationContext extends ParserRuleContext { + public TerminalNode EXTERNAL() { return getToken(CocoParser.EXTERNAL, 0); } + public TerminalNode VAL() { return getToken(CocoParser.VAL, 0); } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode COLON() { return getToken(CocoParser.COLON, 0); } + public TypeContext type() { + return getRuleContext(TypeContext.class,0); + } + public TerminalNode ASSIGN() { return getToken(CocoParser.ASSIGN, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public ExternalConstantDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_externalConstantDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterExternalConstantDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitExternalConstantDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitExternalConstantDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final ExternalConstantDeclarationContext externalConstantDeclaration() throws RecognitionException { + ExternalConstantDeclarationContext _localctx = new ExternalConstantDeclarationContext(_ctx, getState()); + enterRule(_localctx, 26, RULE_externalConstantDeclaration); + try { + enterOuterAlt(_localctx, 1); + { + setState(335); + match(EXTERNAL); + setState(336); + match(VAL); + setState(337); + match(IDENTIFIER); + setState(338); + match(COLON); + setState(339); + type(0); + setState(340); + match(ASSIGN); + setState(341); + expression(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ExternalTypeDeclarationContext extends ParserRuleContext { + public TerminalNode EXTERNAL() { return getToken(CocoParser.EXTERNAL, 0); } + public TerminalNode TYPE() { return getToken(CocoParser.TYPE, 0); } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode LC() { return getToken(CocoParser.LC, 0); } + public TerminalNode RC() { return getToken(CocoParser.RC, 0); } + public List externalTypeElement() { + return getRuleContexts(ExternalTypeElementContext.class); + } + public ExternalTypeElementContext externalTypeElement(int i) { + return getRuleContext(ExternalTypeElementContext.class,i); + } + public ExternalTypeDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_externalTypeDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterExternalTypeDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitExternalTypeDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitExternalTypeDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final ExternalTypeDeclarationContext externalTypeDeclaration() throws RecognitionException { + ExternalTypeDeclarationContext _localctx = new ExternalTypeDeclarationContext(_ctx, getState()); + enterRule(_localctx, 28, RULE_externalTypeDeclaration); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(343); + match(EXTERNAL); + setState(344); + match(TYPE); + setState(345); + match(IDENTIFIER); + setState(354); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==LC) { + { + setState(346); + match(LC); + setState(350); + _errHandler.sync(this); + _la = _input.LA(1); + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << EXTERNAL) | (1L << MUT) | (1L << MUTATING) | (1L << PRIVATE) | (1L << STATIC) | (1L << VAL) | (1L << VAR))) != 0)) { + { + { + setState(347); + externalTypeElement(); + } + } + setState(352); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(353); + match(RC); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ExternalTypeElementContext extends ParserRuleContext { + public StaticMemberDeclarationContext staticMemberDeclaration() { + return getRuleContext(StaticMemberDeclarationContext.class,0); + } + public VariableDeclarationContext variableDeclaration() { + return getRuleContext(VariableDeclarationContext.class,0); + } + public ExternalFunctionDeclarationContext externalFunctionDeclaration() { + return getRuleContext(ExternalFunctionDeclarationContext.class,0); + } + public TerminalNode MUT() { return getToken(CocoParser.MUT, 0); } + public TerminalNode MUTATING() { return getToken(CocoParser.MUTATING, 0); } + public ExternalTypeElementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_externalTypeElement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterExternalTypeElement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitExternalTypeElement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitExternalTypeElement(this); + else return visitor.visitChildren(this); + } + } + + public final ExternalTypeElementContext externalTypeElement() throws RecognitionException { + ExternalTypeElementContext _localctx = new ExternalTypeElementContext(_ctx, getState()); + enterRule(_localctx, 30, RULE_externalTypeElement); + int _la; + try { + setState(362); + _errHandler.sync(this); + switch (_input.LA(1)) { + case STATIC: + enterOuterAlt(_localctx, 1); + { + setState(356); + staticMemberDeclaration(); + } + break; + case PRIVATE: + case VAL: + case VAR: + enterOuterAlt(_localctx, 2); + { + setState(357); + variableDeclaration(); + } + break; + case EXTERNAL: + case MUT: + case MUTATING: + enterOuterAlt(_localctx, 3); + { + setState(359); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==MUT || _la==MUTATING) { + { + setState(358); + _la = _input.LA(1); + if ( !(_la==MUT || _la==MUTATING) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + + setState(361); + externalFunctionDeclaration(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ExternalFunctionDeclarationContext extends ParserRuleContext { + public TerminalNode EXTERNAL() { return getToken(CocoParser.EXTERNAL, 0); } + public TerminalNode FUNCTION() { return getToken(CocoParser.FUNCTION, 0); } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public TerminalNode COLON() { return getToken(CocoParser.COLON, 0); } + public TypeContext type() { + return getRuleContext(TypeContext.class,0); + } + public TerminalNode ASSIGN() { return getToken(CocoParser.ASSIGN, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public ParametersContext parameters() { + return getRuleContext(ParametersContext.class,0); + } + public ExternalFunctionDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_externalFunctionDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterExternalFunctionDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitExternalFunctionDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitExternalFunctionDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final ExternalFunctionDeclarationContext externalFunctionDeclaration() throws RecognitionException { + ExternalFunctionDeclarationContext _localctx = new ExternalFunctionDeclarationContext(_ctx, getState()); + enterRule(_localctx, 32, RULE_externalFunctionDeclaration); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(364); + match(EXTERNAL); + setState(365); + match(FUNCTION); + setState(366); + match(IDENTIFIER); + setState(367); + match(LP); + setState(369); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==VAR || _la==IDENTIFIER) { + { + setState(368); + parameters(); + } + } + + setState(371); + match(RP); + setState(372); + match(COLON); + setState(373); + type(0); + setState(374); + match(ASSIGN); + setState(375); + expression(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class GenericTypeDeclarationContext extends ParserRuleContext { + public TerminalNode LT() { return getToken(CocoParser.LT, 0); } + public GenericTypesContext genericTypes() { + return getRuleContext(GenericTypesContext.class,0); + } + public TerminalNode GT() { return getToken(CocoParser.GT, 0); } + public TerminalNode WHERE() { return getToken(CocoParser.WHERE, 0); } + public ExpressionsContext expressions() { + return getRuleContext(ExpressionsContext.class,0); + } + public GenericTypeDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_genericTypeDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterGenericTypeDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitGenericTypeDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitGenericTypeDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final GenericTypeDeclarationContext genericTypeDeclaration() throws RecognitionException { + GenericTypeDeclarationContext _localctx = new GenericTypeDeclarationContext(_ctx, getState()); + enterRule(_localctx, 34, RULE_genericTypeDeclaration); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(377); + match(LT); + setState(378); + genericTypes(); + setState(381); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==WHERE) { + { + setState(379); + match(WHERE); + setState(380); + expressions(); + } + } + + setState(383); + match(GT); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class GenericTypesContext extends ParserRuleContext { + public List genericType() { + return getRuleContexts(GenericTypeContext.class); + } + public GenericTypeContext genericType(int i) { + return getRuleContext(GenericTypeContext.class,i); + } + public List COMMA() { return getTokens(CocoParser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(CocoParser.COMMA, i); + } + public GenericTypesContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_genericTypes; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterGenericTypes(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitGenericTypes(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitGenericTypes(this); + else return visitor.visitChildren(this); + } + } + + public final GenericTypesContext genericTypes() throws RecognitionException { + GenericTypesContext _localctx = new GenericTypesContext(_ctx, getState()); + enterRule(_localctx, 36, RULE_genericTypes); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(385); + genericType(); + setState(390); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==COMMA) { + { + { + setState(386); + match(COMMA); + setState(387); + genericType(); + } + } + setState(392); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class GenericTypeContext extends ParserRuleContext { + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode VAL() { return getToken(CocoParser.VAL, 0); } + public TerminalNode COLON() { return getToken(CocoParser.COLON, 0); } + public TypeContext type() { + return getRuleContext(TypeContext.class,0); + } + public GenericTypeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_genericType; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterGenericType(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitGenericType(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitGenericType(this); + else return visitor.visitChildren(this); + } + } + + public final GenericTypeContext genericType() throws RecognitionException { + GenericTypeContext _localctx = new GenericTypeContext(_ctx, getState()); + enterRule(_localctx, 38, RULE_genericType); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(394); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==VAL) { + { + setState(393); + match(VAL); + } + } + + setState(396); + match(IDENTIFIER); + setState(399); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COLON) { + { + setState(397); + match(COLON); + setState(398); + type(0); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class EnumElementContext extends ParserRuleContext { + public EnumCaseContext enumCase() { + return getRuleContext(EnumCaseContext.class,0); + } + public FunctionDeclarationContext functionDeclaration() { + return getRuleContext(FunctionDeclarationContext.class,0); + } + public TerminalNode MUT() { return getToken(CocoParser.MUT, 0); } + public TerminalNode MUTATING() { return getToken(CocoParser.MUTATING, 0); } + public StaticMemberDeclarationContext staticMemberDeclaration() { + return getRuleContext(StaticMemberDeclarationContext.class,0); + } + public EnumElementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_enumElement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterEnumElement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitEnumElement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitEnumElement(this); + else return visitor.visitChildren(this); + } + } + + public final EnumElementContext enumElement() throws RecognitionException { + EnumElementContext _localctx = new EnumElementContext(_ctx, getState()); + enterRule(_localctx, 40, RULE_enumElement); + int _la; + try { + setState(407); + _errHandler.sync(this); + switch (_input.LA(1)) { + case CASE: + enterOuterAlt(_localctx, 1); + { + setState(401); + enumCase(); + } + break; + case FUNCTION: + case MUT: + case MUTATING: + enterOuterAlt(_localctx, 2); + { + setState(403); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==MUT || _la==MUTATING) { + { + setState(402); + _la = _input.LA(1); + if ( !(_la==MUT || _la==MUTATING) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + + setState(405); + functionDeclaration(); + } + break; + case STATIC: + enterOuterAlt(_localctx, 3); + { + setState(406); + staticMemberDeclaration(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class EnumCaseContext extends ParserRuleContext { + public TerminalNode CASE() { return getToken(CocoParser.CASE, 0); } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public TerminalNode ASSIGN() { return getToken(CocoParser.ASSIGN, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public CaseParametersContext caseParameters() { + return getRuleContext(CaseParametersContext.class,0); + } + public EnumCaseContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_enumCase; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterEnumCase(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitEnumCase(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitEnumCase(this); + else return visitor.visitChildren(this); + } + } + + public final EnumCaseContext enumCase() throws RecognitionException { + EnumCaseContext _localctx = new EnumCaseContext(_ctx, getState()); + enterRule(_localctx, 42, RULE_enumCase); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(409); + match(CASE); + setState(410); + match(IDENTIFIER); + setState(416); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==LP) { + { + setState(411); + match(LP); + setState(413); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==IDENTIFIER) { + { + setState(412); + caseParameters(); + } + } + + setState(415); + match(RP); + } + } + + setState(420); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==ASSIGN) { + { + setState(418); + match(ASSIGN); + setState(419); + expression(0); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class CaseParametersContext extends ParserRuleContext { + public List caseParameter() { + return getRuleContexts(CaseParameterContext.class); + } + public CaseParameterContext caseParameter(int i) { + return getRuleContext(CaseParameterContext.class,i); + } + public List COMMA() { return getTokens(CocoParser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(CocoParser.COMMA, i); + } + public CaseParametersContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_caseParameters; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterCaseParameters(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitCaseParameters(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitCaseParameters(this); + else return visitor.visitChildren(this); + } + } + + public final CaseParametersContext caseParameters() throws RecognitionException { + CaseParametersContext _localctx = new CaseParametersContext(_ctx, getState()); + enterRule(_localctx, 44, RULE_caseParameters); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(422); + caseParameter(); + setState(427); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==COMMA) { + { + { + setState(423); + match(COMMA); + setState(424); + caseParameter(); + } + } + setState(429); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class CaseParameterContext extends ParserRuleContext { + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode COLON() { return getToken(CocoParser.COLON, 0); } + public TypeContext type() { + return getRuleContext(TypeContext.class,0); + } + public CaseParameterContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_caseParameter; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterCaseParameter(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitCaseParameter(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitCaseParameter(this); + else return visitor.visitChildren(this); + } + } + + public final CaseParameterContext caseParameter() throws RecognitionException { + CaseParameterContext _localctx = new CaseParameterContext(_ctx, getState()); + enterRule(_localctx, 46, RULE_caseParameter); + try { + enterOuterAlt(_localctx, 1); + { + setState(430); + match(IDENTIFIER); + setState(431); + match(COLON); + setState(432); + type(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class StructElementContext extends ParserRuleContext { + public FieldDeclarationContext fieldDeclaration() { + return getRuleContext(FieldDeclarationContext.class,0); + } + public FunctionDeclarationContext functionDeclaration() { + return getRuleContext(FunctionDeclarationContext.class,0); + } + public StaticMemberDeclarationContext staticMemberDeclaration() { + return getRuleContext(StaticMemberDeclarationContext.class,0); + } + public TerminalNode SEMI() { return getToken(CocoParser.SEMI, 0); } + public TerminalNode MUT() { return getToken(CocoParser.MUT, 0); } + public TerminalNode MUTATING() { return getToken(CocoParser.MUTATING, 0); } + public StructElementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_structElement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterStructElement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitStructElement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitStructElement(this); + else return visitor.visitChildren(this); + } + } + + public final StructElementContext structElement() throws RecognitionException { + StructElementContext _localctx = new StructElementContext(_ctx, getState()); + enterRule(_localctx, 48, RULE_structElement); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(440); + _errHandler.sync(this); + switch (_input.LA(1)) { + case VAL: + case VAR: + case IDENTIFIER: + { + setState(434); + fieldDeclaration(); + } + break; + case FUNCTION: + case MUT: + case MUTATING: + { + setState(436); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==MUT || _la==MUTATING) { + { + setState(435); + _la = _input.LA(1); + if ( !(_la==MUT || _la==MUTATING) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + + setState(438); + functionDeclaration(); + } + break; + case STATIC: + { + setState(439); + staticMemberDeclaration(); + } + break; + default: + throw new NoViableAltException(this); + } + setState(443); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==SEMI) { + { + setState(442); + match(SEMI); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class FieldDeclarationContext extends ParserRuleContext { + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode COLON() { return getToken(CocoParser.COLON, 0); } + public TypeContext type() { + return getRuleContext(TypeContext.class,0); + } + public TerminalNode ASSIGN() { return getToken(CocoParser.ASSIGN, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode VAL() { return getToken(CocoParser.VAL, 0); } + public TerminalNode VAR() { return getToken(CocoParser.VAR, 0); } + public FieldDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_fieldDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterFieldDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitFieldDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitFieldDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final FieldDeclarationContext fieldDeclaration() throws RecognitionException { + FieldDeclarationContext _localctx = new FieldDeclarationContext(_ctx, getState()); + enterRule(_localctx, 50, RULE_fieldDeclaration); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(446); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==VAL || _la==VAR) { + { + setState(445); + _la = _input.LA(1); + if ( !(_la==VAL || _la==VAR) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + + setState(448); + match(IDENTIFIER); + setState(449); + match(COLON); + setState(450); + type(0); + setState(453); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==ASSIGN) { + { + setState(451); + match(ASSIGN); + setState(452); + expression(0); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ComponentElementContext extends ParserRuleContext { + public FieldDeclarationContext fieldDeclaration() { + return getRuleContext(FieldDeclarationContext.class,0); + } + public VariableDeclarationContext variableDeclaration() { + return getRuleContext(VariableDeclarationContext.class,0); + } + public ConstructorDeclarationContext constructorDeclaration() { + return getRuleContext(ConstructorDeclarationContext.class,0); + } + public StateMachineDeclarationContext stateMachineDeclaration() { + return getRuleContext(StateMachineDeclarationContext.class,0); + } + public StaticMemberDeclarationContext staticMemberDeclaration() { + return getRuleContext(StaticMemberDeclarationContext.class,0); + } + public List attribute() { + return getRuleContexts(AttributeContext.class); + } + public AttributeContext attribute(int i) { + return getRuleContext(AttributeContext.class,i); + } + public TerminalNode SEMI() { return getToken(CocoParser.SEMI, 0); } + public ComponentElementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_componentElement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterComponentElement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitComponentElement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitComponentElement(this); + else return visitor.visitChildren(this); + } + } + + public final ComponentElementContext componentElement() throws RecognitionException { + ComponentElementContext _localctx = new ComponentElementContext(_ctx, getState()); + enterRule(_localctx, 52, RULE_componentElement); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(458); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==AT) { + { + { + setState(455); + attribute(); + } + } + setState(460); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(466); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,47,_ctx) ) { + case 1: + { + setState(461); + fieldDeclaration(); + } + break; + case 2: + { + setState(462); + variableDeclaration(); + } + break; + case 3: + { + setState(463); + constructorDeclaration(); + } + break; + case 4: + { + setState(464); + stateMachineDeclaration(); + } + break; + case 5: + { + setState(465); + staticMemberDeclaration(); + } + break; + } + setState(469); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==SEMI) { + { + setState(468); + match(SEMI); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class StaticMemberDeclarationContext extends ParserRuleContext { + public TerminalNode STATIC() { return getToken(CocoParser.STATIC, 0); } + public TerminalNode VAL() { return getToken(CocoParser.VAL, 0); } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode COLON() { return getToken(CocoParser.COLON, 0); } + public TypeContext type() { + return getRuleContext(TypeContext.class,0); + } + public TerminalNode ASSIGN() { return getToken(CocoParser.ASSIGN, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public StaticMemberDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_staticMemberDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterStaticMemberDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitStaticMemberDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitStaticMemberDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final StaticMemberDeclarationContext staticMemberDeclaration() throws RecognitionException { + StaticMemberDeclarationContext _localctx = new StaticMemberDeclarationContext(_ctx, getState()); + enterRule(_localctx, 54, RULE_staticMemberDeclaration); + try { + enterOuterAlt(_localctx, 1); + { + setState(471); + match(STATIC); + setState(472); + match(VAL); + setState(473); + match(IDENTIFIER); + setState(474); + match(COLON); + setState(475); + type(0); + setState(476); + match(ASSIGN); + setState(477); + expression(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ConstructorDeclarationContext extends ParserRuleContext { + public TerminalNode INIT() { return getToken(CocoParser.INIT, 0); } + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public TerminalNode ASSIGN() { return getToken(CocoParser.ASSIGN, 0); } + public BlockExpression_Context blockExpression_() { + return getRuleContext(BlockExpression_Context.class,0); + } + public ParametersContext parameters() { + return getRuleContext(ParametersContext.class,0); + } + public ConstructorDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_constructorDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterConstructorDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitConstructorDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitConstructorDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final ConstructorDeclarationContext constructorDeclaration() throws RecognitionException { + ConstructorDeclarationContext _localctx = new ConstructorDeclarationContext(_ctx, getState()); + enterRule(_localctx, 56, RULE_constructorDeclaration); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(479); + match(INIT); + setState(480); + match(LP); + setState(482); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==VAR || _la==IDENTIFIER) { + { + setState(481); + parameters(); + } + } + + setState(484); + match(RP); + setState(485); + match(ASSIGN); + setState(486); + blockExpression_(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ExpressionContext extends ParserRuleContext { + public ExpressionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_expression; } + + public ExpressionContext() { } + public void copyFrom(ExpressionContext ctx) { + super.copyFrom(ctx); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class IfExpressionContext extends ExpressionContext { + public IfExpression_Context ifExpression_() { + return getRuleContext(IfExpression_Context.class,0); + } + public IfExpressionContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterIfExpression(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitIfExpression(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitIfExpression(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class TryOperatorExpressionContext extends ExpressionContext { + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode QM() { return getToken(CocoParser.QM, 0); } + public TryOperatorExpressionContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterTryOperatorExpression(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitTryOperatorExpression(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitTryOperatorExpression(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class UnaryOperatorExpressionContext extends ExpressionContext { + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode MINUS() { return getToken(CocoParser.MINUS, 0); } + public TerminalNode EXCL() { return getToken(CocoParser.EXCL, 0); } + public TerminalNode AMP() { return getToken(CocoParser.AMP, 0); } + public UnaryOperatorExpressionContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterUnaryOperatorExpression(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitUnaryOperatorExpression(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitUnaryOperatorExpression(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class OptionalExpressionContext extends ExpressionContext { + public TerminalNode OPTIONAL() { return getToken(CocoParser.OPTIONAL, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public OptionalExpressionContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterOptionalExpression(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitOptionalExpression(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitOptionalExpression(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ArithmicOrLogicalExpressionContext extends ExpressionContext { + public List expression() { + return getRuleContexts(ExpressionContext.class); + } + public ExpressionContext expression(int i) { + return getRuleContext(ExpressionContext.class,i); + } + public TerminalNode MUL() { return getToken(CocoParser.MUL, 0); } + public TerminalNode DIV() { return getToken(CocoParser.DIV, 0); } + public TerminalNode MOD() { return getToken(CocoParser.MOD, 0); } + public TerminalNode PLUS() { return getToken(CocoParser.PLUS, 0); } + public TerminalNode MINUS() { return getToken(CocoParser.MINUS, 0); } + public TerminalNode EQ() { return getToken(CocoParser.EQ, 0); } + public TerminalNode NE() { return getToken(CocoParser.NE, 0); } + public TerminalNode OR() { return getToken(CocoParser.OR, 0); } + public TerminalNode AND() { return getToken(CocoParser.AND, 0); } + public TerminalNode LT() { return getToken(CocoParser.LT, 0); } + public TerminalNode LE() { return getToken(CocoParser.LE, 0); } + public TerminalNode GT() { return getToken(CocoParser.GT, 0); } + public TerminalNode GE() { return getToken(CocoParser.GE, 0); } + public ArithmicOrLogicalExpressionContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterArithmicOrLogicalExpression(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitArithmicOrLogicalExpression(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitArithmicOrLogicalExpression(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class LiteralExpressionContext extends ExpressionContext { + public LiteralExpression_Context literalExpression_() { + return getRuleContext(LiteralExpression_Context.class,0); + } + public LiteralExpressionContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterLiteralExpression(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitLiteralExpression(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitLiteralExpression(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ArrayLiteralExpressionContext extends ExpressionContext { + public TerminalNode LB() { return getToken(CocoParser.LB, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode RB() { return getToken(CocoParser.RB, 0); } + public ArrayLiteralExpressionContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterArrayLiteralExpression(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitArrayLiteralExpression(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitArrayLiteralExpression(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class NondetExpressionContext extends ExpressionContext { + public NondetExpression_Context nondetExpression_() { + return getRuleContext(NondetExpression_Context.class,0); + } + public NondetExpressionContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterNondetExpression(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitNondetExpression(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitNondetExpression(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class GroupedExpressionContext extends ExpressionContext { + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public ExpressionsContext expressions() { + return getRuleContext(ExpressionsContext.class,0); + } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public GroupedExpressionContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterGroupedExpression(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitGroupedExpression(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitGroupedExpression(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class BlockExpressionContext extends ExpressionContext { + public BlockExpression_Context blockExpression_() { + return getRuleContext(BlockExpression_Context.class,0); + } + public BlockExpressionContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterBlockExpression(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitBlockExpression(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitBlockExpression(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class MatchExpressionContext extends ExpressionContext { + public MatchExpression_Context matchExpression_() { + return getRuleContext(MatchExpression_Context.class,0); + } + public MatchExpressionContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterMatchExpression(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitMatchExpression(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitMatchExpression(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class StructLiteralExpressionContext extends ExpressionContext { + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode LC() { return getToken(CocoParser.LC, 0); } + public FieldAssignmentsContext fieldAssignments() { + return getRuleContext(FieldAssignmentsContext.class,0); + } + public TerminalNode RC() { return getToken(CocoParser.RC, 0); } + public StructLiteralExpressionContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterStructLiteralExpression(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitStructLiteralExpression(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitStructLiteralExpression(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class MemberReferenceExpressionContext extends ExpressionContext { + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode DOT() { return getToken(CocoParser.DOT, 0); } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public MemberReferenceExpressionContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterMemberReferenceExpression(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitMemberReferenceExpression(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitMemberReferenceExpression(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class AssignmentExpressionContext extends ExpressionContext { + public List expression() { + return getRuleContexts(ExpressionContext.class); + } + public ExpressionContext expression(int i) { + return getRuleContext(ExpressionContext.class,i); + } + public TerminalNode ASSIGN() { return getToken(CocoParser.ASSIGN, 0); } + public AssignmentExpressionContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterAssignmentExpression(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitAssignmentExpression(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitAssignmentExpression(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class VariableReferenceExpressionContext extends ExpressionContext { + public DotIdentifierListContext dotIdentifierList() { + return getRuleContext(DotIdentifierListContext.class,0); + } + public TerminalNode LT() { return getToken(CocoParser.LT, 0); } + public GenericTypesContext genericTypes() { + return getRuleContext(GenericTypesContext.class,0); + } + public TerminalNode GT() { return getToken(CocoParser.GT, 0); } + public VariableReferenceExpressionContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterVariableReferenceExpression(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitVariableReferenceExpression(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitVariableReferenceExpression(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ImplicitMemberExpressionContext extends ExpressionContext { + public TerminalNode DOT() { return getToken(CocoParser.DOT, 0); } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public ImplicitMemberExpressionContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterImplicitMemberExpression(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitImplicitMemberExpression(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitImplicitMemberExpression(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ExternalFunctionContext extends ExpressionContext { + public ExternalFunctionDeclarationContext externalFunctionDeclaration() { + return getRuleContext(ExternalFunctionDeclarationContext.class,0); + } + public ExternalFunctionContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterExternalFunction(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitExternalFunction(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitExternalFunction(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class CastExpressionContext extends ExpressionContext { + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode AS() { return getToken(CocoParser.AS, 0); } + public TypeContext type() { + return getRuleContext(TypeContext.class,0); + } + public CastExpressionContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterCastExpression(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitCastExpression(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitCastExpression(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class StateInvariantExpressionContext extends ExpressionContext { + public StateInvariantContext stateInvariant() { + return getRuleContext(StateInvariantContext.class,0); + } + public StateInvariantExpressionContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterStateInvariantExpression(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitStateInvariantExpression(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitStateInvariantExpression(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class CallExpressionContext extends ExpressionContext { + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public ExpressionsContext expressions() { + return getRuleContext(ExpressionsContext.class,0); + } + public CallExpressionContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterCallExpression(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitCallExpression(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitCallExpression(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ExternalLiteralContext extends ExpressionContext { + public TerminalNode EXTERNAL() { return getToken(CocoParser.EXTERNAL, 0); } + public TerminalNode BACKTICK_LITERAL() { return getToken(CocoParser.BACKTICK_LITERAL, 0); } + public ExternalLiteralContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterExternalLiteral(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitExternalLiteral(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitExternalLiteral(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ArraySubscriptExpressionContext extends ExpressionContext { + public List expression() { + return getRuleContexts(ExpressionContext.class); + } + public ExpressionContext expression(int i) { + return getRuleContext(ExpressionContext.class,i); + } + public TerminalNode LB() { return getToken(CocoParser.LB, 0); } + public TerminalNode RB() { return getToken(CocoParser.RB, 0); } + public ArraySubscriptExpressionContext(ExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterArraySubscriptExpression(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitArraySubscriptExpression(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitArraySubscriptExpression(this); + else return visitor.visitChildren(this); + } + } + + public final ExpressionContext expression() throws RecognitionException { + return expression(0); + } + + private ExpressionContext expression(int _p) throws RecognitionException { + ParserRuleContext _parentctx = _ctx; + int _parentState = getState(); + ExpressionContext _localctx = new ExpressionContext(_ctx, _parentState); + ExpressionContext _prevctx = _localctx; + int _startState = 58; + enterRecursionRule(_localctx, 58, RULE_expression, _p); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(519); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,51,_ctx) ) { + case 1: + { + _localctx = new LiteralExpressionContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + + setState(489); + literalExpression_(); + } + break; + case 2: + { + _localctx = new ExternalLiteralContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(490); + match(EXTERNAL); + setState(491); + match(BACKTICK_LITERAL); + } + break; + case 3: + { + _localctx = new ExternalFunctionContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(492); + externalFunctionDeclaration(); + } + break; + case 4: + { + _localctx = new VariableReferenceExpressionContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(493); + dotIdentifierList(); + setState(498); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,50,_ctx) ) { + case 1: + { + setState(494); + match(LT); + setState(495); + genericTypes(); + setState(496); + match(GT); + } + break; + } + } + break; + case 5: + { + _localctx = new StateInvariantExpressionContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(500); + stateInvariant(); + } + break; + case 6: + { + _localctx = new UnaryOperatorExpressionContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(501); + _la = _input.LA(1); + if ( !(((((_la - 67)) & ~0x3f) == 0 && ((1L << (_la - 67)) & ((1L << (MINUS - 67)) | (1L << (AMP - 67)) | (1L << (EXCL - 67)))) != 0)) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(502); + expression(14); + } + break; + case 7: + { + _localctx = new IfExpressionContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(503); + ifExpression_(); + } + break; + case 8: + { + _localctx = new MatchExpressionContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(504); + matchExpression_(); + } + break; + case 9: + { + _localctx = new ImplicitMemberExpressionContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(505); + match(DOT); + setState(506); + match(IDENTIFIER); + } + break; + case 10: + { + _localctx = new GroupedExpressionContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(507); + match(LP); + setState(508); + expressions(); + setState(509); + match(RP); + } + break; + case 11: + { + _localctx = new ArrayLiteralExpressionContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(511); + match(LB); + setState(512); + expression(0); + setState(513); + match(RB); + } + break; + case 12: + { + _localctx = new NondetExpressionContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(515); + nondetExpression_(); + } + break; + case 13: + { + _localctx = new OptionalExpressionContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(516); + match(OPTIONAL); + setState(517); + expression(2); + } + break; + case 14: + { + _localctx = new BlockExpressionContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(518); + blockExpression_(); + } + break; + } + _ctx.stop = _input.LT(-1); + setState(559); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,54,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + if ( _parseListeners!=null ) triggerExitRuleEvent(); + _prevctx = _localctx; + { + setState(557); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,53,_ctx) ) { + case 1: + { + _localctx = new ArithmicOrLogicalExpressionContext(new ExpressionContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expression); + setState(521); + if (!(precpred(_ctx, 12))) throw new FailedPredicateException(this, "precpred(_ctx, 12)"); + setState(522); + _la = _input.LA(1); + if ( !(((((_la - 65)) & ~0x3f) == 0 && ((1L << (_la - 65)) & ((1L << (MUL - 65)) | (1L << (DIV - 65)) | (1L << (MOD - 65)))) != 0)) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(523); + expression(13); + } + break; + case 2: + { + _localctx = new ArithmicOrLogicalExpressionContext(new ExpressionContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expression); + setState(524); + if (!(precpred(_ctx, 11))) throw new FailedPredicateException(this, "precpred(_ctx, 11)"); + setState(525); + _la = _input.LA(1); + if ( !(_la==MINUS || _la==PLUS) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(526); + expression(12); + } + break; + case 3: + { + _localctx = new ArithmicOrLogicalExpressionContext(new ExpressionContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expression); + setState(527); + if (!(precpred(_ctx, 10))) throw new FailedPredicateException(this, "precpred(_ctx, 10)"); + setState(528); + _la = _input.LA(1); + if ( !(((((_la - 63)) & ~0x3f) == 0 && ((1L << (_la - 63)) & ((1L << (LT - 63)) | (1L << (GT - 63)) | (1L << (EQ - 63)) | (1L << (NE - 63)) | (1L << (OR - 63)) | (1L << (AND - 63)) | (1L << (LE - 63)) | (1L << (GE - 63)))) != 0)) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(529); + expression(11); + } + break; + case 4: + { + _localctx = new AssignmentExpressionContext(new ExpressionContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expression); + setState(530); + if (!(precpred(_ctx, 9))) throw new FailedPredicateException(this, "precpred(_ctx, 9)"); + setState(531); + match(ASSIGN); + setState(532); + expression(10); + } + break; + case 5: + { + _localctx = new MemberReferenceExpressionContext(new ExpressionContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expression); + setState(533); + if (!(precpred(_ctx, 20))) throw new FailedPredicateException(this, "precpred(_ctx, 20)"); + setState(534); + match(DOT); + setState(535); + match(IDENTIFIER); + } + break; + case 6: + { + _localctx = new CallExpressionContext(new ExpressionContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expression); + setState(536); + if (!(precpred(_ctx, 18))) throw new FailedPredicateException(this, "precpred(_ctx, 18)"); + setState(537); + match(LP); + setState(539); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ASSERT) | (1L << EXTERNAL) | (1L << IF) | (1L << MATCH) | (1L << NONDET) | (1L << OPTIONAL) | (1L << IDENTIFIER) | (1L << LP) | (1L << LC) | (1L << LB) | (1L << DOT))) != 0) || ((((_la - 67)) & ~0x3f) == 0 && ((1L << (_la - 67)) & ((1L << (MINUS - 67)) | (1L << (AMP - 67)) | (1L << (EXCL - 67)) | (1L << (INTEGER - 67)) | (1L << (CHAR_LITERAL - 67)) | (1L << (STRING_LITERAL - 67)))) != 0)) { + { + setState(538); + expressions(); + } + } + + setState(541); + match(RP); + } + break; + case 7: + { + _localctx = new ArraySubscriptExpressionContext(new ExpressionContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expression); + setState(542); + if (!(precpred(_ctx, 17))) throw new FailedPredicateException(this, "precpred(_ctx, 17)"); + setState(543); + match(LB); + setState(544); + expression(0); + setState(545); + match(RB); + } + break; + case 8: + { + _localctx = new StructLiteralExpressionContext(new ExpressionContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expression); + setState(547); + if (!(precpred(_ctx, 16))) throw new FailedPredicateException(this, "precpred(_ctx, 16)"); + setState(548); + match(LC); + setState(549); + fieldAssignments(); + setState(550); + match(RC); + } + break; + case 9: + { + _localctx = new TryOperatorExpressionContext(new ExpressionContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expression); + setState(552); + if (!(precpred(_ctx, 15))) throw new FailedPredicateException(this, "precpred(_ctx, 15)"); + setState(553); + match(QM); + } + break; + case 10: + { + _localctx = new CastExpressionContext(new ExpressionContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expression); + setState(554); + if (!(precpred(_ctx, 13))) throw new FailedPredicateException(this, "precpred(_ctx, 13)"); + setState(555); + match(AS); + setState(556); + type(0); + } + break; + } + } + } + setState(561); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,54,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + unrollRecursionContexts(_parentctx); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class BlockExpression_Context extends ParserRuleContext { + public TerminalNode LC() { return getToken(CocoParser.LC, 0); } + public TerminalNode RC() { return getToken(CocoParser.RC, 0); } + public List statement() { + return getRuleContexts(StatementContext.class); + } + public StatementContext statement(int i) { + return getRuleContext(StatementContext.class,i); + } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public BlockExpression_Context(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_blockExpression_; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterBlockExpression_(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitBlockExpression_(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitBlockExpression_(this); + else return visitor.visitChildren(this); + } + } + + public final BlockExpression_Context blockExpression_() throws RecognitionException { + BlockExpression_Context _localctx = new BlockExpression_Context(_ctx, getState()); + enterRule(_localctx, 60, RULE_blockExpression_); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(562); + match(LC); + setState(566); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,55,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(563); + statement(); + } + } + } + setState(568); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,55,_ctx); + } + setState(570); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ASSERT) | (1L << EXTERNAL) | (1L << IF) | (1L << MATCH) | (1L << NONDET) | (1L << OPTIONAL) | (1L << IDENTIFIER) | (1L << LP) | (1L << LC) | (1L << LB) | (1L << DOT))) != 0) || ((((_la - 67)) & ~0x3f) == 0 && ((1L << (_la - 67)) & ((1L << (MINUS - 67)) | (1L << (AMP - 67)) | (1L << (EXCL - 67)) | (1L << (INTEGER - 67)) | (1L << (CHAR_LITERAL - 67)) | (1L << (STRING_LITERAL - 67)))) != 0)) { + { + setState(569); + expression(0); + } + } + + setState(572); + match(RC); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class IfExpression_Context extends ParserRuleContext { + public TerminalNode IF() { return getToken(CocoParser.IF, 0); } + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public List expression() { + return getRuleContexts(ExpressionContext.class); + } + public ExpressionContext expression(int i) { + return getRuleContext(ExpressionContext.class,i); + } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public TerminalNode ELSE() { return getToken(CocoParser.ELSE, 0); } + public IfExpression_Context(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_ifExpression_; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterIfExpression_(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitIfExpression_(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitIfExpression_(this); + else return visitor.visitChildren(this); + } + } + + public final IfExpression_Context ifExpression_() throws RecognitionException { + IfExpression_Context _localctx = new IfExpression_Context(_ctx, getState()); + enterRule(_localctx, 62, RULE_ifExpression_); + try { + enterOuterAlt(_localctx, 1); + { + setState(574); + match(IF); + setState(575); + match(LP); + setState(576); + expression(0); + setState(577); + match(RP); + setState(578); + expression(0); + setState(581); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,57,_ctx) ) { + case 1: + { + setState(579); + match(ELSE); + setState(580); + expression(0); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class MatchExpression_Context extends ParserRuleContext { + public TerminalNode MATCH() { return getToken(CocoParser.MATCH, 0); } + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public TerminalNode LC() { return getToken(CocoParser.LC, 0); } + public MatchClausesContext matchClauses() { + return getRuleContext(MatchClausesContext.class,0); + } + public TerminalNode RC() { return getToken(CocoParser.RC, 0); } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode COLON() { return getToken(CocoParser.COLON, 0); } + public MatchExpression_Context(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_matchExpression_; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterMatchExpression_(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitMatchExpression_(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitMatchExpression_(this); + else return visitor.visitChildren(this); + } + } + + public final MatchExpression_Context matchExpression_() throws RecognitionException { + MatchExpression_Context _localctx = new MatchExpression_Context(_ctx, getState()); + enterRule(_localctx, 64, RULE_matchExpression_); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(585); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==IDENTIFIER) { + { + setState(583); + match(IDENTIFIER); + setState(584); + match(COLON); + } + } + + setState(587); + match(MATCH); + setState(588); + match(LP); + setState(589); + expression(0); + setState(590); + match(RP); + setState(591); + match(LC); + setState(592); + matchClauses(); + setState(593); + match(RC); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class NondetExpression_Context extends ParserRuleContext { + public TerminalNode NONDET() { return getToken(CocoParser.NONDET, 0); } + public TerminalNode LC() { return getToken(CocoParser.LC, 0); } + public NondetClausesContext nondetClauses() { + return getRuleContext(NondetClausesContext.class,0); + } + public TerminalNode RC() { return getToken(CocoParser.RC, 0); } + public TerminalNode OTHERWISE() { return getToken(CocoParser.OTHERWISE, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode COMMA() { return getToken(CocoParser.COMMA, 0); } + public TerminalNode SEMI() { return getToken(CocoParser.SEMI, 0); } + public NondetExpression_Context(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_nondetExpression_; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterNondetExpression_(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitNondetExpression_(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitNondetExpression_(this); + else return visitor.visitChildren(this); + } + } + + public final NondetExpression_Context nondetExpression_() throws RecognitionException { + NondetExpression_Context _localctx = new NondetExpression_Context(_ctx, getState()); + enterRule(_localctx, 66, RULE_nondetExpression_); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(595); + match(NONDET); + setState(596); + match(LC); + setState(597); + nondetClauses(); + setState(600); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==OTHERWISE) { + { + setState(598); + match(OTHERWISE); + setState(599); + expression(0); + } + } + + setState(603); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COMMA || _la==SEMI) { + { + setState(602); + _la = _input.LA(1); + if ( !(_la==COMMA || _la==SEMI) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + + setState(605); + match(RC); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class FieldAssignmentsContext extends ParserRuleContext { + public List fieldAssignment() { + return getRuleContexts(FieldAssignmentContext.class); + } + public FieldAssignmentContext fieldAssignment(int i) { + return getRuleContext(FieldAssignmentContext.class,i); + } + public List COMMA() { return getTokens(CocoParser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(CocoParser.COMMA, i); + } + public FieldAssignmentsContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_fieldAssignments; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterFieldAssignments(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitFieldAssignments(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitFieldAssignments(this); + else return visitor.visitChildren(this); + } + } + + public final FieldAssignmentsContext fieldAssignments() throws RecognitionException { + FieldAssignmentsContext _localctx = new FieldAssignmentsContext(_ctx, getState()); + enterRule(_localctx, 68, RULE_fieldAssignments); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(607); + fieldAssignment(); + setState(612); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,61,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(608); + match(COMMA); + setState(609); + fieldAssignment(); + } + } + } + setState(614); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,61,_ctx); + } + setState(616); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COMMA) { + { + setState(615); + match(COMMA); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class FieldAssignmentContext extends ParserRuleContext { + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode ASSIGN() { return getToken(CocoParser.ASSIGN, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public FieldAssignmentContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_fieldAssignment; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterFieldAssignment(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitFieldAssignment(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitFieldAssignment(this); + else return visitor.visitChildren(this); + } + } + + public final FieldAssignmentContext fieldAssignment() throws RecognitionException { + FieldAssignmentContext _localctx = new FieldAssignmentContext(_ctx, getState()); + enterRule(_localctx, 70, RULE_fieldAssignment); + try { + enterOuterAlt(_localctx, 1); + { + setState(618); + match(IDENTIFIER); + setState(619); + match(ASSIGN); + setState(620); + expression(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class NondetClausesContext extends ParserRuleContext { + public List nondetClause() { + return getRuleContexts(NondetClauseContext.class); + } + public NondetClauseContext nondetClause(int i) { + return getRuleContext(NondetClauseContext.class,i); + } + public List COMMA() { return getTokens(CocoParser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(CocoParser.COMMA, i); + } + public List SEMI() { return getTokens(CocoParser.SEMI); } + public TerminalNode SEMI(int i) { + return getToken(CocoParser.SEMI, i); + } + public NondetClausesContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_nondetClauses; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterNondetClauses(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitNondetClauses(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitNondetClauses(this); + else return visitor.visitChildren(this); + } + } + + public final NondetClausesContext nondetClauses() throws RecognitionException { + NondetClausesContext _localctx = new NondetClausesContext(_ctx, getState()); + enterRule(_localctx, 72, RULE_nondetClauses); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(622); + nondetClause(); + setState(627); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,63,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(623); + _la = _input.LA(1); + if ( !(_la==COMMA || _la==SEMI) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(624); + nondetClause(); + } + } + } + setState(629); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,63,_ctx); + } + setState(631); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,64,_ctx) ) { + case 1: + { + setState(630); + _la = _input.LA(1); + if ( !(_la==COMMA || _la==SEMI) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class NondetClauseContext extends ParserRuleContext { + public List expression() { + return getRuleContexts(ExpressionContext.class); + } + public ExpressionContext expression(int i) { + return getRuleContext(ExpressionContext.class,i); + } + public TerminalNode IF() { return getToken(CocoParser.IF, 0); } + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public NondetClauseContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_nondetClause; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterNondetClause(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitNondetClause(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitNondetClause(this); + else return visitor.visitChildren(this); + } + } + + public final NondetClauseContext nondetClause() throws RecognitionException { + NondetClauseContext _localctx = new NondetClauseContext(_ctx, getState()); + enterRule(_localctx, 74, RULE_nondetClause); + try { + enterOuterAlt(_localctx, 1); + { + setState(638); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,65,_ctx) ) { + case 1: + { + setState(633); + match(IF); + setState(634); + match(LP); + setState(635); + expression(0); + setState(636); + match(RP); + } + break; + } + setState(640); + expression(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class MatchClausesContext extends ParserRuleContext { + public List matchClause() { + return getRuleContexts(MatchClauseContext.class); + } + public MatchClauseContext matchClause(int i) { + return getRuleContext(MatchClauseContext.class,i); + } + public List COMMA() { return getTokens(CocoParser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(CocoParser.COMMA, i); + } + public List SEMI() { return getTokens(CocoParser.SEMI); } + public TerminalNode SEMI(int i) { + return getToken(CocoParser.SEMI, i); + } + public MatchClausesContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_matchClauses; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterMatchClauses(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitMatchClauses(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitMatchClauses(this); + else return visitor.visitChildren(this); + } + } + + public final MatchClausesContext matchClauses() throws RecognitionException { + MatchClausesContext _localctx = new MatchClausesContext(_ctx, getState()); + enterRule(_localctx, 76, RULE_matchClauses); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(642); + matchClause(); + setState(647); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,66,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(643); + _la = _input.LA(1); + if ( !(_la==COMMA || _la==SEMI) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(644); + matchClause(); + } + } + } + setState(649); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,66,_ctx); + } + setState(651); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COMMA || _la==SEMI) { + { + setState(650); + _la = _input.LA(1); + if ( !(_la==COMMA || _la==SEMI) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class MatchClauseContext extends ParserRuleContext { + public PatternContext pattern() { + return getRuleContext(PatternContext.class,0); + } + public TerminalNode IMPL() { return getToken(CocoParser.IMPL, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public MatchClauseContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_matchClause; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterMatchClause(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitMatchClause(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitMatchClause(this); + else return visitor.visitChildren(this); + } + } + + public final MatchClauseContext matchClause() throws RecognitionException { + MatchClauseContext _localctx = new MatchClauseContext(_ctx, getState()); + enterRule(_localctx, 78, RULE_matchClause); + try { + enterOuterAlt(_localctx, 1); + { + setState(653); + pattern(); + setState(654); + match(IMPL); + setState(655); + expression(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class PatternContext extends ParserRuleContext { + public EnumCasePatternContext enumCasePattern() { + return getRuleContext(EnumCasePatternContext.class,0); + } + public LiteralExpression_Context literalExpression_() { + return getRuleContext(LiteralExpression_Context.class,0); + } + public VariableDeclarationPatternContext variableDeclarationPattern() { + return getRuleContext(VariableDeclarationPatternContext.class,0); + } + public PatternContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_pattern; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterPattern(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitPattern(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitPattern(this); + else return visitor.visitChildren(this); + } + } + + public final PatternContext pattern() throws RecognitionException { + PatternContext _localctx = new PatternContext(_ctx, getState()); + enterRule(_localctx, 80, RULE_pattern); + try { + setState(660); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,68,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(657); + enumCasePattern(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(658); + literalExpression_(); + } + break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(659); + variableDeclarationPattern(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class EnumCasePatternContext extends ParserRuleContext { + public IdParameterPatternsContext idParameterPatterns() { + return getRuleContext(IdParameterPatternsContext.class,0); + } + public TerminalNode IF() { return getToken(CocoParser.IF, 0); } + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public EnumCasePatternContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_enumCasePattern; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterEnumCasePattern(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitEnumCasePattern(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitEnumCasePattern(this); + else return visitor.visitChildren(this); + } + } + + public final EnumCasePatternContext enumCasePattern() throws RecognitionException { + EnumCasePatternContext _localctx = new EnumCasePatternContext(_ctx, getState()); + enterRule(_localctx, 82, RULE_enumCasePattern); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(662); + idParameterPatterns(); + setState(668); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==IF) { + { + setState(663); + match(IF); + setState(664); + match(LP); + setState(665); + expression(0); + setState(666); + match(RP); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class IdParameterPatternsContext extends ParserRuleContext { + public List idParameterPattern() { + return getRuleContexts(IdParameterPatternContext.class); + } + public IdParameterPatternContext idParameterPattern(int i) { + return getRuleContext(IdParameterPatternContext.class,i); + } + public List DOT() { return getTokens(CocoParser.DOT); } + public TerminalNode DOT(int i) { + return getToken(CocoParser.DOT, i); + } + public IdParameterPatternsContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_idParameterPatterns; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterIdParameterPatterns(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitIdParameterPatterns(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitIdParameterPatterns(this); + else return visitor.visitChildren(this); + } + } + + public final IdParameterPatternsContext idParameterPatterns() throws RecognitionException { + IdParameterPatternsContext _localctx = new IdParameterPatternsContext(_ctx, getState()); + enterRule(_localctx, 84, RULE_idParameterPatterns); + int _la; + try { + setState(687); + _errHandler.sync(this); + switch (_input.LA(1)) { + case IDENTIFIER: + enterOuterAlt(_localctx, 1); + { + setState(670); + idParameterPattern(); + setState(675); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==DOT) { + { + { + setState(671); + match(DOT); + setState(672); + idParameterPattern(); + } + } + setState(677); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + break; + case DOT: + enterOuterAlt(_localctx, 2); + { + setState(678); + match(DOT); + setState(679); + idParameterPattern(); + setState(684); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==DOT) { + { + { + setState(680); + match(DOT); + setState(681); + idParameterPattern(); + } + } + setState(686); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class IdParameterPatternContext extends ParserRuleContext { + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public ParameterPatternsContext parameterPatterns() { + return getRuleContext(ParameterPatternsContext.class,0); + } + public IdParameterPatternContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_idParameterPattern; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterIdParameterPattern(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitIdParameterPattern(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitIdParameterPattern(this); + else return visitor.visitChildren(this); + } + } + + public final IdParameterPatternContext idParameterPattern() throws RecognitionException { + IdParameterPatternContext _localctx = new IdParameterPatternContext(_ctx, getState()); + enterRule(_localctx, 86, RULE_idParameterPattern); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(689); + match(IDENTIFIER); + setState(695); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==LP) { + { + setState(690); + match(LP); + setState(692); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==VAR || _la==IDENTIFIER) { + { + setState(691); + parameterPatterns(); + } + } + + setState(694); + match(RP); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class VariableDeclarationPatternContext extends ParserRuleContext { + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode VAL() { return getToken(CocoParser.VAL, 0); } + public TerminalNode DOT() { return getToken(CocoParser.DOT, 0); } + public TerminalNode COLON() { return getToken(CocoParser.COLON, 0); } + public TypeContext type() { + return getRuleContext(TypeContext.class,0); + } + public VariableDeclarationPatternContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_variableDeclarationPattern; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterVariableDeclarationPattern(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitVariableDeclarationPattern(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitVariableDeclarationPattern(this); + else return visitor.visitChildren(this); + } + } + + public final VariableDeclarationPatternContext variableDeclarationPattern() throws RecognitionException { + VariableDeclarationPatternContext _localctx = new VariableDeclarationPatternContext(_ctx, getState()); + enterRule(_localctx, 88, RULE_variableDeclarationPattern); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(697); + _la = _input.LA(1); + if ( !(_la==VAL || _la==DOT) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(698); + match(IDENTIFIER); + setState(701); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COLON) { + { + setState(699); + match(COLON); + setState(700); + type(0); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ParameterPatternsContext extends ParserRuleContext { + public List parameterPattern() { + return getRuleContexts(ParameterPatternContext.class); + } + public ParameterPatternContext parameterPattern(int i) { + return getRuleContext(ParameterPatternContext.class,i); + } + public List COMMA() { return getTokens(CocoParser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(CocoParser.COMMA, i); + } + public ParameterPatternsContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_parameterPatterns; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterParameterPatterns(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitParameterPatterns(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitParameterPatterns(this); + else return visitor.visitChildren(this); + } + } + + public final ParameterPatternsContext parameterPatterns() throws RecognitionException { + ParameterPatternsContext _localctx = new ParameterPatternsContext(_ctx, getState()); + enterRule(_localctx, 90, RULE_parameterPatterns); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(703); + parameterPattern(); + setState(708); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==COMMA) { + { + { + setState(704); + match(COMMA); + setState(705); + parameterPattern(); + } + } + setState(710); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ParameterPatternContext extends ParserRuleContext { + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode VAR() { return getToken(CocoParser.VAR, 0); } + public ParameterPatternContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_parameterPattern; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterParameterPattern(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitParameterPattern(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitParameterPattern(this); + else return visitor.visitChildren(this); + } + } + + public final ParameterPatternContext parameterPattern() throws RecognitionException { + ParameterPatternContext _localctx = new ParameterPatternContext(_ctx, getState()); + enterRule(_localctx, 92, RULE_parameterPattern); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(712); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==VAR) { + { + setState(711); + match(VAR); + } + } + + setState(714); + match(IDENTIFIER); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ExpressionsContext extends ParserRuleContext { + public List expression() { + return getRuleContexts(ExpressionContext.class); + } + public ExpressionContext expression(int i) { + return getRuleContext(ExpressionContext.class,i); + } + public List COMMA() { return getTokens(CocoParser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(CocoParser.COMMA, i); + } + public ExpressionsContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_expressions; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterExpressions(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitExpressions(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitExpressions(this); + else return visitor.visitChildren(this); + } + } + + public final ExpressionsContext expressions() throws RecognitionException { + ExpressionsContext _localctx = new ExpressionsContext(_ctx, getState()); + enterRule(_localctx, 94, RULE_expressions); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(716); + expression(0); + setState(721); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==COMMA) { + { + { + setState(717); + match(COMMA); + setState(718); + expression(0); + } + } + setState(723); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class StatementContext extends ParserRuleContext { + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public StateInvariantContext stateInvariant() { + return getRuleContext(StateInvariantContext.class,0); + } + public DeclarationStatementContext declarationStatement() { + return getRuleContext(DeclarationStatementContext.class,0); + } + public ReturnStatementContext returnStatement() { + return getRuleContext(ReturnStatementContext.class,0); + } + public BecomeStatementContext becomeStatement() { + return getRuleContext(BecomeStatementContext.class,0); + } + public WhileStatementContext whileStatement() { + return getRuleContext(WhileStatementContext.class,0); + } + public ForStatementContext forStatement() { + return getRuleContext(ForStatementContext.class,0); + } + public BreakStatementContext breakStatement() { + return getRuleContext(BreakStatementContext.class,0); + } + public ContinueStatementContext continueStatement() { + return getRuleContext(ContinueStatementContext.class,0); + } + public List attribute() { + return getRuleContexts(AttributeContext.class); + } + public AttributeContext attribute(int i) { + return getRuleContext(AttributeContext.class,i); + } + public TerminalNode SEMI() { return getToken(CocoParser.SEMI, 0); } + public StatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_statement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterStatement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitStatement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitStatement(this); + else return visitor.visitChildren(this); + } + } + + public final StatementContext statement() throws RecognitionException { + StatementContext _localctx = new StatementContext(_ctx, getState()); + enterRule(_localctx, 96, RULE_statement); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(727); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==AT) { + { + { + setState(724); + attribute(); + } + } + setState(729); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(745); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,82,_ctx) ) { + case 1: + { + setState(730); + expression(0); + setState(732); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==SEMI) { + { + setState(731); + match(SEMI); + } + } + + } + break; + case 2: + { + setState(734); + stateInvariant(); + setState(736); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==SEMI) { + { + setState(735); + match(SEMI); + } + } + + } + break; + case 3: + { + setState(738); + declarationStatement(); + } + break; + case 4: + { + setState(739); + returnStatement(); + } + break; + case 5: + { + setState(740); + becomeStatement(); + } + break; + case 6: + { + setState(741); + whileStatement(); + } + break; + case 7: + { + setState(742); + forStatement(); + } + break; + case 8: + { + setState(743); + breakStatement(); + } + break; + case 9: + { + setState(744); + continueStatement(); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class DeclarationStatementContext extends ParserRuleContext { + public VariableDeclarationContext variableDeclaration() { + return getRuleContext(VariableDeclarationContext.class,0); + } + public TerminalNode SEMI() { return getToken(CocoParser.SEMI, 0); } + public DeclarationStatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_declarationStatement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterDeclarationStatement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitDeclarationStatement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitDeclarationStatement(this); + else return visitor.visitChildren(this); + } + } + + public final DeclarationStatementContext declarationStatement() throws RecognitionException { + DeclarationStatementContext _localctx = new DeclarationStatementContext(_ctx, getState()); + enterRule(_localctx, 98, RULE_declarationStatement); + try { + enterOuterAlt(_localctx, 1); + { + setState(747); + variableDeclaration(); + setState(748); + match(SEMI); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ReturnStatementContext extends ParserRuleContext { + public TerminalNode RETURN() { return getToken(CocoParser.RETURN, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode SEMI() { return getToken(CocoParser.SEMI, 0); } + public ReturnStatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_returnStatement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterReturnStatement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitReturnStatement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitReturnStatement(this); + else return visitor.visitChildren(this); + } + } + + public final ReturnStatementContext returnStatement() throws RecognitionException { + ReturnStatementContext _localctx = new ReturnStatementContext(_ctx, getState()); + enterRule(_localctx, 100, RULE_returnStatement); + try { + enterOuterAlt(_localctx, 1); + { + setState(750); + match(RETURN); + setState(751); + expression(0); + setState(752); + match(SEMI); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class BecomeStatementContext extends ParserRuleContext { + public TerminalNode BECOME() { return getToken(CocoParser.BECOME, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode SEMI() { return getToken(CocoParser.SEMI, 0); } + public BecomeStatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_becomeStatement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterBecomeStatement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitBecomeStatement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitBecomeStatement(this); + else return visitor.visitChildren(this); + } + } + + public final BecomeStatementContext becomeStatement() throws RecognitionException { + BecomeStatementContext _localctx = new BecomeStatementContext(_ctx, getState()); + enterRule(_localctx, 102, RULE_becomeStatement); + try { + enterOuterAlt(_localctx, 1); + { + setState(754); + match(BECOME); + setState(755); + expression(0); + setState(756); + match(SEMI); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class WhileStatementContext extends ParserRuleContext { + public TerminalNode WHILE() { return getToken(CocoParser.WHILE, 0); } + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public BlockExpression_Context blockExpression_() { + return getRuleContext(BlockExpression_Context.class,0); + } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode COLON() { return getToken(CocoParser.COLON, 0); } + public WhileStatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_whileStatement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterWhileStatement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitWhileStatement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitWhileStatement(this); + else return visitor.visitChildren(this); + } + } + + public final WhileStatementContext whileStatement() throws RecognitionException { + WhileStatementContext _localctx = new WhileStatementContext(_ctx, getState()); + enterRule(_localctx, 104, RULE_whileStatement); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(760); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==IDENTIFIER) { + { + setState(758); + match(IDENTIFIER); + setState(759); + match(COLON); + } + } + + setState(762); + match(WHILE); + setState(763); + match(LP); + setState(764); + expression(0); + setState(765); + match(RP); + setState(766); + blockExpression_(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ForStatementContext extends ParserRuleContext { + public TerminalNode FOR() { return getToken(CocoParser.FOR, 0); } + public List IDENTIFIER() { return getTokens(CocoParser.IDENTIFIER); } + public TerminalNode IDENTIFIER(int i) { + return getToken(CocoParser.IDENTIFIER, i); + } + public TerminalNode IN() { return getToken(CocoParser.IN, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public BlockExpression_Context blockExpression_() { + return getRuleContext(BlockExpression_Context.class,0); + } + public List COLON() { return getTokens(CocoParser.COLON); } + public TerminalNode COLON(int i) { + return getToken(CocoParser.COLON, i); + } + public TypeContext type() { + return getRuleContext(TypeContext.class,0); + } + public ForStatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_forStatement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterForStatement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitForStatement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitForStatement(this); + else return visitor.visitChildren(this); + } + } + + public final ForStatementContext forStatement() throws RecognitionException { + ForStatementContext _localctx = new ForStatementContext(_ctx, getState()); + enterRule(_localctx, 106, RULE_forStatement); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(770); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==IDENTIFIER) { + { + setState(768); + match(IDENTIFIER); + setState(769); + match(COLON); + } + } + + setState(772); + match(FOR); + setState(773); + match(IDENTIFIER); + setState(776); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COLON) { + { + setState(774); + match(COLON); + setState(775); + type(0); + } + } + + setState(778); + match(IN); + setState(779); + expression(0); + setState(780); + blockExpression_(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class BreakStatementContext extends ParserRuleContext { + public TerminalNode BREAK() { return getToken(CocoParser.BREAK, 0); } + public TerminalNode SEMI() { return getToken(CocoParser.SEMI, 0); } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public BreakStatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_breakStatement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterBreakStatement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitBreakStatement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitBreakStatement(this); + else return visitor.visitChildren(this); + } + } + + public final BreakStatementContext breakStatement() throws RecognitionException { + BreakStatementContext _localctx = new BreakStatementContext(_ctx, getState()); + enterRule(_localctx, 108, RULE_breakStatement); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(782); + match(BREAK); + setState(784); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==IDENTIFIER) { + { + setState(783); + match(IDENTIFIER); + } + } + + setState(786); + match(SEMI); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ContinueStatementContext extends ParserRuleContext { + public TerminalNode CONTINUE() { return getToken(CocoParser.CONTINUE, 0); } + public TerminalNode SEMI() { return getToken(CocoParser.SEMI, 0); } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public ContinueStatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_continueStatement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterContinueStatement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitContinueStatement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitContinueStatement(this); + else return visitor.visitChildren(this); + } + } + + public final ContinueStatementContext continueStatement() throws RecognitionException { + ContinueStatementContext _localctx = new ContinueStatementContext(_ctx, getState()); + enterRule(_localctx, 110, RULE_continueStatement); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(788); + match(CONTINUE); + setState(790); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==IDENTIFIER) { + { + setState(789); + match(IDENTIFIER); + } + } + + setState(792); + match(SEMI); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class PortElementContext extends ParserRuleContext { + public EnumDeclarationContext enumDeclaration() { + return getRuleContext(EnumDeclarationContext.class,0); + } + public FunctionInterfaceDeclarationContext functionInterfaceDeclaration() { + return getRuleContext(FunctionInterfaceDeclarationContext.class,0); + } + public SignalDeclarationContext signalDeclaration() { + return getRuleContext(SignalDeclarationContext.class,0); + } + public FieldDeclarationContext fieldDeclaration() { + return getRuleContext(FieldDeclarationContext.class,0); + } + public StateMachineDeclarationContext stateMachineDeclaration() { + return getRuleContext(StateMachineDeclarationContext.class,0); + } + public PortDeclarationContext portDeclaration() { + return getRuleContext(PortDeclarationContext.class,0); + } + public StaticMemberDeclarationContext staticMemberDeclaration() { + return getRuleContext(StaticMemberDeclarationContext.class,0); + } + public StructDeclarationContext structDeclaration() { + return getRuleContext(StructDeclarationContext.class,0); + } + public TypeAliasDeclarationContext typeAliasDeclaration() { + return getRuleContext(TypeAliasDeclarationContext.class,0); + } + public ExternalTypeDeclarationContext externalTypeDeclaration() { + return getRuleContext(ExternalTypeDeclarationContext.class,0); + } + public List attribute() { + return getRuleContexts(AttributeContext.class); + } + public AttributeContext attribute(int i) { + return getRuleContext(AttributeContext.class,i); + } + public PortElementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_portElement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterPortElement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitPortElement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitPortElement(this); + else return visitor.visitChildren(this); + } + } + + public final PortElementContext portElement() throws RecognitionException { + PortElementContext _localctx = new PortElementContext(_ctx, getState()); + enterRule(_localctx, 112, RULE_portElement); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(797); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==AT) { + { + { + setState(794); + attribute(); + } + } + setState(799); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(810); + _errHandler.sync(this); + switch (_input.LA(1)) { + case ENUM: + { + setState(800); + enumDeclaration(); + } + break; + case FUNCTION: + { + setState(801); + functionInterfaceDeclaration(); + } + break; + case OUTGOING: + { + setState(802); + signalDeclaration(); + } + break; + case VAL: + case VAR: + case IDENTIFIER: + { + setState(803); + fieldDeclaration(); + } + break; + case MACHINE: + { + setState(804); + stateMachineDeclaration(); + } + break; + case PORT: + { + setState(805); + portDeclaration(); + } + break; + case STATIC: + { + setState(806); + staticMemberDeclaration(); + } + break; + case STRUCT: + { + setState(807); + structDeclaration(); + } + break; + case TYPE: + { + setState(808); + typeAliasDeclaration(); + } + break; + case EXTERNAL: + { + setState(809); + externalTypeDeclaration(); + } + break; + default: + throw new NoViableAltException(this); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class FunctionInterfaceDeclarationContext extends ParserRuleContext { + public TerminalNode FUNCTION() { return getToken(CocoParser.FUNCTION, 0); } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public TerminalNode COLON() { return getToken(CocoParser.COLON, 0); } + public TypeContext type() { + return getRuleContext(TypeContext.class,0); + } + public ParametersContext parameters() { + return getRuleContext(ParametersContext.class,0); + } + public FunctionInterfaceDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_functionInterfaceDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterFunctionInterfaceDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitFunctionInterfaceDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitFunctionInterfaceDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final FunctionInterfaceDeclarationContext functionInterfaceDeclaration() throws RecognitionException { + FunctionInterfaceDeclarationContext _localctx = new FunctionInterfaceDeclarationContext(_ctx, getState()); + enterRule(_localctx, 114, RULE_functionInterfaceDeclaration); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(812); + match(FUNCTION); + setState(813); + match(IDENTIFIER); + setState(814); + match(LP); + setState(816); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==VAR || _la==IDENTIFIER) { + { + setState(815); + parameters(); + } + } + + setState(818); + match(RP); + setState(819); + match(COLON); + setState(820); + type(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class SignalDeclarationContext extends ParserRuleContext { + public TerminalNode OUTGOING() { return getToken(CocoParser.OUTGOING, 0); } + public TerminalNode SIGNAL() { return getToken(CocoParser.SIGNAL, 0); } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public ParametersContext parameters() { + return getRuleContext(ParametersContext.class,0); + } + public SignalDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_signalDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterSignalDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitSignalDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitSignalDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final SignalDeclarationContext signalDeclaration() throws RecognitionException { + SignalDeclarationContext _localctx = new SignalDeclarationContext(_ctx, getState()); + enterRule(_localctx, 116, RULE_signalDeclaration); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(822); + match(OUTGOING); + setState(823); + match(SIGNAL); + setState(824); + match(IDENTIFIER); + setState(825); + match(LP); + setState(827); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==VAR || _la==IDENTIFIER) { + { + setState(826); + parameters(); + } + } + + setState(829); + match(RP); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class StateMachineDeclarationContext extends ParserRuleContext { + public TerminalNode MACHINE() { return getToken(CocoParser.MACHINE, 0); } + public TerminalNode LC() { return getToken(CocoParser.LC, 0); } + public TerminalNode RC() { return getToken(CocoParser.RC, 0); } + public List IDENTIFIER() { return getTokens(CocoParser.IDENTIFIER); } + public TerminalNode IDENTIFIER(int i) { + return getToken(CocoParser.IDENTIFIER, i); + } + public TerminalNode COLON() { return getToken(CocoParser.COLON, 0); } + public List stateMachineElement() { + return getRuleContexts(StateMachineElementContext.class); + } + public StateMachineElementContext stateMachineElement(int i) { + return getRuleContext(StateMachineElementContext.class,i); + } + public StateMachineDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_stateMachineDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterStateMachineDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitStateMachineDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitStateMachineDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final StateMachineDeclarationContext stateMachineDeclaration() throws RecognitionException { + StateMachineDeclarationContext _localctx = new StateMachineDeclarationContext(_ctx, getState()); + enterRule(_localctx, 118, RULE_stateMachineDeclaration); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(831); + match(MACHINE); + setState(833); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==IDENTIFIER) { + { + setState(832); + match(IDENTIFIER); + } + } + + setState(837); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COLON) { + { + setState(835); + match(COLON); + setState(836); + match(IDENTIFIER); + } + } + + setState(839); + match(LC); + setState(843); + _errHandler.sync(this); + _la = _input.LA(1); + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << AFTER) | (1L << ASSERT) | (1L << ENUM) | (1L << ENTRY) | (1L << EXECUTION) | (1L << EXIT) | (1L << FUNCTION) | (1L << IF) | (1L << PERIODIC) | (1L << PRIVATE) | (1L << SPONTANEOUS) | (1L << STATE) | (1L << STATIC) | (1L << TYPE) | (1L << VAL) | (1L << VAR) | (1L << IDENTIFIER) | (1L << AT))) != 0)) { + { + { + setState(840); + stateMachineElement(); + } + } + setState(845); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(846); + match(RC); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class StateMachineElementContext extends ParserRuleContext { + public EnumDeclarationContext enumDeclaration() { + return getRuleContext(EnumDeclarationContext.class,0); + } + public EntryFunctionDeclarationContext entryFunctionDeclaration() { + return getRuleContext(EntryFunctionDeclarationContext.class,0); + } + public ExitFunctionDeclarationContext exitFunctionDeclaration() { + return getRuleContext(ExitFunctionDeclarationContext.class,0); + } + public FunctionDeclarationContext functionDeclaration() { + return getRuleContext(FunctionDeclarationContext.class,0); + } + public StateInvariantContext stateInvariant() { + return getRuleContext(StateInvariantContext.class,0); + } + public StateDeclarationContext stateDeclaration() { + return getRuleContext(StateDeclarationContext.class,0); + } + public StaticMemberDeclarationContext staticMemberDeclaration() { + return getRuleContext(StaticMemberDeclarationContext.class,0); + } + public TypeAliasDeclarationContext typeAliasDeclaration() { + return getRuleContext(TypeAliasDeclarationContext.class,0); + } + public VariableDeclarationContext variableDeclaration() { + return getRuleContext(VariableDeclarationContext.class,0); + } + public TransitionDeclarationContext transitionDeclaration() { + return getRuleContext(TransitionDeclarationContext.class,0); + } + public List attribute() { + return getRuleContexts(AttributeContext.class); + } + public AttributeContext attribute(int i) { + return getRuleContext(AttributeContext.class,i); + } + public StateMachineElementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_stateMachineElement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterStateMachineElement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitStateMachineElement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitStateMachineElement(this); + else return visitor.visitChildren(this); + } + } + + public final StateMachineElementContext stateMachineElement() throws RecognitionException { + StateMachineElementContext _localctx = new StateMachineElementContext(_ctx, getState()); + enterRule(_localctx, 120, RULE_stateMachineElement); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(851); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==AT) { + { + { + setState(848); + attribute(); + } + } + setState(853); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(864); + _errHandler.sync(this); + switch (_input.LA(1)) { + case ENUM: + { + setState(854); + enumDeclaration(); + } + break; + case ENTRY: + { + setState(855); + entryFunctionDeclaration(); + } + break; + case EXIT: + { + setState(856); + exitFunctionDeclaration(); + } + break; + case FUNCTION: + { + setState(857); + functionDeclaration(); + } + break; + case ASSERT: + { + setState(858); + stateInvariant(); + } + break; + case EXECUTION: + case STATE: + { + setState(859); + stateDeclaration(); + } + break; + case STATIC: + { + setState(860); + staticMemberDeclaration(); + } + break; + case TYPE: + { + setState(861); + typeAliasDeclaration(); + } + break; + case PRIVATE: + case VAL: + case VAR: + { + setState(862); + variableDeclaration(); + } + break; + case AFTER: + case IF: + case PERIODIC: + case SPONTANEOUS: + case IDENTIFIER: + { + setState(863); + transitionDeclaration(); + } + break; + default: + throw new NoViableAltException(this); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class StateDeclarationContext extends ParserRuleContext { + public EventStateDeclarationContext eventStateDeclaration() { + return getRuleContext(EventStateDeclarationContext.class,0); + } + public ExecutionStateDeclarationContext executionStateDeclaration() { + return getRuleContext(ExecutionStateDeclarationContext.class,0); + } + public StateDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_stateDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterStateDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitStateDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitStateDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final StateDeclarationContext stateDeclaration() throws RecognitionException { + StateDeclarationContext _localctx = new StateDeclarationContext(_ctx, getState()); + enterRule(_localctx, 122, RULE_stateDeclaration); + try { + setState(868); + _errHandler.sync(this); + switch (_input.LA(1)) { + case STATE: + enterOuterAlt(_localctx, 1); + { + setState(866); + eventStateDeclaration(); + } + break; + case EXECUTION: + enterOuterAlt(_localctx, 2); + { + setState(867); + executionStateDeclaration(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class EventStateDeclarationContext extends ParserRuleContext { + public TerminalNode STATE() { return getToken(CocoParser.STATE, 0); } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode LC() { return getToken(CocoParser.LC, 0); } + public TerminalNode RC() { return getToken(CocoParser.RC, 0); } + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public List eventStateElement() { + return getRuleContexts(EventStateElementContext.class); + } + public EventStateElementContext eventStateElement(int i) { + return getRuleContext(EventStateElementContext.class,i); + } + public ParametersContext parameters() { + return getRuleContext(ParametersContext.class,0); + } + public EventStateDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_eventStateDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterEventStateDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitEventStateDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitEventStateDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final EventStateDeclarationContext eventStateDeclaration() throws RecognitionException { + EventStateDeclarationContext _localctx = new EventStateDeclarationContext(_ctx, getState()); + enterRule(_localctx, 124, RULE_eventStateDeclaration); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(870); + match(STATE); + setState(871); + match(IDENTIFIER); + setState(877); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==LP) { + { + setState(872); + match(LP); + setState(874); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==VAR || _la==IDENTIFIER) { + { + setState(873); + parameters(); + } + } + + setState(876); + match(RP); + } + } + + setState(879); + match(LC); + setState(883); + _errHandler.sync(this); + _la = _input.LA(1); + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << AFTER) | (1L << ASSERT) | (1L << ENUM) | (1L << ENTRY) | (1L << EXECUTION) | (1L << EXIT) | (1L << FUNCTION) | (1L << IF) | (1L << PERIODIC) | (1L << PRIVATE) | (1L << SPONTANEOUS) | (1L << STATE) | (1L << STATIC) | (1L << STRUCT) | (1L << TYPE) | (1L << VAL) | (1L << VAR) | (1L << IDENTIFIER) | (1L << AT))) != 0)) { + { + { + setState(880); + eventStateElement(); + } + } + setState(885); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(886); + match(RC); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ExecutionStateDeclarationContext extends ParserRuleContext { + public TerminalNode EXECUTION() { return getToken(CocoParser.EXECUTION, 0); } + public TerminalNode STATE() { return getToken(CocoParser.STATE, 0); } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public BlockExpression_Context blockExpression_() { + return getRuleContext(BlockExpression_Context.class,0); + } + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public ParametersContext parameters() { + return getRuleContext(ParametersContext.class,0); + } + public ExecutionStateDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_executionStateDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterExecutionStateDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitExecutionStateDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitExecutionStateDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final ExecutionStateDeclarationContext executionStateDeclaration() throws RecognitionException { + ExecutionStateDeclarationContext _localctx = new ExecutionStateDeclarationContext(_ctx, getState()); + enterRule(_localctx, 126, RULE_executionStateDeclaration); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(888); + match(EXECUTION); + setState(889); + match(STATE); + setState(890); + match(IDENTIFIER); + setState(896); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==LP) { + { + setState(891); + match(LP); + setState(893); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==VAR || _la==IDENTIFIER) { + { + setState(892); + parameters(); + } + } + + setState(895); + match(RP); + } + } + + setState(898); + blockExpression_(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class EventStateElementContext extends ParserRuleContext { + public EnumDeclarationContext enumDeclaration() { + return getRuleContext(EnumDeclarationContext.class,0); + } + public EntryFunctionDeclarationContext entryFunctionDeclaration() { + return getRuleContext(EntryFunctionDeclarationContext.class,0); + } + public ExitFunctionDeclarationContext exitFunctionDeclaration() { + return getRuleContext(ExitFunctionDeclarationContext.class,0); + } + public FunctionDeclarationContext functionDeclaration() { + return getRuleContext(FunctionDeclarationContext.class,0); + } + public StateDeclarationContext stateDeclaration() { + return getRuleContext(StateDeclarationContext.class,0); + } + public StateInvariantContext stateInvariant() { + return getRuleContext(StateInvariantContext.class,0); + } + public StaticMemberDeclarationContext staticMemberDeclaration() { + return getRuleContext(StaticMemberDeclarationContext.class,0); + } + public StructDeclarationContext structDeclaration() { + return getRuleContext(StructDeclarationContext.class,0); + } + public TransitionDeclarationContext transitionDeclaration() { + return getRuleContext(TransitionDeclarationContext.class,0); + } + public TypeAliasDeclarationContext typeAliasDeclaration() { + return getRuleContext(TypeAliasDeclarationContext.class,0); + } + public VariableDeclarationContext variableDeclaration() { + return getRuleContext(VariableDeclarationContext.class,0); + } + public List attribute() { + return getRuleContexts(AttributeContext.class); + } + public AttributeContext attribute(int i) { + return getRuleContext(AttributeContext.class,i); + } + public EventStateElementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_eventStateElement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterEventStateElement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitEventStateElement(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitEventStateElement(this); + else return visitor.visitChildren(this); + } + } + + public final EventStateElementContext eventStateElement() throws RecognitionException { + EventStateElementContext _localctx = new EventStateElementContext(_ctx, getState()); + enterRule(_localctx, 128, RULE_eventStateElement); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(903); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==AT) { + { + { + setState(900); + attribute(); + } + } + setState(905); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(917); + _errHandler.sync(this); + switch (_input.LA(1)) { + case ENUM: + { + setState(906); + enumDeclaration(); + } + break; + case ENTRY: + { + setState(907); + entryFunctionDeclaration(); + } + break; + case EXIT: + { + setState(908); + exitFunctionDeclaration(); + } + break; + case FUNCTION: + { + setState(909); + functionDeclaration(); + } + break; + case EXECUTION: + case STATE: + { + setState(910); + stateDeclaration(); + } + break; + case ASSERT: + { + setState(911); + stateInvariant(); + } + break; + case STATIC: + { + setState(912); + staticMemberDeclaration(); + } + break; + case STRUCT: + { + setState(913); + structDeclaration(); + } + break; + case AFTER: + case IF: + case PERIODIC: + case SPONTANEOUS: + case IDENTIFIER: + { + setState(914); + transitionDeclaration(); + } + break; + case TYPE: + { + setState(915); + typeAliasDeclaration(); + } + break; + case PRIVATE: + case VAL: + case VAR: + { + setState(916); + variableDeclaration(); + } + break; + default: + throw new NoViableAltException(this); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class EntryFunctionDeclarationContext extends ParserRuleContext { + public TerminalNode ENTRY() { return getToken(CocoParser.ENTRY, 0); } + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public TerminalNode ASSIGN() { return getToken(CocoParser.ASSIGN, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public EntryFunctionDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_entryFunctionDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterEntryFunctionDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitEntryFunctionDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitEntryFunctionDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final EntryFunctionDeclarationContext entryFunctionDeclaration() throws RecognitionException { + EntryFunctionDeclarationContext _localctx = new EntryFunctionDeclarationContext(_ctx, getState()); + enterRule(_localctx, 130, RULE_entryFunctionDeclaration); + try { + enterOuterAlt(_localctx, 1); + { + setState(919); + match(ENTRY); + setState(920); + match(LP); + setState(921); + match(RP); + setState(922); + match(ASSIGN); + setState(923); + expression(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ExitFunctionDeclarationContext extends ParserRuleContext { + public TerminalNode EXIT() { return getToken(CocoParser.EXIT, 0); } + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public TerminalNode ASSIGN() { return getToken(CocoParser.ASSIGN, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public ExitFunctionDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_exitFunctionDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterExitFunctionDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitExitFunctionDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitExitFunctionDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final ExitFunctionDeclarationContext exitFunctionDeclaration() throws RecognitionException { + ExitFunctionDeclarationContext _localctx = new ExitFunctionDeclarationContext(_ctx, getState()); + enterRule(_localctx, 132, RULE_exitFunctionDeclaration); + try { + enterOuterAlt(_localctx, 1); + { + setState(925); + match(EXIT); + setState(926); + match(LP); + setState(927); + match(RP); + setState(928); + match(ASSIGN); + setState(929); + expression(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class StateInvariantContext extends ParserRuleContext { + public TerminalNode ASSERT() { return getToken(CocoParser.ASSERT, 0); } + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public StateInvariantContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_stateInvariant; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterStateInvariant(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitStateInvariant(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitStateInvariant(this); + else return visitor.visitChildren(this); + } + } + + public final StateInvariantContext stateInvariant() throws RecognitionException { + StateInvariantContext _localctx = new StateInvariantContext(_ctx, getState()); + enterRule(_localctx, 134, RULE_stateInvariant); + try { + enterOuterAlt(_localctx, 1); + { + setState(931); + match(ASSERT); + setState(932); + match(LP); + setState(933); + expression(0); + setState(934); + match(RP); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class TransitionDeclarationContext extends ParserRuleContext { + public EventTransitionContext eventTransition() { + return getRuleContext(EventTransitionContext.class,0); + } + public SpontaneousTransitionContext spontaneousTransition() { + return getRuleContext(SpontaneousTransitionContext.class,0); + } + public TimerTransitionContext timerTransition() { + return getRuleContext(TimerTransitionContext.class,0); + } + public TransitionDeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_transitionDeclaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterTransitionDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitTransitionDeclaration(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitTransitionDeclaration(this); + else return visitor.visitChildren(this); + } + } + + public final TransitionDeclarationContext transitionDeclaration() throws RecognitionException { + TransitionDeclarationContext _localctx = new TransitionDeclarationContext(_ctx, getState()); + enterRule(_localctx, 136, RULE_transitionDeclaration); + try { + setState(939); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,105,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(936); + eventTransition(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(937); + spontaneousTransition(); + } + break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(938); + timerTransition(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class EventTransitionContext extends ParserRuleContext { + public DotIdentifierListContext dotIdentifierList() { + return getRuleContext(DotIdentifierListContext.class,0); + } + public List LP() { return getTokens(CocoParser.LP); } + public TerminalNode LP(int i) { + return getToken(CocoParser.LP, i); + } + public List RP() { return getTokens(CocoParser.RP); } + public TerminalNode RP(int i) { + return getToken(CocoParser.RP, i); + } + public TerminalNode ASSIGN() { return getToken(CocoParser.ASSIGN, 0); } + public EventHandlerContext eventHandler() { + return getRuleContext(EventHandlerContext.class,0); + } + public TerminalNode IF() { return getToken(CocoParser.IF, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public List eventSource() { + return getRuleContexts(EventSourceContext.class); + } + public EventSourceContext eventSource(int i) { + return getRuleContext(EventSourceContext.class,i); + } + public List DOT() { return getTokens(CocoParser.DOT); } + public TerminalNode DOT(int i) { + return getToken(CocoParser.DOT, i); + } + public ParametersContext parameters() { + return getRuleContext(ParametersContext.class,0); + } + public EventTransitionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_eventTransition; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterEventTransition(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitEventTransition(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitEventTransition(this); + else return visitor.visitChildren(this); + } + } + + public final EventTransitionContext eventTransition() throws RecognitionException { + EventTransitionContext _localctx = new EventTransitionContext(_ctx, getState()); + enterRule(_localctx, 138, RULE_eventTransition); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(946); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==IF) { + { + setState(941); + match(IF); + setState(942); + match(LP); + setState(943); + expression(0); + setState(944); + match(RP); + } + } + + setState(953); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,107,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(948); + eventSource(); + setState(949); + match(DOT); + } + } + } + setState(955); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,107,_ctx); + } + setState(956); + dotIdentifierList(); + setState(957); + match(LP); + setState(959); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==VAR || _la==IDENTIFIER) { + { + setState(958); + parameters(); + } + } + + setState(961); + match(RP); + setState(962); + match(ASSIGN); + setState(963); + eventHandler(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class EventSourceContext extends ParserRuleContext { + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode LB() { return getToken(CocoParser.LB, 0); } + public PatternContext pattern() { + return getRuleContext(PatternContext.class,0); + } + public TerminalNode RB() { return getToken(CocoParser.RB, 0); } + public TerminalNode PIPE() { return getToken(CocoParser.PIPE, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public EventSourceContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_eventSource; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterEventSource(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitEventSource(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitEventSource(this); + else return visitor.visitChildren(this); + } + } + + public final EventSourceContext eventSource() throws RecognitionException { + EventSourceContext _localctx = new EventSourceContext(_ctx, getState()); + enterRule(_localctx, 140, RULE_eventSource); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(965); + match(IDENTIFIER); + setState(974); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==LB) { + { + setState(966); + match(LB); + setState(967); + pattern(); + setState(970); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==PIPE) { + { + setState(968); + match(PIPE); + setState(969); + expression(0); + } + } + + setState(972); + match(RB); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class SpontaneousTransitionContext extends ParserRuleContext { + public TerminalNode SPONTANEOUS() { return getToken(CocoParser.SPONTANEOUS, 0); } + public TerminalNode ASSIGN() { return getToken(CocoParser.ASSIGN, 0); } + public List expression() { + return getRuleContexts(ExpressionContext.class); + } + public ExpressionContext expression(int i) { + return getRuleContext(ExpressionContext.class,i); + } + public TerminalNode IF() { return getToken(CocoParser.IF, 0); } + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public SpontaneousTransitionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_spontaneousTransition; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterSpontaneousTransition(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitSpontaneousTransition(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitSpontaneousTransition(this); + else return visitor.visitChildren(this); + } + } + + public final SpontaneousTransitionContext spontaneousTransition() throws RecognitionException { + SpontaneousTransitionContext _localctx = new SpontaneousTransitionContext(_ctx, getState()); + enterRule(_localctx, 142, RULE_spontaneousTransition); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(981); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==IF) { + { + setState(976); + match(IF); + setState(977); + match(LP); + setState(978); + expression(0); + setState(979); + match(RP); + } + } + + setState(983); + match(SPONTANEOUS); + setState(984); + match(ASSIGN); + setState(985); + expression(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class TimerTransitionContext extends ParserRuleContext { + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public List expression() { + return getRuleContexts(ExpressionContext.class); + } + public ExpressionContext expression(int i) { + return getRuleContext(ExpressionContext.class,i); + } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public TerminalNode ASSIGN() { return getToken(CocoParser.ASSIGN, 0); } + public TerminalNode AFTER() { return getToken(CocoParser.AFTER, 0); } + public TerminalNode PERIODIC() { return getToken(CocoParser.PERIODIC, 0); } + public TimerTransitionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_timerTransition; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterTimerTransition(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitTimerTransition(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitTimerTransition(this); + else return visitor.visitChildren(this); + } + } + + public final TimerTransitionContext timerTransition() throws RecognitionException { + TimerTransitionContext _localctx = new TimerTransitionContext(_ctx, getState()); + enterRule(_localctx, 144, RULE_timerTransition); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(987); + _la = _input.LA(1); + if ( !(_la==AFTER || _la==PERIODIC) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(988); + match(LP); + setState(989); + expression(0); + setState(990); + match(RP); + setState(991); + match(ASSIGN); + setState(992); + expression(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class EventHandlerContext extends ParserRuleContext { + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode ILLEGAL() { return getToken(CocoParser.ILLEGAL, 0); } + public OfferContext offer() { + return getRuleContext(OfferContext.class,0); + } + public EventHandlerContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_eventHandler; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterEventHandler(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitEventHandler(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitEventHandler(this); + else return visitor.visitChildren(this); + } + } + + public final EventHandlerContext eventHandler() throws RecognitionException { + EventHandlerContext _localctx = new EventHandlerContext(_ctx, getState()); + enterRule(_localctx, 146, RULE_eventHandler); + try { + setState(997); + _errHandler.sync(this); + switch (_input.LA(1)) { + case ASSERT: + case EXTERNAL: + case IF: + case MATCH: + case NONDET: + case OPTIONAL: + case IDENTIFIER: + case LP: + case LC: + case LB: + case DOT: + case MINUS: + case AMP: + case EXCL: + case INTEGER: + case CHAR_LITERAL: + case STRING_LITERAL: + enterOuterAlt(_localctx, 1); + { + setState(994); + expression(0); + } + break; + case ILLEGAL: + enterOuterAlt(_localctx, 2); + { + setState(995); + match(ILLEGAL); + } + break; + case OFFER: + enterOuterAlt(_localctx, 3); + { + setState(996); + offer(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class OfferContext extends ParserRuleContext { + public TerminalNode OFFER() { return getToken(CocoParser.OFFER, 0); } + public TerminalNode LC() { return getToken(CocoParser.LC, 0); } + public OfferClausesContext offerClauses() { + return getRuleContext(OfferClausesContext.class,0); + } + public TerminalNode RC() { return getToken(CocoParser.RC, 0); } + public TerminalNode OTHERWISE() { return getToken(CocoParser.OTHERWISE, 0); } + public EventHandlerContext eventHandler() { + return getRuleContext(EventHandlerContext.class,0); + } + public TerminalNode COMMA() { return getToken(CocoParser.COMMA, 0); } + public OfferContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_offer; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterOffer(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitOffer(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitOffer(this); + else return visitor.visitChildren(this); + } + } + + public final OfferContext offer() throws RecognitionException { + OfferContext _localctx = new OfferContext(_ctx, getState()); + enterRule(_localctx, 148, RULE_offer); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(999); + match(OFFER); + setState(1000); + match(LC); + setState(1001); + offerClauses(); + setState(1007); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==OTHERWISE) { + { + setState(1002); + match(OTHERWISE); + setState(1003); + eventHandler(); + setState(1005); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COMMA) { + { + setState(1004); + match(COMMA); + } + } + + } + } + + setState(1009); + match(RC); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class OfferClausesContext extends ParserRuleContext { + public List offerClause() { + return getRuleContexts(OfferClauseContext.class); + } + public OfferClauseContext offerClause(int i) { + return getRuleContext(OfferClauseContext.class,i); + } + public List COMMA() { return getTokens(CocoParser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(CocoParser.COMMA, i); + } + public OfferClausesContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_offerClauses; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterOfferClauses(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitOfferClauses(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitOfferClauses(this); + else return visitor.visitChildren(this); + } + } + + public final OfferClausesContext offerClauses() throws RecognitionException { + OfferClausesContext _localctx = new OfferClausesContext(_ctx, getState()); + enterRule(_localctx, 150, RULE_offerClauses); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(1011); + offerClause(); + setState(1016); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,115,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(1012); + match(COMMA); + setState(1013); + offerClause(); + } + } + } + setState(1018); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,115,_ctx); + } + setState(1020); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COMMA) { + { + setState(1019); + match(COMMA); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class OfferClauseContext extends ParserRuleContext { + public EventHandlerContext eventHandler() { + return getRuleContext(EventHandlerContext.class,0); + } + public List attribute() { + return getRuleContexts(AttributeContext.class); + } + public AttributeContext attribute(int i) { + return getRuleContext(AttributeContext.class,i); + } + public TerminalNode IF() { return getToken(CocoParser.IF, 0); } + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public OfferClauseContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_offerClause; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterOfferClause(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitOfferClause(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitOfferClause(this); + else return visitor.visitChildren(this); + } + } + + public final OfferClauseContext offerClause() throws RecognitionException { + OfferClauseContext _localctx = new OfferClauseContext(_ctx, getState()); + enterRule(_localctx, 152, RULE_offerClause); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(1025); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==AT) { + { + { + setState(1022); + attribute(); + } + } + setState(1027); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(1033); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,118,_ctx) ) { + case 1: + { + setState(1028); + match(IF); + setState(1029); + match(LP); + setState(1030); + expression(0); + setState(1031); + match(RP); + } + break; + } + setState(1035); + eventHandler(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ParametersContext extends ParserRuleContext { + public List parameter() { + return getRuleContexts(ParameterContext.class); + } + public ParameterContext parameter(int i) { + return getRuleContext(ParameterContext.class,i); + } + public List COMMA() { return getTokens(CocoParser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(CocoParser.COMMA, i); + } + public ParametersContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_parameters; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterParameters(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitParameters(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitParameters(this); + else return visitor.visitChildren(this); + } + } + + public final ParametersContext parameters() throws RecognitionException { + ParametersContext _localctx = new ParametersContext(_ctx, getState()); + enterRule(_localctx, 154, RULE_parameters); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(1037); + parameter(); + setState(1042); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==COMMA) { + { + { + setState(1038); + match(COMMA); + setState(1039); + parameter(); + } + } + setState(1044); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ParameterContext extends ParserRuleContext { + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TerminalNode VAR() { return getToken(CocoParser.VAR, 0); } + public TerminalNode ELLIP() { return getToken(CocoParser.ELLIP, 0); } + public TerminalNode COLON() { return getToken(CocoParser.COLON, 0); } + public TypeContext type() { + return getRuleContext(TypeContext.class,0); + } + public GenericTypeDeclarationContext genericTypeDeclaration() { + return getRuleContext(GenericTypeDeclarationContext.class,0); + } + public ParameterContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_parameter; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterParameter(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitParameter(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitParameter(this); + else return visitor.visitChildren(this); + } + } + + public final ParameterContext parameter() throws RecognitionException { + ParameterContext _localctx = new ParameterContext(_ctx, getState()); + enterRule(_localctx, 156, RULE_parameter); + int _la; + try { + setState(1058); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,123,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(1046); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==VAR) { + { + setState(1045); + match(VAR); + } + } + + setState(1048); + match(IDENTIFIER); + setState(1050); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==ELLIP) { + { + setState(1049); + match(ELLIP); + } + } + + setState(1054); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COLON) { + { + setState(1052); + match(COLON); + setState(1053); + type(0); + } + } + + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(1056); + match(IDENTIFIER); + setState(1057); + genericTypeDeclaration(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class LiteralExpression_Context extends ParserRuleContext { + public TerminalNode INTEGER() { return getToken(CocoParser.INTEGER, 0); } + public TerminalNode CHAR_LITERAL() { return getToken(CocoParser.CHAR_LITERAL, 0); } + public TerminalNode STRING_LITERAL() { return getToken(CocoParser.STRING_LITERAL, 0); } + public LiteralExpression_Context(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_literalExpression_; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterLiteralExpression_(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitLiteralExpression_(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitLiteralExpression_(this); + else return visitor.visitChildren(this); + } + } + + public final LiteralExpression_Context literalExpression_() throws RecognitionException { + LiteralExpression_Context _localctx = new LiteralExpression_Context(_ctx, getState()); + enterRule(_localctx, 158, RULE_literalExpression_); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(1060); + _la = _input.LA(1); + if ( !(((((_la - 87)) & ~0x3f) == 0 && ((1L << (_la - 87)) & ((1L << (INTEGER - 87)) | (1L << (CHAR_LITERAL - 87)) | (1L << (STRING_LITERAL - 87)))) != 0)) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class TypeContext extends ParserRuleContext { + public TypeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_type; } + + public TypeContext() { } + public void copyFrom(TypeContext ctx) { + super.copyFrom(ctx); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class BinaryTypeContext extends TypeContext { + public List type() { + return getRuleContexts(TypeContext.class); + } + public TypeContext type(int i) { + return getRuleContext(TypeContext.class,i); + } + public TerminalNode MUL() { return getToken(CocoParser.MUL, 0); } + public TerminalNode DIV() { return getToken(CocoParser.DIV, 0); } + public TerminalNode MOD() { return getToken(CocoParser.MOD, 0); } + public TerminalNode PLUS() { return getToken(CocoParser.PLUS, 0); } + public TerminalNode MINUS() { return getToken(CocoParser.MINUS, 0); } + public BinaryTypeContext(TypeContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterBinaryType(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitBinaryType(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitBinaryType(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class GroupTypeContext extends TypeContext { + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public TypeContext type() { + return getRuleContext(TypeContext.class,0); + } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public GroupTypeContext(TypeContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterGroupType(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitGroupType(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitGroupType(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class FunctionTypeContext extends TypeContext { + public TerminalNode LP() { return getToken(CocoParser.LP, 0); } + public TypesContext types() { + return getRuleContext(TypesContext.class,0); + } + public TerminalNode RP() { return getToken(CocoParser.RP, 0); } + public TerminalNode ARROW() { return getToken(CocoParser.ARROW, 0); } + public TypeContext type() { + return getRuleContext(TypeContext.class,0); + } + public FunctionTypeContext(TypeContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterFunctionType(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitFunctionType(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitFunctionType(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class UnaryTypeContext extends TypeContext { + public TerminalNode MINUS() { return getToken(CocoParser.MINUS, 0); } + public TypeContext type() { + return getRuleContext(TypeContext.class,0); + } + public UnaryTypeContext(TypeContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterUnaryType(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitUnaryType(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitUnaryType(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class LiteralTypeContext extends TypeContext { + public LiteralExpression_Context literalExpression_() { + return getRuleContext(LiteralExpression_Context.class,0); + } + public LiteralTypeContext(TypeContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterLiteralType(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitLiteralType(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitLiteralType(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class TypeReferenceContext extends TypeContext { + public DotIdentifierListContext dotIdentifierList() { + return getRuleContext(DotIdentifierListContext.class,0); + } + public TerminalNode LT() { return getToken(CocoParser.LT, 0); } + public TypesContext types() { + return getRuleContext(TypesContext.class,0); + } + public TerminalNode GT() { return getToken(CocoParser.GT, 0); } + public TerminalNode DOT() { return getToken(CocoParser.DOT, 0); } + public TerminalNode IDENTIFIER() { return getToken(CocoParser.IDENTIFIER, 0); } + public TypeReferenceContext(TypeContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterTypeReference(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitTypeReference(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitTypeReference(this); + else return visitor.visitChildren(this); + } + } + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class ReferenceTypeContext extends TypeContext { + public TerminalNode AMP() { return getToken(CocoParser.AMP, 0); } + public TypeContext type() { + return getRuleContext(TypeContext.class,0); + } + public TerminalNode MUT() { return getToken(CocoParser.MUT, 0); } + public TerminalNode OUT() { return getToken(CocoParser.OUT, 0); } + public ReferenceTypeContext(TypeContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterReferenceType(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitReferenceType(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitReferenceType(this); + else return visitor.visitChildren(this); + } + } + + public final TypeContext type() throws RecognitionException { + return type(0); + } + + private TypeContext type(int _p) throws RecognitionException { + ParserRuleContext _parentctx = _ctx; + int _parentState = getState(); + TypeContext _localctx = new TypeContext(_ctx, _parentState); + TypeContext _prevctx = _localctx; + int _startState = 160; + enterRecursionRule(_localctx, 160, RULE_type, _p); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(1092); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,127,_ctx) ) { + case 1: + { + _localctx = new GroupTypeContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + + setState(1063); + match(LP); + setState(1064); + type(0); + setState(1065); + match(RP); + } + break; + case 2: + { + _localctx = new TypeReferenceContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(1067); + dotIdentifierList(); + setState(1072); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,124,_ctx) ) { + case 1: + { + setState(1068); + match(LT); + setState(1069); + types(); + setState(1070); + match(GT); + } + break; + } + setState(1076); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,125,_ctx) ) { + case 1: + { + setState(1074); + match(DOT); + setState(1075); + match(IDENTIFIER); + } + break; + } + } + break; + case 3: + { + _localctx = new FunctionTypeContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(1078); + match(LP); + setState(1079); + types(); + setState(1080); + match(RP); + setState(1081); + match(ARROW); + setState(1082); + type(4); + } + break; + case 4: + { + _localctx = new LiteralTypeContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(1084); + literalExpression_(); + } + break; + case 5: + { + _localctx = new ReferenceTypeContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(1085); + match(AMP); + setState(1087); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==MUT || _la==OUT) { + { + setState(1086); + _la = _input.LA(1); + if ( !(_la==MUT || _la==OUT) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + + setState(1089); + type(2); + } + break; + case 6: + { + _localctx = new UnaryTypeContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(1090); + match(MINUS); + setState(1091); + type(1); + } + break; + } + _ctx.stop = _input.LT(-1); + setState(1102); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,129,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + if ( _parseListeners!=null ) triggerExitRuleEvent(); + _prevctx = _localctx; + { + setState(1100); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,128,_ctx) ) { + case 1: + { + _localctx = new BinaryTypeContext(new TypeContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_type); + setState(1094); + if (!(precpred(_ctx, 8))) throw new FailedPredicateException(this, "precpred(_ctx, 8)"); + setState(1095); + _la = _input.LA(1); + if ( !(((((_la - 65)) & ~0x3f) == 0 && ((1L << (_la - 65)) & ((1L << (MUL - 65)) | (1L << (DIV - 65)) | (1L << (MOD - 65)))) != 0)) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(1096); + type(9); + } + break; + case 2: + { + _localctx = new BinaryTypeContext(new TypeContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_type); + setState(1097); + if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)"); + setState(1098); + _la = _input.LA(1); + if ( !(_la==MINUS || _la==PLUS) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(1099); + type(8); + } + break; + } + } + } + setState(1104); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,129,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + unrollRecursionContexts(_parentctx); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class TypesContext extends ParserRuleContext { + public List type() { + return getRuleContexts(TypeContext.class); + } + public TypeContext type(int i) { + return getRuleContext(TypeContext.class,i); + } + public List COMMA() { return getTokens(CocoParser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(CocoParser.COMMA, i); + } + public TypesContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_types; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterTypes(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitTypes(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitTypes(this); + else return visitor.visitChildren(this); + } + } + + public final TypesContext types() throws RecognitionException { + TypesContext _localctx = new TypesContext(_ctx, getState()); + enterRule(_localctx, 162, RULE_types); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(1105); + type(0); + setState(1110); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==COMMA) { + { + { + setState(1106); + match(COMMA); + setState(1107); + type(0); + } + } + setState(1112); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public static class DotIdentifierListContext extends ParserRuleContext { + public List IDENTIFIER() { return getTokens(CocoParser.IDENTIFIER); } + public TerminalNode IDENTIFIER(int i) { + return getToken(CocoParser.IDENTIFIER, i); + } + public List DOT() { return getTokens(CocoParser.DOT); } + public TerminalNode DOT(int i) { + return getToken(CocoParser.DOT, i); + } + public DotIdentifierListContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_dotIdentifierList; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).enterDotIdentifierList(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CocoListener ) ((CocoListener)listener).exitDotIdentifierList(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof CocoVisitor ) return ((CocoVisitor)visitor).visitDotIdentifierList(this); + else return visitor.visitChildren(this); + } + } + + public final DotIdentifierListContext dotIdentifierList() throws RecognitionException { + DotIdentifierListContext _localctx = new DotIdentifierListContext(_ctx, getState()); + enterRule(_localctx, 164, RULE_dotIdentifierList); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(1113); + match(IDENTIFIER); + setState(1118); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,131,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(1114); + match(DOT); + setState(1115); + match(IDENTIFIER); + } + } + } + setState(1120); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,131,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { + switch (ruleIndex) { + case 29: + return expression_sempred((ExpressionContext)_localctx, predIndex); + case 80: + return type_sempred((TypeContext)_localctx, predIndex); + } + return true; + } + private boolean expression_sempred(ExpressionContext _localctx, int predIndex) { + switch (predIndex) { + case 0: + return precpred(_ctx, 12); + case 1: + return precpred(_ctx, 11); + case 2: + return precpred(_ctx, 10); + case 3: + return precpred(_ctx, 9); + case 4: + return precpred(_ctx, 20); + case 5: + return precpred(_ctx, 18); + case 6: + return precpred(_ctx, 17); + case 7: + return precpred(_ctx, 16); + case 8: + return precpred(_ctx, 15); + case 9: + return precpred(_ctx, 13); + } + return true; + } + private boolean type_sempred(TypeContext _localctx, int predIndex) { + switch (predIndex) { + case 10: + return precpred(_ctx, 8); + case 11: + return precpred(_ctx, 7); + } + return true; + } + + public static final String _serializedATN = + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\\\u0464\4\2\t\2\4"+ + "\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t"+ + "\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ + "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+ + "\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+ + "\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4"+ + ",\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64\t"+ + "\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\4=\t="+ + "\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4I"+ + "\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\tT"+ + "\3\2\7\2\u00aa\n\2\f\2\16\2\u00ad\13\2\3\2\3\2\3\3\7\3\u00b2\n\3\f\3\16"+ + "\3\u00b5\13\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\5\3"+ + "\u00c4\n\3\3\4\3\4\3\4\3\4\3\4\3\4\5\4\u00cc\n\4\3\5\3\5\3\5\3\5\3\5\5"+ + "\5\u00d3\n\5\3\5\5\5\u00d6\n\5\3\6\3\6\5\6\u00da\n\6\3\6\3\6\3\6\5\6\u00df"+ + "\n\6\3\7\5\7\u00e2\n\7\3\7\3\7\3\7\5\7\u00e7\n\7\3\7\3\7\5\7\u00eb\n\7"+ + "\3\7\3\7\5\7\u00ef\n\7\3\b\3\b\3\b\5\b\u00f4\n\b\3\b\3\b\7\b\u00f8\n\b"+ + "\f\b\16\b\u00fb\13\b\3\b\3\b\3\t\3\t\3\t\5\t\u0102\n\t\3\t\3\t\7\t\u0106"+ + "\n\t\f\t\16\t\u0109\13\t\3\t\3\t\3\n\3\n\3\n\5\n\u0110\n\n\3\n\3\n\3\n"+ + "\3\13\3\13\3\13\5\13\u0118\n\13\3\13\3\13\5\13\u011c\n\13\3\13\3\13\3"+ + "\13\3\13\3\13\3\13\3\f\3\f\3\f\5\f\u0127\n\f\3\f\3\f\3\f\3\f\3\f\3\r\3"+ + "\r\3\r\3\r\5\r\u0132\n\r\3\r\5\r\u0135\n\r\3\r\3\r\7\r\u0139\n\r\f\r\16"+ + "\r\u013c\13\r\3\r\3\r\3\16\5\16\u0141\n\16\3\16\3\16\3\16\3\16\5\16\u0147"+ + "\n\16\3\16\3\16\7\16\u014b\n\16\f\16\16\16\u014e\13\16\3\16\3\16\3\17"+ + "\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3\20\3\20\7\20\u015f"+ + "\n\20\f\20\16\20\u0162\13\20\3\20\5\20\u0165\n\20\3\21\3\21\3\21\5\21"+ + "\u016a\n\21\3\21\5\21\u016d\n\21\3\22\3\22\3\22\3\22\3\22\5\22\u0174\n"+ + "\22\3\22\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\23\5\23\u0180\n\23"+ + "\3\23\3\23\3\24\3\24\3\24\7\24\u0187\n\24\f\24\16\24\u018a\13\24\3\25"+ + "\5\25\u018d\n\25\3\25\3\25\3\25\5\25\u0192\n\25\3\26\3\26\5\26\u0196\n"+ + "\26\3\26\3\26\5\26\u019a\n\26\3\27\3\27\3\27\3\27\5\27\u01a0\n\27\3\27"+ + "\5\27\u01a3\n\27\3\27\3\27\5\27\u01a7\n\27\3\30\3\30\3\30\7\30\u01ac\n"+ + "\30\f\30\16\30\u01af\13\30\3\31\3\31\3\31\3\31\3\32\3\32\5\32\u01b7\n"+ + "\32\3\32\3\32\5\32\u01bb\n\32\3\32\5\32\u01be\n\32\3\33\5\33\u01c1\n\33"+ + "\3\33\3\33\3\33\3\33\3\33\5\33\u01c8\n\33\3\34\7\34\u01cb\n\34\f\34\16"+ + "\34\u01ce\13\34\3\34\3\34\3\34\3\34\3\34\5\34\u01d5\n\34\3\34\5\34\u01d8"+ + "\n\34\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\36\3\36\3\36\5\36\u01e5"+ + "\n\36\3\36\3\36\3\36\3\36\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37"+ + "\3\37\5\37\u01f5\n\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37"+ + "\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\5\37\u020a\n\37\3\37\3\37"+ + "\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37"+ + "\3\37\3\37\5\37\u021e\n\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37"+ + "\3\37\3\37\3\37\3\37\3\37\3\37\3\37\7\37\u0230\n\37\f\37\16\37\u0233\13"+ + "\37\3 \3 \7 \u0237\n \f \16 \u023a\13 \3 \5 \u023d\n \3 \3 \3!\3!\3!\3"+ + "!\3!\3!\3!\5!\u0248\n!\3\"\3\"\5\"\u024c\n\"\3\"\3\"\3\"\3\"\3\"\3\"\3"+ + "\"\3\"\3#\3#\3#\3#\3#\5#\u025b\n#\3#\5#\u025e\n#\3#\3#\3$\3$\3$\7$\u0265"+ + "\n$\f$\16$\u0268\13$\3$\5$\u026b\n$\3%\3%\3%\3%\3&\3&\3&\7&\u0274\n&\f"+ + "&\16&\u0277\13&\3&\5&\u027a\n&\3\'\3\'\3\'\3\'\3\'\5\'\u0281\n\'\3\'\3"+ + "\'\3(\3(\3(\7(\u0288\n(\f(\16(\u028b\13(\3(\5(\u028e\n(\3)\3)\3)\3)\3"+ + "*\3*\3*\5*\u0297\n*\3+\3+\3+\3+\3+\3+\5+\u029f\n+\3,\3,\3,\7,\u02a4\n"+ + ",\f,\16,\u02a7\13,\3,\3,\3,\3,\7,\u02ad\n,\f,\16,\u02b0\13,\5,\u02b2\n"+ + ",\3-\3-\3-\5-\u02b7\n-\3-\5-\u02ba\n-\3.\3.\3.\3.\5.\u02c0\n.\3/\3/\3"+ + "/\7/\u02c5\n/\f/\16/\u02c8\13/\3\60\5\60\u02cb\n\60\3\60\3\60\3\61\3\61"+ + "\3\61\7\61\u02d2\n\61\f\61\16\61\u02d5\13\61\3\62\7\62\u02d8\n\62\f\62"+ + "\16\62\u02db\13\62\3\62\3\62\5\62\u02df\n\62\3\62\3\62\5\62\u02e3\n\62"+ + "\3\62\3\62\3\62\3\62\3\62\3\62\3\62\5\62\u02ec\n\62\3\63\3\63\3\63\3\64"+ + "\3\64\3\64\3\64\3\65\3\65\3\65\3\65\3\66\3\66\5\66\u02fb\n\66\3\66\3\66"+ + "\3\66\3\66\3\66\3\66\3\67\3\67\5\67\u0305\n\67\3\67\3\67\3\67\3\67\5\67"+ + "\u030b\n\67\3\67\3\67\3\67\3\67\38\38\58\u0313\n8\38\38\39\39\59\u0319"+ + "\n9\39\39\3:\7:\u031e\n:\f:\16:\u0321\13:\3:\3:\3:\3:\3:\3:\3:\3:\3:\3"+ + ":\5:\u032d\n:\3;\3;\3;\3;\5;\u0333\n;\3;\3;\3;\3;\3<\3<\3<\3<\3<\5<\u033e"+ + "\n<\3<\3<\3=\3=\5=\u0344\n=\3=\3=\5=\u0348\n=\3=\3=\7=\u034c\n=\f=\16"+ + "=\u034f\13=\3=\3=\3>\7>\u0354\n>\f>\16>\u0357\13>\3>\3>\3>\3>\3>\3>\3"+ + ">\3>\3>\3>\5>\u0363\n>\3?\3?\5?\u0367\n?\3@\3@\3@\3@\5@\u036d\n@\3@\5"+ + "@\u0370\n@\3@\3@\7@\u0374\n@\f@\16@\u0377\13@\3@\3@\3A\3A\3A\3A\3A\5A"+ + "\u0380\nA\3A\5A\u0383\nA\3A\3A\3B\7B\u0388\nB\fB\16B\u038b\13B\3B\3B\3"+ + "B\3B\3B\3B\3B\3B\3B\3B\3B\5B\u0398\nB\3C\3C\3C\3C\3C\3C\3D\3D\3D\3D\3"+ + "D\3D\3E\3E\3E\3E\3E\3F\3F\3F\5F\u03ae\nF\3G\3G\3G\3G\3G\5G\u03b5\nG\3"+ + "G\3G\3G\7G\u03ba\nG\fG\16G\u03bd\13G\3G\3G\3G\5G\u03c2\nG\3G\3G\3G\3G"+ + "\3H\3H\3H\3H\3H\5H\u03cd\nH\3H\3H\5H\u03d1\nH\3I\3I\3I\3I\3I\5I\u03d8"+ + "\nI\3I\3I\3I\3I\3J\3J\3J\3J\3J\3J\3J\3K\3K\3K\5K\u03e8\nK\3L\3L\3L\3L"+ + "\3L\3L\5L\u03f0\nL\5L\u03f2\nL\3L\3L\3M\3M\3M\7M\u03f9\nM\fM\16M\u03fc"+ + "\13M\3M\5M\u03ff\nM\3N\7N\u0402\nN\fN\16N\u0405\13N\3N\3N\3N\3N\3N\5N"+ + "\u040c\nN\3N\3N\3O\3O\3O\7O\u0413\nO\fO\16O\u0416\13O\3P\5P\u0419\nP\3"+ + "P\3P\5P\u041d\nP\3P\3P\5P\u0421\nP\3P\3P\5P\u0425\nP\3Q\3Q\3R\3R\3R\3"+ + "R\3R\3R\3R\3R\3R\3R\5R\u0433\nR\3R\3R\5R\u0437\nR\3R\3R\3R\3R\3R\3R\3"+ + "R\3R\3R\5R\u0442\nR\3R\3R\3R\5R\u0447\nR\3R\3R\3R\3R\3R\3R\7R\u044f\n"+ + "R\fR\16R\u0452\13R\3S\3S\3S\7S\u0457\nS\fS\16S\u045a\13S\3T\3T\3T\7T\u045f"+ + "\nT\fT\16T\u0462\13T\3T\2\4<\u00a2U\2\4\6\b\n\f\16\20\22\24\26\30\32\34"+ + "\36 \"$&(*,.\60\62\64\668:<>@BDFHJLNPRTVXZ\\^`bdfhjlnprtvxz|~\u0080\u0082"+ + "\u0084\u0086\u0088\u008a\u008c\u008e\u0090\u0092\u0094\u0096\u0098\u009a"+ + "\u009c\u009e\u00a0\u00a2\u00a4\u00a6\2\r\3\2\60\61\3\2\35\36\5\2EEJJM"+ + "M\4\2CDFF\4\2EEGG\4\2ABOT\3\2>?\4\2\60\60@@\4\2\3\3%%\4\2YY[\\\4\2\35"+ + "\35##\2\u04e0\2\u00ab\3\2\2\2\4\u00b3\3\2\2\2\6\u00c5\3\2\2\2\b\u00cd"+ + "\3\2\2\2\n\u00d7\3\2\2\2\f\u00e1\3\2\2\2\16\u00f0\3\2\2\2\20\u00fe\3\2"+ + "\2\2\22\u010c\3\2\2\2\24\u0114\3\2\2\2\26\u0123\3\2\2\2\30\u012d\3\2\2"+ + "\2\32\u0140\3\2\2\2\34\u0151\3\2\2\2\36\u0159\3\2\2\2 \u016c\3\2\2\2\""+ + "\u016e\3\2\2\2$\u017b\3\2\2\2&\u0183\3\2\2\2(\u018c\3\2\2\2*\u0199\3\2"+ + "\2\2,\u019b\3\2\2\2.\u01a8\3\2\2\2\60\u01b0\3\2\2\2\62\u01ba\3\2\2\2\64"+ + "\u01c0\3\2\2\2\66\u01cc\3\2\2\28\u01d9\3\2\2\2:\u01e1\3\2\2\2<\u0209\3"+ + "\2\2\2>\u0234\3\2\2\2@\u0240\3\2\2\2B\u024b\3\2\2\2D\u0255\3\2\2\2F\u0261"+ + "\3\2\2\2H\u026c\3\2\2\2J\u0270\3\2\2\2L\u0280\3\2\2\2N\u0284\3\2\2\2P"+ + "\u028f\3\2\2\2R\u0296\3\2\2\2T\u0298\3\2\2\2V\u02b1\3\2\2\2X\u02b3\3\2"+ + "\2\2Z\u02bb\3\2\2\2\\\u02c1\3\2\2\2^\u02ca\3\2\2\2`\u02ce\3\2\2\2b\u02d9"+ + "\3\2\2\2d\u02ed\3\2\2\2f\u02f0\3\2\2\2h\u02f4\3\2\2\2j\u02fa\3\2\2\2l"+ + "\u0304\3\2\2\2n\u0310\3\2\2\2p\u0316\3\2\2\2r\u031f\3\2\2\2t\u032e\3\2"+ + "\2\2v\u0338\3\2\2\2x\u0341\3\2\2\2z\u0355\3\2\2\2|\u0366\3\2\2\2~\u0368"+ + "\3\2\2\2\u0080\u037a\3\2\2\2\u0082\u0389\3\2\2\2\u0084\u0399\3\2\2\2\u0086"+ + "\u039f\3\2\2\2\u0088\u03a5\3\2\2\2\u008a\u03ad\3\2\2\2\u008c\u03b4\3\2"+ + "\2\2\u008e\u03c7\3\2\2\2\u0090\u03d7\3\2\2\2\u0092\u03dd\3\2\2\2\u0094"+ + "\u03e7\3\2\2\2\u0096\u03e9\3\2\2\2\u0098\u03f5\3\2\2\2\u009a\u0403\3\2"+ + "\2\2\u009c\u040f\3\2\2\2\u009e\u0424\3\2\2\2\u00a0\u0426\3\2\2\2\u00a2"+ + "\u0446\3\2\2\2\u00a4\u0453\3\2\2\2\u00a6\u045b\3\2\2\2\u00a8\u00aa\5\4"+ + "\3\2\u00a9\u00a8\3\2\2\2\u00aa\u00ad\3\2\2\2\u00ab\u00a9\3\2\2\2\u00ab"+ + "\u00ac\3\2\2\2\u00ac\u00ae\3\2\2\2\u00ad\u00ab\3\2\2\2\u00ae\u00af\7\2"+ + "\2\3\u00af\3\3\2\2\2\u00b0\u00b2\5\6\4\2\u00b1\u00b0\3\2\2\2\u00b2\u00b5"+ + "\3\2\2\2\u00b3\u00b1\3\2\2\2\u00b3\u00b4\3\2\2\2\u00b4\u00c3\3\2\2\2\u00b5"+ + "\u00b3\3\2\2\2\u00b6\u00c4\5\n\6\2\u00b7\u00c4\5\f\7\2\u00b8\u00c4\5\16"+ + "\b\2\u00b9\u00c4\5\20\t\2\u00ba\u00c4\5\22\n\2\u00bb\u00c4\5\24\13\2\u00bc"+ + "\u00c4\5\26\f\2\u00bd\u00c4\5\30\r\2\u00be\u00c4\5\32\16\2\u00bf\u00c4"+ + "\5\34\17\2\u00c0\u00c4\5\"\22\2\u00c1\u00c4\5\36\20\2\u00c2\u00c4\5\b"+ + "\5\2\u00c3\u00b6\3\2\2\2\u00c3\u00b7\3\2\2\2\u00c3\u00b8\3\2\2\2\u00c3"+ + "\u00b9\3\2\2\2\u00c3\u00ba\3\2\2\2\u00c3\u00bb\3\2\2\2\u00c3\u00bc\3\2"+ + "\2\2\u00c3\u00bd\3\2\2\2\u00c3\u00be\3\2\2\2\u00c3\u00bf\3\2\2\2\u00c3"+ + "\u00c0\3\2\2\2\u00c3\u00c1\3\2\2\2\u00c3\u00c2\3\2\2\2\u00c4\5\3\2\2\2"+ + "\u00c5\u00c6\7\65\2\2\u00c6\u00cb\5\u00a6T\2\u00c7\u00c8\78\2\2\u00c8"+ + "\u00c9\5`\61\2\u00c9\u00ca\79\2\2\u00ca\u00cc\3\2\2\2\u00cb\u00c7\3\2"+ + "\2\2\u00cb\u00cc\3\2\2\2\u00cc\7\3\2\2\2\u00cd\u00ce\7\6\2\2\u00ce\u00cf"+ + "\7\65\2\2\u00cf\u00d5\5\u00a6T\2\u00d0\u00d2\78\2\2\u00d1\u00d3\5\u009c"+ + "O\2\u00d2\u00d1\3\2\2\2\u00d2\u00d3\3\2\2\2\u00d3\u00d4\3\2\2\2\u00d4"+ + "\u00d6\79\2\2\u00d5\u00d0\3\2\2\2\u00d5\u00d6\3\2\2\2\u00d6\t\3\2\2\2"+ + "\u00d7\u00d9\7\27\2\2\u00d8\u00da\7/\2\2\u00d9\u00d8\3\2\2\2\u00d9\u00da"+ + "\3\2\2\2\u00da\u00db\3\2\2\2\u00db\u00de\5\u00a6T\2\u00dc\u00dd\7\4\2"+ + "\2\u00dd\u00df\7\64\2\2\u00de\u00dc\3\2\2\2\u00de\u00df\3\2\2\2\u00df"+ + "\13\3\2\2\2\u00e0\u00e2\7\'\2\2\u00e1\u00e0\3\2\2\2\u00e1\u00e2\3\2\2"+ + "\2\u00e2\u00e3\3\2\2\2\u00e3\u00e4\t\2\2\2\u00e4\u00e6\7\64\2\2\u00e5"+ + "\u00e7\5$\23\2\u00e6\u00e5\3\2\2\2\u00e6\u00e7\3\2\2\2\u00e7\u00ea\3\2"+ + "\2\2\u00e8\u00e9\7\67\2\2\u00e9\u00eb\5\u00a2R\2\u00ea\u00e8\3\2\2\2\u00ea"+ + "\u00eb\3\2\2\2\u00eb\u00ee\3\2\2\2\u00ec\u00ed\7\66\2\2\u00ed\u00ef\5"+ + "<\37\2\u00ee\u00ec\3\2\2\2\u00ee\u00ef\3\2\2\2\u00ef\r\3\2\2\2\u00f0\u00f1"+ + "\7\r\2\2\u00f1\u00f3\7\64\2\2\u00f2\u00f4\5$\23\2\u00f3\u00f2\3\2\2\2"+ + "\u00f3\u00f4\3\2\2\2\u00f4\u00f5\3\2\2\2\u00f5\u00f9\7:\2\2\u00f6\u00f8"+ + "\5*\26\2\u00f7\u00f6\3\2\2\2\u00f8\u00fb\3\2\2\2\u00f9\u00f7\3\2\2\2\u00f9"+ + "\u00fa\3\2\2\2\u00fa\u00fc\3\2\2\2\u00fb\u00f9\3\2\2\2\u00fc\u00fd\7;"+ + "\2\2\u00fd\17\3\2\2\2\u00fe\u00ff\7-\2\2\u00ff\u0101\7\64\2\2\u0100\u0102"+ + "\5$\23\2\u0101\u0100\3\2\2\2\u0101\u0102\3\2\2\2\u0102\u0103\3\2\2\2\u0103"+ + "\u0107\7:\2\2\u0104\u0106\5\62\32\2\u0105\u0104\3\2\2\2\u0106\u0109\3"+ + "\2\2\2\u0107\u0105\3\2\2\2\u0107\u0108\3\2\2\2\u0108\u010a\3\2\2\2\u0109"+ + "\u0107\3\2\2\2\u010a\u010b\7;\2\2\u010b\21\3\2\2\2\u010c\u010d\7.\2\2"+ + "\u010d\u010f\7\64\2\2\u010e\u0110\5$\23\2\u010f\u010e\3\2\2\2\u010f\u0110"+ + "\3\2\2\2\u0110\u0111\3\2\2\2\u0111\u0112\7\66\2\2\u0112\u0113\5\u00a2"+ + "R\2\u0113\23\3\2\2\2\u0114\u0115\7\24\2\2\u0115\u0117\7\64\2\2\u0116\u0118"+ + "\5$\23\2\u0117\u0116\3\2\2\2\u0117\u0118\3\2\2\2\u0118\u0119\3\2\2\2\u0119"+ + "\u011b\78\2\2\u011a\u011c\5\u009cO\2\u011b\u011a\3\2\2\2\u011b\u011c\3"+ + "\2\2\2\u011c\u011d\3\2\2\2\u011d\u011e\79\2\2\u011e\u011f\7\67\2\2\u011f"+ + "\u0120\5\u00a2R\2\u0120\u0121\7\66\2\2\u0121\u0122\5<\37\2\u0122\25\3"+ + "\2\2\2\u0123\u0124\7\32\2\2\u0124\u0126\7\64\2\2\u0125\u0127\5$\23\2\u0126"+ + "\u0125\3\2\2\2\u0126\u0127\3\2\2\2\u0127\u0128\3\2\2\2\u0128\u0129\78"+ + "\2\2\u0129\u012a\5\u009cO\2\u012a\u012b\79\2\2\u012b\u012c\5> \2\u012c"+ + "\27\3\2\2\2\u012d\u012e\7&\2\2\u012e\u0131\7\64\2\2\u012f\u0130\7\67\2"+ + "\2\u0130\u0132\5\u00a4S\2\u0131\u012f\3\2\2\2\u0131\u0132\3\2\2\2\u0132"+ + "\u0134\3\2\2\2\u0133\u0135\7\22\2\2\u0134\u0133\3\2\2\2\u0134\u0135\3"+ + "\2\2\2\u0135\u0136\3\2\2\2\u0136\u013a\7:\2\2\u0137\u0139\5r:\2\u0138"+ + "\u0137\3\2\2\2\u0139\u013c\3\2\2\2\u013a\u0138\3\2\2\2\u013a\u013b\3\2"+ + "\2\2\u013b\u013d\3\2\2\2\u013c\u013a\3\2\2\2\u013d\u013e\7;\2\2\u013e"+ + "\31\3\2\2\2\u013f\u0141\7\21\2\2\u0140\u013f\3\2\2\2\u0140\u0141\3\2\2"+ + "\2\u0141\u0142\3\2\2\2\u0142\u0143\7\n\2\2\u0143\u0146\7\64\2\2\u0144"+ + "\u0145\7\67\2\2\u0145\u0147\5\u00a2R\2\u0146\u0144\3\2\2\2\u0146\u0147"+ + "\3\2\2\2\u0147\u0148\3\2\2\2\u0148\u014c\7:\2\2\u0149\u014b\5\66\34\2"+ + "\u014a\u0149\3\2\2\2\u014b\u014e\3\2\2\2\u014c\u014a\3\2\2\2\u014c\u014d"+ + "\3\2\2\2\u014d\u014f\3\2\2\2\u014e\u014c\3\2\2\2\u014f\u0150\7;\2\2\u0150"+ + "\33\3\2\2\2\u0151\u0152\7\21\2\2\u0152\u0153\7\60\2\2\u0153\u0154\7\64"+ + "\2\2\u0154\u0155\7\67\2\2\u0155\u0156\5\u00a2R\2\u0156\u0157\7\66\2\2"+ + "\u0157\u0158\5<\37\2\u0158\35\3\2\2\2\u0159\u015a\7\21\2\2\u015a\u015b"+ + "\7.\2\2\u015b\u0164\7\64\2\2\u015c\u0160\7:\2\2\u015d\u015f\5 \21\2\u015e"+ + "\u015d\3\2\2\2\u015f\u0162\3\2\2\2\u0160\u015e\3\2\2\2\u0160\u0161\3\2"+ + "\2\2\u0161\u0163\3\2\2\2\u0162\u0160\3\2\2\2\u0163\u0165\7;\2\2\u0164"+ + "\u015c\3\2\2\2\u0164\u0165\3\2\2\2\u0165\37\3\2\2\2\u0166\u016d\58\35"+ + "\2\u0167\u016d\5\f\7\2\u0168\u016a\t\3\2\2\u0169\u0168\3\2\2\2\u0169\u016a"+ + "\3\2\2\2\u016a\u016b\3\2\2\2\u016b\u016d\5\"\22\2\u016c\u0166\3\2\2\2"+ + "\u016c\u0167\3\2\2\2\u016c\u0169\3\2\2\2\u016d!\3\2\2\2\u016e\u016f\7"+ + "\21\2\2\u016f\u0170\7\24\2\2\u0170\u0171\7\64\2\2\u0171\u0173\78\2\2\u0172"+ + "\u0174\5\u009cO\2\u0173\u0172\3\2\2\2\u0173\u0174\3\2\2\2\u0174\u0175"+ + "\3\2\2\2\u0175\u0176\79\2\2\u0176\u0177\7\67\2\2\u0177\u0178\5\u00a2R"+ + "\2\u0178\u0179\7\66\2\2\u0179\u017a\5<\37\2\u017a#\3\2\2\2\u017b\u017c"+ + "\7A\2\2\u017c\u017f\5&\24\2\u017d\u017e\7\62\2\2\u017e\u0180\5`\61\2\u017f"+ + "\u017d\3\2\2\2\u017f\u0180\3\2\2\2\u0180\u0181\3\2\2\2\u0181\u0182\7B"+ + "\2\2\u0182%\3\2\2\2\u0183\u0188\5(\25\2\u0184\u0185\7>\2\2\u0185\u0187"+ + "\5(\25\2\u0186\u0184\3\2\2\2\u0187\u018a\3\2\2\2\u0188\u0186\3\2\2\2\u0188"+ + "\u0189\3\2\2\2\u0189\'\3\2\2\2\u018a\u0188\3\2\2\2\u018b\u018d\7\60\2"+ + "\2\u018c\u018b\3\2\2\2\u018c\u018d\3\2\2\2\u018d\u018e\3\2\2\2\u018e\u0191"+ + "\7\64\2\2\u018f\u0190\7\67\2\2\u0190\u0192\5\u00a2R\2\u0191\u018f\3\2"+ + "\2\2\u0191\u0192\3\2\2\2\u0192)\3\2\2\2\u0193\u019a\5,\27\2\u0194\u0196"+ + "\t\3\2\2\u0195\u0194\3\2\2\2\u0195\u0196\3\2\2\2\u0196\u0197\3\2\2\2\u0197"+ + "\u019a\5\24\13\2\u0198\u019a\58\35\2\u0199\u0193\3\2\2\2\u0199\u0195\3"+ + "\2\2\2\u0199\u0198\3\2\2\2\u019a+\3\2\2\2\u019b\u019c\7\t\2\2\u019c\u01a2"+ + "\7\64\2\2\u019d\u019f\78\2\2\u019e\u01a0\5.\30\2\u019f\u019e\3\2\2\2\u019f"+ + "\u01a0\3\2\2\2\u01a0\u01a1\3\2\2\2\u01a1\u01a3\79\2\2\u01a2\u019d\3\2"+ + "\2\2\u01a2\u01a3\3\2\2\2\u01a3\u01a6\3\2\2\2\u01a4\u01a5\7\66\2\2\u01a5"+ + "\u01a7\5<\37\2\u01a6\u01a4\3\2\2\2\u01a6\u01a7\3\2\2\2\u01a7-\3\2\2\2"+ + "\u01a8\u01ad\5\60\31\2\u01a9\u01aa\7>\2\2\u01aa\u01ac\5\60\31\2\u01ab"+ + "\u01a9\3\2\2\2\u01ac\u01af\3\2\2\2\u01ad\u01ab\3\2\2\2\u01ad\u01ae\3\2"+ + "\2\2\u01ae/\3\2\2\2\u01af\u01ad\3\2\2\2\u01b0\u01b1\7\64\2\2\u01b1\u01b2"+ + "\7\67\2\2\u01b2\u01b3\5\u00a2R\2\u01b3\61\3\2\2\2\u01b4\u01bb\5\64\33"+ + "\2\u01b5\u01b7\t\3\2\2\u01b6\u01b5\3\2\2\2\u01b6\u01b7\3\2\2\2\u01b7\u01b8"+ + "\3\2\2\2\u01b8\u01bb\5\24\13\2\u01b9\u01bb\58\35\2\u01ba\u01b4\3\2\2\2"+ + "\u01ba\u01b6\3\2\2\2\u01ba\u01b9\3\2\2\2\u01bb\u01bd\3\2\2\2\u01bc\u01be"+ + "\7?\2\2\u01bd\u01bc\3\2\2\2\u01bd\u01be\3\2\2\2\u01be\63\3\2\2\2\u01bf"+ + "\u01c1\t\2\2\2\u01c0\u01bf\3\2\2\2\u01c0\u01c1\3\2\2\2\u01c1\u01c2\3\2"+ + "\2\2\u01c2\u01c3\7\64\2\2\u01c3\u01c4\7\67\2\2\u01c4\u01c7\5\u00a2R\2"+ + "\u01c5\u01c6\7\66\2\2\u01c6\u01c8\5<\37\2\u01c7\u01c5\3\2\2\2\u01c7\u01c8"+ + "\3\2\2\2\u01c8\65\3\2\2\2\u01c9\u01cb\5\6\4\2\u01ca\u01c9\3\2\2\2\u01cb"+ + "\u01ce\3\2\2\2\u01cc\u01ca\3\2\2\2\u01cc\u01cd\3\2\2\2\u01cd\u01d4\3\2"+ + "\2\2\u01ce\u01cc\3\2\2\2\u01cf\u01d5\5\64\33\2\u01d0\u01d5\5\f\7\2\u01d1"+ + "\u01d5\5:\36\2\u01d2\u01d5\5x=\2\u01d3\u01d5\58\35\2\u01d4\u01cf\3\2\2"+ + "\2\u01d4\u01d0\3\2\2\2\u01d4\u01d1\3\2\2\2\u01d4\u01d2\3\2\2\2\u01d4\u01d3"+ + "\3\2\2\2\u01d5\u01d7\3\2\2\2\u01d6\u01d8\7?\2\2\u01d7\u01d6\3\2\2\2\u01d7"+ + "\u01d8\3\2\2\2\u01d8\67\3\2\2\2\u01d9\u01da\7,\2\2\u01da\u01db\7\60\2"+ + "\2\u01db\u01dc\7\64\2\2\u01dc\u01dd\7\67\2\2\u01dd\u01de\5\u00a2R\2\u01de"+ + "\u01df\7\66\2\2\u01df\u01e0\5<\37\2\u01e09\3\2\2\2\u01e1\u01e2\7\31\2"+ + "\2\u01e2\u01e4\78\2\2\u01e3\u01e5\5\u009cO\2\u01e4\u01e3\3\2\2\2\u01e4"+ + "\u01e5\3\2\2\2\u01e5\u01e6\3\2\2\2\u01e6\u01e7\79\2\2\u01e7\u01e8\7\66"+ + "\2\2\u01e8\u01e9\5> \2\u01e9;\3\2\2\2\u01ea\u01eb\b\37\1\2\u01eb\u020a"+ + "\5\u00a0Q\2\u01ec\u01ed\7\21\2\2\u01ed\u020a\7Z\2\2\u01ee\u020a\5\"\22"+ + "\2\u01ef\u01f4\5\u00a6T\2\u01f0\u01f1\7A\2\2\u01f1\u01f2\5&\24\2\u01f2"+ + "\u01f3\7B\2\2\u01f3\u01f5\3\2\2\2\u01f4\u01f0\3\2\2\2\u01f4\u01f5\3\2"+ + "\2\2\u01f5\u020a\3\2\2\2\u01f6\u020a\5\u0088E\2\u01f7\u01f8\t\4\2\2\u01f8"+ + "\u020a\5<\37\20\u01f9\u020a\5@!\2\u01fa\u020a\5B\"\2\u01fb\u01fc\7@\2"+ + "\2\u01fc\u020a\7\64\2\2\u01fd\u01fe\78\2\2\u01fe\u01ff\5`\61\2\u01ff\u0200"+ + "\79\2\2\u0200\u020a\3\2\2\2\u0201\u0202\7<\2\2\u0202\u0203\5<\37\2\u0203"+ + "\u0204\7=\2\2\u0204\u020a\3\2\2\2\u0205\u020a\5D#\2\u0206\u0207\7!\2\2"+ + "\u0207\u020a\5<\37\4\u0208\u020a\5> \2\u0209\u01ea\3\2\2\2\u0209\u01ec"+ + "\3\2\2\2\u0209\u01ee\3\2\2\2\u0209\u01ef\3\2\2\2\u0209\u01f6\3\2\2\2\u0209"+ + "\u01f7\3\2\2\2\u0209\u01f9\3\2\2\2\u0209\u01fa\3\2\2\2\u0209\u01fb\3\2"+ + "\2\2\u0209\u01fd\3\2\2\2\u0209\u0201\3\2\2\2\u0209\u0205\3\2\2\2\u0209"+ + "\u0206\3\2\2\2\u0209\u0208\3\2\2\2\u020a\u0231\3\2\2\2\u020b\u020c\f\16"+ + "\2\2\u020c\u020d\t\5\2\2\u020d\u0230\5<\37\17\u020e\u020f\f\r\2\2\u020f"+ + "\u0210\t\6\2\2\u0210\u0230\5<\37\16\u0211\u0212\f\f\2\2\u0212\u0213\t"+ + "\7\2\2\u0213\u0230\5<\37\r\u0214\u0215\f\13\2\2\u0215\u0216\7\66\2\2\u0216"+ + "\u0230\5<\37\f\u0217\u0218\f\26\2\2\u0218\u0219\7@\2\2\u0219\u0230\7\64"+ + "\2\2\u021a\u021b\f\24\2\2\u021b\u021d\78\2\2\u021c\u021e\5`\61\2\u021d"+ + "\u021c\3\2\2\2\u021d\u021e\3\2\2\2\u021e\u021f\3\2\2\2\u021f\u0230\79"+ + "\2\2\u0220\u0221\f\23\2\2\u0221\u0222\7<\2\2\u0222\u0223\5<\37\2\u0223"+ + "\u0224\7=\2\2\u0224\u0230\3\2\2\2\u0225\u0226\f\22\2\2\u0226\u0227\7:"+ + "\2\2\u0227\u0228\5F$\2\u0228\u0229\7;\2\2\u0229\u0230\3\2\2\2\u022a\u022b"+ + "\f\21\2\2\u022b\u0230\7K\2\2\u022c\u022d\f\17\2\2\u022d\u022e\7\4\2\2"+ + "\u022e\u0230\5\u00a2R\2\u022f\u020b\3\2\2\2\u022f\u020e\3\2\2\2\u022f"+ + "\u0211\3\2\2\2\u022f\u0214\3\2\2\2\u022f\u0217\3\2\2\2\u022f\u021a\3\2"+ + "\2\2\u022f\u0220\3\2\2\2\u022f\u0225\3\2\2\2\u022f\u022a\3\2\2\2\u022f"+ + "\u022c\3\2\2\2\u0230\u0233\3\2\2\2\u0231\u022f\3\2\2\2\u0231\u0232\3\2"+ + "\2\2\u0232=\3\2\2\2\u0233\u0231\3\2\2\2\u0234\u0238\7:\2\2\u0235\u0237"+ + "\5b\62\2\u0236\u0235\3\2\2\2\u0237\u023a\3\2\2\2\u0238\u0236\3\2\2\2\u0238"+ + "\u0239\3\2\2\2\u0239\u023c\3\2\2\2\u023a\u0238\3\2\2\2\u023b\u023d\5<"+ + "\37\2\u023c\u023b\3\2\2\2\u023c\u023d\3\2\2\2\u023d\u023e\3\2\2\2\u023e"+ + "\u023f\7;\2\2\u023f?\3\2\2\2\u0240\u0241\7\25\2\2\u0241\u0242\78\2\2\u0242"+ + "\u0243\5<\37\2\u0243\u0244\79\2\2\u0244\u0247\5<\37\2\u0245\u0246\7\f"+ + "\2\2\u0246\u0248\5<\37\2\u0247\u0245\3\2\2\2\u0247\u0248\3\2\2\2\u0248"+ + "A\3\2\2\2\u0249\u024a\7\64\2\2\u024a\u024c\7\67\2\2\u024b\u0249\3\2\2"+ + "\2\u024b\u024c\3\2\2\2\u024c\u024d\3\2\2\2\u024d\u024e\7\34\2\2\u024e"+ + "\u024f\78\2\2\u024f\u0250\5<\37\2\u0250\u0251\79\2\2\u0251\u0252\7:\2"+ + "\2\u0252\u0253\5N(\2\u0253\u0254\7;\2\2\u0254C\3\2\2\2\u0255\u0256\7\37"+ + "\2\2\u0256\u0257\7:\2\2\u0257\u025a\5J&\2\u0258\u0259\7\"\2\2\u0259\u025b"+ + "\5<\37\2\u025a\u0258\3\2\2\2\u025a\u025b\3\2\2\2\u025b\u025d\3\2\2\2\u025c"+ + "\u025e\t\b\2\2\u025d\u025c\3\2\2\2\u025d\u025e\3\2\2\2\u025e\u025f\3\2"+ + "\2\2\u025f\u0260\7;\2\2\u0260E\3\2\2\2\u0261\u0266\5H%\2\u0262\u0263\7"+ + ">\2\2\u0263\u0265\5H%\2\u0264\u0262\3\2\2\2\u0265\u0268\3\2\2\2\u0266"+ + "\u0264\3\2\2\2\u0266\u0267\3\2\2\2\u0267\u026a\3\2\2\2\u0268\u0266\3\2"+ + "\2\2\u0269\u026b\7>\2\2\u026a\u0269\3\2\2\2\u026a\u026b\3\2\2\2\u026b"+ + "G\3\2\2\2\u026c\u026d\7\64\2\2\u026d\u026e\7\66\2\2\u026e\u026f\5<\37"+ + "\2\u026fI\3\2\2\2\u0270\u0275\5L\'\2\u0271\u0272\t\b\2\2\u0272\u0274\5"+ + "L\'\2\u0273\u0271\3\2\2\2\u0274\u0277\3\2\2\2\u0275\u0273\3\2\2\2\u0275"+ + "\u0276\3\2\2\2\u0276\u0279\3\2\2\2\u0277\u0275\3\2\2\2\u0278\u027a\t\b"+ + "\2\2\u0279\u0278\3\2\2\2\u0279\u027a\3\2\2\2\u027aK\3\2\2\2\u027b\u027c"+ + "\7\25\2\2\u027c\u027d\78\2\2\u027d\u027e\5<\37\2\u027e\u027f\79\2\2\u027f"+ + "\u0281\3\2\2\2\u0280\u027b\3\2\2\2\u0280\u0281\3\2\2\2\u0281\u0282\3\2"+ + "\2\2\u0282\u0283\5<\37\2\u0283M\3\2\2\2\u0284\u0289\5P)\2\u0285\u0286"+ + "\t\b\2\2\u0286\u0288\5P)\2\u0287\u0285\3\2\2\2\u0288\u028b\3\2\2\2\u0289"+ + "\u0287\3\2\2\2\u0289\u028a\3\2\2\2\u028a\u028d\3\2\2\2\u028b\u0289\3\2"+ + "\2\2\u028c\u028e\t\b\2\2\u028d\u028c\3\2\2\2\u028d\u028e\3\2\2\2\u028e"+ + "O\3\2\2\2\u028f\u0290\5R*\2\u0290\u0291\7H\2\2\u0291\u0292\5<\37\2\u0292"+ + "Q\3\2\2\2\u0293\u0297\5T+\2\u0294\u0297\5\u00a0Q\2\u0295\u0297\5Z.\2\u0296"+ + "\u0293\3\2\2\2\u0296\u0294\3\2\2\2\u0296\u0295\3\2\2\2\u0297S\3\2\2\2"+ + "\u0298\u029e\5V,\2\u0299\u029a\7\25\2\2\u029a\u029b\78\2\2\u029b\u029c"+ + "\5<\37\2\u029c\u029d\79\2\2\u029d\u029f\3\2\2\2\u029e\u0299\3\2\2\2\u029e"+ + "\u029f\3\2\2\2\u029fU\3\2\2\2\u02a0\u02a5\5X-\2\u02a1\u02a2\7@\2\2\u02a2"+ + "\u02a4\5X-\2\u02a3\u02a1\3\2\2\2\u02a4\u02a7\3\2\2\2\u02a5\u02a3\3\2\2"+ + "\2\u02a5\u02a6\3\2\2\2\u02a6\u02b2\3\2\2\2\u02a7\u02a5\3\2\2\2\u02a8\u02a9"+ + "\7@\2\2\u02a9\u02ae\5X-\2\u02aa\u02ab\7@\2\2\u02ab\u02ad\5X-\2\u02ac\u02aa"+ + "\3\2\2\2\u02ad\u02b0\3\2\2\2\u02ae\u02ac\3\2\2\2\u02ae\u02af\3\2\2\2\u02af"+ + "\u02b2\3\2\2\2\u02b0\u02ae\3\2\2\2\u02b1\u02a0\3\2\2\2\u02b1\u02a8\3\2"+ + "\2\2\u02b2W\3\2\2\2\u02b3\u02b9\7\64\2\2\u02b4\u02b6\78\2\2\u02b5\u02b7"+ + "\5\\/\2\u02b6\u02b5\3\2\2\2\u02b6\u02b7\3\2\2\2\u02b7\u02b8\3\2\2\2\u02b8"+ + "\u02ba\79\2\2\u02b9\u02b4\3\2\2\2\u02b9\u02ba\3\2\2\2\u02baY\3\2\2\2\u02bb"+ + "\u02bc\t\t\2\2\u02bc\u02bf\7\64\2\2\u02bd\u02be\7\67\2\2\u02be\u02c0\5"+ + "\u00a2R\2\u02bf\u02bd\3\2\2\2\u02bf\u02c0\3\2\2\2\u02c0[\3\2\2\2\u02c1"+ + "\u02c6\5^\60\2\u02c2\u02c3\7>\2\2\u02c3\u02c5\5^\60\2\u02c4\u02c2\3\2"+ + "\2\2\u02c5\u02c8\3\2\2\2\u02c6\u02c4\3\2\2\2\u02c6\u02c7\3\2\2\2\u02c7"+ + "]\3\2\2\2\u02c8\u02c6\3\2\2\2\u02c9\u02cb\7\61\2\2\u02ca\u02c9\3\2\2\2"+ + "\u02ca\u02cb\3\2\2\2\u02cb\u02cc\3\2\2\2\u02cc\u02cd\7\64\2\2\u02cd_\3"+ + "\2\2\2\u02ce\u02d3\5<\37\2\u02cf\u02d0\7>\2\2\u02d0\u02d2\5<\37\2\u02d1"+ + "\u02cf\3\2\2\2\u02d2\u02d5\3\2\2\2\u02d3\u02d1\3\2\2\2\u02d3\u02d4\3\2"+ + "\2\2\u02d4a\3\2\2\2\u02d5\u02d3\3\2\2\2\u02d6\u02d8\5\6\4\2\u02d7\u02d6"+ + "\3\2\2\2\u02d8\u02db\3\2\2\2\u02d9\u02d7\3\2\2\2\u02d9\u02da\3\2\2\2\u02da"+ + "\u02eb\3\2\2\2\u02db\u02d9\3\2\2\2\u02dc\u02de\5<\37\2\u02dd\u02df\7?"+ + "\2\2\u02de\u02dd\3\2\2\2\u02de\u02df\3\2\2\2\u02df\u02ec\3\2\2\2\u02e0"+ + "\u02e2\5\u0088E\2\u02e1\u02e3\7?\2\2\u02e2\u02e1\3\2\2\2\u02e2\u02e3\3"+ + "\2\2\2\u02e3\u02ec\3\2\2\2\u02e4\u02ec\5d\63\2\u02e5\u02ec\5f\64\2\u02e6"+ + "\u02ec\5h\65\2\u02e7\u02ec\5j\66\2\u02e8\u02ec\5l\67\2\u02e9\u02ec\5n"+ + "8\2\u02ea\u02ec\5p9\2\u02eb\u02dc\3\2\2\2\u02eb\u02e0\3\2\2\2\u02eb\u02e4"+ + "\3\2\2\2\u02eb\u02e5\3\2\2\2\u02eb\u02e6\3\2\2\2\u02eb\u02e7\3\2\2\2\u02eb"+ + "\u02e8\3\2\2\2\u02eb\u02e9\3\2\2\2\u02eb\u02ea\3\2\2\2\u02ecc\3\2\2\2"+ + "\u02ed\u02ee\5\f\7\2\u02ee\u02ef\7?\2\2\u02efe\3\2\2\2\u02f0\u02f1\7("+ + "\2\2\u02f1\u02f2\5<\37\2\u02f2\u02f3\7?\2\2\u02f3g\3\2\2\2\u02f4\u02f5"+ + "\7\7\2\2\u02f5\u02f6\5<\37\2\u02f6\u02f7\7?\2\2\u02f7i\3\2\2\2\u02f8\u02f9"+ + "\7\64\2\2\u02f9\u02fb\7\67\2\2\u02fa\u02f8\3\2\2\2\u02fa\u02fb\3\2\2\2"+ + "\u02fb\u02fc\3\2\2\2\u02fc\u02fd\7\63\2\2\u02fd\u02fe\78\2\2\u02fe\u02ff"+ + "\5<\37\2\u02ff\u0300\79\2\2\u0300\u0301\5> \2\u0301k\3\2\2\2\u0302\u0303"+ + "\7\64\2\2\u0303\u0305\7\67\2\2\u0304\u0302\3\2\2\2\u0304\u0305\3\2\2\2"+ + "\u0305\u0306\3\2\2\2\u0306\u0307\7\23\2\2\u0307\u030a\7\64\2\2\u0308\u0309"+ + "\7\67\2\2\u0309\u030b\5\u00a2R\2\u030a\u0308\3\2\2\2\u030a\u030b\3\2\2"+ + "\2\u030b\u030c\3\2\2\2\u030c\u030d\7\30\2\2\u030d\u030e\5<\37\2\u030e"+ + "\u030f\5> \2\u030fm\3\2\2\2\u0310\u0312\7\b\2\2\u0311\u0313\7\64\2\2\u0312"+ + "\u0311\3\2\2\2\u0312\u0313\3\2\2\2\u0313\u0314\3\2\2\2\u0314\u0315\7?"+ + "\2\2\u0315o\3\2\2\2\u0316\u0318\7\13\2\2\u0317\u0319\7\64\2\2\u0318\u0317"+ + "\3\2\2\2\u0318\u0319\3\2\2\2\u0319\u031a\3\2\2\2\u031a\u031b\7?\2\2\u031b"+ + "q\3\2\2\2\u031c\u031e\5\6\4\2\u031d\u031c\3\2\2\2\u031e\u0321\3\2\2\2"+ + "\u031f\u031d\3\2\2\2\u031f\u0320\3\2\2\2\u0320\u032c\3\2\2\2\u0321\u031f"+ + "\3\2\2\2\u0322\u032d\5\16\b\2\u0323\u032d\5t;\2\u0324\u032d\5v<\2\u0325"+ + "\u032d\5\64\33\2\u0326\u032d\5x=\2\u0327\u032d\5\30\r\2\u0328\u032d\5"+ + "8\35\2\u0329\u032d\5\20\t\2\u032a\u032d\5\22\n\2\u032b\u032d\5\36\20\2"+ + "\u032c\u0322\3\2\2\2\u032c\u0323\3\2\2\2\u032c\u0324\3\2\2\2\u032c\u0325"+ + "\3\2\2\2\u032c\u0326\3\2\2\2\u032c\u0327\3\2\2\2\u032c\u0328\3\2\2\2\u032c"+ + "\u0329\3\2\2\2\u032c\u032a\3\2\2\2\u032c\u032b\3\2\2\2\u032ds\3\2\2\2"+ + "\u032e\u032f\7\24\2\2\u032f\u0330\7\64\2\2\u0330\u0332\78\2\2\u0331\u0333"+ + "\5\u009cO\2\u0332\u0331\3\2\2\2\u0332\u0333\3\2\2\2\u0333\u0334\3\2\2"+ + "\2\u0334\u0335\79\2\2\u0335\u0336\7\67\2\2\u0336\u0337\5\u00a2R\2\u0337"+ + "u\3\2\2\2\u0338\u0339\7$\2\2\u0339\u033a\7)\2\2\u033a\u033b\7\64\2\2\u033b"+ + "\u033d\78\2\2\u033c\u033e\5\u009cO\2\u033d\u033c\3\2\2\2\u033d\u033e\3"+ + "\2\2\2\u033e\u033f\3\2\2\2\u033f\u0340\79\2\2\u0340w\3\2\2\2\u0341\u0343"+ + "\7\33\2\2\u0342\u0344\7\64\2\2\u0343\u0342\3\2\2\2\u0343\u0344\3\2\2\2"+ + "\u0344\u0347\3\2\2\2\u0345\u0346\7\67\2\2\u0346\u0348\7\64\2\2\u0347\u0345"+ + "\3\2\2\2\u0347\u0348\3\2\2\2\u0348\u0349\3\2\2\2\u0349\u034d\7:\2\2\u034a"+ + "\u034c\5z>\2\u034b\u034a\3\2\2\2\u034c\u034f\3\2\2\2\u034d\u034b\3\2\2"+ + "\2\u034d\u034e\3\2\2\2\u034e\u0350\3\2\2\2\u034f\u034d\3\2\2\2\u0350\u0351"+ + "\7;\2\2\u0351y\3\2\2\2\u0352\u0354\5\6\4\2\u0353\u0352\3\2\2\2\u0354\u0357"+ + "\3\2\2\2\u0355\u0353\3\2\2\2\u0355\u0356\3\2\2\2\u0356\u0362\3\2\2\2\u0357"+ + "\u0355\3\2\2\2\u0358\u0363\5\16\b\2\u0359\u0363\5\u0084C\2\u035a\u0363"+ + "\5\u0086D\2\u035b\u0363\5\24\13\2\u035c\u0363\5\u0088E\2\u035d\u0363\5"+ + "|?\2\u035e\u0363\58\35\2\u035f\u0363\5\22\n\2\u0360\u0363\5\f\7\2\u0361"+ + "\u0363\5\u008aF\2\u0362\u0358\3\2\2\2\u0362\u0359\3\2\2\2\u0362\u035a"+ + "\3\2\2\2\u0362\u035b\3\2\2\2\u0362\u035c\3\2\2\2\u0362\u035d\3\2\2\2\u0362"+ + "\u035e\3\2\2\2\u0362\u035f\3\2\2\2\u0362\u0360\3\2\2\2\u0362\u0361\3\2"+ + "\2\2\u0363{\3\2\2\2\u0364\u0367\5~@\2\u0365\u0367\5\u0080A\2\u0366\u0364"+ + "\3\2\2\2\u0366\u0365\3\2\2\2\u0367}\3\2\2\2\u0368\u0369\7+\2\2\u0369\u036f"+ + "\7\64\2\2\u036a\u036c\78\2\2\u036b\u036d\5\u009cO\2\u036c\u036b\3\2\2"+ + "\2\u036c\u036d\3\2\2\2\u036d\u036e\3\2\2\2\u036e\u0370\79\2\2\u036f\u036a"+ + "\3\2\2\2\u036f\u0370\3\2\2\2\u0370\u0371\3\2\2\2\u0371\u0375\7:\2\2\u0372"+ + "\u0374\5\u0082B\2\u0373\u0372\3\2\2\2\u0374\u0377\3\2\2\2\u0375\u0373"+ + "\3\2\2\2\u0375\u0376\3\2\2\2\u0376\u0378\3\2\2\2\u0377\u0375\3\2\2\2\u0378"+ + "\u0379\7;\2\2\u0379\177\3\2\2\2\u037a\u037b\7\17\2\2\u037b\u037c\7+\2"+ + "\2\u037c\u0382\7\64\2\2\u037d\u037f\78\2\2\u037e\u0380\5\u009cO\2\u037f"+ + "\u037e\3\2\2\2\u037f\u0380\3\2\2\2\u0380\u0381\3\2\2\2\u0381\u0383\79"+ + "\2\2\u0382\u037d\3\2\2\2\u0382\u0383\3\2\2\2\u0383\u0384\3\2\2\2\u0384"+ + "\u0385\5> \2\u0385\u0081\3\2\2\2\u0386\u0388\5\6\4\2\u0387\u0386\3\2\2"+ + "\2\u0388\u038b\3\2\2\2\u0389\u0387\3\2\2\2\u0389\u038a\3\2\2\2\u038a\u0397"+ + "\3\2\2\2\u038b\u0389\3\2\2\2\u038c\u0398\5\16\b\2\u038d\u0398\5\u0084"+ + "C\2\u038e\u0398\5\u0086D\2\u038f\u0398\5\24\13\2\u0390\u0398\5|?\2\u0391"+ + "\u0398\5\u0088E\2\u0392\u0398\58\35\2\u0393\u0398\5\20\t\2\u0394\u0398"+ + "\5\u008aF\2\u0395\u0398\5\22\n\2\u0396\u0398\5\f\7\2\u0397\u038c\3\2\2"+ + "\2\u0397\u038d\3\2\2\2\u0397\u038e\3\2\2\2\u0397\u038f\3\2\2\2\u0397\u0390"+ + "\3\2\2\2\u0397\u0391\3\2\2\2\u0397\u0392\3\2\2\2\u0397\u0393\3\2\2\2\u0397"+ + "\u0394\3\2\2\2\u0397\u0395\3\2\2\2\u0397\u0396\3\2\2\2\u0398\u0083\3\2"+ + "\2\2\u0399\u039a\7\16\2\2\u039a\u039b\78\2\2\u039b\u039c\79\2\2\u039c"+ + "\u039d\7\66\2\2\u039d\u039e\5<\37\2\u039e\u0085\3\2\2\2\u039f\u03a0\7"+ + "\20\2\2\u03a0\u03a1\78\2\2\u03a1\u03a2\79\2\2\u03a2\u03a3\7\66\2\2\u03a3"+ + "\u03a4\5<\37\2\u03a4\u0087\3\2\2\2\u03a5\u03a6\7\5\2\2\u03a6\u03a7\78"+ + "\2\2\u03a7\u03a8\5<\37\2\u03a8\u03a9\79\2\2\u03a9\u0089\3\2\2\2\u03aa"+ + "\u03ae\5\u008cG\2\u03ab\u03ae\5\u0090I\2\u03ac\u03ae\5\u0092J\2\u03ad"+ + "\u03aa\3\2\2\2\u03ad\u03ab\3\2\2\2\u03ad\u03ac\3\2\2\2\u03ae\u008b\3\2"+ + "\2\2\u03af\u03b0\7\25\2\2\u03b0\u03b1\78\2\2\u03b1\u03b2\5<\37\2\u03b2"+ + "\u03b3\79\2\2\u03b3\u03b5\3\2\2\2\u03b4\u03af\3\2\2\2\u03b4\u03b5\3\2"+ + "\2\2\u03b5\u03bb\3\2\2\2\u03b6\u03b7\5\u008eH\2\u03b7\u03b8\7@\2\2\u03b8"+ + "\u03ba\3\2\2\2\u03b9\u03b6\3\2\2\2\u03ba\u03bd\3\2\2\2\u03bb\u03b9\3\2"+ + "\2\2\u03bb\u03bc\3\2\2\2\u03bc\u03be\3\2\2\2\u03bd\u03bb\3\2\2\2\u03be"+ + "\u03bf\5\u00a6T\2\u03bf\u03c1\78\2\2\u03c0\u03c2\5\u009cO\2\u03c1\u03c0"+ + "\3\2\2\2\u03c1\u03c2\3\2\2\2\u03c2\u03c3\3\2\2\2\u03c3\u03c4\79\2\2\u03c4"+ + "\u03c5\7\66\2\2\u03c5\u03c6\5\u0094K\2\u03c6\u008d\3\2\2\2\u03c7\u03d0"+ + "\7\64\2\2\u03c8\u03c9\7<\2\2\u03c9\u03cc\5R*\2\u03ca\u03cb\7L\2\2\u03cb"+ + "\u03cd\5<\37\2\u03cc\u03ca\3\2\2\2\u03cc\u03cd\3\2\2\2\u03cd\u03ce\3\2"+ + "\2\2\u03ce\u03cf\7=\2\2\u03cf\u03d1\3\2\2\2\u03d0\u03c8\3\2\2\2\u03d0"+ + "\u03d1\3\2\2\2\u03d1\u008f\3\2\2\2\u03d2\u03d3\7\25\2\2\u03d3\u03d4\7"+ + "8\2\2\u03d4\u03d5\5<\37\2\u03d5\u03d6\79\2\2\u03d6\u03d8\3\2\2\2\u03d7"+ + "\u03d2\3\2\2\2\u03d7\u03d8\3\2\2\2\u03d8\u03d9\3\2\2\2\u03d9\u03da\7*"+ + "\2\2\u03da\u03db\7\66\2\2\u03db\u03dc\5<\37\2\u03dc\u0091\3\2\2\2\u03dd"+ + "\u03de\t\n\2\2\u03de\u03df\78\2\2\u03df\u03e0\5<\37\2\u03e0\u03e1\79\2"+ + "\2\u03e1\u03e2\7\66\2\2\u03e2\u03e3\5<\37\2\u03e3\u0093\3\2\2\2\u03e4"+ + "\u03e8\5<\37\2\u03e5\u03e8\7\26\2\2\u03e6\u03e8\5\u0096L\2\u03e7\u03e4"+ + "\3\2\2\2\u03e7\u03e5\3\2\2\2\u03e7\u03e6\3\2\2\2\u03e8\u0095\3\2\2\2\u03e9"+ + "\u03ea\7 \2\2\u03ea\u03eb\7:\2\2\u03eb\u03f1\5\u0098M\2\u03ec\u03ed\7"+ + "\"\2\2\u03ed\u03ef\5\u0094K\2\u03ee\u03f0\7>\2\2\u03ef\u03ee\3\2\2\2\u03ef"+ + "\u03f0\3\2\2\2\u03f0\u03f2\3\2\2\2\u03f1\u03ec\3\2\2\2\u03f1\u03f2\3\2"+ + "\2\2\u03f2\u03f3\3\2\2\2\u03f3\u03f4\7;\2\2\u03f4\u0097\3\2\2\2\u03f5"+ + "\u03fa\5\u009aN\2\u03f6\u03f7\7>\2\2\u03f7\u03f9\5\u009aN\2\u03f8\u03f6"+ + "\3\2\2\2\u03f9\u03fc\3\2\2\2\u03fa\u03f8\3\2\2\2\u03fa\u03fb\3\2\2\2\u03fb"+ + "\u03fe\3\2\2\2\u03fc\u03fa\3\2\2\2\u03fd\u03ff\7>\2\2\u03fe\u03fd\3\2"+ + "\2\2\u03fe\u03ff\3\2\2\2\u03ff\u0099\3\2\2\2\u0400\u0402\5\6\4\2\u0401"+ + "\u0400\3\2\2\2\u0402\u0405\3\2\2\2\u0403\u0401\3\2\2\2\u0403\u0404\3\2"+ + "\2\2\u0404\u040b\3\2\2\2\u0405\u0403\3\2\2\2\u0406\u0407\7\25\2\2\u0407"+ + "\u0408\78\2\2\u0408\u0409\5<\37\2\u0409\u040a\79\2\2\u040a\u040c\3\2\2"+ + "\2\u040b\u0406\3\2\2\2\u040b\u040c\3\2\2\2\u040c\u040d\3\2\2\2\u040d\u040e"+ + "\5\u0094K\2\u040e\u009b\3\2\2\2\u040f\u0414\5\u009eP\2\u0410\u0411\7>"+ + "\2\2\u0411\u0413\5\u009eP\2\u0412\u0410\3\2\2\2\u0413\u0416\3\2\2\2\u0414"+ + "\u0412\3\2\2\2\u0414\u0415\3\2\2\2\u0415\u009d\3\2\2\2\u0416\u0414\3\2"+ + "\2\2\u0417\u0419\7\61\2\2\u0418\u0417\3\2\2\2\u0418\u0419\3\2\2\2\u0419"+ + "\u041a\3\2\2\2\u041a\u041c\7\64\2\2\u041b\u041d\7N\2\2\u041c\u041b\3\2"+ + "\2\2\u041c\u041d\3\2\2\2\u041d\u0420\3\2\2\2\u041e\u041f\7\67\2\2\u041f"+ + "\u0421\5\u00a2R\2\u0420\u041e\3\2\2\2\u0420\u0421\3\2\2\2\u0421\u0425"+ + "\3\2\2\2\u0422\u0423\7\64\2\2\u0423\u0425\5$\23\2\u0424\u0418\3\2\2\2"+ + "\u0424\u0422\3\2\2\2\u0425\u009f\3\2\2\2\u0426\u0427\t\13\2\2\u0427\u00a1"+ + "\3\2\2\2\u0428\u0429\bR\1\2\u0429\u042a\78\2\2\u042a\u042b\5\u00a2R\2"+ + "\u042b\u042c\79\2\2\u042c\u0447\3\2\2\2\u042d\u0432\5\u00a6T\2\u042e\u042f"+ + "\7A\2\2\u042f\u0430\5\u00a4S\2\u0430\u0431\7B\2\2\u0431\u0433\3\2\2\2"+ + "\u0432\u042e\3\2\2\2\u0432\u0433\3\2\2\2\u0433\u0436\3\2\2\2\u0434\u0435"+ + "\7@\2\2\u0435\u0437\7\64\2\2\u0436\u0434\3\2\2\2\u0436\u0437\3\2\2\2\u0437"+ + "\u0447\3\2\2\2\u0438\u0439\78\2\2\u0439\u043a\5\u00a4S\2\u043a\u043b\7"+ + "9\2\2\u043b\u043c\7I\2\2\u043c\u043d\5\u00a2R\6\u043d\u0447\3\2\2\2\u043e"+ + "\u0447\5\u00a0Q\2\u043f\u0441\7J\2\2\u0440\u0442\t\f\2\2\u0441\u0440\3"+ + "\2\2\2\u0441\u0442\3\2\2\2\u0442\u0443\3\2\2\2\u0443\u0447\5\u00a2R\4"+ + "\u0444\u0445\7E\2\2\u0445\u0447\5\u00a2R\3\u0446\u0428\3\2\2\2\u0446\u042d"+ + "\3\2\2\2\u0446\u0438\3\2\2\2\u0446\u043e\3\2\2\2\u0446\u043f\3\2\2\2\u0446"+ + "\u0444\3\2\2\2\u0447\u0450\3\2\2\2\u0448\u0449\f\n\2\2\u0449\u044a\t\5"+ + "\2\2\u044a\u044f\5\u00a2R\13\u044b\u044c\f\t\2\2\u044c\u044d\t\6\2\2\u044d"+ + "\u044f\5\u00a2R\n\u044e\u0448\3\2\2\2\u044e\u044b\3\2\2\2\u044f\u0452"+ + "\3\2\2\2\u0450\u044e\3\2\2\2\u0450\u0451\3\2\2\2\u0451\u00a3\3\2\2\2\u0452"+ + "\u0450\3\2\2\2\u0453\u0458\5\u00a2R\2\u0454\u0455\7>\2\2\u0455\u0457\5"+ + "\u00a2R\2\u0456\u0454\3\2\2\2\u0457\u045a\3\2\2\2\u0458\u0456\3\2\2\2"+ + "\u0458\u0459\3\2\2\2\u0459\u00a5\3\2\2\2\u045a\u0458\3\2\2\2\u045b\u0460"+ + "\7\64\2\2\u045c\u045d\7@\2\2\u045d\u045f\7\64\2\2\u045e\u045c\3\2\2\2"+ + "\u045f\u0462\3\2\2\2\u0460\u045e\3\2\2\2\u0460\u0461\3\2\2\2\u0461\u00a7"+ + "\3\2\2\2\u0462\u0460\3\2\2\2\u0086\u00ab\u00b3\u00c3\u00cb\u00d2\u00d5"+ + "\u00d9\u00de\u00e1\u00e6\u00ea\u00ee\u00f3\u00f9\u0101\u0107\u010f\u0117"+ + "\u011b\u0126\u0131\u0134\u013a\u0140\u0146\u014c\u0160\u0164\u0169\u016c"+ + "\u0173\u017f\u0188\u018c\u0191\u0195\u0199\u019f\u01a2\u01a6\u01ad\u01b6"+ + "\u01ba\u01bd\u01c0\u01c7\u01cc\u01d4\u01d7\u01e4\u01f4\u0209\u021d\u022f"+ + "\u0231\u0238\u023c\u0247\u024b\u025a\u025d\u0266\u026a\u0275\u0279\u0280"+ + "\u0289\u028d\u0296\u029e\u02a5\u02ae\u02b1\u02b6\u02b9\u02bf\u02c6\u02ca"+ + "\u02d3\u02d9\u02de\u02e2\u02eb\u02fa\u0304\u030a\u0312\u0318\u031f\u032c"+ + "\u0332\u033d\u0343\u0347\u034d\u0355\u0362\u0366\u036c\u036f\u0375\u037f"+ + "\u0382\u0389\u0397\u03ad\u03b4\u03bb\u03c1\u03cc\u03d0\u03d7\u03e7\u03ef"+ + "\u03f1\u03fa\u03fe\u0403\u040b\u0414\u0418\u041c\u0420\u0424\u0432\u0436"+ + "\u0441\u0446\u044e\u0450\u0458\u0460"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} diff --git a/pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoVisitor.java b/pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoVisitor.java new file mode 100644 index 00000000000..46d72f6f4e2 --- /dev/null +++ b/pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoVisitor.java @@ -0,0 +1,712 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +// CHECKSTYLE:OFF +// Generated from net/sourceforge/pmd/lang/coco/ast/Coco.g4 by ANTLR 4.9.3 +package net.sourceforge.pmd.lang.coco.ast; +import org.antlr.v4.runtime.tree.ParseTreeVisitor; + +/** + * This interface defines a complete generic visitor for a parse tree produced + * by {@link CocoParser}. + * + * @param The return type of the visit operation. Use {@link Void} for + * operations with no return type. + * + * @deprecated Since 7.8.0. This class was never intended to be generated. It will be removed with no replacement. + */ + +@Deprecated +@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool") + public interface CocoVisitor extends ParseTreeVisitor { + /** + * Visit a parse tree produced by {@link CocoParser#module}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitModule(CocoParser.ModuleContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#declaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitDeclaration(CocoParser.DeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#attribute}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitAttribute(CocoParser.AttributeContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#attributeDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitAttributeDeclaration(CocoParser.AttributeDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#importDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitImportDeclaration(CocoParser.ImportDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#variableDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitVariableDeclaration(CocoParser.VariableDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#enumDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitEnumDeclaration(CocoParser.EnumDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#structDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStructDeclaration(CocoParser.StructDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#typeAliasDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTypeAliasDeclaration(CocoParser.TypeAliasDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#functionDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitFunctionDeclaration(CocoParser.FunctionDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#instanceDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInstanceDeclaration(CocoParser.InstanceDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#portDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitPortDeclaration(CocoParser.PortDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#componentDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitComponentDeclaration(CocoParser.ComponentDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#externalConstantDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExternalConstantDeclaration(CocoParser.ExternalConstantDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#externalTypeDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExternalTypeDeclaration(CocoParser.ExternalTypeDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#externalTypeElement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExternalTypeElement(CocoParser.ExternalTypeElementContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#externalFunctionDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExternalFunctionDeclaration(CocoParser.ExternalFunctionDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#genericTypeDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitGenericTypeDeclaration(CocoParser.GenericTypeDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#genericTypes}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitGenericTypes(CocoParser.GenericTypesContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#genericType}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitGenericType(CocoParser.GenericTypeContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#enumElement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitEnumElement(CocoParser.EnumElementContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#enumCase}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitEnumCase(CocoParser.EnumCaseContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#caseParameters}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitCaseParameters(CocoParser.CaseParametersContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#caseParameter}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitCaseParameter(CocoParser.CaseParameterContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#structElement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStructElement(CocoParser.StructElementContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#fieldDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitFieldDeclaration(CocoParser.FieldDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#componentElement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitComponentElement(CocoParser.ComponentElementContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#staticMemberDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStaticMemberDeclaration(CocoParser.StaticMemberDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#constructorDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitConstructorDeclaration(CocoParser.ConstructorDeclarationContext ctx); + /** + * Visit a parse tree produced by the {@code IfExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitIfExpression(CocoParser.IfExpressionContext ctx); + /** + * Visit a parse tree produced by the {@code TryOperatorExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTryOperatorExpression(CocoParser.TryOperatorExpressionContext ctx); + /** + * Visit a parse tree produced by the {@code UnaryOperatorExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitUnaryOperatorExpression(CocoParser.UnaryOperatorExpressionContext ctx); + /** + * Visit a parse tree produced by the {@code OptionalExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitOptionalExpression(CocoParser.OptionalExpressionContext ctx); + /** + * Visit a parse tree produced by the {@code ArithmicOrLogicalExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitArithmicOrLogicalExpression(CocoParser.ArithmicOrLogicalExpressionContext ctx); + /** + * Visit a parse tree produced by the {@code LiteralExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitLiteralExpression(CocoParser.LiteralExpressionContext ctx); + /** + * Visit a parse tree produced by the {@code ArrayLiteralExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitArrayLiteralExpression(CocoParser.ArrayLiteralExpressionContext ctx); + /** + * Visit a parse tree produced by the {@code NondetExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitNondetExpression(CocoParser.NondetExpressionContext ctx); + /** + * Visit a parse tree produced by the {@code GroupedExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitGroupedExpression(CocoParser.GroupedExpressionContext ctx); + /** + * Visit a parse tree produced by the {@code BlockExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitBlockExpression(CocoParser.BlockExpressionContext ctx); + /** + * Visit a parse tree produced by the {@code MatchExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitMatchExpression(CocoParser.MatchExpressionContext ctx); + /** + * Visit a parse tree produced by the {@code StructLiteralExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStructLiteralExpression(CocoParser.StructLiteralExpressionContext ctx); + /** + * Visit a parse tree produced by the {@code MemberReferenceExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitMemberReferenceExpression(CocoParser.MemberReferenceExpressionContext ctx); + /** + * Visit a parse tree produced by the {@code AssignmentExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitAssignmentExpression(CocoParser.AssignmentExpressionContext ctx); + /** + * Visit a parse tree produced by the {@code VariableReferenceExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitVariableReferenceExpression(CocoParser.VariableReferenceExpressionContext ctx); + /** + * Visit a parse tree produced by the {@code ImplicitMemberExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitImplicitMemberExpression(CocoParser.ImplicitMemberExpressionContext ctx); + /** + * Visit a parse tree produced by the {@code ExternalFunction} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExternalFunction(CocoParser.ExternalFunctionContext ctx); + /** + * Visit a parse tree produced by the {@code CastExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitCastExpression(CocoParser.CastExpressionContext ctx); + /** + * Visit a parse tree produced by the {@code StateInvariantExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStateInvariantExpression(CocoParser.StateInvariantExpressionContext ctx); + /** + * Visit a parse tree produced by the {@code CallExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitCallExpression(CocoParser.CallExpressionContext ctx); + /** + * Visit a parse tree produced by the {@code ExternalLiteral} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExternalLiteral(CocoParser.ExternalLiteralContext ctx); + /** + * Visit a parse tree produced by the {@code ArraySubscriptExpression} + * labeled alternative in {@link CocoParser#expression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitArraySubscriptExpression(CocoParser.ArraySubscriptExpressionContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#blockExpression_}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitBlockExpression_(CocoParser.BlockExpression_Context ctx); + /** + * Visit a parse tree produced by {@link CocoParser#ifExpression_}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitIfExpression_(CocoParser.IfExpression_Context ctx); + /** + * Visit a parse tree produced by {@link CocoParser#matchExpression_}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitMatchExpression_(CocoParser.MatchExpression_Context ctx); + /** + * Visit a parse tree produced by {@link CocoParser#nondetExpression_}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitNondetExpression_(CocoParser.NondetExpression_Context ctx); + /** + * Visit a parse tree produced by {@link CocoParser#fieldAssignments}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitFieldAssignments(CocoParser.FieldAssignmentsContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#fieldAssignment}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitFieldAssignment(CocoParser.FieldAssignmentContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#nondetClauses}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitNondetClauses(CocoParser.NondetClausesContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#nondetClause}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitNondetClause(CocoParser.NondetClauseContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#matchClauses}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitMatchClauses(CocoParser.MatchClausesContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#matchClause}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitMatchClause(CocoParser.MatchClauseContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#pattern}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitPattern(CocoParser.PatternContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#enumCasePattern}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitEnumCasePattern(CocoParser.EnumCasePatternContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#idParameterPatterns}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitIdParameterPatterns(CocoParser.IdParameterPatternsContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#idParameterPattern}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitIdParameterPattern(CocoParser.IdParameterPatternContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#variableDeclarationPattern}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitVariableDeclarationPattern(CocoParser.VariableDeclarationPatternContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#parameterPatterns}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitParameterPatterns(CocoParser.ParameterPatternsContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#parameterPattern}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitParameterPattern(CocoParser.ParameterPatternContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#expressions}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExpressions(CocoParser.ExpressionsContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#statement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStatement(CocoParser.StatementContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#declarationStatement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitDeclarationStatement(CocoParser.DeclarationStatementContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#returnStatement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitReturnStatement(CocoParser.ReturnStatementContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#becomeStatement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitBecomeStatement(CocoParser.BecomeStatementContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#whileStatement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitWhileStatement(CocoParser.WhileStatementContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#forStatement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitForStatement(CocoParser.ForStatementContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#breakStatement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitBreakStatement(CocoParser.BreakStatementContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#continueStatement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitContinueStatement(CocoParser.ContinueStatementContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#portElement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitPortElement(CocoParser.PortElementContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#functionInterfaceDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitFunctionInterfaceDeclaration(CocoParser.FunctionInterfaceDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#signalDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitSignalDeclaration(CocoParser.SignalDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#stateMachineDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStateMachineDeclaration(CocoParser.StateMachineDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#stateMachineElement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStateMachineElement(CocoParser.StateMachineElementContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#stateDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStateDeclaration(CocoParser.StateDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#eventStateDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitEventStateDeclaration(CocoParser.EventStateDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#executionStateDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExecutionStateDeclaration(CocoParser.ExecutionStateDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#eventStateElement}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitEventStateElement(CocoParser.EventStateElementContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#entryFunctionDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitEntryFunctionDeclaration(CocoParser.EntryFunctionDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#exitFunctionDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExitFunctionDeclaration(CocoParser.ExitFunctionDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#stateInvariant}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStateInvariant(CocoParser.StateInvariantContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#transitionDeclaration}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTransitionDeclaration(CocoParser.TransitionDeclarationContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#eventTransition}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitEventTransition(CocoParser.EventTransitionContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#eventSource}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitEventSource(CocoParser.EventSourceContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#spontaneousTransition}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitSpontaneousTransition(CocoParser.SpontaneousTransitionContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#timerTransition}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTimerTransition(CocoParser.TimerTransitionContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#eventHandler}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitEventHandler(CocoParser.EventHandlerContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#offer}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitOffer(CocoParser.OfferContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#offerClauses}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitOfferClauses(CocoParser.OfferClausesContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#offerClause}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitOfferClause(CocoParser.OfferClauseContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#parameters}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitParameters(CocoParser.ParametersContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#parameter}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitParameter(CocoParser.ParameterContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#literalExpression_}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitLiteralExpression_(CocoParser.LiteralExpression_Context ctx); + /** + * Visit a parse tree produced by the {@code BinaryType} + * labeled alternative in {@link CocoParser#type}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitBinaryType(CocoParser.BinaryTypeContext ctx); + /** + * Visit a parse tree produced by the {@code GroupType} + * labeled alternative in {@link CocoParser#type}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitGroupType(CocoParser.GroupTypeContext ctx); + /** + * Visit a parse tree produced by the {@code FunctionType} + * labeled alternative in {@link CocoParser#type}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitFunctionType(CocoParser.FunctionTypeContext ctx); + /** + * Visit a parse tree produced by the {@code UnaryType} + * labeled alternative in {@link CocoParser#type}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitUnaryType(CocoParser.UnaryTypeContext ctx); + /** + * Visit a parse tree produced by the {@code LiteralType} + * labeled alternative in {@link CocoParser#type}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitLiteralType(CocoParser.LiteralTypeContext ctx); + /** + * Visit a parse tree produced by the {@code TypeReference} + * labeled alternative in {@link CocoParser#type}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTypeReference(CocoParser.TypeReferenceContext ctx); + /** + * Visit a parse tree produced by the {@code ReferenceType} + * labeled alternative in {@link CocoParser#type}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitReferenceType(CocoParser.ReferenceTypeContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#types}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTypes(CocoParser.TypesContext ctx); + /** + * Visit a parse tree produced by {@link CocoParser#dotIdentifierList}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitDotIdentifierList(CocoParser.DotIdentifierListContext ctx); +} From ea6689bface7e6832edd5dec2794d4e20d14a344 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Sun, 17 Nov 2024 16:14:31 -0300 Subject: [PATCH 0265/1962] Update changelog --- docs/pages/release_notes.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 14dc38def2d..04bad61db32 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -44,6 +44,17 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿšจ API Changes #### Deprecations +* pmd-coco + * {%jdoc coco::lang.coco.ast.CocoBaseListener %} is deprecated for removal. This class was never intended + to be generated. It will be removed with no replacement. + * {%jdoc coco::lang.coco.ast.CocoBaseVisitor %} is deprecated for removal. This class was never intended + to be generated. It will be removed with no replacement. + * {%jdoc coco::lang.coco.ast.CocoListener %} is deprecated for removal. This class was never intended + to be generated. It will be removed with no replacement. + * {%jdoc coco::lang.coco.ast.CocoParser %} is deprecated for removal. This class was never intended + to be generated. It will be removed with no replacement. + * {%jdoc coco::lang.coco.ast.CocoVisitor %} is deprecated for removal. This class was never intended + to be generated. It will be removed with no replacement. * pmd-gherkin * {%jdoc gherkin::lang.gherkin.ast.GherkinBaseListener %} is deprecated for removal. This class was never intended to be generated. It will be removed with no replacement. From 2243991f3cf7c9c38cfaab9149cf0d0d31bee1b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Sun, 17 Nov 2024 16:19:10 -0300 Subject: [PATCH 0266/1962] Add cleanup after generating ts lexer --- pmd-javascript/pom.xml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index bb46814cfc7..70629cc7ca4 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -27,6 +27,27 @@ org.antlr antlr4-maven-plugin
    + + org.apache.maven.plugins + maven-antrun-plugin + + + antlr-cleanup + generate-sources + + run + + + + + + + + + + + + maven-resources-plugin From aa115202c7bdb9378b1cace3827e34f4f5520d2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Sun, 17 Nov 2024 16:22:41 -0300 Subject: [PATCH 0267/1962] Ignore CPD in generated code --- .../main/java/net/sourceforge/pmd/lang/coco/ast/CocoParser.java | 1 + 1 file changed, 1 insertion(+) diff --git a/pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoParser.java b/pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoParser.java index a091be9d24b..aac2c30df20 100644 --- a/pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoParser.java +++ b/pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/ast/CocoParser.java @@ -2,6 +2,7 @@ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ +// CPD-OFF // CHECKSTYLE:OFF // Generated from net/sourceforge/pmd/lang/coco/ast/Coco.g4 by ANTLR 4.9.3 package net.sourceforge.pmd.lang.coco.ast; From fed128155c8d05b9f485eb1fb452601e962a190d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Sun, 17 Nov 2024 16:30:02 -0300 Subject: [PATCH 0268/1962] [tsql] Flag generated lexer as generated --- pmd-tsql/pom.xml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index 8094d1662d5..0bc61234493 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -17,6 +17,27 @@ org.antlr antlr4-maven-plugin + + org.apache.maven.plugins + maven-antrun-plugin + + + antlr-cleanup + generate-sources + + run + + + + + + + + + + + + maven-resources-plugin From 5efe279abb5ccfc57fd6bf9c154effb0e9477249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Sun, 17 Nov 2024 16:33:10 -0300 Subject: [PATCH 0269/1962] Ensure timestamp flags don't collide --- antlr4-wrapper.xml | 2 +- javacc-wrapper.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/antlr4-wrapper.xml b/antlr4-wrapper.xml index bf6bc88ee67..fac0445d012 100644 --- a/antlr4-wrapper.xml +++ b/antlr4-wrapper.xml @@ -15,7 +15,7 @@ - + diff --git a/javacc-wrapper.xml b/javacc-wrapper.xml index cde14d0ae19..1e782ca565f 100644 --- a/javacc-wrapper.xml +++ b/javacc-wrapper.xml @@ -38,7 +38,7 @@ - + From 46ef55c9a9d28f040fbe547376bc44ae3ab590f5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 03:46:56 +0000 Subject: [PATCH 0270/1962] Bump rouge from 4.5.0 to 4.5.1 in the all-gems group across 1 directory Bumps the all-gems group with 1 update in the / directory: [rouge](https://github.com/rouge-ruby/rouge). Updates `rouge` from 4.5.0 to 4.5.1 - [Release notes](https://github.com/rouge-ruby/rouge/releases) - [Changelog](https://github.com/rouge-ruby/rouge/blob/master/CHANGELOG.md) - [Commits](https://github.com/rouge-ruby/rouge/compare/v4.5.0...v4.5.1) --- updated-dependencies: - dependency-name: rouge dependency-type: direct:development update-type: version-update:semver-patch dependency-group: all-gems ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 41dfc5878a2..f8a2bea4ede 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -75,7 +75,7 @@ GEM racc (1.8.1) rchardet (1.8.0) rexml (3.3.9) - rouge (4.5.0) + rouge (4.5.1) rufus-scheduler (3.9.2) fugit (~> 1.1, >= 1.11.1) safe_yaml (1.0.5) From 2e4f16d5163122581d983ea550b895215d010c97 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 04:05:13 +0000 Subject: [PATCH 0271/1962] Bump org.apache.commons:commons-lang3 from 3.14.0 to 3.17.0 Bumps org.apache.commons:commons-lang3 from 3.14.0 to 3.17.0. --- updated-dependencies: - dependency-name: org.apache.commons:commons-lang3 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index dec91f16ef1..09c4793b2f9 100644 --- a/pom.xml +++ b/pom.xml @@ -863,7 +863,7 @@ org.apache.commons commons-lang3 - 3.14.0 + 3.17.0 org.apache.commons From e8a0be1cdfb3193e6c4b810d4e1e39c0696fc197 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 4 Nov 2024 15:37:45 +0100 Subject: [PATCH 0272/1962] Fix #5283 - inner class has public private modifiers --- .../pmd/lang/java/symbols/internal/asm/ClassStub.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java index 15ae7b0535d..aaadf8b7b67 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java @@ -207,17 +207,17 @@ in InnerClasses (resp. ClassInfo), the rest are available in both) Since the differences are disjoint we can just OR the two sets of flags. */ - + final int visibilityMask = Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE; int myAccess = this.accessFlags; if (fromClassInfo) { // we don't care about ACC_SUPER and it conflicts // with ACC_SYNCHRONIZED accessFlags = accessFlags & ~Opcodes.ACC_SUPER; } else if ((myAccess & Opcodes.ACC_PUBLIC) != 0 - && (accessFlags & Opcodes.ACC_PROTECTED) != 0) { + && (accessFlags & visibilityMask) != Opcodes.ACC_PUBLIC) { // ClassInfo mentions ACC_PUBLIC even if the real - // visibility is protected - // We remove the public to avoid a "public protected" combination + // visibility is protected or private + // We remove the public to avoid a "public protected" or "public private" combination myAccess = myAccess & ~Opcodes.ACC_PUBLIC; } this.accessFlags = myAccess | accessFlags; From 97ac5664de4bee01b48aa8b7b16dbeb0d4c5a4f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 18 Nov 2024 11:02:25 +0100 Subject: [PATCH 0273/1962] Add tests --- .../symbols/internal/asm/ClassStubTest.java | 34 ++++++++++++++++-- .../InterfaceWithPrivateInner$.class | Bin 0 -> 537 bytes .../InterfaceWithPrivateInner$AndThen.class | Bin 0 -> 1039 bytes .../InterfaceWithPrivateInner$Inner.class | Bin 0 -> 1097 bytes .../InterfaceWithPrivateInner.class | Bin 0 -> 1734 bytes .../InterfaceWithPrivateInner.scala | 24 +++++++++++++ .../InterfaceWithPrivateInner.tasty | Bin 0 -> 1017 bytes 7 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/scalaclasses/InterfaceWithPrivateInner$.class create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/scalaclasses/InterfaceWithPrivateInner$AndThen.class create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/scalaclasses/InterfaceWithPrivateInner$Inner.class create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/scalaclasses/InterfaceWithPrivateInner.class create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/scalaclasses/InterfaceWithPrivateInner.scala create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/scalaclasses/InterfaceWithPrivateInner.tasty diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStubTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStubTest.java index dd63b8d47d5..b5a221886d2 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStubTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStubTest.java @@ -6,7 +6,9 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasProperty; import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.sameInstance; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -17,6 +19,7 @@ import java.util.List; import org.checkerframework.checker.nullness.qual.NonNull; +import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Test; import org.pcollections.PSet; @@ -118,6 +121,24 @@ void targetRecordComponentReflectionTest() { } + @Test + void testLoadScalaPrivateClassInInterface() { + TypeSystem ts = TypeSystem.usingClassLoaderClasspath(JavaParsingHelper.class.getClassLoader()); + JClassSymbol itf = loadScalaClass(ts, "InterfaceWithPrivateInner"); + assertThat(itf, hasProperty("interface", equalTo(true))); + assertThat(itf.getDeclaredClasses(), hasSize(2)); + + JClassSymbol inner = loadScalaClass(ts, "InterfaceWithPrivateInner$Inner"); + assertThat(inner, sameInstance(itf.getDeclaredClass("Inner"))); + assertThat(inner, hasProperty("modifiers", equalTo(Modifier.PRIVATE))); + + JClassSymbol innerOfObj = loadScalaClass(ts, "InterfaceWithPrivateInner$AndThen"); + assertThat(innerOfObj, sameInstance(itf.getDeclaredClass("AndThen"))); + assertThat(innerOfObj, hasProperty("modifiers", equalTo(Modifier.PRIVATE | Modifier.STATIC))); + } + + + private static void assertIsListWithTyAnnotation(JClassType withTyAnnotation) { assertThat(withTyAnnotation.getSymbol().getBinaryName(), equalTo("java.util.List")); @@ -128,11 +149,20 @@ private static void assertIsListWithTyAnnotation(JClassType withTyAnnotation) { } + private static @NonNull JClassSymbol loadScalaClass(TypeSystem typeSystem, String simpleName) { + return loadClassInPackage("net.sourceforge.pmd.lang.java.symbols.scalaclasses", simpleName, typeSystem); + } + private static @NonNull JClassSymbol loadRecordClass(TypeSystem typeSystem, String simpleName) { - String binaryName = "net.sourceforge.pmd.lang.java.symbols.recordclasses." + simpleName; + JClassSymbol symbol = loadClassInPackage("net.sourceforge.pmd.lang.java.symbols.recordclasses", simpleName, typeSystem); + assertTrue(symbol.isRecord(), "is a record"); + return symbol; + } + + private static @NotNull JClassSymbol loadClassInPackage(String x, String simpleName, TypeSystem typeSystem) { + String binaryName = x + "." + simpleName; JClassSymbol sym = typeSystem.getClassSymbol(binaryName); assertNotNull(sym, binaryName + " not found"); - assertTrue(sym.isRecord(), "is a record"); return sym; } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/scalaclasses/InterfaceWithPrivateInner$.class b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/scalaclasses/InterfaceWithPrivateInner$.class new file mode 100644 index 0000000000000000000000000000000000000000..28f624fbc7df3b7a1f674afa278a9db5f12d088d GIT binary patch literal 537 zcmb_ZO-}+b5Pe-fmR(Q~{5X2ypd8$on0SzQ@gpHw#0152cPUV^bj@}l@n;ziB%1gG z{87efnW;C^O>X!B^$vhRVdO1 z7(7#uJcqmrU4|V(EwbjgA8^*Fy;|UyRyTxmvWDVy*4XO2p>8M+n)I5_7=;QcwaBae Y649`A3fQ&G686Y?v@K?28TJX{2d}Vw+yDRo literal 0 HcmV?d00001 diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/scalaclasses/InterfaceWithPrivateInner$AndThen.class b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/scalaclasses/InterfaceWithPrivateInner$AndThen.class new file mode 100644 index 0000000000000000000000000000000000000000..d49e436ab403f4457dd3b70d345dad9186f0b9ac GIT binary patch literal 1039 zcmb_b%TB^j5Is|Y@~EQterv)4SlET`G$zKxgoG$Yg6m7UNKLslZ6)z%{03cVT=)Tg zlyU9_ce?9lo_EfinautA{`drNggrt>$;6Gr$HI2DLfyIdVl3SFY19jY z*o{3A2rm$EEMvE+5*ZDICvW{^*pB?MNMutf8CB0zzcZA|1`*~BfPuQ|-AgaAF+*sj z+0RCnu=_8a1H+nNPie6wCIkuXT0K=N$AtV8yh?bkr3;=iR|h3HCFC$m$RtBQCUjFJ z{CfzzmE4K1{N$7{Q>%9!ETB?E28*1i>I5(AI_+g~n`Nx%`Br(p^RO=o<(9AH<>RO) zqmJkW9I3QIKI*QBeC~ai0*mo!< literal 0 HcmV?d00001 diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/scalaclasses/InterfaceWithPrivateInner$Inner.class b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/scalaclasses/InterfaceWithPrivateInner$Inner.class new file mode 100644 index 0000000000000000000000000000000000000000..5eed85a33307503784ca2d4b3b6305b7e8579a3b GIT binary patch literal 1097 zcmb_b%Wl(95Iy504sl*?f%2xRHBz8B>P2=L&mF-mGuRsDJ zv4ABKAB8x+2~sz(@@D4FcphhtXMX+u_8q`;>kPnVKqyl%+CT9sUT8WrZayS=Q>@eK)((1{17L z9Tma;KU1HX4uVmccSd|9rbi53KV zw0vrzt_?n;^Rf7hdz7|uHgTWtB9sB>!lf3DxXY*_`Hb44b`O7|CO-y;U(gwR#obTz zRq((_u}wk81UA{ZZHn$~61PQJ!k`m8WKvDga9zTFM8jc63w7M0d`#OSk|)$1g0c)2 JGYy{7hd=mNGHCz+ literal 0 HcmV?d00001 diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/scalaclasses/InterfaceWithPrivateInner.class b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/scalaclasses/InterfaceWithPrivateInner.class new file mode 100644 index 0000000000000000000000000000000000000000..344ed0531c77fc6001170a5ec41db05c3531b237 GIT binary patch literal 1734 zcmb_c>rNY25T4n?dVTN(uN@#516|l~4{o>!Fc4`m2{8r&HX&H5TOHfS_9ACCLAe=hV&wB2CuP&Qz zuO+iTb{pA_a9Y`0@gTC^r*6&dcv-J5I-=eYo+rI*!SQ9UDeCg0?YA#__Ji~HHPwR7IoElqp$_kciF5m$~Y^~I*y##o}o-cb;cWp5~5WfqH~S2i3Tc@ z8vk&3i4j#*DoNc;?c5hnHpjb_jhk}mNGn#ie#)0t$4@dlO}VUFvqunUeJRM>$tNc~1 zy7M68tF3M(*Dfw|G%dv~mNF<*1-C8TYP{2wy(KP8i}}Z)#`sI77<>GcUij{yTues= zo@}}0l9`{glDc|lqz4Q^X6=7vvxeTKNg?fx|H*q&tuKQjGA*ZZ)s~J196@_B5K05pc&gec z6<4rD2#ZHq6XBP|fqoo&OM|7Om`%TJd-OU_F(X_o4p<}#Nk~ONfoBNkgN{G6Z#%aC z8i6e?T}NRYo)5z?Odt$B-YaDG&nXj^gU-Y?Y2@98L>M`>9eIA=t;yb%sCCGbJawt_ zT#KIFx1XGeGwHY8#)asKuB7fquO1C5CjZzI5r)e_6MbvAP>xZpHhs<|(%E`;>bL)4l9Sc1a{B*>m7D+@?J0Co8@jQ&a+1!iat z1Hnh&!(>3kAp=uSajX!w zkH_C=`Z|X2S22+6zhh8gmH`tpx= N=syU;JRL9<;2&8Zvk3qI literal 0 HcmV?d00001 diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/scalaclasses/InterfaceWithPrivateInner.scala b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/scalaclasses/InterfaceWithPrivateInner.scala new file mode 100644 index 00000000000..0d67e00d967 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/scalaclasses/InterfaceWithPrivateInner.scala @@ -0,0 +1,24 @@ +package net.sourceforge.pmd.lang.java.symbols.scalaclasses + +/** + * This source is compiled manually with scalac 2.12 and + * the classes are checked in for tests. In Scala, + * class members of interfaces can be private, not in Java. + * + * Note that scalac >3 does not generate private classes + * for these! + */ +trait InterfaceWithPrivateInner { + import InterfaceWithPrivateInner._ + + // This class has modifiers private + private class Inner + + def andThen : InterfaceWithPrivateInner = new AndThen() + +} + +object InterfaceWithPrivateInner { + // This class has modifiers private static + private class AndThen extends InterfaceWithPrivateInner +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/scalaclasses/InterfaceWithPrivateInner.tasty b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/scalaclasses/InterfaceWithPrivateInner.tasty new file mode 100644 index 0000000000000000000000000000000000000000..95f8c1fa5ab63c5c9ad8856330767c8b78989a71 GIT binary patch literal 1017 zcmZ`&UuYaf7~gM8EBGdr=Fxc$%@q_Mgs#0%5K<9CFCs|s*t<-6TX$!}?rduE;O))c z?QSl~_O3}TceyinNn@^QO>$nXS}oG2J}5{7N`r;s1*AeN&9g#r_7bTtzRZ5Je7`?4 z^Zm{(Uw@^Rv!`N7S(VXik=G-y3KK8AFtdB}XW^K0@57xZ)k6))_Q!@ya0sR_W$KoZ z#3QxrO%_oPA;`X*%G;~&U%X&@7aT(?zZ zg-fScu>_t>hKEv^h-@b4$yC7W|98Jwi_FD(zVo+3AoH6OkXq^U-jZMg%4)2Hyx47`u7ce=fn@Z@^1pl8 znJEPNRcSkVv@!NF|oNO`~vyyMtZ5!`MzEke(H1@!o6>{c;(hgz#cWy zYkPam!n*w>v~zInL~rkls22^T6cg>|1Mw=UYomPBhLI){OIFo!bdgUv+D`%E!x~~} z3ZsKaAlcw`3MW6}7=<97F~nb&nh`WWP%I43@etB&M;g`=*f5bk!g~)=#5HAt5*Ur{ bN9j1?Gagc%;em{B?1?v`f^hpL%QXK1k~y`i literal 0 HcmV?d00001 From 12f7f98803bdc837aa4f8208aab7956faa0dec0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 18 Nov 2024 11:43:51 +0100 Subject: [PATCH 0274/1962] Fix junit 5 warning return type of factory method must be a collection or array or stream --- .../net/sourceforge/pmd/lang/ast/impl/AbstractNodeTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/impl/AbstractNodeTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/impl/AbstractNodeTest.java index 824086f38ea..430f6b3dc8c 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/impl/AbstractNodeTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/impl/AbstractNodeTest.java @@ -48,7 +48,7 @@ private static Integer[] getIntRange(final int exclusiveLimit) { return childIndexes; } - static Object childrenAndGrandChildrenIndexes() { + static Object[] childrenAndGrandChildrenIndexes() { final Integer[] childrenIndexes = childrenIndexes(); final Integer[] grandChildrenIndexes = grandChildrenIndexes(); final Object[] indexes = new Object[childrenIndexes.length * grandChildrenIndexes.length]; From d5efa45f1f4ad529475a6c55d4044e1339257587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 19 Nov 2024 13:03:50 +0100 Subject: [PATCH 0275/1962] [java] Infer permitted subtypes when needed --- .../ast/ASTAnonymousClassDeclaration.java | 13 +++ .../lang/java/ast/ASTClassDeclaration.java | 18 +--- .../pmd/lang/java/ast/ASTTypeDeclaration.java | 18 ++++ .../pmd/lang/java/symbols/JClassSymbol.java | 35 +++++--- .../java/symbols/internal/asm/ClassStub.java | 5 +- .../symbols/internal/ast/AstClassSym.java | 85 +++++++++++++++---- .../symbols/internal/asm/AsmLoaderTest.kt | 8 +- 7 files changed, 133 insertions(+), 49 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnonymousClassDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnonymousClassDeclaration.java index 1c1a3221513..f9d035a1583 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnonymousClassDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnonymousClassDeclaration.java @@ -5,6 +5,7 @@ package net.sourceforge.pmd.lang.java.ast; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.ast.NodeStream; @@ -53,6 +54,18 @@ public boolean isFindBoundary() { return NodeStream.empty(); } + @Override + public @Nullable ASTClassType getSuperClassTypeNode() { + if (getParent() instanceof ASTConstructorCall) { + ASTConstructorCall ctor = (ASTConstructorCall) getParent(); + @NonNull JTypeMirror type = ctor.getTypeMirror(); + if (!type.isInterface()) { + return ctor.getTypeNode(); + } + } + return null; + } + @Override public Visibility getVisibility() { return Visibility.V_ANONYMOUS; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassDeclaration.java index 5345f207920..9d0e280cbea 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassDeclaration.java @@ -7,6 +7,7 @@ import java.util.List; import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; /** @@ -59,22 +60,9 @@ void setInterface() { /** - * Returns the superclass type node if this node is a class - * declaration and explicitly declares an {@code extends} - * clause. Superinterfaces of an interface are not considered. - * - *

    Returns {@code null} otherwise. + * @deprecated Use {@link #getPermitsClause()} or {@link JClassSymbol#getPermittedSubtypes()} */ - public ASTClassType getSuperClassTypeNode() { - if (isInterface()) { - return null; - } - - ASTExtendsList extendsList = firstChild(ASTExtendsList.class); - return extendsList == null ? null : extendsList.iterator().next(); - } - - + @Deprecated public List getPermittedSubclasses() { return ASTList.orEmpty(children(ASTPermitsList.class).first()); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeDeclaration.java index f81721a3bd1..8be428332a1 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeDeclaration.java @@ -287,6 +287,24 @@ default boolean isAnnotation() { : firstChild(ASTImplementsList.class)); } + /** + * Returns the superclass type node if this node is a class + * declaration and explicitly declares an {@code extends} + * clause. Superinterfaces of an interface are not considered. + * Note that enum or record declarations never have an explicit + * superclass type node. Anonymous class declarations have such + * a type node if the class being created is a class, otherwise, + * it is an interface, and the superclass is implicitly object, + * so this method returns null. Enum constants with a subclass + * body will return null. + */ + default @Nullable ASTClassType getSuperClassTypeNode() { + if (isInterface()) { + return null; + } + return ASTList.singleOrNull(firstChild(ASTExtendsList.class)); + } + /** Return the permits list if this is a sealed type, null otherwise. */ default @Nullable ASTPermitsList getPermitsClause() { return firstChild(ASTPermitsList.class); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JClassSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JClassSymbol.java index 3642a0d44b7..377933db622 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JClassSymbol.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JClassSymbol.java @@ -238,30 +238,43 @@ default boolean isAbstract() { boolean isAnonymousClass(); /** - * Return the list of permitted subclasses, as defined in the {@code permits} - * clause of a sealed class or interface. + * Return the list of permitted subclasses or subinterfaces, as defined in the + * {@code permits} clause of a sealed class or interface. If this class is sealed + * but has no permits clause, the permitted subtypes are inferred from the types + * in the compilation unit. If the class is not sealed, returns an empty list. + * + *

    Note that an enum class for which some constants declare a body is technically + * implicitly sealed, and implicitly permits only the anonymous classes for those enum + * constants. For consistency, this method will return only symbols that have a canonical + * name, and therefore always return an empty list for enums. * * @see #isSealed() */ - default List getPermittedSubclasses() { + default List getPermittedSubtypes() { return Collections.emptyList(); } /** * Return true if this type is sealed. Then it has a non-empty list of permitted - * subclasses. Note that there is no trace of the non-sealed modifier in class files. - * A class must have the {@code non-sealed} modifier if it is not sealed, not final, - * and has a sealed supertype. + * subclasses (or it is a compile-time error). Note that there is no trace of the + * non-sealed modifier in class files. A class must have the {@code non-sealed} + * modifier if it is not sealed, not final, and has a sealed supertype. + * + *

    Note that an enum class for which some constants declare a body is technically + * implicitly sealed, and implicitly permits only the anonymous classes for those enum + * constants. For consistency with {@link #getPermittedSubtypes()}, we treat such enums + * as not sealed. * - * @see #getPermittedSubclasses() + * @see #getPermittedSubtypes() */ default boolean isSealed() { - return !getPermittedSubclasses().isEmpty(); + return !getPermittedSubtypes().isEmpty(); } /** * Return true if this type is final, that is, does not admit subtypes. Note that - * array types have both modifiers final and abstract. + * array types have both modifiers final and abstract. Note also that enum classes + * may be non-final if they have constants that declare an anonymous body. */ default boolean isFinal() { return Modifier.isFinal(getModifiers()); @@ -331,11 +344,9 @@ default boolean annotationAppliesTo(ElementType elementType) { return target.attributeContains("value", elementType).isTrue(); } - // todo isSealed + getPermittedSubclasses - // (isNonSealed is not so useful I think) - /** * This returns true if this is not an interface, primitive or array. + * Note that this includes in particular records and enums. */ default boolean isClass() { return !isInterface() && !isArray() && !isPrimitive(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java index 58c98491295..dd35234d6c3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStub.java @@ -119,6 +119,9 @@ protected void finishParse(boolean failed) { memberClasses = Collections.unmodifiableList(memberClasses); enumConstants = CollectionUtil.makeUnmodifiableAndNonNull(enumConstants); recordComponents = CollectionUtil.makeUnmodifiableAndNonNull(recordComponents); + if (isEnum()) { + permittedSubclasses = Collections.emptyList(); + } permittedSubclasses = CollectionUtil.makeUnmodifiableAndNonNull(permittedSubclasses); if (EnclosingInfo.NO_ENCLOSING.equals(enclosingInfo)) { @@ -405,7 +408,7 @@ public PSet getAnnotationAttributeNames() { @Override - public List getPermittedSubclasses() { + public List getPermittedSubtypes() { parseLock.ensureParsed(); return permittedSubclasses; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstClassSym.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstClassSym.java index a9038a051f9..3e72a96b44e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstClassSym.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstClassSym.java @@ -14,6 +14,7 @@ import org.pcollections.HashTreePSet; import org.pcollections.PSet; +import net.sourceforge.pmd.lang.ast.NodeStream; import net.sourceforge.pmd.lang.java.ast.ASTBodyDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTClassDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTClassType; @@ -28,6 +29,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTVariableId; import net.sourceforge.pmd.lang.java.ast.InternalApiBridge; +import net.sourceforge.pmd.lang.java.ast.JModifier; import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; import net.sourceforge.pmd.lang.java.symbols.JConstructorSymbol; import net.sourceforge.pmd.lang.java.symbols.JElementSymbol; @@ -57,9 +59,10 @@ final class AstClassSym private final List declaredFields; private final List enumConstants; // subset of declaredFields private final List recordComponents; - private final List permittedSubclasses; private final PSet annotAttributes; + private List permittedSubclasses; + AstClassSym(ASTTypeDeclaration node, AstSymFactory factory, @Nullable JTypeParameterOwnerSymbol enclosing) { @@ -101,20 +104,6 @@ final class AstClassSym enumConstants = null; } - - ASTPermitsList permits = node.getPermitsClause(); - if (permits != null) { - this.permittedSubclasses = permits.toList().stream().map(it -> { - JTypeDeclSymbol symbol = it.getTypeMirror().getSymbol(); - if (symbol instanceof JClassSymbol) - return (JClassSymbol) symbol; - else return null; - }).filter(Objects::nonNull).collect(CollectionUtil.toUnmodifiableList()); - } else { - this.permittedSubclasses = Collections.emptyList(); - } - - for (ASTBodyDeclaration dnode : node.getDeclarations()) { if (dnode instanceof ASTTypeDeclaration) { @@ -164,6 +153,7 @@ final class AstClassSym : HashTreePSet.empty(); } + private List mapComponentsToMutableList(AstSymFactory factory, ASTRecordComponentList components, List fieldSyms) { @@ -244,10 +234,71 @@ public List getDeclaredFields() { @Override - public List getPermittedSubclasses() { + public List getPermittedSubtypes() { + // permitted subclasses are populated lazily because they require + // symbol and type resolution to determine which types are sealed. + if (permittedSubclasses == null) { + ASTPermitsList permits = node.getPermitsClause(); + if (permits != null) { + this.permittedSubclasses = permits.toList().stream().map(it -> { + JTypeDeclSymbol symbol = it.getTypeMirror().getSymbol(); + if (symbol instanceof JClassSymbol) { + return (JClassSymbol) symbol; + } else { + return null; + } + }).filter(Objects::nonNull).collect(CollectionUtil.toUnmodifiableList()); + } else if (isSealed()) { + // sealed with no permits clause: infer permitted + this.permittedSubclasses = inferPermittedSubclasses(); + } else { + this.permittedSubclasses = Collections.emptyList(); + } + } return permittedSubclasses; } + private List inferPermittedSubclasses() { + /* + * If the declaration of a sealed class C lacks a permits clause, + * then the permitted direct subclasses of C are as follows: + * + * 1. If C is not an enum class, then its permitted direct subclasses + * are those classes declared in the same compilation unit as C (ยง7.3) + * which have a canonical name (ยง6.7) and whose direct superclass is C. + * + * That is, the permitted direct subclasses are inferred as the classes + * in the same compilation unit that specify C as their direct superclass. + * The requirement for a canonical name means that no local classes or + * anonymous classes will be considered. + * + * It is a compile-time error if the declaration of a sealed class C lacks + * a permits clause and C has no permitted direct subclasses. + * + * 2. If C is an enum class, then its permitted direct subclasses, if any, + * are specified in ยง8.9. + */ + if (!isEnum()) { + boolean isInterface = isInterface(); + List list = node + .getRoot().descendants(ASTTypeDeclaration.class).crossFindBoundaries() + .filter(it -> it.getCanonicalName() != null) + .filter(it -> { + if (isInterface) { + return it.getSuperInterfaceTypeNodes().any(ty -> Objects.equals(ty.getTypeMirror().getSymbol(), this)); + } + return NodeStream.of(it.getSuperClassTypeNode()).any(ty -> Objects.equals(ty.getTypeMirror().getSymbol(), this)); + }).toList(ASTTypeDeclaration::getSymbol); + return Collections.unmodifiableList(list); + } + return Collections.emptyList(); + } + + @Override + public boolean isSealed() { + return node.hasModifiers(JModifier.SEALED); + } + @Override public @Nullable JClassType getSuperclassType(Substitution substitution) { TypeSystem ts = getTypeSystem(); @@ -258,7 +309,7 @@ public List getPermittedSubclasses() { } else if (node instanceof ASTClassDeclaration) { - ASTClassType superClass = ((ASTClassDeclaration) node).getSuperClassTypeNode(); + ASTClassType superClass = node.getSuperClassTypeNode(); return superClass == null ? ts.OBJECT // this cast relies on the fact that the superclass is not a type variable diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmLoaderTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmLoaderTest.kt index 47adf436682..c50a18fe676 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmLoaderTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmLoaderTest.kt @@ -247,7 +247,7 @@ class AsmLoaderTest : IntelliMarker, FunSpec({ // sealed interface SealedTypesTestData permits A, B, C sealedInterface::getSimpleName shouldBe "SealedTypesTestData" sealedInterface::isSealed shouldBe true - sealedInterface.permittedSubclasses.let { + sealedInterface.permittedSubtypes.let { it.shouldHaveSize(3) it[0].shouldBeA { // sealed interface A extends SealedTypesTestData permits X @@ -255,7 +255,7 @@ class AsmLoaderTest : IntelliMarker, FunSpec({ it::isSealed shouldBe true it::isInterface shouldBe true it::isFinal shouldBe false - it.permittedSubclasses.shouldBeSingleton { + it.permittedSubtypes.shouldBeSingleton { // final class X implements A {} it::getSimpleName shouldBe "X" it::isFinal shouldBe true @@ -267,7 +267,7 @@ class AsmLoaderTest : IntelliMarker, FunSpec({ it::isInterface shouldBe true it::isSealed shouldBe false it::isFinal shouldBe false - it::getPermittedSubclasses shouldBe emptyList() + it::getPermittedSubtypes shouldBe emptyList() } it[2].shouldBeA { // final class C implements SealedTypesTestData @@ -275,7 +275,7 @@ class AsmLoaderTest : IntelliMarker, FunSpec({ it::isInterface shouldBe false it::isSealed shouldBe false it::isFinal shouldBe true - it::getPermittedSubclasses shouldBe emptyList() + it::getPermittedSubtypes shouldBe emptyList() } } } From d14cb30376cb6470f2225c45f895dee3707f2e93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 19 Nov 2024 15:15:45 +0100 Subject: [PATCH 0276/1962] Add tests --- .../pmd/lang/java/ast/ASTTypeDeclaration.java | 8 +- .../symbols/internal/SymImplementation.java | 83 ++++++++++++++---- .../symbols/internal/JClassSymbolTest.java | 68 ++++++++++++++ .../symbols/internal/asm/AsmLoaderTest.kt | 44 ---------- .../table/internal/LocalTypeScopesTest.kt | 4 +- .../symbols/testdata/sealed/Foo$Bar.class | Bin 0 -> 615 bytes .../java/symbols/testdata/sealed/Foo.class | Bin 0 -> 380 bytes .../symbols/testdata/sealed/FooEnum$1.class | Bin 0 -> 436 bytes .../symbols/testdata/sealed/FooEnum.class | Bin 0 -> 1492 bytes .../symbols/testdata/sealed/FooRecord.class | Bin 0 -> 1245 bytes .../sealed/ImplicitPermitsClause.class | Bin 0 -> 534 bytes .../sealed/ImplicitPermitsClause.java | 32 +++++++ .../sealed/ImplicitPermitsClauseItf.class | Bin 0 -> 447 bytes .../java/symbols/testdata/sealed/Qux$1.class | Bin 0 -> 673 bytes .../java/symbols/testdata/sealed/Qux.class | Bin 0 -> 643 bytes .../java/symbols/testdata/sealed/SubItf.class | Bin 0 -> 248 bytes .../symbols/testdata/sealed/SubItf2.class | Bin 0 -> 401 bytes .../pmd/lang/test/ast/BaseParsingHelper.kt | 21 +++-- 18 files changed, 190 insertions(+), 70 deletions(-) create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/Foo$Bar.class create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/Foo.class create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/FooEnum$1.class create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/FooEnum.class create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/FooRecord.class create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/ImplicitPermitsClause.class create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/ImplicitPermitsClause.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/ImplicitPermitsClauseItf.class create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/Qux$1.class create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/Qux.class create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/SubItf.class create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/SubItf2.class diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeDeclaration.java index 8be428332a1..dca287f136e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeDeclaration.java @@ -305,7 +305,13 @@ default boolean isAnnotation() { return ASTList.singleOrNull(firstChild(ASTExtendsList.class)); } - /** Return the permits list if this is a sealed type, null otherwise. */ + /** + * Return the explicit permits list if there is one. Note + * that the permitted subtypes list may be implicit and inferred + * from subtypes found in the current compilation unit. Use + * {@link JClassSymbol#getPermittedSubtypes()} for an API + * that works in all cases. + */ default @Nullable ASTPermitsList getPermitsClause() { return firstChild(ASTPermitsList.class); } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/SymImplementation.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/SymImplementation.java index a9418a1e41a..04e58f8b121 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/SymImplementation.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/SymImplementation.java @@ -18,11 +18,13 @@ import java.util.stream.Collectors; import org.checkerframework.checker.nullness.qual.NonNull; +import org.jetbrains.annotations.NotNull; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; import net.sourceforge.pmd.lang.java.JavaParsingHelper; import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; +import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration; import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; import net.sourceforge.pmd.lang.java.symbols.JFieldSymbol; import net.sourceforge.pmd.lang.java.symbols.JFormalParamSymbol; @@ -41,22 +43,31 @@ public enum SymImplementation { ASM { @Override - public @NonNull JClassSymbol getSymbol(Class aClass) { - return Objects.requireNonNull(JavaParsingHelper.TEST_TYPE_SYSTEM.getClassSymbol(aClass), aClass.getName()); + public Fixture findClass(String binaryName) { + int idx = binaryName.lastIndexOf('.'); + String packageName = idx == -1 ? "" : binaryName.substring(0, idx); + return new Fixture(packageName) { + @Override + public @NotNull JClassSymbol getByBinaryName(String binaryName) { + JClassSymbol sym = JavaParsingHelper.TEST_TYPE_SYSTEM.getClassSymbol(binaryName); + return Objects.requireNonNull(sym, binaryName); + } + }; } }, AST { @Override - public @NonNull JClassSymbol getSymbol(Class aClass) { - ASTCompilationUnit ast = JavaParsingHelper.DEFAULT.parseClass(aClass); - JClassSymbol symbol = ast.getTypeDeclarations().first(it -> it.getSimpleName().equals(aClass.getSimpleName())).getSymbol(); - return Objects.requireNonNull(symbol, aClass.getName()); - } - - @Override - public JClassType getDeclaration(Class aClass) { - ASTCompilationUnit ast = JavaParsingHelper.DEFAULT.parseClass(aClass); - return ast.getTypeDeclarations().first(it -> it.getSimpleName().equals(aClass.getSimpleName())).getTypeMirror(); + public Fixture findClass(String binaryName) { + ASTCompilationUnit ast = JavaParsingHelper.DEFAULT.parseClass(binaryName); + return new Fixture(ast.getPackageName()) { + @Override + public @NotNull JClassSymbol getByBinaryName(String binaryName) { + return ast.descendants(ASTTypeDeclaration.class).crossFindBoundaries() + .filter(it -> it.getBinaryName().equals(binaryName)) + .firstOrThrow().getSymbol(); + } + + }; } @Override @@ -69,11 +80,17 @@ public boolean supportsDebugSymbols() { return false; } - public abstract @NonNull JClassSymbol getSymbol(Class aClass); + /** + * Find the source file identified by the given binary name and parse it into the fixture. + */ + public abstract Fixture findClass(String binaryName); + + public @NonNull JClassSymbol getSymbol(Class aClass) { + return findClass(aClass.getName()).getByBinaryName(aClass.getName()); + } public JClassType getDeclaration(Class aClass) { - JClassSymbol symbol = getSymbol(aClass); - return (JClassType) symbol.getTypeSystem().declaration(symbol); + return findClass(aClass.getName()).getDeclaration(aClass); } @@ -145,4 +162,40 @@ private void assertParameterMatch(Parameter p, JFormalParamSymbol pSym) { assertEquals(expectedType, pSym.getTypeMirror(Substitution.EMPTY)); } + /** + * In order to test simultaneously types defined in the same compilation unit, + * we must store them somewhere. The fixture stores the parsed AST and allows + * convenient access to the parsed types. This makes sure that we don't parse + * the file once per lookup. + */ + public abstract static class Fixture { + private final String packageName; + + Fixture(String packageName) { + this.packageName = packageName; + } + + /** + * Return a symbol found in the package with the given simple name. + */ + public @NonNull JClassSymbol getSymbol(String simpleName) { + return getByBinaryName(packageName + "." + simpleName); + } + + /** + * Return a symbol found in the package with the given binary name. + */ + public abstract @NonNull JClassSymbol getByBinaryName(String binaryName); + + public @NonNull JClassSymbol getByBinaryName(Class klass) { + return getByBinaryName(klass.getName()); + } + + public JClassType getDeclaration(Class aClass) { + JClassSymbol symbol = getByBinaryName(aClass); + return (JClassType) symbol.getTypeSystem().declaration(symbol); + } + } + + } diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/JClassSymbolTest.java b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/JClassSymbolTest.java index c2d23e9cb5d..4f48e80f295 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/JClassSymbolTest.java +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/JClassSymbolTest.java @@ -4,7 +4,12 @@ package net.sourceforge.pmd.lang.java.symbols.internal; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.empty; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.lang.annotation.ElementType; import java.lang.annotation.RetentionPolicy; @@ -13,6 +18,7 @@ import org.junit.jupiter.params.provider.EnumSource; import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; +import net.sourceforge.pmd.lang.java.symbols.internal.SymImplementation.Fixture; import net.sourceforge.pmd.lang.java.symbols.testdata.AnnotationWithNoRetention; import net.sourceforge.pmd.lang.java.symbols.testdata.TypeAnnotation; @@ -51,4 +57,66 @@ void testAnnotWithNoTarget(SymImplementation impl) { "annot supports " + type); } } + + private static final String SEALED_TESTDATA = "net.sourceforge.pmd.lang.java.symbols.testdata.sealed."; + + @EnumSource + @ParameterizedTest + void testSealedInterfaces(SymImplementation impl) { + Fixture fixture = impl.findClass(SEALED_TESTDATA + "SealedTypesTestData"); + + JClassSymbol stTestData = fixture.getSymbol("SealedTypesTestData"); + JClassSymbol stA = fixture.getSymbol("A"); + JClassSymbol stB = fixture.getSymbol("B"); + JClassSymbol stC = fixture.getSymbol("C"); + JClassSymbol stX = fixture.getSymbol("X"); + + assertIsSealed(stTestData, stA, stB, stC); + assertIsSealed(stA, stX); + + assertNotSealed(stB); + + assertNotSealed(stC); + assertTrue(stC.isFinal(), "final"); + + assertNotSealed(stX); + assertTrue(stX.isFinal(), "final"); + } + + + @EnumSource + @ParameterizedTest + void testImplicitPermitsClause(SymImplementation impl) { + Fixture fixture = impl.findClass(SEALED_TESTDATA + "ImplicitPermitsClause"); + + JClassSymbol sealedClass = fixture.getSymbol("ImplicitPermitsClause"); + JClassSymbol sealedItf = fixture.getSymbol("ImplicitPermitsClauseItf"); + JClassSymbol bar = fixture.getSymbol("Foo$Bar"); + JClassSymbol qux = fixture.getSymbol("Qux"); + JClassSymbol subitf = fixture.getSymbol("SubItf"); + JClassSymbol subitf2 = fixture.getSymbol("SubItf2"); + JClassSymbol fooEnum = fixture.getSymbol("FooEnum"); + JClassSymbol fooRecord = fixture.getSymbol("FooRecord"); + + assertIsSealed(sealedClass, bar, qux); + assertIsSealed(sealedItf, bar, subitf); + + assertNotSealed(bar); + assertNotSealed(qux); + assertNotSealed(subitf); + + assertIsSealed(subitf2, fooEnum, fooRecord); + assertNotSealed(fooEnum); + } + + private static void assertIsSealed(JClassSymbol sealedClass, JClassSymbol... permittedSubtypes) { + assertTrue(sealedClass.isSealed(), "sealed"); + assertThat(sealedClass.getPermittedSubtypes(), containsInAnyOrder(permittedSubtypes)); + } + + private static void assertNotSealed(JClassSymbol sealedClass) { + assertFalse(sealedClass.isSealed(), "sealed"); + assertThat(sealedClass.getPermittedSubtypes(), empty()); + } + } diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmLoaderTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmLoaderTest.kt index c50a18fe676..339be0147ac 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmLoaderTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/asm/AsmLoaderTest.kt @@ -7,7 +7,6 @@ package net.sourceforge.pmd.lang.java.symbols.internal.asm import io.kotest.core.spec.style.FunSpec import io.kotest.inspectors.forExactly import io.kotest.matchers.collections.shouldBeEmpty -import io.kotest.matchers.collections.shouldBeSingleton import io.kotest.matchers.collections.shouldContainExactlyInAnyOrder import io.kotest.matchers.collections.shouldHaveSize import io.kotest.matchers.nulls.shouldBeNull @@ -21,11 +20,9 @@ import javasymbols.testdata.deep.AClassWithLocals import javasymbols.testdata.deep.`Another$ClassWith$Dollar` import javasymbols.testdata.deep.OuterWithoutDollar import javasymbols.testdata.impls.GenericClass -import net.sourceforge.pmd.lang.java.symbols.JClassSymbol import net.sourceforge.pmd.lang.java.types.testTypeSystem import net.sourceforge.pmd.lang.test.ast.IntelliMarker import net.sourceforge.pmd.lang.test.ast.shouldBe -import net.sourceforge.pmd.lang.test.ast.shouldBeA import org.objectweb.asm.Opcodes import kotlin.test.assertSame @@ -238,45 +235,4 @@ class AsmLoaderTest : IntelliMarker, FunSpec({ notAnEnum::getEnumConstants shouldBe emptyList() } - test("Permitted subclasses") { - - val outerName = "net.sourceforge.pmd.lang.java.symbols.testdata.sealed.SealedTypesTestData" - - // Note here we are loading a .class file that is in the test/resources directory. - val sealedInterface = symLoader().resolveClassFromBinaryName(outerName)!! - // sealed interface SealedTypesTestData permits A, B, C - sealedInterface::getSimpleName shouldBe "SealedTypesTestData" - sealedInterface::isSealed shouldBe true - sealedInterface.permittedSubtypes.let { - it.shouldHaveSize(3) - it[0].shouldBeA { - // sealed interface A extends SealedTypesTestData permits X - it::getSimpleName shouldBe "A" - it::isSealed shouldBe true - it::isInterface shouldBe true - it::isFinal shouldBe false - it.permittedSubtypes.shouldBeSingleton { - // final class X implements A {} - it::getSimpleName shouldBe "X" - it::isFinal shouldBe true - } - } - it[1].shouldBeA { - // non-sealed interface B extends SealedTypesTestData - it::getSimpleName shouldBe "B" - it::isInterface shouldBe true - it::isSealed shouldBe false - it::isFinal shouldBe false - it::getPermittedSubtypes shouldBe emptyList() - } - it[2].shouldBeA { - // final class C implements SealedTypesTestData - it::getSimpleName shouldBe "C" - it::isInterface shouldBe false - it::isSealed shouldBe false - it::isFinal shouldBe true - it::getPermittedSubtypes shouldBe emptyList() - } - } - } }) diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/LocalTypeScopesTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/LocalTypeScopesTest.kt index cd723cebc89..2bfaf872d8d 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/LocalTypeScopesTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/LocalTypeScopesTest.kt @@ -5,11 +5,11 @@ package net.sourceforge.pmd.lang.java.symbols.table.internal import io.kotest.matchers.shouldBe -import net.sourceforge.pmd.lang.test.ast.shouldBe import net.sourceforge.pmd.lang.java.ast.* import net.sourceforge.pmd.lang.java.types.JClassType import net.sourceforge.pmd.lang.java.types.shouldHaveType import net.sourceforge.pmd.lang.java.types.typeDsl +import net.sourceforge.pmd.lang.test.ast.shouldBe class LocalTypeScopesTest : ParserTestSpec({ parserTestContainer("Scoping of types in a compilation unit") { @@ -112,7 +112,7 @@ class LocalTypeScopesTest : ParserTestSpec({ } doTest("Inside extends clause: Inner is the import") { - foo.superClassTypeNode.symbolTable.shouldResolveTypeTo("Inner").let { + foo.superClassTypeNode!!.symbolTable.shouldResolveTypeTo("Inner").let { it.symbol::getCanonicalName shouldBe "somewhere.Inner" } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/Foo$Bar.class b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/Foo$Bar.class new file mode 100644 index 0000000000000000000000000000000000000000..b8b7c572f289612d76b1d9aebf3a35eda6a9a8ca GIT binary patch literal 615 zcmbVKJx>Bb5Pi!5hbIE!M`2=OVF4CiO;id$uBvBa4bRE9R zHyPUZWT9glImJB;Pll0fxVrONdMyiRxSqb6`yjDMu{ zLwS7|-0*y;$RJaz{J{(nwN;?fsnZ?EM=rKl9;O1YS9GnY8 zJ)4t2XQT{`%VI|ELC!Qs(t8TeHlIi*3ku}CKr*e`8K~9!&ahZ&HCJImu28}Ev@AWH zu1e)}eKXhAbE$t>1e#-R^v?Pq&>k8?j``k`@17y%!L62H%cEm#vA2&pZy-KC+5Lcc quLucagNeW%))`x@Oxf~@(B?}G8`xwURXICVq*hT9mc{I&oBje^I%}E$ literal 0 HcmV?d00001 diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/FooEnum.class b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/FooEnum.class new file mode 100644 index 0000000000000000000000000000000000000000..dffb1c1678b089c4d030b6a8c42cffa3134ce2a0 GIT binary patch literal 1492 zcmbtUTTc@~6#k~$W!rUuQV^t4xro?;vVx)yMJy0Vnv_ejN5?74n(zWwp@>vsTac%dN0@Y3a>9(a-8xbsCsR!?!hGz$Q$b+zDhNR%8&0G4W=WV!=lLbRsgNz;qw#x9T-c`7Yh?mij zjpMC}(=81edKr}Iz18}g4TGWjw#y_c`jJ!6t6>0n2Dxc_E@v1jmFscOarZloL*5K4 zDu!@d!LWuA++pauG7#-kS;wXw@tp&PrBa9Yx@`tQr9)wazU8(nof$-cIDSFHU5qjG zEL*M>t}qODhDtnZT=UgZtP>nRf~IF?y`cF$_)b~$W<6rBPR8xB~U8VoFm(6 zTH!AD9V-lIKBIuoi)ki`Z40HJPSNFOLMpLO z#acDbX3sHr33lE7G5N|A_5;X?7z8PH9VaQ#CuMeS>s4g%1bX7Onz&6~ptzqOm(DP83h9DEm;}&eeh_3wm=I>3N_*y9#UIXL<$d)(gU2<@iuX5dyRKpssD)s zJt5`558y{3#<8myhKgp>Xf#XBr{FS;wmK@a5dPGj$qjR56RjIcg@5c z=BY#RIp&^XIJi7>u8X(!k?84Gq?>#qRSZ@2F=k{FvPDH+|)sDwwCAN}FC56w2 zskSYpRyyM0YoQ0yQ6=1EKy?Q9D_F;dfd?iYqRy~79)~CnwCf8i6*LQEDBI^;3}^Wg z-QYwX3o8Y_;(_A{wce5PI1XF6PO>S>d9uL$(@^XR)r;Iv%P1d0O(~UkWE`LVCdp_2 zZMd_sU@+T3AfgeaPzE*`HpV?)(1U@;3@aByN%FK|Ji!7zak@kr_#%Du%xQOntUI)l z_Ly#d13M#w;U@i)W8fA&jWU+VPN1u_CSIdCgaLdd^H13E`KZ^;8fgiw+ zLR^xSDVFSaey4l)?ECrs`UWt@L4XcCAKegZ=m`v#>QzajvW2{lmJ~aI-lfj8yB6?H z&z^m(3*2Pnq|M7BrkA`}kX)rnQ&U&l_cY3lm5!`SlvC1@GL*ehqQ8F*1*eGks`sfQ>wR1Yn z^OLbEeC!B}+DSZ?Zvx>g%c$UoHiq_EtFa;ef3}2U_&l*{3En(2#tn{+7;EPI6XK&z e2Ygm(Ab^KW#tuSk)ocgb7+|-~366)@2mS!f5|ncQ literal 0 HcmV?d00001 diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/ImplicitPermitsClause.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/ImplicitPermitsClause.java new file mode 100644 index 00000000000..9f606760a26 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/ImplicitPermitsClause.java @@ -0,0 +1,32 @@ +package net.sourceforge.pmd.lang.java.symbols.testdata.sealed; + +/* + * This class is in resources because it uses Java 17 features. + * It must be compiled manually, the generated class files and + * this source file are put into the test/resources directory. + */ + + +sealed class ImplicitPermitsClause { } +sealed interface ImplicitPermitsClauseItf { } + +class Foo { + non-sealed class Bar extends ImplicitPermitsClause implements ImplicitPermitsClauseItf {} +} + +final class Qux extends ImplicitPermitsClause { + static { + new Foo().new Bar() {}; + } +} + +non-sealed interface SubItf extends ImplicitPermitsClauseItf {} + +sealed interface SubItf2 extends SubItf {} + +record FooRecord() implements SubItf2 {} + +enum FooEnum implements SubItf2 { + A { }, + B +} \ No newline at end of file diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/ImplicitPermitsClauseItf.class b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/ImplicitPermitsClauseItf.class new file mode 100644 index 0000000000000000000000000000000000000000..3976864f6cd954916dc8af26b4a6be9f3bd0da26 GIT binary patch literal 447 zcmbV}u};G<5QhJ2AugdnB{t^H^^62dkt$^Yq&|U@T&q-0T=^U%UX6hV;Gq!LbY+SM z-!JR_|Gtxde!so}tg$ed5MDb@Rze>u-i5eldu(g#UAMOf_u;I3wq@{Q6HBUH(g${) zYg@EO-&9R{=h!w$UcBpti?lPiAS?#!5b{qL`;r<+%xZd_< z<(&wN!4=_o9O)*6<=RDqYr@mG2nEsA2=k)rIO?uvrdz_}xIkqhOqD7FROok{&J>q= WPmsZA%~Z{hW3D>at{HA{2mAqu_KDyC literal 0 HcmV?d00001 diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/Qux$1.class b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/Qux$1.class new file mode 100644 index 0000000000000000000000000000000000000000..f938d7fca44f344034d0655557673587f8314979 GIT binary patch literal 673 zcmbVK%Sr<=6g{!EQ)_*-KI=wM#0NOIlxi0h#X_x$qPR>u*BZ$rI?0HBmMg`DAK*uc zw}U%(y>Op7IZ5u#_s{1SfF_np7(p&TzKl^61ZE!OvkX(Oba>W%pq_UElLl< zlk<`EGIS(0Md7ivYfYI56!w)-z9G=qXb(+Q-@FbmDNrAd;Uaxm+ZD(k+K2?E+R9KT zjk}aw$*$%~=`wrYu^J?`R{W?{Px*67V&&bTmZ_ti!E1T%k?CpclQ zZzWLdaN|y_^8)3TF_iFe&XEhSG&C{yULeQa#|kERngbE6JWuvh9IYb9ABZbk+qWMO sH}44EGSD>JLI$oPj~UKJP(hV_9{_Og%1lR#+(?E}OT{W{GdPXIdk=xgU@hYOrV=2J}Pj0cv!Kut}?V6{la2RTTi|4bEqB$x08g_q@b^2Imn}tOz*@< z6H{)D^-tsc+l3chW%<2-+k9f3VWutsQ~ zR%V%_8Q2>EhINW|89Q}!o;P6XJ5L(^Wig>710 N((|xG$X_4=z&CPxsWSio literal 0 HcmV?d00001 diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/SubItf.class b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/SubItf.class new file mode 100644 index 0000000000000000000000000000000000000000..233e26f7ebbdaa8f1699d8c0d8cb3bd01cd70bdc GIT binary patch literal 248 zcmbVHK@Ng25S*e?_2k({*bi{h#Dt5Q@PYyhDQSVw#l)|9@Bu!`SU7v~u$#?fW_ITN zdAzbE!E1q%D;y8}pPaiKW19 zCeD&;-cZ33vB2d&-_-Ti6ozj!IK%#A_2?;l64+*Q$g{B|u>Z+BOi5xuU=d~&T28kN HJHq-4&@oOX literal 0 HcmV?d00001 diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/SubItf2.class b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/symbols/testdata/sealed/SubItf2.class new file mode 100644 index 0000000000000000000000000000000000000000..70dc5ba0eb0e1b94e8777d187684a357dcfd0b31 GIT binary patch literal 401 zcmbtQTWSJ95UlaBqsD|l{yc;OekTZ#2!18#31(+nS((|9?OwsF`H=(UP$84e4a`S( z(?xexQD5KJPXMoY(C8_=)Fg&e+c?^%=0N5Yy$QBHn4>*g!~K;G=y zawGeN#z5h*yX=16%Og3_C={OmL#!~_b)ME$Acff`o, T : RootNode */ @JvmOverloads open fun parseClass(clazz: Class<*>, version: String? = null): T = - parse(readClassSource(clazz), version) + parseClass(clazz.name, version) + + @JvmOverloads + open fun parseClass(binaryName: String, version: String? = null): T = + parse(readClassSource(binaryName), version) fun readResource(resourceName: String): String { @@ -210,14 +214,15 @@ abstract class BaseParsingHelper, T : RootNode * * @throws IllegalArgumentException if the source file wasn't found */ - fun readClassSource(clazz: Class<*>): String { - var sourceFile = clazz.name.replace('.', '/') + ".java" + fun readClassSource(clazz: Class<*>): String = readClassSource(clazz.name) + + fun readClassSource(binaryName: String): String { // Consider nested classes - if (clazz.name.contains("$")) { - sourceFile = sourceFile.substring(0, clazz.name.indexOf('$')) + ".java" - } - val input = (params.resourceLoader ?: javaClass).classLoader.getResourceAsStream(sourceFile) - ?: throw IllegalArgumentException("Unable to find source file $sourceFile for $clazz") + val outerName = binaryName.substringBefore('$') + val sourceFile = outerName.replace('.', '/') + ".java" + + val input = resourceLoader.classLoader.getResourceAsStream(sourceFile) + ?: throw IllegalArgumentException("Unable to find source file $sourceFile for $binaryName") input.use { return consume(input) From f9257ce4001cd4d7687132069cf1785a52da8335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 19 Nov 2024 15:58:53 +0100 Subject: [PATCH 0277/1962] Fix merge, interaction between #5339 and #5341 --- .../types/internal/infer/ExprCheckHelper.java | 22 +++++++++++++++---- .../infer/UnresolvedTypesRecoveryTest.kt | 6 ++--- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java index 959614a860e..89c3c2e6d0e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java @@ -259,10 +259,24 @@ private void handleFunctionalExprWithoutTargetType(FunctionalExprMirror expr, JT // Object. checker.checkExprConstraint(infCtx, ts.UNKNOWN, targetType); } - infCtx.addInstantiationListener(infCtx.freeVarsIn(targetType), ctx -> { - expr.setInferredType(ctx.ground(targetType)); - expr.setFunctionalMethod(ts.UNRESOLVED_METHOD); - }); + if (mayMutateExpr()) { + infCtx.addInstantiationListener(infCtx.freeVarsIn(targetType), ctx -> { + expr.setInferredType(ctx.ground(targetType)); + if (expr instanceof LambdaExprMirror) { + expr.setFunctionalMethod(ts.UNRESOLVED_METHOD); + } else { + MethodRefMirror mref = (MethodRefMirror) expr; + if (!TypeOps.isUnresolved(mref.getTypeToSearch())) { + JMethodSig exactMethod = ExprOps.getExactMethod(mref); + if (exactMethod != null) { + // as a fallback, if the method reference is exact, + // we populate the compile time decl anyway. + mref.setCompileTimeDecl(exactMethod); + } + } + } + }); + } } // we can't ask the infctx to solve the ivar, as that would require all bounds to be ground diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt index 619d3562d50..ec1754c6834 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt @@ -543,8 +543,8 @@ class C { mref shouldHaveType targetTy mref.functionalMethod shouldBe ts.UNRESOLVED_METHOD mref.referencedMethod shouldBe fooDecl // still populated because unambiguous - lambdaCall.methodType.symbol shouldBe fooDecl - mrefCall.methodType.symbol shouldBe fooDecl + lambdaCall.methodType shouldBe fooDecl + mrefCall.methodType shouldBe fooDecl } } @@ -849,7 +849,7 @@ class C { parserTest("Lambda with unresolved target type return type should be unknown") { - val (acu, _) = parser.logTypeInferenceVerbose().parseWithTypeInferenceSpy( + val (acu, _) = parser.parseWithTypeInferenceSpy( """ class Foo { public void methodA() { From 316367d1d836aaca2eeba2a5cafe90ca0d71ba87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 19 Nov 2024 16:09:21 +0100 Subject: [PATCH 0278/1962] Cleanup --- .../types/internal/infer/ExprCheckHelper.java | 19 +++--------------- .../java/types/internal/infer/ExprMirror.java | 8 ++++++++ .../java/types/internal/infer/ExprOps.java | 4 ++-- .../lang/java/types/internal/infer/Infer.java | 18 +---------------- .../infer/ast/BaseFunctionalMirror.java | 7 +++++++ .../internal/infer/ast/LambdaMirrorImpl.java | 1 + .../infer/ast/MethodRefMirrorImpl.java | 20 ++++++++++++++++++- 7 files changed, 41 insertions(+), 36 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java index 89c3c2e6d0e..3aededfa5ea 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java @@ -260,22 +260,9 @@ private void handleFunctionalExprWithoutTargetType(FunctionalExprMirror expr, JT checker.checkExprConstraint(infCtx, ts.UNKNOWN, targetType); } if (mayMutateExpr()) { - infCtx.addInstantiationListener(infCtx.freeVarsIn(targetType), ctx -> { - expr.setInferredType(ctx.ground(targetType)); - if (expr instanceof LambdaExprMirror) { - expr.setFunctionalMethod(ts.UNRESOLVED_METHOD); - } else { - MethodRefMirror mref = (MethodRefMirror) expr; - if (!TypeOps.isUnresolved(mref.getTypeToSearch())) { - JMethodSig exactMethod = ExprOps.getExactMethod(mref); - if (exactMethod != null) { - // as a fallback, if the method reference is exact, - // we populate the compile time decl anyway. - mref.setCompileTimeDecl(exactMethod); - } - } - } - }); + infCtx.addInstantiationListener( + infCtx.freeVarsIn(targetType), + ctx -> expr.finishFailedInference(ctx.ground(targetType))); } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java index 4f814bd6459..9c21289e3af 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java @@ -230,6 +230,14 @@ interface FunctionalExprMirror extends PolyExprMirror { */ void setFunctionalMethod(@Nullable JMethodSig methodType); + /** + * If the matching between this expr and its target type failed, + * finish the inference by setting the data to UNKNOWN, or likely + * values. This is used as a fallback. + * + * @param targetType Target type for the expression, null if there is none + */ + void finishFailedInference(@Nullable JTypeMirror targetType); } /** diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java index 7629ca4b65e..287faa28661 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java @@ -39,7 +39,7 @@ import net.sourceforge.pmd.util.CollectionUtil; @SuppressWarnings("PMD.CompareObjectsWithEquals") -final class ExprOps { +public final class ExprOps { private final Infer infer; private final TypeSystem ts; @@ -181,7 +181,7 @@ static boolean isPertinentToApplicability(ExprMirror arg, JMethodSig m, JTypeMir /** * Returns null if the method reference is inexact. */ - static @Nullable JMethodSig getExactMethod(MethodRefMirror mref) { + public static @Nullable JMethodSig getExactMethod(MethodRefMirror mref) { JMethodSig cached = mref.getCachedExactMethod(); if (cached == null) { // inexact diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java index e51ef905f22..0016cc60560 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java @@ -36,7 +36,6 @@ import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.FunctionalExprMirror; import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.InvocationMirror; import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.InvocationMirror.MethodCtDecl; -import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.MethodRefMirror; import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.PolyExprMirror; import net.sourceforge.pmd.lang.java.types.internal.infer.InferenceVar.BoundKind; import net.sourceforge.pmd.util.CollectionUtil; @@ -142,22 +141,7 @@ public void inferFunctionalExprInUnambiguousContext(PolySite // setInferredType(mirrors.ts.UNKNOWN); } + @Override + public void finishFailedInference(@Nullable JTypeMirror targetType) { + super.finishFailedInference(targetType); + if (!TypeOps.isUnresolved(getTypeToSearch())) { + JMethodSig exactMethod = ExprOps.getExactMethod(this); + if (exactMethod != null) { + // as a fallback, if the method reference is exact, + // we populate the compile time decl anyway. + setCompileTimeDecl(exactMethod); + return; + } + } + setCompileTimeDecl(factory.ts.UNRESOLVED_METHOD); + } @Override public boolean isEquivalentToUnderlyingAst() { @@ -78,7 +94,9 @@ public String getMethodName() { @Override public void setCompileTimeDecl(JMethodSig methodType) { this.ctdecl = methodType; - InternalApiBridge.setCompileTimeDecl(myNode, methodType); + if (mayMutateAst()) { + InternalApiBridge.setCompileTimeDecl(myNode, methodType); + } } @Override From 0d11f151bd6ec67e2bb28b9c155f3e046382c8e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 21 Nov 2024 14:55:51 +0100 Subject: [PATCH 0279/1962] [java] Add more details to parse failures in signatures --- .../java/symbols/internal/asm/GenericSigBase.java | 15 +++++++++++++-- .../lang/java/symbols/internal/asm/ParseLock.java | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java index eabeb13c5af..07555bae9eb 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java @@ -31,6 +31,7 @@ import net.sourceforge.pmd.lang.java.types.LexicalScope; import net.sourceforge.pmd.lang.java.types.Substitution; import net.sourceforge.pmd.lang.java.types.TypeOps; +import net.sourceforge.pmd.util.AssertionUtil; import net.sourceforge.pmd.util.CollectionUtil; abstract class GenericSigBase { @@ -51,8 +52,18 @@ protected GenericSigBase(T ctx, String parseLockName) { this.lock = new ParseLock(parseLockName) { @Override protected boolean doParse() { - GenericSigBase.this.doParse(); - return true; + try { + GenericSigBase.this.doParse(); + return true; + } catch (RuntimeException e) { + throw AssertionUtil.contexted(e) + .addContextValue("signature", GenericSigBase.this) + // Here we don't use the toString of the ctx directly because + // it could be using the signature indirectly, which would fail + .addContextValue("owner class", ctx.getEnclosingClass()) + .addContextValue("owner name", ctx.getSimpleName()) + .addContextValue("owner package", ctx.getPackageName()); + } } @Override diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java index a0150e00fe7..d78f9e51cd6 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java @@ -50,7 +50,7 @@ private ParseStatus getFinalStatus() { finishParse(!success); } catch (Throwable t) { status = ParseStatus.FAILED; - LOG.error("Parsing failed in ParseLock#doParse()", t); + LOG.error("Parsing failed in ParseLock#doParse() of {}", name, t); finishParse(true); } From e63edf358e737f8f07a7ef2f7b142f73ce18d8c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 21 Nov 2024 15:26:54 +0100 Subject: [PATCH 0280/1962] [java] Fix #5263 - UnnecessaryFullyQualifiedName FP with forward reference. --- .../lang/java/ast/internal/JavaAstUtils.java | 12 +++- .../UnnecessaryFullyQualifiedNameRule.java | 46 +++++++++++- .../xml/UnnecessaryFullyQualifiedName.xml | 72 +++++++++++++++++++ 3 files changed, 128 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java index 3c32710efe0..9de709b90fb 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java @@ -32,6 +32,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr.AccessType; import net.sourceforge.pmd.lang.java.ast.ASTAssignmentExpression; import net.sourceforge.pmd.lang.java.ast.ASTBlock; +import net.sourceforge.pmd.lang.java.ast.ASTBodyDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTBooleanLiteral; import net.sourceforge.pmd.lang.java.ast.ASTBreakStatement; import net.sourceforge.pmd.lang.java.ast.ASTCastExpression; @@ -40,11 +41,13 @@ import net.sourceforge.pmd.lang.java.ast.ASTCompactConstructorDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTConstructorCall; import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTEnumConstant; import net.sourceforge.pmd.lang.java.ast.ASTExecutableDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTExplicitConstructorInvocation; import net.sourceforge.pmd.lang.java.ast.ASTExpression; import net.sourceforge.pmd.lang.java.ast.ASTExpressionStatement; import net.sourceforge.pmd.lang.java.ast.ASTFieldAccess; +import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTForStatement; import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter; import net.sourceforge.pmd.lang.java.ast.ASTFormalParameters; @@ -806,10 +809,17 @@ && isReferenceToVar(((ASTThrowStatement) stmt).getExpr(), return false; } + /** + * Return true if the node is in static context relative to the deepest enclosing class. + */ public static boolean isInStaticCtx(JavaNode node) { - return node.ancestors() + return node.ancestorsOrSelf() + .map(NodeStream.asInstanceOf(ASTBodyDeclaration.class, ASTExplicitConstructorInvocation.class)) + .take(1) .any(it -> it instanceof ASTExecutableDeclaration && ((ASTExecutableDeclaration) it).isStatic() + || it instanceof ASTFieldDeclaration && ((ASTFieldDeclaration) it).isStatic() || it instanceof ASTInitializer && ((ASTInitializer) it).isStatic() + || it instanceof ASTEnumConstant || it instanceof ASTExplicitConstructorInvocation ); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameRule.java index 4c2b79b4bc3..172e5cfc9ae 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameRule.java @@ -13,11 +13,15 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import net.sourceforge.pmd.lang.java.ast.ASTBodyDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTClassType; import net.sourceforge.pmd.lang.java.ast.ASTFieldAccess; import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; +import net.sourceforge.pmd.lang.java.ast.ASTTypeBody; import net.sourceforge.pmd.lang.java.ast.ASTTypeExpression; +import net.sourceforge.pmd.lang.java.ast.ASTVariableId; import net.sourceforge.pmd.lang.java.ast.JavaNode; +import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; import net.sourceforge.pmd.lang.java.symbols.JAccessibleElementSymbol; import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; @@ -94,7 +98,7 @@ && methodProbablyMeansSame(methodCall)) { } else if (getProperty(REPORT_FIELDS) && opa instanceof ASTFieldAccess) { ASTFieldAccess fieldAccess = (ASTFieldAccess) opa; ScopeInfo reasonForFieldInScope = fieldMeansSame(fieldAccess); - if (reasonForFieldInScope != null) { + if (reasonForFieldInScope != null && !isForwardReference(fieldAccess)) { String simpleName = formatMemberName(next, fieldAccess.getReferencedSym()); String reasonToString = unnecessaryReasonWrapper(reasonForFieldInScope); String unnecessary = produceQualifier(deepest, next, true); @@ -252,4 +256,44 @@ private static String unnecessaryReason(ScopeInfo scopeInfo) { throw AssertionUtil.shouldNotReachHere("unknown constant ScopeInfo: " + scopeInfo); } } + + /** + * Return true if removing the qualification from this field access + * would produce an "Illegal forward reference" compiler error. This + * would happen if the referenced field is defined after the reference, + * in the same class. Note that the java compiler uses definite assignment + * to find forward references. Here we over-approximate this, to avoid + * depending on the dataflow pass. We could fix this later though. + * + * @param fieldAccess A field access + */ + private static boolean isForwardReference(ASTFieldAccess fieldAccess) { + JFieldSymbol referencedSym = fieldAccess.getReferencedSym(); + if (referencedSym == null || referencedSym.isUnresolved()) { + return false; + } + // The field must be declared in the same compilation unit + // to be a forward reference. + ASTVariableId fieldDecl = referencedSym.tryGetNode(); + if (fieldDecl == null) { + return false; + } + ASTBodyDeclaration enclosing = fieldAccess.ancestors(ASTBodyDeclaration.class) + .first(); + if (enclosing != null + && enclosing.getParent().getParent() == fieldDecl.getEnclosingType()) { + // the access is made in the same class + + if (JavaAstUtils.isInStaticCtx(fieldDecl) + && !JavaAstUtils.isInStaticCtx(fieldAccess)) { + // field is static but access is non-static: no problem + return false; + } + // else compare position: if access is before definition, we have a problem + int declIndex = fieldDecl.ancestors().filter(it -> it.getParent() instanceof ASTTypeBody).firstOrThrow().getIndexInParent(); + int accessIndex = enclosing.getIndexInParent(); + return accessIndex <= declIndex; + } + return false; + } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml index 056c77453e1..083d6445660 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml @@ -1125,4 +1125,76 @@ public class Foo { } ]]> + + #5263 FP when forward reference is illegal + 0 + + + + #5263 FP when forward reference is illegal (class) + 0 + + + + #5263 not forward references + 4 + + From 85b76a900b19de251fdb2b1200e42731a2853468 Mon Sep 17 00:00:00 2001 From: Sam Crossland Date: Thu, 21 Nov 2024 14:40:32 +0000 Subject: [PATCH 0281/1962] Updated the docs for UnusedMethod as per discussion #5200 --- pmd-apex/src/main/resources/category/apex/design.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pmd-apex/src/main/resources/category/apex/design.xml b/pmd-apex/src/main/resources/category/apex/design.xml index b1a56f9ff4f..ea5a435c023 100644 --- a/pmd-apex/src/main/resources/category/apex/design.xml +++ b/pmd-apex/src/main/resources/category/apex/design.xml @@ -45,7 +45,8 @@ public class Foo { Date: Thu, 21 Nov 2024 16:51:05 +0100 Subject: [PATCH 0282/1962] Fix static methods being whitelisted --- .../UnnecessaryFullyQualifiedNameRule.java | 13 +++++++++++-- .../codestyle/xml/UnnecessaryFullyQualifiedName.xml | 6 +++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameRule.java index 172e5cfc9ae..20e072efed9 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameRule.java @@ -15,7 +15,10 @@ import net.sourceforge.pmd.lang.java.ast.ASTBodyDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTClassType; +import net.sourceforge.pmd.lang.java.ast.ASTEnumConstant; import net.sourceforge.pmd.lang.java.ast.ASTFieldAccess; +import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTInitializer; import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; import net.sourceforge.pmd.lang.java.ast.ASTTypeBody; import net.sourceforge.pmd.lang.java.ast.ASTTypeExpression; @@ -257,6 +260,12 @@ private static String unnecessaryReason(ScopeInfo scopeInfo) { } } + private static boolean isPartOfStaticInitialization(ASTBodyDeclaration decl) { + return decl instanceof ASTFieldDeclaration && ((ASTFieldDeclaration) decl).isStatic() + || decl instanceof ASTInitializer && ((ASTInitializer) decl).isStatic() + || decl instanceof ASTEnumConstant; + } + /** * Return true if removing the qualification from this field access * would produce an "Illegal forward reference" compiler error. This @@ -275,12 +284,12 @@ private static boolean isForwardReference(ASTFieldAccess fieldAccess) { // The field must be declared in the same compilation unit // to be a forward reference. ASTVariableId fieldDecl = referencedSym.tryGetNode(); - if (fieldDecl == null) { + if (fieldDecl == null || !fieldDecl.isStatic()) { return false; } ASTBodyDeclaration enclosing = fieldAccess.ancestors(ASTBodyDeclaration.class) .first(); - if (enclosing != null + if (isPartOfStaticInitialization(enclosing) && enclosing.getParent().getParent() == fieldDecl.getEnclosingType()) { // the access is made in the same class diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml index 083d6445660..eae7f46f935 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml @@ -1173,7 +1173,7 @@ public class Foo { #5263 not forward references - 4 + 5 From 3e9e128aa7712fdd7c013d21909de74307e28794 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 22 Nov 2024 09:46:35 +0100 Subject: [PATCH 0283/1962] [java] UnnecessaryFullyQualifiedName - improve test case --- .../xml/UnnecessaryFullyQualifiedName.xml | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml index eae7f46f935..25a69a3bc10 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml @@ -1129,9 +1129,7 @@ public class Foo { #5263 FP when forward reference is illegal 0 #5263 FP when forward reference is illegal (class) 0 #5263 not forward references 5 + 3,6,9,13,17 Date: Fri, 22 Nov 2024 09:47:53 +0100 Subject: [PATCH 0284/1962] [doc] Update release notes (#5263, #5353) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 14dc38def2d..aecf590b889 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -37,6 +37,8 @@ This is a {{ site.pmd.release_type }} release. * [#5083](https://github.com/pmd/pmd/issues/5083): \[java] UnusedPrivateMethod false positive when method reference has no target type * [#5097](https://github.com/pmd/pmd/issues/5097): \[java] UnusedPrivateMethod FP with raw type missing from the classpath * [#5318](https://github.com/pmd/pmd/issues/5318): \[java] PreserveStackTraceRule: false-positive on Pattern Matching with instanceof +* java-codestyle + * [#5263](https://github.com/pmd/pmd/issues/5263): \[java] UnnecessaryFullyQualifiedName: false-positive in an enum that uses its own static variables * java-performance * [#5287](https://github.com/pmd/pmd/issues/5287): \[java] TooFewBranchesForSwitch false-positive with switch using list of case constants * [#5314](https://github.com/pmd/pmd/issues/5314): \[java] InsufficientStringBufferDeclarationRule: Lack of handling for char type parameters From 9db4265fd8a9ba05c313f3b76b79e073081f6ac3 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 22 Nov 2024 10:14:18 +0100 Subject: [PATCH 0285/1962] [apex] UnusedMethod: clarify (un)used class --- pmd-apex/src/main/resources/category/apex/design.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pmd-apex/src/main/resources/category/apex/design.xml b/pmd-apex/src/main/resources/category/apex/design.xml index ea5a435c023..0c7f7a6ad9b 100644 --- a/pmd-apex/src/main/resources/category/apex/design.xml +++ b/pmd-apex/src/main/resources/category/apex/design.xml @@ -45,8 +45,10 @@ public class Foo { Date: Fri, 22 Nov 2024 10:15:49 +0100 Subject: [PATCH 0286/1962] [doc] Update release notes (#5354) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 14dc38def2d..7de7f68351a 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -76,6 +76,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ External Contributions * [#5284](https://github.com/pmd/pmd/pull/5284): \[apex] Use case-insensitive input stream to avoid choking on Unicode escape sequences - [Willem A. Hajenius](https://github.com/wahajenius) (@wahajenius) * [#5303](https://github.com/pmd/pmd/pull/5303): \[apex] New Rule: Queueable Should Attach Finalizer - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) +* [#5354](https://github.com/pmd/pmd/pull/5354): \[apex] Updated the docs for UnusedMethod as per discussion #5200 - [samc-gearset](https://github.com/sam-gearset) (@sam-gearset) {% endtocmaker %} From 30996eac53e355c7e711788921e0e8cd0109f47c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 22 Nov 2024 10:16:10 +0100 Subject: [PATCH 0287/1962] Add @sam-gearset as a contributor --- .all-contributorsrc | 9 +++++++++ docs/pages/pmd/projectdocs/credits.md | 15 ++++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 72a0c129d0e..82ba2b36c8b 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7893,6 +7893,15 @@ "contributions": [ "bug" ] + }, + { + "login": "sam-gearset", + "name": "samc-gearset", + "avatar_url": "https://avatars.githubusercontent.com/u/110605614?v=4", + "profile": "https://github.com/sam-gearset", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 8fc171d45be..fbb94b3e18c 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -1052,67 +1052,68 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d ryan-gustafson
    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ› sabi0
    sabi0

    ๐Ÿ› + samc-gearset
    samc-gearset

    ๐Ÿ“– scais
    scais

    ๐Ÿ› schosin
    schosin

    ๐Ÿ› screamingfrog
    screamingfrog

    ๐Ÿ’ต sebbASF
    sebbASF

    ๐Ÿ› - sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป + sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป shilko2013
    shilko2013

    ๐Ÿ› shiomiyan
    shiomiyan

    ๐Ÿ“– simeonKondr
    simeonKondr

    ๐Ÿ› snajberk
    snajberk

    ๐Ÿ› sniperrifle2004
    sniperrifle2004

    ๐Ÿ› snuyanzin
    snuyanzin

    ๐Ÿ› ๐Ÿ’ป - soloturn
    soloturn

    ๐Ÿ› + soloturn
    soloturn

    ๐Ÿ› soyodream
    soyodream

    ๐Ÿ› sratz
    sratz

    ๐Ÿ› stonio
    stonio

    ๐Ÿ› sturton
    sturton

    ๐Ÿ’ป ๐Ÿ› sudharmohan
    sudharmohan

    ๐Ÿ› suruchidawar
    suruchidawar

    ๐Ÿ› - svenfinitiv
    svenfinitiv

    ๐Ÿ› + svenfinitiv
    svenfinitiv

    ๐Ÿ› szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป tashiscool
    tashiscool

    ๐Ÿ› test-git-hook
    test-git-hook

    ๐Ÿ› testation21
    testation21

    ๐Ÿ’ป ๐Ÿ› thanosa
    thanosa

    ๐Ÿ› tiandiyixian
    tiandiyixian

    ๐Ÿ› - tobwoerk
    tobwoerk

    ๐Ÿ› + tobwoerk
    tobwoerk

    ๐Ÿ› tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป trentchilders
    trentchilders

    ๐Ÿ› triandicAnt
    triandicAnt

    ๐Ÿ› trishul14
    trishul14

    ๐Ÿ› tsui
    tsui

    ๐Ÿ› wangzitom12306
    wangzitom12306

    ๐Ÿ› - winhkey
    winhkey

    ๐Ÿ› + winhkey
    winhkey

    ๐Ÿ› witherspore
    witherspore

    ๐Ÿ› wjljack
    wjljack

    ๐Ÿ› wuchiuwong
    wuchiuwong

    ๐Ÿ› xingsong
    xingsong

    ๐Ÿ› xioayuge
    xioayuge

    ๐Ÿ› xnYi9wRezm
    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ› - xuanuy
    xuanuy

    ๐Ÿ› + xuanuy
    xuanuy

    ๐Ÿ› xyf0921
    xyf0921

    ๐Ÿ› yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› yasuharu-sato
    yasuharu-sato

    ๐Ÿ› zenglian
    zenglian

    ๐Ÿ› zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› zh3ng
    zh3ng

    ๐Ÿ› - zt_soft
    zt_soft

    ๐Ÿ› + zt_soft
    zt_soft

    ๐Ÿ› ztt79
    ztt79

    ๐Ÿ› zzzzfeng
    zzzzfeng

    ๐Ÿ› รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› From 8eb0b1beefac5e5e7f3283eceaf55f01a2f8a711 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 22 Nov 2024 10:53:46 +0100 Subject: [PATCH 0288/1962] [java] Update UnresolvedTypesRecoveryTest --- .../internal/infer/UnresolvedTypesRecoveryTest.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt index ec1754c6834..668e749dfcc 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt @@ -760,10 +760,9 @@ class C { private void foo(int y, FunctionalItf x) { } private void foo(FunctionalItf x) { - return SummaryDto.ItemDto.builder().build(); } private T bar(T x) { - return SummaryDto.ItemDto.builder().build(); + return x; } // interface FunctionalItf { String x(); } } @@ -808,10 +807,9 @@ class C { private void foo(int y, FunctionalItf x) { } private void foo(FunctionalItf x) { - return SummaryDto.ItemDto.builder().build(); } private T bar(T x) { - return SummaryDto.ItemDto.builder().build(); + return x; } // interface FunctionalItf { String x(int x, int y); } } @@ -859,7 +857,9 @@ class C { var result = foo(2, (a, b) -> a + b); } - private T foo(int y, FunctionalItf x) {} + private T foo(int y, FunctionalItf x) { + return x.fun(y, y); + } // interface FunctionalItf { A fun(int x, B y); } } From 5c533a2a5203cdb20f3e1bbee91ddc5498ffc46b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 22 Nov 2024 10:54:29 +0100 Subject: [PATCH 0289/1962] [doc] Update release notes (#5338, #5339) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 14dc38def2d..dfbc83e66c1 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -33,6 +33,7 @@ This is a {{ site.pmd.release_type }} release. * [#5293](https://github.com/pmd/pmd/issues/5293): \[java] Deadlock when executing PMD in multiple threads * [#5324](https://github.com/pmd/pmd/issues/5324): \[java] Issue with type inference of nested lambdas * [#5329](https://github.com/pmd/pmd/issues/5329): \[java] Type inference issue with unknown method ref in call chain + * [#5338](https://github.com/pmd/pmd/issues/5338): \[java] Unresolved target type for lambdas make overload resolution fail * java-bestpractices * [#5083](https://github.com/pmd/pmd/issues/5083): \[java] UnusedPrivateMethod false positive when method reference has no target type * [#5097](https://github.com/pmd/pmd/issues/5097): \[java] UnusedPrivateMethod FP with raw type missing from the classpath From 9828a92d17429a64c5f4337a7641ef940f794426 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 22 Nov 2024 11:02:12 +0100 Subject: [PATCH 0290/1962] [doc] Update release notes (#5283, #5310) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 14dc38def2d..2d0abdefedc 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -30,6 +30,7 @@ This is a {{ site.pmd.release_type }} release. * html * [#5322](https://github.com/pmd/pmd/issues/5322): \[html] CPD throws exception on when HTML file is missing closing tag * java + * [#5283](https://github.com/pmd/pmd/issues/5283): \[java] AssertionError "this should be unreachable" with scala library * [#5293](https://github.com/pmd/pmd/issues/5293): \[java] Deadlock when executing PMD in multiple threads * [#5324](https://github.com/pmd/pmd/issues/5324): \[java] Issue with type inference of nested lambdas * [#5329](https://github.com/pmd/pmd/issues/5329): \[java] Type inference issue with unknown method ref in call chain From 13ece583fa81e3b158548a430de13c1b2d6d34b9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 22 Nov 2024 11:46:42 +0100 Subject: [PATCH 0291/1962] [java] UnitTestShouldIncludeAssert: Correctly consider assertSoftly --- .../UnitTestShouldIncludeAssertRule.java | 7 ++-- .../rule/internal/TestFrameworksUtil.java | 10 +++--- .../xml/UnitTestShouldIncludeAssert.xml | 34 +++++++++++++++++-- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertRule.java index 755fb02b003..3f071aa7130 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertRule.java @@ -38,9 +38,10 @@ public UnitTestShouldIncludeAssertRule() { public Object visit(ASTMethodDeclaration method, Object data) { boolean usesSoftAssertExtension = usesSoftAssertExtension(method.getEnclosingType()); Set extraAsserts = getProperty(EXTRA_ASSERT_METHOD_NAMES); - Predicate isAssertCall = usesSoftAssertExtension - ? TestFrameworksUtil::isSoftAssert - : TestFrameworksUtil::isProbableAssertCall; + Predicate isAssertCall = TestFrameworksUtil::isProbableAssertCall; + if (usesSoftAssertExtension) { + isAssertCall = isAssertCall.or(TestFrameworksUtil::isSoftAssert); + } ASTBlock body = method.getBody(); if (body != null diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java index 95e2f9777d8..18bf1140634 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java @@ -172,7 +172,10 @@ public static boolean isCallOnAssertionContainer(ASTMethodCall call) { public static boolean isProbableAssertCall(ASTMethodCall call) { String name = call.getMethodName(); - return name.startsWith("assert") && !isSoftAssert(call) + boolean isSoftAssertType = isSoftAssert(call); + return name.startsWith("assert") && !isSoftAssertType + || "assertAll".equals(name) && isSoftAssertType + || "assertSoftly".equals(name) && isSoftAssertType || name.startsWith("check") || name.startsWith("verify") || "fail".equals(name) @@ -182,10 +185,9 @@ public static boolean isProbableAssertCall(ASTMethodCall call) { public static boolean isSoftAssert(ASTMethodCall call) { JTypeMirror declaringType = call.getMethodType().getDeclaringType(); - return (TypeTestUtil.isA("org.assertj.core.api.StandardSoftAssertionsProvider", declaringType) + return TypeTestUtil.isA("org.assertj.core.api.StandardSoftAssertionsProvider", declaringType) || TypeTestUtil.isA("org.assertj.core.api.Java6StandardSoftAssertionsProvider", declaringType) - || TypeTestUtil.isA("org.assertj.core.api.AbstractSoftAssertions", declaringType)) - && !"assertAll".equals(call.getMethodName()); + || TypeTestUtil.isA("org.assertj.core.api.AbstractSoftAssertions", declaringType); } /** diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldIncludeAssert.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldIncludeAssert.xml index 2d0de33aa64..3041059b1c8 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldIncludeAssert.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldIncludeAssert.xml @@ -810,13 +810,14 @@ class ShouldIncludeAssertTest { #4113 [java] JUnitTestsShouldIncludeAssert - false positive with SoftAssertionsExtension 1 - 27 + 19 + + + + #4113 [java] JUnitTestsShouldIncludeAssert - false positive with assertSoftly + 1 + 17 + From c85250289784c348834e7e3dae2300967d14f533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Fri, 22 Nov 2024 09:08:16 -0300 Subject: [PATCH 0292/1962] Update README.md Force refresh coverage badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8d215b233af..5f85c703fd3 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![Build Status](https://github.com/pmd/pmd/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/pmd/pmd/actions) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/net.sourceforge.pmd/pmd/badge.svg)](https://maven-badges.herokuapp.com/maven-central/net.sourceforge.pmd/pmd) [![Reproducible Builds](https://img.shields.io/badge/Reproducible_Builds-ok-green?labelColor=blue)](https://github.com/jvm-repo-rebuild/reproducible-central/tree/master/content/net/sourceforge/pmd#readme) -[![Coverage Status](https://coveralls.io/repos/github/pmd/pmd/badge.svg?branch=main)](https://coveralls.io/github/pmd/pmd?branch=main) +[![Coverage Status](https://coveralls.io/repos/github/pmd/pmd/badge.svg?branch=main&v=1)](https://coveralls.io/github/pmd/pmd?branch=main) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/ea550046a02344ec850553476c4aa2ca)](https://app.codacy.com/organizations/gh/pmd/dashboard) [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg)](code_of_conduct.md) [![Documentation (latest)](https://img.shields.io/badge/docs-latest-green)](https://docs.pmd-code.org/latest/) From 183b3f3a403ffd94e51e23e9a9b8fffb8924de3c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 22 Nov 2024 15:03:58 +0100 Subject: [PATCH 0293/1962] Ask for a GITHUB_TOKEN during release --- do-release.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/do-release.sh b/do-release.sh index 786139c7211..a3b450e0d3b 100755 --- a/do-release.sh +++ b/do-release.sh @@ -95,6 +95,20 @@ echo echo "Press enter to continue... (or CTRL+C to cancel)" read -r +echo +echo "Please enter a GITHUB_TOKEN (https://github.com/settings/tokens) that can be used to query github" +echo "when generating release notes. If you don't have one, you can just press enter, then anonymous access" +echo "will be used, but access might be rate limited (https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2022-11-28)." +echo +echo -n "GITHUB_TOKEN=" +read GITHUB_TOKEN +if [ -n "$GITHUB_TOKEN" ]; then + export GITHUB_TOKEN + echo "Using GITHUB_TOKEN..." +else + echo "Not using GITHUB_TOKEN" +fi + export LAST_VERSION export RELEASE_VERSION export DEVELOPMENT_VERSION From 12e203bfef48363204baa66ac25ab37155d2968a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 22 Nov 2024 15:10:31 +0100 Subject: [PATCH 0294/1962] [doc] Update release notes --- docs/pages/release_notes.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 87300b8a728..2faf1cc3f86 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -93,11 +93,45 @@ This is a {{ site.pmd.release_type }} release. ### โœจ Merged pull requests * [#5284](https://github.com/pmd/pmd/pull/5284): \[apex] Use case-insensitive input stream to avoid choking on Unicode escape sequences - [Willem A. Hajenius](https://github.com/wahajenius) (@wahajenius) +* [#5286](https://github.com/pmd/pmd/pull/5286): \[ant] Formatter: avoid reflective access to determine console encoding - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5289](https://github.com/pmd/pmd/pull/5289): \[java] TooFewBranchesForSwitch - allow list of case constants - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5296](https://github.com/pmd/pmd/pull/5296): \[xml] Have pmd-xml Lexer in line with other antlr grammars - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) * [#5303](https://github.com/pmd/pmd/pull/5303): \[apex] New Rule: Queueable Should Attach Finalizer - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) +* [#5309](https://github.com/pmd/pmd/pull/5309): \[java] Fix #5293: Parse number of type parameters eagerly - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5310](https://github.com/pmd/pmd/pull/5310): \[java] Fix #5283 - inner class has public private modifiers - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5325](https://github.com/pmd/pmd/pull/5325): \[java] Fix inference dependency issue with nested lambdas - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5326](https://github.com/pmd/pmd/pull/5326): \[java] UseStringBufferLength - consider sb.toString().equals("") - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5328](https://github.com/pmd/pmd/pull/5328): \[html] Test for a closing tag when determining node positions - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5330](https://github.com/pmd/pmd/pull/5330): \[java] Propagate unknown type better when mref is unresolved - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5331](https://github.com/pmd/pmd/pull/5331): \[java] PreserveStackTrace - consider instance type patterns - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5332](https://github.com/pmd/pmd/pull/5332): \[java] InsufficientStringBufferDeclaration: Fix CCE for Character - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5334](https://github.com/pmd/pmd/pull/5334): \[java] UnitTestShouldIncludeAssert - consider SoftAssertionsExtension - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5335](https://github.com/pmd/pmd/pull/5335): \[kotlin] Prevent auxiliary grammars from generating lexers - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5336](https://github.com/pmd/pmd/pull/5336): \[gherkin] Remove generated gherkin code from coverage report - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5339](https://github.com/pmd/pmd/pull/5339): \[java] Allow lambdas with unresolved target types to succeed inference - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5340](https://github.com/pmd/pmd/pull/5340): \[java] Fix #5097 - problem with unchecked conversion - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5341](https://github.com/pmd/pmd/pull/5341): \[java] Fix #5083 - UnusedPrivateMethod false positive with mref without target type but with exact method - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5342](https://github.com/pmd/pmd/pull/5342): \[julia] Ignore generated code in Julia module - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5345](https://github.com/pmd/pmd/pull/5345): \[coco] Remove generated coco files form coverage - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5346](https://github.com/pmd/pmd/pull/5346): \[typescript] Add cleanup after generating ts lexer - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5347](https://github.com/pmd/pmd/pull/5347): \[tsql] Flag generated lexer as generated - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5352](https://github.com/pmd/pmd/pull/5352): \[java] Add permitted subtypes to symbol API - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5353](https://github.com/pmd/pmd/pull/5353): \[java] Fix #5263 - UnnecessaryFullyQualifiedName FP with forward references - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5354](https://github.com/pmd/pmd/pull/5354): \[apex] Updated the docs for UnusedMethod as per discussion #5200 - [samc-gearset](https://github.com/sam-gearset) (@sam-gearset) ### ๐Ÿ“ฆ Dependency updates +* [#5285](https://github.com/pmd/pmd/pull/5285): Bump pmd from 7.5.0 to 7.7.0 +* [#5288](https://github.com/pmd/pmd/pull/5288): Bump asm from 9.7 to 9.7.1 +* [#5290](https://github.com/pmd/pmd/pull/5290): Bump org.apache.maven.plugins:maven-assembly-plugin from 3.6.0 to 3.7.1 +* [#5301](https://github.com/pmd/pmd/pull/5301): Bump gems and bundler +* [#5307](https://github.com/pmd/pmd/pull/5307): Bump org.apache.maven.plugins:maven-clean-plugin from 3.3.2 to 3.4.0 +* [#5308](https://github.com/pmd/pmd/pull/5308): Bump webrick from 1.8.2 to 1.9.0 in /docs in the all-gems group across 1 directory +* [#5312](https://github.com/pmd/pmd/pull/5312): Bump maven-pmd-plugin from 3.24.0 to 3.26.0 +* [#5316](https://github.com/pmd/pmd/pull/5316): Bump rouge from 4.4.0 to 4.5.0 in the all-gems group across 1 directory +* [#5317](https://github.com/pmd/pmd/pull/5317): Bump org.apache.commons:commons-compress from 1.26.0 to 1.27.1 +* [#5348](https://github.com/pmd/pmd/pull/5348): Bump rouge from 4.5.0 to 4.5.1 in the all-gems group across 1 directory +* [#5350](https://github.com/pmd/pmd/pull/5350): Bump org.apache.commons:commons-lang3 from 3.14.0 to 3.17.0 ### ๐Ÿ“ˆ Stats From e017cbe50b0e3c7e8461d55b0ce18ff152c17f63 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 22 Nov 2024 15:18:48 +0100 Subject: [PATCH 0295/1962] Only ask for GITHUB_TOKEN if not yet given Also use IFS= and `read -r`, see https://www.shellcheck.net/wiki/SC2162 --- do-release.sh | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/do-release.sh b/do-release.sh index a3b450e0d3b..caaca61d7e6 100755 --- a/do-release.sh +++ b/do-release.sh @@ -95,18 +95,20 @@ echo echo "Press enter to continue... (or CTRL+C to cancel)" read -r -echo -echo "Please enter a GITHUB_TOKEN (https://github.com/settings/tokens) that can be used to query github" -echo "when generating release notes. If you don't have one, you can just press enter, then anonymous access" -echo "will be used, but access might be rate limited (https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2022-11-28)." -echo -echo -n "GITHUB_TOKEN=" -read GITHUB_TOKEN -if [ -n "$GITHUB_TOKEN" ]; then - export GITHUB_TOKEN - echo "Using GITHUB_TOKEN..." -else - echo "Not using GITHUB_TOKEN" +if [ -z "$GITHUB_TOKEN" ]; then + echo + echo "Please enter a GITHUB_TOKEN (https://github.com/settings/tokens) that can be used to query github" + echo "when generating release notes. If you don't have one, you can just press enter, then anonymous access" + echo "will be used, but access might be rate limited (https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2022-11-28)." + echo + echo -n "GITHUB_TOKEN=" + IFS= read -r GITHUB_TOKEN + if [ -n "$GITHUB_TOKEN" ]; then + export GITHUB_TOKEN + echo "Using provided GITHUB_TOKEN..." + else + echo "Not using GITHUB_TOKEN" + fi fi export LAST_VERSION From 4df05a2fe5356b0fca0e4bf44fa0dfe435b62762 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 22 Nov 2024 15:36:27 +0100 Subject: [PATCH 0296/1962] Bump build-tools to 28 (#5356) This contains the PMD Release Signing Key, that is valid for another year. --- .github/workflows/build.yml | 2 +- .github/workflows/git-repo-sync.yml | 2 +- .github/workflows/troubleshooting.yml | 2 +- pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c98a1196bdd..19a0cb5e1ad 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -59,7 +59,7 @@ jobs: run: | echo "LANG=en_US.UTF-8" >> $GITHUB_ENV echo "MAVEN_OPTS=-Daether.connector.http.connectionMaxTtl=180 -DautoReleaseAfterClose=true -DstagingProgressTimeoutMinutes=30" >> $GITHUB_ENV - echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/27/scripts" >> $GITHUB_ENV + echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/28/scripts" >> $GITHUB_ENV - name: Check Environment shell: bash run: | diff --git a/.github/workflows/git-repo-sync.yml b/.github/workflows/git-repo-sync.yml index 7665bc6d3ba..85bf40bbe13 100644 --- a/.github/workflows/git-repo-sync.yml +++ b/.github/workflows/git-repo-sync.yml @@ -23,7 +23,7 @@ jobs: shell: bash run: | echo "LANG=en_US.UTF-8" >> $GITHUB_ENV - echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/27/scripts" >> $GITHUB_ENV + echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/28/scripts" >> $GITHUB_ENV - name: Sync run: .ci/git-repo-sync.sh shell: bash diff --git a/.github/workflows/troubleshooting.yml b/.github/workflows/troubleshooting.yml index 91351ed96f4..841da066910 100644 --- a/.github/workflows/troubleshooting.yml +++ b/.github/workflows/troubleshooting.yml @@ -36,7 +36,7 @@ jobs: run: | echo "LANG=en_US.UTF-8" >> $GITHUB_ENV echo "MAVEN_OPTS=-Daether.connector.http.connectionMaxTtl=180 -DstagingProgressTimeoutMinutes=30" >> $GITHUB_ENV - echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/27/scripts" >> $GITHUB_ENV + echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/28/scripts" >> $GITHUB_ENV - name: Check Environment shell: bash run: | diff --git a/pom.xml b/pom.xml index 09c4793b2f9..c810dde0856 100644 --- a/pom.xml +++ b/pom.xml @@ -115,7 +115,7 @@ -Xmx512m -Dfile.encoding=${project.build.sourceEncoding} ${extraArgLine} - 28-SNAPSHOT + 28 7.2.0 From 327e9bfe9f0fc2192d3ccb8137a896044ad3c022 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 22 Nov 2024 15:52:24 +0100 Subject: [PATCH 0297/1962] Increase dependabot pull request limit --- .github/dependabot.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 75a3d100ebd..b8e8a80eb0a 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,6 +5,8 @@ updates: directory: "/" schedule: interval: "weekly" + # Allow up to 10 open pull requests for maven dependencies + open-pull-requests-limit: 10 - package-ecosystem: "bundler" directories: - "/" From 18fb574091418e6dfa16e2db8fb13c4705e03d4a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 22 Nov 2024 16:16:17 +0100 Subject: [PATCH 0298/1962] [java] ImmutableField: ref #4869 --- .../pmd/lang/java/rule/design/xml/ImmutableField.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml index 0947ab4ef35..5dea51b8231 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml @@ -958,6 +958,11 @@ public class D { 0 Date: Fri, 22 Nov 2024 17:36:34 +0100 Subject: [PATCH 0299/1962] Bump log4j.version from 2.23.0 to 2.24.2 (#5357) Bumps `log4j.version` from 2.23.0 to 2.24.2. Updates `org.apache.logging.log4j:log4j-api` from 2.23.0 to 2.24.2 Updates `org.apache.logging.log4j:log4j-core` from 2.23.0 to 2.24.2 --- updated-dependencies: - dependency-name: org.apache.logging.log4j:log4j-api dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: org.apache.logging.log4j:log4j-core dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-java/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 184e6ece62c..3fe1ebcbcc8 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -12,7 +12,7 @@ - 2.23.0 + 2.24.2 From eaf28404fd9c4fdc1aae199c04bcd196c8b47a52 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Nov 2024 17:36:59 +0100 Subject: [PATCH 0300/1962] Bump org.apache.maven.plugins:maven-dependency-plugin from 3.7.1 to 3.8.1 (#5358) Bump org.apache.maven.plugins:maven-dependency-plugin Bumps [org.apache.maven.plugins:maven-dependency-plugin](https://github.com/apache/maven-dependency-plugin) from 3.7.1 to 3.8.1. - [Release notes](https://github.com/apache/maven-dependency-plugin/releases) - [Commits](https://github.com/apache/maven-dependency-plugin/compare/maven-dependency-plugin-3.7.1...maven-dependency-plugin-3.8.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-dependency-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c810dde0856..3a04d9a4057 100644 --- a/pom.xml +++ b/pom.xml @@ -184,7 +184,7 @@ org.apache.maven.plugins maven-dependency-plugin - 3.7.1 + 3.8.1 org.apache.maven.plugins From fc60ab4cb64856712174e7ab295300489c99fdad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Nov 2024 17:37:19 +0100 Subject: [PATCH 0301/1962] Bump org.apache.maven.plugins:maven-release-plugin from 3.0.1 to 3.1.1 (#5359) Bumps [org.apache.maven.plugins:maven-release-plugin](https://github.com/apache/maven-release) from 3.0.1 to 3.1.1. - [Release notes](https://github.com/apache/maven-release/releases) - [Commits](https://github.com/apache/maven-release/compare/maven-release-3.0.1...maven-release-3.1.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-release-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3a04d9a4057..552cfddb73f 100644 --- a/pom.xml +++ b/pom.xml @@ -189,7 +189,7 @@ org.apache.maven.plugins maven-release-plugin - 3.0.1 + 3.1.1 pmd-release,sign true From 69e2110ba95fd539f50d91bffb17b78166f7d44c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Nov 2024 17:37:58 +0100 Subject: [PATCH 0302/1962] Bump io.github.apex-dev-tools:apex-ls_2.13 from 5.2.0 to 5.5.0 (#5360) Bumps [io.github.apex-dev-tools:apex-ls_2.13](https://github.com/apex-dev-tools/apex-ls) from 5.2.0 to 5.5.0. - [Release notes](https://github.com/apex-dev-tools/apex-ls/releases) - [Commits](https://github.com/apex-dev-tools/apex-ls/compare/v5.2.0...v5.5.0) --- updated-dependencies: - dependency-name: io.github.apex-dev-tools:apex-ls_2.13 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-apex/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 4bcd6b91994..ce6eeb1986a 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -106,7 +106,7 @@ io.github.apex-dev-tools apex-ls_2.13 - 5.2.0 + 5.5.0 From f7a0cb47710e8f43453d483a949660317e2c6d0d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Nov 2024 17:38:18 +0100 Subject: [PATCH 0303/1962] Bump ant.version from 1.10.14 to 1.10.15 (#5361) Bumps `ant.version` from 1.10.14 to 1.10.15. Updates `org.apache.ant:ant` from 1.10.14 to 1.10.15 Updates `org.apache.ant:ant-launcher` from 1.10.14 to 1.10.15 --- updated-dependencies: - dependency-name: org.apache.ant:ant dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.apache.ant:ant-launcher dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 552cfddb73f..1c3f10f6806 100644 --- a/pom.xml +++ b/pom.xml @@ -102,7 +102,7 @@ 10.18.1 3.5.0 3.26.0 - 1.10.14 + 1.10.15 3.6.3 4.9.3 1.7.36 From 0fae9e3f50dee05d5887555e95180e8cb1ed073b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Nov 2024 17:38:54 +0100 Subject: [PATCH 0304/1962] Bump org.jetbrains:annotations from 24.1.0 to 26.0.1 (#5362) Bumps [org.jetbrains:annotations](https://github.com/JetBrains/java-annotations) from 24.1.0 to 26.0.1. - [Release notes](https://github.com/JetBrains/java-annotations/releases) - [Changelog](https://github.com/JetBrains/java-annotations/blob/master/CHANGELOG.md) - [Commits](https://github.com/JetBrains/java-annotations/compare/24.1.0...26.0.1) --- updated-dependencies: - dependency-name: org.jetbrains:annotations dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1c3f10f6806..74f9098c468 100644 --- a/pom.xml +++ b/pom.xml @@ -1083,7 +1083,7 @@ org.jetbrains annotations - 24.1.0 + 26.0.1 test From f8014ef1ba79addf0361fc31036efaa015fda291 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 03:33:13 +0000 Subject: [PATCH 0305/1962] Bump com.puppycrawl.tools:checkstyle from 10.18.1 to 10.20.1 Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.18.1 to 10.20.1. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.18.1...checkstyle-10.20.1) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 74f9098c468..bc037d35b9c 100644 --- a/pom.xml +++ b/pom.xml @@ -99,7 +99,7 @@ 5.0 3.2.5 - 10.18.1 + 10.20.1 3.5.0 3.26.0 1.10.15 From 5b7a0f4135a051a3a24cb4e31b336b8424a0d41c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 03:33:17 +0000 Subject: [PATCH 0306/1962] Bump info.picocli:picocli from 4.7.5 to 4.7.6 Bumps [info.picocli:picocli](https://github.com/remkop/picocli) from 4.7.5 to 4.7.6. - [Release notes](https://github.com/remkop/picocli/releases) - [Changelog](https://github.com/remkop/picocli/blob/main/RELEASE-NOTES.md) - [Commits](https://github.com/remkop/picocli/compare/v4.7.5...v4.7.6) --- updated-dependencies: - dependency-name: info.picocli:picocli dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 74f9098c468..5a065432c99 100644 --- a/pom.xml +++ b/pom.xml @@ -818,7 +818,7 @@ info.picocli picocli - 4.7.5 + 4.7.6 me.tongfei From 830972b4692e75fbf9931fd7e326d815c6551a42 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 03:33:20 +0000 Subject: [PATCH 0307/1962] Bump com.github.hazendaz.maven:coveralls-maven-plugin Bumps [com.github.hazendaz.maven:coveralls-maven-plugin](https://github.com/trautonen/coveralls-maven-plugin) from 4.5.0-M3 to 4.5.0-M5. - [Changelog](https://github.com/trautonen/coveralls-maven-plugin/blob/master/CHANGELOG.md) - [Commits](https://github.com/trautonen/coveralls-maven-plugin/commits) --- updated-dependencies: - dependency-name: com.github.hazendaz.maven:coveralls-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 74f9098c468..5b05844c665 100644 --- a/pom.xml +++ b/pom.xml @@ -1276,7 +1276,7 @@ com.github.hazendaz.maven coveralls-maven-plugin - 4.5.0-M3 + 4.5.0-M5 From 4d452d22c0dcb8c2d17ecc38bd250b944ac2755f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 03:33:25 +0000 Subject: [PATCH 0308/1962] Bump org.mockito:mockito-core from 4.11.0 to 5.14.2 Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 4.11.0 to 5.14.2. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v4.11.0...v5.14.2) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 74f9098c468..903e404ecb3 100644 --- a/pom.xml +++ b/pom.xml @@ -984,7 +984,7 @@ org.mockito mockito-core - 4.11.0 + 5.14.2 test From 5b6e4c01a9b141748b36a47aa747176afbfd18fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 03:33:35 +0000 Subject: [PATCH 0309/1962] Bump org.junit.platform:junit-platform-suite from 1.11.2 to 1.11.3 Bumps [org.junit.platform:junit-platform-suite](https://github.com/junit-team/junit5) from 1.11.2 to 1.11.3. - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/commits) --- updated-dependencies: - dependency-name: org.junit.platform:junit-platform-suite dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 74f9098c468..f25a800f798 100644 --- a/pom.xml +++ b/pom.xml @@ -970,7 +970,7 @@ org.junit.platform junit-platform-suite - 1.11.2 + 1.11.3 test From f9b7057b89f7485a2fc93d7434f521acf4af7d25 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 18:47:24 +0000 Subject: [PATCH 0310/1962] Bump surefire.version from 3.2.5 to 3.5.2 Bumps `surefire.version` from 3.2.5 to 3.5.2. Updates `org.apache.maven.plugins:maven-surefire-plugin` from 3.2.5 to 3.5.2 - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.2.5...surefire-3.5.2) Updates `org.apache.maven.plugins:maven-failsafe-plugin` from 3.2.5 to 3.5.2 - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.2.5...surefire-3.5.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-surefire-plugin dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.apache.maven.plugins:maven-failsafe-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6438e35d97f..2ec4831aa49 100644 --- a/pom.xml +++ b/pom.xml @@ -98,7 +98,7 @@ 1.9.20 5.0 - 3.2.5 + 3.5.2 10.20.1 3.5.0 3.26.0 From 242b46b22b8421a01eea02d0e3c1a0c11af664a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 26 Nov 2024 09:56:41 +0100 Subject: [PATCH 0311/1962] [java] Fix #5214 - LambdaCanBeMethodReference issue with method of enclosing class --- .../LambdaCanBeMethodReferenceRule.java | 26 ++++++++++--- .../pmd/lang/java/types/TypeOps.java | 19 +++++++++- .../xml/LambdaCanBeMethodReference.xml | 38 +++++++++++++++++++ 3 files changed, 76 insertions(+), 7 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LambdaCanBeMethodReferenceRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LambdaCanBeMethodReferenceRule.java index e2c9bd56ec2..ddfe188625d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LambdaCanBeMethodReferenceRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LambdaCanBeMethodReferenceRule.java @@ -19,13 +19,18 @@ import net.sourceforge.pmd.lang.java.ast.ASTStatement; import net.sourceforge.pmd.lang.java.ast.ASTSuperExpression; import net.sourceforge.pmd.lang.java.ast.ASTThisExpression; +import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTTypeExpression; import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; import net.sourceforge.pmd.lang.java.ast.internal.PrettyPrintingUtil; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; +import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; import net.sourceforge.pmd.lang.java.symbols.JTypeDeclSymbol; import net.sourceforge.pmd.lang.java.symbols.JVariableSymbol; +import net.sourceforge.pmd.lang.java.types.JClassType; +import net.sourceforge.pmd.lang.java.types.JTypeMirror; import net.sourceforge.pmd.lang.java.types.OverloadSelectionResult; +import net.sourceforge.pmd.lang.java.types.TypeOps; import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.properties.PropertyFactory; import net.sourceforge.pmd.reporting.RuleContext; @@ -90,17 +95,26 @@ private String buildMethodRefString(ASTLambdaExpression lambda, ASTMethodCall ca OverloadSelectionResult info = call.getOverloadSelectionInfo(); assert !info.isFailed() : "should not be failed: " + call; + JTypeMirror methodSource = info.getMethodType().getDeclaringType(); + JTypeDeclSymbol classSym = methodSource.getSymbol(); + assert classSym != null + : "null symbol for " + methodSource + ", method " + info.getMethodType(); if (qualifier == null && info.getMethodType().isStatic() || lambda.getParameters().size() != call.getArguments().size()) { // this second condition corresponds to the case the first lambda // param is the receiver of the method call - - JTypeDeclSymbol symbol = info.getMethodType().getDeclaringType().getSymbol(); - assert symbol != null - : "null symbol for " + info.getMethodType().getDeclaringType() + ", method " + info.getMethodType(); - sb.append(symbol.getSimpleName()); + sb.append(classSym.getSimpleName()); } else if (qualifier == null) { - sb.append("this"); + // non-static method with null qualifier + ASTTypeDeclaration enclosing = call.getEnclosingType(); + JClassType receiver = TypeOps.getReceiverType(enclosing.getTypeMirror(), (JClassSymbol) classSym); + if (receiver != null && !receiver.getSymbol().equals(enclosing.getSymbol())) { + // method is declared in an enclosing type and receiver + // needs qualification + sb.append(receiver.getSymbol().getSimpleName()).append(".this"); + } else { + sb.append("this"); + } } else { boolean needsParentheses = !(qualifier instanceof ASTPrimaryExpression); if (needsParentheses) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java index 451c6fb8b97..b5f39166e4e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java @@ -1681,7 +1681,7 @@ private static boolean isNotDeclaredInClassObject(JMethodSig it) { * Return the base type of t or any of its outer types that starts * with the given type. If none exists, return null. */ - public static JClassType asOuterSuper(JTypeMirror t, JClassSymbol sym) { + public static @Nullable JClassType asOuterSuper(JTypeMirror t, JClassSymbol sym) { if (t instanceof JClassType) { JClassType ct = (JClassType) t; do { @@ -1697,6 +1697,23 @@ public static JClassType asOuterSuper(JTypeMirror t, JClassSymbol sym) { return null; } + /** + * Return the first enclosing type of the container type + * that has the given symbol in its supertypes. Return null + * if this is not found. + */ + public static @Nullable JClassType getReceiverType(@NonNull JClassType containerType, JClassSymbol sym) { + JClassType ct = containerType; + do { + JClassType sup = ct.getAsSuper(sym); + if (sup != null) { + return ct; + } + ct = ct.getEnclosingType(); + } while (ct != null); + return null; + } + private static final class AsSuperVisitor implements JTypeVisitor<@Nullable JTypeMirror, JClassSymbol> { static final AsSuperVisitor INSTANCE = new AsSuperVisitor(); diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LambdaCanBeMethodReference.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LambdaCanBeMethodReference.xml index 48f0f2d328c..9025e8a88cf 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LambdaCanBeMethodReference.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LambdaCanBeMethodReference.xml @@ -336,5 +336,43 @@ + + #5214 message when method is in outer class + 2 + + Lambda expression could be written as a method reference: `Outer.this::correct` + Lambda expression could be written as a method reference: `Inner.this::something` + + correct(i)); + } + + boolean something(int x) { return true; } + class Deeper { + + { + iTakeLambda(i -> something(i)); + } + } + } + + static void iTakeLambda(ALambda2 l) { + } + + public boolean correct(int a) { + return false; + } + } + interface ALambda2 { + boolean doSomething(int a); + } + ]]> + + From a5f0c1ac7e7a6740c21ac15be77ef0183bf48fad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Tue, 26 Nov 2024 11:12:10 -0300 Subject: [PATCH 0312/1962] Improve docs on adding Antlr languages - Properly name the antlr4 plugin instead of ant. - Mention the ant cleanup task and targets. --- .../major_contributions/adding_a_new_antlr_based_language.md | 3 +++ .../pmd/devdocs/major_contributions/adding_new_cpd_language.md | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md index e1427c93a37..adc76418e4f 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md @@ -110,6 +110,8 @@ definitely don't come for free. It is much effort and requires perseverance to i ### 4. Generate your parser (using ANTLR) * Make sure, you have the property `true` in your `pom.xml` file. +* Include the antlr and antrun plugins to the module `pom.xml`. Antlr needs to be first, to ensure it runs first. + The antrun plugin should execute the `pmd-language` target using the `${antlr4.ant.wrapper}` antfile. * This is just a matter of building the language module. ANTLR is called via ant, and this step is added to the phase `generate-sources`. So you can just call e.g. `./mvnw generate-sources -pl pmd-swift` to have the parser generated. @@ -163,6 +165,7 @@ definitely don't come for free. It is much effort and requires perseverance to i ### 9. Make PMD recognize your language * Create your own subclass of `net.sourceforge.pmd.lang.impl.SimpleLanguageModuleBase`, see Swift as an example: [`SwiftLanguageModule`](https://github.com/pmd/pmd/blob/main/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftLanguageModule.java). +* Ensure the language name and language id used, match those set as properties when running `ant` in step #4. * Add for each version of your language a call to `addVersion` in your language moduleโ€™s constructor. Use `addDefaultVersion` for defining the default version. * Youโ€™ll need to refer the language version handler created in step #7. diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md index 5588cabbdf7..43fe65edaab 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md @@ -27,11 +27,12 @@ Use the following guide to set up a new language module that supports CPD. is automatically available in the binary distribution (pmd-dist). 2. Implement a {% jdoc core::cpd.CpdLexer %}. - - For Antlr grammars you can take the grammar from [antlr/grammars-v4](https://github.com/antlr/grammars-v4) and place it in `src/main/antlr4` followed by the package name of the language. You then need to call the appropriate ant wrapper to generate + - For Antlr grammars you can take the grammar from [antlr/grammars-v4](https://github.com/antlr/grammars-v4) and place it in `src/main/antlr4` followed by the package name of the language. You then need to call the antlr4 plugin and the appropriate ant wrapper with target `cpd-language` to generate the lexer from the grammar. To do so, edit `pom.xml` (eg like [the Golang module](https://github.com/pmd/pmd/tree/main/pmd-go/pom.xml)). Once that is done, `mvn generate-sources` should generate the lexer sources for you. You can now implement a CpdLexer, for instance by extending {% jdoc core::cpd.impl.AntlrCpdLexer %}. The following reproduces the Go implementation: + ```java // mind the package convention if you are going to make a PR package net.sourceforge.pmd.lang.go.cpd; From 1475ca28fd35eb9fe54cfb2c7a8142837f8cf797 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 26 Nov 2024 19:29:49 +0100 Subject: [PATCH 0313/1962] [doc] Update release notes (#5214, #5370) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 2faf1cc3f86..cd85ef35aad 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -41,6 +41,7 @@ This is a {{ site.pmd.release_type }} release. * [#5097](https://github.com/pmd/pmd/issues/5097): \[java] UnusedPrivateMethod FP with raw type missing from the classpath * [#5318](https://github.com/pmd/pmd/issues/5318): \[java] PreserveStackTraceRule: false-positive on Pattern Matching with instanceof * java-codestyle + * [#5214](https://github.com/pmd/pmd/issues/5214): \[java] Wrong message for LambdaCanBeMethodReference with method of enclosing class * [#5263](https://github.com/pmd/pmd/issues/5263): \[java] UnnecessaryFullyQualifiedName: false-positive in an enum that uses its own static variables * java-performance * [#5287](https://github.com/pmd/pmd/issues/5287): \[java] TooFewBranchesForSwitch false-positive with switch using list of case constants @@ -118,6 +119,7 @@ This is a {{ site.pmd.release_type }} release. * [#5352](https://github.com/pmd/pmd/pull/5352): \[java] Add permitted subtypes to symbol API - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5353](https://github.com/pmd/pmd/pull/5353): \[java] Fix #5263 - UnnecessaryFullyQualifiedName FP with forward references - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5354](https://github.com/pmd/pmd/pull/5354): \[apex] Updated the docs for UnusedMethod as per discussion #5200 - [samc-gearset](https://github.com/sam-gearset) (@sam-gearset) +* [#5370](https://github.com/pmd/pmd/pull/5370): \[java] Fix #5214 - LambdaCanBeMethodReference issue with method of enclosing class - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) ### ๐Ÿ“ฆ Dependency updates From 66e6c7ce7dfbdb0388e93f1d167268b23edebdc2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 26 Nov 2024 19:32:38 +0100 Subject: [PATCH 0314/1962] [doc] Update release notes (#5371) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 2faf1cc3f86..61299c082ce 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -118,6 +118,7 @@ This is a {{ site.pmd.release_type }} release. * [#5352](https://github.com/pmd/pmd/pull/5352): \[java] Add permitted subtypes to symbol API - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5353](https://github.com/pmd/pmd/pull/5353): \[java] Fix #5263 - UnnecessaryFullyQualifiedName FP with forward references - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5354](https://github.com/pmd/pmd/pull/5354): \[apex] Updated the docs for UnusedMethod as per discussion #5200 - [samc-gearset](https://github.com/sam-gearset) (@sam-gearset) +* [#5371](https://github.com/pmd/pmd/pull/5371): \[doc] Improve docs on adding Antlr languages - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) ### ๐Ÿ“ฆ Dependency updates From f7a10eaebd5a3e9d8a371a23ac0dc0255e6f57fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 27 Nov 2024 14:50:01 +0100 Subject: [PATCH 0315/1962] [java] Fix #5315 - UnusedImport FP with import on demand --- docs/pages/release_notes.md | 1 + .../rule/codestyle/UnnecessaryImportRule.java | 97 ++++++++++++------- .../rule/codestyle/xml/UnnecessaryImport.xml | 38 ++++++-- 3 files changed, 94 insertions(+), 42 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 7d6c383a224..55e1b748ae6 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -43,6 +43,7 @@ This is a {{ site.pmd.release_type }} release. * java-codestyle * [#5214](https://github.com/pmd/pmd/issues/5214): \[java] Wrong message for LambdaCanBeMethodReference with method of enclosing class * [#5263](https://github.com/pmd/pmd/issues/5263): \[java] UnnecessaryFullyQualifiedName: false-positive in an enum that uses its own static variables + * [#5315](https://github.com/pmd/pmd/issues/5315): \[java] UnnecessaryImport false positive for on-demand imports * java-performance * [#5287](https://github.com/pmd/pmd/issues/5287): \[java] TooFewBranchesForSwitch false-positive with switch using list of case constants * [#5314](https://github.com/pmd/pmd/issues/5314): \[java] InsufficientStringBufferDeclarationRule: Lack of handling for char type parameters diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java index 3be1848b7fb..515035cf624 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java @@ -68,7 +68,8 @@ public class UnnecessaryImportRule extends AbstractJavaRule { private static final Logger LOG = LoggerFactory.getLogger(UnnecessaryImportRule.class); private final Set allSingleNameImports = new HashSet<>(); - private final Set allImportsOnDemand = new HashSet<>(); + private final Set staticImportsOnDemand = new HashSet<>(); + private final Set typeImportsOnDemand = new HashSet<>(); private final Set moduleImports = new HashSet<>(); private final Set unnecessaryJavaLangImports = new HashSet<>(); private final Set unnecessaryImportsFromSamePackage = new HashSet<>(); @@ -121,7 +122,8 @@ public class UnnecessaryImportRule extends AbstractJavaRule { public Object visit(ASTCompilationUnit node, Object data) { this.moduleImports.clear(); this.allSingleNameImports.clear(); - this.allImportsOnDemand.clear(); + this.staticImportsOnDemand.clear(); + this.typeImportsOnDemand.clear(); this.unnecessaryJavaLangImports.clear(); this.unnecessaryImportsFromSamePackage.clear(); String packageName = node.getPackageName(); @@ -152,9 +154,11 @@ private void doReporting(Object data) { String message = wrapper.isStatic() ? UNUSED_STATIC_IMPORT_MESSAGE : UNUSED_IMPORT_MESSAGE; reportWithMessage(wrapper.node, data, message); } - for (ImportWrapper wrapper : allImportsOnDemand) { - String message = wrapper.isStatic() ? UNUSED_STATIC_IMPORT_MESSAGE : UNUSED_IMPORT_MESSAGE; - reportWithMessage(wrapper.node, data, message); + for (ImportWrapper wrapper : staticImportsOnDemand) { + reportWithMessage(wrapper.node, data, UNUSED_STATIC_IMPORT_MESSAGE); + } + for (ImportWrapper wrapper : typeImportsOnDemand) { + reportWithMessage(wrapper.node, data, UNUSED_IMPORT_MESSAGE); } for (ImportWrapper wrapper : moduleImports) { reportWithMessage(wrapper.node, data, "Unused module import ''{0}''"); @@ -162,9 +166,11 @@ private void doReporting(Object data) { // remove unused ones, they have already been reported unnecessaryJavaLangImports.removeAll(allSingleNameImports); - unnecessaryJavaLangImports.removeAll(allImportsOnDemand); + unnecessaryJavaLangImports.removeAll(staticImportsOnDemand); + unnecessaryJavaLangImports.removeAll(typeImportsOnDemand); unnecessaryImportsFromSamePackage.removeAll(allSingleNameImports); - unnecessaryImportsFromSamePackage.removeAll(allImportsOnDemand); + unnecessaryImportsFromSamePackage.removeAll(staticImportsOnDemand); + unnecessaryImportsFromSamePackage.removeAll(typeImportsOnDemand); for (ImportWrapper wrapper : unnecessaryJavaLangImports) { reportWithMessage(wrapper.node, data, IMPORT_FROM_JAVA_LANG_MESSAGE); } @@ -226,10 +232,7 @@ private void visitImport(ASTImportDeclaration node, Object data, String thisPack unnecessaryImportsFromSamePackage.add(new ImportWrapper(node)); } - Set container = - node.isModuleImport() ? moduleImports - : node.isImportOnDemand() ? allImportsOnDemand - : allSingleNameImports; + Set container = getImportContainer(node); if (!container.add(new ImportWrapper(node))) { @@ -238,6 +241,18 @@ private void visitImport(ASTImportDeclaration node, Object data, String thisPack } } + private Set getImportContainer(ASTImportDeclaration node) { + if (node.isModuleImport()) { + return moduleImports; + } else if (node.isImportOnDemand()) { + if (node.isStatic()) { + return staticImportsOnDemand; + } + return typeImportsOnDemand; + } + return allSingleNameImports; + } + private void reportWithMessage(ASTImportDeclaration node, Object data, String message) { asCtx(data).addViolationWithMessage(node, message, PrettyPrintingUtil.prettyImport(node)); } @@ -275,7 +290,11 @@ private void recordFailedTypeResWithName(JavaNode location, String name, boolean if (!foundNamedImport) { LOG.debug("+ Since no such named import can be found, all {}on-demand-imports will be marked as used", target); - allImportsOnDemand.removeIf(it -> !onlyStatics || it.isStatic()); + if (onlyStatics) { + staticImportsOnDemand.clear(); + } else { + typeImportsOnDemand.clear(); + } } } @@ -347,30 +366,10 @@ private void checkScopeChain(boolean recursive, } else if (scopeIter.getScopeTag() == ScopeInfo.IMPORT_ON_DEMAND) { - allImportsOnDemand.removeIf(it -> { - if (!it.isStatic() && onlyStatic) { - return false; - } - // This is the class that contains the symbol - // we're looking for. - // We have to test whether this symbol is contained - // by the imported type or package. - JClassSymbol symbolOwner = symbol.getEnclosingClass(); - if (symbolOwner == null) { - // package import on demand - return it.node.getImportedName().equals(symbol.getPackageName()); - } else { - if (it.node.getImportedName().equals(symbolOwner.getCanonicalName())) { - // importing the container directly - return it.isStatic() == symbol.isStatic(); - } - // maybe we're importing a subclass of the container. - TypeSystem ts = symbolOwner.getTypeSystem(); - JClassSymbol importedContainer = ts.getClassSymbol(it.node.getImportedName()); - return importedContainer == null // insufficient classpath, err towards FNs - || TypeTestUtil.isA(ts.rawType(symbolOwner), ts.rawType(importedContainer)); - } - }); + boolean found = typeImportsOnDemand.removeIf(it -> importOnDemandImportsSymbol(symbol, onlyStatic, it)); + if (!found) { + staticImportsOnDemand.removeIf(it -> importOnDemandImportsSymbol(symbol, onlyStatic, it)); + } } else if (scopeIter.getScopeTag() == ScopeInfo.MODULE_IMPORT) { moduleImports.removeIf(it -> { if (!(symbol instanceof JTypeDeclSymbol)) { @@ -404,6 +403,32 @@ private void checkScopeChain(boolean recursive, // unknown reference } + private static boolean importOnDemandImportsSymbol(JAccessibleElementSymbol symbol, boolean onlyStatic, ImportWrapper it) { + if (!it.isStatic() && onlyStatic) { + return false; + } + // This is the class that contains the symbol + // we're looking for. + // We have to test whether this symbol is contained + // by the imported type or package. + JClassSymbol symbolOwner = symbol.getEnclosingClass(); + if (symbolOwner == null) { + // package import on demand + return it.node.getImportedName().equals(symbol.getPackageName()); + } else { + if (it.node.getImportedName().equals(symbolOwner.getCanonicalName())) { + // If the import is not static, then it imports static and non-static types. + // Otherwise, it imports static members (types + other things) + return !it.isStatic() || symbol.isStatic(); + } + // maybe we're importing a subclass of the container. + TypeSystem ts = symbolOwner.getTypeSystem(); + JClassSymbol importedContainer = ts.getClassSymbol(it.node.getImportedName()); + return importedContainer == null // insufficient classpath, err towards FNs + || TypeTestUtil.isA(ts.rawType(symbolOwner), ts.rawType(importedContainer)); + } + } + /** We found a reference to the type given by the name. */ private void removeReferenceSingleImport(String referenceName) { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml index eb7b1c853b5..ec6badd2bf2 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml @@ -773,14 +773,18 @@ class NPEImport {} [java] #2546 -- similar imports static/nonstatic - static is used 1 - 2 + 8 - Unused import 'net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryimport.NonStaticContainer.*' + Unused static import 'net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryimport.NonStaticContainer.*' Unused static import 'net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryimport.NonStaticContainer.*' java 23-preview + + + imports used in markdown javadoc comment (since java 23, JEP 467) + 0 + map = Map.of("key1", "value1"); + var weirdCopy = map.entrySet().stream().collect(toMap(Entry::getKey, Entry::getValue)); + System.out.println(weirdCopy); + } + } + ]]> + + From 8598a4d63f96afd75e2bf5d4956e3a81785d39b2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 28 Nov 2024 10:12:15 +0100 Subject: [PATCH 0316/1962] [doc] Add PMD Guru to various help pages --- CONTRIBUTING.md | 2 ++ README.md | 3 ++- docs/pages/pmd/about/help.md | 6 +++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1622cb421f7..c7d16e5a8dd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -49,6 +49,8 @@ There are various channels, on which you can ask questions: * Ask your question in our [Gitter room](https://app.gitter.im/#/room/#pmd_pmd:gitter.im). +* Ask your question our [PMD Guru at Gurubase](https://gurubase.io/g/pmd). + ## Code Style PMD uses [checkstyle](http://checkstyle.sourceforge.net/) to enforce a common code style. diff --git a/README.md b/README.md index 22e830efb83..d91d848be44 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,8 @@ See [Tools / Integrations](https://docs.pmd-code.org/latest/pmd_userdocs_tools.h or on [discussions](https://github.com/pmd/pmd/discussions). * I got this error and I'm sure it's a bug -- file an [issue](https://github.com/pmd/pmd/issues). * I have an idea/request/question -- create a new [discussion](https://github.com/pmd/pmd/discussions). -* I have a quick question -- ask in our [Gitter room](https://app.gitter.im/#/room/#pmd_pmd:gitter.im). +* I have a quick question -- ask in our [Gitter room](https://app.gitter.im/#/room/#pmd_pmd:gitter.im) + or our [PMD Guru at Gurubase](https://gurubase.io/g/pmd). * Where's your documentation? -- ## ๐Ÿค Contributing diff --git a/docs/pages/pmd/about/help.md b/docs/pages/pmd/about/help.md index abc0434f17a..5d276779e8f 100644 --- a/docs/pages/pmd/about/help.md +++ b/docs/pages/pmd/about/help.md @@ -2,7 +2,7 @@ title: Getting Help permalink: pmd_about_help.html author: Andreas Dangel -last_updated: January 2021 +last_updated: November 2024 --- There are numerous ways of getting help: @@ -18,4 +18,8 @@ There are numerous ways of getting help: * Or you can join the [Mailing List](https://lists.sourceforge.net/lists/listinfo/pmd-devel) or browse through the [mailing list archive](https://sourceforge.net/p/pmd/mailman/pmd-devel/). +* Ask your question in our [Gitter room](https://app.gitter.im/#/room/#pmd_pmd:gitter.im). + +* Ask your question our [PMD Guru at Gurubase](https://gurubase.io/g/pmd). + * Of course, you can also directly jump to our [source code on github](https://github.com/pmd/pmd). From 5f2910177f17f0030f044271ad8927a73ba8352b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 28 Nov 2024 10:12:37 +0100 Subject: [PATCH 0317/1962] [doc] Update release notes (#5337) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index f9967dcfc36..5f069bddff3 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -33,6 +33,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ External Contributions * [#5284](https://github.com/pmd/pmd/pull/5284): \[apex] Use case-insensitive input stream to avoid choking on Unicode escape sequences - [Willem A. Hajenius](https://github.com/wahajenius) (@wahajenius) +* [#5337](https://github.com/pmd/pmd/pull/5337): \[doc] Introducing PMD Guru on Gurubase.io - [Kursat Aktas](https://github.com/kursataktas) (@kursataktas) {% endtocmaker %} From 185a4058be0a73349886259c50ed2215c5013f4f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 28 Nov 2024 10:13:02 +0100 Subject: [PATCH 0318/1962] Add @kursataktas as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 149 +++++++++++++------------- 2 files changed, 84 insertions(+), 74 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 3ccf2e8784b..6cdd7184442 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7874,6 +7874,15 @@ "contributions": [ "code" ] + }, + { + "login": "kursataktas", + "name": "Kursat Aktas", + "avatar_url": "https://avatars.githubusercontent.com/u/17837825?v=4", + "profile": "https://github.com/kursataktas", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 8bedbc0f630..1c5f91143e0 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -451,668 +451,669 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Kris Scheibe
    Kris Scheibe

    ๐Ÿ’ป ๐Ÿ› Krystian Dabrowski
    Krystian Dabrowski

    ๐Ÿ› ๐Ÿ’ป Kunal Thanki
    Kunal Thanki

    ๐Ÿ› + Kursat Aktas
    Kursat Aktas

    ๐Ÿ“– LaLucid
    LaLucid

    ๐Ÿ’ป Larry Diamond
    Larry Diamond

    ๐Ÿ’ป ๐Ÿ› - Lars Knickrehm
    Lars Knickrehm

    ๐Ÿ› + Lars Knickrehm
    Lars Knickrehm

    ๐Ÿ› Laurent Bovet
    Laurent Bovet

    ๐Ÿ› ๐Ÿ’ป Leo Gutierrez
    Leo Gutierrez

    ๐Ÿ› LiGaOg
    LiGaOg

    ๐Ÿ’ป Liam Sharp
    Liam Sharp

    ๐Ÿ› Lintsi
    Lintsi

    ๐Ÿ› Linus Fernandes
    Linus Fernandes

    ๐Ÿ› - Lixon Lookose
    Lixon Lookose

    ๐Ÿ› + Lixon Lookose
    Lixon Lookose

    ๐Ÿ› Logesh
    Logesh

    ๐Ÿ› Lorenzo Gabriele
    Lorenzo Gabriele

    ๐Ÿ› Loรฏc Ledoyen
    Loรฏc Ledoyen

    ๐Ÿ› Lucas
    Lucas

    ๐Ÿ› Lucas Silva
    Lucas Silva

    ๐Ÿ› Lucas Soncini
    Lucas Soncini

    ๐Ÿ’ป ๐Ÿ› - Luis Alcantar
    Luis Alcantar

    ๐Ÿ’ป + Luis Alcantar
    Luis Alcantar

    ๐Ÿ’ป Lukas Grรคf
    Lukas Grรคf

    ๐Ÿ’ป Lukasz Slonina
    Lukasz Slonina

    ๐Ÿ› Lukebray
    Lukebray

    ๐Ÿ› Lynn
    Lynn

    ๐Ÿ’ป ๐Ÿ› Lyor Goldstein
    Lyor Goldstein

    ๐Ÿ› MCMicS
    MCMicS

    ๐Ÿ› - Macarse
    Macarse

    ๐Ÿ› + Macarse
    Macarse

    ๐Ÿ› Machine account for PMD
    Machine account for PMD

    ๐Ÿ’ป Maciek Siemczyk
    Maciek Siemczyk

    ๐Ÿ› Maikel Steneker
    Maikel Steneker

    ๐Ÿ’ป ๐Ÿ› Maksim Moiseikin
    Maksim Moiseikin

    ๐Ÿ› Manfred Koch
    Manfred Koch

    ๐Ÿ› Manuel Moya Ferrer
    Manuel Moya Ferrer

    ๐Ÿ’ป ๐Ÿ› - Manuel Ryan
    Manuel Ryan

    ๐Ÿ› + Manuel Ryan
    Manuel Ryan

    ๐Ÿ› Marat Vyshegorodtsev
    Marat Vyshegorodtsev

    ๐Ÿ› Marcel Hรคrle
    Marcel Hรคrle

    ๐Ÿ› Marcello Fialho
    Marcello Fialho

    ๐Ÿ› Marcin Dฤ…browski
    Marcin Dฤ…browski

    ๐Ÿ’ป Marcin Rataj
    Marcin Rataj

    ๐Ÿ› Marcono1234
    Marcono1234

    ๐Ÿ› - Mark Adamcin
    Mark Adamcin

    ๐Ÿ› + Mark Adamcin
    Mark Adamcin

    ๐Ÿ› Mark Hall
    Mark Hall

    ๐Ÿ’ป ๐Ÿ› Mark Kolich
    Mark Kolich

    ๐Ÿ› Mark Pritchard
    Mark Pritchard

    ๐Ÿ› Markus Rathgeb
    Markus Rathgeb

    ๐Ÿ› Marquis Wang
    Marquis Wang

    ๐Ÿ› MartGit
    MartGit

    ๐Ÿ› - Martin Feldsztejn
    Martin Feldsztejn

    ๐Ÿ› + Martin Feldsztejn
    Martin Feldsztejn

    ๐Ÿ› Martin Lehmann
    Martin Lehmann

    ๐Ÿ› Martin Spamer
    Martin Spamer

    ๐Ÿ› Martin Tarjรกnyi
    Martin Tarjรกnyi

    ๐Ÿ› MatFl
    MatFl

    ๐Ÿ› Mateusz Stefanski
    Mateusz Stefanski

    ๐Ÿ› Mathieu Gouin
    Mathieu Gouin

    ๐Ÿ› - MatiasComercio
    MatiasComercio

    ๐Ÿ’ป ๐Ÿ› + MatiasComercio
    MatiasComercio

    ๐Ÿ’ป ๐Ÿ› Matt Benson
    Matt Benson

    ๐Ÿ› Matt De Poorter
    Matt De Poorter

    ๐Ÿ› Matt Hargett
    Matt Hargett

    ๐Ÿ’ป ๐Ÿ’ต Matt Harrah
    Matt Harrah

    ๐Ÿ› Matt Nelson
    Matt Nelson

    ๐Ÿ› Matthew Amos
    Matthew Amos

    ๐Ÿ› - Matthew Duggan
    Matthew Duggan

    ๐Ÿ› + Matthew Duggan
    Matthew Duggan

    ๐Ÿ› Matthew Hall
    Matthew Hall

    ๐Ÿ› Matthew Rossner
    Matthew Rossner

    ๐Ÿ› Matรญas Fraga
    Matรญas Fraga

    ๐Ÿ’ป ๐Ÿ› Maxime Robert
    Maxime Robert

    ๐Ÿ’ป ๐Ÿ› MetaBF
    MetaBF

    ๐Ÿ› Metin Dagcilar
    Metin Dagcilar

    ๐Ÿ› - Michael
    Michael

    ๐Ÿ› + Michael
    Michael

    ๐Ÿ› Michael Bell
    Michael Bell

    ๐Ÿ› Michael Bernstein
    Michael Bernstein

    ๐Ÿ› Michael Clay
    Michael Clay

    ๐Ÿ› Michael Dombrowski
    Michael Dombrowski

    ๐Ÿ› Michael Hausegger
    Michael Hausegger

    ๐Ÿ› Michael Hoefer
    Michael Hoefer

    ๐Ÿ› - Michael Kolesnikov
    Michael Kolesnikov

    ๐Ÿ› + Michael Kolesnikov
    Michael Kolesnikov

    ๐Ÿ› Michael Mรถbius
    Michael Mรถbius

    ๐Ÿ› Michael N. Lipp
    Michael N. Lipp

    ๐Ÿ› Michael Pellegrini
    Michael Pellegrini

    ๐Ÿ› Michal Kordas
    Michal Kordas

    ๐Ÿ› Michaล‚ Borek
    Michaล‚ Borek

    ๐Ÿ› Michaล‚ Kuliล„ski
    Michaล‚ Kuliล„ski

    ๐Ÿ› - Miguel Nรบรฑez Dรญaz-Montes
    Miguel Nรบรฑez Dรญaz-Montes

    ๐Ÿ› + Miguel Nรบรฑez Dรญaz-Montes
    Miguel Nรบรฑez Dรญaz-Montes

    ๐Ÿ› Mihai Ionut
    Mihai Ionut

    ๐Ÿ› Mikhail Kuchma
    Mikhail Kuchma

    ๐Ÿ› Mirek Hankus
    Mirek Hankus

    ๐Ÿ› Mitch Spano
    Mitch Spano

    ๐Ÿ› Mladjan Gadzic
    Mladjan Gadzic

    ๐Ÿ› MrAngry52
    MrAngry52

    ๐Ÿ› - Muminur Choudhury
    Muminur Choudhury

    ๐Ÿ› + Muminur Choudhury
    Muminur Choudhury

    ๐Ÿ› Mykhailo Palahuta
    Mykhailo Palahuta

    ๐Ÿ’ป ๐Ÿ› Nagendra Kumar Singh
    Nagendra Kumar Singh

    ๐Ÿ› Nahuel Barrios
    Nahuel Barrios

    ๐Ÿ› Nakul Sharma
    Nakul Sharma

    ๐Ÿ› Nathan Braun
    Nathan Braun

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› - Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› + Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› Nathanaรซl
    Nathanaรซl

    ๐Ÿ› Naveen
    Naveen

    ๐Ÿ’ป Nazdravi
    Nazdravi

    ๐Ÿ› Neha-Dhonde
    Neha-Dhonde

    ๐Ÿ› Nicholas Doyle
    Nicholas Doyle

    ๐Ÿ› Nick Butcher
    Nick Butcher

    ๐Ÿ› - Nico Gallinal
    Nico Gallinal

    ๐Ÿ› + Nico Gallinal
    Nico Gallinal

    ๐Ÿ› Nicola Dal Maso
    Nicola Dal Maso

    ๐Ÿ› Nicolas Filotto
    Nicolas Filotto

    ๐Ÿ’ป Nicolas Vervelle
    Nicolas Vervelle

    ๐Ÿ› Nicolas Vuillamy
    Nicolas Vuillamy

    ๐Ÿ“– Nikita Chursin
    Nikita Chursin

    ๐Ÿ› Niklas Baudy
    Niklas Baudy

    ๐Ÿ› - Nikolas Havrikov
    Nikolas Havrikov

    ๐Ÿ› + Nikolas Havrikov
    Nikolas Havrikov

    ๐Ÿ› Nilesh Virkar
    Nilesh Virkar

    ๐Ÿ› Nimit Patel
    Nimit Patel

    ๐Ÿ› Niranjan Harpale
    Niranjan Harpale

    ๐Ÿ› Nirvik Patel
    Nirvik Patel

    ๐Ÿ’ป Noah Sussman
    Noah Sussman

    ๐Ÿ› Noah0120
    Noah0120

    ๐Ÿ› - Noam Tamim
    Noam Tamim

    ๐Ÿ› + Noam Tamim
    Noam Tamim

    ๐Ÿ› Noel Grandin
    Noel Grandin

    ๐Ÿ› Olaf Haalstra
    Olaf Haalstra

    ๐Ÿ› Oleg Andreych
    Oleg Andreych

    ๐Ÿ’ป ๐Ÿ› Oleg Pavlenko
    Oleg Pavlenko

    ๐Ÿ› Oleksii Dykov
    Oleksii Dykov

    ๐Ÿ’ป ๐Ÿ› Oliver Eikemeier
    Oliver Eikemeier

    ๐Ÿ› - Oliver Siegmar
    Oliver Siegmar

    ๐Ÿ’ต + Oliver Siegmar
    Oliver Siegmar

    ๐Ÿ’ต Olivier Parent
    Olivier Parent

    ๐Ÿ’ป ๐Ÿ› Ollie Abbey
    Ollie Abbey

    ๐Ÿ’ป ๐Ÿ› Ondrej Kratochvil
    Ondrej Kratochvil

    ๐Ÿ› OverDrone
    OverDrone

    ๐Ÿ› Ozan Gulle
    Ozan Gulle

    ๐Ÿ’ป ๐Ÿ› PUNEET JAIN
    PUNEET JAIN

    ๐Ÿ› - Parbati Bose
    Parbati Bose

    ๐Ÿ› + Parbati Bose
    Parbati Bose

    ๐Ÿ› Paul Berg
    Paul Berg

    ๐Ÿ› Paul Guyot
    Paul Guyot

    ๐Ÿ’ป Pavel Bludov
    Pavel Bludov

    ๐Ÿ› Pavel Miฤka
    Pavel Miฤka

    ๐Ÿ› Pedro Nuno Santos
    Pedro Nuno Santos

    ๐Ÿ› Pedro Rijo
    Pedro Rijo

    ๐Ÿ› - Pelisse Romain
    Pelisse Romain

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› + Pelisse Romain
    Pelisse Romain

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Per Abich
    Per Abich

    ๐Ÿ’ป Pete Davids
    Pete Davids

    ๐Ÿ› Peter Bruin
    Peter Bruin

    ๐Ÿ› Peter Chittum
    Peter Chittum

    ๐Ÿ’ป ๐Ÿ› Peter Cudmore
    Peter Cudmore

    ๐Ÿ› Peter Kasson
    Peter Kasson

    ๐Ÿ› - Peter Kofler
    Peter Kofler

    ๐Ÿ› + Peter Kofler
    Peter Kofler

    ๐Ÿ› Peter Paul Bakker
    Peter Paul Bakker

    ๐Ÿ’ป Peter Rader
    Peter Rader

    ๐Ÿ› Pham Hai Trung
    Pham Hai Trung

    ๐Ÿ› Philip Graf
    Philip Graf

    ๐Ÿ’ป ๐Ÿ› Philip Hachey
    Philip Hachey

    ๐Ÿ› Philippe Ozil
    Philippe Ozil

    ๐Ÿ› - Phinehas Artemix
    Phinehas Artemix

    ๐Ÿ› + Phinehas Artemix
    Phinehas Artemix

    ๐Ÿ› Phokham Nonava
    Phokham Nonava

    ๐Ÿ› Pim van der Loos
    Pim van der Loos

    ๐Ÿ’ป โš ๏ธ Piotr Szymaล„ski
    Piotr Szymaล„ski

    ๐Ÿ› Piotrek ลปygieล‚o
    Piotrek ลปygieล‚o

    ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– Pranay Jaiswal
    Pranay Jaiswal

    ๐Ÿ› Prasad Kamath
    Prasad Kamath

    ๐Ÿ› - Prasanna
    Prasanna

    ๐Ÿ› + Prasanna
    Prasanna

    ๐Ÿ› Presh-AR
    Presh-AR

    ๐Ÿ› Puneet1726
    Puneet1726

    ๐Ÿ› RBRi
    RBRi

    ๐Ÿ› Rafael Cortรชs
    Rafael Cortรชs

    ๐Ÿ› RaheemShaik999
    RaheemShaik999

    ๐Ÿ› RajeshR
    RajeshR

    ๐Ÿ’ป ๐Ÿ› - Ramachandra Mohan
    Ramachandra Mohan

    ๐Ÿ› + Ramachandra Mohan
    Ramachandra Mohan

    ๐Ÿ› Ramel0921
    Ramel0921

    ๐Ÿ› Raquel Pau
    Raquel Pau

    ๐Ÿ› Ravikiran Janardhana
    Ravikiran Janardhana

    ๐Ÿ› Reda Benhemmouche
    Reda Benhemmouche

    ๐Ÿ› Reinhard Schiedermeier
    Reinhard Schiedermeier

    ๐Ÿ› Renato Oliveira
    Renato Oliveira

    ๐Ÿ’ป ๐Ÿ› - Rich DiCroce
    Rich DiCroce

    ๐Ÿ› + Rich DiCroce
    Rich DiCroce

    ๐Ÿ› Richard Corfield
    Richard Corfield

    ๐Ÿ’ป Richard Corfield
    Richard Corfield

    ๐Ÿ› ๐Ÿ’ป Riot R1cket
    Riot R1cket

    ๐Ÿ› Rishabh Jain
    Rishabh Jain

    ๐Ÿ› RishabhDeep Singh
    RishabhDeep Singh

    ๐Ÿ› Rob Baillie
    Rob Baillie

    ๐Ÿ› - Robbie Martinus
    Robbie Martinus

    ๐Ÿ’ป ๐Ÿ› + Robbie Martinus
    Robbie Martinus

    ๐Ÿ’ป ๐Ÿ› Robert Henry
    Robert Henry

    ๐Ÿ› Robert Mihaly
    Robert Mihaly

    ๐Ÿ› Robert Painsi
    Robert Painsi

    ๐Ÿ› Robert Russell
    Robert Russell

    ๐Ÿ› Robert Sรถsemann
    Robert Sรถsemann

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ› Robert Whitebit
    Robert Whitebit

    ๐Ÿ› - Robin Richtsfeld
    Robin Richtsfeld

    ๐Ÿ› + Robin Richtsfeld
    Robin Richtsfeld

    ๐Ÿ› Robin Stocker
    Robin Stocker

    ๐Ÿ’ป ๐Ÿ› Robin Wils
    Robin Wils

    ๐Ÿ› RochusOest
    RochusOest

    ๐Ÿ› Rodolfo Noviski
    Rodolfo Noviski

    ๐Ÿ› Rodrigo Casara
    Rodrigo Casara

    ๐Ÿ› Rodrigo Fernandes
    Rodrigo Fernandes

    ๐Ÿ› - Roman Salvador
    Roman Salvador

    ๐Ÿ’ป ๐Ÿ› + Roman Salvador
    Roman Salvador

    ๐Ÿ’ป ๐Ÿ› Ronald Blaschke
    Ronald Blaschke

    ๐Ÿ› Rรณbert Papp
    Rรณbert Papp

    ๐Ÿ› Saikat Sengupta
    Saikat Sengupta

    ๐Ÿ› Saksham Handu
    Saksham Handu

    ๐Ÿ› Saladoc
    Saladoc

    ๐Ÿ› Salesforce Bob Lightning
    Salesforce Bob Lightning

    ๐Ÿ› - Sam Carlberg
    Sam Carlberg

    ๐Ÿ› + Sam Carlberg
    Sam Carlberg

    ๐Ÿ› Sascha Riemer
    Sascha Riemer

    ๐Ÿ› Sashko
    Sashko

    ๐Ÿ’ป Satoshi Kubo
    Satoshi Kubo

    ๐Ÿ› Scott Kennedy
    Scott Kennedy

    ๐Ÿ› Scott Wells
    Scott Wells

    ๐Ÿ› ๐Ÿ’ป Scrates1
    Scrates1

    ๐Ÿ› ๐Ÿ’ป - Scrsloota
    Scrsloota

    ๐Ÿ’ป + Scrsloota
    Scrsloota

    ๐Ÿ’ป Sebastian Bรถgl
    Sebastian Bรถgl

    ๐Ÿ› Sebastian Davids
    Sebastian Davids

    ๐Ÿ› Sebastian Schuberth
    Sebastian Schuberth

    ๐Ÿ› Sebastian Schwarz
    Sebastian Schwarz

    ๐Ÿ› Seren
    Seren

    ๐Ÿ› ๐Ÿ’ป Sergey Gorbaty
    Sergey Gorbaty

    ๐Ÿ› - Sergey Kozlov
    Sergey Kozlov

    ๐Ÿ› + Sergey Kozlov
    Sergey Kozlov

    ๐Ÿ› Sergey Yanzin
    Sergey Yanzin

    ๐Ÿ’ป ๐Ÿ› Seth Wilcox
    Seth Wilcox

    ๐Ÿ’ป Shai Bennathan
    Shai Bennathan

    ๐Ÿ› ๐Ÿ’ป Shubham
    Shubham

    ๐Ÿ’ป ๐Ÿ› Simon Abykov
    Simon Abykov

    ๐Ÿ’ป ๐Ÿ› Simon Xiao
    Simon Xiao

    ๐Ÿ› - Srinivasan Venkatachalam
    Srinivasan Venkatachalam

    ๐Ÿ› + Srinivasan Venkatachalam
    Srinivasan Venkatachalam

    ๐Ÿ› Stanislav Gromov
    Stanislav Gromov

    ๐Ÿ› Stanislav Myachenkov
    Stanislav Myachenkov

    ๐Ÿ’ป Stefan Birkner
    Stefan Birkner

    ๐Ÿ› Stefan Bohn
    Stefan Bohn

    ๐Ÿ› Stefan Endrullis
    Stefan Endrullis

    ๐Ÿ› Stefan Klรถss-Schuster
    Stefan Klรถss-Schuster

    ๐Ÿ› - Stefan Wolf
    Stefan Wolf

    ๐Ÿ› + Stefan Wolf
    Stefan Wolf

    ๐Ÿ› Stephan H. Wissel
    Stephan H. Wissel

    ๐Ÿ› Stephen
    Stephen

    ๐Ÿ› Stephen Carter
    Stephen Carter

    ๐Ÿ› Stephen Friedrich
    Stephen Friedrich

    ๐Ÿ› Steve Babula
    Steve Babula

    ๐Ÿ’ป Steven Stearns
    Steven Stearns

    ๐Ÿ› ๐Ÿ’ป - Stexxe
    Stexxe

    ๐Ÿ› + Stexxe
    Stexxe

    ๐Ÿ› Stian Lรฅgstad
    Stian Lรฅgstad

    ๐Ÿ› StuartClayton5
    StuartClayton5

    ๐Ÿ› Supun Arunoda
    Supun Arunoda

    ๐Ÿ› Suren Abrahamyan
    Suren Abrahamyan

    ๐Ÿ› Suvashri
    Suvashri

    ๐Ÿ“– SwatiBGupta1110
    SwatiBGupta1110

    ๐Ÿ› - SyedThoufich
    SyedThoufich

    ๐Ÿ› + SyedThoufich
    SyedThoufich

    ๐Ÿ› Szymon Sasin
    Szymon Sasin

    ๐Ÿ› T-chuangxin
    T-chuangxin

    ๐Ÿ› TERAI Atsuhiro
    TERAI Atsuhiro

    ๐Ÿ› TIOBE Software
    TIOBE Software

    ๐Ÿ’ป ๐Ÿ› Tarush Singh
    Tarush Singh

    ๐Ÿ’ป Taylor Smock
    Taylor Smock

    ๐Ÿ› - Techeira Damiรกn
    Techeira Damiรกn

    ๐Ÿ’ป ๐Ÿ› + Techeira Damiรกn
    Techeira Damiรกn

    ๐Ÿ’ป ๐Ÿ› Ted Husted
    Ted Husted

    ๐Ÿ› TehBakker
    TehBakker

    ๐Ÿ› The Gitter Badger
    The Gitter Badger

    ๐Ÿ› Theodoor
    Theodoor

    ๐Ÿ› Thiago Henrique Hรผpner
    Thiago Henrique Hรผpner

    ๐Ÿ› Thibault Meyer
    Thibault Meyer

    ๐Ÿ› - Thomas Gรผttler
    Thomas Gรผttler

    ๐Ÿ› + Thomas Gรผttler
    Thomas Gรผttler

    ๐Ÿ› Thomas Jones-Low
    Thomas Jones-Low

    ๐Ÿ› Thomas Smith
    Thomas Smith

    ๐Ÿ’ป ๐Ÿ› ThrawnCA
    ThrawnCA

    ๐Ÿ› Thu Vo
    Thu Vo

    ๐Ÿ› Thunderforge
    Thunderforge

    ๐Ÿ’ป ๐Ÿ› Tim van der Lippe
    Tim van der Lippe

    ๐Ÿ› - Tobias Weimer
    Tobias Weimer

    ๐Ÿ’ป ๐Ÿ› + Tobias Weimer
    Tobias Weimer

    ๐Ÿ’ป ๐Ÿ› Tom Copeland
    Tom Copeland

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– Tom Daly
    Tom Daly

    ๐Ÿ› Tomas
    Tomas

    ๐Ÿ› Tomer Figenblat
    Tomer Figenblat

    ๐Ÿ› Tomi De Lucca
    Tomi De Lucca

    ๐Ÿ’ป ๐Ÿ› Tony
    Tony

    ๐Ÿ“– - Torsten Kleiber
    Torsten Kleiber

    ๐Ÿ› + Torsten Kleiber
    Torsten Kleiber

    ๐Ÿ› TrackerSB
    TrackerSB

    ๐Ÿ› Tyson Stewart
    Tyson Stewart

    ๐Ÿ› Ullrich Hafner
    Ullrich Hafner

    ๐Ÿ› Utku Cuhadaroglu
    Utku Cuhadaroglu

    ๐Ÿ’ป ๐Ÿ› Valentin Brandl
    Valentin Brandl

    ๐Ÿ› Valeria
    Valeria

    ๐Ÿ› - Valery Yatsynovich
    Valery Yatsynovich

    ๐Ÿ“– + Valery Yatsynovich
    Valery Yatsynovich

    ๐Ÿ“– Vasily Anisimov
    Vasily Anisimov

    ๐Ÿ› Vedant Chokshi
    Vedant Chokshi

    ๐Ÿ› Vibhor Goyal
    Vibhor Goyal

    ๐Ÿ› Vickenty Fesunov
    Vickenty Fesunov

    ๐Ÿ› Victor Noรซl
    Victor Noรซl

    ๐Ÿ› Vincent Galloy
    Vincent Galloy

    ๐Ÿ’ป - Vincent HUYNH
    Vincent HUYNH

    ๐Ÿ› + Vincent HUYNH
    Vincent HUYNH

    ๐Ÿ› Vincent Maurin
    Vincent Maurin

    ๐Ÿ› Vincent Privat
    Vincent Privat

    ๐Ÿ› Vishhwas
    Vishhwas

    ๐Ÿ› Vishv_Android
    Vishv_Android

    ๐Ÿ› Vitaly
    Vitaly

    ๐Ÿ› Vitaly Polonetsky
    Vitaly Polonetsky

    ๐Ÿ› - Vojtech Polivka
    Vojtech Polivka

    ๐Ÿ› + Vojtech Polivka
    Vojtech Polivka

    ๐Ÿ› Vsevolod Zholobov
    Vsevolod Zholobov

    ๐Ÿ› Vyom Yadav
    Vyom Yadav

    ๐Ÿ’ป Wang Shidong
    Wang Shidong

    ๐Ÿ› Waqas Ahmed
    Waqas Ahmed

    ๐Ÿ› Wayne J. Earl
    Wayne J. Earl

    ๐Ÿ› Wchenghui
    Wchenghui

    ๐Ÿ› - Wener
    Wener

    ๐Ÿ’ป + Wener
    Wener

    ๐Ÿ’ป Will Winder
    Will Winder

    ๐Ÿ› Willem A. Hajenius
    Willem A. Hajenius

    ๐Ÿ’ป William Brockhus
    William Brockhus

    ๐Ÿ’ป ๐Ÿ› Wilson Kurniawan
    Wilson Kurniawan

    ๐Ÿ› Wim Deblauwe
    Wim Deblauwe

    ๐Ÿ› Woongsik Choi
    Woongsik Choi

    ๐Ÿ› - XenoAmess
    XenoAmess

    ๐Ÿ’ป ๐Ÿ› + XenoAmess
    XenoAmess

    ๐Ÿ’ป ๐Ÿ› Yang
    Yang

    ๐Ÿ’ป YaroslavTER
    YaroslavTER

    ๐Ÿ› Yasar Shaikh
    Yasar Shaikh

    ๐Ÿ’ป Young Chan
    Young Chan

    ๐Ÿ’ป ๐Ÿ› YuJin Kim
    YuJin Kim

    ๐Ÿ› Yuri Dolzhenko
    Yuri Dolzhenko

    ๐Ÿ› - Yurii Dubinka
    Yurii Dubinka

    ๐Ÿ› + Yurii Dubinka
    Yurii Dubinka

    ๐Ÿ› Zoltan Farkas
    Zoltan Farkas

    ๐Ÿ› Zustin
    Zustin

    ๐Ÿ› aaronhurst-google
    aaronhurst-google

    ๐Ÿ› ๐Ÿ’ป alexmodis
    alexmodis

    ๐Ÿ› andreoss
    andreoss

    ๐Ÿ› andrey81inmd
    andrey81inmd

    ๐Ÿ’ป ๐Ÿ› - anicoara
    anicoara

    ๐Ÿ› + anicoara
    anicoara

    ๐Ÿ› arunprasathav
    arunprasathav

    ๐Ÿ› asiercamara
    asiercamara

    ๐Ÿ› astillich-igniti
    astillich-igniti

    ๐Ÿ’ป avesolovksyy
    avesolovksyy

    ๐Ÿ› avishvat
    avishvat

    ๐Ÿ› avivmu
    avivmu

    ๐Ÿ› - axelbarfod1
    axelbarfod1

    ๐Ÿ› + axelbarfod1
    axelbarfod1

    ๐Ÿ› b-3-n
    b-3-n

    ๐Ÿ› balbhadra9
    balbhadra9

    ๐Ÿ› base23de
    base23de

    ๐Ÿ› bergander
    bergander

    ๐Ÿ› ๐Ÿ’ป berkam
    berkam

    ๐Ÿ’ป ๐Ÿ› breizh31
    breizh31

    ๐Ÿ› - caesarkim
    caesarkim

    ๐Ÿ› + caesarkim
    caesarkim

    ๐Ÿ› carolyujing
    carolyujing

    ๐Ÿ› cbfiddle
    cbfiddle

    ๐Ÿ› cesares-basilico
    cesares-basilico

    ๐Ÿ› chrite
    chrite

    ๐Ÿ› ciufudean
    ciufudean

    ๐Ÿ“– cobratbq
    cobratbq

    ๐Ÿ› - coladict
    coladict

    ๐Ÿ› + coladict
    coladict

    ๐Ÿ› cosmoJFH
    cosmoJFH

    ๐Ÿ› cristalp
    cristalp

    ๐Ÿ› crunsk
    crunsk

    ๐Ÿ› cwholmes
    cwholmes

    ๐Ÿ› cyberjj999
    cyberjj999

    ๐Ÿ› cyw3
    cyw3

    ๐Ÿ› ๐Ÿ“– - d1ss0nanz
    d1ss0nanz

    ๐Ÿ› + d1ss0nanz
    d1ss0nanz

    ๐Ÿ› dague1
    dague1

    ๐Ÿ“– dalizi007
    dalizi007

    ๐Ÿ’ป danbrycefairsailcom
    danbrycefairsailcom

    ๐Ÿ› dariansanity
    dariansanity

    ๐Ÿ› darrenmiliband
    darrenmiliband

    ๐Ÿ› davidburstrom
    davidburstrom

    ๐Ÿ› - dbirkman-paloalto
    dbirkman-paloalto

    ๐Ÿ› + dbirkman-paloalto
    dbirkman-paloalto

    ๐Ÿ› deepak-patra
    deepak-patra

    ๐Ÿ› dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› dinesh150
    dinesh150

    ๐Ÿ› diziaq
    diziaq

    ๐Ÿ› dreaminpast123
    dreaminpast123

    ๐Ÿ› duanyanan
    duanyanan

    ๐Ÿ› - dutt-sanjay
    dutt-sanjay

    ๐Ÿ› + dutt-sanjay
    dutt-sanjay

    ๐Ÿ› duursma
    duursma

    ๐Ÿ’ป dylanleung
    dylanleung

    ๐Ÿ› dzeigler
    dzeigler

    ๐Ÿ› eant60
    eant60

    ๐Ÿ› ekkirala
    ekkirala

    ๐Ÿ› emersonmoura
    emersonmoura

    ๐Ÿ› - emouty
    emouty

    ๐Ÿ’ป ๐Ÿ› + emouty
    emouty

    ๐Ÿ’ป ๐Ÿ› eugenepugach
    eugenepugach

    ๐Ÿ› fairy
    fairy

    ๐Ÿ› filiprafalowicz
    filiprafalowicz

    ๐Ÿ’ป flxbl-io
    flxbl-io

    ๐Ÿ’ต foxmason
    foxmason

    ๐Ÿ› frankegabor
    frankegabor

    ๐Ÿ› - frankl
    frankl

    ๐Ÿ› + frankl
    frankl

    ๐Ÿ› freafrea
    freafrea

    ๐Ÿ› fsapatin
    fsapatin

    ๐Ÿ› gearsethenry
    gearsethenry

    ๐Ÿ› gracia19
    gracia19

    ๐Ÿ› gudzpoz
    gudzpoz

    ๐Ÿ› guo fei
    guo fei

    ๐Ÿ› - gurmsc5
    gurmsc5

    ๐Ÿ› + gurmsc5
    gurmsc5

    ๐Ÿ› gwilymatgearset
    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ› haigsn
    haigsn

    ๐Ÿ› hemanshu070
    hemanshu070

    ๐Ÿ› henrik242
    henrik242

    ๐Ÿ› hongpuwu
    hongpuwu

    ๐Ÿ› hvbtup
    hvbtup

    ๐Ÿ’ป ๐Ÿ› - igniti GmbH
    igniti GmbH

    ๐Ÿ› + igniti GmbH
    igniti GmbH

    ๐Ÿ› ilovezfs
    ilovezfs

    ๐Ÿ› imax-erik
    imax-erik

    ๐Ÿ› itaigilo
    itaigilo

    ๐Ÿ› jakivey32
    jakivey32

    ๐Ÿ› jbennett2091
    jbennett2091

    ๐Ÿ› jcamerin
    jcamerin

    ๐Ÿ› - jkeener1
    jkeener1

    ๐Ÿ› + jkeener1
    jkeener1

    ๐Ÿ› jmetertea
    jmetertea

    ๐Ÿ› johnra2
    johnra2

    ๐Ÿ’ป johnzhao9
    johnzhao9

    ๐Ÿ› josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ› kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ› karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“– - karwer
    karwer

    ๐Ÿ› + karwer
    karwer

    ๐Ÿ› kaulonline
    kaulonline

    ๐Ÿ› kdaemonv
    kdaemonv

    ๐Ÿ› kdebski85
    kdebski85

    ๐Ÿ› ๐Ÿ’ป kenji21
    kenji21

    ๐Ÿ’ป ๐Ÿ› kfranic
    kfranic

    ๐Ÿ› khalidkh
    khalidkh

    ๐Ÿ› - koalalam
    koalalam

    ๐Ÿ› + koalalam
    koalalam

    ๐Ÿ› krzyk
    krzyk

    ๐Ÿ› lasselindqvist
    lasselindqvist

    ๐Ÿ› lgemeinhardt
    lgemeinhardt

    ๐Ÿ› lihuaib
    lihuaib

    ๐Ÿ› liqingjun123
    liqingjun123

    ๐Ÿ› lonelyma1021
    lonelyma1021

    ๐Ÿ› - lpeddy
    lpeddy

    ๐Ÿ› + lpeddy
    lpeddy

    ๐Ÿ› lujiefsi
    lujiefsi

    ๐Ÿ’ป lukelukes
    lukelukes

    ๐Ÿ’ป lyriccoder
    lyriccoder

    ๐Ÿ› marcelmore
    marcelmore

    ๐Ÿ› matchbox
    matchbox

    ๐Ÿ› matthiaskraaz
    matthiaskraaz

    ๐Ÿ› - meandonlyme
    meandonlyme

    ๐Ÿ› + meandonlyme
    meandonlyme

    ๐Ÿ› mikesive
    mikesive

    ๐Ÿ› milossesic
    milossesic

    ๐Ÿ› mluckam
    mluckam

    ๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
    mohan-chinnappan-n

    ๐Ÿ’ป mriddell95
    mriddell95

    ๐Ÿ› mrlzh
    mrlzh

    ๐Ÿ› - msloan
    msloan

    ๐Ÿ› + msloan
    msloan

    ๐Ÿ› mucharlaravalika
    mucharlaravalika

    ๐Ÿ› mvenneman
    mvenneman

    ๐Ÿ› nareshl119
    nareshl119

    ๐Ÿ› nicolas-harraudeau-sonarsource
    nicolas-harraudeau-sonarsource

    ๐Ÿ› noerremark
    noerremark

    ๐Ÿ› novsirion
    novsirion

    ๐Ÿ› - nwcm
    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป + nwcm
    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
    oggboy

    ๐Ÿ› oinume
    oinume

    ๐Ÿ› orimarko
    orimarko

    ๐Ÿ’ป ๐Ÿ› pablogomez2197
    pablogomez2197

    ๐Ÿ› pacvz
    pacvz

    ๐Ÿ’ป pallavi agarwal
    pallavi agarwal

    ๐Ÿ› - parksungrin
    parksungrin

    ๐Ÿ› + parksungrin
    parksungrin

    ๐Ÿ› patpatpat123
    patpatpat123

    ๐Ÿ› patriksevallius
    patriksevallius

    ๐Ÿ› pbrajesh1
    pbrajesh1

    ๐Ÿ› phoenix384
    phoenix384

    ๐Ÿ› piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป plan3d
    plan3d

    ๐Ÿ› - poojasix
    poojasix

    ๐Ÿ› + poojasix
    poojasix

    ๐Ÿ› prabhushrikant
    prabhushrikant

    ๐Ÿ› pujitha8783
    pujitha8783

    ๐Ÿ› r-r-a-j
    r-r-a-j

    ๐Ÿ› raghujayjunk
    raghujayjunk

    ๐Ÿ› rajeshveera
    rajeshveera

    ๐Ÿ› rajeswarreddy88
    rajeswarreddy88

    ๐Ÿ› - recdevs
    recdevs

    ๐Ÿ› + recdevs
    recdevs

    ๐Ÿ› reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ› rijkt
    rijkt

    ๐Ÿ› rillig-tk
    rillig-tk

    ๐Ÿ› rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ› rnveach
    rnveach

    ๐Ÿ› rxmicro
    rxmicro

    ๐Ÿ› - ryan-gustafson
    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ› + ryan-gustafson
    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ› sabi0
    sabi0

    ๐Ÿ› scais
    scais

    ๐Ÿ› schosin
    schosin

    ๐Ÿ› screamingfrog
    screamingfrog

    ๐Ÿ’ต sebbASF
    sebbASF

    ๐Ÿ› sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป - shilko2013
    shilko2013

    ๐Ÿ› + shilko2013
    shilko2013

    ๐Ÿ› shiomiyan
    shiomiyan

    ๐Ÿ“– simeonKondr
    simeonKondr

    ๐Ÿ› snajberk
    snajberk

    ๐Ÿ› sniperrifle2004
    sniperrifle2004

    ๐Ÿ› snuyanzin
    snuyanzin

    ๐Ÿ› ๐Ÿ’ป soloturn
    soloturn

    ๐Ÿ› - soyodream
    soyodream

    ๐Ÿ› + soyodream
    soyodream

    ๐Ÿ› sratz
    sratz

    ๐Ÿ› stonio
    stonio

    ๐Ÿ› sturton
    sturton

    ๐Ÿ’ป ๐Ÿ› sudharmohan
    sudharmohan

    ๐Ÿ› suruchidawar
    suruchidawar

    ๐Ÿ› svenfinitiv
    svenfinitiv

    ๐Ÿ› - szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป + szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป tashiscool
    tashiscool

    ๐Ÿ› test-git-hook
    test-git-hook

    ๐Ÿ› testation21
    testation21

    ๐Ÿ’ป ๐Ÿ› thanosa
    thanosa

    ๐Ÿ› tiandiyixian
    tiandiyixian

    ๐Ÿ› tobwoerk
    tobwoerk

    ๐Ÿ› - tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป + tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป trentchilders
    trentchilders

    ๐Ÿ› triandicAnt
    triandicAnt

    ๐Ÿ› trishul14
    trishul14

    ๐Ÿ› tsui
    tsui

    ๐Ÿ› wangzitom12306
    wangzitom12306

    ๐Ÿ› winhkey
    winhkey

    ๐Ÿ› - witherspore
    witherspore

    ๐Ÿ› + witherspore
    witherspore

    ๐Ÿ› wjljack
    wjljack

    ๐Ÿ› wuchiuwong
    wuchiuwong

    ๐Ÿ› xingsong
    xingsong

    ๐Ÿ› xioayuge
    xioayuge

    ๐Ÿ› xnYi9wRezm
    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ› xuanuy
    xuanuy

    ๐Ÿ› - xyf0921
    xyf0921

    ๐Ÿ› + xyf0921
    xyf0921

    ๐Ÿ› yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› yasuharu-sato
    yasuharu-sato

    ๐Ÿ› zenglian
    zenglian

    ๐Ÿ› zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› zh3ng
    zh3ng

    ๐Ÿ› zt_soft
    zt_soft

    ๐Ÿ› - ztt79
    ztt79

    ๐Ÿ› + ztt79
    ztt79

    ๐Ÿ› zzzzfeng
    zzzzfeng

    ๐Ÿ› รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› ไปป่ดตๆฐ
    ไปป่ดตๆฐ

    ๐Ÿ› From f0277d7b330d649a27db32c95134e8686dc07886 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 28 Nov 2024 10:26:20 +0100 Subject: [PATCH 0319/1962] [java] UnnecessaryImport - update test case name (#5315) --- .../pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml index ec6badd2bf2..89f502d6b9d 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml @@ -1323,7 +1323,7 @@ public class Foo { - imports used in markdown javadoc comment (since java 23, JEP 467) + #5315 [java] UnnecessaryImport false positive for on-demand imports 0 Date: Thu, 28 Nov 2024 10:27:08 +0100 Subject: [PATCH 0320/1962] [doc] Update release notes (#5315, #5372) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 55e1b748ae6..9e8889e46bc 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -122,6 +122,7 @@ This is a {{ site.pmd.release_type }} release. * [#5354](https://github.com/pmd/pmd/pull/5354): \[apex] Updated the docs for UnusedMethod as per discussion #5200 - [samc-gearset](https://github.com/sam-gearset) (@sam-gearset) * [#5370](https://github.com/pmd/pmd/pull/5370): \[java] Fix #5214 - LambdaCanBeMethodReference issue with method of enclosing class - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5371](https://github.com/pmd/pmd/pull/5371): \[doc] Improve docs on adding Antlr languages - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5372](https://github.com/pmd/pmd/pull/5372): \[java] Fix #5315 - UnusedImport FP with import on demand - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) ### ๐Ÿ“ฆ Dependency updates From bd280baa721ece9f983fd0af8e0ab616ca4292f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 28 Nov 2024 11:55:34 +0100 Subject: [PATCH 0321/1962] [java] Fix #4763 - wrong message for SimplifyBooleanReturns Curiously existing tests had correct comments but wrong test assertions... --- .../design/SimplifyBooleanReturnsRule.java | 4 +-- .../design/xml/SimplifyBooleanReturns.xml | 32 +++++++++++++++++-- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SimplifyBooleanReturnsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SimplifyBooleanReturnsRule.java index 300fa40cffa..dfd0521aba7 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SimplifyBooleanReturnsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SimplifyBooleanReturnsRule.java @@ -139,9 +139,9 @@ && doesNotNeedNewParensUnderInfix(branch, op)) { if (thenTrue) { return "return {condition} || {elseBranch};"; } else if (thenFalse) { - return "return !{condition} || {elseBranch};"; + return "return !{condition} && {elseBranch};"; } else if (elseTrue) { - return "return !{condition} && {thenBranch};"; + return "return !{condition} || {thenBranch};"; } else { return "return {condition} && {thenBranch};"; } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SimplifyBooleanReturns.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SimplifyBooleanReturns.xml index 9ef56b3eaa6..ca5d5892fee 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SimplifyBooleanReturns.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SimplifyBooleanReturns.xml @@ -185,8 +185,8 @@ public class SimplifyBooleanReturns { 2 3,8 - This if statement can be replaced by `return !{condition} && {thenBranch};` - This if statement can be replaced by `return !{condition} && {thenBranch};` + This if statement can be replaced by `return !{condition} || {thenBranch};` + This if statement can be replaced by `return !{condition} || {thenBranch};` 1 6 - This if statement can be replaced by `return !{condition} && {thenBranch};` + This if statement can be replaced by `return !{condition} || {thenBranch};` + + [java] SimplifyBooleanReturns - wrong suggested solution #4763 + 2 + + This if statement can be replaced by `return !{condition} && {elseBranch};` + This if statement can be replaced by `return !{condition} && {elseBranch};` + + + From e1e5a14bae62e008600650bd952ac6d49e67cc26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 28 Nov 2024 12:04:37 +0100 Subject: [PATCH 0322/1962] [java] Fix #5070 - confusing argument to varargs method FP when types are unknown --- .../ConfusingArgumentToVarargsMethodRule.java | 4 +++- .../xml/ConfusingArgumentToVarargsMethod.xml | 20 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConfusingArgumentToVarargsMethodRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConfusingArgumentToVarargsMethodRule.java index 0bd64ef2590..82b3ec3c06e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConfusingArgumentToVarargsMethodRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConfusingArgumentToVarargsMethodRule.java @@ -14,6 +14,7 @@ import net.sourceforge.pmd.lang.java.types.JArrayType; import net.sourceforge.pmd.lang.java.types.JTypeMirror; import net.sourceforge.pmd.lang.java.types.OverloadSelectionResult; +import net.sourceforge.pmd.lang.java.types.TypeOps; import net.sourceforge.pmd.lang.java.types.TypePrettyPrint; public class ConfusingArgumentToVarargsMethodRule extends AbstractJavaRulechainRule { @@ -45,7 +46,8 @@ public Object visit(ASTArgumentList argList, Object data) { ASTExpression varargsArg = argList.getLastChild(); assert varargsArg != null; if (varargsArg.getTypeMirror().isSubtypeOf(expectedComponent) - && !varargsArg.getTypeMirror().equals(lastFormal)) { + && !varargsArg.getTypeMirror().equals(lastFormal) + && !TypeOps.isSpecialUnresolved(varargsArg.getTypeMirror())) { // confusing String message; diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ConfusingArgumentToVarargsMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ConfusingArgumentToVarargsMethod.xml index 81d3545ff1e..4de300c984c 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ConfusingArgumentToVarargsMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ConfusingArgumentToVarargsMethod.xml @@ -106,4 +106,24 @@ ]]> + + + Types of args are unresolved + 1 + 7 + + + From c7014fc455cebbea3e8243f29347ce028d9b9cd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 28 Nov 2024 14:46:14 +0100 Subject: [PATCH 0323/1962] Add new test case for (*unknown*)[] --- .../ConfusingArgumentToVarargsMethodRule.java | 2 +- .../sourceforge/pmd/lang/java/types/TypeOps.java | 10 ++++++++++ .../xml/ConfusingArgumentToVarargsMethod.xml | 16 ++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConfusingArgumentToVarargsMethodRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConfusingArgumentToVarargsMethodRule.java index 82b3ec3c06e..37b8d565b6f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConfusingArgumentToVarargsMethodRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConfusingArgumentToVarargsMethodRule.java @@ -47,7 +47,7 @@ public Object visit(ASTArgumentList argList, Object data) { assert varargsArg != null; if (varargsArg.getTypeMirror().isSubtypeOf(expectedComponent) && !varargsArg.getTypeMirror().equals(lastFormal) - && !TypeOps.isSpecialUnresolved(varargsArg.getTypeMirror())) { + && !TypeOps.isSpecialUnresolvedOrArray(varargsArg.getTypeMirror())) { // confusing String message; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java index b5f39166e4e..49bc9f3d636 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java @@ -2110,6 +2110,16 @@ public static boolean isUnresolvedOrNull(@Nullable JTypeMirror t) { return t == null || isUnresolved(t); } + /** + * Return true if the type is null, (*unknown*), (*error*), or an array + * of unknown or error type. + */ + public static boolean isSpecialUnresolvedOrArray(@Nullable JTypeMirror t) { + return t == null + || isSpecialUnresolved(t) + || t instanceof JArrayType && isSpecialUnresolved(((JArrayType) t).getElementType()); + } + public static @Nullable JTypeMirror getArrayComponent(@Nullable JTypeMirror t) { return t instanceof JArrayType ? ((JArrayType) t).getComponentType() : null; diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ConfusingArgumentToVarargsMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ConfusingArgumentToVarargsMethod.xml index 4de300c984c..408261234ec 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ConfusingArgumentToVarargsMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ConfusingArgumentToVarargsMethod.xml @@ -126,4 +126,20 @@ ]]> + + + Types of args is array of unknown + 0 + T[] arr(T[] x) { return x; } + static void foo(Object... args) {} + } + ]]> + + From f7920e78e97e786c401a77cdc70b5f7822e71291 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 28 Nov 2024 15:28:22 +0100 Subject: [PATCH 0324/1962] Make behavior of isUnresolved in TypeOps more consistent wrt arrays. Make new methods that say in their name whether they treat array as unresolved or not. Both behaviors are desirable in different cases. --- .../codestyle/UseDiamondOperatorRule.java | 2 +- .../pmd/lang/java/types/TypeOps.java | 67 +++++++++++---- .../internal/infer/PhaseOverloadSet.java | 2 +- .../pmd/lang/java/types/TypeGenerationUtil.kt | 2 +- .../pmd/lang/java/types/TypeOpsTest.kt | 81 +++++++++++++++++++ 5 files changed, 134 insertions(+), 20 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseDiamondOperatorRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseDiamondOperatorRule.java index d73916d5805..fad61d36f8f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseDiamondOperatorRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseDiamondOperatorRule.java @@ -71,7 +71,7 @@ public Object visit(ASTConstructorCall ctorCall, Object data) { ASTTypeArguments targs = newTypeNode.getTypeArguments(); if (targs != null && targs.isDiamond() // if unresolved we can't know whether the class is generic or not - || TypeOps.isUnresolved(newType)) { + || TypeOps.hasUnresolvedSymbol(newType)) { return null; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java index 49bc9f3d636..40d86e04ba8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java @@ -634,7 +634,7 @@ Convertibility isConvertible(@NonNull JTypeMirror t, @NonNull JTypeMirror s, boo return isConvertible(t, lower); } // otherwise fallthrough - } else if (hasUnresolvedSymbol(t) && t instanceof JClassType) { + } else if (hasUnresolvedSymbol(t)) { // This also considers types with an unresolved symbol // subtypes of (nearly) anything. This allows them to // pass bound checks on type variables. @@ -1797,7 +1797,7 @@ public static Set mostSpecific(Collection se vLoop: for (JTypeMirror v : set) { for (JTypeMirror w : set) { - if (!w.equals(v) && !hasUnresolvedSymbol(w)) { + if (!w.equals(v) && !hasUnresolvedSymbolOrArray(w)) { Convertibility isConvertible = isConvertiblePure(w, v); if (isConvertible.bySubtyping() // This last case covers unchecked conversion. It is made antisymmetric by the @@ -2079,7 +2079,8 @@ public static boolean areRelated(@NonNull JTypeMirror t, JTypeMirror s) { /** * Returns true if the type is {@link TypeSystem#UNKNOWN}, - * {@link TypeSystem#ERROR}, or its symbol is unresolved. + * {@link TypeSystem#ERROR}, or a class type with unresolved + * symbol. * * @param t Non-null type * @@ -2089,38 +2090,70 @@ public static boolean isUnresolved(@NonNull JTypeMirror t) { return isSpecialUnresolved(t) || hasUnresolvedSymbol(t); } + /** + * Returns true if the type is {@link TypeSystem#UNKNOWN}, + * or {@link TypeSystem#ERROR}, or a class type with unresolved + * symbol, or an array of such types. + * + * @param t Non-null type + * + * @throws NullPointerException if the parameter is null + */ + public static boolean isUnresolvedOrArray(@NonNull JTypeMirror t) { + return isSpecialUnresolvedOrArray(t) || hasUnresolvedSymbolOrArray(t); + } + + /** + * Returns true if the type is {@link TypeSystem#UNKNOWN}, + * or {@link TypeSystem#ERROR}. + * + * @param t Non-null type + * + * @throws NullPointerException if the parameter is null + */ public static boolean isSpecialUnresolved(@NonNull JTypeMirror t) { TypeSystem ts = t.getTypeSystem(); return t == ts.UNKNOWN || t == ts.ERROR; } + /** + * Returns true if the type is {@link TypeSystem#UNKNOWN}, + * or {@link TypeSystem#ERROR}, or an array of such types. + * + * @param t Non-null type + * + * @throws NullPointerException if the parameter is null + */ + public static boolean isSpecialUnresolvedOrArray(@Nullable JTypeMirror t) { + return t == null + || isSpecialUnresolved(t) + || t instanceof JArrayType && isSpecialUnresolved(((JArrayType) t).getElementType()); + } + /** * Return true if the argument is a {@link JClassType} with - * {@linkplain JClassSymbol#isUnresolved() an unresolved symbol} or - * a {@link JArrayType} whose element type matches the first criterion. + * {@linkplain JClassSymbol#isUnresolved() an unresolved symbol}. */ public static boolean hasUnresolvedSymbol(@Nullable JTypeMirror t) { + return t instanceof JClassType && t.getSymbol().isUnresolved(); + } + + /** + * Return true if the argument is a {@link JClassType} with + * {@linkplain JClassSymbol#isUnresolved() an unresolved symbol}, + * or an array whose element type has an unresolved symbol. + */ + public static boolean hasUnresolvedSymbolOrArray(@Nullable JTypeMirror t) { if (!(t instanceof JClassType)) { return t instanceof JArrayType && hasUnresolvedSymbol(((JArrayType) t).getElementType()); } - return t.getSymbol() != null && t.getSymbol().isUnresolved(); + return hasUnresolvedSymbol(t); } public static boolean isUnresolvedOrNull(@Nullable JTypeMirror t) { return t == null || isUnresolved(t); } - /** - * Return true if the type is null, (*unknown*), (*error*), or an array - * of unknown or error type. - */ - public static boolean isSpecialUnresolvedOrArray(@Nullable JTypeMirror t) { - return t == null - || isSpecialUnresolved(t) - || t instanceof JArrayType && isSpecialUnresolved(((JArrayType) t).getElementType()); - } - - public static @Nullable JTypeMirror getArrayComponent(@Nullable JTypeMirror t) { return t instanceof JArrayType ? ((JArrayType) t).getComponentType() : null; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/PhaseOverloadSet.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/PhaseOverloadSet.java index 5a2763f0624..fcbc9234bba 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/PhaseOverloadSet.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/PhaseOverloadSet.java @@ -210,7 +210,7 @@ private boolean doInfer(JMethodSig m1, JMethodSig m2) { private @NonNull OptionalBool unresolvedTypeFallback(JTypeMirror si, JTypeMirror ti, ExprMirror argExpr) { JTypeMirror standalone = argExpr.getStandaloneType(); - if (standalone != null && TypeOps.isUnresolved(standalone)) { + if (TypeOps.hasUnresolvedSymbolOrArray(standalone)) { if (standalone.equals(si)) { return YES; } else if (standalone.equals(ti)) { diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TypeGenerationUtil.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TypeGenerationUtil.kt index 145be6f6b48..e67c8b69f8e 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TypeGenerationUtil.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TypeGenerationUtil.kt @@ -38,7 +38,7 @@ val TypeSystem.allTypesGen: Arb fun TypeSystem.subtypesArb() = Arb.pair(refTypeGen, refTypeGen) .filter { (t, s) -> t.isConvertibleTo(s).bySubtyping() } - .filter { (t, s) -> !TypeOps.hasUnresolvedSymbol(t) && !TypeOps.hasUnresolvedSymbol(s) } + .filter { (t, s) -> !TypeOps.hasUnresolvedSymbolOrArray(t) && !TypeOps.hasUnresolvedSymbolOrArray(s) } infix fun Boolean.implies(v: () -> Boolean): Boolean = !this || v() diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TypeOpsTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TypeOpsTest.kt index 421a778c4a0..1167087bd55 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TypeOpsTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TypeOpsTest.kt @@ -7,6 +7,7 @@ package net.sourceforge.pmd.lang.java.types import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.collections.shouldContainExactly import io.kotest.matchers.collections.shouldContainExactlyInAnyOrder +import io.kotest.matchers.shouldBe import io.kotest.property.Arb import io.kotest.property.arbitrary.shuffle import io.kotest.property.checkAll @@ -131,6 +132,86 @@ class Foo { methodId shouldHaveType barT[`?`] } } + + test("isSpecialUnresolved") { + val unresolved = ts.declaration(ts.createUnresolvedAsmSymbol("Unknown")) + TypeOps.isSpecialUnresolved(unresolved) shouldBe false + TypeOps.isSpecialUnresolved(unresolved.toArray()) shouldBe false + TypeOps.isSpecialUnresolved(unresolved.toArray(3)) shouldBe false + + for (ty in listOf(ts.UNKNOWN, ts.ERROR)) { + TypeOps.isSpecialUnresolved(ty) shouldBe true + TypeOps.isSpecialUnresolved(ty.toArray()) shouldBe false + TypeOps.isSpecialUnresolved(ty.toArray(3)) shouldBe false + } + } + + test("isSpecialUnresolvedOrArray") { + val unresolved = ts.declaration(ts.createUnresolvedAsmSymbol("Unknown")) + TypeOps.isSpecialUnresolvedOrArray(unresolved) shouldBe false + TypeOps.isSpecialUnresolvedOrArray(unresolved.toArray()) shouldBe false + TypeOps.isSpecialUnresolvedOrArray(unresolved.toArray(3)) shouldBe false + + for (ty in listOf(ts.UNKNOWN, ts.ERROR)) { + TypeOps.isSpecialUnresolvedOrArray(ty) shouldBe true + TypeOps.isSpecialUnresolvedOrArray(ty.toArray()) shouldBe true + TypeOps.isSpecialUnresolvedOrArray(ty.toArray(3)) shouldBe true + } + } + + test("hasUnresolvedSymbol") { + val unresolved = ts.declaration(ts.createUnresolvedAsmSymbol("Unknown")) + TypeOps.hasUnresolvedSymbol(unresolved) shouldBe true + TypeOps.hasUnresolvedSymbol(unresolved.toArray()) shouldBe false + TypeOps.hasUnresolvedSymbol(unresolved.toArray(3)) shouldBe false + + for (ty in listOf(ts.UNKNOWN, ts.ERROR)) { + TypeOps.hasUnresolvedSymbol(ty) shouldBe false + TypeOps.hasUnresolvedSymbol(ty.toArray()) shouldBe false + TypeOps.hasUnresolvedSymbol(ty.toArray(3)) shouldBe false + } + } + + + test("hasUnresolvedSymbolOrArray") { + val unresolved = ts.declaration(ts.createUnresolvedAsmSymbol("Unknown")) + TypeOps.hasUnresolvedSymbolOrArray(unresolved) shouldBe true + TypeOps.hasUnresolvedSymbolOrArray(unresolved.toArray()) shouldBe true + TypeOps.hasUnresolvedSymbolOrArray(unresolved.toArray(3)) shouldBe true + + for (ty in listOf(ts.UNKNOWN, ts.ERROR)) { + TypeOps.hasUnresolvedSymbolOrArray(ty) shouldBe false + TypeOps.hasUnresolvedSymbolOrArray(ty.toArray()) shouldBe false + TypeOps.hasUnresolvedSymbolOrArray(ty.toArray(3)) shouldBe false + } + } + + + test("isUnresolved") { + val unresolved = ts.declaration(ts.createUnresolvedAsmSymbol("Unknown")) + TypeOps.isUnresolved(unresolved) shouldBe true + TypeOps.isUnresolved(unresolved.toArray()) shouldBe false + TypeOps.isUnresolved(unresolved.toArray(3)) shouldBe false + + for (ty in listOf(ts.UNKNOWN, ts.ERROR)) { + TypeOps.isUnresolved(ty) shouldBe true + TypeOps.isUnresolved(ty.toArray()) shouldBe false + TypeOps.isUnresolved(ty.toArray(3)) shouldBe false + } + } + + test("isUnresolvedOrArray") { + val unresolved = ts.declaration(ts.createUnresolvedAsmSymbol("Unknown")) + TypeOps.isUnresolvedOrArray(unresolved) shouldBe true + TypeOps.isUnresolvedOrArray(unresolved.toArray()) shouldBe true + TypeOps.isUnresolvedOrArray(unresolved.toArray(3)) shouldBe true + + for (ty in listOf(ts.UNKNOWN, ts.ERROR)) { + TypeOps.isUnresolvedOrArray(ty) shouldBe true + TypeOps.isUnresolvedOrArray(ty.toArray()) shouldBe true + TypeOps.isUnresolvedOrArray(ty.toArray(3)) shouldBe true + } + } } } From 593b242648fee94491350cfc0e3d6d177bdc259b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 28 Nov 2024 18:48:37 +0100 Subject: [PATCH 0325/1962] [doc] Update release notes (#5300) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 2faf1cc3f86..0fbf4e2f23f 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -96,6 +96,7 @@ This is a {{ site.pmd.release_type }} release. * [#5286](https://github.com/pmd/pmd/pull/5286): \[ant] Formatter: avoid reflective access to determine console encoding - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5289](https://github.com/pmd/pmd/pull/5289): \[java] TooFewBranchesForSwitch - allow list of case constants - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5296](https://github.com/pmd/pmd/pull/5296): \[xml] Have pmd-xml Lexer in line with other antlr grammars - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5300](https://github.com/pmd/pmd/pull/5300): Add rule test cases for issues fixed with PMD 7.0.0 - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5303](https://github.com/pmd/pmd/pull/5303): \[apex] New Rule: Queueable Should Attach Finalizer - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) * [#5309](https://github.com/pmd/pmd/pull/5309): \[java] Fix #5293: Parse number of type parameters eagerly - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5310](https://github.com/pmd/pmd/pull/5310): \[java] Fix #5283 - inner class has public private modifiers - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) From ea32fbb6b4a7ce7514e30b2034b1b9436102c883 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 29 Nov 2024 09:09:42 +0100 Subject: [PATCH 0326/1962] [doc] Update release notes (#4763, #5373) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 7d6c383a224..25c39a6086c 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -43,6 +43,8 @@ This is a {{ site.pmd.release_type }} release. * java-codestyle * [#5214](https://github.com/pmd/pmd/issues/5214): \[java] Wrong message for LambdaCanBeMethodReference with method of enclosing class * [#5263](https://github.com/pmd/pmd/issues/5263): \[java] UnnecessaryFullyQualifiedName: false-positive in an enum that uses its own static variables +* java-design + * [#4763](https://github.com/pmd/pmd/issues/4763): \[java] SimplifyBooleanReturns - wrong suggested solution * java-performance * [#5287](https://github.com/pmd/pmd/issues/5287): \[java] TooFewBranchesForSwitch false-positive with switch using list of case constants * [#5314](https://github.com/pmd/pmd/issues/5314): \[java] InsufficientStringBufferDeclarationRule: Lack of handling for char type parameters @@ -121,6 +123,7 @@ This is a {{ site.pmd.release_type }} release. * [#5354](https://github.com/pmd/pmd/pull/5354): \[apex] Updated the docs for UnusedMethod as per discussion #5200 - [samc-gearset](https://github.com/sam-gearset) (@sam-gearset) * [#5370](https://github.com/pmd/pmd/pull/5370): \[java] Fix #5214 - LambdaCanBeMethodReference issue with method of enclosing class - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5371](https://github.com/pmd/pmd/pull/5371): \[doc] Improve docs on adding Antlr languages - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5373](https://github.com/pmd/pmd/pull/5373): \[java] Fix #4763 - wrong message for SimplifyBooleanReturns - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) ### ๐Ÿ“ฆ Dependency updates From 8fcfb834df8d0f734075dc4e65646703529aecea Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 29 Nov 2024 09:16:24 +0100 Subject: [PATCH 0327/1962] [doc] Update release notes (#5070, #5374) --- docs/pages/release_notes.md | 3 +++ .../rule/errorprone/xml/ConfusingArgumentToVarargsMethod.xml | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 0640946f2b8..5dd2650abee 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -44,6 +44,8 @@ This is a {{ site.pmd.release_type }} release. * [#5214](https://github.com/pmd/pmd/issues/5214): \[java] Wrong message for LambdaCanBeMethodReference with method of enclosing class * [#5263](https://github.com/pmd/pmd/issues/5263): \[java] UnnecessaryFullyQualifiedName: false-positive in an enum that uses its own static variables * [#5315](https://github.com/pmd/pmd/issues/5315): \[java] UnnecessaryImport false positive for on-demand imports +* java-errorprone + * [#5070](https://github.com/pmd/pmd/issues/5070): \[java] ConfusingArgumentToVarargsMethod FP when types are unresolved * java-performance * [#5287](https://github.com/pmd/pmd/issues/5287): \[java] TooFewBranchesForSwitch false-positive with switch using list of case constants * [#5314](https://github.com/pmd/pmd/issues/5314): \[java] InsufficientStringBufferDeclarationRule: Lack of handling for char type parameters @@ -124,6 +126,7 @@ This is a {{ site.pmd.release_type }} release. * [#5370](https://github.com/pmd/pmd/pull/5370): \[java] Fix #5214 - LambdaCanBeMethodReference issue with method of enclosing class - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5371](https://github.com/pmd/pmd/pull/5371): \[doc] Improve docs on adding Antlr languages - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) * [#5372](https://github.com/pmd/pmd/pull/5372): \[java] Fix #5315 - UnusedImport FP with import on demand - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5374](https://github.com/pmd/pmd/pull/5374): \[java] Fix #5070 - confusing argument to varargs method FP when types are unknown - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) ### ๐Ÿ“ฆ Dependency updates diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ConfusingArgumentToVarargsMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ConfusingArgumentToVarargsMethod.xml index 408261234ec..a4beae343c9 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ConfusingArgumentToVarargsMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ConfusingArgumentToVarargsMethod.xml @@ -108,7 +108,7 @@ - Types of args are unresolved + #5070 Types of args are unresolved 1 7 - Types of args is array of unknown + #5070 Types of args is array of unknown 0 Date: Fri, 29 Nov 2024 10:58:37 +0100 Subject: [PATCH 0328/1962] Prepare pmd release 7.8.0 --- docs/_config.yml | 2 +- docs/pages/release_notes.md | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 27190ef965e..4d514d71049 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,7 +1,7 @@ repository: pmd/pmd pmd: - version: 7.8.0-SNAPSHOT + version: 7.8.0 previous_version: 7.7.0 date: 2024-11-29 # release types: major, minor, bugfix diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index f1708455fe6..9d142ca2014 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -98,6 +98,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ Merged pull requests +* [#5240](https://github.com/pmd/pmd/pull/5240): Release notes improvements - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5284](https://github.com/pmd/pmd/pull/5284): \[apex] Use case-insensitive input stream to avoid choking on Unicode escape sequences - [Willem A. Hajenius](https://github.com/wahajenius) (@wahajenius) * [#5286](https://github.com/pmd/pmd/pull/5286): \[ant] Formatter: avoid reflective access to determine console encoding - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5289](https://github.com/pmd/pmd/pull/5289): \[java] TooFewBranchesForSwitch - allow list of case constants - [Andreas Dangel](https://github.com/adangel) (@adangel) @@ -145,9 +146,24 @@ This is a {{ site.pmd.release_type }} release. * [#5317](https://github.com/pmd/pmd/pull/5317): Bump org.apache.commons:commons-compress from 1.26.0 to 1.27.1 * [#5348](https://github.com/pmd/pmd/pull/5348): Bump rouge from 4.5.0 to 4.5.1 in the all-gems group across 1 directory * [#5350](https://github.com/pmd/pmd/pull/5350): Bump org.apache.commons:commons-lang3 from 3.14.0 to 3.17.0 +* [#5356](https://github.com/pmd/pmd/pull/5356): Bump build-tools to 28 +* [#5357](https://github.com/pmd/pmd/pull/5357): Bump log4j.version from 2.23.0 to 2.24.2 +* [#5358](https://github.com/pmd/pmd/pull/5358): Bump org.apache.maven.plugins:maven-dependency-plugin from 3.7.1 to 3.8.1 +* [#5359](https://github.com/pmd/pmd/pull/5359): Bump org.apache.maven.plugins:maven-release-plugin from 3.0.1 to 3.1.1 +* [#5360](https://github.com/pmd/pmd/pull/5360): Bump io.github.apex-dev-tools:apex-ls_2.13 from 5.2.0 to 5.5.0 +* [#5361](https://github.com/pmd/pmd/pull/5361): Bump ant.version from 1.10.14 to 1.10.15 +* [#5362](https://github.com/pmd/pmd/pull/5362): Bump org.jetbrains:annotations from 24.1.0 to 26.0.1 +* [#5363](https://github.com/pmd/pmd/pull/5363): Bump com.puppycrawl.tools:checkstyle from 10.18.1 to 10.20.1 +* [#5364](https://github.com/pmd/pmd/pull/5364): Bump info.picocli:picocli from 4.7.5 to 4.7.6 +* [#5365](https://github.com/pmd/pmd/pull/5365): Bump com.github.hazendaz.maven:coveralls-maven-plugin from 4.5.0-M3 to 4.5.0-M5 +* [#5366](https://github.com/pmd/pmd/pull/5366): Bump org.mockito:mockito-core from 4.11.0 to 5.14.2 +* [#5367](https://github.com/pmd/pmd/pull/5367): Bump surefire.version from 3.2.5 to 3.5.2 +* [#5368](https://github.com/pmd/pmd/pull/5368): Bump org.junit.platform:junit-platform-suite from 1.11.2 to 1.11.3 ### ๐Ÿ“ˆ Stats +* 216 commits +* 55 closed tickets & PRs +* Days since last release: 35 {% endtocmaker %} - From f80ec21752b094bdccb041cc545e21a369e00ac6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 29 Nov 2024 11:19:07 +0100 Subject: [PATCH 0329/1962] [release] prepare release pmd_releases/7.8.0 --- pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 6 +++--- 42 files changed, 44 insertions(+), 44 deletions(-) diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index 6f6d37badfa..5e56b956024 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.8.0-SNAPSHOT + 7.8.0 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index ce6eeb1986a..c369fc2b02b 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index c75f5f91fe4..68cffae576e 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index 5d9270a0ac3..05e9a873a74 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index e84a30f8c92..505f656513d 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index 5c75467663f..8c0be6d9591 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index 97580cbf236..160521c05a6 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index 3cc180bb9cc..83b07d4ed0c 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index 5a40e514e2f..c59614efc32 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index 4a6b36ac2eb..811a3cfb219 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index fac80382f4d..8628469f581 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index 58343201395..a9e0b04f72e 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index aef92908372..afa3e44bf6d 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index 1ffd4b60f4b..459f6394541 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index 51cffc88236..b84da497af2 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 3fe1ebcbcc8..ee923aa14c5 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index 70629cc7ca4..0ec0ca77294 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index 749144cd602..b05c121fc82 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index e4235671694..b0773c09cfb 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index 85a26cf1d7c..1dd8ab79f7b 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index 6b32cbca37b..737d34f384c 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index 31428dbacce..5b6c774c8b4 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index 1a5924d3f68..4eb6a0d0653 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index 997cd9179cb..75b58664a21 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index c8db88656aa..4511784569f 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index 015222667c5..81a34dbd16b 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index 3a7b91adccc..56f818b4a5b 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index 928d7d78c5e..e71d3a87d0d 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index c694ce4fca5..6614848cb62 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index ca86db7ca65..0b1964d8526 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index 2c953e41f5e..2f93efe6a0d 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index 81159650ef5..a0f513aeae5 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index ed15aa35f8e..19d6460ce82 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.8.0-SNAPSHOT + 7.8.0 ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index 31bdc20be32..d503cad8812 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.8.0-SNAPSHOT + 7.8.0 ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index 78c80b613c1..a82dbaa9c74 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index ad89145dcfd..5d545ed804a 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index a4fbf656ebc..4ab53d18a73 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index 0bc61234493..65678125f99 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index 485ee45b6cd..b6dbed04f98 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index 49da6f08583..73ca939712e 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index 3c51ee552e3..89aa94aad40 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 ../pom.xml diff --git a/pom.xml b/pom.xml index 2ec4831aa49..32abd8b122d 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.8.0-SNAPSHOT + 7.8.0 pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - HEAD + pmd_releases/7.8.0 @@ -83,7 +83,7 @@ - 2024-10-25T06:47:53Z + 2024-11-29T09:58:44Z 8 From b0485e1bb321ae7d6b51ad451cd26d3ab304fdaf Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 29 Nov 2024 11:50:31 +0100 Subject: [PATCH 0330/1962] [release] Prepare next development version [skip ci] --- docs/_config.yml | 6 +- docs/pages/release_notes.md | 140 +---------------- docs/pages/release_notes_old.md | 172 +++++++++++++++++++++ pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 4 +- 45 files changed, 219 insertions(+), 185 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 4d514d71049..69e442b4ff7 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,9 +1,9 @@ repository: pmd/pmd pmd: - version: 7.8.0 - previous_version: 7.7.0 - date: 2024-11-29 + version: 7.9.0-SNAPSHOT + previous_version: 7.8.0 + date: 2024-12-27 # release types: major, minor, bugfix release_type: minor diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 9d142ca2014..26ec825d013 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -14,156 +14,18 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy -### ๐ŸŒŸ New and changed rules - -#### New Rules -* The new Apex rule {% rule apex/bestpractices/QueueableWithoutFinalizer %} detects when the Queueable interface - is used but a Finalizer is not attached. Without attaching a Finalizer, there is no way of designing error - recovery actions should the Queueable action fail. - ### ๐Ÿ› Fixed Issues -* ant - * [#1860](https://github.com/pmd/pmd/issues/1860): \[ant] Reflective access warnings on java > 9 and java < 17 -* apex - * [#5302](https://github.com/pmd/pmd/issues/5302): \[apex] New Rule: Queueable Should Attach Finalizer - * [#5333](https://github.com/pmd/pmd/issues/5333): \[apex] Token recognition errors for string containing unicode escape sequence -* html - * [#5322](https://github.com/pmd/pmd/issues/5322): \[html] CPD throws exception on when HTML file is missing closing tag -* java - * [#5283](https://github.com/pmd/pmd/issues/5283): \[java] AssertionError "this should be unreachable" with scala library - * [#5293](https://github.com/pmd/pmd/issues/5293): \[java] Deadlock when executing PMD in multiple threads - * [#5324](https://github.com/pmd/pmd/issues/5324): \[java] Issue with type inference of nested lambdas - * [#5329](https://github.com/pmd/pmd/issues/5329): \[java] Type inference issue with unknown method ref in call chain - * [#5338](https://github.com/pmd/pmd/issues/5338): \[java] Unresolved target type for lambdas make overload resolution fail -* java-bestpractices - * [#4113](https://github.com/pmd/pmd/issues/4113): \[java] JUnitTestsShouldIncludeAssert - false positive with SoftAssertionsExtension - * [#5083](https://github.com/pmd/pmd/issues/5083): \[java] UnusedPrivateMethod false positive when method reference has no target type - * [#5097](https://github.com/pmd/pmd/issues/5097): \[java] UnusedPrivateMethod FP with raw type missing from the classpath - * [#5318](https://github.com/pmd/pmd/issues/5318): \[java] PreserveStackTraceRule: false-positive on Pattern Matching with instanceof -* java-codestyle - * [#5214](https://github.com/pmd/pmd/issues/5214): \[java] Wrong message for LambdaCanBeMethodReference with method of enclosing class - * [#5263](https://github.com/pmd/pmd/issues/5263): \[java] UnnecessaryFullyQualifiedName: false-positive in an enum that uses its own static variables - * [#5315](https://github.com/pmd/pmd/issues/5315): \[java] UnnecessaryImport false positive for on-demand imports -* java-design - * [#4763](https://github.com/pmd/pmd/issues/4763): \[java] SimplifyBooleanReturns - wrong suggested solution -* java-errorprone - * [#5070](https://github.com/pmd/pmd/issues/5070): \[java] ConfusingArgumentToVarargsMethod FP when types are unresolved -* java-performance - * [#5287](https://github.com/pmd/pmd/issues/5287): \[java] TooFewBranchesForSwitch false-positive with switch using list of case constants - * [#5314](https://github.com/pmd/pmd/issues/5314): \[java] InsufficientStringBufferDeclarationRule: Lack of handling for char type parameters - * [#5320](https://github.com/pmd/pmd/issues/5320): \[java] UseStringBufferLength: false-negative on StringBuffer of sb.toString().equals("") ### ๐Ÿšจ API Changes -#### Deprecations -* pmd-coco - * {%jdoc coco::lang.coco.ast.CocoBaseListener %} is deprecated for removal. This class was never intended - to be generated. It will be removed with no replacement. - * {%jdoc coco::lang.coco.ast.CocoBaseVisitor %} is deprecated for removal. This class was never intended - to be generated. It will be removed with no replacement. - * {%jdoc coco::lang.coco.ast.CocoListener %} is deprecated for removal. This class was never intended - to be generated. It will be removed with no replacement. - * {%jdoc coco::lang.coco.ast.CocoParser %} is deprecated for removal. This class was never intended - to be generated. It will be removed with no replacement. - * {%jdoc coco::lang.coco.ast.CocoVisitor %} is deprecated for removal. This class was never intended - to be generated. It will be removed with no replacement. -* pmd-gherkin - * {%jdoc gherkin::lang.gherkin.ast.GherkinBaseListener %} is deprecated for removal. This class was never intended - to be generated. It will be removed with no replacement. - * {%jdoc gherkin::lang.gherkin.ast.GherkinBaseVisitor %} is deprecated for removal. This class was never intended - to be generated. It will be removed with no replacement. - * {%jdoc gherkin::lang.gherkin.ast.GherkinListener %} is deprecated for removal. This class was never intended - to be generated. It will be removed with no replacement. - * {%jdoc gherkin::lang.gherkin.ast.GherkinParser %} is deprecated for removal. This class was never intended - to be generated. It will be removed with no replacement. - * {%jdoc gherkin::lang.gherkin.ast.GherkinVisitor %} is deprecated for removal. This class was never intended - to be generated. It will be removed with no replacement. -* pmd-julia - * {%jdoc julia::lang.julia.ast.JuliaBaseListener %} is deprecated for removal. This class was never intended to - be generated. It will be removed with no replacement. - * {%jdoc julia::lang.julia.ast.JuliaBaseVisitor %} is deprecated for removal. This class was never intended to - be generated. It will be removed with no replacement. - * {%jdoc julia::lang.julia.ast.JuliaListener %} is deprecated for removal. This class was never intended to - be generated. It will be removed with no replacement. - * {%jdoc julia::lang.julia.ast.JuliaParser %} is deprecated for removal. This class was never intended to - be generated. It will be removed with no replacement. - * {%jdoc julia::lang.julia.ast.JuliaVisitor %} is deprecated for removal. This class was never intended to - be generated. It will be removed with no replacement. -* pmd-kotlin - * {%jdoc kotlin::lang.kotlin.ast.UnicodeClasses %} is deprecated for removal. This class was never intended to - be generated. It will be removed with no replacement. -* pmd-xml - * {%jdoc xml::lang.xml.antlr4.XMLLexer %} is deprecated for removal. Use {%jdoc !!xml::lang.xml.ast.XMLLexer %} - instead (note different package `ast` instead of `antlr4`). - ### โœจ Merged pull requests -* [#5240](https://github.com/pmd/pmd/pull/5240): Release notes improvements - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5284](https://github.com/pmd/pmd/pull/5284): \[apex] Use case-insensitive input stream to avoid choking on Unicode escape sequences - [Willem A. Hajenius](https://github.com/wahajenius) (@wahajenius) -* [#5286](https://github.com/pmd/pmd/pull/5286): \[ant] Formatter: avoid reflective access to determine console encoding - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5289](https://github.com/pmd/pmd/pull/5289): \[java] TooFewBranchesForSwitch - allow list of case constants - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5296](https://github.com/pmd/pmd/pull/5296): \[xml] Have pmd-xml Lexer in line with other antlr grammars - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) -* [#5300](https://github.com/pmd/pmd/pull/5300): Add rule test cases for issues fixed with PMD 7.0.0 - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5303](https://github.com/pmd/pmd/pull/5303): \[apex] New Rule: Queueable Should Attach Finalizer - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) -* [#5309](https://github.com/pmd/pmd/pull/5309): \[java] Fix #5293: Parse number of type parameters eagerly - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5310](https://github.com/pmd/pmd/pull/5310): \[java] Fix #5283 - inner class has public private modifiers - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5325](https://github.com/pmd/pmd/pull/5325): \[java] Fix inference dependency issue with nested lambdas - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5326](https://github.com/pmd/pmd/pull/5326): \[java] UseStringBufferLength - consider sb.toString().equals("") - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5328](https://github.com/pmd/pmd/pull/5328): \[html] Test for a closing tag when determining node positions - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5330](https://github.com/pmd/pmd/pull/5330): \[java] Propagate unknown type better when mref is unresolved - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5331](https://github.com/pmd/pmd/pull/5331): \[java] PreserveStackTrace - consider instance type patterns - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5332](https://github.com/pmd/pmd/pull/5332): \[java] InsufficientStringBufferDeclaration: Fix CCE for Character - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5334](https://github.com/pmd/pmd/pull/5334): \[java] UnitTestShouldIncludeAssert - consider SoftAssertionsExtension - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5335](https://github.com/pmd/pmd/pull/5335): \[kotlin] Prevent auxiliary grammars from generating lexers - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) -* [#5336](https://github.com/pmd/pmd/pull/5336): \[gherkin] Remove generated gherkin code from coverage report - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) -* [#5337](https://github.com/pmd/pmd/pull/5337): \[doc] Introducing PMD Guru on Gurubase.io - [Kursat Aktas](https://github.com/kursataktas) (@kursataktas) -* [#5339](https://github.com/pmd/pmd/pull/5339): \[java] Allow lambdas with unresolved target types to succeed inference - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5340](https://github.com/pmd/pmd/pull/5340): \[java] Fix #5097 - problem with unchecked conversion - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5341](https://github.com/pmd/pmd/pull/5341): \[java] Fix #5083 - UnusedPrivateMethod false positive with mref without target type but with exact method - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5342](https://github.com/pmd/pmd/pull/5342): \[julia] Ignore generated code in Julia module - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) -* [#5345](https://github.com/pmd/pmd/pull/5345): \[coco] Remove generated coco files form coverage - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) -* [#5346](https://github.com/pmd/pmd/pull/5346): \[typescript] Add cleanup after generating ts lexer - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) -* [#5347](https://github.com/pmd/pmd/pull/5347): \[tsql] Flag generated lexer as generated - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) -* [#5352](https://github.com/pmd/pmd/pull/5352): \[java] Add permitted subtypes to symbol API - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5353](https://github.com/pmd/pmd/pull/5353): \[java] Fix #5263 - UnnecessaryFullyQualifiedName FP with forward references - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5354](https://github.com/pmd/pmd/pull/5354): \[apex] Updated the docs for UnusedMethod as per discussion #5200 - [samc-gearset](https://github.com/sam-gearset) (@sam-gearset) -* [#5370](https://github.com/pmd/pmd/pull/5370): \[java] Fix #5214 - LambdaCanBeMethodReference issue with method of enclosing class - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5371](https://github.com/pmd/pmd/pull/5371): \[doc] Improve docs on adding Antlr languages - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) -* [#5372](https://github.com/pmd/pmd/pull/5372): \[java] Fix #5315 - UnusedImport FP with import on demand - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5373](https://github.com/pmd/pmd/pull/5373): \[java] Fix #4763 - wrong message for SimplifyBooleanReturns - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5374](https://github.com/pmd/pmd/pull/5374): \[java] Fix #5070 - confusing argument to varargs method FP when types are unknown - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) ### ๐Ÿ“ฆ Dependency updates -* [#5285](https://github.com/pmd/pmd/pull/5285): Bump pmd from 7.5.0 to 7.7.0 -* [#5288](https://github.com/pmd/pmd/pull/5288): Bump asm from 9.7 to 9.7.1 -* [#5290](https://github.com/pmd/pmd/pull/5290): Bump org.apache.maven.plugins:maven-assembly-plugin from 3.6.0 to 3.7.1 -* [#5301](https://github.com/pmd/pmd/pull/5301): Bump gems and bundler -* [#5307](https://github.com/pmd/pmd/pull/5307): Bump org.apache.maven.plugins:maven-clean-plugin from 3.3.2 to 3.4.0 -* [#5308](https://github.com/pmd/pmd/pull/5308): Bump webrick from 1.8.2 to 1.9.0 in /docs in the all-gems group across 1 directory -* [#5312](https://github.com/pmd/pmd/pull/5312): Bump maven-pmd-plugin from 3.24.0 to 3.26.0 -* [#5316](https://github.com/pmd/pmd/pull/5316): Bump rouge from 4.4.0 to 4.5.0 in the all-gems group across 1 directory -* [#5317](https://github.com/pmd/pmd/pull/5317): Bump org.apache.commons:commons-compress from 1.26.0 to 1.27.1 -* [#5348](https://github.com/pmd/pmd/pull/5348): Bump rouge from 4.5.0 to 4.5.1 in the all-gems group across 1 directory -* [#5350](https://github.com/pmd/pmd/pull/5350): Bump org.apache.commons:commons-lang3 from 3.14.0 to 3.17.0 -* [#5356](https://github.com/pmd/pmd/pull/5356): Bump build-tools to 28 -* [#5357](https://github.com/pmd/pmd/pull/5357): Bump log4j.version from 2.23.0 to 2.24.2 -* [#5358](https://github.com/pmd/pmd/pull/5358): Bump org.apache.maven.plugins:maven-dependency-plugin from 3.7.1 to 3.8.1 -* [#5359](https://github.com/pmd/pmd/pull/5359): Bump org.apache.maven.plugins:maven-release-plugin from 3.0.1 to 3.1.1 -* [#5360](https://github.com/pmd/pmd/pull/5360): Bump io.github.apex-dev-tools:apex-ls_2.13 from 5.2.0 to 5.5.0 -* [#5361](https://github.com/pmd/pmd/pull/5361): Bump ant.version from 1.10.14 to 1.10.15 -* [#5362](https://github.com/pmd/pmd/pull/5362): Bump org.jetbrains:annotations from 24.1.0 to 26.0.1 -* [#5363](https://github.com/pmd/pmd/pull/5363): Bump com.puppycrawl.tools:checkstyle from 10.18.1 to 10.20.1 -* [#5364](https://github.com/pmd/pmd/pull/5364): Bump info.picocli:picocli from 4.7.5 to 4.7.6 -* [#5365](https://github.com/pmd/pmd/pull/5365): Bump com.github.hazendaz.maven:coveralls-maven-plugin from 4.5.0-M3 to 4.5.0-M5 -* [#5366](https://github.com/pmd/pmd/pull/5366): Bump org.mockito:mockito-core from 4.11.0 to 5.14.2 -* [#5367](https://github.com/pmd/pmd/pull/5367): Bump surefire.version from 3.2.5 to 3.5.2 -* [#5368](https://github.com/pmd/pmd/pull/5368): Bump org.junit.platform:junit-platform-suite from 1.11.2 to 1.11.3 ### ๐Ÿ“ˆ Stats -* 216 commits -* 55 closed tickets & PRs -* Days since last release: 35 {% endtocmaker %} + diff --git a/docs/pages/release_notes_old.md b/docs/pages/release_notes_old.md index 74a1cfcd25b..03bfce226f2 100644 --- a/docs/pages/release_notes_old.md +++ b/docs/pages/release_notes_old.md @@ -5,6 +5,178 @@ permalink: pmd_release_notes_old.html Previous versions of PMD can be downloaded here: [Releases - pmd/pmd (GitHub)](https://github.com/pmd/pmd/releases) +## 29-November-2024 - 7.8.0 + +The PMD team is pleased to announce PMD 7.8.0. + +This is a minor release. + +### Table Of Contents + +* [๐Ÿš€ New and noteworthy](#new-and-noteworthy) +* [๐ŸŒŸ New and changed rules](#new-and-changed-rules) + * [New Rules](#new-rules) +* [๐Ÿ› Fixed Issues](#fixed-issues) +* [๐Ÿšจ API Changes](#api-changes) + * [Deprecations](#deprecations) +* [โœจ Merged pull requests](#merged-pull-requests) +* [๐Ÿ“ฆ Dependency updates](#dependency-updates) +* [๐Ÿ“ˆ Stats](#stats) + +### ๐Ÿš€ New and noteworthy + +### ๐ŸŒŸ New and changed rules + +#### New Rules +* The new Apex rule [`QueueableWithoutFinalizer`](https://docs.pmd-code.org/pmd-doc-7.8.0/pmd_rules_apex_bestpractices.html#queueablewithoutfinalizer) detects when the Queueable interface + is used but a Finalizer is not attached. Without attaching a Finalizer, there is no way of designing error + recovery actions should the Queueable action fail. + +### ๐Ÿ› Fixed Issues +* ant + * [#1860](https://github.com/pmd/pmd/issues/1860): \[ant] Reflective access warnings on java > 9 and java < 17 +* apex + * [#5302](https://github.com/pmd/pmd/issues/5302): \[apex] New Rule: Queueable Should Attach Finalizer + * [#5333](https://github.com/pmd/pmd/issues/5333): \[apex] Token recognition errors for string containing unicode escape sequence +* html + * [#5322](https://github.com/pmd/pmd/issues/5322): \[html] CPD throws exception on when HTML file is missing closing tag +* java + * [#5283](https://github.com/pmd/pmd/issues/5283): \[java] AssertionError "this should be unreachable" with scala library + * [#5293](https://github.com/pmd/pmd/issues/5293): \[java] Deadlock when executing PMD in multiple threads + * [#5324](https://github.com/pmd/pmd/issues/5324): \[java] Issue with type inference of nested lambdas + * [#5329](https://github.com/pmd/pmd/issues/5329): \[java] Type inference issue with unknown method ref in call chain + * [#5338](https://github.com/pmd/pmd/issues/5338): \[java] Unresolved target type for lambdas make overload resolution fail +* java-bestpractices + * [#4113](https://github.com/pmd/pmd/issues/4113): \[java] JUnitTestsShouldIncludeAssert - false positive with SoftAssertionsExtension + * [#5083](https://github.com/pmd/pmd/issues/5083): \[java] UnusedPrivateMethod false positive when method reference has no target type + * [#5097](https://github.com/pmd/pmd/issues/5097): \[java] UnusedPrivateMethod FP with raw type missing from the classpath + * [#5318](https://github.com/pmd/pmd/issues/5318): \[java] PreserveStackTraceRule: false-positive on Pattern Matching with instanceof +* java-codestyle + * [#5214](https://github.com/pmd/pmd/issues/5214): \[java] Wrong message for LambdaCanBeMethodReference with method of enclosing class + * [#5263](https://github.com/pmd/pmd/issues/5263): \[java] UnnecessaryFullyQualifiedName: false-positive in an enum that uses its own static variables + * [#5315](https://github.com/pmd/pmd/issues/5315): \[java] UnnecessaryImport false positive for on-demand imports +* java-design + * [#4763](https://github.com/pmd/pmd/issues/4763): \[java] SimplifyBooleanReturns - wrong suggested solution +* java-errorprone + * [#5070](https://github.com/pmd/pmd/issues/5070): \[java] ConfusingArgumentToVarargsMethod FP when types are unresolved +* java-performance + * [#5287](https://github.com/pmd/pmd/issues/5287): \[java] TooFewBranchesForSwitch false-positive with switch using list of case constants + * [#5314](https://github.com/pmd/pmd/issues/5314): \[java] InsufficientStringBufferDeclarationRule: Lack of handling for char type parameters + * [#5320](https://github.com/pmd/pmd/issues/5320): \[java] UseStringBufferLength: false-negative on StringBuffer of sb.toString().equals("") + +### ๐Ÿšจ API Changes + +#### Deprecations +* pmd-coco + * CocoBaseListener is deprecated for removal. This class was never intended + to be generated. It will be removed with no replacement. + * CocoBaseVisitor is deprecated for removal. This class was never intended + to be generated. It will be removed with no replacement. + * CocoListener is deprecated for removal. This class was never intended + to be generated. It will be removed with no replacement. + * CocoParser is deprecated for removal. This class was never intended + to be generated. It will be removed with no replacement. + * CocoVisitor is deprecated for removal. This class was never intended + to be generated. It will be removed with no replacement. +* pmd-gherkin + * GherkinBaseListener is deprecated for removal. This class was never intended + to be generated. It will be removed with no replacement. + * GherkinBaseVisitor is deprecated for removal. This class was never intended + to be generated. It will be removed with no replacement. + * GherkinListener is deprecated for removal. This class was never intended + to be generated. It will be removed with no replacement. + * GherkinParser is deprecated for removal. This class was never intended + to be generated. It will be removed with no replacement. + * GherkinVisitor is deprecated for removal. This class was never intended + to be generated. It will be removed with no replacement. +* pmd-julia + * JuliaBaseListener is deprecated for removal. This class was never intended to + be generated. It will be removed with no replacement. + * JuliaBaseVisitor is deprecated for removal. This class was never intended to + be generated. It will be removed with no replacement. + * JuliaListener is deprecated for removal. This class was never intended to + be generated. It will be removed with no replacement. + * JuliaParser is deprecated for removal. This class was never intended to + be generated. It will be removed with no replacement. + * JuliaVisitor is deprecated for removal. This class was never intended to + be generated. It will be removed with no replacement. +* pmd-kotlin + * UnicodeClasses is deprecated for removal. This class was never intended to + be generated. It will be removed with no replacement. +* pmd-xml + * XMLLexer is deprecated for removal. Use net.sourceforge.pmd.lang.xml.ast.XMLLexer + instead (note different package `ast` instead of `antlr4`). + +### โœจ Merged pull requests + +* [#5240](https://github.com/pmd/pmd/pull/5240): Release notes improvements - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5284](https://github.com/pmd/pmd/pull/5284): \[apex] Use case-insensitive input stream to avoid choking on Unicode escape sequences - [Willem A. Hajenius](https://github.com/wahajenius) (@wahajenius) +* [#5286](https://github.com/pmd/pmd/pull/5286): \[ant] Formatter: avoid reflective access to determine console encoding - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5289](https://github.com/pmd/pmd/pull/5289): \[java] TooFewBranchesForSwitch - allow list of case constants - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5296](https://github.com/pmd/pmd/pull/5296): \[xml] Have pmd-xml Lexer in line with other antlr grammars - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5300](https://github.com/pmd/pmd/pull/5300): Add rule test cases for issues fixed with PMD 7.0.0 - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5303](https://github.com/pmd/pmd/pull/5303): \[apex] New Rule: Queueable Should Attach Finalizer - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) +* [#5309](https://github.com/pmd/pmd/pull/5309): \[java] Fix #5293: Parse number of type parameters eagerly - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5310](https://github.com/pmd/pmd/pull/5310): \[java] Fix #5283 - inner class has public private modifiers - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5325](https://github.com/pmd/pmd/pull/5325): \[java] Fix inference dependency issue with nested lambdas - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5326](https://github.com/pmd/pmd/pull/5326): \[java] UseStringBufferLength - consider sb.toString().equals("") - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5328](https://github.com/pmd/pmd/pull/5328): \[html] Test for a closing tag when determining node positions - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5330](https://github.com/pmd/pmd/pull/5330): \[java] Propagate unknown type better when mref is unresolved - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5331](https://github.com/pmd/pmd/pull/5331): \[java] PreserveStackTrace - consider instance type patterns - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5332](https://github.com/pmd/pmd/pull/5332): \[java] InsufficientStringBufferDeclaration: Fix CCE for Character - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5334](https://github.com/pmd/pmd/pull/5334): \[java] UnitTestShouldIncludeAssert - consider SoftAssertionsExtension - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5335](https://github.com/pmd/pmd/pull/5335): \[kotlin] Prevent auxiliary grammars from generating lexers - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5336](https://github.com/pmd/pmd/pull/5336): \[gherkin] Remove generated gherkin code from coverage report - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5337](https://github.com/pmd/pmd/pull/5337): \[doc] Introducing PMD Guru on Gurubase.io - [Kursat Aktas](https://github.com/kursataktas) (@kursataktas) +* [#5339](https://github.com/pmd/pmd/pull/5339): \[java] Allow lambdas with unresolved target types to succeed inference - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5340](https://github.com/pmd/pmd/pull/5340): \[java] Fix #5097 - problem with unchecked conversion - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5341](https://github.com/pmd/pmd/pull/5341): \[java] Fix #5083 - UnusedPrivateMethod false positive with mref without target type but with exact method - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5342](https://github.com/pmd/pmd/pull/5342): \[julia] Ignore generated code in Julia module - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5345](https://github.com/pmd/pmd/pull/5345): \[coco] Remove generated coco files form coverage - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5346](https://github.com/pmd/pmd/pull/5346): \[typescript] Add cleanup after generating ts lexer - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5347](https://github.com/pmd/pmd/pull/5347): \[tsql] Flag generated lexer as generated - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5352](https://github.com/pmd/pmd/pull/5352): \[java] Add permitted subtypes to symbol API - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5353](https://github.com/pmd/pmd/pull/5353): \[java] Fix #5263 - UnnecessaryFullyQualifiedName FP with forward references - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5354](https://github.com/pmd/pmd/pull/5354): \[apex] Updated the docs for UnusedMethod as per discussion #5200 - [samc-gearset](https://github.com/sam-gearset) (@sam-gearset) +* [#5370](https://github.com/pmd/pmd/pull/5370): \[java] Fix #5214 - LambdaCanBeMethodReference issue with method of enclosing class - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5371](https://github.com/pmd/pmd/pull/5371): \[doc] Improve docs on adding Antlr languages - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5372](https://github.com/pmd/pmd/pull/5372): \[java] Fix #5315 - UnusedImport FP with import on demand - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5373](https://github.com/pmd/pmd/pull/5373): \[java] Fix #4763 - wrong message for SimplifyBooleanReturns - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5374](https://github.com/pmd/pmd/pull/5374): \[java] Fix #5070 - confusing argument to varargs method FP when types are unknown - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) + +### ๐Ÿ“ฆ Dependency updates + +* [#5285](https://github.com/pmd/pmd/pull/5285): Bump pmd from 7.5.0 to 7.7.0 +* [#5288](https://github.com/pmd/pmd/pull/5288): Bump asm from 9.7 to 9.7.1 +* [#5290](https://github.com/pmd/pmd/pull/5290): Bump org.apache.maven.plugins:maven-assembly-plugin from 3.6.0 to 3.7.1 +* [#5301](https://github.com/pmd/pmd/pull/5301): Bump gems and bundler +* [#5307](https://github.com/pmd/pmd/pull/5307): Bump org.apache.maven.plugins:maven-clean-plugin from 3.3.2 to 3.4.0 +* [#5308](https://github.com/pmd/pmd/pull/5308): Bump webrick from 1.8.2 to 1.9.0 in /docs in the all-gems group across 1 directory +* [#5312](https://github.com/pmd/pmd/pull/5312): Bump maven-pmd-plugin from 3.24.0 to 3.26.0 +* [#5316](https://github.com/pmd/pmd/pull/5316): Bump rouge from 4.4.0 to 4.5.0 in the all-gems group across 1 directory +* [#5317](https://github.com/pmd/pmd/pull/5317): Bump org.apache.commons:commons-compress from 1.26.0 to 1.27.1 +* [#5348](https://github.com/pmd/pmd/pull/5348): Bump rouge from 4.5.0 to 4.5.1 in the all-gems group across 1 directory +* [#5350](https://github.com/pmd/pmd/pull/5350): Bump org.apache.commons:commons-lang3 from 3.14.0 to 3.17.0 +* [#5356](https://github.com/pmd/pmd/pull/5356): Bump build-tools to 28 +* [#5357](https://github.com/pmd/pmd/pull/5357): Bump log4j.version from 2.23.0 to 2.24.2 +* [#5358](https://github.com/pmd/pmd/pull/5358): Bump org.apache.maven.plugins:maven-dependency-plugin from 3.7.1 to 3.8.1 +* [#5359](https://github.com/pmd/pmd/pull/5359): Bump org.apache.maven.plugins:maven-release-plugin from 3.0.1 to 3.1.1 +* [#5360](https://github.com/pmd/pmd/pull/5360): Bump io.github.apex-dev-tools:apex-ls_2.13 from 5.2.0 to 5.5.0 +* [#5361](https://github.com/pmd/pmd/pull/5361): Bump ant.version from 1.10.14 to 1.10.15 +* [#5362](https://github.com/pmd/pmd/pull/5362): Bump org.jetbrains:annotations from 24.1.0 to 26.0.1 +* [#5363](https://github.com/pmd/pmd/pull/5363): Bump com.puppycrawl.tools:checkstyle from 10.18.1 to 10.20.1 +* [#5364](https://github.com/pmd/pmd/pull/5364): Bump info.picocli:picocli from 4.7.5 to 4.7.6 +* [#5365](https://github.com/pmd/pmd/pull/5365): Bump com.github.hazendaz.maven:coveralls-maven-plugin from 4.5.0-M3 to 4.5.0-M5 +* [#5366](https://github.com/pmd/pmd/pull/5366): Bump org.mockito:mockito-core from 4.11.0 to 5.14.2 +* [#5367](https://github.com/pmd/pmd/pull/5367): Bump surefire.version from 3.2.5 to 3.5.2 +* [#5368](https://github.com/pmd/pmd/pull/5368): Bump org.junit.platform:junit-platform-suite from 1.11.2 to 1.11.3 + +### ๐Ÿ“ˆ Stats + +* 216 commits +* 55 closed tickets & PRs +* Days since last release: 35 + ## 25-October-2024 - 7.7.0 The PMD team is pleased to announce PMD 7.7.0. diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index 5e56b956024..c84d4ad7a79 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.8.0 + 7.9.0-SNAPSHOT 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index c369fc2b02b..b4806807e84 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index 68cffae576e..24de0ef92c4 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index 05e9a873a74..1a37e20c6bd 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index 505f656513d..f7ff6b9b423 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index 8c0be6d9591..08f2d8d1f52 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index 160521c05a6..ebfe7646b8d 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index 83b07d4ed0c..7c5e6f85e6b 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index c59614efc32..7c67b8fd6ac 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index 811a3cfb219..5e29bfe1e97 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index 8628469f581..87605dc557d 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index a9e0b04f72e..71a1d2847b3 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index afa3e44bf6d..58eaff969be 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index 459f6394541..304faf6c71e 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index b84da497af2..ff858631e8a 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index ee923aa14c5..a88059c2266 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index 0ec0ca77294..7d21f8d640f 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index b05c121fc82..b524a13e6a0 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index b0773c09cfb..11d0ebfa066 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index 1dd8ab79f7b..4973fbf025a 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index 737d34f384c..983571a0939 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index 5b6c774c8b4..dbd59b55627 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index 4eb6a0d0653..adc0eb82506 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index 75b58664a21..d991a9a2f65 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index 4511784569f..917b5d603a4 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index 81a34dbd16b..0123cfcb882 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index 56f818b4a5b..f5df3977a4c 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index e71d3a87d0d..b12d207a296 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index 6614848cb62..8e288479aa0 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index 0b1964d8526..32d272b70f8 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index 2f93efe6a0d..b73a1e1ef5c 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index a0f513aeae5..0286dd39df2 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index 19d6460ce82..da3b27eef4b 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.8.0 + 7.9.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index d503cad8812..4d2cca74526 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.8.0 + 7.9.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index a82dbaa9c74..11facecdbd3 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index 5d545ed804a..e1a5aecf23d 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index 4ab53d18a73..0b9fcc3d675 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index 65678125f99..7a7eba1b4e4 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index b6dbed04f98..c54b1f1601b 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index 73ca939712e..628cb34f91f 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index 89aa94aad40..371f385f6dc 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index 32abd8b122d..888154c70ab 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.8.0 + 7.9.0-SNAPSHOT pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - pmd_releases/7.8.0 + HEAD From fc608e1f931d68746291cfb0a1c9e1bb1181d3f7 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 29 Nov 2024 12:55:34 +0100 Subject: [PATCH 0331/1962] Bump pmd from 7.7.0 to 7.8.0 (#5375) --- pom.xml | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index 888154c70ab..995fb485ca7 100644 --- a/pom.xml +++ b/pom.xml @@ -569,22 +569,22 @@ net.sourceforge.pmd pmd-core - 7.7.0 + 7.8.0 net.sourceforge.pmd pmd-java - 7.7.0 + 7.8.0 net.sourceforge.pmd pmd-jsp - 7.7.0 + 7.8.0 net.sourceforge.pmd pmd-javascript - 7.7.0 + 7.8.0 @@ -592,12 +592,6 @@ pmd-build-tools-config ${pmd.build-tools.version} - - - org.ow2.asm - asm - 9.7.1 - From 473c2cfea7f2db4022005d6301fc4b300401a0b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 29 Nov 2024 15:46:24 +0100 Subject: [PATCH 0332/1962] [java] Fix #4861 - UnusedPrivateMethod FP in JDK classes --- .../UnusedPrivateMethodRule.java | 29 +++++++++++++++++++ .../java/symbols/internal/SymbolEquality.java | 23 ++++++++------- .../bestpractices/xml/UnusedPrivateMethod.xml | 15 ++++++++++ 3 files changed, 57 insertions(+), 10 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java index f26108d9dc3..a6a165d0a82 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java @@ -15,6 +15,7 @@ import java.util.stream.Stream; import org.apache.commons.lang3.StringUtils; +import org.checkerframework.checker.nullness.qual.Nullable; import net.sourceforge.pmd.lang.ast.NodeStream; import net.sourceforge.pmd.lang.java.ast.ASTAnnotation; @@ -23,6 +24,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTMethodReference; +import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration; import net.sourceforge.pmd.lang.java.ast.JavaNode; import net.sourceforge.pmd.lang.java.ast.MethodUsage; import net.sourceforge.pmd.lang.java.ast.ModifierOwner.Visibility; @@ -112,6 +114,9 @@ public Object visit(ASTCompilationUnit file, Object param) { } JavaNode reffed = sym.tryGetNode(); + if (reffed == null) { + reffed = findDeclarationInCompilationUnit(file, sym); + } if (reffed instanceof ASTMethodDeclaration && ref.ancestors(ASTMethodDeclaration.class).first() != reffed) { // remove from set, but only if it is called outside of itself @@ -137,4 +142,28 @@ public Object visit(ASTCompilationUnit file, Object param) { private boolean hasExcludedName(ASTMethodDeclaration node) { return SERIALIZATION_METHODS.contains(node.getName()); } + + /** + * Find the method in the compilation unit. Note that this + * is a patch to fix some incorrect behavior of the rule in + * the java.lang package. This is due to the fact that some + * java.lang types (like Object, or primitive boxes) are + * treated specially by the type resolution framework, and + * for those the preexisting ASM symbol is preferred over + * the AST symbol. Since it only applies to these types we + * check that the package name is java.lang, to avoid doing + * that for other types. + */ + private static @Nullable ASTMethodDeclaration findDeclarationInCompilationUnit(ASTCompilationUnit acu, JExecutableSymbol symbol) { + if (!"java.lang".equals(acu.getPackageName()) + || !"java.lang".equals(symbol.getPackageName())) { + return null; + } + return acu.descendants(ASTTypeDeclaration.class) + .crossFindBoundaries() + .filter(it -> it.getSymbol().equals(symbol.getEnclosingClass())) + .take(1) + .flatMap(it -> it.getDeclarations(ASTMethodDeclaration.class)) + .first(m -> m.getSymbol().equals(symbol)); + } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/SymbolEquality.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/SymbolEquality.java index 2f009f73047..25f0ac80c7c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/SymbolEquality.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/SymbolEquality.java @@ -9,6 +9,7 @@ import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; import net.sourceforge.pmd.lang.java.symbols.JConstructorSymbol; import net.sourceforge.pmd.lang.java.symbols.JElementSymbol; +import net.sourceforge.pmd.lang.java.symbols.JExecutableSymbol; import net.sourceforge.pmd.lang.java.symbols.JFieldSymbol; import net.sourceforge.pmd.lang.java.symbols.JFormalParamSymbol; import net.sourceforge.pmd.lang.java.symbols.JLocalVariableSymbol; @@ -17,6 +18,7 @@ import net.sourceforge.pmd.lang.java.symbols.JTypeParameterSymbol; import net.sourceforge.pmd.lang.java.symbols.SymbolVisitor; import net.sourceforge.pmd.lang.java.symbols.SymbolicValue.SymAnnot; +import net.sourceforge.pmd.lang.java.types.Substitution; /** * Routines to share logic for equality, respecting the contract of @@ -71,14 +73,19 @@ public boolean equals(JMethodSymbol m1, Object o) { } JMethodSymbol m2 = (JMethodSymbol) o; - // FIXME arity check is not enough for overloads - return m1.getModifiers() == m2.getModifiers() - && m1.getArity() == m2.getArity() - && Objects.equals(m1.getSimpleName(), m2.getSimpleName()) - && m1.getEnclosingClass().equals(m2.getEnclosingClass()); + return executableSymsAreEqual(m1, m2); } }; + private static boolean executableSymsAreEqual(JExecutableSymbol m1, JExecutableSymbol m2) { + return m1.getModifiers() == m2.getModifiers() + && m1.getArity() == m2.getArity() + && Objects.equals(m1.getSimpleName(), m2.getSimpleName()) + && m1.getEnclosingClass().equals(m2.getEnclosingClass()) + && m1.getFormalParameterTypes(Substitution.erasing(m1.getTypeParameters())) + .equals(m2.getFormalParameterTypes(Substitution.erasing(m2.getTypeParameters()))); + } + public static final EqAndHash CONSTRUCTOR = new EqAndHash() { @Override public int hash(JConstructorSymbol t1) { @@ -95,11 +102,7 @@ public boolean equals(JConstructorSymbol m1, Object o) { } JConstructorSymbol m2 = (JConstructorSymbol) o; - // FIXME arity check is not enough for overloads - return m1.getModifiers() == m2.getModifiers() - && m1.getArity() == m2.getArity() - && Objects.equals(m1.getSimpleName(), m2.getSimpleName()) - && m1.getEnclosingClass().equals(m2.getEnclosingClass()); + return executableSymsAreEqual(m1, m2); } }; diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index 923eea53e4d..716a94b77e3 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2353,4 +2353,19 @@ public class ObtainViaTest { } ]]> + + + + [java] UnusedPrivateMethod - false positive with static methods in core JDK classes #4861 + 0 + + From a5d6c87d1e43bd467ebf85fbd29444c07258bd5b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 03:56:41 +0000 Subject: [PATCH 0333/1962] Bump com.puppycrawl.tools:checkstyle from 10.20.1 to 10.20.2 Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.20.1 to 10.20.2. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.20.1...checkstyle-10.20.2) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 995fb485ca7..667010b3244 100644 --- a/pom.xml +++ b/pom.xml @@ -99,7 +99,7 @@ 5.0 3.5.2 - 10.20.1 + 10.20.2 3.5.0 3.26.0 1.10.15 From 569c03841b36e450a00111600cd8d5e0d5edea90 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 03:56:45 +0000 Subject: [PATCH 0334/1962] Bump net.bytebuddy:byte-buddy from 1.14.12 to 1.15.10 Bumps [net.bytebuddy:byte-buddy](https://github.com/raphw/byte-buddy) from 1.14.12 to 1.15.10. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.14.12...byte-buddy-1.15.10) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 995fb485ca7..e1ca75fed47 100644 --- a/pom.xml +++ b/pom.xml @@ -989,7 +989,7 @@ net.bytebuddy byte-buddy - 1.14.12 + 1.15.10 test From 67687d7e05ee72e51bd1827c4d416856957de4b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 03:56:48 +0000 Subject: [PATCH 0335/1962] Bump io.github.git-commit-id:git-commit-id-maven-plugin Bumps [io.github.git-commit-id:git-commit-id-maven-plugin](https://github.com/git-commit-id/git-commit-id-maven-plugin) from 7.0.0 to 9.0.1. - [Release notes](https://github.com/git-commit-id/git-commit-id-maven-plugin/releases) - [Commits](https://github.com/git-commit-id/git-commit-id-maven-plugin/compare/v7.0.0...v9.0.1) --- updated-dependencies: - dependency-name: io.github.git-commit-id:git-commit-id-maven-plugin dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- pmd-core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index f7ff6b9b423..335e68b21d6 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -29,7 +29,7 @@ io.github.git-commit-id git-commit-id-maven-plugin - 7.0.0 + 9.0.1 get-the-git-infos From 68ddb5885c9bf595543a9605e6d9e1a6b9ace153 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 03:56:51 +0000 Subject: [PATCH 0336/1962] Bump org.apache.maven.plugins:maven-shade-plugin from 3.5.2 to 3.6.0 Bumps [org.apache.maven.plugins:maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.5.2 to 3.6.0. - [Release notes](https://github.com/apache/maven-shade-plugin/releases) - [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.5.2...maven-shade-plugin-3.6.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-shade-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 995fb485ca7..6cad0315a4a 100644 --- a/pom.xml +++ b/pom.xml @@ -333,7 +333,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.5.2 + 3.6.0 org.apache.maven.plugins From 50b5786577ecd21f484905404cdff0831c0a7d6e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 04:10:58 +0000 Subject: [PATCH 0337/1962] Bump org.apache.groovy:groovy from 4.0.19 to 4.0.24 Bumps [org.apache.groovy:groovy](https://github.com/apache/groovy) from 4.0.19 to 4.0.24. - [Commits](https://github.com/apache/groovy/commits) --- updated-dependencies: - dependency-name: org.apache.groovy:groovy dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 995fb485ca7..7ef794643a8 100644 --- a/pom.xml +++ b/pom.xml @@ -882,7 +882,7 @@ org.apache.groovy groovy - 4.0.19 + 4.0.24 com.google.code.gson From 97a57fe88dccf37ba5e27a475624e7a933f93bb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 4 Dec 2024 17:23:52 +0100 Subject: [PATCH 0338/1962] [java] Fix #5096 - StackOverflowError with recursively bounded tvar --- .../pmd/lang/java/types/JTypeVar.java | 10 ++ .../pmd/lang/java/types/TypeConversion.java | 9 +- .../pmd/lang/java/types/TypeOps.java | 6 +- .../pmd/lang/java/types/TypeVarImpl.java | 101 +++++++++++++++--- .../pmd/lang/java/types/AstTestUtil.kt | 4 +- .../pmd/lang/java/types/CaptureTest.kt | 38 ++++++- .../pmd/lang/java/types/GlbTest.kt | 23 ++++ 7 files changed, 165 insertions(+), 26 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/JTypeVar.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/JTypeVar.java index 432e917c29f..ee9059d8779 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/JTypeVar.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/JTypeVar.java @@ -14,6 +14,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.pcollections.PSet; +import net.sourceforge.pmd.annotation.InternalApi; import net.sourceforge.pmd.lang.java.symbols.JMethodSymbol; import net.sourceforge.pmd.lang.java.symbols.JTypeParameterSymbol; import net.sourceforge.pmd.lang.java.symbols.SymbolicValue.SymAnnot; @@ -112,17 +113,26 @@ default T acceptVisitor(JTypeVisitor visitor, P p) { /** * @throws UnsupportedOperationException If this is not a capture var + * + *

    Note that this is only supposed to be used internally. */ + @InternalApi JTypeVar cloneWithBounds(JTypeMirror lower, JTypeMirror upper); /** * Return a new type variable with the same underlying symbol or * capture variable, but the upper bound is now the given type. * + *

    Note that this is only supposed to be used internally. For + * now it only serves to apply type annotations to the upper bound + * when parsing class files. Some implementations may therefore throw + * {@link UnsupportedOperationException}. + * * @param newUB New upper bound * * @return a new tvar */ + @InternalApi JTypeVar withUpperBound(@NonNull JTypeMirror newUB); @Override // refine return type diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeConversion.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeConversion.java index e8927f0d1aa..e7180a949f8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeConversion.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeConversion.java @@ -17,6 +17,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; +import net.sourceforge.pmd.lang.java.types.TypeVarImpl.CapturedTypeVar; import net.sourceforge.pmd.lang.java.types.internal.infer.InferenceVar; import net.sourceforge.pmd.util.CollectionUtil; @@ -145,11 +146,7 @@ private static boolean isConvertibleCommon(JTypeMirror t, JTypeMirror s, boolean */ public static JTypeMirror capture(JTypeMirror t) { if (t instanceof JTypeVar) { - // Need to capture the upper bound because that bound contributes the methods of the tvar. - // Eg in `>` the methods available in C may mention the type - // parameter of collection. But this is a wildcard `? super X` that needs to be captured. - JTypeVar tv = (JTypeVar) t; - return tv.withUpperBound(capture(tv.getUpperBound())); + return TypeVarImpl.tvarCapture((JTypeVar) t); } return t instanceof JClassType ? capture((JClassType) t) : t; } @@ -207,7 +204,7 @@ public static JClassType capture(JClassType type) { if (arg instanceof JWildcardType) { JWildcardType w = (JWildcardType) arg; // Ti alias - TypeVarImpl.CapturedTypeVar freshVar = (TypeVarImpl.CapturedTypeVar) fresh; // Si alias + CapturedTypeVar freshVar = (CapturedTypeVar) fresh; // Si alias JTypeMirror prevUpper = wellFormed ? typeParams.get(i).getUpperBound() : ts.OBJECT; // Ui JTypeMirror substituted = TypeOps.subst(prevUpper, subst); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java index 40d86e04ba8..b4e5bf049be 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java @@ -398,7 +398,7 @@ public Void visitPrimitive(JPrimitiveType t, Set result) { public static Convertibility isConvertible(@NonNull JTypeMirror t, @NonNull JTypeMirror s) { - return SubtypeVisitor.INFERENCE.isConvertible(t, s); + return SubtypeVisitor.INFERENCE.isConvertible(t, s, true); } @Deprecated // unused @@ -595,7 +595,7 @@ private SubtypeVisitor(boolean pure) { Convertibility isConvertible(@NonNull JTypeMirror t, @NonNull JTypeMirror s) { - return isConvertible(t, s, true); + return isConvertible(t, s, false); } /** @@ -1798,7 +1798,7 @@ public static Set mostSpecific(Collection se for (JTypeMirror v : set) { for (JTypeMirror w : set) { if (!w.equals(v) && !hasUnresolvedSymbolOrArray(w)) { - Convertibility isConvertible = isConvertiblePure(w, v); + Convertibility isConvertible = isConvertibleNoCapture(w, v); if (isConvertible.bySubtyping() // This last case covers unchecked conversion. It is made antisymmetric by the // test for a symbol. eg |G| <~> G so it would fail. diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeVarImpl.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeVarImpl.java index e682425b6c2..ca01e1bda31 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeVarImpl.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeVarImpl.java @@ -4,6 +4,8 @@ package net.sourceforge.pmd.lang.java.types; +import static net.sourceforge.pmd.lang.java.types.TypeConversion.capture; + import java.util.Objects; import java.util.function.Function; @@ -13,7 +15,6 @@ import net.sourceforge.pmd.lang.java.symbols.JTypeParameterSymbol; import net.sourceforge.pmd.lang.java.symbols.SymbolicValue.SymAnnot; -import net.sourceforge.pmd.util.AssertionUtil; @SuppressWarnings("PMD.CompareObjectsWithEquals") abstract class TypeVarImpl implements JTypeVar { @@ -59,10 +60,62 @@ public String toString() { * the capture conversion algo in {@link TypeConversion#capture(JTypeMirror)}. * Captured variables use reference identity as equality relation. */ - static TypeVarImpl.CapturedTypeVar freshCapture(JWildcardType wildcard) { + static TypeVarImpl.CapturedTypeVar freshCapture(@NonNull JWildcardType wildcard) { return new CapturedTypeVar(wildcard, wildcard.getTypeAnnotations()); } + /** + * Capture a type variable, that is, capture its bounds if needed. + * This is necessary because those bounds contributes to the methods + * of the type variable. + * Eg in {@code >} the methods available + * in C may mention the type parameter of Collection. But this is a + * wildcard `? super X` that needs to be replaced by a capture variable. + * + * @param tv a type var + */ + static JTypeVar tvarCapture(@NonNull JTypeVar tv) { + if (tv.isCaptured()) { + return tv; + } + // Need to capture the bounds because those bounds contributes the methods of the tvar. + // Eg in `>` the methods available in C may mention the type + // parameter of collection. But this is a wildcard `? super X` that needs to be captured. + JTypeMirror upperBoundCap = capture(tv.getUpperBound()); + JTypeMirror lowerBoundCap = capture(tv.getLowerBound()); + if (upperBoundCap == tv.getUpperBound() && lowerBoundCap == tv.getLowerBound()) { + // no change + return tv; + } + // We will return a new var. + CapturedTypeVar newTv = new CapturedTypeVar(tv, upperBoundCap, lowerBoundCap, tv.getTypeAnnotations()); + + // We have to update the bounds again, to uphold recursive bounds. Eg if you have the following: + // class C> + // then capturing T in the body of the class C should produce a new capture var, call it T2, + // which has captured bounds. The upper bound of T2 should be + // capture(C) + // and notice that here it's T2 and not T, otherwise the recursive bound is + // not preserved by capture. So this last update is there to map T to T2 (ie, tv to newTv). + newTv.upperBound = upperBoundCap.subst(sv -> updateBounds(tv, sv, newTv)); + newTv.lowerBound = lowerBoundCap.subst(sv -> updateBounds(tv, sv, newTv)); + return newTv; + } + + private static SubstVar updateBounds(JTypeVar tv, SubstVar sv, CapturedTypeVar newTv) { + if (sv == tv) { + return newTv; + } else if (sv instanceof JTypeVar) { + return ((JTypeVar) sv).substInBounds(sv2 -> { + if (sv2 == tv) { + return newTv; + } + return sv2; + }); + } + return sv; + } + static final class RegularTypeVar extends TypeVarImpl { private final @NonNull JTypeParameterSymbol symbol; @@ -173,7 +226,7 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(symbol); + return symbol.hashCode(); } } @@ -181,20 +234,38 @@ static final class CapturedTypeVar extends TypeVarImpl { private static final int PRIME = 997; // largest prime less than 1000 - private final @NonNull JWildcardType wildcard; + private final @Nullable JWildcardType wildcard; + private final @Nullable JTypeVar tvar; private JTypeMirror upperBound; private JTypeMirror lowerBound; - private CapturedTypeVar(JWildcardType wild, PSet typeAnnots) { + private CapturedTypeVar(@NonNull JWildcardType wild, PSet typeAnnots) { this(wild, wild.asLowerBound(), wild.asUpperBound(), typeAnnots); } - private CapturedTypeVar(JWildcardType wild, @NonNull JTypeMirror lower, @NonNull JTypeMirror upper, PSet typeAnnots) { - super(wild.getTypeSystem(), typeAnnots); + private CapturedTypeVar(@Nullable JWildcardType wild, @NonNull JTypeMirror lower, @NonNull JTypeMirror upper, PSet typeAnnots) { + super(lower.getTypeSystem(), typeAnnots); this.upperBound = upper; this.lowerBound = lower; this.wildcard = wild; + this.tvar = null; + } + + private CapturedTypeVar(@Nullable JTypeVar tvar, @NonNull JTypeMirror lower, @NonNull JTypeMirror upper, PSet typeAnnots) { + super(lower.getTypeSystem(), typeAnnots); + this.upperBound = upper; + this.lowerBound = lower; + this.tvar = tvar; + this.wildcard = null; + } + + private CapturedTypeVar(@Nullable JTypeVar tvar, JWildcardType wild, @NonNull JTypeMirror lower, @NonNull JTypeMirror upper, PSet typeAnnots) { + super(lower.getTypeSystem(), typeAnnots); + this.upperBound = upper; + this.lowerBound = lower; + this.tvar = tvar; + this.wildcard = wild; } void setUpperBound(@NonNull JTypeMirror upperBound) { @@ -223,7 +294,7 @@ public boolean isCaptured() { @Override public boolean isCaptureOf(JWildcardType wildcard) { - return this.wildcard.equals(wildcard); + return this.wildcard != null && this.wildcard.equals(wildcard); } @Override @@ -233,11 +304,13 @@ public JWildcardType getCapturedOrigin() { @Override public JTypeVar substInBounds(Function substitution) { - JWildcardType wild = this.wildcard.subst(substitution); + JWildcardType wild = this.wildcard == null ? null : this.wildcard.subst(substitution); JTypeMirror lower = getLowerBound().subst(substitution); JTypeMirror upper = getUpperBound().subst(substitution); if (wild == this.wildcard && lower == this.lowerBound && upper == this.lowerBound) { return this; + } else if (wild == null) { + return new CapturedTypeVar(tvar, lower, upper, typeAnnots); } return new CapturedTypeVar(wild, lower, upper, getTypeAnnotations()); } @@ -253,13 +326,12 @@ public JTypeVar withAnnotations(PSet newTypeAnnots) { if (newTypeAnnots.isEmpty() && typeAnnots.isEmpty()) { return this; } - return new CapturedTypeVar(wildcard, lowerBound, upperBound, newTypeAnnots); + return new CapturedTypeVar(tvar, wildcard, lowerBound, upperBound, newTypeAnnots); } @Override public JTypeVar withUpperBound(@NonNull JTypeMirror newUB) { - AssertionUtil.requireParamNotNull("upper bound", newUB); - return new CapturedTypeVar(wildcard, lowerBound, newUB, getTypeAnnotations()); + throw new UnsupportedOperationException("This only needs to be implemented on regular type variables"); } @Override @@ -274,12 +346,13 @@ public JTypeVar withUpperBound(@NonNull JTypeMirror newUB) { @Override public @Nullable JTypeParameterSymbol getSymbol() { - return null; + return tvar == null ? null : tvar.getSymbol(); } @Override public @NonNull String getName() { - return "capture#" + hashCode() % PRIME + " of " + wildcard; + Object captureOrigin = wildcard == null ? tvar : wildcard; + return "capture#" + hashCode() % PRIME + " of " + captureOrigin; } } } diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/AstTestUtil.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/AstTestUtil.kt index e5c04d1ac59..61b2287ff69 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/AstTestUtil.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/AstTestUtil.kt @@ -27,6 +27,6 @@ fun JavaNode.ctorCalls(): DescendantNodeStream = descendants fun JavaNode.firstCtorCall() = ctorCalls().crossFindBoundaries().firstOrThrow() fun JavaNode.typeVariables(): MutableList = descendants(ASTTypeParameter::class.java).crossFindBoundaries().toList { it.typeMirror } -fun JavaNode.varAccesses(name: String): NodeStream = descendants(ASTVariableAccess::class.java).filter { it.name == name } +fun JavaNode.varAccesses(name: String): NodeStream = descendants(ASTVariableAccess::class.java).crossFindBoundaries().filter { it.name == name } fun JavaNode.varId(name: String) = descendants(ASTVariableId::class.java).filter { it.name == name }.firstOrThrow() -fun JavaNode.typeVar(name: String) = descendants(ASTTypeParameter::class.java).filter { it.name == name }.firstOrThrow().typeMirror +fun JavaNode.typeVar(name: String) = descendants(ASTTypeParameter::class.java).crossFindBoundaries().filter { it.name == name }.firstOrThrow().typeMirror diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/CaptureTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/CaptureTest.kt index a686a7436ad..d5168dba956 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/CaptureTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/CaptureTest.kt @@ -7,9 +7,12 @@ package net.sourceforge.pmd.lang.java.types import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe +import io.kotest.matchers.types.shouldBeSameInstanceAs +import net.sourceforge.pmd.lang.java.ast.ASTVariableId import net.sourceforge.pmd.lang.java.symbols.internal.asm.createUnresolvedAsmSymbol -import net.sourceforge.pmd.lang.java.types.TypeConversion.* +import net.sourceforge.pmd.lang.java.types.TypeConversion.capture import net.sourceforge.pmd.lang.test.ast.IntelliMarker +import net.sourceforge.pmd.lang.test.ast.shouldBeA /** * @author Clรฉment Fournier @@ -88,6 +91,39 @@ class CaptureTest : IntelliMarker, FunSpec({ capture(type) shouldBe box[captureMatcher(`?` extends child)] } + test("Capture of recursive types #5096") { + val acu = javaParser.parse( + """ + + class Child> { + Child(C t) { + super(t); // <-- The bug is triggered by capture of the `t` here + } + } + """.trimIndent() + ) + + val (child) = acu.declaredTypeSignatures() + + val parm = acu.descendants(ASTVariableId::class.java).firstOrThrow() + + parm shouldHaveType child.typeArgs[0] + val captured = capture(parm.typeMirror) + captured.shouldBeA { + it.isCaptured shouldBe true // its bounds are captured + + it.upperBound.shouldBeA { + it.symbol shouldBe child.symbol + it.typeArgs[0].shouldBeA { cvar -> + cvar.isCaptured shouldBe true + cvar.upperBound.shouldBeSameInstanceAs(captured) + } + } + } + } + + + } } diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/GlbTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/GlbTest.kt index d2446498638..a911cc49412 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/GlbTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/GlbTest.kt @@ -186,6 +186,29 @@ class GlbTest : FunSpec({ it.components.shouldContainExactly(tA, tB) } } + + test("Test GLB of recursive types #5096") { + val (acu, _) = javaParser.parseWithTypeInferenceSpy( + """ + abstract class Settings, B extends Settings.Builder> implements Serializable { + + abstract static class Builder, S extends Settings> extends DomainObjectBuilder> { + + protected Builder(S bound, boolean boundToInstance) { + super(bound, boundToInstance); + } + } + + static class Modification> implements DomainObjectModification { + } + } + """.trimIndent() + ) + + acu.varAccesses("bound").firstOrThrow().typeMirror.shouldBeA { + it.symbol shouldBe acu.typeVar("S").symbol + } + } } } From afe0960d7a9c79e801d6af2c7035e9c950838310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 5 Dec 2024 14:24:57 +0100 Subject: [PATCH 0339/1962] Update PULL_REQUEST_TEMPLATE.md --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 41efb1e92c5..d7f130be116 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -6,7 +6,7 @@ -- Fixes # +- Fix # ## Ready? From 375df89d72be2bdb1a1471e1b0476d88e284f2d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 5 Dec 2024 16:56:50 +0100 Subject: [PATCH 0340/1962] Remove `@InternalApi`, keep this for later --- .../java/net/sourceforge/pmd/lang/java/types/JTypeVar.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/JTypeVar.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/JTypeVar.java index ee9059d8779..c702168864d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/JTypeVar.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/JTypeVar.java @@ -14,7 +14,6 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.pcollections.PSet; -import net.sourceforge.pmd.annotation.InternalApi; import net.sourceforge.pmd.lang.java.symbols.JMethodSymbol; import net.sourceforge.pmd.lang.java.symbols.JTypeParameterSymbol; import net.sourceforge.pmd.lang.java.symbols.SymbolicValue.SymAnnot; @@ -116,7 +115,6 @@ default T acceptVisitor(JTypeVisitor visitor, P p) { * *

    Note that this is only supposed to be used internally. */ - @InternalApi JTypeVar cloneWithBounds(JTypeMirror lower, JTypeMirror upper); /** @@ -132,7 +130,6 @@ default T acceptVisitor(JTypeVisitor visitor, P p) { * * @return a new tvar */ - @InternalApi JTypeVar withUpperBound(@NonNull JTypeMirror newUB); @Override // refine return type From a79c9298a06acfce0fa25ceb3f0d30b471f508fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 03:45:18 +0000 Subject: [PATCH 0341/1962] Bump com.google.protobuf:protobuf-java from 4.28.2 to 4.29.1 Bumps [com.google.protobuf:protobuf-java](https://github.com/protocolbuffers/protobuf) from 4.28.2 to 4.29.1. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl) - [Commits](https://github.com/protocolbuffers/protobuf/commits) --- updated-dependencies: - dependency-name: com.google.protobuf:protobuf-java dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9db638b955c..d05088c2b3d 100644 --- a/pom.xml +++ b/pom.xml @@ -1085,7 +1085,7 @@ com.google.protobuf protobuf-java - 4.28.2 + 4.29.1 + diff --git a/docs/pages/pmd/userdocs/tools/tools.md b/docs/pages/pmd/userdocs/tools/tools.md index 5f215c10619..882177b3553 100644 --- a/docs/pages/pmd/userdocs/tools/tools.md +++ b/docs/pages/pmd/userdocs/tools/tools.md @@ -47,15 +47,7 @@ Codiga uses PMD to check Java and Apex code. ### GitHub Actions -PMD provides its own GitHub Action, that can be integrated in custom workflows. - -It can execute PMD with your own ruleset against your project. It creates a -[SARIF](https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html) report which is uploaded as a -build artifact. Furthermore, the build can be failed based on the number of violations. - -The action can also be used as a code scanner to create "Code scanning alerts". - -* Homepage: +See [Continuous Integrations plugins](pmd_userdocs_tools_ci.html#github-action) ### TCA From 5577857578d20820810099d5770dd3a0cf9a1e53 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 13 Dec 2024 18:16:45 +0100 Subject: [PATCH 0352/1962] [doc] Update IDE Plugins --- docs/pages/pmd/userdocs/tools/ide-plugins.md | 318 +++++++------------ 1 file changed, 114 insertions(+), 204 deletions(-) diff --git a/docs/pages/pmd/userdocs/tools/ide-plugins.md b/docs/pages/pmd/userdocs/tools/ide-plugins.md index ccd5906d0ba..e05f6b250d5 100644 --- a/docs/pages/pmd/userdocs/tools/ide-plugins.md +++ b/docs/pages/pmd/userdocs/tools/ide-plugins.md @@ -3,6 +3,7 @@ title: IDE Plugins tags: [userdocs, tools] permalink: pmd_userdocs_tools_ide_plugins.html author: David Dixon-Peugh , Andreas Dangel +last_updated: December 2024 (7.9.0) --- ## IDE Integrations @@ -16,143 +17,40 @@ being used by a getResourceAsStream() call to load it out of the PMD jar files. ### Summary - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    IDEHomepageSource CodeMaintainers
    BlueJpmd-bluejTom Copeland
    CodeGuideN/AAustin Moore
    Eclipsegithub: pmd/pmd-eclipsePhilippe Herlin
    qa-Eclipseqa-EclipseChristian Wulf
    eclipse-pmdhttp://acanda.github.io/eclipse-pmd/github: acanda/eclipse-pmdPhilip Graf
    Emacsgithub: pmd/pmd-emacsNascif Abousalh Neto
    Gelgithub: pmd/pmd-misc/pmd-gelAndrei Lumianski
    GradleGradle: The PMD Plugingithub: gradle/gradleGradle.org
    IntelliJ IDEAgithub: amitdev/PMD-IntellijAmit Dev
    IntelliJ IDEA - QAPlughttp://qaplug.com/N/AJakub Sล‚awiล„ski
    JBuildergithub: pmd/pmd-misc/pmd-jbuilderTom Copeland
    JCreatorN/ABrant Gurganus
    JDevelopergithub: pmd/pmd-jdeveloperTorsten Kleiber
    JEditjEdit - PMD Pluginsourceforge: jedit/PMDPluginJiger Patel, Dale Anson
    NetBeansSQEgithub: sqe-team/sqeN/A
    TextPadN/AJeff Epstein
    WebLogic Workshop 8.1.xN/AKevin Conaway
    - - +Status column: +* ๐ŸŸข = Supports at least PMD 7, latest release not older than 12 months. +* ๐Ÿ”ด = Doesn't support PMD 7 or the latest release is older than 12 months, indicating that this plugin is not actively maintained anymore. + +| IDE | Plugin Name / Marketplace Link | Status | Homepage | Source Code | More Info | +|--------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------|:-------|-----------------------------------------------------------|-----------------------------------------------------------------------------------------------------|---------------------------------------------| +| [Apache NetBeans](https://netbeans.apache.org/index.html) | SQE - Software Quality Environment | ๐Ÿ”ด | [sqe-team](https://sqe-team.github.io/) | [github: sqe-team/sqe](https://github.com/sqe-team/sqe) | | +| [Apache NetBeans](https://netbeans.apache.org/index.html) | EasyPmd | ๐Ÿ”ด | | [github: giancosta86/EasyPmd](https://github.com/giancosta86/EasyPmd) | | +| [BlueJ](https://bluej.org/) | pmd-bluej | ๐Ÿ”ด | | [github: pmd/bluej](https://github.com/pmd/pmd-bluej) | [โ†“ see below](#bluej) | +| [Eclipse IDE](https://eclipseide.org/) | [eclipse-pmd](https://marketplace.eclipse.org/content/eclipse-pmd) | ๐ŸŸข | [eclipse-pmd](https://eclipse-pmd.acanda.ch/) | [github: eclipse-pmd/eclipse-pmd](https://github.com/eclipse-pmd/eclipse-pmd) | | +| [Eclipse IDE](https://eclipseide.org/) | [pmd-eclipse-plugin](https://marketplace.eclipse.org/content/pmd-eclipse-plugin) | ๐ŸŸข | | [github: pmd/pmd-eclipse-plugin](https://github.com/pmd/pmd-eclipse-plugin) | [โ†“ see below](#pmd-eclipse-plugin) | +| [Eclipse IDE](https://eclipseide.org/) | qa-eclipse-plugin | ๐Ÿ”ด | | [github: ChristianWulf/qa-eclipse-plugin](https://github.com/ChristianWulf/qa-eclipse-plugin) | | +| [Emacs](https://www.gnu.org/software/emacs/) | pmd-emacs | ๐Ÿ”ด | | [github: pmd/pmd-emacs](https://github.com/pmd/pmd-emacs/) | | +| [Emacs](https://www.gnu.org/software/emacs/) | emacs-pmd | ๐Ÿ”ด | [emacs-pmd](http://yrk.nfshost.com/projects/emacs-pmd/) | [yrk.nfshost.com/projects/emacs-pmd/](http://yrk.nfshost.com/projects/emacs-pmd/) | [โ†“ see below](#emacs) | +| [IntelliJ IDEA](https://www.jetbrains.com/idea/) | [PMD](https://plugins.jetbrains.com/plugin/1137-pmd) | ๐ŸŸข | | [github: amitdev/PMD-Intellij](https://github.com/amitdev/PMD-Intellij) | | +| [IntelliJ IDEA](https://www.jetbrains.com/idea/) | [QAPlug - PMD](https://plugins.jetbrains.com/plugin/4596-qaplug--pmd) | ๐Ÿ”ด | [QA Plug โ€“ quality assurance plugin](https://qaplug.com/) | | [โ†“ see below](#intellij-idea---qaplug) | +| [IntelliJ IDEA](https://www.jetbrains.com/idea/) | none - external tool | | | | [โ†“ see below](#intellij-idea-external-tool) | +| [Oracle JDeveloper](https://www.oracle.com/application-development/technologies/jdeveloper.html) | pmd-jdeveloper | ๐Ÿ”ด | | [github: pmd/pmd-jdeveloper](https://github.com/pmd/pmd-jdeveloper) | [โ†“ see below](#jdeveloper) | +| [jEdit](https://www.jedit.org/) | [PMDPlugin](https://plugins.jedit.org/plugins/?PMDPlugin) | ๐Ÿ”ด | | [sourceforge: jedit/PMDPlugin](https://sourceforge.net/p/jedit/PMDPlugin/ci/master/tree/) | [โ†“ see below](#jedit) | +| [TextPad](https://www.textpad.com/home) | none - external tool | | | | [โ†“ see below](#textpad) | +| [Visual Studio Code](https://code.visualstudio.com/) | [Apex PMD](https://marketplace.visualstudio.com/items?itemName=chuckjonas.apex-pmd) | ๐ŸŸข | | [github: ChuckJonas/vscode-apex-pmd](https://github.com/ChuckJonas/vscode-apex-pmd) | | +| [Visual Studio Code](https://code.visualstudio.com/) | [VSCode Apex PMD](https://marketplace.visualstudio.com/items?itemName=mohanChinnappan.apex-pmd-code-scanner) | ๐Ÿ”ด | | [github: mohan-chinnappan-n/vscode-apex-pmd](https://github.com/mohan-chinnappan-n/vscode-apex-pmd) | | +| [Visual Studio Code](https://code.visualstudio.com/) | [PMD CPD](https://marketplace.visualstudio.com/items?itemName=nwcm.pmd-cpd) | ๐ŸŸข | | [github: nwcm/vscode-pmd-cpd](https://github.com/nwcm/vscode-pmd-cpd) | | +| [Visual Studio Code](https://code.visualstudio.com/) | [PMD for Java](https://marketplace.visualstudio.com/items?itemName=cracrayol.pmd-java) | ๐ŸŸข | | [github: cracrayol/vscode-java-pmd](https://github.com/cracrayol/vscode-java-pmd) | | +| [Visual Studio Code](https://code.visualstudio.com/) | [Alibaba Java Coding Guidelines](https://marketplace.visualstudio.com/items?itemName=yangbaopan.vscode-java-p3c) | ๐Ÿ”ด | | | | +| [Visual Studio Code](https://code.visualstudio.com/) | vscode-pmd-daemon | | | [github: hvbargen/vscode-pmd-daemon](https://github.com/hvbargen/vscode-pmd-daemon) | | ### BlueJ -[BlueJ](http://bluej.org/) is a teaching IDE. To install the PMD extension for BlueJ, download -the [PMDExtension jar file](http://sourceforge.net/projects/pmd/files/pmd-bluej/pmd-bluej-1.0/) +[BlueJ](https://bluej.org/) is a teaching IDE. To install the PMD extension for BlueJ, download +the [PMDExecExt.jar file](https://github.com/pmd/pmd-bluej/releases/latest) and place it in your `bluej/lib/extensions/` directory. -### Eclipse +### PMD Eclipse Plugin To install the PMD plugin for Eclipse: @@ -192,33 +90,10 @@ The output is captured in a compilation buffer which allows the user to "jump" directly to the source code position associated with the PMD warnings. -### Gel - -Here's how to set up the Gel plugin: - -* Download the pmd-gel-[version].zip file -* Close Gel -* Remove any old plugin versions from your gel\plugins directory -* Unzip the new zip file into your gel\plugins directory -* Start Gel -* Go to Tools->Options->Plugin -* Select the PMD plugin and click "Remove" -* Click "Add" and select "net.sourceforge.pmd.gel.PMDPlugin" -* Restart Gel - -That's pretty much it. Now you can open a Java project and click on Plugins->PMD and -a configuration panel will pop up. You can pick which ruleset you want to run and -you can also pick whether you want to run PMD on the current file or on every -source file in your project. - - -### IDEA +### IntelliJ IDEA External Tool You can use an integrated plugin or just use it as an IDEA "External Tool". -Amit Dev wrote an integrated plugin for IDEA; you can download that -[from the IntelliJ plugins site](http://plugins.jetbrains.com/idea/plugin/1137-pmdplugin). - Here's how to set it up as an "External Tool": * Open IDEA and go to File->Settings @@ -241,56 +116,15 @@ right-click on the message window title bar and unselect "autohide" so the windo away every time I fix something in the code window. -### IDEA - QAPlug +### IntelliJ IDEA - QAPlug QAPlug is an Intellij IDEA plugin to manage code quality. It integrates no less than Checkstyle, FindBugs, and PMD. -The plugin is available at . +The plugin is available at . Also available at the JetBrains site, [QAPlug-PMD](http://plugins.jetbrains.com/idea/plugin/4596-qaplug--pmd) and [QAPlug](http://plugins.jetbrains.com/idea/plugin/4594-qaplug). - -### JBuilder - -To enable this OpenTool in JBuilder: - -* Download the [latest binary release](https://sourceforge.net/projects/pmd/files/pmd-jbuilder/) -* Unzip it into your `jbuilder/lib/ext/` directory -* Restart JBuilder - -What you can do: - -* Check a single file by bringing up the context menu from the file tab and selecting PMDCheck -* Configure the rulesets that the PMD OpenTool will use by selecting Tools->PMD->Configure PMD -* Check all the files in a project by bringing up the context menu for - the project node and selecting PMD Check Project -* Locate duplicate code by right clicking on a package and selection "Check with CPD" - -When running PMD, the results will be displayed in the MessageView under a tab called PMD Results. If you click on a -violation message within this view, you will be taken to the line in the source code where the violation was detected. - -Things still to do: - -* Enable selection of individual rules within a rule set (maybe) -* Optional insertion of @todo comments at the point of a violation -* Possibly provide configurable ability to limit the number of violations per rule per file - - -### JCreator - -1. Open Configure > Options -2. Go to the Tools panel -3. Click New > Program -4. Browse for PMD's pmd.bat -5. Put quotations around the path if it has spaces. -6. Set the initial directory to PMD's \bin directory -7. Check capture output -8. Put '"$[PrjDir]" emacs' followed by desired rulesets in the arguments - -To run PMD on a project, just pick pmd from the Tools menu. - - ### JDeveloper To install the PMD plugin for JDeveloper: @@ -331,11 +165,6 @@ Also, you can change the plugin to prompt you for a directory to check by going selecting the "Ask for Directory" checkbox. -### NetBeans - -The [SQE](http://kenai.com/projects/sqe/) project includes PMD integration for NetBeans. - - ### TextPad **Assumptions** @@ -411,6 +240,87 @@ The [SQE](http://kenai.com/projects/sqe/) project includes PMD integration for N the (blank Command Results) document, and then confirming that, "yes, I do really want to exit the tool". + + +## Archived Integrations + +These are integrations that are no longer maintained or for IDEs that no longer exist. + +### CodeGuide + +CodeGuide was a Java IDE by omnicore: + +### Gel + +Gel was once an IDE: + +Source code for the PMD plugin is here: + +Here's how to set up the Gel plugin: + +* Download the pmd-gel-[version].zip file +* Close Gel +* Remove any old plugin versions from your gel\plugins directory +* Unzip the new zip file into your gel\plugins directory +* Start Gel +* Go to Tools->Options->Plugin +* Select the PMD plugin and click "Remove" +* Click "Add" and select "net.sourceforge.pmd.gel.PMDPlugin" +* Restart Gel + +That's pretty much it. Now you can open a Java project and click on Plugins->PMD and +a configuration panel will pop up. You can pick which ruleset you want to run and +you can also pick whether you want to run PMD on the current file or on every +source file in your project. + +### JBuilder + +Was once a IDE by Borland (later Embarcadero): see and + + +Source code for the plugin is here: + +To enable this OpenTool in JBuilder: + +* Download the [latest binary release](https://sourceforge.net/projects/pmd/files/pmd-jbuilder/) +* Unzip it into your `jbuilder/lib/ext/` directory +* Restart JBuilder + +What you can do: + +* Check a single file by bringing up the context menu from the file tab and selecting PMDCheck +* Configure the rulesets that the PMD OpenTool will use by selecting Tools->PMD->Configure PMD +* Check all the files in a project by bringing up the context menu for + the project node and selecting PMD Check Project +* Locate duplicate code by right clicking on a package and selection "Check with CPD" + +When running PMD, the results will be displayed in the MessageView under a tab called PMD Results. If you click on a +violation message within this view, you will be taken to the line in the source code where the violation was detected. + +Things still to do: + +* Enable selection of individual rules within a rule set (maybe) +* Optional insertion of @todo comments at the point of a violation +* Possibly provide configurable ability to limit the number of violations per rule per file + +### JCreator + +Was once a IDE: + +1. Open Configure > Options +2. Go to the Tools panel +3. Click New > Program +4. Browse for PMD's pmd.bat +5. Put quotations around the path if it has spaces. +6. Set the initial directory to PMD's \bin directory +7. Check capture output +8. Put '"$[PrjDir]" emacs' followed by desired rulesets in the arguments + +To run PMD on a project, just pick pmd from the Tools menu. + ### WebLogic Workshop 8.1.x +That's a plugin for an old version of Bea WebLogic Workshop 8.1.x (which is now available from Oracle). +The new versions are based on Eclipse and don't require this plugin anymore. + Please see [the WebLogic Workshop plugin project home page](http://pmdwlw.sf.net/) for more information. From a4598cb1b8d3fcabe8d5a9a0abc7f748fd7fe223 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 13 Dec 2024 18:17:30 +0100 Subject: [PATCH 0353/1962] [doc] Move MegaLinter to Tools, add CodeClimate and SonarQube PMD --- docs/pages/pmd/userdocs/tools/ci.md | 15 ++------------ docs/pages/pmd/userdocs/tools/tools.md | 27 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/docs/pages/pmd/userdocs/tools/ci.md b/docs/pages/pmd/userdocs/tools/ci.md index 0e26791b079..431e26ad1fe 100644 --- a/docs/pages/pmd/userdocs/tools/ci.md +++ b/docs/pages/pmd/userdocs/tools/ci.md @@ -3,7 +3,7 @@ title: Continuous Integrations plugins tags: [userdocs, tools] permalink: pmd_userdocs_tools_ci.html author: Romain PELISSE , Andreas Dangel -last_updated: December 2024 +last_updated: December 2024 (7.9.0) --- ## Introduction @@ -45,6 +45,7 @@ build artifact. Furthermore, the build can be failed based on the number of viol The action can also be used as a code scanner to create "Code scanning alerts". * Homepage: +* Marketplace: ## GitLab @@ -69,15 +70,3 @@ PMD among many other linting tools. * Homepage: * Source: and - - - -## MegaLinter - -[๐Ÿฆ™ Mega-Linter](https://oxsecurity.github.io/megalinter/latest/) analyzes 50 languages, 22 formats, 21 tooling -formats, excessive copy-pastes, spelling mistakes and security issues in your repository sources with a -GitHub Action, other CI tools or locally. - -It [natively embeds PMD](https://oxsecurity.github.io/megalinter/latest/descriptors/java_pmd/). - - diff --git a/docs/pages/pmd/userdocs/tools/tools.md b/docs/pages/pmd/userdocs/tools/tools.md index 882177b3553..924b3b03bed 100644 --- a/docs/pages/pmd/userdocs/tools/tools.md +++ b/docs/pages/pmd/userdocs/tools/tools.md @@ -3,12 +3,22 @@ title: Tools / Integrations tags: [userdocs, tools] permalink: pmd_userdocs_tools.html author: David Dixon-Peugh +last_updated: December 2024 (7.9.0) --- ## Automated Code Review {% include note.html content="The tools are listed in alphabetical order without rating." %} +### CodeClimate Quality + +[CodeClimate Quality](https://codeclimate.com/quality) provides automatic code reviews and quality +monitoring of your projects. Among many SCA tools, it integrates [PMD as a plugin](https://docs.codeclimate.com/docs/pmd). +It integrates into your project via GitHub. + +* Homepage: +* Documentation: + ### Codacy [Codacy](https://www.codacy.com/) automates code reviews and monitors code quality on every commit and pull request. @@ -19,6 +29,7 @@ Codacy is static analysis without the hassle. With Codacy you have PMDJava analysis out-of-the-box, and it is free for open source projects. * Homepage: +* Documentation: * Source code: * Maintainer: Codacy @@ -67,3 +78,19 @@ With TCA you have PMD analysis out-of-the-box, and it is open source under the M * Source code: * Documentation: * Maintainer: TCA + +## Others + +### MegaLinter + +[๐Ÿฆ™ Mega-Linter](https://megalinter.io/latest/) analyzes 50 languages, 22 formats, 21 tooling +formats, excessive copy-pastes, spelling mistakes and security issues in your repository sources with a +GitHub Action, other CI tools or locally. + +It [natively embeds PMD](https://megalinter.io/latest/descriptors/java_pmd/). + +### SonarQube PMD Plugin + +[sonar-pmd](https://github.com/jborgers/sonar-pmd) is a plugin for [SonarQube](https://www.sonarsource.com/products/sonarqube/), +that provides coding rules from PMD. + From 4bcc790c8278eae7e8084d5b9ee8fefc3b8f4f70 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 13 Dec 2024 18:17:46 +0100 Subject: [PATCH 0354/1962] [doc] Add Alibaba p3c ruleset --- docs/pages/pmd/userdocs/3rdpartyrulesets.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/pages/pmd/userdocs/3rdpartyrulesets.md b/docs/pages/pmd/userdocs/3rdpartyrulesets.md index 92ebd1784b5..949dd0d5ff9 100644 --- a/docs/pages/pmd/userdocs/3rdpartyrulesets.md +++ b/docs/pages/pmd/userdocs/3rdpartyrulesets.md @@ -5,7 +5,7 @@ language_name: 3rd party rulesets tags: [rule_references, userdocs] summary: Lists rulesets and rules from the community permalink: pmd_userdocs_3rdpartyrulesets.html -last_updated: September 2022 +last_updated: December 2024 (7.9.0) --- ## For Java @@ -21,7 +21,8 @@ last_updated: September 2022 * Sample ruleset from **geotools**, an open source Java library that provides tools for geospatial data. * * - +* **Alibaba p3c**: Implementation of [Alibaba Java Coding Guidelines](https://alibaba.github.io/Alibaba-Java-Coding-Guidelines) + as PMD rules: ## For Apex * **unhappy-soup**, a repository with problematic Salesforce code to showcase PMD, the SFDX Scanner CLI From cdfbd25b1e3838994584e5b9a50c453f4bbcfcbe Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 13 Dec 2024 19:57:32 +0100 Subject: [PATCH 0355/1962] [doc] Update news with new articles --- docs/pages/pmd/projectdocs/trivia/news.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/pages/pmd/projectdocs/trivia/news.md b/docs/pages/pmd/projectdocs/trivia/news.md index 337a11ec6e2..7c176983332 100644 --- a/docs/pages/pmd/projectdocs/trivia/news.md +++ b/docs/pages/pmd/projectdocs/trivia/news.md @@ -2,6 +2,7 @@ title: PMD in the press permalink: pmd_projectdocs_trivia_news.html author: Tom Copeland +last_updated: December 2024 (7.9.0) --- ## Sites/Articles about PMD @@ -9,6 +10,9 @@ author: Tom Copeland ### Salesforce / Apex Language Module +* January 2022 - [Writing Clean and Consistent Code with Static Analysis using PMD and Apex](https://dzone.com/articles/static-analysis-with-pmd-and-apex) + by [Michael Bogan](https://dzone.com/authors/mbogan) + * October 2020 - [Salesforce CLI Scanner Custom XPath Rules - Part 1](https://bobbuzzard.blogspot.com/2020/10/salesforce-cli-scanner-custom-xpath.html), [Salesforce CLI Scanner Custom XPath Rules - Part 2](http://bobbuzzard.blogspot.com/2020/10/salesforce-cli-scanner-custom-xpath_11.html) by [Keir Bowden](https://twitter.com/bob_buzzard) @@ -24,6 +28,9 @@ author: Tom Copeland * June 2018 - [Salesforce Way Podcast](https://salesforceway.com/podcast/podcast/) with [Robert Sรถsemann](https://github.com/rsoesemann) [Static Code Analysis with PMD for Apex](https://salesforceway.com/podcast/podcast/static-code-analysis-with-pmd-for-apex/) +* February 2018 - [Integrating Static Analysis with PMD in the Salesforce Development Lifecycle](https://ktema.org/articles/static-analysis-pmd-salesforce/) + by [David Reed](https://ktema.org/) + * January 2018 - [Webinar: How to contribute Apex rules to PMD with Robert Sรถsemann](https://www.youtube.com/watch?v=7_Ex9WWS_3Q) * August 2017 - Webinar about how to use PMD with The Welkin Suite Salesforce IDE - Author @@ -36,6 +43,9 @@ author: Tom Copeland ### PMD in general and other Language Modules +* October 2024 - Presentation at [Java User Group Munich](https://jugm.de/): [Journey to PMD 7](https://youtu.be/N9b4jobKieQ) + by [Andreas Dangel](https://adangel.org) + * April 2022 - Prediction of who should refactor the code, research available at . @@ -47,8 +57,10 @@ author: Tom Copeland [J-Fall Virtual 2020: Jeroen Borgers - Fixing your performance and concurrency bugs before they bite you]( https://www.youtube.com/watch?v=Z_sT38KTRNk) -* May 2019 - [Code quality assurance with PMD โ€“ An extensible static code analyser for Java and other languages]( - https://www.datarespons.com/code-quality-assurance-with-pmd/) +* April 2019 - [Code quality assurance with PMD โ€“ An extensible static code analyser for Java and other languages](https://adangel.org/2019/04/30/code-quality-assurance-with-pmd/) + by [Andreas Dangel](https://adangel.org) + +* September 2018 - [Setting Up Static Code Analysis for Java](https://medium.com/@mladen.bolic/setting-up-static-code-analysis-for-java-3428dc79f7f9) * February 2012 - Romain Pelisse's lightning talk at FOSDEM 2012 about "PMD5: What can it do for you?". [Video recording is available](http://video.fosdem.org/2012/lightningtalks/PMD5.webm). From 2909e63eeac17e79e5c57397f3885125f4923fa4 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 13 Dec 2024 22:14:19 +0100 Subject: [PATCH 0356/1962] Fix dead link --- docs/pages/pmd/userdocs/pmd_report_formats.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/pmd/userdocs/pmd_report_formats.md b/docs/pages/pmd/userdocs/pmd_report_formats.md index 0b32afb05e4..39873fc11c4 100644 --- a/docs/pages/pmd/userdocs/pmd_report_formats.md +++ b/docs/pages/pmd/userdocs/pmd_report_formats.md @@ -119,7 +119,7 @@ normal source file extensions (e.g. ".java") with ".html", so that the generated IntelliJ IDEA integration. -{% include warning.html content="This format can only be used as described in [Tools: IDEA](pmd_userdocs_tools.html#idea)." %} +{% include warning.html content="This format can only be used as described in [Tools: IntelliJ IDEA External Tool](pmd_userdocs_tools_ide_plugins.html#intellij-idea-external-tool)." %} It has two ways of calling: From 20bc724dbe326fdadb7bdfb6c1db916fbbac5cf0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 14 Dec 2024 20:04:56 +0100 Subject: [PATCH 0357/1962] [java] UnusedPrivateMethod - improve comments --- .../java/rule/bestpractices/UnusedPrivateMethodRule.java | 5 ++++- .../lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml | 3 +-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java index a6a165d0a82..0c739460af1 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java @@ -150,9 +150,12 @@ private boolean hasExcludedName(ASTMethodDeclaration node) { * java.lang types (like Object, or primitive boxes) are * treated specially by the type resolution framework, and * for those the preexisting ASM symbol is preferred over - * the AST symbol. Since it only applies to these types we + * the AST symbol - symbol.tryGetNode() returns null in that + * case. Since it only applies to these types we * check that the package name is java.lang, to avoid doing * that for other types. + * This is only relevant, when PMD is used to analyze OpenJDK + * sources, like with the regression tester. */ private static @Nullable ASTMethodDeclaration findDeclarationInCompilationUnit(ASTCompilationUnit acu, JExecutableSymbol symbol) { if (!"java.lang".equals(acu.getPackageName()) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index 6fd51e6fa04..c9ecabd130c 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2500,8 +2500,7 @@ public class PmdTestCase { - - [java] UnusedPrivateMethod - false positive with static methods in core JDK classes #4861 + #4861 [java] UnusedPrivateMethod - false positive with static methods in core JDK classes 0 Date: Sat, 14 Dec 2024 20:05:09 +0100 Subject: [PATCH 0358/1962] [doc] Update release notes (#4861, #5376) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index fe3fe12e743..5eda7dc889c 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -18,6 +18,8 @@ This is a {{ site.pmd.release_type }} release. * cli * [#5399](https://github.com/pmd/pmd/issues/5399): \[cli] Windows: PMD fails to start with special characters in path names * [#5401](https://github.com/pmd/pmd/issues/5401): \[cli] Windows: Console output doesn't use unicode +* java-bestpractices + * [#4861](https://github.com/pmd/pmd/issues/4861): \[java] UnusedPrivateMethod - false positive with static methods in core JDK classes ### ๐Ÿšจ API Changes From f825c096d50f71aea7569af041c2241f279845f7 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 14 Nov 2024 16:35:36 +0100 Subject: [PATCH 0359/1962] Bump apex-parser from 4.3.0 to 4.3.1 See https://github.com/apex-dev-tools/apex-parser/releases/tag/v4.3.1 --- pmd-apex/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index b4806807e84..ba3ba7b6c44 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -96,7 +96,7 @@ io.github.apex-dev-tools apex-parser - 4.3.0 + 4.3.1 com.google.summit From 610c28dd65e2d4ec8c6c20c18104b9c934742c5b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 22 Nov 2024 17:19:54 +0100 Subject: [PATCH 0360/1962] Fix test after apex-parser upgrade --- .../java/net/sourceforge/pmd/lang/apex/ast/ApexLexerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexLexerTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexLexerTest.java index 22104ac4010..0d456d29559 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexLexerTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexLexerTest.java @@ -58,7 +58,7 @@ void testParser() { void testLexerUnicodeEscapes() { String s = "'Fran\\u00E7ois'"; // note: with apex-parser 4.3.1, no errors are reported anymore - assertEquals(2, getLexingErrors(CharStreams.fromString(s))); + assertEquals(0, getLexingErrors(CharStreams.fromString(s))); assertEquals(0, getLexingErrors(new CaseInsensitiveInputStream(CharStreams.fromString(s)))); } From fa8689d7b39cae6c66d26f7362a258196c958ddb Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 14 Dec 2024 20:24:11 +0100 Subject: [PATCH 0361/1962] Bump apex-parser from 4.3.1 to 4.4.0 --- pmd-apex/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index ba3ba7b6c44..5ce3d53926a 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -96,7 +96,7 @@ io.github.apex-dev-tools apex-parser - 4.3.1 + 4.4.0 com.google.summit From ea3b5f414734efd19a0cd84f9546c99e38e636a6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 14 Dec 2024 20:31:01 +0100 Subject: [PATCH 0362/1962] Fix duplicated antrun plugin declaration --- pmd-javascript/pom.xml | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index 7d21f8d640f..6070f32408f 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -46,22 +46,7 @@ - - - - maven-resources-plugin - - false - - ${*} - - - - - org.apache.maven.plugins - maven-antrun-plugin - generate-sources generate-sources @@ -81,6 +66,15 @@ + + maven-resources-plugin + + false + + ${*} + + + org.codehaus.mojo From b5027dd1d9aea08da8ef0cdf2c304f2d794991dd Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 15 Dec 2024 17:57:29 +0100 Subject: [PATCH 0363/1962] [doc] Update release notes (#5096, #5387) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 26ec825d013..b354b815ddb 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -15,6 +15,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* java + * [#5096](https://github.com/pmd/pmd/issues/5096): \[java] StackOverflowError with recursively bound type variable ### ๐Ÿšจ API Changes From 25f7748d0b2317d3cf9162745d6e42e615d83625 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 03:41:32 +0000 Subject: [PATCH 0364/1962] Bump org.yaml:snakeyaml from 2.2 to 2.3 Bumps [org.yaml:snakeyaml](https://bitbucket.org/snakeyaml/snakeyaml) from 2.2 to 2.3. - [Commits](https://bitbucket.org/snakeyaml/snakeyaml/branches/compare/snakeyaml-2.3..snakeyaml-2.2) --- updated-dependencies: - dependency-name: org.yaml:snakeyaml dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 422e654637e..82c21507358 100644 --- a/pom.xml +++ b/pom.xml @@ -892,7 +892,7 @@ org.yaml snakeyaml - 2.2 + 2.3 com.google.guava From b7bc3336c12c18c25db224afac1f36f9aad97c37 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 03:41:38 +0000 Subject: [PATCH 0365/1962] Bump io.github.apex-dev-tools:apex-ls_2.13 from 5.5.0 to 5.7.0 Bumps [io.github.apex-dev-tools:apex-ls_2.13](https://github.com/apex-dev-tools/apex-ls) from 5.5.0 to 5.7.0. - [Release notes](https://github.com/apex-dev-tools/apex-ls/releases) - [Commits](https://github.com/apex-dev-tools/apex-ls/compare/v5.5.0...v5.7.0) --- updated-dependencies: - dependency-name: io.github.apex-dev-tools:apex-ls_2.13 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pmd-apex/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index b4806807e84..6b0776fc4f4 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -106,7 +106,7 @@ io.github.apex-dev-tools apex-ls_2.13 - 5.5.0 + 5.7.0 From 14117cfa489e50804af3b4c7e058a8978ade15bd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 03:41:45 +0000 Subject: [PATCH 0366/1962] Bump net.bytebuddy:byte-buddy-agent from 1.14.19 to 1.15.11 Bumps [net.bytebuddy:byte-buddy-agent](https://github.com/raphw/byte-buddy) from 1.14.19 to 1.15.11. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.14.19...byte-buddy-1.15.11) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy-agent dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 422e654637e..3f164e6ed08 100644 --- a/pom.xml +++ b/pom.xml @@ -995,7 +995,7 @@ net.bytebuddy byte-buddy-agent - 1.14.19 + 1.15.11 test From b56bec3e313de379e4df45b614ef552e806976e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 03:42:03 +0000 Subject: [PATCH 0367/1962] Bump net.bytebuddy:byte-buddy from 1.15.10 to 1.15.11 Bumps [net.bytebuddy:byte-buddy](https://github.com/raphw/byte-buddy) from 1.15.10 to 1.15.11. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.15.10...byte-buddy-1.15.11) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 422e654637e..0668e8bcd15 100644 --- a/pom.xml +++ b/pom.xml @@ -989,7 +989,7 @@ net.bytebuddy byte-buddy - 1.15.10 + 1.15.11 test From 5f1944c2eb0070785d14f627de979b92fcffa50f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 03:42:07 +0000 Subject: [PATCH 0368/1962] Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.6.3 to 3.11.2 Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.6.3 to 3.11.2. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.6.3...maven-javadoc-plugin-3.11.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 422e654637e..404af9af9e4 100644 --- a/pom.xml +++ b/pom.xml @@ -103,7 +103,7 @@ 3.5.0 3.26.0 1.10.15 - 3.6.3 + 3.11.2 4.9.3 1.7.36 12.5 From cdcbcb55a3df89cf735cb5eb7432c575226ecd0d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 04:01:34 +0000 Subject: [PATCH 0369/1962] Bump csv in /docs in the all-gems group across 1 directory Bumps the all-gems group with 1 update in the /docs directory: [csv](https://github.com/ruby/csv). Updates `csv` from 3.3.0 to 3.3.1 - [Release notes](https://github.com/ruby/csv/releases) - [Changelog](https://github.com/ruby/csv/blob/master/NEWS.md) - [Commits](https://github.com/ruby/csv/compare/v3.3.0...v3.3.1) --- updated-dependencies: - dependency-name: csv dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all-gems ... Signed-off-by: dependabot[bot] --- docs/Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index a3323923f79..af709969d26 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -26,7 +26,7 @@ GEM commonmarker (0.23.10) concurrent-ruby (1.3.4) connection_pool (2.4.1) - csv (3.3.0) + csv (3.3.1) dnsruby (1.72.2) simpleidn (~> 0.2.1) drb (2.2.1) From 4e61eb546ac2a115573f4b3556d6ef22a55f0a42 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 17 Dec 2024 11:43:06 +0100 Subject: [PATCH 0370/1962] [apex] Verify #5388 is fixed after updating apex-parser --- docs/pages/release_notes.md | 2 ++ .../pmd/lang/apex/ast/ApexTreeDumpTest.java | 8 ++++++++ .../pmd/lang/apex/ast/TimeLiteralsInSoql.cls | 5 +++++ .../pmd/lang/apex/ast/TimeLiteralsInSoql.txt | 15 +++++++++++++++ 4 files changed, 30 insertions(+) create mode 100644 pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/TimeLiteralsInSoql.cls create mode 100644 pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/TimeLiteralsInSoql.txt diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 5eda7dc889c..99b25913d6a 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -15,6 +15,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* apex + * [#5388](https://github.com/pmd/pmd/issues/5388): \[apex] Parse error with time literal in SOQL query * cli * [#5399](https://github.com/pmd/pmd/issues/5399): \[cli] Windows: PMD fails to start with special characters in path names * [#5401](https://github.com/pmd/pmd/issues/5401): \[cli] Windows: Console output doesn't use unicode diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexTreeDumpTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexTreeDumpTest.java index 1f5b2618fe0..7986aa22ce3 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexTreeDumpTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexTreeDumpTest.java @@ -110,4 +110,12 @@ void nestedSubqueries() { void convertCurrencyInSoqlAndSosl() { doTest("ConvertCurrencyInSoqlAndSosl"); } + + /** + * @see [apex] Parse error with time literal in SOQL query + */ + @Test + void timeLiteralsInSoql() { + doTest("TimeLiteralsInSoql"); + } } diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/TimeLiteralsInSoql.cls b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/TimeLiteralsInSoql.cls new file mode 100644 index 00000000000..65e447256af --- /dev/null +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/TimeLiteralsInSoql.cls @@ -0,0 +1,5 @@ +public class PmdTest { + void runSoql() { + Object o = [SELECT Break__c,Check_Out__c FROM VMS_Time_Card_Item__c WHERE Time_Card__c =:timeCard.Id AND Check_Out__c = 01:00:00.000Z]; + } +} diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/TimeLiteralsInSoql.txt b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/TimeLiteralsInSoql.txt new file mode 100644 index 00000000000..e181c548f30 --- /dev/null +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/TimeLiteralsInSoql.txt @@ -0,0 +1,15 @@ ++- ApexFile[@DefiningType = "PmdTest", @RealLoc = true] + +- UserClass[@DefiningType = "PmdTest", @Image = "PmdTest", @InterfaceNames = (), @Nested = false, @RealLoc = true, @SimpleName = "PmdTest", @SuperClassName = ""] + +- ModifierNode[@Abstract = false, @DefiningType = "PmdTest", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] + +- Method[@Arity = 0, @CanonicalName = "runSoql", @Constructor = false, @DefiningType = "PmdTest", @Image = "runSoql", @RealLoc = true, @ReturnType = "void", @StaticInitializer = false] + +- ModifierNode[@Abstract = false, @DefiningType = "PmdTest", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] + +- BlockStatement[@CurlyBrace = true, @DefiningType = "PmdTest", @RealLoc = true] + +- VariableDeclarationStatements[@DefiningType = "PmdTest", @RealLoc = true] + +- ModifierNode[@Abstract = false, @DefiningType = "PmdTest", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] + +- VariableDeclaration[@DefiningType = "PmdTest", @Image = "o", @RealLoc = true, @Type = "Object"] + +- SoqlExpression[@CanonicalQuery = "SELECT Break__c,Check_Out__c FROM VMS_Time_Card_Item__c WHERE Time_Card__c =:tmpVar1 AND Check_Out__c = 01:tmpVar2:tmpVar3", @DefiningType = "PmdTest", @Query = "SELECT Break__c,Check_Out__c FROM VMS_Time_Card_Item__c WHERE Time_Card__c =:timeCard.Id AND Check_Out__c = 01:00:00.000Z", @RealLoc = true] + | +- BindExpressions[@DefiningType = "PmdTest", @RealLoc = true] + | +- VariableExpression[@DefiningType = "PmdTest", @Image = "Id", @RealLoc = true] + | +- ReferenceExpression[@DefiningType = "PmdTest", @Image = "timeCard", @RealLoc = true, @ReferenceType = ReferenceType.LOAD, @SObjectType = false, @SafeNav = false] + +- VariableExpression[@DefiningType = "PmdTest", @Image = "o", @RealLoc = true] + +- EmptyReferenceExpression[@DefiningType = null, @RealLoc = false] From cacca53bc1d90a7f80c8dafd9d4f6c35fcd6d23a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 17 Dec 2024 12:48:34 +0100 Subject: [PATCH 0371/1962] Small fixes from review (#4939) --- .../java/net/sourceforge/pmd/reporting/RuleContext.java | 8 ++++---- .../lang/java/rule/documentation/xml/CommentContent.xml | 2 +- .../pmd/lang/java/rule/documentation/xml/CommentSize.xml | 5 +++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java index ec4a714f718..7d38e71117b 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java @@ -152,14 +152,14 @@ public void addViolationWithPosition(Node node, int beginLine, int endLine, Stri * as a format string for a {@link MessageFormat} and should hence use * appropriate escapes. The given formatting arguments are used. * - * @param reportable Location of the violation (node or token) + * @param reportable Location of the violation (node or token) - only used to determine suppression * @param astInfo Info about the root of the tree ({@link Node#getAstInfo()}) + * @param location Report location of the violation * @param message Violation message * @param formatArgs Format arguments for the message - * * @experimental This will probably never be stabilized, will instead be - * replaced by a fluent API or something to report violations. Do not use - * this outside of the PMD codebase. See https://github.com/pmd/pmd/issues/5039. + * replaced by a fluent API or something to report violations. Do not use + * this outside of the PMD codebase. See [core] Add fluent API to report violations #5039. */ @Experimental public void addViolationWithPosition(Reportable reportable, AstInfo astInfo, FileLocation location, diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentContent.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentContent.xml index b5db4316e45..cb44d380bca 100755 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentContent.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentContent.xml @@ -58,7 +58,7 @@ public class Foo { ]]> - Suppression + #2996 Test Suppression idiot|jerk 0 - Suppression + #2996 Test Suppression 2 0 - Not suppressed + #2996 Not suppressed 2 1 + 6 Date: Tue, 17 Dec 2024 12:49:32 +0100 Subject: [PATCH 0372/1962] [doc] Update release notes (#2996, #4939) --- docs/pages/release_notes.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 1d3c202acd5..8a6fbe267cb 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -22,9 +22,15 @@ This is a {{ site.pmd.release_type }} release. * [#5096](https://github.com/pmd/pmd/issues/5096): \[java] StackOverflowError with recursively bound type variable * java-bestpractices * [#4861](https://github.com/pmd/pmd/issues/4861): \[java] UnusedPrivateMethod - false positive with static methods in core JDK classes +* java-documentation + * [#2996](https://github.com/pmd/pmd/issues/2996): \[java] CommentSize rule violation is not suppressed at method level ### ๐Ÿšจ API Changes +#### Experimental API + +* pmd-core: {%jdoc !!core::reporting.RuleContext#addViolationWithPosition(core::reporting.Reportable,core::lang.ast.AstInfo,core::lang.document.FileLocation,java.lang.String,java.lang.Object...) %} + ### โœจ Merged pull requests From 0d84358c6354abd6f8bfd953d1d8e3b1b658c16a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 18 Dec 2024 12:25:36 +0100 Subject: [PATCH 0373/1962] [java] Implement ASTSwitchLike#isExhaustive for sealed classes --- .../pmd/lang/java/ast/ASTSwitchLike.java | 57 +++++- .../pmd/lang/java/ast/ASTSwitchLikeTest.java | 183 ++++++++++++++++++ 2 files changed, 238 insertions(+), 2 deletions(-) create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLikeTest.java diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLike.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLike.java index 52e37af737b..c245d38ebce 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLike.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLike.java @@ -4,11 +4,15 @@ package net.sourceforge.pmd.lang.java.ast; +import java.util.HashSet; import java.util.Iterator; +import java.util.Set; +import java.util.stream.Collectors; import net.sourceforge.pmd.lang.ast.NodeStream; import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; import net.sourceforge.pmd.lang.java.symbols.JTypeDeclSymbol; +import net.sourceforge.pmd.lang.java.types.JTypeMirror; /** @@ -59,7 +63,7 @@ default ASTExpression getTestedExpression() { /** - * Returns true if this switch statement tests an expression + * Returns true if this switch block tests an expression * having an enum type and all the constants of this type * are covered by a switch case. Returns false if the type of * the tested expression could not be resolved. @@ -76,7 +80,7 @@ default boolean isExhaustiveEnumSwitch() { } /** - * Returns true if this switch statement tests an expression + * Returns true if this switch block tests an expression * having an enum type. */ default boolean isEnumSwitch() { @@ -84,6 +88,55 @@ default boolean isEnumSwitch() { return type instanceof JClassSymbol && ((JClassSymbol) type).isEnum(); } + /** + * Returns true if this switch block tests an expression + * having a sealed type or an enum type and all the possible + * constants or types are covered by a switch case. + * Returns false if the type of the tested expression could not + * be resolved. + * + * @see #isExhaustiveEnumSwitch() + */ + default boolean isExhaustive() { + JTypeDeclSymbol symbol = getTestedExpression().getTypeMirror().getSymbol(); + if (symbol instanceof JClassSymbol) { + JClassSymbol classSymbol = (JClassSymbol) symbol; + if (classSymbol.isSealed()) { + Set checkedSubtypes = getBranches() + .map(ASTSwitchBranch::getLabel) + .children(ASTTypePattern.class) + .map(ASTTypePattern::getTypeNode) + .toStream() + .map(TypeNode::getTypeMirror) + .map(JTypeMirror::getSymbol) + .filter(s -> s instanceof JClassSymbol) + .map(s -> (JClassSymbol) s) + .collect(Collectors.toSet()); + + Set permittedSubtypes = new HashSet<>(classSymbol.getPermittedSubtypes()); + // for all the switch cases, remove the checked type itself + permittedSubtypes.removeAll(checkedSubtypes); + + // if there are any remaining types left, they might be covered, if they are sealed + // (there are no other possible subtypes) and all subtypes are covered + // Note: This currently only checks one level. If the type hierarchy is deeper, we don't + // recognize all possible permitted subtypes. + for (JClassSymbol remainingType : new HashSet<>(permittedSubtypes)) { + if (remainingType.isSealed()) { + Set subtypes = new HashSet<>(remainingType.getPermittedSubtypes()); + subtypes.removeAll(checkedSubtypes); + if (subtypes.isEmpty()) { + permittedSubtypes.remove(remainingType); + } + } + } + + return permittedSubtypes.isEmpty(); + } + } + + return isExhaustiveEnumSwitch(); + } @Override default Iterator iterator() { diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLikeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLikeTest.java new file mode 100644 index 00000000000..98b47f288f9 --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLikeTest.java @@ -0,0 +1,183 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.ast; + +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.Test; + +import net.sourceforge.pmd.lang.java.BaseParserTest; + +class ASTSwitchLikeTest extends BaseParserTest { + + @Test + void exhaustiveSwitchSealedClassesAST() { + Map switchStatements = + java.parse( + "import net.sourceforge.pmd.lang.java.rule.bestpractices.switchstmtsshouldhavedefault.SimpleEnum;\n" + + "public sealed class Foo {\n" + + " public static final class Sub1 extends Foo {}\n" + + " public static final class Sub2 extends Foo {}\n" + + " void exhaustiveSealed(Foo x) {\n" + + " switch (x) {\n" + + " case Sub1 sub1 -> System.out.println(\"x is sub1\");\n" + + " case Sub2 sub2 -> System.out.println(\"x is sub2\");\n" + + " }\n" + + " }\n" + + " void exhaustiveSealedWithDefault(Foo x) {\n" + + " switch (x) {\n" + + " case Sub1 sub1 -> System.out.println(\"x is sub1\");\n" + + " case Sub2 sub2 -> System.out.println(\"x is sub2\");\n" + + " default -> System.out.println(\"unnecessary default\");\n" + + " }\n" + + " }\n" + + " void notExhaustiveSealed(Foo x) {\n" + + " switch (x) {\n" + + " case Sub1 sub1 -> System.out.println(\"x is sub1\");\n" + + " // sub2 is missing -> would be a compile error\n" + + " }\n" + + " }\n" + + " void notExhaustiveSealedWithDefault(Foo x) {\n" + + " switch (x) {\n" + + " case Sub1 sub1 -> System.out.println(\"x is sub1\");\n" + + " // sub2 is missing\n" + + " default -> System.out.println(\"anything else\");\n" + + " }\n" + + " }\n" + + " void exhaustiveEnum(SimpleEnum x) {\n" + + " switch (x) {\n" + + " case FOO -> System.out.println(\"x is foo\");\n" + + " case BAR -> System.out.println(\"x is bar\");\n" + + " case BZAZ -> System.out.println(\" x is bzaz\");\n" + + " }\n" + + " }\n" + + " void exhaustiveEnumWithDefault(SimpleEnum x) {\n" + + " switch (x) {\n" + + " case FOO -> System.out.println(\"x is foo\");\n" + + " case BAR -> System.out.println(\"x is bar\");\n" + + " case BZAZ -> System.out.println(\" x is bzaz\");\n" + + " default -> System.out.println(\"unnecessary default\");\n" + + " }\n" + + " }\n" + + " void notExhaustiveEnum(SimpleEnum x) {\n" + + " switch (x) {\n" + + " case FOO -> System.out.println(\"x is foo\");\n" + + " // missing: case BAR -> System.out.println(\"x is bar\");\n" + + " case BZAZ -> System.out.println(\" x is bzaz\");\n" + + " }\n" + + " }\n" + + " void notExhaustiveEnumWithDefault(SimpleEnum x) {\n" + + " switch (x) {\n" + + " case FOO -> System.out.println(\"x is foo\");\n" + + " //missing: case BAR -> System.out.println(\"x is bar\");\n" + + " case BZAZ -> System.out.println(\" x is bzaz\");\n" + + " default -> System.out.println(\"unnecessary default\");\n" + + " }\n" + + " }\n" + + "}") + .descendants(ASTSwitchLike.class) + .collect(Collectors.toMap(s -> s.ancestors(ASTMethodDeclaration.class).firstOrThrow().getName(), + Function.identity())); + + assertAll( + () -> assertSwitch(switchStatements.get("exhaustiveSealed"), false, true, false), + () -> assertSwitch(switchStatements.get("exhaustiveSealedWithDefault"), false, true, true), + () -> assertSwitch(switchStatements.get("notExhaustiveSealed"), false, false, false), + () -> assertSwitch(switchStatements.get("notExhaustiveSealedWithDefault"), false, false, true), + () -> assertSwitch(switchStatements.get("exhaustiveEnum"), true, true, false), + () -> assertSwitch(switchStatements.get("exhaustiveEnumWithDefault"), true, true, true), + () -> assertSwitch(switchStatements.get("notExhaustiveEnum"), true, false, false), + () -> assertSwitch(switchStatements.get("notExhaustiveEnumWithDefault"), true, false, true) + ); + } + + @Test + void exhaustiveSwitchExpressionSealedClassesAST() { + Map switchExpressions = + java.parse( + "public sealed class Foo {\n" + + " public static final class Sub1 extends Foo {}\n" + + " public static final class Sub2 extends Foo {}\n" + + " String exhaustiveSealed(Foo x) {\n" + + " return switch (x) {\n" + + " case Sub1 sub1 -> \"x is sub1\";\n" + + " case Sub2 sub2 -> \"x is sub2\";\n" + + " };\n" + + " }\n" + + " String exhaustiveSealedWithDefault(Foo x) {\n" + + " return switch (x) {\n" + + " case Sub1 sub1 -> \"x is sub1\";\n" + + " case Sub2 sub2 -> \"x is sub2\";\n" + + " default -> \"unnecessary default\";\n" + + " };\n" + + " }\n" + + " String notExhaustiveSealedWithDefault(Foo x) {\n" + + " return switch (x) {\n" + + " case Sub1 sub1 -> \"x is sub1\";\n" + + " // sub2 is missing\n" + + " default -> \"anything else\";\n" + + " };\n" + + " }\n" + + "}") + .descendants(ASTSwitchLike.class) + .collect(Collectors.toMap(s -> s.ancestors(ASTMethodDeclaration.class).firstOrThrow().getName(), + Function.identity())); + + assertAll( + () -> assertSwitch(switchExpressions.get("exhaustiveSealed"), false, true, false), + () -> assertSwitch(switchExpressions.get("exhaustiveSealedWithDefault"), false, true, true), + () -> assertSwitch(switchExpressions.get("notExhaustiveSealedWithDefault"), false, false, true) + ); + } + + @Test + void exhaustiveSwitchStatementSealedASM() { + // net.sourceforge.pmd.lang.java.symbols.testdata.sealed.SealedTypesTestData + Map switchStatements = + java.parse( + "import net.sourceforge.pmd.lang.java.symbols.testdata.sealed.SealedTypesTestData;\n" + + "import net.sourceforge.pmd.lang.java.symbols.testdata.sealed.A;\n" + + "import net.sourceforge.pmd.lang.java.symbols.testdata.sealed.B;\n" + + "import net.sourceforge.pmd.lang.java.symbols.testdata.sealed.C;\n" + + "import net.sourceforge.pmd.lang.java.symbols.testdata.sealed.X;\n" + + "public class Foo {\n" + + " void exhaustiveSealed(SealedTypesTestData x) {\n" + + " switch (x) {\n" + + " case A a -> System.out.println(\"x is a\");\n" + + " case B b -> System.out.println(\"x is b\");\n" + + " case C c -> System.out.println(\"x is c\");\n" + + " }\n" + + " }\n" + + " void exhaustiveSealedX(SealedTypesTestData x) {\n" + + " switch (x) {\n" + + " // X is the only subtype of A, so this switch is still exhaustive\n" + + " case X x2 -> System.out.println(\"x is x\");\n" + + " case B b -> System.out.println(\"x is b\");\n" + + " case C c -> System.out.println(\"x is c\");\n" + + " }\n" + + " }\n" + + "}") + .descendants(ASTSwitchLike.class) + .collect(Collectors.toMap(s -> s.ancestors(ASTMethodDeclaration.class).firstOrThrow().getName(), + Function.identity())); + + assertAll( + () -> assertSwitch(switchStatements.get("exhaustiveSealed"), false, true, false), + () -> assertSwitch(switchStatements.get("exhaustiveSealedX"), false, true, false) + ); + } + + private static void assertSwitch(ASTSwitchLike switchLike, boolean isEnum, boolean isExhaustive, boolean hasDefault) { + assertEquals(isEnum, switchLike.isEnumSwitch(), "wrong isEnumSwitch"); + assertEquals(isEnum & isExhaustive, switchLike.isExhaustiveEnumSwitch(), "wrong isExhaustiveEnumSwitch"); + assertEquals(isExhaustive, switchLike.isExhaustive(), "wrong isExhaustive"); + assertEquals(hasDefault, switchLike.hasDefaultCase(), "wrong hasDefaultCase"); + } +} From 88876dc4735de2ed648759a9268a47e7198f5293 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 18 Dec 2024 15:24:16 +0100 Subject: [PATCH 0374/1962] [java] Add shortcuts for ASTSwitchLike#isExhaustive And fix tree dump tests. The "Exhaustive" flag should be correct now in the test data, the implementation in ASTSwitchLike still needs to be improved. --- .../pmd/lang/java/ast/ASTSwitchLike.java | 19 +++++++++++++++++++ .../pmd/lang/java/ast/ASTSwitchLikeTest.java | 4 +++- .../pmd/lang/java/ast/ParserCornerCases17.txt | 4 ++-- .../pmd/lang/java/ast/SwitchStatements.txt | 6 +++--- .../lang/java/ast/SwitchWithFallthrough.txt | 2 +- .../java14/MultipleCaseLabels.txt | 2 +- .../java14/SimpleSwitchExpressions.txt | 2 +- .../java14/SwitchExpressions.txt | 12 ++++++------ .../jdkversiontests/java14/SwitchRules.txt | 2 +- .../java14/YieldStatements.txt | 4 ++-- .../java21/DealingWithNull.txt | 16 ++++++++-------- .../java21/EnhancedTypeCheckingSwitch.txt | 2 +- .../java21/ExhaustiveSwitch.txt | 10 +++++----- .../java21/GuardedPatterns.txt | 4 ++-- .../java21/Jep440_RecordPatterns.txt | 2 +- .../Jep441_PatternMatchingForSwitch.txt | 16 ++++++++-------- .../java21/PatternsInSwitchLabels.txt | 2 +- .../java21/RecordPatternsExhaustiveSwitch.txt | 6 +++--- .../java21/RefiningPatternsInSwitch.txt | 6 +++--- .../ScopeOfPatternVariableDeclarations.txt | 6 +++--- .../Jep456_UnnamedPatternsAndVariables.txt | 6 +++--- .../java22p/Jep447_StatementsBeforeSuper.txt | 2 +- ...tiveTypesInPatternsInstanceofAndSwitch.txt | 6 +++--- .../Jep482_FlexibleConstructorBodies.txt | 2 +- 24 files changed, 82 insertions(+), 61 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLike.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLike.java index c245d38ebce..4eaa9af0d59 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLike.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLike.java @@ -99,8 +99,27 @@ default boolean isEnumSwitch() { */ default boolean isExhaustive() { JTypeDeclSymbol symbol = getTestedExpression().getTypeMirror().getSymbol(); + + // shortcut1 - if we have any type patterns and there is no default case, + // then the compiler already ensured that the switch is exhaustive. + // This assumes, we only analyze valid, compiled source code. + boolean hasPatterns = getBranches().map(ASTSwitchBranch::getLabel) + .any(ASTSwitchLabel::isPatternLabel); + if (hasPatterns && !hasDefaultCase()) { + return true; + } + if (symbol instanceof JClassSymbol) { JClassSymbol classSymbol = (JClassSymbol) symbol; + + // shortcut2 - if we are dealing with a sealed type or a boolean (java 23 preview, JEP 455) + // and there is no default case then the compiler already checked for exhaustiveness + if (classSymbol.isSealed() || classSymbol.equals(getTypeSystem().BOOLEAN.getSymbol())) { + if (!hasDefaultCase()) { + return true; + } + } + if (classSymbol.isSealed()) { Set checkedSubtypes = getBranches() .map(ASTSwitchBranch::getLabel) diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLikeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLikeTest.java index 98b47f288f9..e13580cc868 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLikeTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLikeTest.java @@ -89,7 +89,9 @@ void exhaustiveSwitchSealedClassesAST() { assertAll( () -> assertSwitch(switchStatements.get("exhaustiveSealed"), false, true, false), () -> assertSwitch(switchStatements.get("exhaustiveSealedWithDefault"), false, true, true), - () -> assertSwitch(switchStatements.get("notExhaustiveSealed"), false, false, false), + // Note: the method "notExhaustiveSealed" doesn't actually compile - it is not exhaustive and doesn't have a default + // the implementation of #isExhaustive uses a shortcut by assuming, the code it sees compiles and assumes it is exhausive... + //() -> assertSwitch(switchStatements.get("notExhaustiveSealed"), false, false, false), () -> assertSwitch(switchStatements.get("notExhaustiveSealedWithDefault"), false, false, true), () -> assertSwitch(switchStatements.get("exhaustiveEnum"), true, true, false), () -> assertSwitch(switchStatements.get("exhaustiveEnumWithDefault"), true, true, true), diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.txt index bea2307a185..5d2073665d3 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.txt @@ -102,7 +102,7 @@ | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.AND, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "instruction", @Name = "instruction", @ParenthesisDepth = 0, @Parenthesized = false] | | +- NumericLiteral[@Base = 2, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0b00001111", @IntLiteral = true, @Integral = true, @LiteralText = "0b00001111", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 15.0, @ValueAsFloat = 15.0, @ValueAsInt = 15, @ValueAsLong = 15] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.AND, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "instruction", @Name = "instruction", @ParenthesisDepth = 0, @Parenthesized = false] | | +- NumericLiteral[@Base = 2, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0b11110000", @IntLiteral = true, @Integral = true, @LiteralText = "0b11110000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 240.0, @ValueAsFloat = 240.0, @ValueAsInt = 240, @ValueAsLong = 240] @@ -255,7 +255,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] | | +- VariableDeclarator[@Initializer = false, @Name = "typeOfDay"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "typeOfDay", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "dayOfWeekArg", @Name = "dayOfWeekArg", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchFallthroughBranch[@Default = false] | | | +- SwitchLabel[@Default = false, @PatternLabel = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchStatements.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchStatements.txt index dbfa7a45099..f5356906563 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchStatements.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchStatements.txt @@ -13,16 +13,16 @@ | +- VariableDeclarator[@Initializer = true, @Name = "a"] | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "a", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] - +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "a", @Name = "a", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchFallthroughBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = false] | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | +- SwitchFallthroughBranch[@Default = true] | +- SwitchLabel[@Default = true, @PatternLabel = false] - +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "a", @Name = "a", @ParenthesisDepth = 0, @Parenthesized = false] - +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "a", @Name = "a", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchFallthroughBranch[@Default = false] | +- SwitchLabel[@Default = false, @PatternLabel = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchWithFallthrough.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchWithFallthrough.txt index 5f16e3c6a77..b7ccd9f2bc2 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchWithFallthrough.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchWithFallthrough.txt @@ -13,7 +13,7 @@ | +- VariableDeclarator[@Initializer = true, @Name = "a"] | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "a", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] - +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "a", @Name = "a", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchFallthroughBranch[@Default = false] | +- SwitchLabel[@Default = false, @PatternLabel = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/MultipleCaseLabels.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/MultipleCaseLabels.txt index a9007b47873..944e6311a9c 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/MultipleCaseLabels.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/MultipleCaseLabels.txt @@ -62,7 +62,7 @@ | +- VariableDeclarator[@Initializer = true, @Name = "day"] | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "day", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "THURSDAY", @Name = "THURSDAY", @ParenthesisDepth = 0, @Parenthesized = false] - +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "day", @Name = "day", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchFallthroughBranch[@Default = false] | +- SwitchLabel[@Default = false, @PatternLabel = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SimpleSwitchExpressions.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SimpleSwitchExpressions.txt index 63cbacf6b46..b56461320f3 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SimpleSwitchExpressions.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SimpleSwitchExpressions.txt @@ -66,7 +66,7 @@ | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | +- VariableDeclarator[@Initializer = true, @Name = "numLetters"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "numLetters", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "day", @Name = "day", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] | | | +- SwitchLabel[@Default = false, @PatternLabel = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchExpressions.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchExpressions.txt index 72c512b8494..5e657237559 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchExpressions.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchExpressions.txt @@ -52,7 +52,7 @@ | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "THURSDAY", @Name = "THURSDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Day"] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = true, @ExhaustiveEnumSwitch = true, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = true, @Exhaustive = true, @ExhaustiveEnumSwitch = true, @FallthroughSwitch = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "day", @Name = "day", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] | | | +- SwitchLabel[@Default = false, @PatternLabel = false] @@ -98,7 +98,7 @@ | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] | | +- VariableDeclarator[@Initializer = true, @Name = "numLetters"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "numLetters", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = true, @ExhaustiveEnumSwitch = true, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = true, @Exhaustive = true, @ExhaustiveEnumSwitch = true, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "day", @Name = "day", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] | | | +- SwitchLabel[@Default = false, @PatternLabel = false] @@ -156,7 +156,7 @@ | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] | | +- VariableDeclarator[@Initializer = true, @Name = "j"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "j", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = true, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "day", @Name = "day", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] | | | +- SwitchLabel[@Default = false, @PatternLabel = false] @@ -208,7 +208,7 @@ | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] | | +- VariableDeclarator[@Initializer = true, @Name = "result"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "result", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchFallthroughBranch[@Default = false] | | | +- SwitchLabel[@Default = false, @PatternLabel = false] @@ -255,7 +255,7 @@ | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "k", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "k", @Name = "k", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = false] @@ -298,7 +298,7 @@ | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] | +- ArgumentList[@Empty = false, @Size = 1] - | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "k", @Name = "k", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchRules.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchRules.txt index 4eb465db714..4aad77ffc44 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchRules.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchRules.txt @@ -62,7 +62,7 @@ | +- VariableDeclarator[@Initializer = true, @Name = "day"] | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "day", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "WEDNESDAY", @Name = "WEDNESDAY", @ParenthesisDepth = 0, @Parenthesized = false] - +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "day", @Name = "day", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchArrowBranch[@Default = false] | +- SwitchLabel[@Default = false, @PatternLabel = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.txt index 766c74cde24..6a146330036 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.txt @@ -26,7 +26,7 @@ +- ExpressionStatement[] +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] +- VariableAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "yield", @Name = "yield", @ParenthesisDepth = 0, @Parenthesized = false] - +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "e", @Name = "e", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchArrowBranch[@Default = false] +- SwitchLabel[@Default = false, @PatternLabel = false] @@ -64,7 +64,7 @@ +- ExpressionStatement[] | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "yield", @Name = "yield", @ParenthesisDepth = 0, @Parenthesized = false] - | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "foo", @Name = "foo", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | +- SwitchLabel[@Default = false, @PatternLabel = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/DealingWithNull.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/DealingWithNull.txt index 1eb5bde018a..0716f68aa71 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/DealingWithNull.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/DealingWithNull.txt @@ -11,7 +11,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = false] @@ -49,7 +49,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "o", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = true] @@ -91,7 +91,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "o", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = true] @@ -125,7 +125,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "o", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = false] @@ -177,7 +177,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "o", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 4, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchFallthroughBranch[@Default = false] | | | +- SwitchLabel[@Default = false, @PatternLabel = false] @@ -214,7 +214,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "default case", @Empty = false, @Image = "\"default case\"", @Length = 12, @LiteralText = "\"default case\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- BreakStatement[@Label = null] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] | | | +- SwitchLabel[@Default = false, @PatternLabel = false] @@ -245,7 +245,7 @@ | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "default case", @Empty = false, @Image = "\"default case\"", @Length = 12, @LiteralText = "\"default case\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchFallthroughBranch[@Default = false] | | | +- SwitchLabel[@Default = false, @PatternLabel = false] @@ -259,7 +259,7 @@ | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "The rest (including null)", @Empty = false, @Image = "\"The rest (including null)\"", @Length = 25, @LiteralText = "\"The rest (including null)\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = true] | +- SwitchLabel[@Default = true, @PatternLabel = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/EnhancedTypeCheckingSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/EnhancedTypeCheckingSwitch.txt index aec1b522244..ad78a4f00fe 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/EnhancedTypeCheckingSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/EnhancedTypeCheckingSwitch.txt @@ -35,7 +35,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "obj", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "obj", @Name = "obj", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ExhaustiveSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ExhaustiveSwitch.txt index 0690ebc5ba9..f3aafd2a07d 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ExhaustiveSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ExhaustiveSwitch.txt @@ -12,7 +12,7 @@ | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "obj", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] | +- ReturnStatement[] - | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "obj", @Name = "obj", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = true] @@ -42,7 +42,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "o", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchFallthroughBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = true] @@ -112,7 +112,7 @@ | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] | +- ReturnStatement[] - | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = true] @@ -144,7 +144,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "S"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 2, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchFallthroughBranch[@Default = false] | | | +- SwitchLabel[@Default = false, @PatternLabel = true] @@ -223,7 +223,7 @@ | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] | +- ReturnStatement[] - | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | +- SwitchLabel[@Default = false, @PatternLabel = true] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/GuardedPatterns.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/GuardedPatterns.txt index e9ec43cda38..fc4111aa7bb 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/GuardedPatterns.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/GuardedPatterns.txt @@ -11,7 +11,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "o", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = true] @@ -115,7 +115,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "o", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = true] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep440_RecordPatterns.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep440_RecordPatterns.txt index 8756417a538..187801751da 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep440_RecordPatterns.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep440_RecordPatterns.txt @@ -257,7 +257,7 @@ | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "pair", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "pair", @Name = "pair", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | +- SwitchLabel[@Default = false, @PatternLabel = true] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt index fce6b81fdf1..0fe43b24319 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt @@ -12,7 +12,7 @@ | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "obj", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] | +- ReturnStatement[] - | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "obj", @Name = "obj", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = true] @@ -76,7 +76,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = false] @@ -114,7 +114,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "response", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "response", @Name = "response", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = false] @@ -181,7 +181,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "response", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "response", @Name = "response", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = false] @@ -300,7 +300,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "CardClassification"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "c", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "c", @Name = "c", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = true] @@ -399,7 +399,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "CardClassification"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "c", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "c", @Name = "c", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = false] @@ -492,7 +492,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Currency"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "c", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "c", @Name = "c", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = false] @@ -529,7 +529,7 @@ | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Coin"] | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "c", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] +- Block[@Empty = false, @Size = 1, @containsComment = false] - +- SwitchStatement[@DefaultCase = false, @EnumSwitch = true, @ExhaustiveEnumSwitch = true, @FallthroughSwitch = false] + +- SwitchStatement[@DefaultCase = false, @EnumSwitch = true, @Exhaustive = true, @ExhaustiveEnumSwitch = true, @FallthroughSwitch = false] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "c", @Name = "c", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchArrowBranch[@Default = false] | +- SwitchLabel[@Default = false, @PatternLabel = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/PatternsInSwitchLabels.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/PatternsInSwitchLabels.txt index c78fee3b6ce..8805f7d44c3 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/PatternsInSwitchLabels.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/PatternsInSwitchLabels.txt @@ -25,7 +25,7 @@ | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] | +- VariableDeclarator[@Initializer = true, @Name = "formatted"] | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "formatted", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = true] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatternsExhaustiveSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatternsExhaustiveSwitch.txt index 78a8d5d4955..4c2bf0e9e0c 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatternsExhaustiveSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatternsExhaustiveSwitch.txt @@ -61,7 +61,7 @@ | +- VariableDeclarator[@Initializer = true, @Name = "p2"] | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "p2", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] - +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "p1", @Name = "p1", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = true] @@ -126,7 +126,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] | +- ArgumentList[@Empty = false, @Size = 1] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "exhaustive now", @Empty = false, @Image = "\"exhaustive now\"", @Length = 14, @LiteralText = "\"exhaustive now\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "p2", @Name = "p2", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = true] @@ -170,7 +170,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] | +- ArgumentList[@Empty = false, @Size = 1] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "a", @Empty = false, @Image = "\"a\"", @Length = 1, @LiteralText = "\"a\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "p2", @Name = "p2", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchArrowBranch[@Default = false] | +- SwitchLabel[@Default = false, @PatternLabel = true] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RefiningPatternsInSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RefiningPatternsInSwitch.txt index 8090943eaf3..1ade3b146fc 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RefiningPatternsInSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RefiningPatternsInSwitch.txt @@ -49,7 +49,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Shape"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchFallthroughBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = false] @@ -94,7 +94,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Shape"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = false] @@ -136,7 +136,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Shape"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ScopeOfPatternVariableDeclarations.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ScopeOfPatternVariableDeclarations.txt index ee01695dd41..9d5dfc52cfb 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ScopeOfPatternVariableDeclarations.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ScopeOfPatternVariableDeclarations.txt @@ -11,7 +11,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "obj", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "obj", @Name = "obj", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchFallthroughBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = true] @@ -45,7 +45,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "o", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = true] @@ -103,7 +103,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "o", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchFallthroughBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = true] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt index 06b6a2128c5..698a2f5780e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt @@ -178,7 +178,7 @@ | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "RedBall"] | | +- ArgumentList[@Empty = true, @Size = 0] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] | | | +- SwitchLabel[@Default = false, @PatternLabel = true] @@ -215,7 +215,7 @@ | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "_", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = true, @Visibility = Visibility.V_LOCAL] | | +- MethodCall[@CompileTimeConstant = false, @Image = "stopProcessing", @MethodName = "stopProcessing", @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArgumentList[@Empty = true, @Size = 0] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] | | | +- SwitchLabel[@Default = false, @PatternLabel = true] @@ -261,7 +261,7 @@ | | +- VariableDeclarator[@Initializer = true, @Name = "x"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "42", @IntLiteral = true, @Integral = true, @LiteralText = "42", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 42.0, @ValueAsFloat = 42.0, @ValueAsInt = 42, @ValueAsLong = 42] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = true] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22p/Jep447_StatementsBeforeSuper.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22p/Jep447_StatementsBeforeSuper.txt index 9fa3cd28107..c4e872bcf6a 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22p/Jep447_StatementsBeforeSuper.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22p/Jep447_StatementsBeforeSuper.txt @@ -102,7 +102,7 @@ | | | +- ArrayTypeDim[@Varargs = false] | | +- VariableDeclarator[@Initializer = true, @Name = "byteArray"] | | +- VariableId[@ArrayType = true, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "byteArray", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "publicKey", @Name = "publicKey", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] | | | +- SwitchLabel[@Default = false, @PatternLabel = true] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep455_PrimitiveTypesInPatternsInstanceofAndSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep455_PrimitiveTypesInPatternsInstanceofAndSwitch.txt index 850597a25e3..998f29bf63a 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep455_PrimitiveTypesInPatternsInstanceofAndSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep455_PrimitiveTypesInPatternsInstanceofAndSwitch.txt @@ -344,7 +344,7 @@ | | +- VariableDeclarator[@Initializer = true, @Name = "i"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1000", @IntLiteral = true, @Integral = true, @LiteralText = "1000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1000.0, @ValueAsFloat = 1000.0, @ValueAsInt = 1000, @ValueAsLong = 1000] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchFallthroughBranch[@Default = false] | +- SwitchLabel[@Default = false, @PatternLabel = true] @@ -378,7 +378,7 @@ | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] | | +- VariableDeclarator[@Initializer = true, @Name = "f"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "f", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "v", @Name = "v", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] | | | +- SwitchLabel[@Default = false, @PatternLabel = false] @@ -421,7 +421,7 @@ | | +- VariableDeclarator[@Initializer = true, @Name = "b"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "b", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | | +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "true", @ParenthesisDepth = 0, @Parenthesized = false, @True = true] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep482_FlexibleConstructorBodies.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep482_FlexibleConstructorBodies.txt index a796c0b5859..0233d0ccdc9 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep482_FlexibleConstructorBodies.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep482_FlexibleConstructorBodies.txt @@ -102,7 +102,7 @@ | | | +- ArrayTypeDim[@Varargs = false] | | +- VariableDeclarator[@Initializer = true, @Name = "byteArray"] | | +- VariableId[@ArrayType = true, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "byteArray", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "publicKey", @Name = "publicKey", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] | | | +- SwitchLabel[@Default = false, @PatternLabel = true] From ab6b1d0ff595bfa30ea92242ef99f86207b2d144 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 18 Dec 2024 15:42:34 +0100 Subject: [PATCH 0375/1962] [java] TooFewBranchesForSwitch: don't report exhaustive switches Fixes #5311 --- docs/pages/release_notes.md | 2 + .../resources/category/java/performance.xml | 9 +-- .../xml/TooFewBranchesForSwitch.xml | 55 +++++++++++++++++++ 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 8a6fbe267cb..1069ea35d03 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -22,6 +22,8 @@ This is a {{ site.pmd.release_type }} release. * [#5096](https://github.com/pmd/pmd/issues/5096): \[java] StackOverflowError with recursively bound type variable * java-bestpractices * [#4861](https://github.com/pmd/pmd/issues/4861): \[java] UnusedPrivateMethod - false positive with static methods in core JDK classes +* java-performance + * [#5311](https://github.com/pmd/pmd/issues/5311): \[java] TooFewBranchesForSwitch false positive for exhaustive switches over enums without default case * java-documentation * [#2996](https://github.com/pmd/pmd/issues/2996): \[java] CommentSize rule violation is not suppressed at method level diff --git a/pmd-java/src/main/resources/category/java/performance.xml b/pmd-java/src/main/resources/category/java/performance.xml index d196aca0cf4..a189b14e930 100644 --- a/pmd-java/src/main/resources/category/java/performance.xml +++ b/pmd-java/src/main/resources/category/java/performance.xml @@ -629,9 +629,10 @@ Note: This rule was named TooFewBranchesForASwitchStatement before PMD 7.7.0. 1 ] (: ignore empty switch blocks :) [ (count(*/SwitchLabel/*) + count(*/SwitchLabel[@Default = true()])) < $minimumNumberCaseForASwitch ] - (: only consider if no pattern matching is used :) - [*/SwitchLabel[@PatternLabel = false()]] + (: do not consider exhaustive switches unless there is a default case :) + [@Exhaustive = false() or @DefaultCase = true()] ]]> @@ -640,9 +641,9 @@ Note: This rule was named TooFewBranchesForASwitchStatement before PMD 7.7.0. + + + + #5311 [java] TooFewBranchesForSwitch false positive for exhaustive switches over enums without default case + 50 + 1 + 10 + "A"; + case B -> "B"; + }; + } + + String fooWithDefault(Bar bar) { + return switch (bar) { // line 10 - violation + case A -> "A"; + case B -> "B"; + default -> "?"; + }; + } + + enum Bar { A, B } +} +]]> + + + + #5311 [java] TooFewBranchesForSwitch false positive for exhaustive switches over sealed without default case + 50 + 1 + 13 + "A"; + case B b -> "B"; + }; + } + + String fooWithDefault(Foo foo) { + return switch (foo) { // line 13 - violation + case A a -> "A"; + case B b -> "B"; + default -> "?"; + }; + } +} ]]> From 874760f468c37dc779ff0abe78409af73855ccaf Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 18 Dec 2024 16:19:03 +0100 Subject: [PATCH 0376/1962] [java] New Rule ExhaustiveSwitchHasDefault --- docs/pages/release_notes.md | 8 ++ .../resources/category/java/bestpractices.xml | 42 ++++++++++ .../resources/rulesets/java/quickstart.xml | 1 + .../ExhaustiveSwitchHasDefaultTest.java | 11 +++ .../xml/ExhaustiveSwitchHasDefault.xml | 80 +++++++++++++++++++ 5 files changed, 142 insertions(+) create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ExhaustiveSwitchHasDefaultTest.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/ExhaustiveSwitchHasDefault.xml diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 1069ea35d03..cb3f53968f7 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -14,6 +14,14 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy +### ๐ŸŒŸ New and changed rules + +#### New Rules + +* The new Java rule {%rule java/bestpractices/ExhaustiveSwitchHasDefault %} finds switch statements and + expressions, that cover already all cases but still have a default case. This default case is unnecessary + and prevents getting compiler errors when e.g. new enum constants are added without extending the switch. + ### ๐Ÿ› Fixed Issues * cli * [#5399](https://github.com/pmd/pmd/issues/5399): \[cli] Windows: PMD fails to start with special characters in path names diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 282cf5466c5..4fad8b47b0e 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -541,6 +541,48 @@ return a; + + +When switching over an enum or sealed class, the compiler will ensure that all possible cases are covered. +If a case is missed, this will result in a compilation error. But if a default case is added, this compiler +check is not performed anymore, leading to difficulties in noticing bugs at runtime. + +Not using a default case makes sure, a compiler error is introduced whenever a new enum constant or a +new subclass to the sealed class hierarchy is added. We will discover this problem at compile time +rather than at runtime (if at all). + + 3 + + + + //(SwitchStatement | SwitchExpression) + [@Exhaustive = true()] + [@DefaultCase = true()] + + + + + System.out.println("a"); + case B -> System.out.println("b"); + default -> System.out.println("unnecessary default"); + }; + } +} +]]> + + + + diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ExhaustiveSwitchHasDefaultTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ExhaustiveSwitchHasDefaultTest.java new file mode 100644 index 00000000000..3ab64e80655 --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ExhaustiveSwitchHasDefaultTest.java @@ -0,0 +1,11 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.bestpractices; + +import net.sourceforge.pmd.test.PmdRuleTst; + +public class ExhaustiveSwitchHasDefaultTest extends PmdRuleTst { + // no additional unit tests +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/ExhaustiveSwitchHasDefault.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/ExhaustiveSwitchHasDefault.xml new file mode 100644 index 00000000000..94433afe4f1 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/ExhaustiveSwitchHasDefault.xml @@ -0,0 +1,80 @@ + + + + + Exhaustive Enum Switch - no default: ok + 0 + System.out.println("a"); + case B -> System.out.println("b"); + }; + } +} +]]> + + + + Exhaustive Enum Switch - with default: nok + 1 + 5 + System.out.println("a"); + case B -> System.out.println("b"); + default -> System.out.println("unnecessary default"); + }; + } +} +]]> + + + + Exhaustive Switch with sealed classes - without default: ok + 0 + System.out.println("a"); + case B b -> System.out.println("b"); + } + } +} +]]> + + + + Exhaustive Switch with sealed classes - with default: nok + 1 + 6 + System.out.println("a"); + case B b -> System.out.println("b"); + default -> System.out.println("unnecessary default"); + } + } +} +]]> + + From 48326287d9aa67303fba7e025f06934059254c2a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 18 Dec 2024 17:34:08 +0100 Subject: [PATCH 0377/1962] Fix quickstart.xml --- pmd-java/src/main/resources/rulesets/java/quickstart.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/main/resources/rulesets/java/quickstart.xml b/pmd-java/src/main/resources/rulesets/java/quickstart.xml index 985d0fcd942..43bcbf849e8 100644 --- a/pmd-java/src/main/resources/rulesets/java/quickstart.xml +++ b/pmd-java/src/main/resources/rulesets/java/quickstart.xml @@ -20,7 +20,7 @@ - From 3c9779b1ac31f36391dd155a22d6c733ded8d85f Mon Sep 17 00:00:00 2001 From: Julia Paluch Date: Thu, 19 Dec 2024 20:32:07 -0500 Subject: [PATCH 0378/1962] create new Maven module for rust --- pmd-languages-deps/pom.xml | 5 +++ pmd-rust/pom.xml | 78 ++++++++++++++++++++++++++++++++++++++ pom.xml | 1 + 3 files changed, 84 insertions(+) create mode 100644 pmd-rust/pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index dbd59b55627..48c387ec1f7 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -132,6 +132,11 @@ pmd-ruby ${project.version} + + net.sourceforge.pmd + pmd-rust + ${project.version} + net.sourceforge.pmd pmd-scala_2.13 diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml new file mode 100644 index 00000000000..fb157112607 --- /dev/null +++ b/pmd-rust/pom.xml @@ -0,0 +1,78 @@ + + + 4.0.0 + pmd-rust + PMD Rust + + + net.sourceforge.pmd + pmd + 7.9.0-SNAPSHOT + ../pom.xml + + + + + + org.antlr + antlr4-maven-plugin + + + org.apache.maven.plugins + maven-antrun-plugin + + + antlr-cleanup + generate-sources + + run + + + + + + + + + + + + + + maven-resources-plugin + + false + + ${*} + + + + + + + + net.sourceforge.pmd + pmd-core + + + org.antlr + antlr4-runtime + + + + org.junit.jupiter + junit-jupiter + test + + + net.sourceforge.pmd + pmd-test + test + + + net.sourceforge.pmd + pmd-lang-test + test + + + diff --git a/pom.xml b/pom.xml index 32e665ecfda..cf951d57a59 100644 --- a/pom.xml +++ b/pom.xml @@ -1361,6 +1361,7 @@ pmd-plsql pmd-python pmd-ruby + pmd-rust pmd-scala-modules/pmd-scala-common pmd-scala-modules/pmd-scala_2.13 pmd-scala-modules/pmd-scala_2.12 From c6222fc1be86cca0b99d344822e6a1a6106f3a26 Mon Sep 17 00:00:00 2001 From: Julia Paluch Date: Thu, 19 Dec 2024 20:36:37 -0500 Subject: [PATCH 0379/1962] add Rust antlr4 grammar --- pmd-rust/src/main/antlr4/RustLexer.g4 | 272 ++++++ pmd-rust/src/main/antlr4/RustParser.g4 | 1201 ++++++++++++++++++++++++ 2 files changed, 1473 insertions(+) create mode 100644 pmd-rust/src/main/antlr4/RustLexer.g4 create mode 100644 pmd-rust/src/main/antlr4/RustParser.g4 diff --git a/pmd-rust/src/main/antlr4/RustLexer.g4 b/pmd-rust/src/main/antlr4/RustLexer.g4 new file mode 100644 index 00000000000..afe41edfe01 --- /dev/null +++ b/pmd-rust/src/main/antlr4/RustLexer.g4 @@ -0,0 +1,272 @@ +/* +Copyright (c) 2010 The Rust Project Developers +Copyright (c) 2020-2022 Student Main + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +// $antlr-format alignTrailingComments true, columnLimit 150, maxEmptyLinesToKeep 1, reflowComments false, useTab false +// $antlr-format allowShortRulesOnASingleLine true, allowShortBlocksOnASingleLine true, minEmptyLines 0, alignSemicolons ownLine +// $antlr-format alignColons trailing, singleLineOverrulesHangingColon true, alignLexerCommands true, alignLabels true, alignTrailers true + +lexer grammar RustLexer; + +// Insert here @header for C++ lexer. + +options +{ + superClass = RustLexerBase; +} + +// https://doc.rust-lang.org/reference/keywords.html strict +KW_AS : 'as'; +KW_BREAK : 'break'; +KW_CONST : 'const'; +KW_CONTINUE : 'continue'; +KW_CRATE : 'crate'; +KW_ELSE : 'else'; +KW_ENUM : 'enum'; +KW_EXTERN : 'extern'; +KW_FALSE : 'false'; +KW_FN : 'fn'; +KW_FOR : 'for'; +KW_IF : 'if'; +KW_IMPL : 'impl'; +KW_IN : 'in'; +KW_LET : 'let'; +KW_LOOP : 'loop'; +KW_MATCH : 'match'; +KW_MOD : 'mod'; +KW_MOVE : 'move'; +KW_MUT : 'mut'; +KW_PUB : 'pub'; +KW_REF : 'ref'; +KW_RETURN : 'return'; +KW_SELFVALUE : 'self'; +KW_SELFTYPE : 'Self'; +KW_STATIC : 'static'; +KW_STRUCT : 'struct'; +KW_SUPER : 'super'; +KW_TRAIT : 'trait'; +KW_TRUE : 'true'; +KW_TYPE : 'type'; +KW_UNSAFE : 'unsafe'; +KW_USE : 'use'; +KW_WHERE : 'where'; +KW_WHILE : 'while'; + +// 2018+ +KW_ASYNC : 'async'; +KW_AWAIT : 'await'; +KW_DYN : 'dyn'; + +// reserved +KW_ABSTRACT : 'abstract'; +KW_BECOME : 'become'; +KW_BOX : 'box'; +KW_DO : 'do'; +KW_FINAL : 'final'; +KW_MACRO : 'macro'; +KW_OVERRIDE : 'override'; +KW_PRIV : 'priv'; +KW_TYPEOF : 'typeof'; +KW_UNSIZED : 'unsized'; +KW_VIRTUAL : 'virtual'; +KW_YIELD : 'yield'; + +// reserved 2018+ +KW_TRY: 'try'; + +// weak +KW_UNION : 'union'; +KW_STATICLIFETIME : '\'static'; + +KW_MACRORULES : 'macro_rules'; +KW_UNDERLINELIFETIME : '\'_'; +KW_DOLLARCRATE : '$crate'; + +// rule itself allow any identifier, but keyword has been matched before +NON_KEYWORD_IDENTIFIER: XID_Start XID_Continue* | '_' XID_Continue+; + +// [\p{L}\p{Nl}\p{Other_ID_Start}-\p{Pattern_Syntax}-\p{Pattern_White_Space}] +fragment XID_Start: [\p{L}\p{Nl}] | UNICODE_OIDS; + +// [\p{ID_Start}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\p{Other_ID_Continue}-\p{Pattern_Syntax}-\p{Pattern_White_Space}] +fragment XID_Continue: XID_Start | [\p{Mn}\p{Mc}\p{Nd}\p{Pc}] | UNICODE_OIDC; + +fragment UNICODE_OIDS: '\u1885' ..'\u1886' | '\u2118' | '\u212e' | '\u309b' ..'\u309c'; + +fragment UNICODE_OIDC: '\u00b7' | '\u0387' | '\u1369' ..'\u1371' | '\u19da'; + +RAW_IDENTIFIER: 'r#' NON_KEYWORD_IDENTIFIER; +// comments https://doc.rust-lang.org/reference/comments.html +LINE_COMMENT: ('//' (~[/!] | '//') ~[\r\n]* | '//') -> channel (HIDDEN); + +BLOCK_COMMENT: + ( + '/*' (~[*!] | '**' | BLOCK_COMMENT_OR_DOC) (BLOCK_COMMENT_OR_DOC | ~[*])*? '*/' + | '/**/' + | '/***/' + ) -> channel (HIDDEN) +; + +INNER_LINE_DOC: '//!' ~[\n\r]* -> channel (HIDDEN); // isolated cr + +INNER_BLOCK_DOC: '/*!' ( BLOCK_COMMENT_OR_DOC | ~[*])*? '*/' -> channel (HIDDEN); + +OUTER_LINE_DOC: '///' (~[/] ~[\n\r]*)? -> channel (HIDDEN); // isolated cr + +OUTER_BLOCK_DOC: + '/**' (~[*] | BLOCK_COMMENT_OR_DOC) (BLOCK_COMMENT_OR_DOC | ~[*])*? '*/' -> channel (HIDDEN) +; + +BLOCK_COMMENT_OR_DOC: ( BLOCK_COMMENT | INNER_BLOCK_DOC | OUTER_BLOCK_DOC) -> channel (HIDDEN); + +SHEBANG: {this.SOF()}? '\ufeff'? '#!' ~[\r\n]* -> channel(HIDDEN); + +//ISOLATED_CR +// : '\r' {_input.LA(1)!='\n'}// not followed with \n ; + +// whitespace https://doc.rust-lang.org/reference/whitespace.html +WHITESPACE : [\p{Zs}] -> channel(HIDDEN); +NEWLINE : ('\r\n' | [\r\n]) -> channel(HIDDEN); + +// tokens char and string +CHAR_LITERAL: '\'' ( ~['\\\n\r\t] | QUOTE_ESCAPE | ASCII_ESCAPE | UNICODE_ESCAPE) '\''; + +STRING_LITERAL: '"' ( ~["] | QUOTE_ESCAPE | ASCII_ESCAPE | UNICODE_ESCAPE | ESC_NEWLINE)* '"'; + +RAW_STRING_LITERAL: 'r' RAW_STRING_CONTENT; + +fragment RAW_STRING_CONTENT: '#' RAW_STRING_CONTENT '#' | '"' .*? '"'; + +BYTE_LITERAL: 'b\'' (. | QUOTE_ESCAPE | BYTE_ESCAPE) '\''; + +BYTE_STRING_LITERAL: 'b"' (~["] | QUOTE_ESCAPE | BYTE_ESCAPE)* '"'; + +RAW_BYTE_STRING_LITERAL: 'br' RAW_STRING_CONTENT; + +fragment ASCII_ESCAPE: '\\x' OCT_DIGIT HEX_DIGIT | COMMON_ESCAPE; + +fragment BYTE_ESCAPE: '\\x' HEX_DIGIT HEX_DIGIT | COMMON_ESCAPE; + +fragment COMMON_ESCAPE: '\\' [nrt\\0]; + +fragment UNICODE_ESCAPE: + '\\u{' HEX_DIGIT HEX_DIGIT? HEX_DIGIT? HEX_DIGIT? HEX_DIGIT? HEX_DIGIT? '}' +; + +fragment QUOTE_ESCAPE: '\\' ['"]; + +fragment ESC_NEWLINE: '\\' '\n'; + +// number + +INTEGER_LITERAL: ( DEC_LITERAL | BIN_LITERAL | OCT_LITERAL | HEX_LITERAL) INTEGER_SUFFIX?; + +DEC_LITERAL: DEC_DIGIT (DEC_DIGIT | '_')*; + +HEX_LITERAL: '0x' '_'* HEX_DIGIT (HEX_DIGIT | '_')*; + +OCT_LITERAL: '0o' '_'* OCT_DIGIT (OCT_DIGIT | '_')*; + +BIN_LITERAL: '0b' '_'* [01] [01_]*; + +FLOAT_LITERAL: + {this.floatLiteralPossible()}? ( + DEC_LITERAL '.' {this.floatDotPossible()}? + | DEC_LITERAL ( '.' DEC_LITERAL)? FLOAT_EXPONENT? FLOAT_SUFFIX? + ) +; + +fragment INTEGER_SUFFIX: + 'u8' + | 'u16' + | 'u32' + | 'u64' + | 'u128' + | 'usize' + | 'i8' + | 'i16' + | 'i32' + | 'i64' + | 'i128' + | 'isize' +; + +fragment FLOAT_SUFFIX: 'f32' | 'f64'; + +fragment FLOAT_EXPONENT: [eE] [+-]? '_'* DEC_LITERAL; + +fragment OCT_DIGIT: [0-7]; + +fragment DEC_DIGIT: [0-9]; + +fragment HEX_DIGIT: [0-9a-fA-F]; + +// LIFETIME_TOKEN: '\'' IDENTIFIER_OR_KEYWORD | '\'_'; + +LIFETIME_OR_LABEL: '\'' NON_KEYWORD_IDENTIFIER; + +PLUS : '+'; +MINUS : '-'; +STAR : '*'; +SLASH : '/'; +PERCENT : '%'; +CARET : '^'; +NOT : '!'; +AND : '&'; +OR : '|'; +ANDAND : '&&'; +OROR : '||'; +//SHL: '<<'; SHR: '>>'; removed to avoid confusion in type parameter +PLUSEQ : '+='; +MINUSEQ : '-='; +STAREQ : '*='; +SLASHEQ : '/='; +PERCENTEQ : '%='; +CARETEQ : '^='; +ANDEQ : '&='; +OREQ : '|='; +SHLEQ : '<<='; +SHREQ : '>>='; +EQ : '='; +EQEQ : '=='; +NE : '!='; +GT : '>'; +LT : '<'; +GE : '>='; +LE : '<='; +AT : '@'; +UNDERSCORE : '_'; +DOT : '.'; +DOTDOT : '..'; +DOTDOTDOT : '...'; +DOTDOTEQ : '..='; +COMMA : ','; +SEMI : ';'; +COLON : ':'; +PATHSEP : '::'; +RARROW : '->'; +FATARROW : '=>'; +POUND : '#'; +DOLLAR : '$'; +QUESTION : '?'; + +LCURLYBRACE : '{'; +RCURLYBRACE : '}'; +LSQUAREBRACKET : '['; +RSQUAREBRACKET : ']'; +LPAREN : '('; +RPAREN : ')'; diff --git a/pmd-rust/src/main/antlr4/RustParser.g4 b/pmd-rust/src/main/antlr4/RustParser.g4 new file mode 100644 index 00000000000..640b6b13184 --- /dev/null +++ b/pmd-rust/src/main/antlr4/RustParser.g4 @@ -0,0 +1,1201 @@ +/* +Copyright (c) 2010 The Rust Project Developers +Copyright (c) 2020-2022 Student Main + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +// $antlr-format alignTrailingComments true, columnLimit 150, minEmptyLines 1, maxEmptyLinesToKeep 1, reflowComments false, useTab false +// $antlr-format allowShortRulesOnASingleLine false, allowShortBlocksOnASingleLine true, alignSemicolons hanging, alignColons hanging + +parser grammar RustParser; + +// Insert here @header for C++ parser. + +options +{ + tokenVocab = RustLexer; + superClass = RustParserBase; +} + +// entry point +// 4 +crate + : innerAttribute* item* EOF + ; + +// 3 +macroInvocation + : simplePath NOT delimTokenTree + ; + +delimTokenTree + : LPAREN tokenTree* RPAREN + | LSQUAREBRACKET tokenTree* RSQUAREBRACKET + | LCURLYBRACE tokenTree* RCURLYBRACE + ; + +tokenTree + : tokenTreeToken+ + | delimTokenTree + ; + +tokenTreeToken + : macroIdentifierLikeToken + | macroLiteralToken + | macroPunctuationToken + | macroRepOp + | DOLLAR + ; + +macroInvocationSemi + : simplePath NOT LPAREN tokenTree* RPAREN SEMI + | simplePath NOT LSQUAREBRACKET tokenTree* RSQUAREBRACKET SEMI + | simplePath NOT LCURLYBRACE tokenTree* RCURLYBRACE + ; + +// 3.1 +macroRulesDefinition + : KW_MACRORULES NOT identifier macroRulesDef + ; + +macroRulesDef + : LPAREN macroRules RPAREN SEMI + | LSQUAREBRACKET macroRules RSQUAREBRACKET SEMI + | LCURLYBRACE macroRules RCURLYBRACE + ; + +macroRules + : macroRule (SEMI macroRule)* SEMI? + ; + +macroRule + : macroMatcher FATARROW macroTranscriber + ; + +macroMatcher + : LPAREN macroMatch* RPAREN + | LSQUAREBRACKET macroMatch* RSQUAREBRACKET + | LCURLYBRACE macroMatch* RCURLYBRACE + ; + +macroMatch + : macroMatchToken+ + | macroMatcher + | DOLLAR (identifier | KW_SELFVALUE) COLON macroFragSpec + | DOLLAR LPAREN macroMatch+ RPAREN macroRepSep? macroRepOp + ; + +macroMatchToken + : macroIdentifierLikeToken + | macroLiteralToken + | macroPunctuationToken + | macroRepOp + ; + +macroFragSpec + : identifier // do validate here is wasting token + ; + +macroRepSep + : macroIdentifierLikeToken + | macroLiteralToken + | macroPunctuationToken + | DOLLAR + ; + +macroRepOp + : STAR + | PLUS + | QUESTION + ; + +macroTranscriber + : delimTokenTree + ; + +//configurationPredicate +// : configurationOption | configurationAll | configurationAny | configurationNot ; configurationOption: identifier ( +// EQ (STRING_LITERAL | RAW_STRING_LITERAL))?; configurationAll: 'all' LPAREN configurationPredicateList? RPAREN; +// configurationAny: 'any' LPAREN configurationPredicateList? RPAREN; configurationNot: 'not' LPAREN configurationPredicate RPAREN; + +//configurationPredicateList +// : configurationPredicate (COMMA configurationPredicate)* COMMA? ; cfgAttribute: 'cfg' LPAREN configurationPredicate RPAREN; +// cfgAttrAttribute: 'cfg_attr' LPAREN configurationPredicate COMMA cfgAttrs? RPAREN; cfgAttrs: attr (COMMA attr)* COMMA?; + +// 6 +item + : outerAttribute* (visItem | macroItem) + ; + +visItem + : visibility? ( + module + | externCrate + | useDeclaration + | function_ + | typeAlias + | struct_ + | enumeration + | union_ + | constantItem + | staticItem + | trait_ + | implementation + | externBlock + ) + ; + +macroItem + : macroInvocationSemi + | macroRulesDefinition + ; + +// 6.1 +module + : KW_UNSAFE? KW_MOD identifier (SEMI | LCURLYBRACE innerAttribute* item* RCURLYBRACE) + ; + +// 6.2 +externCrate + : KW_EXTERN KW_CRATE crateRef asClause? SEMI + ; + +crateRef + : identifier + | KW_SELFVALUE + ; + +asClause + : KW_AS (identifier | UNDERSCORE) + ; + +// 6.3 +useDeclaration + : KW_USE useTree SEMI + ; + +useTree + : (simplePath? PATHSEP)? (STAR | LCURLYBRACE ( useTree (COMMA useTree)* COMMA?)? RCURLYBRACE) + | simplePath (KW_AS (identifier | UNDERSCORE))? + ; + +// 6.4 +function_ + : functionQualifiers KW_FN identifier genericParams? LPAREN functionParameters? RPAREN functionReturnType? whereClause? ( + blockExpression + | SEMI + ) + ; + +functionQualifiers + : KW_CONST? KW_ASYNC? KW_UNSAFE? (KW_EXTERN abi?)? + ; + +abi + : STRING_LITERAL + | RAW_STRING_LITERAL + ; + +functionParameters + : selfParam COMMA? + | (selfParam COMMA)? functionParam (COMMA functionParam)* COMMA? + ; + +selfParam + : outerAttribute* (shorthandSelf | typedSelf) + ; + +shorthandSelf + : (AND lifetime?)? KW_MUT? KW_SELFVALUE + ; + +typedSelf + : KW_MUT? KW_SELFVALUE COLON type_ + ; + +functionParam + : outerAttribute* (functionParamPattern | DOTDOTDOT | type_) + ; + +functionParamPattern + : pattern COLON (type_ | DOTDOTDOT) + ; + +functionReturnType + : RARROW type_ + ; + +// 6.5 +typeAlias + : KW_TYPE identifier genericParams? whereClause? (EQ type_)? SEMI + ; + +// 6.6 +struct_ + : structStruct + | tupleStruct + ; + +structStruct + : KW_STRUCT identifier genericParams? whereClause? (LCURLYBRACE structFields? RCURLYBRACE | SEMI) + ; + +tupleStruct + : KW_STRUCT identifier genericParams? LPAREN tupleFields? RPAREN whereClause? SEMI + ; + +structFields + : structField (COMMA structField)* COMMA? + ; + +structField + : outerAttribute* visibility? identifier COLON type_ + ; + +tupleFields + : tupleField (COMMA tupleField)* COMMA? + ; + +tupleField + : outerAttribute* visibility? type_ + ; + +// 6.7 +enumeration + : KW_ENUM identifier genericParams? whereClause? LCURLYBRACE enumItems? RCURLYBRACE + ; + +enumItems + : enumItem (COMMA enumItem)* COMMA? + ; + +enumItem + : outerAttribute* visibility? identifier ( + enumItemTuple + | enumItemStruct + | enumItemDiscriminant + )? + ; + +enumItemTuple + : LPAREN tupleFields? RPAREN + ; + +enumItemStruct + : LCURLYBRACE structFields? RCURLYBRACE + ; + +enumItemDiscriminant + : EQ expression + ; + +// 6.8 +union_ + : KW_UNION identifier genericParams? whereClause? LCURLYBRACE structFields RCURLYBRACE + ; + +// 6.9 +constantItem + : KW_CONST (identifier | UNDERSCORE) COLON type_ (EQ expression)? SEMI + ; + +// 6.10 +staticItem + : KW_STATIC KW_MUT? identifier COLON type_ (EQ expression)? SEMI + ; + +// 6.11 +trait_ + : KW_UNSAFE? KW_TRAIT identifier genericParams? (COLON typeParamBounds?)? whereClause? LCURLYBRACE innerAttribute* associatedItem* RCURLYBRACE + ; + +// 6.12 +implementation + : inherentImpl + | traitImpl + ; + +inherentImpl + : KW_IMPL genericParams? type_ whereClause? LCURLYBRACE innerAttribute* associatedItem* RCURLYBRACE + ; + +traitImpl + : KW_UNSAFE? KW_IMPL genericParams? NOT? typePath KW_FOR type_ whereClause? LCURLYBRACE innerAttribute* associatedItem* RCURLYBRACE + ; + +// 6.13 +externBlock + : KW_UNSAFE? KW_EXTERN abi? LCURLYBRACE innerAttribute* externalItem* RCURLYBRACE + ; + +externalItem + : outerAttribute* (macroInvocationSemi | visibility? ( staticItem | function_)) + ; + +// 6.14 +genericParams + : LT ((genericParam COMMA)* genericParam COMMA?)? GT + ; + +genericParam + : outerAttribute* (lifetimeParam | typeParam | constParam) + ; + +lifetimeParam + : outerAttribute? LIFETIME_OR_LABEL (COLON lifetimeBounds)? + ; + +typeParam + : outerAttribute? identifier (COLON typeParamBounds?)? (EQ type_)? + ; + +constParam + : KW_CONST identifier COLON type_ + ; + +whereClause + : KW_WHERE (whereClauseItem COMMA)* whereClauseItem? + ; + +whereClauseItem + : lifetimeWhereClauseItem + | typeBoundWhereClauseItem + ; + +lifetimeWhereClauseItem + : lifetime COLON lifetimeBounds + ; + +typeBoundWhereClauseItem + : forLifetimes? type_ COLON typeParamBounds? + ; + +forLifetimes + : KW_FOR genericParams + ; + +// 6.15 +associatedItem + : outerAttribute* (macroInvocationSemi | visibility? ( typeAlias | constantItem | function_)) + ; + +// 7 +innerAttribute + : POUND NOT LSQUAREBRACKET attr RSQUAREBRACKET + ; + +outerAttribute + : POUND LSQUAREBRACKET attr RSQUAREBRACKET + ; + +attr + : simplePath attrInput? + ; + +attrInput + : delimTokenTree + | EQ literalExpression + ; // w/o suffix + +//metaItem +// : simplePath ( EQ literalExpression //w | LPAREN metaSeq RPAREN )? ; metaSeq: metaItemInner (COMMA metaItemInner)* COMMA?; +// metaItemInner: metaItem | literalExpression; // w + +//metaWord: identifier; metaNameValueStr: identifier EQ ( STRING_LITERAL | RAW_STRING_LITERAL); metaListPaths: +// identifier LPAREN ( simplePath (COMMA simplePath)* COMMA?)? RPAREN; metaListIdents: identifier LPAREN ( identifier (COMMA +// identifier)* COMMA?)? RPAREN; metaListNameValueStr : identifier LPAREN (metaNameValueStr ( COMMA metaNameValueStr)* COMMA?)? RPAREN +// ; + +// 8 +statement + : SEMI + | item + | letStatement + | expressionStatement + | macroInvocationSemi + ; + +letStatement + : outerAttribute* KW_LET patternNoTopAlt (COLON type_)? (EQ expression)? SEMI + ; + +expressionStatement + : expression SEMI + | expressionWithBlock SEMI? + ; + +// 8.2 +expression + : outerAttribute+ expression # AttributedExpression // technical, remove left recursive + | literalExpression # LiteralExpression_ + | pathExpression # PathExpression_ + | expression DOT pathExprSegment LPAREN callParams? RPAREN # MethodCallExpression // 8.2.10 + | expression DOT identifier # FieldExpression // 8.2.11 + | expression DOT tupleIndex # TupleIndexingExpression // 8.2.7 + | expression DOT KW_AWAIT # AwaitExpression // 8.2.18 + | expression LPAREN callParams? RPAREN # CallExpression // 8.2.9 + | expression LSQUAREBRACKET expression RSQUAREBRACKET # IndexExpression // 8.2.6 + | expression QUESTION # ErrorPropagationExpression // 8.2.4 + | (AND | ANDAND) KW_MUT? expression # BorrowExpression // 8.2.4 + | STAR expression # DereferenceExpression // 8.2.4 + | (MINUS | NOT) expression # NegationExpression // 8.2.4 + | expression KW_AS typeNoBounds # TypeCastExpression // 8.2.4 + | expression (STAR | SLASH | PERCENT) expression # ArithmeticOrLogicalExpression // 8.2.4 + | expression (PLUS | MINUS) expression # ArithmeticOrLogicalExpression // 8.2.4 + | expression (shl | shr) expression # ArithmeticOrLogicalExpression // 8.2.4 + | expression AND expression # ArithmeticOrLogicalExpression // 8.2.4 + | expression CARET expression # ArithmeticOrLogicalExpression // 8.2.4 + | expression OR expression # ArithmeticOrLogicalExpression // 8.2.4 + | expression comparisonOperator expression # ComparisonExpression // 8.2.4 + | expression ANDAND expression # LazyBooleanExpression // 8.2.4 + | expression OROR expression # LazyBooleanExpression // 8.2.4 + | expression DOTDOT expression? # RangeExpression // 8.2.14 + | DOTDOT expression? # RangeExpression // 8.2.14 + | DOTDOTEQ expression # RangeExpression // 8.2.14 + | expression DOTDOTEQ expression # RangeExpression // 8.2.14 + | expression EQ expression # AssignmentExpression // 8.2.4 + | expression compoundAssignOperator expression # CompoundAssignmentExpression // 8.2.4 + | KW_CONTINUE LIFETIME_OR_LABEL? expression? # ContinueExpression // 8.2.13 + | KW_BREAK LIFETIME_OR_LABEL? expression? # BreakExpression // 8.2.13 + | KW_RETURN expression? # ReturnExpression // 8.2.17 + | LPAREN innerAttribute* expression RPAREN # GroupedExpression // 8.2.5 + | LSQUAREBRACKET innerAttribute* arrayElements? RSQUAREBRACKET # ArrayExpression // 8.2.6 + | LPAREN innerAttribute* tupleElements? RPAREN # TupleExpression // 8.2.7 + | structExpression # StructExpression_ // 8.2.8 + | enumerationVariantExpression # EnumerationVariantExpression_ + | closureExpression # ClosureExpression_ // 8.2.12 + | expressionWithBlock # ExpressionWithBlock_ + | macroInvocation # MacroInvocationAsExpression + ; + +comparisonOperator + : EQEQ + | NE + | GT + | LT + | GE + | LE + ; + +compoundAssignOperator + : PLUSEQ + | MINUSEQ + | STAREQ + | SLASHEQ + | PERCENTEQ + | ANDEQ + | OREQ + | CARETEQ + | SHLEQ + | SHREQ + ; + +expressionWithBlock + : outerAttribute+ expressionWithBlock // technical + | blockExpression + | asyncBlockExpression + | unsafeBlockExpression + | loopExpression + | ifExpression + | ifLetExpression + | matchExpression + ; + +// 8.2.1 +literalExpression + : CHAR_LITERAL + | STRING_LITERAL + | RAW_STRING_LITERAL + | BYTE_LITERAL + | BYTE_STRING_LITERAL + | RAW_BYTE_STRING_LITERAL + | INTEGER_LITERAL + | FLOAT_LITERAL + | KW_TRUE + | KW_FALSE + ; + +// 8.2.2 +pathExpression + : pathInExpression + | qualifiedPathInExpression + ; + +// 8.2.3 +blockExpression + : LCURLYBRACE innerAttribute* statements? RCURLYBRACE + ; + +statements + : statement+ expression? + | expression + ; + +asyncBlockExpression + : KW_ASYNC KW_MOVE? blockExpression + ; + +unsafeBlockExpression + : KW_UNSAFE blockExpression + ; + +// 8.2.6 +arrayElements + : expression (COMMA expression)* COMMA? + | expression SEMI expression + ; + +// 8.2.7 +tupleElements + : (expression COMMA)+ expression? + ; + +tupleIndex + : INTEGER_LITERAL + ; + +// 8.2.8 +structExpression + : structExprStruct + | structExprTuple + | structExprUnit + ; + +structExprStruct + : pathInExpression LCURLYBRACE innerAttribute* (structExprFields | structBase)? RCURLYBRACE + ; + +structExprFields + : structExprField (COMMA structExprField)* (COMMA structBase | COMMA?) + ; + +// outerAttribute here is not in doc +structExprField + : outerAttribute* (identifier | (identifier | tupleIndex) COLON expression) + ; + +structBase + : DOTDOT expression + ; + +structExprTuple + : pathInExpression LPAREN innerAttribute* (expression ( COMMA expression)* COMMA?)? RPAREN + ; + +structExprUnit + : pathInExpression + ; + +enumerationVariantExpression + : enumExprStruct + | enumExprTuple + | enumExprFieldless + ; + +enumExprStruct + : pathInExpression LCURLYBRACE enumExprFields? RCURLYBRACE + ; + +enumExprFields + : enumExprField (COMMA enumExprField)* COMMA? + ; + +enumExprField + : identifier + | (identifier | tupleIndex) COLON expression + ; + +enumExprTuple + : pathInExpression LPAREN (expression (COMMA expression)* COMMA?)? RPAREN + ; + +enumExprFieldless + : pathInExpression + ; + +// 8.2.9 +callParams + : expression (COMMA expression)* COMMA? + ; + +// 8.2.12 +closureExpression + : KW_MOVE? (OROR | OR closureParameters? OR) (expression | RARROW typeNoBounds blockExpression) + ; + +closureParameters + : closureParam (COMMA closureParam)* COMMA? + ; + +closureParam + : outerAttribute* pattern (COLON type_)? + ; + +// 8.2.13 +loopExpression + : loopLabel? ( + infiniteLoopExpression + | predicateLoopExpression + | predicatePatternLoopExpression + | iteratorLoopExpression + ) + ; + +infiniteLoopExpression + : KW_LOOP blockExpression + ; + +predicateLoopExpression + : KW_WHILE expression /*except structExpression*/ blockExpression + ; + +predicatePatternLoopExpression + : KW_WHILE KW_LET pattern EQ expression blockExpression + ; + +iteratorLoopExpression + : KW_FOR pattern KW_IN expression blockExpression + ; + +loopLabel + : LIFETIME_OR_LABEL COLON + ; + +// 8.2.15 +ifExpression + : KW_IF expression blockExpression (KW_ELSE (blockExpression | ifExpression | ifLetExpression))? + ; + +ifLetExpression + : KW_IF KW_LET pattern EQ expression blockExpression ( + KW_ELSE (blockExpression | ifExpression | ifLetExpression) + )? + ; + +// 8.2.16 +matchExpression + : KW_MATCH expression LCURLYBRACE innerAttribute* matchArms? RCURLYBRACE + ; + +matchArms + : (matchArm FATARROW matchArmExpression)* matchArm FATARROW expression COMMA? + ; + +matchArmExpression + : expression COMMA + | expressionWithBlock COMMA? + ; + +matchArm + : outerAttribute* pattern matchArmGuard? + ; + +matchArmGuard + : KW_IF expression + ; + +// 9 +pattern + : OR? patternNoTopAlt (OR patternNoTopAlt)* + ; + +patternNoTopAlt + : patternWithoutRange + | rangePattern + ; + +patternWithoutRange + : literalPattern + | identifierPattern + | wildcardPattern + | restPattern + | referencePattern + | structPattern + | tupleStructPattern + | tuplePattern + | groupedPattern + | slicePattern + | pathPattern + | macroInvocation + ; + +literalPattern + : KW_TRUE + | KW_FALSE + | CHAR_LITERAL + | BYTE_LITERAL + | STRING_LITERAL + | RAW_STRING_LITERAL + | BYTE_STRING_LITERAL + | RAW_BYTE_STRING_LITERAL + | MINUS? INTEGER_LITERAL + | MINUS? FLOAT_LITERAL + ; + +identifierPattern + : KW_REF? KW_MUT? identifier (AT pattern)? + ; + +wildcardPattern + : UNDERSCORE + ; + +restPattern + : DOTDOT + ; + +rangePattern + : rangePatternBound DOTDOTEQ rangePatternBound # InclusiveRangePattern + | rangePatternBound DOTDOT # HalfOpenRangePattern + | rangePatternBound DOTDOTDOT rangePatternBound # ObsoleteRangePattern + ; + +rangePatternBound + : CHAR_LITERAL + | BYTE_LITERAL + | MINUS? INTEGER_LITERAL + | MINUS? FLOAT_LITERAL + | pathPattern + ; + +referencePattern + : (AND | ANDAND) KW_MUT? patternWithoutRange + ; + +structPattern + : pathInExpression LCURLYBRACE structPatternElements? RCURLYBRACE + ; + +structPatternElements + : structPatternFields (COMMA structPatternEtCetera?)? + | structPatternEtCetera + ; + +structPatternFields + : structPatternField (COMMA structPatternField)* + ; + +structPatternField + : outerAttribute* (tupleIndex COLON pattern | identifier COLON pattern | KW_REF? KW_MUT? identifier) + ; + +structPatternEtCetera + : outerAttribute* DOTDOT + ; + +tupleStructPattern + : pathInExpression LPAREN tupleStructItems? RPAREN + ; + +tupleStructItems + : pattern (COMMA pattern)* COMMA? + ; + +tuplePattern + : LPAREN tuplePatternItems? RPAREN + ; + +tuplePatternItems + : pattern COMMA + | restPattern + | pattern (COMMA pattern)+ COMMA? + ; + +groupedPattern + : LPAREN pattern RPAREN + ; + +slicePattern + : LSQUAREBRACKET slicePatternItems? RSQUAREBRACKET + ; + +slicePatternItems + : pattern (COMMA pattern)* COMMA? + ; + +pathPattern + : pathInExpression + | qualifiedPathInExpression + ; + +// 10.1 +type_ + : typeNoBounds + | implTraitType + | traitObjectType + ; + +typeNoBounds + : parenthesizedType + | implTraitTypeOneBound + | traitObjectTypeOneBound + | typePath + | tupleType + | neverType + | rawPointerType + | referenceType + | arrayType + | sliceType + | inferredType + | qualifiedPathInType + | bareFunctionType + | macroInvocation + ; + +parenthesizedType + : LPAREN type_ RPAREN + ; + +// 10.1.4 +neverType + : NOT + ; + +// 10.1.5 +tupleType + : LPAREN ((type_ COMMA)+ type_?)? RPAREN + ; + +// 10.1.6 +arrayType + : LSQUAREBRACKET type_ SEMI expression RSQUAREBRACKET + ; + +// 10.1.7 +sliceType + : LSQUAREBRACKET type_ RSQUAREBRACKET + ; + +// 10.1.13 +referenceType + : AND lifetime? KW_MUT? typeNoBounds + ; + +rawPointerType + : STAR (KW_MUT | KW_CONST) typeNoBounds + ; + +// 10.1.14 +bareFunctionType + : forLifetimes? functionTypeQualifiers KW_FN LPAREN functionParametersMaybeNamedVariadic? RPAREN bareFunctionReturnType? + ; + +functionTypeQualifiers + : KW_UNSAFE? (KW_EXTERN abi?)? + ; + +bareFunctionReturnType + : RARROW typeNoBounds + ; + +functionParametersMaybeNamedVariadic + : maybeNamedFunctionParameters + | maybeNamedFunctionParametersVariadic + ; + +maybeNamedFunctionParameters + : maybeNamedParam (COMMA maybeNamedParam)* COMMA? + ; + +maybeNamedParam + : outerAttribute* ((identifier | UNDERSCORE) COLON)? type_ + ; + +maybeNamedFunctionParametersVariadic + : (maybeNamedParam COMMA)* maybeNamedParam COMMA outerAttribute* DOTDOTDOT + ; + +// 10.1.15 +traitObjectType + : KW_DYN? typeParamBounds + ; + +traitObjectTypeOneBound + : KW_DYN? traitBound + ; + +implTraitType + : KW_IMPL typeParamBounds + ; + +implTraitTypeOneBound + : KW_IMPL traitBound + ; + +// 10.1.18 +inferredType + : UNDERSCORE + ; + +// 10.6 +typeParamBounds + : typeParamBound (PLUS typeParamBound)* PLUS? + ; + +typeParamBound + : lifetime + | traitBound + ; + +traitBound + : QUESTION? forLifetimes? typePath + | LPAREN QUESTION? forLifetimes? typePath RPAREN + ; + +lifetimeBounds + : (lifetime PLUS)* lifetime? + ; + +lifetime + : LIFETIME_OR_LABEL + | KW_STATICLIFETIME + | KW_UNDERLINELIFETIME + ; + +// 12.4 +simplePath + : PATHSEP? simplePathSegment (PATHSEP simplePathSegment)* + ; + +simplePathSegment + : identifier + | KW_SUPER + | KW_SELFVALUE + | KW_CRATE + | KW_DOLLARCRATE + ; + +pathInExpression + : PATHSEP? pathExprSegment (PATHSEP pathExprSegment)* + ; + +pathExprSegment + : pathIdentSegment (PATHSEP genericArgs)? + ; + +pathIdentSegment + : identifier + | KW_SUPER + | KW_SELFVALUE + | KW_SELFTYPE + | KW_CRATE + | KW_DOLLARCRATE + ; + +//TODO: let x : T<_>=something; +genericArgs + : LT GT + | LT genericArgsLifetimes (COMMA genericArgsTypes)? (COMMA genericArgsBindings)? COMMA? GT + | LT genericArgsTypes (COMMA genericArgsBindings)? COMMA? GT + | LT (genericArg COMMA)* genericArg COMMA? GT + ; + +genericArg + : lifetime + | type_ + | genericArgsConst + | genericArgsBinding + ; + +genericArgsConst + : blockExpression + | MINUS? literalExpression + | simplePathSegment + ; + +genericArgsLifetimes + : lifetime (COMMA lifetime)* + ; + +genericArgsTypes + : type_ (COMMA type_)* + ; + +genericArgsBindings + : genericArgsBinding (COMMA genericArgsBinding)* + ; + +genericArgsBinding + : identifier EQ type_ + ; + +qualifiedPathInExpression + : qualifiedPathType (PATHSEP pathExprSegment)+ + ; + +qualifiedPathType + : LT type_ (KW_AS typePath)? GT + ; + +qualifiedPathInType + : qualifiedPathType (PATHSEP typePathSegment)+ + ; + +typePath + : PATHSEP? typePathSegment (PATHSEP typePathSegment)* + ; + +typePathSegment + : pathIdentSegment PATHSEP? (genericArgs | typePathFn)? + ; + +typePathFn + : LPAREN typePathInputs? RPAREN (RARROW type_)? + ; + +typePathInputs + : type_ (COMMA type_)* COMMA? + ; + +// 12.6 +visibility + : KW_PUB (LPAREN ( KW_CRATE | KW_SELFVALUE | KW_SUPER | KW_IN simplePath) RPAREN)? + ; + +// technical +identifier + : NON_KEYWORD_IDENTIFIER + | RAW_IDENTIFIER + | KW_MACRORULES + ; + +keyword + : KW_AS + | KW_BREAK + | KW_CONST + | KW_CONTINUE + | KW_CRATE + | KW_ELSE + | KW_ENUM + | KW_EXTERN + | KW_FALSE + | KW_FN + | KW_FOR + | KW_IF + | KW_IMPL + | KW_IN + | KW_LET + | KW_LOOP + | KW_MATCH + | KW_MOD + | KW_MOVE + | KW_MUT + | KW_PUB + | KW_REF + | KW_RETURN + | KW_SELFVALUE + | KW_SELFTYPE + | KW_STATIC + | KW_STRUCT + | KW_SUPER + | KW_TRAIT + | KW_TRUE + | KW_TYPE + | KW_UNSAFE + | KW_USE + | KW_WHERE + | KW_WHILE + + // 2018+ + | KW_ASYNC + | KW_AWAIT + | KW_DYN + // reserved + | KW_ABSTRACT + | KW_BECOME + | KW_BOX + | KW_DO + | KW_FINAL + | KW_MACRO + | KW_OVERRIDE + | KW_PRIV + | KW_TYPEOF + | KW_UNSIZED + | KW_VIRTUAL + | KW_YIELD + | KW_TRY + | KW_UNION + | KW_STATICLIFETIME + ; + +macroIdentifierLikeToken + : keyword + | identifier + | KW_MACRORULES + | KW_UNDERLINELIFETIME + | KW_DOLLARCRATE + | LIFETIME_OR_LABEL + ; + +macroLiteralToken + : literalExpression + ; + +// macroDelimiterToken: LCURLYBRACE | RCURLYBRACE | LSQUAREBRACKET | RSQUAREBRACKET | LPAREN | RPAREN; +macroPunctuationToken + : MINUS + //| PLUS | STAR + | SLASH + | PERCENT + | CARET + | NOT + | AND + | OR + | ANDAND + | OROR + // already covered by LT and GT in macro | shl | shr + | PLUSEQ + | MINUSEQ + | STAREQ + | SLASHEQ + | PERCENTEQ + | CARETEQ + | ANDEQ + | OREQ + | SHLEQ + | SHREQ + | EQ + | EQEQ + | NE + | GT + | LT + | GE + | LE + | AT + | UNDERSCORE + | DOT + | DOTDOT + | DOTDOTDOT + | DOTDOTEQ + | COMMA + | SEMI + | COLON + | PATHSEP + | RARROW + | FATARROW + | POUND + //| DOLLAR | QUESTION + ; + +// LA can be removed, legal rust code still pass but the cost is `let c = a < < b` will pass... i hope antlr5 can add +// some new syntax? dsl? for these stuff so i needn't write it in (at least) 5 language + +shl + : LT {this.next('<')}? LT + ; + +shr + : GT {this.next('>')}? GT + ; From bf30f3c06844fbb47b5275b977063ad36fe08685 Mon Sep 17 00:00:00 2001 From: Julia Paluch Date: Thu, 19 Dec 2024 21:25:54 -0500 Subject: [PATCH 0380/1962] move antlr4 grammar into package and add RustLanguageModule and RustCpdLexer --- .../pmd/dist/BinaryDistributionIT.java | 2 +- .../pmd/lang/rust/ast}/RustLexer.g4 | 0 .../pmd/lang/rust/ast}/RustParser.g4 | 0 .../pmd/lang/rust/RustLanguageModule.java | 29 +++++++++++++++++++ .../pmd/lang/rust/cpd/RustCpdLexer.java | 19 ++++++++++++ .../net.sourceforge.pmd.lang.Language | 1 + 6 files changed, 50 insertions(+), 1 deletion(-) rename pmd-rust/src/main/antlr4/{ => net/sourceforge/pmd/lang/rust/ast}/RustLexer.g4 (100%) rename pmd-rust/src/main/antlr4/{ => net/sourceforge/pmd/lang/rust/ast}/RustParser.g4 (100%) create mode 100644 pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/RustLanguageModule.java create mode 100644 pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/cpd/RustCpdLexer.java create mode 100644 pmd-rust/src/main/resources/META-INF/services/net.sourceforge.pmd.lang.Language diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java b/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java index d953641d964..82547b1973e 100644 --- a/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java +++ b/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java @@ -33,7 +33,7 @@ class BinaryDistributionIT extends AbstractBinaryDistributionTest { "fortran", "gherkin", "go", "groovy", "html", "java", "jsp", "julia", "kotlin", "lua", "matlab", "modelica", "objectivec", "perl", - "php", "plsql", "pom", "python", "ruby", "scala", "swift", + "php", "plsql", "pom", "python", "ruby", "rust", "scala", "swift", "tsql", "typescript", "velocity", "visualforce", "wsdl", "xml", "xsl" ); diff --git a/pmd-rust/src/main/antlr4/RustLexer.g4 b/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/RustLexer.g4 similarity index 100% rename from pmd-rust/src/main/antlr4/RustLexer.g4 rename to pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/RustLexer.g4 diff --git a/pmd-rust/src/main/antlr4/RustParser.g4 b/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/RustParser.g4 similarity index 100% rename from pmd-rust/src/main/antlr4/RustParser.g4 rename to pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/RustParser.g4 diff --git a/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/RustLanguageModule.java b/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/RustLanguageModule.java new file mode 100644 index 00000000000..5177044996e --- /dev/null +++ b/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/RustLanguageModule.java @@ -0,0 +1,29 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.rust; + +import net.sourceforge.pmd.cpd.CpdLexer; +import net.sourceforge.pmd.lang.LanguagePropertyBundle; +import net.sourceforge.pmd.lang.LanguageRegistry; +import net.sourceforge.pmd.lang.rust.cpd.RustCpdLexer; +import net.sourceforge.pmd.lang.impl.CpdOnlyLanguageModuleBase; + +public class RustLanguageModule extends CpdOnlyLanguageModuleBase { + private static final String ID = "rust"; + + public RustLanguageModule() { + super(LanguageMetadata.withId(ID).name("Rust").extensions("rust")); + } + + public static RustLanguageModule getInstance() { + return (RustLanguageModule) LanguageRegistry.CPD.getLanguageById(ID); + } + + @Override + public CpdLexer createCpdLexer(LanguagePropertyBundle bundle) { + return new RustCpdLexer(); + } + +} diff --git a/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/cpd/RustCpdLexer.java b/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/cpd/RustCpdLexer.java new file mode 100644 index 00000000000..f0cea61b151 --- /dev/null +++ b/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/cpd/RustCpdLexer.java @@ -0,0 +1,19 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.rust.cpd; + +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Lexer; + +import net.sourceforge.pmd.cpd.impl.AntlrCpdLexer; +import net.sourceforge.pmd.lang.rust.ast.RustLexer; + +public class RustCpdLexer extends AntlrCpdLexer { + + @Override + protected Lexer getLexerForSource(CharStream charStream) { + return new RustCpdLexer(charStream); + } +} diff --git a/pmd-rust/src/main/resources/META-INF/services/net.sourceforge.pmd.lang.Language b/pmd-rust/src/main/resources/META-INF/services/net.sourceforge.pmd.lang.Language new file mode 100644 index 00000000000..f448b030251 --- /dev/null +++ b/pmd-rust/src/main/resources/META-INF/services/net.sourceforge.pmd.lang.Language @@ -0,0 +1 @@ +net.sourceforge.pmd.lang.rust.RustLanguageModule \ No newline at end of file From 5a36c28cdea4d79cb6634cff893dd87814b5e52f Mon Sep 17 00:00:00 2001 From: Julia Paluch Date: Thu, 19 Dec 2024 22:13:15 -0500 Subject: [PATCH 0381/1962] add hello world test --- .../pmd/lang/rust/cpd/RustCpdLexerTest.java | 22 +++++++++++++++++++ .../pmd/lang/rust/cpd/testdata/helloworld.rs | 15 +++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 pmd-rust/src/test/java/net/sourceforge/pmd/lang/rust/cpd/RustCpdLexerTest.java create mode 100644 pmd-rust/src/test/resources/net/sourceforge/pmd/lang/rust/cpd/testdata/helloworld.rs diff --git a/pmd-rust/src/test/java/net/sourceforge/pmd/lang/rust/cpd/RustCpdLexerTest.java b/pmd-rust/src/test/java/net/sourceforge/pmd/lang/rust/cpd/RustCpdLexerTest.java new file mode 100644 index 00000000000..f9763ff741f --- /dev/null +++ b/pmd-rust/src/test/java/net/sourceforge/pmd/lang/rust/cpd/RustCpdLexerTest.java @@ -0,0 +1,22 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.rust.cpd; + +import org.junit.jupiter.api.Test; + +import net.sourceforge.pmd.lang.test.cpd.CpdTextComparisonTest; + +public class RustCpdLexerTest extends CpdTextComparisonTest { + + public RustCpdLexerTest() { + super("rust", ".rs"); + } + + @Test + public void testHelloWorld() { + doTest("helloworld"); + } + +} \ No newline at end of file diff --git a/pmd-rust/src/test/resources/net/sourceforge/pmd/lang/rust/cpd/testdata/helloworld.rs b/pmd-rust/src/test/resources/net/sourceforge/pmd/lang/rust/cpd/testdata/helloworld.rs new file mode 100644 index 00000000000..53ea487e83f --- /dev/null +++ b/pmd-rust/src/test/resources/net/sourceforge/pmd/lang/rust/cpd/testdata/helloworld.rs @@ -0,0 +1,15 @@ +// This is a comment, and is ignored by the compiler. +// You can test this code by clicking the "Run" button over there -> +// or if you prefer to use your keyboard, you can use the "Ctrl + Enter" +// shortcut. + +// This code is editable, feel free to hack it! +// You can always return to the original code by clicking the "Reset" button -> + +// This is the main function. +fn main() { + // Statements here are executed when the compiled binary is called. + + // Print text to the console. + println!("Hello World!"); +} From 75103acc3f78f9770fd048cafb3e06ae3b7766b2 Mon Sep 17 00:00:00 2001 From: Julia Paluch Date: Thu, 19 Dec 2024 22:52:27 -0500 Subject: [PATCH 0382/1962] docs --- docs/pages/pmd/languages/rust.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 docs/pages/pmd/languages/rust.md diff --git a/docs/pages/pmd/languages/rust.md b/docs/pages/pmd/languages/rust.md new file mode 100644 index 00000000000..0a4ce58ac30 --- /dev/null +++ b/docs/pages/pmd/languages/rust.md @@ -0,0 +1,13 @@ +--- +title: Rust +permalink: pmd_languages_rust.html +last_updated: December 2024 (7.0.0) +tags: [languages, CpdCapableLanguage] +summary: "Rust features and guidance" +--- + +> [Rust](https://www.rust-lang.org/) is blazingly fast and memory-efficient: with no runtime +> or garbage collector, it can power performance-critical services, run on embedded devices, +> and easily integrate with other languages. + +{% include language_info.html name='Rust' id='rust' implementation='rust::lang.rust.rustLanguageModule' supports_cpd=true %} \ No newline at end of file From da524115c0b943256a1466c4d0145b0fc49b1a8f Mon Sep 17 00:00:00 2001 From: Julia Paluch Date: Fri, 20 Dec 2024 10:12:22 -0500 Subject: [PATCH 0383/1962] extension should be rs --- .../java/net/sourceforge/pmd/lang/rust/RustLanguageModule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/RustLanguageModule.java b/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/RustLanguageModule.java index 5177044996e..b23ee83665d 100644 --- a/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/RustLanguageModule.java +++ b/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/RustLanguageModule.java @@ -14,7 +14,7 @@ public class RustLanguageModule extends CpdOnlyLanguageModuleBase { private static final String ID = "rust"; public RustLanguageModule() { - super(LanguageMetadata.withId(ID).name("Rust").extensions("rust")); + super(LanguageMetadata.withId(ID).name("Rust").extensions("rs")); } public static RustLanguageModule getInstance() { From d82ea7b5dbccbc2317cdb120cbc6182906b32a5c Mon Sep 17 00:00:00 2001 From: Julia Paluch Date: Fri, 20 Dec 2024 10:54:19 -0500 Subject: [PATCH 0384/1962] parser is unnecessary --- .../pmd/lang/rust/ast/RustParser.g4 | 1201 ----------------- 1 file changed, 1201 deletions(-) delete mode 100644 pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/RustParser.g4 diff --git a/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/RustParser.g4 b/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/RustParser.g4 deleted file mode 100644 index 640b6b13184..00000000000 --- a/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/RustParser.g4 +++ /dev/null @@ -1,1201 +0,0 @@ -/* -Copyright (c) 2010 The Rust Project Developers -Copyright (c) 2020-2022 Student Main - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -// $antlr-format alignTrailingComments true, columnLimit 150, minEmptyLines 1, maxEmptyLinesToKeep 1, reflowComments false, useTab false -// $antlr-format allowShortRulesOnASingleLine false, allowShortBlocksOnASingleLine true, alignSemicolons hanging, alignColons hanging - -parser grammar RustParser; - -// Insert here @header for C++ parser. - -options -{ - tokenVocab = RustLexer; - superClass = RustParserBase; -} - -// entry point -// 4 -crate - : innerAttribute* item* EOF - ; - -// 3 -macroInvocation - : simplePath NOT delimTokenTree - ; - -delimTokenTree - : LPAREN tokenTree* RPAREN - | LSQUAREBRACKET tokenTree* RSQUAREBRACKET - | LCURLYBRACE tokenTree* RCURLYBRACE - ; - -tokenTree - : tokenTreeToken+ - | delimTokenTree - ; - -tokenTreeToken - : macroIdentifierLikeToken - | macroLiteralToken - | macroPunctuationToken - | macroRepOp - | DOLLAR - ; - -macroInvocationSemi - : simplePath NOT LPAREN tokenTree* RPAREN SEMI - | simplePath NOT LSQUAREBRACKET tokenTree* RSQUAREBRACKET SEMI - | simplePath NOT LCURLYBRACE tokenTree* RCURLYBRACE - ; - -// 3.1 -macroRulesDefinition - : KW_MACRORULES NOT identifier macroRulesDef - ; - -macroRulesDef - : LPAREN macroRules RPAREN SEMI - | LSQUAREBRACKET macroRules RSQUAREBRACKET SEMI - | LCURLYBRACE macroRules RCURLYBRACE - ; - -macroRules - : macroRule (SEMI macroRule)* SEMI? - ; - -macroRule - : macroMatcher FATARROW macroTranscriber - ; - -macroMatcher - : LPAREN macroMatch* RPAREN - | LSQUAREBRACKET macroMatch* RSQUAREBRACKET - | LCURLYBRACE macroMatch* RCURLYBRACE - ; - -macroMatch - : macroMatchToken+ - | macroMatcher - | DOLLAR (identifier | KW_SELFVALUE) COLON macroFragSpec - | DOLLAR LPAREN macroMatch+ RPAREN macroRepSep? macroRepOp - ; - -macroMatchToken - : macroIdentifierLikeToken - | macroLiteralToken - | macroPunctuationToken - | macroRepOp - ; - -macroFragSpec - : identifier // do validate here is wasting token - ; - -macroRepSep - : macroIdentifierLikeToken - | macroLiteralToken - | macroPunctuationToken - | DOLLAR - ; - -macroRepOp - : STAR - | PLUS - | QUESTION - ; - -macroTranscriber - : delimTokenTree - ; - -//configurationPredicate -// : configurationOption | configurationAll | configurationAny | configurationNot ; configurationOption: identifier ( -// EQ (STRING_LITERAL | RAW_STRING_LITERAL))?; configurationAll: 'all' LPAREN configurationPredicateList? RPAREN; -// configurationAny: 'any' LPAREN configurationPredicateList? RPAREN; configurationNot: 'not' LPAREN configurationPredicate RPAREN; - -//configurationPredicateList -// : configurationPredicate (COMMA configurationPredicate)* COMMA? ; cfgAttribute: 'cfg' LPAREN configurationPredicate RPAREN; -// cfgAttrAttribute: 'cfg_attr' LPAREN configurationPredicate COMMA cfgAttrs? RPAREN; cfgAttrs: attr (COMMA attr)* COMMA?; - -// 6 -item - : outerAttribute* (visItem | macroItem) - ; - -visItem - : visibility? ( - module - | externCrate - | useDeclaration - | function_ - | typeAlias - | struct_ - | enumeration - | union_ - | constantItem - | staticItem - | trait_ - | implementation - | externBlock - ) - ; - -macroItem - : macroInvocationSemi - | macroRulesDefinition - ; - -// 6.1 -module - : KW_UNSAFE? KW_MOD identifier (SEMI | LCURLYBRACE innerAttribute* item* RCURLYBRACE) - ; - -// 6.2 -externCrate - : KW_EXTERN KW_CRATE crateRef asClause? SEMI - ; - -crateRef - : identifier - | KW_SELFVALUE - ; - -asClause - : KW_AS (identifier | UNDERSCORE) - ; - -// 6.3 -useDeclaration - : KW_USE useTree SEMI - ; - -useTree - : (simplePath? PATHSEP)? (STAR | LCURLYBRACE ( useTree (COMMA useTree)* COMMA?)? RCURLYBRACE) - | simplePath (KW_AS (identifier | UNDERSCORE))? - ; - -// 6.4 -function_ - : functionQualifiers KW_FN identifier genericParams? LPAREN functionParameters? RPAREN functionReturnType? whereClause? ( - blockExpression - | SEMI - ) - ; - -functionQualifiers - : KW_CONST? KW_ASYNC? KW_UNSAFE? (KW_EXTERN abi?)? - ; - -abi - : STRING_LITERAL - | RAW_STRING_LITERAL - ; - -functionParameters - : selfParam COMMA? - | (selfParam COMMA)? functionParam (COMMA functionParam)* COMMA? - ; - -selfParam - : outerAttribute* (shorthandSelf | typedSelf) - ; - -shorthandSelf - : (AND lifetime?)? KW_MUT? KW_SELFVALUE - ; - -typedSelf - : KW_MUT? KW_SELFVALUE COLON type_ - ; - -functionParam - : outerAttribute* (functionParamPattern | DOTDOTDOT | type_) - ; - -functionParamPattern - : pattern COLON (type_ | DOTDOTDOT) - ; - -functionReturnType - : RARROW type_ - ; - -// 6.5 -typeAlias - : KW_TYPE identifier genericParams? whereClause? (EQ type_)? SEMI - ; - -// 6.6 -struct_ - : structStruct - | tupleStruct - ; - -structStruct - : KW_STRUCT identifier genericParams? whereClause? (LCURLYBRACE structFields? RCURLYBRACE | SEMI) - ; - -tupleStruct - : KW_STRUCT identifier genericParams? LPAREN tupleFields? RPAREN whereClause? SEMI - ; - -structFields - : structField (COMMA structField)* COMMA? - ; - -structField - : outerAttribute* visibility? identifier COLON type_ - ; - -tupleFields - : tupleField (COMMA tupleField)* COMMA? - ; - -tupleField - : outerAttribute* visibility? type_ - ; - -// 6.7 -enumeration - : KW_ENUM identifier genericParams? whereClause? LCURLYBRACE enumItems? RCURLYBRACE - ; - -enumItems - : enumItem (COMMA enumItem)* COMMA? - ; - -enumItem - : outerAttribute* visibility? identifier ( - enumItemTuple - | enumItemStruct - | enumItemDiscriminant - )? - ; - -enumItemTuple - : LPAREN tupleFields? RPAREN - ; - -enumItemStruct - : LCURLYBRACE structFields? RCURLYBRACE - ; - -enumItemDiscriminant - : EQ expression - ; - -// 6.8 -union_ - : KW_UNION identifier genericParams? whereClause? LCURLYBRACE structFields RCURLYBRACE - ; - -// 6.9 -constantItem - : KW_CONST (identifier | UNDERSCORE) COLON type_ (EQ expression)? SEMI - ; - -// 6.10 -staticItem - : KW_STATIC KW_MUT? identifier COLON type_ (EQ expression)? SEMI - ; - -// 6.11 -trait_ - : KW_UNSAFE? KW_TRAIT identifier genericParams? (COLON typeParamBounds?)? whereClause? LCURLYBRACE innerAttribute* associatedItem* RCURLYBRACE - ; - -// 6.12 -implementation - : inherentImpl - | traitImpl - ; - -inherentImpl - : KW_IMPL genericParams? type_ whereClause? LCURLYBRACE innerAttribute* associatedItem* RCURLYBRACE - ; - -traitImpl - : KW_UNSAFE? KW_IMPL genericParams? NOT? typePath KW_FOR type_ whereClause? LCURLYBRACE innerAttribute* associatedItem* RCURLYBRACE - ; - -// 6.13 -externBlock - : KW_UNSAFE? KW_EXTERN abi? LCURLYBRACE innerAttribute* externalItem* RCURLYBRACE - ; - -externalItem - : outerAttribute* (macroInvocationSemi | visibility? ( staticItem | function_)) - ; - -// 6.14 -genericParams - : LT ((genericParam COMMA)* genericParam COMMA?)? GT - ; - -genericParam - : outerAttribute* (lifetimeParam | typeParam | constParam) - ; - -lifetimeParam - : outerAttribute? LIFETIME_OR_LABEL (COLON lifetimeBounds)? - ; - -typeParam - : outerAttribute? identifier (COLON typeParamBounds?)? (EQ type_)? - ; - -constParam - : KW_CONST identifier COLON type_ - ; - -whereClause - : KW_WHERE (whereClauseItem COMMA)* whereClauseItem? - ; - -whereClauseItem - : lifetimeWhereClauseItem - | typeBoundWhereClauseItem - ; - -lifetimeWhereClauseItem - : lifetime COLON lifetimeBounds - ; - -typeBoundWhereClauseItem - : forLifetimes? type_ COLON typeParamBounds? - ; - -forLifetimes - : KW_FOR genericParams - ; - -// 6.15 -associatedItem - : outerAttribute* (macroInvocationSemi | visibility? ( typeAlias | constantItem | function_)) - ; - -// 7 -innerAttribute - : POUND NOT LSQUAREBRACKET attr RSQUAREBRACKET - ; - -outerAttribute - : POUND LSQUAREBRACKET attr RSQUAREBRACKET - ; - -attr - : simplePath attrInput? - ; - -attrInput - : delimTokenTree - | EQ literalExpression - ; // w/o suffix - -//metaItem -// : simplePath ( EQ literalExpression //w | LPAREN metaSeq RPAREN )? ; metaSeq: metaItemInner (COMMA metaItemInner)* COMMA?; -// metaItemInner: metaItem | literalExpression; // w - -//metaWord: identifier; metaNameValueStr: identifier EQ ( STRING_LITERAL | RAW_STRING_LITERAL); metaListPaths: -// identifier LPAREN ( simplePath (COMMA simplePath)* COMMA?)? RPAREN; metaListIdents: identifier LPAREN ( identifier (COMMA -// identifier)* COMMA?)? RPAREN; metaListNameValueStr : identifier LPAREN (metaNameValueStr ( COMMA metaNameValueStr)* COMMA?)? RPAREN -// ; - -// 8 -statement - : SEMI - | item - | letStatement - | expressionStatement - | macroInvocationSemi - ; - -letStatement - : outerAttribute* KW_LET patternNoTopAlt (COLON type_)? (EQ expression)? SEMI - ; - -expressionStatement - : expression SEMI - | expressionWithBlock SEMI? - ; - -// 8.2 -expression - : outerAttribute+ expression # AttributedExpression // technical, remove left recursive - | literalExpression # LiteralExpression_ - | pathExpression # PathExpression_ - | expression DOT pathExprSegment LPAREN callParams? RPAREN # MethodCallExpression // 8.2.10 - | expression DOT identifier # FieldExpression // 8.2.11 - | expression DOT tupleIndex # TupleIndexingExpression // 8.2.7 - | expression DOT KW_AWAIT # AwaitExpression // 8.2.18 - | expression LPAREN callParams? RPAREN # CallExpression // 8.2.9 - | expression LSQUAREBRACKET expression RSQUAREBRACKET # IndexExpression // 8.2.6 - | expression QUESTION # ErrorPropagationExpression // 8.2.4 - | (AND | ANDAND) KW_MUT? expression # BorrowExpression // 8.2.4 - | STAR expression # DereferenceExpression // 8.2.4 - | (MINUS | NOT) expression # NegationExpression // 8.2.4 - | expression KW_AS typeNoBounds # TypeCastExpression // 8.2.4 - | expression (STAR | SLASH | PERCENT) expression # ArithmeticOrLogicalExpression // 8.2.4 - | expression (PLUS | MINUS) expression # ArithmeticOrLogicalExpression // 8.2.4 - | expression (shl | shr) expression # ArithmeticOrLogicalExpression // 8.2.4 - | expression AND expression # ArithmeticOrLogicalExpression // 8.2.4 - | expression CARET expression # ArithmeticOrLogicalExpression // 8.2.4 - | expression OR expression # ArithmeticOrLogicalExpression // 8.2.4 - | expression comparisonOperator expression # ComparisonExpression // 8.2.4 - | expression ANDAND expression # LazyBooleanExpression // 8.2.4 - | expression OROR expression # LazyBooleanExpression // 8.2.4 - | expression DOTDOT expression? # RangeExpression // 8.2.14 - | DOTDOT expression? # RangeExpression // 8.2.14 - | DOTDOTEQ expression # RangeExpression // 8.2.14 - | expression DOTDOTEQ expression # RangeExpression // 8.2.14 - | expression EQ expression # AssignmentExpression // 8.2.4 - | expression compoundAssignOperator expression # CompoundAssignmentExpression // 8.2.4 - | KW_CONTINUE LIFETIME_OR_LABEL? expression? # ContinueExpression // 8.2.13 - | KW_BREAK LIFETIME_OR_LABEL? expression? # BreakExpression // 8.2.13 - | KW_RETURN expression? # ReturnExpression // 8.2.17 - | LPAREN innerAttribute* expression RPAREN # GroupedExpression // 8.2.5 - | LSQUAREBRACKET innerAttribute* arrayElements? RSQUAREBRACKET # ArrayExpression // 8.2.6 - | LPAREN innerAttribute* tupleElements? RPAREN # TupleExpression // 8.2.7 - | structExpression # StructExpression_ // 8.2.8 - | enumerationVariantExpression # EnumerationVariantExpression_ - | closureExpression # ClosureExpression_ // 8.2.12 - | expressionWithBlock # ExpressionWithBlock_ - | macroInvocation # MacroInvocationAsExpression - ; - -comparisonOperator - : EQEQ - | NE - | GT - | LT - | GE - | LE - ; - -compoundAssignOperator - : PLUSEQ - | MINUSEQ - | STAREQ - | SLASHEQ - | PERCENTEQ - | ANDEQ - | OREQ - | CARETEQ - | SHLEQ - | SHREQ - ; - -expressionWithBlock - : outerAttribute+ expressionWithBlock // technical - | blockExpression - | asyncBlockExpression - | unsafeBlockExpression - | loopExpression - | ifExpression - | ifLetExpression - | matchExpression - ; - -// 8.2.1 -literalExpression - : CHAR_LITERAL - | STRING_LITERAL - | RAW_STRING_LITERAL - | BYTE_LITERAL - | BYTE_STRING_LITERAL - | RAW_BYTE_STRING_LITERAL - | INTEGER_LITERAL - | FLOAT_LITERAL - | KW_TRUE - | KW_FALSE - ; - -// 8.2.2 -pathExpression - : pathInExpression - | qualifiedPathInExpression - ; - -// 8.2.3 -blockExpression - : LCURLYBRACE innerAttribute* statements? RCURLYBRACE - ; - -statements - : statement+ expression? - | expression - ; - -asyncBlockExpression - : KW_ASYNC KW_MOVE? blockExpression - ; - -unsafeBlockExpression - : KW_UNSAFE blockExpression - ; - -// 8.2.6 -arrayElements - : expression (COMMA expression)* COMMA? - | expression SEMI expression - ; - -// 8.2.7 -tupleElements - : (expression COMMA)+ expression? - ; - -tupleIndex - : INTEGER_LITERAL - ; - -// 8.2.8 -structExpression - : structExprStruct - | structExprTuple - | structExprUnit - ; - -structExprStruct - : pathInExpression LCURLYBRACE innerAttribute* (structExprFields | structBase)? RCURLYBRACE - ; - -structExprFields - : structExprField (COMMA structExprField)* (COMMA structBase | COMMA?) - ; - -// outerAttribute here is not in doc -structExprField - : outerAttribute* (identifier | (identifier | tupleIndex) COLON expression) - ; - -structBase - : DOTDOT expression - ; - -structExprTuple - : pathInExpression LPAREN innerAttribute* (expression ( COMMA expression)* COMMA?)? RPAREN - ; - -structExprUnit - : pathInExpression - ; - -enumerationVariantExpression - : enumExprStruct - | enumExprTuple - | enumExprFieldless - ; - -enumExprStruct - : pathInExpression LCURLYBRACE enumExprFields? RCURLYBRACE - ; - -enumExprFields - : enumExprField (COMMA enumExprField)* COMMA? - ; - -enumExprField - : identifier - | (identifier | tupleIndex) COLON expression - ; - -enumExprTuple - : pathInExpression LPAREN (expression (COMMA expression)* COMMA?)? RPAREN - ; - -enumExprFieldless - : pathInExpression - ; - -// 8.2.9 -callParams - : expression (COMMA expression)* COMMA? - ; - -// 8.2.12 -closureExpression - : KW_MOVE? (OROR | OR closureParameters? OR) (expression | RARROW typeNoBounds blockExpression) - ; - -closureParameters - : closureParam (COMMA closureParam)* COMMA? - ; - -closureParam - : outerAttribute* pattern (COLON type_)? - ; - -// 8.2.13 -loopExpression - : loopLabel? ( - infiniteLoopExpression - | predicateLoopExpression - | predicatePatternLoopExpression - | iteratorLoopExpression - ) - ; - -infiniteLoopExpression - : KW_LOOP blockExpression - ; - -predicateLoopExpression - : KW_WHILE expression /*except structExpression*/ blockExpression - ; - -predicatePatternLoopExpression - : KW_WHILE KW_LET pattern EQ expression blockExpression - ; - -iteratorLoopExpression - : KW_FOR pattern KW_IN expression blockExpression - ; - -loopLabel - : LIFETIME_OR_LABEL COLON - ; - -// 8.2.15 -ifExpression - : KW_IF expression blockExpression (KW_ELSE (blockExpression | ifExpression | ifLetExpression))? - ; - -ifLetExpression - : KW_IF KW_LET pattern EQ expression blockExpression ( - KW_ELSE (blockExpression | ifExpression | ifLetExpression) - )? - ; - -// 8.2.16 -matchExpression - : KW_MATCH expression LCURLYBRACE innerAttribute* matchArms? RCURLYBRACE - ; - -matchArms - : (matchArm FATARROW matchArmExpression)* matchArm FATARROW expression COMMA? - ; - -matchArmExpression - : expression COMMA - | expressionWithBlock COMMA? - ; - -matchArm - : outerAttribute* pattern matchArmGuard? - ; - -matchArmGuard - : KW_IF expression - ; - -// 9 -pattern - : OR? patternNoTopAlt (OR patternNoTopAlt)* - ; - -patternNoTopAlt - : patternWithoutRange - | rangePattern - ; - -patternWithoutRange - : literalPattern - | identifierPattern - | wildcardPattern - | restPattern - | referencePattern - | structPattern - | tupleStructPattern - | tuplePattern - | groupedPattern - | slicePattern - | pathPattern - | macroInvocation - ; - -literalPattern - : KW_TRUE - | KW_FALSE - | CHAR_LITERAL - | BYTE_LITERAL - | STRING_LITERAL - | RAW_STRING_LITERAL - | BYTE_STRING_LITERAL - | RAW_BYTE_STRING_LITERAL - | MINUS? INTEGER_LITERAL - | MINUS? FLOAT_LITERAL - ; - -identifierPattern - : KW_REF? KW_MUT? identifier (AT pattern)? - ; - -wildcardPattern - : UNDERSCORE - ; - -restPattern - : DOTDOT - ; - -rangePattern - : rangePatternBound DOTDOTEQ rangePatternBound # InclusiveRangePattern - | rangePatternBound DOTDOT # HalfOpenRangePattern - | rangePatternBound DOTDOTDOT rangePatternBound # ObsoleteRangePattern - ; - -rangePatternBound - : CHAR_LITERAL - | BYTE_LITERAL - | MINUS? INTEGER_LITERAL - | MINUS? FLOAT_LITERAL - | pathPattern - ; - -referencePattern - : (AND | ANDAND) KW_MUT? patternWithoutRange - ; - -structPattern - : pathInExpression LCURLYBRACE structPatternElements? RCURLYBRACE - ; - -structPatternElements - : structPatternFields (COMMA structPatternEtCetera?)? - | structPatternEtCetera - ; - -structPatternFields - : structPatternField (COMMA structPatternField)* - ; - -structPatternField - : outerAttribute* (tupleIndex COLON pattern | identifier COLON pattern | KW_REF? KW_MUT? identifier) - ; - -structPatternEtCetera - : outerAttribute* DOTDOT - ; - -tupleStructPattern - : pathInExpression LPAREN tupleStructItems? RPAREN - ; - -tupleStructItems - : pattern (COMMA pattern)* COMMA? - ; - -tuplePattern - : LPAREN tuplePatternItems? RPAREN - ; - -tuplePatternItems - : pattern COMMA - | restPattern - | pattern (COMMA pattern)+ COMMA? - ; - -groupedPattern - : LPAREN pattern RPAREN - ; - -slicePattern - : LSQUAREBRACKET slicePatternItems? RSQUAREBRACKET - ; - -slicePatternItems - : pattern (COMMA pattern)* COMMA? - ; - -pathPattern - : pathInExpression - | qualifiedPathInExpression - ; - -// 10.1 -type_ - : typeNoBounds - | implTraitType - | traitObjectType - ; - -typeNoBounds - : parenthesizedType - | implTraitTypeOneBound - | traitObjectTypeOneBound - | typePath - | tupleType - | neverType - | rawPointerType - | referenceType - | arrayType - | sliceType - | inferredType - | qualifiedPathInType - | bareFunctionType - | macroInvocation - ; - -parenthesizedType - : LPAREN type_ RPAREN - ; - -// 10.1.4 -neverType - : NOT - ; - -// 10.1.5 -tupleType - : LPAREN ((type_ COMMA)+ type_?)? RPAREN - ; - -// 10.1.6 -arrayType - : LSQUAREBRACKET type_ SEMI expression RSQUAREBRACKET - ; - -// 10.1.7 -sliceType - : LSQUAREBRACKET type_ RSQUAREBRACKET - ; - -// 10.1.13 -referenceType - : AND lifetime? KW_MUT? typeNoBounds - ; - -rawPointerType - : STAR (KW_MUT | KW_CONST) typeNoBounds - ; - -// 10.1.14 -bareFunctionType - : forLifetimes? functionTypeQualifiers KW_FN LPAREN functionParametersMaybeNamedVariadic? RPAREN bareFunctionReturnType? - ; - -functionTypeQualifiers - : KW_UNSAFE? (KW_EXTERN abi?)? - ; - -bareFunctionReturnType - : RARROW typeNoBounds - ; - -functionParametersMaybeNamedVariadic - : maybeNamedFunctionParameters - | maybeNamedFunctionParametersVariadic - ; - -maybeNamedFunctionParameters - : maybeNamedParam (COMMA maybeNamedParam)* COMMA? - ; - -maybeNamedParam - : outerAttribute* ((identifier | UNDERSCORE) COLON)? type_ - ; - -maybeNamedFunctionParametersVariadic - : (maybeNamedParam COMMA)* maybeNamedParam COMMA outerAttribute* DOTDOTDOT - ; - -// 10.1.15 -traitObjectType - : KW_DYN? typeParamBounds - ; - -traitObjectTypeOneBound - : KW_DYN? traitBound - ; - -implTraitType - : KW_IMPL typeParamBounds - ; - -implTraitTypeOneBound - : KW_IMPL traitBound - ; - -// 10.1.18 -inferredType - : UNDERSCORE - ; - -// 10.6 -typeParamBounds - : typeParamBound (PLUS typeParamBound)* PLUS? - ; - -typeParamBound - : lifetime - | traitBound - ; - -traitBound - : QUESTION? forLifetimes? typePath - | LPAREN QUESTION? forLifetimes? typePath RPAREN - ; - -lifetimeBounds - : (lifetime PLUS)* lifetime? - ; - -lifetime - : LIFETIME_OR_LABEL - | KW_STATICLIFETIME - | KW_UNDERLINELIFETIME - ; - -// 12.4 -simplePath - : PATHSEP? simplePathSegment (PATHSEP simplePathSegment)* - ; - -simplePathSegment - : identifier - | KW_SUPER - | KW_SELFVALUE - | KW_CRATE - | KW_DOLLARCRATE - ; - -pathInExpression - : PATHSEP? pathExprSegment (PATHSEP pathExprSegment)* - ; - -pathExprSegment - : pathIdentSegment (PATHSEP genericArgs)? - ; - -pathIdentSegment - : identifier - | KW_SUPER - | KW_SELFVALUE - | KW_SELFTYPE - | KW_CRATE - | KW_DOLLARCRATE - ; - -//TODO: let x : T<_>=something; -genericArgs - : LT GT - | LT genericArgsLifetimes (COMMA genericArgsTypes)? (COMMA genericArgsBindings)? COMMA? GT - | LT genericArgsTypes (COMMA genericArgsBindings)? COMMA? GT - | LT (genericArg COMMA)* genericArg COMMA? GT - ; - -genericArg - : lifetime - | type_ - | genericArgsConst - | genericArgsBinding - ; - -genericArgsConst - : blockExpression - | MINUS? literalExpression - | simplePathSegment - ; - -genericArgsLifetimes - : lifetime (COMMA lifetime)* - ; - -genericArgsTypes - : type_ (COMMA type_)* - ; - -genericArgsBindings - : genericArgsBinding (COMMA genericArgsBinding)* - ; - -genericArgsBinding - : identifier EQ type_ - ; - -qualifiedPathInExpression - : qualifiedPathType (PATHSEP pathExprSegment)+ - ; - -qualifiedPathType - : LT type_ (KW_AS typePath)? GT - ; - -qualifiedPathInType - : qualifiedPathType (PATHSEP typePathSegment)+ - ; - -typePath - : PATHSEP? typePathSegment (PATHSEP typePathSegment)* - ; - -typePathSegment - : pathIdentSegment PATHSEP? (genericArgs | typePathFn)? - ; - -typePathFn - : LPAREN typePathInputs? RPAREN (RARROW type_)? - ; - -typePathInputs - : type_ (COMMA type_)* COMMA? - ; - -// 12.6 -visibility - : KW_PUB (LPAREN ( KW_CRATE | KW_SELFVALUE | KW_SUPER | KW_IN simplePath) RPAREN)? - ; - -// technical -identifier - : NON_KEYWORD_IDENTIFIER - | RAW_IDENTIFIER - | KW_MACRORULES - ; - -keyword - : KW_AS - | KW_BREAK - | KW_CONST - | KW_CONTINUE - | KW_CRATE - | KW_ELSE - | KW_ENUM - | KW_EXTERN - | KW_FALSE - | KW_FN - | KW_FOR - | KW_IF - | KW_IMPL - | KW_IN - | KW_LET - | KW_LOOP - | KW_MATCH - | KW_MOD - | KW_MOVE - | KW_MUT - | KW_PUB - | KW_REF - | KW_RETURN - | KW_SELFVALUE - | KW_SELFTYPE - | KW_STATIC - | KW_STRUCT - | KW_SUPER - | KW_TRAIT - | KW_TRUE - | KW_TYPE - | KW_UNSAFE - | KW_USE - | KW_WHERE - | KW_WHILE - - // 2018+ - | KW_ASYNC - | KW_AWAIT - | KW_DYN - // reserved - | KW_ABSTRACT - | KW_BECOME - | KW_BOX - | KW_DO - | KW_FINAL - | KW_MACRO - | KW_OVERRIDE - | KW_PRIV - | KW_TYPEOF - | KW_UNSIZED - | KW_VIRTUAL - | KW_YIELD - | KW_TRY - | KW_UNION - | KW_STATICLIFETIME - ; - -macroIdentifierLikeToken - : keyword - | identifier - | KW_MACRORULES - | KW_UNDERLINELIFETIME - | KW_DOLLARCRATE - | LIFETIME_OR_LABEL - ; - -macroLiteralToken - : literalExpression - ; - -// macroDelimiterToken: LCURLYBRACE | RCURLYBRACE | LSQUAREBRACKET | RSQUAREBRACKET | LPAREN | RPAREN; -macroPunctuationToken - : MINUS - //| PLUS | STAR - | SLASH - | PERCENT - | CARET - | NOT - | AND - | OR - | ANDAND - | OROR - // already covered by LT and GT in macro | shl | shr - | PLUSEQ - | MINUSEQ - | STAREQ - | SLASHEQ - | PERCENTEQ - | CARETEQ - | ANDEQ - | OREQ - | SHLEQ - | SHREQ - | EQ - | EQEQ - | NE - | GT - | LT - | GE - | LE - | AT - | UNDERSCORE - | DOT - | DOTDOT - | DOTDOTDOT - | DOTDOTEQ - | COMMA - | SEMI - | COLON - | PATHSEP - | RARROW - | FATARROW - | POUND - //| DOLLAR | QUESTION - ; - -// LA can be removed, legal rust code still pass but the cost is `let c = a < < b` will pass... i hope antlr5 can add -// some new syntax? dsl? for these stuff so i needn't write it in (at least) 5 language - -shl - : LT {this.next('<')}? LT - ; - -shr - : GT {this.next('>')}? GT - ; From 6261ac5a7e221f354ae1af321573fe56f44c8c94 Mon Sep 17 00:00:00 2001 From: Julia Paluch Date: Fri, 20 Dec 2024 10:55:04 -0500 Subject: [PATCH 0385/1962] add README for rust grammar --- .../sourceforge/pmd/lang/rust/ast/README.md | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/README.md diff --git a/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/README.md b/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/README.md new file mode 100644 index 00000000000..6928ff1c585 --- /dev/null +++ b/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/README.md @@ -0,0 +1,26 @@ +# Rust Grammar + +The grammar files for Rust are taken from , released +under the MIT License: + +``` +Copyright (c) 2010 The Rust Project Developers +Copyright (c) 2020-2022 Student Main + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` + +## Currently used version + +* Source: From 8d7d5e938fea75a7e2477fff15cdb63cfb322a74 Mon Sep 17 00:00:00 2001 From: Julia Paluch Date: Fri, 20 Dec 2024 23:57:35 +0000 Subject: [PATCH 0386/1962] add placeholder for japicmp oldVersion and ignore missing old version for now --- pmd-rust/pom.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index fb157112607..a4920b9c367 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -47,6 +47,19 @@ + + com.github.siom79.japicmp + japicmp-maven-plugin + 0.23.0 + + + + ${project.build.directory}/${project.artifactId}-${project.version}.jar + + + true + + From 8c96831806696fb7fb6786bf66b39ecab5c74c9e Mon Sep 17 00:00:00 2001 From: Julia Paluch Date: Fri, 20 Dec 2024 23:59:00 +0000 Subject: [PATCH 0387/1962] ignore CPD and checkstyle for autogenerated and third-party files, fix import order, add helloworld.txt to test data --- .../pmd/lang/rust/RustLanguageModule.java | 2 +- .../pmd/lang/rust/ast/RustLexer.java | 1233 +++++++++++++++++ .../pmd/lang/rust/ast/RustLexerBase.java | 84 ++ .../pmd/lang/rust/cpd/RustCpdLexer.java | 2 +- .../pmd/lang/rust/cpd/RustCpdLexerTest.java | 8 +- .../pmd/lang/rust/cpd/testdata/helloworld.txt | 17 + 6 files changed, 1340 insertions(+), 6 deletions(-) create mode 100644 pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/ast/RustLexer.java create mode 100644 pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/ast/RustLexerBase.java create mode 100644 pmd-rust/src/test/resources/net/sourceforge/pmd/lang/rust/cpd/testdata/helloworld.txt diff --git a/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/RustLanguageModule.java b/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/RustLanguageModule.java index b23ee83665d..85a604cccc6 100644 --- a/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/RustLanguageModule.java +++ b/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/RustLanguageModule.java @@ -7,8 +7,8 @@ import net.sourceforge.pmd.cpd.CpdLexer; import net.sourceforge.pmd.lang.LanguagePropertyBundle; import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.rust.cpd.RustCpdLexer; import net.sourceforge.pmd.lang.impl.CpdOnlyLanguageModuleBase; +import net.sourceforge.pmd.lang.rust.cpd.RustCpdLexer; public class RustLanguageModule extends CpdOnlyLanguageModuleBase { private static final String ID = "rust"; diff --git a/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/ast/RustLexer.java b/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/ast/RustLexer.java new file mode 100644 index 00000000000..bea76462b9d --- /dev/null +++ b/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/ast/RustLexer.java @@ -0,0 +1,1233 @@ +// CHECKSTYLE:OFF Suppressing checkstyle checks for generated code +// Generated from RustLexer.g4 by ANTLR 4.13.2 +// CPD-OFF: Suppressing CPD checks for generated code +package net.sourceforge.pmd.lang.rust.cpd; + +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.misc.*; + +import net.sourceforge.pmd.lang.rust.ast.RustLexerBase; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue", "this-escape"}) +public class RustLexer extends RustLexerBase { + static { RuntimeMetaData.checkVersion("4.13.2", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + KW_AS=1, KW_BREAK=2, KW_CONST=3, KW_CONTINUE=4, KW_CRATE=5, KW_ELSE=6, + KW_ENUM=7, KW_EXTERN=8, KW_FALSE=9, KW_FN=10, KW_FOR=11, KW_IF=12, KW_IMPL=13, + KW_IN=14, KW_LET=15, KW_LOOP=16, KW_MATCH=17, KW_MOD=18, KW_MOVE=19, KW_MUT=20, + KW_PUB=21, KW_REF=22, KW_RETURN=23, KW_SELFVALUE=24, KW_SELFTYPE=25, KW_STATIC=26, + KW_STRUCT=27, KW_SUPER=28, KW_TRAIT=29, KW_TRUE=30, KW_TYPE=31, KW_UNSAFE=32, + KW_USE=33, KW_WHERE=34, KW_WHILE=35, KW_ASYNC=36, KW_AWAIT=37, KW_DYN=38, + KW_ABSTRACT=39, KW_BECOME=40, KW_BOX=41, KW_DO=42, KW_FINAL=43, KW_MACRO=44, + KW_OVERRIDE=45, KW_PRIV=46, KW_TYPEOF=47, KW_UNSIZED=48, KW_VIRTUAL=49, + KW_YIELD=50, KW_TRY=51, KW_UNION=52, KW_STATICLIFETIME=53, KW_MACRORULES=54, + KW_UNDERLINELIFETIME=55, KW_DOLLARCRATE=56, NON_KEYWORD_IDENTIFIER=57, + RAW_IDENTIFIER=58, LINE_COMMENT=59, BLOCK_COMMENT=60, INNER_LINE_DOC=61, + INNER_BLOCK_DOC=62, OUTER_LINE_DOC=63, OUTER_BLOCK_DOC=64, BLOCK_COMMENT_OR_DOC=65, + SHEBANG=66, WHITESPACE=67, NEWLINE=68, CHAR_LITERAL=69, STRING_LITERAL=70, + RAW_STRING_LITERAL=71, BYTE_LITERAL=72, BYTE_STRING_LITERAL=73, RAW_BYTE_STRING_LITERAL=74, + INTEGER_LITERAL=75, DEC_LITERAL=76, HEX_LITERAL=77, OCT_LITERAL=78, BIN_LITERAL=79, + FLOAT_LITERAL=80, LIFETIME_OR_LABEL=81, PLUS=82, MINUS=83, STAR=84, SLASH=85, + PERCENT=86, CARET=87, NOT=88, AND=89, OR=90, ANDAND=91, OROR=92, PLUSEQ=93, + MINUSEQ=94, STAREQ=95, SLASHEQ=96, PERCENTEQ=97, CARETEQ=98, ANDEQ=99, + OREQ=100, SHLEQ=101, SHREQ=102, EQ=103, EQEQ=104, NE=105, GT=106, LT=107, + GE=108, LE=109, AT=110, UNDERSCORE=111, DOT=112, DOTDOT=113, DOTDOTDOT=114, + DOTDOTEQ=115, COMMA=116, SEMI=117, COLON=118, PATHSEP=119, RARROW=120, + FATARROW=121, POUND=122, DOLLAR=123, QUESTION=124, LCURLYBRACE=125, RCURLYBRACE=126, + LSQUAREBRACKET=127, RSQUAREBRACKET=128, LPAREN=129, RPAREN=130; + public static String[] channelNames = { + "DEFAULT_TOKEN_CHANNEL", "HIDDEN" + }; + + public static String[] modeNames = { + "DEFAULT_MODE" + }; + + private static String[] makeRuleNames() { + return new String[] { + "KW_AS", "KW_BREAK", "KW_CONST", "KW_CONTINUE", "KW_CRATE", "KW_ELSE", + "KW_ENUM", "KW_EXTERN", "KW_FALSE", "KW_FN", "KW_FOR", "KW_IF", "KW_IMPL", + "KW_IN", "KW_LET", "KW_LOOP", "KW_MATCH", "KW_MOD", "KW_MOVE", "KW_MUT", + "KW_PUB", "KW_REF", "KW_RETURN", "KW_SELFVALUE", "KW_SELFTYPE", "KW_STATIC", + "KW_STRUCT", "KW_SUPER", "KW_TRAIT", "KW_TRUE", "KW_TYPE", "KW_UNSAFE", + "KW_USE", "KW_WHERE", "KW_WHILE", "KW_ASYNC", "KW_AWAIT", "KW_DYN", "KW_ABSTRACT", + "KW_BECOME", "KW_BOX", "KW_DO", "KW_FINAL", "KW_MACRO", "KW_OVERRIDE", + "KW_PRIV", "KW_TYPEOF", "KW_UNSIZED", "KW_VIRTUAL", "KW_YIELD", "KW_TRY", + "KW_UNION", "KW_STATICLIFETIME", "KW_MACRORULES", "KW_UNDERLINELIFETIME", + "KW_DOLLARCRATE", "NON_KEYWORD_IDENTIFIER", "XID_Start", "XID_Continue", + "UNICODE_OIDS", "UNICODE_OIDC", "RAW_IDENTIFIER", "LINE_COMMENT", "BLOCK_COMMENT", + "INNER_LINE_DOC", "INNER_BLOCK_DOC", "OUTER_LINE_DOC", "OUTER_BLOCK_DOC", + "BLOCK_COMMENT_OR_DOC", "SHEBANG", "WHITESPACE", "NEWLINE", "CHAR_LITERAL", + "STRING_LITERAL", "RAW_STRING_LITERAL", "RAW_STRING_CONTENT", "BYTE_LITERAL", + "BYTE_STRING_LITERAL", "RAW_BYTE_STRING_LITERAL", "ASCII_ESCAPE", "BYTE_ESCAPE", + "COMMON_ESCAPE", "UNICODE_ESCAPE", "QUOTE_ESCAPE", "ESC_NEWLINE", "INTEGER_LITERAL", + "DEC_LITERAL", "HEX_LITERAL", "OCT_LITERAL", "BIN_LITERAL", "FLOAT_LITERAL", + "INTEGER_SUFFIX", "FLOAT_SUFFIX", "FLOAT_EXPONENT", "OCT_DIGIT", "DEC_DIGIT", + "HEX_DIGIT", "LIFETIME_OR_LABEL", "PLUS", "MINUS", "STAR", "SLASH", "PERCENT", + "CARET", "NOT", "AND", "OR", "ANDAND", "OROR", "PLUSEQ", "MINUSEQ", "STAREQ", + "SLASHEQ", "PERCENTEQ", "CARETEQ", "ANDEQ", "OREQ", "SHLEQ", "SHREQ", + "EQ", "EQEQ", "NE", "GT", "LT", "GE", "LE", "AT", "UNDERSCORE", "DOT", + "DOTDOT", "DOTDOTDOT", "DOTDOTEQ", "COMMA", "SEMI", "COLON", "PATHSEP", + "RARROW", "FATARROW", "POUND", "DOLLAR", "QUESTION", "LCURLYBRACE", "RCURLYBRACE", + "LSQUAREBRACKET", "RSQUAREBRACKET", "LPAREN", "RPAREN" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, "'as'", "'break'", "'const'", "'continue'", "'crate'", "'else'", + "'enum'", "'extern'", "'false'", "'fn'", "'for'", "'if'", "'impl'", "'in'", + "'let'", "'loop'", "'match'", "'mod'", "'move'", "'mut'", "'pub'", "'ref'", + "'return'", "'self'", "'Self'", "'static'", "'struct'", "'super'", "'trait'", + "'true'", "'type'", "'unsafe'", "'use'", "'where'", "'while'", "'async'", + "'await'", "'dyn'", "'abstract'", "'become'", "'box'", "'do'", "'final'", + "'macro'", "'override'", "'priv'", "'typeof'", "'unsized'", "'virtual'", + "'yield'", "'try'", "'union'", "''static'", "'macro_rules'", "''_'", + "'$crate'", null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, "'+'", "'-'", "'*'", "'/'", "'%'", "'^'", "'!'", "'&'", + "'|'", "'&&'", "'||'", "'+='", "'-='", "'*='", "'/='", "'%='", "'^='", + "'&='", "'|='", "'<<='", "'>>='", "'='", "'=='", "'!='", "'>'", "'<'", + "'>='", "'<='", "'@'", "'_'", "'.'", "'..'", "'...'", "'..='", "','", + "';'", "':'", "'::'", "'->'", "'=>'", "'#'", "'$'", "'?'", "'{'", "'}'", + "'['", "']'", "'('", "')'" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, "KW_AS", "KW_BREAK", "KW_CONST", "KW_CONTINUE", "KW_CRATE", "KW_ELSE", + "KW_ENUM", "KW_EXTERN", "KW_FALSE", "KW_FN", "KW_FOR", "KW_IF", "KW_IMPL", + "KW_IN", "KW_LET", "KW_LOOP", "KW_MATCH", "KW_MOD", "KW_MOVE", "KW_MUT", + "KW_PUB", "KW_REF", "KW_RETURN", "KW_SELFVALUE", "KW_SELFTYPE", "KW_STATIC", + "KW_STRUCT", "KW_SUPER", "KW_TRAIT", "KW_TRUE", "KW_TYPE", "KW_UNSAFE", + "KW_USE", "KW_WHERE", "KW_WHILE", "KW_ASYNC", "KW_AWAIT", "KW_DYN", "KW_ABSTRACT", + "KW_BECOME", "KW_BOX", "KW_DO", "KW_FINAL", "KW_MACRO", "KW_OVERRIDE", + "KW_PRIV", "KW_TYPEOF", "KW_UNSIZED", "KW_VIRTUAL", "KW_YIELD", "KW_TRY", + "KW_UNION", "KW_STATICLIFETIME", "KW_MACRORULES", "KW_UNDERLINELIFETIME", + "KW_DOLLARCRATE", "NON_KEYWORD_IDENTIFIER", "RAW_IDENTIFIER", "LINE_COMMENT", + "BLOCK_COMMENT", "INNER_LINE_DOC", "INNER_BLOCK_DOC", "OUTER_LINE_DOC", + "OUTER_BLOCK_DOC", "BLOCK_COMMENT_OR_DOC", "SHEBANG", "WHITESPACE", "NEWLINE", + "CHAR_LITERAL", "STRING_LITERAL", "RAW_STRING_LITERAL", "BYTE_LITERAL", + "BYTE_STRING_LITERAL", "RAW_BYTE_STRING_LITERAL", "INTEGER_LITERAL", + "DEC_LITERAL", "HEX_LITERAL", "OCT_LITERAL", "BIN_LITERAL", "FLOAT_LITERAL", + "LIFETIME_OR_LABEL", "PLUS", "MINUS", "STAR", "SLASH", "PERCENT", "CARET", + "NOT", "AND", "OR", "ANDAND", "OROR", "PLUSEQ", "MINUSEQ", "STAREQ", + "SLASHEQ", "PERCENTEQ", "CARETEQ", "ANDEQ", "OREQ", "SHLEQ", "SHREQ", + "EQ", "EQEQ", "NE", "GT", "LT", "GE", "LE", "AT", "UNDERSCORE", "DOT", + "DOTDOT", "DOTDOTDOT", "DOTDOTEQ", "COMMA", "SEMI", "COLON", "PATHSEP", + "RARROW", "FATARROW", "POUND", "DOLLAR", "QUESTION", "LCURLYBRACE", "RCURLYBRACE", + "LSQUAREBRACKET", "RSQUAREBRACKET", "LPAREN", "RPAREN" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + + public RustLexer(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @Override + public String getGrammarFileName() { return "RustLexer.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public String[] getChannelNames() { return channelNames; } + + @Override + public String[] getModeNames() { return modeNames; } + + @Override + public ATN getATN() { return _ATN; } + + @Override + public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { + switch (ruleIndex) { + case 69: + return SHEBANG_sempred((RuleContext)_localctx, predIndex); + case 90: + return FLOAT_LITERAL_sempred((RuleContext)_localctx, predIndex); + } + return true; + } + private boolean SHEBANG_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 0: + return this.SOF(); + } + return true; + } + private boolean FLOAT_LITERAL_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 1: + return this.floatLiteralPossible(); + case 2: + return this.floatDotPossible(); + } + return true; + } + + public static final String _serializedATN = + "\u0004\u0000\u0082\u04a4\u0006\uffff\uffff\u0002\u0000\u0007\u0000\u0002"+ + "\u0001\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002"+ + "\u0004\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002"+ + "\u0007\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002"+ + "\u000b\u0007\u000b\u0002\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e"+ + "\u0002\u000f\u0007\u000f\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011"+ + "\u0002\u0012\u0007\u0012\u0002\u0013\u0007\u0013\u0002\u0014\u0007\u0014"+ + "\u0002\u0015\u0007\u0015\u0002\u0016\u0007\u0016\u0002\u0017\u0007\u0017"+ + "\u0002\u0018\u0007\u0018\u0002\u0019\u0007\u0019\u0002\u001a\u0007\u001a"+ + "\u0002\u001b\u0007\u001b\u0002\u001c\u0007\u001c\u0002\u001d\u0007\u001d"+ + "\u0002\u001e\u0007\u001e\u0002\u001f\u0007\u001f\u0002 \u0007 \u0002!"+ + "\u0007!\u0002\"\u0007\"\u0002#\u0007#\u0002$\u0007$\u0002%\u0007%\u0002"+ + "&\u0007&\u0002\'\u0007\'\u0002(\u0007(\u0002)\u0007)\u0002*\u0007*\u0002"+ + "+\u0007+\u0002,\u0007,\u0002-\u0007-\u0002.\u0007.\u0002/\u0007/\u0002"+ + "0\u00070\u00021\u00071\u00022\u00072\u00023\u00073\u00024\u00074\u0002"+ + "5\u00075\u00026\u00076\u00027\u00077\u00028\u00078\u00029\u00079\u0002"+ + ":\u0007:\u0002;\u0007;\u0002<\u0007<\u0002=\u0007=\u0002>\u0007>\u0002"+ + "?\u0007?\u0002@\u0007@\u0002A\u0007A\u0002B\u0007B\u0002C\u0007C\u0002"+ + "D\u0007D\u0002E\u0007E\u0002F\u0007F\u0002G\u0007G\u0002H\u0007H\u0002"+ + "I\u0007I\u0002J\u0007J\u0002K\u0007K\u0002L\u0007L\u0002M\u0007M\u0002"+ + "N\u0007N\u0002O\u0007O\u0002P\u0007P\u0002Q\u0007Q\u0002R\u0007R\u0002"+ + "S\u0007S\u0002T\u0007T\u0002U\u0007U\u0002V\u0007V\u0002W\u0007W\u0002"+ + "X\u0007X\u0002Y\u0007Y\u0002Z\u0007Z\u0002[\u0007[\u0002\\\u0007\\\u0002"+ + "]\u0007]\u0002^\u0007^\u0002_\u0007_\u0002`\u0007`\u0002a\u0007a\u0002"+ + "b\u0007b\u0002c\u0007c\u0002d\u0007d\u0002e\u0007e\u0002f\u0007f\u0002"+ + "g\u0007g\u0002h\u0007h\u0002i\u0007i\u0002j\u0007j\u0002k\u0007k\u0002"+ + "l\u0007l\u0002m\u0007m\u0002n\u0007n\u0002o\u0007o\u0002p\u0007p\u0002"+ + "q\u0007q\u0002r\u0007r\u0002s\u0007s\u0002t\u0007t\u0002u\u0007u\u0002"+ + "v\u0007v\u0002w\u0007w\u0002x\u0007x\u0002y\u0007y\u0002z\u0007z\u0002"+ + "{\u0007{\u0002|\u0007|\u0002}\u0007}\u0002~\u0007~\u0002\u007f\u0007\u007f"+ + "\u0002\u0080\u0007\u0080\u0002\u0081\u0007\u0081\u0002\u0082\u0007\u0082"+ + "\u0002\u0083\u0007\u0083\u0002\u0084\u0007\u0084\u0002\u0085\u0007\u0085"+ + "\u0002\u0086\u0007\u0086\u0002\u0087\u0007\u0087\u0002\u0088\u0007\u0088"+ + "\u0002\u0089\u0007\u0089\u0002\u008a\u0007\u008a\u0002\u008b\u0007\u008b"+ + "\u0002\u008c\u0007\u008c\u0002\u008d\u0007\u008d\u0002\u008e\u0007\u008e"+ + "\u0002\u008f\u0007\u008f\u0002\u0090\u0007\u0090\u0002\u0091\u0007\u0091"+ + "\u0002\u0092\u0007\u0092\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002"+ + "\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0003"+ + "\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003"+ + "\u0001\u0003\u0001\u0003\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004"+ + "\u0001\u0004\u0001\u0004\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005"+ + "\u0001\u0005\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006"+ + "\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007"+ + "\u0001\u0007\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\t\u0001"+ + "\t\u0001\t\u0001\n\u0001\n\u0001\n\u0001\n\u0001\u000b\u0001\u000b\u0001"+ + "\u000b\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\r\u0001\r\u0001\r"+ + "\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000f\u0001\u000f"+ + "\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u0010\u0001\u0010\u0001\u0010"+ + "\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0011\u0001\u0011\u0001\u0011"+ + "\u0001\u0011\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012"+ + "\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0014\u0001\u0014"+ + "\u0001\u0014\u0001\u0014\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015"+ + "\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016"+ + "\u0001\u0016\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017"+ + "\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0019"+ + "\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019"+ + "\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001a"+ + "\u0001\u001a\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b"+ + "\u0001\u001b\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001c"+ + "\u0001\u001c\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d"+ + "\u0001\u001e\u0001\u001e\u0001\u001e\u0001\u001e\u0001\u001e\u0001\u001f"+ + "\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f"+ + "\u0001 \u0001 \u0001 \u0001 \u0001!\u0001!\u0001!\u0001!\u0001!\u0001"+ + "!\u0001\"\u0001\"\u0001\"\u0001\"\u0001\"\u0001\"\u0001#\u0001#\u0001"+ + "#\u0001#\u0001#\u0001#\u0001$\u0001$\u0001$\u0001$\u0001$\u0001$\u0001"+ + "%\u0001%\u0001%\u0001%\u0001&\u0001&\u0001&\u0001&\u0001&\u0001&\u0001"+ + "&\u0001&\u0001&\u0001\'\u0001\'\u0001\'\u0001\'\u0001\'\u0001\'\u0001"+ + "\'\u0001(\u0001(\u0001(\u0001(\u0001)\u0001)\u0001)\u0001*\u0001*\u0001"+ + "*\u0001*\u0001*\u0001*\u0001+\u0001+\u0001+\u0001+\u0001+\u0001+\u0001"+ + ",\u0001,\u0001,\u0001,\u0001,\u0001,\u0001,\u0001,\u0001,\u0001-\u0001"+ + "-\u0001-\u0001-\u0001-\u0001.\u0001.\u0001.\u0001.\u0001.\u0001.\u0001"+ + ".\u0001/\u0001/\u0001/\u0001/\u0001/\u0001/\u0001/\u0001/\u00010\u0001"+ + "0\u00010\u00010\u00010\u00010\u00010\u00010\u00011\u00011\u00011\u0001"+ + "1\u00011\u00011\u00012\u00012\u00012\u00012\u00013\u00013\u00013\u0001"+ + "3\u00013\u00013\u00014\u00014\u00014\u00014\u00014\u00014\u00014\u0001"+ + "4\u00015\u00015\u00015\u00015\u00015\u00015\u00015\u00015\u00015\u0001"+ + "5\u00015\u00015\u00016\u00016\u00016\u00017\u00017\u00017\u00017\u0001"+ + "7\u00017\u00017\u00018\u00018\u00058\u0267\b8\n8\f8\u026a\t8\u00018\u0001"+ + "8\u00048\u026e\b8\u000b8\f8\u026f\u00038\u0272\b8\u00019\u00019\u0003"+ + "9\u0276\b9\u0001:\u0001:\u0001:\u0003:\u027b\b:\u0001;\u0001;\u0001<\u0001"+ + "<\u0001=\u0001=\u0001=\u0001=\u0001=\u0001>\u0001>\u0001>\u0001>\u0001"+ + ">\u0001>\u0003>\u028c\b>\u0001>\u0005>\u028f\b>\n>\f>\u0292\t>\u0001>"+ + "\u0001>\u0003>\u0296\b>\u0001>\u0001>\u0001?\u0001?\u0001?\u0001?\u0001"+ + "?\u0001?\u0001?\u0003?\u02a1\b?\u0001?\u0001?\u0005?\u02a5\b?\n?\f?\u02a8"+ + "\t?\u0001?\u0001?\u0001?\u0001?\u0001?\u0001?\u0001?\u0001?\u0001?\u0001"+ + "?\u0001?\u0003?\u02b5\b?\u0001?\u0001?\u0001@\u0001@\u0001@\u0001@\u0001"+ + "@\u0005@\u02be\b@\n@\f@\u02c1\t@\u0001@\u0001@\u0001A\u0001A\u0001A\u0001"+ + "A\u0001A\u0001A\u0005A\u02cb\bA\nA\fA\u02ce\tA\u0001A\u0001A\u0001A\u0001"+ + "A\u0001A\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0005B\u02db\bB\nB"+ + "\fB\u02de\tB\u0003B\u02e0\bB\u0001B\u0001B\u0001C\u0001C\u0001C\u0001"+ + "C\u0001C\u0001C\u0003C\u02ea\bC\u0001C\u0001C\u0005C\u02ee\bC\nC\fC\u02f1"+ + "\tC\u0001C\u0001C\u0001C\u0001C\u0001C\u0001D\u0001D\u0001D\u0003D\u02fb"+ + "\bD\u0001D\u0001D\u0001E\u0001E\u0003E\u0301\bE\u0001E\u0001E\u0001E\u0001"+ + "E\u0005E\u0307\bE\nE\fE\u030a\tE\u0001E\u0001E\u0001F\u0001F\u0001F\u0001"+ + "F\u0001G\u0001G\u0001G\u0003G\u0315\bG\u0001G\u0001G\u0001H\u0001H\u0001"+ + "H\u0001H\u0001H\u0003H\u031e\bH\u0001H\u0001H\u0001I\u0001I\u0001I\u0001"+ + "I\u0001I\u0001I\u0005I\u0328\bI\nI\fI\u032b\tI\u0001I\u0001I\u0001J\u0001"+ + "J\u0001J\u0001K\u0001K\u0001K\u0001K\u0001K\u0001K\u0005K\u0338\bK\nK"+ + "\fK\u033b\tK\u0001K\u0003K\u033e\bK\u0001L\u0001L\u0001L\u0001L\u0001"+ + "L\u0001L\u0003L\u0346\bL\u0001L\u0001L\u0001M\u0001M\u0001M\u0001M\u0001"+ + "M\u0001M\u0005M\u0350\bM\nM\fM\u0353\tM\u0001M\u0001M\u0001N\u0001N\u0001"+ + "N\u0001N\u0001N\u0001O\u0001O\u0001O\u0001O\u0001O\u0001O\u0001O\u0003"+ + "O\u0363\bO\u0001P\u0001P\u0001P\u0001P\u0001P\u0001P\u0001P\u0003P\u036c"+ + "\bP\u0001Q\u0001Q\u0001Q\u0001R\u0001R\u0001R\u0001R\u0001R\u0001R\u0003"+ + "R\u0377\bR\u0001R\u0003R\u037a\bR\u0001R\u0003R\u037d\bR\u0001R\u0003"+ + "R\u0380\bR\u0001R\u0003R\u0383\bR\u0001R\u0001R\u0001S\u0001S\u0001S\u0001"+ + "T\u0001T\u0001T\u0001U\u0001U\u0001U\u0001U\u0003U\u0391\bU\u0001U\u0003"+ + "U\u0394\bU\u0001V\u0001V\u0001V\u0005V\u0399\bV\nV\fV\u039c\tV\u0001W"+ + "\u0001W\u0001W\u0001W\u0005W\u03a2\bW\nW\fW\u03a5\tW\u0001W\u0001W\u0001"+ + "W\u0005W\u03aa\bW\nW\fW\u03ad\tW\u0001X\u0001X\u0001X\u0001X\u0005X\u03b3"+ + "\bX\nX\fX\u03b6\tX\u0001X\u0001X\u0001X\u0005X\u03bb\bX\nX\fX\u03be\t"+ + "X\u0001Y\u0001Y\u0001Y\u0001Y\u0005Y\u03c4\bY\nY\fY\u03c7\tY\u0001Y\u0001"+ + "Y\u0005Y\u03cb\bY\nY\fY\u03ce\tY\u0001Z\u0001Z\u0001Z\u0001Z\u0001Z\u0001"+ + "Z\u0001Z\u0001Z\u0003Z\u03d8\bZ\u0001Z\u0003Z\u03db\bZ\u0001Z\u0003Z\u03de"+ + "\bZ\u0003Z\u03e0\bZ\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001"+ + "[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001"+ + "[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001"+ + "[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001"+ + "[\u0001[\u0001[\u0003[\u040a\b[\u0001\\\u0001\\\u0001\\\u0001\\\u0001"+ + "\\\u0001\\\u0003\\\u0412\b\\\u0001]\u0001]\u0003]\u0416\b]\u0001]\u0005"+ + "]\u0419\b]\n]\f]\u041c\t]\u0001]\u0001]\u0001^\u0001^\u0001_\u0001_\u0001"+ + "`\u0001`\u0001a\u0001a\u0001a\u0001b\u0001b\u0001c\u0001c\u0001d\u0001"+ + "d\u0001e\u0001e\u0001f\u0001f\u0001g\u0001g\u0001h\u0001h\u0001i\u0001"+ + "i\u0001j\u0001j\u0001k\u0001k\u0001k\u0001l\u0001l\u0001l\u0001m\u0001"+ + "m\u0001m\u0001n\u0001n\u0001n\u0001o\u0001o\u0001o\u0001p\u0001p\u0001"+ + "p\u0001q\u0001q\u0001q\u0001r\u0001r\u0001r\u0001s\u0001s\u0001s\u0001"+ + "t\u0001t\u0001t\u0001u\u0001u\u0001u\u0001u\u0001v\u0001v\u0001v\u0001"+ + "v\u0001w\u0001w\u0001x\u0001x\u0001x\u0001y\u0001y\u0001y\u0001z\u0001"+ + "z\u0001{\u0001{\u0001|\u0001|\u0001|\u0001}\u0001}\u0001}\u0001~\u0001"+ + "~\u0001\u007f\u0001\u007f\u0001\u0080\u0001\u0080\u0001\u0081\u0001\u0081"+ + "\u0001\u0081\u0001\u0082\u0001\u0082\u0001\u0082\u0001\u0082\u0001\u0083"+ + "\u0001\u0083\u0001\u0083\u0001\u0083\u0001\u0084\u0001\u0084\u0001\u0085"+ + "\u0001\u0085\u0001\u0086\u0001\u0086\u0001\u0087\u0001\u0087\u0001\u0087"+ + "\u0001\u0088\u0001\u0088\u0001\u0088\u0001\u0089\u0001\u0089\u0001\u0089"+ + "\u0001\u008a\u0001\u008a\u0001\u008b\u0001\u008b\u0001\u008c\u0001\u008c"+ + "\u0001\u008d\u0001\u008d\u0001\u008e\u0001\u008e\u0001\u008f\u0001\u008f"+ + "\u0001\u0090\u0001\u0090\u0001\u0091\u0001\u0091\u0001\u0092\u0001\u0092"+ + "\u0004\u02a6\u02cc\u02ef\u0339\u0000\u0093\u0001\u0001\u0003\u0002\u0005"+ + "\u0003\u0007\u0004\t\u0005\u000b\u0006\r\u0007\u000f\b\u0011\t\u0013\n"+ + "\u0015\u000b\u0017\f\u0019\r\u001b\u000e\u001d\u000f\u001f\u0010!\u0011"+ + "#\u0012%\u0013\'\u0014)\u0015+\u0016-\u0017/\u00181\u00193\u001a5\u001b"+ + "7\u001c9\u001d;\u001e=\u001f? A!C\"E#G$I%K&M\'O(Q)S*U+W,Y-[.]/_0a1c2e"+ + "3g4i5k6m7o8q9s\u0000u\u0000w\u0000y\u0000{:};\u007f<\u0081=\u0083>\u0085"+ + "?\u0087@\u0089A\u008bB\u008dC\u008fD\u0091E\u0093F\u0095G\u0097\u0000"+ + "\u0099H\u009bI\u009dJ\u009f\u0000\u00a1\u0000\u00a3\u0000\u00a5\u0000"+ + "\u00a7\u0000\u00a9\u0000\u00abK\u00adL\u00afM\u00b1N\u00b3O\u00b5P\u00b7"+ + "\u0000\u00b9\u0000\u00bb\u0000\u00bd\u0000\u00bf\u0000\u00c1\u0000\u00c3"+ + "Q\u00c5R\u00c7S\u00c9T\u00cbU\u00cdV\u00cfW\u00d1X\u00d3Y\u00d5Z\u00d7"+ + "[\u00d9\\\u00db]\u00dd^\u00df_\u00e1`\u00e3a\u00e5b\u00e7c\u00e9d\u00eb"+ + "e\u00edf\u00efg\u00f1h\u00f3i\u00f5j\u00f7k\u00f9l\u00fbm\u00fdn\u00ff"+ + "o\u0101p\u0103q\u0105r\u0107s\u0109t\u010bu\u010dv\u010fw\u0111x\u0113"+ + "y\u0115z\u0117{\u0119|\u011b}\u011d~\u011f\u007f\u0121\u0080\u0123\u0081"+ + "\u0125\u0082\u0001\u0000\u0015\u0296\u0000AZaz\u00aa\u00aa\u00b5\u00b5"+ + "\u00ba\u00ba\u00c0\u00d6\u00d8\u00f6\u00f8\u02c1\u02c6\u02d1\u02e0\u02e4"+ + "\u02ec\u02ec\u02ee\u02ee\u0370\u0374\u0376\u0377\u037a\u037d\u037f\u037f"+ + "\u0386\u0386\u0388\u038a\u038c\u038c\u038e\u03a1\u03a3\u03f5\u03f7\u0481"+ + "\u048a\u052f\u0531\u0556\u0559\u0559\u0560\u0588\u05d0\u05ea\u05ef\u05f2"+ + "\u0620\u064a\u066e\u066f\u0671\u06d3\u06d5\u06d5\u06e5\u06e6\u06ee\u06ef"+ + "\u06fa\u06fc\u06ff\u06ff\u0710\u0710\u0712\u072f\u074d\u07a5\u07b1\u07b1"+ + "\u07ca\u07ea\u07f4\u07f5\u07fa\u07fa\u0800\u0815\u081a\u081a\u0824\u0824"+ + "\u0828\u0828\u0840\u0858\u0860\u086a\u0870\u0887\u0889\u088e\u08a0\u08c9"+ + "\u0904\u0939\u093d\u093d\u0950\u0950\u0958\u0961\u0971\u0980\u0985\u098c"+ + "\u098f\u0990\u0993\u09a8\u09aa\u09b0\u09b2\u09b2\u09b6\u09b9\u09bd\u09bd"+ + "\u09ce\u09ce\u09dc\u09dd\u09df\u09e1\u09f0\u09f1\u09fc\u09fc\u0a05\u0a0a"+ + "\u0a0f\u0a10\u0a13\u0a28\u0a2a\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39"+ + "\u0a59\u0a5c\u0a5e\u0a5e\u0a72\u0a74\u0a85\u0a8d\u0a8f\u0a91\u0a93\u0aa8"+ + "\u0aaa\u0ab0\u0ab2\u0ab3\u0ab5\u0ab9\u0abd\u0abd\u0ad0\u0ad0\u0ae0\u0ae1"+ + "\u0af9\u0af9\u0b05\u0b0c\u0b0f\u0b10\u0b13\u0b28\u0b2a\u0b30\u0b32\u0b33"+ + "\u0b35\u0b39\u0b3d\u0b3d\u0b5c\u0b5d\u0b5f\u0b61\u0b71\u0b71\u0b83\u0b83"+ + "\u0b85\u0b8a\u0b8e\u0b90\u0b92\u0b95\u0b99\u0b9a\u0b9c\u0b9c\u0b9e\u0b9f"+ + "\u0ba3\u0ba4\u0ba8\u0baa\u0bae\u0bb9\u0bd0\u0bd0\u0c05\u0c0c\u0c0e\u0c10"+ + "\u0c12\u0c28\u0c2a\u0c39\u0c3d\u0c3d\u0c58\u0c5a\u0c5d\u0c5d\u0c60\u0c61"+ + "\u0c80\u0c80\u0c85\u0c8c\u0c8e\u0c90\u0c92\u0ca8\u0caa\u0cb3\u0cb5\u0cb9"+ + "\u0cbd\u0cbd\u0cdd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04\u0d0c\u0d0e\u0d10"+ + "\u0d12\u0d3a\u0d3d\u0d3d\u0d4e\u0d4e\u0d54\u0d56\u0d5f\u0d61\u0d7a\u0d7f"+ + "\u0d85\u0d96\u0d9a\u0db1\u0db3\u0dbb\u0dbd\u0dbd\u0dc0\u0dc6\u0e01\u0e30"+ + "\u0e32\u0e33\u0e40\u0e46\u0e81\u0e82\u0e84\u0e84\u0e86\u0e8a\u0e8c\u0ea3"+ + "\u0ea5\u0ea5\u0ea7\u0eb0\u0eb2\u0eb3\u0ebd\u0ebd\u0ec0\u0ec4\u0ec6\u0ec6"+ + "\u0edc\u0edf\u0f00\u0f00\u0f40\u0f47\u0f49\u0f6c\u0f88\u0f8c\u1000\u102a"+ + "\u103f\u103f\u1050\u1055\u105a\u105d\u1061\u1061\u1065\u1066\u106e\u1070"+ + "\u1075\u1081\u108e\u108e\u10a0\u10c5\u10c7\u10c7\u10cd\u10cd\u10d0\u10fa"+ + "\u10fc\u1248\u124a\u124d\u1250\u1256\u1258\u1258\u125a\u125d\u1260\u1288"+ + "\u128a\u128d\u1290\u12b0\u12b2\u12b5\u12b8\u12be\u12c0\u12c0\u12c2\u12c5"+ + "\u12c8\u12d6\u12d8\u1310\u1312\u1315\u1318\u135a\u1380\u138f\u13a0\u13f5"+ + "\u13f8\u13fd\u1401\u166c\u166f\u167f\u1681\u169a\u16a0\u16ea\u16ee\u16f8"+ + "\u1700\u1711\u171f\u1731\u1740\u1751\u1760\u176c\u176e\u1770\u1780\u17b3"+ + "\u17d7\u17d7\u17dc\u17dc\u1820\u1878\u1880\u1884\u1887\u18a8\u18aa\u18aa"+ + "\u18b0\u18f5\u1900\u191e\u1950\u196d\u1970\u1974\u1980\u19ab\u19b0\u19c9"+ + "\u1a00\u1a16\u1a20\u1a54\u1aa7\u1aa7\u1b05\u1b33\u1b45\u1b4c\u1b83\u1ba0"+ + "\u1bae\u1baf\u1bba\u1be5\u1c00\u1c23\u1c4d\u1c4f\u1c5a\u1c7d\u1c80\u1c88"+ + "\u1c90\u1cba\u1cbd\u1cbf\u1ce9\u1cec\u1cee\u1cf3\u1cf5\u1cf6\u1cfa\u1cfa"+ + "\u1d00\u1dbf\u1e00\u1f15\u1f18\u1f1d\u1f20\u1f45\u1f48\u1f4d\u1f50\u1f57"+ + "\u1f59\u1f59\u1f5b\u1f5b\u1f5d\u1f5d\u1f5f\u1f7d\u1f80\u1fb4\u1fb6\u1fbc"+ + "\u1fbe\u1fbe\u1fc2\u1fc4\u1fc6\u1fcc\u1fd0\u1fd3\u1fd6\u1fdb\u1fe0\u1fec"+ + "\u1ff2\u1ff4\u1ff6\u1ffc\u2071\u2071\u207f\u207f\u2090\u209c\u2102\u2102"+ + "\u2107\u2107\u210a\u2113\u2115\u2115\u2119\u211d\u2124\u2124\u2126\u2126"+ + "\u2128\u2128\u212a\u212d\u212f\u2139\u213c\u213f\u2145\u2149\u214e\u214e"+ + "\u2160\u2188\u2c00\u2ce4\u2ceb\u2cee\u2cf2\u2cf3\u2d00\u2d25\u2d27\u2d27"+ + "\u2d2d\u2d2d\u2d30\u2d67\u2d6f\u2d6f\u2d80\u2d96\u2da0\u2da6\u2da8\u2dae"+ + "\u2db0\u2db6\u2db8\u2dbe\u2dc0\u2dc6\u2dc8\u2dce\u2dd0\u2dd6\u2dd8\u2dde"+ + "\u2e2f\u2e2f\u3005\u3007\u3021\u3029\u3031\u3035\u3038\u303c\u3041\u3096"+ + "\u309d\u309f\u30a1\u30fa\u30fc\u30ff\u3105\u312f\u3131\u318e\u31a0\u31bf"+ + "\u31f0\u31ff\u3400\u4dbf\u4e00\u8000\ua48c\u8000\ua4d0\u8000\ua4fd\u8000"+ + "\ua500\u8000\ua60c\u8000\ua610\u8000\ua61f\u8000\ua62a\u8000\ua62b\u8000"+ + "\ua640\u8000\ua66e\u8000\ua67f\u8000\ua69d\u8000\ua6a0\u8000\ua6ef\u8000"+ + "\ua717\u8000\ua71f\u8000\ua722\u8000\ua788\u8000\ua78b\u8000\ua7ca\u8000"+ + "\ua7d0\u8000\ua7d1\u8000\ua7d3\u8000\ua7d3\u8000\ua7d5\u8000\ua7d9\u8000"+ + "\ua7f2\u8000\ua801\u8000\ua803\u8000\ua805\u8000\ua807\u8000\ua80a\u8000"+ + "\ua80c\u8000\ua822\u8000\ua840\u8000\ua873\u8000\ua882\u8000\ua8b3\u8000"+ + "\ua8f2\u8000\ua8f7\u8000\ua8fb\u8000\ua8fb\u8000\ua8fd\u8000\ua8fe\u8000"+ + "\ua90a\u8000\ua925\u8000\ua930\u8000\ua946\u8000\ua960\u8000\ua97c\u8000"+ + "\ua984\u8000\ua9b2\u8000\ua9cf\u8000\ua9cf\u8000\ua9e0\u8000\ua9e4\u8000"+ + "\ua9e6\u8000\ua9ef\u8000\ua9fa\u8000\ua9fe\u8000\uaa00\u8000\uaa28\u8000"+ + "\uaa40\u8000\uaa42\u8000\uaa44\u8000\uaa4b\u8000\uaa60\u8000\uaa76\u8000"+ + "\uaa7a\u8000\uaa7a\u8000\uaa7e\u8000\uaaaf\u8000\uaab1\u8000\uaab1\u8000"+ + "\uaab5\u8000\uaab6\u8000\uaab9\u8000\uaabd\u8000\uaac0\u8000\uaac0\u8000"+ + "\uaac2\u8000\uaac2\u8000\uaadb\u8000\uaadd\u8000\uaae0\u8000\uaaea\u8000"+ + "\uaaf2\u8000\uaaf4\u8000\uab01\u8000\uab06\u8000\uab09\u8000\uab0e\u8000"+ + "\uab11\u8000\uab16\u8000\uab20\u8000\uab26\u8000\uab28\u8000\uab2e\u8000"+ + "\uab30\u8000\uab5a\u8000\uab5c\u8000\uab69\u8000\uab70\u8000\uabe2\u8000"+ + "\uac00\u8000\ud7a3\u8000\ud7b0\u8000\ud7c6\u8000\ud7cb\u8000\ud7fb\u8000"+ + "\uf900\u8000\ufa6d\u8000\ufa70\u8000\ufad9\u8000\ufb00\u8000\ufb06\u8000"+ + "\ufb13\u8000\ufb17\u8000\ufb1d\u8000\ufb1d\u8000\ufb1f\u8000\ufb28\u8000"+ + "\ufb2a\u8000\ufb36\u8000\ufb38\u8000\ufb3c\u8000\ufb3e\u8000\ufb3e\u8000"+ + "\ufb40\u8000\ufb41\u8000\ufb43\u8000\ufb44\u8000\ufb46\u8000\ufbb1\u8000"+ + "\ufbd3\u8000\ufd3d\u8000\ufd50\u8000\ufd8f\u8000\ufd92\u8000\ufdc7\u8000"+ + "\ufdf0\u8000\ufdfb\u8000\ufe70\u8000\ufe74\u8000\ufe76\u8000\ufefc\u8000"+ + "\uff21\u8000\uff3a\u8000\uff41\u8000\uff5a\u8000\uff66\u8000\uffbe\u8000"+ + "\uffc2\u8000\uffc7\u8000\uffca\u8000\uffcf\u8000\uffd2\u8000\uffd7\u8000"+ + "\uffda\u8000\uffdc\u8001\u0000\u8001\u000b\u8001\r\u8001&\u8001(\u8001"+ + ":\u8001<\u8001=\u8001?\u8001M\u8001P\u8001]\u8001\u0080\u8001\u00fa\u8001"+ + "\u0140\u8001\u0174\u8001\u0280\u8001\u029c\u8001\u02a0\u8001\u02d0\u8001"+ + "\u0300\u8001\u031f\u8001\u032d\u8001\u034a\u8001\u0350\u8001\u0375\u8001"+ + "\u0380\u8001\u039d\u8001\u03a0\u8001\u03c3\u8001\u03c8\u8001\u03cf\u8001"+ + "\u03d1\u8001\u03d5\u8001\u0400\u8001\u049d\u8001\u04b0\u8001\u04d3\u8001"+ + "\u04d8\u8001\u04fb\u8001\u0500\u8001\u0527\u8001\u0530\u8001\u0563\u8001"+ + "\u0570\u8001\u057a\u8001\u057c\u8001\u058a\u8001\u058c\u8001\u0592\u8001"+ + "\u0594\u8001\u0595\u8001\u0597\u8001\u05a1\u8001\u05a3\u8001\u05b1\u8001"+ + "\u05b3\u8001\u05b9\u8001\u05bb\u8001\u05bc\u8001\u0600\u8001\u0736\u8001"+ + "\u0740\u8001\u0755\u8001\u0760\u8001\u0767\u8001\u0780\u8001\u0785\u8001"+ + "\u0787\u8001\u07b0\u8001\u07b2\u8001\u07ba\u8001\u0800\u8001\u0805\u8001"+ + "\u0808\u8001\u0808\u8001\u080a\u8001\u0835\u8001\u0837\u8001\u0838\u8001"+ + "\u083c\u8001\u083c\u8001\u083f\u8001\u0855\u8001\u0860\u8001\u0876\u8001"+ + "\u0880\u8001\u089e\u8001\u08e0\u8001\u08f2\u8001\u08f4\u8001\u08f5\u8001"+ + "\u0900\u8001\u0915\u8001\u0920\u8001\u0939\u8001\u0980\u8001\u09b7\u8001"+ + "\u09be\u8001\u09bf\u8001\u0a00\u8001\u0a00\u8001\u0a10\u8001\u0a13\u8001"+ + "\u0a15\u8001\u0a17\u8001\u0a19\u8001\u0a35\u8001\u0a60\u8001\u0a7c\u8001"+ + "\u0a80\u8001\u0a9c\u8001\u0ac0\u8001\u0ac7\u8001\u0ac9\u8001\u0ae4\u8001"+ + "\u0b00\u8001\u0b35\u8001\u0b40\u8001\u0b55\u8001\u0b60\u8001\u0b72\u8001"+ + "\u0b80\u8001\u0b91\u8001\u0c00\u8001\u0c48\u8001\u0c80\u8001\u0cb2\u8001"+ + "\u0cc0\u8001\u0cf2\u8001\u0d00\u8001\u0d23\u8001\u0e80\u8001\u0ea9\u8001"+ + "\u0eb0\u8001\u0eb1\u8001\u0f00\u8001\u0f1c\u8001\u0f27\u8001\u0f27\u8001"+ + "\u0f30\u8001\u0f45\u8001\u0f70\u8001\u0f81\u8001\u0fb0\u8001\u0fc4\u8001"+ + "\u0fe0\u8001\u0ff6\u8001\u1003\u8001\u1037\u8001\u1071\u8001\u1072\u8001"+ + "\u1075\u8001\u1075\u8001\u1083\u8001\u10af\u8001\u10d0\u8001\u10e8\u8001"+ + "\u1103\u8001\u1126\u8001\u1144\u8001\u1144\u8001\u1147\u8001\u1147\u8001"+ + "\u1150\u8001\u1172\u8001\u1176\u8001\u1176\u8001\u1183\u8001\u11b2\u8001"+ + "\u11c1\u8001\u11c4\u8001\u11da\u8001\u11da\u8001\u11dc\u8001\u11dc\u8001"+ + "\u1200\u8001\u1211\u8001\u1213\u8001\u122b\u8001\u123f\u8001\u1240\u8001"+ + "\u1280\u8001\u1286\u8001\u1288\u8001\u1288\u8001\u128a\u8001\u128d\u8001"+ + "\u128f\u8001\u129d\u8001\u129f\u8001\u12a8\u8001\u12b0\u8001\u12de\u8001"+ + "\u1305\u8001\u130c\u8001\u130f\u8001\u1310\u8001\u1313\u8001\u1328\u8001"+ + "\u132a\u8001\u1330\u8001\u1332\u8001\u1333\u8001\u1335\u8001\u1339\u8001"+ + "\u133d\u8001\u133d\u8001\u1350\u8001\u1350\u8001\u135d\u8001\u1361\u8001"+ + "\u1400\u8001\u1434\u8001\u1447\u8001\u144a\u8001\u145f\u8001\u1461\u8001"+ + "\u1480\u8001\u14af\u8001\u14c4\u8001\u14c5\u8001\u14c7\u8001\u14c7\u8001"+ + "\u1580\u8001\u15ae\u8001\u15d8\u8001\u15db\u8001\u1600\u8001\u162f\u8001"+ + "\u1644\u8001\u1644\u8001\u1680\u8001\u16aa\u8001\u16b8\u8001\u16b8\u8001"+ + "\u1700\u8001\u171a\u8001\u1740\u8001\u1746\u8001\u1800\u8001\u182b\u8001"+ + "\u18a0\u8001\u18df\u8001\u18ff\u8001\u1906\u8001\u1909\u8001\u1909\u8001"+ + "\u190c\u8001\u1913\u8001\u1915\u8001\u1916\u8001\u1918\u8001\u192f\u8001"+ + "\u193f\u8001\u193f\u8001\u1941\u8001\u1941\u8001\u19a0\u8001\u19a7\u8001"+ + "\u19aa\u8001\u19d0\u8001\u19e1\u8001\u19e1\u8001\u19e3\u8001\u19e3\u8001"+ + "\u1a00\u8001\u1a00\u8001\u1a0b\u8001\u1a32\u8001\u1a3a\u8001\u1a3a\u8001"+ + "\u1a50\u8001\u1a50\u8001\u1a5c\u8001\u1a89\u8001\u1a9d\u8001\u1a9d\u8001"+ + "\u1ab0\u8001\u1af8\u8001\u1c00\u8001\u1c08\u8001\u1c0a\u8001\u1c2e\u8001"+ + "\u1c40\u8001\u1c40\u8001\u1c72\u8001\u1c8f\u8001\u1d00\u8001\u1d06\u8001"+ + "\u1d08\u8001\u1d09\u8001\u1d0b\u8001\u1d30\u8001\u1d46\u8001\u1d46\u8001"+ + "\u1d60\u8001\u1d65\u8001\u1d67\u8001\u1d68\u8001\u1d6a\u8001\u1d89\u8001"+ + "\u1d98\u8001\u1d98\u8001\u1ee0\u8001\u1ef2\u8001\u1f02\u8001\u1f02\u8001"+ + "\u1f04\u8001\u1f10\u8001\u1f12\u8001\u1f33\u8001\u1fb0\u8001\u1fb0\u8001"+ + "\u2000\u8001\u2399\u8001\u2400\u8001\u246e\u8001\u2480\u8001\u2543\u8001"+ + "\u2f90\u8001\u2ff0\u8001\u3000\u8001\u342f\u8001\u3441\u8001\u3446\u8001"+ + "\u4400\u8001\u4646\u8001\u6800\u8001\u6a38\u8001\u6a40\u8001\u6a5e\u8001"+ + "\u6a70\u8001\u6abe\u8001\u6ad0\u8001\u6aed\u8001\u6b00\u8001\u6b2f\u8001"+ + "\u6b40\u8001\u6b43\u8001\u6b63\u8001\u6b77\u8001\u6b7d\u8001\u6b8f\u8001"+ + "\u6e40\u8001\u6e7f\u8001\u6f00\u8001\u6f4a\u8001\u6f50\u8001\u6f50\u8001"+ + "\u6f93\u8001\u6f9f\u8001\u6fe0\u8001\u6fe1\u8001\u6fe3\u8001\u6fe3\u8001"+ + "\u7000\u8001\u87f7\u8001\u8800\u8001\u8cd5\u8001\u8d00\u8001\u8d08\u8001"+ + "\uaff0\u8001\uaff3\u8001\uaff5\u8001\uaffb\u8001\uaffd\u8001\uaffe\u8001"+ + "\ub000\u8001\ub122\u8001\ub132\u8001\ub132\u8001\ub150\u8001\ub152\u8001"+ + "\ub155\u8001\ub155\u8001\ub164\u8001\ub167\u8001\ub170\u8001\ub2fb\u8001"+ + "\ubc00\u8001\ubc6a\u8001\ubc70\u8001\ubc7c\u8001\ubc80\u8001\ubc88\u8001"+ + "\ubc90\u8001\ubc99\u8001\ud400\u8001\ud454\u8001\ud456\u8001\ud49c\u8001"+ + "\ud49e\u8001\ud49f\u8001\ud4a2\u8001\ud4a2\u8001\ud4a5\u8001\ud4a6\u8001"+ + "\ud4a9\u8001\ud4ac\u8001\ud4ae\u8001\ud4b9\u8001\ud4bb\u8001\ud4bb\u8001"+ + "\ud4bd\u8001\ud4c3\u8001\ud4c5\u8001\ud505\u8001\ud507\u8001\ud50a\u8001"+ + "\ud50d\u8001\ud514\u8001\ud516\u8001\ud51c\u8001\ud51e\u8001\ud539\u8001"+ + "\ud53b\u8001\ud53e\u8001\ud540\u8001\ud544\u8001\ud546\u8001\ud546\u8001"+ + "\ud54a\u8001\ud550\u8001\ud552\u8001\ud6a5\u8001\ud6a8\u8001\ud6c0\u8001"+ + "\ud6c2\u8001\ud6da\u8001\ud6dc\u8001\ud6fa\u8001\ud6fc\u8001\ud714\u8001"+ + "\ud716\u8001\ud734\u8001\ud736\u8001\ud74e\u8001\ud750\u8001\ud76e\u8001"+ + "\ud770\u8001\ud788\u8001\ud78a\u8001\ud7a8\u8001\ud7aa\u8001\ud7c2\u8001"+ + "\ud7c4\u8001\ud7cb\u8001\udf00\u8001\udf1e\u8001\udf25\u8001\udf2a\u8001"+ + "\ue030\u8001\ue06d\u8001\ue100\u8001\ue12c\u8001\ue137\u8001\ue13d\u8001"+ + "\ue14e\u8001\ue14e\u8001\ue290\u8001\ue2ad\u8001\ue2c0\u8001\ue2eb\u8001"+ + "\ue4d0\u8001\ue4eb\u8001\ue7e0\u8001\ue7e6\u8001\ue7e8\u8001\ue7eb\u8001"+ + "\ue7ed\u8001\ue7ee\u8001\ue7f0\u8001\ue7fe\u8001\ue800\u8001\ue8c4\u8001"+ + "\ue900\u8001\ue943\u8001\ue94b\u8001\ue94b\u8001\uee00\u8001\uee03\u8001"+ + "\uee05\u8001\uee1f\u8001\uee21\u8001\uee22\u8001\uee24\u8001\uee24\u8001"+ + "\uee27\u8001\uee27\u8001\uee29\u8001\uee32\u8001\uee34\u8001\uee37\u8001"+ + "\uee39\u8001\uee39\u8001\uee3b\u8001\uee3b\u8001\uee42\u8001\uee42\u8001"+ + "\uee47\u8001\uee47\u8001\uee49\u8001\uee49\u8001\uee4b\u8001\uee4b\u8001"+ + "\uee4d\u8001\uee4f\u8001\uee51\u8001\uee52\u8001\uee54\u8001\uee54\u8001"+ + "\uee57\u8001\uee57\u8001\uee59\u8001\uee59\u8001\uee5b\u8001\uee5b\u8001"+ + "\uee5d\u8001\uee5d\u8001\uee5f\u8001\uee5f\u8001\uee61\u8001\uee62\u8001"+ + "\uee64\u8001\uee64\u8001\uee67\u8001\uee6a\u8001\uee6c\u8001\uee72\u8001"+ + "\uee74\u8001\uee77\u8001\uee79\u8001\uee7c\u8001\uee7e\u8001\uee7e\u8001"+ + "\uee80\u8001\uee89\u8001\uee8b\u8001\uee9b\u8001\ueea1\u8001\ueea3\u8001"+ + "\ueea5\u8001\ueea9\u8001\ueeab\u8001\ueebb\u8002\u0000\u8002\ua6df\u8002"+ + "\ua700\u8002\ub739\u8002\ub740\u8002\ub81d\u8002\ub820\u8002\ucea1\u8002"+ + "\uceb0\u8002\uebe0\u8002\uf800\u8002\ufa1d\u8003\u0000\u8003\u134a\u8003"+ + "\u1350\u8003\u23af\u0174\u000009__\u0300\u036f\u0483\u0487\u0591\u05bd"+ + "\u05bf\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u05c7\u0610\u061a\u064b\u0669"+ + "\u0670\u0670\u06d6\u06dc\u06df\u06e4\u06e7\u06e8\u06ea\u06ed\u06f0\u06f9"+ + "\u0711\u0711\u0730\u074a\u07a6\u07b0\u07c0\u07c9\u07eb\u07f3\u07fd\u07fd"+ + "\u0816\u0819\u081b\u0823\u0825\u0827\u0829\u082d\u0859\u085b\u0898\u089f"+ + "\u08ca\u08e1\u08e3\u0903\u093a\u093c\u093e\u094f\u0951\u0957\u0962\u0963"+ + "\u0966\u096f\u0981\u0983\u09bc\u09bc\u09be\u09c4\u09c7\u09c8\u09cb\u09cd"+ + "\u09d7\u09d7\u09e2\u09e3\u09e6\u09ef\u09fe\u09fe\u0a01\u0a03\u0a3c\u0a3c"+ + "\u0a3e\u0a42\u0a47\u0a48\u0a4b\u0a4d\u0a51\u0a51\u0a66\u0a71\u0a75\u0a75"+ + "\u0a81\u0a83\u0abc\u0abc\u0abe\u0ac5\u0ac7\u0ac9\u0acb\u0acd\u0ae2\u0ae3"+ + "\u0ae6\u0aef\u0afa\u0aff\u0b01\u0b03\u0b3c\u0b3c\u0b3e\u0b44\u0b47\u0b48"+ + "\u0b4b\u0b4d\u0b55\u0b57\u0b62\u0b63\u0b66\u0b6f\u0b82\u0b82\u0bbe\u0bc2"+ + "\u0bc6\u0bc8\u0bca\u0bcd\u0bd7\u0bd7\u0be6\u0bef\u0c00\u0c04\u0c3c\u0c3c"+ + "\u0c3e\u0c44\u0c46\u0c48\u0c4a\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66\u0c6f"+ + "\u0c81\u0c83\u0cbc\u0cbc\u0cbe\u0cc4\u0cc6\u0cc8\u0cca\u0ccd\u0cd5\u0cd6"+ + "\u0ce2\u0ce3\u0ce6\u0cef\u0cf3\u0cf3\u0d00\u0d03\u0d3b\u0d3c\u0d3e\u0d44"+ + "\u0d46\u0d48\u0d4a\u0d4d\u0d57\u0d57\u0d62\u0d63\u0d66\u0d6f\u0d81\u0d83"+ + "\u0dca\u0dca\u0dcf\u0dd4\u0dd6\u0dd6\u0dd8\u0ddf\u0de6\u0def\u0df2\u0df3"+ + "\u0e31\u0e31\u0e34\u0e3a\u0e47\u0e4e\u0e50\u0e59\u0eb1\u0eb1\u0eb4\u0ebc"+ + "\u0ec8\u0ece\u0ed0\u0ed9\u0f18\u0f19\u0f20\u0f29\u0f35\u0f35\u0f37\u0f37"+ + "\u0f39\u0f39\u0f3e\u0f3f\u0f71\u0f84\u0f86\u0f87\u0f8d\u0f97\u0f99\u0fbc"+ + "\u0fc6\u0fc6\u102b\u103e\u1040\u1049\u1056\u1059\u105e\u1060\u1062\u1064"+ + "\u1067\u106d\u1071\u1074\u1082\u108d\u108f\u109d\u135d\u135f\u1712\u1715"+ + "\u1732\u1734\u1752\u1753\u1772\u1773\u17b4\u17d3\u17dd\u17dd\u17e0\u17e9"+ + "\u180b\u180d\u180f\u1819\u1885\u1886\u18a9\u18a9\u1920\u192b\u1930\u193b"+ + "\u1946\u194f\u19d0\u19d9\u1a17\u1a1b\u1a55\u1a5e\u1a60\u1a7c\u1a7f\u1a89"+ + "\u1a90\u1a99\u1ab0\u1abd\u1abf\u1ace\u1b00\u1b04\u1b34\u1b44\u1b50\u1b59"+ + "\u1b6b\u1b73\u1b80\u1b82\u1ba1\u1bad\u1bb0\u1bb9\u1be6\u1bf3\u1c24\u1c37"+ + "\u1c40\u1c49\u1c50\u1c59\u1cd0\u1cd2\u1cd4\u1ce8\u1ced\u1ced\u1cf4\u1cf4"+ + "\u1cf7\u1cf9\u1dc0\u1dff\u203f\u2040\u2054\u2054\u20d0\u20dc\u20e1\u20e1"+ + "\u20e5\u20f0\u2cef\u2cf1\u2d7f\u2d7f\u2de0\u2dff\u302a\u302f\u3099\u309a"+ + "\u8000\ua620\u8000\ua629\u8000\ua66f\u8000\ua66f\u8000\ua674\u8000\ua67d"+ + "\u8000\ua69e\u8000\ua69f\u8000\ua6f0\u8000\ua6f1\u8000\ua802\u8000\ua802"+ + "\u8000\ua806\u8000\ua806\u8000\ua80b\u8000\ua80b\u8000\ua823\u8000\ua827"+ + "\u8000\ua82c\u8000\ua82c\u8000\ua880\u8000\ua881\u8000\ua8b4\u8000\ua8c5"+ + "\u8000\ua8d0\u8000\ua8d9\u8000\ua8e0\u8000\ua8f1\u8000\ua8ff\u8000\ua909"+ + "\u8000\ua926\u8000\ua92d\u8000\ua947\u8000\ua953\u8000\ua980\u8000\ua983"+ + "\u8000\ua9b3\u8000\ua9c0\u8000\ua9d0\u8000\ua9d9\u8000\ua9e5\u8000\ua9e5"+ + "\u8000\ua9f0\u8000\ua9f9\u8000\uaa29\u8000\uaa36\u8000\uaa43\u8000\uaa43"+ + "\u8000\uaa4c\u8000\uaa4d\u8000\uaa50\u8000\uaa59\u8000\uaa7b\u8000\uaa7d"+ + "\u8000\uaab0\u8000\uaab0\u8000\uaab2\u8000\uaab4\u8000\uaab7\u8000\uaab8"+ + "\u8000\uaabe\u8000\uaabf\u8000\uaac1\u8000\uaac1\u8000\uaaeb\u8000\uaaef"+ + "\u8000\uaaf5\u8000\uaaf6\u8000\uabe3\u8000\uabea\u8000\uabec\u8000\uabed"+ + "\u8000\uabf0\u8000\uabf9\u8000\ufb1e\u8000\ufb1e\u8000\ufe00\u8000\ufe0f"+ + "\u8000\ufe20\u8000\ufe2f\u8000\ufe33\u8000\ufe34\u8000\ufe4d\u8000\ufe4f"+ + "\u8000\uff10\u8000\uff19\u8000\uff3f\u8000\uff3f\u8001\u01fd\u8001\u01fd"+ + "\u8001\u02e0\u8001\u02e0\u8001\u0376\u8001\u037a\u8001\u04a0\u8001\u04a9"+ + "\u8001\u0a01\u8001\u0a03\u8001\u0a05\u8001\u0a06\u8001\u0a0c\u8001\u0a0f"+ + "\u8001\u0a38\u8001\u0a3a\u8001\u0a3f\u8001\u0a3f\u8001\u0ae5\u8001\u0ae6"+ + "\u8001\u0d24\u8001\u0d27\u8001\u0d30\u8001\u0d39\u8001\u0eab\u8001\u0eac"+ + "\u8001\u0efd\u8001\u0eff\u8001\u0f46\u8001\u0f50\u8001\u0f82\u8001\u0f85"+ + "\u8001\u1000\u8001\u1002\u8001\u1038\u8001\u1046\u8001\u1066\u8001\u1070"+ + "\u8001\u1073\u8001\u1074\u8001\u107f\u8001\u1082\u8001\u10b0\u8001\u10ba"+ + "\u8001\u10c2\u8001\u10c2\u8001\u10f0\u8001\u10f9\u8001\u1100\u8001\u1102"+ + "\u8001\u1127\u8001\u1134\u8001\u1136\u8001\u113f\u8001\u1145\u8001\u1146"+ + "\u8001\u1173\u8001\u1173\u8001\u1180\u8001\u1182\u8001\u11b3\u8001\u11c0"+ + "\u8001\u11c9\u8001\u11cc\u8001\u11ce\u8001\u11d9\u8001\u122c\u8001\u1237"+ + "\u8001\u123e\u8001\u123e\u8001\u1241\u8001\u1241\u8001\u12df\u8001\u12ea"+ + "\u8001\u12f0\u8001\u12f9\u8001\u1300\u8001\u1303\u8001\u133b\u8001\u133c"+ + "\u8001\u133e\u8001\u1344\u8001\u1347\u8001\u1348\u8001\u134b\u8001\u134d"+ + "\u8001\u1357\u8001\u1357\u8001\u1362\u8001\u1363\u8001\u1366\u8001\u136c"+ + "\u8001\u1370\u8001\u1374\u8001\u1435\u8001\u1446\u8001\u1450\u8001\u1459"+ + "\u8001\u145e\u8001\u145e\u8001\u14b0\u8001\u14c3\u8001\u14d0\u8001\u14d9"+ + "\u8001\u15af\u8001\u15b5\u8001\u15b8\u8001\u15c0\u8001\u15dc\u8001\u15dd"+ + "\u8001\u1630\u8001\u1640\u8001\u1650\u8001\u1659\u8001\u16ab\u8001\u16b7"+ + "\u8001\u16c0\u8001\u16c9\u8001\u171d\u8001\u172b\u8001\u1730\u8001\u1739"+ + "\u8001\u182c\u8001\u183a\u8001\u18e0\u8001\u18e9\u8001\u1930\u8001\u1935"+ + "\u8001\u1937\u8001\u1938\u8001\u193b\u8001\u193e\u8001\u1940\u8001\u1940"+ + "\u8001\u1942\u8001\u1943\u8001\u1950\u8001\u1959\u8001\u19d1\u8001\u19d7"+ + "\u8001\u19da\u8001\u19e0\u8001\u19e4\u8001\u19e4\u8001\u1a01\u8001\u1a0a"+ + "\u8001\u1a33\u8001\u1a39\u8001\u1a3b\u8001\u1a3e\u8001\u1a47\u8001\u1a47"+ + "\u8001\u1a51\u8001\u1a5b\u8001\u1a8a\u8001\u1a99\u8001\u1c2f\u8001\u1c36"+ + "\u8001\u1c38\u8001\u1c3f\u8001\u1c50\u8001\u1c59\u8001\u1c92\u8001\u1ca7"+ + "\u8001\u1ca9\u8001\u1cb6\u8001\u1d31\u8001\u1d36\u8001\u1d3a\u8001\u1d3a"+ + "\u8001\u1d3c\u8001\u1d3d\u8001\u1d3f\u8001\u1d45\u8001\u1d47\u8001\u1d47"+ + "\u8001\u1d50\u8001\u1d59\u8001\u1d8a\u8001\u1d8e\u8001\u1d90\u8001\u1d91"+ + "\u8001\u1d93\u8001\u1d97\u8001\u1da0\u8001\u1da9\u8001\u1ef3\u8001\u1ef6"+ + "\u8001\u1f00\u8001\u1f01\u8001\u1f03\u8001\u1f03\u8001\u1f34\u8001\u1f3a"+ + "\u8001\u1f3e\u8001\u1f42\u8001\u1f50\u8001\u1f59\u8001\u3440\u8001\u3440"+ + "\u8001\u3447\u8001\u3455\u8001\u6a60\u8001\u6a69\u8001\u6ac0\u8001\u6ac9"+ + "\u8001\u6af0\u8001\u6af4\u8001\u6b30\u8001\u6b36\u8001\u6b50\u8001\u6b59"+ + "\u8001\u6f4f\u8001\u6f4f\u8001\u6f51\u8001\u6f87\u8001\u6f8f\u8001\u6f92"+ + "\u8001\u6fe4\u8001\u6fe4\u8001\u6ff0\u8001\u6ff1\u8001\ubc9d\u8001\ubc9e"+ + "\u8001\ucf00\u8001\ucf2d\u8001\ucf30\u8001\ucf46\u8001\ud165\u8001\ud169"+ + "\u8001\ud16d\u8001\ud172\u8001\ud17b\u8001\ud182\u8001\ud185\u8001\ud18b"+ + "\u8001\ud1aa\u8001\ud1ad\u8001\ud242\u8001\ud244\u8001\ud7ce\u8001\ud7ff"+ + "\u8001\uda00\u8001\uda36\u8001\uda3b\u8001\uda6c\u8001\uda75\u8001\uda75"+ + "\u8001\uda84\u8001\uda84\u8001\uda9b\u8001\uda9f\u8001\udaa1\u8001\udaaf"+ + "\u8001\ue000\u8001\ue006\u8001\ue008\u8001\ue018\u8001\ue01b\u8001\ue021"+ + "\u8001\ue023\u8001\ue024\u8001\ue026\u8001\ue02a\u8001\ue08f\u8001\ue08f"+ + "\u8001\ue130\u8001\ue136\u8001\ue140\u8001\ue149\u8001\ue2ae\u8001\ue2ae"+ + "\u8001\ue2ec\u8001\ue2f9\u8001\ue4ec\u8001\ue4f9\u8001\ue8d0\u8001\ue8d6"+ + "\u8001\ue944\u8001\ue94a\u8001\ue950\u8001\ue959\u8001\ufbf0\u8001\ufbf9"+ + "\u800e\u0100\u800e\u01ef\u0004\u0000\u1885\u1886\u2118\u2118\u212e\u212e"+ + "\u309b\u309c\u0004\u0000\u00b7\u00b7\u0387\u0387\u1369\u1371\u19da\u19da"+ + "\u0002\u0000!!//\u0002\u0000\n\n\r\r\u0002\u0000!!**\u0001\u0000**\u0001"+ + "\u0000//\u0007\u0000 \u00a0\u00a0\u1680\u1680\u2000\u200a\u202f\u202f"+ + "\u205f\u205f\u3000\u3000\u0004\u0000\t\n\r\r\'\'\\\\\u0001\u0000\"\"\u0005"+ + "\u000000\\\\nnrrtt\u0002\u0000\"\"\'\'\u0001\u000001\u0002\u000001__\u0002"+ + "\u0000EEee\u0002\u0000++--\u0001\u000007\u0001\u000009\u0003\u000009A"+ + "Faf\u04e4\u0000\u0001\u0001\u0000\u0000\u0000\u0000\u0003\u0001\u0000"+ + "\u0000\u0000\u0000\u0005\u0001\u0000\u0000\u0000\u0000\u0007\u0001\u0000"+ + "\u0000\u0000\u0000\t\u0001\u0000\u0000\u0000\u0000\u000b\u0001\u0000\u0000"+ + "\u0000\u0000\r\u0001\u0000\u0000\u0000\u0000\u000f\u0001\u0000\u0000\u0000"+ + "\u0000\u0011\u0001\u0000\u0000\u0000\u0000\u0013\u0001\u0000\u0000\u0000"+ + "\u0000\u0015\u0001\u0000\u0000\u0000\u0000\u0017\u0001\u0000\u0000\u0000"+ + "\u0000\u0019\u0001\u0000\u0000\u0000\u0000\u001b\u0001\u0000\u0000\u0000"+ + "\u0000\u001d\u0001\u0000\u0000\u0000\u0000\u001f\u0001\u0000\u0000\u0000"+ + "\u0000!\u0001\u0000\u0000\u0000\u0000#\u0001\u0000\u0000\u0000\u0000%"+ + "\u0001\u0000\u0000\u0000\u0000\'\u0001\u0000\u0000\u0000\u0000)\u0001"+ + "\u0000\u0000\u0000\u0000+\u0001\u0000\u0000\u0000\u0000-\u0001\u0000\u0000"+ + "\u0000\u0000/\u0001\u0000\u0000\u0000\u00001\u0001\u0000\u0000\u0000\u0000"+ + "3\u0001\u0000\u0000\u0000\u00005\u0001\u0000\u0000\u0000\u00007\u0001"+ + "\u0000\u0000\u0000\u00009\u0001\u0000\u0000\u0000\u0000;\u0001\u0000\u0000"+ + "\u0000\u0000=\u0001\u0000\u0000\u0000\u0000?\u0001\u0000\u0000\u0000\u0000"+ + "A\u0001\u0000\u0000\u0000\u0000C\u0001\u0000\u0000\u0000\u0000E\u0001"+ + "\u0000\u0000\u0000\u0000G\u0001\u0000\u0000\u0000\u0000I\u0001\u0000\u0000"+ + "\u0000\u0000K\u0001\u0000\u0000\u0000\u0000M\u0001\u0000\u0000\u0000\u0000"+ + "O\u0001\u0000\u0000\u0000\u0000Q\u0001\u0000\u0000\u0000\u0000S\u0001"+ + "\u0000\u0000\u0000\u0000U\u0001\u0000\u0000\u0000\u0000W\u0001\u0000\u0000"+ + "\u0000\u0000Y\u0001\u0000\u0000\u0000\u0000[\u0001\u0000\u0000\u0000\u0000"+ + "]\u0001\u0000\u0000\u0000\u0000_\u0001\u0000\u0000\u0000\u0000a\u0001"+ + "\u0000\u0000\u0000\u0000c\u0001\u0000\u0000\u0000\u0000e\u0001\u0000\u0000"+ + "\u0000\u0000g\u0001\u0000\u0000\u0000\u0000i\u0001\u0000\u0000\u0000\u0000"+ + "k\u0001\u0000\u0000\u0000\u0000m\u0001\u0000\u0000\u0000\u0000o\u0001"+ + "\u0000\u0000\u0000\u0000q\u0001\u0000\u0000\u0000\u0000{\u0001\u0000\u0000"+ + "\u0000\u0000}\u0001\u0000\u0000\u0000\u0000\u007f\u0001\u0000\u0000\u0000"+ + "\u0000\u0081\u0001\u0000\u0000\u0000\u0000\u0083\u0001\u0000\u0000\u0000"+ + "\u0000\u0085\u0001\u0000\u0000\u0000\u0000\u0087\u0001\u0000\u0000\u0000"+ + "\u0000\u0089\u0001\u0000\u0000\u0000\u0000\u008b\u0001\u0000\u0000\u0000"+ + "\u0000\u008d\u0001\u0000\u0000\u0000\u0000\u008f\u0001\u0000\u0000\u0000"+ + "\u0000\u0091\u0001\u0000\u0000\u0000\u0000\u0093\u0001\u0000\u0000\u0000"+ + "\u0000\u0095\u0001\u0000\u0000\u0000\u0000\u0099\u0001\u0000\u0000\u0000"+ + "\u0000\u009b\u0001\u0000\u0000\u0000\u0000\u009d\u0001\u0000\u0000\u0000"+ + "\u0000\u00ab\u0001\u0000\u0000\u0000\u0000\u00ad\u0001\u0000\u0000\u0000"+ + "\u0000\u00af\u0001\u0000\u0000\u0000\u0000\u00b1\u0001\u0000\u0000\u0000"+ + "\u0000\u00b3\u0001\u0000\u0000\u0000\u0000\u00b5\u0001\u0000\u0000\u0000"+ + "\u0000\u00c3\u0001\u0000\u0000\u0000\u0000\u00c5\u0001\u0000\u0000\u0000"+ + "\u0000\u00c7\u0001\u0000\u0000\u0000\u0000\u00c9\u0001\u0000\u0000\u0000"+ + "\u0000\u00cb\u0001\u0000\u0000\u0000\u0000\u00cd\u0001\u0000\u0000\u0000"+ + "\u0000\u00cf\u0001\u0000\u0000\u0000\u0000\u00d1\u0001\u0000\u0000\u0000"+ + "\u0000\u00d3\u0001\u0000\u0000\u0000\u0000\u00d5\u0001\u0000\u0000\u0000"+ + "\u0000\u00d7\u0001\u0000\u0000\u0000\u0000\u00d9\u0001\u0000\u0000\u0000"+ + "\u0000\u00db\u0001\u0000\u0000\u0000\u0000\u00dd\u0001\u0000\u0000\u0000"+ + "\u0000\u00df\u0001\u0000\u0000\u0000\u0000\u00e1\u0001\u0000\u0000\u0000"+ + "\u0000\u00e3\u0001\u0000\u0000\u0000\u0000\u00e5\u0001\u0000\u0000\u0000"+ + "\u0000\u00e7\u0001\u0000\u0000\u0000\u0000\u00e9\u0001\u0000\u0000\u0000"+ + "\u0000\u00eb\u0001\u0000\u0000\u0000\u0000\u00ed\u0001\u0000\u0000\u0000"+ + "\u0000\u00ef\u0001\u0000\u0000\u0000\u0000\u00f1\u0001\u0000\u0000\u0000"+ + "\u0000\u00f3\u0001\u0000\u0000\u0000\u0000\u00f5\u0001\u0000\u0000\u0000"+ + "\u0000\u00f7\u0001\u0000\u0000\u0000\u0000\u00f9\u0001\u0000\u0000\u0000"+ + "\u0000\u00fb\u0001\u0000\u0000\u0000\u0000\u00fd\u0001\u0000\u0000\u0000"+ + "\u0000\u00ff\u0001\u0000\u0000\u0000\u0000\u0101\u0001\u0000\u0000\u0000"+ + "\u0000\u0103\u0001\u0000\u0000\u0000\u0000\u0105\u0001\u0000\u0000\u0000"+ + "\u0000\u0107\u0001\u0000\u0000\u0000\u0000\u0109\u0001\u0000\u0000\u0000"+ + "\u0000\u010b\u0001\u0000\u0000\u0000\u0000\u010d\u0001\u0000\u0000\u0000"+ + "\u0000\u010f\u0001\u0000\u0000\u0000\u0000\u0111\u0001\u0000\u0000\u0000"+ + "\u0000\u0113\u0001\u0000\u0000\u0000\u0000\u0115\u0001\u0000\u0000\u0000"+ + "\u0000\u0117\u0001\u0000\u0000\u0000\u0000\u0119\u0001\u0000\u0000\u0000"+ + "\u0000\u011b\u0001\u0000\u0000\u0000\u0000\u011d\u0001\u0000\u0000\u0000"+ + "\u0000\u011f\u0001\u0000\u0000\u0000\u0000\u0121\u0001\u0000\u0000\u0000"+ + "\u0000\u0123\u0001\u0000\u0000\u0000\u0000\u0125\u0001\u0000\u0000\u0000"+ + "\u0001\u0127\u0001\u0000\u0000\u0000\u0003\u012a\u0001\u0000\u0000\u0000"+ + "\u0005\u0130\u0001\u0000\u0000\u0000\u0007\u0136\u0001\u0000\u0000\u0000"+ + "\t\u013f\u0001\u0000\u0000\u0000\u000b\u0145\u0001\u0000\u0000\u0000\r"+ + "\u014a\u0001\u0000\u0000\u0000\u000f\u014f\u0001\u0000\u0000\u0000\u0011"+ + "\u0156\u0001\u0000\u0000\u0000\u0013\u015c\u0001\u0000\u0000\u0000\u0015"+ + "\u015f\u0001\u0000\u0000\u0000\u0017\u0163\u0001\u0000\u0000\u0000\u0019"+ + "\u0166\u0001\u0000\u0000\u0000\u001b\u016b\u0001\u0000\u0000\u0000\u001d"+ + "\u016e\u0001\u0000\u0000\u0000\u001f\u0172\u0001\u0000\u0000\u0000!\u0177"+ + "\u0001\u0000\u0000\u0000#\u017d\u0001\u0000\u0000\u0000%\u0181\u0001\u0000"+ + "\u0000\u0000\'\u0186\u0001\u0000\u0000\u0000)\u018a\u0001\u0000\u0000"+ + "\u0000+\u018e\u0001\u0000\u0000\u0000-\u0192\u0001\u0000\u0000\u0000/"+ + "\u0199\u0001\u0000\u0000\u00001\u019e\u0001\u0000\u0000\u00003\u01a3\u0001"+ + "\u0000\u0000\u00005\u01aa\u0001\u0000\u0000\u00007\u01b1\u0001\u0000\u0000"+ + "\u00009\u01b7\u0001\u0000\u0000\u0000;\u01bd\u0001\u0000\u0000\u0000="+ + "\u01c2\u0001\u0000\u0000\u0000?\u01c7\u0001\u0000\u0000\u0000A\u01ce\u0001"+ + "\u0000\u0000\u0000C\u01d2\u0001\u0000\u0000\u0000E\u01d8\u0001\u0000\u0000"+ + "\u0000G\u01de\u0001\u0000\u0000\u0000I\u01e4\u0001\u0000\u0000\u0000K"+ + "\u01ea\u0001\u0000\u0000\u0000M\u01ee\u0001\u0000\u0000\u0000O\u01f7\u0001"+ + "\u0000\u0000\u0000Q\u01fe\u0001\u0000\u0000\u0000S\u0202\u0001\u0000\u0000"+ + "\u0000U\u0205\u0001\u0000\u0000\u0000W\u020b\u0001\u0000\u0000\u0000Y"+ + "\u0211\u0001\u0000\u0000\u0000[\u021a\u0001\u0000\u0000\u0000]\u021f\u0001"+ + "\u0000\u0000\u0000_\u0226\u0001\u0000\u0000\u0000a\u022e\u0001\u0000\u0000"+ + "\u0000c\u0236\u0001\u0000\u0000\u0000e\u023c\u0001\u0000\u0000\u0000g"+ + "\u0240\u0001\u0000\u0000\u0000i\u0246\u0001\u0000\u0000\u0000k\u024e\u0001"+ + "\u0000\u0000\u0000m\u025a\u0001\u0000\u0000\u0000o\u025d\u0001\u0000\u0000"+ + "\u0000q\u0271\u0001\u0000\u0000\u0000s\u0275\u0001\u0000\u0000\u0000u"+ + "\u027a\u0001\u0000\u0000\u0000w\u027c\u0001\u0000\u0000\u0000y\u027e\u0001"+ + "\u0000\u0000\u0000{\u0280\u0001\u0000\u0000\u0000}\u0295\u0001\u0000\u0000"+ + "\u0000\u007f\u02b4\u0001\u0000\u0000\u0000\u0081\u02b8\u0001\u0000\u0000"+ + "\u0000\u0083\u02c4\u0001\u0000\u0000\u0000\u0085\u02d4\u0001\u0000\u0000"+ + "\u0000\u0087\u02e3\u0001\u0000\u0000\u0000\u0089\u02fa\u0001\u0000\u0000"+ + "\u0000\u008b\u02fe\u0001\u0000\u0000\u0000\u008d\u030d\u0001\u0000\u0000"+ + "\u0000\u008f\u0314\u0001\u0000\u0000\u0000\u0091\u0318\u0001\u0000\u0000"+ + "\u0000\u0093\u0321\u0001\u0000\u0000\u0000\u0095\u032e\u0001\u0000\u0000"+ + "\u0000\u0097\u033d\u0001\u0000\u0000\u0000\u0099\u033f\u0001\u0000\u0000"+ + "\u0000\u009b\u0349\u0001\u0000\u0000\u0000\u009d\u0356\u0001\u0000\u0000"+ + "\u0000\u009f\u0362\u0001\u0000\u0000\u0000\u00a1\u036b\u0001\u0000\u0000"+ + "\u0000\u00a3\u036d\u0001\u0000\u0000\u0000\u00a5\u0370\u0001\u0000\u0000"+ + "\u0000\u00a7\u0386\u0001\u0000\u0000\u0000\u00a9\u0389\u0001\u0000\u0000"+ + "\u0000\u00ab\u0390\u0001\u0000\u0000\u0000\u00ad\u0395\u0001\u0000\u0000"+ + "\u0000\u00af\u039d\u0001\u0000\u0000\u0000\u00b1\u03ae\u0001\u0000\u0000"+ + "\u0000\u00b3\u03bf\u0001\u0000\u0000\u0000\u00b5\u03cf\u0001\u0000\u0000"+ + "\u0000\u00b7\u0409\u0001\u0000\u0000\u0000\u00b9\u0411\u0001\u0000\u0000"+ + "\u0000\u00bb\u0413\u0001\u0000\u0000\u0000\u00bd\u041f\u0001\u0000\u0000"+ + "\u0000\u00bf\u0421\u0001\u0000\u0000\u0000\u00c1\u0423\u0001\u0000\u0000"+ + "\u0000\u00c3\u0425\u0001\u0000\u0000\u0000\u00c5\u0428\u0001\u0000\u0000"+ + "\u0000\u00c7\u042a\u0001\u0000\u0000\u0000\u00c9\u042c\u0001\u0000\u0000"+ + "\u0000\u00cb\u042e\u0001\u0000\u0000\u0000\u00cd\u0430\u0001\u0000\u0000"+ + "\u0000\u00cf\u0432\u0001\u0000\u0000\u0000\u00d1\u0434\u0001\u0000\u0000"+ + "\u0000\u00d3\u0436\u0001\u0000\u0000\u0000\u00d5\u0438\u0001\u0000\u0000"+ + "\u0000\u00d7\u043a\u0001\u0000\u0000\u0000\u00d9\u043d\u0001\u0000\u0000"+ + "\u0000\u00db\u0440\u0001\u0000\u0000\u0000\u00dd\u0443\u0001\u0000\u0000"+ + "\u0000\u00df\u0446\u0001\u0000\u0000\u0000\u00e1\u0449\u0001\u0000\u0000"+ + "\u0000\u00e3\u044c\u0001\u0000\u0000\u0000\u00e5\u044f\u0001\u0000\u0000"+ + "\u0000\u00e7\u0452\u0001\u0000\u0000\u0000\u00e9\u0455\u0001\u0000\u0000"+ + "\u0000\u00eb\u0458\u0001\u0000\u0000\u0000\u00ed\u045c\u0001\u0000\u0000"+ + "\u0000\u00ef\u0460\u0001\u0000\u0000\u0000\u00f1\u0462\u0001\u0000\u0000"+ + "\u0000\u00f3\u0465\u0001\u0000\u0000\u0000\u00f5\u0468\u0001\u0000\u0000"+ + "\u0000\u00f7\u046a\u0001\u0000\u0000\u0000\u00f9\u046c\u0001\u0000\u0000"+ + "\u0000\u00fb\u046f\u0001\u0000\u0000\u0000\u00fd\u0472\u0001\u0000\u0000"+ + "\u0000\u00ff\u0474\u0001\u0000\u0000\u0000\u0101\u0476\u0001\u0000\u0000"+ + "\u0000\u0103\u0478\u0001\u0000\u0000\u0000\u0105\u047b\u0001\u0000\u0000"+ + "\u0000\u0107\u047f\u0001\u0000\u0000\u0000\u0109\u0483\u0001\u0000\u0000"+ + "\u0000\u010b\u0485\u0001\u0000\u0000\u0000\u010d\u0487\u0001\u0000\u0000"+ + "\u0000\u010f\u0489\u0001\u0000\u0000\u0000\u0111\u048c\u0001\u0000\u0000"+ + "\u0000\u0113\u048f\u0001\u0000\u0000\u0000\u0115\u0492\u0001\u0000\u0000"+ + "\u0000\u0117\u0494\u0001\u0000\u0000\u0000\u0119\u0496\u0001\u0000\u0000"+ + "\u0000\u011b\u0498\u0001\u0000\u0000\u0000\u011d\u049a\u0001\u0000\u0000"+ + "\u0000\u011f\u049c\u0001\u0000\u0000\u0000\u0121\u049e\u0001\u0000\u0000"+ + "\u0000\u0123\u04a0\u0001\u0000\u0000\u0000\u0125\u04a2\u0001\u0000\u0000"+ + "\u0000\u0127\u0128\u0005a\u0000\u0000\u0128\u0129\u0005s\u0000\u0000\u0129"+ + "\u0002\u0001\u0000\u0000\u0000\u012a\u012b\u0005b\u0000\u0000\u012b\u012c"+ + "\u0005r\u0000\u0000\u012c\u012d\u0005e\u0000\u0000\u012d\u012e\u0005a"+ + "\u0000\u0000\u012e\u012f\u0005k\u0000\u0000\u012f\u0004\u0001\u0000\u0000"+ + "\u0000\u0130\u0131\u0005c\u0000\u0000\u0131\u0132\u0005o\u0000\u0000\u0132"+ + "\u0133\u0005n\u0000\u0000\u0133\u0134\u0005s\u0000\u0000\u0134\u0135\u0005"+ + "t\u0000\u0000\u0135\u0006\u0001\u0000\u0000\u0000\u0136\u0137\u0005c\u0000"+ + "\u0000\u0137\u0138\u0005o\u0000\u0000\u0138\u0139\u0005n\u0000\u0000\u0139"+ + "\u013a\u0005t\u0000\u0000\u013a\u013b\u0005i\u0000\u0000\u013b\u013c\u0005"+ + "n\u0000\u0000\u013c\u013d\u0005u\u0000\u0000\u013d\u013e\u0005e\u0000"+ + "\u0000\u013e\b\u0001\u0000\u0000\u0000\u013f\u0140\u0005c\u0000\u0000"+ + "\u0140\u0141\u0005r\u0000\u0000\u0141\u0142\u0005a\u0000\u0000\u0142\u0143"+ + "\u0005t\u0000\u0000\u0143\u0144\u0005e\u0000\u0000\u0144\n\u0001\u0000"+ + "\u0000\u0000\u0145\u0146\u0005e\u0000\u0000\u0146\u0147\u0005l\u0000\u0000"+ + "\u0147\u0148\u0005s\u0000\u0000\u0148\u0149\u0005e\u0000\u0000\u0149\f"+ + "\u0001\u0000\u0000\u0000\u014a\u014b\u0005e\u0000\u0000\u014b\u014c\u0005"+ + "n\u0000\u0000\u014c\u014d\u0005u\u0000\u0000\u014d\u014e\u0005m\u0000"+ + "\u0000\u014e\u000e\u0001\u0000\u0000\u0000\u014f\u0150\u0005e\u0000\u0000"+ + "\u0150\u0151\u0005x\u0000\u0000\u0151\u0152\u0005t\u0000\u0000\u0152\u0153"+ + "\u0005e\u0000\u0000\u0153\u0154\u0005r\u0000\u0000\u0154\u0155\u0005n"+ + "\u0000\u0000\u0155\u0010\u0001\u0000\u0000\u0000\u0156\u0157\u0005f\u0000"+ + "\u0000\u0157\u0158\u0005a\u0000\u0000\u0158\u0159\u0005l\u0000\u0000\u0159"+ + "\u015a\u0005s\u0000\u0000\u015a\u015b\u0005e\u0000\u0000\u015b\u0012\u0001"+ + "\u0000\u0000\u0000\u015c\u015d\u0005f\u0000\u0000\u015d\u015e\u0005n\u0000"+ + "\u0000\u015e\u0014\u0001\u0000\u0000\u0000\u015f\u0160\u0005f\u0000\u0000"+ + "\u0160\u0161\u0005o\u0000\u0000\u0161\u0162\u0005r\u0000\u0000\u0162\u0016"+ + "\u0001\u0000\u0000\u0000\u0163\u0164\u0005i\u0000\u0000\u0164\u0165\u0005"+ + "f\u0000\u0000\u0165\u0018\u0001\u0000\u0000\u0000\u0166\u0167\u0005i\u0000"+ + "\u0000\u0167\u0168\u0005m\u0000\u0000\u0168\u0169\u0005p\u0000\u0000\u0169"+ + "\u016a\u0005l\u0000\u0000\u016a\u001a\u0001\u0000\u0000\u0000\u016b\u016c"+ + "\u0005i\u0000\u0000\u016c\u016d\u0005n\u0000\u0000\u016d\u001c\u0001\u0000"+ + "\u0000\u0000\u016e\u016f\u0005l\u0000\u0000\u016f\u0170\u0005e\u0000\u0000"+ + "\u0170\u0171\u0005t\u0000\u0000\u0171\u001e\u0001\u0000\u0000\u0000\u0172"+ + "\u0173\u0005l\u0000\u0000\u0173\u0174\u0005o\u0000\u0000\u0174\u0175\u0005"+ + "o\u0000\u0000\u0175\u0176\u0005p\u0000\u0000\u0176 \u0001\u0000\u0000"+ + "\u0000\u0177\u0178\u0005m\u0000\u0000\u0178\u0179\u0005a\u0000\u0000\u0179"+ + "\u017a\u0005t\u0000\u0000\u017a\u017b\u0005c\u0000\u0000\u017b\u017c\u0005"+ + "h\u0000\u0000\u017c\"\u0001\u0000\u0000\u0000\u017d\u017e\u0005m\u0000"+ + "\u0000\u017e\u017f\u0005o\u0000\u0000\u017f\u0180\u0005d\u0000\u0000\u0180"+ + "$\u0001\u0000\u0000\u0000\u0181\u0182\u0005m\u0000\u0000\u0182\u0183\u0005"+ + "o\u0000\u0000\u0183\u0184\u0005v\u0000\u0000\u0184\u0185\u0005e\u0000"+ + "\u0000\u0185&\u0001\u0000\u0000\u0000\u0186\u0187\u0005m\u0000\u0000\u0187"+ + "\u0188\u0005u\u0000\u0000\u0188\u0189\u0005t\u0000\u0000\u0189(\u0001"+ + "\u0000\u0000\u0000\u018a\u018b\u0005p\u0000\u0000\u018b\u018c\u0005u\u0000"+ + "\u0000\u018c\u018d\u0005b\u0000\u0000\u018d*\u0001\u0000\u0000\u0000\u018e"+ + "\u018f\u0005r\u0000\u0000\u018f\u0190\u0005e\u0000\u0000\u0190\u0191\u0005"+ + "f\u0000\u0000\u0191,\u0001\u0000\u0000\u0000\u0192\u0193\u0005r\u0000"+ + "\u0000\u0193\u0194\u0005e\u0000\u0000\u0194\u0195\u0005t\u0000\u0000\u0195"+ + "\u0196\u0005u\u0000\u0000\u0196\u0197\u0005r\u0000\u0000\u0197\u0198\u0005"+ + "n\u0000\u0000\u0198.\u0001\u0000\u0000\u0000\u0199\u019a\u0005s\u0000"+ + "\u0000\u019a\u019b\u0005e\u0000\u0000\u019b\u019c\u0005l\u0000\u0000\u019c"+ + "\u019d\u0005f\u0000\u0000\u019d0\u0001\u0000\u0000\u0000\u019e\u019f\u0005"+ + "S\u0000\u0000\u019f\u01a0\u0005e\u0000\u0000\u01a0\u01a1\u0005l\u0000"+ + "\u0000\u01a1\u01a2\u0005f\u0000\u0000\u01a22\u0001\u0000\u0000\u0000\u01a3"+ + "\u01a4\u0005s\u0000\u0000\u01a4\u01a5\u0005t\u0000\u0000\u01a5\u01a6\u0005"+ + "a\u0000\u0000\u01a6\u01a7\u0005t\u0000\u0000\u01a7\u01a8\u0005i\u0000"+ + "\u0000\u01a8\u01a9\u0005c\u0000\u0000\u01a94\u0001\u0000\u0000\u0000\u01aa"+ + "\u01ab\u0005s\u0000\u0000\u01ab\u01ac\u0005t\u0000\u0000\u01ac\u01ad\u0005"+ + "r\u0000\u0000\u01ad\u01ae\u0005u\u0000\u0000\u01ae\u01af\u0005c\u0000"+ + "\u0000\u01af\u01b0\u0005t\u0000\u0000\u01b06\u0001\u0000\u0000\u0000\u01b1"+ + "\u01b2\u0005s\u0000\u0000\u01b2\u01b3\u0005u\u0000\u0000\u01b3\u01b4\u0005"+ + "p\u0000\u0000\u01b4\u01b5\u0005e\u0000\u0000\u01b5\u01b6\u0005r\u0000"+ + "\u0000\u01b68\u0001\u0000\u0000\u0000\u01b7\u01b8\u0005t\u0000\u0000\u01b8"+ + "\u01b9\u0005r\u0000\u0000\u01b9\u01ba\u0005a\u0000\u0000\u01ba\u01bb\u0005"+ + "i\u0000\u0000\u01bb\u01bc\u0005t\u0000\u0000\u01bc:\u0001\u0000\u0000"+ + "\u0000\u01bd\u01be\u0005t\u0000\u0000\u01be\u01bf\u0005r\u0000\u0000\u01bf"+ + "\u01c0\u0005u\u0000\u0000\u01c0\u01c1\u0005e\u0000\u0000\u01c1<\u0001"+ + "\u0000\u0000\u0000\u01c2\u01c3\u0005t\u0000\u0000\u01c3\u01c4\u0005y\u0000"+ + "\u0000\u01c4\u01c5\u0005p\u0000\u0000\u01c5\u01c6\u0005e\u0000\u0000\u01c6"+ + ">\u0001\u0000\u0000\u0000\u01c7\u01c8\u0005u\u0000\u0000\u01c8\u01c9\u0005"+ + "n\u0000\u0000\u01c9\u01ca\u0005s\u0000\u0000\u01ca\u01cb\u0005a\u0000"+ + "\u0000\u01cb\u01cc\u0005f\u0000\u0000\u01cc\u01cd\u0005e\u0000\u0000\u01cd"+ + "@\u0001\u0000\u0000\u0000\u01ce\u01cf\u0005u\u0000\u0000\u01cf\u01d0\u0005"+ + "s\u0000\u0000\u01d0\u01d1\u0005e\u0000\u0000\u01d1B\u0001\u0000\u0000"+ + "\u0000\u01d2\u01d3\u0005w\u0000\u0000\u01d3\u01d4\u0005h\u0000\u0000\u01d4"+ + "\u01d5\u0005e\u0000\u0000\u01d5\u01d6\u0005r\u0000\u0000\u01d6\u01d7\u0005"+ + "e\u0000\u0000\u01d7D\u0001\u0000\u0000\u0000\u01d8\u01d9\u0005w\u0000"+ + "\u0000\u01d9\u01da\u0005h\u0000\u0000\u01da\u01db\u0005i\u0000\u0000\u01db"+ + "\u01dc\u0005l\u0000\u0000\u01dc\u01dd\u0005e\u0000\u0000\u01ddF\u0001"+ + "\u0000\u0000\u0000\u01de\u01df\u0005a\u0000\u0000\u01df\u01e0\u0005s\u0000"+ + "\u0000\u01e0\u01e1\u0005y\u0000\u0000\u01e1\u01e2\u0005n\u0000\u0000\u01e2"+ + "\u01e3\u0005c\u0000\u0000\u01e3H\u0001\u0000\u0000\u0000\u01e4\u01e5\u0005"+ + "a\u0000\u0000\u01e5\u01e6\u0005w\u0000\u0000\u01e6\u01e7\u0005a\u0000"+ + "\u0000\u01e7\u01e8\u0005i\u0000\u0000\u01e8\u01e9\u0005t\u0000\u0000\u01e9"+ + "J\u0001\u0000\u0000\u0000\u01ea\u01eb\u0005d\u0000\u0000\u01eb\u01ec\u0005"+ + "y\u0000\u0000\u01ec\u01ed\u0005n\u0000\u0000\u01edL\u0001\u0000\u0000"+ + "\u0000\u01ee\u01ef\u0005a\u0000\u0000\u01ef\u01f0\u0005b\u0000\u0000\u01f0"+ + "\u01f1\u0005s\u0000\u0000\u01f1\u01f2\u0005t\u0000\u0000\u01f2\u01f3\u0005"+ + "r\u0000\u0000\u01f3\u01f4\u0005a\u0000\u0000\u01f4\u01f5\u0005c\u0000"+ + "\u0000\u01f5\u01f6\u0005t\u0000\u0000\u01f6N\u0001\u0000\u0000\u0000\u01f7"+ + "\u01f8\u0005b\u0000\u0000\u01f8\u01f9\u0005e\u0000\u0000\u01f9\u01fa\u0005"+ + "c\u0000\u0000\u01fa\u01fb\u0005o\u0000\u0000\u01fb\u01fc\u0005m\u0000"+ + "\u0000\u01fc\u01fd\u0005e\u0000\u0000\u01fdP\u0001\u0000\u0000\u0000\u01fe"+ + "\u01ff\u0005b\u0000\u0000\u01ff\u0200\u0005o\u0000\u0000\u0200\u0201\u0005"+ + "x\u0000\u0000\u0201R\u0001\u0000\u0000\u0000\u0202\u0203\u0005d\u0000"+ + "\u0000\u0203\u0204\u0005o\u0000\u0000\u0204T\u0001\u0000\u0000\u0000\u0205"+ + "\u0206\u0005f\u0000\u0000\u0206\u0207\u0005i\u0000\u0000\u0207\u0208\u0005"+ + "n\u0000\u0000\u0208\u0209\u0005a\u0000\u0000\u0209\u020a\u0005l\u0000"+ + "\u0000\u020aV\u0001\u0000\u0000\u0000\u020b\u020c\u0005m\u0000\u0000\u020c"+ + "\u020d\u0005a\u0000\u0000\u020d\u020e\u0005c\u0000\u0000\u020e\u020f\u0005"+ + "r\u0000\u0000\u020f\u0210\u0005o\u0000\u0000\u0210X\u0001\u0000\u0000"+ + "\u0000\u0211\u0212\u0005o\u0000\u0000\u0212\u0213\u0005v\u0000\u0000\u0213"+ + "\u0214\u0005e\u0000\u0000\u0214\u0215\u0005r\u0000\u0000\u0215\u0216\u0005"+ + "r\u0000\u0000\u0216\u0217\u0005i\u0000\u0000\u0217\u0218\u0005d\u0000"+ + "\u0000\u0218\u0219\u0005e\u0000\u0000\u0219Z\u0001\u0000\u0000\u0000\u021a"+ + "\u021b\u0005p\u0000\u0000\u021b\u021c\u0005r\u0000\u0000\u021c\u021d\u0005"+ + "i\u0000\u0000\u021d\u021e\u0005v\u0000\u0000\u021e\\\u0001\u0000\u0000"+ + "\u0000\u021f\u0220\u0005t\u0000\u0000\u0220\u0221\u0005y\u0000\u0000\u0221"+ + "\u0222\u0005p\u0000\u0000\u0222\u0223\u0005e\u0000\u0000\u0223\u0224\u0005"+ + "o\u0000\u0000\u0224\u0225\u0005f\u0000\u0000\u0225^\u0001\u0000\u0000"+ + "\u0000\u0226\u0227\u0005u\u0000\u0000\u0227\u0228\u0005n\u0000\u0000\u0228"+ + "\u0229\u0005s\u0000\u0000\u0229\u022a\u0005i\u0000\u0000\u022a\u022b\u0005"+ + "z\u0000\u0000\u022b\u022c\u0005e\u0000\u0000\u022c\u022d\u0005d\u0000"+ + "\u0000\u022d`\u0001\u0000\u0000\u0000\u022e\u022f\u0005v\u0000\u0000\u022f"+ + "\u0230\u0005i\u0000\u0000\u0230\u0231\u0005r\u0000\u0000\u0231\u0232\u0005"+ + "t\u0000\u0000\u0232\u0233\u0005u\u0000\u0000\u0233\u0234\u0005a\u0000"+ + "\u0000\u0234\u0235\u0005l\u0000\u0000\u0235b\u0001\u0000\u0000\u0000\u0236"+ + "\u0237\u0005y\u0000\u0000\u0237\u0238\u0005i\u0000\u0000\u0238\u0239\u0005"+ + "e\u0000\u0000\u0239\u023a\u0005l\u0000\u0000\u023a\u023b\u0005d\u0000"+ + "\u0000\u023bd\u0001\u0000\u0000\u0000\u023c\u023d\u0005t\u0000\u0000\u023d"+ + "\u023e\u0005r\u0000\u0000\u023e\u023f\u0005y\u0000\u0000\u023ff\u0001"+ + "\u0000\u0000\u0000\u0240\u0241\u0005u\u0000\u0000\u0241\u0242\u0005n\u0000"+ + "\u0000\u0242\u0243\u0005i\u0000\u0000\u0243\u0244\u0005o\u0000\u0000\u0244"+ + "\u0245\u0005n\u0000\u0000\u0245h\u0001\u0000\u0000\u0000\u0246\u0247\u0005"+ + "\'\u0000\u0000\u0247\u0248\u0005s\u0000\u0000\u0248\u0249\u0005t\u0000"+ + "\u0000\u0249\u024a\u0005a\u0000\u0000\u024a\u024b\u0005t\u0000\u0000\u024b"+ + "\u024c\u0005i\u0000\u0000\u024c\u024d\u0005c\u0000\u0000\u024dj\u0001"+ + "\u0000\u0000\u0000\u024e\u024f\u0005m\u0000\u0000\u024f\u0250\u0005a\u0000"+ + "\u0000\u0250\u0251\u0005c\u0000\u0000\u0251\u0252\u0005r\u0000\u0000\u0252"+ + "\u0253\u0005o\u0000\u0000\u0253\u0254\u0005_\u0000\u0000\u0254\u0255\u0005"+ + "r\u0000\u0000\u0255\u0256\u0005u\u0000\u0000\u0256\u0257\u0005l\u0000"+ + "\u0000\u0257\u0258\u0005e\u0000\u0000\u0258\u0259\u0005s\u0000\u0000\u0259"+ + "l\u0001\u0000\u0000\u0000\u025a\u025b\u0005\'\u0000\u0000\u025b\u025c"+ + "\u0005_\u0000\u0000\u025cn\u0001\u0000\u0000\u0000\u025d\u025e\u0005$"+ + "\u0000\u0000\u025e\u025f\u0005c\u0000\u0000\u025f\u0260\u0005r\u0000\u0000"+ + "\u0260\u0261\u0005a\u0000\u0000\u0261\u0262\u0005t\u0000\u0000\u0262\u0263"+ + "\u0005e\u0000\u0000\u0263p\u0001\u0000\u0000\u0000\u0264\u0268\u0003s"+ + "9\u0000\u0265\u0267\u0003u:\u0000\u0266\u0265\u0001\u0000\u0000\u0000"+ + "\u0267\u026a\u0001\u0000\u0000\u0000\u0268\u0266\u0001\u0000\u0000\u0000"+ + "\u0268\u0269\u0001\u0000\u0000\u0000\u0269\u0272\u0001\u0000\u0000\u0000"+ + "\u026a\u0268\u0001\u0000\u0000\u0000\u026b\u026d\u0005_\u0000\u0000\u026c"+ + "\u026e\u0003u:\u0000\u026d\u026c\u0001\u0000\u0000\u0000\u026e\u026f\u0001"+ + "\u0000\u0000\u0000\u026f\u026d\u0001\u0000\u0000\u0000\u026f\u0270\u0001"+ + "\u0000\u0000\u0000\u0270\u0272\u0001\u0000\u0000\u0000\u0271\u0264\u0001"+ + "\u0000\u0000\u0000\u0271\u026b\u0001\u0000\u0000\u0000\u0272r\u0001\u0000"+ + "\u0000\u0000\u0273\u0276\u0007\u0000\u0000\u0000\u0274\u0276\u0003w;\u0000"+ + "\u0275\u0273\u0001\u0000\u0000\u0000\u0275\u0274\u0001\u0000\u0000\u0000"+ + "\u0276t\u0001\u0000\u0000\u0000\u0277\u027b\u0003s9\u0000\u0278\u027b"+ + "\u0007\u0001\u0000\u0000\u0279\u027b\u0003y<\u0000\u027a\u0277\u0001\u0000"+ + "\u0000\u0000\u027a\u0278\u0001\u0000\u0000\u0000\u027a\u0279\u0001\u0000"+ + "\u0000\u0000\u027bv\u0001\u0000\u0000\u0000\u027c\u027d\u0007\u0002\u0000"+ + "\u0000\u027dx\u0001\u0000\u0000\u0000\u027e\u027f\u0007\u0003\u0000\u0000"+ + "\u027fz\u0001\u0000\u0000\u0000\u0280\u0281\u0005r\u0000\u0000\u0281\u0282"+ + "\u0005#\u0000\u0000\u0282\u0283\u0001\u0000\u0000\u0000\u0283\u0284\u0003"+ + "q8\u0000\u0284|\u0001\u0000\u0000\u0000\u0285\u0286\u0005/\u0000\u0000"+ + "\u0286\u0287\u0005/\u0000\u0000\u0287\u028b\u0001\u0000\u0000\u0000\u0288"+ + "\u028c\b\u0004\u0000\u0000\u0289\u028a\u0005/\u0000\u0000\u028a\u028c"+ + "\u0005/\u0000\u0000\u028b\u0288\u0001\u0000\u0000\u0000\u028b\u0289\u0001"+ + "\u0000\u0000\u0000\u028c\u0290\u0001\u0000\u0000\u0000\u028d\u028f\b\u0005"+ + "\u0000\u0000\u028e\u028d\u0001\u0000\u0000\u0000\u028f\u0292\u0001\u0000"+ + "\u0000\u0000\u0290\u028e\u0001\u0000\u0000\u0000\u0290\u0291\u0001\u0000"+ + "\u0000\u0000\u0291\u0296\u0001\u0000\u0000\u0000\u0292\u0290\u0001\u0000"+ + "\u0000\u0000\u0293\u0294\u0005/\u0000\u0000\u0294\u0296\u0005/\u0000\u0000"+ + "\u0295\u0285\u0001\u0000\u0000\u0000\u0295\u0293\u0001\u0000\u0000\u0000"+ + "\u0296\u0297\u0001\u0000\u0000\u0000\u0297\u0298\u0006>\u0000\u0000\u0298"+ + "~\u0001\u0000\u0000\u0000\u0299\u029a\u0005/\u0000\u0000\u029a\u029b\u0005"+ + "*\u0000\u0000\u029b\u02a0\u0001\u0000\u0000\u0000\u029c\u02a1\b\u0006"+ + "\u0000\u0000\u029d\u029e\u0005*\u0000\u0000\u029e\u02a1\u0005*\u0000\u0000"+ + "\u029f\u02a1\u0003\u0089D\u0000\u02a0\u029c\u0001\u0000\u0000\u0000\u02a0"+ + "\u029d\u0001\u0000\u0000\u0000\u02a0\u029f\u0001\u0000\u0000\u0000\u02a1"+ + "\u02a6\u0001\u0000\u0000\u0000\u02a2\u02a5\u0003\u0089D\u0000\u02a3\u02a5"+ + "\b\u0007\u0000\u0000\u02a4\u02a2\u0001\u0000\u0000\u0000\u02a4\u02a3\u0001"+ + "\u0000\u0000\u0000\u02a5\u02a8\u0001\u0000\u0000\u0000\u02a6\u02a7\u0001"+ + "\u0000\u0000\u0000\u02a6\u02a4\u0001\u0000\u0000\u0000\u02a7\u02a9\u0001"+ + "\u0000\u0000\u0000\u02a8\u02a6\u0001\u0000\u0000\u0000\u02a9\u02aa\u0005"+ + "*\u0000\u0000\u02aa\u02b5\u0005/\u0000\u0000\u02ab\u02ac\u0005/\u0000"+ + "\u0000\u02ac\u02ad\u0005*\u0000\u0000\u02ad\u02ae\u0005*\u0000\u0000\u02ae"+ + "\u02b5\u0005/\u0000\u0000\u02af\u02b0\u0005/\u0000\u0000\u02b0\u02b1\u0005"+ + "*\u0000\u0000\u02b1\u02b2\u0005*\u0000\u0000\u02b2\u02b3\u0005*\u0000"+ + "\u0000\u02b3\u02b5\u0005/\u0000\u0000\u02b4\u0299\u0001\u0000\u0000\u0000"+ + "\u02b4\u02ab\u0001\u0000\u0000\u0000\u02b4\u02af\u0001\u0000\u0000\u0000"+ + "\u02b5\u02b6\u0001\u0000\u0000\u0000\u02b6\u02b7\u0006?\u0000\u0000\u02b7"+ + "\u0080\u0001\u0000\u0000\u0000\u02b8\u02b9\u0005/\u0000\u0000\u02b9\u02ba"+ + "\u0005/\u0000\u0000\u02ba\u02bb\u0005!\u0000\u0000\u02bb\u02bf\u0001\u0000"+ + "\u0000\u0000\u02bc\u02be\b\u0005\u0000\u0000\u02bd\u02bc\u0001\u0000\u0000"+ + "\u0000\u02be\u02c1\u0001\u0000\u0000\u0000\u02bf\u02bd\u0001\u0000\u0000"+ + "\u0000\u02bf\u02c0\u0001\u0000\u0000\u0000\u02c0\u02c2\u0001\u0000\u0000"+ + "\u0000\u02c1\u02bf\u0001\u0000\u0000\u0000\u02c2\u02c3\u0006@\u0000\u0000"+ + "\u02c3\u0082\u0001\u0000\u0000\u0000\u02c4\u02c5\u0005/\u0000\u0000\u02c5"+ + "\u02c6\u0005*\u0000\u0000\u02c6\u02c7\u0005!\u0000\u0000\u02c7\u02cc\u0001"+ + "\u0000\u0000\u0000\u02c8\u02cb\u0003\u0089D\u0000\u02c9\u02cb\b\u0007"+ + "\u0000\u0000\u02ca\u02c8\u0001\u0000\u0000\u0000\u02ca\u02c9\u0001\u0000"+ + "\u0000\u0000\u02cb\u02ce\u0001\u0000\u0000\u0000\u02cc\u02cd\u0001\u0000"+ + "\u0000\u0000\u02cc\u02ca\u0001\u0000\u0000\u0000\u02cd\u02cf\u0001\u0000"+ + "\u0000\u0000\u02ce\u02cc\u0001\u0000\u0000\u0000\u02cf\u02d0\u0005*\u0000"+ + "\u0000\u02d0\u02d1\u0005/\u0000\u0000\u02d1\u02d2\u0001\u0000\u0000\u0000"+ + "\u02d2\u02d3\u0006A\u0000\u0000\u02d3\u0084\u0001\u0000\u0000\u0000\u02d4"+ + "\u02d5\u0005/\u0000\u0000\u02d5\u02d6\u0005/\u0000\u0000\u02d6\u02d7\u0005"+ + "/\u0000\u0000\u02d7\u02df\u0001\u0000\u0000\u0000\u02d8\u02dc\b\b\u0000"+ + "\u0000\u02d9\u02db\b\u0005\u0000\u0000\u02da\u02d9\u0001\u0000\u0000\u0000"+ + "\u02db\u02de\u0001\u0000\u0000\u0000\u02dc\u02da\u0001\u0000\u0000\u0000"+ + "\u02dc\u02dd\u0001\u0000\u0000\u0000\u02dd\u02e0\u0001\u0000\u0000\u0000"+ + "\u02de\u02dc\u0001\u0000\u0000\u0000\u02df\u02d8\u0001\u0000\u0000\u0000"+ + "\u02df\u02e0\u0001\u0000\u0000\u0000\u02e0\u02e1\u0001\u0000\u0000\u0000"+ + "\u02e1\u02e2\u0006B\u0000\u0000\u02e2\u0086\u0001\u0000\u0000\u0000\u02e3"+ + "\u02e4\u0005/\u0000\u0000\u02e4\u02e5\u0005*\u0000\u0000\u02e5\u02e6\u0005"+ + "*\u0000\u0000\u02e6\u02e9\u0001\u0000\u0000\u0000\u02e7\u02ea\b\u0007"+ + "\u0000\u0000\u02e8\u02ea\u0003\u0089D\u0000\u02e9\u02e7\u0001\u0000\u0000"+ + "\u0000\u02e9\u02e8\u0001\u0000\u0000\u0000\u02ea\u02ef\u0001\u0000\u0000"+ + "\u0000\u02eb\u02ee\u0003\u0089D\u0000\u02ec\u02ee\b\u0007\u0000\u0000"+ + "\u02ed\u02eb\u0001\u0000\u0000\u0000\u02ed\u02ec\u0001\u0000\u0000\u0000"+ + "\u02ee\u02f1\u0001\u0000\u0000\u0000\u02ef\u02f0\u0001\u0000\u0000\u0000"+ + "\u02ef\u02ed\u0001\u0000\u0000\u0000\u02f0\u02f2\u0001\u0000\u0000\u0000"+ + "\u02f1\u02ef\u0001\u0000\u0000\u0000\u02f2\u02f3\u0005*\u0000\u0000\u02f3"+ + "\u02f4\u0005/\u0000\u0000\u02f4\u02f5\u0001\u0000\u0000\u0000\u02f5\u02f6"+ + "\u0006C\u0000\u0000\u02f6\u0088\u0001\u0000\u0000\u0000\u02f7\u02fb\u0003"+ + "\u007f?\u0000\u02f8\u02fb\u0003\u0083A\u0000\u02f9\u02fb\u0003\u0087C"+ + "\u0000\u02fa\u02f7\u0001\u0000\u0000\u0000\u02fa\u02f8\u0001\u0000\u0000"+ + "\u0000\u02fa\u02f9\u0001\u0000\u0000\u0000\u02fb\u02fc\u0001\u0000\u0000"+ + "\u0000\u02fc\u02fd\u0006D\u0000\u0000\u02fd\u008a\u0001\u0000\u0000\u0000"+ + "\u02fe\u0300\u0004E\u0000\u0000\u02ff\u0301\u0005\u8000\ufeff\u0000\u0000"+ + "\u0300\u02ff\u0001\u0000\u0000\u0000\u0300\u0301\u0001\u0000\u0000\u0000"+ + "\u0301\u0302\u0001\u0000\u0000\u0000\u0302\u0303\u0005#\u0000\u0000\u0303"+ + "\u0304\u0005!\u0000\u0000\u0304\u0308\u0001\u0000\u0000\u0000\u0305\u0307"+ + "\b\u0005\u0000\u0000\u0306\u0305\u0001\u0000\u0000\u0000\u0307\u030a\u0001"+ + "\u0000\u0000\u0000\u0308\u0306\u0001\u0000\u0000\u0000\u0308\u0309\u0001"+ + "\u0000\u0000\u0000\u0309\u030b\u0001\u0000\u0000\u0000\u030a\u0308\u0001"+ + "\u0000\u0000\u0000\u030b\u030c\u0006E\u0000\u0000\u030c\u008c\u0001\u0000"+ + "\u0000\u0000\u030d\u030e\u0007\t\u0000\u0000\u030e\u030f\u0001\u0000\u0000"+ + "\u0000\u030f\u0310\u0006F\u0000\u0000\u0310\u008e\u0001\u0000\u0000\u0000"+ + "\u0311\u0312\u0005\r\u0000\u0000\u0312\u0315\u0005\n\u0000\u0000\u0313"+ + "\u0315\u0007\u0005\u0000\u0000\u0314\u0311\u0001\u0000\u0000\u0000\u0314"+ + "\u0313\u0001\u0000\u0000\u0000\u0315\u0316\u0001\u0000\u0000\u0000\u0316"+ + "\u0317\u0006G\u0000\u0000\u0317\u0090\u0001\u0000\u0000\u0000\u0318\u031d"+ + "\u0005\'\u0000\u0000\u0319\u031e\b\n\u0000\u0000\u031a\u031e\u0003\u00a7"+ + "S\u0000\u031b\u031e\u0003\u009fO\u0000\u031c\u031e\u0003\u00a5R\u0000"+ + "\u031d\u0319\u0001\u0000\u0000\u0000\u031d\u031a\u0001\u0000\u0000\u0000"+ + "\u031d\u031b\u0001\u0000\u0000\u0000\u031d\u031c\u0001\u0000\u0000\u0000"+ + "\u031e\u031f\u0001\u0000\u0000\u0000\u031f\u0320\u0005\'\u0000\u0000\u0320"+ + "\u0092\u0001\u0000\u0000\u0000\u0321\u0329\u0005\"\u0000\u0000\u0322\u0328"+ + "\b\u000b\u0000\u0000\u0323\u0328\u0003\u00a7S\u0000\u0324\u0328\u0003"+ + "\u009fO\u0000\u0325\u0328\u0003\u00a5R\u0000\u0326\u0328\u0003\u00a9T"+ + "\u0000\u0327\u0322\u0001\u0000\u0000\u0000\u0327\u0323\u0001\u0000\u0000"+ + "\u0000\u0327\u0324\u0001\u0000\u0000\u0000\u0327\u0325\u0001\u0000\u0000"+ + "\u0000\u0327\u0326\u0001\u0000\u0000\u0000\u0328\u032b\u0001\u0000\u0000"+ + "\u0000\u0329\u0327\u0001\u0000\u0000\u0000\u0329\u032a\u0001\u0000\u0000"+ + "\u0000\u032a\u032c\u0001\u0000\u0000\u0000\u032b\u0329\u0001\u0000\u0000"+ + "\u0000\u032c\u032d\u0005\"\u0000\u0000\u032d\u0094\u0001\u0000\u0000\u0000"+ + "\u032e\u032f\u0005r\u0000\u0000\u032f\u0330\u0003\u0097K\u0000\u0330\u0096"+ + "\u0001\u0000\u0000\u0000\u0331\u0332\u0005#\u0000\u0000\u0332\u0333\u0003"+ + "\u0097K\u0000\u0333\u0334\u0005#\u0000\u0000\u0334\u033e\u0001\u0000\u0000"+ + "\u0000\u0335\u0339\u0005\"\u0000\u0000\u0336\u0338\t\u0000\u0000\u0000"+ + "\u0337\u0336\u0001\u0000\u0000\u0000\u0338\u033b\u0001\u0000\u0000\u0000"+ + "\u0339\u033a\u0001\u0000\u0000\u0000\u0339\u0337\u0001\u0000\u0000\u0000"+ + "\u033a\u033c\u0001\u0000\u0000\u0000\u033b\u0339\u0001\u0000\u0000\u0000"+ + "\u033c\u033e\u0005\"\u0000\u0000\u033d\u0331\u0001\u0000\u0000\u0000\u033d"+ + "\u0335\u0001\u0000\u0000\u0000\u033e\u0098\u0001\u0000\u0000\u0000\u033f"+ + "\u0340\u0005b\u0000\u0000\u0340\u0341\u0005\'\u0000\u0000\u0341\u0345"+ + "\u0001\u0000\u0000\u0000\u0342\u0346\t\u0000\u0000\u0000\u0343\u0346\u0003"+ + "\u00a7S\u0000\u0344\u0346\u0003\u00a1P\u0000\u0345\u0342\u0001\u0000\u0000"+ + "\u0000\u0345\u0343\u0001\u0000\u0000\u0000\u0345\u0344\u0001\u0000\u0000"+ + "\u0000\u0346\u0347\u0001\u0000\u0000\u0000\u0347\u0348\u0005\'\u0000\u0000"+ + "\u0348\u009a\u0001\u0000\u0000\u0000\u0349\u034a\u0005b\u0000\u0000\u034a"+ + "\u034b\u0005\"\u0000\u0000\u034b\u0351\u0001\u0000\u0000\u0000\u034c\u0350"+ + "\b\u000b\u0000\u0000\u034d\u0350\u0003\u00a7S\u0000\u034e\u0350\u0003"+ + "\u00a1P\u0000\u034f\u034c\u0001\u0000\u0000\u0000\u034f\u034d\u0001\u0000"+ + "\u0000\u0000\u034f\u034e\u0001\u0000\u0000\u0000\u0350\u0353\u0001\u0000"+ + "\u0000\u0000\u0351\u034f\u0001\u0000\u0000\u0000\u0351\u0352\u0001\u0000"+ + "\u0000\u0000\u0352\u0354\u0001\u0000\u0000\u0000\u0353\u0351\u0001\u0000"+ + "\u0000\u0000\u0354\u0355\u0005\"\u0000\u0000\u0355\u009c\u0001\u0000\u0000"+ + "\u0000\u0356\u0357\u0005b\u0000\u0000\u0357\u0358\u0005r\u0000\u0000\u0358"+ + "\u0359\u0001\u0000\u0000\u0000\u0359\u035a\u0003\u0097K\u0000\u035a\u009e"+ + "\u0001\u0000\u0000\u0000\u035b\u035c\u0005\\\u0000\u0000\u035c\u035d\u0005"+ + "x\u0000\u0000\u035d\u035e\u0001\u0000\u0000\u0000\u035e\u035f\u0003\u00bd"+ + "^\u0000\u035f\u0360\u0003\u00c1`\u0000\u0360\u0363\u0001\u0000\u0000\u0000"+ + "\u0361\u0363\u0003\u00a3Q\u0000\u0362\u035b\u0001\u0000\u0000\u0000\u0362"+ + "\u0361\u0001\u0000\u0000\u0000\u0363\u00a0\u0001\u0000\u0000\u0000\u0364"+ + "\u0365\u0005\\\u0000\u0000\u0365\u0366\u0005x\u0000\u0000\u0366\u0367"+ + "\u0001\u0000\u0000\u0000\u0367\u0368\u0003\u00c1`\u0000\u0368\u0369\u0003"+ + "\u00c1`\u0000\u0369\u036c\u0001\u0000\u0000\u0000\u036a\u036c\u0003\u00a3"+ + "Q\u0000\u036b\u0364\u0001\u0000\u0000\u0000\u036b\u036a\u0001\u0000\u0000"+ + "\u0000\u036c\u00a2\u0001\u0000\u0000\u0000\u036d\u036e\u0005\\\u0000\u0000"+ + "\u036e\u036f\u0007\f\u0000\u0000\u036f\u00a4\u0001\u0000\u0000\u0000\u0370"+ + "\u0371\u0005\\\u0000\u0000\u0371\u0372\u0005u\u0000\u0000\u0372\u0373"+ + "\u0005{\u0000\u0000\u0373\u0374\u0001\u0000\u0000\u0000\u0374\u0376\u0003"+ + "\u00c1`\u0000\u0375\u0377\u0003\u00c1`\u0000\u0376\u0375\u0001\u0000\u0000"+ + "\u0000\u0376\u0377\u0001\u0000\u0000\u0000\u0377\u0379\u0001\u0000\u0000"+ + "\u0000\u0378\u037a\u0003\u00c1`\u0000\u0379\u0378\u0001\u0000\u0000\u0000"+ + "\u0379\u037a\u0001\u0000\u0000\u0000\u037a\u037c\u0001\u0000\u0000\u0000"+ + "\u037b\u037d\u0003\u00c1`\u0000\u037c\u037b\u0001\u0000\u0000\u0000\u037c"+ + "\u037d\u0001\u0000\u0000\u0000\u037d\u037f\u0001\u0000\u0000\u0000\u037e"+ + "\u0380\u0003\u00c1`\u0000\u037f\u037e\u0001\u0000\u0000\u0000\u037f\u0380"+ + "\u0001\u0000\u0000\u0000\u0380\u0382\u0001\u0000\u0000\u0000\u0381\u0383"+ + "\u0003\u00c1`\u0000\u0382\u0381\u0001\u0000\u0000\u0000\u0382\u0383\u0001"+ + "\u0000\u0000\u0000\u0383\u0384\u0001\u0000\u0000\u0000\u0384\u0385\u0005"+ + "}\u0000\u0000\u0385\u00a6\u0001\u0000\u0000\u0000\u0386\u0387\u0005\\"+ + "\u0000\u0000\u0387\u0388\u0007\r\u0000\u0000\u0388\u00a8\u0001\u0000\u0000"+ + "\u0000\u0389\u038a\u0005\\\u0000\u0000\u038a\u038b\u0005\n\u0000\u0000"+ + "\u038b\u00aa\u0001\u0000\u0000\u0000\u038c\u0391\u0003\u00adV\u0000\u038d"+ + "\u0391\u0003\u00b3Y\u0000\u038e\u0391\u0003\u00b1X\u0000\u038f\u0391\u0003"+ + "\u00afW\u0000\u0390\u038c\u0001\u0000\u0000\u0000\u0390\u038d\u0001\u0000"+ + "\u0000\u0000\u0390\u038e\u0001\u0000\u0000\u0000\u0390\u038f\u0001\u0000"+ + "\u0000\u0000\u0391\u0393\u0001\u0000\u0000\u0000\u0392\u0394\u0003\u00b7"+ + "[\u0000\u0393\u0392\u0001\u0000\u0000\u0000\u0393\u0394\u0001\u0000\u0000"+ + "\u0000\u0394\u00ac\u0001\u0000\u0000\u0000\u0395\u039a\u0003\u00bf_\u0000"+ + "\u0396\u0399\u0003\u00bf_\u0000\u0397\u0399\u0005_\u0000\u0000\u0398\u0396"+ + "\u0001\u0000\u0000\u0000\u0398\u0397\u0001\u0000\u0000\u0000\u0399\u039c"+ + "\u0001\u0000\u0000\u0000\u039a\u0398\u0001\u0000\u0000\u0000\u039a\u039b"+ + "\u0001\u0000\u0000\u0000\u039b\u00ae\u0001\u0000\u0000\u0000\u039c\u039a"+ + "\u0001\u0000\u0000\u0000\u039d\u039e\u00050\u0000\u0000\u039e\u039f\u0005"+ + "x\u0000\u0000\u039f\u03a3\u0001\u0000\u0000\u0000\u03a0\u03a2\u0005_\u0000"+ + "\u0000\u03a1\u03a0\u0001\u0000\u0000\u0000\u03a2\u03a5\u0001\u0000\u0000"+ + "\u0000\u03a3\u03a1\u0001\u0000\u0000\u0000\u03a3\u03a4\u0001\u0000\u0000"+ + "\u0000\u03a4\u03a6\u0001\u0000\u0000\u0000\u03a5\u03a3\u0001\u0000\u0000"+ + "\u0000\u03a6\u03ab\u0003\u00c1`\u0000\u03a7\u03aa\u0003\u00c1`\u0000\u03a8"+ + "\u03aa\u0005_\u0000\u0000\u03a9\u03a7\u0001\u0000\u0000\u0000\u03a9\u03a8"+ + "\u0001\u0000\u0000\u0000\u03aa\u03ad\u0001\u0000\u0000\u0000\u03ab\u03a9"+ + "\u0001\u0000\u0000\u0000\u03ab\u03ac\u0001\u0000\u0000\u0000\u03ac\u00b0"+ + "\u0001\u0000\u0000\u0000\u03ad\u03ab\u0001\u0000\u0000\u0000\u03ae\u03af"+ + "\u00050\u0000\u0000\u03af\u03b0\u0005o\u0000\u0000\u03b0\u03b4\u0001\u0000"+ + "\u0000\u0000\u03b1\u03b3\u0005_\u0000\u0000\u03b2\u03b1\u0001\u0000\u0000"+ + "\u0000\u03b3\u03b6\u0001\u0000\u0000\u0000\u03b4\u03b2\u0001\u0000\u0000"+ + "\u0000\u03b4\u03b5\u0001\u0000\u0000\u0000\u03b5\u03b7\u0001\u0000\u0000"+ + "\u0000\u03b6\u03b4\u0001\u0000\u0000\u0000\u03b7\u03bc\u0003\u00bd^\u0000"+ + "\u03b8\u03bb\u0003\u00bd^\u0000\u03b9\u03bb\u0005_\u0000\u0000\u03ba\u03b8"+ + "\u0001\u0000\u0000\u0000\u03ba\u03b9\u0001\u0000\u0000\u0000\u03bb\u03be"+ + "\u0001\u0000\u0000\u0000\u03bc\u03ba\u0001\u0000\u0000\u0000\u03bc\u03bd"+ + "\u0001\u0000\u0000\u0000\u03bd\u00b2\u0001\u0000\u0000\u0000\u03be\u03bc"+ + "\u0001\u0000\u0000\u0000\u03bf\u03c0\u00050\u0000\u0000\u03c0\u03c1\u0005"+ + "b\u0000\u0000\u03c1\u03c5\u0001\u0000\u0000\u0000\u03c2\u03c4\u0005_\u0000"+ + "\u0000\u03c3\u03c2\u0001\u0000\u0000\u0000\u03c4\u03c7\u0001\u0000\u0000"+ + "\u0000\u03c5\u03c3\u0001\u0000\u0000\u0000\u03c5\u03c6\u0001\u0000\u0000"+ + "\u0000\u03c6\u03c8\u0001\u0000\u0000\u0000\u03c7\u03c5\u0001\u0000\u0000"+ + "\u0000\u03c8\u03cc\u0007\u000e\u0000\u0000\u03c9\u03cb\u0007\u000f\u0000"+ + "\u0000\u03ca\u03c9\u0001\u0000\u0000\u0000\u03cb\u03ce\u0001\u0000\u0000"+ + "\u0000\u03cc\u03ca\u0001\u0000\u0000\u0000\u03cc\u03cd\u0001\u0000\u0000"+ + "\u0000\u03cd\u00b4\u0001\u0000\u0000\u0000\u03ce\u03cc\u0001\u0000\u0000"+ + "\u0000\u03cf\u03df\u0004Z\u0001\u0000\u03d0\u03d1\u0003\u00adV\u0000\u03d1"+ + "\u03d2\u0005.\u0000\u0000\u03d2\u03d3\u0004Z\u0002\u0000\u03d3\u03e0\u0001"+ + "\u0000\u0000\u0000\u03d4\u03d7\u0003\u00adV\u0000\u03d5\u03d6\u0005.\u0000"+ + "\u0000\u03d6\u03d8\u0003\u00adV\u0000\u03d7\u03d5\u0001\u0000\u0000\u0000"+ + "\u03d7\u03d8\u0001\u0000\u0000\u0000\u03d8\u03da\u0001\u0000\u0000\u0000"+ + "\u03d9\u03db\u0003\u00bb]\u0000\u03da\u03d9\u0001\u0000\u0000\u0000\u03da"+ + "\u03db\u0001\u0000\u0000\u0000\u03db\u03dd\u0001\u0000\u0000\u0000\u03dc"+ + "\u03de\u0003\u00b9\\\u0000\u03dd\u03dc\u0001\u0000\u0000\u0000\u03dd\u03de"+ + "\u0001\u0000\u0000\u0000\u03de\u03e0\u0001\u0000\u0000\u0000\u03df\u03d0"+ + "\u0001\u0000\u0000\u0000\u03df\u03d4\u0001\u0000\u0000\u0000\u03e0\u00b6"+ + "\u0001\u0000\u0000\u0000\u03e1\u03e2\u0005u\u0000\u0000\u03e2\u040a\u0005"+ + "8\u0000\u0000\u03e3\u03e4\u0005u\u0000\u0000\u03e4\u03e5\u00051\u0000"+ + "\u0000\u03e5\u040a\u00056\u0000\u0000\u03e6\u03e7\u0005u\u0000\u0000\u03e7"+ + "\u03e8\u00053\u0000\u0000\u03e8\u040a\u00052\u0000\u0000\u03e9\u03ea\u0005"+ + "u\u0000\u0000\u03ea\u03eb\u00056\u0000\u0000\u03eb\u040a\u00054\u0000"+ + "\u0000\u03ec\u03ed\u0005u\u0000\u0000\u03ed\u03ee\u00051\u0000\u0000\u03ee"+ + "\u03ef\u00052\u0000\u0000\u03ef\u040a\u00058\u0000\u0000\u03f0\u03f1\u0005"+ + "u\u0000\u0000\u03f1\u03f2\u0005s\u0000\u0000\u03f2\u03f3\u0005i\u0000"+ + "\u0000\u03f3\u03f4\u0005z\u0000\u0000\u03f4\u040a\u0005e\u0000\u0000\u03f5"+ + "\u03f6\u0005i\u0000\u0000\u03f6\u040a\u00058\u0000\u0000\u03f7\u03f8\u0005"+ + "i\u0000\u0000\u03f8\u03f9\u00051\u0000\u0000\u03f9\u040a\u00056\u0000"+ + "\u0000\u03fa\u03fb\u0005i\u0000\u0000\u03fb\u03fc\u00053\u0000\u0000\u03fc"+ + "\u040a\u00052\u0000\u0000\u03fd\u03fe\u0005i\u0000\u0000\u03fe\u03ff\u0005"+ + "6\u0000\u0000\u03ff\u040a\u00054\u0000\u0000\u0400\u0401\u0005i\u0000"+ + "\u0000\u0401\u0402\u00051\u0000\u0000\u0402\u0403\u00052\u0000\u0000\u0403"+ + "\u040a\u00058\u0000\u0000\u0404\u0405\u0005i\u0000\u0000\u0405\u0406\u0005"+ + "s\u0000\u0000\u0406\u0407\u0005i\u0000\u0000\u0407\u0408\u0005z\u0000"+ + "\u0000\u0408\u040a\u0005e\u0000\u0000\u0409\u03e1\u0001\u0000\u0000\u0000"+ + "\u0409\u03e3\u0001\u0000\u0000\u0000\u0409\u03e6\u0001\u0000\u0000\u0000"+ + "\u0409\u03e9\u0001\u0000\u0000\u0000\u0409\u03ec\u0001\u0000\u0000\u0000"+ + "\u0409\u03f0\u0001\u0000\u0000\u0000\u0409\u03f5\u0001\u0000\u0000\u0000"+ + "\u0409\u03f7\u0001\u0000\u0000\u0000\u0409\u03fa\u0001\u0000\u0000\u0000"+ + "\u0409\u03fd\u0001\u0000\u0000\u0000\u0409\u0400\u0001\u0000\u0000\u0000"+ + "\u0409\u0404\u0001\u0000\u0000\u0000\u040a\u00b8\u0001\u0000\u0000\u0000"+ + "\u040b\u040c\u0005f\u0000\u0000\u040c\u040d\u00053\u0000\u0000\u040d\u0412"+ + "\u00052\u0000\u0000\u040e\u040f\u0005f\u0000\u0000\u040f\u0410\u00056"+ + "\u0000\u0000\u0410\u0412\u00054\u0000\u0000\u0411\u040b\u0001\u0000\u0000"+ + "\u0000\u0411\u040e\u0001\u0000\u0000\u0000\u0412\u00ba\u0001\u0000\u0000"+ + "\u0000\u0413\u0415\u0007\u0010\u0000\u0000\u0414\u0416\u0007\u0011\u0000"+ + "\u0000\u0415\u0414\u0001\u0000\u0000\u0000\u0415\u0416\u0001\u0000\u0000"+ + "\u0000\u0416\u041a\u0001\u0000\u0000\u0000\u0417\u0419\u0005_\u0000\u0000"+ + "\u0418\u0417\u0001\u0000\u0000\u0000\u0419\u041c\u0001\u0000\u0000\u0000"+ + "\u041a\u0418\u0001\u0000\u0000\u0000\u041a\u041b\u0001\u0000\u0000\u0000"+ + "\u041b\u041d\u0001\u0000\u0000\u0000\u041c\u041a\u0001\u0000\u0000\u0000"+ + "\u041d\u041e\u0003\u00adV\u0000\u041e\u00bc\u0001\u0000\u0000\u0000\u041f"+ + "\u0420\u0007\u0012\u0000\u0000\u0420\u00be\u0001\u0000\u0000\u0000\u0421"+ + "\u0422\u0007\u0013\u0000\u0000\u0422\u00c0\u0001\u0000\u0000\u0000\u0423"+ + "\u0424\u0007\u0014\u0000\u0000\u0424\u00c2\u0001\u0000\u0000\u0000\u0425"+ + "\u0426\u0005\'\u0000\u0000\u0426\u0427\u0003q8\u0000\u0427\u00c4\u0001"+ + "\u0000\u0000\u0000\u0428\u0429\u0005+\u0000\u0000\u0429\u00c6\u0001\u0000"+ + "\u0000\u0000\u042a\u042b\u0005-\u0000\u0000\u042b\u00c8\u0001\u0000\u0000"+ + "\u0000\u042c\u042d\u0005*\u0000\u0000\u042d\u00ca\u0001\u0000\u0000\u0000"+ + "\u042e\u042f\u0005/\u0000\u0000\u042f\u00cc\u0001\u0000\u0000\u0000\u0430"+ + "\u0431\u0005%\u0000\u0000\u0431\u00ce\u0001\u0000\u0000\u0000\u0432\u0433"+ + "\u0005^\u0000\u0000\u0433\u00d0\u0001\u0000\u0000\u0000\u0434\u0435\u0005"+ + "!\u0000\u0000\u0435\u00d2\u0001\u0000\u0000\u0000\u0436\u0437\u0005&\u0000"+ + "\u0000\u0437\u00d4\u0001\u0000\u0000\u0000\u0438\u0439\u0005|\u0000\u0000"+ + "\u0439\u00d6\u0001\u0000\u0000\u0000\u043a\u043b\u0005&\u0000\u0000\u043b"+ + "\u043c\u0005&\u0000\u0000\u043c\u00d8\u0001\u0000\u0000\u0000\u043d\u043e"+ + "\u0005|\u0000\u0000\u043e\u043f\u0005|\u0000\u0000\u043f\u00da\u0001\u0000"+ + "\u0000\u0000\u0440\u0441\u0005+\u0000\u0000\u0441\u0442\u0005=\u0000\u0000"+ + "\u0442\u00dc\u0001\u0000\u0000\u0000\u0443\u0444\u0005-\u0000\u0000\u0444"+ + "\u0445\u0005=\u0000\u0000\u0445\u00de\u0001\u0000\u0000\u0000\u0446\u0447"+ + "\u0005*\u0000\u0000\u0447\u0448\u0005=\u0000\u0000\u0448\u00e0\u0001\u0000"+ + "\u0000\u0000\u0449\u044a\u0005/\u0000\u0000\u044a\u044b\u0005=\u0000\u0000"+ + "\u044b\u00e2\u0001\u0000\u0000\u0000\u044c\u044d\u0005%\u0000\u0000\u044d"+ + "\u044e\u0005=\u0000\u0000\u044e\u00e4\u0001\u0000\u0000\u0000\u044f\u0450"+ + "\u0005^\u0000\u0000\u0450\u0451\u0005=\u0000\u0000\u0451\u00e6\u0001\u0000"+ + "\u0000\u0000\u0452\u0453\u0005&\u0000\u0000\u0453\u0454\u0005=\u0000\u0000"+ + "\u0454\u00e8\u0001\u0000\u0000\u0000\u0455\u0456\u0005|\u0000\u0000\u0456"+ + "\u0457\u0005=\u0000\u0000\u0457\u00ea\u0001\u0000\u0000\u0000\u0458\u0459"+ + "\u0005<\u0000\u0000\u0459\u045a\u0005<\u0000\u0000\u045a\u045b\u0005="+ + "\u0000\u0000\u045b\u00ec\u0001\u0000\u0000\u0000\u045c\u045d\u0005>\u0000"+ + "\u0000\u045d\u045e\u0005>\u0000\u0000\u045e\u045f\u0005=\u0000\u0000\u045f"+ + "\u00ee\u0001\u0000\u0000\u0000\u0460\u0461\u0005=\u0000\u0000\u0461\u00f0"+ + "\u0001\u0000\u0000\u0000\u0462\u0463\u0005=\u0000\u0000\u0463\u0464\u0005"+ + "=\u0000\u0000\u0464\u00f2\u0001\u0000\u0000\u0000\u0465\u0466\u0005!\u0000"+ + "\u0000\u0466\u0467\u0005=\u0000\u0000\u0467\u00f4\u0001\u0000\u0000\u0000"+ + "\u0468\u0469\u0005>\u0000\u0000\u0469\u00f6\u0001\u0000\u0000\u0000\u046a"+ + "\u046b\u0005<\u0000\u0000\u046b\u00f8\u0001\u0000\u0000\u0000\u046c\u046d"+ + "\u0005>\u0000\u0000\u046d\u046e\u0005=\u0000\u0000\u046e\u00fa\u0001\u0000"+ + "\u0000\u0000\u046f\u0470\u0005<\u0000\u0000\u0470\u0471\u0005=\u0000\u0000"+ + "\u0471\u00fc\u0001\u0000\u0000\u0000\u0472\u0473\u0005@\u0000\u0000\u0473"+ + "\u00fe\u0001\u0000\u0000\u0000\u0474\u0475\u0005_\u0000\u0000\u0475\u0100"+ + "\u0001\u0000\u0000\u0000\u0476\u0477\u0005.\u0000\u0000\u0477\u0102\u0001"+ + "\u0000\u0000\u0000\u0478\u0479\u0005.\u0000\u0000\u0479\u047a\u0005.\u0000"+ + "\u0000\u047a\u0104\u0001\u0000\u0000\u0000\u047b\u047c\u0005.\u0000\u0000"+ + "\u047c\u047d\u0005.\u0000\u0000\u047d\u047e\u0005.\u0000\u0000\u047e\u0106"+ + "\u0001\u0000\u0000\u0000\u047f\u0480\u0005.\u0000\u0000\u0480\u0481\u0005"+ + ".\u0000\u0000\u0481\u0482\u0005=\u0000\u0000\u0482\u0108\u0001\u0000\u0000"+ + "\u0000\u0483\u0484\u0005,\u0000\u0000\u0484\u010a\u0001\u0000\u0000\u0000"+ + "\u0485\u0486\u0005;\u0000\u0000\u0486\u010c\u0001\u0000\u0000\u0000\u0487"+ + "\u0488\u0005:\u0000\u0000\u0488\u010e\u0001\u0000\u0000\u0000\u0489\u048a"+ + "\u0005:\u0000\u0000\u048a\u048b\u0005:\u0000\u0000\u048b\u0110\u0001\u0000"+ + "\u0000\u0000\u048c\u048d\u0005-\u0000\u0000\u048d\u048e\u0005>\u0000\u0000"+ + "\u048e\u0112\u0001\u0000\u0000\u0000\u048f\u0490\u0005=\u0000\u0000\u0490"+ + "\u0491\u0005>\u0000\u0000\u0491\u0114\u0001\u0000\u0000\u0000\u0492\u0493"+ + "\u0005#\u0000\u0000\u0493\u0116\u0001\u0000\u0000\u0000\u0494\u0495\u0005"+ + "$\u0000\u0000\u0495\u0118\u0001\u0000\u0000\u0000\u0496\u0497\u0005?\u0000"+ + "\u0000\u0497\u011a\u0001\u0000\u0000\u0000\u0498\u0499\u0005{\u0000\u0000"+ + "\u0499\u011c\u0001\u0000\u0000\u0000\u049a\u049b\u0005}\u0000\u0000\u049b"+ + "\u011e\u0001\u0000\u0000\u0000\u049c\u049d\u0005[\u0000\u0000\u049d\u0120"+ + "\u0001\u0000\u0000\u0000\u049e\u049f\u0005]\u0000\u0000\u049f\u0122\u0001"+ + "\u0000\u0000\u0000\u04a0\u04a1\u0005(\u0000\u0000\u04a1\u0124\u0001\u0000"+ + "\u0000\u0000\u04a2\u04a3\u0005)\u0000\u0000\u04a3\u0126\u0001\u0000\u0000"+ + "\u0000<\u0000\u0268\u026f\u0271\u0275\u027a\u028b\u0290\u0295\u02a0\u02a4"+ + "\u02a6\u02b4\u02bf\u02ca\u02cc\u02dc\u02df\u02e9\u02ed\u02ef\u02fa\u0300"+ + "\u0308\u0314\u031d\u0327\u0329\u0339\u033d\u0345\u034f\u0351\u0362\u036b"+ + "\u0376\u0379\u037c\u037f\u0382\u0390\u0393\u0398\u039a\u03a3\u03a9\u03ab"+ + "\u03b4\u03ba\u03bc\u03c5\u03cc\u03d7\u03da\u03dd\u03df\u0409\u0411\u0415"+ + "\u041a\u0001\u0000\u0001\u0000"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} +// CPD-ON: End suppressing CPD checks for generated code +// CHECKSTYLE:ON diff --git a/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/ast/RustLexerBase.java b/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/ast/RustLexerBase.java new file mode 100644 index 00000000000..9103fdb7eee --- /dev/null +++ b/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/ast/RustLexerBase.java @@ -0,0 +1,84 @@ +// CHECKSTYLE:OFF +package net.sourceforge.pmd.lang.rust.ast; + +import org.antlr.v4.runtime.*; + +public abstract class RustLexerBase extends Lexer{ + public RustLexerBase(CharStream input){ + super(input); + } + + Token current; + Token previous; + + @Override + public Token nextToken() { + Token next = super.nextToken(); + + if (next.getChannel() == Token.DEFAULT_CHANNEL) { + // Keep track of the last token on the default channel. + this.previous = this.current; + this.current = next; + } + + return next; + } + + public boolean SOF(){ + return _input.LA(-1) <=0; + } + + public boolean next(char expect){ + return _input.LA(1) == expect; + } + + public boolean floatDotPossible(){ + int next = _input.LA(1); + // only block . _ identifier after float + if(next == '.' || next =='_') { return false; } + if(next == 'f') { + return _input.LA(2)=='3'&&_input.LA(3)=='2' || _input.LA(2)=='6'&&_input.LA(3)=='4'; + } + if(next>='a'&&next<='z') { return false; } + return next>='A'&&next<='Z'; + } + + public boolean floatLiteralPossible(){ + if(this.current == null || this.previous == null) { return true; } + if(this.current.getType() != RustLexer.DOT) { return true; } + switch (this.previous.getType()){ + case RustLexer.CHAR_LITERAL: + case RustLexer.STRING_LITERAL: + case RustLexer.RAW_STRING_LITERAL: + case RustLexer.BYTE_LITERAL: + case RustLexer.BYTE_STRING_LITERAL: + case RustLexer.RAW_BYTE_STRING_LITERAL: + case RustLexer.INTEGER_LITERAL: + case RustLexer.DEC_LITERAL: + case RustLexer.HEX_LITERAL: + case RustLexer.OCT_LITERAL: + case RustLexer.BIN_LITERAL: + + case RustLexer.KW_SUPER: + case RustLexer.KW_SELFVALUE: + case RustLexer.KW_SELFTYPE: + case RustLexer.KW_CRATE: + case RustLexer.KW_DOLLARCRATE: + + case RustLexer.GT: + case RustLexer.RCURLYBRACE: + case RustLexer.RSQUAREBRACKET: + case RustLexer.RPAREN: + + case RustLexer.KW_AWAIT: + + case RustLexer.NON_KEYWORD_IDENTIFIER: + case RustLexer.RAW_IDENTIFIER: + case RustLexer.KW_MACRORULES: + return false; + default: + return true; + } + } +} +// CHECKSTYLE:ON diff --git a/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/cpd/RustCpdLexer.java b/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/cpd/RustCpdLexer.java index f0cea61b151..513d2f1713a 100644 --- a/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/cpd/RustCpdLexer.java +++ b/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/cpd/RustCpdLexer.java @@ -14,6 +14,6 @@ public class RustCpdLexer extends AntlrCpdLexer { @Override protected Lexer getLexerForSource(CharStream charStream) { - return new RustCpdLexer(charStream); + return new RustLexer(charStream); } } diff --git a/pmd-rust/src/test/java/net/sourceforge/pmd/lang/rust/cpd/RustCpdLexerTest.java b/pmd-rust/src/test/java/net/sourceforge/pmd/lang/rust/cpd/RustCpdLexerTest.java index f9763ff741f..85de0e076e5 100644 --- a/pmd-rust/src/test/java/net/sourceforge/pmd/lang/rust/cpd/RustCpdLexerTest.java +++ b/pmd-rust/src/test/java/net/sourceforge/pmd/lang/rust/cpd/RustCpdLexerTest.java @@ -8,15 +8,15 @@ import net.sourceforge.pmd.lang.test.cpd.CpdTextComparisonTest; -public class RustCpdLexerTest extends CpdTextComparisonTest { +class RustCpdLexerTest extends CpdTextComparisonTest { - public RustCpdLexerTest() { + RustCpdLexerTest() { super("rust", ".rs"); } @Test - public void testHelloWorld() { + void testHelloWorld() { doTest("helloworld"); } -} \ No newline at end of file +} diff --git a/pmd-rust/src/test/resources/net/sourceforge/pmd/lang/rust/cpd/testdata/helloworld.txt b/pmd-rust/src/test/resources/net/sourceforge/pmd/lang/rust/cpd/testdata/helloworld.txt new file mode 100644 index 00000000000..8d4cbbfb045 --- /dev/null +++ b/pmd-rust/src/test/resources/net/sourceforge/pmd/lang/rust/cpd/testdata/helloworld.txt @@ -0,0 +1,17 @@ + [Image] or [Truncated image[ Bcol Ecol +L10 + [fn] 1 3 + [main] 4 8 + [(] 8 9 + [)] 9 10 + [{] 11 12 +L14 + [println] 5 12 + [!] 12 13 + [(] 13 14 + ["Hello World!"] 14 28 + [)] 28 29 + [;] 29 30 +L15 + [}] 1 2 +EOF From 0f58dae1f25ae3c6b72f6dc1e070d86599c3e716 Mon Sep 17 00:00:00 2001 From: Julia Paluch Date: Sat, 21 Dec 2024 00:56:45 +0000 Subject: [PATCH 0388/1962] inline custom antlr functions so that lexer class can be generated without issues --- .../sourceforge/pmd/lang/rust/ast/README.md | 5 + .../pmd/lang/rust/ast/RustLexer.g4 | 85 +- .../pmd/lang/rust/ast/RustLexer.java | 1233 ----------------- .../pmd/lang/rust/ast/RustLexerBase.java | 84 -- 4 files changed, 85 insertions(+), 1322 deletions(-) delete mode 100644 pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/ast/RustLexer.java delete mode 100644 pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/ast/RustLexerBase.java diff --git a/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/README.md b/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/README.md index 6928ff1c585..8122ccdc66e 100644 --- a/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/README.md +++ b/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/README.md @@ -24,3 +24,8 @@ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ## Currently used version * Source: + +## Modifications + +The custom functions defined [here](https://github.com/antlr/grammars-v4/blob/master/rust/Java/RustLexerBase.java) +have been inlined in and the dependency on `RustLexerBase` has been removed. diff --git a/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/RustLexer.g4 b/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/RustLexer.g4 index afe41edfe01..c592ddf3df6 100644 --- a/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/RustLexer.g4 +++ b/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/RustLexer.g4 @@ -22,13 +22,88 @@ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR lexer grammar RustLexer; -// Insert here @header for C++ lexer. - -options -{ - superClass = RustLexerBase; +@lexer::members { + Token current; + Token previous; + + @Override + public Token nextToken() { + Token next = super.nextToken(); + + if (next.getChannel() == Token.DEFAULT_CHANNEL) { + // Keep track of the last token on the default channel. + this.previous = this.current; + this.current = next; + } + + return next; + } + + public boolean SOF(){ + return _input.LA(-1) <=0; + } + + public boolean next(char expect){ + return _input.LA(1) == expect; + } + + public boolean floatDotPossible(){ + int next = _input.LA(1); + // only block . _ identifier after float + if(next == '.' || next =='_') return false; + if(next == 'f') { + // 1.f32 + if (_input.LA(2)=='3'&&_input.LA(3)=='2')return true; + //1.f64 + if (_input.LA(2)=='6'&&_input.LA(3)=='4')return true; + return false; + } + if(next>='a'&&next<='z') return false; + if(next>='A'&&next<='Z') return false; + return true; + } + + public boolean floatLiteralPossible(){ + if(this.current == null || this.previous == null) return true; + if(this.current.getType() != RustLexer.DOT) return true; + switch (this.previous.getType()){ + case RustLexer.CHAR_LITERAL: + case RustLexer.STRING_LITERAL: + case RustLexer.RAW_STRING_LITERAL: + case RustLexer.BYTE_LITERAL: + case RustLexer.BYTE_STRING_LITERAL: + case RustLexer.RAW_BYTE_STRING_LITERAL: + case RustLexer.INTEGER_LITERAL: + case RustLexer.DEC_LITERAL: + case RustLexer.HEX_LITERAL: + case RustLexer.OCT_LITERAL: + case RustLexer.BIN_LITERAL: + + case RustLexer.KW_SUPER: + case RustLexer.KW_SELFVALUE: + case RustLexer.KW_SELFTYPE: + case RustLexer.KW_CRATE: + case RustLexer.KW_DOLLARCRATE: + + case RustLexer.GT: + case RustLexer.RCURLYBRACE: + case RustLexer.RSQUAREBRACKET: + case RustLexer.RPAREN: + + case RustLexer.KW_AWAIT: + + case RustLexer.NON_KEYWORD_IDENTIFIER: + case RustLexer.RAW_IDENTIFIER: + case RustLexer.KW_MACRORULES: + return false; + default: + return true; + } + } } + + // https://doc.rust-lang.org/reference/keywords.html strict KW_AS : 'as'; KW_BREAK : 'break'; diff --git a/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/ast/RustLexer.java b/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/ast/RustLexer.java deleted file mode 100644 index bea76462b9d..00000000000 --- a/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/ast/RustLexer.java +++ /dev/null @@ -1,1233 +0,0 @@ -// CHECKSTYLE:OFF Suppressing checkstyle checks for generated code -// Generated from RustLexer.g4 by ANTLR 4.13.2 -// CPD-OFF: Suppressing CPD checks for generated code -package net.sourceforge.pmd.lang.rust.cpd; - -import org.antlr.v4.runtime.Lexer; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.TokenStream; -import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.atn.*; -import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.misc.*; - -import net.sourceforge.pmd.lang.rust.ast.RustLexerBase; - -@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue", "this-escape"}) -public class RustLexer extends RustLexerBase { - static { RuntimeMetaData.checkVersion("4.13.2", RuntimeMetaData.VERSION); } - - protected static final DFA[] _decisionToDFA; - protected static final PredictionContextCache _sharedContextCache = - new PredictionContextCache(); - public static final int - KW_AS=1, KW_BREAK=2, KW_CONST=3, KW_CONTINUE=4, KW_CRATE=5, KW_ELSE=6, - KW_ENUM=7, KW_EXTERN=8, KW_FALSE=9, KW_FN=10, KW_FOR=11, KW_IF=12, KW_IMPL=13, - KW_IN=14, KW_LET=15, KW_LOOP=16, KW_MATCH=17, KW_MOD=18, KW_MOVE=19, KW_MUT=20, - KW_PUB=21, KW_REF=22, KW_RETURN=23, KW_SELFVALUE=24, KW_SELFTYPE=25, KW_STATIC=26, - KW_STRUCT=27, KW_SUPER=28, KW_TRAIT=29, KW_TRUE=30, KW_TYPE=31, KW_UNSAFE=32, - KW_USE=33, KW_WHERE=34, KW_WHILE=35, KW_ASYNC=36, KW_AWAIT=37, KW_DYN=38, - KW_ABSTRACT=39, KW_BECOME=40, KW_BOX=41, KW_DO=42, KW_FINAL=43, KW_MACRO=44, - KW_OVERRIDE=45, KW_PRIV=46, KW_TYPEOF=47, KW_UNSIZED=48, KW_VIRTUAL=49, - KW_YIELD=50, KW_TRY=51, KW_UNION=52, KW_STATICLIFETIME=53, KW_MACRORULES=54, - KW_UNDERLINELIFETIME=55, KW_DOLLARCRATE=56, NON_KEYWORD_IDENTIFIER=57, - RAW_IDENTIFIER=58, LINE_COMMENT=59, BLOCK_COMMENT=60, INNER_LINE_DOC=61, - INNER_BLOCK_DOC=62, OUTER_LINE_DOC=63, OUTER_BLOCK_DOC=64, BLOCK_COMMENT_OR_DOC=65, - SHEBANG=66, WHITESPACE=67, NEWLINE=68, CHAR_LITERAL=69, STRING_LITERAL=70, - RAW_STRING_LITERAL=71, BYTE_LITERAL=72, BYTE_STRING_LITERAL=73, RAW_BYTE_STRING_LITERAL=74, - INTEGER_LITERAL=75, DEC_LITERAL=76, HEX_LITERAL=77, OCT_LITERAL=78, BIN_LITERAL=79, - FLOAT_LITERAL=80, LIFETIME_OR_LABEL=81, PLUS=82, MINUS=83, STAR=84, SLASH=85, - PERCENT=86, CARET=87, NOT=88, AND=89, OR=90, ANDAND=91, OROR=92, PLUSEQ=93, - MINUSEQ=94, STAREQ=95, SLASHEQ=96, PERCENTEQ=97, CARETEQ=98, ANDEQ=99, - OREQ=100, SHLEQ=101, SHREQ=102, EQ=103, EQEQ=104, NE=105, GT=106, LT=107, - GE=108, LE=109, AT=110, UNDERSCORE=111, DOT=112, DOTDOT=113, DOTDOTDOT=114, - DOTDOTEQ=115, COMMA=116, SEMI=117, COLON=118, PATHSEP=119, RARROW=120, - FATARROW=121, POUND=122, DOLLAR=123, QUESTION=124, LCURLYBRACE=125, RCURLYBRACE=126, - LSQUAREBRACKET=127, RSQUAREBRACKET=128, LPAREN=129, RPAREN=130; - public static String[] channelNames = { - "DEFAULT_TOKEN_CHANNEL", "HIDDEN" - }; - - public static String[] modeNames = { - "DEFAULT_MODE" - }; - - private static String[] makeRuleNames() { - return new String[] { - "KW_AS", "KW_BREAK", "KW_CONST", "KW_CONTINUE", "KW_CRATE", "KW_ELSE", - "KW_ENUM", "KW_EXTERN", "KW_FALSE", "KW_FN", "KW_FOR", "KW_IF", "KW_IMPL", - "KW_IN", "KW_LET", "KW_LOOP", "KW_MATCH", "KW_MOD", "KW_MOVE", "KW_MUT", - "KW_PUB", "KW_REF", "KW_RETURN", "KW_SELFVALUE", "KW_SELFTYPE", "KW_STATIC", - "KW_STRUCT", "KW_SUPER", "KW_TRAIT", "KW_TRUE", "KW_TYPE", "KW_UNSAFE", - "KW_USE", "KW_WHERE", "KW_WHILE", "KW_ASYNC", "KW_AWAIT", "KW_DYN", "KW_ABSTRACT", - "KW_BECOME", "KW_BOX", "KW_DO", "KW_FINAL", "KW_MACRO", "KW_OVERRIDE", - "KW_PRIV", "KW_TYPEOF", "KW_UNSIZED", "KW_VIRTUAL", "KW_YIELD", "KW_TRY", - "KW_UNION", "KW_STATICLIFETIME", "KW_MACRORULES", "KW_UNDERLINELIFETIME", - "KW_DOLLARCRATE", "NON_KEYWORD_IDENTIFIER", "XID_Start", "XID_Continue", - "UNICODE_OIDS", "UNICODE_OIDC", "RAW_IDENTIFIER", "LINE_COMMENT", "BLOCK_COMMENT", - "INNER_LINE_DOC", "INNER_BLOCK_DOC", "OUTER_LINE_DOC", "OUTER_BLOCK_DOC", - "BLOCK_COMMENT_OR_DOC", "SHEBANG", "WHITESPACE", "NEWLINE", "CHAR_LITERAL", - "STRING_LITERAL", "RAW_STRING_LITERAL", "RAW_STRING_CONTENT", "BYTE_LITERAL", - "BYTE_STRING_LITERAL", "RAW_BYTE_STRING_LITERAL", "ASCII_ESCAPE", "BYTE_ESCAPE", - "COMMON_ESCAPE", "UNICODE_ESCAPE", "QUOTE_ESCAPE", "ESC_NEWLINE", "INTEGER_LITERAL", - "DEC_LITERAL", "HEX_LITERAL", "OCT_LITERAL", "BIN_LITERAL", "FLOAT_LITERAL", - "INTEGER_SUFFIX", "FLOAT_SUFFIX", "FLOAT_EXPONENT", "OCT_DIGIT", "DEC_DIGIT", - "HEX_DIGIT", "LIFETIME_OR_LABEL", "PLUS", "MINUS", "STAR", "SLASH", "PERCENT", - "CARET", "NOT", "AND", "OR", "ANDAND", "OROR", "PLUSEQ", "MINUSEQ", "STAREQ", - "SLASHEQ", "PERCENTEQ", "CARETEQ", "ANDEQ", "OREQ", "SHLEQ", "SHREQ", - "EQ", "EQEQ", "NE", "GT", "LT", "GE", "LE", "AT", "UNDERSCORE", "DOT", - "DOTDOT", "DOTDOTDOT", "DOTDOTEQ", "COMMA", "SEMI", "COLON", "PATHSEP", - "RARROW", "FATARROW", "POUND", "DOLLAR", "QUESTION", "LCURLYBRACE", "RCURLYBRACE", - "LSQUAREBRACKET", "RSQUAREBRACKET", "LPAREN", "RPAREN" - }; - } - public static final String[] ruleNames = makeRuleNames(); - - private static String[] makeLiteralNames() { - return new String[] { - null, "'as'", "'break'", "'const'", "'continue'", "'crate'", "'else'", - "'enum'", "'extern'", "'false'", "'fn'", "'for'", "'if'", "'impl'", "'in'", - "'let'", "'loop'", "'match'", "'mod'", "'move'", "'mut'", "'pub'", "'ref'", - "'return'", "'self'", "'Self'", "'static'", "'struct'", "'super'", "'trait'", - "'true'", "'type'", "'unsafe'", "'use'", "'where'", "'while'", "'async'", - "'await'", "'dyn'", "'abstract'", "'become'", "'box'", "'do'", "'final'", - "'macro'", "'override'", "'priv'", "'typeof'", "'unsized'", "'virtual'", - "'yield'", "'try'", "'union'", "''static'", "'macro_rules'", "''_'", - "'$crate'", null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, "'+'", "'-'", "'*'", "'/'", "'%'", "'^'", "'!'", "'&'", - "'|'", "'&&'", "'||'", "'+='", "'-='", "'*='", "'/='", "'%='", "'^='", - "'&='", "'|='", "'<<='", "'>>='", "'='", "'=='", "'!='", "'>'", "'<'", - "'>='", "'<='", "'@'", "'_'", "'.'", "'..'", "'...'", "'..='", "','", - "';'", "':'", "'::'", "'->'", "'=>'", "'#'", "'$'", "'?'", "'{'", "'}'", - "'['", "']'", "'('", "')'" - }; - } - private static final String[] _LITERAL_NAMES = makeLiteralNames(); - private static String[] makeSymbolicNames() { - return new String[] { - null, "KW_AS", "KW_BREAK", "KW_CONST", "KW_CONTINUE", "KW_CRATE", "KW_ELSE", - "KW_ENUM", "KW_EXTERN", "KW_FALSE", "KW_FN", "KW_FOR", "KW_IF", "KW_IMPL", - "KW_IN", "KW_LET", "KW_LOOP", "KW_MATCH", "KW_MOD", "KW_MOVE", "KW_MUT", - "KW_PUB", "KW_REF", "KW_RETURN", "KW_SELFVALUE", "KW_SELFTYPE", "KW_STATIC", - "KW_STRUCT", "KW_SUPER", "KW_TRAIT", "KW_TRUE", "KW_TYPE", "KW_UNSAFE", - "KW_USE", "KW_WHERE", "KW_WHILE", "KW_ASYNC", "KW_AWAIT", "KW_DYN", "KW_ABSTRACT", - "KW_BECOME", "KW_BOX", "KW_DO", "KW_FINAL", "KW_MACRO", "KW_OVERRIDE", - "KW_PRIV", "KW_TYPEOF", "KW_UNSIZED", "KW_VIRTUAL", "KW_YIELD", "KW_TRY", - "KW_UNION", "KW_STATICLIFETIME", "KW_MACRORULES", "KW_UNDERLINELIFETIME", - "KW_DOLLARCRATE", "NON_KEYWORD_IDENTIFIER", "RAW_IDENTIFIER", "LINE_COMMENT", - "BLOCK_COMMENT", "INNER_LINE_DOC", "INNER_BLOCK_DOC", "OUTER_LINE_DOC", - "OUTER_BLOCK_DOC", "BLOCK_COMMENT_OR_DOC", "SHEBANG", "WHITESPACE", "NEWLINE", - "CHAR_LITERAL", "STRING_LITERAL", "RAW_STRING_LITERAL", "BYTE_LITERAL", - "BYTE_STRING_LITERAL", "RAW_BYTE_STRING_LITERAL", "INTEGER_LITERAL", - "DEC_LITERAL", "HEX_LITERAL", "OCT_LITERAL", "BIN_LITERAL", "FLOAT_LITERAL", - "LIFETIME_OR_LABEL", "PLUS", "MINUS", "STAR", "SLASH", "PERCENT", "CARET", - "NOT", "AND", "OR", "ANDAND", "OROR", "PLUSEQ", "MINUSEQ", "STAREQ", - "SLASHEQ", "PERCENTEQ", "CARETEQ", "ANDEQ", "OREQ", "SHLEQ", "SHREQ", - "EQ", "EQEQ", "NE", "GT", "LT", "GE", "LE", "AT", "UNDERSCORE", "DOT", - "DOTDOT", "DOTDOTDOT", "DOTDOTEQ", "COMMA", "SEMI", "COLON", "PATHSEP", - "RARROW", "FATARROW", "POUND", "DOLLAR", "QUESTION", "LCURLYBRACE", "RCURLYBRACE", - "LSQUAREBRACKET", "RSQUAREBRACKET", "LPAREN", "RPAREN" - }; - } - private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); - public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); - - /** - * @deprecated Use {@link #VOCABULARY} instead. - */ - @Deprecated - public static final String[] tokenNames; - static { - tokenNames = new String[_SYMBOLIC_NAMES.length]; - for (int i = 0; i < tokenNames.length; i++) { - tokenNames[i] = VOCABULARY.getLiteralName(i); - if (tokenNames[i] == null) { - tokenNames[i] = VOCABULARY.getSymbolicName(i); - } - - if (tokenNames[i] == null) { - tokenNames[i] = ""; - } - } - } - - @Override - @Deprecated - public String[] getTokenNames() { - return tokenNames; - } - - @Override - - public Vocabulary getVocabulary() { - return VOCABULARY; - } - - - public RustLexer(CharStream input) { - super(input); - _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); - } - - @Override - public String getGrammarFileName() { return "RustLexer.g4"; } - - @Override - public String[] getRuleNames() { return ruleNames; } - - @Override - public String getSerializedATN() { return _serializedATN; } - - @Override - public String[] getChannelNames() { return channelNames; } - - @Override - public String[] getModeNames() { return modeNames; } - - @Override - public ATN getATN() { return _ATN; } - - @Override - public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { - switch (ruleIndex) { - case 69: - return SHEBANG_sempred((RuleContext)_localctx, predIndex); - case 90: - return FLOAT_LITERAL_sempred((RuleContext)_localctx, predIndex); - } - return true; - } - private boolean SHEBANG_sempred(RuleContext _localctx, int predIndex) { - switch (predIndex) { - case 0: - return this.SOF(); - } - return true; - } - private boolean FLOAT_LITERAL_sempred(RuleContext _localctx, int predIndex) { - switch (predIndex) { - case 1: - return this.floatLiteralPossible(); - case 2: - return this.floatDotPossible(); - } - return true; - } - - public static final String _serializedATN = - "\u0004\u0000\u0082\u04a4\u0006\uffff\uffff\u0002\u0000\u0007\u0000\u0002"+ - "\u0001\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002"+ - "\u0004\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002"+ - "\u0007\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002"+ - "\u000b\u0007\u000b\u0002\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e"+ - "\u0002\u000f\u0007\u000f\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011"+ - "\u0002\u0012\u0007\u0012\u0002\u0013\u0007\u0013\u0002\u0014\u0007\u0014"+ - "\u0002\u0015\u0007\u0015\u0002\u0016\u0007\u0016\u0002\u0017\u0007\u0017"+ - "\u0002\u0018\u0007\u0018\u0002\u0019\u0007\u0019\u0002\u001a\u0007\u001a"+ - "\u0002\u001b\u0007\u001b\u0002\u001c\u0007\u001c\u0002\u001d\u0007\u001d"+ - "\u0002\u001e\u0007\u001e\u0002\u001f\u0007\u001f\u0002 \u0007 \u0002!"+ - "\u0007!\u0002\"\u0007\"\u0002#\u0007#\u0002$\u0007$\u0002%\u0007%\u0002"+ - "&\u0007&\u0002\'\u0007\'\u0002(\u0007(\u0002)\u0007)\u0002*\u0007*\u0002"+ - "+\u0007+\u0002,\u0007,\u0002-\u0007-\u0002.\u0007.\u0002/\u0007/\u0002"+ - "0\u00070\u00021\u00071\u00022\u00072\u00023\u00073\u00024\u00074\u0002"+ - "5\u00075\u00026\u00076\u00027\u00077\u00028\u00078\u00029\u00079\u0002"+ - ":\u0007:\u0002;\u0007;\u0002<\u0007<\u0002=\u0007=\u0002>\u0007>\u0002"+ - "?\u0007?\u0002@\u0007@\u0002A\u0007A\u0002B\u0007B\u0002C\u0007C\u0002"+ - "D\u0007D\u0002E\u0007E\u0002F\u0007F\u0002G\u0007G\u0002H\u0007H\u0002"+ - "I\u0007I\u0002J\u0007J\u0002K\u0007K\u0002L\u0007L\u0002M\u0007M\u0002"+ - "N\u0007N\u0002O\u0007O\u0002P\u0007P\u0002Q\u0007Q\u0002R\u0007R\u0002"+ - "S\u0007S\u0002T\u0007T\u0002U\u0007U\u0002V\u0007V\u0002W\u0007W\u0002"+ - "X\u0007X\u0002Y\u0007Y\u0002Z\u0007Z\u0002[\u0007[\u0002\\\u0007\\\u0002"+ - "]\u0007]\u0002^\u0007^\u0002_\u0007_\u0002`\u0007`\u0002a\u0007a\u0002"+ - "b\u0007b\u0002c\u0007c\u0002d\u0007d\u0002e\u0007e\u0002f\u0007f\u0002"+ - "g\u0007g\u0002h\u0007h\u0002i\u0007i\u0002j\u0007j\u0002k\u0007k\u0002"+ - "l\u0007l\u0002m\u0007m\u0002n\u0007n\u0002o\u0007o\u0002p\u0007p\u0002"+ - "q\u0007q\u0002r\u0007r\u0002s\u0007s\u0002t\u0007t\u0002u\u0007u\u0002"+ - "v\u0007v\u0002w\u0007w\u0002x\u0007x\u0002y\u0007y\u0002z\u0007z\u0002"+ - "{\u0007{\u0002|\u0007|\u0002}\u0007}\u0002~\u0007~\u0002\u007f\u0007\u007f"+ - "\u0002\u0080\u0007\u0080\u0002\u0081\u0007\u0081\u0002\u0082\u0007\u0082"+ - "\u0002\u0083\u0007\u0083\u0002\u0084\u0007\u0084\u0002\u0085\u0007\u0085"+ - "\u0002\u0086\u0007\u0086\u0002\u0087\u0007\u0087\u0002\u0088\u0007\u0088"+ - "\u0002\u0089\u0007\u0089\u0002\u008a\u0007\u008a\u0002\u008b\u0007\u008b"+ - "\u0002\u008c\u0007\u008c\u0002\u008d\u0007\u008d\u0002\u008e\u0007\u008e"+ - "\u0002\u008f\u0007\u008f\u0002\u0090\u0007\u0090\u0002\u0091\u0007\u0091"+ - "\u0002\u0092\u0007\u0092\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0001"+ - "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002"+ - "\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0003"+ - "\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003"+ - "\u0001\u0003\u0001\u0003\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004"+ - "\u0001\u0004\u0001\u0004\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005"+ - "\u0001\u0005\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001\u0006"+ - "\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007\u0001\u0007"+ - "\u0001\u0007\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0001\t\u0001"+ - "\t\u0001\t\u0001\n\u0001\n\u0001\n\u0001\n\u0001\u000b\u0001\u000b\u0001"+ - "\u000b\u0001\f\u0001\f\u0001\f\u0001\f\u0001\f\u0001\r\u0001\r\u0001\r"+ - "\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000f\u0001\u000f"+ - "\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u0010\u0001\u0010\u0001\u0010"+ - "\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0011\u0001\u0011\u0001\u0011"+ - "\u0001\u0011\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012"+ - "\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0014\u0001\u0014"+ - "\u0001\u0014\u0001\u0014\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0015"+ - "\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016"+ - "\u0001\u0016\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017"+ - "\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0019"+ - "\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u0019"+ - "\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001a\u0001\u001a"+ - "\u0001\u001a\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b\u0001\u001b"+ - "\u0001\u001b\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001c\u0001\u001c"+ - "\u0001\u001c\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d\u0001\u001d"+ - "\u0001\u001e\u0001\u001e\u0001\u001e\u0001\u001e\u0001\u001e\u0001\u001f"+ - "\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f"+ - "\u0001 \u0001 \u0001 \u0001 \u0001!\u0001!\u0001!\u0001!\u0001!\u0001"+ - "!\u0001\"\u0001\"\u0001\"\u0001\"\u0001\"\u0001\"\u0001#\u0001#\u0001"+ - "#\u0001#\u0001#\u0001#\u0001$\u0001$\u0001$\u0001$\u0001$\u0001$\u0001"+ - "%\u0001%\u0001%\u0001%\u0001&\u0001&\u0001&\u0001&\u0001&\u0001&\u0001"+ - "&\u0001&\u0001&\u0001\'\u0001\'\u0001\'\u0001\'\u0001\'\u0001\'\u0001"+ - "\'\u0001(\u0001(\u0001(\u0001(\u0001)\u0001)\u0001)\u0001*\u0001*\u0001"+ - "*\u0001*\u0001*\u0001*\u0001+\u0001+\u0001+\u0001+\u0001+\u0001+\u0001"+ - ",\u0001,\u0001,\u0001,\u0001,\u0001,\u0001,\u0001,\u0001,\u0001-\u0001"+ - "-\u0001-\u0001-\u0001-\u0001.\u0001.\u0001.\u0001.\u0001.\u0001.\u0001"+ - ".\u0001/\u0001/\u0001/\u0001/\u0001/\u0001/\u0001/\u0001/\u00010\u0001"+ - "0\u00010\u00010\u00010\u00010\u00010\u00010\u00011\u00011\u00011\u0001"+ - "1\u00011\u00011\u00012\u00012\u00012\u00012\u00013\u00013\u00013\u0001"+ - "3\u00013\u00013\u00014\u00014\u00014\u00014\u00014\u00014\u00014\u0001"+ - "4\u00015\u00015\u00015\u00015\u00015\u00015\u00015\u00015\u00015\u0001"+ - "5\u00015\u00015\u00016\u00016\u00016\u00017\u00017\u00017\u00017\u0001"+ - "7\u00017\u00017\u00018\u00018\u00058\u0267\b8\n8\f8\u026a\t8\u00018\u0001"+ - "8\u00048\u026e\b8\u000b8\f8\u026f\u00038\u0272\b8\u00019\u00019\u0003"+ - "9\u0276\b9\u0001:\u0001:\u0001:\u0003:\u027b\b:\u0001;\u0001;\u0001<\u0001"+ - "<\u0001=\u0001=\u0001=\u0001=\u0001=\u0001>\u0001>\u0001>\u0001>\u0001"+ - ">\u0001>\u0003>\u028c\b>\u0001>\u0005>\u028f\b>\n>\f>\u0292\t>\u0001>"+ - "\u0001>\u0003>\u0296\b>\u0001>\u0001>\u0001?\u0001?\u0001?\u0001?\u0001"+ - "?\u0001?\u0001?\u0003?\u02a1\b?\u0001?\u0001?\u0005?\u02a5\b?\n?\f?\u02a8"+ - "\t?\u0001?\u0001?\u0001?\u0001?\u0001?\u0001?\u0001?\u0001?\u0001?\u0001"+ - "?\u0001?\u0003?\u02b5\b?\u0001?\u0001?\u0001@\u0001@\u0001@\u0001@\u0001"+ - "@\u0005@\u02be\b@\n@\f@\u02c1\t@\u0001@\u0001@\u0001A\u0001A\u0001A\u0001"+ - "A\u0001A\u0001A\u0005A\u02cb\bA\nA\fA\u02ce\tA\u0001A\u0001A\u0001A\u0001"+ - "A\u0001A\u0001B\u0001B\u0001B\u0001B\u0001B\u0001B\u0005B\u02db\bB\nB"+ - "\fB\u02de\tB\u0003B\u02e0\bB\u0001B\u0001B\u0001C\u0001C\u0001C\u0001"+ - "C\u0001C\u0001C\u0003C\u02ea\bC\u0001C\u0001C\u0005C\u02ee\bC\nC\fC\u02f1"+ - "\tC\u0001C\u0001C\u0001C\u0001C\u0001C\u0001D\u0001D\u0001D\u0003D\u02fb"+ - "\bD\u0001D\u0001D\u0001E\u0001E\u0003E\u0301\bE\u0001E\u0001E\u0001E\u0001"+ - "E\u0005E\u0307\bE\nE\fE\u030a\tE\u0001E\u0001E\u0001F\u0001F\u0001F\u0001"+ - "F\u0001G\u0001G\u0001G\u0003G\u0315\bG\u0001G\u0001G\u0001H\u0001H\u0001"+ - "H\u0001H\u0001H\u0003H\u031e\bH\u0001H\u0001H\u0001I\u0001I\u0001I\u0001"+ - "I\u0001I\u0001I\u0005I\u0328\bI\nI\fI\u032b\tI\u0001I\u0001I\u0001J\u0001"+ - "J\u0001J\u0001K\u0001K\u0001K\u0001K\u0001K\u0001K\u0005K\u0338\bK\nK"+ - "\fK\u033b\tK\u0001K\u0003K\u033e\bK\u0001L\u0001L\u0001L\u0001L\u0001"+ - "L\u0001L\u0003L\u0346\bL\u0001L\u0001L\u0001M\u0001M\u0001M\u0001M\u0001"+ - "M\u0001M\u0005M\u0350\bM\nM\fM\u0353\tM\u0001M\u0001M\u0001N\u0001N\u0001"+ - "N\u0001N\u0001N\u0001O\u0001O\u0001O\u0001O\u0001O\u0001O\u0001O\u0003"+ - "O\u0363\bO\u0001P\u0001P\u0001P\u0001P\u0001P\u0001P\u0001P\u0003P\u036c"+ - "\bP\u0001Q\u0001Q\u0001Q\u0001R\u0001R\u0001R\u0001R\u0001R\u0001R\u0003"+ - "R\u0377\bR\u0001R\u0003R\u037a\bR\u0001R\u0003R\u037d\bR\u0001R\u0003"+ - "R\u0380\bR\u0001R\u0003R\u0383\bR\u0001R\u0001R\u0001S\u0001S\u0001S\u0001"+ - "T\u0001T\u0001T\u0001U\u0001U\u0001U\u0001U\u0003U\u0391\bU\u0001U\u0003"+ - "U\u0394\bU\u0001V\u0001V\u0001V\u0005V\u0399\bV\nV\fV\u039c\tV\u0001W"+ - "\u0001W\u0001W\u0001W\u0005W\u03a2\bW\nW\fW\u03a5\tW\u0001W\u0001W\u0001"+ - "W\u0005W\u03aa\bW\nW\fW\u03ad\tW\u0001X\u0001X\u0001X\u0001X\u0005X\u03b3"+ - "\bX\nX\fX\u03b6\tX\u0001X\u0001X\u0001X\u0005X\u03bb\bX\nX\fX\u03be\t"+ - "X\u0001Y\u0001Y\u0001Y\u0001Y\u0005Y\u03c4\bY\nY\fY\u03c7\tY\u0001Y\u0001"+ - "Y\u0005Y\u03cb\bY\nY\fY\u03ce\tY\u0001Z\u0001Z\u0001Z\u0001Z\u0001Z\u0001"+ - "Z\u0001Z\u0001Z\u0003Z\u03d8\bZ\u0001Z\u0003Z\u03db\bZ\u0001Z\u0003Z\u03de"+ - "\bZ\u0003Z\u03e0\bZ\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001"+ - "[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001"+ - "[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001"+ - "[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001[\u0001"+ - "[\u0001[\u0001[\u0003[\u040a\b[\u0001\\\u0001\\\u0001\\\u0001\\\u0001"+ - "\\\u0001\\\u0003\\\u0412\b\\\u0001]\u0001]\u0003]\u0416\b]\u0001]\u0005"+ - "]\u0419\b]\n]\f]\u041c\t]\u0001]\u0001]\u0001^\u0001^\u0001_\u0001_\u0001"+ - "`\u0001`\u0001a\u0001a\u0001a\u0001b\u0001b\u0001c\u0001c\u0001d\u0001"+ - "d\u0001e\u0001e\u0001f\u0001f\u0001g\u0001g\u0001h\u0001h\u0001i\u0001"+ - "i\u0001j\u0001j\u0001k\u0001k\u0001k\u0001l\u0001l\u0001l\u0001m\u0001"+ - "m\u0001m\u0001n\u0001n\u0001n\u0001o\u0001o\u0001o\u0001p\u0001p\u0001"+ - "p\u0001q\u0001q\u0001q\u0001r\u0001r\u0001r\u0001s\u0001s\u0001s\u0001"+ - "t\u0001t\u0001t\u0001u\u0001u\u0001u\u0001u\u0001v\u0001v\u0001v\u0001"+ - "v\u0001w\u0001w\u0001x\u0001x\u0001x\u0001y\u0001y\u0001y\u0001z\u0001"+ - "z\u0001{\u0001{\u0001|\u0001|\u0001|\u0001}\u0001}\u0001}\u0001~\u0001"+ - "~\u0001\u007f\u0001\u007f\u0001\u0080\u0001\u0080\u0001\u0081\u0001\u0081"+ - "\u0001\u0081\u0001\u0082\u0001\u0082\u0001\u0082\u0001\u0082\u0001\u0083"+ - "\u0001\u0083\u0001\u0083\u0001\u0083\u0001\u0084\u0001\u0084\u0001\u0085"+ - "\u0001\u0085\u0001\u0086\u0001\u0086\u0001\u0087\u0001\u0087\u0001\u0087"+ - "\u0001\u0088\u0001\u0088\u0001\u0088\u0001\u0089\u0001\u0089\u0001\u0089"+ - "\u0001\u008a\u0001\u008a\u0001\u008b\u0001\u008b\u0001\u008c\u0001\u008c"+ - "\u0001\u008d\u0001\u008d\u0001\u008e\u0001\u008e\u0001\u008f\u0001\u008f"+ - "\u0001\u0090\u0001\u0090\u0001\u0091\u0001\u0091\u0001\u0092\u0001\u0092"+ - "\u0004\u02a6\u02cc\u02ef\u0339\u0000\u0093\u0001\u0001\u0003\u0002\u0005"+ - "\u0003\u0007\u0004\t\u0005\u000b\u0006\r\u0007\u000f\b\u0011\t\u0013\n"+ - "\u0015\u000b\u0017\f\u0019\r\u001b\u000e\u001d\u000f\u001f\u0010!\u0011"+ - "#\u0012%\u0013\'\u0014)\u0015+\u0016-\u0017/\u00181\u00193\u001a5\u001b"+ - "7\u001c9\u001d;\u001e=\u001f? A!C\"E#G$I%K&M\'O(Q)S*U+W,Y-[.]/_0a1c2e"+ - "3g4i5k6m7o8q9s\u0000u\u0000w\u0000y\u0000{:};\u007f<\u0081=\u0083>\u0085"+ - "?\u0087@\u0089A\u008bB\u008dC\u008fD\u0091E\u0093F\u0095G\u0097\u0000"+ - "\u0099H\u009bI\u009dJ\u009f\u0000\u00a1\u0000\u00a3\u0000\u00a5\u0000"+ - "\u00a7\u0000\u00a9\u0000\u00abK\u00adL\u00afM\u00b1N\u00b3O\u00b5P\u00b7"+ - "\u0000\u00b9\u0000\u00bb\u0000\u00bd\u0000\u00bf\u0000\u00c1\u0000\u00c3"+ - "Q\u00c5R\u00c7S\u00c9T\u00cbU\u00cdV\u00cfW\u00d1X\u00d3Y\u00d5Z\u00d7"+ - "[\u00d9\\\u00db]\u00dd^\u00df_\u00e1`\u00e3a\u00e5b\u00e7c\u00e9d\u00eb"+ - "e\u00edf\u00efg\u00f1h\u00f3i\u00f5j\u00f7k\u00f9l\u00fbm\u00fdn\u00ff"+ - "o\u0101p\u0103q\u0105r\u0107s\u0109t\u010bu\u010dv\u010fw\u0111x\u0113"+ - "y\u0115z\u0117{\u0119|\u011b}\u011d~\u011f\u007f\u0121\u0080\u0123\u0081"+ - "\u0125\u0082\u0001\u0000\u0015\u0296\u0000AZaz\u00aa\u00aa\u00b5\u00b5"+ - "\u00ba\u00ba\u00c0\u00d6\u00d8\u00f6\u00f8\u02c1\u02c6\u02d1\u02e0\u02e4"+ - "\u02ec\u02ec\u02ee\u02ee\u0370\u0374\u0376\u0377\u037a\u037d\u037f\u037f"+ - "\u0386\u0386\u0388\u038a\u038c\u038c\u038e\u03a1\u03a3\u03f5\u03f7\u0481"+ - "\u048a\u052f\u0531\u0556\u0559\u0559\u0560\u0588\u05d0\u05ea\u05ef\u05f2"+ - "\u0620\u064a\u066e\u066f\u0671\u06d3\u06d5\u06d5\u06e5\u06e6\u06ee\u06ef"+ - "\u06fa\u06fc\u06ff\u06ff\u0710\u0710\u0712\u072f\u074d\u07a5\u07b1\u07b1"+ - "\u07ca\u07ea\u07f4\u07f5\u07fa\u07fa\u0800\u0815\u081a\u081a\u0824\u0824"+ - "\u0828\u0828\u0840\u0858\u0860\u086a\u0870\u0887\u0889\u088e\u08a0\u08c9"+ - "\u0904\u0939\u093d\u093d\u0950\u0950\u0958\u0961\u0971\u0980\u0985\u098c"+ - "\u098f\u0990\u0993\u09a8\u09aa\u09b0\u09b2\u09b2\u09b6\u09b9\u09bd\u09bd"+ - "\u09ce\u09ce\u09dc\u09dd\u09df\u09e1\u09f0\u09f1\u09fc\u09fc\u0a05\u0a0a"+ - "\u0a0f\u0a10\u0a13\u0a28\u0a2a\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39"+ - "\u0a59\u0a5c\u0a5e\u0a5e\u0a72\u0a74\u0a85\u0a8d\u0a8f\u0a91\u0a93\u0aa8"+ - "\u0aaa\u0ab0\u0ab2\u0ab3\u0ab5\u0ab9\u0abd\u0abd\u0ad0\u0ad0\u0ae0\u0ae1"+ - "\u0af9\u0af9\u0b05\u0b0c\u0b0f\u0b10\u0b13\u0b28\u0b2a\u0b30\u0b32\u0b33"+ - "\u0b35\u0b39\u0b3d\u0b3d\u0b5c\u0b5d\u0b5f\u0b61\u0b71\u0b71\u0b83\u0b83"+ - "\u0b85\u0b8a\u0b8e\u0b90\u0b92\u0b95\u0b99\u0b9a\u0b9c\u0b9c\u0b9e\u0b9f"+ - "\u0ba3\u0ba4\u0ba8\u0baa\u0bae\u0bb9\u0bd0\u0bd0\u0c05\u0c0c\u0c0e\u0c10"+ - "\u0c12\u0c28\u0c2a\u0c39\u0c3d\u0c3d\u0c58\u0c5a\u0c5d\u0c5d\u0c60\u0c61"+ - "\u0c80\u0c80\u0c85\u0c8c\u0c8e\u0c90\u0c92\u0ca8\u0caa\u0cb3\u0cb5\u0cb9"+ - "\u0cbd\u0cbd\u0cdd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04\u0d0c\u0d0e\u0d10"+ - "\u0d12\u0d3a\u0d3d\u0d3d\u0d4e\u0d4e\u0d54\u0d56\u0d5f\u0d61\u0d7a\u0d7f"+ - "\u0d85\u0d96\u0d9a\u0db1\u0db3\u0dbb\u0dbd\u0dbd\u0dc0\u0dc6\u0e01\u0e30"+ - "\u0e32\u0e33\u0e40\u0e46\u0e81\u0e82\u0e84\u0e84\u0e86\u0e8a\u0e8c\u0ea3"+ - "\u0ea5\u0ea5\u0ea7\u0eb0\u0eb2\u0eb3\u0ebd\u0ebd\u0ec0\u0ec4\u0ec6\u0ec6"+ - "\u0edc\u0edf\u0f00\u0f00\u0f40\u0f47\u0f49\u0f6c\u0f88\u0f8c\u1000\u102a"+ - "\u103f\u103f\u1050\u1055\u105a\u105d\u1061\u1061\u1065\u1066\u106e\u1070"+ - "\u1075\u1081\u108e\u108e\u10a0\u10c5\u10c7\u10c7\u10cd\u10cd\u10d0\u10fa"+ - "\u10fc\u1248\u124a\u124d\u1250\u1256\u1258\u1258\u125a\u125d\u1260\u1288"+ - "\u128a\u128d\u1290\u12b0\u12b2\u12b5\u12b8\u12be\u12c0\u12c0\u12c2\u12c5"+ - "\u12c8\u12d6\u12d8\u1310\u1312\u1315\u1318\u135a\u1380\u138f\u13a0\u13f5"+ - "\u13f8\u13fd\u1401\u166c\u166f\u167f\u1681\u169a\u16a0\u16ea\u16ee\u16f8"+ - "\u1700\u1711\u171f\u1731\u1740\u1751\u1760\u176c\u176e\u1770\u1780\u17b3"+ - "\u17d7\u17d7\u17dc\u17dc\u1820\u1878\u1880\u1884\u1887\u18a8\u18aa\u18aa"+ - "\u18b0\u18f5\u1900\u191e\u1950\u196d\u1970\u1974\u1980\u19ab\u19b0\u19c9"+ - "\u1a00\u1a16\u1a20\u1a54\u1aa7\u1aa7\u1b05\u1b33\u1b45\u1b4c\u1b83\u1ba0"+ - "\u1bae\u1baf\u1bba\u1be5\u1c00\u1c23\u1c4d\u1c4f\u1c5a\u1c7d\u1c80\u1c88"+ - "\u1c90\u1cba\u1cbd\u1cbf\u1ce9\u1cec\u1cee\u1cf3\u1cf5\u1cf6\u1cfa\u1cfa"+ - "\u1d00\u1dbf\u1e00\u1f15\u1f18\u1f1d\u1f20\u1f45\u1f48\u1f4d\u1f50\u1f57"+ - "\u1f59\u1f59\u1f5b\u1f5b\u1f5d\u1f5d\u1f5f\u1f7d\u1f80\u1fb4\u1fb6\u1fbc"+ - "\u1fbe\u1fbe\u1fc2\u1fc4\u1fc6\u1fcc\u1fd0\u1fd3\u1fd6\u1fdb\u1fe0\u1fec"+ - "\u1ff2\u1ff4\u1ff6\u1ffc\u2071\u2071\u207f\u207f\u2090\u209c\u2102\u2102"+ - "\u2107\u2107\u210a\u2113\u2115\u2115\u2119\u211d\u2124\u2124\u2126\u2126"+ - "\u2128\u2128\u212a\u212d\u212f\u2139\u213c\u213f\u2145\u2149\u214e\u214e"+ - "\u2160\u2188\u2c00\u2ce4\u2ceb\u2cee\u2cf2\u2cf3\u2d00\u2d25\u2d27\u2d27"+ - "\u2d2d\u2d2d\u2d30\u2d67\u2d6f\u2d6f\u2d80\u2d96\u2da0\u2da6\u2da8\u2dae"+ - "\u2db0\u2db6\u2db8\u2dbe\u2dc0\u2dc6\u2dc8\u2dce\u2dd0\u2dd6\u2dd8\u2dde"+ - "\u2e2f\u2e2f\u3005\u3007\u3021\u3029\u3031\u3035\u3038\u303c\u3041\u3096"+ - "\u309d\u309f\u30a1\u30fa\u30fc\u30ff\u3105\u312f\u3131\u318e\u31a0\u31bf"+ - "\u31f0\u31ff\u3400\u4dbf\u4e00\u8000\ua48c\u8000\ua4d0\u8000\ua4fd\u8000"+ - "\ua500\u8000\ua60c\u8000\ua610\u8000\ua61f\u8000\ua62a\u8000\ua62b\u8000"+ - "\ua640\u8000\ua66e\u8000\ua67f\u8000\ua69d\u8000\ua6a0\u8000\ua6ef\u8000"+ - "\ua717\u8000\ua71f\u8000\ua722\u8000\ua788\u8000\ua78b\u8000\ua7ca\u8000"+ - "\ua7d0\u8000\ua7d1\u8000\ua7d3\u8000\ua7d3\u8000\ua7d5\u8000\ua7d9\u8000"+ - "\ua7f2\u8000\ua801\u8000\ua803\u8000\ua805\u8000\ua807\u8000\ua80a\u8000"+ - "\ua80c\u8000\ua822\u8000\ua840\u8000\ua873\u8000\ua882\u8000\ua8b3\u8000"+ - "\ua8f2\u8000\ua8f7\u8000\ua8fb\u8000\ua8fb\u8000\ua8fd\u8000\ua8fe\u8000"+ - "\ua90a\u8000\ua925\u8000\ua930\u8000\ua946\u8000\ua960\u8000\ua97c\u8000"+ - "\ua984\u8000\ua9b2\u8000\ua9cf\u8000\ua9cf\u8000\ua9e0\u8000\ua9e4\u8000"+ - "\ua9e6\u8000\ua9ef\u8000\ua9fa\u8000\ua9fe\u8000\uaa00\u8000\uaa28\u8000"+ - "\uaa40\u8000\uaa42\u8000\uaa44\u8000\uaa4b\u8000\uaa60\u8000\uaa76\u8000"+ - "\uaa7a\u8000\uaa7a\u8000\uaa7e\u8000\uaaaf\u8000\uaab1\u8000\uaab1\u8000"+ - "\uaab5\u8000\uaab6\u8000\uaab9\u8000\uaabd\u8000\uaac0\u8000\uaac0\u8000"+ - "\uaac2\u8000\uaac2\u8000\uaadb\u8000\uaadd\u8000\uaae0\u8000\uaaea\u8000"+ - "\uaaf2\u8000\uaaf4\u8000\uab01\u8000\uab06\u8000\uab09\u8000\uab0e\u8000"+ - "\uab11\u8000\uab16\u8000\uab20\u8000\uab26\u8000\uab28\u8000\uab2e\u8000"+ - "\uab30\u8000\uab5a\u8000\uab5c\u8000\uab69\u8000\uab70\u8000\uabe2\u8000"+ - "\uac00\u8000\ud7a3\u8000\ud7b0\u8000\ud7c6\u8000\ud7cb\u8000\ud7fb\u8000"+ - "\uf900\u8000\ufa6d\u8000\ufa70\u8000\ufad9\u8000\ufb00\u8000\ufb06\u8000"+ - "\ufb13\u8000\ufb17\u8000\ufb1d\u8000\ufb1d\u8000\ufb1f\u8000\ufb28\u8000"+ - "\ufb2a\u8000\ufb36\u8000\ufb38\u8000\ufb3c\u8000\ufb3e\u8000\ufb3e\u8000"+ - "\ufb40\u8000\ufb41\u8000\ufb43\u8000\ufb44\u8000\ufb46\u8000\ufbb1\u8000"+ - "\ufbd3\u8000\ufd3d\u8000\ufd50\u8000\ufd8f\u8000\ufd92\u8000\ufdc7\u8000"+ - "\ufdf0\u8000\ufdfb\u8000\ufe70\u8000\ufe74\u8000\ufe76\u8000\ufefc\u8000"+ - "\uff21\u8000\uff3a\u8000\uff41\u8000\uff5a\u8000\uff66\u8000\uffbe\u8000"+ - "\uffc2\u8000\uffc7\u8000\uffca\u8000\uffcf\u8000\uffd2\u8000\uffd7\u8000"+ - "\uffda\u8000\uffdc\u8001\u0000\u8001\u000b\u8001\r\u8001&\u8001(\u8001"+ - ":\u8001<\u8001=\u8001?\u8001M\u8001P\u8001]\u8001\u0080\u8001\u00fa\u8001"+ - "\u0140\u8001\u0174\u8001\u0280\u8001\u029c\u8001\u02a0\u8001\u02d0\u8001"+ - "\u0300\u8001\u031f\u8001\u032d\u8001\u034a\u8001\u0350\u8001\u0375\u8001"+ - "\u0380\u8001\u039d\u8001\u03a0\u8001\u03c3\u8001\u03c8\u8001\u03cf\u8001"+ - "\u03d1\u8001\u03d5\u8001\u0400\u8001\u049d\u8001\u04b0\u8001\u04d3\u8001"+ - "\u04d8\u8001\u04fb\u8001\u0500\u8001\u0527\u8001\u0530\u8001\u0563\u8001"+ - "\u0570\u8001\u057a\u8001\u057c\u8001\u058a\u8001\u058c\u8001\u0592\u8001"+ - "\u0594\u8001\u0595\u8001\u0597\u8001\u05a1\u8001\u05a3\u8001\u05b1\u8001"+ - "\u05b3\u8001\u05b9\u8001\u05bb\u8001\u05bc\u8001\u0600\u8001\u0736\u8001"+ - "\u0740\u8001\u0755\u8001\u0760\u8001\u0767\u8001\u0780\u8001\u0785\u8001"+ - "\u0787\u8001\u07b0\u8001\u07b2\u8001\u07ba\u8001\u0800\u8001\u0805\u8001"+ - "\u0808\u8001\u0808\u8001\u080a\u8001\u0835\u8001\u0837\u8001\u0838\u8001"+ - "\u083c\u8001\u083c\u8001\u083f\u8001\u0855\u8001\u0860\u8001\u0876\u8001"+ - "\u0880\u8001\u089e\u8001\u08e0\u8001\u08f2\u8001\u08f4\u8001\u08f5\u8001"+ - "\u0900\u8001\u0915\u8001\u0920\u8001\u0939\u8001\u0980\u8001\u09b7\u8001"+ - "\u09be\u8001\u09bf\u8001\u0a00\u8001\u0a00\u8001\u0a10\u8001\u0a13\u8001"+ - "\u0a15\u8001\u0a17\u8001\u0a19\u8001\u0a35\u8001\u0a60\u8001\u0a7c\u8001"+ - "\u0a80\u8001\u0a9c\u8001\u0ac0\u8001\u0ac7\u8001\u0ac9\u8001\u0ae4\u8001"+ - "\u0b00\u8001\u0b35\u8001\u0b40\u8001\u0b55\u8001\u0b60\u8001\u0b72\u8001"+ - "\u0b80\u8001\u0b91\u8001\u0c00\u8001\u0c48\u8001\u0c80\u8001\u0cb2\u8001"+ - "\u0cc0\u8001\u0cf2\u8001\u0d00\u8001\u0d23\u8001\u0e80\u8001\u0ea9\u8001"+ - "\u0eb0\u8001\u0eb1\u8001\u0f00\u8001\u0f1c\u8001\u0f27\u8001\u0f27\u8001"+ - "\u0f30\u8001\u0f45\u8001\u0f70\u8001\u0f81\u8001\u0fb0\u8001\u0fc4\u8001"+ - "\u0fe0\u8001\u0ff6\u8001\u1003\u8001\u1037\u8001\u1071\u8001\u1072\u8001"+ - "\u1075\u8001\u1075\u8001\u1083\u8001\u10af\u8001\u10d0\u8001\u10e8\u8001"+ - "\u1103\u8001\u1126\u8001\u1144\u8001\u1144\u8001\u1147\u8001\u1147\u8001"+ - "\u1150\u8001\u1172\u8001\u1176\u8001\u1176\u8001\u1183\u8001\u11b2\u8001"+ - "\u11c1\u8001\u11c4\u8001\u11da\u8001\u11da\u8001\u11dc\u8001\u11dc\u8001"+ - "\u1200\u8001\u1211\u8001\u1213\u8001\u122b\u8001\u123f\u8001\u1240\u8001"+ - "\u1280\u8001\u1286\u8001\u1288\u8001\u1288\u8001\u128a\u8001\u128d\u8001"+ - "\u128f\u8001\u129d\u8001\u129f\u8001\u12a8\u8001\u12b0\u8001\u12de\u8001"+ - "\u1305\u8001\u130c\u8001\u130f\u8001\u1310\u8001\u1313\u8001\u1328\u8001"+ - "\u132a\u8001\u1330\u8001\u1332\u8001\u1333\u8001\u1335\u8001\u1339\u8001"+ - "\u133d\u8001\u133d\u8001\u1350\u8001\u1350\u8001\u135d\u8001\u1361\u8001"+ - "\u1400\u8001\u1434\u8001\u1447\u8001\u144a\u8001\u145f\u8001\u1461\u8001"+ - "\u1480\u8001\u14af\u8001\u14c4\u8001\u14c5\u8001\u14c7\u8001\u14c7\u8001"+ - "\u1580\u8001\u15ae\u8001\u15d8\u8001\u15db\u8001\u1600\u8001\u162f\u8001"+ - "\u1644\u8001\u1644\u8001\u1680\u8001\u16aa\u8001\u16b8\u8001\u16b8\u8001"+ - "\u1700\u8001\u171a\u8001\u1740\u8001\u1746\u8001\u1800\u8001\u182b\u8001"+ - "\u18a0\u8001\u18df\u8001\u18ff\u8001\u1906\u8001\u1909\u8001\u1909\u8001"+ - "\u190c\u8001\u1913\u8001\u1915\u8001\u1916\u8001\u1918\u8001\u192f\u8001"+ - "\u193f\u8001\u193f\u8001\u1941\u8001\u1941\u8001\u19a0\u8001\u19a7\u8001"+ - "\u19aa\u8001\u19d0\u8001\u19e1\u8001\u19e1\u8001\u19e3\u8001\u19e3\u8001"+ - "\u1a00\u8001\u1a00\u8001\u1a0b\u8001\u1a32\u8001\u1a3a\u8001\u1a3a\u8001"+ - "\u1a50\u8001\u1a50\u8001\u1a5c\u8001\u1a89\u8001\u1a9d\u8001\u1a9d\u8001"+ - "\u1ab0\u8001\u1af8\u8001\u1c00\u8001\u1c08\u8001\u1c0a\u8001\u1c2e\u8001"+ - "\u1c40\u8001\u1c40\u8001\u1c72\u8001\u1c8f\u8001\u1d00\u8001\u1d06\u8001"+ - "\u1d08\u8001\u1d09\u8001\u1d0b\u8001\u1d30\u8001\u1d46\u8001\u1d46\u8001"+ - "\u1d60\u8001\u1d65\u8001\u1d67\u8001\u1d68\u8001\u1d6a\u8001\u1d89\u8001"+ - "\u1d98\u8001\u1d98\u8001\u1ee0\u8001\u1ef2\u8001\u1f02\u8001\u1f02\u8001"+ - "\u1f04\u8001\u1f10\u8001\u1f12\u8001\u1f33\u8001\u1fb0\u8001\u1fb0\u8001"+ - "\u2000\u8001\u2399\u8001\u2400\u8001\u246e\u8001\u2480\u8001\u2543\u8001"+ - "\u2f90\u8001\u2ff0\u8001\u3000\u8001\u342f\u8001\u3441\u8001\u3446\u8001"+ - "\u4400\u8001\u4646\u8001\u6800\u8001\u6a38\u8001\u6a40\u8001\u6a5e\u8001"+ - "\u6a70\u8001\u6abe\u8001\u6ad0\u8001\u6aed\u8001\u6b00\u8001\u6b2f\u8001"+ - "\u6b40\u8001\u6b43\u8001\u6b63\u8001\u6b77\u8001\u6b7d\u8001\u6b8f\u8001"+ - "\u6e40\u8001\u6e7f\u8001\u6f00\u8001\u6f4a\u8001\u6f50\u8001\u6f50\u8001"+ - "\u6f93\u8001\u6f9f\u8001\u6fe0\u8001\u6fe1\u8001\u6fe3\u8001\u6fe3\u8001"+ - "\u7000\u8001\u87f7\u8001\u8800\u8001\u8cd5\u8001\u8d00\u8001\u8d08\u8001"+ - "\uaff0\u8001\uaff3\u8001\uaff5\u8001\uaffb\u8001\uaffd\u8001\uaffe\u8001"+ - "\ub000\u8001\ub122\u8001\ub132\u8001\ub132\u8001\ub150\u8001\ub152\u8001"+ - "\ub155\u8001\ub155\u8001\ub164\u8001\ub167\u8001\ub170\u8001\ub2fb\u8001"+ - "\ubc00\u8001\ubc6a\u8001\ubc70\u8001\ubc7c\u8001\ubc80\u8001\ubc88\u8001"+ - "\ubc90\u8001\ubc99\u8001\ud400\u8001\ud454\u8001\ud456\u8001\ud49c\u8001"+ - "\ud49e\u8001\ud49f\u8001\ud4a2\u8001\ud4a2\u8001\ud4a5\u8001\ud4a6\u8001"+ - "\ud4a9\u8001\ud4ac\u8001\ud4ae\u8001\ud4b9\u8001\ud4bb\u8001\ud4bb\u8001"+ - "\ud4bd\u8001\ud4c3\u8001\ud4c5\u8001\ud505\u8001\ud507\u8001\ud50a\u8001"+ - "\ud50d\u8001\ud514\u8001\ud516\u8001\ud51c\u8001\ud51e\u8001\ud539\u8001"+ - "\ud53b\u8001\ud53e\u8001\ud540\u8001\ud544\u8001\ud546\u8001\ud546\u8001"+ - "\ud54a\u8001\ud550\u8001\ud552\u8001\ud6a5\u8001\ud6a8\u8001\ud6c0\u8001"+ - "\ud6c2\u8001\ud6da\u8001\ud6dc\u8001\ud6fa\u8001\ud6fc\u8001\ud714\u8001"+ - "\ud716\u8001\ud734\u8001\ud736\u8001\ud74e\u8001\ud750\u8001\ud76e\u8001"+ - "\ud770\u8001\ud788\u8001\ud78a\u8001\ud7a8\u8001\ud7aa\u8001\ud7c2\u8001"+ - "\ud7c4\u8001\ud7cb\u8001\udf00\u8001\udf1e\u8001\udf25\u8001\udf2a\u8001"+ - "\ue030\u8001\ue06d\u8001\ue100\u8001\ue12c\u8001\ue137\u8001\ue13d\u8001"+ - "\ue14e\u8001\ue14e\u8001\ue290\u8001\ue2ad\u8001\ue2c0\u8001\ue2eb\u8001"+ - "\ue4d0\u8001\ue4eb\u8001\ue7e0\u8001\ue7e6\u8001\ue7e8\u8001\ue7eb\u8001"+ - "\ue7ed\u8001\ue7ee\u8001\ue7f0\u8001\ue7fe\u8001\ue800\u8001\ue8c4\u8001"+ - "\ue900\u8001\ue943\u8001\ue94b\u8001\ue94b\u8001\uee00\u8001\uee03\u8001"+ - "\uee05\u8001\uee1f\u8001\uee21\u8001\uee22\u8001\uee24\u8001\uee24\u8001"+ - "\uee27\u8001\uee27\u8001\uee29\u8001\uee32\u8001\uee34\u8001\uee37\u8001"+ - "\uee39\u8001\uee39\u8001\uee3b\u8001\uee3b\u8001\uee42\u8001\uee42\u8001"+ - "\uee47\u8001\uee47\u8001\uee49\u8001\uee49\u8001\uee4b\u8001\uee4b\u8001"+ - "\uee4d\u8001\uee4f\u8001\uee51\u8001\uee52\u8001\uee54\u8001\uee54\u8001"+ - "\uee57\u8001\uee57\u8001\uee59\u8001\uee59\u8001\uee5b\u8001\uee5b\u8001"+ - "\uee5d\u8001\uee5d\u8001\uee5f\u8001\uee5f\u8001\uee61\u8001\uee62\u8001"+ - "\uee64\u8001\uee64\u8001\uee67\u8001\uee6a\u8001\uee6c\u8001\uee72\u8001"+ - "\uee74\u8001\uee77\u8001\uee79\u8001\uee7c\u8001\uee7e\u8001\uee7e\u8001"+ - "\uee80\u8001\uee89\u8001\uee8b\u8001\uee9b\u8001\ueea1\u8001\ueea3\u8001"+ - "\ueea5\u8001\ueea9\u8001\ueeab\u8001\ueebb\u8002\u0000\u8002\ua6df\u8002"+ - "\ua700\u8002\ub739\u8002\ub740\u8002\ub81d\u8002\ub820\u8002\ucea1\u8002"+ - "\uceb0\u8002\uebe0\u8002\uf800\u8002\ufa1d\u8003\u0000\u8003\u134a\u8003"+ - "\u1350\u8003\u23af\u0174\u000009__\u0300\u036f\u0483\u0487\u0591\u05bd"+ - "\u05bf\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u05c7\u0610\u061a\u064b\u0669"+ - "\u0670\u0670\u06d6\u06dc\u06df\u06e4\u06e7\u06e8\u06ea\u06ed\u06f0\u06f9"+ - "\u0711\u0711\u0730\u074a\u07a6\u07b0\u07c0\u07c9\u07eb\u07f3\u07fd\u07fd"+ - "\u0816\u0819\u081b\u0823\u0825\u0827\u0829\u082d\u0859\u085b\u0898\u089f"+ - "\u08ca\u08e1\u08e3\u0903\u093a\u093c\u093e\u094f\u0951\u0957\u0962\u0963"+ - "\u0966\u096f\u0981\u0983\u09bc\u09bc\u09be\u09c4\u09c7\u09c8\u09cb\u09cd"+ - "\u09d7\u09d7\u09e2\u09e3\u09e6\u09ef\u09fe\u09fe\u0a01\u0a03\u0a3c\u0a3c"+ - "\u0a3e\u0a42\u0a47\u0a48\u0a4b\u0a4d\u0a51\u0a51\u0a66\u0a71\u0a75\u0a75"+ - "\u0a81\u0a83\u0abc\u0abc\u0abe\u0ac5\u0ac7\u0ac9\u0acb\u0acd\u0ae2\u0ae3"+ - "\u0ae6\u0aef\u0afa\u0aff\u0b01\u0b03\u0b3c\u0b3c\u0b3e\u0b44\u0b47\u0b48"+ - "\u0b4b\u0b4d\u0b55\u0b57\u0b62\u0b63\u0b66\u0b6f\u0b82\u0b82\u0bbe\u0bc2"+ - "\u0bc6\u0bc8\u0bca\u0bcd\u0bd7\u0bd7\u0be6\u0bef\u0c00\u0c04\u0c3c\u0c3c"+ - "\u0c3e\u0c44\u0c46\u0c48\u0c4a\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66\u0c6f"+ - "\u0c81\u0c83\u0cbc\u0cbc\u0cbe\u0cc4\u0cc6\u0cc8\u0cca\u0ccd\u0cd5\u0cd6"+ - "\u0ce2\u0ce3\u0ce6\u0cef\u0cf3\u0cf3\u0d00\u0d03\u0d3b\u0d3c\u0d3e\u0d44"+ - "\u0d46\u0d48\u0d4a\u0d4d\u0d57\u0d57\u0d62\u0d63\u0d66\u0d6f\u0d81\u0d83"+ - "\u0dca\u0dca\u0dcf\u0dd4\u0dd6\u0dd6\u0dd8\u0ddf\u0de6\u0def\u0df2\u0df3"+ - "\u0e31\u0e31\u0e34\u0e3a\u0e47\u0e4e\u0e50\u0e59\u0eb1\u0eb1\u0eb4\u0ebc"+ - "\u0ec8\u0ece\u0ed0\u0ed9\u0f18\u0f19\u0f20\u0f29\u0f35\u0f35\u0f37\u0f37"+ - "\u0f39\u0f39\u0f3e\u0f3f\u0f71\u0f84\u0f86\u0f87\u0f8d\u0f97\u0f99\u0fbc"+ - "\u0fc6\u0fc6\u102b\u103e\u1040\u1049\u1056\u1059\u105e\u1060\u1062\u1064"+ - "\u1067\u106d\u1071\u1074\u1082\u108d\u108f\u109d\u135d\u135f\u1712\u1715"+ - "\u1732\u1734\u1752\u1753\u1772\u1773\u17b4\u17d3\u17dd\u17dd\u17e0\u17e9"+ - "\u180b\u180d\u180f\u1819\u1885\u1886\u18a9\u18a9\u1920\u192b\u1930\u193b"+ - "\u1946\u194f\u19d0\u19d9\u1a17\u1a1b\u1a55\u1a5e\u1a60\u1a7c\u1a7f\u1a89"+ - "\u1a90\u1a99\u1ab0\u1abd\u1abf\u1ace\u1b00\u1b04\u1b34\u1b44\u1b50\u1b59"+ - "\u1b6b\u1b73\u1b80\u1b82\u1ba1\u1bad\u1bb0\u1bb9\u1be6\u1bf3\u1c24\u1c37"+ - "\u1c40\u1c49\u1c50\u1c59\u1cd0\u1cd2\u1cd4\u1ce8\u1ced\u1ced\u1cf4\u1cf4"+ - "\u1cf7\u1cf9\u1dc0\u1dff\u203f\u2040\u2054\u2054\u20d0\u20dc\u20e1\u20e1"+ - "\u20e5\u20f0\u2cef\u2cf1\u2d7f\u2d7f\u2de0\u2dff\u302a\u302f\u3099\u309a"+ - "\u8000\ua620\u8000\ua629\u8000\ua66f\u8000\ua66f\u8000\ua674\u8000\ua67d"+ - "\u8000\ua69e\u8000\ua69f\u8000\ua6f0\u8000\ua6f1\u8000\ua802\u8000\ua802"+ - "\u8000\ua806\u8000\ua806\u8000\ua80b\u8000\ua80b\u8000\ua823\u8000\ua827"+ - "\u8000\ua82c\u8000\ua82c\u8000\ua880\u8000\ua881\u8000\ua8b4\u8000\ua8c5"+ - "\u8000\ua8d0\u8000\ua8d9\u8000\ua8e0\u8000\ua8f1\u8000\ua8ff\u8000\ua909"+ - "\u8000\ua926\u8000\ua92d\u8000\ua947\u8000\ua953\u8000\ua980\u8000\ua983"+ - "\u8000\ua9b3\u8000\ua9c0\u8000\ua9d0\u8000\ua9d9\u8000\ua9e5\u8000\ua9e5"+ - "\u8000\ua9f0\u8000\ua9f9\u8000\uaa29\u8000\uaa36\u8000\uaa43\u8000\uaa43"+ - "\u8000\uaa4c\u8000\uaa4d\u8000\uaa50\u8000\uaa59\u8000\uaa7b\u8000\uaa7d"+ - "\u8000\uaab0\u8000\uaab0\u8000\uaab2\u8000\uaab4\u8000\uaab7\u8000\uaab8"+ - "\u8000\uaabe\u8000\uaabf\u8000\uaac1\u8000\uaac1\u8000\uaaeb\u8000\uaaef"+ - "\u8000\uaaf5\u8000\uaaf6\u8000\uabe3\u8000\uabea\u8000\uabec\u8000\uabed"+ - "\u8000\uabf0\u8000\uabf9\u8000\ufb1e\u8000\ufb1e\u8000\ufe00\u8000\ufe0f"+ - "\u8000\ufe20\u8000\ufe2f\u8000\ufe33\u8000\ufe34\u8000\ufe4d\u8000\ufe4f"+ - "\u8000\uff10\u8000\uff19\u8000\uff3f\u8000\uff3f\u8001\u01fd\u8001\u01fd"+ - "\u8001\u02e0\u8001\u02e0\u8001\u0376\u8001\u037a\u8001\u04a0\u8001\u04a9"+ - "\u8001\u0a01\u8001\u0a03\u8001\u0a05\u8001\u0a06\u8001\u0a0c\u8001\u0a0f"+ - "\u8001\u0a38\u8001\u0a3a\u8001\u0a3f\u8001\u0a3f\u8001\u0ae5\u8001\u0ae6"+ - "\u8001\u0d24\u8001\u0d27\u8001\u0d30\u8001\u0d39\u8001\u0eab\u8001\u0eac"+ - "\u8001\u0efd\u8001\u0eff\u8001\u0f46\u8001\u0f50\u8001\u0f82\u8001\u0f85"+ - "\u8001\u1000\u8001\u1002\u8001\u1038\u8001\u1046\u8001\u1066\u8001\u1070"+ - "\u8001\u1073\u8001\u1074\u8001\u107f\u8001\u1082\u8001\u10b0\u8001\u10ba"+ - "\u8001\u10c2\u8001\u10c2\u8001\u10f0\u8001\u10f9\u8001\u1100\u8001\u1102"+ - "\u8001\u1127\u8001\u1134\u8001\u1136\u8001\u113f\u8001\u1145\u8001\u1146"+ - "\u8001\u1173\u8001\u1173\u8001\u1180\u8001\u1182\u8001\u11b3\u8001\u11c0"+ - "\u8001\u11c9\u8001\u11cc\u8001\u11ce\u8001\u11d9\u8001\u122c\u8001\u1237"+ - "\u8001\u123e\u8001\u123e\u8001\u1241\u8001\u1241\u8001\u12df\u8001\u12ea"+ - "\u8001\u12f0\u8001\u12f9\u8001\u1300\u8001\u1303\u8001\u133b\u8001\u133c"+ - "\u8001\u133e\u8001\u1344\u8001\u1347\u8001\u1348\u8001\u134b\u8001\u134d"+ - "\u8001\u1357\u8001\u1357\u8001\u1362\u8001\u1363\u8001\u1366\u8001\u136c"+ - "\u8001\u1370\u8001\u1374\u8001\u1435\u8001\u1446\u8001\u1450\u8001\u1459"+ - "\u8001\u145e\u8001\u145e\u8001\u14b0\u8001\u14c3\u8001\u14d0\u8001\u14d9"+ - "\u8001\u15af\u8001\u15b5\u8001\u15b8\u8001\u15c0\u8001\u15dc\u8001\u15dd"+ - "\u8001\u1630\u8001\u1640\u8001\u1650\u8001\u1659\u8001\u16ab\u8001\u16b7"+ - "\u8001\u16c0\u8001\u16c9\u8001\u171d\u8001\u172b\u8001\u1730\u8001\u1739"+ - "\u8001\u182c\u8001\u183a\u8001\u18e0\u8001\u18e9\u8001\u1930\u8001\u1935"+ - "\u8001\u1937\u8001\u1938\u8001\u193b\u8001\u193e\u8001\u1940\u8001\u1940"+ - "\u8001\u1942\u8001\u1943\u8001\u1950\u8001\u1959\u8001\u19d1\u8001\u19d7"+ - "\u8001\u19da\u8001\u19e0\u8001\u19e4\u8001\u19e4\u8001\u1a01\u8001\u1a0a"+ - "\u8001\u1a33\u8001\u1a39\u8001\u1a3b\u8001\u1a3e\u8001\u1a47\u8001\u1a47"+ - "\u8001\u1a51\u8001\u1a5b\u8001\u1a8a\u8001\u1a99\u8001\u1c2f\u8001\u1c36"+ - "\u8001\u1c38\u8001\u1c3f\u8001\u1c50\u8001\u1c59\u8001\u1c92\u8001\u1ca7"+ - "\u8001\u1ca9\u8001\u1cb6\u8001\u1d31\u8001\u1d36\u8001\u1d3a\u8001\u1d3a"+ - "\u8001\u1d3c\u8001\u1d3d\u8001\u1d3f\u8001\u1d45\u8001\u1d47\u8001\u1d47"+ - "\u8001\u1d50\u8001\u1d59\u8001\u1d8a\u8001\u1d8e\u8001\u1d90\u8001\u1d91"+ - "\u8001\u1d93\u8001\u1d97\u8001\u1da0\u8001\u1da9\u8001\u1ef3\u8001\u1ef6"+ - "\u8001\u1f00\u8001\u1f01\u8001\u1f03\u8001\u1f03\u8001\u1f34\u8001\u1f3a"+ - "\u8001\u1f3e\u8001\u1f42\u8001\u1f50\u8001\u1f59\u8001\u3440\u8001\u3440"+ - "\u8001\u3447\u8001\u3455\u8001\u6a60\u8001\u6a69\u8001\u6ac0\u8001\u6ac9"+ - "\u8001\u6af0\u8001\u6af4\u8001\u6b30\u8001\u6b36\u8001\u6b50\u8001\u6b59"+ - "\u8001\u6f4f\u8001\u6f4f\u8001\u6f51\u8001\u6f87\u8001\u6f8f\u8001\u6f92"+ - "\u8001\u6fe4\u8001\u6fe4\u8001\u6ff0\u8001\u6ff1\u8001\ubc9d\u8001\ubc9e"+ - "\u8001\ucf00\u8001\ucf2d\u8001\ucf30\u8001\ucf46\u8001\ud165\u8001\ud169"+ - "\u8001\ud16d\u8001\ud172\u8001\ud17b\u8001\ud182\u8001\ud185\u8001\ud18b"+ - "\u8001\ud1aa\u8001\ud1ad\u8001\ud242\u8001\ud244\u8001\ud7ce\u8001\ud7ff"+ - "\u8001\uda00\u8001\uda36\u8001\uda3b\u8001\uda6c\u8001\uda75\u8001\uda75"+ - "\u8001\uda84\u8001\uda84\u8001\uda9b\u8001\uda9f\u8001\udaa1\u8001\udaaf"+ - "\u8001\ue000\u8001\ue006\u8001\ue008\u8001\ue018\u8001\ue01b\u8001\ue021"+ - "\u8001\ue023\u8001\ue024\u8001\ue026\u8001\ue02a\u8001\ue08f\u8001\ue08f"+ - "\u8001\ue130\u8001\ue136\u8001\ue140\u8001\ue149\u8001\ue2ae\u8001\ue2ae"+ - "\u8001\ue2ec\u8001\ue2f9\u8001\ue4ec\u8001\ue4f9\u8001\ue8d0\u8001\ue8d6"+ - "\u8001\ue944\u8001\ue94a\u8001\ue950\u8001\ue959\u8001\ufbf0\u8001\ufbf9"+ - "\u800e\u0100\u800e\u01ef\u0004\u0000\u1885\u1886\u2118\u2118\u212e\u212e"+ - "\u309b\u309c\u0004\u0000\u00b7\u00b7\u0387\u0387\u1369\u1371\u19da\u19da"+ - "\u0002\u0000!!//\u0002\u0000\n\n\r\r\u0002\u0000!!**\u0001\u0000**\u0001"+ - "\u0000//\u0007\u0000 \u00a0\u00a0\u1680\u1680\u2000\u200a\u202f\u202f"+ - "\u205f\u205f\u3000\u3000\u0004\u0000\t\n\r\r\'\'\\\\\u0001\u0000\"\"\u0005"+ - "\u000000\\\\nnrrtt\u0002\u0000\"\"\'\'\u0001\u000001\u0002\u000001__\u0002"+ - "\u0000EEee\u0002\u0000++--\u0001\u000007\u0001\u000009\u0003\u000009A"+ - "Faf\u04e4\u0000\u0001\u0001\u0000\u0000\u0000\u0000\u0003\u0001\u0000"+ - "\u0000\u0000\u0000\u0005\u0001\u0000\u0000\u0000\u0000\u0007\u0001\u0000"+ - "\u0000\u0000\u0000\t\u0001\u0000\u0000\u0000\u0000\u000b\u0001\u0000\u0000"+ - "\u0000\u0000\r\u0001\u0000\u0000\u0000\u0000\u000f\u0001\u0000\u0000\u0000"+ - "\u0000\u0011\u0001\u0000\u0000\u0000\u0000\u0013\u0001\u0000\u0000\u0000"+ - "\u0000\u0015\u0001\u0000\u0000\u0000\u0000\u0017\u0001\u0000\u0000\u0000"+ - "\u0000\u0019\u0001\u0000\u0000\u0000\u0000\u001b\u0001\u0000\u0000\u0000"+ - "\u0000\u001d\u0001\u0000\u0000\u0000\u0000\u001f\u0001\u0000\u0000\u0000"+ - "\u0000!\u0001\u0000\u0000\u0000\u0000#\u0001\u0000\u0000\u0000\u0000%"+ - "\u0001\u0000\u0000\u0000\u0000\'\u0001\u0000\u0000\u0000\u0000)\u0001"+ - "\u0000\u0000\u0000\u0000+\u0001\u0000\u0000\u0000\u0000-\u0001\u0000\u0000"+ - "\u0000\u0000/\u0001\u0000\u0000\u0000\u00001\u0001\u0000\u0000\u0000\u0000"+ - "3\u0001\u0000\u0000\u0000\u00005\u0001\u0000\u0000\u0000\u00007\u0001"+ - "\u0000\u0000\u0000\u00009\u0001\u0000\u0000\u0000\u0000;\u0001\u0000\u0000"+ - "\u0000\u0000=\u0001\u0000\u0000\u0000\u0000?\u0001\u0000\u0000\u0000\u0000"+ - "A\u0001\u0000\u0000\u0000\u0000C\u0001\u0000\u0000\u0000\u0000E\u0001"+ - "\u0000\u0000\u0000\u0000G\u0001\u0000\u0000\u0000\u0000I\u0001\u0000\u0000"+ - "\u0000\u0000K\u0001\u0000\u0000\u0000\u0000M\u0001\u0000\u0000\u0000\u0000"+ - "O\u0001\u0000\u0000\u0000\u0000Q\u0001\u0000\u0000\u0000\u0000S\u0001"+ - "\u0000\u0000\u0000\u0000U\u0001\u0000\u0000\u0000\u0000W\u0001\u0000\u0000"+ - "\u0000\u0000Y\u0001\u0000\u0000\u0000\u0000[\u0001\u0000\u0000\u0000\u0000"+ - "]\u0001\u0000\u0000\u0000\u0000_\u0001\u0000\u0000\u0000\u0000a\u0001"+ - "\u0000\u0000\u0000\u0000c\u0001\u0000\u0000\u0000\u0000e\u0001\u0000\u0000"+ - "\u0000\u0000g\u0001\u0000\u0000\u0000\u0000i\u0001\u0000\u0000\u0000\u0000"+ - "k\u0001\u0000\u0000\u0000\u0000m\u0001\u0000\u0000\u0000\u0000o\u0001"+ - "\u0000\u0000\u0000\u0000q\u0001\u0000\u0000\u0000\u0000{\u0001\u0000\u0000"+ - "\u0000\u0000}\u0001\u0000\u0000\u0000\u0000\u007f\u0001\u0000\u0000\u0000"+ - "\u0000\u0081\u0001\u0000\u0000\u0000\u0000\u0083\u0001\u0000\u0000\u0000"+ - "\u0000\u0085\u0001\u0000\u0000\u0000\u0000\u0087\u0001\u0000\u0000\u0000"+ - "\u0000\u0089\u0001\u0000\u0000\u0000\u0000\u008b\u0001\u0000\u0000\u0000"+ - "\u0000\u008d\u0001\u0000\u0000\u0000\u0000\u008f\u0001\u0000\u0000\u0000"+ - "\u0000\u0091\u0001\u0000\u0000\u0000\u0000\u0093\u0001\u0000\u0000\u0000"+ - "\u0000\u0095\u0001\u0000\u0000\u0000\u0000\u0099\u0001\u0000\u0000\u0000"+ - "\u0000\u009b\u0001\u0000\u0000\u0000\u0000\u009d\u0001\u0000\u0000\u0000"+ - "\u0000\u00ab\u0001\u0000\u0000\u0000\u0000\u00ad\u0001\u0000\u0000\u0000"+ - "\u0000\u00af\u0001\u0000\u0000\u0000\u0000\u00b1\u0001\u0000\u0000\u0000"+ - "\u0000\u00b3\u0001\u0000\u0000\u0000\u0000\u00b5\u0001\u0000\u0000\u0000"+ - "\u0000\u00c3\u0001\u0000\u0000\u0000\u0000\u00c5\u0001\u0000\u0000\u0000"+ - "\u0000\u00c7\u0001\u0000\u0000\u0000\u0000\u00c9\u0001\u0000\u0000\u0000"+ - "\u0000\u00cb\u0001\u0000\u0000\u0000\u0000\u00cd\u0001\u0000\u0000\u0000"+ - "\u0000\u00cf\u0001\u0000\u0000\u0000\u0000\u00d1\u0001\u0000\u0000\u0000"+ - "\u0000\u00d3\u0001\u0000\u0000\u0000\u0000\u00d5\u0001\u0000\u0000\u0000"+ - "\u0000\u00d7\u0001\u0000\u0000\u0000\u0000\u00d9\u0001\u0000\u0000\u0000"+ - "\u0000\u00db\u0001\u0000\u0000\u0000\u0000\u00dd\u0001\u0000\u0000\u0000"+ - "\u0000\u00df\u0001\u0000\u0000\u0000\u0000\u00e1\u0001\u0000\u0000\u0000"+ - "\u0000\u00e3\u0001\u0000\u0000\u0000\u0000\u00e5\u0001\u0000\u0000\u0000"+ - "\u0000\u00e7\u0001\u0000\u0000\u0000\u0000\u00e9\u0001\u0000\u0000\u0000"+ - "\u0000\u00eb\u0001\u0000\u0000\u0000\u0000\u00ed\u0001\u0000\u0000\u0000"+ - "\u0000\u00ef\u0001\u0000\u0000\u0000\u0000\u00f1\u0001\u0000\u0000\u0000"+ - "\u0000\u00f3\u0001\u0000\u0000\u0000\u0000\u00f5\u0001\u0000\u0000\u0000"+ - "\u0000\u00f7\u0001\u0000\u0000\u0000\u0000\u00f9\u0001\u0000\u0000\u0000"+ - "\u0000\u00fb\u0001\u0000\u0000\u0000\u0000\u00fd\u0001\u0000\u0000\u0000"+ - "\u0000\u00ff\u0001\u0000\u0000\u0000\u0000\u0101\u0001\u0000\u0000\u0000"+ - "\u0000\u0103\u0001\u0000\u0000\u0000\u0000\u0105\u0001\u0000\u0000\u0000"+ - "\u0000\u0107\u0001\u0000\u0000\u0000\u0000\u0109\u0001\u0000\u0000\u0000"+ - "\u0000\u010b\u0001\u0000\u0000\u0000\u0000\u010d\u0001\u0000\u0000\u0000"+ - "\u0000\u010f\u0001\u0000\u0000\u0000\u0000\u0111\u0001\u0000\u0000\u0000"+ - "\u0000\u0113\u0001\u0000\u0000\u0000\u0000\u0115\u0001\u0000\u0000\u0000"+ - "\u0000\u0117\u0001\u0000\u0000\u0000\u0000\u0119\u0001\u0000\u0000\u0000"+ - "\u0000\u011b\u0001\u0000\u0000\u0000\u0000\u011d\u0001\u0000\u0000\u0000"+ - "\u0000\u011f\u0001\u0000\u0000\u0000\u0000\u0121\u0001\u0000\u0000\u0000"+ - "\u0000\u0123\u0001\u0000\u0000\u0000\u0000\u0125\u0001\u0000\u0000\u0000"+ - "\u0001\u0127\u0001\u0000\u0000\u0000\u0003\u012a\u0001\u0000\u0000\u0000"+ - "\u0005\u0130\u0001\u0000\u0000\u0000\u0007\u0136\u0001\u0000\u0000\u0000"+ - "\t\u013f\u0001\u0000\u0000\u0000\u000b\u0145\u0001\u0000\u0000\u0000\r"+ - "\u014a\u0001\u0000\u0000\u0000\u000f\u014f\u0001\u0000\u0000\u0000\u0011"+ - "\u0156\u0001\u0000\u0000\u0000\u0013\u015c\u0001\u0000\u0000\u0000\u0015"+ - "\u015f\u0001\u0000\u0000\u0000\u0017\u0163\u0001\u0000\u0000\u0000\u0019"+ - "\u0166\u0001\u0000\u0000\u0000\u001b\u016b\u0001\u0000\u0000\u0000\u001d"+ - "\u016e\u0001\u0000\u0000\u0000\u001f\u0172\u0001\u0000\u0000\u0000!\u0177"+ - "\u0001\u0000\u0000\u0000#\u017d\u0001\u0000\u0000\u0000%\u0181\u0001\u0000"+ - "\u0000\u0000\'\u0186\u0001\u0000\u0000\u0000)\u018a\u0001\u0000\u0000"+ - "\u0000+\u018e\u0001\u0000\u0000\u0000-\u0192\u0001\u0000\u0000\u0000/"+ - "\u0199\u0001\u0000\u0000\u00001\u019e\u0001\u0000\u0000\u00003\u01a3\u0001"+ - "\u0000\u0000\u00005\u01aa\u0001\u0000\u0000\u00007\u01b1\u0001\u0000\u0000"+ - "\u00009\u01b7\u0001\u0000\u0000\u0000;\u01bd\u0001\u0000\u0000\u0000="+ - "\u01c2\u0001\u0000\u0000\u0000?\u01c7\u0001\u0000\u0000\u0000A\u01ce\u0001"+ - "\u0000\u0000\u0000C\u01d2\u0001\u0000\u0000\u0000E\u01d8\u0001\u0000\u0000"+ - "\u0000G\u01de\u0001\u0000\u0000\u0000I\u01e4\u0001\u0000\u0000\u0000K"+ - "\u01ea\u0001\u0000\u0000\u0000M\u01ee\u0001\u0000\u0000\u0000O\u01f7\u0001"+ - "\u0000\u0000\u0000Q\u01fe\u0001\u0000\u0000\u0000S\u0202\u0001\u0000\u0000"+ - "\u0000U\u0205\u0001\u0000\u0000\u0000W\u020b\u0001\u0000\u0000\u0000Y"+ - "\u0211\u0001\u0000\u0000\u0000[\u021a\u0001\u0000\u0000\u0000]\u021f\u0001"+ - "\u0000\u0000\u0000_\u0226\u0001\u0000\u0000\u0000a\u022e\u0001\u0000\u0000"+ - "\u0000c\u0236\u0001\u0000\u0000\u0000e\u023c\u0001\u0000\u0000\u0000g"+ - "\u0240\u0001\u0000\u0000\u0000i\u0246\u0001\u0000\u0000\u0000k\u024e\u0001"+ - "\u0000\u0000\u0000m\u025a\u0001\u0000\u0000\u0000o\u025d\u0001\u0000\u0000"+ - "\u0000q\u0271\u0001\u0000\u0000\u0000s\u0275\u0001\u0000\u0000\u0000u"+ - "\u027a\u0001\u0000\u0000\u0000w\u027c\u0001\u0000\u0000\u0000y\u027e\u0001"+ - "\u0000\u0000\u0000{\u0280\u0001\u0000\u0000\u0000}\u0295\u0001\u0000\u0000"+ - "\u0000\u007f\u02b4\u0001\u0000\u0000\u0000\u0081\u02b8\u0001\u0000\u0000"+ - "\u0000\u0083\u02c4\u0001\u0000\u0000\u0000\u0085\u02d4\u0001\u0000\u0000"+ - "\u0000\u0087\u02e3\u0001\u0000\u0000\u0000\u0089\u02fa\u0001\u0000\u0000"+ - "\u0000\u008b\u02fe\u0001\u0000\u0000\u0000\u008d\u030d\u0001\u0000\u0000"+ - "\u0000\u008f\u0314\u0001\u0000\u0000\u0000\u0091\u0318\u0001\u0000\u0000"+ - "\u0000\u0093\u0321\u0001\u0000\u0000\u0000\u0095\u032e\u0001\u0000\u0000"+ - "\u0000\u0097\u033d\u0001\u0000\u0000\u0000\u0099\u033f\u0001\u0000\u0000"+ - "\u0000\u009b\u0349\u0001\u0000\u0000\u0000\u009d\u0356\u0001\u0000\u0000"+ - "\u0000\u009f\u0362\u0001\u0000\u0000\u0000\u00a1\u036b\u0001\u0000\u0000"+ - "\u0000\u00a3\u036d\u0001\u0000\u0000\u0000\u00a5\u0370\u0001\u0000\u0000"+ - "\u0000\u00a7\u0386\u0001\u0000\u0000\u0000\u00a9\u0389\u0001\u0000\u0000"+ - "\u0000\u00ab\u0390\u0001\u0000\u0000\u0000\u00ad\u0395\u0001\u0000\u0000"+ - "\u0000\u00af\u039d\u0001\u0000\u0000\u0000\u00b1\u03ae\u0001\u0000\u0000"+ - "\u0000\u00b3\u03bf\u0001\u0000\u0000\u0000\u00b5\u03cf\u0001\u0000\u0000"+ - "\u0000\u00b7\u0409\u0001\u0000\u0000\u0000\u00b9\u0411\u0001\u0000\u0000"+ - "\u0000\u00bb\u0413\u0001\u0000\u0000\u0000\u00bd\u041f\u0001\u0000\u0000"+ - "\u0000\u00bf\u0421\u0001\u0000\u0000\u0000\u00c1\u0423\u0001\u0000\u0000"+ - "\u0000\u00c3\u0425\u0001\u0000\u0000\u0000\u00c5\u0428\u0001\u0000\u0000"+ - "\u0000\u00c7\u042a\u0001\u0000\u0000\u0000\u00c9\u042c\u0001\u0000\u0000"+ - "\u0000\u00cb\u042e\u0001\u0000\u0000\u0000\u00cd\u0430\u0001\u0000\u0000"+ - "\u0000\u00cf\u0432\u0001\u0000\u0000\u0000\u00d1\u0434\u0001\u0000\u0000"+ - "\u0000\u00d3\u0436\u0001\u0000\u0000\u0000\u00d5\u0438\u0001\u0000\u0000"+ - "\u0000\u00d7\u043a\u0001\u0000\u0000\u0000\u00d9\u043d\u0001\u0000\u0000"+ - "\u0000\u00db\u0440\u0001\u0000\u0000\u0000\u00dd\u0443\u0001\u0000\u0000"+ - "\u0000\u00df\u0446\u0001\u0000\u0000\u0000\u00e1\u0449\u0001\u0000\u0000"+ - "\u0000\u00e3\u044c\u0001\u0000\u0000\u0000\u00e5\u044f\u0001\u0000\u0000"+ - "\u0000\u00e7\u0452\u0001\u0000\u0000\u0000\u00e9\u0455\u0001\u0000\u0000"+ - "\u0000\u00eb\u0458\u0001\u0000\u0000\u0000\u00ed\u045c\u0001\u0000\u0000"+ - "\u0000\u00ef\u0460\u0001\u0000\u0000\u0000\u00f1\u0462\u0001\u0000\u0000"+ - "\u0000\u00f3\u0465\u0001\u0000\u0000\u0000\u00f5\u0468\u0001\u0000\u0000"+ - "\u0000\u00f7\u046a\u0001\u0000\u0000\u0000\u00f9\u046c\u0001\u0000\u0000"+ - "\u0000\u00fb\u046f\u0001\u0000\u0000\u0000\u00fd\u0472\u0001\u0000\u0000"+ - "\u0000\u00ff\u0474\u0001\u0000\u0000\u0000\u0101\u0476\u0001\u0000\u0000"+ - "\u0000\u0103\u0478\u0001\u0000\u0000\u0000\u0105\u047b\u0001\u0000\u0000"+ - "\u0000\u0107\u047f\u0001\u0000\u0000\u0000\u0109\u0483\u0001\u0000\u0000"+ - "\u0000\u010b\u0485\u0001\u0000\u0000\u0000\u010d\u0487\u0001\u0000\u0000"+ - "\u0000\u010f\u0489\u0001\u0000\u0000\u0000\u0111\u048c\u0001\u0000\u0000"+ - "\u0000\u0113\u048f\u0001\u0000\u0000\u0000\u0115\u0492\u0001\u0000\u0000"+ - "\u0000\u0117\u0494\u0001\u0000\u0000\u0000\u0119\u0496\u0001\u0000\u0000"+ - "\u0000\u011b\u0498\u0001\u0000\u0000\u0000\u011d\u049a\u0001\u0000\u0000"+ - "\u0000\u011f\u049c\u0001\u0000\u0000\u0000\u0121\u049e\u0001\u0000\u0000"+ - "\u0000\u0123\u04a0\u0001\u0000\u0000\u0000\u0125\u04a2\u0001\u0000\u0000"+ - "\u0000\u0127\u0128\u0005a\u0000\u0000\u0128\u0129\u0005s\u0000\u0000\u0129"+ - "\u0002\u0001\u0000\u0000\u0000\u012a\u012b\u0005b\u0000\u0000\u012b\u012c"+ - "\u0005r\u0000\u0000\u012c\u012d\u0005e\u0000\u0000\u012d\u012e\u0005a"+ - "\u0000\u0000\u012e\u012f\u0005k\u0000\u0000\u012f\u0004\u0001\u0000\u0000"+ - "\u0000\u0130\u0131\u0005c\u0000\u0000\u0131\u0132\u0005o\u0000\u0000\u0132"+ - "\u0133\u0005n\u0000\u0000\u0133\u0134\u0005s\u0000\u0000\u0134\u0135\u0005"+ - "t\u0000\u0000\u0135\u0006\u0001\u0000\u0000\u0000\u0136\u0137\u0005c\u0000"+ - "\u0000\u0137\u0138\u0005o\u0000\u0000\u0138\u0139\u0005n\u0000\u0000\u0139"+ - "\u013a\u0005t\u0000\u0000\u013a\u013b\u0005i\u0000\u0000\u013b\u013c\u0005"+ - "n\u0000\u0000\u013c\u013d\u0005u\u0000\u0000\u013d\u013e\u0005e\u0000"+ - "\u0000\u013e\b\u0001\u0000\u0000\u0000\u013f\u0140\u0005c\u0000\u0000"+ - "\u0140\u0141\u0005r\u0000\u0000\u0141\u0142\u0005a\u0000\u0000\u0142\u0143"+ - "\u0005t\u0000\u0000\u0143\u0144\u0005e\u0000\u0000\u0144\n\u0001\u0000"+ - "\u0000\u0000\u0145\u0146\u0005e\u0000\u0000\u0146\u0147\u0005l\u0000\u0000"+ - "\u0147\u0148\u0005s\u0000\u0000\u0148\u0149\u0005e\u0000\u0000\u0149\f"+ - "\u0001\u0000\u0000\u0000\u014a\u014b\u0005e\u0000\u0000\u014b\u014c\u0005"+ - "n\u0000\u0000\u014c\u014d\u0005u\u0000\u0000\u014d\u014e\u0005m\u0000"+ - "\u0000\u014e\u000e\u0001\u0000\u0000\u0000\u014f\u0150\u0005e\u0000\u0000"+ - "\u0150\u0151\u0005x\u0000\u0000\u0151\u0152\u0005t\u0000\u0000\u0152\u0153"+ - "\u0005e\u0000\u0000\u0153\u0154\u0005r\u0000\u0000\u0154\u0155\u0005n"+ - "\u0000\u0000\u0155\u0010\u0001\u0000\u0000\u0000\u0156\u0157\u0005f\u0000"+ - "\u0000\u0157\u0158\u0005a\u0000\u0000\u0158\u0159\u0005l\u0000\u0000\u0159"+ - "\u015a\u0005s\u0000\u0000\u015a\u015b\u0005e\u0000\u0000\u015b\u0012\u0001"+ - "\u0000\u0000\u0000\u015c\u015d\u0005f\u0000\u0000\u015d\u015e\u0005n\u0000"+ - "\u0000\u015e\u0014\u0001\u0000\u0000\u0000\u015f\u0160\u0005f\u0000\u0000"+ - "\u0160\u0161\u0005o\u0000\u0000\u0161\u0162\u0005r\u0000\u0000\u0162\u0016"+ - "\u0001\u0000\u0000\u0000\u0163\u0164\u0005i\u0000\u0000\u0164\u0165\u0005"+ - "f\u0000\u0000\u0165\u0018\u0001\u0000\u0000\u0000\u0166\u0167\u0005i\u0000"+ - "\u0000\u0167\u0168\u0005m\u0000\u0000\u0168\u0169\u0005p\u0000\u0000\u0169"+ - "\u016a\u0005l\u0000\u0000\u016a\u001a\u0001\u0000\u0000\u0000\u016b\u016c"+ - "\u0005i\u0000\u0000\u016c\u016d\u0005n\u0000\u0000\u016d\u001c\u0001\u0000"+ - "\u0000\u0000\u016e\u016f\u0005l\u0000\u0000\u016f\u0170\u0005e\u0000\u0000"+ - "\u0170\u0171\u0005t\u0000\u0000\u0171\u001e\u0001\u0000\u0000\u0000\u0172"+ - "\u0173\u0005l\u0000\u0000\u0173\u0174\u0005o\u0000\u0000\u0174\u0175\u0005"+ - "o\u0000\u0000\u0175\u0176\u0005p\u0000\u0000\u0176 \u0001\u0000\u0000"+ - "\u0000\u0177\u0178\u0005m\u0000\u0000\u0178\u0179\u0005a\u0000\u0000\u0179"+ - "\u017a\u0005t\u0000\u0000\u017a\u017b\u0005c\u0000\u0000\u017b\u017c\u0005"+ - "h\u0000\u0000\u017c\"\u0001\u0000\u0000\u0000\u017d\u017e\u0005m\u0000"+ - "\u0000\u017e\u017f\u0005o\u0000\u0000\u017f\u0180\u0005d\u0000\u0000\u0180"+ - "$\u0001\u0000\u0000\u0000\u0181\u0182\u0005m\u0000\u0000\u0182\u0183\u0005"+ - "o\u0000\u0000\u0183\u0184\u0005v\u0000\u0000\u0184\u0185\u0005e\u0000"+ - "\u0000\u0185&\u0001\u0000\u0000\u0000\u0186\u0187\u0005m\u0000\u0000\u0187"+ - "\u0188\u0005u\u0000\u0000\u0188\u0189\u0005t\u0000\u0000\u0189(\u0001"+ - "\u0000\u0000\u0000\u018a\u018b\u0005p\u0000\u0000\u018b\u018c\u0005u\u0000"+ - "\u0000\u018c\u018d\u0005b\u0000\u0000\u018d*\u0001\u0000\u0000\u0000\u018e"+ - "\u018f\u0005r\u0000\u0000\u018f\u0190\u0005e\u0000\u0000\u0190\u0191\u0005"+ - "f\u0000\u0000\u0191,\u0001\u0000\u0000\u0000\u0192\u0193\u0005r\u0000"+ - "\u0000\u0193\u0194\u0005e\u0000\u0000\u0194\u0195\u0005t\u0000\u0000\u0195"+ - "\u0196\u0005u\u0000\u0000\u0196\u0197\u0005r\u0000\u0000\u0197\u0198\u0005"+ - "n\u0000\u0000\u0198.\u0001\u0000\u0000\u0000\u0199\u019a\u0005s\u0000"+ - "\u0000\u019a\u019b\u0005e\u0000\u0000\u019b\u019c\u0005l\u0000\u0000\u019c"+ - "\u019d\u0005f\u0000\u0000\u019d0\u0001\u0000\u0000\u0000\u019e\u019f\u0005"+ - "S\u0000\u0000\u019f\u01a0\u0005e\u0000\u0000\u01a0\u01a1\u0005l\u0000"+ - "\u0000\u01a1\u01a2\u0005f\u0000\u0000\u01a22\u0001\u0000\u0000\u0000\u01a3"+ - "\u01a4\u0005s\u0000\u0000\u01a4\u01a5\u0005t\u0000\u0000\u01a5\u01a6\u0005"+ - "a\u0000\u0000\u01a6\u01a7\u0005t\u0000\u0000\u01a7\u01a8\u0005i\u0000"+ - "\u0000\u01a8\u01a9\u0005c\u0000\u0000\u01a94\u0001\u0000\u0000\u0000\u01aa"+ - "\u01ab\u0005s\u0000\u0000\u01ab\u01ac\u0005t\u0000\u0000\u01ac\u01ad\u0005"+ - "r\u0000\u0000\u01ad\u01ae\u0005u\u0000\u0000\u01ae\u01af\u0005c\u0000"+ - "\u0000\u01af\u01b0\u0005t\u0000\u0000\u01b06\u0001\u0000\u0000\u0000\u01b1"+ - "\u01b2\u0005s\u0000\u0000\u01b2\u01b3\u0005u\u0000\u0000\u01b3\u01b4\u0005"+ - "p\u0000\u0000\u01b4\u01b5\u0005e\u0000\u0000\u01b5\u01b6\u0005r\u0000"+ - "\u0000\u01b68\u0001\u0000\u0000\u0000\u01b7\u01b8\u0005t\u0000\u0000\u01b8"+ - "\u01b9\u0005r\u0000\u0000\u01b9\u01ba\u0005a\u0000\u0000\u01ba\u01bb\u0005"+ - "i\u0000\u0000\u01bb\u01bc\u0005t\u0000\u0000\u01bc:\u0001\u0000\u0000"+ - "\u0000\u01bd\u01be\u0005t\u0000\u0000\u01be\u01bf\u0005r\u0000\u0000\u01bf"+ - "\u01c0\u0005u\u0000\u0000\u01c0\u01c1\u0005e\u0000\u0000\u01c1<\u0001"+ - "\u0000\u0000\u0000\u01c2\u01c3\u0005t\u0000\u0000\u01c3\u01c4\u0005y\u0000"+ - "\u0000\u01c4\u01c5\u0005p\u0000\u0000\u01c5\u01c6\u0005e\u0000\u0000\u01c6"+ - ">\u0001\u0000\u0000\u0000\u01c7\u01c8\u0005u\u0000\u0000\u01c8\u01c9\u0005"+ - "n\u0000\u0000\u01c9\u01ca\u0005s\u0000\u0000\u01ca\u01cb\u0005a\u0000"+ - "\u0000\u01cb\u01cc\u0005f\u0000\u0000\u01cc\u01cd\u0005e\u0000\u0000\u01cd"+ - "@\u0001\u0000\u0000\u0000\u01ce\u01cf\u0005u\u0000\u0000\u01cf\u01d0\u0005"+ - "s\u0000\u0000\u01d0\u01d1\u0005e\u0000\u0000\u01d1B\u0001\u0000\u0000"+ - "\u0000\u01d2\u01d3\u0005w\u0000\u0000\u01d3\u01d4\u0005h\u0000\u0000\u01d4"+ - "\u01d5\u0005e\u0000\u0000\u01d5\u01d6\u0005r\u0000\u0000\u01d6\u01d7\u0005"+ - "e\u0000\u0000\u01d7D\u0001\u0000\u0000\u0000\u01d8\u01d9\u0005w\u0000"+ - "\u0000\u01d9\u01da\u0005h\u0000\u0000\u01da\u01db\u0005i\u0000\u0000\u01db"+ - "\u01dc\u0005l\u0000\u0000\u01dc\u01dd\u0005e\u0000\u0000\u01ddF\u0001"+ - "\u0000\u0000\u0000\u01de\u01df\u0005a\u0000\u0000\u01df\u01e0\u0005s\u0000"+ - "\u0000\u01e0\u01e1\u0005y\u0000\u0000\u01e1\u01e2\u0005n\u0000\u0000\u01e2"+ - "\u01e3\u0005c\u0000\u0000\u01e3H\u0001\u0000\u0000\u0000\u01e4\u01e5\u0005"+ - "a\u0000\u0000\u01e5\u01e6\u0005w\u0000\u0000\u01e6\u01e7\u0005a\u0000"+ - "\u0000\u01e7\u01e8\u0005i\u0000\u0000\u01e8\u01e9\u0005t\u0000\u0000\u01e9"+ - "J\u0001\u0000\u0000\u0000\u01ea\u01eb\u0005d\u0000\u0000\u01eb\u01ec\u0005"+ - "y\u0000\u0000\u01ec\u01ed\u0005n\u0000\u0000\u01edL\u0001\u0000\u0000"+ - "\u0000\u01ee\u01ef\u0005a\u0000\u0000\u01ef\u01f0\u0005b\u0000\u0000\u01f0"+ - "\u01f1\u0005s\u0000\u0000\u01f1\u01f2\u0005t\u0000\u0000\u01f2\u01f3\u0005"+ - "r\u0000\u0000\u01f3\u01f4\u0005a\u0000\u0000\u01f4\u01f5\u0005c\u0000"+ - "\u0000\u01f5\u01f6\u0005t\u0000\u0000\u01f6N\u0001\u0000\u0000\u0000\u01f7"+ - "\u01f8\u0005b\u0000\u0000\u01f8\u01f9\u0005e\u0000\u0000\u01f9\u01fa\u0005"+ - "c\u0000\u0000\u01fa\u01fb\u0005o\u0000\u0000\u01fb\u01fc\u0005m\u0000"+ - "\u0000\u01fc\u01fd\u0005e\u0000\u0000\u01fdP\u0001\u0000\u0000\u0000\u01fe"+ - "\u01ff\u0005b\u0000\u0000\u01ff\u0200\u0005o\u0000\u0000\u0200\u0201\u0005"+ - "x\u0000\u0000\u0201R\u0001\u0000\u0000\u0000\u0202\u0203\u0005d\u0000"+ - "\u0000\u0203\u0204\u0005o\u0000\u0000\u0204T\u0001\u0000\u0000\u0000\u0205"+ - "\u0206\u0005f\u0000\u0000\u0206\u0207\u0005i\u0000\u0000\u0207\u0208\u0005"+ - "n\u0000\u0000\u0208\u0209\u0005a\u0000\u0000\u0209\u020a\u0005l\u0000"+ - "\u0000\u020aV\u0001\u0000\u0000\u0000\u020b\u020c\u0005m\u0000\u0000\u020c"+ - "\u020d\u0005a\u0000\u0000\u020d\u020e\u0005c\u0000\u0000\u020e\u020f\u0005"+ - "r\u0000\u0000\u020f\u0210\u0005o\u0000\u0000\u0210X\u0001\u0000\u0000"+ - "\u0000\u0211\u0212\u0005o\u0000\u0000\u0212\u0213\u0005v\u0000\u0000\u0213"+ - "\u0214\u0005e\u0000\u0000\u0214\u0215\u0005r\u0000\u0000\u0215\u0216\u0005"+ - "r\u0000\u0000\u0216\u0217\u0005i\u0000\u0000\u0217\u0218\u0005d\u0000"+ - "\u0000\u0218\u0219\u0005e\u0000\u0000\u0219Z\u0001\u0000\u0000\u0000\u021a"+ - "\u021b\u0005p\u0000\u0000\u021b\u021c\u0005r\u0000\u0000\u021c\u021d\u0005"+ - "i\u0000\u0000\u021d\u021e\u0005v\u0000\u0000\u021e\\\u0001\u0000\u0000"+ - "\u0000\u021f\u0220\u0005t\u0000\u0000\u0220\u0221\u0005y\u0000\u0000\u0221"+ - "\u0222\u0005p\u0000\u0000\u0222\u0223\u0005e\u0000\u0000\u0223\u0224\u0005"+ - "o\u0000\u0000\u0224\u0225\u0005f\u0000\u0000\u0225^\u0001\u0000\u0000"+ - "\u0000\u0226\u0227\u0005u\u0000\u0000\u0227\u0228\u0005n\u0000\u0000\u0228"+ - "\u0229\u0005s\u0000\u0000\u0229\u022a\u0005i\u0000\u0000\u022a\u022b\u0005"+ - "z\u0000\u0000\u022b\u022c\u0005e\u0000\u0000\u022c\u022d\u0005d\u0000"+ - "\u0000\u022d`\u0001\u0000\u0000\u0000\u022e\u022f\u0005v\u0000\u0000\u022f"+ - "\u0230\u0005i\u0000\u0000\u0230\u0231\u0005r\u0000\u0000\u0231\u0232\u0005"+ - "t\u0000\u0000\u0232\u0233\u0005u\u0000\u0000\u0233\u0234\u0005a\u0000"+ - "\u0000\u0234\u0235\u0005l\u0000\u0000\u0235b\u0001\u0000\u0000\u0000\u0236"+ - "\u0237\u0005y\u0000\u0000\u0237\u0238\u0005i\u0000\u0000\u0238\u0239\u0005"+ - "e\u0000\u0000\u0239\u023a\u0005l\u0000\u0000\u023a\u023b\u0005d\u0000"+ - "\u0000\u023bd\u0001\u0000\u0000\u0000\u023c\u023d\u0005t\u0000\u0000\u023d"+ - "\u023e\u0005r\u0000\u0000\u023e\u023f\u0005y\u0000\u0000\u023ff\u0001"+ - "\u0000\u0000\u0000\u0240\u0241\u0005u\u0000\u0000\u0241\u0242\u0005n\u0000"+ - "\u0000\u0242\u0243\u0005i\u0000\u0000\u0243\u0244\u0005o\u0000\u0000\u0244"+ - "\u0245\u0005n\u0000\u0000\u0245h\u0001\u0000\u0000\u0000\u0246\u0247\u0005"+ - "\'\u0000\u0000\u0247\u0248\u0005s\u0000\u0000\u0248\u0249\u0005t\u0000"+ - "\u0000\u0249\u024a\u0005a\u0000\u0000\u024a\u024b\u0005t\u0000\u0000\u024b"+ - "\u024c\u0005i\u0000\u0000\u024c\u024d\u0005c\u0000\u0000\u024dj\u0001"+ - "\u0000\u0000\u0000\u024e\u024f\u0005m\u0000\u0000\u024f\u0250\u0005a\u0000"+ - "\u0000\u0250\u0251\u0005c\u0000\u0000\u0251\u0252\u0005r\u0000\u0000\u0252"+ - "\u0253\u0005o\u0000\u0000\u0253\u0254\u0005_\u0000\u0000\u0254\u0255\u0005"+ - "r\u0000\u0000\u0255\u0256\u0005u\u0000\u0000\u0256\u0257\u0005l\u0000"+ - "\u0000\u0257\u0258\u0005e\u0000\u0000\u0258\u0259\u0005s\u0000\u0000\u0259"+ - "l\u0001\u0000\u0000\u0000\u025a\u025b\u0005\'\u0000\u0000\u025b\u025c"+ - "\u0005_\u0000\u0000\u025cn\u0001\u0000\u0000\u0000\u025d\u025e\u0005$"+ - "\u0000\u0000\u025e\u025f\u0005c\u0000\u0000\u025f\u0260\u0005r\u0000\u0000"+ - "\u0260\u0261\u0005a\u0000\u0000\u0261\u0262\u0005t\u0000\u0000\u0262\u0263"+ - "\u0005e\u0000\u0000\u0263p\u0001\u0000\u0000\u0000\u0264\u0268\u0003s"+ - "9\u0000\u0265\u0267\u0003u:\u0000\u0266\u0265\u0001\u0000\u0000\u0000"+ - "\u0267\u026a\u0001\u0000\u0000\u0000\u0268\u0266\u0001\u0000\u0000\u0000"+ - "\u0268\u0269\u0001\u0000\u0000\u0000\u0269\u0272\u0001\u0000\u0000\u0000"+ - "\u026a\u0268\u0001\u0000\u0000\u0000\u026b\u026d\u0005_\u0000\u0000\u026c"+ - "\u026e\u0003u:\u0000\u026d\u026c\u0001\u0000\u0000\u0000\u026e\u026f\u0001"+ - "\u0000\u0000\u0000\u026f\u026d\u0001\u0000\u0000\u0000\u026f\u0270\u0001"+ - "\u0000\u0000\u0000\u0270\u0272\u0001\u0000\u0000\u0000\u0271\u0264\u0001"+ - "\u0000\u0000\u0000\u0271\u026b\u0001\u0000\u0000\u0000\u0272r\u0001\u0000"+ - "\u0000\u0000\u0273\u0276\u0007\u0000\u0000\u0000\u0274\u0276\u0003w;\u0000"+ - "\u0275\u0273\u0001\u0000\u0000\u0000\u0275\u0274\u0001\u0000\u0000\u0000"+ - "\u0276t\u0001\u0000\u0000\u0000\u0277\u027b\u0003s9\u0000\u0278\u027b"+ - "\u0007\u0001\u0000\u0000\u0279\u027b\u0003y<\u0000\u027a\u0277\u0001\u0000"+ - "\u0000\u0000\u027a\u0278\u0001\u0000\u0000\u0000\u027a\u0279\u0001\u0000"+ - "\u0000\u0000\u027bv\u0001\u0000\u0000\u0000\u027c\u027d\u0007\u0002\u0000"+ - "\u0000\u027dx\u0001\u0000\u0000\u0000\u027e\u027f\u0007\u0003\u0000\u0000"+ - "\u027fz\u0001\u0000\u0000\u0000\u0280\u0281\u0005r\u0000\u0000\u0281\u0282"+ - "\u0005#\u0000\u0000\u0282\u0283\u0001\u0000\u0000\u0000\u0283\u0284\u0003"+ - "q8\u0000\u0284|\u0001\u0000\u0000\u0000\u0285\u0286\u0005/\u0000\u0000"+ - "\u0286\u0287\u0005/\u0000\u0000\u0287\u028b\u0001\u0000\u0000\u0000\u0288"+ - "\u028c\b\u0004\u0000\u0000\u0289\u028a\u0005/\u0000\u0000\u028a\u028c"+ - "\u0005/\u0000\u0000\u028b\u0288\u0001\u0000\u0000\u0000\u028b\u0289\u0001"+ - "\u0000\u0000\u0000\u028c\u0290\u0001\u0000\u0000\u0000\u028d\u028f\b\u0005"+ - "\u0000\u0000\u028e\u028d\u0001\u0000\u0000\u0000\u028f\u0292\u0001\u0000"+ - "\u0000\u0000\u0290\u028e\u0001\u0000\u0000\u0000\u0290\u0291\u0001\u0000"+ - "\u0000\u0000\u0291\u0296\u0001\u0000\u0000\u0000\u0292\u0290\u0001\u0000"+ - "\u0000\u0000\u0293\u0294\u0005/\u0000\u0000\u0294\u0296\u0005/\u0000\u0000"+ - "\u0295\u0285\u0001\u0000\u0000\u0000\u0295\u0293\u0001\u0000\u0000\u0000"+ - "\u0296\u0297\u0001\u0000\u0000\u0000\u0297\u0298\u0006>\u0000\u0000\u0298"+ - "~\u0001\u0000\u0000\u0000\u0299\u029a\u0005/\u0000\u0000\u029a\u029b\u0005"+ - "*\u0000\u0000\u029b\u02a0\u0001\u0000\u0000\u0000\u029c\u02a1\b\u0006"+ - "\u0000\u0000\u029d\u029e\u0005*\u0000\u0000\u029e\u02a1\u0005*\u0000\u0000"+ - "\u029f\u02a1\u0003\u0089D\u0000\u02a0\u029c\u0001\u0000\u0000\u0000\u02a0"+ - "\u029d\u0001\u0000\u0000\u0000\u02a0\u029f\u0001\u0000\u0000\u0000\u02a1"+ - "\u02a6\u0001\u0000\u0000\u0000\u02a2\u02a5\u0003\u0089D\u0000\u02a3\u02a5"+ - "\b\u0007\u0000\u0000\u02a4\u02a2\u0001\u0000\u0000\u0000\u02a4\u02a3\u0001"+ - "\u0000\u0000\u0000\u02a5\u02a8\u0001\u0000\u0000\u0000\u02a6\u02a7\u0001"+ - "\u0000\u0000\u0000\u02a6\u02a4\u0001\u0000\u0000\u0000\u02a7\u02a9\u0001"+ - "\u0000\u0000\u0000\u02a8\u02a6\u0001\u0000\u0000\u0000\u02a9\u02aa\u0005"+ - "*\u0000\u0000\u02aa\u02b5\u0005/\u0000\u0000\u02ab\u02ac\u0005/\u0000"+ - "\u0000\u02ac\u02ad\u0005*\u0000\u0000\u02ad\u02ae\u0005*\u0000\u0000\u02ae"+ - "\u02b5\u0005/\u0000\u0000\u02af\u02b0\u0005/\u0000\u0000\u02b0\u02b1\u0005"+ - "*\u0000\u0000\u02b1\u02b2\u0005*\u0000\u0000\u02b2\u02b3\u0005*\u0000"+ - "\u0000\u02b3\u02b5\u0005/\u0000\u0000\u02b4\u0299\u0001\u0000\u0000\u0000"+ - "\u02b4\u02ab\u0001\u0000\u0000\u0000\u02b4\u02af\u0001\u0000\u0000\u0000"+ - "\u02b5\u02b6\u0001\u0000\u0000\u0000\u02b6\u02b7\u0006?\u0000\u0000\u02b7"+ - "\u0080\u0001\u0000\u0000\u0000\u02b8\u02b9\u0005/\u0000\u0000\u02b9\u02ba"+ - "\u0005/\u0000\u0000\u02ba\u02bb\u0005!\u0000\u0000\u02bb\u02bf\u0001\u0000"+ - "\u0000\u0000\u02bc\u02be\b\u0005\u0000\u0000\u02bd\u02bc\u0001\u0000\u0000"+ - "\u0000\u02be\u02c1\u0001\u0000\u0000\u0000\u02bf\u02bd\u0001\u0000\u0000"+ - "\u0000\u02bf\u02c0\u0001\u0000\u0000\u0000\u02c0\u02c2\u0001\u0000\u0000"+ - "\u0000\u02c1\u02bf\u0001\u0000\u0000\u0000\u02c2\u02c3\u0006@\u0000\u0000"+ - "\u02c3\u0082\u0001\u0000\u0000\u0000\u02c4\u02c5\u0005/\u0000\u0000\u02c5"+ - "\u02c6\u0005*\u0000\u0000\u02c6\u02c7\u0005!\u0000\u0000\u02c7\u02cc\u0001"+ - "\u0000\u0000\u0000\u02c8\u02cb\u0003\u0089D\u0000\u02c9\u02cb\b\u0007"+ - "\u0000\u0000\u02ca\u02c8\u0001\u0000\u0000\u0000\u02ca\u02c9\u0001\u0000"+ - "\u0000\u0000\u02cb\u02ce\u0001\u0000\u0000\u0000\u02cc\u02cd\u0001\u0000"+ - "\u0000\u0000\u02cc\u02ca\u0001\u0000\u0000\u0000\u02cd\u02cf\u0001\u0000"+ - "\u0000\u0000\u02ce\u02cc\u0001\u0000\u0000\u0000\u02cf\u02d0\u0005*\u0000"+ - "\u0000\u02d0\u02d1\u0005/\u0000\u0000\u02d1\u02d2\u0001\u0000\u0000\u0000"+ - "\u02d2\u02d3\u0006A\u0000\u0000\u02d3\u0084\u0001\u0000\u0000\u0000\u02d4"+ - "\u02d5\u0005/\u0000\u0000\u02d5\u02d6\u0005/\u0000\u0000\u02d6\u02d7\u0005"+ - "/\u0000\u0000\u02d7\u02df\u0001\u0000\u0000\u0000\u02d8\u02dc\b\b\u0000"+ - "\u0000\u02d9\u02db\b\u0005\u0000\u0000\u02da\u02d9\u0001\u0000\u0000\u0000"+ - "\u02db\u02de\u0001\u0000\u0000\u0000\u02dc\u02da\u0001\u0000\u0000\u0000"+ - "\u02dc\u02dd\u0001\u0000\u0000\u0000\u02dd\u02e0\u0001\u0000\u0000\u0000"+ - "\u02de\u02dc\u0001\u0000\u0000\u0000\u02df\u02d8\u0001\u0000\u0000\u0000"+ - "\u02df\u02e0\u0001\u0000\u0000\u0000\u02e0\u02e1\u0001\u0000\u0000\u0000"+ - "\u02e1\u02e2\u0006B\u0000\u0000\u02e2\u0086\u0001\u0000\u0000\u0000\u02e3"+ - "\u02e4\u0005/\u0000\u0000\u02e4\u02e5\u0005*\u0000\u0000\u02e5\u02e6\u0005"+ - "*\u0000\u0000\u02e6\u02e9\u0001\u0000\u0000\u0000\u02e7\u02ea\b\u0007"+ - "\u0000\u0000\u02e8\u02ea\u0003\u0089D\u0000\u02e9\u02e7\u0001\u0000\u0000"+ - "\u0000\u02e9\u02e8\u0001\u0000\u0000\u0000\u02ea\u02ef\u0001\u0000\u0000"+ - "\u0000\u02eb\u02ee\u0003\u0089D\u0000\u02ec\u02ee\b\u0007\u0000\u0000"+ - "\u02ed\u02eb\u0001\u0000\u0000\u0000\u02ed\u02ec\u0001\u0000\u0000\u0000"+ - "\u02ee\u02f1\u0001\u0000\u0000\u0000\u02ef\u02f0\u0001\u0000\u0000\u0000"+ - "\u02ef\u02ed\u0001\u0000\u0000\u0000\u02f0\u02f2\u0001\u0000\u0000\u0000"+ - "\u02f1\u02ef\u0001\u0000\u0000\u0000\u02f2\u02f3\u0005*\u0000\u0000\u02f3"+ - "\u02f4\u0005/\u0000\u0000\u02f4\u02f5\u0001\u0000\u0000\u0000\u02f5\u02f6"+ - "\u0006C\u0000\u0000\u02f6\u0088\u0001\u0000\u0000\u0000\u02f7\u02fb\u0003"+ - "\u007f?\u0000\u02f8\u02fb\u0003\u0083A\u0000\u02f9\u02fb\u0003\u0087C"+ - "\u0000\u02fa\u02f7\u0001\u0000\u0000\u0000\u02fa\u02f8\u0001\u0000\u0000"+ - "\u0000\u02fa\u02f9\u0001\u0000\u0000\u0000\u02fb\u02fc\u0001\u0000\u0000"+ - "\u0000\u02fc\u02fd\u0006D\u0000\u0000\u02fd\u008a\u0001\u0000\u0000\u0000"+ - "\u02fe\u0300\u0004E\u0000\u0000\u02ff\u0301\u0005\u8000\ufeff\u0000\u0000"+ - "\u0300\u02ff\u0001\u0000\u0000\u0000\u0300\u0301\u0001\u0000\u0000\u0000"+ - "\u0301\u0302\u0001\u0000\u0000\u0000\u0302\u0303\u0005#\u0000\u0000\u0303"+ - "\u0304\u0005!\u0000\u0000\u0304\u0308\u0001\u0000\u0000\u0000\u0305\u0307"+ - "\b\u0005\u0000\u0000\u0306\u0305\u0001\u0000\u0000\u0000\u0307\u030a\u0001"+ - "\u0000\u0000\u0000\u0308\u0306\u0001\u0000\u0000\u0000\u0308\u0309\u0001"+ - "\u0000\u0000\u0000\u0309\u030b\u0001\u0000\u0000\u0000\u030a\u0308\u0001"+ - "\u0000\u0000\u0000\u030b\u030c\u0006E\u0000\u0000\u030c\u008c\u0001\u0000"+ - "\u0000\u0000\u030d\u030e\u0007\t\u0000\u0000\u030e\u030f\u0001\u0000\u0000"+ - "\u0000\u030f\u0310\u0006F\u0000\u0000\u0310\u008e\u0001\u0000\u0000\u0000"+ - "\u0311\u0312\u0005\r\u0000\u0000\u0312\u0315\u0005\n\u0000\u0000\u0313"+ - "\u0315\u0007\u0005\u0000\u0000\u0314\u0311\u0001\u0000\u0000\u0000\u0314"+ - "\u0313\u0001\u0000\u0000\u0000\u0315\u0316\u0001\u0000\u0000\u0000\u0316"+ - "\u0317\u0006G\u0000\u0000\u0317\u0090\u0001\u0000\u0000\u0000\u0318\u031d"+ - "\u0005\'\u0000\u0000\u0319\u031e\b\n\u0000\u0000\u031a\u031e\u0003\u00a7"+ - "S\u0000\u031b\u031e\u0003\u009fO\u0000\u031c\u031e\u0003\u00a5R\u0000"+ - "\u031d\u0319\u0001\u0000\u0000\u0000\u031d\u031a\u0001\u0000\u0000\u0000"+ - "\u031d\u031b\u0001\u0000\u0000\u0000\u031d\u031c\u0001\u0000\u0000\u0000"+ - "\u031e\u031f\u0001\u0000\u0000\u0000\u031f\u0320\u0005\'\u0000\u0000\u0320"+ - "\u0092\u0001\u0000\u0000\u0000\u0321\u0329\u0005\"\u0000\u0000\u0322\u0328"+ - "\b\u000b\u0000\u0000\u0323\u0328\u0003\u00a7S\u0000\u0324\u0328\u0003"+ - "\u009fO\u0000\u0325\u0328\u0003\u00a5R\u0000\u0326\u0328\u0003\u00a9T"+ - "\u0000\u0327\u0322\u0001\u0000\u0000\u0000\u0327\u0323\u0001\u0000\u0000"+ - "\u0000\u0327\u0324\u0001\u0000\u0000\u0000\u0327\u0325\u0001\u0000\u0000"+ - "\u0000\u0327\u0326\u0001\u0000\u0000\u0000\u0328\u032b\u0001\u0000\u0000"+ - "\u0000\u0329\u0327\u0001\u0000\u0000\u0000\u0329\u032a\u0001\u0000\u0000"+ - "\u0000\u032a\u032c\u0001\u0000\u0000\u0000\u032b\u0329\u0001\u0000\u0000"+ - "\u0000\u032c\u032d\u0005\"\u0000\u0000\u032d\u0094\u0001\u0000\u0000\u0000"+ - "\u032e\u032f\u0005r\u0000\u0000\u032f\u0330\u0003\u0097K\u0000\u0330\u0096"+ - "\u0001\u0000\u0000\u0000\u0331\u0332\u0005#\u0000\u0000\u0332\u0333\u0003"+ - "\u0097K\u0000\u0333\u0334\u0005#\u0000\u0000\u0334\u033e\u0001\u0000\u0000"+ - "\u0000\u0335\u0339\u0005\"\u0000\u0000\u0336\u0338\t\u0000\u0000\u0000"+ - "\u0337\u0336\u0001\u0000\u0000\u0000\u0338\u033b\u0001\u0000\u0000\u0000"+ - "\u0339\u033a\u0001\u0000\u0000\u0000\u0339\u0337\u0001\u0000\u0000\u0000"+ - "\u033a\u033c\u0001\u0000\u0000\u0000\u033b\u0339\u0001\u0000\u0000\u0000"+ - "\u033c\u033e\u0005\"\u0000\u0000\u033d\u0331\u0001\u0000\u0000\u0000\u033d"+ - "\u0335\u0001\u0000\u0000\u0000\u033e\u0098\u0001\u0000\u0000\u0000\u033f"+ - "\u0340\u0005b\u0000\u0000\u0340\u0341\u0005\'\u0000\u0000\u0341\u0345"+ - "\u0001\u0000\u0000\u0000\u0342\u0346\t\u0000\u0000\u0000\u0343\u0346\u0003"+ - "\u00a7S\u0000\u0344\u0346\u0003\u00a1P\u0000\u0345\u0342\u0001\u0000\u0000"+ - "\u0000\u0345\u0343\u0001\u0000\u0000\u0000\u0345\u0344\u0001\u0000\u0000"+ - "\u0000\u0346\u0347\u0001\u0000\u0000\u0000\u0347\u0348\u0005\'\u0000\u0000"+ - "\u0348\u009a\u0001\u0000\u0000\u0000\u0349\u034a\u0005b\u0000\u0000\u034a"+ - "\u034b\u0005\"\u0000\u0000\u034b\u0351\u0001\u0000\u0000\u0000\u034c\u0350"+ - "\b\u000b\u0000\u0000\u034d\u0350\u0003\u00a7S\u0000\u034e\u0350\u0003"+ - "\u00a1P\u0000\u034f\u034c\u0001\u0000\u0000\u0000\u034f\u034d\u0001\u0000"+ - "\u0000\u0000\u034f\u034e\u0001\u0000\u0000\u0000\u0350\u0353\u0001\u0000"+ - "\u0000\u0000\u0351\u034f\u0001\u0000\u0000\u0000\u0351\u0352\u0001\u0000"+ - "\u0000\u0000\u0352\u0354\u0001\u0000\u0000\u0000\u0353\u0351\u0001\u0000"+ - "\u0000\u0000\u0354\u0355\u0005\"\u0000\u0000\u0355\u009c\u0001\u0000\u0000"+ - "\u0000\u0356\u0357\u0005b\u0000\u0000\u0357\u0358\u0005r\u0000\u0000\u0358"+ - "\u0359\u0001\u0000\u0000\u0000\u0359\u035a\u0003\u0097K\u0000\u035a\u009e"+ - "\u0001\u0000\u0000\u0000\u035b\u035c\u0005\\\u0000\u0000\u035c\u035d\u0005"+ - "x\u0000\u0000\u035d\u035e\u0001\u0000\u0000\u0000\u035e\u035f\u0003\u00bd"+ - "^\u0000\u035f\u0360\u0003\u00c1`\u0000\u0360\u0363\u0001\u0000\u0000\u0000"+ - "\u0361\u0363\u0003\u00a3Q\u0000\u0362\u035b\u0001\u0000\u0000\u0000\u0362"+ - "\u0361\u0001\u0000\u0000\u0000\u0363\u00a0\u0001\u0000\u0000\u0000\u0364"+ - "\u0365\u0005\\\u0000\u0000\u0365\u0366\u0005x\u0000\u0000\u0366\u0367"+ - "\u0001\u0000\u0000\u0000\u0367\u0368\u0003\u00c1`\u0000\u0368\u0369\u0003"+ - "\u00c1`\u0000\u0369\u036c\u0001\u0000\u0000\u0000\u036a\u036c\u0003\u00a3"+ - "Q\u0000\u036b\u0364\u0001\u0000\u0000\u0000\u036b\u036a\u0001\u0000\u0000"+ - "\u0000\u036c\u00a2\u0001\u0000\u0000\u0000\u036d\u036e\u0005\\\u0000\u0000"+ - "\u036e\u036f\u0007\f\u0000\u0000\u036f\u00a4\u0001\u0000\u0000\u0000\u0370"+ - "\u0371\u0005\\\u0000\u0000\u0371\u0372\u0005u\u0000\u0000\u0372\u0373"+ - "\u0005{\u0000\u0000\u0373\u0374\u0001\u0000\u0000\u0000\u0374\u0376\u0003"+ - "\u00c1`\u0000\u0375\u0377\u0003\u00c1`\u0000\u0376\u0375\u0001\u0000\u0000"+ - "\u0000\u0376\u0377\u0001\u0000\u0000\u0000\u0377\u0379\u0001\u0000\u0000"+ - "\u0000\u0378\u037a\u0003\u00c1`\u0000\u0379\u0378\u0001\u0000\u0000\u0000"+ - "\u0379\u037a\u0001\u0000\u0000\u0000\u037a\u037c\u0001\u0000\u0000\u0000"+ - "\u037b\u037d\u0003\u00c1`\u0000\u037c\u037b\u0001\u0000\u0000\u0000\u037c"+ - "\u037d\u0001\u0000\u0000\u0000\u037d\u037f\u0001\u0000\u0000\u0000\u037e"+ - "\u0380\u0003\u00c1`\u0000\u037f\u037e\u0001\u0000\u0000\u0000\u037f\u0380"+ - "\u0001\u0000\u0000\u0000\u0380\u0382\u0001\u0000\u0000\u0000\u0381\u0383"+ - "\u0003\u00c1`\u0000\u0382\u0381\u0001\u0000\u0000\u0000\u0382\u0383\u0001"+ - "\u0000\u0000\u0000\u0383\u0384\u0001\u0000\u0000\u0000\u0384\u0385\u0005"+ - "}\u0000\u0000\u0385\u00a6\u0001\u0000\u0000\u0000\u0386\u0387\u0005\\"+ - "\u0000\u0000\u0387\u0388\u0007\r\u0000\u0000\u0388\u00a8\u0001\u0000\u0000"+ - "\u0000\u0389\u038a\u0005\\\u0000\u0000\u038a\u038b\u0005\n\u0000\u0000"+ - "\u038b\u00aa\u0001\u0000\u0000\u0000\u038c\u0391\u0003\u00adV\u0000\u038d"+ - "\u0391\u0003\u00b3Y\u0000\u038e\u0391\u0003\u00b1X\u0000\u038f\u0391\u0003"+ - "\u00afW\u0000\u0390\u038c\u0001\u0000\u0000\u0000\u0390\u038d\u0001\u0000"+ - "\u0000\u0000\u0390\u038e\u0001\u0000\u0000\u0000\u0390\u038f\u0001\u0000"+ - "\u0000\u0000\u0391\u0393\u0001\u0000\u0000\u0000\u0392\u0394\u0003\u00b7"+ - "[\u0000\u0393\u0392\u0001\u0000\u0000\u0000\u0393\u0394\u0001\u0000\u0000"+ - "\u0000\u0394\u00ac\u0001\u0000\u0000\u0000\u0395\u039a\u0003\u00bf_\u0000"+ - "\u0396\u0399\u0003\u00bf_\u0000\u0397\u0399\u0005_\u0000\u0000\u0398\u0396"+ - "\u0001\u0000\u0000\u0000\u0398\u0397\u0001\u0000\u0000\u0000\u0399\u039c"+ - "\u0001\u0000\u0000\u0000\u039a\u0398\u0001\u0000\u0000\u0000\u039a\u039b"+ - "\u0001\u0000\u0000\u0000\u039b\u00ae\u0001\u0000\u0000\u0000\u039c\u039a"+ - "\u0001\u0000\u0000\u0000\u039d\u039e\u00050\u0000\u0000\u039e\u039f\u0005"+ - "x\u0000\u0000\u039f\u03a3\u0001\u0000\u0000\u0000\u03a0\u03a2\u0005_\u0000"+ - "\u0000\u03a1\u03a0\u0001\u0000\u0000\u0000\u03a2\u03a5\u0001\u0000\u0000"+ - "\u0000\u03a3\u03a1\u0001\u0000\u0000\u0000\u03a3\u03a4\u0001\u0000\u0000"+ - "\u0000\u03a4\u03a6\u0001\u0000\u0000\u0000\u03a5\u03a3\u0001\u0000\u0000"+ - "\u0000\u03a6\u03ab\u0003\u00c1`\u0000\u03a7\u03aa\u0003\u00c1`\u0000\u03a8"+ - "\u03aa\u0005_\u0000\u0000\u03a9\u03a7\u0001\u0000\u0000\u0000\u03a9\u03a8"+ - "\u0001\u0000\u0000\u0000\u03aa\u03ad\u0001\u0000\u0000\u0000\u03ab\u03a9"+ - "\u0001\u0000\u0000\u0000\u03ab\u03ac\u0001\u0000\u0000\u0000\u03ac\u00b0"+ - "\u0001\u0000\u0000\u0000\u03ad\u03ab\u0001\u0000\u0000\u0000\u03ae\u03af"+ - "\u00050\u0000\u0000\u03af\u03b0\u0005o\u0000\u0000\u03b0\u03b4\u0001\u0000"+ - "\u0000\u0000\u03b1\u03b3\u0005_\u0000\u0000\u03b2\u03b1\u0001\u0000\u0000"+ - "\u0000\u03b3\u03b6\u0001\u0000\u0000\u0000\u03b4\u03b2\u0001\u0000\u0000"+ - "\u0000\u03b4\u03b5\u0001\u0000\u0000\u0000\u03b5\u03b7\u0001\u0000\u0000"+ - "\u0000\u03b6\u03b4\u0001\u0000\u0000\u0000\u03b7\u03bc\u0003\u00bd^\u0000"+ - "\u03b8\u03bb\u0003\u00bd^\u0000\u03b9\u03bb\u0005_\u0000\u0000\u03ba\u03b8"+ - "\u0001\u0000\u0000\u0000\u03ba\u03b9\u0001\u0000\u0000\u0000\u03bb\u03be"+ - "\u0001\u0000\u0000\u0000\u03bc\u03ba\u0001\u0000\u0000\u0000\u03bc\u03bd"+ - "\u0001\u0000\u0000\u0000\u03bd\u00b2\u0001\u0000\u0000\u0000\u03be\u03bc"+ - "\u0001\u0000\u0000\u0000\u03bf\u03c0\u00050\u0000\u0000\u03c0\u03c1\u0005"+ - "b\u0000\u0000\u03c1\u03c5\u0001\u0000\u0000\u0000\u03c2\u03c4\u0005_\u0000"+ - "\u0000\u03c3\u03c2\u0001\u0000\u0000\u0000\u03c4\u03c7\u0001\u0000\u0000"+ - "\u0000\u03c5\u03c3\u0001\u0000\u0000\u0000\u03c5\u03c6\u0001\u0000\u0000"+ - "\u0000\u03c6\u03c8\u0001\u0000\u0000\u0000\u03c7\u03c5\u0001\u0000\u0000"+ - "\u0000\u03c8\u03cc\u0007\u000e\u0000\u0000\u03c9\u03cb\u0007\u000f\u0000"+ - "\u0000\u03ca\u03c9\u0001\u0000\u0000\u0000\u03cb\u03ce\u0001\u0000\u0000"+ - "\u0000\u03cc\u03ca\u0001\u0000\u0000\u0000\u03cc\u03cd\u0001\u0000\u0000"+ - "\u0000\u03cd\u00b4\u0001\u0000\u0000\u0000\u03ce\u03cc\u0001\u0000\u0000"+ - "\u0000\u03cf\u03df\u0004Z\u0001\u0000\u03d0\u03d1\u0003\u00adV\u0000\u03d1"+ - "\u03d2\u0005.\u0000\u0000\u03d2\u03d3\u0004Z\u0002\u0000\u03d3\u03e0\u0001"+ - "\u0000\u0000\u0000\u03d4\u03d7\u0003\u00adV\u0000\u03d5\u03d6\u0005.\u0000"+ - "\u0000\u03d6\u03d8\u0003\u00adV\u0000\u03d7\u03d5\u0001\u0000\u0000\u0000"+ - "\u03d7\u03d8\u0001\u0000\u0000\u0000\u03d8\u03da\u0001\u0000\u0000\u0000"+ - "\u03d9\u03db\u0003\u00bb]\u0000\u03da\u03d9\u0001\u0000\u0000\u0000\u03da"+ - "\u03db\u0001\u0000\u0000\u0000\u03db\u03dd\u0001\u0000\u0000\u0000\u03dc"+ - "\u03de\u0003\u00b9\\\u0000\u03dd\u03dc\u0001\u0000\u0000\u0000\u03dd\u03de"+ - "\u0001\u0000\u0000\u0000\u03de\u03e0\u0001\u0000\u0000\u0000\u03df\u03d0"+ - "\u0001\u0000\u0000\u0000\u03df\u03d4\u0001\u0000\u0000\u0000\u03e0\u00b6"+ - "\u0001\u0000\u0000\u0000\u03e1\u03e2\u0005u\u0000\u0000\u03e2\u040a\u0005"+ - "8\u0000\u0000\u03e3\u03e4\u0005u\u0000\u0000\u03e4\u03e5\u00051\u0000"+ - "\u0000\u03e5\u040a\u00056\u0000\u0000\u03e6\u03e7\u0005u\u0000\u0000\u03e7"+ - "\u03e8\u00053\u0000\u0000\u03e8\u040a\u00052\u0000\u0000\u03e9\u03ea\u0005"+ - "u\u0000\u0000\u03ea\u03eb\u00056\u0000\u0000\u03eb\u040a\u00054\u0000"+ - "\u0000\u03ec\u03ed\u0005u\u0000\u0000\u03ed\u03ee\u00051\u0000\u0000\u03ee"+ - "\u03ef\u00052\u0000\u0000\u03ef\u040a\u00058\u0000\u0000\u03f0\u03f1\u0005"+ - "u\u0000\u0000\u03f1\u03f2\u0005s\u0000\u0000\u03f2\u03f3\u0005i\u0000"+ - "\u0000\u03f3\u03f4\u0005z\u0000\u0000\u03f4\u040a\u0005e\u0000\u0000\u03f5"+ - "\u03f6\u0005i\u0000\u0000\u03f6\u040a\u00058\u0000\u0000\u03f7\u03f8\u0005"+ - "i\u0000\u0000\u03f8\u03f9\u00051\u0000\u0000\u03f9\u040a\u00056\u0000"+ - "\u0000\u03fa\u03fb\u0005i\u0000\u0000\u03fb\u03fc\u00053\u0000\u0000\u03fc"+ - "\u040a\u00052\u0000\u0000\u03fd\u03fe\u0005i\u0000\u0000\u03fe\u03ff\u0005"+ - "6\u0000\u0000\u03ff\u040a\u00054\u0000\u0000\u0400\u0401\u0005i\u0000"+ - "\u0000\u0401\u0402\u00051\u0000\u0000\u0402\u0403\u00052\u0000\u0000\u0403"+ - "\u040a\u00058\u0000\u0000\u0404\u0405\u0005i\u0000\u0000\u0405\u0406\u0005"+ - "s\u0000\u0000\u0406\u0407\u0005i\u0000\u0000\u0407\u0408\u0005z\u0000"+ - "\u0000\u0408\u040a\u0005e\u0000\u0000\u0409\u03e1\u0001\u0000\u0000\u0000"+ - "\u0409\u03e3\u0001\u0000\u0000\u0000\u0409\u03e6\u0001\u0000\u0000\u0000"+ - "\u0409\u03e9\u0001\u0000\u0000\u0000\u0409\u03ec\u0001\u0000\u0000\u0000"+ - "\u0409\u03f0\u0001\u0000\u0000\u0000\u0409\u03f5\u0001\u0000\u0000\u0000"+ - "\u0409\u03f7\u0001\u0000\u0000\u0000\u0409\u03fa\u0001\u0000\u0000\u0000"+ - "\u0409\u03fd\u0001\u0000\u0000\u0000\u0409\u0400\u0001\u0000\u0000\u0000"+ - "\u0409\u0404\u0001\u0000\u0000\u0000\u040a\u00b8\u0001\u0000\u0000\u0000"+ - "\u040b\u040c\u0005f\u0000\u0000\u040c\u040d\u00053\u0000\u0000\u040d\u0412"+ - "\u00052\u0000\u0000\u040e\u040f\u0005f\u0000\u0000\u040f\u0410\u00056"+ - "\u0000\u0000\u0410\u0412\u00054\u0000\u0000\u0411\u040b\u0001\u0000\u0000"+ - "\u0000\u0411\u040e\u0001\u0000\u0000\u0000\u0412\u00ba\u0001\u0000\u0000"+ - "\u0000\u0413\u0415\u0007\u0010\u0000\u0000\u0414\u0416\u0007\u0011\u0000"+ - "\u0000\u0415\u0414\u0001\u0000\u0000\u0000\u0415\u0416\u0001\u0000\u0000"+ - "\u0000\u0416\u041a\u0001\u0000\u0000\u0000\u0417\u0419\u0005_\u0000\u0000"+ - "\u0418\u0417\u0001\u0000\u0000\u0000\u0419\u041c\u0001\u0000\u0000\u0000"+ - "\u041a\u0418\u0001\u0000\u0000\u0000\u041a\u041b\u0001\u0000\u0000\u0000"+ - "\u041b\u041d\u0001\u0000\u0000\u0000\u041c\u041a\u0001\u0000\u0000\u0000"+ - "\u041d\u041e\u0003\u00adV\u0000\u041e\u00bc\u0001\u0000\u0000\u0000\u041f"+ - "\u0420\u0007\u0012\u0000\u0000\u0420\u00be\u0001\u0000\u0000\u0000\u0421"+ - "\u0422\u0007\u0013\u0000\u0000\u0422\u00c0\u0001\u0000\u0000\u0000\u0423"+ - "\u0424\u0007\u0014\u0000\u0000\u0424\u00c2\u0001\u0000\u0000\u0000\u0425"+ - "\u0426\u0005\'\u0000\u0000\u0426\u0427\u0003q8\u0000\u0427\u00c4\u0001"+ - "\u0000\u0000\u0000\u0428\u0429\u0005+\u0000\u0000\u0429\u00c6\u0001\u0000"+ - "\u0000\u0000\u042a\u042b\u0005-\u0000\u0000\u042b\u00c8\u0001\u0000\u0000"+ - "\u0000\u042c\u042d\u0005*\u0000\u0000\u042d\u00ca\u0001\u0000\u0000\u0000"+ - "\u042e\u042f\u0005/\u0000\u0000\u042f\u00cc\u0001\u0000\u0000\u0000\u0430"+ - "\u0431\u0005%\u0000\u0000\u0431\u00ce\u0001\u0000\u0000\u0000\u0432\u0433"+ - "\u0005^\u0000\u0000\u0433\u00d0\u0001\u0000\u0000\u0000\u0434\u0435\u0005"+ - "!\u0000\u0000\u0435\u00d2\u0001\u0000\u0000\u0000\u0436\u0437\u0005&\u0000"+ - "\u0000\u0437\u00d4\u0001\u0000\u0000\u0000\u0438\u0439\u0005|\u0000\u0000"+ - "\u0439\u00d6\u0001\u0000\u0000\u0000\u043a\u043b\u0005&\u0000\u0000\u043b"+ - "\u043c\u0005&\u0000\u0000\u043c\u00d8\u0001\u0000\u0000\u0000\u043d\u043e"+ - "\u0005|\u0000\u0000\u043e\u043f\u0005|\u0000\u0000\u043f\u00da\u0001\u0000"+ - "\u0000\u0000\u0440\u0441\u0005+\u0000\u0000\u0441\u0442\u0005=\u0000\u0000"+ - "\u0442\u00dc\u0001\u0000\u0000\u0000\u0443\u0444\u0005-\u0000\u0000\u0444"+ - "\u0445\u0005=\u0000\u0000\u0445\u00de\u0001\u0000\u0000\u0000\u0446\u0447"+ - "\u0005*\u0000\u0000\u0447\u0448\u0005=\u0000\u0000\u0448\u00e0\u0001\u0000"+ - "\u0000\u0000\u0449\u044a\u0005/\u0000\u0000\u044a\u044b\u0005=\u0000\u0000"+ - "\u044b\u00e2\u0001\u0000\u0000\u0000\u044c\u044d\u0005%\u0000\u0000\u044d"+ - "\u044e\u0005=\u0000\u0000\u044e\u00e4\u0001\u0000\u0000\u0000\u044f\u0450"+ - "\u0005^\u0000\u0000\u0450\u0451\u0005=\u0000\u0000\u0451\u00e6\u0001\u0000"+ - "\u0000\u0000\u0452\u0453\u0005&\u0000\u0000\u0453\u0454\u0005=\u0000\u0000"+ - "\u0454\u00e8\u0001\u0000\u0000\u0000\u0455\u0456\u0005|\u0000\u0000\u0456"+ - "\u0457\u0005=\u0000\u0000\u0457\u00ea\u0001\u0000\u0000\u0000\u0458\u0459"+ - "\u0005<\u0000\u0000\u0459\u045a\u0005<\u0000\u0000\u045a\u045b\u0005="+ - "\u0000\u0000\u045b\u00ec\u0001\u0000\u0000\u0000\u045c\u045d\u0005>\u0000"+ - "\u0000\u045d\u045e\u0005>\u0000\u0000\u045e\u045f\u0005=\u0000\u0000\u045f"+ - "\u00ee\u0001\u0000\u0000\u0000\u0460\u0461\u0005=\u0000\u0000\u0461\u00f0"+ - "\u0001\u0000\u0000\u0000\u0462\u0463\u0005=\u0000\u0000\u0463\u0464\u0005"+ - "=\u0000\u0000\u0464\u00f2\u0001\u0000\u0000\u0000\u0465\u0466\u0005!\u0000"+ - "\u0000\u0466\u0467\u0005=\u0000\u0000\u0467\u00f4\u0001\u0000\u0000\u0000"+ - "\u0468\u0469\u0005>\u0000\u0000\u0469\u00f6\u0001\u0000\u0000\u0000\u046a"+ - "\u046b\u0005<\u0000\u0000\u046b\u00f8\u0001\u0000\u0000\u0000\u046c\u046d"+ - "\u0005>\u0000\u0000\u046d\u046e\u0005=\u0000\u0000\u046e\u00fa\u0001\u0000"+ - "\u0000\u0000\u046f\u0470\u0005<\u0000\u0000\u0470\u0471\u0005=\u0000\u0000"+ - "\u0471\u00fc\u0001\u0000\u0000\u0000\u0472\u0473\u0005@\u0000\u0000\u0473"+ - "\u00fe\u0001\u0000\u0000\u0000\u0474\u0475\u0005_\u0000\u0000\u0475\u0100"+ - "\u0001\u0000\u0000\u0000\u0476\u0477\u0005.\u0000\u0000\u0477\u0102\u0001"+ - "\u0000\u0000\u0000\u0478\u0479\u0005.\u0000\u0000\u0479\u047a\u0005.\u0000"+ - "\u0000\u047a\u0104\u0001\u0000\u0000\u0000\u047b\u047c\u0005.\u0000\u0000"+ - "\u047c\u047d\u0005.\u0000\u0000\u047d\u047e\u0005.\u0000\u0000\u047e\u0106"+ - "\u0001\u0000\u0000\u0000\u047f\u0480\u0005.\u0000\u0000\u0480\u0481\u0005"+ - ".\u0000\u0000\u0481\u0482\u0005=\u0000\u0000\u0482\u0108\u0001\u0000\u0000"+ - "\u0000\u0483\u0484\u0005,\u0000\u0000\u0484\u010a\u0001\u0000\u0000\u0000"+ - "\u0485\u0486\u0005;\u0000\u0000\u0486\u010c\u0001\u0000\u0000\u0000\u0487"+ - "\u0488\u0005:\u0000\u0000\u0488\u010e\u0001\u0000\u0000\u0000\u0489\u048a"+ - "\u0005:\u0000\u0000\u048a\u048b\u0005:\u0000\u0000\u048b\u0110\u0001\u0000"+ - "\u0000\u0000\u048c\u048d\u0005-\u0000\u0000\u048d\u048e\u0005>\u0000\u0000"+ - "\u048e\u0112\u0001\u0000\u0000\u0000\u048f\u0490\u0005=\u0000\u0000\u0490"+ - "\u0491\u0005>\u0000\u0000\u0491\u0114\u0001\u0000\u0000\u0000\u0492\u0493"+ - "\u0005#\u0000\u0000\u0493\u0116\u0001\u0000\u0000\u0000\u0494\u0495\u0005"+ - "$\u0000\u0000\u0495\u0118\u0001\u0000\u0000\u0000\u0496\u0497\u0005?\u0000"+ - "\u0000\u0497\u011a\u0001\u0000\u0000\u0000\u0498\u0499\u0005{\u0000\u0000"+ - "\u0499\u011c\u0001\u0000\u0000\u0000\u049a\u049b\u0005}\u0000\u0000\u049b"+ - "\u011e\u0001\u0000\u0000\u0000\u049c\u049d\u0005[\u0000\u0000\u049d\u0120"+ - "\u0001\u0000\u0000\u0000\u049e\u049f\u0005]\u0000\u0000\u049f\u0122\u0001"+ - "\u0000\u0000\u0000\u04a0\u04a1\u0005(\u0000\u0000\u04a1\u0124\u0001\u0000"+ - "\u0000\u0000\u04a2\u04a3\u0005)\u0000\u0000\u04a3\u0126\u0001\u0000\u0000"+ - "\u0000<\u0000\u0268\u026f\u0271\u0275\u027a\u028b\u0290\u0295\u02a0\u02a4"+ - "\u02a6\u02b4\u02bf\u02ca\u02cc\u02dc\u02df\u02e9\u02ed\u02ef\u02fa\u0300"+ - "\u0308\u0314\u031d\u0327\u0329\u0339\u033d\u0345\u034f\u0351\u0362\u036b"+ - "\u0376\u0379\u037c\u037f\u0382\u0390\u0393\u0398\u039a\u03a3\u03a9\u03ab"+ - "\u03b4\u03ba\u03bc\u03c5\u03cc\u03d7\u03da\u03dd\u03df\u0409\u0411\u0415"+ - "\u041a\u0001\u0000\u0001\u0000"; - public static final ATN _ATN = - new ATNDeserializer().deserialize(_serializedATN.toCharArray()); - static { - _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; - for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { - _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); - } - } -} -// CPD-ON: End suppressing CPD checks for generated code -// CHECKSTYLE:ON diff --git a/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/ast/RustLexerBase.java b/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/ast/RustLexerBase.java deleted file mode 100644 index 9103fdb7eee..00000000000 --- a/pmd-rust/src/main/java/net/sourceforge/pmd/lang/rust/ast/RustLexerBase.java +++ /dev/null @@ -1,84 +0,0 @@ -// CHECKSTYLE:OFF -package net.sourceforge.pmd.lang.rust.ast; - -import org.antlr.v4.runtime.*; - -public abstract class RustLexerBase extends Lexer{ - public RustLexerBase(CharStream input){ - super(input); - } - - Token current; - Token previous; - - @Override - public Token nextToken() { - Token next = super.nextToken(); - - if (next.getChannel() == Token.DEFAULT_CHANNEL) { - // Keep track of the last token on the default channel. - this.previous = this.current; - this.current = next; - } - - return next; - } - - public boolean SOF(){ - return _input.LA(-1) <=0; - } - - public boolean next(char expect){ - return _input.LA(1) == expect; - } - - public boolean floatDotPossible(){ - int next = _input.LA(1); - // only block . _ identifier after float - if(next == '.' || next =='_') { return false; } - if(next == 'f') { - return _input.LA(2)=='3'&&_input.LA(3)=='2' || _input.LA(2)=='6'&&_input.LA(3)=='4'; - } - if(next>='a'&&next<='z') { return false; } - return next>='A'&&next<='Z'; - } - - public boolean floatLiteralPossible(){ - if(this.current == null || this.previous == null) { return true; } - if(this.current.getType() != RustLexer.DOT) { return true; } - switch (this.previous.getType()){ - case RustLexer.CHAR_LITERAL: - case RustLexer.STRING_LITERAL: - case RustLexer.RAW_STRING_LITERAL: - case RustLexer.BYTE_LITERAL: - case RustLexer.BYTE_STRING_LITERAL: - case RustLexer.RAW_BYTE_STRING_LITERAL: - case RustLexer.INTEGER_LITERAL: - case RustLexer.DEC_LITERAL: - case RustLexer.HEX_LITERAL: - case RustLexer.OCT_LITERAL: - case RustLexer.BIN_LITERAL: - - case RustLexer.KW_SUPER: - case RustLexer.KW_SELFVALUE: - case RustLexer.KW_SELFTYPE: - case RustLexer.KW_CRATE: - case RustLexer.KW_DOLLARCRATE: - - case RustLexer.GT: - case RustLexer.RCURLYBRACE: - case RustLexer.RSQUAREBRACKET: - case RustLexer.RPAREN: - - case RustLexer.KW_AWAIT: - - case RustLexer.NON_KEYWORD_IDENTIFIER: - case RustLexer.RAW_IDENTIFIER: - case RustLexer.KW_MACRORULES: - return false; - default: - return true; - } - } -} -// CHECKSTYLE:ON From 4b773a003ab6e95fc1f4d2dbe87adeb1c28d2412 Mon Sep 17 00:00:00 2001 From: Julia Paluch Date: Sat, 21 Dec 2024 02:03:38 +0000 Subject: [PATCH 0389/1962] add support for backticks --- .../main/antlr4/net/sourceforge/pmd/lang/rust/ast/README.md | 4 +++- .../antlr4/net/sourceforge/pmd/lang/rust/ast/RustLexer.g4 | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/README.md b/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/README.md index 8122ccdc66e..d161f760510 100644 --- a/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/README.md +++ b/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/README.md @@ -28,4 +28,6 @@ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ## Modifications The custom functions defined [here](https://github.com/antlr/grammars-v4/blob/master/rust/Java/RustLexerBase.java) -have been inlined in and the dependency on `RustLexerBase` has been removed. +have been inlined and the dependency on `RustLexerBase` has been removed. + +Support for backticks ("`") has been added. diff --git a/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/RustLexer.g4 b/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/RustLexer.g4 index c592ddf3df6..c2d4c066ad7 100644 --- a/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/RustLexer.g4 +++ b/pmd-rust/src/main/antlr4/net/sourceforge/pmd/lang/rust/ast/RustLexer.g4 @@ -338,7 +338,7 @@ FATARROW : '=>'; POUND : '#'; DOLLAR : '$'; QUESTION : '?'; - +BACKTICK : '`'; LCURLYBRACE : '{'; RCURLYBRACE : '}'; LSQUAREBRACKET : '['; From abc84fd166d12dffca04da18dbdec49dc33de7a7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 03:11:21 +0000 Subject: [PATCH 0390/1962] Bump org.cyclonedx:cyclonedx-maven-plugin from 2.7.11 to 2.9.1 Bumps [org.cyclonedx:cyclonedx-maven-plugin](https://github.com/CycloneDX/cyclonedx-maven-plugin) from 2.7.11 to 2.9.1. - [Release notes](https://github.com/CycloneDX/cyclonedx-maven-plugin/releases) - [Commits](https://github.com/CycloneDX/cyclonedx-maven-plugin/compare/cyclonedx-maven-plugin-2.7.11...cyclonedx-maven-plugin-2.9.1) --- updated-dependencies: - dependency-name: org.cyclonedx:cyclonedx-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 32e665ecfda..29989056cca 100644 --- a/pom.xml +++ b/pom.xml @@ -622,7 +622,7 @@ org.cyclonedx cyclonedx-maven-plugin - 2.7.11 + 2.9.1 From bdc432233ec5f4c3738d21312b7c728ca073d88e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 03:11:27 +0000 Subject: [PATCH 0391/1962] Bump org.checkerframework:checker-qual from 3.48.1 to 3.48.3 Bumps [org.checkerframework:checker-qual](https://github.com/typetools/checker-framework) from 3.48.1 to 3.48.3. - [Release notes](https://github.com/typetools/checker-framework/releases) - [Changelog](https://github.com/typetools/checker-framework/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/typetools/checker-framework/compare/checker-framework-3.48.1...checker-framework-3.48.3) --- updated-dependencies: - dependency-name: org.checkerframework:checker-qual dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 32e665ecfda..802c8a4f45b 100644 --- a/pom.xml +++ b/pom.xml @@ -852,7 +852,7 @@ org.checkerframework checker-qual - 3.48.1 + 3.48.3 net.sf.saxon From 9a5e58a340e9794570771a94221299e41d9633cf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 09:50:21 +0100 Subject: [PATCH 0392/1962] Bump the all-gems group across 2 directories with 2 updates (#5422) Bumps the all-gems group with 1 update in the / directory: [liquid](https://github.com/Shopify/liquid). Bumps the all-gems group with 1 update in the /docs directory: [csv](https://github.com/ruby/csv). Updates `liquid` from 5.5.1 to 5.6.0 - [Release notes](https://github.com/Shopify/liquid/releases) - [Changelog](https://github.com/Shopify/liquid/blob/main/History.md) - [Commits](https://github.com/Shopify/liquid/compare/v5.5.1...v5.6.0) Updates `csv` from 3.3.1 to 3.3.2 - [Release notes](https://github.com/ruby/csv/releases) - [Changelog](https://github.com/ruby/csv/blob/master/NEWS.md) - [Commits](https://github.com/ruby/csv/compare/v3.3.1...v3.3.2) --- updated-dependencies: - dependency-name: liquid dependency-type: direct:development update-type: version-update:semver-minor dependency-group: all-gems - dependency-name: csv dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all-gems ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 5 ++++- docs/Gemfile.lock | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index f8a2bea4ede..23766fb4e64 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -50,7 +50,9 @@ GEM rexml kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) - liquid (5.5.1) + liquid (5.6.0) + bigdecimal + strscan logger (1.6.1) logger-colors (1.0.0) nap (1.1.0) @@ -83,6 +85,7 @@ GEM addressable (>= 2.3.5) faraday (>= 0.17.3, < 3) slop (4.10.1) + strscan (3.1.2) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) tzinfo (2.0.6) diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index af709969d26..e3cc6a1794a 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -26,7 +26,7 @@ GEM commonmarker (0.23.10) concurrent-ruby (1.3.4) connection_pool (2.4.1) - csv (3.3.1) + csv (3.3.2) dnsruby (1.72.2) simpleidn (~> 0.2.1) drb (2.2.1) From 6c4825f96090a3554b1b87702e3a19870758e215 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 09:50:49 +0100 Subject: [PATCH 0393/1962] Bump org.apache.maven.plugins:maven-checkstyle-plugin from 3.5.0 to 3.6.0 (#5419) Bump org.apache.maven.plugins:maven-checkstyle-plugin Bumps [org.apache.maven.plugins:maven-checkstyle-plugin](https://github.com/apache/maven-checkstyle-plugin) from 3.5.0 to 3.6.0. - [Commits](https://github.com/apache/maven-checkstyle-plugin/compare/maven-checkstyle-plugin-3.5.0...maven-checkstyle-plugin-3.6.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-checkstyle-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 74956fe6bb2..6b373820616 100644 --- a/pom.xml +++ b/pom.xml @@ -100,7 +100,7 @@ 5.0 3.5.2 10.20.2 - 3.5.0 + 3.6.0 3.26.0 1.10.15 3.11.2 From 7085e0dfe9e4c44c75448c3e552314d2d63abe7e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Dec 2024 09:00:49 +0100 Subject: [PATCH 0394/1962] [rust] Fix japicmp config to ignore missing old version --- pmd-rust/pom.xml | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index a4920b9c367..83c82adecf3 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -47,17 +47,13 @@ - + com.github.siom79.japicmp japicmp-maven-plugin - 0.23.0 - - - ${project.build.directory}/${project.artifactId}-${project.version}.jar - - - true + + true + From 4c58683eb00a02e82bce6655a1cbd3f4ab54d085 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Dec 2024 09:05:46 +0100 Subject: [PATCH 0395/1962] [doc] Add Rust as additional CPD language --- docs/_data/sidebars/pmd_sidebar.yml | 3 +++ docs/_plugins/jdoc_namespace_tag.rb | 2 +- docs/index.md | 2 +- docs/pages/pmd/languages/rust.md | 4 ++-- docs/pages/pmd/userdocs/cpd/cpd.md | 1 + pom.xml | 2 +- 6 files changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/_data/sidebars/pmd_sidebar.yml b/docs/_data/sidebars/pmd_sidebar.yml index 3378073c4b8..1a59e19ae65 100644 --- a/docs/_data/sidebars/pmd_sidebar.yml +++ b/docs/_data/sidebars/pmd_sidebar.yml @@ -499,6 +499,9 @@ entries: - title: Ruby url: /pmd_languages_ruby.html output: web, pdf + - title: Rust + url: /pmd_languages_rust.html + output: web, pdf - title: Scala url: /pmd_languages_scala.html output: web, pdf diff --git a/docs/_plugins/jdoc_namespace_tag.rb b/docs/_plugins/jdoc_namespace_tag.rb index 4688e860ce8..f6a1a1500df 100644 --- a/docs/_plugins/jdoc_namespace_tag.rb +++ b/docs/_plugins/jdoc_namespace_tag.rb @@ -102,7 +102,7 @@ def self.parse_fqcn(fqcn, var_ctx, allow_sym = true) RESERVED_NSPACES = ['ant', 'apex', 'cli', 'coco', 'core', 'cpp', 'cs', 'dart', 'dist', 'doc', 'fortran', 'gherkin', 'go', 'groovy', 'html', 'java', 'javascript', 'jsp', 'julia', - 'kotlin', 'lang-test', 'lua', 'matlab', 'objectivec', 'perl', 'php', 'plsql', 'python', 'ruby', 'scala', 'swift', + 'kotlin', 'lang-test', 'lua', 'matlab', 'objectivec', 'perl', 'php', 'plsql', 'python', 'ruby', 'rust', 'scala', 'swift', 'test', 'test-schema', 'tsql', 'ui', 'modelica', 'visualforce', 'velocity', 'xml', 'vm', # pre-pmd7 name for velocity, only useful for jdoc_old or jdoc_package_old diff --git a/docs/index.md b/docs/index.md index 3bafc43f4d6..0a9e0be8758 100644 --- a/docs/index.md +++ b/docs/index.md @@ -36,7 +36,7 @@ Scala is supported, but there are currently no Scala rules available. Additionally, it includes **CPD**, the copy-paste-detector. CPD finds duplicated code in Coco, C/C++, C#, Dart, Fortran, Gherkin, Go, Groovy, HTML, Java, JavaScript, JSP, Julia, Kotlin, -Lua, Matlab, Modelica, Objective-C, Perl, PHP, PLSQL, Python, Ruby, Salesforce.com Apex and +Lua, Matlab, Modelica, Objective-C, Perl, PHP, PLSQL, Python, Ruby, Rust, Salesforce.com Apex and Visualforce, Scala, Swift, T-SQL, Typescript, Apache Velocity, WSDL, XML and XSL. PMD features many **built-in checks** (in PMD lingo, *rules*), which are documented diff --git a/docs/pages/pmd/languages/rust.md b/docs/pages/pmd/languages/rust.md index 0a4ce58ac30..72aa979321a 100644 --- a/docs/pages/pmd/languages/rust.md +++ b/docs/pages/pmd/languages/rust.md @@ -1,7 +1,7 @@ --- title: Rust permalink: pmd_languages_rust.html -last_updated: December 2024 (7.0.0) +last_updated: December 2024 (7.9.0) tags: [languages, CpdCapableLanguage] summary: "Rust features and guidance" --- @@ -10,4 +10,4 @@ summary: "Rust features and guidance" > or garbage collector, it can power performance-critical services, run on embedded devices, > and easily integrate with other languages. -{% include language_info.html name='Rust' id='rust' implementation='rust::lang.rust.rustLanguageModule' supports_cpd=true %} \ No newline at end of file +{% include language_info.html name='Rust' id='rust' implementation='rust::lang.rust.RustLanguageModule' supports_cpd=true %} diff --git a/docs/pages/pmd/userdocs/cpd/cpd.md b/docs/pages/pmd/userdocs/cpd/cpd.md index 0580732bb4a..410e3be413b 100644 --- a/docs/pages/pmd/userdocs/cpd/cpd.md +++ b/docs/pages/pmd/userdocs/cpd/cpd.md @@ -335,6 +335,7 @@ to be "debug". * [PL/SQL](pmd_languages_plsql.html) * Python * Ruby +* [Rust](pmd_languages_rust.html) * [Salesforce.com Apex](pmd_languages_apex.html) * Scala * Swift diff --git a/pom.xml b/pom.xml index cf951d57a59..5296b91ddef 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ Additionally, it includes CPD, the copy-paste-detector. CPD finds duplicated code in Coco, C/C++, C#, Dart, Fortran, Gherkin, Go, Groovy, HTML, Java, JavaScript, JSP, Julia, Kotlin, - Lua, Matlab, Modelica, Objective-C, Perl, PHP, PLSQL, Python, Ruby, Salesforce.com Apex and + Lua, Matlab, Modelica, Objective-C, Perl, PHP, PLSQL, Python, Ruby, Rust, Salesforce.com Apex and Visualforce, Scala, Swift, T-SQL, Typescript, Apache Velocity, WSDL, XML and XSL. From c4c833a7ccd03fcca22a1b3e1d718f515fc6ba17 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Dec 2024 09:06:04 +0100 Subject: [PATCH 0396/1962] [doc] Update release notes (#5414) --- docs/pages/release_notes.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 8a6fbe267cb..999cde2f0f3 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -14,6 +14,11 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy +#### New: CPD support for Rust + +CPD now supports Rust, a blazingly fast and memory-efficient programming language. +It is shipped in the new module `pmd-rust`. + ### ๐Ÿ› Fixed Issues * cli * [#5399](https://github.com/pmd/pmd/issues/5399): \[cli] Windows: PMD fails to start with special characters in path names @@ -33,6 +38,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ Merged pull requests +* [#5414](https://github.com/pmd/pmd/pull/5414): Add Rust CPD - [Julia Paluch](https://github.com/juliapaluch) (@juliapaluch) ### ๐Ÿ“ฆ Dependency updates From f742092a8ec761f80156342dc9c74e79d9971e9e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Dec 2024 13:28:48 +0100 Subject: [PATCH 0397/1962] Prepare pmd release 7.9.0 --- docs/_config.yml | 2 +- docs/pages/release_notes.md | 32 +++++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 69e442b4ff7..9eecfca42c4 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,7 +1,7 @@ repository: pmd/pmd pmd: - version: 7.9.0-SNAPSHOT + version: 7.9.0 previous_version: 7.8.0 date: 2024-12-27 # release types: major, minor, bugfix diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 999cde2f0f3..14209e5af23 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -38,13 +38,43 @@ It is shipped in the new module `pmd-rust`. ### โœจ Merged pull requests +* [#4939](https://github.com/pmd/pmd/pull/4939): \[java] Fix #2996 - CommentSize/CommentContent suppression - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5376](https://github.com/pmd/pmd/pull/5376): \[java] Fix #4861 - UnusedPrivateMethod FP in JDK classes - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5387](https://github.com/pmd/pmd/pull/5387): \[java] Fix #5096 - StackOverflowError with recursively bounded tvar - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5400](https://github.com/pmd/pmd/pull/5400): Fix #5399: \[cli] pmd.bat: Quote all variables when using SET - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5402](https://github.com/pmd/pmd/pull/5402): Fix #5401: \[cli] pmd.bat: set codepage to 65001 (UTF-8) - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5404](https://github.com/pmd/pmd/pull/5404): \[doc] Update tools / integrations / ide plugins / news pages - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5414](https://github.com/pmd/pmd/pull/5414): Add Rust CPD - [Julia Paluch](https://github.com/juliapaluch) (@juliapaluch) ### ๐Ÿ“ฆ Dependency updates +* [#5375](https://github.com/pmd/pmd/pull/5375): Bump pmd from 7.7.0 to 7.8.0 +* [#5377](https://github.com/pmd/pmd/pull/5377): Bump com.puppycrawl.tools:checkstyle from 10.20.1 to 10.20.2 +* [#5378](https://github.com/pmd/pmd/pull/5378): Bump net.bytebuddy:byte-buddy from 1.14.12 to 1.15.10 +* [#5379](https://github.com/pmd/pmd/pull/5379): Bump io.github.git-commit-id:git-commit-id-maven-plugin from 7.0.0 to 9.0.1 +* [#5380](https://github.com/pmd/pmd/pull/5380): Bump org.apache.maven.plugins:maven-shade-plugin from 3.5.2 to 3.6.0 +* [#5384](https://github.com/pmd/pmd/pull/5384): Bump org.apache.groovy:groovy from 4.0.19 to 4.0.24 +* [#5390](https://github.com/pmd/pmd/pull/5390): Bump com.google.protobuf:protobuf-java from 4.28.2 to 4.29.1 +* [#5391](https://github.com/pmd/pmd/pull/5391): Bump org.hamcrest:hamcrest from 2.2 to 3.0 +* [#5392](https://github.com/pmd/pmd/pull/5392): Bump org.codehaus.mojo:build-helper-maven-plugin from 3.5.0 to 3.6.0 +* [#5393](https://github.com/pmd/pmd/pull/5393): Bump org.jsoup:jsoup from 1.17.2 to 1.18.3 +* [#5394](https://github.com/pmd/pmd/pull/5394): Bump org.apache.maven.plugins:maven-jar-plugin from 3.3.0 to 3.4.2 +* [#5395](https://github.com/pmd/pmd/pull/5395): Bump webrick from 1.9.0 to 1.9.1 in /docs in the all-gems group across 1 directory +* [#5405](https://github.com/pmd/pmd/pull/5405): Bump org.yaml:snakeyaml from 2.2 to 2.3 +* [#5406](https://github.com/pmd/pmd/pull/5406): Bump io.github.apex-dev-tools:apex-ls_2.13 from 5.5.0 to 5.7.0 +* [#5407](https://github.com/pmd/pmd/pull/5407): Bump net.bytebuddy:byte-buddy-agent from 1.14.19 to 1.15.11 +* [#5409](https://github.com/pmd/pmd/pull/5409): Bump net.bytebuddy:byte-buddy from 1.15.10 to 1.15.11 +* [#5410](https://github.com/pmd/pmd/pull/5410): Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.6.3 to 3.11.2 +* [#5411](https://github.com/pmd/pmd/pull/5411): Bump csv from 3.3.0 to 3.3.1 in /docs in the all-gems group across 1 directory +* [#5417](https://github.com/pmd/pmd/pull/5417): Bump org.cyclonedx:cyclonedx-maven-plugin from 2.7.11 to 2.9.1 +* [#5418](https://github.com/pmd/pmd/pull/5418): Bump org.checkerframework:checker-qual from 3.48.1 to 3.48.3 +* [#5419](https://github.com/pmd/pmd/pull/5419): Bump org.apache.maven.plugins:maven-checkstyle-plugin from 3.5.0 to 3.6.0 +* [#5422](https://github.com/pmd/pmd/pull/5422): Bump the all-gems group across 2 directories with 2 updates ### ๐Ÿ“ˆ Stats +* 69 commits +* 12 closed tickets & PRs +* Days since last release: 28 {% endtocmaker %} - From 83b543d83cbc1214c583ed9c84043ede6237c191 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Dec 2024 13:44:52 +0100 Subject: [PATCH 0398/1962] [doc] Rust support since 7.9.0 --- docs/pages/pmd/languages/rust.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/pmd/languages/rust.md b/docs/pages/pmd/languages/rust.md index 72aa979321a..b7eaee636e2 100644 --- a/docs/pages/pmd/languages/rust.md +++ b/docs/pages/pmd/languages/rust.md @@ -10,4 +10,4 @@ summary: "Rust features and guidance" > or garbage collector, it can power performance-critical services, run on embedded devices, > and easily integrate with other languages. -{% include language_info.html name='Rust' id='rust' implementation='rust::lang.rust.RustLanguageModule' supports_cpd=true %} +{% include language_info.html name='Rust' id='rust' implementation='rust::lang.rust.RustLanguageModule' supports_cpd=true since='7.9.0' %} From 10b47319e42bb817df69d29196ceca8fdb94b461 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Dec 2024 13:48:21 +0100 Subject: [PATCH 0399/1962] [release] prepare release pmd_releases/7.9.0 --- pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-rust/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 6 +++--- 43 files changed, 45 insertions(+), 45 deletions(-) diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index c84d4ad7a79..c84a4065e24 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.9.0-SNAPSHOT + 7.9.0 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 6b0776fc4f4..3fd07cc0c04 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index 24de0ef92c4..1667e37df62 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index 1a37e20c6bd..5c2a139c252 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index 335e68b21d6..9da761de4b7 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index 08f2d8d1f52..5a5ab065771 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index ebfe7646b8d..87a5315bd13 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index 7c5e6f85e6b..e16911422fd 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index 7c67b8fd6ac..a88673d4497 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index 5e29bfe1e97..ebe9db8f44c 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index 87605dc557d..2b795cdbc2a 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index 71a1d2847b3..b01a1297829 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index 58eaff969be..da636d87ba8 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index 304faf6c71e..0a096902679 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index 240d8f0c985..622fc58b087 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index a88059c2266..096b217bf03 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index 6070f32408f..bdc39b4edff 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index b524a13e6a0..a7397d6053a 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index 11d0ebfa066..63315823044 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index 4973fbf025a..b4ac170f7f1 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index 983571a0939..a797c9c1ee3 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index 48c387ec1f7..712db766fc7 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index adc0eb82506..c3192b2589f 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index d991a9a2f65..66ec6365f0e 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index 917b5d603a4..094d1d4c17d 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index 0123cfcb882..458860dad26 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index f5df3977a4c..f9800c71336 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index b12d207a296..53e05dc5426 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index 8e288479aa0..ea087fdd611 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index 32d272b70f8..7bc5d73a310 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index b73a1e1ef5c..0c662e6d3e6 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index 83c82adecf3..342069a20b8 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index 0286dd39df2..9af4c711f1c 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index da3b27eef4b..3411cb93a0b 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.9.0-SNAPSHOT + 7.9.0 ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index 4d2cca74526..e883c27a612 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.9.0-SNAPSHOT + 7.9.0 ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index 11facecdbd3..f423a5b3ba7 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index e1a5aecf23d..f2392abb88d 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index 0b9fcc3d675..814b04f79e0 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index 7a7eba1b4e4..4fa94024b41 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index c54b1f1601b..efc93122e40 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index 628cb34f91f..97ec7a4a480 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index 371f385f6dc..21d1d0d3494 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 ../pom.xml diff --git a/pom.xml b/pom.xml index 8c28865a1a4..a04fe8f84e3 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.9.0-SNAPSHOT + 7.9.0 pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - HEAD + pmd_releases/7.9.0 @@ -83,7 +83,7 @@ - 2024-11-29T09:58:44Z + 2024-12-27T12:29:08Z 8 From d7fe3993d7420d1b4802b02abc7eed51ef0ff972 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Dec 2024 14:08:38 +0100 Subject: [PATCH 0400/1962] [release] Prepare next development version [skip ci] --- docs/_config.yml | 6 +- docs/pages/release_notes.md | 51 +------------- docs/pages/release_notes_old.md | 82 ++++++++++++++++++++++ pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-rust/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 4 +- 46 files changed, 130 insertions(+), 97 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 9eecfca42c4..7796f5fb64f 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,9 +1,9 @@ repository: pmd/pmd pmd: - version: 7.9.0 - previous_version: 7.8.0 - date: 2024-12-27 + version: 7.10.0-SNAPSHOT + previous_version: 7.9.0 + date: 2025-01-31 # release types: major, minor, bugfix release_type: minor diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 14209e5af23..26ec825d013 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -14,67 +14,18 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy -#### New: CPD support for Rust - -CPD now supports Rust, a blazingly fast and memory-efficient programming language. -It is shipped in the new module `pmd-rust`. - ### ๐Ÿ› Fixed Issues -* cli - * [#5399](https://github.com/pmd/pmd/issues/5399): \[cli] Windows: PMD fails to start with special characters in path names - * [#5401](https://github.com/pmd/pmd/issues/5401): \[cli] Windows: Console output doesn't use unicode -* java - * [#5096](https://github.com/pmd/pmd/issues/5096): \[java] StackOverflowError with recursively bound type variable -* java-bestpractices - * [#4861](https://github.com/pmd/pmd/issues/4861): \[java] UnusedPrivateMethod - false positive with static methods in core JDK classes -* java-documentation - * [#2996](https://github.com/pmd/pmd/issues/2996): \[java] CommentSize rule violation is not suppressed at method level ### ๐Ÿšจ API Changes -#### Experimental API - -* pmd-core: {%jdoc !!core::reporting.RuleContext#addViolationWithPosition(core::reporting.Reportable,core::lang.ast.AstInfo,core::lang.document.FileLocation,java.lang.String,java.lang.Object...) %} - ### โœจ Merged pull requests -* [#4939](https://github.com/pmd/pmd/pull/4939): \[java] Fix #2996 - CommentSize/CommentContent suppression - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5376](https://github.com/pmd/pmd/pull/5376): \[java] Fix #4861 - UnusedPrivateMethod FP in JDK classes - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5387](https://github.com/pmd/pmd/pull/5387): \[java] Fix #5096 - StackOverflowError with recursively bounded tvar - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5400](https://github.com/pmd/pmd/pull/5400): Fix #5399: \[cli] pmd.bat: Quote all variables when using SET - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5402](https://github.com/pmd/pmd/pull/5402): Fix #5401: \[cli] pmd.bat: set codepage to 65001 (UTF-8) - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5404](https://github.com/pmd/pmd/pull/5404): \[doc] Update tools / integrations / ide plugins / news pages - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5414](https://github.com/pmd/pmd/pull/5414): Add Rust CPD - [Julia Paluch](https://github.com/juliapaluch) (@juliapaluch) ### ๐Ÿ“ฆ Dependency updates -* [#5375](https://github.com/pmd/pmd/pull/5375): Bump pmd from 7.7.0 to 7.8.0 -* [#5377](https://github.com/pmd/pmd/pull/5377): Bump com.puppycrawl.tools:checkstyle from 10.20.1 to 10.20.2 -* [#5378](https://github.com/pmd/pmd/pull/5378): Bump net.bytebuddy:byte-buddy from 1.14.12 to 1.15.10 -* [#5379](https://github.com/pmd/pmd/pull/5379): Bump io.github.git-commit-id:git-commit-id-maven-plugin from 7.0.0 to 9.0.1 -* [#5380](https://github.com/pmd/pmd/pull/5380): Bump org.apache.maven.plugins:maven-shade-plugin from 3.5.2 to 3.6.0 -* [#5384](https://github.com/pmd/pmd/pull/5384): Bump org.apache.groovy:groovy from 4.0.19 to 4.0.24 -* [#5390](https://github.com/pmd/pmd/pull/5390): Bump com.google.protobuf:protobuf-java from 4.28.2 to 4.29.1 -* [#5391](https://github.com/pmd/pmd/pull/5391): Bump org.hamcrest:hamcrest from 2.2 to 3.0 -* [#5392](https://github.com/pmd/pmd/pull/5392): Bump org.codehaus.mojo:build-helper-maven-plugin from 3.5.0 to 3.6.0 -* [#5393](https://github.com/pmd/pmd/pull/5393): Bump org.jsoup:jsoup from 1.17.2 to 1.18.3 -* [#5394](https://github.com/pmd/pmd/pull/5394): Bump org.apache.maven.plugins:maven-jar-plugin from 3.3.0 to 3.4.2 -* [#5395](https://github.com/pmd/pmd/pull/5395): Bump webrick from 1.9.0 to 1.9.1 in /docs in the all-gems group across 1 directory -* [#5405](https://github.com/pmd/pmd/pull/5405): Bump org.yaml:snakeyaml from 2.2 to 2.3 -* [#5406](https://github.com/pmd/pmd/pull/5406): Bump io.github.apex-dev-tools:apex-ls_2.13 from 5.5.0 to 5.7.0 -* [#5407](https://github.com/pmd/pmd/pull/5407): Bump net.bytebuddy:byte-buddy-agent from 1.14.19 to 1.15.11 -* [#5409](https://github.com/pmd/pmd/pull/5409): Bump net.bytebuddy:byte-buddy from 1.15.10 to 1.15.11 -* [#5410](https://github.com/pmd/pmd/pull/5410): Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.6.3 to 3.11.2 -* [#5411](https://github.com/pmd/pmd/pull/5411): Bump csv from 3.3.0 to 3.3.1 in /docs in the all-gems group across 1 directory -* [#5417](https://github.com/pmd/pmd/pull/5417): Bump org.cyclonedx:cyclonedx-maven-plugin from 2.7.11 to 2.9.1 -* [#5418](https://github.com/pmd/pmd/pull/5418): Bump org.checkerframework:checker-qual from 3.48.1 to 3.48.3 -* [#5419](https://github.com/pmd/pmd/pull/5419): Bump org.apache.maven.plugins:maven-checkstyle-plugin from 3.5.0 to 3.6.0 -* [#5422](https://github.com/pmd/pmd/pull/5422): Bump the all-gems group across 2 directories with 2 updates ### ๐Ÿ“ˆ Stats -* 69 commits -* 12 closed tickets & PRs -* Days since last release: 28 {% endtocmaker %} + diff --git a/docs/pages/release_notes_old.md b/docs/pages/release_notes_old.md index 03bfce226f2..348840576b8 100644 --- a/docs/pages/release_notes_old.md +++ b/docs/pages/release_notes_old.md @@ -5,6 +5,88 @@ permalink: pmd_release_notes_old.html Previous versions of PMD can be downloaded here: [Releases - pmd/pmd (GitHub)](https://github.com/pmd/pmd/releases) +## 27-December-2024 - 7.9.0 + +The PMD team is pleased to announce PMD 7.9.0. + +This is a minor release. + +### Table Of Contents + +* [๐Ÿš€ New and noteworthy](#new-and-noteworthy) + * [New: CPD support for Rust](#new-cpd-support-for-rust) +* [๐Ÿ› Fixed Issues](#fixed-issues) +* [๐Ÿšจ API Changes](#api-changes) + * [Experimental API](#experimental-api) +* [โœจ Merged pull requests](#merged-pull-requests) +* [๐Ÿ“ฆ Dependency updates](#dependency-updates) +* [๐Ÿ“ˆ Stats](#stats) + +### ๐Ÿš€ New and noteworthy + +#### New: CPD support for Rust + +CPD now supports Rust, a blazingly fast and memory-efficient programming language. +It is shipped in the new module `pmd-rust`. + +### ๐Ÿ› Fixed Issues +* cli + * [#5399](https://github.com/pmd/pmd/issues/5399): \[cli] Windows: PMD fails to start with special characters in path names + * [#5401](https://github.com/pmd/pmd/issues/5401): \[cli] Windows: Console output doesn't use unicode +* java + * [#5096](https://github.com/pmd/pmd/issues/5096): \[java] StackOverflowError with recursively bound type variable +* java-bestpractices + * [#4861](https://github.com/pmd/pmd/issues/4861): \[java] UnusedPrivateMethod - false positive with static methods in core JDK classes +* java-documentation + * [#2996](https://github.com/pmd/pmd/issues/2996): \[java] CommentSize rule violation is not suppressed at method level + +### ๐Ÿšจ API Changes + +#### Experimental API + +* pmd-core: RuleContext#addViolationWithPosition + +### โœจ Merged pull requests + +* [#4939](https://github.com/pmd/pmd/pull/4939): \[java] Fix #2996 - CommentSize/CommentContent suppression - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5376](https://github.com/pmd/pmd/pull/5376): \[java] Fix #4861 - UnusedPrivateMethod FP in JDK classes - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5387](https://github.com/pmd/pmd/pull/5387): \[java] Fix #5096 - StackOverflowError with recursively bounded tvar - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5400](https://github.com/pmd/pmd/pull/5400): Fix #5399: \[cli] pmd.bat: Quote all variables when using SET - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5402](https://github.com/pmd/pmd/pull/5402): Fix #5401: \[cli] pmd.bat: set codepage to 65001 (UTF-8) - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5404](https://github.com/pmd/pmd/pull/5404): \[doc] Update tools / integrations / ide plugins / news pages - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5414](https://github.com/pmd/pmd/pull/5414): Add Rust CPD - [Julia Paluch](https://github.com/juliapaluch) (@juliapaluch) + +### ๐Ÿ“ฆ Dependency updates + +* [#5375](https://github.com/pmd/pmd/pull/5375): Bump pmd from 7.7.0 to 7.8.0 +* [#5377](https://github.com/pmd/pmd/pull/5377): Bump com.puppycrawl.tools:checkstyle from 10.20.1 to 10.20.2 +* [#5378](https://github.com/pmd/pmd/pull/5378): Bump net.bytebuddy:byte-buddy from 1.14.12 to 1.15.10 +* [#5379](https://github.com/pmd/pmd/pull/5379): Bump io.github.git-commit-id:git-commit-id-maven-plugin from 7.0.0 to 9.0.1 +* [#5380](https://github.com/pmd/pmd/pull/5380): Bump org.apache.maven.plugins:maven-shade-plugin from 3.5.2 to 3.6.0 +* [#5384](https://github.com/pmd/pmd/pull/5384): Bump org.apache.groovy:groovy from 4.0.19 to 4.0.24 +* [#5390](https://github.com/pmd/pmd/pull/5390): Bump com.google.protobuf:protobuf-java from 4.28.2 to 4.29.1 +* [#5391](https://github.com/pmd/pmd/pull/5391): Bump org.hamcrest:hamcrest from 2.2 to 3.0 +* [#5392](https://github.com/pmd/pmd/pull/5392): Bump org.codehaus.mojo:build-helper-maven-plugin from 3.5.0 to 3.6.0 +* [#5393](https://github.com/pmd/pmd/pull/5393): Bump org.jsoup:jsoup from 1.17.2 to 1.18.3 +* [#5394](https://github.com/pmd/pmd/pull/5394): Bump org.apache.maven.plugins:maven-jar-plugin from 3.3.0 to 3.4.2 +* [#5395](https://github.com/pmd/pmd/pull/5395): Bump webrick from 1.9.0 to 1.9.1 in /docs in the all-gems group across 1 directory +* [#5405](https://github.com/pmd/pmd/pull/5405): Bump org.yaml:snakeyaml from 2.2 to 2.3 +* [#5406](https://github.com/pmd/pmd/pull/5406): Bump io.github.apex-dev-tools:apex-ls_2.13 from 5.5.0 to 5.7.0 +* [#5407](https://github.com/pmd/pmd/pull/5407): Bump net.bytebuddy:byte-buddy-agent from 1.14.19 to 1.15.11 +* [#5409](https://github.com/pmd/pmd/pull/5409): Bump net.bytebuddy:byte-buddy from 1.15.10 to 1.15.11 +* [#5410](https://github.com/pmd/pmd/pull/5410): Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.6.3 to 3.11.2 +* [#5411](https://github.com/pmd/pmd/pull/5411): Bump csv from 3.3.0 to 3.3.1 in /docs in the all-gems group across 1 directory +* [#5417](https://github.com/pmd/pmd/pull/5417): Bump org.cyclonedx:cyclonedx-maven-plugin from 2.7.11 to 2.9.1 +* [#5418](https://github.com/pmd/pmd/pull/5418): Bump org.checkerframework:checker-qual from 3.48.1 to 3.48.3 +* [#5419](https://github.com/pmd/pmd/pull/5419): Bump org.apache.maven.plugins:maven-checkstyle-plugin from 3.5.0 to 3.6.0 +* [#5422](https://github.com/pmd/pmd/pull/5422): Bump the all-gems group across 2 directories with 2 updates + +### ๐Ÿ“ˆ Stats + +* 69 commits +* 12 closed tickets & PRs +* Days since last release: 28 + ## 29-November-2024 - 7.8.0 The PMD team is pleased to announce PMD 7.8.0. diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index c84a4065e24..76f07557c61 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.9.0 + 7.10.0-SNAPSHOT 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 3fd07cc0c04..ec4ebd21aa3 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index 1667e37df62..e77d806f14e 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index 5c2a139c252..534722c4ccf 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index 9da761de4b7..08f6ef6d8cb 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index 5a5ab065771..ebe754895d2 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index 87a5315bd13..43e9d50beff 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index e16911422fd..bc64e99a773 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index a88673d4497..45684f597a7 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index ebe9db8f44c..250a03912f4 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index 2b795cdbc2a..9a06ce3c6c7 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index b01a1297829..ec0b11fd316 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index da636d87ba8..577b2a609ad 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index 0a096902679..fb5277db5f3 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index 622fc58b087..7f924f36370 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 096b217bf03..5c1f7296194 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index bdc39b4edff..9316ac5bc89 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index a7397d6053a..c70650f13ba 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index 63315823044..2a32d15cff9 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index b4ac170f7f1..c670960e120 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index a797c9c1ee3..9058c9f6c06 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index 712db766fc7..d6a171088dc 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index c3192b2589f..2dd5f607852 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index 66ec6365f0e..5291a464f42 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index 094d1d4c17d..c81aa3c8b2f 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index 458860dad26..db16fc8e95e 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index f9800c71336..f0a5f199681 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index 53e05dc5426..0a8a066d7b0 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index ea087fdd611..6e27cfcd09d 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index 7bc5d73a310..fe34865c2b7 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index 0c662e6d3e6..acc5d9d19c9 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index 342069a20b8..6224824f22d 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index 9af4c711f1c..529841b9118 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index 3411cb93a0b..0e18f596a5d 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.9.0 + 7.10.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index e883c27a612..23640f722a2 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.9.0 + 7.10.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index f423a5b3ba7..ba48d174355 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index f2392abb88d..3013fca5613 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index 814b04f79e0..b5449ba0025 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index 4fa94024b41..0760cf9d694 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index efc93122e40..8c5de7470c6 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index 97ec7a4a480..3011e80135e 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index 21d1d0d3494..ea2ea26b704 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index a04fe8f84e3..25b13a07819 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.9.0 + 7.10.0-SNAPSHOT pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - pmd_releases/7.9.0 + HEAD From 17a495c38dd5d3b70a905f55d972a665f5235d76 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Dec 2024 17:33:29 +0100 Subject: [PATCH 0401/1962] Bump PMD from 7.8.0 to 7.9.0 --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 25b13a07819..568e8322aee 100644 --- a/pom.xml +++ b/pom.xml @@ -574,22 +574,22 @@ net.sourceforge.pmd pmd-core - 7.8.0 + 7.9.0 net.sourceforge.pmd pmd-java - 7.8.0 + 7.9.0 net.sourceforge.pmd pmd-jsp - 7.8.0 + 7.9.0 net.sourceforge.pmd pmd-javascript - 7.8.0 + 7.9.0 From ac114df3b8cfe9b3a7ace1e107e0629530f532dd Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Dec 2024 17:44:03 +0100 Subject: [PATCH 0402/1962] [rust] Cleanup japicmp config --- pmd-rust/pom.xml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index 6224824f22d..7e36c915226 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -47,15 +47,6 @@ - - com.github.siom79.japicmp - japicmp-maven-plugin - - - true - - - From dd371c69977267078097300ad7f7e38e47c3a4ac Mon Sep 17 00:00:00 2001 From: mitchspano Date: Sat, 28 Dec 2024 05:22:17 +0000 Subject: [PATCH 0403/1962] initial rule definition --- .../AvoidStatefulDatabaseResultRule.java | 83 +++++++++++++++++++ .../resources/category/apex/errorprone.xml | 79 ++++++++++++++++++ .../AvoidStatefulDatabaseResultTest.java | 11 +++ .../xml/AvoidStatefulDatabaseResult.xml | 29 +++++++ 4 files changed, 202 insertions(+) create mode 100644 pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidStatefulDatabaseResultRule.java create mode 100644 pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidStatefulDatabaseResultTest.java create mode 100644 pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/AvoidStatefulDatabaseResult.xml diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidStatefulDatabaseResultRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidStatefulDatabaseResultRule.java new file mode 100644 index 00000000000..e4903a62550 --- /dev/null +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidStatefulDatabaseResultRule.java @@ -0,0 +1,83 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.apex.rule.errorprone; + +import com.google.common.base.Ascii; +import com.google.common.collect.ImmutableSet; +import net.sourceforge.pmd.lang.apex.ast.ASTField; +import net.sourceforge.pmd.lang.apex.ast.ASTUserClass; +import net.sourceforge.pmd.lang.apex.rule.AbstractApexRule; + +/** + * Using stateful `Database.[x]Result` instance variables can cause odd + * serialization errors between successive batch iterations. + * + * https://issues.salesforce.com/issue/a028c00000qPwlqAAC/stateful-batch-job-that-stores-databasesaveresult-failed-after-validation-errors-throws-error-during-deserialization + * + * This rule scans classes which implement the `Database.Stateful` interface. If + * there are instance variables of type `Database.[x]Result` (ex: + * `Database.SaveResult`), then a violation will be added to those variables. + */ +public final class AvoidStatefulDatabaseResultRule extends AbstractApexRule { + + private static final ImmutableSet DATABASE_RESULT_TYPES = ImmutableSet.of( + "database.convertleadresult", + "database.deleteresult", + "database.emptyrecyclebinresult", + "database.mergeresult", + "database.saveresult", + "database.undeleteresult", + "database.upsertresult"); + + @Override + public Object visit(ASTUserClass theClass, Object data) { + if (!implementsDatabaseStateful(theClass)) { + return data; + } + // Note that inner classes cannot implement `Database.Stateful` + // interface, so we only need to check the top level class + for (ASTField theField : theClass.descendants(ASTField.class)) { + if (isNonTransientInstanceDatabaseResultField(theField)) { + asCtx(data).addViolation(theField); + } + } + return data; + } + + /** Determines if the class implements the `Database.Stateful` interface */ + private boolean implementsDatabaseStateful(ASTUserClass theClass) { + for (String interfaceName : theClass.getInterfaceNames()) { + if (Ascii.equalsIgnoreCase(interfaceName, "database.stateful")) { + return true; + } + } + return false; + } + + /** + * Determines if a variable's definition may cause issues within batch + * iteration by being: an instance variable, not transient, and a data type + * of `Database.[x]Result` (or collection of them). + */ + private boolean isNonTransientInstanceDatabaseResultField(ASTField theField) { + return !theField.getModifiers().isStatic() + && !theField.getModifiers().isTransient() + && isDatabaseResultOrCollection(theField.getType()); + } + + /** + * Determines if any of the unsupported types contains the type. We check + * containment even as a substring to check if the type is a collection of + * the result types ex: `List`. + */ + private boolean isDatabaseResultOrCollection(String type) { + for (String databaseResultType : DATABASE_RESULT_TYPES) { + if (Ascii.toLowerCase(type).contains(databaseResultType)) { + return true; + } + } + return false; + } +} diff --git a/pmd-apex/src/main/resources/category/apex/errorprone.xml b/pmd-apex/src/main/resources/category/apex/errorprone.xml index cd0b6334dec..4ac5795aa00 100644 --- a/pmd-apex/src/main/resources/category/apex/errorprone.xml +++ b/pmd-apex/src/main/resources/category/apex/errorprone.xml @@ -510,6 +510,85 @@ private class TestClass { // Code here } } +]]> + + + + + Storing Database.insertResult, Database.updateResult, etc. in instance variables + of a stateful batch class can cause serialization errors between batch iterations. + When this occurs, it is often inconsistent and challenging to troubleshoot. + + This issue can be avoided by marking the variable as transient, or using a different + data type that is safe to serialize. + + 3 + + scope){ + Database.SaveResult[] saveResults = Database.update(scope, false); + results.addAll(saveResults); + } + + public void finish(database.BatchableContext context){ + } +} + +// Compliant +public class Example implements Database.Batchable, Database.Stateful { + StatefulResult[] results = new StatefulResult[]; // Use a different custom type to persist state + + public Database.Querylocator start(Database.BatchableContext context){ + return Database.getQueryLocator('SELECT Id FROM Account'); + } + + public void execute(Database.BatchableContext context, List scope){ + Database.SaveResult[] saveResults = Database.update(scope, false); + for (Database.SaveResult result : saveResults) { + results.add(new StatefulResult(result)); + } + } + + public void finish(database.BatchableContext context){ + } + +} + +public class StatefulResult { + private Boolean isSuccess; + private Id id; + private Database.Error[] errors; + + public StatefulResult(Database.SaveResult result){ + isSuccess = result.isSuccess(); + id = result.getId(); + errors = result.getErrors(); + } + + public Boolean isSuccess(){ + return isSuccess; + } + + public Id getId(){ + return id; + } + + public Database.Error[] getErrors(){ + return errors; + } +} ]]> diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidStatefulDatabaseResultTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidStatefulDatabaseResultTest.java new file mode 100644 index 00000000000..d070788e2e8 --- /dev/null +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidStatefulDatabaseResultTest.java @@ -0,0 +1,11 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.apex.rule.errorprone; + +import net.sourceforge.pmd.test.PmdRuleTst; + +class AvoidStatefulDatabaseResultTest extends PmdRuleTst { + // no additional unit tests +} diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/AvoidStatefulDatabaseResult.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/AvoidStatefulDatabaseResult.xml new file mode 100644 index 00000000000..b19acfc0a3a --- /dev/null +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/AvoidStatefulDatabaseResult.xml @@ -0,0 +1,29 @@ + + + + + SaveResult array. + 1 + scope){ + Database.SaveResult[] saveResults = Database.update(scope, false); + results.addAll(saveResults); + } + + public void finish(database.BatchableContext context){ + } +} + ]]> + + + From 1b745354816d5160dc83d58fe50c972bf1f4c54d Mon Sep 17 00:00:00 2001 From: mitchspano Date: Sun, 29 Dec 2024 02:04:41 +0000 Subject: [PATCH 0404/1962] Update testing and formatting --- .../AvoidStatefulDatabaseResultRule.java | 24 +- .../resources/category/apex/errorprone.xml | 630 +++++++++--------- .../xml/AvoidStatefulDatabaseResult.xml | 184 ++++- 3 files changed, 498 insertions(+), 340 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidStatefulDatabaseResultRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidStatefulDatabaseResultRule.java index e4903a62550..05b5a3be364 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidStatefulDatabaseResultRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidStatefulDatabaseResultRule.java @@ -4,11 +4,13 @@ package net.sourceforge.pmd.lang.apex.rule.errorprone; -import com.google.common.base.Ascii; -import com.google.common.collect.ImmutableSet; +import java.util.Locale; +import java.util.Set; + import net.sourceforge.pmd.lang.apex.ast.ASTField; import net.sourceforge.pmd.lang.apex.ast.ASTUserClass; import net.sourceforge.pmd.lang.apex.rule.AbstractApexRule; +import net.sourceforge.pmd.util.CollectionUtil; /** * Using stateful `Database.[x]Result` instance variables can cause odd @@ -22,14 +24,9 @@ */ public final class AvoidStatefulDatabaseResultRule extends AbstractApexRule { - private static final ImmutableSet DATABASE_RESULT_TYPES = ImmutableSet.of( - "database.convertleadresult", - "database.deleteresult", - "database.emptyrecyclebinresult", - "database.mergeresult", - "database.saveresult", - "database.undeleteresult", - "database.upsertresult"); + private static final Set DATABASE_RESULT_TYPES = CollectionUtil.immutableSetOf("database.leadconvertresult", + "database.deleteresult", "database.emptyrecyclebinresult", "database.mergeresult", "database.saveresult", + "database.undeleteresult", "database.upsertresult"); @Override public Object visit(ASTUserClass theClass, Object data) { @@ -49,7 +46,7 @@ public Object visit(ASTUserClass theClass, Object data) { /** Determines if the class implements the `Database.Stateful` interface */ private boolean implementsDatabaseStateful(ASTUserClass theClass) { for (String interfaceName : theClass.getInterfaceNames()) { - if (Ascii.equalsIgnoreCase(interfaceName, "database.stateful")) { + if ("database.stateful".equalsIgnoreCase(interfaceName)) { return true; } } @@ -62,8 +59,7 @@ private boolean implementsDatabaseStateful(ASTUserClass theClass) { * of `Database.[x]Result` (or collection of them). */ private boolean isNonTransientInstanceDatabaseResultField(ASTField theField) { - return !theField.getModifiers().isStatic() - && !theField.getModifiers().isTransient() + return !theField.getModifiers().isStatic() && !theField.getModifiers().isTransient() && isDatabaseResultOrCollection(theField.getType()); } @@ -74,7 +70,7 @@ private boolean isNonTransientInstanceDatabaseResultField(ASTField theField) { */ private boolean isDatabaseResultOrCollection(String type) { for (String databaseResultType : DATABASE_RESULT_TYPES) { - if (Ascii.toLowerCase(type).contains(databaseResultType)) { + if (type.toLowerCase(Locale.ROOT).contains(databaseResultType)) { return true; } } diff --git a/pmd-apex/src/main/resources/category/apex/errorprone.xml b/pmd-apex/src/main/resources/category/apex/errorprone.xml index 4ac5795aa00..291ca41c193 100644 --- a/pmd-apex/src/main/resources/category/apex/errorprone.xml +++ b/pmd-apex/src/main/resources/category/apex/errorprone.xml @@ -4,32 +4,32 @@ xmlns="http://pmd.sourceforge.net/ruleset/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd"> - + + + Rules to detect constructs that are either broken, extremely confusing or prone to runtime errors. + + + -Rules to detect constructs that are either broken, extremely confusing or prone to runtime errors. + Having DML operations in Apex class constructor or initializers can have unexpected side effects: + By just accessing a page, the DML statements would be executed and the database would be modified. + Just querying the database is permitted. + + In addition to constructors and initializers, any method called `init` is checked as well. + + Salesforce Apex already protects against this scenario and raises a runtime exception. + + Note: This rule has been moved from category "Security" to "Error Prone" with PMD 6.21.0, since + using DML in constructors is not a security problem, but crashes the application. - - - -Having DML operations in Apex class constructor or initializers can have unexpected side effects: -By just accessing a page, the DML statements would be executed and the database would be modified. -Just querying the database is permitted. - -In addition to constructors and initializers, any method called `init` is checked as well. - -Salesforce Apex already protects against this scenario and raises a runtime exception. - -Note: This rule has been moved from category "Security" to "Error Prone" with PMD 6.21.0, since -using DML in constructors is not a security problem, but crashes the application. - - 3 - -3 + + - - - - - -Avoid directly accessing Trigger.old and Trigger.new as it can lead to a bug. Triggers should be bulkified and iterate through the map to handle the actions for each item separately. - - 3 - - - - + + + + + Avoid directly accessing Trigger.old and Trigger.new as it can lead to a bug. Triggers should be bulkified and iterate through the map to handle the actions for each item separately. + + 3 + + + + - - - - - + + + + - - - - - -When deploying Apex code between sandbox and production environments, or installing Force.com AppExchange packages, -it is essential to avoid hardcoding IDs in the Apex code. By doing so, if the record IDs change between environments, -the logic can dynamically identify the proper data to operate against and not fail. - - 3 - - + + + + + When deploying Apex code between sandbox and production environments, or installing Force.com AppExchange packages, + it is essential to avoid hardcoding IDs in the Apex code. By doing so, if the record IDs change between environments, + the logic can dynamically identify the proper data to operate against and not fail. + + 3 + + - - - - - - Apex supported non existent annotations for legacy reasons. - In the future, use of such non-existent annotations could result in broken apex code that will not compile. - This will prevent users of garbage annotations from being able to use legitimate annotations added to Apex in the future. - A full list of supported annotations can be found at https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation.htm - - 3 - - + + + + + Apex supported non existent annotations for legacy reasons. + In the future, use of such non-existent annotations could result in broken apex code that will not compile. + This will prevent users of garbage annotations from being able to use legitimate annotations added to Apex in the future. + A full list of supported annotations can be found at https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation.htm + + 3 + + - - - - - -Empty Catch Block finds instances where an exception is caught, but nothing is done. -In most circumstances, this swallows an exception which should either be acted on -or reported. - - 3 - - - - - - + + + + + Empty Catch Block finds instances where an exception is caught, but nothing is done. + In most circumstances, this swallows an exception which should either be acted on + or reported. + + 3 + + + + + + - - - - - + + + + - - - - - -Empty If Statement finds instances where a condition is checked but nothing is done about it. - - 3 - - - - - - - - - + + + + + Empty If Statement finds instances where a condition is checked but nothing is done about it. + + 3 + + + + + + + + + - - - - - -Empty block statements serve no purpose and should be removed. - - 3 - - - - - - + + + + + Empty block statements serve no purpose and should be removed. + + 3 + + + + + + - - - - - + + + + - - - - - -Avoid empty try or finally blocks - what's the point? - - 3 - - - - - - - - - + + + + + Avoid empty try or finally blocks - what's the point? + + 3 + + + + + + + + + - - - - - -Empty While Statement finds all instances where a while statement does nothing. -If it is a timing loop, then you should use Thread.sleep() for it; if it is -a while loop that does a lot in the exit expression, rewrite it to make it clearer. - - 3 - - - - - - - - - + + + + + Empty While Statement finds all instances where a while statement does nothing. + If it is a timing loop, then you should use Thread.sleep() for it; if it is + a while loop that does a lot in the exit expression, rewrite it to make it clearer. + + 3 + + + + + + + + + - - - - - -In the Summer '21 release, a mandatory security update enforces access modifiers on Apex properties in -Lightning component markup. The update prevents access to private or protected Apex getters from Aura -and Lightning Web Components. - - 3 - - + + + + + In the Summer '21 release, a mandatory security update enforces access modifiers on Apex properties in + Lightning component markup. The update prevents access to private or protected Apex getters from Aura + and Lightning Web Components. + + 3 + + - - - + + - - - + + - - - - - -Non-constructor methods should not have the same name as the enclosing class. - - 3 - - + + + + + Non-constructor methods should not have the same name as the enclosing class. + + 3 + + - - - - - -Override both `public Boolean equals(Object obj)`, and `public Integer hashCode()`, or override neither. -Even if you are inheriting a hashCode() from a parent class, consider implementing hashCode and explicitly -delegating to your superclass. - -This is especially important when [Using Custom Types in Map Keys and Sets](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_collections_maps_keys_userdefined.htm). - - 3 - - + + + + + Override both `public Boolean equals(Object obj)`, and `public Integer hashCode()`, or override neither. + Even if you are inheriting a hashCode() from a parent class, consider implementing hashCode and explicitly + delegating to your superclass. + + This is especially important when [Using Custom Types in Map Keys and Sets](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_collections_maps_keys_userdefined.htm). + + 3 + + - - - - - - Test methods marked as a testMethod or annotated with @IsTest, - but not residing in a test class should be moved to a proper - class or have the @IsTest annotation added to the class. - - Support for tests inside functional classes was removed in Spring-13 (API Version 27.0), - making classes that violate this rule fail compile-time. This rule is mostly usable when - dealing with legacy code. - - 3 - - - - + + + + + Test methods marked as a testMethod or annotated with @IsTest, + but not residing in a test class should be moved to a proper + class or have the @IsTest annotation added to the class. + + Support for tests inside functional classes was removed in Spring-13 (API Version 27.0), + making classes that violate this rule fail compile-time. This rule is mostly usable when + dealing with legacy code. + + 3 + + + + - - - - - + + + + - - - - - Storing Database.insertResult, Database.updateResult, etc. in instance variables - of a stateful batch class can cause serialization errors between batch iterations. - When this occurs, it is often inconsistent and challenging to troubleshoot. - - This issue can be avoided by marking the variable as transient, or using a different - data type that is safe to serialize. - - 3 - - + + + + Storing Database.insertResult, Database.updateResult, etc. in instance variables + of a stateful batch class can cause serialization errors between batch iterations. + When this occurs, it is often inconsistent and challenging to troubleshoot. + + See https://issues.salesforce.com/issue/a028c00000qPwlqAAC/stateful-batch-job-that-stores-databasesaveresult-failed-after-validation-errors-throws-error-during-deserialization for more details. + + This issue can be avoided by marking the variable as transient, or using a different + data type that is safe to serialize. + + 3 + + results = new List(); // this can cause failures public Database.Querylocator start(Database.BatchableContext context){ return Database.getQueryLocator('SELECT Id FROM Account'); @@ -548,7 +550,7 @@ public class Example implements Database.Batchable, Database.Stateful { // Compliant public class Example implements Database.Batchable, Database.Stateful { - StatefulResult[] results = new StatefulResult[]; // Use a different custom type to persist state + List results = new List(); // Use a different custom type to persist state public Database.Querylocator start(Database.BatchableContext context){ return Database.getQueryLocator('SELECT Id FROM Account'); @@ -590,6 +592,6 @@ public class StatefulResult { } } ]]> - - + + diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/AvoidStatefulDatabaseResult.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/AvoidStatefulDatabaseResult.xml index b19acfc0a3a..728376eb00c 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/AvoidStatefulDatabaseResult.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/AvoidStatefulDatabaseResult.xml @@ -1,29 +1,189 @@ + xmlns="http://pmd.sourceforge.net/rule-tests" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests http://pmd.sourceforge.net/rule-tests_1_0_0.xsd"> + + + Result instances in stateful class + 7 + , Database.Stateful { + private Database.DeleteResult deleteResult; + private Database.EmptyRecycleBinResult emptyRecycleBinResult; + private Database.LeadConvertResult leadConvertResult; + private Database.MergeResult mergeResult; + private Database.SaveResult saveResult; + private Database.UndeleteResult undeleteResult; + private Database.UpsertResult upsertResult; - - SaveResult array. - 1 - scope){ + } + + public void finish(database.BatchableContext context){ + } +} + ]]> + + + + Result lists in stateful class + 7 + , Database.Stateful { + private List deleteResults = new List(); + private List emptyRecycleBinResults = new List(); + private List leadConvertResults = new List(); + private List mergeResults = new List(); + private List saveResults = new List(); + private List undeleteResults = new List(); + private List upsertResults = new List(); + + public Database.Querylocator start(Database.BatchableContext context){ + return Database.getQueryLocator('SELECT Id FROM Account'); + } + + public void execute(Database.BatchableContext context, List scope){ + } + + public void finish(database.BatchableContext context){ + } +} + ]]> + + + + Result sets in stateful class + 7 + , Database.Stateful { + private Set deleteResults = new Set(); + private Set emptyRecycleBinResults = new Set(); + private Set leadConvertResults = new Set(); + private Set mergeResults = new Set(); + private Set saveResults = new Set(); + private Set undeleteResults = new Set(); + private Set upsertResults = new Set(); + + public Database.Querylocator start(Database.BatchableContext context){ + return Database.getQueryLocator('SELECT Id FROM Account'); + } + + public void execute(Database.BatchableContext context, List scope){ + } + + public void finish(database.BatchableContext context){ + } +} + ]]> + + + + Result maps in stateful class + 7 + , Database.Stateful { + private Map deleteResults = new Map(); + private Map emptyRecycleBinResults = new Map(); + private Map leadConvertResults = new Map(); + private Map mergeResults = new Map(); + private Map saveResults = new Map(); + private Map undeleteResults = new Map(); + private Map upsertResults = new Map(); public Database.Querylocator start(Database.BatchableContext context){ return Database.getQueryLocator('SELECT Id FROM Account'); } public void execute(Database.BatchableContext context, List scope){ - Database.SaveResult[] saveResults = Database.update(scope, false); - results.addAll(saveResults); } public void finish(database.BatchableContext context){ } } ]]> - + + + + Transient result in stateful class + 0 + , Database.Stateful { + private transient Database.DeleteResult deleteResult; + private transient Database.EmptyRecycleBinResult emptyRecycleBinResult; + private transient Database.LeadConvertResult leadConvertResult; + private transient Database.MergeResult mergeResult; + private transient Database.SaveResult saveResult; + private transient Database.UndeleteResult undeleteResult; + private transient Database.UpsertResult upsertResult; + public Database.Querylocator start(Database.BatchableContext context){ + return Database.getQueryLocator('SELECT Id FROM Account'); + } + + public void execute(Database.BatchableContext context, List scope){ + } + + public void finish(database.BatchableContext context){ + } +} + ]]> + + + + Static results in stateful class + 0 + , Database.Stateful { + private static Database.DeleteResult deleteResult; + private static Database.EmptyRecycleBinResult emptyRecycleBinResult; + private static Database.LeadConvertResult leadConvertResult; + private static Database.MergeResult mergeResult; + private static Database.SaveResult saveResult; + private static Database.UndeleteResult undeleteResult; + private static Database.UpsertResult upsertResult; + + public Database.Querylocator start(Database.BatchableContext context){ + return Database.getQueryLocator('SELECT Id FROM Account'); + } + + public void execute(Database.BatchableContext context, List scope){ + } + + public void finish(database.BatchableContext context){ + } +} + ]]> + + + + Results in non-stateful class. + 0 + { + private Database.DeleteResult deleteResult; + private Database.EmptyRecycleBinResult emptyRecycleBinResult; + private Database.LeadConvertResult leadConvertResult; + private Database.MergeResult mergeResult; + private Database.SaveResult saveResult; + private Database.UndeleteResult undeleteResult; + private Database.UpsertResult upsertResult; + + public Database.Querylocator start(Database.BatchableContext context){ + return Database.getQueryLocator('SELECT Id FROM Account'); + } + + public void execute(Database.BatchableContext context, List scope){ + } + + public void finish(database.BatchableContext context){ + } +} + ]]> + + From 9de260d635b3495e25e0367702a27acda856dd19 Mon Sep 17 00:00:00 2001 From: mitchspano Date: Sun, 29 Dec 2024 09:59:59 +0000 Subject: [PATCH 0405/1962] Update formatting and error description --- .../resources/category/apex/errorprone.xml | 44 +++++++++++-------- .../xml/AvoidStatefulDatabaseResult.xml | 42 +++++++++--------- 2 files changed, 46 insertions(+), 40 deletions(-) diff --git a/pmd-apex/src/main/resources/category/apex/errorprone.xml b/pmd-apex/src/main/resources/category/apex/errorprone.xml index 291ca41c193..21dcb8c08bb 100644 --- a/pmd-apex/src/main/resources/category/apex/errorprone.xml +++ b/pmd-apex/src/main/resources/category/apex/errorprone.xml @@ -520,50 +520,56 @@ private class TestClass { class="net.sourceforge.pmd.lang.apex.rule.errorprone.AvoidStatefulDatabaseResultRule" externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_errorprone.html#avoidstatefuldatabaseresult"> - Storing Database.insertResult, Database.updateResult, etc. in instance variables - of a stateful batch class can cause serialization errors between batch iterations. - When this occurs, it is often inconsistent and challenging to troubleshoot. + Using instance variables of the following types (or collections of these types) within a stateful batch class can cause serialization errors between batch iterations: - See https://issues.salesforce.com/issue/a028c00000qPwlqAAC/stateful-batch-job-that-stores-databasesaveresult-failed-after-validation-errors-throws-error-during-deserialization for more details. + - `Database.DeleteResult` + - `Database.EmptyRecycleBinResult` + - `Database.MergeResult` + - `Database.SaveResult` + - `Database.UndeleteResult` + - `Database.UpsertResult` - This issue can be avoided by marking the variable as transient, or using a different + This error occurs inconsistently and asynchronously with an obscure error message - making it particularly challenging to troubleshoot. + See [this issue](https://issues.salesforce.com/issue/a028c00000qPwlqAAC/stateful-batch-job-that-stores-databasesaveresult-failed-after-validation-errors-throws-error-during-deserialization) for more details. + + These errors can be avoided by marking the variable as static, transient, or using a different data type that is safe to serialize. - 3 + 2 results = new List(); // this can cause failures +public class Example implements Database.Batchable, Database.Stateful { + List results = new List(); // This can cause failures - public Database.Querylocator start(Database.BatchableContext context){ + public Database.Querylocator start(Database.BatchableContext context) { return Database.getQueryLocator('SELECT Id FROM Account'); } - public void execute(Database.BatchableContext context, List scope){ + public void execute(Database.BatchableContext context, List scope) { Database.SaveResult[] saveResults = Database.update(scope, false); results.addAll(saveResults); } - public void finish(database.BatchableContext context){ + public void finish(database.BatchableContext context) { } } // Compliant -public class Example implements Database.Batchable, Database.Stateful { +public class Example implements Database.Batchable, Database.Stateful { List results = new List(); // Use a different custom type to persist state - public Database.Querylocator start(Database.BatchableContext context){ + public Database.Querylocator start(Database.BatchableContext context) { return Database.getQueryLocator('SELECT Id FROM Account'); } - public void execute(Database.BatchableContext context, List scope){ + public void execute(Database.BatchableContext context, List scope) { Database.SaveResult[] saveResults = Database.update(scope, false); for (Database.SaveResult result : saveResults) { results.add(new StatefulResult(result)); } } - public void finish(database.BatchableContext context){ + public void finish(database.BatchableContext context) { } } @@ -573,21 +579,21 @@ public class StatefulResult { private Id id; private Database.Error[] errors; - public StatefulResult(Database.SaveResult result){ + public StatefulResult(Database.SaveResult result) { isSuccess = result.isSuccess(); id = result.getId(); errors = result.getErrors(); } - public Boolean isSuccess(){ + public Boolean isSuccess() { return isSuccess; } - public Id getId(){ + public Id getId() { return id; } - public Database.Error[] getErrors(){ + public Database.Error[] getErrors() { return errors; } } diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/AvoidStatefulDatabaseResult.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/AvoidStatefulDatabaseResult.xml index 728376eb00c..81e352d268c 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/AvoidStatefulDatabaseResult.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/AvoidStatefulDatabaseResult.xml @@ -17,14 +17,14 @@ public class Example implements Database.Batchable, Database.Stateful { private Database.UndeleteResult undeleteResult; private Database.UpsertResult upsertResult; - public Database.Querylocator start(Database.BatchableContext context){ + public Database.Querylocator start(Database.BatchableContext context) { return Database.getQueryLocator('SELECT Id FROM Account'); } - public void execute(Database.BatchableContext context, List scope){ + public void execute(Database.BatchableContext context, List scope) { } - public void finish(database.BatchableContext context){ + public void finish(database.BatchableContext context) { } } ]]> @@ -43,14 +43,14 @@ public class Example implements Database.Batchable, Database.Stateful { private List undeleteResults = new List(); private List upsertResults = new List(); - public Database.Querylocator start(Database.BatchableContext context){ + public Database.Querylocator start(Database.BatchableContext context) { return Database.getQueryLocator('SELECT Id FROM Account'); } - public void execute(Database.BatchableContext context, List scope){ + public void execute(Database.BatchableContext context, List scope) { } - public void finish(database.BatchableContext context){ + public void finish(database.BatchableContext context) { } } ]]>
    @@ -69,14 +69,14 @@ public class Example implements Database.Batchable, Database.Stateful { private Set undeleteResults = new Set(); private Set upsertResults = new Set(); - public Database.Querylocator start(Database.BatchableContext context){ + public Database.Querylocator start(Database.BatchableContext context) { return Database.getQueryLocator('SELECT Id FROM Account'); } - public void execute(Database.BatchableContext context, List scope){ + public void execute(Database.BatchableContext context, List scope) { } - public void finish(database.BatchableContext context){ + public void finish(database.BatchableContext context) { } } ]]> @@ -95,14 +95,14 @@ public class Example implements Database.Batchable, Database.Stateful { private Map undeleteResults = new Map(); private Map upsertResults = new Map(); - public Database.Querylocator start(Database.BatchableContext context){ + public Database.Querylocator start(Database.BatchableContext context) { return Database.getQueryLocator('SELECT Id FROM Account'); } - public void execute(Database.BatchableContext context, List scope){ + public void execute(Database.BatchableContext context, List scope) { } - public void finish(database.BatchableContext context){ + public void finish(database.BatchableContext context) { } } ]]> @@ -121,14 +121,14 @@ public class Example implements Database.Batchable, Database.Stateful { private transient Database.UndeleteResult undeleteResult; private transient Database.UpsertResult upsertResult; - public Database.Querylocator start(Database.BatchableContext context){ + public Database.Querylocator start(Database.BatchableContext context) { return Database.getQueryLocator('SELECT Id FROM Account'); } - public void execute(Database.BatchableContext context, List scope){ + public void execute(Database.BatchableContext context, List scope) { } - public void finish(database.BatchableContext context){ + public void finish(database.BatchableContext context) { } } ]]> @@ -147,14 +147,14 @@ public class Example implements Database.Batchable, Database.Stateful { private static Database.UndeleteResult undeleteResult; private static Database.UpsertResult upsertResult; - public Database.Querylocator start(Database.BatchableContext context){ + public Database.Querylocator start(Database.BatchableContext context) { return Database.getQueryLocator('SELECT Id FROM Account'); } - public void execute(Database.BatchableContext context, List scope){ + public void execute(Database.BatchableContext context, List scope) { } - public void finish(database.BatchableContext context){ + public void finish(database.BatchableContext context) { } } ]]> @@ -173,14 +173,14 @@ public class Example implements Database.Batchable { private Database.UndeleteResult undeleteResult; private Database.UpsertResult upsertResult; - public Database.Querylocator start(Database.BatchableContext context){ + public Database.Querylocator start(Database.BatchableContext context) { return Database.getQueryLocator('SELECT Id FROM Account'); } - public void execute(Database.BatchableContext context, List scope){ + public void execute(Database.BatchableContext context, List scope) { } - public void finish(database.BatchableContext context){ + public void finish(database.BatchableContext context) { } } ]]> From 9c9d9cb3472406f381f50ee60bcb185c2b4e081c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Dec 2024 03:41:37 +0000 Subject: [PATCH 0406/1962] Bump org.codehaus.mojo:exec-maven-plugin from 3.2.0 to 3.5.0 Bumps [org.codehaus.mojo:exec-maven-plugin](https://github.com/mojohaus/exec-maven-plugin) from 3.2.0 to 3.5.0. - [Release notes](https://github.com/mojohaus/exec-maven-plugin/releases) - [Commits](https://github.com/mojohaus/exec-maven-plugin/compare/3.2.0...3.5.0) --- updated-dependencies: - dependency-name: org.codehaus.mojo:exec-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 568e8322aee..a8a9549ed68 100644 --- a/pom.xml +++ b/pom.xml @@ -375,7 +375,7 @@ org.codehaus.mojo exec-maven-plugin - 3.2.0 + 3.5.0 org.apache.maven.plugins From 9dc6fd177aaed7bbb10e0710e58ddeb21501701e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Dec 2024 03:41:40 +0000 Subject: [PATCH 0407/1962] Bump commons-logging:commons-logging from 1.3.0 to 1.3.4 Bumps commons-logging:commons-logging from 1.3.0 to 1.3.4. --- updated-dependencies: - dependency-name: commons-logging:commons-logging dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pmd-java/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 5c1f7296194..90fc3064313 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -279,7 +279,7 @@ commons-logging commons-logging - 1.3.0 + 1.3.4 test From 9c4808858616dc427984eb7c4503c1481c5a3370 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Dec 2024 03:41:45 +0000 Subject: [PATCH 0408/1962] Bump org.apache.maven.plugins:maven-enforcer-plugin from 3.4.1 to 3.5.0 Bumps [org.apache.maven.plugins:maven-enforcer-plugin](https://github.com/apache/maven-enforcer) from 3.4.1 to 3.5.0. - [Release notes](https://github.com/apache/maven-enforcer/releases) - [Commits](https://github.com/apache/maven-enforcer/compare/enforcer-3.4.1...enforcer-3.5.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-enforcer-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 568e8322aee..0f8f84f6748 100644 --- a/pom.xml +++ b/pom.xml @@ -506,7 +506,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 3.4.1 + 3.5.0 org.apache.maven.plugins From 26e1ce6b2c1d42140beff5f7695e34011d9d06f8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Dec 2024 03:53:50 +0000 Subject: [PATCH 0409/1962] Bump the all-gems group across 2 directories with 1 update Bumps the all-gems group with 1 update in the / directory: [bigdecimal](https://github.com/ruby/bigdecimal). Bumps the all-gems group with 1 update in the /docs directory: [bigdecimal](https://github.com/ruby/bigdecimal). Updates `bigdecimal` from 3.1.8 to 3.1.9 - [Release notes](https://github.com/ruby/bigdecimal/releases) - [Changelog](https://github.com/ruby/bigdecimal/blob/master/CHANGES.md) - [Commits](https://github.com/ruby/bigdecimal/compare/v3.1.8...v3.1.9) Updates `bigdecimal` from 3.1.8 to 3.1.9 - [Release notes](https://github.com/ruby/bigdecimal/releases) - [Changelog](https://github.com/ruby/bigdecimal/blob/master/CHANGES.md) - [Commits](https://github.com/ruby/bigdecimal/compare/v3.1.8...v3.1.9) --- updated-dependencies: - dependency-name: bigdecimal dependency-type: direct:development update-type: version-update:semver-patch dependency-group: all-gems - dependency-name: bigdecimal dependency-type: indirect update-type: version-update:semver-patch dependency-group: all-gems ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- docs/Gemfile.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 23766fb4e64..ef60207471b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -4,7 +4,7 @@ GEM addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) base64 (0.2.0) - bigdecimal (3.1.8) + bigdecimal (3.1.9) claide (1.1.0) claide-plugins (0.9.2) cork diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index e3cc6a1794a..2f647446db9 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -17,7 +17,7 @@ GEM public_suffix (>= 2.0.2, < 7.0) base64 (0.2.0) benchmark (0.3.0) - bigdecimal (3.1.8) + bigdecimal (3.1.9) coffee-script (2.4.1) coffee-script-source execjs From 1569af3c4bff49a610ff605c2ed0d98d42ba335e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 2 May 2024 17:22:15 +0200 Subject: [PATCH 0410/1962] Add dialect concept, make POM, WSDL, XSL dialects of XML --- .../net/sourceforge/pmd/lang/Language.java | 26 +++++++++++++++ .../pmd/lang/LanguageModuleBase.java | 32 ++++++++++++++----- .../pmd/lang/LanguageVersionDiscoverer.java | 15 ++++++--- .../pmd/lang/xml/XmlLanguageModule.java | 5 +++ .../pmd/lang/xml/pom/PomLanguageModule.java | 13 ++------ .../pmd/lang/xml/wsdl/WsdlLanguageModule.java | 18 +++-------- .../pmd/lang/xml/xsl/XslLanguageModule.java | 17 +++------- 7 files changed, 79 insertions(+), 47 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java index de5289cc281..428d55ced37 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java @@ -12,6 +12,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import net.sourceforge.pmd.cpd.CpdCapableLanguage; +import net.sourceforge.pmd.util.AssertionUtil; /** * Represents a language module, and provides access to language-specific @@ -62,6 +63,31 @@ public interface Language extends Comparable { */ String getId(); + /** + * If this is a dialect of another language, returns the base language. + * Dialects are for example different flavors of XML. + */ + default @Nullable String getBaseLanguageId() { + return null; + } + + /** + * Return true if this language is the given language, or a dialect thereof. + * + * @param language A language (not null) + */ + default boolean isDialectOf(Language language) { + AssertionUtil.requireParamNotNull("language", language); + if (this.equals(language)) { + return true; + } + String base = getBaseLanguageId(); + if (base == null) { + return false; + } + return base.equals(language.getId()); + } + /** * Returns the list of file extensions associated with this language. * This list is unmodifiable. Extensions do not have a '.' prefix. diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageModuleBase.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageModuleBase.java index aa59dd2a311..89caaa99e56 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageModuleBase.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageModuleBase.java @@ -40,6 +40,7 @@ public abstract class LanguageModuleBase implements Language { private final Map byName; private final LanguageVersion defaultVersion; private final Set dependencies; + private final @Nullable String baseLanguageId; /** @@ -52,6 +53,8 @@ protected LanguageModuleBase(LanguageMetadata metadata) { this.meta = metadata; metadata.validate(); this.dependencies = Collections.unmodifiableSet(metadata.dependencies); + this.baseLanguageId = meta.baseLanguageId; + List versions = new ArrayList<>(); Map byName = new HashMap<>(); LanguageVersion defaultVersion = null; @@ -102,6 +105,11 @@ private static void checkNotPresent(Map map, String alias) { } } + @Override + public @Nullable String getBaseLanguageId() { + return baseLanguageId; + } + @Override public List getVersions() { return distinctVersions; @@ -199,15 +207,13 @@ public static final class LanguageMetadata { private String name; private @Nullable String shortName; private final @NonNull String id; + private @Nullable String baseLanguageId; private List extensions; private final List versionMetadata = new ArrayList<>(); private LanguageMetadata(@NonNull String id) { this.id = id; - if (!VALID_LANG_ID.matcher(id).matches()) { - throw new IllegalArgumentException( - "ID '" + id + "' is not a valid language ID (should match " + VALID_LANG_ID + ")."); - } + checkValidLangId(id); } void validate() { @@ -355,6 +361,19 @@ public LanguageMetadata addAllVersionsOf(Language language) { return this; } + public LanguageMetadata dialectOf(String id) { + checkValidLangId(id); + this.baseLanguageId = id; + return this; + } + + private static void checkValidLangId(String id) { + if (!VALID_LANG_ID.matcher(id).matches()) { + throw new IllegalArgumentException( + "ID '" + id + "' is not a valid language ID (should match " + VALID_LANG_ID + ")."); + } + } + /** * Record that this language depends on another language, identified * by its id. This means any {@link LanguageProcessorRegistry} that @@ -368,10 +387,7 @@ public LanguageMetadata addAllVersionsOf(Language language) { */ public LanguageMetadata dependsOnLanguage(String id) { - if (!VALID_LANG_ID.matcher(id).matches()) { - throw new IllegalArgumentException( - "ID '" + id + "' is not a valid language ID (should match " + VALID_LANG_ID + ")."); - } + checkValidLangId(id); dependencies.add(id); return this; } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionDiscoverer.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionDiscoverer.java index 0fe6bbc7b76..d322fef0be3 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionDiscoverer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionDiscoverer.java @@ -9,12 +9,12 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.checkerframework.checker.nullness.qual.Nullable; import net.sourceforge.pmd.util.AssertionUtil; +import net.sourceforge.pmd.util.CollectionUtil; /** * This class can discover the LanguageVersion of a source file. Further, every @@ -130,9 +130,16 @@ public void setForcedVersion(LanguageVersion forceLanguageVersion) { */ public List getLanguagesForFile(String fileName) { String extension = getExtension(fileName); - return languageRegistry.getLanguages().stream() - .filter(it -> it.hasExtension(extension)) - .collect(Collectors.toList()); + List matching = languageRegistry.getLanguages().stream() + .filter(it -> it.hasExtension(extension)) + .collect(CollectionUtil.toMutableList()); + + if (matching.size() > 1) { + // Remove all languages that have a more specific dialect that matched. + matching.removeIf(l -> CollectionUtil.any(matching, it -> it.isDialectOf(l))); + } + + return matching; } // Get the extensions from a file diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/XmlLanguageModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/XmlLanguageModule.java index 4b3e30929ce..1762a787c2c 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/XmlLanguageModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/XmlLanguageModule.java @@ -24,6 +24,11 @@ public XmlLanguageModule() { new XmlHandler()); } + /** Constructor for dialects. */ + protected XmlLanguageModule(LanguageMetadata meta, XmlHandler xmlHandler) { + super(meta, xmlHandler); + } + public static XmlLanguageModule getInstance() { return (XmlLanguageModule) LanguageRegistry.PMD.getLanguageById(ID); } diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java index eb133f56e53..3e4ecf1ccf6 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java @@ -4,18 +4,15 @@ package net.sourceforge.pmd.lang.xml.pom; -import net.sourceforge.pmd.cpd.CpdLexer; -import net.sourceforge.pmd.lang.LanguagePropertyBundle; import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.impl.SimpleLanguageModuleBase; import net.sourceforge.pmd.lang.xml.XmlHandler; -import net.sourceforge.pmd.lang.xml.cpd.XmlCpdLexer; +import net.sourceforge.pmd.lang.xml.XmlLanguageModule; -public class PomLanguageModule extends SimpleLanguageModuleBase { +public class PomLanguageModule extends XmlLanguageModule { private static final String ID = "pom"; public PomLanguageModule() { - super(LanguageMetadata.withId(ID).name("Maven POM") + super(LanguageMetadata.withId(ID).name("Maven POM").dialectOf("xml") .extensions("pom") .addDefaultVersion("4.0.0"), new XmlHandler()); @@ -25,8 +22,4 @@ public static PomLanguageModule getInstance() { return (PomLanguageModule) LanguageRegistry.PMD.getLanguageById(ID); } - @Override - public CpdLexer createCpdLexer(LanguagePropertyBundle bundle) { - return new XmlCpdLexer(); - } } diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java index b439f019d36..fd6646ef03d 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java @@ -4,33 +4,25 @@ package net.sourceforge.pmd.lang.xml.wsdl; -import net.sourceforge.pmd.cpd.CpdLexer; -import net.sourceforge.pmd.lang.LanguagePropertyBundle; import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.impl.SimpleLanguageModuleBase; import net.sourceforge.pmd.lang.xml.XmlHandler; -import net.sourceforge.pmd.lang.xml.cpd.XmlCpdLexer; +import net.sourceforge.pmd.lang.xml.XmlLanguageModule; /** * Created by bernardo-macedo on 24.06.15. */ -public class WsdlLanguageModule extends SimpleLanguageModuleBase { +public class WsdlLanguageModule extends XmlLanguageModule { private static final String ID = "wsdl"; public WsdlLanguageModule() { - super(LanguageMetadata.withId(ID).name("WSDL") + super(LanguageMetadata.withId(ID).name("WSDL").dialectOf("xml") .extensions("wsdl") .addVersion("1.1") .addDefaultVersion("2.0"), - new XmlHandler()); + new XmlHandler()); } public static WsdlLanguageModule getInstance() { return (WsdlLanguageModule) LanguageRegistry.PMD.getLanguageById(ID); } - - @Override - public CpdLexer createCpdLexer(LanguagePropertyBundle bundle) { - return new XmlCpdLexer(); - } -} +} \ No newline at end of file diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java index 422cccd8535..fac4f7d6dcf 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java @@ -4,34 +4,27 @@ package net.sourceforge.pmd.lang.xml.xsl; -import net.sourceforge.pmd.cpd.CpdLexer; -import net.sourceforge.pmd.lang.LanguagePropertyBundle; import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.impl.SimpleLanguageModuleBase; import net.sourceforge.pmd.lang.xml.XmlHandler; -import net.sourceforge.pmd.lang.xml.cpd.XmlCpdLexer; +import net.sourceforge.pmd.lang.xml.XmlLanguageModule; /** * Created by christoferdutz on 20.09.14. */ -public class XslLanguageModule extends SimpleLanguageModuleBase { +public class XslLanguageModule extends XmlLanguageModule { private static final String ID = "xsl"; public XslLanguageModule() { - super(LanguageMetadata.withId(ID).name("XSL") + super(LanguageMetadata.withId(ID).name("XSL").dialectOf("xml") .extensions("xsl", "xslt") .addVersion("1.0") .addVersion("2.0") .addDefaultVersion("3.0"), - new XmlHandler()); + new XmlHandler()); } public static XslLanguageModule getInstance() { return (XslLanguageModule) LanguageRegistry.PMD.getLanguageById(ID); } - @Override - public CpdLexer createCpdLexer(LanguagePropertyBundle bundle) { - return new XmlCpdLexer(); - } -} +} \ No newline at end of file From dc3b762510bb2b7320c4af3e2202b164ce62514e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 2 May 2024 17:30:30 +0200 Subject: [PATCH 0411/1962] Make rules of XML apply to its dialects --- pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java | 4 +++- .../src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java index 428d55ced37..82ba3897583 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java @@ -65,7 +65,9 @@ public interface Language extends Comparable { /** * If this is a dialect of another language, returns the base language. - * Dialects are for example different flavors of XML. + * Dialects are for example different flavors of XML. Dialects must share + * the same AST as their base language. This makes it so that rules written + * for the base language can be applied files of all dialects uniformly. */ default @Nullable String getBaseLanguageId() { return null; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java index 7d39f31c1df..fce0b4c5735 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java @@ -631,7 +631,9 @@ static boolean applies(Rule rule, LanguageVersion languageVersion) { final LanguageVersion min = rule.getMinimumLanguageVersion(); final LanguageVersion max = rule.getMaximumLanguageVersion(); assert rule.getLanguage() != null : "Rule has no language " + rule; - return rule.getLanguage().equals(languageVersion.getLanguage()) + // All rules from base languages also apply to dialects. They + // have to share a parser for that to work. + return languageVersion.getLanguage().isDialectOf(rule.getLanguage()) && (min == null || min.compareTo(languageVersion) <= 0) && (max == null || max.compareTo(languageVersion) >= 0); } From 79e46a993b29f0c6ae0a7cba83b7f1ec4ac94b34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Wed, 1 Jan 2025 16:10:52 -0300 Subject: [PATCH 0412/1962] Model Dialect Language Metadata as standalone - The idea is to force people defining a metadata to follow a different implementation path (and hence, ensuring it behaves as a dialect) --- .../pmd/lang/LanguageModuleBase.java | 41 +++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageModuleBase.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageModuleBase.java index 89caaa99e56..c2ac58d5a5c 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageModuleBase.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageModuleBase.java @@ -23,6 +23,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import net.sourceforge.pmd.annotation.Experimental; import net.sourceforge.pmd.lang.LanguageModuleBase.LanguageMetadata.LangVersionMetadata; import net.sourceforge.pmd.util.AssertionUtil; import net.sourceforge.pmd.util.StringUtil; @@ -50,10 +51,14 @@ public abstract class LanguageModuleBase implements Language { * @throws IllegalStateException If the metadata is invalid (eg missing extensions or name or no versions) */ protected LanguageModuleBase(LanguageMetadata metadata) { + this(metadata, null); + } + + private LanguageModuleBase(LanguageMetadata metadata, String baseLanguageId) { this.meta = metadata; metadata.validate(); this.dependencies = Collections.unmodifiableSet(metadata.dependencies); - this.baseLanguageId = meta.baseLanguageId; + this.baseLanguageId = baseLanguageId; List versions = new ArrayList<>(); Map byName = new HashMap<>(); @@ -95,9 +100,12 @@ protected LanguageModuleBase(LanguageMetadata metadata) { this.byName = Collections.unmodifiableMap(byName); this.distinctVersions = Collections.unmodifiableList(versions); this.defaultVersion = Objects.requireNonNull(defaultVersion, "No default version for " + getId()); - } + @Experimental + protected LanguageModuleBase(DialectLanguageMetadata metadata) { + this(metadata.metadata, metadata.baseLanguageId); + } private static void checkNotPresent(Map map, String alias) { if (map.containsKey(alias)) { @@ -195,7 +203,6 @@ public boolean equals(Object obj) { *

  • The display name ({@link #name(String)}) *
  • The file extensions ({@link #extensions(String, String...)} * - * */ public static final class LanguageMetadata { @@ -207,7 +214,6 @@ public static final class LanguageMetadata { private String name; private @Nullable String shortName; private final @NonNull String id; - private @Nullable String baseLanguageId; private List extensions; private final List versionMetadata = new ArrayList<>(); @@ -361,10 +367,17 @@ public LanguageMetadata addAllVersionsOf(Language language) { return this; } - public LanguageMetadata dialectOf(String id) { + /** + * Defines the language as a dialect of another language. + * + * @param id The id of the base language this is a dialect of. + * @return A new dialect language metadata model. + */ + @Experimental + public DialectLanguageMetadata asDialectOf(String id) { checkValidLangId(id); - this.baseLanguageId = id; - return this; + dependsOnLanguage(id); // a dialect automatically depends on it's base language at runtime + return new DialectLanguageMetadata(this, id); } private static void checkValidLangId(String id) { @@ -422,4 +435,18 @@ private static void checkVersionName(String name) { } } } + + /** + * Expresses the language as a dialect of another language. + */ + @Experimental + public static final class DialectLanguageMetadata { + private final @NonNull LanguageMetadata metadata; + private final @NonNull String baseLanguageId; + + private DialectLanguageMetadata(LanguageMetadata metadata, String baseLanguageId) { + this.metadata = metadata; + this.baseLanguageId = baseLanguageId; + } + } } From 619f35ed517bed80e5c8d8ee5c86f89de2969051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Wed, 1 Jan 2025 16:12:16 -0300 Subject: [PATCH 0413/1962] Allow to combine to XPathHandlers together --- .../pmd/lang/rule/xpath/impl/XPathHandler.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/impl/XPathHandler.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/impl/XPathHandler.java index 73af54e17d2..fe71b8305e0 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/impl/XPathHandler.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/impl/XPathHandler.java @@ -38,4 +38,16 @@ static XPathHandler getHandlerForFunctionDefs(XPathFunctionDefinition first, XPa return () -> Collections.unmodifiableSet(set); } + + /** + * Return a new XPath handler combining all available functions from this and another handler. + * @param other The handler whose functions to merge with this one. + * @return Anew handler exposing all functions from both XPath handlers. + */ + default XPathHandler combine(XPathHandler other) { + Set set = new HashSet<>(getRegisteredExtensionFunctions()); + set.addAll(other.getRegisteredExtensionFunctions()); + + return () -> Collections.unmodifiableSet(set); + } } From cd09b2606b105cfd65dcca176c39745f9dd10b70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Wed, 1 Jan 2025 16:12:46 -0300 Subject: [PATCH 0414/1962] Provide base implementation for dialects - This takes in DialectLanguageMetadata instances and ensures the implementation for the language: - Uses the same parser as the base language, and therefore the same AST, so rules of the base language are applicable to a dialect. - Keeps all decorators from the base language, and adds the dialect's - Keeps all XPath functions from the base language, and adds the dialect's - Keeps all metrics from the base language, and adds the dialect's - Keeps all violation suppression from the base language, and adds the dialect's - Keeps all language properties from the language, and adds the dialect's --- .../BasePmdDialectLanguageVersionHandler.java | 25 ++ .../impl/SimpleDialectLanguageModuleBase.java | 214 ++++++++++++++++++ 2 files changed, 239 insertions(+) create mode 100644 pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/BasePmdDialectLanguageVersionHandler.java create mode 100644 pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/BasePmdDialectLanguageVersionHandler.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/BasePmdDialectLanguageVersionHandler.java new file mode 100644 index 00000000000..7f29bd6e1f6 --- /dev/null +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/BasePmdDialectLanguageVersionHandler.java @@ -0,0 +1,25 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.impl; + +import net.sourceforge.pmd.annotation.Experimental; +import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler; +import net.sourceforge.pmd.lang.ast.Parser; + +/** + * Base language version handler for dialect languages that support PMD, i.e. can build an AST + * and support AST processing stages. + * + * @author Juan Martรญn Sotuyo Dodero + * @since 7.10.0 + */ +@Experimental +public class BasePmdDialectLanguageVersionHandler extends AbstractPmdLanguageVersionHandler { + + @Override + public final Parser getParser() { + return null; + } +} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java new file mode 100644 index 00000000000..47bb5b72a90 --- /dev/null +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java @@ -0,0 +1,214 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.impl; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Function; + +import org.checkerframework.checker.nullness.qual.NonNull; + +import net.sourceforge.pmd.annotation.Experimental; +import net.sourceforge.pmd.cpd.CpdCapableLanguage; +import net.sourceforge.pmd.cpd.CpdLexer; +import net.sourceforge.pmd.lang.AbstractPmdLanguageVersionHandler; +import net.sourceforge.pmd.lang.Language; +import net.sourceforge.pmd.lang.LanguageModuleBase; +import net.sourceforge.pmd.lang.LanguageProcessor; +import net.sourceforge.pmd.lang.LanguagePropertyBundle; +import net.sourceforge.pmd.lang.LanguageRegistry; +import net.sourceforge.pmd.lang.LanguageVersionHandler; +import net.sourceforge.pmd.lang.PmdCapableLanguage; +import net.sourceforge.pmd.lang.ast.Parser; +import net.sourceforge.pmd.lang.metrics.LanguageMetricsProvider; +import net.sourceforge.pmd.lang.metrics.Metric; +import net.sourceforge.pmd.lang.rule.xpath.impl.XPathHandler; +import net.sourceforge.pmd.properties.PropertyDescriptor; +import net.sourceforge.pmd.reporting.ViolationDecorator; +import net.sourceforge.pmd.reporting.ViolationSuppressor; +import net.sourceforge.pmd.util.CollectionUtil; +import net.sourceforge.pmd.util.designerbindings.DesignerBindings; + +/** + * The simplest implementation of a dialect, where only a {@link LanguageMetadata} + * needs to be implemented. Everything gets delegated to the base language, + * with all dialect extension applied. + * + * @author Juan Martรญn Sotuyo Dodero + * @since 7.10.0 + */ +@Experimental +public class SimpleDialectLanguageModuleBase extends LanguageModuleBase implements PmdCapableLanguage, CpdCapableLanguage { + + private final Function handler; + + protected SimpleDialectLanguageModuleBase(DialectLanguageMetadata metadata) { + this(metadata, new BasePmdDialectLanguageVersionHandler()); + } + + protected SimpleDialectLanguageModuleBase(DialectLanguageMetadata metadata, BasePmdDialectLanguageVersionHandler handler) { + this(metadata, p -> handler); + } + + protected SimpleDialectLanguageModuleBase(DialectLanguageMetadata metadata, Function makeHandler) { + super(metadata); + assert getBaseLanguageId() != null : "Language " + getId() + " is not a dialect of another language."; + + this.handler = makeHandler; + } + + private @NonNull Language getBaseLanguageFromRegistry(LanguageRegistry registry) { + final Language baseLanguage = registry.getLanguageById(getBaseLanguageId()); + + if (baseLanguage == null) { + throw new IllegalStateException( + "Language " + getId() + " has unsatisfied dependencies: " + + getBaseLanguageId() + " is not found in " + registry + ); + } + + return baseLanguage; + } + + /** + * Creates a combined property bundle with all properties from the dialect and the base language. + * To define dialect-specific properties to be added to this bundle, override {@link #newDialectPropertyBundle()} + * @return A new set of properties + */ + @Override + public final LanguagePropertyBundle newPropertyBundle() { + LanguagePropertyBundle baseBundle = getBaseLanguageFromRegistry(LanguageRegistry.PMD).newPropertyBundle(); + LanguagePropertyBundle dialectBundle = newDialectPropertyBundle(); + + for (PropertyDescriptor pd : baseBundle.getPropertyDescriptors()) { + if (!dialectBundle.hasDescriptor(pd)) { + dialectBundle.definePropertyDescriptor(pd); + } + } + + return dialectBundle; + } + + protected @NonNull LanguagePropertyBundle newDialectPropertyBundle() { + return new LanguagePropertyBundle(this); + } + + @Override + public final LanguageProcessor createProcessor(LanguagePropertyBundle bundle) { + final PmdCapableLanguage baseLanguage = (PmdCapableLanguage) getBaseLanguageFromRegistry(LanguageRegistry.PMD); + final BasePmdDialectLanguageVersionHandler dialectHandler = handler.apply(bundle); + + return new DialectLanguageProcessor(baseLanguage, dialectHandler, bundle); + } + + @Override + public CpdLexer createCpdLexer(LanguagePropertyBundle bundle) { + final CpdCapableLanguage baseLanguage = (CpdCapableLanguage) getBaseLanguageFromRegistry(LanguageRegistry.CPD); + return baseLanguage.createCpdLexer(bundle); + } + + /** + * A Language processor for dialects. It delegates everything to the base language, but extends + * the {@link LanguageVersionHandler} with any dialect-specific options. + */ + private static class DialectLanguageProcessor extends BatchLanguageProcessor { + private final LanguageProcessor baseLanguageProcessor; + private final LanguageVersionHandler combinedHandler; + + private DialectLanguageProcessor(PmdCapableLanguage baseLanguage, BasePmdDialectLanguageVersionHandler dialectHandler, LanguagePropertyBundle bundle) { + super(bundle); + this.baseLanguageProcessor = baseLanguage.createProcessor(bundle); + this.combinedHandler = new SimpleDialectLanguageVersionHandler(baseLanguageProcessor.services(), dialectHandler); + } + + @Override + public @NonNull LanguageVersionHandler services() { + return combinedHandler; + } + + @Override + public @NonNull AutoCloseable launchAnalysis(@NonNull AnalysisTask analysisTask) { + return baseLanguageProcessor.launchAnalysis(analysisTask); + } + + @Override + public void close() throws Exception { + super.close(); + baseLanguageProcessor.close(); + } + } + + /** + * A composite language version handler that merges a dialect's extension with the bae language. + */ + private static class SimpleDialectLanguageVersionHandler extends AbstractPmdLanguageVersionHandler { + + private final LanguageVersionHandler baseLanguageVersionHandler; + private final LanguageVersionHandler dialectLanguageVersionHandler; + + public SimpleDialectLanguageVersionHandler(LanguageVersionHandler baseLanguageVersionHandler, LanguageVersionHandler dialectLanguageVersionHandler) { + this.baseLanguageVersionHandler = baseLanguageVersionHandler; + this.dialectLanguageVersionHandler = dialectLanguageVersionHandler; + } + + @Override + public XPathHandler getXPathHandler() { + // Add dialect-specific XPath functions + return baseLanguageVersionHandler.getXPathHandler() + .combine(dialectLanguageVersionHandler.getXPathHandler()); + } + + @Override + public Parser getParser() { + // Always the base language parser for full compatibility (same AST) + return baseLanguageVersionHandler.getParser(); + } + + @Override + public ViolationDecorator getViolationDecorator() { + return ViolationDecorator.chain( + Arrays.asList(baseLanguageVersionHandler.getViolationDecorator(), + dialectLanguageVersionHandler.getViolationDecorator())); + } + + @Override + public List getExtraViolationSuppressors() { + return CollectionUtil.concatView( + baseLanguageVersionHandler.getExtraViolationSuppressors(), + dialectLanguageVersionHandler.getExtraViolationSuppressors()); + } + + @Override + public LanguageMetricsProvider getLanguageMetricsProvider() { + if (baseLanguageVersionHandler.getLanguageMetricsProvider() == null) { + return dialectLanguageVersionHandler.getLanguageMetricsProvider(); + } + + if (dialectLanguageVersionHandler.getLanguageMetricsProvider() == null) { + return baseLanguageVersionHandler.getLanguageMetricsProvider(); + } + + // merge metrics if both define any + return () -> { + Set> mergedSet = new HashSet<>(); + mergedSet.addAll(baseLanguageVersionHandler.getLanguageMetricsProvider().getMetrics()); + mergedSet.addAll(dialectLanguageVersionHandler.getLanguageMetricsProvider().getMetrics()); + return mergedSet; + }; + } + + @Override + public DesignerBindings getDesignerBindings() { + // if the dialect set something it has priority + if (DesignerBindings.DefaultDesignerBindings.getInstance().equals(dialectLanguageVersionHandler.getDesignerBindings())) { + return baseLanguageVersionHandler.getDesignerBindings(); + } + + return dialectLanguageVersionHandler.getDesignerBindings(); + } + } +} From 7761a95b29c279a9ceccc37a3d04352b9d70ff0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Wed, 1 Jan 2025 16:16:11 -0300 Subject: [PATCH 0415/1962] Update the XML languages' implementation - Now they are proper dialects, without needing to extend or have a compile-time dependency into the base language. --- .../sourceforge/pmd/lang/xml/XmlLanguageModule.java | 5 ----- .../pmd/lang/xml/pom/PomLanguageModule.java | 11 +++++------ .../pmd/lang/xml/wsdl/WsdlLanguageModule.java | 11 +++++------ .../pmd/lang/xml/xsl/XslLanguageModule.java | 11 +++++------ 4 files changed, 15 insertions(+), 23 deletions(-) diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/XmlLanguageModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/XmlLanguageModule.java index 1762a787c2c..4b3e30929ce 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/XmlLanguageModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/XmlLanguageModule.java @@ -24,11 +24,6 @@ public XmlLanguageModule() { new XmlHandler()); } - /** Constructor for dialects. */ - protected XmlLanguageModule(LanguageMetadata meta, XmlHandler xmlHandler) { - super(meta, xmlHandler); - } - public static XmlLanguageModule getInstance() { return (XmlLanguageModule) LanguageRegistry.PMD.getLanguageById(ID); } diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java index 3e4ecf1ccf6..5e73f2bfa5e 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java @@ -5,17 +5,16 @@ package net.sourceforge.pmd.lang.xml.pom; import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.xml.XmlHandler; -import net.sourceforge.pmd.lang.xml.XmlLanguageModule; +import net.sourceforge.pmd.lang.impl.SimpleDialectLanguageModuleBase; -public class PomLanguageModule extends XmlLanguageModule { +public class PomLanguageModule extends SimpleDialectLanguageModuleBase { private static final String ID = "pom"; public PomLanguageModule() { - super(LanguageMetadata.withId(ID).name("Maven POM").dialectOf("xml") + super(LanguageMetadata.withId(ID).name("Maven POM") .extensions("pom") - .addDefaultVersion("4.0.0"), - new XmlHandler()); + .addDefaultVersion("4.0.0") + .asDialectOf("xml")); } public static PomLanguageModule getInstance() { diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java index fd6646ef03d..4ec26d74ab4 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java @@ -5,21 +5,20 @@ package net.sourceforge.pmd.lang.xml.wsdl; import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.xml.XmlHandler; -import net.sourceforge.pmd.lang.xml.XmlLanguageModule; +import net.sourceforge.pmd.lang.impl.SimpleDialectLanguageModuleBase; /** * Created by bernardo-macedo on 24.06.15. */ -public class WsdlLanguageModule extends XmlLanguageModule { +public class WsdlLanguageModule extends SimpleDialectLanguageModuleBase { private static final String ID = "wsdl"; public WsdlLanguageModule() { - super(LanguageMetadata.withId(ID).name("WSDL").dialectOf("xml") + super(LanguageMetadata.withId(ID).name("WSDL") .extensions("wsdl") .addVersion("1.1") - .addDefaultVersion("2.0"), - new XmlHandler()); + .addDefaultVersion("2.0") + .asDialectOf("xml")); } public static WsdlLanguageModule getInstance() { diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java index fac4f7d6dcf..19396e52374 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java @@ -5,22 +5,21 @@ package net.sourceforge.pmd.lang.xml.xsl; import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.xml.XmlHandler; -import net.sourceforge.pmd.lang.xml.XmlLanguageModule; +import net.sourceforge.pmd.lang.impl.SimpleDialectLanguageModuleBase; /** * Created by christoferdutz on 20.09.14. */ -public class XslLanguageModule extends XmlLanguageModule { +public class XslLanguageModule extends SimpleDialectLanguageModuleBase { private static final String ID = "xsl"; public XslLanguageModule() { - super(LanguageMetadata.withId(ID).name("XSL").dialectOf("xml") + super(LanguageMetadata.withId(ID).name("XSL") .extensions("xsl", "xslt") .addVersion("1.0") .addVersion("2.0") - .addDefaultVersion("3.0"), - new XmlHandler()); + .addDefaultVersion("3.0") + .asDialectOf("xml")); } public static XslLanguageModule getInstance() { From 954097ad6ce99bf4ee9ec1857b0e8fb12bd8618a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Wed, 1 Jan 2025 17:10:53 -0300 Subject: [PATCH 0416/1962] Fix PMD warnings --- pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java | 4 ++++ .../pmd/lang/impl/SimpleDialectLanguageModuleBase.java | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java index 82ba3897583..7c98532de86 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java @@ -11,6 +11,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import net.sourceforge.pmd.annotation.Experimental; import net.sourceforge.pmd.cpd.CpdCapableLanguage; import net.sourceforge.pmd.util.AssertionUtil; @@ -69,6 +70,7 @@ public interface Language extends Comparable { * the same AST as their base language. This makes it so that rules written * for the base language can be applied files of all dialects uniformly. */ + @Experimental default @Nullable String getBaseLanguageId() { return null; } @@ -78,6 +80,8 @@ public interface Language extends Comparable { * * @param language A language (not null) */ + @Experimental + @SuppressWarnings("PMD.SimplifyBooleanReturns") default boolean isDialectOf(Language language) { AssertionUtil.requireParamNotNull("language", language); if (this.equals(language)) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java index 47bb5b72a90..a1452812e08 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java @@ -115,7 +115,7 @@ public CpdLexer createCpdLexer(LanguagePropertyBundle bundle) { * A Language processor for dialects. It delegates everything to the base language, but extends * the {@link LanguageVersionHandler} with any dialect-specific options. */ - private static class DialectLanguageProcessor extends BatchLanguageProcessor { + private final static class DialectLanguageProcessor extends BatchLanguageProcessor { private final LanguageProcessor baseLanguageProcessor; private final LanguageVersionHandler combinedHandler; From 892bb3006a7df31910b7d3fe793dbdef5b144c00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Wed, 1 Jan 2025 17:34:51 -0300 Subject: [PATCH 0417/1962] Fix style violations --- .../pmd/lang/impl/SimpleDialectLanguageModuleBase.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java index a1452812e08..b0aa80ae07f 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java @@ -115,7 +115,7 @@ public CpdLexer createCpdLexer(LanguagePropertyBundle bundle) { * A Language processor for dialects. It delegates everything to the base language, but extends * the {@link LanguageVersionHandler} with any dialect-specific options. */ - private final static class DialectLanguageProcessor extends BatchLanguageProcessor { + private static final class DialectLanguageProcessor extends BatchLanguageProcessor { private final LanguageProcessor baseLanguageProcessor; private final LanguageVersionHandler combinedHandler; @@ -150,7 +150,7 @@ private static class SimpleDialectLanguageVersionHandler extends AbstractPmdLang private final LanguageVersionHandler baseLanguageVersionHandler; private final LanguageVersionHandler dialectLanguageVersionHandler; - public SimpleDialectLanguageVersionHandler(LanguageVersionHandler baseLanguageVersionHandler, LanguageVersionHandler dialectLanguageVersionHandler) { + SimpleDialectLanguageVersionHandler(LanguageVersionHandler baseLanguageVersionHandler, LanguageVersionHandler dialectLanguageVersionHandler) { this.baseLanguageVersionHandler = baseLanguageVersionHandler; this.dialectLanguageVersionHandler = dialectLanguageVersionHandler; } From 254e803e5cc4644372e17988c74fdf44634f9984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Wed, 1 Jan 2025 18:12:26 -0300 Subject: [PATCH 0418/1962] Style issues --- .../net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java | 2 +- .../net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java index 4ec26d74ab4..b8acf0c7705 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java @@ -24,4 +24,4 @@ public WsdlLanguageModule() { public static WsdlLanguageModule getInstance() { return (WsdlLanguageModule) LanguageRegistry.PMD.getLanguageById(ID); } -} \ No newline at end of file +} diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java index 19396e52374..d6c92686bfb 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java @@ -25,5 +25,4 @@ public XslLanguageModule() { public static XslLanguageModule getInstance() { return (XslLanguageModule) LanguageRegistry.PMD.getLanguageById(ID); } - -} \ No newline at end of file +} From 3d33d4bb4251cc3023a04daea95eec414b2be9c8 Mon Sep 17 00:00:00 2001 From: mitchspano Date: Fri, 3 Jan 2025 17:34:55 +0000 Subject: [PATCH 0419/1962] Add SystemNamespaceCollision rule --- .../resources/category/apex/errorprone.xml | 259 +++++++++++------- 1 file changed, 164 insertions(+), 95 deletions(-) diff --git a/pmd-apex/src/main/resources/category/apex/errorprone.xml b/pmd-apex/src/main/resources/category/apex/errorprone.xml index cd0b6334dec..4a855b94380 100644 --- a/pmd-apex/src/main/resources/category/apex/errorprone.xml +++ b/pmd-apex/src/main/resources/category/apex/errorprone.xml @@ -4,11 +4,11 @@ xmlns="http://pmd.sourceforge.net/ruleset/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd"> - + -Rules to detect constructs that are either broken, extremely confusing or prone to runtime errors. + Rules to detect constructs that are either broken, extremely confusing or prone to runtime errors. - + -Having DML operations in Apex class constructor or initializers can have unexpected side effects: -By just accessing a page, the DML statements would be executed and the database would be modified. -Just querying the database is permitted. - -In addition to constructors and initializers, any method called `init` is checked as well. - -Salesforce Apex already protects against this scenario and raises a runtime exception. - -Note: This rule has been moved from category "Security" to "Error Prone" with PMD 6.21.0, since -using DML in constructors is not a security problem, but crashes the application. + Having DML operations in Apex class constructor or initializers can have unexpected side effects: + By just accessing a page, the DML statements would be executed and the database would be modified. + Just querying the database is permitted. + + In addition to constructors and initializers, any method called `init` is checked as well. + + Salesforce Apex already protects against this scenario and raises a runtime exception. + + Note: This rule has been moved from category "Security" to "Error Prone" with PMD 6.21.0, since + using DML in constructors is not a security problem, but crashes the application. 3 - - + -Avoid directly accessing Trigger.old and Trigger.new as it can lead to a bug. Triggers should be bulkified and iterate through the map to handle the actions for each item separately. + Avoid directly accessing Trigger.old and Trigger.new as it can lead to a bug. Triggers should be bulkified and iterate through the map to handle the actions for each item separately. 3 - + - - - + -When deploying Apex code between sandbox and production environments, or installing Force.com AppExchange packages, -it is essential to avoid hardcoding IDs in the Apex code. By doing so, if the record IDs change between environments, -the logic can dynamically identify the proper data to operate against and not fail. + When deploying Apex code between sandbox and production environments, or installing Force.com AppExchange packages, + it is essential to avoid hardcoding IDs in the Apex code. By doing so, if the record IDs change between environments, + the logic can dynamically identify the proper data to operate against and not fail. 3 - - + 3 - - + -Empty Catch Block finds instances where an exception is caught, but nothing is done. -In most circumstances, this swallows an exception which should either be acted on -or reported. + Empty Catch Block finds instances where an exception is caught, but nothing is done. + In most circumstances, this swallows an exception which should either be acted on + or reported. 3 @@ -151,7 +151,7 @@ or reported. - - - + -Empty If Statement finds instances where a condition is checked but nothing is done about it. + Empty If Statement finds instances where a condition is checked but nothing is done about it. 3 - + - - + -Empty block statements serve no purpose and should be removed. + Empty block statements serve no purpose and should be removed. 3 @@ -221,7 +221,7 @@ Empty block statements serve no purpose and should be removed. - - - + -Avoid empty try or finally blocks - what's the point? + Avoid empty try or finally blocks - what's the point? 3 - + - - + -Empty While Statement finds all instances where a while statement does nothing. -If it is a timing loop, then you should use Thread.sleep() for it; if it is -a while loop that does a lot in the exit expression, rewrite it to make it clearer. + Empty While Statement finds all instances where a while statement does nothing. + If it is a timing loop, then you should use Thread.sleep() for it; if it is + a while loop that does a lot in the exit expression, rewrite it to make it clearer. 3 - + - - + -In the Summer '21 release, a mandatory security update enforces access modifiers on Apex properties in -Lightning component markup. The update prevents access to private or protected Apex getters from Aura -and Lightning Web Components. + In the Summer '21 release, a mandatory security update enforces access modifiers on Apex properties in + Lightning component markup. The update prevents access to private or protected Apex getters from Aura + and Lightning Web Components. 3 - - - - + -Non-constructor methods should not have the same name as the enclosing class. + Non-constructor methods should not have the same name as the enclosing class. 3 - - + -Override both `public Boolean equals(Object obj)`, and `public Integer hashCode()`, or override neither. -Even if you are inheriting a hashCode() from a parent class, consider implementing hashCode and explicitly -delegating to your superclass. - -This is especially important when [Using Custom Types in Map Keys and Sets](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_collections_maps_keys_userdefined.htm). + Override both `public Boolean equals(Object obj)`, and `public Integer hashCode()`, or override neither. + Even if you are inheriting a hashCode() from a parent class, consider implementing hashCode and explicitly + delegating to your superclass. + + This is especially important when [Using Custom Types in Map Keys and Sets](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_collections_maps_keys_userdefined.htm). 3 - - + - - Test methods marked as a testMethod or annotated with @IsTest, - but not residing in a test class should be moved to a proper - class or have the @IsTest annotation added to the class. - - Support for tests inside functional classes was removed in Spring-13 (API Version 27.0), - making classes that violate this rule fail compile-time. This rule is mostly usable when - dealing with legacy code. - - 3 - - - - + Test methods marked as a testMethod or annotated with @IsTest, + but not residing in a test class should be moved to a proper + class or have the @IsTest annotation added to the class. + + Support for tests inside functional classes was removed in Spring-13 (API Version 27.0), + making classes that violate this rule fail compile-time. This rule is mostly usable when + dealing with legacy code. + + 3 + + + + - - - - - + + + + - + + + + + + This rule finds Apex classes, enums, and interfaces that have the same name as a class, enum, or interface in the `System` namespace. + Shadowing the `System` namespace in this way can lead to confusion and unexpected behavior. + Code that intends to reference a `System` class, enum, or interface may inadvertently reference the locally defined type instead. + This can result in ambiguous code and unexpected runtime behavior. + It is best to avoid naming your types the same as those in the `System` namespace to prevent these issues. + + 1 + + + + + + + + + + + + + From 35209c0b83fc4c15947407aec3b476c8da9ea2cf Mon Sep 17 00:00:00 2001 From: mitchspano Date: Sat, 4 Jan 2025 01:02:24 +0000 Subject: [PATCH 0420/1962] Tests for System namespace --- .../resources/category/apex/errorprone.xml | 9 ++-- .../SystemNamespaceCollisionTest.java | 11 +++++ .../xml/SystemNamespaceCollision.xml | 44 +++++++++++++++++++ 3 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/SystemNamespaceCollisionTest.java create mode 100644 pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/SystemNamespaceCollision.xml diff --git a/pmd-apex/src/main/resources/category/apex/errorprone.xml b/pmd-apex/src/main/resources/category/apex/errorprone.xml index 4a855b94380..c44e2bc4998 100644 --- a/pmd-apex/src/main/resources/category/apex/errorprone.xml +++ b/pmd-apex/src/main/resources/category/apex/errorprone.xml @@ -516,10 +516,10 @@ private class TestClass { + class="net.sourceforge.pmd.lang.rule.xpath.XPathRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_errorprone.html#systemnamespacecollision"> This rule finds Apex classes, enums, and interfaces that have the same name as a class, enum, or interface in the `System` namespace. Shadowing the `System` namespace in this way can lead to confusion and unexpected behavior. @@ -547,8 +547,7 @@ private class TestClass { description="Comma-separated list of interfaces in the `System` namespace." value="callable,comparable,comparator,httpcalloutmock,installhandler,queueable,queueablecontext,sandboxpostcopy,schedulable,schedulablecontext,stubprovider,uninstallhandler,webservicemock" /> - + + + + + Shadows a class in the System namespace + 1 + 1 + + + + + Shadows an enum in the System namespace + 1 + 1 + + + + + Shadows an interface in the System namespace + 1 + 1 + + + + + No shadowing + 0 + + + \ No newline at end of file From e848d5bf6f79923655220a5781478a4a1661cf31 Mon Sep 17 00:00:00 2001 From: Mitchell spano Date: Mon, 6 Jan 2025 10:26:49 -0600 Subject: [PATCH 0421/1962] Reset formatting --- .../resources/category/apex/errorprone.xml | 191 +++++++++--------- 1 file changed, 95 insertions(+), 96 deletions(-) diff --git a/pmd-apex/src/main/resources/category/apex/errorprone.xml b/pmd-apex/src/main/resources/category/apex/errorprone.xml index c44e2bc4998..cca3bcbbe0c 100644 --- a/pmd-apex/src/main/resources/category/apex/errorprone.xml +++ b/pmd-apex/src/main/resources/category/apex/errorprone.xml @@ -4,11 +4,11 @@ xmlns="http://pmd.sourceforge.net/ruleset/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd"> - + - Rules to detect constructs that are either broken, extremely confusing or prone to runtime errors. +Rules to detect constructs that are either broken, extremely confusing or prone to runtime errors. - + - Having DML operations in Apex class constructor or initializers can have unexpected side effects: - By just accessing a page, the DML statements would be executed and the database would be modified. - Just querying the database is permitted. - - In addition to constructors and initializers, any method called `init` is checked as well. - - Salesforce Apex already protects against this scenario and raises a runtime exception. - - Note: This rule has been moved from category "Security" to "Error Prone" with PMD 6.21.0, since - using DML in constructors is not a security problem, but crashes the application. +Having DML operations in Apex class constructor or initializers can have unexpected side effects: +By just accessing a page, the DML statements would be executed and the database would be modified. +Just querying the database is permitted. + +In addition to constructors and initializers, any method called `init` is checked as well. + +Salesforce Apex already protects against this scenario and raises a runtime exception. + +Note: This rule has been moved from category "Security" to "Error Prone" with PMD 6.21.0, since +using DML in constructors is not a security problem, but crashes the application. 3 - - + - Avoid directly accessing Trigger.old and Trigger.new as it can lead to a bug. Triggers should be bulkified and iterate through the map to handle the actions for each item separately. +Avoid directly accessing Trigger.old and Trigger.new as it can lead to a bug. Triggers should be bulkified and iterate through the map to handle the actions for each item separately. 3 - + - - - + - When deploying Apex code between sandbox and production environments, or installing Force.com AppExchange packages, - it is essential to avoid hardcoding IDs in the Apex code. By doing so, if the record IDs change between environments, - the logic can dynamically identify the proper data to operate against and not fail. +When deploying Apex code between sandbox and production environments, or installing Force.com AppExchange packages, +it is essential to avoid hardcoding IDs in the Apex code. By doing so, if the record IDs change between environments, +the logic can dynamically identify the proper data to operate against and not fail. 3 - - + 3 - - + - Empty Catch Block finds instances where an exception is caught, but nothing is done. - In most circumstances, this swallows an exception which should either be acted on - or reported. +Empty Catch Block finds instances where an exception is caught, but nothing is done. +In most circumstances, this swallows an exception which should either be acted on +or reported. 3 @@ -151,7 +151,7 @@ public without sharing class Foo { - - - + - Empty If Statement finds instances where a condition is checked but nothing is done about it. +Empty If Statement finds instances where a condition is checked but nothing is done about it. 3 - + - - + - Empty block statements serve no purpose and should be removed. +Empty block statements serve no purpose and should be removed. 3 @@ -221,7 +221,7 @@ public class Foo { - - - + - Avoid empty try or finally blocks - what's the point? +Avoid empty try or finally blocks - what's the point? 3 - + - - + - Empty While Statement finds all instances where a while statement does nothing. - If it is a timing loop, then you should use Thread.sleep() for it; if it is - a while loop that does a lot in the exit expression, rewrite it to make it clearer. +Empty While Statement finds all instances where a while statement does nothing. +If it is a timing loop, then you should use Thread.sleep() for it; if it is +a while loop that does a lot in the exit expression, rewrite it to make it clearer. 3 - + - - + - In the Summer '21 release, a mandatory security update enforces access modifiers on Apex properties in - Lightning component markup. The update prevents access to private or protected Apex getters from Aura - and Lightning Web Components. +In the Summer '21 release, a mandatory security update enforces access modifiers on Apex properties in +Lightning component markup. The update prevents access to private or protected Apex getters from Aura +and Lightning Web Components. 3 - - - - + - Non-constructor methods should not have the same name as the enclosing class. +Non-constructor methods should not have the same name as the enclosing class. 3 - - + - Override both `public Boolean equals(Object obj)`, and `public Integer hashCode()`, or override neither. - Even if you are inheriting a hashCode() from a parent class, consider implementing hashCode and explicitly - delegating to your superclass. - - This is especially important when [Using Custom Types in Map Keys and Sets](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_collections_maps_keys_userdefined.htm). +Override both `public Boolean equals(Object obj)`, and `public Integer hashCode()`, or override neither. +Even if you are inheriting a hashCode() from a parent class, consider implementing hashCode and explicitly +delegating to your superclass. + +This is especially important when [Using Custom Types in Map Keys and Sets](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_collections_maps_keys_userdefined.htm). 3 - - + - - Test methods marked as a testMethod or annotated with @IsTest, - but not residing in a test class should be moved to a proper - class or have the @IsTest annotation added to the class. - - Support for tests inside functional classes was removed in Spring-13 (API Version 27.0), - making classes that violate this rule fail compile-time. This rule is mostly usable when - dealing with legacy code. - - 3 - - - - + Test methods marked as a testMethod or annotated with @IsTest, + but not residing in a test class should be moved to a proper + class or have the @IsTest annotation added to the class. + + Support for tests inside functional classes was removed in Spring-13 (API Version 27.0), + making classes that violate this rule fail compile-time. This rule is mostly usable when + dealing with legacy code. + + 3 + + + + - - - - - + + + + - + - Date: Mon, 6 Jan 2025 19:18:56 +0100 Subject: [PATCH 0422/1962] Use new gpg key (A0B5CA1A4E086838) --- .github/workflows/build.yml | 4 +++- docs/pages/release_notes.md | 11 +++++++++++ pom.xml | 7 +++++-- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 19a0cb5e1ad..1a223b5d894 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -59,7 +59,7 @@ jobs: run: | echo "LANG=en_US.UTF-8" >> $GITHUB_ENV echo "MAVEN_OPTS=-Daether.connector.http.connectionMaxTtl=180 -DautoReleaseAfterClose=true -DstagingProgressTimeoutMinutes=30" >> $GITHUB_ENV - echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/28/scripts" >> $GITHUB_ENV + echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/main/scripts" >> $GITHUB_ENV - name: Check Environment shell: bash run: | @@ -75,6 +75,8 @@ jobs: BUILD_CLI_DIST_ONLY: ${{ inputs.build_cli_dist_only }} PMD_CI_SECRET_PASSPHRASE: ${{ secrets.PMD_CI_SECRET_PASSPHRASE }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PMD_CI_GPG_PRIVATE_KEY: ${{ secrets.PMD_CI_GPG_PRIVATE_KEY }} + MAVEN_GPG_PASSPHRASE: ${{ secrets.PMD_CI_GPG_PASSPHRASE }} - name: Workaround actions/upload-artifact#176 run: | echo "artifacts_path=$(realpath ..)" >> $GITHUB_ENV diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 26ec825d013..6dc55dc7975 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -14,6 +14,17 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy +### New GPG Release Signing Key + +Since January 2025, we switched the GPG Key we use for signing releases in Maven Central to be +[A0B5CA1A4E086838](https://keyserver.ubuntu.com/pks/lookup?search=0x2EFA55D0785C31F956F2F87EA0B5CA1A4E086838&fingerprint=on&op=index). +The full fingerprint is `2EFA 55D0 785C 31F9 56F2 F87E A0B5 CA1A 4E08 6838`. + +This step was necessary, as the passphrase of the old key has been compromised and therefore the key is not +safe to use anymore. While the key itself is not compromised as far as we know, we still decided to generate a +new key, just to be safe. As until now (January 2025) we are not aware, that the key actually has been misused. +The previous releases of PMD in Maven Central can still be considered untampered, as Maven Central is read-only. + ### ๐Ÿ› Fixed Issues ### ๐Ÿšจ API Changes diff --git a/pom.xml b/pom.xml index 42a42b01474..50d9949affd 100644 --- a/pom.xml +++ b/pom.xml @@ -115,7 +115,7 @@ -Xmx512m -Dfile.encoding=${project.build.sourceEncoding} ${extraArgLine} - 28 + 29-SNAPSHOT 7.2.0 @@ -1206,7 +1206,10 @@ org.apache.maven.plugins maven-gpg-plugin - 3.1.0 + 3.2.7 + + true + sign-artifacts From 8d92230074885f85f84c4d55dbbb7ab48934c208 Mon Sep 17 00:00:00 2001 From: Mitchell spano Date: Mon, 6 Jan 2025 13:51:30 -0600 Subject: [PATCH 0423/1962] Rename to `TypeShadowsSystemNamespace` --- .../src/main/resources/category/apex/errorprone.xml | 4 ++-- ...Test.java => TypeShadowsSystemNamespaceTest.java} | 2 +- ...eCollision.xml => TypeShadowsSystemNamespace.xml} | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) rename pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/{SystemNamespaceCollisionTest.java => TypeShadowsSystemNamespaceTest.java} (79%) rename pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/{SystemNamespaceCollision.xml => TypeShadowsSystemNamespace.xml} (85%) diff --git a/pmd-apex/src/main/resources/category/apex/errorprone.xml b/pmd-apex/src/main/resources/category/apex/errorprone.xml index cca3bcbbe0c..b55dc709f71 100644 --- a/pmd-apex/src/main/resources/category/apex/errorprone.xml +++ b/pmd-apex/src/main/resources/category/apex/errorprone.xml @@ -513,12 +513,12 @@ private class TestClass { ]]> - + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_errorprone.html#typeshadowssystemnamespace"> This rule finds Apex classes, enums, and interfaces that have the same name as a class, enum, or interface in the `System` namespace. Shadowing the `System` namespace in this way can lead to confusion and unexpected behavior. diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/SystemNamespaceCollisionTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/TypeShadowsSystemNamespaceTest.java similarity index 79% rename from pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/SystemNamespaceCollisionTest.java rename to pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/TypeShadowsSystemNamespaceTest.java index 8bb6be2fdf8..8608a0ca5b9 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/SystemNamespaceCollisionTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/TypeShadowsSystemNamespaceTest.java @@ -6,6 +6,6 @@ import net.sourceforge.pmd.test.PmdRuleTst; -class SystemNamespaceCollisionTest extends PmdRuleTst { +class TypeShadowsSystemNamespaceTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/SystemNamespaceCollision.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/TypeShadowsSystemNamespace.xml similarity index 85% rename from pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/SystemNamespaceCollision.xml rename to pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/TypeShadowsSystemNamespace.xml index 74899f6bdfd..53c7814085c 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/SystemNamespaceCollision.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/TypeShadowsSystemNamespace.xml @@ -1,8 +1,8 @@ - + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests http://pmd.sourceforge.net/rule-tests_1_0_0.xsd"> + Shadows a class in the System namespace 1 @@ -12,7 +12,7 @@ public class Database { } ]]> - + Shadows an enum in the System namespace 1 @@ -22,7 +22,7 @@ public class CallbackStatus { } ]]> - + Shadows an interface in the System namespace 1 @@ -32,7 +32,7 @@ public class Callable { } ]]> - + No shadowing 0 From b212a42d35c438e12ce65e6bddc5cce4507c26cc Mon Sep 17 00:00:00 2001 From: mitchspano Date: Tue, 7 Jan 2025 19:21:43 +0000 Subject: [PATCH 0424/1962] Add context for source of statically defined class/enum/interface names. --- .../resources/category/apex/errorprone.xml | 192 +++++++++--------- 1 file changed, 97 insertions(+), 95 deletions(-) diff --git a/pmd-apex/src/main/resources/category/apex/errorprone.xml b/pmd-apex/src/main/resources/category/apex/errorprone.xml index b55dc709f71..081ca87da2d 100644 --- a/pmd-apex/src/main/resources/category/apex/errorprone.xml +++ b/pmd-apex/src/main/resources/category/apex/errorprone.xml @@ -4,11 +4,11 @@ xmlns="http://pmd.sourceforge.net/ruleset/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd"> - + -Rules to detect constructs that are either broken, extremely confusing or prone to runtime errors. + Rules to detect constructs that are either broken, extremely confusing or prone to runtime errors. - + -Having DML operations in Apex class constructor or initializers can have unexpected side effects: -By just accessing a page, the DML statements would be executed and the database would be modified. -Just querying the database is permitted. - -In addition to constructors and initializers, any method called `init` is checked as well. - -Salesforce Apex already protects against this scenario and raises a runtime exception. - -Note: This rule has been moved from category "Security" to "Error Prone" with PMD 6.21.0, since -using DML in constructors is not a security problem, but crashes the application. + Having DML operations in Apex class constructor or initializers can have unexpected side effects: + By just accessing a page, the DML statements would be executed and the database would be modified. + Just querying the database is permitted. + + In addition to constructors and initializers, any method called `init` is checked as well. + + Salesforce Apex already protects against this scenario and raises a runtime exception. + + Note: This rule has been moved from category "Security" to "Error Prone" with PMD 6.21.0, since + using DML in constructors is not a security problem, but crashes the application. 3 - - + -Avoid directly accessing Trigger.old and Trigger.new as it can lead to a bug. Triggers should be bulkified and iterate through the map to handle the actions for each item separately. + Avoid directly accessing Trigger.old and Trigger.new as it can lead to a bug. Triggers should be bulkified and iterate through the map to handle the actions for each item separately. 3 - + - - - + -When deploying Apex code between sandbox and production environments, or installing Force.com AppExchange packages, -it is essential to avoid hardcoding IDs in the Apex code. By doing so, if the record IDs change between environments, -the logic can dynamically identify the proper data to operate against and not fail. + When deploying Apex code between sandbox and production environments, or installing Force.com AppExchange packages, + it is essential to avoid hardcoding IDs in the Apex code. By doing so, if the record IDs change between environments, + the logic can dynamically identify the proper data to operate against and not fail. 3 - - + 3 - - + -Empty Catch Block finds instances where an exception is caught, but nothing is done. -In most circumstances, this swallows an exception which should either be acted on -or reported. + Empty Catch Block finds instances where an exception is caught, but nothing is done. + In most circumstances, this swallows an exception which should either be acted on + or reported. 3 @@ -151,7 +151,7 @@ or reported. - - - + -Empty If Statement finds instances where a condition is checked but nothing is done about it. + Empty If Statement finds instances where a condition is checked but nothing is done about it. 3 - + - - + -Empty block statements serve no purpose and should be removed. + Empty block statements serve no purpose and should be removed. 3 @@ -221,7 +221,7 @@ Empty block statements serve no purpose and should be removed. - - - + -Avoid empty try or finally blocks - what's the point? + Avoid empty try or finally blocks - what's the point? 3 - + - - + -Empty While Statement finds all instances where a while statement does nothing. -If it is a timing loop, then you should use Thread.sleep() for it; if it is -a while loop that does a lot in the exit expression, rewrite it to make it clearer. + Empty While Statement finds all instances where a while statement does nothing. + If it is a timing loop, then you should use Thread.sleep() for it; if it is + a while loop that does a lot in the exit expression, rewrite it to make it clearer. 3 - + - - + -In the Summer '21 release, a mandatory security update enforces access modifiers on Apex properties in -Lightning component markup. The update prevents access to private or protected Apex getters from Aura -and Lightning Web Components. + In the Summer '21 release, a mandatory security update enforces access modifiers on Apex properties in + Lightning component markup. The update prevents access to private or protected Apex getters from Aura + and Lightning Web Components. 3 - - - - + -Non-constructor methods should not have the same name as the enclosing class. + Non-constructor methods should not have the same name as the enclosing class. 3 - - + -Override both `public Boolean equals(Object obj)`, and `public Integer hashCode()`, or override neither. -Even if you are inheriting a hashCode() from a parent class, consider implementing hashCode and explicitly -delegating to your superclass. - -This is especially important when [Using Custom Types in Map Keys and Sets](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_collections_maps_keys_userdefined.htm). + Override both `public Boolean equals(Object obj)`, and `public Integer hashCode()`, or override neither. + Even if you are inheriting a hashCode() from a parent class, consider implementing hashCode and explicitly + delegating to your superclass. + + This is especially important when [Using Custom Types in Map Keys and Sets](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_collections_maps_keys_userdefined.htm). 3 - - + - - Test methods marked as a testMethod or annotated with @IsTest, - but not residing in a test class should be moved to a proper - class or have the @IsTest annotation added to the class. - - Support for tests inside functional classes was removed in Spring-13 (API Version 27.0), - making classes that violate this rule fail compile-time. This rule is mostly usable when - dealing with legacy code. - - 3 - - - - + Test methods marked as a testMethod or annotated with @IsTest, + but not residing in a test class should be moved to a proper + class or have the @IsTest annotation added to the class. + + Support for tests inside functional classes was removed in Spring-13 (API Version 27.0), + making classes that violate this rule fail compile-time. This rule is mostly usable when + dealing with legacy code. + + 3 + + + + - - - - - + + + + - + 1 From 1d0e4162c96696cf9098bbe56a5f2cfc5919f3f0 Mon Sep 17 00:00:00 2001 From: mitchspano Date: Tue, 7 Jan 2025 22:58:38 +0000 Subject: [PATCH 0425/1962] Reset XML whitespace formatting --- .../resources/category/apex/errorprone.xml | 190 +++++++++--------- 1 file changed, 95 insertions(+), 95 deletions(-) diff --git a/pmd-apex/src/main/resources/category/apex/errorprone.xml b/pmd-apex/src/main/resources/category/apex/errorprone.xml index 081ca87da2d..e087b935758 100644 --- a/pmd-apex/src/main/resources/category/apex/errorprone.xml +++ b/pmd-apex/src/main/resources/category/apex/errorprone.xml @@ -4,11 +4,11 @@ xmlns="http://pmd.sourceforge.net/ruleset/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd"> - + - Rules to detect constructs that are either broken, extremely confusing or prone to runtime errors. +Rules to detect constructs that are either broken, extremely confusing or prone to runtime errors. - + - Having DML operations in Apex class constructor or initializers can have unexpected side effects: - By just accessing a page, the DML statements would be executed and the database would be modified. - Just querying the database is permitted. - - In addition to constructors and initializers, any method called `init` is checked as well. - - Salesforce Apex already protects against this scenario and raises a runtime exception. - - Note: This rule has been moved from category "Security" to "Error Prone" with PMD 6.21.0, since - using DML in constructors is not a security problem, but crashes the application. +Having DML operations in Apex class constructor or initializers can have unexpected side effects: +By just accessing a page, the DML statements would be executed and the database would be modified. +Just querying the database is permitted. + +In addition to constructors and initializers, any method called `init` is checked as well. + +Salesforce Apex already protects against this scenario and raises a runtime exception. + +Note: This rule has been moved from category "Security" to "Error Prone" with PMD 6.21.0, since +using DML in constructors is not a security problem, but crashes the application. 3 - - + - Avoid directly accessing Trigger.old and Trigger.new as it can lead to a bug. Triggers should be bulkified and iterate through the map to handle the actions for each item separately. +Avoid directly accessing Trigger.old and Trigger.new as it can lead to a bug. Triggers should be bulkified and iterate through the map to handle the actions for each item separately. 3 - + - - - + - When deploying Apex code between sandbox and production environments, or installing Force.com AppExchange packages, - it is essential to avoid hardcoding IDs in the Apex code. By doing so, if the record IDs change between environments, - the logic can dynamically identify the proper data to operate against and not fail. +When deploying Apex code between sandbox and production environments, or installing Force.com AppExchange packages, +it is essential to avoid hardcoding IDs in the Apex code. By doing so, if the record IDs change between environments, +the logic can dynamically identify the proper data to operate against and not fail. 3 - - + 3 - - + - Empty Catch Block finds instances where an exception is caught, but nothing is done. - In most circumstances, this swallows an exception which should either be acted on - or reported. +Empty Catch Block finds instances where an exception is caught, but nothing is done. +In most circumstances, this swallows an exception which should either be acted on +or reported. 3 @@ -151,7 +151,7 @@ public without sharing class Foo { - - - + - Empty If Statement finds instances where a condition is checked but nothing is done about it. +Empty If Statement finds instances where a condition is checked but nothing is done about it. 3 - + - - + - Empty block statements serve no purpose and should be removed. +Empty block statements serve no purpose and should be removed. 3 @@ -221,7 +221,7 @@ public class Foo { - - - + - Avoid empty try or finally blocks - what's the point? +Avoid empty try or finally blocks - what's the point? 3 - + - - + - Empty While Statement finds all instances where a while statement does nothing. - If it is a timing loop, then you should use Thread.sleep() for it; if it is - a while loop that does a lot in the exit expression, rewrite it to make it clearer. +Empty While Statement finds all instances where a while statement does nothing. +If it is a timing loop, then you should use Thread.sleep() for it; if it is +a while loop that does a lot in the exit expression, rewrite it to make it clearer. 3 - + - - + - In the Summer '21 release, a mandatory security update enforces access modifiers on Apex properties in - Lightning component markup. The update prevents access to private or protected Apex getters from Aura - and Lightning Web Components. +In the Summer '21 release, a mandatory security update enforces access modifiers on Apex properties in +Lightning component markup. The update prevents access to private or protected Apex getters from Aura +and Lightning Web Components. 3 - - - - + - Non-constructor methods should not have the same name as the enclosing class. +Non-constructor methods should not have the same name as the enclosing class. 3 - - + - Override both `public Boolean equals(Object obj)`, and `public Integer hashCode()`, or override neither. - Even if you are inheriting a hashCode() from a parent class, consider implementing hashCode and explicitly - delegating to your superclass. - - This is especially important when [Using Custom Types in Map Keys and Sets](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_collections_maps_keys_userdefined.htm). +Override both `public Boolean equals(Object obj)`, and `public Integer hashCode()`, or override neither. +Even if you are inheriting a hashCode() from a parent class, consider implementing hashCode and explicitly +delegating to your superclass. + +This is especially important when [Using Custom Types in Map Keys and Sets](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_collections_maps_keys_userdefined.htm). 3 - - + - - Test methods marked as a testMethod or annotated with @IsTest, - but not residing in a test class should be moved to a proper - class or have the @IsTest annotation added to the class. - - Support for tests inside functional classes was removed in Spring-13 (API Version 27.0), - making classes that violate this rule fail compile-time. This rule is mostly usable when - dealing with legacy code. - - 3 - - - - + Test methods marked as a testMethod or annotated with @IsTest, + but not residing in a test class should be moved to a proper + class or have the @IsTest annotation added to the class. + + Support for tests inside functional classes was removed in Spring-13 (API Version 27.0), + making classes that violate this rule fail compile-time. This rule is mostly usable when + dealing with legacy code. + + 3 + + + + - - - - - + + + + - + Date: Thu, 9 Jan 2025 09:29:12 +0100 Subject: [PATCH 0426/1962] Bump org.junit.platform:junit-platform-commons from 1.11.2 to 1.11.4 (#5445) Bumps [org.junit.platform:junit-platform-commons](https://github.com/junit-team/junit5) from 1.11.2 to 1.11.4. - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/commits) --- updated-dependencies: - dependency-name: org.junit.platform:junit-platform-commons dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 42a42b01474..d8e63fbe7da 100644 --- a/pom.xml +++ b/pom.xml @@ -1099,7 +1099,7 @@ org.junit.platform junit-platform-commons - 1.11.2 + 1.11.4 test From dc7e739c77d3ee49f2ff03cd37b642a8dadb5f76 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Jan 2025 09:31:45 +0100 Subject: [PATCH 0427/1962] Bump org.sonarsource.scanner.maven:sonar-maven-plugin from 3.10.0.2594 to 5.0.0.4389 (#5446) Bump org.sonarsource.scanner.maven:sonar-maven-plugin Bumps [org.sonarsource.scanner.maven:sonar-maven-plugin](https://github.com/SonarSource/sonar-scanner-maven) from 3.10.0.2594 to 5.0.0.4389. - [Release notes](https://github.com/SonarSource/sonar-scanner-maven/releases) - [Commits](https://github.com/SonarSource/sonar-scanner-maven/compare/3.10.0.2594...5.0.0.4389) --- updated-dependencies: - dependency-name: org.sonarsource.scanner.maven:sonar-maven-plugin dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d8e63fbe7da..a753072d0d9 100644 --- a/pom.xml +++ b/pom.xml @@ -1298,7 +1298,7 @@ org.sonarsource.scanner.maven sonar-maven-plugin - 3.10.0.2594 + 5.0.0.4389 From 745e5d9164bdeb914a5ae5444e863368630eea5b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 10 Jan 2025 12:46:41 +0100 Subject: [PATCH 0428/1962] [doc] Improve note info-box --- docs/_includes/note.html | 6 +++++- docs/pages/pmd/devdocs/writing_documentation.md | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/_includes/note.html b/docs/_includes/note.html index e8ed7ab24a7..8159b490697 100644 --- a/docs/_includes/note.html +++ b/docs/_includes/note.html @@ -1 +1,5 @@ - + diff --git a/docs/pages/pmd/devdocs/writing_documentation.md b/docs/pages/pmd/devdocs/writing_documentation.md index 5c27b940fac..39a55cc9a7e 100644 --- a/docs/pages/pmd/devdocs/writing_documentation.md +++ b/docs/pages/pmd/devdocs/writing_documentation.md @@ -1,7 +1,7 @@ --- title: Writing documentation tags: [devdocs] -last_update: August 2017 +last_updated: January 2025 (7.10.0) permalink: pmd_devdocs_writing_documentation.html keywords: documentation, jekyll, markdown author: Andreas Dangel @@ -134,7 +134,7 @@ is separated by 3 dashes (`---`). Example: --- title: Writing Documentation - last_update: August 2017 + last_updated: January 2025 (7.10.0) permalink: pmd_devdocs_writing_documentation.html --- From 1bf54b234848f85b80c5e01b40b4b014695f30db Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 9 Jan 2025 16:18:33 +0100 Subject: [PATCH 0429/1962] [doc] Move IDE Setup Pages from wiki Refs #2492 --- docs/_data/sidebars/pmd_sidebar.yml | 19 ++- .../pmd/devdocs/building/building_eclipse.md | 121 ++++++++++++++++++ .../building_from_source.md} | 81 +++++++----- .../pmd/devdocs/building/building_general.md | 49 +++++++ .../pmd/devdocs/building/building_intellij.md | 86 +++++++++++++ 5 files changed, 323 insertions(+), 33 deletions(-) create mode 100644 docs/pages/pmd/devdocs/building/building_eclipse.md rename docs/pages/pmd/devdocs/{building.md => building/building_from_source.md} (55%) create mode 100644 docs/pages/pmd/devdocs/building/building_general.md create mode 100644 docs/pages/pmd/devdocs/building/building_intellij.md diff --git a/docs/_data/sidebars/pmd_sidebar.yml b/docs/_data/sidebars/pmd_sidebar.yml index 1a59e19ae65..bc0b9569e10 100644 --- a/docs/_data/sidebars/pmd_sidebar.yml +++ b/docs/_data/sidebars/pmd_sidebar.yml @@ -526,9 +526,24 @@ entries: - title: Developer resources url: /pmd_devdocs_development.html output: web, pdf - - title: Building PMD from source - url: /pmd_devdocs_building.html + - title: null output: web, pdf + subfolders: + - title: Building PMD + output: web, pdf + subfolderitems: + - title: General Info + url: /pmd_devdocs_building_general.html + output: web, pdf + - title: Building PMD from source + url: /pmd_devdocs_building.html + output: web, pdf + - title: Building PMD with IntelliJ IDEA + url: /pmd_devdocs_building_intellij.html + output: web, pdf + - title: Building PMD with Eclipse IDE + url: /pmd_devdocs_building_eclipse.html + output: web, pdf - title: Contributing external_url: https://github.com/pmd/pmd/blob/main/CONTRIBUTING.md output: web, pdf diff --git a/docs/pages/pmd/devdocs/building/building_eclipse.md b/docs/pages/pmd/devdocs/building/building_eclipse.md new file mode 100644 index 00000000000..ebec9a03ca1 --- /dev/null +++ b/docs/pages/pmd/devdocs/building/building_eclipse.md @@ -0,0 +1,121 @@ +--- +title: Building PMD with Eclipse +tags: [devdocs] +permalink: pmd_devdocs_building_eclipse.html +author: Andreas Dangel +--- + +## Import PMD Project + +1. Download the latest [Eclipse IDE for Java Developers](http://www.eclipse.org/downloads/eclipse-packages/) +2. Install it by extracting it into a directory of your choice +3. Start `eclipse`. You'll be asked for a workspace. It's recommended to use an extra, separate new workspace for PMD, + because you'll import many projects. Otherwise you might clutter your existing workspace with PMD projects. +4. Close the welcome screen, if it is shown. +5. Select menu `File`, `Import...`. In the dialog, select `Maven / Existing Maven Projects` and click `Next`. +6. As `Root Directory` select the directory, into which PMD's repository has been cloned. +7. Then click `Select All` and then `Finish`. + +You might be asked about a missing m2e connectors for the kotlin plugin. You can simply select `Resolve All Later` +and ignore this problem for now. + +Now all PMD projects are imported. This might take a while. All the projects will appear on the left inside +the `Project Explorer`. + +## Running unit tests + +To verify, that the basics work, right-click on the `pmd-java` project and select `Run As -> JUnit Test`. +If everything is well, the project will be built and the unit tests are executed. + +You probably get some build errors in some projects. Try to ignore them for now - at least some unit test +should be executed. See also "Known Issues" below. + + +## Code Templates, Formatter + +1. Menu `Window` -> `Preferences` +2. Under `Java / Code Style / Code Templates`: + Click `Import...` and choose the file `eclipse/pmd-eclipse-codetemplates.xml` from the "build-tools" repository. +3. Under `Java / Code Style / Formatter`: + Click `Import...` and choose the file `eclipse/pmd-eclipse-code-formatter.xml` from the "build-tools" repository. +4. Under `Java / Code Style / Clean Up`: + Click `Import...` and choose the file `eclipse/pmd-eclipse-code-cleanup.xml` from the "build-tools" repository. +5. Under `Java / Code STyle / Organize Imports`: + Click `Import...` and choose the file `eclipse/pmd-eclipse-imports.importorder` from the build-tools" repository. +6. Click `Apply and Close` + +## Checkstyle + +We are going to install two plugins: The checkstyle plugin itself and the m2e-code-quality plugin, which seamlessly activates and configures checkstyle in eclipse according to the maven configuration of PMD. + +1. Menu `Help`, `Install New Software...` +2. Enter the URL `http://eclipse-cs.sourceforge.net/update/` into the text field and press enter. +3. Select the checkbox for "Checkstyle" and click `Next` +4. Restart eclipse if you are requested to do so. +5. Install the next plugin for the URL `http://m2e-code-quality.github.com/m2e-code-quality/site/latest` +6. This time, select only "Checkstyle configuration plugin for M2Eclipse" and click `Next` +7. Restart eclipse if you are requested to do so. +8. Finally, right click on one project in the package explorer. Select `Maven / Update project...` in the context + menu. In the dialog, select all projects and click `OK`. + + +## Other settings + +* Consider displaying the white space characters: Window, Preferences; General / Editors / Text Editors: Show whitespace characters +* Insert spaces for tabs also in text files: Window, Preferences; General / Editors / Text Editors: Insert spaces for tabs + +## Executing the Designer + +The designer lives now in a separate repository, that you'll need to clone first: + +``` shell +$ git clone https://github.com/pmd/pmd-designer.git +``` + +Import the designer project via menu `File`, `Import...`. In the dialog, select `Maven / Existing Maven Projects` and click `Next`. + +Open the class `net.sourceforge.pmd.util.fxdesigner.DesignerStarter` via menu "Navigate / Open Type...". + +Right click in the editor window and select "Run as -> Java Application". + +## Known Issues + +* pmd-apex, pmd-dist, pmd-doc and other projects are missing the project "pmd-apex-jorje". The project is actually + existing, but it is not a java project in eclipse. + + Workaround: + + 1. Build the project once from outside eclipse: `$ ./mvnw clean install -f pmd-apex-jorje/pom.xml` + This installs the dependency in your local maven repository. + 2. In eclipse, close the project "pmd-apex-jorje". That way, eclipse will use the jar file from the + local maven repository instead of the project. + +* Many tests depend on kotlin. Kotlin is not really supported in Eclipse. As long as you don't need to change + the kotlin tests, you can ignore this for now. In order to be able to execute the tests, there is a similar + workaround: + + 1. Build the project "pmd-lang-test" once from outside eclipse: `$ ./mvnw clean install -f pmd-lang-test/pom.xml` + This installs this module in your local maven repository. + 2. In eclipse, close the project "pmd-lang-test". That way, eclipse will use the jar file (which contains + the already compiled kotlin base test classes) from the local maven repository instead. + +* pmd-scala project has no source code / tests: If you don't want to work on scala, then you can simply + close all scala projects. + + For scala, there are two versions: 2.12 and 2.13. Both share the same code, which is in + `pmd-scala-modules/pmd-scala-common`. However, this code is not used directly, but referenced from the two + projects `pmd-scala-moduls/pmd-scala_2.12` and `pmd-scala-moduls/pmd-scala_2.13`. When working on scala, + it is recommended to close pmd-scala_2.12 and only work on pmd-scala_2.13. Then you need to configure + "pmd-scala_2.13" manually, so that eclipse finds the source folders: + + 1. Right-click on the project and open the "Properties". On the left navigate to "Java Build Path". + 2. Open the tab "Source" + 3. Delete the all source folders + 4. Click on "Link Source..." and manually choose via "Linked folder location" the path in the repository + to `pmd-scala-modules/pmd-scala-common/src/main/java`. Name it "src-main-java" and click "Finish". + 5. Repeat it for `pmd-scala-modules/pmd-scala-common/src/main/resources`. Name it "src-main-resources". + 6. Repeat it for `pmd-scala-modules/pmd-scala-common/src/test/java` and `pmd-scala-modules/pmd-scala-common/src/test/resources`. + 7. Change "src-test-java" to "Contains test sources: Yes", select "Source Output Folder > Specific Output Folder" and + choose "target/test-classes". + 8. Repeat this for "src-test-resources". + diff --git a/docs/pages/pmd/devdocs/building.md b/docs/pages/pmd/devdocs/building/building_from_source.md similarity index 55% rename from docs/pages/pmd/devdocs/building.md rename to docs/pages/pmd/devdocs/building/building_from_source.md index 625b9bb2fbc..6b231c6e45f 100644 --- a/docs/pages/pmd/devdocs/building.md +++ b/docs/pages/pmd/devdocs/building/building_from_source.md @@ -3,17 +3,14 @@ title: Building PMD from source tags: [devdocs] permalink: pmd_devdocs_building.html author: Tom Copeland, Xavier Le Vourch +last_updated: January 2025 (7.10.0) --- - -{%include note.html content="TODO add IDE specific indications" %} - # Compiling PMD * JDK 11 or higher -{% include note.html content="While Java 11 is required for building, running PMD only requires Java 7 -(or Java 8 for Apex, JavaScript, Scala, Visualforce, and the Designer)." %} +{% include note.html content="While Java 11 is required for building, running PMD only requires Java 8." %} Youโ€™ll need to either check out the source code or download the latest source release. Assuming youโ€™ve got the latest source release, unzip it to a directory: @@ -47,36 +44,58 @@ Thatโ€™s the project configuration for mavenโ€ฆ letโ€™s compile! ... ... after a few minutes ... [INFO] ------------------------------------------------------------------------ -[INFO] Reactor Summary: -[INFO] -[INFO] PMD ................................................ SUCCESS [ 3.061 s] -[INFO] PMD Core ........................................... SUCCESS [ 25.675 s] -[INFO] PMD Test Framework ................................. SUCCESS [ 0.457 s] -[INFO] PMD C++ ............................................ SUCCESS [ 1.893 s] -[INFO] PMD C# ............................................. SUCCESS [ 0.619 s] -[INFO] PMD Fortran ........................................ SUCCESS [ 0.609 s] -[INFO] PMD Go ............................................. SUCCESS [ 0.103 s] -[INFO] PMD Java ........................................... SUCCESS [01:08 min] -[INFO] PMD JavaScript ..................................... SUCCESS [ 3.279 s] -[INFO] PMD JSP ............................................ SUCCESS [ 3.944 s] -[INFO] PMD Matlab ......................................... SUCCESS [ 1.342 s] -[INFO] PMD Objective-C .................................... SUCCESS [ 2.281 s] -[INFO] PMD PHP ............................................ SUCCESS [ 0.536 s] -[INFO] PMD PL/SQL ......................................... SUCCESS [ 10.973 s] -[INFO] PMD Python ......................................... SUCCESS [ 1.758 s] -[INFO] PMD Ruby ........................................... SUCCESS [ 0.438 s] -[INFO] PMD Velocity ....................................... SUCCESS [ 3.941 s] -[INFO] PMD XML and XSL .................................... SUCCESS [ 2.174 s] -[INFO] PMD Scala .......................................... SUCCESS [ 11.901 s] -[INFO] PMD Distribution Packages .......................... SUCCESS [ 11.366 s] -[INFO] PMD Java 8 Integration ............................. SUCCESS [ 0.560 s] +[INFO] Reactor Summary for PMD {{site.pmd.version}}: +[INFO] +[INFO] PMD ................................................ SUCCESS [ 31.653 s] +[INFO] PMD Core ........................................... SUCCESS [01:10 min] +[INFO] PMD Test Schema .................................... SUCCESS [ 5.408 s] +[INFO] PMD Ant Integration ................................ SUCCESS [ 9.623 s] +[INFO] PMD Test Framework ................................. SUCCESS [ 7.571 s] +[INFO] PMD language module testing utilities .............. SUCCESS [ 30.390 s] +[INFO] PMD Apex ........................................... SUCCESS [ 56.152 s] +[INFO] PMD Coco ........................................... SUCCESS [01:18 min] +[INFO] PMD C++ ............................................ SUCCESS [ 11.274 s] +[INFO] PMD C# ............................................. SUCCESS [ 16.891 s] +[INFO] PMD Dart ........................................... SUCCESS [ 9.317 s] +[INFO] PMD Fortran ........................................ SUCCESS [ 6.105 s] +[INFO] PMD Gherkin ........................................ SUCCESS [ 16.105 s] +[INFO] PMD Go ............................................. SUCCESS [ 8.768 s] +[INFO] PMD Groovy ......................................... SUCCESS [ 9.565 s] +[INFO] PMD HTML ........................................... SUCCESS [ 8.741 s] +[INFO] PMD Java ........................................... SUCCESS [03:17 min] +[INFO] PMD JavaScript ..................................... SUCCESS [ 25.659 s] +[INFO] PMD JSP ............................................ SUCCESS [ 17.373 s] +[INFO] PMD Julia .......................................... SUCCESS [ 26.660 s] +[INFO] PMD Kotlin ......................................... SUCCESS [ 41.748 s] +[INFO] PMD Lua ............................................ SUCCESS [ 18.991 s] +[INFO] PMD Matlab ......................................... SUCCESS [ 14.886 s] +[INFO] PMD Modelica ....................................... SUCCESS [ 30.926 s] +[INFO] PMD Objective-C .................................... SUCCESS [ 9.005 s] +[INFO] PMD Perl ........................................... SUCCESS [ 5.979 s] +[INFO] PMD PHP ............................................ SUCCESS [ 6.914 s] +[INFO] PMD PL/SQL ......................................... SUCCESS [02:14 min] +[INFO] PMD Python ......................................... SUCCESS [ 6.971 s] +[INFO] PMD Ruby ........................................... SUCCESS [ 5.493 s] +[INFO] PMD Rust ........................................... SUCCESS [ 7.290 s] +[INFO] PMD Scala Common Source and Settings ............... SUCCESS [ 1.874 s] +[INFO] PMD Scala for Scala 2.13 ........................... SUCCESS [ 24.269 s] +[INFO] PMD Swift .......................................... SUCCESS [ 23.196 s] +[INFO] PMD TSql ........................................... SUCCESS [ 7.145 s] +[INFO] PMD Visualforce .................................... SUCCESS [ 12.353 s] +[INFO] PMD Velocity Template Language (VTL) ............... SUCCESS [ 10.073 s] +[INFO] PMD XML and XSL .................................... SUCCESS [ 7.855 s] +[INFO] PMD Languages Dependencies ......................... SUCCESS [ 2.878 s] +[INFO] PMD Documentation Generator (internal) ............. SUCCESS [ 10.902 s] +[INFO] PMD Scala for Scala 2.12 ........................... SUCCESS [ 21.131 s] +[INFO] PMD CLI ............................................ SUCCESS [ 11.246 s] +[INFO] PMD Distribution Packages .......................... SUCCESS [ 11.457 s] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ -[INFO] Total time: 02:36 min -[INFO] Finished at: 2015-11-14T17:46:06+01:00 -[INFO] Final Memory: 63M/765M +[INFO] Total time: 17:52 min +[INFO] Finished at: 2025-01-09T15:49:59+01:00 [INFO] ------------------------------------------------------------------------ + [tom@hal pmd-src-{{site.pmd.version}}]$ ``` diff --git a/docs/pages/pmd/devdocs/building/building_general.md b/docs/pages/pmd/devdocs/building/building_general.md new file mode 100644 index 00000000000..3b0c9f39c05 --- /dev/null +++ b/docs/pages/pmd/devdocs/building/building_general.md @@ -0,0 +1,49 @@ +--- +title: Building PMD General Info +tags: [devdocs] +permalink: pmd_devdocs_building_general.html +author: Andreas Dangel +last_updated: January 2025 (7.10.0) +--- + +# Before Development + +1. Ensure that [Git](https://git-scm.com/) and Java JDK >= 11 are installed. You can get a OpenJDK distribution + from e.g. [Adoptium](https://adoptium.net/). +2. Fork the [PMD repository](https://github.com/pmd/pmd) on GitHub as explained in [Fork a repository](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo). +3. Clone your forked repository to your computer: + ```shell + git clone git@github.com:your_user_name/pmd.git --depth=10 --no-tags + ``` +4. Clone additionally the [build-tools repository](https://github.com/pmd/build-tools). It contains some settings, we'll later use for configuring IDE: + ```shell + git clone git@github.com:pmd/build-tools.git + ``` +5. To make sure your Maven environment is correctly setup, we'll build pmd once: + + ```shell + cd pmd + ./mvnw clean verify -DskipTests + ``` + + This will help with Maven IDE integration. It may take some time, because it will download all dependencies, + so go brew some coffee to get ready for the steps to come. + +{%capture notetext%} +This only clones the last ten commits and not the whole PMD repository. This makes it faster, as much less data needs +to be downloaded. However, the history is incomplete. If you want to browse/annotate the source with the complete +commit history locally, either clone the repo without the "depth" option or convert it to a "full" clone using +`git fetch --unshallow`. +{%endcapture%} +{%include note.html content=notetext %} + +# Development + +* Use a IDE, see the other guides +* Contributing via GitHub and Pull Requests: +* setup upstream repo +* create a dev branch +* commit dev branch +* push dev branch +* send a pull request +* keep your fork up to date diff --git a/docs/pages/pmd/devdocs/building/building_intellij.md b/docs/pages/pmd/devdocs/building/building_intellij.md new file mode 100644 index 00000000000..ed596f4985b --- /dev/null +++ b/docs/pages/pmd/devdocs/building/building_intellij.md @@ -0,0 +1,86 @@ +--- +title: Building PMD with IntelliJ IDEA +tags: [devdocs] +permalink: pmd_devdocs_building_intellij.html +author: Andreas Dangel , Clรฉment Fournier +--- + +## Import PMD Project + +1. Download the community edition of IntelliJ IDEA from [jetbrains](https://www.jetbrains.com/idea/download/). +2. Install it, that means, extract the archive +3. Start it with `bin/idea.sh` +4. In the startup dialog, choose the button `Open` and select the folder, into which PMD's repository has been cloned. + Then select "Trust Project". After that, IJ will automatically detect that PMD is a maven project and import it. + Make sure, you have previously built PMD on command line via `./mvnw clean verify`, as described in the preparation + step. +5. If you are using IJ for the first time, you'll need to configure the path to your installed Java SDK. You + have to use at least Java 9 here. + If the dialog doesn't show automatically, you can open it with menu `File > Project Structure` (CTRL+ALT+SHIFT+S). + On the left, choose "Platform Settings > SDK" and add your Java SDK. Then choose "Project Settings > Project" and + select the SDK for PMD. +6. Finish the wizard and wait a bit, until all PMD modules appear on the left. + +## Running Unit Tests + +* Right click on "pmd-java" and select "Run 'All Tests'" +* You can run individual unit tests or a single unit test class by right-clicking, or CTRL + SHIFT + F10. + You can debug the current Run configuration using SHIFT + F9. + +## Setting up Checkstyle + +If you don't have the Checkstyle plugin: + +* Open `File > Settings` (CTRL+ALT+S) and navigate to "Plugins" on the left +* Click on "Browse repositories" on the bottom +* Search for "Checkstyle-IDEA" and click "Install" +* When done, restart IJ + +Once you have the Checkstyle plugin: + +* Open `File > Settings` (CTRL+ALT+S) and navigate to "Tools > Checkstyle" on the left +* Make sure to select the latest Checkstyle version and click Apply +* Add a configuration file with the Add button on the right +* Choose a descriptive name, then tick "Use a Checkstyle file accessible via HTTP" and enter the following URL: + ``` + https://raw.githubusercontent.com/pmd/build-tools/master/src/main/resources/net/sourceforge/pmd/pmd-checkstyle-config.xml + ``` +* Tick the "Active" checkbox for this added checkstyle configuration + +## Formatter and inspection configuration + +Import the code style settings (formatter) so that it conforms with our Checkstyle config. +To do that, go to `File > Settings` (CTLR+ALT+S) then navigate to "Editor > Code Style > Java". +Click on the cogwheel symbol, choose "Import Scheme > IntelliJ IDEA code style XML" and choose the file +`intellij-idea/PMD-code-style.xml` from the build-tools repository. + +Take some time to tweak the inspections so that they conform to the code style, for example flagging switch statements +with no `default` case. This takes some time but can make your code much cleaner. +To do that, go to `File > Settings` then navigate to "Inspections > Java". + +## Running the designer + +The designer lives now in a separate repository, that you'll need to clone first: + +``` shell +$ git clone https://github.com/pmd/pmd-designer.git +``` + +See [Contributing Guide](https://github.com/pmd/pmd-designer/blob/master/CONTRIBUTING.md) of the Designer for details. + +* We recommend creating and saving a new run configuration (see + [IJ doc](https://www.jetbrains.com/help/idea/creating-and-editing-run-debug-configurations.html)), + using the "Application" template. On IJ < 2017.3, there is also a "JavaFX Application" template. +* When editing the run configuration, add `-v` to the program arguments, to get debug output +* Be sure to use the classpath of the `pmd-ui` module + +## Known Issues +* Some compilation errors: If you didn't build PMD from command line outside of IDEA, then the sources, + that are usually generated during the build, are not available. You can right-click on the PMD project and + select "Maven > Generate Sources and Update Folders". It seems, that IDEA doesn't use the correct JDK when + executing this command. Try again - it seems, it works on the second try only. After that, the folder are there, + but IDEA doesn't use them. Select "Maven > Reimport". +* When editing FXML or CSS files for the designer, IJ sometimes fails to put the updated version in the classpath + when running. You need to run `mvn process-resources -pl pmd-ui`. +* As a quickfix for the two problems above, `mvn compile` is quick to execute when your Maven dependency cache + is up-to-date. From 3768685d768eb96a627dcf7a0090dd98b4b0c7f0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 10 Jan 2025 15:10:18 +0100 Subject: [PATCH 0430/1962] [doc] Add Netbeans Guide --- docs/_data/sidebars/pmd_sidebar.yml | 3 + .../pmd/devdocs/building/building_netbeans.md | 81 +++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 docs/pages/pmd/devdocs/building/building_netbeans.md diff --git a/docs/_data/sidebars/pmd_sidebar.yml b/docs/_data/sidebars/pmd_sidebar.yml index bc0b9569e10..17452c139be 100644 --- a/docs/_data/sidebars/pmd_sidebar.yml +++ b/docs/_data/sidebars/pmd_sidebar.yml @@ -544,6 +544,9 @@ entries: - title: Building PMD with Eclipse IDE url: /pmd_devdocs_building_eclipse.html output: web, pdf + - title: Building PMD with Netbeans IDE + url: /pmd_devdocs_building_netbeans.html + output: web, pdf - title: Contributing external_url: https://github.com/pmd/pmd/blob/main/CONTRIBUTING.md output: web, pdf diff --git a/docs/pages/pmd/devdocs/building/building_netbeans.md b/docs/pages/pmd/devdocs/building/building_netbeans.md new file mode 100644 index 00000000000..1e1f7b6ac61 --- /dev/null +++ b/docs/pages/pmd/devdocs/building/building_netbeans.md @@ -0,0 +1,81 @@ +--- +title: Building PMD with Netbeans +tags: [devdocs] +permalink: pmd_devdocs_building_netbeans.html +author: Andreas Dangel +last_updated: January 2025 (7.10.0) +--- + +## Import PMD Project + +This needs to be done only once. + +1. Install [Apache Netbeans](https://netbeans.apache.org/index.html) +2. Select File > Open Project... and choose the already checked out PMD source folder. +3. After a while, you should see under "Projects > PMD > Modules" all the modules. You can then + open individual projects. + +## Running Unit Tests + +* Right-click on an open project, e.g. "PMD Java" and select "Test". Netbeans then uses maven + to execute the unit tests. +* You can also run individual test classes. + +{%include note.html content="When executing tests, NetBeans actually calls Maven with `surefire:test` goal. " %} + +## Running / Debugging PMD + +* Open the project "PMD CLI" and navigate to the class `PmdCli`. +* Right-click on the class and select "Run File". This runs PMD without any commands and just shows the help text. +* In the output window at the bottom, click the double yellow arrow to open a "Run Maven" dialog and configure + the arguments as e.g. `exec.appArgs=check --help`. Also change the classpath scope to `exec.classpathScope=test`. +* In the "Run Maven" dialog, use the "Add >" button to add the debug configuration - then you can set breakpoints + and run in the debugger. Unfortunately, this doesn't work correctly, as Netbeans seems to start maven with + the debugger instead of the executed java app. Therefore, instead of using `jpda.listen=maven`, we use + `exec.vmArgs=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000`. This will stop PMD at the + beginning to wait for the debugger. Then you can run in NetBeans "Debug > Attach Debugger...", select + "SocketAttach" using port "8000". + +{%capture notetext %} +If you want to run/debug other PMD modules than PMD Java, then you need to add additional dependencies to +PMD CLI as scope test, e.g. + +```xml + + net.sourceforge.pmd + pmd-apex + ${project.version} + test + +``` +{%endcapture%} +{%include note.html content=notetext%} + + +## Formatter configuration + +Import the code style settings (formatter) so that it conforms with our Checkstyle config. +To do that, go to `Tool > Options` and the use the button "Import..." and the bottom. +Choose the file `netbeans/formatting.zip` from the build-tools repository. + +## Running the Designer + +The designer lives in a separate repository, that you'll need to fork and clone first: +[Designer repository](https://github.com/pmd/pmd-designer) + +```shell +git clone git@github.com:your_user_name/pmd-designer.git +``` + +1. Select File > Open Project... and choose the pmd-designer source folder. +2. Navigate to class `DesignerStarter` +3. Select "Run File" +4. In the output window at the bottom, click the double yellow arrow to open a "Run Maven" dialog and configure + the profiles: "running,with-javafx" + +## Known Issues +* There is no Kotlin support for Netbeans. As some parts of PMD use Kotlin, there is no + IDE support. See [kotlin-netbeans#122](https://github.com/JetBrains/kotlin-netbeans/issues/122). +* There is no recent checkstyle plugin for Netbeans. +* When executing tests, the test results are not always recognized by Netbeans. It sometimes says no tests + executed although surefire did run tests. From 442e83462188e2522c000368e208c433110d6d64 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 10 Jan 2025 15:10:33 +0100 Subject: [PATCH 0431/1962] [doc] Add VS Code Guide --- docs/_data/sidebars/pmd_sidebar.yml | 3 + .../pmd/devdocs/building/building_vscode.md | 99 +++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 docs/pages/pmd/devdocs/building/building_vscode.md diff --git a/docs/_data/sidebars/pmd_sidebar.yml b/docs/_data/sidebars/pmd_sidebar.yml index 17452c139be..6ed2024891f 100644 --- a/docs/_data/sidebars/pmd_sidebar.yml +++ b/docs/_data/sidebars/pmd_sidebar.yml @@ -544,6 +544,9 @@ entries: - title: Building PMD with Eclipse IDE url: /pmd_devdocs_building_eclipse.html output: web, pdf + - title: Building PMD with VS Code IDE + url: /pmd_devdocs_building_vscode.html + output: web, pdf - title: Building PMD with Netbeans IDE url: /pmd_devdocs_building_netbeans.html output: web, pdf diff --git a/docs/pages/pmd/devdocs/building/building_vscode.md b/docs/pages/pmd/devdocs/building/building_vscode.md new file mode 100644 index 00000000000..52363fbadd3 --- /dev/null +++ b/docs/pages/pmd/devdocs/building/building_vscode.md @@ -0,0 +1,99 @@ +--- +title: Building PMD with VS Code +tags: [devdocs] +permalink: pmd_devdocs_building_vscode.html +author: Andreas Dangel +last_updated: January 2025 (7.10.0) +--- + +{%include warning.html content="It is not recommend to use VS Code for developing. See Known Issues below."%} + +## Import PMD Project + +This needs to be done only once. + +1. Install [Visual Studio Code](https://code.visualstudio.com/) +2. Select File > Open Folder... and choose the already checked out PMD source folder. +3. Install [Extension Pack for Java](https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-pack) +4. After a while, you should see in the Explorer under "Java Projects" all the modules. This is the "Java Project Explorer". + +## Running Unit Tests + +* Navigate to a test class and select "Run Test". + +{%capture notetext%} +You'll get the notification "Build failed". You can try to ignore the error and continue, but you might end +up with "Unresolved compilation problems". See below under "Known Issues" for more information. + +PMD currently is still built for Java 8 and the VS Code plugin chooses a Java 8 runtime. For building however, +we use Java 11 and also the tests require some Java 11 features. You might need to override the java version +manually: Ctlr+Shift+P and enter "configure java runtime". There you can override the java version for +each project/module. +{%endcapture%} +{%include note.html content=notetext %} + +## Running / Debugging PMD + +* Navigate to the class `PmdCli`. +* Click on the "Run" link just above the `main`-method. +* To customize the options, open the "Run and Debug" window (Ctlr+Shift+D) and click the link "create a launch.json + file". Add the following configuration: + ```json + { + "type": "java", + "name": "PmdCli with args", + "request": "launch", + "mainClass": "net.sourceforge.pmd.cli.PmdCli", + "projectName": "pmd-cli", + "args": "check --help", + "classPaths": ["$Test"] + }, + ``` +* Select the run configuration "PmdCli with args" in the dropdown and use File > Start Debugging or + File > Run Without Debugging. + +{%capture notetext %} +If you want to run/debug other PMD modules than PMD Java, then you need to add additional dependencies to +PMD CLI as scope test, e.g. + +```xml + + net.sourceforge.pmd + pmd-apex + ${project.version} + test + +``` +{%endcapture%} +{%include note.html content=notetext%} + + +## Formatter configuration + +Select File > Preferences > Settings and search for "java format settings". Then enter the full path to +`eclipse/pmd-eclipse-code-formatter.xml` from the "build-tools" repository. + +## Running the Designer + +The designer lives in a separate repository, that you'll need to fork and clone first: +[Designer repository](https://github.com/pmd/pmd-designer) + +```shell +git clone git@github.com:your_user_name/pmd-designer.git +``` + +1. Select File > Add Folder to Workspace... and choose the pmd-designer source folder. +2. Wait until the project has been successfully imported. +3. Navigate to class `DesignerStarter` and run it. + +## Known Issues +* Some Java files in PMD cannot be compiled with VS Code. The Java plugin for VS Code is based on the + Eclipse Java Plugin which uses an own compiler (ejc). This compiler + has some subtle differences when dealing with type inference and generics and sometimes cannot compile PMD source code + correctly. PMD source is valid, it compiles with openjdk, but just not with ecj. + + You'll get the notification "Build failed". You can try to ignore the error and continue, but you might end + up with "Unresolved compilation problems". +* There is no Kotlin support. As some parts of PMD use Kotlin, there is no + IDE support. +* There is no recent checkstyle plugin for Netbeans. From 52341be486e8ee7c136a95af145dd158492cdaf0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 10 Jan 2025 12:46:03 +0100 Subject: [PATCH 0432/1962] [doc] Update IntelliJ guide --- .../pmd/devdocs/building/building_intellij.md | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/docs/pages/pmd/devdocs/building/building_intellij.md b/docs/pages/pmd/devdocs/building/building_intellij.md index ed596f4985b..51bced9d4e8 100644 --- a/docs/pages/pmd/devdocs/building/building_intellij.md +++ b/docs/pages/pmd/devdocs/building/building_intellij.md @@ -3,19 +3,20 @@ title: Building PMD with IntelliJ IDEA tags: [devdocs] permalink: pmd_devdocs_building_intellij.html author: Andreas Dangel , Clรฉment Fournier +last_updated: January 2025 (7.10.0) --- ## Import PMD Project -1. Download the community edition of IntelliJ IDEA from [jetbrains](https://www.jetbrains.com/idea/download/). +1. Download the Community Edition of IntelliJ IDEA from . 2. Install it, that means, extract the archive 3. Start it with `bin/idea.sh` 4. In the startup dialog, choose the button `Open` and select the folder, into which PMD's repository has been cloned. Then select "Trust Project". After that, IJ will automatically detect that PMD is a maven project and import it. - Make sure, you have previously built PMD on command line via `./mvnw clean verify`, as described in the preparation - step. + Make sure, you have previously built PMD on command line via `./mvnw clean verify`, as described in the general + info page. 5. If you are using IJ for the first time, you'll need to configure the path to your installed Java SDK. You - have to use at least Java 9 here. + have to use at least Java 11 here. If the dialog doesn't show automatically, you can open it with menu `File > Project Structure` (CTRL+ALT+SHIFT+S). On the left, choose "Platform Settings > SDK" and add your Java SDK. Then choose "Project Settings > Project" and select the SDK for PMD. @@ -27,12 +28,19 @@ author: Andreas Dangel , Clรฉment Fournier Edit Configurations... and set as program arguments eg. "check --help" +* Instead of run, you can easily choose "Debug" to run the debugger. +* Select the module "pmd-dist" for the classpath, so that all language modules are available while running PmdCli. + ## Setting up Checkstyle If you don't have the Checkstyle plugin: * Open `File > Settings` (CTRL+ALT+S) and navigate to "Plugins" on the left -* Click on "Browse repositories" on the bottom * Search for "Checkstyle-IDEA" and click "Install" * When done, restart IJ @@ -40,8 +48,8 @@ Once you have the Checkstyle plugin: * Open `File > Settings` (CTRL+ALT+S) and navigate to "Tools > Checkstyle" on the left * Make sure to select the latest Checkstyle version and click Apply -* Add a configuration file with the Add button on the right -* Choose a descriptive name, then tick "Use a Checkstyle file accessible via HTTP" and enter the following URL: +* Add a configuration file with the "+" button on top of the table +* Choose a descriptive name e.g. "pmd checkstyle", then tick "Use a Checkstyle file accessible via HTTP" and enter the following URL: ``` https://raw.githubusercontent.com/pmd/build-tools/master/src/main/resources/net/sourceforge/pmd/pmd-checkstyle-config.xml ``` @@ -60,19 +68,17 @@ To do that, go to `File > Settings` then navigate to "Inspections > Java". ## Running the designer -The designer lives now in a separate repository, that you'll need to clone first: +The designer lives in a separate repository, that you'll need to fork and clone first: +[Designer repository](https://github.com/pmd/pmd-designer) -``` shell -$ git clone https://github.com/pmd/pmd-designer.git +```shell +git clone git@github.com:your_user_name/pmd-designer.git ``` See [Contributing Guide](https://github.com/pmd/pmd-designer/blob/master/CONTRIBUTING.md) of the Designer for details. -* We recommend creating and saving a new run configuration (see - [IJ doc](https://www.jetbrains.com/help/idea/creating-and-editing-run-debug-configurations.html)), - using the "Application" template. On IJ < 2017.3, there is also a "JavaFX Application" template. -* When editing the run configuration, add `-v` to the program arguments, to get debug output -* Be sure to use the classpath of the `pmd-ui` module +* You'll need to configure SDKs and select a Project SDK. +* We recommend using the provided run configurations like "Designer (Java 21)". ## Known Issues * Some compilation errors: If you didn't build PMD from command line outside of IDEA, then the sources, @@ -81,6 +87,6 @@ See [Contributing Guide](https://github.com/pmd/pmd-designer/blob/master/CONTRIB executing this command. Try again - it seems, it works on the second try only. After that, the folder are there, but IDEA doesn't use them. Select "Maven > Reimport". * When editing FXML or CSS files for the designer, IJ sometimes fails to put the updated version in the classpath - when running. You need to run `mvn process-resources -pl pmd-ui`. + when running. You might need to run `mvn process-resources` manually before. * As a quickfix for the two problems above, `mvn compile` is quick to execute when your Maven dependency cache is up-to-date. From 4301116239f86829ffbaf9ab97356631685814f6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 10 Jan 2025 15:06:47 +0100 Subject: [PATCH 0433/1962] [doc] Update Eclipse guide --- .../pmd/devdocs/building/building_eclipse.md | 74 +++++++++++-------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/docs/pages/pmd/devdocs/building/building_eclipse.md b/docs/pages/pmd/devdocs/building/building_eclipse.md index ebec9a03ca1..cb0cbb96207 100644 --- a/docs/pages/pmd/devdocs/building/building_eclipse.md +++ b/docs/pages/pmd/devdocs/building/building_eclipse.md @@ -3,11 +3,12 @@ title: Building PMD with Eclipse tags: [devdocs] permalink: pmd_devdocs_building_eclipse.html author: Andreas Dangel +last_updated: January 2025 (7.10.0) --- ## Import PMD Project -1. Download the latest [Eclipse IDE for Java Developers](http://www.eclipse.org/downloads/eclipse-packages/) +1. Download the latest [Eclipse IDE for Enterprise Java and Web Developers](http://www.eclipse.org/downloads/eclipse-packages/) 2. Install it by extracting it into a directory of your choice 3. Start `eclipse`. You'll be asked for a workspace. It's recommended to use an extra, separate new workspace for PMD, because you'll import many projects. Otherwise you might clutter your existing workspace with PMD projects. @@ -16,20 +17,32 @@ author: Andreas Dangel 6. As `Root Directory` select the directory, into which PMD's repository has been cloned. 7. Then click `Select All` and then `Finish`. -You might be asked about a missing m2e connectors for the kotlin plugin. You can simply select `Resolve All Later` -and ignore this problem for now. - Now all PMD projects are imported. This might take a while. All the projects will appear on the left inside the `Project Explorer`. +While PMD still runs with Java 8, we need at least Java 11 for building and running unit tests. +To make sure, Eclipse uses Java 11 instead of Java 8, go to Window > Preferences and select +Java > Installed JREs. Make sure, you have a Java 11 or newer available. Then go to "Execution Environments", +choose "JavaSE-1.8" and check your Java 11 installation on the right. + ## Running unit tests -To verify, that the basics work, right-click on the `pmd-java` project and select `Run As -> JUnit Test`. +To verify, that the basics work, right-click on the `pmd-core` project and select `Run As -> JUnit Test`. If everything is well, the project will be built and the unit tests are executed. -You probably get some build errors in some projects. Try to ignore them for now - at least some unit test +If you do this for other projects, you might get some build errors. Try to ignore them for now - at least some unit test should be executed. See also "Known Issues" below. +## Running / Debugging PMD + +* Navigate to class `PmdCli` +* Right-Click and select "Run As -> Java Application". +* Ignore any build errors for now and choose "Proceed". +* In the console you should see the output from PMD. +* Now you have a run configuration: Modify this through menu "Run > Run Configurations..." + * In tab arguments: use `check --help` as program arguments + * In tab dependencies you can add the modules of languages you want to test with to the classpath, eg. pmd-java +* Instead of run, you can use the same configuration for debugging. ## Code Templates, Formatter @@ -40,7 +53,7 @@ should be executed. See also "Known Issues" below. Click `Import...` and choose the file `eclipse/pmd-eclipse-code-formatter.xml` from the "build-tools" repository. 4. Under `Java / Code Style / Clean Up`: Click `Import...` and choose the file `eclipse/pmd-eclipse-code-cleanup.xml` from the "build-tools" repository. -5. Under `Java / Code STyle / Organize Imports`: +5. Under `Java / Code Style / Organize Imports`: Click `Import...` and choose the file `eclipse/pmd-eclipse-imports.importorder` from the build-tools" repository. 6. Click `Apply and Close` @@ -49,14 +62,14 @@ should be executed. See also "Known Issues" below. We are going to install two plugins: The checkstyle plugin itself and the m2e-code-quality plugin, which seamlessly activates and configures checkstyle in eclipse according to the maven configuration of PMD. 1. Menu `Help`, `Install New Software...` -2. Enter the URL `http://eclipse-cs.sourceforge.net/update/` into the text field and press enter. +2. Enter the URL `https://checkstyle.org/eclipse-cs-update-site` into the text field and press enter. 3. Select the checkbox for "Checkstyle" and click `Next` 4. Restart eclipse if you are requested to do so. -5. Install the next plugin for the URL `http://m2e-code-quality.github.com/m2e-code-quality/site/latest` +5. Install the next plugin for the URL `https://m2e-code-quality.github.io/m2e-code-quality-p2-site/` 6. This time, select only "Checkstyle configuration plugin for M2Eclipse" and click `Next` 7. Restart eclipse if you are requested to do so. 8. Finally, right click on one project in the package explorer. Select `Maven / Update project...` in the context - menu. In the dialog, select all projects and click `OK`. + menu. In the dialog, select all projects, unselect the option "Clean projects" and click `OK`. ## Other settings @@ -64,35 +77,36 @@ We are going to install two plugins: The checkstyle plugin itself and the m2e-co * Consider displaying the white space characters: Window, Preferences; General / Editors / Text Editors: Show whitespace characters * Insert spaces for tabs also in text files: Window, Preferences; General / Editors / Text Editors: Insert spaces for tabs -## Executing the Designer +## Running the designer -The designer lives now in a separate repository, that you'll need to clone first: +The designer lives in a separate repository, that you'll need to fork and clone first: +[Designer repository](https://github.com/pmd/pmd-designer) -``` shell -$ git clone https://github.com/pmd/pmd-designer.git +```shell +git clone git@github.com:your_user_name/pmd-designer.git ``` -Import the designer project via menu `File`, `Import...`. In the dialog, select `Maven / Existing Maven Projects` and click `Next`. +See [Contributing Guide](https://github.com/pmd/pmd-designer/blob/master/CONTRIBUTING.md) of the Designer for details. -Open the class `net.sourceforge.pmd.util.fxdesigner.DesignerStarter` via menu "Navigate / Open Type...". - -Right click in the editor window and select "Run as -> Java Application". +* Import the designer project via menu `File`, `Import...`. In the dialog, select `Maven / Existing Maven Projects` and click `Next`. +* Open the class `net.sourceforge.pmd.util.fxdesigner.DesignerStarter` via menu "Navigate / Open Type...". +* Right click in the editor window and select "Run as -> Java Application". ## Known Issues -* pmd-apex, pmd-dist, pmd-doc and other projects are missing the project "pmd-apex-jorje". The project is actually - existing, but it is not a java project in eclipse. - - Workaround: +* Eclipse is very slow without making progress when building the complete PMD project. + * It could be, that eclipse runs out of memory. Open `eclipse.ini` and replace `-Xmx2048m` with `-Xmx4096m`. Restart eclipse. + * Close the other languages modules, that you are not interested in. The fewer projects that are open the better + for eclipse performance. + * Temporarily disable "Project > Build Automatically" and build the project using Maven: Run `./mvnw compile` and + after that select the top level project in Project Explorer ("pmd") and use "File > Refresh". Then enable + "Build Automatically" again. - 1. Build the project once from outside eclipse: `$ ./mvnw clean install -f pmd-apex-jorje/pom.xml` - This installs the dependency in your local maven repository. - 2. In eclipse, close the project "pmd-apex-jorje". That way, eclipse will use the jar file from the - local maven repository instead of the project. +* There is no good Kotlin support for Eclipse. Many tests depend on Kotlin and at least pmd-apex uses Kotlin + for the main sources. This means, you need to compile the project with Maven without Eclipse. -* Many tests depend on kotlin. Kotlin is not really supported in Eclipse. As long as you don't need to change - the kotlin tests, you can ignore this for now. In order to be able to execute the tests, there is a similar - workaround: + As long as you don't need to change the Kotlin code, you can ignore this for now. + In order to be able to execute the tests, there is a workaround: 1. Build the project "pmd-lang-test" once from outside eclipse: `$ ./mvnw clean install -f pmd-lang-test/pom.xml` This installs this module in your local maven repository. @@ -108,7 +122,7 @@ Right click in the editor window and select "Run as -> Java Application". it is recommended to close pmd-scala_2.12 and only work on pmd-scala_2.13. Then you need to configure "pmd-scala_2.13" manually, so that eclipse finds the source folders: - 1. Right-click on the project and open the "Properties". On the left navigate to "Java Build Path". + 1. Right-click on the project "pmd-scala_2.13" and open the "Properties". On the left navigate to "Java Build Path". 2. Open the tab "Source" 3. Delete the all source folders 4. Click on "Link Source..." and manually choose via "Linked folder location" the path in the repository From b8247de53e10a630bede1bde5fb186541b069dab Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 10 Jan 2025 17:44:01 +0100 Subject: [PATCH 0434/1962] [doc] Move Newcomers' Guide from Wiki --- docs/_data/sidebars/pmd_sidebar.yml | 9 + .../devdocs/contributing/newcomers_guide.md | 175 ++++++++++++++++++ 2 files changed, 184 insertions(+) create mode 100644 docs/pages/pmd/devdocs/contributing/newcomers_guide.md diff --git a/docs/_data/sidebars/pmd_sidebar.yml b/docs/_data/sidebars/pmd_sidebar.yml index 6ed2024891f..3efdfa39f5c 100644 --- a/docs/_data/sidebars/pmd_sidebar.yml +++ b/docs/_data/sidebars/pmd_sidebar.yml @@ -550,6 +550,15 @@ entries: - title: Building PMD with Netbeans IDE url: /pmd_devdocs_building_netbeans.html output: web, pdf + - title: null + output: web, pdf + subfolders: + - title: Contributing + output: web, pdf + subfolderitems: + - title: Newcomers' Guide + url: /pmd_devdocs_contributing_newcomers_guide.html + output: web, pdf - title: Contributing external_url: https://github.com/pmd/pmd/blob/main/CONTRIBUTING.md output: web, pdf diff --git a/docs/pages/pmd/devdocs/contributing/newcomers_guide.md b/docs/pages/pmd/devdocs/contributing/newcomers_guide.md new file mode 100644 index 00000000000..280f108f389 --- /dev/null +++ b/docs/pages/pmd/devdocs/contributing/newcomers_guide.md @@ -0,0 +1,175 @@ +--- +title: Newcomers' Guide +tags: [devdocs] +permalink: pmd_devdocs_contributing_newcomers_guide.html +author: Andreas Dangel +last_updated: January 2025 (7.10.0) +--- + +This is a small guide for GSoC Students and new contributors. + +## 1. Check out PMD + +As you want to engage with PMD, your first task is, to find out what PMD is - if you didn't do this already. +Read the [webpage](https://pmd.github.io), install PMD with the [Installation Guide](https://pmd.github.io/latest/pmd_userdocs_installation.html) and try it out. + + +Goals: Getting to know PMD, being able to run PMD locally + + +## 2. Meet the community + +Now it's time to say hello to the community. We use mostly GitHub, mailing list and Gitter for communication +and organizing tasks. + +Make sure, you use your GitHub account, when signing in into Gitter (and not your Twitter account) - this helps in recognizing you later on. + +You probably already know on our GitHub presence: + +You can subscribe to our mailing list at: + +We have a single chat room: + +## 3. Pick an issue + +The easiest way to familiarize yourself with the code base is to fix a small bug. You can see all [Good First Issues on GitHub](https://github.com/pmd/pmd/issues?utf8=%E2%9C%93&q=is%3Aopen+label%3A%22good+first+issue%22+no%3Aassignee+-label%3Ahas%3Apr). + +When you have chosen an issue that you want to fix, leave a comment, so that we can assign the issue to you. That +way, we can avoid that multiple people are working on the same issue. + +Goals: Familiarize with the code base + +## 4. Create a fork and get the source code + +In order to work on PMD you'll need the source code and an own fork. From your own fork, you'll create +pull requests later for your fix. + +1. Go to [the pmd repository on GitHub](https://github.com/pmd/pmd) and click the **Fork** button on the top right. +2. Go to your fork and select **Clone or download** and choose your clone url. + + In the following example, the github user id "johndoe" is used. Replace this with your real user id. + +3. Clone your fork: + + ``` shell + $ git clone https://github.com/johndoe/pmd.git --depth=10 --no-tags + ``` + + Now you have a local copy of PMD in the directory `pmd`. Note the options "depth=10" and "no-tags": This + is a speed-up, so that you only download and clone the latest history and not everything, + which would be pretty big. + + Enter this directory with `cd pmd`. The following commands are executed within this directory. + +4. Create a branch for your bug fix based on the "main" branch and directly switch to it: + + ``` shell + $ git checkout -b main + ``` + + Assuming, you are working on issue 123, then you can create a branch called "issue-123". + + _Note:_ It's best practice, to create a separate branch ("topic branch") for the fix and not work on the main branch. + +5. Now work on the fix and make sure, your changes are actually working. Rebuild pmd and run the tests, e.g. + + ``` shell + $ ./mvnw clean verify + ``` + + If your changes are only within one module (e.g. pmd-apex or pmd-java), then it is sufficient to only execute this + module. In order to rebuild only pmd-apex, execute this command: + + ``` shell + $ ./mvnw clean verify -pl pmd-apex + ``` + + We recommend to read the documentation [Building PMD General Info](pmd_devdocs_building_general.html) and + especially the IDE specific guides, such as [Building PMD with IntelliJ IDEA](pmd_devdocs_building_intellij.html). + These pages explain how to prepare your local development environment in order to work on PMD. + + When the build is successful, then commit your changes locally. If necessary, repeat + this step, until the bug is fixed. You can create multiple local commits, this + is no problem. + +## 5. Push your changes + +If you think, your changes are ready to be merged, commit them (if you've not done this already) and push +them into your fork: + +``` shell +$ git push -u origin +``` + +GitHub will display directly a link which you can open in your browser to +create a pull request. + +## 6. Create a pull request + +Either follow the link GitHub provided when you pushed or go to your fork on +GitHub and click the button **New pull request**. + +**Congratulations!** You have now created your first pull request! + +If you know, that your change is not complete yet and you are still working on it, then make sure, you +add the label "is:WIP" (work in progress) to the pull request. + +## 7. Wait for the review + +Now you need to wait a bit. One of the maintainers or other contributors will have a look at your pull request. +There are two possible outcomes of the review: +* The PR is accepted as is and is finally merged into the main branch. +* The PR is not accepted in the first round and some changes are requested. In that case, you can add additionally commits to your branch and push the branch afterwards. Let the reviewer know, that you have fixed/changed the PR. + +While you are waiting for the review, you can also have a look at other PRs and review those. This not only helps the maintainers, it's also another way to learn PMD's code base. + +## 8. Update local fork and further work + +**Awesome!** Your pull request has been accepted. + +But instead of going back to step 4 and repeat it and create a fresh clone/fork, +you'll learn now, how to update your local PMD code with the changes from "upstream". + +We'll first add the main PMD repository as upstream. This step only needs to be done +once: + +``` shell +$ git remote add upstream https://github.com/pmd/pmd +``` + +From now on, whenever you have finished work on a pull request and want to +start the next, you can update your local fork like this: + +We'll first switch back to the main branch and then pull all the changes from +upstream and push it to your fork: + +``` shell +$ git checkout main +$ git pull --ff-only upstream main +$ git push origin +``` + +_Note:_ You have now two remote repositories configured: "origin" is your own fork, +where you have write access and "upstream" is the main PMD repository, where you +only have read access. + +_Note:_ The pull command has the option `--ff-only`, which does only a fast-forward-merge +of the upstream changes. If you have ever committed locally something to your main +branch then the pull command will fail. That's why it is important to always +work on topic branches. + +Now you can go on with another issue or with a new feature. +Continue by creating a new topic branch: + + +``` shell +$ git checkout -b main +``` + + + +----- + +**References:** + +This guide is heavily inspired by From 73af3deda28d16a4ad8c0d3289ce6b0b7589a2ce Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 10 Jan 2025 18:18:42 +0100 Subject: [PATCH 0435/1962] [doc] Move Contributor's Guide into doc --- CONTRIBUTING.md | 67 ++--------- README.md | 2 +- docs/_data/sidebars/pmd_sidebar.yml | 34 +++--- .../pmd/devdocs/contributing/contributing.md | 105 ++++++++++++++++++ .../devdocs/{ => contributing}/development.md | 15 +-- .../writing_documentation.md | 0 6 files changed, 136 insertions(+), 87 deletions(-) create mode 100644 docs/pages/pmd/devdocs/contributing/contributing.md rename docs/pages/pmd/devdocs/{ => contributing}/development.md (80%) rename docs/pages/pmd/devdocs/{ => contributing}/writing_documentation.md (100%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c7d16e5a8dd..96366340a95 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,45 +2,20 @@ First off, thanks for taking the time to contribute! -Please note that this project is released with a Contributor Code of Conduct. -By participating in this project you agree to abide by its terms. +Detailed contributor info can be found in our documentation on . -You can find the code of conduct in the file [code_of_conduct.md](code_of_conduct.md). +**Pull Requests** are welcome. Create them against the `main` branch. -| NB: the rule designer is developed over at [pmd/pmd-designer](https://github.com/pmd/pmd-designer). Please refer to the specific [contributor documentation](https://github.com/pmd/pmd-designer/blob/main/CONTRIBUTING.md) if your issue, feature request or PR touches the designer. | -|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +**Building:** Make sure, you can build PMD locally. You need Java 11+, then run `./mvnw clean verify`. +Guides for using various IDEs are available at . -## Pull requests +**Code of Conduct:** -* Please create your pull request against the `main` branch. We will rebase/merge it to the maintenance - branches, if necessary. +**Bug Reports / Features:** We use the issue tracker on GitHub. Please report new bugs and feature requests at . -* We are using [checkstyle](http://checkstyle.sourceforge.net/) to enforce a common code style. - The check is integrated into the default build - so, make sure, you can [build PMD](BUILDING.md) without errors. - See [code style](#code-style) for more info. - - -## Bug reports - -We use the issue tracker on Github. Please report new bugs at . - -When filing a bug report, please provide as much information as possible, so that we can reproduce the issue: - -* The name of the rule, that is buggy -* A code snippet, which triggers a false positive/negative or crash -* How do you execute PMD? (command line, ant, maven, gradle, other) - - -## Documentation - -There is some documentation available under . Feel free to create a bug report if -documentation is missing, incomplete or outdated. See [Bug reports](#bug-reports). - -The documentation is generated as a Jekyll site, the source is available at: . You can find build instructions there. -For more on contributing documentation check - -## Questions +**Main Documentation:** +**Questions:** There are various channels, on which you can ask questions: * On [StackOverflow](https://stackoverflow.com/questions/tagged/pmd): Make sure, to tag your question with "pmd". @@ -50,29 +25,3 @@ There are various channels, on which you can ask questions: * Ask your question in our [Gitter room](https://app.gitter.im/#/room/#pmd_pmd:gitter.im). * Ask your question our [PMD Guru at Gurubase](https://gurubase.io/g/pmd). - -## Code Style - -PMD uses [checkstyle](http://checkstyle.sourceforge.net/) to enforce a common code style. - -See [pmd-checkstyle-config.xml](https://github.com/pmd/build-tools/blob/main/src/main/resources/net/sourceforge/pmd/pmd-checkstyle-config.xml) for the configuration and -[the eclipse configuration files](https://github.com/pmd/build-tools/tree/main/eclipse) that can -be imported into a fresh workspace. - -## Add yourself as contributor - -We use [All Contributors](https://allcontributors.org/en). - -To add yourself to the table of contributors, follow the -[bot usage instructions](https://allcontributors.org/docs/en/bot/usage) ;). - -Or use the CLI: - -1. Install the CLI: `npm i` (in PMD's top level directory) -2. Add yourself: `npx all-contributors add ` - -Where `username` is your GitHub username and `contribution` is a `,`-separated list -of contributions. See [Emoji Key](https://allcontributors.org/docs/en/emoji-key) for a list -of valid types. Common types are: "code", "doc", "bug", "blog", "talk", "test", "tutorial". - -See also [cli documentation](https://allcontributors.org/docs/en/cli/usage) diff --git a/README.md b/README.md index a05d7e60868..075fbb81fab 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ Pull requests are welcome. For major changes, please open an issue first to disc Our latest source of PMD can be found on [GitHub](https://github.com/pmd/pmd). Fork us! * [How to build PMD](BUILDING.md) -* [How to contribute to PMD](CONTRIBUTING.md) +* [How to contribute to PMD](https://docs.pmd-code.org/latest/pmd_devdocs_contributing.html) The rule designer is developed over at [pmd/pmd-designer](https://github.com/pmd/pmd-designer). Please see [its README](https://github.com/pmd/pmd-designer#contributing) for diff --git a/docs/_data/sidebars/pmd_sidebar.yml b/docs/_data/sidebars/pmd_sidebar.yml index 3efdfa39f5c..de61d56db1c 100644 --- a/docs/_data/sidebars/pmd_sidebar.yml +++ b/docs/_data/sidebars/pmd_sidebar.yml @@ -523,9 +523,24 @@ entries: - title: Developer Documentation output: web, pdf folderitems: - - title: Developer resources - url: /pmd_devdocs_development.html + - title: null output: web, pdf + subfolders: + - title: Contributing + output: web, pdf + subfolderitems: + - title: Contributing + url: /pmd_devdocs_contributing.html + output: web, pdf + - title: Developer resources + url: /pmd_devdocs_development.html + output: web, pdf + - title: Newcomers' Guide + url: /pmd_devdocs_contributing_newcomers_guide.html + output: web, pdf + - title: Writing documentation + url: /pmd_devdocs_writing_documentation.html + output: web, pdf - title: null output: web, pdf subfolders: @@ -550,21 +565,6 @@ entries: - title: Building PMD with Netbeans IDE url: /pmd_devdocs_building_netbeans.html output: web, pdf - - title: null - output: web, pdf - subfolders: - - title: Contributing - output: web, pdf - subfolderitems: - - title: Newcomers' Guide - url: /pmd_devdocs_contributing_newcomers_guide.html - output: web, pdf - - title: Contributing - external_url: https://github.com/pmd/pmd/blob/main/CONTRIBUTING.md - output: web, pdf - - title: Writing documentation - url: /pmd_devdocs_writing_documentation.html - output: web, pdf - title: Roadmap url: /pmd_devdocs_roadmap.html output: web, pdf diff --git a/docs/pages/pmd/devdocs/contributing/contributing.md b/docs/pages/pmd/devdocs/contributing/contributing.md new file mode 100644 index 00000000000..3e0c8d30083 --- /dev/null +++ b/docs/pages/pmd/devdocs/contributing/contributing.md @@ -0,0 +1,105 @@ +--- +title: Contributor's Guide +summary: How to contribute to PMD +tags: [devdocs] +permalink: pmd_devdocs_contributing.html +author: Andreas Dangel +last_updated: January 2025 (7.10.0) +--- + +First off, thanks for taking the time to contribute! + +Please note that this project is released with a Contributor Code of Conduct. +By participating in this project you agree to abide by its terms. +You can find the code of conduct in the file [code_of_conduct.md](https://github.com/pmd/pmd/blob/main/code_of_conduct.md). + +## Getting started + +You can find a lot of detailed information on this page and in the related pages: +* [Developer Resources](pmd_devdocs_development.html) +* [Newcomers' Guide](pmd_devdocs_contributing_newcomers_guide.html) +* [Building PMD](pmd_devdocs_building_general.html) + +Here we'll try to provide a concise overview. + +## Pull requests + +* Pull requests are welcomed. If the task is a bit bigger (say it touches more than 5 files), it might + make sense to create an issue first to discuss the intended change. + +* Please create your pull request against the `main` branch. We will rebase/merge it to the maintenance + branches, if necessary. + +* We are using [Checkstyle](https://checkstyle.org/) to enforce a common code style. + The check is integrated into the default build - so, make sure, you can + [build PMD](pmd_devdocs_building_general.html) without errors. + See [code style](#code-style) for more info. + +* Your pull request will be built automatically. If the build was successful, our + [PMD Regression Tester](pmd_devdocs_pmdtester.html), which runs PMD against a couple of test projects + and creates a report with the found new violations (or removed violations). This helps to + avoid accidentally introducing false positives or negatives. + +## Bug reports + +We use the issue tracker on GitHub. Please report new bugs at . + +When filing a bug report, please provide as much information as possible, so that we can reproduce the issue: + +* The name of the rule, that is buggy +* A code snippet, which triggers a false positive/negative or crash +* How do you execute PMD? (command line, ant, maven, gradle, other) + + +## Documentation + +There is some documentation available under . Feel free to create a bug report if +documentation is missing, incomplete or outdated. See [Bug reports](#bug-reports). + +The documentation is generated as a Jekyll site, the source is available in the subfolder `docs` or at: +. You can find build instructions there. +See also [writing documentation](pmd_devdocs_writing_documentation.html) for detailed information. + +## PMD Designer + +The rule designer is developed over at [pmd/pmd-designer](https://github.com/pmd/pmd-designer). +Please refer to the specific [contributor documentation](https://github.com/pmd/pmd-designer/blob/main/CONTRIBUTING.md) +if your issue, feature request or PR touches the designer. + +## Questions + +There are various channels, on which you can ask questions: + +* On [StackOverflow](https://stackoverflow.com/questions/tagged/pmd): Make sure, to tag your question with "pmd". + +* Create a new discussion for your question at . + +* Ask your question in our [Gitter room](https://app.gitter.im/#/room/#pmd_pmd:gitter.im). + +* Ask your question our [PMD Guru at Gurubase](https://gurubase.io/g/pmd). + +## Code Style + +PMD uses [Checkstyle](https://checkstyle.org/) to enforce a common code style. + +See [pmd-checkstyle-config.xml](https://github.com/pmd/build-tools/blob/main/src/main/resources/net/sourceforge/pmd/pmd-checkstyle-config.xml) for the configuration and +[the eclipse configuration files](https://github.com/pmd/build-tools/tree/main/eclipse) that can +be imported into a fresh workspace. + +## Add yourself as contributor + +We use [All Contributors](https://allcontributors.org/en) - all our contributors are listed on the page [Credits](pmd_projectdocs_credits.html). + +To add yourself to the table of contributors, follow the +[bot usage instructions](https://allcontributors.org/docs/en/bot/usage) ;). + +Or use the CLI: + +1. Install the CLI: `npm i` (in PMD's top level directory) +2. Add yourself: `npx all-contributors add ` + +Where `username` is your GitHub username and `contribution` is a `,`-separated list +of contributions. See [Emoji Key](https://allcontributors.org/docs/en/emoji-key) for a list +of valid types. Common types are: "code", "doc", "bug", "blog", "talk", "test", "tutorial". + +See also [cli documentation](https://allcontributors.org/docs/en/cli/usage) diff --git a/docs/pages/pmd/devdocs/development.md b/docs/pages/pmd/devdocs/contributing/development.md similarity index 80% rename from docs/pages/pmd/devdocs/development.md rename to docs/pages/pmd/devdocs/contributing/development.md index 46a850ef47e..95c657a3032 100644 --- a/docs/pages/pmd/devdocs/development.md +++ b/docs/pages/pmd/devdocs/contributing/development.md @@ -2,18 +2,20 @@ title: Developer Resources tags: [devdocs] permalink: pmd_devdocs_development.html -last_updated: March 2024 +last_updated: January 2025 (7.10.0) --- ## Source Code -The complete source code can be found on Github: +The complete source code can be found on GitHub: * [github.com/pmd/pmd](https://github.com/pmd/pmd) - main PMD repository. Includes all the code to support all languages, including this documentation. * [github.com/pmd/pmd.github.io](https://github.com/pmd/pmd.github.io) - Contains the landing page [https://pmd.github.io](https://pmd.github.io) * [github.com/pmd/build-tools](https://github.com/pmd/build-tools) - Contains the checkstyle rules we use +* [github.com/pmd/pmd-designer](https://github.com/pmd/pmd-designer) - PMD Rule Designer +* [github.com/pmd/pmd-regression-tester](https://github.com/pmd/pmd-regression-tester) - PMD Regression Tester * [github.com/pmd/pmd-eclipse-plugin](https://github.com/pmd/pmd-eclipse-plugin) - The PMD eclipse plugin -* [github.com/pmd](https://github.com/pmd) - PMD Organization at github. There are a couple of more repositories +* [github.com/pmd](https://github.com/pmd) - PMD Organization at GitHub. There are a couple of more repositories ## Continuous Integration @@ -31,10 +33,3 @@ Main documentation server is [docs.pmd-code.org](https://docs.pmd-code.org). A [snapshot](http://docs.pmd-code.org/snapshot/) of the web site for the new version is generated by the ci job as well. The latest release documentation is always available under [docs.pmd-code.org/latest](https://docs.pmd-code.org/latest/) - -## Contributing - -First off, thanks for taking the time to contribute! - -Please have a look at [CONTRIBUTING.md](https://github.com/pmd/pmd/blob/main/CONTRIBUTING.md) and -[BUILDING.md](https://github.com/pmd/pmd/blob/main/BUILDING.md). diff --git a/docs/pages/pmd/devdocs/writing_documentation.md b/docs/pages/pmd/devdocs/contributing/writing_documentation.md similarity index 100% rename from docs/pages/pmd/devdocs/writing_documentation.md rename to docs/pages/pmd/devdocs/contributing/writing_documentation.md From c0363e421500b88597d6b7a0c7fc902f996ccfc1 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 10 Jan 2025 18:36:02 +0100 Subject: [PATCH 0436/1962] [doc] Merge BUILDING.md into building_general.md --- BUILDING.md | 44 ------------- README.md | 3 +- .../pmd/devdocs/building/building_general.md | 63 +++++++++++++++---- 3 files changed, 52 insertions(+), 58 deletions(-) delete mode 100644 BUILDING.md diff --git a/BUILDING.md b/BUILDING.md deleted file mode 100644 index 6a44fb82db0..00000000000 --- a/BUILDING.md +++ /dev/null @@ -1,44 +0,0 @@ -# How to build PMD - -PMD uses [Maven](https://maven.apache.org/) and requires at least Java 11 for building. -You can get Java 11 from [Oracle](http://www.oracle.com/technetwork/java/javase/downloads/index.html) -or from [AdoptOpenJdk](https://adoptopenjdk.net/). - -PMD uses the [maven wrapper](https://maven.apache.org/wrapper/), so you can simply build PMD as following: - -* `./mvnw clean verify` (on Unix-like platform such as Linux and Mac OS X) -* `mvnw.cmd clean verify` (on Windows) - -This will create the zip files in the directory `pmd-dist/target`: - - cd pmd-dist/target - ls *.zip - -That's all ! - -**Note:** While Java 11 is required for building, running PMD only requires Java 7 -(or Java 8 for Apex, JavaScript, Scala, Visualforce, and the Designer). - -**Note:** With PMD 6.24.0, we are creating [Reproducible Builds](https://reproducible-builds.org/). Since we use -[Maven](https://maven.apache.org/guides/mini/guide-reproducible-builds.html) for building, the following -limitations apply: - -* Generally give **different results on Windows and Unix** because of different newlines. - (carriage return linefeed on Windows, linefeed on Unixes). - - We build our releases under **Linux** on [Github Actions](https://github.com/pmd/pmd/actions). - -* Generally depend on the **major version of the JDK** used to compile. (Even with source/target defined, - each major JDK version changes the generated bytecode.). - - We build our releases using OpenJDK 11. - -## How to build the documentation? - - cd docs - bundle install # once - bundle exec jekyll build - -You'll find the built site in the directory `_site/`. - -For more info, see [README in docs directory](docs/README.md). diff --git a/README.md b/README.md index 075fbb81fab..681f710fe73 100644 --- a/README.md +++ b/README.md @@ -63,8 +63,7 @@ Pull requests are welcome. For major changes, please open an issue first to disc Our latest source of PMD can be found on [GitHub](https://github.com/pmd/pmd). Fork us! -* [How to build PMD](BUILDING.md) -* [How to contribute to PMD](https://docs.pmd-code.org/latest/pmd_devdocs_contributing.html) +For details, see [How to contribute to PMD](https://docs.pmd-code.org/latest/pmd_devdocs_contributing.html). The rule designer is developed over at [pmd/pmd-designer](https://github.com/pmd/pmd-designer). Please see [its README](https://github.com/pmd/pmd-designer#contributing) for diff --git a/docs/pages/pmd/devdocs/building/building_general.md b/docs/pages/pmd/devdocs/building/building_general.md index 3b0c9f39c05..42379a5e887 100644 --- a/docs/pages/pmd/devdocs/building/building_general.md +++ b/docs/pages/pmd/devdocs/building/building_general.md @@ -6,10 +6,11 @@ author: Andreas Dangel last_updated: January 2025 (7.10.0) --- -# Before Development +## Before Development -1. Ensure that [Git](https://git-scm.com/) and Java JDK >= 11 are installed. You can get a OpenJDK distribution - from e.g. [Adoptium](https://adoptium.net/). +1. Ensure that [Git](https://git-scm.com/) and Java JDK >= 11 are installed. + You can get a OpenJDK distribution from e.g. [Adoptium](https://adoptium.net/). + **Note:** While Java 11 is required for building, running PMD only requires Java 8. 2. Fork the [PMD repository](https://github.com/pmd/pmd) on GitHub as explained in [Fork a repository](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo). 3. Clone your forked repository to your computer: ```shell @@ -37,13 +38,51 @@ commit history locally, either clone the repo without the "depth" option or conv {%endcapture%} {%include note.html content=notetext %} -# Development +## Reproducible Builds -* Use a IDE, see the other guides -* Contributing via GitHub and Pull Requests: -* setup upstream repo -* create a dev branch -* commit dev branch -* push dev branch -* send a pull request -* keep your fork up to date +Since PMD 6.24.0, we are creating [Reproducible Builds](https://reproducible-builds.org/). As we use +[Maven](https://maven.apache.org/guides/mini/guide-reproducible-builds.html) for building, the following +limitations apply: + +* Generally give **different results on Windows and Unix** because of different newlines. + (carriage return linefeed on Windows, linefeed on Unixes). + + We build our releases under **Linux** on [Github Actions](https://github.com/pmd/pmd/actions). + +* Generally depend on the **major version of the JDK** used to compile. (Even with source/target defined, + each major JDK version changes the generated bytecode.). + + We build our releases using OpenJDK 11. + +You can check the reproducible build status here: + +## How to build the documentation? + + cd docs + bundle install # once + bundle exec jekyll build + +You'll find the built site in the directory `_site/`. + +For more info, see [README in docs directory](https://github.com/pmd/pmd/tree/main/docs#readme). + +## General Development + +* Use a IDE, see one of the other guides + * [Building PMD with IntelliJ IDEA](pmd_devdocs_building_intellij.html) + * [Building PMD with Eclipse](pmd_devdocs_building_eclipse.html) + * [Building PMD with Netbeans](pmd_devdocs_building_netbeans.html) + * [Building PMD with VS Code](pmd_devdocs_building_vscode.html) +* [Contributing via GitHub and Pull Requests](pmd_devdocs_contributing.html#pull-requests) +* Keep your fork up-to-date + * You can do this either via GitHub's Web UI + * Or manually: + ```shell + git remote add upstream git@github.com:pmd/pmd.git + git checkout main + git pull --ff-only upstream main + git push origin + ``` + * See also [Newcomers' Guide](pmd_devdocs_contributing_newcomers_guide.html) +* Always create a dev branch when you are going to commit something, + so that you can easily create a PR later on. From 51159a0fa5fdc18d706a4448593d72cbb66fea14 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 10 Jan 2025 18:49:03 +0100 Subject: [PATCH 0437/1962] [doc] Update building_general.md - SNAPSHOT builds - Build a single module --- .../pmd/devdocs/building/building_general.md | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/docs/pages/pmd/devdocs/building/building_general.md b/docs/pages/pmd/devdocs/building/building_general.md index 42379a5e887..0cd39196631 100644 --- a/docs/pages/pmd/devdocs/building/building_general.md +++ b/docs/pages/pmd/devdocs/building/building_general.md @@ -66,7 +66,34 @@ You'll find the built site in the directory `_site/`. For more info, see [README in docs directory](https://github.com/pmd/pmd/tree/main/docs#readme). -## General Development +## How to test SNAPSHOT builds? + +Every push to our main branch creates a new SNAPSHOT build. You can download the binary distribution +from . The binary distribution ZIP file behaves exactly +the same as the real release: Just unzip it and execute PMD. + +If you integrate PMD as a dependency in your own project, you can also reference the latest SNAPSHOT +version. However, you also need to configure an additional Maven Repository, as the SNAPSHOTS are not published +in Maven Central. + +Use the OSSRH snapshot repository url: `https://oss.sonatype.org/content/repositories/snapshots`. For Maven +projects, this can be configured like: +```xml + + + sonatype-nexus-snapshots + Sonatype Nexus Snapshots + https://oss.sonatype.org/content/repositories/snapshots + false + true + + +``` + +Have a look at to see which +SNAPSHOT versions are available. Note that old SNAPSHOT versions might be removed without prior notice. + +## General Development Tips * Use a IDE, see one of the other guides * [Building PMD with IntelliJ IDEA](pmd_devdocs_building_intellij.html) @@ -86,3 +113,12 @@ For more info, see [README in docs directory](https://github.com/pmd/pmd/tree/ma * See also [Newcomers' Guide](pmd_devdocs_contributing_newcomers_guide.html) * Always create a dev branch when you are going to commit something, so that you can easily create a PR later on. +* Build a single module only: Always (re)building the complete PMD source takes quite a while. If you only + change one module, you build and test just this single module to speed up development. Eg. if you changed + a rule in pmd-apex only, you can just build this: + ```shell + ./mvnw verify -pl pmd-apex + ``` + **Caveats:** We have some integration tests, that run only after all modules have been built. You could + break these without noticing. + **Note:** In our CI (via GitHub Actions) we always build the complete project. From 41958199e67a8038f21a39aff97214c451c253aa Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 10 Jan 2025 18:52:27 +0100 Subject: [PATCH 0438/1962] [doc] Add SECURITY.md --- CONTRIBUTING.md | 2 ++ SECURITY.md | 12 ++++++++++++ docs/pages/pmd/devdocs/contributing/contributing.md | 3 +++ 3 files changed, 17 insertions(+) create mode 100644 SECURITY.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 96366340a95..b94594f559d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,6 +13,8 @@ Guides for using various IDEs are available at . +**Reporting Security Issues:** + **Main Documentation:** **Questions:** diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000000..8ade2dfa24b --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,12 @@ +# Reporting Security Issues + +The PMD team and community take security bugs in PMD seriously. We appreciate your efforts to responsibly disclose +your findings, and will make every effort to acknowledge your contributions. + +To report a security issue, please use the GitHub Security Advisory ["Report a Vulnerability"](https://github.com/pmd/pmd/security/advisories/new) tab. + +The PMD team will send a response indicating the next steps in handling your report. After the initial reply to your +report, the security team will keep you informed of the progress towards a fix and full announcement, +and may ask for additional information or guidance. + +Report security bugs in third-party modules to the person or team maintaining the module. diff --git a/docs/pages/pmd/devdocs/contributing/contributing.md b/docs/pages/pmd/devdocs/contributing/contributing.md index 3e0c8d30083..881b5fd40f0 100644 --- a/docs/pages/pmd/devdocs/contributing/contributing.md +++ b/docs/pages/pmd/devdocs/contributing/contributing.md @@ -50,6 +50,9 @@ When filing a bug report, please provide as much information as possible, so tha * A code snippet, which triggers a false positive/negative or crash * How do you execute PMD? (command line, ant, maven, gradle, other) +## Reporting Security Issues + +See [SECURITY.md](https://github.com/pmd/pmd/blob/main/SECURITY.md) ## Documentation From a112829ed96f0909be91ad9a1030cd29c52e9252 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 10 Jan 2025 18:54:53 +0100 Subject: [PATCH 0439/1962] [doc] Update release notes (#2492) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 26ec825d013..4b8698a6d84 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -15,6 +15,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* documentation + * [#2492](https://github.com/pmd/pmd/issues/2492): \[doc] Promote wiki pages to standard doc pages ### ๐Ÿšจ API Changes From c4e8e8c2adc9b82a025a71c5bb7307aacdaa326c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 18:43:15 +0100 Subject: [PATCH 0440/1962] Bump org.apache.maven.plugins:maven-gpg-plugin from 3.1.0 to 3.2.7 (#5459) Bumps [org.apache.maven.plugins:maven-gpg-plugin](https://github.com/apache/maven-gpg-plugin) from 3.1.0 to 3.2.7. - [Release notes](https://github.com/apache/maven-gpg-plugin/releases) - [Commits](https://github.com/apache/maven-gpg-plugin/compare/maven-gpg-plugin-3.1.0...maven-gpg-plugin-3.2.7) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-gpg-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a753072d0d9..0451c61c613 100644 --- a/pom.xml +++ b/pom.xml @@ -1206,7 +1206,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.1.0 + 3.2.7 sign-artifacts From ed6d14ad1a2ff02264bcb43ab08c979bf8f1f91b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 18:43:48 +0100 Subject: [PATCH 0441/1962] Bump org.apache.commons:commons-text from 1.12.0 to 1.13.0 (#5460) Bumps org.apache.commons:commons-text from 1.12.0 to 1.13.0. --- updated-dependencies: - dependency-name: org.apache.commons:commons-text dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0451c61c613..fdabfb9f5a4 100644 --- a/pom.xml +++ b/pom.xml @@ -867,7 +867,7 @@ org.apache.commons commons-text - 1.12.0 + 1.13.0 org.slf4j From 8e7d1c5d5ba52fda0c4d5499b09a83c7dc04b216 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 18:44:30 +0100 Subject: [PATCH 0442/1962] Bump com.google.protobuf:protobuf-java from 4.29.1 to 4.29.3 (#5461) Bumps [com.google.protobuf:protobuf-java](https://github.com/protocolbuffers/protobuf) from 4.29.1 to 4.29.3. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl) - [Commits](https://github.com/protocolbuffers/protobuf/commits) --- updated-dependencies: - dependency-name: com.google.protobuf:protobuf-java dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fdabfb9f5a4..9f631468e91 100644 --- a/pom.xml +++ b/pom.xml @@ -1090,7 +1090,7 @@ com.google.protobuf protobuf-java - 4.29.1 + 4.29.3 diff --git a/pmd-java/etc/grammar/Java.jjt b/pmd-java/etc/grammar/Java.jjt index 75afdc49777..a68ace413da 100644 --- a/pmd-java/etc/grammar/Java.jjt +++ b/pmd-java/etc/grammar/Java.jjt @@ -1,4 +1,7 @@ /** + * Removed support for String Templates, introduced in Java 21 / 22 Preview + * Andreas Dangel 01/2025 + *==================================================================== * Support "JEP 455: Primitive Types in Patterns, instanceof, and switch (Preview)" (Java 23) * Changes in InstanceOfExpression * Support "JEP 476: Module Import Declarations (Preview)" (Java 23) @@ -614,50 +617,6 @@ PARSER_END(JavaParserImpl) TOKEN_MGR_DECLS : { protected List comments = new ArrayList(); - private Deque savedTemplateKind = new ArrayDeque(); - private Deque braceDepthInTemplate = new ArrayDeque(); - private int braceDepthCurrentTemplate; - private boolean templateKind; - - private static final java.util.regex.Pattern TEXT_BLOCK_TEMPLATE_END_PATTERN = - java.util.regex.Pattern.compile("^}[^\"]*\"\"\""); - private static final java.util.regex.Pattern STRING_TEMPLATE_MID_OR_END_PATTERN = - java.util.regex.Pattern.compile("^}(?:[^\"\\\\\n\r]|\\\\(?:[ntbrfs\\\\'\"]|[0-7][0-7]?|[0-3][0-7][0-7]))*(\\{|\")"); - - private void pushBrace() { - braceDepthCurrentTemplate++; - } - private void pushTemplate(boolean isTextBlockTemplate) { - braceDepthInTemplate.push(braceDepthCurrentTemplate); - savedTemplateKind.push(templateKind); - templateKind = isTextBlockTemplate; - braceDepthCurrentTemplate = 1; - } - private boolean isInTemplate() { - return braceDepthCurrentTemplate > 0; - } - private void popBrace() { - if (!isInTemplate()) - return; - if (--braceDepthCurrentTemplate == 0) { - // this brace ends the template - popTemplate(); - } - } - private void popTemplate() { - boolean isInTextBlockTemplate = templateKind; - if (!braceDepthInTemplate.isEmpty()) { - braceDepthCurrentTemplate = braceDepthInTemplate.pop(); - templateKind = savedTemplateKind.pop(); - if (isInTextBlockTemplate) { - SwitchTo(JavaTokenKinds.IN_TEXT_BLOCK_LITERAL); - } else { - SwitchTo(JavaTokenKinds.IN_STRING_TEMPLATE); - } - } else { - SwitchTo(JavaTokenKinds.DEFAULT); - } - } private net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken rereadTokenAs(int kind, int length) { input_stream.backup(lengthOfMatch); try { @@ -670,14 +629,6 @@ TOKEN_MGR_DECLS : jjmatchedKind = kind; return jjFillToken(); } - - private net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken handleBlock() { - net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken matchedToken = rereadTokenAs(JavaTokenKinds.RBRACE, 1); - if (!"}".equals(input_stream.getTokenImage())) { - throw new IllegalStateException("Expected '}'"); - } - return matchedToken; - } } /* WHITE SPACE */ @@ -859,8 +810,6 @@ TOKEN : ) > | < #TEXT_BLOCK_CHARACTER: ~["\\"] | | ("\\")? > -| < #STRING_FRAGMENT: ()* > -| < STRING_TEMPLATE_BEGIN: "\"" "\\{" > { pushTemplate(false); } } /* TEXT BLOCKS */ @@ -874,7 +823,6 @@ MORE : TOKEN : { : DEFAULT -| { pushTemplate(true); }: DEFAULT } @@ -883,13 +831,6 @@ MORE : < > } - -TOKEN: -{ - < STRING_TEMPLATE_END: "\"" > : DEFAULT -| < STRING_TEMPLATE_MID: "\\{" > { pushTemplate(false); } : DEFAULT -} - /* IDENTIFIERS */ TOKEN : @@ -1027,8 +968,8 @@ TOKEN : { < LPAREN: "(" > | < RPAREN: ")" > -| < LBRACE: "{" > { pushBrace(); } -| < RBRACE: "}" > { popBrace(); } +| < LBRACE: "{" > +| < RBRACE: "}" > | < LBRACKET: "[" > | < RBRACKET: "]" > | < SEMICOLON: ";" > @@ -2186,7 +2127,6 @@ void PrimaryStep2() #void: // "super" alone is not a valid expression ("." MemberSelector() | MethodReference()) | MemberSelector() - | {forceExprContext();} Template() #TemplateExpression(2) ) // catches the case where the ambig name is the start of an array type | LOOKAHEAD("@" | "[" "]") {forceTypeContext();} Dims() #ArrayType(2) (MethodReference() | "." "class" #ClassLiteral(1)) @@ -2291,41 +2231,6 @@ boolean LambdaParameterType() #void : | FormalParamType() { return false; } } -void Template() : -{} -{ - StringTemplate() - | TextBlockTemplate() - | #TemplateFragment - | #TemplateFragment - -} - -void StringTemplate() #void : -{} -{ - #TemplateFragment - EmbeddedExpression() - (LOOKAHEAD(2) ( ) #TemplateFragment EmbeddedExpression() )* - ( ) #TemplateFragment -} - -void TextBlockTemplate() #void : -{} -{ - - #TemplateFragment - EmbeddedExpression() - (LOOKAHEAD(2) ( ) #TemplateFragment EmbeddedExpression() )* - ( ) #TemplateFragment -} - -void EmbeddedExpression() #void : -{} -{ - [ Expression() ] -} - void Literal() #void : {} { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTemplate.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTemplate.java deleted file mode 100644 index 3ce54c7cadf..00000000000 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTemplate.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.ast; - -import net.sourceforge.pmd.annotation.Experimental; - -/** - * The template of a {@link ASTTemplateExpression}. This is a Java 21/22 Preview feature. - * - *
    - *
    - * Template ::= ({@link ASTTemplateFragment TemplateFragment} {@link ASTExpression Expression}?)* {@link ASTTemplateFragment TemplateFragment}
    - *
    - * 
    - * - * @see JEP 430: String Templates (Preview) (Java 21) - * @see JEP 459: String Templates (Second Preview) (Java 22) - */ -@Experimental("String templates is a Java 21/22 Preview feature") -public final class ASTTemplate extends AbstractJavaNode { - ASTTemplate(int i) { - super(i); - } - - @Override - protected R acceptVisitor(JavaVisitor visitor, P data) { - return visitor.visit(this, data); - } -} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTemplateExpression.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTemplateExpression.java deleted file mode 100644 index 73c00d841bd..00000000000 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTemplateExpression.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.ast; - -import net.sourceforge.pmd.annotation.Experimental; -import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr.ASTNamedReferenceExpr; - -/** - * A string template expression. This is a Java 21/22 Preview feature. - * - *
    - *
    - * TemplateExpression ::= ({@link ASTVariableAccess VariableAccess} | {@link ASTFieldAccess FieldAccess}) {@link ASTTemplate Template}
    - *
    - * 
    - * - * @see JEP 430: String Templates (Preview) (Java 21) - * @see JEP 459: String Templates (Second Preview) (Java 22) - */ -@Experimental("String templates is a Java 21/22 Preview feature") -public final class ASTTemplateExpression extends AbstractJavaExpr { - ASTTemplateExpression(int i) { - super(i); - } - - @Override - protected R acceptVisitor(JavaVisitor visitor, P data) { - return visitor.visit(this, data); - } - - public ASTExpression getTemplateProcessor() { - return (ASTExpression) getChild(0); - } - - public JavaNode getTemplateArgument() { - return getChild(1); - } - - public boolean isStringTemplate() { - String name; - if (getTemplateProcessor() instanceof ASTNamedReferenceExpr) { - name = ((ASTNamedReferenceExpr) getTemplateProcessor()).getName(); - } else { - name = getTemplateProcessor().getFirstToken().getImage(); - } - return "STR".equals(name); - } -} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTemplateFragment.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTemplateFragment.java deleted file mode 100644 index 2f88b7903be..00000000000 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTemplateFragment.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.ast; - -import net.sourceforge.pmd.annotation.Experimental; - -/** - * This is a Java 21/22 Preview feature. - * - *
    - *
    - * TemplateFragment ::= StringTemplateBegin|StringTemplateMid|StringTemplateEnd
    - *                      |TextBlockTemplateBegin|TextBlockTemplateMid|TextBlockTemplateEnd
    - *
    - * 
    - * - * @see JEP 430: String Templates (Preview) (Java 21) - * @see JEP 459: String Templates (Second Preview) (Java 22) - */ -@Experimental("String templates is a Java 21/22 Preview feature") -public final class ASTTemplateFragment extends AbstractJavaNode { - - ASTTemplateFragment(int i) { - super(i); - } - - @Override - protected R acceptVisitor(JavaVisitor visitor, P data) { - return visitor.visit(this, data); - } - - public String getContent() { - return getText().toString(); - } - -} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java index 1f0dd09986b..872d1000401 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java @@ -44,7 +44,6 @@ import net.sourceforge.pmd.lang.java.ast.ASTSwitchArrowBranch; import net.sourceforge.pmd.lang.java.ast.ASTSwitchExpression; import net.sourceforge.pmd.lang.java.ast.ASTSwitchLabel; -import net.sourceforge.pmd.lang.java.ast.ASTTemplateExpression; import net.sourceforge.pmd.lang.java.ast.ASTTryStatement; import net.sourceforge.pmd.lang.java.ast.ASTType; import net.sourceforge.pmd.lang.java.ast.ASTTypeArguments; @@ -129,14 +128,6 @@ private static String versionDisplayName(int jdk) { * They might be also be standardized. */ private enum PreviewFeature implements LanguageFeature { - /** - * String Templates. Only support with Java 22 Preview now. - * @see JEP 430: String Templates (Preview) (Java 21) - * @see JEP 459: String Templates (Second Preview) (Java 22) - * @see JDK-8329949 Remove the String Templates preview feature (Java 23) - */ - STRING_TEMPLATES(22, 22, false), - /** * Unnamed Classes and Instance Main Methods * @see JEP 445: Unnamed Classes and Instance Main Methods (Preview) (Java 21) @@ -685,12 +676,6 @@ public Void visit(ASTVariableId node, T data) { return null; } - @Override - public Void visit(ASTTemplateExpression node, T data) { - check(node, PreviewFeature.STRING_TEMPLATES, data); - return null; - } - @Override public Void visit(ASTUnnamedPattern node, T data) { check(node, RegularLanguageFeature.UNNAMED_VARIABLES_AND_PATTERNS, data); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/LazyTypeResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/LazyTypeResolver.java index 1cc5b4344f7..f607c386082 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/LazyTypeResolver.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/LazyTypeResolver.java @@ -53,7 +53,6 @@ import net.sourceforge.pmd.lang.java.ast.ASTSwitchExpression; import net.sourceforge.pmd.lang.java.ast.ASTSwitchLabel; import net.sourceforge.pmd.lang.java.ast.ASTSwitchLike; -import net.sourceforge.pmd.lang.java.ast.ASTTemplateExpression; import net.sourceforge.pmd.lang.java.ast.ASTThisExpression; import net.sourceforge.pmd.lang.java.ast.ASTType; import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration; @@ -509,15 +508,6 @@ public JTypeMirror visit(ASTCastExpression node, TypingContext ctx) { return node.getCastType().getTypeMirror(ctx); } - @Override - public @NonNull JTypeMirror visit(ASTTemplateExpression node, TypingContext data) { - if (node.isStringTemplate()) { - return stringType; - } - - return ts.UNKNOWN; - } - @Override public JTypeMirror visit(ASTNullLiteral node, TypingContext ctx) { return ts.NULL_TYPE; diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java23PreviewTreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java23PreviewTreeDumpTest.java index 1981bfa960e..732e73e5ac6 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java23PreviewTreeDumpTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java23PreviewTreeDumpTest.java @@ -17,6 +17,7 @@ import org.junit.jupiter.api.Test; +import net.sourceforge.pmd.lang.ast.LexException; import net.sourceforge.pmd.lang.ast.ParseException; import net.sourceforge.pmd.lang.java.BaseJavaTreeDumpTest; import net.sourceforge.pmd.lang.java.JavaParsingHelper; @@ -114,9 +115,9 @@ void jep455PrimitiveTypesInPatternsInstanceofAndSwitchBeforeJava23Preview() { @Test void stringTemplatesAreNotSupportedAnymore() { - ParseException thrown = assertThrows(ParseException.class, () -> java23p.parseResource("StringTemplatesAreNotSupportedAnymore.java")); - assertThat(thrown.getMessage(), containsString("String templates is a preview feature of JDK 22, you should select your language version accordingly")); - ParseException thrown2 = assertThrows(ParseException.class, () -> java23.parseResource("StringTemplatesAreNotSupportedAnymore.java")); - assertThat(thrown2.getMessage(), containsString("String templates is a preview feature of JDK 22, you should select your language version accordingly")); + LexException thrown = assertThrows(LexException.class, () -> java23p.parseResource("StringTemplatesAreNotSupportedAnymore.java")); + assertThat(thrown.getMessage(), containsString("Lexical error in file")); + LexException thrown2 = assertThrows(LexException.class, () -> java23.parseResource("StringTemplatesAreNotSupportedAnymore.java")); + assertThat(thrown2.getMessage(), containsString("Lexical error in file")); } } From e3c8ff27b377c696590959d85cb48eb9b46ea4b7 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 23 Jan 2025 18:09:51 +0100 Subject: [PATCH 0460/1962] [doc] Update release notes (#5154) --- docs/pages/release_notes.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index c790457baa6..a8f1f4ea16c 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -14,7 +14,28 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy +### ๐Ÿš€ New: Java 24 Support +This release of PMD brings support for Java 24. There are no new standard language features, +but a couple of preview language features: + +* [JEP 488: Primitive Types in Patterns, instanceof, and switch (Second Preview)](https://openjdk.org/jeps/488) +* [JEP 492: Flexible Constructor Bodies (Third Preview)](https://openjdk.org/jeps/492) +* [JEP 494: Module Import Declarations (Second Preview)](https://openjdk.org/jeps/494) +* [JEP 495: Simple Source Files and Instance Main Methods (Fourth Preview)](https://openjdk.org/jeps/495) + +In order to analyze a project with PMD that uses these preview language features, +you'll need to enable it via the environment variable `PMD_JAVA_OPTS` and select the new language +version `24-preview`: + + export PMD_JAVA_OPTS=--enable-preview + pmd check --use-version java-24-preview ... + +Note: Support for Java 22 preview language features have been removed. The version "22-preview" +are no longer available. + ### ๐Ÿ› Fixed Issues +* java + * [#5154](https://github.com/pmd/pmd/issues/5154): \[java] Support Java 24 ### ๐Ÿšจ API Changes From 87732ede5d82067793cc9866ff5ba23fe1e0f22b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 23 Jan 2025 18:52:40 +0100 Subject: [PATCH 0461/1962] [java] Exclude removed String Template classes from japicmp --- pmd-java/pom.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 90fc3064313..2817db55775 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -138,6 +138,13 @@ net.sourceforge.pmd.lang.java.symbols.table.internal net.sourceforge.pmd.lang.java.types.internal net.sourceforge.pmd.lang.java.types.ast.internal + + net.sourceforge.pmd.lang.java.ast.JavaVisitor#visit(net.sourceforge.pmd.lang.java.ast.ASTTemplate,java.lang.Object) + net.sourceforge.pmd.lang.java.ast.JavaVisitor#visit(net.sourceforge.pmd.lang.java.ast.ASTTemplateExpression,java.lang.Object) + net.sourceforge.pmd.lang.java.ast.JavaVisitor#visit(net.sourceforge.pmd.lang.java.ast.ASTTemplateFragment,java.lang.Object) From 06d68104040add6c032c16a4a6d9bef868ebc44a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 23 Jan 2025 19:11:19 +0100 Subject: [PATCH 0462/1962] Allow to build with Java 24 --- .../java/net/sourceforge/pmd/cli/PmdCli.java | 11 ++++++++--- .../net/sourceforge/pmd/cli/BaseCliTest.java | 18 +++++++++--------- pom.xml | 11 ----------- 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/PmdCli.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/PmdCli.java index 3e630bd9dca..a31326f4fc1 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/PmdCli.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/PmdCli.java @@ -12,7 +12,8 @@ public final class PmdCli { private PmdCli() { } - public static void main(String[] args) { + // package private for test only without calling System.exit + static int mainWithoutExit(String[] args) { // See https://github.com/remkop/picocli/blob/main/RELEASE-NOTES.md#-picocli-470 // and https://picocli.info/#_closures_in_annotations // we don't use this feature. Disabling it avoids leaving the groovy jar open @@ -20,7 +21,11 @@ public static void main(String[] args) { System.setProperty("picocli.disable.closures", "true"); final CommandLine cli = new CommandLine(new PmdRootCommand()) .setCaseInsensitiveEnumValuesAllowed(true); - - System.exit(cli.execute(args)); + + return cli.execute(args); + } + + public static void main(String[] args) { + System.exit(mainWithoutExit(args)); } } diff --git a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/BaseCliTest.java b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/BaseCliTest.java index c19230a94fc..c8deed0a7a3 100644 --- a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/BaseCliTest.java +++ b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/BaseCliTest.java @@ -13,6 +13,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.concurrent.atomic.AtomicReference; import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; @@ -55,26 +56,25 @@ protected CliExecutionResult runCli(CliExitCode expectedExitCode, String... args final PrintStream formerOut = System.out; final PrintStream formerErr = System.err; - CliExitCode exitCode; + final AtomicReference exitCode = new AtomicReference<>(); try { System.out.println("running: pmd " + String.join(" ", argList)); System.setOut(new PrintStream(out)); System.setErr(new PrintStream(err)); - int actualExitCode = SystemLambda.catchSystemExit( - // restoring system properties: --debug might change logging properties - () -> SystemLambda.restoreSystemProperties( - () -> PmdCli.main(argList.toArray(new String[0])) - ) + // restoring system properties: --debug might change logging properties + SystemLambda.restoreSystemProperties( + () -> { + int actualExitCode = PmdCli.mainWithoutExit(argList.toArray(new String[0])); + exitCode.set(CliExitCode.fromInt(actualExitCode)); + } ); - exitCode = CliExitCode.fromInt(actualExitCode); - } finally { System.setOut(formerOut); System.setErr(formerErr); } return new CliExecutionResult( - out, err, exitCode + out, err, exitCode.get() ).verify(e -> assertEquals(expectedExitCode, e.exitCode)); } diff --git a/pom.xml b/pom.xml index 9f631468e91..8af0ca9f8b1 100644 --- a/pom.xml +++ b/pom.xml @@ -1182,17 +1182,6 @@ - - Java 18+ - - [18,) - - - - -Djava.security.manager=allow - - - pmd-release From fe2720dd9b623bc9eeb2abee775cc3b228fb232e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 24 Jan 2025 18:11:52 +0100 Subject: [PATCH 0463/1962] Bump build-tools to 29 --- .github/workflows/build.yml | 2 +- .github/workflows/git-repo-sync.yml | 2 +- .github/workflows/troubleshooting.yml | 2 +- pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1a223b5d894..2c8dd8adf69 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -59,7 +59,7 @@ jobs: run: | echo "LANG=en_US.UTF-8" >> $GITHUB_ENV echo "MAVEN_OPTS=-Daether.connector.http.connectionMaxTtl=180 -DautoReleaseAfterClose=true -DstagingProgressTimeoutMinutes=30" >> $GITHUB_ENV - echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/main/scripts" >> $GITHUB_ENV + echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/29/scripts" >> $GITHUB_ENV - name: Check Environment shell: bash run: | diff --git a/.github/workflows/git-repo-sync.yml b/.github/workflows/git-repo-sync.yml index 85bf40bbe13..3db1780f6d7 100644 --- a/.github/workflows/git-repo-sync.yml +++ b/.github/workflows/git-repo-sync.yml @@ -23,7 +23,7 @@ jobs: shell: bash run: | echo "LANG=en_US.UTF-8" >> $GITHUB_ENV - echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/28/scripts" >> $GITHUB_ENV + echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/29/scripts" >> $GITHUB_ENV - name: Sync run: .ci/git-repo-sync.sh shell: bash diff --git a/.github/workflows/troubleshooting.yml b/.github/workflows/troubleshooting.yml index 841da066910..20d76e0832c 100644 --- a/.github/workflows/troubleshooting.yml +++ b/.github/workflows/troubleshooting.yml @@ -36,7 +36,7 @@ jobs: run: | echo "LANG=en_US.UTF-8" >> $GITHUB_ENV echo "MAVEN_OPTS=-Daether.connector.http.connectionMaxTtl=180 -DstagingProgressTimeoutMinutes=30" >> $GITHUB_ENV - echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/28/scripts" >> $GITHUB_ENV + echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/29/scripts" >> $GITHUB_ENV - name: Check Environment shell: bash run: | diff --git a/pom.xml b/pom.xml index 50d9949affd..5d4629299e2 100644 --- a/pom.xml +++ b/pom.xml @@ -115,7 +115,7 @@ -Xmx512m -Dfile.encoding=${project.build.sourceEncoding} ${extraArgLine} - 29-SNAPSHOT + 29 7.2.0 From e17a87f6b3cc43f9d3c20fb8a2e6e2ff8719729e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 24 Jan 2025 18:15:27 +0100 Subject: [PATCH 0464/1962] [doc] Update release notes --- docs/pages/release_notes.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 6dc55dc7975..fa2d139137b 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,6 +25,12 @@ safe to use anymore. While the key itself is not compromised as far as we know, new key, just to be safe. As until now (January 2025) we are not aware, that the key actually has been misused. The previous releases of PMD in Maven Central can still be considered untampered, as Maven Central is read-only. +This unexpected issue was discovered while checking [Reproducible Builds](https://reproducible-builds.org/) by a +third party. + +The compromised passphrase is tracked as [GHSA-88m4-h43f-wx84](https://github.com/pmd/pmd/security/advisories/GHSA-88m4-h43f-wx84) +and [CVE-2025-23215](https://www.cve.org/CVERecord?id=CVE-2025-23215). + ### ๐Ÿ› Fixed Issues ### ๐Ÿšจ API Changes From 965626c0dd58794b9237c0cfb4d89dd2c8714cfa Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 24 Jan 2025 19:03:58 +0100 Subject: [PATCH 0465/1962] Bump pmd-designer from 7.2.0 to 7.10.0 --- docs/pages/release_notes.md | 7 ++++++- pom.xml | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 6ce070d180c..9f96a9d48d9 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -14,7 +14,7 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy -### New GPG Release Signing Key +#### New GPG Release Signing Key Since January 2025, we switched the GPG Key we use for signing releases in Maven Central to be [A0B5CA1A4E086838](https://keyserver.ubuntu.com/pks/lookup?search=0x2EFA55D0785C31F956F2F87EA0B5CA1A4E086838&fingerprint=on&op=index). @@ -31,6 +31,11 @@ third party. The compromised passphrase is tracked as [GHSA-88m4-h43f-wx84](https://github.com/pmd/pmd/security/advisories/GHSA-88m4-h43f-wx84) and [CVE-2025-23215](https://www.cve.org/CVERecord?id=CVE-2025-23215). +#### Updated PMD Designer + +This PMD release ships a new version of the pmd-designer. +For the changes, see [PMD Designer Changelog (7.10.0)](https://github.com/pmd/pmd-designer/releases/tag/7.10.0). + ### ๐Ÿ› Fixed Issues * apex * [#5388](https://github.com/pmd/pmd/issues/5388): \[apex] Parse error with time literal in SOQL query diff --git a/pom.xml b/pom.xml index ef14a2431bd..f23c89c790b 100644 --- a/pom.xml +++ b/pom.xml @@ -117,7 +117,7 @@ 29 - 7.2.0 + 7.10.0 ${project.build.directory}/generated-sources/javacc ${project.basedir}/../javacc-wrapper.xml From c11ed240a576bc35c3be79e0fc81170a18f69f27 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 24 Jan 2025 19:06:57 +0100 Subject: [PATCH 0466/1962] [doc] Fix sidebar --- docs/_data/sidebars/pmd_sidebar.yml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/_data/sidebars/pmd_sidebar.yml b/docs/_data/sidebars/pmd_sidebar.yml index de61d56db1c..28f24d9ec96 100644 --- a/docs/_data/sidebars/pmd_sidebar.yml +++ b/docs/_data/sidebars/pmd_sidebar.yml @@ -526,21 +526,21 @@ entries: - title: null output: web, pdf subfolders: + - title: Contributing + output: web, pdf + subfolderitems: - title: Contributing + url: /pmd_devdocs_contributing.html + output: web, pdf + - title: Developer resources + url: /pmd_devdocs_development.html + output: web, pdf + - title: Newcomers' Guide + url: /pmd_devdocs_contributing_newcomers_guide.html + output: web, pdf + - title: Writing documentation + url: /pmd_devdocs_writing_documentation.html output: web, pdf - subfolderitems: - - title: Contributing - url: /pmd_devdocs_contributing.html - output: web, pdf - - title: Developer resources - url: /pmd_devdocs_development.html - output: web, pdf - - title: Newcomers' Guide - url: /pmd_devdocs_contributing_newcomers_guide.html - output: web, pdf - - title: Writing documentation - url: /pmd_devdocs_writing_documentation.html - output: web, pdf - title: null output: web, pdf subfolders: From b02ff4b72163361b18355ac58bc540438b91b082 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 24 Jan 2025 19:14:13 +0100 Subject: [PATCH 0467/1962] [java] Update rule doc for ExhaustiveSwitchHasDefault --- pmd-java/src/main/resources/category/java/bestpractices.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 4fad8b47b0e..7c65d05f4ce 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -543,18 +543,20 @@ return a; When switching over an enum or sealed class, the compiler will ensure that all possible cases are covered. -If a case is missed, this will result in a compilation error. But if a default case is added, this compiler +If a case is missing, this will result in a compilation error. But if a default case is added, this compiler check is not performed anymore, leading to difficulties in noticing bugs at runtime. Not using a default case makes sure, a compiler error is introduced whenever a new enum constant or a new subclass to the sealed class hierarchy is added. We will discover this problem at compile time rather than at runtime (if at all). + +Note: The fix it not necessarily just removing the default case. Maybe a case is missing which needs to be implemented. 3 From 1efe2523f93267f5220722453ab0900ca72f6630 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 24 Jan 2025 19:19:29 +0100 Subject: [PATCH 0468/1962] [ci] Provide missing GPG Key for git-repo-sync.yml --- .github/workflows/git-repo-sync.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/git-repo-sync.yml b/.github/workflows/git-repo-sync.yml index 3db1780f6d7..6117c05e60f 100644 --- a/.github/workflows/git-repo-sync.yml +++ b/.github/workflows/git-repo-sync.yml @@ -30,3 +30,4 @@ jobs: env: PMD_CI_SECRET_PASSPHRASE: ${{ secrets.PMD_CI_SECRET_PASSPHRASE }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PMD_CI_GPG_PRIVATE_KEY: ${{ secrets.PMD_CI_GPG_PRIVATE_KEY }} From 2830e1af7a0813dea5836964b1b9a9e2eca2e579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Fri, 24 Jan 2025 21:06:34 -0300 Subject: [PATCH 0469/1962] Test dialect promises --- .../SimpleDialectLanguageModuleBaseTest.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java new file mode 100644 index 00000000000..9cf59625628 --- /dev/null +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java @@ -0,0 +1,35 @@ +package net.sourceforge.pmd.lang.impl; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import net.sourceforge.pmd.lang.DummyLanguageDialectModule; +import net.sourceforge.pmd.lang.DummyLanguageModule; +import net.sourceforge.pmd.lang.LanguageProcessor; +import net.sourceforge.pmd.lang.rule.xpath.impl.XPathFunctionDefinition; + +class SimpleDialectLanguageModuleBaseTest { + + @Test + void baseLanguageXPathFunctionAvailable() throws Exception { + DummyLanguageModule lang = DummyLanguageModule.getInstance(); + DummyLanguageDialectModule dialect = DummyLanguageDialectModule.getInstance(); + + try (LanguageProcessor baseProcessor = lang.createProcessor(lang.newPropertyBundle()); + LanguageProcessor dialectProcessor = dialect.createProcessor(dialect.newPropertyBundle())) { + + Set dialectFunctions = dialectProcessor.services().getXPathHandler().getRegisteredExtensionFunctions(); + for (XPathFunctionDefinition fn : baseProcessor.services().getXPathHandler().getRegisteredExtensionFunctions()) { + assertTrue(dialectFunctions.contains(fn), "The function " + fn.getQName() + " is not available in the dialect."); + } + } + } + + @Test + void dialectSpecificXPathFunctionAvailable() throws Exception { + // TODO + } +} From 282c4622c5108454cb046b84de7f482365494014 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 25 Jan 2025 16:56:17 +0100 Subject: [PATCH 0470/1962] [scala] Bump scalameta.version from 4.9.1 to 4.12.7 - Bump scala-library 2.12 from 2.12.19 to 2.12.20 - Bump scala-library 2.13 from 2.13.13 to 2.13.16 New AST types: ASTPkgBody, ASTTemplateBody, ASTTermCasesBlock Note: The update of scalameta potentially changes the parsed AST in an incompatible way. --- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- .../pmd/lang/scala/ast/ASTPkgBody.java | 23 + .../pmd/lang/scala/ast/ASTTemplateBody.java | 23 + .../pmd/lang/scala/ast/ASTTermCasesBlock.java | 23 + .../pmd/lang/scala/ast/ScalaTreeBuilder.java | 3 + .../pmd/lang/scala/ast/ScalaVisitor.java | 24 + .../pmd/lang/scala/cpd/ScalaCpdLexer.java | 3 +- .../pmd/lang/scala/cpd/ScalaCpdLexerTest.java | 9 +- .../pmd/lang/scala/rule/ScalaRuleTest.java | 2 +- .../pmd/lang/scala/ast/ScalaTreeTests.kt | 32 +- .../pmd/lang/scala/ast/testdata/List.txt | 3842 ++++++++--------- .../pmd/lang/scala/ast/testdata/package.txt | 202 +- ...le_sample.scala => unclosed_literal.scala} | 0 .../scala/cpd/testdata/unclosed_literal.txt | 29 + pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- 16 files changed, 2171 insertions(+), 2050 deletions(-) create mode 100644 pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ASTPkgBody.java create mode 100644 pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ASTTemplateBody.java create mode 100644 pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ASTTermCasesBlock.java rename pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/cpd/testdata/{unlexable_sample.scala => unclosed_literal.scala} (100%) create mode 100644 pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/cpd/testdata/unclosed_literal.txt diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index 529841b9118..414b66afae3 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -13,7 +13,7 @@ - 4.9.1 + 4.12.7 diff --git a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ASTPkgBody.java b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ASTPkgBody.java new file mode 100644 index 00000000000..e5cd2507d37 --- /dev/null +++ b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ASTPkgBody.java @@ -0,0 +1,23 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.scala.ast; + +import scala.meta.Pkg; + +/** + * The ASTPkgBody node implementation. + * @since 7.10.0 + */ +public final class ASTPkgBody extends AbstractScalaNode { + + ASTPkgBody(Pkg.Body scalaNode) { + super(scalaNode); + } + + @Override + protected R acceptVisitor(ScalaVisitor visitor, P data) { + return visitor.visit(this, data); + } +} diff --git a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ASTTemplateBody.java b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ASTTemplateBody.java new file mode 100644 index 00000000000..16b6540f999 --- /dev/null +++ b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ASTTemplateBody.java @@ -0,0 +1,23 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.scala.ast; + +import scala.meta.Template; + +/** + * The ASTTemplateBody node implementation. + * @since 7.10.0 + */ +public final class ASTTemplateBody extends AbstractScalaNode { + + ASTTemplateBody(Template.Body scalaNode) { + super(scalaNode); + } + + @Override + protected R acceptVisitor(ScalaVisitor visitor, P data) { + return visitor.visit(this, data); + } +} diff --git a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ASTTermCasesBlock.java b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ASTTermCasesBlock.java new file mode 100644 index 00000000000..449e66937fe --- /dev/null +++ b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ASTTermCasesBlock.java @@ -0,0 +1,23 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.scala.ast; + +import scala.meta.Term; + +/** + * The ASTTermCasesBlock node implementation. + * @since 7.10.0 + */ +public final class ASTTermCasesBlock extends AbstractScalaNode { + + ASTTermCasesBlock(Term.CasesBlock scalaNode) { + super(scalaNode); + } + + @Override + protected R acceptVisitor(ScalaVisitor visitor, P data) { + return visitor.visit(this, data); + } +} diff --git a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ScalaTreeBuilder.java b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ScalaTreeBuilder.java index 3c8c96c7c15..afd9a503908 100644 --- a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ScalaTreeBuilder.java +++ b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ScalaTreeBuilder.java @@ -111,11 +111,13 @@ class ScalaTreeBuilder { register(Pat.Wildcard.class, ASTPatWildcard.class); register(Pat.Xml.class, ASTPatXml.class); register(Pkg.class, ASTPkg.class); + register(Pkg.Body.class, ASTPkgBody.class); register(Pkg.Object.class, ASTPkgObject.class); register(Quasi.class, ASTQuasi.class); register(Self.class, ASTSelf.class); register(Source.class, ASTSource.class); register(Template.class, ASTTemplate.class); + register(Template.Body.class, ASTTemplateBody.class); register(Term.Annotate.class, ASTTermAnnotate.class); register(Term.Apply.class, ASTTermApply.class); register(Term.ApplyInfix.class, ASTTermApplyInfix.class); @@ -125,6 +127,7 @@ class ScalaTreeBuilder { register(Term.Ascribe.class, ASTTermAscribe.class); register(Term.Assign.class, ASTTermAssign.class); register(Term.Block.class, ASTTermBlock.class); + register(Term.CasesBlock.class, ASTTermCasesBlock.class); register(Term.Do.class, ASTTermDo.class); register(Term.Eta.class, ASTTermEta.class); register(Term.For.class, ASTTermFor.class); diff --git a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ScalaVisitor.java b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ScalaVisitor.java index caa761f5799..e9bf6119e6f 100644 --- a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ScalaVisitor.java +++ b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ScalaVisitor.java @@ -370,6 +370,14 @@ default R visit(ASTPkg node, D data) { } + /** + * @since 7.10.0 + */ + default R visit(ASTPkgBody node, D data) { + return visit((ScalaNode) node, data); + } + + default R visit(ASTPkgObject node, D data) { return visit((ScalaNode) node, data); } @@ -390,6 +398,14 @@ default R visit(ASTTemplate node, D data) { } + /** + * @since 7.10.0 + */ + default R visit(ASTTemplateBody node, D data) { + return visit((ScalaNode) node, data); + } + + default R visit(ASTTermAnnotate node, D data) { return visit((ScalaNode) node, data); } @@ -430,6 +446,14 @@ default R visit(ASTTermBlock node, D data) { } + /** + * @since 7.10.0 + */ + default R visit(ASTTermCasesBlock node, D data) { + return visit((ScalaNode) node, data); + } + + default R visit(ASTTermDo node, D data) { return visit((ScalaNode) node, data); } diff --git a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/cpd/ScalaCpdLexer.java b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/cpd/ScalaCpdLexer.java index 5e4ea36e4d1..74020fd07da 100644 --- a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/cpd/ScalaCpdLexer.java +++ b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/cpd/ScalaCpdLexer.java @@ -21,6 +21,7 @@ import scala.meta.inputs.Position; import scala.meta.internal.tokenizers.ScalametaTokenizer; import scala.meta.tokenizers.TokenizeException; +import scala.meta.tokenizers.TokenizerOptions; import scala.meta.tokens.Token; /** @@ -49,7 +50,7 @@ public void tokenize(TextDocument document, TokenFactory tokenEntries) { // create the input file for scala Input.VirtualFile vf = new Input.VirtualFile(document.getFileId().getOriginalPath(), fullCode); - ScalametaTokenizer tokenizer = new ScalametaTokenizer(vf, dialect); + ScalametaTokenizer tokenizer = new ScalametaTokenizer(vf, dialect, TokenizerOptions.implicitTokenizerOptions()); // tokenize with a filter scala.meta.tokens.Tokens tokens = tokenizer.tokenize(); diff --git a/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/cpd/ScalaCpdLexerTest.java b/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/cpd/ScalaCpdLexerTest.java index 57056e63557..0237f14a9ac 100644 --- a/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/cpd/ScalaCpdLexerTest.java +++ b/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/cpd/ScalaCpdLexerTest.java @@ -4,11 +4,8 @@ package net.sourceforge.pmd.lang.scala.cpd; -import static org.junit.jupiter.api.Assertions.assertThrows; - import org.junit.jupiter.api.Test; -import net.sourceforge.pmd.lang.ast.LexException; import net.sourceforge.pmd.lang.scala.ScalaLanguageModule; import net.sourceforge.pmd.lang.test.cpd.CpdTextComparisonTest; @@ -29,8 +26,10 @@ void testSuppressionComments() { } @Test - void tokenizeFailTest() { - assertThrows(LexException.class, () -> doTest("unlexable_sample")); + void unclosedLiteral() { + // note: this failed before PMD 7.10.0 with a LexException, but now the string literal is just + // expanded to the end of the line + doTest("unclosed_literal"); } @Test diff --git a/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/rule/ScalaRuleTest.java b/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/rule/ScalaRuleTest.java index 9e53b6ddcd4..a9b91ea6067 100644 --- a/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/rule/ScalaRuleTest.java +++ b/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/rule/ScalaRuleTest.java @@ -35,7 +35,7 @@ public RuleContext visit(ScalaNode node, RuleContext data) { }; ASTSource root = scala.parseResource(SCALA_TEST); rule.apply(root, null); - assertEquals(13, visited.get()); + assertEquals(12, visited.get()); } @Test diff --git a/pmd-scala-modules/pmd-scala-common/src/test/kotlin/net/sourceforge/pmd/lang/scala/ast/ScalaTreeTests.kt b/pmd-scala-modules/pmd-scala-common/src/test/kotlin/net/sourceforge/pmd/lang/scala/ast/ScalaTreeTests.kt index e20c118917a..7b4f678fe88 100644 --- a/pmd-scala-modules/pmd-scala-common/src/test/kotlin/net/sourceforge/pmd/lang/scala/ast/ScalaTreeTests.kt +++ b/pmd-scala-modules/pmd-scala-common/src/test/kotlin/net/sourceforge/pmd/lang/scala/ast/ScalaTreeTests.kt @@ -49,32 +49,28 @@ class Foo { it.assertPosition(bline = 1, bcol = 11, eline = 3, ecol = 2) it::isImplicit shouldBe false - child { - it.assertPosition(bline = 2, bcol = 2, eline = 2, ecol = 2) // node has zero length - it::isImplicit shouldBe true - - child { - it.assertPosition(bline = 2, bcol = 2, eline = 2, ecol = 2) // node has zero length - it::isImplicit shouldBe true - } - } - - child { - it.assertPosition(bline = 2, bcol = 2, eline = 2, ecol = 12) + child { + it.assertPosition(bline = 1, bcol = 11, eline = 3, ecol = 2) it::isImplicit shouldBe false - child { - it.assertPosition(bline = 2, bcol = 6, eline = 2, ecol = 7) + child { + it.assertPosition(bline = 2, bcol = 2, eline = 2, ecol = 12) it::isImplicit shouldBe false - child { + child { it.assertPosition(bline = 2, bcol = 6, eline = 2, ecol = 7) it::isImplicit shouldBe false + + child { + it.assertPosition(bline = 2, bcol = 6, eline = 2, ecol = 7) + it::isImplicit shouldBe false + } } - } - child { - it.assertPosition(bline = 2, bcol = 10, eline = 2, ecol = 12) + child { + it.assertPosition(bline = 2, bcol = 10, eline = 2, ecol = 12) + it::getValue shouldBe "" + } } } } diff --git a/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/ast/testdata/List.txt b/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/ast/testdata/List.txt index 7512ade684d..8ebc51cb02b 100644 --- a/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/ast/testdata/List.txt +++ b/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/ast/testdata/List.txt @@ -1,1935 +1,1935 @@ +- Source +- Pkg +- TermName - +- Pkg - +- TermName + +- PkgBody +- Pkg +- TermName - +- Import - | +- Importer - | +- TermSelect - | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermName - | +- ImporteeName - | +- NameIndeterminate - +- Import - | +- Importer - | +- TermSelect - | | +- TermName - | | +- TermName - | +- ImporteeName - | +- NameIndeterminate - +- Import - | +- Importer - | +- TermName - | +- ImporteeName - | | +- NameIndeterminate - | +- ImporteeName - | +- NameIndeterminate - +- Import - | +- Importer - | +- TermSelect - | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermName - | +- ImporteeName - | +- NameIndeterminate - +- Import - | +- Importer - | +- TermSelect - | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermName - | +- ImporteeName - | +- NameIndeterminate - +- DefnClass - | +- ModAnnot - | | +- Init - | | +- TypeName - | | +- NameAnonymous - | | +- TermArgClause - | | +- LitLong - | +- ModSealed - | +- ModAbstract - | +- TypeName - | +- TypeParamClause - | | +- TypeParam - | | +- ModCovariant - | | +- TypeName - | | +- TypeParamClause - | | +- TypeBounds - | +- CtorPrimary - | | +- NameAnonymous - | +- Template - | +- Init - | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- NameAnonymous - | +- Init - | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- NameAnonymous - | +- Init - | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | | +- TypeName - | | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- NameAnonymous - | +- Init - | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | | +- TypeName - | | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- NameAnonymous - | +- Init - | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | | +- TypeName - | | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- NameAnonymous - | +- Init - | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | | +- TypeName - | | +- NameAnonymous - | +- Init - | | +- TypeName - | | +- NameAnonymous - | +- Self - | | +- NameAnonymous - | +- DefnDef - | | +- ModOverride - | | +- TermName - | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- TermName - | +- DefnDef - | | +- ModOverride - | | +- TermName - | | +- MemberParamClauseGroup - | | | +- TypeParamClause - | | | +- TermParamClause - | | | +- TermParam - | | | +- TermName - | | | +- TypeName - | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- TermIf - | | +- TermApplyInfix - | | | +- TermName - | | | +- TermName - | | | +- TypeArgClause - | | | +- TermArgClause - | | | +- TermApplyInfix - | | | +- TermName - | | | +- TermName - | | | +- TypeArgClause - | | | +- TermArgClause - | | | +- LitInt - | | +- TermName - | | +- TermBlock - | | +- DefnVal - | | | +- PatVar - | | | | +- TermName - | | | +- TermNew - | | | +- Init - | | | +- TypeName - | | | +- NameAnonymous - | | | +- TermArgClause - | | | +- TermName - | | | +- TermName - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TermName - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TermName - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- LitInt - | | +- TermWhile - | | | +- TermBlock - | | | | +- TermIf - | | | | | +- TermSelect - | | | | | | +- TermName - | | | | | | +- TermName - | | | | | +- TermReturn - | | | | | | +- TermThis - | | | | | | +- NameAnonymous - | | | | | +- LitUnit - | | | | +- TermApplyInfix - | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- TermName - | | | +- TermBlock - | | | +- TermApplyInfix - | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- LitInt - | | | +- DefnVal - | | | | +- PatVar - | | | | | +- TermName - | | | | +- TermNew - | | | | +- Init - | | | | +- TypeName - | | | | +- NameAnonymous - | | | | +- TermArgClause - | | | | +- TermSelect - | | | | | +- TermName - | | | | | +- TermName - | | | | +- TermName - | | | +- TermAssign - | | | | +- TermSelect - | | | | | +- TermName - | | | | | +- TermName - | | | | +- TermName - | | | +- TermAssign - | | | | +- TermName - | | | | +- TermName - | | | +- TermAssign - | | | +- TermName - | | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermApply - | | | +- TermName - | | | +- TermArgClause - | | +- TermName - | +- DefnDef - | | +- ModOverride - | | +- TermName - | | +- MemberParamClauseGroup - | | | +- TypeParamClause - | | | +- TermParamClause - | | | +- TermParam - | | | | +- TermName - | | | | +- TypeName - | | | +- TermParam - | | | +- TermName - | | | +- TypeName - | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- TermBlock - | | +- DefnVal - | | | +- PatVar - | | | | +- TermName - | | | +- TermApply - | | | +- TermSelect - | | | | +- TermSelect - | | | | | +- TermName - | | | | | +- TermName - | | | | +- TermName - | | | +- TermArgClause - | | | +- TermName - | | | +- LitInt - | | +- TermIf - | | +- TermApplyInfix - | | | +- TermApplyInfix - | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- TermName - | | | +- TermName - | | | +- TypeArgClause - | | | +- TermArgClause - | | | +- TermName - | | +- TermName - | | +- TermApplyInfix - | | +- TermApplyInfix - | | | +- TermThis - | | | | +- NameAnonymous - | | | +- TermName - | | | +- TypeArgClause - | | | +- TermArgClause - | | | +- TermName - | | +- TermName - | | +- TypeArgClause - | | +- TermArgClause - | | +- TermApplyInfix - | | +- TermName - | | +- TermName - | | +- TypeArgClause - | | +- TermArgClause - | | +- TermName - | +- DefnDef - | | +- ModOverride - | | +- TermName - | | +- MemberParamClauseGroup - | | | +- TypeParamClause - | | | +- TermParamClause - | | | +- TermParam - | | | +- TermName - | | | +- TypeName - | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- TermBlock - | | +- DefnDef - | | | +- ModAnnot - | | | | +- Init - | | | | +- TypeName - | | | | +- NameAnonymous - | | | +- TermName - | | | +- MemberParamClauseGroup - | | | | +- TypeParamClause - | | | | +- TermParamClause - | | | | +- TermParam - | | | | | +- TermName - | | | | | +- TypeApply - | | | | | +- TypeName - | | | | | +- TypeArgClause - | | | | | +- TypeName - | | | | +- TermParam - | | | | +- TermName - | | | | +- TypeApply - | | | | +- TypeName - | | | | +- TypeArgClause - | | | | +- TypeName - | | | +- TypeApply - | | | | +- TypeName - | | | | +- TypeArgClause - | | | | +- TypeName - | | | +- TermMatch - | | | +- TermName - | | | +- Case - | | | | +- TermName - | | | | +- TermName - | | | +- Case - | | | +- PatExtractInfix - | | | | +- PatWildcard - | | | | +- TermName - | | | | +- PatArgClause - | | | | +- PatVar - | | | | +- TermName - | | | +- TermApply - | | | +- TermName - | | | +- TermArgClause - | | | +- TermName - | | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermApply - | | +- TermName - | | +- TermArgClause - | | +- TermApply - | | | +- TermName - | | | +- TermArgClause - | | | +- TermName - | | +- TermThis - | | +- NameAnonymous - | +- DefnDef - | | +- ModOverride - | | +- TermName - | | +- MemberParamClauseGroup - | | | +- TypeParamClause - | | | +- TermParamClause - | | | +- TermParam - | | | +- TermName - | | | +- TypeName - | | +- TypeTuple - | | | +- TypeApply - | | | | +- TypeName - | | | | +- TypeArgClause - | | | | +- TypeName - | | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- TermBlock - | | +- DefnVal - | | | +- PatVar - | | | | +- TermName - | | | +- TermNew - | | | +- Init - | | | +- TypeApply - | | | | +- TypeName - | | | | +- TypeArgClause - | | | | +- TypeName - | | | +- NameAnonymous - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- LitInt - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TermThis - | | | +- NameAnonymous - | | +- TermWhile - | | | +- TermApplyInfix - | | | | +- TermApplyUnary - | | | | | +- TermName - | | | | | +- TermSelect - | | | | | +- TermName - | | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- TermApplyInfix - | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- TermName - | | | +- TermBlock - | | | +- TermApplyInfix - | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- LitInt - | | | +- TermApplyInfix - | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- TermSelect - | | | | +- TermName - | | | | +- TermName - | | | +- TermAssign - | | | +- TermName - | | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermTuple - | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermName - | +- DefnDef - | | +- ModOverride - | | +- TermName - | | +- MemberParamClauseGroup - | | | +- TypeParamClause - | | | | +- TypeParam - | | | | +- TypeName - | | | | +- TypeParamClause - | | | | +- TypeBounds - | | | | +- TypeName - | | | +- TermParamClause - | | | +- TermParam - | | | | +- TermName - | | | | +- TypeName - | | | +- TermParam - | | | +- TermName - | | | +- TypeName - | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- TermBlock - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- LitInt - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TermThis - | | | +- NameAnonymous - | | +- DefnVal - | | | +- PatVar - | | | | +- TermName - | | | +- TermApplyType - | | | +- TermSelect - | | | | +- TermName - | | | | +- TermName - | | | +- TypeArgClause - | | | +- TypeName - | | +- TermWhile - | | | +- TermApplyInfix - | | | | +- TermApplyInfix - | | | | | +- TermName - | | | | | +- TermName - | | | | | +- TypeArgClause - | | | | | +- TermArgClause - | | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- TermSelect - | | | | +- TermName - | | | | +- TermName - | | | +- TermBlock - | | | +- TermApplyInfix - | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- LitInt - | | | +- TermApplyInfix - | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- TermSelect - | | | | +- TermName - | | | | +- TermName - | | | +- TermAssign - | | | +- TermName - | | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermIf - | | +- TermApplyInfix - | | | +- TermApplyInfix - | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- TermName - | | | +- TermName - | | | +- TypeArgClause - | | | +- TermArgClause - | | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermBlock - | | | +- TermApply - | | | +- TermSelect - | | | | +- TermName - | | | | +- TermName - | | | +- TermArgClause - | | | +- TermApplyInfix - | | | +- TermName - | | | +- TermName - | | | +- TypeArgClause - | | | +- TermArgClause - | | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermBlock - | | +- TermThrow - | | +- TermNew - | | +- Init - | | +- TypeName - | | +- NameAnonymous - | | +- TermArgClause - | | +- TermInterpolate - | | +- TermName - | | +- LitString - | | +- LitString - | | +- LitString - | | +- TermName - | | +- TermBlock - | | +- TermApplyInfix - | | +- TermName - | | +- TermName - | | +- TypeArgClause - | | +- TermArgClause - | | +- TermApplyInfix - | | +- TermName - | | +- TermName - | | +- TypeArgClause - | | +- TermArgClause - | | +- LitInt - | +- DefnDef - | | +- ModFinal - | | +- ModOverride - | | +- TermName - | | +- MemberParamClauseGroup - | | | +- TypeParamClause - | | | | +- TypeParam - | | | | +- TypeName - | | | | +- TypeParamClause - | | | | +- TypeBounds - | | | +- TermParamClause - | | | +- TermParam - | | | +- TermName - | | | +- TypeFunction - | | | +- TypeFuncParamClause - | | | | +- TypeName - | | | +- TypeName - | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- TermBlock - | | +- TermIf - | | +- TermApplyInfix - | | | +- TermThis - | | | | +- NameAnonymous - | | | +- TermName - | | | +- TypeArgClause - | | | +- TermArgClause - | | | +- TermName - | | +- TermName - | | +- TermBlock - | | +- DefnVal - | | | +- PatVar - | | | | +- TermName - | | | +- TermNew - | | | +- Init - | | | +- TypeApply - | | | | +- TypeName - | | | | +- TypeArgClause - | | | | +- TypeName - | | | +- NameAnonymous - | | | +- TermArgClause - | | | +- TermApply - | | | | +- TermName - | | | | +- TermArgClause - | | | | +- TermName - | | | +- TermName - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TypeApply - | | | | +- TypeName - | | | | +- TypeArgClause - | | | | +- TypeName - | | | +- TermName - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TermName - | | +- TermWhile - | | | +- TermApplyInfix - | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- TermName - | | | +- TermBlock - | | | +- DefnVal - | | | | +- PatVar - | | | | | +- TermName - | | | | +- TermNew - | | | | +- Init - | | | | +- TypeName - | | | | +- NameAnonymous - | | | | +- TermArgClause - | | | | +- TermApply - | | | | | +- TermName - | | | | | +- TermArgClause - | | | | | +- TermSelect - | | | | | +- TermName - | | | | | +- TermName - | | | | +- TermName - | | | +- TermAssign - | | | | +- TermSelect - | | | | | +- TermName - | | | | | +- TermName - | | | | +- TermName - | | | +- TermAssign - | | | | +- TermName - | | | | +- TermName - | | | +- TermAssign - | | | +- TermName - | | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermApply - | | | +- TermName - | | | +- TermArgClause - | | +- TermName - | +- DefnDef - | | +- ModFinal - | | +- ModOverride - | | +- TermName - | | +- MemberParamClauseGroup - | | | +- TypeParamClause - | | | | +- TypeParam - | | | | +- TypeName - | | | | +- TypeParamClause - | | | | +- TypeBounds - | | | +- TermParamClause - | | | +- TermParam - | | | +- TermName - | | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | | +- TypeName - | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- TermBlock - | | +- TermIf - | | +- TermApplyInfix - | | | +- TermThis - | | | | +- NameAnonymous - | | | +- TermName - | | | +- TypeArgClause - | | | +- TermArgClause - | | | +- TermName - | | +- TermName - | | +- TermBlock - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TermThis - | | | +- NameAnonymous - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TypeApply - | | | | +- TypeName - | | | | +- TypeArgClause - | | | | +- TypeName - | | | +- LitNull - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TypeName - | | | +- LitNull - | | +- TermWhile - | | | +- TermApplyInfix - | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- LitNull - | | | +- TermBlock - | | | +- TermAssign - | | | | +- TermName - | | | | +- TermApply - | | | | +- TermSelect - | | | | | +- TermName - | | | | | +- TermName - | | | | +- TermArgClause - | | | | +- TermSelect - | | | | | +- TermName - | | | | | +- TermName - | | | | +- TermSelect - | | | | +- TermName - | | | | +- TermName - | | | +- TermIf - | | | | +- TermApplyInfix - | | | | | +- TermApplyType - | | | | | | +- TermSelect - | | | | | | | +- TermName - | | | | | | | +- TermName - | | | | | | +- TypeArgClause - | | | | | | +- TypeName - | | | | | +- TermName - | | | | | +- TypeArgClause - | | | | | +- TermArgClause - | | | | | +- TermSelect - | | | | | +- TermName - | | | | | +- TermName - | | | | +- TermAssign - | | | | | +- TermName - | | | | | +- TermNew - | | | | | +- Init - | | | | | +- TypeName - | | | | | +- NameAnonymous - | | | | | +- TermArgClause - | | | | | +- TermApplyType - | | | | | | +- TermSelect - | | | | | | | +- TermName - | | | | | | | +- TermName - | | | | | | +- TypeArgClause - | | | | | | +- TypeName - | | | | | +- TermName - | | | | +- LitUnit - | | | +- TermAssign - | | | | +- TermName - | | | | +- TermSelect - | | | | +- TermName - | | | | +- TermName - | | | +- TermIf - | | | +- TermApplyInfix - | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- TermName - | | | +- TermReturn - | | | | +- TermIf - | | | | +- TermApplyInfix - | | | | | +- TermName - | | | | | +- TermName - | | | | | +- TypeArgClause - | | | | | +- TermArgClause - | | | | | +- LitNull - | | | | +- TermName - | | | | +- TermName - | | | +- LitUnit - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TermName - | | +- TermWhile - | | | +- TermApplyInfix - | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- TermName - | | | +- TermBlock - | | | +- TermAssign - | | | | +- TermName - | | | | +- TermApply - | | | | +- TermSelect - | | | | | +- TermName - | | | | | +- TermName - | | | | +- TermArgClause - | | | | +- TermSelect - | | | | | +- TermName - | | | | | +- TermName - | | | | +- TermSelect - | | | | +- TermName - | | | | +- TermName - | | | +- TermIf - | | | | +- TermApplyInfix - | | | | | +- TermApplyType - | | | | | | +- TermSelect - | | | | | | | +- TermName - | | | | | | | +- TermName - | | | | | | +- TypeArgClause - | | | | | | +- TypeName - | | | | | +- TermName - | | | | | +- TypeArgClause - | | | | | +- TermArgClause - | | | | | +- TermSelect - | | | | | +- TermName - | | | | | +- TermName - | | | | +- TermBlock - | | | | | +- DefnVal - | | | | | | +- PatVar - | | | | | | | +- TermName - | | | | | | +- TermNew - | | | | | | +- Init - | | | | | | +- TypeName - | | | | | | +- NameAnonymous - | | | | | | +- TermArgClause - | | | | | | +- TermApplyType - | | | | | | | +- TermSelect - | | | | | | | | +- TermName - | | | | | | | | +- TermName - | | | | | | | +- TypeArgClause - | | | | | | | +- TypeName - | | | | | | +- TermName - | | | | | +- TermAssign - | | | | | | +- TermSelect - | | | | | | | +- TermName - | | | | | | | +- TermName - | | | | | | +- TermName - | | | | | +- TermAssign - | | | | | +- TermName - | | | | | +- TermName - | | | | +- LitUnit - | | | +- TermAssign - | | | +- TermName - | | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermApply - | | | +- TermName - | | | +- TermArgClause - | | +- TermName - | +- DefnDef - | | +- ModFinal - | | +- ModOverride - | | +- TermName - | | +- MemberParamClauseGroup - | | | +- TypeParamClause - | | | | +- TypeParam - | | | | +- TypeName - | | | | +- TypeParamClause - | | | | +- TypeBounds - | | | +- TermParamClause - | | | +- TermParam - | | | +- TermName - | | | +- TypeFunction - | | | +- TypeFuncParamClause - | | | | +- TypeName - | | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- TermBlock - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TermThis - | | | +- NameAnonymous - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TypeApply - | | | | +- TypeName - | | | | +- TypeArgClause - | | | | +- TypeName - | | | +- LitNull - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TypeApply - | | | | +- TypeName - | | | | +- TypeArgClause - | | | | +- TypeName - | | | +- LitNull - | | +- TermWhile - | | | +- TermApplyInfix - | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- TermName - | | | +- TermBlock - | | | +- DefnVal - | | | | +- PatVar - | | | | | +- TermName - | | | | +- TermSelect - | | | | +- TermApply - | | | | | +- TermName - | | | | | +- TermArgClause - | | | | | +- TermSelect - | | | | | +- TermName - | | | | | +- TermName - | | | | +- TermName - | | | +- TermWhile - | | | | +- TermSelect - | | | | | +- TermName - | | | | | +- TermName - | | | | +- TermBlock - | | | | +- DefnVal - | | | | | +- PatVar - | | | | | | +- TermName - | | | | | +- TermNew - | | | | | +- Init - | | | | | +- TypeName - | | | | | +- NameAnonymous - | | | | | +- TermArgClause - | | | | | +- TermApply - | | | | | | +- TermSelect - | | | | | | | +- TermName - | | | | | | | +- TermName - | | | | | | +- TermArgClause - | | | | | +- TermName - | | | | +- TermIf - | | | | | +- TermApplyInfix - | | | | | | +- TermName - | | | | | | +- TermName - | | | | | | +- TypeArgClause - | | | | | | +- TermArgClause - | | | | | | +- LitNull - | | | | | +- TermBlock - | | | | | | +- TermAssign - | | | | | | +- TermName - | | | | | | +- TermName - | | | | | +- TermBlock - | | | | | +- TermAssign - | | | | | +- TermSelect - | | | | | | +- TermName - | | | | | | +- TermName - | | | | | +- TermName - | | | | +- TermAssign - | | | | +- TermName - | | | | +- TermName - | | | +- TermAssign - | | | +- TermName - | | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermIf - | | +- TermApplyInfix - | | | +- TermName - | | | +- TermName - | | | +- TypeArgClause - | | | +- TermArgClause - | | | +- LitNull - | | +- TermName - | | +- TermBlock - | | +- TermApply - | | | +- TermName - | | | +- TermArgClause - | | +- TermName - | +- DefnDef - | | +- ModAnnot - | | | +- Init - | | | +- TypeName - | | | +- NameAnonymous - | | +- ModFinal - | | +- ModOverride - | | +- TermName - | | +- MemberParamClauseGroup - | | | +- TypeParamClause - | | | +- TermParamClause - | | | +- TermParam - | | | +- TermName - | | | +- TypeFunction - | | | +- TypeFuncParamClause - | | | | +- TypeName - | | | +- TypeName - | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- TermBlock - | | +- DefnVal - | | | +- PatVar - | | | | +- TermName - | | | +- TermNew - | | | +- Init - | | | +- TypeApply - | | | | +- TypeName - | | | | +- TypeArgClause - | | | | +- TypeName - | | | +- NameAnonymous - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TermThis - | | | +- NameAnonymous - | | +- TermWhile - | | | +- TermApplyInfix - | | | | +- TermApplyUnary - | | | | | +- TermName - | | | | | +- TermSelect - | | | | | +- TermName - | | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- TermApply - | | | | +- TermName - | | | | +- TermArgClause - | | | | +- TermSelect - | | | | +- TermName - | | | | +- TermName - | | | +- TermBlock - | | | +- TermApplyInfix - | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- TermSelect - | | | | +- TermName - | | | | +- TermName - | | | +- TermAssign - | | | +- TermName - | | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermSelect - | | +- TermName - | | +- TermName - | +- DefnDef - | | +- ModAnnot - | | | +- Init - | | | +- TypeName - | | | +- NameAnonymous - | | +- ModFinal - | | +- ModOverride - | | +- TermName - | | +- MemberParamClauseGroup - | | | +- TypeParamClause - | | | +- TermParamClause - | | | +- TermParam - | | | +- TermName - | | | +- TypeFunction - | | | +- TypeFuncParamClause - | | | | +- TypeName - | | | +- TypeName - | | +- TypeTuple - | | | +- TypeApply - | | | | +- TypeName - | | | | +- TypeArgClause - | | | | +- TypeName - | | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- TermBlock - | | +- DefnVal - | | | +- PatVar - | | | | +- TermName - | | | +- TermNew - | | | +- Init - | | | +- TypeApply - | | | | +- TypeName - | | | | +- TypeArgClause - | | | | +- TypeName - | | | +- NameAnonymous - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TermThis - | | | +- NameAnonymous - | | +- TermWhile - | | | +- TermApplyInfix - | | | | +- TermApplyUnary - | | | | | +- TermName - | | | | | +- TermSelect - | | | | | +- TermName - | | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- TermApply - | | | | +- TermName - | | | | +- TermArgClause - | | | | +- TermSelect - | | | | +- TermName - | | | | +- TermName - | | | +- TermBlock - | | | +- TermApplyInfix - | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- TermSelect - | | | | +- TermName - | | | | +- TermName - | | | +- TermAssign - | | | +- TermName - | | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermTuple - | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermName - | +- DefnDef - | | +- ModAnnot - | | | +- Init - | | | +- TypeName - | | | +- NameAnonymous - | | +- ModFinal - | | +- ModOverride - | | +- TermName - | | +- MemberParamClauseGroup - | | | +- TypeParamClause - | | | | +- TypeParam - | | | | +- TypeName - | | | | +- TypeParamClause - | | | | +- TypeBounds - | | | +- TermParamClause - | | | +- TermParam - | | | +- TermName - | | | +- TypeFunction - | | | +- TypeFuncParamClause - | | | | +- TypeName - | | | +- TypeName - | | +- TypeName - | | +- TermBlock - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TermThis - | | | +- NameAnonymous - | | +- TermWhile - | | +- TermApplyUnary - | | | +- TermName - | | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermBlock - | | +- TermApply - | | | +- TermName - | | | +- TermArgClause - | | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermAssign - | | +- TermName - | | +- TermSelect - | | +- TermName - | | +- TermName - | +- DefnDef - | | +- ModFinal - | | +- ModOverride - | | +- TermName - | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- TermBlock - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TypeApply - | | | | +- TypeName - | | | | +- TypeArgClause - | | | | +- TypeName - | | | +- TermName - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TermThis - | | | +- NameAnonymous - | | +- TermWhile - | | | +- TermApplyUnary - | | | | +- TermName - | | | | +- TermSelect - | | | | +- TermName - | | | | +- TermName - | | | +- TermBlock - | | | +- TermAssign - | | | | +- TermName - | | | | +- TermApplyInfix - | | | | +- TermSelect - | | | | | +- TermName - | | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- TermName - | | | +- TermAssign - | | | +- TermName - | | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermName - | +- DefnDef - | | +- ModFinal - | | +- ModOverride - | | +- TermName - | | +- MemberParamClauseGroup - | | | +- TypeParamClause - | | | | +- TypeParam - | | | | +- TypeName - | | | | +- TypeParamClause - | | | | +- TypeBounds - | | | +- TermParamClause - | | | | +- TermParam - | | | | +- TermName - | | | | +- TypeName - | | | +- TermParamClause - | | | +- TermParam - | | | +- TermName - | | | +- TypeFunction - | | | +- TypeFuncParamClause - | | | | +- TypeName - | | | | +- TypeName - | | | +- TypeName - | | +- TypeName - | | +- TermBlock - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TermName - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TypeApply - | | | | +- TypeName - | | | | +- TypeArgClause - | | | | +- TypeName - | | | +- TermName - | | +- TermWhile - | | | +- TermApplyUnary - | | | | +- TermName - | | | | +- TermSelect - | | | | +- TermName - | | | | +- TermName - | | | +- TermBlock - | | | +- TermAssign - | | | | +- TermName - | | | | +- TermApply - | | | | +- TermName - | | | | +- TermArgClause - | | | | +- TermSelect - | | | | | +- TermName - | | | | | +- TermName - | | | | +- TermName - | | | +- TermAssign - | | | +- TermName - | | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermName - | +- DefnDef - | | +- ModOverride - | | +- ModFinal - | | +- TermName - | | +- TypeName - | | +- TermBlock - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TermThis - | | | +- NameAnonymous - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- LitInt - | | +- TermWhile - | | | +- TermApplyUnary - | | | | +- TermName - | | | | +- TermSelect - | | | | +- TermName - | | | | +- TermName - | | | +- TermBlock - | | | +- TermApplyInfix - | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- LitInt - | | | +- TermAssign - | | | +- TermName - | | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermName - | +- DefnDef - | | +- ModOverride - | | +- ModFinal - | | +- TermName - | | +- MemberParamClauseGroup - | | | +- TypeParamClause - | | | +- TermParamClause - | | | +- TermParam - | | | +- TermName - | | | +- TypeName - | | +- TypeName - | | +- TermBlock - | | +- DefnDef - | | | +- ModAnnot - | | | | +- Init - | | | | +- TypeName - | | | | +- NameAnonymous - | | | +- TermName - | | | +- MemberParamClauseGroup - | | | | +- TypeParamClause - | | | | +- TermParamClause - | | | | +- TermParam - | | | | | +- TermName - | | | | | +- TypeName - | | | | +- TermParam - | | | | +- TermName - | | | | +- TypeApply - | | | | +- TypeName - | | | | +- TypeArgClause - | | | | +- TypeName - | | | +- TypeName - | | | +- TermBlock - | | | +- TermIf - | | | +- TermApplyInfix - | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- TermName - | | | +- TermIf - | | | | +- TermSelect - | | | | | +- TermName - | | | | | +- TermName - | | | | +- LitInt - | | | | +- LitInt - | | | +- TermIf - | | | +- TermSelect - | | | | +- TermName - | | | | +- TermName - | | | +- LitInt - | | | +- TermApply - | | | +- TermName - | | | +- TermArgClause - | | | +- TermApplyInfix - | | | | +- TermName - | | | | +- TermName - | | | | +- TypeArgClause - | | | | +- TermArgClause - | | | | +- LitInt - | | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermIf - | | +- TermApplyInfix - | | | +- TermName - | | | +- TermName - | | | +- TypeArgClause - | | | +- TermArgClause - | | | +- LitInt - | | +- LitInt - | | +- TermApply - | | +- TermName - | | +- TermArgClause - | | +- LitInt - | | +- TermName - | +- DefnDef - | | +- ModOverride - | | +- ModFinal - | | +- TermName - | | +- MemberParamClauseGroup - | | | +- TypeParamClause - | | | +- TermParamClause - | | | +- TermParam - | | | +- TermName - | | | +- TypeFunction - | | | +- TypeFuncParamClause - | | | | +- TypeName - | | | +- TypeName - | | +- TypeName - | | +- TermBlock - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TypeApply - | | | | +- TypeName - | | | | +- TypeArgClause - | | | | +- TypeName - | | | +- TermThis - | | | +- NameAnonymous - | | +- TermWhile - | | | +- TermApplyUnary - | | | | +- TermName - | | | | +- TermSelect - | | | | +- TermName - | | | | +- TermName - | | | +- TermBlock - | | | +- TermIf - | | | | +- TermApplyUnary - | | | | | +- TermName - | | | | | +- TermApply - | | | | | +- TermName - | | | | | +- TermArgClause - | | | | | +- TermSelect - | | | | | +- TermName - | | | | | +- TermName - | | | | +- TermReturn - | | | | | +- LitBoolean - | | | | +- LitUnit - | | | +- TermAssign - | | | +- TermName - | | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- LitBoolean - | +- DefnDef - | | +- ModOverride - | | +- ModFinal - | | +- TermName - | | +- MemberParamClauseGroup - | | | +- TypeParamClause - | | | +- TermParamClause - | | | +- TermParam - | | | +- TermName - | | | +- TypeFunction - | | | +- TypeFuncParamClause - | | | | +- TypeName - | | | +- TypeName - | | +- TypeName - | | +- TermBlock - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TypeApply - | | | | +- TypeName - | | | | +- TypeArgClause - | | | | +- TypeName - | | | +- TermThis - | | | +- NameAnonymous - | | +- TermWhile - | | | +- TermApplyUnary - | | | | +- TermName - | | | | +- TermSelect - | | | | +- TermName - | | | | +- TermName - | | | +- TermBlock - | | | +- TermIf - | | | | +- TermApply - | | | | | +- TermName - | | | | | +- TermArgClause - | | | | | +- TermSelect - | | | | | +- TermName - | | | | | +- TermName - | | | | +- TermReturn - | | | | | +- LitBoolean - | | | | +- LitUnit - | | | +- TermAssign - | | | +- TermName - | | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- LitBoolean - | +- DefnDef - | | +- ModOverride - | | +- ModFinal - | | +- TermName - | | +- MemberParamClauseGroup - | | | +- TypeParamClause - | | | | +- TypeParam - | | | | +- TypeName - | | | | +- TypeParamClause - | | | | +- TypeBounds - | | | | +- TypeName - | | | +- TermParamClause - | | | +- TermParam - | | | +- TermName - | | | +- TypeName - | | +- TypeName - | | +- TermBlock - | | +- DefnVar - | | | +- PatVar - | | | | +- TermName - | | | +- TypeApply - | | | | +- TypeName - | | | | +- TypeArgClause - | | | | +- TypeName - | | | +- TermThis - | | | +- NameAnonymous - | | +- TermWhile - | | | +- TermApplyUnary - | | | | +- TermName - | | | | +- TermSelect - | | | | +- TermName - | | | | +- TermName - | | | +- TermBlock - | | | +- TermIf - | | | | +- TermApplyInfix - | | | | | +- TermSelect - | | | | | | +- TermName - | | | | | | +- TermName - | | | | | +- TermName - | | | | | +- TypeArgClause - | | | | | +- TermArgClause - | | | | | +- TermName - | | | | +- TermReturn - | | | | | +- LitBoolean - | | | | +- LitUnit - | | | +- TermAssign - | | | +- TermName - | | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- LitBoolean - | +- DefnDef - | +- ModOverride - | +- ModFinal - | +- TermName - | +- MemberParamClauseGroup - | | +- TypeParamClause - | | +- TermParamClause - | | +- TermParam - | | +- TermName - | | +- TypeFunction - | | +- TypeFuncParamClause - | | | +- TypeName - | | +- TypeName - | +- TypeApply - | | +- TypeName - | | +- TypeArgClause - | | +- TypeName - | +- TermBlock - | +- DefnVar - | | +- PatVar - | | | +- TermName - | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- TermThis - | | +- NameAnonymous - | +- TermWhile - | | +- TermApplyUnary - | | | +- TermName - | | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermBlock - | | +- TermIf - | | | +- TermApply - | | | | +- TermName - | | | | +- TermArgClause - | | | | +- TermSelect - | | | | +- TermName - | | | | +- TermName - | | | +- TermReturn - | | | | +- TermApply - | | | | +- TermName - | | | | +- TermArgClause - | | | | +- TermSelect - | | | | +- TermName - | | | | +- TermName - | | | +- LitUnit - | | +- TermAssign - | | +- TermName - | | +- TermSelect - | | +- TermName - | | +- TermName - | +- TermName - +- DefnClass - | +- ModFinal - | +- ModCase - | +- TypeName - | +- TypeParamClause - | | +- TypeParam - | | +- ModCovariant - | | +- TypeName - | | +- TypeParamClause - | | +- TypeBounds - | +- CtorPrimary - | | +- NameAnonymous - | | +- TermParamClause - | | +- TermParam - | | | +- ModOverride - | | | +- ModValParam - | | | +- TermName - | | | +- TypeName - | | +- TermParam - | | +- ModPrivate - | | | +- NameIndeterminate - | | +- ModVarParam - | | +- TermName - | | +- TypeApply - | | +- TypeName - | | +- TypeArgClause - | | +- TypeAnnotate - | | +- TypeName - | | +- ModAnnot - | | +- Init - | | +- TypeName - | | +- NameAnonymous - | +- Template - | +- Init - | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- NameAnonymous - | +- Self - | | +- NameAnonymous - | +- TermApply - | | +- TermName - | | +- TermArgClause - | +- DefnDef - | | +- ModOverride - | | +- TermName - | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- TermApply - | | +- TermName - | | +- TermArgClause - | | +- TermName - | +- DefnDef - | +- ModOverride - | +- TermName - | +- TypeApply - | | +- TypeName - | | +- TypeArgClause - | | +- TypeName - | +- TermName - +- DefnObject - | +- ModCase - | +- TermName - | +- Template - | +- Init - | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- NameAnonymous - | +- Self - | | +- NameAnonymous - | +- DefnDef - | | +- ModOverride - | | +- TermName - | | +- TypeName - | | +- TermThrow - | | +- TermNew - | | +- Init - | | +- TypeName - | | +- NameAnonymous - | | +- TermArgClause - | | +- LitString - | +- DefnDef - | | +- ModOverride - | | +- TermName - | | +- TypeSingleton - | | | +- TermName - | | +- TermName - | +- DefnDef - | | +- ModOverride - | | +- TermName - | | +- TypeName - | | +- TermThrow - | | +- TermNew - | | +- Init - | | +- TypeName - | | +- NameAnonymous - | | +- TermArgClause - | | +- LitString - | +- DefnDef - | | +- ModOverride - | | +- TermName - | | +- TypeName - | | +- TermThrow - | | +- TermNew - | | +- Init - | | +- TypeName - | | +- NameAnonymous - | | +- TermArgClause - | | +- LitString - | +- DefnDef - | | +- ModOverride - | | +- TermName - | | +- TypeName - | | +- TermThrow - | | +- TermNew - | | +- Init - | | +- TypeName - | | +- NameAnonymous - | | +- TermArgClause - | | +- LitString - | +- DefnDef - | | +- ModOverride - | | +- TermName - | | +- TypeName - | | +- LitInt - | +- DefnDef - | | +- ModOverride - | | +- TermName - | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- TermSelect - | | +- TermName - | | +- TermName - | +- DefnDef - | | +- ModOverride - | | +- TermName - | | +- MemberParamClauseGroup - | | | +- TypeParamClause - | | | | +- TypeParam - | | | | | +- TypeName - | | | | | +- TypeParamClause - | | | | | +- TypeBounds - | | | | +- TypeParam - | | | | +- TypeName - | | | | +- TypeParamClause - | | | | +- TypeBounds - | | | +- TermParamClause - | | | +- TermParam - | | | | +- ModImplicit - | | | | +- TermName - | | | | +- TypeFunction - | | | | +- TypeFuncParamClause - | | | | | +- TypeName - | | | | +- TypeTuple - | | | | +- TypeName - | | | | +- TypeName - | | | +- ModImplicit - | | +- TypeTuple - | | | +- TypeApply - | | | | +- TypeName - | | | | +- TypeArgClause - | | | | +- TypeName - | | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- TermName - | +- DefnVal - | +- ModAnnot - | | +- Init - | | +- TypeName - | | +- NameAnonymous - | +- ModPrivate - | | +- TermThis - | | +- NameAnonymous - | +- PatVar - | | +- TermName - | +- TermTuple - | +- TermName - | +- TermName - +- DefnObject - +- ModAnnot - | +- Init - | +- TypeName - | +- NameAnonymous - | +- TermArgClause - | +- LitLong - +- TermName - +- Template - +- Init - | +- TypeApply - | | +- TypeName - | | +- TypeArgClause - | | +- TypeName - | +- NameAnonymous - +- Self - | +- NameAnonymous - +- DefnVal - | +- ModPrivate - | | +- NameAnonymous - | +- PatVar - | | +- TermName - | +- TermTuple - | +- TermName - | +- TermName - +- DefnDef - | +- TermName - | +- MemberParamClauseGroup - | | +- TypeParamClause - | | | +- TypeParam - | | | +- TypeName - | | | +- TypeParamClause - | | | +- TypeBounds - | | +- TermParamClause - | | +- TermParam - | | +- TermName - | | +- TypeApply - | | +- TypeSelect - | | | +- TermName - | | | +- TypeName - | | +- TypeArgClause - | | +- TypeName - | +- TypeApply - | | +- TypeName - | | +- TypeArgClause - | | +- TypeName - | +- TermMatch - | +- TermName - | +- Case - | | +- PatTyped - | | | +- PatVar - | | | | +- TermName - | | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- TermName - | +- Case - | | +- PatWildcard - | | +- TermApplyInfix - | | | +- TermSelect - | | | | +- TermName - | | | | +- TermName - | | | +- TermName - | | | +- TypeArgClause - | | | +- TermArgClause - | | | +- LitInt - | | +- TermApplyType - | | +- TermName - | | +- TypeArgClause - | | +- TypeName - | +- Case - | | +- PatTyped - | | | +- PatVar - | | | | +- TermName - | | | +- TypeApply - | | | +- TypeName - | | | +- TypeArgClause - | | | +- TypeName - | | +- TermSelect - | | +- TermName - | | +- TermName - | +- Case - | +- PatWildcard - | +- TermSelect - | +- TermApply - | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TermArgClause - | | +- TermName - | +- TermName - +- DefnDef - | +- TermName - | +- MemberParamClauseGroup - | | +- TypeParamClause - | | +- TypeParam - | | +- TypeName - | | +- TypeParamClause - | | +- TypeBounds - | +- TypeApply - | | +- TypeName - | | +- TypeArgClause - | | +- TypeName - | | +- TypeApply - | | +- TypeName - | | +- TypeArgClause - | | +- TypeName - | +- TermNew - | +- Init - | +- TypeName - | +- NameAnonymous - | +- TermArgClause - +- DefnDef - | +- TermName - | +- MemberParamClauseGroup - | | +- TypeParamClause - | | +- TypeParam - | | +- TypeName - | | +- TypeParamClause - | | +- TypeBounds - | +- TypeApply - | | +- TypeName - | | +- TypeArgClause - | | +- TypeName - | +- TermName - +- DefnVal - +- ModAnnot - | +- Init - | +- TypeName - | +- NameAnonymous - +- ModPrivate - | +- NameIndeterminate - +- PatVar + +- PkgBody + +- Pkg + +- TermName + +- PkgBody + +- Import + | +- Importer + | +- TermSelect + | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermName + | +- ImporteeName + | +- NameIndeterminate + +- Import + | +- Importer + | +- TermSelect + | | +- TermName + | | +- TermName + | +- ImporteeName + | +- NameIndeterminate + +- Import + | +- Importer + | +- TermName + | +- ImporteeName + | | +- NameIndeterminate + | +- ImporteeName + | +- NameIndeterminate + +- Import + | +- Importer + | +- TermSelect + | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermName + | +- ImporteeName + | +- NameIndeterminate + +- Import + | +- Importer + | +- TermSelect + | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermName + | +- ImporteeName + | +- NameIndeterminate + +- DefnClass + | +- ModAnnot + | | +- Init + | | +- TypeName + | | +- NameAnonymous + | | +- TermArgClause + | | +- LitLong + | +- ModSealed + | +- ModAbstract + | +- TypeName + | +- TypeParamClause + | | +- TypeParam + | | +- ModCovariant + | | +- TypeName + | | +- TypeParamClause + | | +- TypeBounds + | +- CtorPrimary + | | +- NameAnonymous + | +- Template + | +- Init + | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- NameAnonymous + | +- Init + | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- NameAnonymous + | +- Init + | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | | +- TypeName + | | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- NameAnonymous + | +- Init + | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | | +- TypeName + | | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- NameAnonymous + | +- Init + | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | | +- TypeName + | | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- NameAnonymous + | +- Init + | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | | +- TypeName + | | +- NameAnonymous + | +- Init + | | +- TypeName + | | +- NameAnonymous + | +- TemplateBody + | +- DefnDef + | | +- ModOverride + | | +- TermName + | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- TermName + | +- DefnDef + | | +- ModOverride + | | +- TermName + | | +- MemberParamClauseGroup + | | | +- TypeParamClause + | | | +- TermParamClause + | | | +- TermParam + | | | +- TermName + | | | +- TypeName + | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- TermIf + | | +- TermApplyInfix + | | | +- TermName + | | | +- TermName + | | | +- TypeArgClause + | | | +- TermArgClause + | | | +- TermApplyInfix + | | | +- TermName + | | | +- TermName + | | | +- TypeArgClause + | | | +- TermArgClause + | | | +- LitInt + | | +- TermName + | | +- TermBlock + | | +- DefnVal + | | | +- PatVar + | | | | +- TermName + | | | +- TermNew + | | | +- Init + | | | +- TypeName + | | | +- NameAnonymous + | | | +- TermArgClause + | | | +- TermName + | | | +- TermName + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TermName + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TermName + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- LitInt + | | +- TermWhile + | | | +- TermBlock + | | | | +- TermIf + | | | | | +- TermSelect + | | | | | | +- TermName + | | | | | | +- TermName + | | | | | +- TermReturn + | | | | | | +- TermThis + | | | | | | +- NameAnonymous + | | | | | +- LitUnit + | | | | +- TermApplyInfix + | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- TermName + | | | +- TermBlock + | | | +- TermApplyInfix + | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- LitInt + | | | +- DefnVal + | | | | +- PatVar + | | | | | +- TermName + | | | | +- TermNew + | | | | +- Init + | | | | +- TypeName + | | | | +- NameAnonymous + | | | | +- TermArgClause + | | | | +- TermSelect + | | | | | +- TermName + | | | | | +- TermName + | | | | +- TermName + | | | +- TermAssign + | | | | +- TermSelect + | | | | | +- TermName + | | | | | +- TermName + | | | | +- TermName + | | | +- TermAssign + | | | | +- TermName + | | | | +- TermName + | | | +- TermAssign + | | | +- TermName + | | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermApply + | | | +- TermName + | | | +- TermArgClause + | | +- TermName + | +- DefnDef + | | +- ModOverride + | | +- TermName + | | +- MemberParamClauseGroup + | | | +- TypeParamClause + | | | +- TermParamClause + | | | +- TermParam + | | | | +- TermName + | | | | +- TypeName + | | | +- TermParam + | | | +- TermName + | | | +- TypeName + | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- TermBlock + | | +- DefnVal + | | | +- PatVar + | | | | +- TermName + | | | +- TermApply + | | | +- TermSelect + | | | | +- TermSelect + | | | | | +- TermName + | | | | | +- TermName + | | | | +- TermName + | | | +- TermArgClause + | | | +- TermName + | | | +- LitInt + | | +- TermIf + | | +- TermApplyInfix + | | | +- TermApplyInfix + | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- TermName + | | | +- TermName + | | | +- TypeArgClause + | | | +- TermArgClause + | | | +- TermName + | | +- TermName + | | +- TermApplyInfix + | | +- TermApplyInfix + | | | +- TermThis + | | | | +- NameAnonymous + | | | +- TermName + | | | +- TypeArgClause + | | | +- TermArgClause + | | | +- TermName + | | +- TermName + | | +- TypeArgClause + | | +- TermArgClause + | | +- TermApplyInfix + | | +- TermName + | | +- TermName + | | +- TypeArgClause + | | +- TermArgClause + | | +- TermName + | +- DefnDef + | | +- ModOverride + | | +- TermName + | | +- MemberParamClauseGroup + | | | +- TypeParamClause + | | | +- TermParamClause + | | | +- TermParam + | | | +- TermName + | | | +- TypeName + | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- TermBlock + | | +- DefnDef + | | | +- ModAnnot + | | | | +- Init + | | | | +- TypeName + | | | | +- NameAnonymous + | | | +- TermName + | | | +- MemberParamClauseGroup + | | | | +- TypeParamClause + | | | | +- TermParamClause + | | | | +- TermParam + | | | | | +- TermName + | | | | | +- TypeApply + | | | | | +- TypeName + | | | | | +- TypeArgClause + | | | | | +- TypeName + | | | | +- TermParam + | | | | +- TermName + | | | | +- TypeApply + | | | | +- TypeName + | | | | +- TypeArgClause + | | | | +- TypeName + | | | +- TypeApply + | | | | +- TypeName + | | | | +- TypeArgClause + | | | | +- TypeName + | | | +- TermMatch + | | | +- TermName + | | | +- TermCasesBlock + | | | +- Case + | | | | +- TermName + | | | | +- TermName + | | | +- Case + | | | +- PatExtractInfix + | | | | +- PatWildcard + | | | | +- TermName + | | | | +- PatArgClause + | | | | +- PatVar + | | | | +- TermName + | | | +- TermApply + | | | +- TermName + | | | +- TermArgClause + | | | +- TermName + | | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermApply + | | +- TermName + | | +- TermArgClause + | | +- TermApply + | | | +- TermName + | | | +- TermArgClause + | | | +- TermName + | | +- TermThis + | | +- NameAnonymous + | +- DefnDef + | | +- ModOverride + | | +- TermName + | | +- MemberParamClauseGroup + | | | +- TypeParamClause + | | | +- TermParamClause + | | | +- TermParam + | | | +- TermName + | | | +- TypeName + | | +- TypeTuple + | | | +- TypeApply + | | | | +- TypeName + | | | | +- TypeArgClause + | | | | +- TypeName + | | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- TermBlock + | | +- DefnVal + | | | +- PatVar + | | | | +- TermName + | | | +- TermNew + | | | +- Init + | | | +- TypeApply + | | | | +- TypeName + | | | | +- TypeArgClause + | | | | +- TypeName + | | | +- NameAnonymous + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- LitInt + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TermThis + | | | +- NameAnonymous + | | +- TermWhile + | | | +- TermApplyInfix + | | | | +- TermApplyUnary + | | | | | +- TermName + | | | | | +- TermSelect + | | | | | +- TermName + | | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- TermApplyInfix + | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- TermName + | | | +- TermBlock + | | | +- TermApplyInfix + | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- LitInt + | | | +- TermApplyInfix + | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- TermSelect + | | | | +- TermName + | | | | +- TermName + | | | +- TermAssign + | | | +- TermName + | | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermTuple + | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermName + | +- DefnDef + | | +- ModOverride + | | +- TermName + | | +- MemberParamClauseGroup + | | | +- TypeParamClause + | | | | +- TypeParam + | | | | +- TypeName + | | | | +- TypeParamClause + | | | | +- TypeBounds + | | | | +- TypeName + | | | +- TermParamClause + | | | +- TermParam + | | | | +- TermName + | | | | +- TypeName + | | | +- TermParam + | | | +- TermName + | | | +- TypeName + | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- TermBlock + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- LitInt + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TermThis + | | | +- NameAnonymous + | | +- DefnVal + | | | +- PatVar + | | | | +- TermName + | | | +- TermApplyType + | | | +- TermSelect + | | | | +- TermName + | | | | +- TermName + | | | +- TypeArgClause + | | | +- TypeName + | | +- TermWhile + | | | +- TermApplyInfix + | | | | +- TermApplyInfix + | | | | | +- TermName + | | | | | +- TermName + | | | | | +- TypeArgClause + | | | | | +- TermArgClause + | | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- TermSelect + | | | | +- TermName + | | | | +- TermName + | | | +- TermBlock + | | | +- TermApplyInfix + | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- LitInt + | | | +- TermApplyInfix + | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- TermSelect + | | | | +- TermName + | | | | +- TermName + | | | +- TermAssign + | | | +- TermName + | | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermIf + | | +- TermApplyInfix + | | | +- TermApplyInfix + | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- TermName + | | | +- TermName + | | | +- TypeArgClause + | | | +- TermArgClause + | | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermBlock + | | | +- TermApply + | | | +- TermSelect + | | | | +- TermName + | | | | +- TermName + | | | +- TermArgClause + | | | +- TermApplyInfix + | | | +- TermName + | | | +- TermName + | | | +- TypeArgClause + | | | +- TermArgClause + | | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermBlock + | | +- TermThrow + | | +- TermNew + | | +- Init + | | +- TypeName + | | +- NameAnonymous + | | +- TermArgClause + | | +- TermInterpolate + | | +- TermName + | | +- LitString + | | +- LitString + | | +- LitString + | | +- TermName + | | +- TermBlock + | | +- TermApplyInfix + | | +- TermName + | | +- TermName + | | +- TypeArgClause + | | +- TermArgClause + | | +- TermApplyInfix + | | +- TermName + | | +- TermName + | | +- TypeArgClause + | | +- TermArgClause + | | +- LitInt + | +- DefnDef + | | +- ModFinal + | | +- ModOverride + | | +- TermName + | | +- MemberParamClauseGroup + | | | +- TypeParamClause + | | | | +- TypeParam + | | | | +- TypeName + | | | | +- TypeParamClause + | | | | +- TypeBounds + | | | +- TermParamClause + | | | +- TermParam + | | | +- TermName + | | | +- TypeFunction + | | | +- TypeFuncParamClause + | | | | +- TypeName + | | | +- TypeName + | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- TermBlock + | | +- TermIf + | | +- TermApplyInfix + | | | +- TermThis + | | | | +- NameAnonymous + | | | +- TermName + | | | +- TypeArgClause + | | | +- TermArgClause + | | | +- TermName + | | +- TermName + | | +- TermBlock + | | +- DefnVal + | | | +- PatVar + | | | | +- TermName + | | | +- TermNew + | | | +- Init + | | | +- TypeApply + | | | | +- TypeName + | | | | +- TypeArgClause + | | | | +- TypeName + | | | +- NameAnonymous + | | | +- TermArgClause + | | | +- TermApply + | | | | +- TermName + | | | | +- TermArgClause + | | | | +- TermName + | | | +- TermName + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TypeApply + | | | | +- TypeName + | | | | +- TypeArgClause + | | | | +- TypeName + | | | +- TermName + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TermName + | | +- TermWhile + | | | +- TermApplyInfix + | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- TermName + | | | +- TermBlock + | | | +- DefnVal + | | | | +- PatVar + | | | | | +- TermName + | | | | +- TermNew + | | | | +- Init + | | | | +- TypeName + | | | | +- NameAnonymous + | | | | +- TermArgClause + | | | | +- TermApply + | | | | | +- TermName + | | | | | +- TermArgClause + | | | | | +- TermSelect + | | | | | +- TermName + | | | | | +- TermName + | | | | +- TermName + | | | +- TermAssign + | | | | +- TermSelect + | | | | | +- TermName + | | | | | +- TermName + | | | | +- TermName + | | | +- TermAssign + | | | | +- TermName + | | | | +- TermName + | | | +- TermAssign + | | | +- TermName + | | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermApply + | | | +- TermName + | | | +- TermArgClause + | | +- TermName + | +- DefnDef + | | +- ModFinal + | | +- ModOverride + | | +- TermName + | | +- MemberParamClauseGroup + | | | +- TypeParamClause + | | | | +- TypeParam + | | | | +- TypeName + | | | | +- TypeParamClause + | | | | +- TypeBounds + | | | +- TermParamClause + | | | +- TermParam + | | | +- TermName + | | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | | +- TypeName + | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- TermBlock + | | +- TermIf + | | +- TermApplyInfix + | | | +- TermThis + | | | | +- NameAnonymous + | | | +- TermName + | | | +- TypeArgClause + | | | +- TermArgClause + | | | +- TermName + | | +- TermName + | | +- TermBlock + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TermThis + | | | +- NameAnonymous + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TypeApply + | | | | +- TypeName + | | | | +- TypeArgClause + | | | | +- TypeName + | | | +- LitNull + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TypeName + | | | +- LitNull + | | +- TermWhile + | | | +- TermApplyInfix + | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- LitNull + | | | +- TermBlock + | | | +- TermAssign + | | | | +- TermName + | | | | +- TermApply + | | | | +- TermSelect + | | | | | +- TermName + | | | | | +- TermName + | | | | +- TermArgClause + | | | | +- TermSelect + | | | | | +- TermName + | | | | | +- TermName + | | | | +- TermSelect + | | | | +- TermName + | | | | +- TermName + | | | +- TermIf + | | | | +- TermApplyInfix + | | | | | +- TermApplyType + | | | | | | +- TermSelect + | | | | | | | +- TermName + | | | | | | | +- TermName + | | | | | | +- TypeArgClause + | | | | | | +- TypeName + | | | | | +- TermName + | | | | | +- TypeArgClause + | | | | | +- TermArgClause + | | | | | +- TermSelect + | | | | | +- TermName + | | | | | +- TermName + | | | | +- TermAssign + | | | | | +- TermName + | | | | | +- TermNew + | | | | | +- Init + | | | | | +- TypeName + | | | | | +- NameAnonymous + | | | | | +- TermArgClause + | | | | | +- TermApplyType + | | | | | | +- TermSelect + | | | | | | | +- TermName + | | | | | | | +- TermName + | | | | | | +- TypeArgClause + | | | | | | +- TypeName + | | | | | +- TermName + | | | | +- LitUnit + | | | +- TermAssign + | | | | +- TermName + | | | | +- TermSelect + | | | | +- TermName + | | | | +- TermName + | | | +- TermIf + | | | +- TermApplyInfix + | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- TermName + | | | +- TermReturn + | | | | +- TermIf + | | | | +- TermApplyInfix + | | | | | +- TermName + | | | | | +- TermName + | | | | | +- TypeArgClause + | | | | | +- TermArgClause + | | | | | +- LitNull + | | | | +- TermName + | | | | +- TermName + | | | +- LitUnit + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TermName + | | +- TermWhile + | | | +- TermApplyInfix + | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- TermName + | | | +- TermBlock + | | | +- TermAssign + | | | | +- TermName + | | | | +- TermApply + | | | | +- TermSelect + | | | | | +- TermName + | | | | | +- TermName + | | | | +- TermArgClause + | | | | +- TermSelect + | | | | | +- TermName + | | | | | +- TermName + | | | | +- TermSelect + | | | | +- TermName + | | | | +- TermName + | | | +- TermIf + | | | | +- TermApplyInfix + | | | | | +- TermApplyType + | | | | | | +- TermSelect + | | | | | | | +- TermName + | | | | | | | +- TermName + | | | | | | +- TypeArgClause + | | | | | | +- TypeName + | | | | | +- TermName + | | | | | +- TypeArgClause + | | | | | +- TermArgClause + | | | | | +- TermSelect + | | | | | +- TermName + | | | | | +- TermName + | | | | +- TermBlock + | | | | | +- DefnVal + | | | | | | +- PatVar + | | | | | | | +- TermName + | | | | | | +- TermNew + | | | | | | +- Init + | | | | | | +- TypeName + | | | | | | +- NameAnonymous + | | | | | | +- TermArgClause + | | | | | | +- TermApplyType + | | | | | | | +- TermSelect + | | | | | | | | +- TermName + | | | | | | | | +- TermName + | | | | | | | +- TypeArgClause + | | | | | | | +- TypeName + | | | | | | +- TermName + | | | | | +- TermAssign + | | | | | | +- TermSelect + | | | | | | | +- TermName + | | | | | | | +- TermName + | | | | | | +- TermName + | | | | | +- TermAssign + | | | | | +- TermName + | | | | | +- TermName + | | | | +- LitUnit + | | | +- TermAssign + | | | +- TermName + | | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermApply + | | | +- TermName + | | | +- TermArgClause + | | +- TermName + | +- DefnDef + | | +- ModFinal + | | +- ModOverride + | | +- TermName + | | +- MemberParamClauseGroup + | | | +- TypeParamClause + | | | | +- TypeParam + | | | | +- TypeName + | | | | +- TypeParamClause + | | | | +- TypeBounds + | | | +- TermParamClause + | | | +- TermParam + | | | +- TermName + | | | +- TypeFunction + | | | +- TypeFuncParamClause + | | | | +- TypeName + | | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- TermBlock + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TermThis + | | | +- NameAnonymous + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TypeApply + | | | | +- TypeName + | | | | +- TypeArgClause + | | | | +- TypeName + | | | +- LitNull + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TypeApply + | | | | +- TypeName + | | | | +- TypeArgClause + | | | | +- TypeName + | | | +- LitNull + | | +- TermWhile + | | | +- TermApplyInfix + | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- TermName + | | | +- TermBlock + | | | +- DefnVal + | | | | +- PatVar + | | | | | +- TermName + | | | | +- TermSelect + | | | | +- TermApply + | | | | | +- TermName + | | | | | +- TermArgClause + | | | | | +- TermSelect + | | | | | +- TermName + | | | | | +- TermName + | | | | +- TermName + | | | +- TermWhile + | | | | +- TermSelect + | | | | | +- TermName + | | | | | +- TermName + | | | | +- TermBlock + | | | | +- DefnVal + | | | | | +- PatVar + | | | | | | +- TermName + | | | | | +- TermNew + | | | | | +- Init + | | | | | +- TypeName + | | | | | +- NameAnonymous + | | | | | +- TermArgClause + | | | | | +- TermApply + | | | | | | +- TermSelect + | | | | | | | +- TermName + | | | | | | | +- TermName + | | | | | | +- TermArgClause + | | | | | +- TermName + | | | | +- TermIf + | | | | | +- TermApplyInfix + | | | | | | +- TermName + | | | | | | +- TermName + | | | | | | +- TypeArgClause + | | | | | | +- TermArgClause + | | | | | | +- LitNull + | | | | | +- TermBlock + | | | | | | +- TermAssign + | | | | | | +- TermName + | | | | | | +- TermName + | | | | | +- TermBlock + | | | | | +- TermAssign + | | | | | +- TermSelect + | | | | | | +- TermName + | | | | | | +- TermName + | | | | | +- TermName + | | | | +- TermAssign + | | | | +- TermName + | | | | +- TermName + | | | +- TermAssign + | | | +- TermName + | | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermIf + | | +- TermApplyInfix + | | | +- TermName + | | | +- TermName + | | | +- TypeArgClause + | | | +- TermArgClause + | | | +- LitNull + | | +- TermName + | | +- TermBlock + | | +- TermApply + | | | +- TermName + | | | +- TermArgClause + | | +- TermName + | +- DefnDef + | | +- ModAnnot + | | | +- Init + | | | +- TypeName + | | | +- NameAnonymous + | | +- ModFinal + | | +- ModOverride + | | +- TermName + | | +- MemberParamClauseGroup + | | | +- TypeParamClause + | | | +- TermParamClause + | | | +- TermParam + | | | +- TermName + | | | +- TypeFunction + | | | +- TypeFuncParamClause + | | | | +- TypeName + | | | +- TypeName + | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- TermBlock + | | +- DefnVal + | | | +- PatVar + | | | | +- TermName + | | | +- TermNew + | | | +- Init + | | | +- TypeApply + | | | | +- TypeName + | | | | +- TypeArgClause + | | | | +- TypeName + | | | +- NameAnonymous + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TermThis + | | | +- NameAnonymous + | | +- TermWhile + | | | +- TermApplyInfix + | | | | +- TermApplyUnary + | | | | | +- TermName + | | | | | +- TermSelect + | | | | | +- TermName + | | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- TermApply + | | | | +- TermName + | | | | +- TermArgClause + | | | | +- TermSelect + | | | | +- TermName + | | | | +- TermName + | | | +- TermBlock + | | | +- TermApplyInfix + | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- TermSelect + | | | | +- TermName + | | | | +- TermName + | | | +- TermAssign + | | | +- TermName + | | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermSelect + | | +- TermName + | | +- TermName + | +- DefnDef + | | +- ModAnnot + | | | +- Init + | | | +- TypeName + | | | +- NameAnonymous + | | +- ModFinal + | | +- ModOverride + | | +- TermName + | | +- MemberParamClauseGroup + | | | +- TypeParamClause + | | | +- TermParamClause + | | | +- TermParam + | | | +- TermName + | | | +- TypeFunction + | | | +- TypeFuncParamClause + | | | | +- TypeName + | | | +- TypeName + | | +- TypeTuple + | | | +- TypeApply + | | | | +- TypeName + | | | | +- TypeArgClause + | | | | +- TypeName + | | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- TermBlock + | | +- DefnVal + | | | +- PatVar + | | | | +- TermName + | | | +- TermNew + | | | +- Init + | | | +- TypeApply + | | | | +- TypeName + | | | | +- TypeArgClause + | | | | +- TypeName + | | | +- NameAnonymous + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TermThis + | | | +- NameAnonymous + | | +- TermWhile + | | | +- TermApplyInfix + | | | | +- TermApplyUnary + | | | | | +- TermName + | | | | | +- TermSelect + | | | | | +- TermName + | | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- TermApply + | | | | +- TermName + | | | | +- TermArgClause + | | | | +- TermSelect + | | | | +- TermName + | | | | +- TermName + | | | +- TermBlock + | | | +- TermApplyInfix + | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- TermSelect + | | | | +- TermName + | | | | +- TermName + | | | +- TermAssign + | | | +- TermName + | | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermTuple + | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermName + | +- DefnDef + | | +- ModAnnot + | | | +- Init + | | | +- TypeName + | | | +- NameAnonymous + | | +- ModFinal + | | +- ModOverride + | | +- TermName + | | +- MemberParamClauseGroup + | | | +- TypeParamClause + | | | | +- TypeParam + | | | | +- TypeName + | | | | +- TypeParamClause + | | | | +- TypeBounds + | | | +- TermParamClause + | | | +- TermParam + | | | +- TermName + | | | +- TypeFunction + | | | +- TypeFuncParamClause + | | | | +- TypeName + | | | +- TypeName + | | +- TypeName + | | +- TermBlock + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TermThis + | | | +- NameAnonymous + | | +- TermWhile + | | +- TermApplyUnary + | | | +- TermName + | | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermBlock + | | +- TermApply + | | | +- TermName + | | | +- TermArgClause + | | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermAssign + | | +- TermName + | | +- TermSelect + | | +- TermName + | | +- TermName + | +- DefnDef + | | +- ModFinal + | | +- ModOverride + | | +- TermName + | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- TermBlock + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TypeApply + | | | | +- TypeName + | | | | +- TypeArgClause + | | | | +- TypeName + | | | +- TermName + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TermThis + | | | +- NameAnonymous + | | +- TermWhile + | | | +- TermApplyUnary + | | | | +- TermName + | | | | +- TermSelect + | | | | +- TermName + | | | | +- TermName + | | | +- TermBlock + | | | +- TermAssign + | | | | +- TermName + | | | | +- TermApplyInfix + | | | | +- TermSelect + | | | | | +- TermName + | | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- TermName + | | | +- TermAssign + | | | +- TermName + | | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermName + | +- DefnDef + | | +- ModFinal + | | +- ModOverride + | | +- TermName + | | +- MemberParamClauseGroup + | | | +- TypeParamClause + | | | | +- TypeParam + | | | | +- TypeName + | | | | +- TypeParamClause + | | | | +- TypeBounds + | | | +- TermParamClause + | | | | +- TermParam + | | | | +- TermName + | | | | +- TypeName + | | | +- TermParamClause + | | | +- TermParam + | | | +- TermName + | | | +- TypeFunction + | | | +- TypeFuncParamClause + | | | | +- TypeName + | | | | +- TypeName + | | | +- TypeName + | | +- TypeName + | | +- TermBlock + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TermName + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TypeApply + | | | | +- TypeName + | | | | +- TypeArgClause + | | | | +- TypeName + | | | +- TermName + | | +- TermWhile + | | | +- TermApplyUnary + | | | | +- TermName + | | | | +- TermSelect + | | | | +- TermName + | | | | +- TermName + | | | +- TermBlock + | | | +- TermAssign + | | | | +- TermName + | | | | +- TermApply + | | | | +- TermName + | | | | +- TermArgClause + | | | | +- TermSelect + | | | | | +- TermName + | | | | | +- TermName + | | | | +- TermName + | | | +- TermAssign + | | | +- TermName + | | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermName + | +- DefnDef + | | +- ModOverride + | | +- ModFinal + | | +- TermName + | | +- TypeName + | | +- TermBlock + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TermThis + | | | +- NameAnonymous + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- LitInt + | | +- TermWhile + | | | +- TermApplyUnary + | | | | +- TermName + | | | | +- TermSelect + | | | | +- TermName + | | | | +- TermName + | | | +- TermBlock + | | | +- TermApplyInfix + | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- LitInt + | | | +- TermAssign + | | | +- TermName + | | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermName + | +- DefnDef + | | +- ModOverride + | | +- ModFinal + | | +- TermName + | | +- MemberParamClauseGroup + | | | +- TypeParamClause + | | | +- TermParamClause + | | | +- TermParam + | | | +- TermName + | | | +- TypeName + | | +- TypeName + | | +- TermBlock + | | +- DefnDef + | | | +- ModAnnot + | | | | +- Init + | | | | +- TypeName + | | | | +- NameAnonymous + | | | +- TermName + | | | +- MemberParamClauseGroup + | | | | +- TypeParamClause + | | | | +- TermParamClause + | | | | +- TermParam + | | | | | +- TermName + | | | | | +- TypeName + | | | | +- TermParam + | | | | +- TermName + | | | | +- TypeApply + | | | | +- TypeName + | | | | +- TypeArgClause + | | | | +- TypeName + | | | +- TypeName + | | | +- TermBlock + | | | +- TermIf + | | | +- TermApplyInfix + | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- TermName + | | | +- TermIf + | | | | +- TermSelect + | | | | | +- TermName + | | | | | +- TermName + | | | | +- LitInt + | | | | +- LitInt + | | | +- TermIf + | | | +- TermSelect + | | | | +- TermName + | | | | +- TermName + | | | +- LitInt + | | | +- TermApply + | | | +- TermName + | | | +- TermArgClause + | | | +- TermApplyInfix + | | | | +- TermName + | | | | +- TermName + | | | | +- TypeArgClause + | | | | +- TermArgClause + | | | | +- LitInt + | | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermIf + | | +- TermApplyInfix + | | | +- TermName + | | | +- TermName + | | | +- TypeArgClause + | | | +- TermArgClause + | | | +- LitInt + | | +- LitInt + | | +- TermApply + | | +- TermName + | | +- TermArgClause + | | +- LitInt + | | +- TermName + | +- DefnDef + | | +- ModOverride + | | +- ModFinal + | | +- TermName + | | +- MemberParamClauseGroup + | | | +- TypeParamClause + | | | +- TermParamClause + | | | +- TermParam + | | | +- TermName + | | | +- TypeFunction + | | | +- TypeFuncParamClause + | | | | +- TypeName + | | | +- TypeName + | | +- TypeName + | | +- TermBlock + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TypeApply + | | | | +- TypeName + | | | | +- TypeArgClause + | | | | +- TypeName + | | | +- TermThis + | | | +- NameAnonymous + | | +- TermWhile + | | | +- TermApplyUnary + | | | | +- TermName + | | | | +- TermSelect + | | | | +- TermName + | | | | +- TermName + | | | +- TermBlock + | | | +- TermIf + | | | | +- TermApplyUnary + | | | | | +- TermName + | | | | | +- TermApply + | | | | | +- TermName + | | | | | +- TermArgClause + | | | | | +- TermSelect + | | | | | +- TermName + | | | | | +- TermName + | | | | +- TermReturn + | | | | | +- LitBoolean + | | | | +- LitUnit + | | | +- TermAssign + | | | +- TermName + | | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- LitBoolean + | +- DefnDef + | | +- ModOverride + | | +- ModFinal + | | +- TermName + | | +- MemberParamClauseGroup + | | | +- TypeParamClause + | | | +- TermParamClause + | | | +- TermParam + | | | +- TermName + | | | +- TypeFunction + | | | +- TypeFuncParamClause + | | | | +- TypeName + | | | +- TypeName + | | +- TypeName + | | +- TermBlock + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TypeApply + | | | | +- TypeName + | | | | +- TypeArgClause + | | | | +- TypeName + | | | +- TermThis + | | | +- NameAnonymous + | | +- TermWhile + | | | +- TermApplyUnary + | | | | +- TermName + | | | | +- TermSelect + | | | | +- TermName + | | | | +- TermName + | | | +- TermBlock + | | | +- TermIf + | | | | +- TermApply + | | | | | +- TermName + | | | | | +- TermArgClause + | | | | | +- TermSelect + | | | | | +- TermName + | | | | | +- TermName + | | | | +- TermReturn + | | | | | +- LitBoolean + | | | | +- LitUnit + | | | +- TermAssign + | | | +- TermName + | | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- LitBoolean + | +- DefnDef + | | +- ModOverride + | | +- ModFinal + | | +- TermName + | | +- MemberParamClauseGroup + | | | +- TypeParamClause + | | | | +- TypeParam + | | | | +- TypeName + | | | | +- TypeParamClause + | | | | +- TypeBounds + | | | | +- TypeName + | | | +- TermParamClause + | | | +- TermParam + | | | +- TermName + | | | +- TypeName + | | +- TypeName + | | +- TermBlock + | | +- DefnVar + | | | +- PatVar + | | | | +- TermName + | | | +- TypeApply + | | | | +- TypeName + | | | | +- TypeArgClause + | | | | +- TypeName + | | | +- TermThis + | | | +- NameAnonymous + | | +- TermWhile + | | | +- TermApplyUnary + | | | | +- TermName + | | | | +- TermSelect + | | | | +- TermName + | | | | +- TermName + | | | +- TermBlock + | | | +- TermIf + | | | | +- TermApplyInfix + | | | | | +- TermSelect + | | | | | | +- TermName + | | | | | | +- TermName + | | | | | +- TermName + | | | | | +- TypeArgClause + | | | | | +- TermArgClause + | | | | | +- TermName + | | | | +- TermReturn + | | | | | +- LitBoolean + | | | | +- LitUnit + | | | +- TermAssign + | | | +- TermName + | | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- LitBoolean + | +- DefnDef + | +- ModOverride + | +- ModFinal + | +- TermName + | +- MemberParamClauseGroup + | | +- TypeParamClause + | | +- TermParamClause + | | +- TermParam + | | +- TermName + | | +- TypeFunction + | | +- TypeFuncParamClause + | | | +- TypeName + | | +- TypeName + | +- TypeApply + | | +- TypeName + | | +- TypeArgClause + | | +- TypeName + | +- TermBlock + | +- DefnVar + | | +- PatVar + | | | +- TermName + | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- TermThis + | | +- NameAnonymous + | +- TermWhile + | | +- TermApplyUnary + | | | +- TermName + | | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermBlock + | | +- TermIf + | | | +- TermApply + | | | | +- TermName + | | | | +- TermArgClause + | | | | +- TermSelect + | | | | +- TermName + | | | | +- TermName + | | | +- TermReturn + | | | | +- TermApply + | | | | +- TermName + | | | | +- TermArgClause + | | | | +- TermSelect + | | | | +- TermName + | | | | +- TermName + | | | +- LitUnit + | | +- TermAssign + | | +- TermName + | | +- TermSelect + | | +- TermName + | | +- TermName + | +- TermName + +- DefnClass + | +- ModFinal + | +- ModCase + | +- TypeName + | +- TypeParamClause + | | +- TypeParam + | | +- ModCovariant + | | +- TypeName + | | +- TypeParamClause + | | +- TypeBounds + | +- CtorPrimary + | | +- NameAnonymous + | | +- TermParamClause + | | +- TermParam + | | | +- ModOverride + | | | +- ModValParam + | | | +- TermName + | | | +- TypeName + | | +- TermParam + | | +- ModPrivate + | | | +- NameIndeterminate + | | +- ModVarParam + | | +- TermName + | | +- TypeApply + | | +- TypeName + | | +- TypeArgClause + | | +- TypeAnnotate + | | +- TypeName + | | +- ModAnnot + | | +- Init + | | +- TypeName + | | +- NameAnonymous + | +- Template + | +- Init + | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- NameAnonymous + | +- TemplateBody + | +- TermApply + | | +- TermName + | | +- TermArgClause + | +- DefnDef + | | +- ModOverride + | | +- TermName + | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- TermApply + | | +- TermName + | | +- TermArgClause + | | +- TermName + | +- DefnDef + | +- ModOverride + | +- TermName + | +- TypeApply + | | +- TypeName + | | +- TypeArgClause + | | +- TypeName + | +- TermName + +- DefnObject + | +- ModCase | +- TermName - +- TermNewAnonymous + | +- Template + | +- Init + | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- NameAnonymous + | +- TemplateBody + | +- DefnDef + | | +- ModOverride + | | +- TermName + | | +- TypeName + | | +- TermThrow + | | +- TermNew + | | +- Init + | | +- TypeName + | | +- NameAnonymous + | | +- TermArgClause + | | +- LitString + | +- DefnDef + | | +- ModOverride + | | +- TermName + | | +- TypeSingleton + | | | +- TermName + | | +- TermName + | +- DefnDef + | | +- ModOverride + | | +- TermName + | | +- TypeName + | | +- TermThrow + | | +- TermNew + | | +- Init + | | +- TypeName + | | +- NameAnonymous + | | +- TermArgClause + | | +- LitString + | +- DefnDef + | | +- ModOverride + | | +- TermName + | | +- TypeName + | | +- TermThrow + | | +- TermNew + | | +- Init + | | +- TypeName + | | +- NameAnonymous + | | +- TermArgClause + | | +- LitString + | +- DefnDef + | | +- ModOverride + | | +- TermName + | | +- TypeName + | | +- TermThrow + | | +- TermNew + | | +- Init + | | +- TypeName + | | +- NameAnonymous + | | +- TermArgClause + | | +- LitString + | +- DefnDef + | | +- ModOverride + | | +- TermName + | | +- TypeName + | | +- LitInt + | +- DefnDef + | | +- ModOverride + | | +- TermName + | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- TermSelect + | | +- TermName + | | +- TermName + | +- DefnDef + | | +- ModOverride + | | +- TermName + | | +- MemberParamClauseGroup + | | | +- TypeParamClause + | | | | +- TypeParam + | | | | | +- TypeName + | | | | | +- TypeParamClause + | | | | | +- TypeBounds + | | | | +- TypeParam + | | | | +- TypeName + | | | | +- TypeParamClause + | | | | +- TypeBounds + | | | +- TermParamClause + | | | +- TermParam + | | | | +- ModImplicit + | | | | +- TermName + | | | | +- TypeFunction + | | | | +- TypeFuncParamClause + | | | | | +- TypeName + | | | | +- TypeTuple + | | | | +- TypeName + | | | | +- TypeName + | | | +- ModImplicit + | | +- TypeTuple + | | | +- TypeApply + | | | | +- TypeName + | | | | +- TypeArgClause + | | | | +- TypeName + | | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- TermName + | +- DefnVal + | +- ModAnnot + | | +- Init + | | +- TypeName + | | +- NameAnonymous + | +- ModPrivate + | | +- TermThis + | | +- NameAnonymous + | +- PatVar + | | +- TermName + | +- TermTuple + | +- TermName + | +- TermName + +- DefnObject + +- ModAnnot + | +- Init + | +- TypeName + | +- NameAnonymous + | +- TermArgClause + | +- LitLong + +- TermName +- Template +- Init | +- TypeApply | | +- TypeName | | +- TypeArgClause | | +- TypeName - | | +- TypeName - | +- NameAnonymous - +- Self | +- NameAnonymous - +- DefnDef - +- TermName - +- MemberParamClauseGroup - | +- TypeParamClause - | +- TermParamClause - | +- TermParam - | +- TermName + +- TemplateBody + +- DefnVal + | +- ModPrivate + | | +- NameAnonymous + | +- PatVar + | | +- TermName + | +- TermTuple + | +- TermName + | +- TermName + +- DefnDef + | +- TermName + | +- MemberParamClauseGroup + | | +- TypeParamClause + | | | +- TypeParam + | | | +- TypeName + | | | +- TypeParamClause + | | | +- TypeBounds + | | +- TermParamClause + | | +- TermParam + | | +- TermName + | | +- TypeApply + | | +- TypeSelect + | | | +- TermName + | | | +- TypeName + | | +- TypeArgClause + | | +- TypeName + | +- TypeApply + | | +- TypeName + | | +- TypeArgClause + | | +- TypeName + | +- TermMatch + | +- TermName + | +- TermCasesBlock + | +- Case + | | +- PatTyped + | | | +- PatVar + | | | | +- TermName + | | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- TermName + | +- Case + | | +- PatWildcard + | | +- TermApplyInfix + | | | +- TermSelect + | | | | +- TermName + | | | | +- TermName + | | | +- TermName + | | | +- TypeArgClause + | | | +- TermArgClause + | | | +- LitInt + | | +- TermApplyType + | | +- TermName + | | +- TypeArgClause + | | +- TypeName + | +- Case + | | +- PatTyped + | | | +- PatVar + | | | | +- TermName + | | | +- TypeApply + | | | +- TypeName + | | | +- TypeArgClause + | | | +- TypeName + | | +- TermSelect + | | +- TermName + | | +- TermName + | +- Case + | +- PatWildcard + | +- TermSelect + | +- TermApply + | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TermArgClause + | | +- TermName + | +- TermName + +- DefnDef + | +- TermName + | +- MemberParamClauseGroup + | | +- TypeParamClause + | | +- TypeParam + | | +- TypeName + | | +- TypeParamClause + | | +- TypeBounds + | +- TypeApply + | | +- TypeName + | | +- TypeArgClause + | | +- TypeName + | | +- TypeApply + | | +- TypeName + | | +- TypeArgClause + | | +- TypeName + | +- TermNew + | +- Init | +- TypeName - +- TypeName - +- TermThis - +- NameAnonymous + | +- NameAnonymous + | +- TermArgClause + +- DefnDef + | +- TermName + | +- MemberParamClauseGroup + | | +- TypeParamClause + | | +- TypeParam + | | +- TypeName + | | +- TypeParamClause + | | +- TypeBounds + | +- TypeApply + | | +- TypeName + | | +- TypeArgClause + | | +- TypeName + | +- TermName + +- DefnVal + +- ModAnnot + | +- Init + | +- TypeName + | +- NameAnonymous + +- ModPrivate + | +- NameIndeterminate + +- PatVar + | +- TermName + +- TermNewAnonymous + +- Template + +- Init + | +- TypeApply + | | +- TypeName + | | +- TypeArgClause + | | +- TypeName + | | +- TypeName + | +- NameAnonymous + +- TemplateBody + +- DefnDef + +- TermName + +- MemberParamClauseGroup + | +- TypeParamClause + | +- TermParamClause + | +- TermParam + | +- TermName + | +- TypeName + +- TypeName + +- TermThis + +- NameAnonymous diff --git a/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/ast/testdata/package.txt b/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/ast/testdata/package.txt index 0226a700224..388789ced5b 100644 --- a/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/ast/testdata/package.txt +++ b/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/ast/testdata/package.txt @@ -3,104 +3,104 @@ +- TermSelect | +- TermName | +- TermName - +- PkgObject - +- TermName - +- Template - +- Self - | +- NameAnonymous - +- DefnType - | +- TypeName - | +- TypeParamClause - | +- TypeSelect - | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TypeName - | +- TypeBounds - +- DefnVal - | +- PatVar - | | +- TermName - | +- TermSelect - | +- TermSelect - | | +- TermName - | | +- TermName - | +- TermName - +- DefnType - | +- TypeName - | +- TypeParamClause - | +- TypeSelect - | | +- TermSelect - | | | +- TermName - | | | +- TermName - | | +- TypeName - | +- TypeBounds - +- DefnVal - | +- PatVar - | | +- TermName - | +- TermSelect - | +- TermSelect - | | +- TermName - | | +- TermName - | +- TermName - +- DefnType - | +- ModAnnot - | | +- Init - | | +- TypeName - | | +- NameAnonymous - | | +- TermArgClause - | | +- LitString - | | +- LitString - | +- TypeName - | +- TypeParamClause - | | +- TypeParam - | | +- ModCovariant - | | +- TypeName - | | +- TypeParamClause - | | +- TypeBounds - | +- TypeApply - | | +- TypeName - | | +- TypeArgClause - | | +- TypeName - | +- TypeBounds - +- DefnVal - | +- ModAnnot - | | +- Init - | | +- TypeName - | | +- NameAnonymous - | | +- TermArgClause - | | +- LitString - | | +- LitString - | +- PatVar - | | +- TermName - | +- TermName - +- DefnType - +- ModAnnot - | +- Init - | +- TypeName - | +- NameAnonymous - | +- TermArgClause - | +- LitString - | +- LitString - +- TypeName - +- TypeParamClause - | +- TypeParam - | | +- TypeName - | | +- TypeParamClause - | | +- TypeBounds - | +- TypeParam - | +- ModCovariant - | +- TypeName - | +- TypeParamClause - | +- TypeBounds - +- TypeApply - | +- TypeSelect - | | +- TermSelect - | | | +- TermSelect - | | | | +- TermName - | | | | +- TermName - | | | +- TermName - | | +- TypeName - | +- TypeArgClause - | +- TypeName - | +- TypeName - +- TypeBounds + +- PkgBody + +- PkgObject + +- TermName + +- Template + +- TemplateBody + +- DefnType + | +- TypeName + | +- TypeParamClause + | +- TypeSelect + | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TypeName + | +- TypeBounds + +- DefnVal + | +- PatVar + | | +- TermName + | +- TermSelect + | +- TermSelect + | | +- TermName + | | +- TermName + | +- TermName + +- DefnType + | +- TypeName + | +- TypeParamClause + | +- TypeSelect + | | +- TermSelect + | | | +- TermName + | | | +- TermName + | | +- TypeName + | +- TypeBounds + +- DefnVal + | +- PatVar + | | +- TermName + | +- TermSelect + | +- TermSelect + | | +- TermName + | | +- TermName + | +- TermName + +- DefnType + | +- ModAnnot + | | +- Init + | | +- TypeName + | | +- NameAnonymous + | | +- TermArgClause + | | +- LitString + | | +- LitString + | +- TypeName + | +- TypeParamClause + | | +- TypeParam + | | +- ModCovariant + | | +- TypeName + | | +- TypeParamClause + | | +- TypeBounds + | +- TypeApply + | | +- TypeName + | | +- TypeArgClause + | | +- TypeName + | +- TypeBounds + +- DefnVal + | +- ModAnnot + | | +- Init + | | +- TypeName + | | +- NameAnonymous + | | +- TermArgClause + | | +- LitString + | | +- LitString + | +- PatVar + | | +- TermName + | +- TermName + +- DefnType + +- ModAnnot + | +- Init + | +- TypeName + | +- NameAnonymous + | +- TermArgClause + | +- LitString + | +- LitString + +- TypeName + +- TypeParamClause + | +- TypeParam + | | +- TypeName + | | +- TypeParamClause + | | +- TypeBounds + | +- TypeParam + | +- ModCovariant + | +- TypeName + | +- TypeParamClause + | +- TypeBounds + +- TypeApply + | +- TypeSelect + | | +- TermSelect + | | | +- TermSelect + | | | | +- TermName + | | | | +- TermName + | | | +- TermName + | | +- TypeName + | +- TypeArgClause + | +- TypeName + | +- TypeName + +- TypeBounds diff --git a/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/cpd/testdata/unlexable_sample.scala b/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/cpd/testdata/unclosed_literal.scala similarity index 100% rename from pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/cpd/testdata/unlexable_sample.scala rename to pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/cpd/testdata/unclosed_literal.scala diff --git a/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/cpd/testdata/unclosed_literal.txt b/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/cpd/testdata/unclosed_literal.txt new file mode 100644 index 00000000000..34d2efbef6e --- /dev/null +++ b/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/cpd/testdata/unclosed_literal.txt @@ -0,0 +1,29 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [object] 1 7 + [Main] 8 12 + [{] 13 14 +L2 + [def] 2 5 + [main] 6 10 + [(] 10 11 + [args] 11 15 + [:] 15 16 + [Array] 17 22 + [\[] 22 23 + [String] 23 29 + [\]] 29 30 + [)] 30 31 + [:] 31 32 + [Unit] 33 37 + [=] 38 39 + [{] 40 41 +L3 + [println] 3 10 + [(] 10 11 + ["Hello, World!) // unclosed liter[ 11 47 +L4 + [}] 2 3 +L5 + [}] 1 2 +EOF diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index 0e18f596a5d..7d15513440e 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -36,7 +36,7 @@ org.scala-lang scala-library - ${scalaVersion}.19 + ${scalaVersion}.20 org.scalameta diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index 23640f722a2..5d815bb324e 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -36,7 +36,7 @@ org.scala-lang scala-library - ${scalaVersion}.13 + ${scalaVersion}.16 org.scalameta From 23c7b0e3016640c262a669c062e1784846da0d2a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2025 03:37:55 +0000 Subject: [PATCH 0471/1962] Bump liquid from 5.7.0 to 5.7.1 in the all-gems group across 1 directory Bumps the all-gems group with 1 update in the / directory: [liquid](https://github.com/Shopify/liquid). Updates `liquid` from 5.7.0 to 5.7.1 - [Release notes](https://github.com/Shopify/liquid/releases) - [Changelog](https://github.com/Shopify/liquid/blob/main/History.md) - [Commits](https://github.com/Shopify/liquid/compare/v5.7.0...v5.7.1) --- updated-dependencies: - dependency-name: liquid dependency-type: direct:development update-type: version-update:semver-patch dependency-group: all-gems ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index fef20fc70f3..b36824f46b5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -50,7 +50,7 @@ GEM rexml kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) - liquid (5.7.0) + liquid (5.7.1) bigdecimal strscan (>= 3.1.1) logger (1.6.1) From 4612e93bb835f732005193f71c4677b9b02fce7e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2025 03:43:45 +0000 Subject: [PATCH 0472/1962] Bump org.codehaus.mojo:versions-maven-plugin from 2.17.1 to 2.18.0 Bumps [org.codehaus.mojo:versions-maven-plugin](https://github.com/mojohaus/versions) from 2.17.1 to 2.18.0. - [Release notes](https://github.com/mojohaus/versions/releases) - [Changelog](https://github.com/mojohaus/versions/blob/master/ReleaseNotes.md) - [Commits](https://github.com/mojohaus/versions/compare/2.17.1...2.18.0) --- updated-dependencies: - dependency-name: org.codehaus.mojo:versions-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f23c89c790b..0fa0f18e906 100644 --- a/pom.xml +++ b/pom.xml @@ -607,7 +607,7 @@ org.codehaus.mojo versions-maven-plugin - 2.17.1 + 2.18.0 org.sonatype.plugins From f4894031ee39c6260fb7fd4f98d03b3fe7f9d6db Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2025 03:43:52 +0000 Subject: [PATCH 0473/1962] Bump org.jetbrains.dokka:dokka-maven-plugin from 1.9.20 to 2.0.0 Bumps [org.jetbrains.dokka:dokka-maven-plugin](https://github.com/Kotlin/dokka) from 1.9.20 to 2.0.0. - [Release notes](https://github.com/Kotlin/dokka/releases) - [Commits](https://github.com/Kotlin/dokka/compare/v1.9.20...v2.0.0) --- updated-dependencies: - dependency-name: org.jetbrains.dokka:dokka-maven-plugin dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f23c89c790b..2098fb29523 100644 --- a/pom.xml +++ b/pom.xml @@ -95,7 +95,7 @@ 1.9.24 5.9.1 5.11.2 - 1.9.20 + 2.0.0 5.0 3.5.2 From 6f88f1c0566282c3332eb1985e77ebec0ae71a51 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2025 03:43:56 +0000 Subject: [PATCH 0474/1962] Bump com.github.hazendaz.maven:coveralls-maven-plugin Bumps [com.github.hazendaz.maven:coveralls-maven-plugin](https://github.com/trautonen/coveralls-maven-plugin) from 4.5.0-M5 to 4.5.0-M6. - [Changelog](https://github.com/trautonen/coveralls-maven-plugin/blob/master/CHANGELOG.md) - [Commits](https://github.com/trautonen/coveralls-maven-plugin/commits) --- updated-dependencies: - dependency-name: com.github.hazendaz.maven:coveralls-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f23c89c790b..a8cf37b8b08 100644 --- a/pom.xml +++ b/pom.xml @@ -1278,7 +1278,7 @@ com.github.hazendaz.maven coveralls-maven-plugin - 4.5.0-M5 + 4.5.0-M6 From 26316006daf5147a228ab887a4133df9c037d409 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2025 03:44:03 +0000 Subject: [PATCH 0475/1962] Bump com.puppycrawl.tools:checkstyle from 10.20.2 to 10.21.2 Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.20.2 to 10.21.2. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.20.2...checkstyle-10.21.2) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f23c89c790b..b441c59a9d5 100644 --- a/pom.xml +++ b/pom.xml @@ -99,7 +99,7 @@ 5.0 3.5.2 - 10.20.2 + 10.21.2 3.6.0 3.26.0 1.10.15 From acbf85dab8f19b7a91be15987ec00896fdcd47e4 Mon Sep 17 00:00:00 2001 From: William Brockhus Date: Thu, 30 Jan 2025 14:14:07 +1100 Subject: [PATCH 0476/1962] [apex] fix false positives in ApexSuggestUsingNamedCredRule --- .../ApexSuggestUsingNamedCredRule.java | 124 ++++++--- .../xml/ApexSuggestUsingNamedCred.xml | 258 ++++++++++++++++++ 2 files changed, 349 insertions(+), 33 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSuggestUsingNamedCredRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSuggestUsingNamedCredRule.java index 935bd80a1cc..f2af171e819 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSuggestUsingNamedCredRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSuggestUsingNamedCredRule.java @@ -32,8 +32,10 @@ public class ApexSuggestUsingNamedCredRule extends AbstractApexRule { private static final String SET_HEADER = "setHeader"; private static final String AUTHORIZATION = "Authorization"; + private static final String CREDENTIAL_PREFIX = "{!$Credential."; private final Set listOfAuthorizationVariables = new HashSet<>(); + private final Set listOfCredentialVariables = new HashSet<>(); @Override protected @NonNull RuleTargetSelector buildTargetSelector() { @@ -47,11 +49,13 @@ public Object visit(ASTUserClass node, Object data) { } for (ASTVariableDeclaration varDecl : node.descendants(ASTVariableDeclaration.class)) { - findAuthLiterals(varDecl); + findAuthVariables(varDecl); + findCredentialVariables(varDecl); } for (ASTField fDecl : node.descendants(ASTField.class)) { - findFieldLiterals(fDecl); + findAuthFields(fDecl); + findCredentialFields(fDecl); } for (ASTMethodCallExpression method : node.descendants(ASTMethodCallExpression.class)) { @@ -59,66 +63,120 @@ public Object visit(ASTUserClass node, Object data) { } listOfAuthorizationVariables.clear(); + listOfCredentialVariables.clear(); return data; } - private void findFieldLiterals(final ASTField fDecl) { + private void findAuthVariables(final ApexNode node) { + ASTLiteralExpression literal = node.firstChild(ASTLiteralExpression.class); + if (literal != null) { + ASTVariableExpression variable = node.firstChild(ASTVariableExpression.class); + if (variable != null) { + if (isAuthorizationLiteral(literal)) { + listOfAuthorizationVariables.add(Helper.getFQVariableName(variable)); + } + } + } + } + + private void findCredentialVariables(final ApexNode node) { + ASTLiteralExpression literal = node.firstChild(ASTLiteralExpression.class); + if (literal != null) { + ASTVariableExpression variable = node.firstChild(ASTVariableExpression.class); + if (variable != null) { + if (isCredentialLiteral(literal)) { + listOfCredentialVariables.add(Helper.getFQVariableName(variable)); + } + } + } + } + + private void findAuthFields(final ASTField fDecl) { if ("String".equals(fDecl.getType()) && AUTHORIZATION.equalsIgnoreCase(fDecl.getValue())) { listOfAuthorizationVariables.add(Helper.getFQVariableName(fDecl)); } } - private void flagAuthorizationHeaders(final ASTMethodCallExpression node, Object data) { - if (!Helper.isMethodName(node, SET_HEADER)) { + private void findCredentialFields(final ASTField fDecl) { + if (!"String".equals(fDecl.getType())) { return; } - final ASTBinaryExpression binaryNode = node.firstChild(ASTBinaryExpression.class); - if (binaryNode != null) { - runChecks(binaryNode, data); - } + String value = fDecl.getValue(); - runChecks(node, data); + if (value == null) { + return; + } + if (value.contains(CREDENTIAL_PREFIX)) { + listOfCredentialVariables.add(Helper.getFQVariableName(fDecl)); + } } - private void findAuthLiterals(final ApexNode node) { - ASTLiteralExpression literal = node.firstChild(ASTLiteralExpression.class); - if (literal != null) { - ASTVariableExpression variable = node.firstChild(ASTVariableExpression.class); - if (variable != null) { - if (isAuthorizationLiteral(literal)) { - listOfAuthorizationVariables.add(Helper.getFQVariableName(variable)); - } - } + private void flagAuthorizationHeaders(final ASTMethodCallExpression node, Object data) { + if (!Helper.isMethodName(node, SET_HEADER)) { + return; } + + runChecks(node, data); } private void runChecks(final ApexNode node, Object data) { - ASTLiteralExpression literalNode = node.firstChild(ASTLiteralExpression.class); - if (literalNode != null) { - if (isAuthorizationLiteral(literalNode)) { - asCtx(data).addViolation(literalNode); - } + ApexNode keyNode = node.getChild(1); + ApexNode valueNode = node.getChild(2); + + if (keyNode == null || !isAuthorizationReference(keyNode)) { + return; } - final ASTVariableExpression varNode = node.firstChild(ASTVariableExpression.class); - if (varNode != null) { - if (listOfAuthorizationVariables.contains(Helper.getFQVariableName(varNode))) { - asCtx(data).addViolation(varNode); - } + if (valueNode == null || !isCredentialReference(valueNode)) { + asCtx(data).addViolation(keyNode); + } + } + + private boolean isAuthorizationReference(final ApexNode node) { + if (node instanceof ASTLiteralExpression) { + return isAuthorizationLiteral((ASTLiteralExpression) node); + } + if (node instanceof ASTVariableExpression) { + return isAuthorizationVariable((ASTVariableExpression) node); } + return node instanceof ASTBinaryExpression && isAuthorizationReference(node.getChild(0)); } private boolean isAuthorizationLiteral(final ASTLiteralExpression literal) { - if (literal.isString()) { - String lit = literal.getImage(); - if (AUTHORIZATION.equalsIgnoreCase(lit)) { + return literal.isString() && AUTHORIZATION.equalsIgnoreCase(literal.getImage()); + } + + private boolean isAuthorizationVariable(final ASTVariableExpression variable) { + return listOfAuthorizationVariables.contains(Helper.getFQVariableName(variable)); + } + + private boolean isCredentialReference(ApexNode node) { + if (node instanceof ASTLiteralExpression) { + return isCredentialLiteral((ASTLiteralExpression) node); + } + if (node instanceof ASTVariableExpression) { + return isCredentialVariable((ASTVariableExpression) node); + } + return node instanceof ASTBinaryExpression && isCredentialBinaryExpression((ASTBinaryExpression) node); + } + + private boolean isCredentialLiteral(final ASTLiteralExpression literal) { + return literal.isString() && literal.getImage().contains(CREDENTIAL_PREFIX); + } + + private boolean isCredentialVariable(final ASTVariableExpression variable) { + return listOfCredentialVariables.contains(Helper.getFQVariableName(variable)); + } + + private boolean isCredentialBinaryExpression(ASTBinaryExpression binaryExpression) { + for (int i = 0; i < binaryExpression.getNumChildren(); i++) { + if (isCredentialReference(binaryExpression.getChild(i))) { return true; } } - return false; } } diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/security/xml/ApexSuggestUsingNamedCred.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/security/xml/ApexSuggestUsingNamedCred.xml index f28beddb4f4..d260fb34055 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/security/xml/ApexSuggestUsingNamedCred.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/security/xml/ApexSuggestUsingNamedCred.xml @@ -51,4 +51,262 @@ public class Foo { } ]]> + + + key Authorization as literal negative + 0 + + + + + key Authorization as literal positive + 1 + + + + + key Authorization as variable negative + 0 + + + + + key Authorization as variable positive + 1 + + + + + key Authorization as field negative + 0 + + + + + key Authorization as field positive + 1 + + + + + key Authorization as binary expression first negative + 0 + + + + + key Authorization as binary expression nonfirst negative + 0 + + + + + key Authorization as binary expression positive + 1 + + + + + value as literal negative + 0 + + + + + value as literal positive + 1 + + + + + value as variable negative + 0 + + + + + value as variable positive + 1 + + + + + value as field negative + 0 + + + + + value as field positive + 1 + + + + + value as binary expression literal negative + 0 + + + + + value as binary expression variable negative + 0 + + + + + value as binary expression literal positive + 1 + + + + + value as binary expression variable positive + 1 + + + From d2114fa3080021b6504dd5657dd6aecb2f1000e6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 30 Jan 2025 09:26:01 +0100 Subject: [PATCH 0477/1962] Apply suggestions from code review --- .../lang/apex/rule/security/xml/ApexSuggestUsingNamedCred.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/security/xml/ApexSuggestUsingNamedCred.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/security/xml/ApexSuggestUsingNamedCred.xml index d260fb34055..695a3f8283f 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/security/xml/ApexSuggestUsingNamedCred.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/security/xml/ApexSuggestUsingNamedCred.xml @@ -174,7 +174,7 @@ public class Foo { - value as literal negative + #3158 value as literal negative 0 - value as variable negative + #3158 value as variable negative 0 Date: Thu, 30 Jan 2025 09:28:13 +0100 Subject: [PATCH 0478/1962] [doc] Update release notes (#3158, #5488) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 9f96a9d48d9..c4c6961fd66 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -40,6 +40,8 @@ For the changes, see [PMD Designer Changelog (7.10.0)](https://github.com/pmd/pm * apex * [#5388](https://github.com/pmd/pmd/issues/5388): \[apex] Parse error with time literal in SOQL query * [#5456](https://github.com/pmd/pmd/issues/5456): \[apex] Issue with java dependency apex-parser-4.3.1 but apex-parser-4.3.0 works +* apex-security + * [#3158](https://github.com/pmd/pmd/issues/3158): \[apex] ApexSuggestUsingNamedCred false positive with Named Credential merge fields * documentation * [#2492](https://github.com/pmd/pmd/issues/2492): \[doc] Promote wiki pages to standard doc pages @@ -47,6 +49,7 @@ For the changes, see [PMD Designer Changelog (7.10.0)](https://github.com/pmd/pm ### โœจ Merged pull requests +* [#5488](https://github.com/pmd/pmd/pull/5488): \[apex] Fix #3158: Recognize Named Credentials merge fields in ApexSuggestUsingNamedCredRule - [William Brockhus](https://github.com/YodaDaCoda) (@YodaDaCoda) ### ๐Ÿ“ฆ Dependency updates From 64c52c884fa733f66344a8f3a0af77e31a862a3e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 30 Jan 2025 10:09:19 +0100 Subject: [PATCH 0479/1962] [doc] Update release notes (#5412) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index d08c106943e..911e36a07d0 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -52,6 +52,7 @@ and [CVE-2025-23215](https://www.cve.org/CVERecord?id=CVE-2025-23215). ### โœจ Merged pull requests +* [#5412](https://github.com/pmd/pmd/pull/5412): \[java] Support exhaustive switches - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ Dependency updates From f8f81e48c3a4bcc7d89c2751607f5347a04d4535 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 30 Jan 2025 10:14:57 +0100 Subject: [PATCH 0480/1962] Add @esc-sbarden as a contributor --- .all-contributorsrc | 9 +++ docs/pages/pmd/projectdocs/credits.md | 83 ++++++++++++++------------- 2 files changed, 51 insertions(+), 41 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 430b3a022d6..78f4dde04c7 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7911,6 +7911,15 @@ "contributions": [ "doc" ] + }, + { + "login": "esc-sbarden", + "name": "Sven Barden", + "avatar_url": "https://avatars.githubusercontent.com/u/108530649?v=4", + "profile": "https://github.com/esc-sbarden", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 36a1f99ca39..1678f740943 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -759,369 +759,370 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Supun Arunoda
    Supun Arunoda

    ๐Ÿ› Suren Abrahamyan
    Suren Abrahamyan

    ๐Ÿ› Suvashri
    Suvashri

    ๐Ÿ“– - SwatiBGupta1110
    SwatiBGupta1110

    ๐Ÿ› + Sven Barden
    Sven Barden

    ๐Ÿ› + SwatiBGupta1110
    SwatiBGupta1110

    ๐Ÿ› SyedThoufich
    SyedThoufich

    ๐Ÿ› Szymon Sasin
    Szymon Sasin

    ๐Ÿ› T-chuangxin
    T-chuangxin

    ๐Ÿ› TERAI Atsuhiro
    TERAI Atsuhiro

    ๐Ÿ› TIOBE Software
    TIOBE Software

    ๐Ÿ’ป ๐Ÿ› Tarush Singh
    Tarush Singh

    ๐Ÿ’ป - Taylor Smock
    Taylor Smock

    ๐Ÿ› + Taylor Smock
    Taylor Smock

    ๐Ÿ› Techeira Damiรกn
    Techeira Damiรกn

    ๐Ÿ’ป ๐Ÿ› Ted Husted
    Ted Husted

    ๐Ÿ› TehBakker
    TehBakker

    ๐Ÿ› The Gitter Badger
    The Gitter Badger

    ๐Ÿ› Theodoor
    Theodoor

    ๐Ÿ› Thiago Henrique Hรผpner
    Thiago Henrique Hรผpner

    ๐Ÿ› - Thibault Meyer
    Thibault Meyer

    ๐Ÿ› + Thibault Meyer
    Thibault Meyer

    ๐Ÿ› Thomas Gรผttler
    Thomas Gรผttler

    ๐Ÿ› Thomas Jones-Low
    Thomas Jones-Low

    ๐Ÿ› Thomas Smith
    Thomas Smith

    ๐Ÿ’ป ๐Ÿ› ThrawnCA
    ThrawnCA

    ๐Ÿ› Thu Vo
    Thu Vo

    ๐Ÿ› Thunderforge
    Thunderforge

    ๐Ÿ’ป ๐Ÿ› - Tim van der Lippe
    Tim van der Lippe

    ๐Ÿ› + Tim van der Lippe
    Tim van der Lippe

    ๐Ÿ› Tobias Weimer
    Tobias Weimer

    ๐Ÿ’ป ๐Ÿ› Tom Copeland
    Tom Copeland

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– Tom Daly
    Tom Daly

    ๐Ÿ› Tomas
    Tomas

    ๐Ÿ› Tomer Figenblat
    Tomer Figenblat

    ๐Ÿ› Tomi De Lucca
    Tomi De Lucca

    ๐Ÿ’ป ๐Ÿ› - Tony
    Tony

    ๐Ÿ“– + Tony
    Tony

    ๐Ÿ“– Torsten Kleiber
    Torsten Kleiber

    ๐Ÿ› TrackerSB
    TrackerSB

    ๐Ÿ› Tyson Stewart
    Tyson Stewart

    ๐Ÿ› Ullrich Hafner
    Ullrich Hafner

    ๐Ÿ› Utku Cuhadaroglu
    Utku Cuhadaroglu

    ๐Ÿ’ป ๐Ÿ› Valentin Brandl
    Valentin Brandl

    ๐Ÿ› - Valeria
    Valeria

    ๐Ÿ› + Valeria
    Valeria

    ๐Ÿ› Valery Yatsynovich
    Valery Yatsynovich

    ๐Ÿ“– Vasily Anisimov
    Vasily Anisimov

    ๐Ÿ› Vedant Chokshi
    Vedant Chokshi

    ๐Ÿ› Vibhor Goyal
    Vibhor Goyal

    ๐Ÿ› Vickenty Fesunov
    Vickenty Fesunov

    ๐Ÿ› Victor Noรซl
    Victor Noรซl

    ๐Ÿ› - Vincent Galloy
    Vincent Galloy

    ๐Ÿ’ป + Vincent Galloy
    Vincent Galloy

    ๐Ÿ’ป Vincent HUYNH
    Vincent HUYNH

    ๐Ÿ› Vincent Maurin
    Vincent Maurin

    ๐Ÿ› Vincent Privat
    Vincent Privat

    ๐Ÿ› Vishhwas
    Vishhwas

    ๐Ÿ› Vishv_Android
    Vishv_Android

    ๐Ÿ› Vitalii Yevtushenko
    Vitalii Yevtushenko

    ๐Ÿ› - Vitaly
    Vitaly

    ๐Ÿ› + Vitaly
    Vitaly

    ๐Ÿ› Vitaly Polonetsky
    Vitaly Polonetsky

    ๐Ÿ› Vojtech Polivka
    Vojtech Polivka

    ๐Ÿ› Vsevolod Zholobov
    Vsevolod Zholobov

    ๐Ÿ› Vyom Yadav
    Vyom Yadav

    ๐Ÿ’ป Wang Shidong
    Wang Shidong

    ๐Ÿ› Waqas Ahmed
    Waqas Ahmed

    ๐Ÿ› - Wayne J. Earl
    Wayne J. Earl

    ๐Ÿ› + Wayne J. Earl
    Wayne J. Earl

    ๐Ÿ› Wchenghui
    Wchenghui

    ๐Ÿ› Wener
    Wener

    ๐Ÿ’ป Will Winder
    Will Winder

    ๐Ÿ› Willem A. Hajenius
    Willem A. Hajenius

    ๐Ÿ’ป William Brockhus
    William Brockhus

    ๐Ÿ’ป ๐Ÿ› Wilson Kurniawan
    Wilson Kurniawan

    ๐Ÿ› - Wim Deblauwe
    Wim Deblauwe

    ๐Ÿ› + Wim Deblauwe
    Wim Deblauwe

    ๐Ÿ› Woongsik Choi
    Woongsik Choi

    ๐Ÿ› XenoAmess
    XenoAmess

    ๐Ÿ’ป ๐Ÿ› Yang
    Yang

    ๐Ÿ’ป YaroslavTER
    YaroslavTER

    ๐Ÿ› Yasar Shaikh
    Yasar Shaikh

    ๐Ÿ’ป Young Chan
    Young Chan

    ๐Ÿ’ป ๐Ÿ› - YuJin Kim
    YuJin Kim

    ๐Ÿ› + YuJin Kim
    YuJin Kim

    ๐Ÿ› Yuri Dolzhenko
    Yuri Dolzhenko

    ๐Ÿ› Yurii Dubinka
    Yurii Dubinka

    ๐Ÿ› Zoltan Farkas
    Zoltan Farkas

    ๐Ÿ› Zustin
    Zustin

    ๐Ÿ› aaronhurst-google
    aaronhurst-google

    ๐Ÿ› ๐Ÿ’ป alexmodis
    alexmodis

    ๐Ÿ› - andreoss
    andreoss

    ๐Ÿ› + andreoss
    andreoss

    ๐Ÿ› andrey81inmd
    andrey81inmd

    ๐Ÿ’ป ๐Ÿ› anicoara
    anicoara

    ๐Ÿ› arunprasathav
    arunprasathav

    ๐Ÿ› asiercamara
    asiercamara

    ๐Ÿ› astillich-igniti
    astillich-igniti

    ๐Ÿ’ป avesolovksyy
    avesolovksyy

    ๐Ÿ› - avishvat
    avishvat

    ๐Ÿ› + avishvat
    avishvat

    ๐Ÿ› avivmu
    avivmu

    ๐Ÿ› axelbarfod1
    axelbarfod1

    ๐Ÿ› b-3-n
    b-3-n

    ๐Ÿ› balbhadra9
    balbhadra9

    ๐Ÿ› base23de
    base23de

    ๐Ÿ› bergander
    bergander

    ๐Ÿ› ๐Ÿ’ป - berkam
    berkam

    ๐Ÿ’ป ๐Ÿ› + berkam
    berkam

    ๐Ÿ’ป ๐Ÿ› breizh31
    breizh31

    ๐Ÿ› caesarkim
    caesarkim

    ๐Ÿ› carolyujing
    carolyujing

    ๐Ÿ› cbfiddle
    cbfiddle

    ๐Ÿ› cesares-basilico
    cesares-basilico

    ๐Ÿ› chrite
    chrite

    ๐Ÿ› - ciufudean
    ciufudean

    ๐Ÿ“– + ciufudean
    ciufudean

    ๐Ÿ“– cobratbq
    cobratbq

    ๐Ÿ› coladict
    coladict

    ๐Ÿ› cosmoJFH
    cosmoJFH

    ๐Ÿ› cristalp
    cristalp

    ๐Ÿ› crunsk
    crunsk

    ๐Ÿ› cwholmes
    cwholmes

    ๐Ÿ› - cyberjj999
    cyberjj999

    ๐Ÿ› + cyberjj999
    cyberjj999

    ๐Ÿ› cyw3
    cyw3

    ๐Ÿ› ๐Ÿ“– d1ss0nanz
    d1ss0nanz

    ๐Ÿ› dague1
    dague1

    ๐Ÿ“– dalizi007
    dalizi007

    ๐Ÿ’ป danbrycefairsailcom
    danbrycefairsailcom

    ๐Ÿ› dariansanity
    dariansanity

    ๐Ÿ› - darrenmiliband
    darrenmiliband

    ๐Ÿ› + darrenmiliband
    darrenmiliband

    ๐Ÿ› davidburstrom
    davidburstrom

    ๐Ÿ› dbirkman-paloalto
    dbirkman-paloalto

    ๐Ÿ› deepak-patra
    deepak-patra

    ๐Ÿ› dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› dinesh150
    dinesh150

    ๐Ÿ› diziaq
    diziaq

    ๐Ÿ› - dreaminpast123
    dreaminpast123

    ๐Ÿ› + dreaminpast123
    dreaminpast123

    ๐Ÿ› duanyanan
    duanyanan

    ๐Ÿ› dutt-sanjay
    dutt-sanjay

    ๐Ÿ› duursma
    duursma

    ๐Ÿ’ป dylanleung
    dylanleung

    ๐Ÿ› dzeigler
    dzeigler

    ๐Ÿ› eant60
    eant60

    ๐Ÿ› - ekkirala
    ekkirala

    ๐Ÿ› + ekkirala
    ekkirala

    ๐Ÿ› emersonmoura
    emersonmoura

    ๐Ÿ› emouty
    emouty

    ๐Ÿ’ป ๐Ÿ› eugenepugach
    eugenepugach

    ๐Ÿ› fairy
    fairy

    ๐Ÿ› filiprafalowicz
    filiprafalowicz

    ๐Ÿ’ป flxbl-io
    flxbl-io

    ๐Ÿ’ต - foxmason
    foxmason

    ๐Ÿ› + foxmason
    foxmason

    ๐Ÿ› frankegabor
    frankegabor

    ๐Ÿ› frankl
    frankl

    ๐Ÿ› freafrea
    freafrea

    ๐Ÿ› fsapatin
    fsapatin

    ๐Ÿ› gearsethenry
    gearsethenry

    ๐Ÿ› gracia19
    gracia19

    ๐Ÿ› - gudzpoz
    gudzpoz

    ๐Ÿ› + gudzpoz
    gudzpoz

    ๐Ÿ› guo fei
    guo fei

    ๐Ÿ› gurmsc5
    gurmsc5

    ๐Ÿ› gwilymatgearset
    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ› haigsn
    haigsn

    ๐Ÿ› hemanshu070
    hemanshu070

    ๐Ÿ› henrik242
    henrik242

    ๐Ÿ› - hongpuwu
    hongpuwu

    ๐Ÿ› + hongpuwu
    hongpuwu

    ๐Ÿ› hvbtup
    hvbtup

    ๐Ÿ’ป ๐Ÿ› igniti GmbH
    igniti GmbH

    ๐Ÿ› ilovezfs
    ilovezfs

    ๐Ÿ› imax-erik
    imax-erik

    ๐Ÿ› itaigilo
    itaigilo

    ๐Ÿ› jakivey32
    jakivey32

    ๐Ÿ› - jbennett2091
    jbennett2091

    ๐Ÿ› + jbennett2091
    jbennett2091

    ๐Ÿ› jcamerin
    jcamerin

    ๐Ÿ› jkeener1
    jkeener1

    ๐Ÿ› jmetertea
    jmetertea

    ๐Ÿ› johnra2
    johnra2

    ๐Ÿ’ป johnzhao9
    johnzhao9

    ๐Ÿ› josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ› - kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ› + kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ› karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“– karwer
    karwer

    ๐Ÿ› kaulonline
    kaulonline

    ๐Ÿ› kdaemonv
    kdaemonv

    ๐Ÿ› kdebski85
    kdebski85

    ๐Ÿ› ๐Ÿ’ป kenji21
    kenji21

    ๐Ÿ’ป ๐Ÿ› - kfranic
    kfranic

    ๐Ÿ› + kfranic
    kfranic

    ๐Ÿ› khalidkh
    khalidkh

    ๐Ÿ› koalalam
    koalalam

    ๐Ÿ› krzyk
    krzyk

    ๐Ÿ› lasselindqvist
    lasselindqvist

    ๐Ÿ› lgemeinhardt
    lgemeinhardt

    ๐Ÿ› lihuaib
    lihuaib

    ๐Ÿ› - liqingjun123
    liqingjun123

    ๐Ÿ› + liqingjun123
    liqingjun123

    ๐Ÿ› lonelyma1021
    lonelyma1021

    ๐Ÿ› lpeddy
    lpeddy

    ๐Ÿ› lujiefsi
    lujiefsi

    ๐Ÿ’ป lukelukes
    lukelukes

    ๐Ÿ’ป lyriccoder
    lyriccoder

    ๐Ÿ› marcelmore
    marcelmore

    ๐Ÿ› - matchbox
    matchbox

    ๐Ÿ› + matchbox
    matchbox

    ๐Ÿ› matthiaskraaz
    matthiaskraaz

    ๐Ÿ› meandonlyme
    meandonlyme

    ๐Ÿ› mikesive
    mikesive

    ๐Ÿ› milossesic
    milossesic

    ๐Ÿ› mluckam
    mluckam

    ๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
    mohan-chinnappan-n

    ๐Ÿ’ป - mriddell95
    mriddell95

    ๐Ÿ› + mriddell95
    mriddell95

    ๐Ÿ› mrlzh
    mrlzh

    ๐Ÿ› msloan
    msloan

    ๐Ÿ› mucharlaravalika
    mucharlaravalika

    ๐Ÿ› mvenneman
    mvenneman

    ๐Ÿ› nareshl119
    nareshl119

    ๐Ÿ› nicolas-harraudeau-sonarsource
    nicolas-harraudeau-sonarsource

    ๐Ÿ› - noerremark
    noerremark

    ๐Ÿ› + noerremark
    noerremark

    ๐Ÿ› novsirion
    novsirion

    ๐Ÿ› nwcm
    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
    oggboy

    ๐Ÿ› oinume
    oinume

    ๐Ÿ› orimarko
    orimarko

    ๐Ÿ’ป ๐Ÿ› pablogomez2197
    pablogomez2197

    ๐Ÿ› - pacvz
    pacvz

    ๐Ÿ’ป + pacvz
    pacvz

    ๐Ÿ’ป pallavi agarwal
    pallavi agarwal

    ๐Ÿ› parksungrin
    parksungrin

    ๐Ÿ› patpatpat123
    patpatpat123

    ๐Ÿ› patriksevallius
    patriksevallius

    ๐Ÿ› pbrajesh1
    pbrajesh1

    ๐Ÿ› phoenix384
    phoenix384

    ๐Ÿ› - piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป + piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป plan3d
    plan3d

    ๐Ÿ› poojasix
    poojasix

    ๐Ÿ› prabhushrikant
    prabhushrikant

    ๐Ÿ› pujitha8783
    pujitha8783

    ๐Ÿ› r-r-a-j
    r-r-a-j

    ๐Ÿ› raghujayjunk
    raghujayjunk

    ๐Ÿ› - rajeshveera
    rajeshveera

    ๐Ÿ› + rajeshveera
    rajeshveera

    ๐Ÿ› rajeswarreddy88
    rajeswarreddy88

    ๐Ÿ› recdevs
    recdevs

    ๐Ÿ› reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ› rijkt
    rijkt

    ๐Ÿ› rillig-tk
    rillig-tk

    ๐Ÿ› rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ› - rnveach
    rnveach

    ๐Ÿ› + rnveach
    rnveach

    ๐Ÿ› rxmicro
    rxmicro

    ๐Ÿ› ryan-gustafson
    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ› sabi0
    sabi0

    ๐Ÿ› samc-gearset
    samc-gearset

    ๐Ÿ“– scais
    scais

    ๐Ÿ› schosin
    schosin

    ๐Ÿ› - screamingfrog
    screamingfrog

    ๐Ÿ’ต + screamingfrog
    screamingfrog

    ๐Ÿ’ต sebbASF
    sebbASF

    ๐Ÿ› sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป shilko2013
    shilko2013

    ๐Ÿ› shiomiyan
    shiomiyan

    ๐Ÿ“– simeonKondr
    simeonKondr

    ๐Ÿ› snajberk
    snajberk

    ๐Ÿ› - sniperrifle2004
    sniperrifle2004

    ๐Ÿ› + sniperrifle2004
    sniperrifle2004

    ๐Ÿ› snuyanzin
    snuyanzin

    ๐Ÿ› ๐Ÿ’ป soloturn
    soloturn

    ๐Ÿ› soyodream
    soyodream

    ๐Ÿ› sratz
    sratz

    ๐Ÿ› stonio
    stonio

    ๐Ÿ› sturton
    sturton

    ๐Ÿ’ป ๐Ÿ› - sudharmohan
    sudharmohan

    ๐Ÿ› + sudharmohan
    sudharmohan

    ๐Ÿ› suruchidawar
    suruchidawar

    ๐Ÿ› svenfinitiv
    svenfinitiv

    ๐Ÿ› szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป tashiscool
    tashiscool

    ๐Ÿ› test-git-hook
    test-git-hook

    ๐Ÿ› testation21
    testation21

    ๐Ÿ’ป ๐Ÿ› - thanosa
    thanosa

    ๐Ÿ› + thanosa
    thanosa

    ๐Ÿ› tiandiyixian
    tiandiyixian

    ๐Ÿ› tobwoerk
    tobwoerk

    ๐Ÿ› tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป trentchilders
    trentchilders

    ๐Ÿ› triandicAnt
    triandicAnt

    ๐Ÿ› trishul14
    trishul14

    ๐Ÿ› - tsui
    tsui

    ๐Ÿ› + tsui
    tsui

    ๐Ÿ› wangzitom12306
    wangzitom12306

    ๐Ÿ› winhkey
    winhkey

    ๐Ÿ› witherspore
    witherspore

    ๐Ÿ› wjljack
    wjljack

    ๐Ÿ› wuchiuwong
    wuchiuwong

    ๐Ÿ› xingsong
    xingsong

    ๐Ÿ› - xioayuge
    xioayuge

    ๐Ÿ› + xioayuge
    xioayuge

    ๐Ÿ› xnYi9wRezm
    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ› xuanuy
    xuanuy

    ๐Ÿ› xyf0921
    xyf0921

    ๐Ÿ› yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› yasuharu-sato
    yasuharu-sato

    ๐Ÿ› zenglian
    zenglian

    ๐Ÿ› - zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› + zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› zh3ng
    zh3ng

    ๐Ÿ› zt_soft
    zt_soft

    ๐Ÿ› ztt79
    ztt79

    ๐Ÿ› zzzzfeng
    zzzzfeng

    ๐Ÿ› รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› ไปป่ดตๆฐ
    ไปป่ดตๆฐ

    ๐Ÿ› - ๅคฉ็ƒญๅƒ่ฅฟ็“œ
    ๅคฉ็ƒญๅƒ่ฅฟ็“œ

    ๐Ÿ› + ๅคฉ็ƒญๅƒ่ฅฟ็“œ
    ๅคฉ็ƒญๅƒ่ฅฟ็“œ

    ๐Ÿ› ่Œ…ๅปถๅฎ‰
    ่Œ…ๅปถๅฎ‰

    ๐Ÿ’ป From 42fc62c7a5196fc1ce1c30425aabc5a5518797a5 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 30 Jan 2025 10:16:09 +0100 Subject: [PATCH 0481/1962] Add @caiocarvalhotero as a contributor --- .all-contributorsrc | 9 +++++ docs/pages/pmd/projectdocs/credits.md | 55 ++++++++++++++------------- 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 78f4dde04c7..f1e3bd6f15f 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7920,6 +7920,15 @@ "contributions": [ "bug" ] + }, + { + "login": "caiocarvalhotero", + "name": "caiocarvalhotero", + "avatar_url": "https://avatars.githubusercontent.com/u/143206673?v=4", + "profile": "https://github.com/caiocarvalhotero", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 1678f740943..fd96b21e22a 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -882,246 +882,247 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d berkam
    berkam

    ๐Ÿ’ป ๐Ÿ› breizh31
    breizh31

    ๐Ÿ› caesarkim
    caesarkim

    ๐Ÿ› + caiocarvalhotero
    caiocarvalhotero

    ๐Ÿ› carolyujing
    carolyujing

    ๐Ÿ› cbfiddle
    cbfiddle

    ๐Ÿ› cesares-basilico
    cesares-basilico

    ๐Ÿ› - chrite
    chrite

    ๐Ÿ› + chrite
    chrite

    ๐Ÿ› ciufudean
    ciufudean

    ๐Ÿ“– cobratbq
    cobratbq

    ๐Ÿ› coladict
    coladict

    ๐Ÿ› cosmoJFH
    cosmoJFH

    ๐Ÿ› cristalp
    cristalp

    ๐Ÿ› crunsk
    crunsk

    ๐Ÿ› - cwholmes
    cwholmes

    ๐Ÿ› + cwholmes
    cwholmes

    ๐Ÿ› cyberjj999
    cyberjj999

    ๐Ÿ› cyw3
    cyw3

    ๐Ÿ› ๐Ÿ“– d1ss0nanz
    d1ss0nanz

    ๐Ÿ› dague1
    dague1

    ๐Ÿ“– dalizi007
    dalizi007

    ๐Ÿ’ป danbrycefairsailcom
    danbrycefairsailcom

    ๐Ÿ› - dariansanity
    dariansanity

    ๐Ÿ› + dariansanity
    dariansanity

    ๐Ÿ› darrenmiliband
    darrenmiliband

    ๐Ÿ› davidburstrom
    davidburstrom

    ๐Ÿ› dbirkman-paloalto
    dbirkman-paloalto

    ๐Ÿ› deepak-patra
    deepak-patra

    ๐Ÿ› dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› dinesh150
    dinesh150

    ๐Ÿ› - diziaq
    diziaq

    ๐Ÿ› + diziaq
    diziaq

    ๐Ÿ› dreaminpast123
    dreaminpast123

    ๐Ÿ› duanyanan
    duanyanan

    ๐Ÿ› dutt-sanjay
    dutt-sanjay

    ๐Ÿ› duursma
    duursma

    ๐Ÿ’ป dylanleung
    dylanleung

    ๐Ÿ› dzeigler
    dzeigler

    ๐Ÿ› - eant60
    eant60

    ๐Ÿ› + eant60
    eant60

    ๐Ÿ› ekkirala
    ekkirala

    ๐Ÿ› emersonmoura
    emersonmoura

    ๐Ÿ› emouty
    emouty

    ๐Ÿ’ป ๐Ÿ› eugenepugach
    eugenepugach

    ๐Ÿ› fairy
    fairy

    ๐Ÿ› filiprafalowicz
    filiprafalowicz

    ๐Ÿ’ป - flxbl-io
    flxbl-io

    ๐Ÿ’ต + flxbl-io
    flxbl-io

    ๐Ÿ’ต foxmason
    foxmason

    ๐Ÿ› frankegabor
    frankegabor

    ๐Ÿ› frankl
    frankl

    ๐Ÿ› freafrea
    freafrea

    ๐Ÿ› fsapatin
    fsapatin

    ๐Ÿ› gearsethenry
    gearsethenry

    ๐Ÿ› - gracia19
    gracia19

    ๐Ÿ› + gracia19
    gracia19

    ๐Ÿ› gudzpoz
    gudzpoz

    ๐Ÿ› guo fei
    guo fei

    ๐Ÿ› gurmsc5
    gurmsc5

    ๐Ÿ› gwilymatgearset
    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ› haigsn
    haigsn

    ๐Ÿ› hemanshu070
    hemanshu070

    ๐Ÿ› - henrik242
    henrik242

    ๐Ÿ› + henrik242
    henrik242

    ๐Ÿ› hongpuwu
    hongpuwu

    ๐Ÿ› hvbtup
    hvbtup

    ๐Ÿ’ป ๐Ÿ› igniti GmbH
    igniti GmbH

    ๐Ÿ› ilovezfs
    ilovezfs

    ๐Ÿ› imax-erik
    imax-erik

    ๐Ÿ› itaigilo
    itaigilo

    ๐Ÿ› - jakivey32
    jakivey32

    ๐Ÿ› + jakivey32
    jakivey32

    ๐Ÿ› jbennett2091
    jbennett2091

    ๐Ÿ› jcamerin
    jcamerin

    ๐Ÿ› jkeener1
    jkeener1

    ๐Ÿ› jmetertea
    jmetertea

    ๐Ÿ› johnra2
    johnra2

    ๐Ÿ’ป johnzhao9
    johnzhao9

    ๐Ÿ› - josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ› + josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ› kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ› karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“– karwer
    karwer

    ๐Ÿ› kaulonline
    kaulonline

    ๐Ÿ› kdaemonv
    kdaemonv

    ๐Ÿ› kdebski85
    kdebski85

    ๐Ÿ› ๐Ÿ’ป - kenji21
    kenji21

    ๐Ÿ’ป ๐Ÿ› + kenji21
    kenji21

    ๐Ÿ’ป ๐Ÿ› kfranic
    kfranic

    ๐Ÿ› khalidkh
    khalidkh

    ๐Ÿ› koalalam
    koalalam

    ๐Ÿ› krzyk
    krzyk

    ๐Ÿ› lasselindqvist
    lasselindqvist

    ๐Ÿ› lgemeinhardt
    lgemeinhardt

    ๐Ÿ› - lihuaib
    lihuaib

    ๐Ÿ› + lihuaib
    lihuaib

    ๐Ÿ› liqingjun123
    liqingjun123

    ๐Ÿ› lonelyma1021
    lonelyma1021

    ๐Ÿ› lpeddy
    lpeddy

    ๐Ÿ› lujiefsi
    lujiefsi

    ๐Ÿ’ป lukelukes
    lukelukes

    ๐Ÿ’ป lyriccoder
    lyriccoder

    ๐Ÿ› - marcelmore
    marcelmore

    ๐Ÿ› + marcelmore
    marcelmore

    ๐Ÿ› matchbox
    matchbox

    ๐Ÿ› matthiaskraaz
    matthiaskraaz

    ๐Ÿ› meandonlyme
    meandonlyme

    ๐Ÿ› mikesive
    mikesive

    ๐Ÿ› milossesic
    milossesic

    ๐Ÿ› mluckam
    mluckam

    ๐Ÿ’ป ๐Ÿ› - mohan-chinnappan-n
    mohan-chinnappan-n

    ๐Ÿ’ป + mohan-chinnappan-n
    mohan-chinnappan-n

    ๐Ÿ’ป mriddell95
    mriddell95

    ๐Ÿ› mrlzh
    mrlzh

    ๐Ÿ› msloan
    msloan

    ๐Ÿ› mucharlaravalika
    mucharlaravalika

    ๐Ÿ› mvenneman
    mvenneman

    ๐Ÿ› nareshl119
    nareshl119

    ๐Ÿ› - nicolas-harraudeau-sonarsource
    nicolas-harraudeau-sonarsource

    ๐Ÿ› + nicolas-harraudeau-sonarsource
    nicolas-harraudeau-sonarsource

    ๐Ÿ› noerremark
    noerremark

    ๐Ÿ› novsirion
    novsirion

    ๐Ÿ› nwcm
    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
    oggboy

    ๐Ÿ› oinume
    oinume

    ๐Ÿ› orimarko
    orimarko

    ๐Ÿ’ป ๐Ÿ› - pablogomez2197
    pablogomez2197

    ๐Ÿ› + pablogomez2197
    pablogomez2197

    ๐Ÿ› pacvz
    pacvz

    ๐Ÿ’ป pallavi agarwal
    pallavi agarwal

    ๐Ÿ› parksungrin
    parksungrin

    ๐Ÿ› patpatpat123
    patpatpat123

    ๐Ÿ› patriksevallius
    patriksevallius

    ๐Ÿ› pbrajesh1
    pbrajesh1

    ๐Ÿ› - phoenix384
    phoenix384

    ๐Ÿ› + phoenix384
    phoenix384

    ๐Ÿ› piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป plan3d
    plan3d

    ๐Ÿ› poojasix
    poojasix

    ๐Ÿ› prabhushrikant
    prabhushrikant

    ๐Ÿ› pujitha8783
    pujitha8783

    ๐Ÿ› r-r-a-j
    r-r-a-j

    ๐Ÿ› - raghujayjunk
    raghujayjunk

    ๐Ÿ› + raghujayjunk
    raghujayjunk

    ๐Ÿ› rajeshveera
    rajeshveera

    ๐Ÿ› rajeswarreddy88
    rajeswarreddy88

    ๐Ÿ› recdevs
    recdevs

    ๐Ÿ› reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ› rijkt
    rijkt

    ๐Ÿ› rillig-tk
    rillig-tk

    ๐Ÿ› - rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ› + rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ› rnveach
    rnveach

    ๐Ÿ› rxmicro
    rxmicro

    ๐Ÿ› ryan-gustafson
    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ› sabi0
    sabi0

    ๐Ÿ› samc-gearset
    samc-gearset

    ๐Ÿ“– scais
    scais

    ๐Ÿ› - schosin
    schosin

    ๐Ÿ› + schosin
    schosin

    ๐Ÿ› screamingfrog
    screamingfrog

    ๐Ÿ’ต sebbASF
    sebbASF

    ๐Ÿ› sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป shilko2013
    shilko2013

    ๐Ÿ› shiomiyan
    shiomiyan

    ๐Ÿ“– simeonKondr
    simeonKondr

    ๐Ÿ› - snajberk
    snajberk

    ๐Ÿ› + snajberk
    snajberk

    ๐Ÿ› sniperrifle2004
    sniperrifle2004

    ๐Ÿ› snuyanzin
    snuyanzin

    ๐Ÿ› ๐Ÿ’ป soloturn
    soloturn

    ๐Ÿ› soyodream
    soyodream

    ๐Ÿ› sratz
    sratz

    ๐Ÿ› stonio
    stonio

    ๐Ÿ› - sturton
    sturton

    ๐Ÿ’ป ๐Ÿ› + sturton
    sturton

    ๐Ÿ’ป ๐Ÿ› sudharmohan
    sudharmohan

    ๐Ÿ› suruchidawar
    suruchidawar

    ๐Ÿ› svenfinitiv
    svenfinitiv

    ๐Ÿ› szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป tashiscool
    tashiscool

    ๐Ÿ› test-git-hook
    test-git-hook

    ๐Ÿ› - testation21
    testation21

    ๐Ÿ’ป ๐Ÿ› + testation21
    testation21

    ๐Ÿ’ป ๐Ÿ› thanosa
    thanosa

    ๐Ÿ› tiandiyixian
    tiandiyixian

    ๐Ÿ› tobwoerk
    tobwoerk

    ๐Ÿ› tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป trentchilders
    trentchilders

    ๐Ÿ› triandicAnt
    triandicAnt

    ๐Ÿ› - trishul14
    trishul14

    ๐Ÿ› + trishul14
    trishul14

    ๐Ÿ› tsui
    tsui

    ๐Ÿ› wangzitom12306
    wangzitom12306

    ๐Ÿ› winhkey
    winhkey

    ๐Ÿ› witherspore
    witherspore

    ๐Ÿ› wjljack
    wjljack

    ๐Ÿ› wuchiuwong
    wuchiuwong

    ๐Ÿ› - xingsong
    xingsong

    ๐Ÿ› + xingsong
    xingsong

    ๐Ÿ› xioayuge
    xioayuge

    ๐Ÿ› xnYi9wRezm
    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ› xuanuy
    xuanuy

    ๐Ÿ› xyf0921
    xyf0921

    ๐Ÿ› yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› yasuharu-sato
    yasuharu-sato

    ๐Ÿ› - zenglian
    zenglian

    ๐Ÿ› + zenglian
    zenglian

    ๐Ÿ› zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› zh3ng
    zh3ng

    ๐Ÿ› zt_soft
    zt_soft

    ๐Ÿ› ztt79
    ztt79

    ๐Ÿ› zzzzfeng
    zzzzfeng

    ๐Ÿ› รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› - ไปป่ดตๆฐ
    ไปป่ดตๆฐ

    ๐Ÿ› + ไปป่ดตๆฐ
    ไปป่ดตๆฐ

    ๐Ÿ› ๅคฉ็ƒญๅƒ่ฅฟ็“œ
    ๅคฉ็ƒญๅƒ่ฅฟ็“œ

    ๐Ÿ› ่Œ…ๅปถๅฎ‰
    ่Œ…ๅปถๅฎ‰

    ๐Ÿ’ป From d16a2d02220cf2932d7f2a86c021f6577ad1e7e6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 30 Jan 2025 10:37:07 +0100 Subject: [PATCH 0482/1962] [java] Fix tests --- ...imitiveTypesInPatternsInstanceofAndSwitch.txt | 16 ++++++++-------- .../java24p/Jep492_FlexibleConstructorBodies.txt | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt index d8b9ab41b32..176fa4a1b63 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt @@ -54,7 +54,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] | | +- VariableDeclarator[@Initializer = true, @Name = "status"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "status", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "getStatus", @MethodName = "getStatus", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ArgumentList[@Empty = true, @Size = 0] @@ -88,7 +88,7 @@ | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "status: ", @Empty = false, @Image = "\"status: \"", @Length = 8, @LiteralText = "\"status: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "status", @Name = "status", @ParenthesisDepth = 0, @Parenthesized = false] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "getYearlyFlights", @MethodName = "getYearlyFlights", @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArgumentList[@Empty = true, @Size = 0] @@ -377,7 +377,7 @@ | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] | | +- VariableDeclarator[@Initializer = true, @Name = "userId"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "userId", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "isLoggedIn", @MethodName = "isLoggedIn", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "user", @Name = "user", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ArgumentList[@Empty = true, @Size = 0] @@ -407,7 +407,7 @@ | | +- VariableDeclarator[@Initializer = true, @Name = "v"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "v", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "12345L", @IntLiteral = false, @Integral = true, @LiteralText = "12345L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 12345.0, @ValueAsFloat = 12345.0, @ValueAsInt = 12345, @ValueAsLong = 12345] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "v", @Name = "v", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] | | | +- SwitchLabel[@Default = false, @PatternLabel = false] @@ -470,7 +470,7 @@ | +- ExpressionStatement[] | | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "fv", @Name = "fv", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "fv", @Name = "fv", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] | | | +- SwitchLabel[@Default = false, @PatternLabel = false] @@ -507,7 +507,7 @@ | +- ExpressionStatement[] | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "dd", @Name = "dd", @ParenthesisDepth = 0, @Parenthesized = false] - | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "dd", @Name = "dd", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | | +- SwitchLabel[@Default = false, @PatternLabel = false] @@ -702,7 +702,7 @@ | +- VariableDeclarator[@Initializer = true, @Name = "i"] | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] - +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] | +- SwitchLabel[@Default = false, @PatternLabel = true] @@ -724,7 +724,7 @@ | +- VariableDeclarator[@Initializer = true, @Name = "b"] | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "b", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] - +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchArrowBranch[@Default = false] +- SwitchLabel[@Default = false, @PatternLabel = true] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep492_FlexibleConstructorBodies.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep492_FlexibleConstructorBodies.txt index 61d9674292b..c010e438de3 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep492_FlexibleConstructorBodies.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep492_FlexibleConstructorBodies.txt @@ -85,7 +85,7 @@ | | | +- ArrayTypeDim[@Varargs = false] | | +- VariableDeclarator[@Initializer = true, @Name = "certBytes"] | | +- VariableId[@ArrayType = true, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "certBytes", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "publicKey", @Name = "publicKey", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] | | | +- SwitchLabel[@Default = false, @PatternLabel = true] From 672dfd0874502a31627f91cf7e715b38bae8d685 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 31 Jan 2025 10:21:54 +0100 Subject: [PATCH 0483/1962] Prepare pmd release 7.10.0 --- docs/_config.yml | 2 +- docs/pages/release_notes.md | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 7796f5fb64f..3f79bc7b503 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,7 +1,7 @@ repository: pmd/pmd pmd: - version: 7.10.0-SNAPSHOT + version: 7.10.0 previous_version: 7.9.0 date: 2025-01-31 # release types: major, minor, bugfix diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 284f679f04d..62c4cf9f03f 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -31,7 +31,7 @@ version `24-preview`: pmd check --use-version java-24-preview ... Note: Support for Java 22 preview language features have been removed. The version "22-preview" -are no longer available. +is no longer available. #### New GPG Release Signing Key @@ -47,7 +47,8 @@ The previous releases of PMD in Maven Central can still be considered untampered This unexpected issue was discovered while checking [Reproducible Builds](https://reproducible-builds.org/) by a third party. -The compromised passphrase is tracked as [GHSA-88m4-h43f-wx84](https://github.com/pmd/pmd/security/advisories/GHSA-88m4-h43f-wx84) +The security advisory about the compromised passphrase is tracked as +[GHSA-88m4-h43f-wx84](https://github.com/pmd/pmd/security/advisories/GHSA-88m4-h43f-wx84) and [CVE-2025-23215](https://www.cve.org/CVERecord?id=CVE-2025-23215). #### Updated PMD Designer @@ -87,15 +88,41 @@ For the changes, see [PMD Designer Changelog (7.10.0)](https://github.com/pmd/pm ### โœจ Merged pull requests +* [#5327](https://github.com/pmd/pmd/pull/5327): \[apex] Update apex-parser and summit-ast - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5412](https://github.com/pmd/pmd/pull/5412): \[java] Support exhaustive switches - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5449](https://github.com/pmd/pmd/pull/5449): Use new gpg key (A0B5CA1A4E086838) - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5458](https://github.com/pmd/pmd/pull/5458): \[doc] Move Wiki pages into main documentation, cleanups - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5471](https://github.com/pmd/pmd/pull/5471): \[java] Support Java 24 - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5488](https://github.com/pmd/pmd/pull/5488): \[apex] Fix #3158: Recognize Named Credentials merge fields in ApexSuggestUsingNamedCredRule - [William Brockhus](https://github.com/YodaDaCoda) (@YodaDaCoda) +* [#5488](https://github.com/pmd/pmd/pull/5488): \[apex] Fix #3158: Recognize Named Credentials merge fields in ApexSuggestUsingNamedCredRule - [William Brockhus](https://github.com/YodaDaCoda) (@YodaDaCoda) ### ๐Ÿ“ฆ Dependency updates +* [#5423](https://github.com/pmd/pmd/pull/5423): Bump PMD from 7.8.0 to 7.9.0 +* [#5433](https://github.com/pmd/pmd/pull/5433): Bump org.codehaus.mojo:exec-maven-plugin from 3.2.0 to 3.5.0 +* [#5434](https://github.com/pmd/pmd/pull/5434): Bump commons-logging:commons-logging from 1.3.0 to 1.3.4 +* [#5435](https://github.com/pmd/pmd/pull/5435): Bump org.apache.maven.plugins:maven-enforcer-plugin from 3.4.1 to 3.5.0 +* [#5436](https://github.com/pmd/pmd/pull/5436): Bump the all-gems group across 2 directories with 1 update +* [#5445](https://github.com/pmd/pmd/pull/5445): Bump org.junit.platform:junit-platform-commons from 1.11.2 to 1.11.4 +* [#5446](https://github.com/pmd/pmd/pull/5446): Bump org.sonarsource.scanner.maven:sonar-maven-plugin from 3.10.0.2594 to 5.0.0.4389 +* [#5459](https://github.com/pmd/pmd/pull/5459): Bump org.apache.maven.plugins:maven-gpg-plugin from 3.1.0 to 3.2.7 +* [#5460](https://github.com/pmd/pmd/pull/5460): Bump org.apache.commons:commons-text from 1.12.0 to 1.13.0 +* [#5461](https://github.com/pmd/pmd/pull/5461): Bump com.google.protobuf:protobuf-java from 4.29.1 to 4.29.3 +* [#5472](https://github.com/pmd/pmd/pull/5472): Bump net.bytebuddy:byte-buddy-agent from 1.15.11 to 1.16.1 +* [#5473](https://github.com/pmd/pmd/pull/5473): Bump org.sonatype.plugins:nexus-staging-maven-plugin from 1.6.13 to 1.7.0 +* [#5474](https://github.com/pmd/pmd/pull/5474): Bump com.github.siom79.japicmp:japicmp-maven-plugin from 0.23.0 to 0.23.1 +* [#5475](https://github.com/pmd/pmd/pull/5475): Bump liquid from 5.6.0 to 5.7.0 in the all-gems group across 1 directory +* [#5479](https://github.com/pmd/pmd/pull/5479): Bump pmd-designer from 7.2.0 to 7.10.0 +* [#5480](https://github.com/pmd/pmd/pull/5480): Bump scalameta.version from 4.9.1 to 4.12.7 +* [#5481](https://github.com/pmd/pmd/pull/5481): Bump liquid from 5.7.0 to 5.7.1 in the all-gems group across 1 directory +* [#5482](https://github.com/pmd/pmd/pull/5482): Bump org.codehaus.mojo:versions-maven-plugin from 2.17.1 to 2.18.0 +* [#5483](https://github.com/pmd/pmd/pull/5483): Bump org.jetbrains.dokka:dokka-maven-plugin from 1.9.20 to 2.0.0 +* [#5484](https://github.com/pmd/pmd/pull/5484): Bump com.github.hazendaz.maven:coveralls-maven-plugin from 4.5.0-M5 to 4.5.0-M6 +* [#5485](https://github.com/pmd/pmd/pull/5485): Bump com.puppycrawl.tools:checkstyle from 10.20.2 to 10.21.2 ### ๐Ÿ“ˆ Stats +* 70 commits +* 13 closed tickets & PRs +* Days since last release: 34 {% endtocmaker %} - From db70a20d4294fda0786145c126ca977b1a882a3c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 31 Jan 2025 10:43:34 +0100 Subject: [PATCH 0484/1962] [release] prepare release pmd_releases/7.10.0 --- pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-rust/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 6 +++--- 43 files changed, 45 insertions(+), 45 deletions(-) diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index 76f07557c61..4a87d1995c7 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.10.0-SNAPSHOT + 7.10.0 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 246e5e65b3b..cf784939b75 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index e77d806f14e..5a406aeb846 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index 534722c4ccf..33bb5dd5c6d 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index 08f6ef6d8cb..d1de2b2e6f6 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index ebe754895d2..281622c4d5a 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index 43e9d50beff..f3d4d77d417 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index bc64e99a773..e247d310d17 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index 45684f597a7..55cba8f2fa1 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index 250a03912f4..867fe3db0e7 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index 9a06ce3c6c7..b6807029000 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index ec0b11fd316..8930319c43c 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index 577b2a609ad..c37dbf1d891 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index fb5277db5f3..aa82eea11df 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index 7f924f36370..9dbb8ebb935 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 2817db55775..e1983bebd54 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index 9316ac5bc89..26b95630ee6 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index c70650f13ba..0a8547b763e 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index 2a32d15cff9..331c253ef6f 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index c670960e120..3fb71d4767f 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index 9058c9f6c06..c059cd83123 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index d6a171088dc..c9ed545ad37 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index 2dd5f607852..e01a83f4631 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index 5291a464f42..26e7e488e76 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index c81aa3c8b2f..aed7f8da9e2 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index db16fc8e95e..44b3bf3c2f4 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index f0a5f199681..881f219aca4 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index 0a8a066d7b0..6f2c6a71fc2 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index 6e27cfcd09d..57be616366a 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index fe34865c2b7..a86886ba9dd 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index acc5d9d19c9..bf1d718b2e6 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index 7e36c915226..384a7352e97 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index 414b66afae3..00ca3f1684e 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index 7d15513440e..bb237f9c634 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.10.0-SNAPSHOT + 7.10.0 ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index 5d815bb324e..0bec02984d5 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.10.0-SNAPSHOT + 7.10.0 ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index ba48d174355..6cf6c657116 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index 3013fca5613..733c02ca34f 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index b5449ba0025..142cedd186d 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index 0760cf9d694..55fa9522c37 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index 8c5de7470c6..66d57949cee 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index 3011e80135e..3fbea1fb148 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index ea2ea26b704..d5ae709f693 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 ../pom.xml diff --git a/pom.xml b/pom.xml index c42e140dc0c..cc9b1a7c180 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.10.0-SNAPSHOT + 7.10.0 pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - HEAD + pmd_releases/7.10.0 @@ -83,7 +83,7 @@ - 2024-12-27T12:29:08Z + 2025-01-31T09:22:09Z 8 From b7e383186345efaec5f65f979b49c0b71a8dfe93 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 31 Jan 2025 11:10:24 +0100 Subject: [PATCH 0485/1962] [release] Prepare next development version [skip ci] --- docs/_config.yml | 6 +- docs/pages/release_notes.md | 99 +-------------- docs/pages/release_notes_old.md | 134 +++++++++++++++++++++ pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-rust/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 4 +- 46 files changed, 182 insertions(+), 145 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 3f79bc7b503..08a4da09574 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,9 +1,9 @@ repository: pmd/pmd pmd: - version: 7.10.0 - previous_version: 7.9.0 - date: 2025-01-31 + version: 7.11.0-SNAPSHOT + previous_version: 7.10.0 + date: 2025-02-28 # release types: major, minor, bugfix release_type: minor diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 62c4cf9f03f..26ec825d013 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -14,115 +14,18 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy -#### ๐Ÿš€ New: Java 24 Support -This release of PMD brings support for Java 24. There are no new standard language features, -but a couple of preview language features: - -* [JEP 488: Primitive Types in Patterns, instanceof, and switch (Second Preview)](https://openjdk.org/jeps/488) -* [JEP 492: Flexible Constructor Bodies (Third Preview)](https://openjdk.org/jeps/492) -* [JEP 494: Module Import Declarations (Second Preview)](https://openjdk.org/jeps/494) -* [JEP 495: Simple Source Files and Instance Main Methods (Fourth Preview)](https://openjdk.org/jeps/495) - -In order to analyze a project with PMD that uses these preview language features, -you'll need to enable it via the environment variable `PMD_JAVA_OPTS` and select the new language -version `24-preview`: - - export PMD_JAVA_OPTS=--enable-preview - pmd check --use-version java-24-preview ... - -Note: Support for Java 22 preview language features have been removed. The version "22-preview" -is no longer available. - -#### New GPG Release Signing Key - -Since January 2025, we switched the GPG Key we use for signing releases in Maven Central to be -[A0B5CA1A4E086838](https://keyserver.ubuntu.com/pks/lookup?search=0x2EFA55D0785C31F956F2F87EA0B5CA1A4E086838&fingerprint=on&op=index). -The full fingerprint is `2EFA 55D0 785C 31F9 56F2 F87E A0B5 CA1A 4E08 6838`. - -This step was necessary, as the passphrase of the old key has been compromised and therefore the key is not -safe to use anymore. While the key itself is not compromised as far as we know, we still decided to generate a -new key, just to be safe. As until now (January 2025) we are not aware, that the key actually has been misused. -The previous releases of PMD in Maven Central can still be considered untampered, as Maven Central is read-only. - -This unexpected issue was discovered while checking [Reproducible Builds](https://reproducible-builds.org/) by a -third party. - -The security advisory about the compromised passphrase is tracked as -[GHSA-88m4-h43f-wx84](https://github.com/pmd/pmd/security/advisories/GHSA-88m4-h43f-wx84) -and [CVE-2025-23215](https://www.cve.org/CVERecord?id=CVE-2025-23215). - -#### Updated PMD Designer - -This PMD release ships a new version of the pmd-designer. -For the changes, see [PMD Designer Changelog (7.10.0)](https://github.com/pmd/pmd-designer/releases/tag/7.10.0). - -### ๐ŸŒŸ New and changed rules - -#### New Rules - -* The new Java rule {%rule java/bestpractices/ExhaustiveSwitchHasDefault %} finds switch statements and - expressions, that cover already all cases but still have a default case. This default case is unnecessary - and prevents getting compiler errors when e.g. new enum constants are added without extending the switch. - ### ๐Ÿ› Fixed Issues -* apex - * [#5388](https://github.com/pmd/pmd/issues/5388): \[apex] Parse error with time literal in SOQL query - * [#5456](https://github.com/pmd/pmd/issues/5456): \[apex] Issue with java dependency apex-parser-4.3.1 but apex-parser-4.3.0 works -* apex-security - * [#3158](https://github.com/pmd/pmd/issues/3158): \[apex] ApexSuggestUsingNamedCred false positive with Named Credential merge fields -* documentation - * [#2492](https://github.com/pmd/pmd/issues/2492): \[doc] Promote wiki pages to standard doc pages -* java - * [#5154](https://github.com/pmd/pmd/issues/5154): \[java] Support Java 24 -* java-performance - * [#5311](https://github.com/pmd/pmd/issues/5311): \[java] TooFewBranchesForSwitch false positive for exhaustive switches over enums without default case ### ๐Ÿšจ API Changes -#### Removed Experimental API -* pmd-java - * `net.sourceforge.pmd.lang.java.ast.ASTTemplate`, `net.sourceforge.pmd.lang.java.ast.ASTTemplateExpression`, - `net.sourceforge.pmd.lang.java.ast.ASTTemplateFragment`: These nodes were introduced with Java 21 and 22 - Preview to support String Templates. However, the String Template preview feature was not finalized - and has been removed from Java for now. We now cleaned up the PMD implementation of it. - ### โœจ Merged pull requests -* [#5327](https://github.com/pmd/pmd/pull/5327): \[apex] Update apex-parser and summit-ast - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5412](https://github.com/pmd/pmd/pull/5412): \[java] Support exhaustive switches - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5449](https://github.com/pmd/pmd/pull/5449): Use new gpg key (A0B5CA1A4E086838) - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5458](https://github.com/pmd/pmd/pull/5458): \[doc] Move Wiki pages into main documentation, cleanups - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5471](https://github.com/pmd/pmd/pull/5471): \[java] Support Java 24 - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5488](https://github.com/pmd/pmd/pull/5488): \[apex] Fix #3158: Recognize Named Credentials merge fields in ApexSuggestUsingNamedCredRule - [William Brockhus](https://github.com/YodaDaCoda) (@YodaDaCoda) ### ๐Ÿ“ฆ Dependency updates -* [#5423](https://github.com/pmd/pmd/pull/5423): Bump PMD from 7.8.0 to 7.9.0 -* [#5433](https://github.com/pmd/pmd/pull/5433): Bump org.codehaus.mojo:exec-maven-plugin from 3.2.0 to 3.5.0 -* [#5434](https://github.com/pmd/pmd/pull/5434): Bump commons-logging:commons-logging from 1.3.0 to 1.3.4 -* [#5435](https://github.com/pmd/pmd/pull/5435): Bump org.apache.maven.plugins:maven-enforcer-plugin from 3.4.1 to 3.5.0 -* [#5436](https://github.com/pmd/pmd/pull/5436): Bump the all-gems group across 2 directories with 1 update -* [#5445](https://github.com/pmd/pmd/pull/5445): Bump org.junit.platform:junit-platform-commons from 1.11.2 to 1.11.4 -* [#5446](https://github.com/pmd/pmd/pull/5446): Bump org.sonarsource.scanner.maven:sonar-maven-plugin from 3.10.0.2594 to 5.0.0.4389 -* [#5459](https://github.com/pmd/pmd/pull/5459): Bump org.apache.maven.plugins:maven-gpg-plugin from 3.1.0 to 3.2.7 -* [#5460](https://github.com/pmd/pmd/pull/5460): Bump org.apache.commons:commons-text from 1.12.0 to 1.13.0 -* [#5461](https://github.com/pmd/pmd/pull/5461): Bump com.google.protobuf:protobuf-java from 4.29.1 to 4.29.3 -* [#5472](https://github.com/pmd/pmd/pull/5472): Bump net.bytebuddy:byte-buddy-agent from 1.15.11 to 1.16.1 -* [#5473](https://github.com/pmd/pmd/pull/5473): Bump org.sonatype.plugins:nexus-staging-maven-plugin from 1.6.13 to 1.7.0 -* [#5474](https://github.com/pmd/pmd/pull/5474): Bump com.github.siom79.japicmp:japicmp-maven-plugin from 0.23.0 to 0.23.1 -* [#5475](https://github.com/pmd/pmd/pull/5475): Bump liquid from 5.6.0 to 5.7.0 in the all-gems group across 1 directory -* [#5479](https://github.com/pmd/pmd/pull/5479): Bump pmd-designer from 7.2.0 to 7.10.0 -* [#5480](https://github.com/pmd/pmd/pull/5480): Bump scalameta.version from 4.9.1 to 4.12.7 -* [#5481](https://github.com/pmd/pmd/pull/5481): Bump liquid from 5.7.0 to 5.7.1 in the all-gems group across 1 directory -* [#5482](https://github.com/pmd/pmd/pull/5482): Bump org.codehaus.mojo:versions-maven-plugin from 2.17.1 to 2.18.0 -* [#5483](https://github.com/pmd/pmd/pull/5483): Bump org.jetbrains.dokka:dokka-maven-plugin from 1.9.20 to 2.0.0 -* [#5484](https://github.com/pmd/pmd/pull/5484): Bump com.github.hazendaz.maven:coveralls-maven-plugin from 4.5.0-M5 to 4.5.0-M6 -* [#5485](https://github.com/pmd/pmd/pull/5485): Bump com.puppycrawl.tools:checkstyle from 10.20.2 to 10.21.2 ### ๐Ÿ“ˆ Stats -* 70 commits -* 13 closed tickets & PRs -* Days since last release: 34 {% endtocmaker %} + diff --git a/docs/pages/release_notes_old.md b/docs/pages/release_notes_old.md index 348840576b8..cf0426e580e 100644 --- a/docs/pages/release_notes_old.md +++ b/docs/pages/release_notes_old.md @@ -5,6 +5,140 @@ permalink: pmd_release_notes_old.html Previous versions of PMD can be downloaded here: [Releases - pmd/pmd (GitHub)](https://github.com/pmd/pmd/releases) +## 31-January-2025 - 7.10.0 + +The PMD team is pleased to announce PMD 7.10.0. + +This is a minor release. + +### Table Of Contents + +* [๐Ÿš€ New and noteworthy](#new-and-noteworthy) + * [๐Ÿš€ New: Java 24 Support](#new-java-24-support) + * [New GPG Release Signing Key](#new-gpg-release-signing-key) + * [Updated PMD Designer](#updated-pmd-designer) +* [๐ŸŒŸ New and changed rules](#new-and-changed-rules) + * [New Rules](#new-rules) +* [๐Ÿ› Fixed Issues](#fixed-issues) +* [๐Ÿšจ API Changes](#api-changes) + * [Removed Experimental API](#removed-experimental-api) +* [โœจ Merged pull requests](#merged-pull-requests) +* [๐Ÿ“ฆ Dependency updates](#dependency-updates) +* [๐Ÿ“ˆ Stats](#stats) + +### ๐Ÿš€ New and noteworthy + +#### ๐Ÿš€ New: Java 24 Support +This release of PMD brings support for Java 24. There are no new standard language features, +but a couple of preview language features: + +* [JEP 488: Primitive Types in Patterns, instanceof, and switch (Second Preview)](https://openjdk.org/jeps/488) +* [JEP 492: Flexible Constructor Bodies (Third Preview)](https://openjdk.org/jeps/492) +* [JEP 494: Module Import Declarations (Second Preview)](https://openjdk.org/jeps/494) +* [JEP 495: Simple Source Files and Instance Main Methods (Fourth Preview)](https://openjdk.org/jeps/495) + +In order to analyze a project with PMD that uses these preview language features, +you'll need to enable it via the environment variable `PMD_JAVA_OPTS` and select the new language +version `24-preview`: + + export PMD_JAVA_OPTS=--enable-preview + pmd check --use-version java-24-preview ... + +Note: Support for Java 22 preview language features have been removed. The version "22-preview" +is no longer available. + +#### New GPG Release Signing Key + +Since January 2025, we switched the GPG Key we use for signing releases in Maven Central to be +[A0B5CA1A4E086838](https://keyserver.ubuntu.com/pks/lookup?search=0x2EFA55D0785C31F956F2F87EA0B5CA1A4E086838&fingerprint=on&op=index). +The full fingerprint is `2EFA 55D0 785C 31F9 56F2 F87E A0B5 CA1A 4E08 6838`. + +This step was necessary, as the passphrase of the old key has been compromised and therefore the key is not +safe to use anymore. While the key itself is not compromised as far as we know, we still decided to generate a +new key, just to be safe. As until now (January 2025) we are not aware, that the key actually has been misused. +The previous releases of PMD in Maven Central can still be considered untampered, as Maven Central is read-only. + +This unexpected issue was discovered while checking [Reproducible Builds](https://reproducible-builds.org/) by a +third party. + +The security advisory about the compromised passphrase is tracked as +[GHSA-88m4-h43f-wx84](https://github.com/pmd/pmd/security/advisories/GHSA-88m4-h43f-wx84) +and [CVE-2025-23215](https://www.cve.org/CVERecord?id=CVE-2025-23215). + +#### Updated PMD Designer + +This PMD release ships a new version of the pmd-designer. +For the changes, see [PMD Designer Changelog (7.10.0)](https://github.com/pmd/pmd-designer/releases/tag/7.10.0). + +### ๐ŸŒŸ New and changed rules + +#### New Rules + +* The new Java rule [`ExhaustiveSwitchHasDefault`](https://docs.pmd-code.org/pmd-doc-7.10.0/pmd_rules_java_bestpractices.html#exhaustiveswitchhasdefault) finds switch statements and + expressions, that cover already all cases but still have a default case. This default case is unnecessary + and prevents getting compiler errors when e.g. new enum constants are added without extending the switch. + +### ๐Ÿ› Fixed Issues +* apex + * [#5388](https://github.com/pmd/pmd/issues/5388): \[apex] Parse error with time literal in SOQL query + * [#5456](https://github.com/pmd/pmd/issues/5456): \[apex] Issue with java dependency apex-parser-4.3.1 but apex-parser-4.3.0 works +* apex-security + * [#3158](https://github.com/pmd/pmd/issues/3158): \[apex] ApexSuggestUsingNamedCred false positive with Named Credential merge fields +* documentation + * [#2492](https://github.com/pmd/pmd/issues/2492): \[doc] Promote wiki pages to standard doc pages +* java + * [#5154](https://github.com/pmd/pmd/issues/5154): \[java] Support Java 24 +* java-performance + * [#5311](https://github.com/pmd/pmd/issues/5311): \[java] TooFewBranchesForSwitch false positive for exhaustive switches over enums without default case + +### ๐Ÿšจ API Changes + +#### Removed Experimental API +* pmd-java + * `net.sourceforge.pmd.lang.java.ast.ASTTemplate`, `net.sourceforge.pmd.lang.java.ast.ASTTemplateExpression`, + `net.sourceforge.pmd.lang.java.ast.ASTTemplateFragment`: These nodes were introduced with Java 21 and 22 + Preview to support String Templates. However, the String Template preview feature was not finalized + and has been removed from Java for now. We now cleaned up the PMD implementation of it. + +### โœจ Merged pull requests + +* [#5327](https://github.com/pmd/pmd/pull/5327): \[apex] Update apex-parser and summit-ast - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5412](https://github.com/pmd/pmd/pull/5412): \[java] Support exhaustive switches - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5449](https://github.com/pmd/pmd/pull/5449): Use new gpg key (A0B5CA1A4E086838) - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5458](https://github.com/pmd/pmd/pull/5458): \[doc] Move Wiki pages into main documentation, cleanups - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5471](https://github.com/pmd/pmd/pull/5471): \[java] Support Java 24 - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5488](https://github.com/pmd/pmd/pull/5488): \[apex] Fix #3158: Recognize Named Credentials merge fields in ApexSuggestUsingNamedCredRule - [William Brockhus](https://github.com/YodaDaCoda) (@YodaDaCoda) + +### ๐Ÿ“ฆ Dependency updates + +* [#5423](https://github.com/pmd/pmd/pull/5423): Bump PMD from 7.8.0 to 7.9.0 +* [#5433](https://github.com/pmd/pmd/pull/5433): Bump org.codehaus.mojo:exec-maven-plugin from 3.2.0 to 3.5.0 +* [#5434](https://github.com/pmd/pmd/pull/5434): Bump commons-logging:commons-logging from 1.3.0 to 1.3.4 +* [#5435](https://github.com/pmd/pmd/pull/5435): Bump org.apache.maven.plugins:maven-enforcer-plugin from 3.4.1 to 3.5.0 +* [#5436](https://github.com/pmd/pmd/pull/5436): Bump the all-gems group across 2 directories with 1 update +* [#5445](https://github.com/pmd/pmd/pull/5445): Bump org.junit.platform:junit-platform-commons from 1.11.2 to 1.11.4 +* [#5446](https://github.com/pmd/pmd/pull/5446): Bump org.sonarsource.scanner.maven:sonar-maven-plugin from 3.10.0.2594 to 5.0.0.4389 +* [#5459](https://github.com/pmd/pmd/pull/5459): Bump org.apache.maven.plugins:maven-gpg-plugin from 3.1.0 to 3.2.7 +* [#5460](https://github.com/pmd/pmd/pull/5460): Bump org.apache.commons:commons-text from 1.12.0 to 1.13.0 +* [#5461](https://github.com/pmd/pmd/pull/5461): Bump com.google.protobuf:protobuf-java from 4.29.1 to 4.29.3 +* [#5472](https://github.com/pmd/pmd/pull/5472): Bump net.bytebuddy:byte-buddy-agent from 1.15.11 to 1.16.1 +* [#5473](https://github.com/pmd/pmd/pull/5473): Bump org.sonatype.plugins:nexus-staging-maven-plugin from 1.6.13 to 1.7.0 +* [#5474](https://github.com/pmd/pmd/pull/5474): Bump com.github.siom79.japicmp:japicmp-maven-plugin from 0.23.0 to 0.23.1 +* [#5475](https://github.com/pmd/pmd/pull/5475): Bump liquid from 5.6.0 to 5.7.0 in the all-gems group across 1 directory +* [#5479](https://github.com/pmd/pmd/pull/5479): Bump pmd-designer from 7.2.0 to 7.10.0 +* [#5480](https://github.com/pmd/pmd/pull/5480): Bump scalameta.version from 4.9.1 to 4.12.7 +* [#5481](https://github.com/pmd/pmd/pull/5481): Bump liquid from 5.7.0 to 5.7.1 in the all-gems group across 1 directory +* [#5482](https://github.com/pmd/pmd/pull/5482): Bump org.codehaus.mojo:versions-maven-plugin from 2.17.1 to 2.18.0 +* [#5483](https://github.com/pmd/pmd/pull/5483): Bump org.jetbrains.dokka:dokka-maven-plugin from 1.9.20 to 2.0.0 +* [#5484](https://github.com/pmd/pmd/pull/5484): Bump com.github.hazendaz.maven:coveralls-maven-plugin from 4.5.0-M5 to 4.5.0-M6 +* [#5485](https://github.com/pmd/pmd/pull/5485): Bump com.puppycrawl.tools:checkstyle from 10.20.2 to 10.21.2 + +### ๐Ÿ“ˆ Stats + +* 70 commits +* 13 closed tickets & PRs +* Days since last release: 34 + ## 27-December-2024 - 7.9.0 The PMD team is pleased to announce PMD 7.9.0. diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index 4a87d1995c7..63b3297675c 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.10.0 + 7.11.0-SNAPSHOT 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index cf784939b75..970f45e3fc6 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index 5a406aeb846..609a7988358 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index 33bb5dd5c6d..d855cf31391 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index d1de2b2e6f6..928d09dd724 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index 281622c4d5a..eb34ffd63a6 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index f3d4d77d417..6f3641f811b 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index e247d310d17..84b7b84544c 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index 55cba8f2fa1..3185b4933f6 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index 867fe3db0e7..9f085fd5b02 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index b6807029000..a69d6ae7f6b 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index 8930319c43c..9c4bcd47b57 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index c37dbf1d891..51a0c25f46e 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index aa82eea11df..c0fd9e02864 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index 9dbb8ebb935..8bf845e2c4c 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index e1983bebd54..52df434b648 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index 26b95630ee6..0f8d4615239 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index 0a8547b763e..1fa7f6a0108 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index 331c253ef6f..73e56999e54 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index 3fb71d4767f..ddb62fe18c0 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index c059cd83123..f2a30d6273b 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index c9ed545ad37..407cfc9cdda 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index e01a83f4631..06e0e7c1fab 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index 26e7e488e76..154ca231e98 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index aed7f8da9e2..f350382bfb9 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index 44b3bf3c2f4..562a468adda 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index 881f219aca4..390cc94232e 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index 6f2c6a71fc2..e27b3bb6c10 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index 57be616366a..078653a23f1 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index a86886ba9dd..029f14df721 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index bf1d718b2e6..66a924a3f2e 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index 384a7352e97..e304eec298b 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index 00ca3f1684e..2a3cad064cf 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index bb237f9c634..da9c5ebc5ae 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.10.0 + 7.11.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index 0bec02984d5..640670b8eb0 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.10.0 + 7.11.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index 6cf6c657116..dc172139847 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index 733c02ca34f..6c885190250 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index 142cedd186d..143d347c408 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index 55fa9522c37..dd14dfa9fca 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index 66d57949cee..4bbcfae08c5 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index 3fbea1fb148..0407bb91f25 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index d5ae709f693..51e0201fbda 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index cc9b1a7c180..6ba12e514c6 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.10.0 + 7.11.0-SNAPSHOT pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - pmd_releases/7.10.0 + HEAD From 3aef4f59d366449864ae7b4d89bed16929257273 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 31 Jan 2025 13:04:12 +0100 Subject: [PATCH 0486/1962] Bump PMD from 7.9.0 to 7.10.0 (#5490) --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 6ba12e514c6..b31e4849822 100644 --- a/pom.xml +++ b/pom.xml @@ -574,22 +574,22 @@ net.sourceforge.pmd pmd-core - 7.9.0 + 7.10.0 net.sourceforge.pmd pmd-java - 7.9.0 + 7.10.0 net.sourceforge.pmd pmd-jsp - 7.9.0 + 7.10.0 net.sourceforge.pmd pmd-javascript - 7.9.0 + 7.10.0 From 5766e71b4b92333309bb06db4a44399e5941597a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 31 Jan 2025 15:56:27 +0100 Subject: [PATCH 0487/1962] [docs] Call render_release_notes.rb within docs Then we can reuse the Gemfile from docs rather than using a group. --- .ci/build.sh | 6 +++--- Gemfile | 10 ---------- Gemfile.lock | 6 ------ do-release.sh | 13 ++++++------- docs/Gemfile | 4 ++++ docs/Gemfile.lock | 4 ++++ docs/pages/pmd/projectdocs/committers/releasing.md | 13 ++++++++++--- docs/render_release_notes.rb | 6 +++--- 8 files changed, 30 insertions(+), 32 deletions(-) diff --git a/.ci/build.sh b/.ci/build.sh index cd5200588a6..fd811336054 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -299,13 +299,13 @@ function pmd_ci_build_and_upload_doc() { # render release notes # updating github release text - rm -f .bundle/config + pushd docs || { echo "Directory 'docs' doesn't exist"; exit 1; } bundle config set --local path vendor/bundle - bundle config set --local with release_notes_preprocessing bundle install # renders, and skips the first 6 lines - the Jekyll front-matter local rendered_release_notes - rendered_release_notes=$(bundle exec docs/render_release_notes.rb docs/pages/release_notes.md | tail -n +6) + rendered_release_notes=$(bundle exec render_release_notes.rb pages/release_notes.md | tail -n +6) + popd || exit 1 local release_name release_name="PMD ${PMD_CI_MAVEN_PROJECT_VERSION} ($(date -u +%d-%B-%Y))" # Upload to https://sourceforge.net/projects/pmd/files/pmd/${PMD_CI_MAVEN_PROJECT_VERSION}/ReadMe.md diff --git a/Gemfile b/Gemfile index 6fccc49416c..1be943c8447 100644 --- a/Gemfile +++ b/Gemfile @@ -6,14 +6,4 @@ source 'https://rubygems.org/' gem 'pmdtester' gem 'danger' -# This group is only needed for rendering release notes (docs/render_release_notes.rb) -# this happens during release (.ci/build.sh and do-release.sh) -# but also during regular builds (.ci/build.sh) -group :release_notes_preprocessing do - gem 'liquid' - gem 'safe_yaml' - gem 'rouge' - gem 'bigdecimal' -end - # vim: syntax=ruby diff --git a/Gemfile.lock b/Gemfile.lock index b36824f46b5..b5096669e57 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -77,10 +77,8 @@ GEM racc (1.8.1) rchardet (1.8.0) rexml (3.3.9) - rouge (4.5.1) rufus-scheduler (3.9.2) fugit (~> 1.1, >= 1.11.1) - safe_yaml (1.0.5) sawyer (0.9.2) addressable (>= 2.3.5) faraday (>= 0.17.3, < 3) @@ -97,12 +95,8 @@ PLATFORMS x86_64-linux DEPENDENCIES - bigdecimal danger - liquid pmdtester - rouge - safe_yaml BUNDLED WITH 2.5.22 diff --git a/do-release.sh b/do-release.sh index caaca61d7e6..73f8dfbd13e 100755 --- a/do-release.sh +++ b/do-release.sh @@ -22,16 +22,14 @@ fi # set +e # don't stop for error "command not found" - it is handled ruby_version_full=$(ruby --version 2>&1) -ruby_version=$(echo "${ruby_version_full}" | grep "ruby 3" | head -1 2>&1) -if [ $? -eq 0 ] && [ -n "${ruby_version}" ]; then +if ruby_version=$(echo "${ruby_version_full}" | grep "ruby 3" | head -1 2>&1) && [ -n "${ruby_version}" ]; then echo "Using ${ruby_version_full}" else echo "Wrong ruby version! Expected ruby 3" echo "${ruby_version_full}" exit 1 fi -bundler_version=$(bundler --version 2>&1) -if [ $? -eq 0 ]; then +if bundler_version=$(bundler --version 2>&1); then echo "Using ${bundler_version}" else echo "Missing bundler!" @@ -151,15 +149,16 @@ echo echo "Press enter to continue..." read -r -# install bundles needed for rendering release notes +# install bundles needed for rendering release notes and execute rendering +pushd docs || { echo "Directory 'docs' doesn't exist"; exit 1; } bundle config set --local path vendor/bundle -bundle config set --local with release_notes_preprocessing bundle install +NEW_RELEASE_NOTES=$(bundle exec render_release_notes.rb pages/release_notes.md | tail -n +6) +popd || exit 1 RELEASE_NOTES_POST="_posts/$(date -u +%Y-%m-%d)-PMD-${RELEASE_VERSION}.md" export RELEASE_NOTES_POST echo "Generating ../pmd.github.io/${RELEASE_NOTES_POST}..." -NEW_RELEASE_NOTES=$(bundle exec docs/render_release_notes.rb docs/pages/release_notes.md | tail -n +6) cat > "../pmd.github.io/${RELEASE_NOTES_POST}" < "../pmd.github.io/${RELEASE_NOTES_POST}" < YAML.load_file(travis_dir + "/../docs/_config.yml"), + 'site' => YAML.load_file(docs_dir + "/_config.yml"), 'page' => YAML.load_file(release_notes_file), # This signals the links in {% rule %} tags that they should be rendered as absolute 'is_release_notes_processor' => true From 1c37f81dd8ac928044c157d4c6cc3c27cc0a1ab3 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 31 Jan 2025 16:23:15 +0100 Subject: [PATCH 0488/1962] [docs] Add security page with known vulnerabilities --- docs/_data/sidebars/pmd_sidebar.yml | 3 + docs/pages/pmd/about/security.md | 117 ++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 docs/pages/pmd/about/security.md diff --git a/docs/_data/sidebars/pmd_sidebar.yml b/docs/_data/sidebars/pmd_sidebar.yml index 28f24d9ec96..99cc8972e17 100644 --- a/docs/_data/sidebars/pmd_sidebar.yml +++ b/docs/_data/sidebars/pmd_sidebar.yml @@ -35,6 +35,9 @@ entries: - title: Support lifecycle url: /pmd_about_support_lifecycle.html output: web, pdf + - title: Security + url: /pmd_about_security.html + output: web, pdf - title: User Documentation output: web, pdf folderitems: diff --git a/docs/pages/pmd/about/security.md b/docs/pages/pmd/about/security.md new file mode 100644 index 00000000000..7743f2f7917 --- /dev/null +++ b/docs/pages/pmd/about/security.md @@ -0,0 +1,117 @@ +--- +title: PMD Security +permalink: pmd_about_security.html +author: Andreas Dangel +last_updated: January 2025 (PMD 7.11.0) +--- + +For reporting security issues, see [SECURITY.md](https://github.com/pmd/pmd/blob/main/SECURITY.md). + +## Security Vulnerabilities + +### CVE-2025-23215 +**Published:** 2025-01-31 + +**Severity:** Low + +**Summary:** Release key passphrase (GPG) available on Maven Central in cleartext + +**Versions Affected:** + +* net.sourceforge.pmd:pmd-core 7.9.0 and earlier +* net.sourceforge.pmd:pmd-designer 7.9.0 and earlier +* net.sourceforge.pmd:pmd-ui 7.0.0-rc4 and earlier +* net.sourceforge.pmd.eclipse.plugin 7.9.0.v20241227-1626-r + +**Description:** + +While rebuilding [PMD Designer](https://github.com/pmd/pmd-designer) for Reproducible Builds and digging into issues, +I found out that passphrase for `gpg.keyname=0xD0BF1D737C9A1C22` is included in jar published to Maven Central. + +**Details** +See https://github.com/jvm-repo-rebuild/reproducible-central/blob/master/content/net/sourceforge/pmd/pmd-designer/README.md + +I removed 2 lines from https://github.com/jvm-repo-rebuild/reproducible-central/blob/master/content/net/sourceforge/pmd/pmd-designer/pmd-designer-7.0.0.diffoscope +but real content is: + +``` +โ”œโ”€โ”€ net/sourceforge/pmd/util/fxdesigner/designer.properties +โ”‚ @@ -1,14 +1,12 @@ +โ”‚ #Properties +โ”‚ checkstyle.plugin.version=3.3.1 +โ”‚ checkstyle.version=10.14.0 +โ”‚ -gpg.keyname=0xD0BF1D737C9A1C22 +โ”‚ -gpg.passphrase=evicx0nuPfvSVhVyeXpw +โ”‚ jar.plugin.version=3.3.0 +โ”‚ -java.version=11.0.22 +โ”‚ +java.version=11.0.25 +โ”‚ javadoc.plugin.version=3.6.3 +โ”‚ jflex-output=/home/runner/work/pmd-designer/pmd-designer/target/generated-sources/jflex +โ”‚ junit5.version=5.8.2 +โ”‚ kotest.version=5.5.5 +โ”‚ kotlin.version=1.7.20 +โ”‚ local.lib.repo=/home/runner/work/pmd-designer/pmd-designer/lib/mvn-repo +โ”‚ openjfx.scope=provided +``` + +**PoC** +``` +./rebuild.sh content/net/sourceforge/pmd/pmd-designer/pmd-designer-7.0.0.buildspec +``` + +**Impact** +After further analysis, the passphrase of the following two keys have been compromised: + +1. `94A5 2756 9CAF 7A47 AFCA BDE4 86D3 7ECA 8C2E 4C5B`: PMD Designer (Release Signing Key) + This key has been used since 2019 with the release of [net.sourceforge.pmd:pmd-ui:6.14.0](https://repo.maven.apache.org/maven2/net/sourceforge/pmd/pmd-ui/6.14.0/). + The following versions are signed with the same key: 6.16.0, 6.17.0, 6.19.0. +2. `EBB2 41A5 45CB 17C8 7FAC B2EB D0BF 1D73 7C9A 1C22`: PMD Release Signing Key + This key has been used since 2020 with the release of [net.sourceforge.pmd:pmd-ui:6.21.0](https://repo.maven.apache.org/maven2/net/sourceforge/pmd/pmd-ui/6.21.0/) + and all the other modules of PMD such as [net.sourceforge.pmd:pmd-core:6.21.0](https://repo.maven.apache.org/maven2/net/sourceforge/pmd/pmd-core/6.21.0/). + This key has also been used for PMD 7, for the designer, e.g. [net.sourceforge.pmd:pmd-designer:7.0.0](https://repo.maven.apache.org/maven2/net/sourceforge/pmd/pmd-designer/7.0.0/) + and [net.sourceforge.pmd:pmd-core:7.0.0](https://repo.maven.apache.org/maven2/net/sourceforge/pmd/pmd-core/7.0.0/). + The versions between 6.21.0 and 7.9.0 are signed with this key. + Additionally the key has been used to sign the last release of [PMD Eclipse Plugin 7.9.0.v20241227-1626-r](https://github.com/pmd/pmd-eclipse-plugin/releases/tag/7.9.0.v20241227-1626-r). + +The keys have been used exclusively for signing artifacts that we published to Maven Central under group +id `net.sourceforge.pmd` and once for our pmd-eclipse-plugin. The private key itself is not known to have +been compromised itself, but given its passphrase is, it must also be considered potentially compromised. + +As a mitigation, both compromised keys have been revoked so that no future use of the keys are possible. +For future releases of PMD, PMD Designer and PMD Eclipse Plugin we use a new release signing key: +`2EFA 55D0 785C 31F9 56F2 F87E A0B5 CA1A 4E08 6838` (PMD Release Signing Key ). + +Note, that the published artifacts in Maven Central under the group id `net.sourceforge.pmd` are **not** +compromised and the signatures are valid. No other past usages of the private key is known to the project +and no future use is possible due to the revocation. If anybody finds a past abuse of the private key, +please share with us. + +Note, the module `net.sourceforge.pmd:pmd-ui` has been renamed to `net.sourceforge.pmd:pmd-designer` since PMD 7, +so there won't be a fixed version for `pmd-ui`. + +**Fixes** +* Reworked build script in PMD Designer to not include all system properties + * https://github.com/pmd/pmd-designer/commit/1548f5f27ba2981b890827fecbd0612fa70a0362 + * https://github.com/pmd/pmd-designer/commit/e87a45312753ec46b3e5576c6f6ac1f7de2f5891 + + +**References:** +* [GHSA-88m4-h43f-wx84](https://github.com/pmd/pmd/security/advisories/GHSA-88m4-h43f-wx84) +* [CVE-2025-23215](https://www.cve.org/CVERecord?id=CVE-2025-23215) +* [reproducible-central](https://github.com/jvm-repo-rebuild/reproducible-central?tab=readme-ov-file#reproducible-builds-for-maven-central-repository) + + + +### CVE-2019-7722 +**Published:** 2019-02-11 + +**Description:** + +PMD 5.8.1 and earlier processes XML external entities in ruleset files it parses as part of the analysis process, +allowing attackers tampering it (either by direct modification or MITM attacks when using remote rulesets) +to perform information disclosure, denial of service, or request forgery attacks. (PMD 6.x is unaffected +because of a 2017-09-15 change.) + +**References:** +* [CVE-2019-7722](https://www.cve.org/CVERecord?id=CVE-2019-7722) +* [[core] Advisory - XXE attack on ruleset parsing #1650](https://github.com/pmd/pmd/issues/1650) From a2a78728f975cedf9c0d609cbdc300de7f0246d0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 03:34:20 +0000 Subject: [PATCH 0489/1962] Bump liquid from 5.7.1 to 5.7.2 in the all-gems group across 1 directory Bumps the all-gems group with 1 update in the / directory: [liquid](https://github.com/Shopify/liquid). Updates `liquid` from 5.7.1 to 5.7.2 - [Release notes](https://github.com/Shopify/liquid/releases) - [Changelog](https://github.com/Shopify/liquid/blob/main/History.md) - [Commits](https://github.com/Shopify/liquid/compare/v5.7.1...v5.7.2) --- updated-dependencies: - dependency-name: liquid dependency-type: indirect update-type: version-update:semver-patch dependency-group: all-gems ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index b5096669e57..f6f824df7af 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -50,7 +50,7 @@ GEM rexml kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) - liquid (5.7.1) + liquid (5.7.2) bigdecimal strscan (>= 3.1.1) logger (1.6.1) From b9423559245c3d86ad20ddcfbbec635914868331 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 03:58:50 +0000 Subject: [PATCH 0490/1962] Bump net.bytebuddy:byte-buddy-agent from 1.16.1 to 1.17.0 Bumps [net.bytebuddy:byte-buddy-agent](https://github.com/raphw/byte-buddy) from 1.16.1 to 1.17.0. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.16.1...byte-buddy-1.17.0) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy-agent dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b31e4849822..916976260a8 100644 --- a/pom.xml +++ b/pom.xml @@ -1000,7 +1000,7 @@ net.bytebuddy byte-buddy-agent - 1.16.1 + 1.17.0 test From 3b2195ec37b28f98984664a6d52b6be8f17a35bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 03:58:53 +0000 Subject: [PATCH 0491/1962] Bump org.assertj:assertj-core from 3.25.3 to 3.27.3 Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.25.3 to 3.27.3. - [Release notes](https://github.com/assertj/assertj/releases) - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.25.3...assertj-build-3.27.3) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pmd-java/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 52df434b648..5172893da6c 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -280,7 +280,7 @@ org.assertj assertj-core - 3.25.3 + 3.27.3 test From 3ea963caf07aad094f583e7e6c527703ce507063 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 03:59:00 +0000 Subject: [PATCH 0492/1962] Bump org.mockito:mockito-core from 5.14.2 to 5.15.2 Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.14.2 to 5.15.2. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.14.2...v5.15.2) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b31e4849822..c2287554d72 100644 --- a/pom.xml +++ b/pom.xml @@ -983,7 +983,7 @@ org.mockito mockito-core - 5.14.2 + 5.15.2 test From fc5f6717d1c3abc9ce89eaee5855093f7e479646 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 03:59:04 +0000 Subject: [PATCH 0493/1962] Bump org.junit:junit-bom from 5.11.2 to 5.11.4 Bumps [org.junit:junit-bom](https://github.com/junit-team/junit5) from 5.11.2 to 5.11.4. - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.2...r5.11.4) --- updated-dependencies: - dependency-name: org.junit:junit-bom dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b31e4849822..1abc8344008 100644 --- a/pom.xml +++ b/pom.xml @@ -94,7 +94,7 @@ ${maven.compiler.test.target} 1.9.24 5.9.1 - 5.11.2 + 5.11.4 2.0.0 5.0 From 5623adac908da449ad276f92b2cc29a41b3dc589 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 03:59:10 +0000 Subject: [PATCH 0494/1962] Bump org.scala-lang:scala-reflect from 2.13.15 to 2.13.16 Bumps [org.scala-lang:scala-reflect](https://github.com/scala/scala) from 2.13.15 to 2.13.16. - [Release notes](https://github.com/scala/scala/releases) - [Commits](https://github.com/scala/scala/compare/v2.13.15...v2.13.16) --- updated-dependencies: - dependency-name: org.scala-lang:scala-reflect dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b31e4849822..5fb1083bdcb 100644 --- a/pom.xml +++ b/pom.xml @@ -909,7 +909,7 @@ org.scala-lang scala-reflect - 2.13.15 + 2.13.16 org.scala-lang From 5e7fa1ded12e5a24b793f83125ca4b77edb146e0 Mon Sep 17 00:00:00 2001 From: Balazs Glatz <24852447+gbq6@users.noreply.github.com> Date: Tue, 4 Feb 2025 18:25:58 +0100 Subject: [PATCH 0495/1962] Fixed inconsistency in example --- pmd-java/src/main/resources/category/java/multithreading.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/multithreading.xml b/pmd-java/src/main/resources/category/java/multithreading.xml index 605829ce677..339b9b26a75 100644 --- a/pmd-java/src/main/resources/category/java/multithreading.xml +++ b/pmd-java/src/main/resources/category/java/multithreading.xml @@ -69,10 +69,10 @@ public class Foo { // code, that doesn't need synchronization // ... try { - CLS_LOCK.lock(); + CLASS_LOCK.lock(); // code, that requires synchronization } finally { - CLS_LOCK.unlock(); + CLASS_LOCK.unlock(); } // more code, that doesn't need synchronization // ... From 8e9827c6097473abb7b83365eb68e82589f4149a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 6 Feb 2025 10:08:30 +0100 Subject: [PATCH 0496/1962] Add @gbq6 as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 223 +++++++++++++------------- 2 files changed, 121 insertions(+), 111 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index f1e3bd6f15f..46b435c53b0 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7929,6 +7929,15 @@ "contributions": [ "bug" ] + }, + { + "login": "gbq6", + "name": "Balazs Glatz", + "avatar_url": "https://avatars.githubusercontent.com/u/24852447?v=4", + "profile": "https://github.com/gbq6", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index fd96b21e22a..6182d0abf96 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -126,1002 +126,1003 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Ayoub Kaanich
    Ayoub Kaanich

    ๐Ÿ› BBG
    BBG

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Bailey Tjiong
    Bailey Tjiong

    ๐Ÿ’ป + Balazs Glatz
    Balazs Glatz

    ๐Ÿ“– Barthรฉlemy L.
    Barthรฉlemy L.

    ๐Ÿ› Basavaraj K N
    Basavaraj K N

    ๐Ÿ› Basil Peace
    Basil Peace

    ๐Ÿ› - Belle
    Belle

    ๐Ÿ› + Belle
    Belle

    ๐Ÿ› Ben Lerner
    Ben Lerner

    ๐Ÿ› Ben Manes
    Ben Manes

    ๐Ÿ› Ben McCann
    Ben McCann

    ๐Ÿ› Bendegรบz Nagy
    Bendegรบz Nagy

    ๐Ÿ› Bennet S Yee
    Bennet S Yee

    ๐Ÿ› Benoit Lacelle
    Benoit Lacelle

    ๐Ÿ› - Bernardo Macรชdo
    Bernardo Macรชdo

    ๐Ÿ› + Bernardo Macรชdo
    Bernardo Macรชdo

    ๐Ÿ› Bernd Farka
    Bernd Farka

    ๐Ÿ› Betina Cynthia Mamani
    Betina Cynthia Mamani

    ๐Ÿ› Bhanu Prakash Pamidi
    Bhanu Prakash Pamidi

    ๐Ÿ’ป ๐Ÿ› Bhargav Thanki
    Bhargav Thanki

    ๐Ÿ› Binu R J
    Binu R J

    ๐Ÿ› Bjรถrn Kautler
    Bjรถrn Kautler

    ๐Ÿ’ป ๐Ÿ› - Blightbuster
    Blightbuster

    ๐Ÿ› + Blightbuster
    Blightbuster

    ๐Ÿ› Bo Zhang
    Bo Zhang

    ๐Ÿ› Bob "Wombat" Hogg
    Bob "Wombat" Hogg

    ๐Ÿ› Bobby Wertman
    Bobby Wertman

    ๐Ÿ› Bolarinwa Saheed Olayemi
    Bolarinwa Saheed Olayemi

    ๐Ÿ’ป ๐Ÿ› Boris Petrov
    Boris Petrov

    ๐Ÿ› Brad Kent
    Brad Kent

    ๐Ÿ› - Brandon Mikeska
    Brandon Mikeska

    ๐Ÿ› + Brandon Mikeska
    Brandon Mikeska

    ๐Ÿ› Brian Batronis
    Brian Batronis

    ๐Ÿ› Brian Johnson
    Brian Johnson

    ๐Ÿ› Brice Dutheil
    Brice Dutheil

    ๐Ÿ’ป ๐Ÿ› Bruno Ferreira
    Bruno Ferreira

    ๐Ÿ› Bruno Harbulot
    Bruno Harbulot

    ๐Ÿ› Bruno Ritz
    Bruno Ritz

    ๐Ÿ› - BurovnikovEvgeniy
    BurovnikovEvgeniy

    ๐Ÿ› + BurovnikovEvgeniy
    BurovnikovEvgeniy

    ๐Ÿ› Cameron Donaldson
    Cameron Donaldson

    ๐Ÿ› Carlos Macasaet
    Carlos Macasaet

    ๐Ÿ› Carsten Otto
    Carsten Otto

    ๐Ÿ› Charlie Housh
    Charlie Housh

    ๐Ÿ› Charlie Jonas
    Charlie Jonas

    ๐Ÿ› Chas Honton
    Chas Honton

    ๐Ÿ› ๐Ÿ’ป - Chen Yang
    Chen Yang

    ๐Ÿ› + Chen Yang
    Chen Yang

    ๐Ÿ› Chotu
    Chotu

    ๐Ÿ› Chris Smith
    Chris Smith

    ๐Ÿ› Chris Toomey
    Chris Toomey

    ๐Ÿ› Christian Hujer
    Christian Hujer

    ๐Ÿ› Christian Pontesegger
    Christian Pontesegger

    ๐Ÿ› ChristianWulf
    ChristianWulf

    ๐Ÿ› - Christofer Dutz
    Christofer Dutz

    ๐Ÿ’ป + Christofer Dutz
    Christofer Dutz

    ๐Ÿ’ป Christoffer Anselm
    Christoffer Anselm

    ๐Ÿ› Christophe Vidal
    Christophe Vidal

    ๐Ÿ› Christopher Dancy
    Christopher Dancy

    ๐Ÿ› Clemens Prill
    Clemens Prill

    ๐Ÿ› Clint Chester
    Clint Chester

    ๐Ÿ’ป ๐Ÿ› Clรฉment Fournier
    Clรฉment Fournier

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง - Codacy Badger
    Codacy Badger

    ๐Ÿ› + Codacy Badger
    Codacy Badger

    ๐Ÿ› Code-Nil
    Code-Nil

    ๐Ÿ› ColColonCleaner
    ColColonCleaner

    ๐Ÿ› Colin Ingarfield
    Colin Ingarfield

    ๐Ÿ› Craig Andrews
    Craig Andrews

    ๐Ÿ› Craig Muchinsky
    Craig Muchinsky

    ๐Ÿ› Cyril
    Cyril

    ๐Ÿ’ป ๐Ÿ› - Dale
    Dale

    ๐Ÿ’ป + Dale
    Dale

    ๐Ÿ’ป Damien Jiang
    Damien Jiang

    ๐Ÿ› Dan Berindei
    Dan Berindei

    ๐Ÿ› Dan Rollo
    Dan Rollo

    ๐Ÿ› Dan Ziemba
    Dan Ziemba

    ๐Ÿ› Daniel Gredler
    Daniel Gredler

    ๐Ÿ’ป ๐Ÿ› Daniel Jipa
    Daniel Jipa

    ๐Ÿ› - Daniel Paul Searles
    Daniel Paul Searles

    ๐Ÿ’ป + Daniel Paul Searles
    Daniel Paul Searles

    ๐Ÿ’ป Daniel Reigada
    Daniel Reigada

    ๐Ÿ› Danilo Pianini
    Danilo Pianini

    ๐Ÿ› Darko
    Darko

    ๐Ÿ› David
    David

    ๐Ÿ› David Atkinson
    David Atkinson

    ๐Ÿ› David Burstrรถm
    David Burstrรถm

    ๐Ÿ’ป ๐Ÿ› - David Goatรฉ
    David Goatรฉ

    ๐Ÿ› + David Goatรฉ
    David Goatรฉ

    ๐Ÿ› David Golpira
    David Golpira

    ๐Ÿ› David Kovaล™รญk
    David Kovaล™รญk

    ๐Ÿ› David M. Karr (fullname at gmail.com)
    David M. Karr (fullname at gmail.com)

    ๐Ÿ› David Renz
    David Renz

    ๐Ÿ’ป ๐Ÿ› David Renz
    David Renz

    ๐Ÿ› David Schach
    David Schach

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– - Dawid Ciok
    Dawid Ciok

    ๐Ÿ› ๐Ÿ’ป + Dawid Ciok
    Dawid Ciok

    ๐Ÿ› ๐Ÿ’ป Debamoy Datta
    Debamoy Datta

    ๐Ÿ’ป Deleted user
    Deleted user

    ๐Ÿ› Dell Green
    Dell Green

    ๐Ÿ› Dem Pilafian
    Dem Pilafian

    ๐Ÿ› Den
    Den

    ๐Ÿ› Denis Borovikov
    Denis Borovikov

    ๐Ÿ’ป ๐Ÿ› - Dennie Reniers
    Dennie Reniers

    ๐Ÿ’ป ๐Ÿ› + Dennie Reniers
    Dennie Reniers

    ๐Ÿ’ป ๐Ÿ› Dennis Kieselhorst
    Dennis Kieselhorst

    ๐Ÿ› Derek P. Moore
    Derek P. Moore

    ๐Ÿ› Dichotomia
    Dichotomia

    ๐Ÿ› Dionisio Cortรฉs Fernรกndez
    Dionisio Cortรฉs Fernรกndez

    ๐Ÿ’ป ๐Ÿ› Dmitri Bourlatchkov
    Dmitri Bourlatchkov

    ๐Ÿ› Dmitriy Kuzmin
    Dmitriy Kuzmin

    ๐Ÿ› - Dmytro Dashenkov
    Dmytro Dashenkov

    ๐Ÿ› + Dmytro Dashenkov
    Dmytro Dashenkov

    ๐Ÿ› Dr. Christian Kohlschรผtter
    Dr. Christian Kohlschรผtter

    ๐Ÿ› Drew Hall
    Drew Hall

    ๐Ÿ› Dumitru Postoronca
    Dumitru Postoronca

    ๐Ÿ› Dylan Adams
    Dylan Adams

    ๐Ÿ› Eden Hao
    Eden Hao

    ๐Ÿ› Edward Klimoshenko
    Edward Klimoshenko

    ๐Ÿ› ๐Ÿ’ป - Egor Bredikhin
    Egor Bredikhin

    ๐Ÿ› + Egor Bredikhin
    Egor Bredikhin

    ๐Ÿ› Elan P. Kugelmass
    Elan P. Kugelmass

    ๐Ÿ› Elder S.
    Elder S.

    ๐Ÿ› Eldrick Wega
    Eldrick Wega

    ๐Ÿ“– Emile
    Emile

    ๐Ÿ› Eric
    Eric

    ๐Ÿ› Eric Kintzer
    Eric Kintzer

    ๐Ÿ› - Eric Perret
    Eric Perret

    ๐Ÿ› + Eric Perret
    Eric Perret

    ๐Ÿ› Eric Squires
    Eric Squires

    ๐Ÿ› Erich L Foster
    Erich L Foster

    ๐Ÿ› Erik Bleske
    Erik Bleske

    ๐Ÿ› Erik C. Thauvin
    Erik C. Thauvin

    ๐Ÿ“– Ernst Reissner
    Ernst Reissner

    ๐Ÿ› Ethan Sargent
    Ethan Sargent

    ๐Ÿ› - Ewan Tempero
    Ewan Tempero

    ๐Ÿ› + Ewan Tempero
    Ewan Tempero

    ๐Ÿ› F.W. Dekker
    F.W. Dekker

    ๐Ÿ› FSchliephacke
    FSchliephacke

    ๐Ÿ› Facundo
    Facundo

    ๐Ÿ› Federico Giust
    Federico Giust

    ๐Ÿ› Fedor Sherstobitov
    Fedor Sherstobitov

    ๐Ÿ› Felix Lampe
    Felix Lampe

    ๐Ÿ› - Filip Golonka
    Filip Golonka

    ๐Ÿ› + Filip Golonka
    Filip Golonka

    ๐Ÿ› Filipe Esperandio
    Filipe Esperandio

    ๐Ÿ’ป ๐Ÿ› Filippo Nova
    Filippo Nova

    ๐Ÿ› Francesco la Torre
    Francesco la Torre

    ๐Ÿ› Francisco Duarte
    Francisco Duarte

    ๐Ÿ› Frieder Bluemle
    Frieder Bluemle

    ๐Ÿ› Frits Jalvingh
    Frits Jalvingh

    ๐Ÿ’ป ๐Ÿ› - G. Bazior
    G. Bazior

    ๐Ÿ› + G. Bazior
    G. Bazior

    ๐Ÿ› Gabe Henkes
    Gabe Henkes

    ๐Ÿ› Gary Gregory
    Gary Gregory

    ๐Ÿ› Genoud Magloire
    Genoud Magloire

    ๐Ÿ› Geoffrey555
    Geoffrey555

    ๐Ÿ› Georg Romstorfer
    Georg Romstorfer

    ๐Ÿ› Gili Tzabari
    Gili Tzabari

    ๐Ÿ› - Gio
    Gio

    ๐Ÿ› + Gio
    Gio

    ๐Ÿ› Gol
    Gol

    ๐Ÿ› Gold856
    Gold856

    ๐Ÿ› ๐Ÿ’ป Gonzalo Exequiel Ibars Ingman
    Gonzalo Exequiel Ibars Ingman

    ๐Ÿ’ป ๐Ÿ› GooDer
    GooDer

    ๐Ÿ› Gregor Riegler
    Gregor Riegler

    ๐Ÿ› Grzegorz Olszewski
    Grzegorz Olszewski

    ๐Ÿ› - Gunther Schrijvers
    Gunther Schrijvers

    ๐Ÿ’ป ๐Ÿ› + Gunther Schrijvers
    Gunther Schrijvers

    ๐Ÿ’ป ๐Ÿ› Gustavo Krieger
    Gustavo Krieger

    ๐Ÿ› Guy Elsmore-Paddock
    Guy Elsmore-Paddock

    ๐Ÿ› Gรถrkem Mรผlayim
    Gรถrkem Mรผlayim

    ๐Ÿ› Hanzel Godinez
    Hanzel Godinez

    ๐Ÿ› Haoliang Chen
    Haoliang Chen

    ๐Ÿ› Harsh Kukreja
    Harsh Kukreja

    ๐Ÿ› - Hassan ALAMI
    Hassan ALAMI

    ๐Ÿ› + Hassan ALAMI
    Hassan ALAMI

    ๐Ÿ› Heber
    Heber

    ๐Ÿ› Henning Schmiedehausen
    Henning Schmiedehausen

    ๐Ÿ’ป ๐Ÿ› Henning von Bargen
    Henning von Bargen

    ๐Ÿ’ป Hervรฉ Boutemy
    Hervรฉ Boutemy

    ๐Ÿ› Himanshu Pandey
    Himanshu Pandey

    ๐Ÿ› Hokwang Lee
    Hokwang Lee

    ๐Ÿ› - Hooperbloob
    Hooperbloob

    ๐Ÿ’ป + Hooperbloob
    Hooperbloob

    ๐Ÿ’ป Hung PHAN
    Hung PHAN

    ๐Ÿ› IDoCodingStuffs
    IDoCodingStuffs

    ๐Ÿ’ป ๐Ÿ› Iccen Gan
    Iccen Gan

    ๐Ÿ› Ignacio Mariano Tirabasso
    Ignacio Mariano Tirabasso

    ๐Ÿ› Igor Melnichenko
    Igor Melnichenko

    ๐Ÿ› Igor Moreno
    Igor Moreno

    ๐Ÿ› - Intelesis-MS
    Intelesis-MS

    ๐Ÿ› + Intelesis-MS
    Intelesis-MS

    ๐Ÿ› Iroha_
    Iroha_

    ๐Ÿ› Ishan Srivastava
    Ishan Srivastava

    ๐Ÿ› Iskren Stanislavov
    Iskren Stanislavov

    ๐Ÿ› Ivan Vakhrushev
    Ivan Vakhrushev

    ๐Ÿ› Ivano Guerini
    Ivano Guerini

    ๐Ÿ› Ivar Andreas Bonsaksen
    Ivar Andreas Bonsaksen

    ๐Ÿ› - Ivo ล mรญd
    Ivo ล mรญd

    ๐Ÿ› + Ivo ล mรญd
    Ivo ล mรญd

    ๐Ÿ› JJengility
    JJengility

    ๐Ÿ› Jake Hemmerle
    Jake Hemmerle

    ๐Ÿ› Jakub Dupak
    Jakub Dupak

    ๐Ÿ’ป James Harrison
    James Harrison

    ๐Ÿ› ๐Ÿ’ป Jamie Bisotti
    Jamie Bisotti

    ๐Ÿ› Jan
    Jan

    ๐Ÿ› - Jan Aertgeerts
    Jan Aertgeerts

    ๐Ÿ’ป ๐Ÿ› + Jan Aertgeerts
    Jan Aertgeerts

    ๐Ÿ’ป ๐Ÿ› Jan Brรผmmer
    Jan Brรผmmer

    ๐Ÿ› Jan Tล™รญska
    Jan Tล™รญska

    ๐Ÿ› Jan-Lukas Else
    Jan-Lukas Else

    ๐Ÿ› Jason Qiu
    Jason Qiu

    ๐Ÿ’ป ๐Ÿ“– Jason Williams
    Jason Williams

    ๐Ÿ› Javier Spagnoletti
    Javier Spagnoletti

    ๐Ÿ› - Jean-Paul Mayer
    Jean-Paul Mayer

    ๐Ÿ› + Jean-Paul Mayer
    Jean-Paul Mayer

    ๐Ÿ› Jean-Simon Larochelle
    Jean-Simon Larochelle

    ๐Ÿ› Jeff Bartolotta
    Jeff Bartolotta

    ๐Ÿ’ป ๐Ÿ› Jeff Hube
    Jeff Hube

    ๐Ÿ’ป ๐Ÿ› Jeff Jensen
    Jeff Jensen

    ๐Ÿ› Jeff May
    Jeff May

    ๐Ÿ› Jens Gerdes
    Jens Gerdes

    ๐Ÿ› - Jeroen Borgers
    Jeroen Borgers

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข + Jeroen Borgers
    Jeroen Borgers

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข Jeroen Meijer
    Jeroen Meijer

    ๐Ÿ› Jeroen van Wilgenburg
    Jeroen van Wilgenburg

    ๐Ÿ“– Jerome Russ
    Jerome Russ

    ๐Ÿ› JerritEic
    JerritEic

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Jiri Pejchal
    Jiri Pejchal

    ๐Ÿ› Jithin Sunny
    Jithin Sunny

    ๐Ÿ› - Jiล™รญ ล korpil
    Jiล™รญ ล korpil

    ๐Ÿ› + Jiล™รญ ล korpil
    Jiล™รญ ล korpil

    ๐Ÿ› Joao Machado
    Joao Machado

    ๐Ÿ› Jochen Krauss
    Jochen Krauss

    ๐Ÿ› Johan Hammar
    Johan Hammar

    ๐Ÿ› John Karp
    John Karp

    ๐Ÿ› John Zhang
    John Zhang

    ๐Ÿ› John-Teng
    John-Teng

    ๐Ÿ’ป ๐Ÿ› - Jon Moroney
    Jon Moroney

    ๐Ÿ’ป ๐Ÿ› + Jon Moroney
    Jon Moroney

    ๐Ÿ’ป ๐Ÿ› Jonas Geiregat
    Jonas Geiregat

    ๐Ÿ› Jonas KeรŸler
    Jonas KeรŸler

    ๐Ÿ› Jonathan Wiesel
    Jonathan Wiesel

    ๐Ÿ’ป ๐Ÿ› Jordan
    Jordan

    ๐Ÿ› Jordi Llach
    Jordi Llach

    ๐Ÿ› Jorge Solรณrzano
    Jorge Solรณrzano

    ๐Ÿ› - JorneVL
    JorneVL

    ๐Ÿ› + JorneVL
    JorneVL

    ๐Ÿ› Jose Palafox
    Jose Palafox

    ๐Ÿ› Jose Stovall
    Jose Stovall

    ๐Ÿ› Joseph
    Joseph

    ๐Ÿ’ป Joseph Heenan
    Joseph Heenan

    ๐Ÿ› Josh Feingold
    Josh Feingold

    ๐Ÿ’ป ๐Ÿ› Josh Holthaus
    Josh Holthaus

    ๐Ÿ› - Joshua S Arquilevich
    Joshua S Arquilevich

    ๐Ÿ› + Joshua S Arquilevich
    Joshua S Arquilevich

    ๐Ÿ› Joรฃo Dinis Ferreira
    Joรฃo Dinis Ferreira

    ๐Ÿ“– Joรฃo Ferreira
    Joรฃo Ferreira

    ๐Ÿ’ป ๐Ÿ› Joรฃo Pedro Schmitt
    Joรฃo Pedro Schmitt

    ๐Ÿ› Juan Martรญn Sotuyo Dodero
    Juan Martรญn Sotuyo Dodero

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง Juan Pablo Civile
    Juan Pablo Civile

    ๐Ÿ› Julian Voronetsky
    Julian Voronetsky

    ๐Ÿ› - Julien
    Julien

    ๐Ÿ› + Julien
    Julien

    ๐Ÿ› Julius
    Julius

    ๐Ÿ› JustPRV
    JustPRV

    ๐Ÿ› Justin Stroud
    Justin Stroud

    ๐Ÿ’ป Jรถrn Huxhorn
    Jรถrn Huxhorn

    ๐Ÿ› KThompso
    KThompso

    ๐Ÿ› Kai Amundsen
    Kai Amundsen

    ๐Ÿ› - Karel Vervaeke
    Karel Vervaeke

    ๐Ÿ› + Karel Vervaeke
    Karel Vervaeke

    ๐Ÿ› Karl-Andero Mere
    Karl-Andero Mere

    ๐Ÿ› Karl-Philipp Richter
    Karl-Philipp Richter

    ๐Ÿ› Karsten Silz
    Karsten Silz

    ๐Ÿ› Kazuma Watanabe
    Kazuma Watanabe

    ๐Ÿ› Kev
    Kev

    ๐Ÿ› Keve Mรผller
    Keve Mรผller

    ๐Ÿ› - Kevin Guerra
    Kevin Guerra

    ๐Ÿ’ป + Kevin Guerra
    Kevin Guerra

    ๐Ÿ’ป Kevin Jones
    Kevin Jones

    ๐Ÿ› ๐Ÿ’ป Kevin Poorman
    Kevin Poorman

    ๐Ÿ› Kevin Wayne
    Kevin Wayne

    ๐Ÿ› Kieran Black
    Kieran Black

    ๐Ÿ› Kirill Zubov
    Kirill Zubov

    ๐Ÿ› Kirk Clemens
    Kirk Clemens

    ๐Ÿ’ป ๐Ÿ› - Klaus Hartl
    Klaus Hartl

    ๐Ÿ› + Klaus Hartl
    Klaus Hartl

    ๐Ÿ› Koen Van Looveren
    Koen Van Looveren

    ๐Ÿ› Kris Scheibe
    Kris Scheibe

    ๐Ÿ’ป ๐Ÿ› Krystian Dabrowski
    Krystian Dabrowski

    ๐Ÿ› ๐Ÿ’ป Kunal Thanki
    Kunal Thanki

    ๐Ÿ› Kursat Aktas
    Kursat Aktas

    ๐Ÿ“– LaLucid
    LaLucid

    ๐Ÿ’ป - Larry Diamond
    Larry Diamond

    ๐Ÿ’ป ๐Ÿ› + Larry Diamond
    Larry Diamond

    ๐Ÿ’ป ๐Ÿ› Lars Knickrehm
    Lars Knickrehm

    ๐Ÿ› Laurent Bovet
    Laurent Bovet

    ๐Ÿ› ๐Ÿ’ป Leo Gutierrez
    Leo Gutierrez

    ๐Ÿ› LiGaOg
    LiGaOg

    ๐Ÿ’ป Liam Sharp
    Liam Sharp

    ๐Ÿ› Lintsi
    Lintsi

    ๐Ÿ› - Linus Fernandes
    Linus Fernandes

    ๐Ÿ› + Linus Fernandes
    Linus Fernandes

    ๐Ÿ› Lixon Lookose
    Lixon Lookose

    ๐Ÿ› Logesh
    Logesh

    ๐Ÿ› Lorenzo Gabriele
    Lorenzo Gabriele

    ๐Ÿ› Loรฏc Ledoyen
    Loรฏc Ledoyen

    ๐Ÿ› Lucas
    Lucas

    ๐Ÿ› Lucas Silva
    Lucas Silva

    ๐Ÿ› - Lucas Soncini
    Lucas Soncini

    ๐Ÿ’ป ๐Ÿ› + Lucas Soncini
    Lucas Soncini

    ๐Ÿ’ป ๐Ÿ› Luis Alcantar
    Luis Alcantar

    ๐Ÿ’ป Lukas Grรคf
    Lukas Grรคf

    ๐Ÿ’ป Lukasz Slonina
    Lukasz Slonina

    ๐Ÿ› Lukebray
    Lukebray

    ๐Ÿ› Lynn
    Lynn

    ๐Ÿ’ป ๐Ÿ› Lyor Goldstein
    Lyor Goldstein

    ๐Ÿ› - MCMicS
    MCMicS

    ๐Ÿ› + MCMicS
    MCMicS

    ๐Ÿ› Macarse
    Macarse

    ๐Ÿ› Machine account for PMD
    Machine account for PMD

    ๐Ÿ’ป Maciek Siemczyk
    Maciek Siemczyk

    ๐Ÿ› Maikel Steneker
    Maikel Steneker

    ๐Ÿ’ป ๐Ÿ› Maksim Moiseikin
    Maksim Moiseikin

    ๐Ÿ› Manfred Koch
    Manfred Koch

    ๐Ÿ› - Manuel Moya Ferrer
    Manuel Moya Ferrer

    ๐Ÿ’ป ๐Ÿ› + Manuel Moya Ferrer
    Manuel Moya Ferrer

    ๐Ÿ’ป ๐Ÿ› Manuel Ryan
    Manuel Ryan

    ๐Ÿ› Marat Vyshegorodtsev
    Marat Vyshegorodtsev

    ๐Ÿ› Marcel Hรคrle
    Marcel Hรคrle

    ๐Ÿ› Marcello Fialho
    Marcello Fialho

    ๐Ÿ› Marcin Dฤ…browski
    Marcin Dฤ…browski

    ๐Ÿ’ป Marcin Rataj
    Marcin Rataj

    ๐Ÿ› - Marcono1234
    Marcono1234

    ๐Ÿ› + Marcono1234
    Marcono1234

    ๐Ÿ› Mark Adamcin
    Mark Adamcin

    ๐Ÿ› Mark Hall
    Mark Hall

    ๐Ÿ’ป ๐Ÿ› Mark Kolich
    Mark Kolich

    ๐Ÿ› Mark Pritchard
    Mark Pritchard

    ๐Ÿ› Markus Rathgeb
    Markus Rathgeb

    ๐Ÿ› Marquis Wang
    Marquis Wang

    ๐Ÿ› - MartGit
    MartGit

    ๐Ÿ› + MartGit
    MartGit

    ๐Ÿ› Martin Feldsztejn
    Martin Feldsztejn

    ๐Ÿ› Martin Lehmann
    Martin Lehmann

    ๐Ÿ› Martin Spamer
    Martin Spamer

    ๐Ÿ› Martin Tarjรกnyi
    Martin Tarjรกnyi

    ๐Ÿ› MatFl
    MatFl

    ๐Ÿ› Mateusz Stefanski
    Mateusz Stefanski

    ๐Ÿ› - Mathieu Gouin
    Mathieu Gouin

    ๐Ÿ› + Mathieu Gouin
    Mathieu Gouin

    ๐Ÿ› MatiasComercio
    MatiasComercio

    ๐Ÿ’ป ๐Ÿ› Matt Benson
    Matt Benson

    ๐Ÿ› Matt De Poorter
    Matt De Poorter

    ๐Ÿ› Matt Hargett
    Matt Hargett

    ๐Ÿ’ป ๐Ÿ’ต Matt Harrah
    Matt Harrah

    ๐Ÿ› Matt Nelson
    Matt Nelson

    ๐Ÿ› - Matthew Amos
    Matthew Amos

    ๐Ÿ› + Matthew Amos
    Matthew Amos

    ๐Ÿ› Matthew Duggan
    Matthew Duggan

    ๐Ÿ› Matthew Hall
    Matthew Hall

    ๐Ÿ› Matthew Rossner
    Matthew Rossner

    ๐Ÿ› Matรญas Fraga
    Matรญas Fraga

    ๐Ÿ’ป ๐Ÿ› Maxime Robert
    Maxime Robert

    ๐Ÿ’ป ๐Ÿ› MetaBF
    MetaBF

    ๐Ÿ› - Metin Dagcilar
    Metin Dagcilar

    ๐Ÿ› + Metin Dagcilar
    Metin Dagcilar

    ๐Ÿ› Michael
    Michael

    ๐Ÿ› Michael Bell
    Michael Bell

    ๐Ÿ› Michael Bernstein
    Michael Bernstein

    ๐Ÿ› Michael Clay
    Michael Clay

    ๐Ÿ› Michael Dombrowski
    Michael Dombrowski

    ๐Ÿ› Michael Hausegger
    Michael Hausegger

    ๐Ÿ› - Michael Hoefer
    Michael Hoefer

    ๐Ÿ› + Michael Hoefer
    Michael Hoefer

    ๐Ÿ› Michael Kolesnikov
    Michael Kolesnikov

    ๐Ÿ› Michael Mรถbius
    Michael Mรถbius

    ๐Ÿ› Michael N. Lipp
    Michael N. Lipp

    ๐Ÿ› Michael Pellegrini
    Michael Pellegrini

    ๐Ÿ› Michal Kordas
    Michal Kordas

    ๐Ÿ› Michaล‚ Borek
    Michaล‚ Borek

    ๐Ÿ› - Michaล‚ Kuliล„ski
    Michaล‚ Kuliล„ski

    ๐Ÿ› + Michaล‚ Kuliล„ski
    Michaล‚ Kuliล„ski

    ๐Ÿ› Miguel Nรบรฑez Dรญaz-Montes
    Miguel Nรบรฑez Dรญaz-Montes

    ๐Ÿ› Mihai Ionut
    Mihai Ionut

    ๐Ÿ› Mikhail Kuchma
    Mikhail Kuchma

    ๐Ÿ› Mirek Hankus
    Mirek Hankus

    ๐Ÿ› Mitch Spano
    Mitch Spano

    ๐Ÿ’ป ๐Ÿ› Mladjan Gadzic
    Mladjan Gadzic

    ๐Ÿ› - MrAngry52
    MrAngry52

    ๐Ÿ› + MrAngry52
    MrAngry52

    ๐Ÿ› Muminur Choudhury
    Muminur Choudhury

    ๐Ÿ› Mykhailo Palahuta
    Mykhailo Palahuta

    ๐Ÿ’ป ๐Ÿ› Nagendra Kumar Singh
    Nagendra Kumar Singh

    ๐Ÿ› Nahuel Barrios
    Nahuel Barrios

    ๐Ÿ› Nakul Sharma
    Nakul Sharma

    ๐Ÿ› Nathan Braun
    Nathan Braun

    ๐Ÿ› - Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› + Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› Nathanaรซl
    Nathanaรซl

    ๐Ÿ› Naveen
    Naveen

    ๐Ÿ’ป Nazdravi
    Nazdravi

    ๐Ÿ› Neha-Dhonde
    Neha-Dhonde

    ๐Ÿ› Nicholas Doyle
    Nicholas Doyle

    ๐Ÿ› - Nick Butcher
    Nick Butcher

    ๐Ÿ› + Nick Butcher
    Nick Butcher

    ๐Ÿ› Nico Gallinal
    Nico Gallinal

    ๐Ÿ› Nicola Dal Maso
    Nicola Dal Maso

    ๐Ÿ› Nicolas Filotto
    Nicolas Filotto

    ๐Ÿ’ป Nicolas Vervelle
    Nicolas Vervelle

    ๐Ÿ› Nicolas Vuillamy
    Nicolas Vuillamy

    ๐Ÿ“– Nikita Chursin
    Nikita Chursin

    ๐Ÿ› - Niklas Baudy
    Niklas Baudy

    ๐Ÿ› + Niklas Baudy
    Niklas Baudy

    ๐Ÿ› Nikolas Havrikov
    Nikolas Havrikov

    ๐Ÿ› Nilesh Virkar
    Nilesh Virkar

    ๐Ÿ› Nimit Patel
    Nimit Patel

    ๐Ÿ› Niranjan Harpale
    Niranjan Harpale

    ๐Ÿ› Nirvik Patel
    Nirvik Patel

    ๐Ÿ’ป Noah Sussman
    Noah Sussman

    ๐Ÿ› - Noah0120
    Noah0120

    ๐Ÿ› + Noah0120
    Noah0120

    ๐Ÿ› Noam Tamim
    Noam Tamim

    ๐Ÿ› Noel Grandin
    Noel Grandin

    ๐Ÿ› Olaf Haalstra
    Olaf Haalstra

    ๐Ÿ› Oleg Andreych
    Oleg Andreych

    ๐Ÿ’ป ๐Ÿ› Oleg Pavlenko
    Oleg Pavlenko

    ๐Ÿ› Oleksii Dykov
    Oleksii Dykov

    ๐Ÿ’ป ๐Ÿ› - Oliver Eikemeier
    Oliver Eikemeier

    ๐Ÿ› + Oliver Eikemeier
    Oliver Eikemeier

    ๐Ÿ› Oliver Siegmar
    Oliver Siegmar

    ๐Ÿ’ต Olivier Parent
    Olivier Parent

    ๐Ÿ’ป ๐Ÿ› Ollie Abbey
    Ollie Abbey

    ๐Ÿ’ป ๐Ÿ› Ondrej Kratochvil
    Ondrej Kratochvil

    ๐Ÿ› OverDrone
    OverDrone

    ๐Ÿ› Ozan Gulle
    Ozan Gulle

    ๐Ÿ’ป ๐Ÿ› - PUNEET JAIN
    PUNEET JAIN

    ๐Ÿ› + PUNEET JAIN
    PUNEET JAIN

    ๐Ÿ› Parbati Bose
    Parbati Bose

    ๐Ÿ› Paul Berg
    Paul Berg

    ๐Ÿ› Paul Guyot
    Paul Guyot

    ๐Ÿ’ป Pavel Bludov
    Pavel Bludov

    ๐Ÿ› Pavel Miฤka
    Pavel Miฤka

    ๐Ÿ› Pedro Nuno Santos
    Pedro Nuno Santos

    ๐Ÿ› - Pedro Rijo
    Pedro Rijo

    ๐Ÿ› + Pedro Rijo
    Pedro Rijo

    ๐Ÿ› Pelisse Romain
    Pelisse Romain

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Per Abich
    Per Abich

    ๐Ÿ’ป Pete Davids
    Pete Davids

    ๐Ÿ› Peter Bruin
    Peter Bruin

    ๐Ÿ› Peter Chittum
    Peter Chittum

    ๐Ÿ’ป ๐Ÿ› Peter Cudmore
    Peter Cudmore

    ๐Ÿ› - Peter Kasson
    Peter Kasson

    ๐Ÿ› + Peter Kasson
    Peter Kasson

    ๐Ÿ› Peter Kofler
    Peter Kofler

    ๐Ÿ› Peter Paul Bakker
    Peter Paul Bakker

    ๐Ÿ’ป Peter Rader
    Peter Rader

    ๐Ÿ› Pham Hai Trung
    Pham Hai Trung

    ๐Ÿ› Philip Graf
    Philip Graf

    ๐Ÿ’ป ๐Ÿ› Philip Hachey
    Philip Hachey

    ๐Ÿ› - Philippe Ozil
    Philippe Ozil

    ๐Ÿ› + Philippe Ozil
    Philippe Ozil

    ๐Ÿ› Phinehas Artemix
    Phinehas Artemix

    ๐Ÿ› Phokham Nonava
    Phokham Nonava

    ๐Ÿ› Pim van der Loos
    Pim van der Loos

    ๐Ÿ’ป โš ๏ธ Piotr Szymaล„ski
    Piotr Szymaล„ski

    ๐Ÿ› Piotrek ลปygieล‚o
    Piotrek ลปygieล‚o

    ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– Pranay Jaiswal
    Pranay Jaiswal

    ๐Ÿ› - Prasad Kamath
    Prasad Kamath

    ๐Ÿ› + Prasad Kamath
    Prasad Kamath

    ๐Ÿ› Prasanna
    Prasanna

    ๐Ÿ› Presh-AR
    Presh-AR

    ๐Ÿ› Puneet1726
    Puneet1726

    ๐Ÿ› RBRi
    RBRi

    ๐Ÿ› Rafael Cortรชs
    Rafael Cortรชs

    ๐Ÿ› RaheemShaik999
    RaheemShaik999

    ๐Ÿ› - RajeshR
    RajeshR

    ๐Ÿ’ป ๐Ÿ› + RajeshR
    RajeshR

    ๐Ÿ’ป ๐Ÿ› Ramachandra Mohan
    Ramachandra Mohan

    ๐Ÿ› Ramel0921
    Ramel0921

    ๐Ÿ› Raquel Pau
    Raquel Pau

    ๐Ÿ› Ravikiran Janardhana
    Ravikiran Janardhana

    ๐Ÿ› Reda Benhemmouche
    Reda Benhemmouche

    ๐Ÿ› Reinhard Schiedermeier
    Reinhard Schiedermeier

    ๐Ÿ› - Renato Oliveira
    Renato Oliveira

    ๐Ÿ’ป ๐Ÿ› + Renato Oliveira
    Renato Oliveira

    ๐Ÿ’ป ๐Ÿ› Rich DiCroce
    Rich DiCroce

    ๐Ÿ› Richard Corfield
    Richard Corfield

    ๐Ÿ’ป Richard Corfield
    Richard Corfield

    ๐Ÿ› ๐Ÿ’ป Riot R1cket
    Riot R1cket

    ๐Ÿ› Rishabh Jain
    Rishabh Jain

    ๐Ÿ› RishabhDeep Singh
    RishabhDeep Singh

    ๐Ÿ› - Rob Baillie
    Rob Baillie

    ๐Ÿ› + Rob Baillie
    Rob Baillie

    ๐Ÿ› Robbie Martinus
    Robbie Martinus

    ๐Ÿ’ป ๐Ÿ› Robert Henry
    Robert Henry

    ๐Ÿ› Robert Mihaly
    Robert Mihaly

    ๐Ÿ› Robert Painsi
    Robert Painsi

    ๐Ÿ› Robert Russell
    Robert Russell

    ๐Ÿ› Robert Sรถsemann
    Robert Sรถsemann

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ› - Robert Whitebit
    Robert Whitebit

    ๐Ÿ› + Robert Whitebit
    Robert Whitebit

    ๐Ÿ› Robin Richtsfeld
    Robin Richtsfeld

    ๐Ÿ› Robin Stocker
    Robin Stocker

    ๐Ÿ’ป ๐Ÿ› Robin Wils
    Robin Wils

    ๐Ÿ› RochusOest
    RochusOest

    ๐Ÿ› Rodolfo Noviski
    Rodolfo Noviski

    ๐Ÿ› Rodrigo Casara
    Rodrigo Casara

    ๐Ÿ› - Rodrigo Fernandes
    Rodrigo Fernandes

    ๐Ÿ› + Rodrigo Fernandes
    Rodrigo Fernandes

    ๐Ÿ› Roman Salvador
    Roman Salvador

    ๐Ÿ’ป ๐Ÿ› Ronald Blaschke
    Ronald Blaschke

    ๐Ÿ› Rรณbert Papp
    Rรณbert Papp

    ๐Ÿ› Saikat Sengupta
    Saikat Sengupta

    ๐Ÿ› Saksham Handu
    Saksham Handu

    ๐Ÿ› Saladoc
    Saladoc

    ๐Ÿ› - Salesforce Bob Lightning
    Salesforce Bob Lightning

    ๐Ÿ› + Salesforce Bob Lightning
    Salesforce Bob Lightning

    ๐Ÿ› Sam Carlberg
    Sam Carlberg

    ๐Ÿ› Sascha Riemer
    Sascha Riemer

    ๐Ÿ› Sashko
    Sashko

    ๐Ÿ’ป Satoshi Kubo
    Satoshi Kubo

    ๐Ÿ› Scott Kennedy
    Scott Kennedy

    ๐Ÿ› Scott Wells
    Scott Wells

    ๐Ÿ› ๐Ÿ’ป - Scrates1
    Scrates1

    ๐Ÿ› ๐Ÿ’ป + Scrates1
    Scrates1

    ๐Ÿ› ๐Ÿ’ป Scrsloota
    Scrsloota

    ๐Ÿ’ป Sebastian Bรถgl
    Sebastian Bรถgl

    ๐Ÿ› Sebastian Davids
    Sebastian Davids

    ๐Ÿ› Sebastian Schuberth
    Sebastian Schuberth

    ๐Ÿ› Sebastian Schwarz
    Sebastian Schwarz

    ๐Ÿ› Seren
    Seren

    ๐Ÿ› ๐Ÿ’ป - Sergey Gorbaty
    Sergey Gorbaty

    ๐Ÿ› + Sergey Gorbaty
    Sergey Gorbaty

    ๐Ÿ› Sergey Kozlov
    Sergey Kozlov

    ๐Ÿ› Sergey Yanzin
    Sergey Yanzin

    ๐Ÿ’ป ๐Ÿ› Seth Wilcox
    Seth Wilcox

    ๐Ÿ’ป Shai Bennathan
    Shai Bennathan

    ๐Ÿ› ๐Ÿ’ป Shubham
    Shubham

    ๐Ÿ’ป ๐Ÿ› Simon Abykov
    Simon Abykov

    ๐Ÿ’ป ๐Ÿ› - Simon Xiao
    Simon Xiao

    ๐Ÿ› + Simon Xiao
    Simon Xiao

    ๐Ÿ› Srinivasan Venkatachalam
    Srinivasan Venkatachalam

    ๐Ÿ› Stanislav Gromov
    Stanislav Gromov

    ๐Ÿ› Stanislav Myachenkov
    Stanislav Myachenkov

    ๐Ÿ’ป Stefan Birkner
    Stefan Birkner

    ๐Ÿ› Stefan Bohn
    Stefan Bohn

    ๐Ÿ› Stefan Endrullis
    Stefan Endrullis

    ๐Ÿ› - Stefan Klรถss-Schuster
    Stefan Klรถss-Schuster

    ๐Ÿ› + Stefan Klรถss-Schuster
    Stefan Klรถss-Schuster

    ๐Ÿ› Stefan Wolf
    Stefan Wolf

    ๐Ÿ› Stephan H. Wissel
    Stephan H. Wissel

    ๐Ÿ› Stephen
    Stephen

    ๐Ÿ› Stephen Carter
    Stephen Carter

    ๐Ÿ› Stephen Friedrich
    Stephen Friedrich

    ๐Ÿ› Steve Babula
    Steve Babula

    ๐Ÿ’ป - Steven Stearns
    Steven Stearns

    ๐Ÿ› ๐Ÿ’ป + Steven Stearns
    Steven Stearns

    ๐Ÿ› ๐Ÿ’ป Stexxe
    Stexxe

    ๐Ÿ› Stian Lรฅgstad
    Stian Lรฅgstad

    ๐Ÿ› StuartClayton5
    StuartClayton5

    ๐Ÿ› Supun Arunoda
    Supun Arunoda

    ๐Ÿ› Suren Abrahamyan
    Suren Abrahamyan

    ๐Ÿ› Suvashri
    Suvashri

    ๐Ÿ“– - Sven Barden
    Sven Barden

    ๐Ÿ› + Sven Barden
    Sven Barden

    ๐Ÿ› SwatiBGupta1110
    SwatiBGupta1110

    ๐Ÿ› SyedThoufich
    SyedThoufich

    ๐Ÿ› Szymon Sasin
    Szymon Sasin

    ๐Ÿ› T-chuangxin
    T-chuangxin

    ๐Ÿ› TERAI Atsuhiro
    TERAI Atsuhiro

    ๐Ÿ› TIOBE Software
    TIOBE Software

    ๐Ÿ’ป ๐Ÿ› - Tarush Singh
    Tarush Singh

    ๐Ÿ’ป + Tarush Singh
    Tarush Singh

    ๐Ÿ’ป Taylor Smock
    Taylor Smock

    ๐Ÿ› Techeira Damiรกn
    Techeira Damiรกn

    ๐Ÿ’ป ๐Ÿ› Ted Husted
    Ted Husted

    ๐Ÿ› TehBakker
    TehBakker

    ๐Ÿ› The Gitter Badger
    The Gitter Badger

    ๐Ÿ› Theodoor
    Theodoor

    ๐Ÿ› - Thiago Henrique Hรผpner
    Thiago Henrique Hรผpner

    ๐Ÿ› + Thiago Henrique Hรผpner
    Thiago Henrique Hรผpner

    ๐Ÿ› Thibault Meyer
    Thibault Meyer

    ๐Ÿ› Thomas Gรผttler
    Thomas Gรผttler

    ๐Ÿ› Thomas Jones-Low
    Thomas Jones-Low

    ๐Ÿ› Thomas Smith
    Thomas Smith

    ๐Ÿ’ป ๐Ÿ› ThrawnCA
    ThrawnCA

    ๐Ÿ› Thu Vo
    Thu Vo

    ๐Ÿ› - Thunderforge
    Thunderforge

    ๐Ÿ’ป ๐Ÿ› + Thunderforge
    Thunderforge

    ๐Ÿ’ป ๐Ÿ› Tim van der Lippe
    Tim van der Lippe

    ๐Ÿ› Tobias Weimer
    Tobias Weimer

    ๐Ÿ’ป ๐Ÿ› Tom Copeland
    Tom Copeland

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– Tom Daly
    Tom Daly

    ๐Ÿ› Tomas
    Tomas

    ๐Ÿ› Tomer Figenblat
    Tomer Figenblat

    ๐Ÿ› - Tomi De Lucca
    Tomi De Lucca

    ๐Ÿ’ป ๐Ÿ› + Tomi De Lucca
    Tomi De Lucca

    ๐Ÿ’ป ๐Ÿ› Tony
    Tony

    ๐Ÿ“– Torsten Kleiber
    Torsten Kleiber

    ๐Ÿ› TrackerSB
    TrackerSB

    ๐Ÿ› Tyson Stewart
    Tyson Stewart

    ๐Ÿ› Ullrich Hafner
    Ullrich Hafner

    ๐Ÿ› Utku Cuhadaroglu
    Utku Cuhadaroglu

    ๐Ÿ’ป ๐Ÿ› - Valentin Brandl
    Valentin Brandl

    ๐Ÿ› + Valentin Brandl
    Valentin Brandl

    ๐Ÿ› Valeria
    Valeria

    ๐Ÿ› Valery Yatsynovich
    Valery Yatsynovich

    ๐Ÿ“– Vasily Anisimov
    Vasily Anisimov

    ๐Ÿ› Vedant Chokshi
    Vedant Chokshi

    ๐Ÿ› Vibhor Goyal
    Vibhor Goyal

    ๐Ÿ› Vickenty Fesunov
    Vickenty Fesunov

    ๐Ÿ› - Victor Noรซl
    Victor Noรซl

    ๐Ÿ› + Victor Noรซl
    Victor Noรซl

    ๐Ÿ› Vincent Galloy
    Vincent Galloy

    ๐Ÿ’ป Vincent HUYNH
    Vincent HUYNH

    ๐Ÿ› Vincent Maurin
    Vincent Maurin

    ๐Ÿ› Vincent Privat
    Vincent Privat

    ๐Ÿ› Vishhwas
    Vishhwas

    ๐Ÿ› Vishv_Android
    Vishv_Android

    ๐Ÿ› - Vitalii Yevtushenko
    Vitalii Yevtushenko

    ๐Ÿ› + Vitalii Yevtushenko
    Vitalii Yevtushenko

    ๐Ÿ› Vitaly
    Vitaly

    ๐Ÿ› Vitaly Polonetsky
    Vitaly Polonetsky

    ๐Ÿ› Vojtech Polivka
    Vojtech Polivka

    ๐Ÿ› Vsevolod Zholobov
    Vsevolod Zholobov

    ๐Ÿ› Vyom Yadav
    Vyom Yadav

    ๐Ÿ’ป Wang Shidong
    Wang Shidong

    ๐Ÿ› - Waqas Ahmed
    Waqas Ahmed

    ๐Ÿ› + Waqas Ahmed
    Waqas Ahmed

    ๐Ÿ› Wayne J. Earl
    Wayne J. Earl

    ๐Ÿ› Wchenghui
    Wchenghui

    ๐Ÿ› Wener
    Wener

    ๐Ÿ’ป Will Winder
    Will Winder

    ๐Ÿ› Willem A. Hajenius
    Willem A. Hajenius

    ๐Ÿ’ป William Brockhus
    William Brockhus

    ๐Ÿ’ป ๐Ÿ› - Wilson Kurniawan
    Wilson Kurniawan

    ๐Ÿ› + Wilson Kurniawan
    Wilson Kurniawan

    ๐Ÿ› Wim Deblauwe
    Wim Deblauwe

    ๐Ÿ› Woongsik Choi
    Woongsik Choi

    ๐Ÿ› XenoAmess
    XenoAmess

    ๐Ÿ’ป ๐Ÿ› Yang
    Yang

    ๐Ÿ’ป YaroslavTER
    YaroslavTER

    ๐Ÿ› Yasar Shaikh
    Yasar Shaikh

    ๐Ÿ’ป - Young Chan
    Young Chan

    ๐Ÿ’ป ๐Ÿ› + Young Chan
    Young Chan

    ๐Ÿ’ป ๐Ÿ› YuJin Kim
    YuJin Kim

    ๐Ÿ› Yuri Dolzhenko
    Yuri Dolzhenko

    ๐Ÿ› Yurii Dubinka
    Yurii Dubinka

    ๐Ÿ› Zoltan Farkas
    Zoltan Farkas

    ๐Ÿ› Zustin
    Zustin

    ๐Ÿ› aaronhurst-google
    aaronhurst-google

    ๐Ÿ› ๐Ÿ’ป - alexmodis
    alexmodis

    ๐Ÿ› + alexmodis
    alexmodis

    ๐Ÿ› andreoss
    andreoss

    ๐Ÿ› andrey81inmd
    andrey81inmd

    ๐Ÿ’ป ๐Ÿ› anicoara
    anicoara

    ๐Ÿ› arunprasathav
    arunprasathav

    ๐Ÿ› asiercamara
    asiercamara

    ๐Ÿ› astillich-igniti
    astillich-igniti

    ๐Ÿ’ป - avesolovksyy
    avesolovksyy

    ๐Ÿ› + avesolovksyy
    avesolovksyy

    ๐Ÿ› avishvat
    avishvat

    ๐Ÿ› avivmu
    avivmu

    ๐Ÿ› axelbarfod1
    axelbarfod1

    ๐Ÿ› b-3-n
    b-3-n

    ๐Ÿ› balbhadra9
    balbhadra9

    ๐Ÿ› base23de
    base23de

    ๐Ÿ› - bergander
    bergander

    ๐Ÿ› ๐Ÿ’ป + bergander
    bergander

    ๐Ÿ› ๐Ÿ’ป berkam
    berkam

    ๐Ÿ’ป ๐Ÿ› breizh31
    breizh31

    ๐Ÿ› caesarkim
    caesarkim

    ๐Ÿ› caiocarvalhotero
    caiocarvalhotero

    ๐Ÿ› carolyujing
    carolyujing

    ๐Ÿ› cbfiddle
    cbfiddle

    ๐Ÿ› - cesares-basilico
    cesares-basilico

    ๐Ÿ› + cesares-basilico
    cesares-basilico

    ๐Ÿ› chrite
    chrite

    ๐Ÿ› ciufudean
    ciufudean

    ๐Ÿ“– cobratbq
    cobratbq

    ๐Ÿ› coladict
    coladict

    ๐Ÿ› cosmoJFH
    cosmoJFH

    ๐Ÿ› cristalp
    cristalp

    ๐Ÿ› - crunsk
    crunsk

    ๐Ÿ› + crunsk
    crunsk

    ๐Ÿ› cwholmes
    cwholmes

    ๐Ÿ› cyberjj999
    cyberjj999

    ๐Ÿ› cyw3
    cyw3

    ๐Ÿ› ๐Ÿ“– d1ss0nanz
    d1ss0nanz

    ๐Ÿ› dague1
    dague1

    ๐Ÿ“– dalizi007
    dalizi007

    ๐Ÿ’ป - danbrycefairsailcom
    danbrycefairsailcom

    ๐Ÿ› + danbrycefairsailcom
    danbrycefairsailcom

    ๐Ÿ› dariansanity
    dariansanity

    ๐Ÿ› darrenmiliband
    darrenmiliband

    ๐Ÿ› davidburstrom
    davidburstrom

    ๐Ÿ› dbirkman-paloalto
    dbirkman-paloalto

    ๐Ÿ› deepak-patra
    deepak-patra

    ๐Ÿ› dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› - dinesh150
    dinesh150

    ๐Ÿ› + dinesh150
    dinesh150

    ๐Ÿ› diziaq
    diziaq

    ๐Ÿ› dreaminpast123
    dreaminpast123

    ๐Ÿ› duanyanan
    duanyanan

    ๐Ÿ› dutt-sanjay
    dutt-sanjay

    ๐Ÿ› duursma
    duursma

    ๐Ÿ’ป dylanleung
    dylanleung

    ๐Ÿ› - dzeigler
    dzeigler

    ๐Ÿ› + dzeigler
    dzeigler

    ๐Ÿ› eant60
    eant60

    ๐Ÿ› ekkirala
    ekkirala

    ๐Ÿ› emersonmoura
    emersonmoura

    ๐Ÿ› emouty
    emouty

    ๐Ÿ’ป ๐Ÿ› eugenepugach
    eugenepugach

    ๐Ÿ› fairy
    fairy

    ๐Ÿ› - filiprafalowicz
    filiprafalowicz

    ๐Ÿ’ป + filiprafalowicz
    filiprafalowicz

    ๐Ÿ’ป flxbl-io
    flxbl-io

    ๐Ÿ’ต foxmason
    foxmason

    ๐Ÿ› frankegabor
    frankegabor

    ๐Ÿ› frankl
    frankl

    ๐Ÿ› freafrea
    freafrea

    ๐Ÿ› fsapatin
    fsapatin

    ๐Ÿ› - gearsethenry
    gearsethenry

    ๐Ÿ› + gearsethenry
    gearsethenry

    ๐Ÿ› gracia19
    gracia19

    ๐Ÿ› gudzpoz
    gudzpoz

    ๐Ÿ› guo fei
    guo fei

    ๐Ÿ› gurmsc5
    gurmsc5

    ๐Ÿ› gwilymatgearset
    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ› haigsn
    haigsn

    ๐Ÿ› - hemanshu070
    hemanshu070

    ๐Ÿ› + hemanshu070
    hemanshu070

    ๐Ÿ› henrik242
    henrik242

    ๐Ÿ› hongpuwu
    hongpuwu

    ๐Ÿ› hvbtup
    hvbtup

    ๐Ÿ’ป ๐Ÿ› igniti GmbH
    igniti GmbH

    ๐Ÿ› ilovezfs
    ilovezfs

    ๐Ÿ› imax-erik
    imax-erik

    ๐Ÿ› - itaigilo
    itaigilo

    ๐Ÿ› + itaigilo
    itaigilo

    ๐Ÿ› jakivey32
    jakivey32

    ๐Ÿ› jbennett2091
    jbennett2091

    ๐Ÿ› jcamerin
    jcamerin

    ๐Ÿ› jkeener1
    jkeener1

    ๐Ÿ› jmetertea
    jmetertea

    ๐Ÿ› johnra2
    johnra2

    ๐Ÿ’ป - johnzhao9
    johnzhao9

    ๐Ÿ› + johnzhao9
    johnzhao9

    ๐Ÿ› josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ› kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ› karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“– karwer
    karwer

    ๐Ÿ› kaulonline
    kaulonline

    ๐Ÿ› kdaemonv
    kdaemonv

    ๐Ÿ› - kdebski85
    kdebski85

    ๐Ÿ› ๐Ÿ’ป + kdebski85
    kdebski85

    ๐Ÿ› ๐Ÿ’ป kenji21
    kenji21

    ๐Ÿ’ป ๐Ÿ› kfranic
    kfranic

    ๐Ÿ› khalidkh
    khalidkh

    ๐Ÿ› koalalam
    koalalam

    ๐Ÿ› krzyk
    krzyk

    ๐Ÿ› lasselindqvist
    lasselindqvist

    ๐Ÿ› - lgemeinhardt
    lgemeinhardt

    ๐Ÿ› + lgemeinhardt
    lgemeinhardt

    ๐Ÿ› lihuaib
    lihuaib

    ๐Ÿ› liqingjun123
    liqingjun123

    ๐Ÿ› lonelyma1021
    lonelyma1021

    ๐Ÿ› lpeddy
    lpeddy

    ๐Ÿ› lujiefsi
    lujiefsi

    ๐Ÿ’ป lukelukes
    lukelukes

    ๐Ÿ’ป - lyriccoder
    lyriccoder

    ๐Ÿ› + lyriccoder
    lyriccoder

    ๐Ÿ› marcelmore
    marcelmore

    ๐Ÿ› matchbox
    matchbox

    ๐Ÿ› matthiaskraaz
    matthiaskraaz

    ๐Ÿ› meandonlyme
    meandonlyme

    ๐Ÿ› mikesive
    mikesive

    ๐Ÿ› milossesic
    milossesic

    ๐Ÿ› - mluckam
    mluckam

    ๐Ÿ’ป ๐Ÿ› + mluckam
    mluckam

    ๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
    mohan-chinnappan-n

    ๐Ÿ’ป mriddell95
    mriddell95

    ๐Ÿ› mrlzh
    mrlzh

    ๐Ÿ› msloan
    msloan

    ๐Ÿ› mucharlaravalika
    mucharlaravalika

    ๐Ÿ› mvenneman
    mvenneman

    ๐Ÿ› - nareshl119
    nareshl119

    ๐Ÿ› + nareshl119
    nareshl119

    ๐Ÿ› nicolas-harraudeau-sonarsource
    nicolas-harraudeau-sonarsource

    ๐Ÿ› noerremark
    noerremark

    ๐Ÿ› novsirion
    novsirion

    ๐Ÿ› nwcm
    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
    oggboy

    ๐Ÿ› oinume
    oinume

    ๐Ÿ› - orimarko
    orimarko

    ๐Ÿ’ป ๐Ÿ› + orimarko
    orimarko

    ๐Ÿ’ป ๐Ÿ› pablogomez2197
    pablogomez2197

    ๐Ÿ› pacvz
    pacvz

    ๐Ÿ’ป pallavi agarwal
    pallavi agarwal

    ๐Ÿ› parksungrin
    parksungrin

    ๐Ÿ› patpatpat123
    patpatpat123

    ๐Ÿ› patriksevallius
    patriksevallius

    ๐Ÿ› - pbrajesh1
    pbrajesh1

    ๐Ÿ› + pbrajesh1
    pbrajesh1

    ๐Ÿ› phoenix384
    phoenix384

    ๐Ÿ› piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป plan3d
    plan3d

    ๐Ÿ› poojasix
    poojasix

    ๐Ÿ› prabhushrikant
    prabhushrikant

    ๐Ÿ› pujitha8783
    pujitha8783

    ๐Ÿ› - r-r-a-j
    r-r-a-j

    ๐Ÿ› + r-r-a-j
    r-r-a-j

    ๐Ÿ› raghujayjunk
    raghujayjunk

    ๐Ÿ› rajeshveera
    rajeshveera

    ๐Ÿ› rajeswarreddy88
    rajeswarreddy88

    ๐Ÿ› recdevs
    recdevs

    ๐Ÿ› reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ› rijkt
    rijkt

    ๐Ÿ› - rillig-tk
    rillig-tk

    ๐Ÿ› + rillig-tk
    rillig-tk

    ๐Ÿ› rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ› rnveach
    rnveach

    ๐Ÿ› rxmicro
    rxmicro

    ๐Ÿ› ryan-gustafson
    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ› sabi0
    sabi0

    ๐Ÿ› samc-gearset
    samc-gearset

    ๐Ÿ“– - scais
    scais

    ๐Ÿ› + scais
    scais

    ๐Ÿ› schosin
    schosin

    ๐Ÿ› screamingfrog
    screamingfrog

    ๐Ÿ’ต sebbASF
    sebbASF

    ๐Ÿ› sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป shilko2013
    shilko2013

    ๐Ÿ› shiomiyan
    shiomiyan

    ๐Ÿ“– - simeonKondr
    simeonKondr

    ๐Ÿ› + simeonKondr
    simeonKondr

    ๐Ÿ› snajberk
    snajberk

    ๐Ÿ› sniperrifle2004
    sniperrifle2004

    ๐Ÿ› snuyanzin
    snuyanzin

    ๐Ÿ› ๐Ÿ’ป soloturn
    soloturn

    ๐Ÿ› soyodream
    soyodream

    ๐Ÿ› sratz
    sratz

    ๐Ÿ› - stonio
    stonio

    ๐Ÿ› + stonio
    stonio

    ๐Ÿ› sturton
    sturton

    ๐Ÿ’ป ๐Ÿ› sudharmohan
    sudharmohan

    ๐Ÿ› suruchidawar
    suruchidawar

    ๐Ÿ› svenfinitiv
    svenfinitiv

    ๐Ÿ› szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป tashiscool
    tashiscool

    ๐Ÿ› - test-git-hook
    test-git-hook

    ๐Ÿ› + test-git-hook
    test-git-hook

    ๐Ÿ› testation21
    testation21

    ๐Ÿ’ป ๐Ÿ› thanosa
    thanosa

    ๐Ÿ› tiandiyixian
    tiandiyixian

    ๐Ÿ› tobwoerk
    tobwoerk

    ๐Ÿ› tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป trentchilders
    trentchilders

    ๐Ÿ› - triandicAnt
    triandicAnt

    ๐Ÿ› + triandicAnt
    triandicAnt

    ๐Ÿ› trishul14
    trishul14

    ๐Ÿ› tsui
    tsui

    ๐Ÿ› wangzitom12306
    wangzitom12306

    ๐Ÿ› winhkey
    winhkey

    ๐Ÿ› witherspore
    witherspore

    ๐Ÿ› wjljack
    wjljack

    ๐Ÿ› - wuchiuwong
    wuchiuwong

    ๐Ÿ› + wuchiuwong
    wuchiuwong

    ๐Ÿ› xingsong
    xingsong

    ๐Ÿ› xioayuge
    xioayuge

    ๐Ÿ› xnYi9wRezm
    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ› xuanuy
    xuanuy

    ๐Ÿ› xyf0921
    xyf0921

    ๐Ÿ› yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› - yasuharu-sato
    yasuharu-sato

    ๐Ÿ› + yasuharu-sato
    yasuharu-sato

    ๐Ÿ› zenglian
    zenglian

    ๐Ÿ› zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› zh3ng
    zh3ng

    ๐Ÿ› zt_soft
    zt_soft

    ๐Ÿ› ztt79
    ztt79

    ๐Ÿ› zzzzfeng
    zzzzfeng

    ๐Ÿ› - รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› + รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› ไปป่ดตๆฐ
    ไปป่ดตๆฐ

    ๐Ÿ› ๅคฉ็ƒญๅƒ่ฅฟ็“œ
    ๅคฉ็ƒญๅƒ่ฅฟ็“œ

    ๐Ÿ› ่Œ…ๅปถๅฎ‰
    ่Œ…ๅปถๅฎ‰

    ๐Ÿ’ป From 2933115faa2debffad66dd3a9a5ba60b25570e92 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 6 Feb 2025 10:08:56 +0100 Subject: [PATCH 0497/1962] Update release notes (#5503) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 26ec825d013..9fe328e64fd 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -20,6 +20,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ Merged pull requests +* [#5503](https://github.com/pmd/pmd/pull/5503): \[java] AvoidSynchronizedAtMethodLevel: Fixed error in code example - [Balazs Glatz](https://github.com/gbq6) (@gbq6) ### ๐Ÿ“ฆ Dependency updates From 88c4429f85500ab22da058df31f49295366a8d5f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 6 Feb 2025 12:14:42 +0100 Subject: [PATCH 0498/1962] [java] Fix UnusedPrivateMethod - always search decls in current AST Fixes #5486 --- docs/pages/release_notes.md | 2 ++ .../UnusedPrivateMethodRule.java | 21 ++++++------ .../unusedprivatemethod/issue5486/Class1.java | 25 +++++++++++++++ .../unusedprivatemethod/issue5486/Class2.java | 11 +++++++ .../bestpractices/xml/UnusedPrivateMethod.xml | 32 +++++++++++++++++++ 5 files changed, 80 insertions(+), 11 deletions(-) create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/issue5486/Class1.java create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/issue5486/Class2.java diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 9fe328e64fd..eee99132be8 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -15,6 +15,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* java-bestpractices + * [#5486](https://github.com/pmd/pmd/issues/5486): \[java] UnusedPrivateMethod detected when class is referenced in another class ### ๐Ÿšจ API Changes diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java index 0c739460af1..9495f7de8fb 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java @@ -144,24 +144,23 @@ private boolean hasExcludedName(ASTMethodDeclaration node) { } /** - * Find the method in the compilation unit. Note that this - * is a patch to fix some incorrect behavior of the rule in - * the java.lang package. This is due to the fact that some + * Find the method in the compilation unit. Note that this is a patch to fix some + * incorrect behavior of the rule in two cases: + * + *

    1. While parsing and type resolving a referenced class, that itself + * references the current class. In that case, we end up with the ASM symbols + * and symbol.tryGetNode() returns null. + * + *

    2. When dealing with classes in the java.lang package. + * This is due to the fact that some * java.lang types (like Object, or primitive boxes) are * treated specially by the type resolution framework, and * for those the preexisting ASM symbol is preferred over * the AST symbol - symbol.tryGetNode() returns null in that - * case. Since it only applies to these types we - * check that the package name is java.lang, to avoid doing - * that for other types. - * This is only relevant, when PMD is used to analyze OpenJDK + * case. This is only relevant, when PMD is used to analyze OpenJDK * sources, like with the regression tester. */ private static @Nullable ASTMethodDeclaration findDeclarationInCompilationUnit(ASTCompilationUnit acu, JExecutableSymbol symbol) { - if (!"java.lang".equals(acu.getPackageName()) - || !"java.lang".equals(symbol.getPackageName())) { - return null; - } return acu.descendants(ASTTypeDeclaration.class) .crossFindBoundaries() .filter(it -> it.getSymbol().equals(symbol.getEnclosingClass())) diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/issue5486/Class1.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/issue5486/Class1.java new file mode 100644 index 00000000000..33695ce9edc --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/issue5486/Class1.java @@ -0,0 +1,25 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.bestpractices.unusedprivatemethod.issue5486; + +public class Class1 { + public void publicMethod() { + new Class2().getClass1().privateMethod(); + } + + private void privateMethod() { // This method is detected as UnusedPrivateMethod (false positive) + // do stuff + } + + public void publicMethod2() { + // Declaring the variable, makes the PMD works fine (workaround) + Class1 class1 = new Class2().getClass1(); + class1.privateMethod2(); + } + + private void privateMethod2() { + // do stuff + } +} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/issue5486/Class2.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/issue5486/Class2.java new file mode 100644 index 00000000000..dc36c39082b --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/issue5486/Class2.java @@ -0,0 +1,11 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.bestpractices.unusedprivatemethod.issue5486; + +public class Class2 { + public Class1 getClass1() { + return new Class1(); + } +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index c9ecabd130c..fe92ddd7dd1 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2512,4 +2512,36 @@ public class PmdTestCase { } ]]> + + + #5486 [java] UnusedPrivateMethod detected when class is referenced in another class + 0 + + From aa876a5754796912b6ea669f0f2ee5ff0ea0b275 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 6 Feb 2025 12:15:07 +0100 Subject: [PATCH 0499/1962] Add @manuel-a-romeiro-alb as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 141 +++++++++++++------------- 2 files changed, 80 insertions(+), 70 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 46b435c53b0..b2f73be5df1 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7938,6 +7938,15 @@ "contributions": [ "doc" ] + }, + { + "login": "manuel-a-romeiro-alb", + "name": "Manuel Romeiro", + "avatar_url": "https://avatars.githubusercontent.com/u/170322479?v=4", + "profile": "https://github.com/manuel-a-romeiro-alb", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 6182d0abf96..d4ca3aba05a 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -493,635 +493,636 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Manuel Moya Ferrer
    Manuel Moya Ferrer

    ๐Ÿ’ป ๐Ÿ› + Manuel Romeiro
    Manuel Romeiro

    ๐Ÿ› Manuel Ryan
    Manuel Ryan

    ๐Ÿ› Marat Vyshegorodtsev
    Marat Vyshegorodtsev

    ๐Ÿ› Marcel Hรคrle
    Marcel Hรคrle

    ๐Ÿ› Marcello Fialho
    Marcello Fialho

    ๐Ÿ› Marcin Dฤ…browski
    Marcin Dฤ…browski

    ๐Ÿ’ป - Marcin Rataj
    Marcin Rataj

    ๐Ÿ› + Marcin Rataj
    Marcin Rataj

    ๐Ÿ› Marcono1234
    Marcono1234

    ๐Ÿ› Mark Adamcin
    Mark Adamcin

    ๐Ÿ› Mark Hall
    Mark Hall

    ๐Ÿ’ป ๐Ÿ› Mark Kolich
    Mark Kolich

    ๐Ÿ› Mark Pritchard
    Mark Pritchard

    ๐Ÿ› Markus Rathgeb
    Markus Rathgeb

    ๐Ÿ› - Marquis Wang
    Marquis Wang

    ๐Ÿ› + Marquis Wang
    Marquis Wang

    ๐Ÿ› MartGit
    MartGit

    ๐Ÿ› Martin Feldsztejn
    Martin Feldsztejn

    ๐Ÿ› Martin Lehmann
    Martin Lehmann

    ๐Ÿ› Martin Spamer
    Martin Spamer

    ๐Ÿ› Martin Tarjรกnyi
    Martin Tarjรกnyi

    ๐Ÿ› MatFl
    MatFl

    ๐Ÿ› - Mateusz Stefanski
    Mateusz Stefanski

    ๐Ÿ› + Mateusz Stefanski
    Mateusz Stefanski

    ๐Ÿ› Mathieu Gouin
    Mathieu Gouin

    ๐Ÿ› MatiasComercio
    MatiasComercio

    ๐Ÿ’ป ๐Ÿ› Matt Benson
    Matt Benson

    ๐Ÿ› Matt De Poorter
    Matt De Poorter

    ๐Ÿ› Matt Hargett
    Matt Hargett

    ๐Ÿ’ป ๐Ÿ’ต Matt Harrah
    Matt Harrah

    ๐Ÿ› - Matt Nelson
    Matt Nelson

    ๐Ÿ› + Matt Nelson
    Matt Nelson

    ๐Ÿ› Matthew Amos
    Matthew Amos

    ๐Ÿ› Matthew Duggan
    Matthew Duggan

    ๐Ÿ› Matthew Hall
    Matthew Hall

    ๐Ÿ› Matthew Rossner
    Matthew Rossner

    ๐Ÿ› Matรญas Fraga
    Matรญas Fraga

    ๐Ÿ’ป ๐Ÿ› Maxime Robert
    Maxime Robert

    ๐Ÿ’ป ๐Ÿ› - MetaBF
    MetaBF

    ๐Ÿ› + MetaBF
    MetaBF

    ๐Ÿ› Metin Dagcilar
    Metin Dagcilar

    ๐Ÿ› Michael
    Michael

    ๐Ÿ› Michael Bell
    Michael Bell

    ๐Ÿ› Michael Bernstein
    Michael Bernstein

    ๐Ÿ› Michael Clay
    Michael Clay

    ๐Ÿ› Michael Dombrowski
    Michael Dombrowski

    ๐Ÿ› - Michael Hausegger
    Michael Hausegger

    ๐Ÿ› + Michael Hausegger
    Michael Hausegger

    ๐Ÿ› Michael Hoefer
    Michael Hoefer

    ๐Ÿ› Michael Kolesnikov
    Michael Kolesnikov

    ๐Ÿ› Michael Mรถbius
    Michael Mรถbius

    ๐Ÿ› Michael N. Lipp
    Michael N. Lipp

    ๐Ÿ› Michael Pellegrini
    Michael Pellegrini

    ๐Ÿ› Michal Kordas
    Michal Kordas

    ๐Ÿ› - Michaล‚ Borek
    Michaล‚ Borek

    ๐Ÿ› + Michaล‚ Borek
    Michaล‚ Borek

    ๐Ÿ› Michaล‚ Kuliล„ski
    Michaล‚ Kuliล„ski

    ๐Ÿ› Miguel Nรบรฑez Dรญaz-Montes
    Miguel Nรบรฑez Dรญaz-Montes

    ๐Ÿ› Mihai Ionut
    Mihai Ionut

    ๐Ÿ› Mikhail Kuchma
    Mikhail Kuchma

    ๐Ÿ› Mirek Hankus
    Mirek Hankus

    ๐Ÿ› Mitch Spano
    Mitch Spano

    ๐Ÿ’ป ๐Ÿ› - Mladjan Gadzic
    Mladjan Gadzic

    ๐Ÿ› + Mladjan Gadzic
    Mladjan Gadzic

    ๐Ÿ› MrAngry52
    MrAngry52

    ๐Ÿ› Muminur Choudhury
    Muminur Choudhury

    ๐Ÿ› Mykhailo Palahuta
    Mykhailo Palahuta

    ๐Ÿ’ป ๐Ÿ› Nagendra Kumar Singh
    Nagendra Kumar Singh

    ๐Ÿ› Nahuel Barrios
    Nahuel Barrios

    ๐Ÿ› Nakul Sharma
    Nakul Sharma

    ๐Ÿ› - Nathan Braun
    Nathan Braun

    ๐Ÿ› + Nathan Braun
    Nathan Braun

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› Nathanaรซl
    Nathanaรซl

    ๐Ÿ› Naveen
    Naveen

    ๐Ÿ’ป Nazdravi
    Nazdravi

    ๐Ÿ› Neha-Dhonde
    Neha-Dhonde

    ๐Ÿ› - Nicholas Doyle
    Nicholas Doyle

    ๐Ÿ› + Nicholas Doyle
    Nicholas Doyle

    ๐Ÿ› Nick Butcher
    Nick Butcher

    ๐Ÿ› Nico Gallinal
    Nico Gallinal

    ๐Ÿ› Nicola Dal Maso
    Nicola Dal Maso

    ๐Ÿ› Nicolas Filotto
    Nicolas Filotto

    ๐Ÿ’ป Nicolas Vervelle
    Nicolas Vervelle

    ๐Ÿ› Nicolas Vuillamy
    Nicolas Vuillamy

    ๐Ÿ“– - Nikita Chursin
    Nikita Chursin

    ๐Ÿ› + Nikita Chursin
    Nikita Chursin

    ๐Ÿ› Niklas Baudy
    Niklas Baudy

    ๐Ÿ› Nikolas Havrikov
    Nikolas Havrikov

    ๐Ÿ› Nilesh Virkar
    Nilesh Virkar

    ๐Ÿ› Nimit Patel
    Nimit Patel

    ๐Ÿ› Niranjan Harpale
    Niranjan Harpale

    ๐Ÿ› Nirvik Patel
    Nirvik Patel

    ๐Ÿ’ป - Noah Sussman
    Noah Sussman

    ๐Ÿ› + Noah Sussman
    Noah Sussman

    ๐Ÿ› Noah0120
    Noah0120

    ๐Ÿ› Noam Tamim
    Noam Tamim

    ๐Ÿ› Noel Grandin
    Noel Grandin

    ๐Ÿ› Olaf Haalstra
    Olaf Haalstra

    ๐Ÿ› Oleg Andreych
    Oleg Andreych

    ๐Ÿ’ป ๐Ÿ› Oleg Pavlenko
    Oleg Pavlenko

    ๐Ÿ› - Oleksii Dykov
    Oleksii Dykov

    ๐Ÿ’ป ๐Ÿ› + Oleksii Dykov
    Oleksii Dykov

    ๐Ÿ’ป ๐Ÿ› Oliver Eikemeier
    Oliver Eikemeier

    ๐Ÿ› Oliver Siegmar
    Oliver Siegmar

    ๐Ÿ’ต Olivier Parent
    Olivier Parent

    ๐Ÿ’ป ๐Ÿ› Ollie Abbey
    Ollie Abbey

    ๐Ÿ’ป ๐Ÿ› Ondrej Kratochvil
    Ondrej Kratochvil

    ๐Ÿ› OverDrone
    OverDrone

    ๐Ÿ› - Ozan Gulle
    Ozan Gulle

    ๐Ÿ’ป ๐Ÿ› + Ozan Gulle
    Ozan Gulle

    ๐Ÿ’ป ๐Ÿ› PUNEET JAIN
    PUNEET JAIN

    ๐Ÿ› Parbati Bose
    Parbati Bose

    ๐Ÿ› Paul Berg
    Paul Berg

    ๐Ÿ› Paul Guyot
    Paul Guyot

    ๐Ÿ’ป Pavel Bludov
    Pavel Bludov

    ๐Ÿ› Pavel Miฤka
    Pavel Miฤka

    ๐Ÿ› - Pedro Nuno Santos
    Pedro Nuno Santos

    ๐Ÿ› + Pedro Nuno Santos
    Pedro Nuno Santos

    ๐Ÿ› Pedro Rijo
    Pedro Rijo

    ๐Ÿ› Pelisse Romain
    Pelisse Romain

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Per Abich
    Per Abich

    ๐Ÿ’ป Pete Davids
    Pete Davids

    ๐Ÿ› Peter Bruin
    Peter Bruin

    ๐Ÿ› Peter Chittum
    Peter Chittum

    ๐Ÿ’ป ๐Ÿ› - Peter Cudmore
    Peter Cudmore

    ๐Ÿ› + Peter Cudmore
    Peter Cudmore

    ๐Ÿ› Peter Kasson
    Peter Kasson

    ๐Ÿ› Peter Kofler
    Peter Kofler

    ๐Ÿ› Peter Paul Bakker
    Peter Paul Bakker

    ๐Ÿ’ป Peter Rader
    Peter Rader

    ๐Ÿ› Pham Hai Trung
    Pham Hai Trung

    ๐Ÿ› Philip Graf
    Philip Graf

    ๐Ÿ’ป ๐Ÿ› - Philip Hachey
    Philip Hachey

    ๐Ÿ› + Philip Hachey
    Philip Hachey

    ๐Ÿ› Philippe Ozil
    Philippe Ozil

    ๐Ÿ› Phinehas Artemix
    Phinehas Artemix

    ๐Ÿ› Phokham Nonava
    Phokham Nonava

    ๐Ÿ› Pim van der Loos
    Pim van der Loos

    ๐Ÿ’ป โš ๏ธ Piotr Szymaล„ski
    Piotr Szymaล„ski

    ๐Ÿ› Piotrek ลปygieล‚o
    Piotrek ลปygieล‚o

    ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– - Pranay Jaiswal
    Pranay Jaiswal

    ๐Ÿ› + Pranay Jaiswal
    Pranay Jaiswal

    ๐Ÿ› Prasad Kamath
    Prasad Kamath

    ๐Ÿ› Prasanna
    Prasanna

    ๐Ÿ› Presh-AR
    Presh-AR

    ๐Ÿ› Puneet1726
    Puneet1726

    ๐Ÿ› RBRi
    RBRi

    ๐Ÿ› Rafael Cortรชs
    Rafael Cortรชs

    ๐Ÿ› - RaheemShaik999
    RaheemShaik999

    ๐Ÿ› + RaheemShaik999
    RaheemShaik999

    ๐Ÿ› RajeshR
    RajeshR

    ๐Ÿ’ป ๐Ÿ› Ramachandra Mohan
    Ramachandra Mohan

    ๐Ÿ› Ramel0921
    Ramel0921

    ๐Ÿ› Raquel Pau
    Raquel Pau

    ๐Ÿ› Ravikiran Janardhana
    Ravikiran Janardhana

    ๐Ÿ› Reda Benhemmouche
    Reda Benhemmouche

    ๐Ÿ› - Reinhard Schiedermeier
    Reinhard Schiedermeier

    ๐Ÿ› + Reinhard Schiedermeier
    Reinhard Schiedermeier

    ๐Ÿ› Renato Oliveira
    Renato Oliveira

    ๐Ÿ’ป ๐Ÿ› Rich DiCroce
    Rich DiCroce

    ๐Ÿ› Richard Corfield
    Richard Corfield

    ๐Ÿ’ป Richard Corfield
    Richard Corfield

    ๐Ÿ› ๐Ÿ’ป Riot R1cket
    Riot R1cket

    ๐Ÿ› Rishabh Jain
    Rishabh Jain

    ๐Ÿ› - RishabhDeep Singh
    RishabhDeep Singh

    ๐Ÿ› + RishabhDeep Singh
    RishabhDeep Singh

    ๐Ÿ› Rob Baillie
    Rob Baillie

    ๐Ÿ› Robbie Martinus
    Robbie Martinus

    ๐Ÿ’ป ๐Ÿ› Robert Henry
    Robert Henry

    ๐Ÿ› Robert Mihaly
    Robert Mihaly

    ๐Ÿ› Robert Painsi
    Robert Painsi

    ๐Ÿ› Robert Russell
    Robert Russell

    ๐Ÿ› - Robert Sรถsemann
    Robert Sรถsemann

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ› + Robert Sรถsemann
    Robert Sรถsemann

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ› Robert Whitebit
    Robert Whitebit

    ๐Ÿ› Robin Richtsfeld
    Robin Richtsfeld

    ๐Ÿ› Robin Stocker
    Robin Stocker

    ๐Ÿ’ป ๐Ÿ› Robin Wils
    Robin Wils

    ๐Ÿ› RochusOest
    RochusOest

    ๐Ÿ› Rodolfo Noviski
    Rodolfo Noviski

    ๐Ÿ› - Rodrigo Casara
    Rodrigo Casara

    ๐Ÿ› + Rodrigo Casara
    Rodrigo Casara

    ๐Ÿ› Rodrigo Fernandes
    Rodrigo Fernandes

    ๐Ÿ› Roman Salvador
    Roman Salvador

    ๐Ÿ’ป ๐Ÿ› Ronald Blaschke
    Ronald Blaschke

    ๐Ÿ› Rรณbert Papp
    Rรณbert Papp

    ๐Ÿ› Saikat Sengupta
    Saikat Sengupta

    ๐Ÿ› Saksham Handu
    Saksham Handu

    ๐Ÿ› - Saladoc
    Saladoc

    ๐Ÿ› + Saladoc
    Saladoc

    ๐Ÿ› Salesforce Bob Lightning
    Salesforce Bob Lightning

    ๐Ÿ› Sam Carlberg
    Sam Carlberg

    ๐Ÿ› Sascha Riemer
    Sascha Riemer

    ๐Ÿ› Sashko
    Sashko

    ๐Ÿ’ป Satoshi Kubo
    Satoshi Kubo

    ๐Ÿ› Scott Kennedy
    Scott Kennedy

    ๐Ÿ› - Scott Wells
    Scott Wells

    ๐Ÿ› ๐Ÿ’ป + Scott Wells
    Scott Wells

    ๐Ÿ› ๐Ÿ’ป Scrates1
    Scrates1

    ๐Ÿ› ๐Ÿ’ป Scrsloota
    Scrsloota

    ๐Ÿ’ป Sebastian Bรถgl
    Sebastian Bรถgl

    ๐Ÿ› Sebastian Davids
    Sebastian Davids

    ๐Ÿ› Sebastian Schuberth
    Sebastian Schuberth

    ๐Ÿ› Sebastian Schwarz
    Sebastian Schwarz

    ๐Ÿ› - Seren
    Seren

    ๐Ÿ› ๐Ÿ’ป + Seren
    Seren

    ๐Ÿ› ๐Ÿ’ป Sergey Gorbaty
    Sergey Gorbaty

    ๐Ÿ› Sergey Kozlov
    Sergey Kozlov

    ๐Ÿ› Sergey Yanzin
    Sergey Yanzin

    ๐Ÿ’ป ๐Ÿ› Seth Wilcox
    Seth Wilcox

    ๐Ÿ’ป Shai Bennathan
    Shai Bennathan

    ๐Ÿ› ๐Ÿ’ป Shubham
    Shubham

    ๐Ÿ’ป ๐Ÿ› - Simon Abykov
    Simon Abykov

    ๐Ÿ’ป ๐Ÿ› + Simon Abykov
    Simon Abykov

    ๐Ÿ’ป ๐Ÿ› Simon Xiao
    Simon Xiao

    ๐Ÿ› Srinivasan Venkatachalam
    Srinivasan Venkatachalam

    ๐Ÿ› Stanislav Gromov
    Stanislav Gromov

    ๐Ÿ› Stanislav Myachenkov
    Stanislav Myachenkov

    ๐Ÿ’ป Stefan Birkner
    Stefan Birkner

    ๐Ÿ› Stefan Bohn
    Stefan Bohn

    ๐Ÿ› - Stefan Endrullis
    Stefan Endrullis

    ๐Ÿ› + Stefan Endrullis
    Stefan Endrullis

    ๐Ÿ› Stefan Klรถss-Schuster
    Stefan Klรถss-Schuster

    ๐Ÿ› Stefan Wolf
    Stefan Wolf

    ๐Ÿ› Stephan H. Wissel
    Stephan H. Wissel

    ๐Ÿ› Stephen
    Stephen

    ๐Ÿ› Stephen Carter
    Stephen Carter

    ๐Ÿ› Stephen Friedrich
    Stephen Friedrich

    ๐Ÿ› - Steve Babula
    Steve Babula

    ๐Ÿ’ป + Steve Babula
    Steve Babula

    ๐Ÿ’ป Steven Stearns
    Steven Stearns

    ๐Ÿ› ๐Ÿ’ป Stexxe
    Stexxe

    ๐Ÿ› Stian Lรฅgstad
    Stian Lรฅgstad

    ๐Ÿ› StuartClayton5
    StuartClayton5

    ๐Ÿ› Supun Arunoda
    Supun Arunoda

    ๐Ÿ› Suren Abrahamyan
    Suren Abrahamyan

    ๐Ÿ› - Suvashri
    Suvashri

    ๐Ÿ“– + Suvashri
    Suvashri

    ๐Ÿ“– Sven Barden
    Sven Barden

    ๐Ÿ› SwatiBGupta1110
    SwatiBGupta1110

    ๐Ÿ› SyedThoufich
    SyedThoufich

    ๐Ÿ› Szymon Sasin
    Szymon Sasin

    ๐Ÿ› T-chuangxin
    T-chuangxin

    ๐Ÿ› TERAI Atsuhiro
    TERAI Atsuhiro

    ๐Ÿ› - TIOBE Software
    TIOBE Software

    ๐Ÿ’ป ๐Ÿ› + TIOBE Software
    TIOBE Software

    ๐Ÿ’ป ๐Ÿ› Tarush Singh
    Tarush Singh

    ๐Ÿ’ป Taylor Smock
    Taylor Smock

    ๐Ÿ› Techeira Damiรกn
    Techeira Damiรกn

    ๐Ÿ’ป ๐Ÿ› Ted Husted
    Ted Husted

    ๐Ÿ› TehBakker
    TehBakker

    ๐Ÿ› The Gitter Badger
    The Gitter Badger

    ๐Ÿ› - Theodoor
    Theodoor

    ๐Ÿ› + Theodoor
    Theodoor

    ๐Ÿ› Thiago Henrique Hรผpner
    Thiago Henrique Hรผpner

    ๐Ÿ› Thibault Meyer
    Thibault Meyer

    ๐Ÿ› Thomas Gรผttler
    Thomas Gรผttler

    ๐Ÿ› Thomas Jones-Low
    Thomas Jones-Low

    ๐Ÿ› Thomas Smith
    Thomas Smith

    ๐Ÿ’ป ๐Ÿ› ThrawnCA
    ThrawnCA

    ๐Ÿ› - Thu Vo
    Thu Vo

    ๐Ÿ› + Thu Vo
    Thu Vo

    ๐Ÿ› Thunderforge
    Thunderforge

    ๐Ÿ’ป ๐Ÿ› Tim van der Lippe
    Tim van der Lippe

    ๐Ÿ› Tobias Weimer
    Tobias Weimer

    ๐Ÿ’ป ๐Ÿ› Tom Copeland
    Tom Copeland

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– Tom Daly
    Tom Daly

    ๐Ÿ› Tomas
    Tomas

    ๐Ÿ› - Tomer Figenblat
    Tomer Figenblat

    ๐Ÿ› + Tomer Figenblat
    Tomer Figenblat

    ๐Ÿ› Tomi De Lucca
    Tomi De Lucca

    ๐Ÿ’ป ๐Ÿ› Tony
    Tony

    ๐Ÿ“– Torsten Kleiber
    Torsten Kleiber

    ๐Ÿ› TrackerSB
    TrackerSB

    ๐Ÿ› Tyson Stewart
    Tyson Stewart

    ๐Ÿ› Ullrich Hafner
    Ullrich Hafner

    ๐Ÿ› - Utku Cuhadaroglu
    Utku Cuhadaroglu

    ๐Ÿ’ป ๐Ÿ› + Utku Cuhadaroglu
    Utku Cuhadaroglu

    ๐Ÿ’ป ๐Ÿ› Valentin Brandl
    Valentin Brandl

    ๐Ÿ› Valeria
    Valeria

    ๐Ÿ› Valery Yatsynovich
    Valery Yatsynovich

    ๐Ÿ“– Vasily Anisimov
    Vasily Anisimov

    ๐Ÿ› Vedant Chokshi
    Vedant Chokshi

    ๐Ÿ› Vibhor Goyal
    Vibhor Goyal

    ๐Ÿ› - Vickenty Fesunov
    Vickenty Fesunov

    ๐Ÿ› + Vickenty Fesunov
    Vickenty Fesunov

    ๐Ÿ› Victor Noรซl
    Victor Noรซl

    ๐Ÿ› Vincent Galloy
    Vincent Galloy

    ๐Ÿ’ป Vincent HUYNH
    Vincent HUYNH

    ๐Ÿ› Vincent Maurin
    Vincent Maurin

    ๐Ÿ› Vincent Privat
    Vincent Privat

    ๐Ÿ› Vishhwas
    Vishhwas

    ๐Ÿ› - Vishv_Android
    Vishv_Android

    ๐Ÿ› + Vishv_Android
    Vishv_Android

    ๐Ÿ› Vitalii Yevtushenko
    Vitalii Yevtushenko

    ๐Ÿ› Vitaly
    Vitaly

    ๐Ÿ› Vitaly Polonetsky
    Vitaly Polonetsky

    ๐Ÿ› Vojtech Polivka
    Vojtech Polivka

    ๐Ÿ› Vsevolod Zholobov
    Vsevolod Zholobov

    ๐Ÿ› Vyom Yadav
    Vyom Yadav

    ๐Ÿ’ป - Wang Shidong
    Wang Shidong

    ๐Ÿ› + Wang Shidong
    Wang Shidong

    ๐Ÿ› Waqas Ahmed
    Waqas Ahmed

    ๐Ÿ› Wayne J. Earl
    Wayne J. Earl

    ๐Ÿ› Wchenghui
    Wchenghui

    ๐Ÿ› Wener
    Wener

    ๐Ÿ’ป Will Winder
    Will Winder

    ๐Ÿ› Willem A. Hajenius
    Willem A. Hajenius

    ๐Ÿ’ป - William Brockhus
    William Brockhus

    ๐Ÿ’ป ๐Ÿ› + William Brockhus
    William Brockhus

    ๐Ÿ’ป ๐Ÿ› Wilson Kurniawan
    Wilson Kurniawan

    ๐Ÿ› Wim Deblauwe
    Wim Deblauwe

    ๐Ÿ› Woongsik Choi
    Woongsik Choi

    ๐Ÿ› XenoAmess
    XenoAmess

    ๐Ÿ’ป ๐Ÿ› Yang
    Yang

    ๐Ÿ’ป YaroslavTER
    YaroslavTER

    ๐Ÿ› - Yasar Shaikh
    Yasar Shaikh

    ๐Ÿ’ป + Yasar Shaikh
    Yasar Shaikh

    ๐Ÿ’ป Young Chan
    Young Chan

    ๐Ÿ’ป ๐Ÿ› YuJin Kim
    YuJin Kim

    ๐Ÿ› Yuri Dolzhenko
    Yuri Dolzhenko

    ๐Ÿ› Yurii Dubinka
    Yurii Dubinka

    ๐Ÿ› Zoltan Farkas
    Zoltan Farkas

    ๐Ÿ› Zustin
    Zustin

    ๐Ÿ› - aaronhurst-google
    aaronhurst-google

    ๐Ÿ› ๐Ÿ’ป + aaronhurst-google
    aaronhurst-google

    ๐Ÿ› ๐Ÿ’ป alexmodis
    alexmodis

    ๐Ÿ› andreoss
    andreoss

    ๐Ÿ› andrey81inmd
    andrey81inmd

    ๐Ÿ’ป ๐Ÿ› anicoara
    anicoara

    ๐Ÿ› arunprasathav
    arunprasathav

    ๐Ÿ› asiercamara
    asiercamara

    ๐Ÿ› - astillich-igniti
    astillich-igniti

    ๐Ÿ’ป + astillich-igniti
    astillich-igniti

    ๐Ÿ’ป avesolovksyy
    avesolovksyy

    ๐Ÿ› avishvat
    avishvat

    ๐Ÿ› avivmu
    avivmu

    ๐Ÿ› axelbarfod1
    axelbarfod1

    ๐Ÿ› b-3-n
    b-3-n

    ๐Ÿ› balbhadra9
    balbhadra9

    ๐Ÿ› - base23de
    base23de

    ๐Ÿ› + base23de
    base23de

    ๐Ÿ› bergander
    bergander

    ๐Ÿ› ๐Ÿ’ป berkam
    berkam

    ๐Ÿ’ป ๐Ÿ› breizh31
    breizh31

    ๐Ÿ› caesarkim
    caesarkim

    ๐Ÿ› caiocarvalhotero
    caiocarvalhotero

    ๐Ÿ› carolyujing
    carolyujing

    ๐Ÿ› - cbfiddle
    cbfiddle

    ๐Ÿ› + cbfiddle
    cbfiddle

    ๐Ÿ› cesares-basilico
    cesares-basilico

    ๐Ÿ› chrite
    chrite

    ๐Ÿ› ciufudean
    ciufudean

    ๐Ÿ“– cobratbq
    cobratbq

    ๐Ÿ› coladict
    coladict

    ๐Ÿ› cosmoJFH
    cosmoJFH

    ๐Ÿ› - cristalp
    cristalp

    ๐Ÿ› + cristalp
    cristalp

    ๐Ÿ› crunsk
    crunsk

    ๐Ÿ› cwholmes
    cwholmes

    ๐Ÿ› cyberjj999
    cyberjj999

    ๐Ÿ› cyw3
    cyw3

    ๐Ÿ› ๐Ÿ“– d1ss0nanz
    d1ss0nanz

    ๐Ÿ› dague1
    dague1

    ๐Ÿ“– - dalizi007
    dalizi007

    ๐Ÿ’ป + dalizi007
    dalizi007

    ๐Ÿ’ป danbrycefairsailcom
    danbrycefairsailcom

    ๐Ÿ› dariansanity
    dariansanity

    ๐Ÿ› darrenmiliband
    darrenmiliband

    ๐Ÿ› davidburstrom
    davidburstrom

    ๐Ÿ› dbirkman-paloalto
    dbirkman-paloalto

    ๐Ÿ› deepak-patra
    deepak-patra

    ๐Ÿ› - dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› + dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› dinesh150
    dinesh150

    ๐Ÿ› diziaq
    diziaq

    ๐Ÿ› dreaminpast123
    dreaminpast123

    ๐Ÿ› duanyanan
    duanyanan

    ๐Ÿ› dutt-sanjay
    dutt-sanjay

    ๐Ÿ› duursma
    duursma

    ๐Ÿ’ป - dylanleung
    dylanleung

    ๐Ÿ› + dylanleung
    dylanleung

    ๐Ÿ› dzeigler
    dzeigler

    ๐Ÿ› eant60
    eant60

    ๐Ÿ› ekkirala
    ekkirala

    ๐Ÿ› emersonmoura
    emersonmoura

    ๐Ÿ› emouty
    emouty

    ๐Ÿ’ป ๐Ÿ› eugenepugach
    eugenepugach

    ๐Ÿ› - fairy
    fairy

    ๐Ÿ› + fairy
    fairy

    ๐Ÿ› filiprafalowicz
    filiprafalowicz

    ๐Ÿ’ป flxbl-io
    flxbl-io

    ๐Ÿ’ต foxmason
    foxmason

    ๐Ÿ› frankegabor
    frankegabor

    ๐Ÿ› frankl
    frankl

    ๐Ÿ› freafrea
    freafrea

    ๐Ÿ› - fsapatin
    fsapatin

    ๐Ÿ› + fsapatin
    fsapatin

    ๐Ÿ› gearsethenry
    gearsethenry

    ๐Ÿ› gracia19
    gracia19

    ๐Ÿ› gudzpoz
    gudzpoz

    ๐Ÿ› guo fei
    guo fei

    ๐Ÿ› gurmsc5
    gurmsc5

    ๐Ÿ› gwilymatgearset
    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ› - haigsn
    haigsn

    ๐Ÿ› + haigsn
    haigsn

    ๐Ÿ› hemanshu070
    hemanshu070

    ๐Ÿ› henrik242
    henrik242

    ๐Ÿ› hongpuwu
    hongpuwu

    ๐Ÿ› hvbtup
    hvbtup

    ๐Ÿ’ป ๐Ÿ› igniti GmbH
    igniti GmbH

    ๐Ÿ› ilovezfs
    ilovezfs

    ๐Ÿ› - imax-erik
    imax-erik

    ๐Ÿ› + imax-erik
    imax-erik

    ๐Ÿ› itaigilo
    itaigilo

    ๐Ÿ› jakivey32
    jakivey32

    ๐Ÿ› jbennett2091
    jbennett2091

    ๐Ÿ› jcamerin
    jcamerin

    ๐Ÿ› jkeener1
    jkeener1

    ๐Ÿ› jmetertea
    jmetertea

    ๐Ÿ› - johnra2
    johnra2

    ๐Ÿ’ป + johnra2
    johnra2

    ๐Ÿ’ป johnzhao9
    johnzhao9

    ๐Ÿ› josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ› kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ› karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“– karwer
    karwer

    ๐Ÿ› kaulonline
    kaulonline

    ๐Ÿ› - kdaemonv
    kdaemonv

    ๐Ÿ› + kdaemonv
    kdaemonv

    ๐Ÿ› kdebski85
    kdebski85

    ๐Ÿ› ๐Ÿ’ป kenji21
    kenji21

    ๐Ÿ’ป ๐Ÿ› kfranic
    kfranic

    ๐Ÿ› khalidkh
    khalidkh

    ๐Ÿ› koalalam
    koalalam

    ๐Ÿ› krzyk
    krzyk

    ๐Ÿ› - lasselindqvist
    lasselindqvist

    ๐Ÿ› + lasselindqvist
    lasselindqvist

    ๐Ÿ› lgemeinhardt
    lgemeinhardt

    ๐Ÿ› lihuaib
    lihuaib

    ๐Ÿ› liqingjun123
    liqingjun123

    ๐Ÿ› lonelyma1021
    lonelyma1021

    ๐Ÿ› lpeddy
    lpeddy

    ๐Ÿ› lujiefsi
    lujiefsi

    ๐Ÿ’ป - lukelukes
    lukelukes

    ๐Ÿ’ป + lukelukes
    lukelukes

    ๐Ÿ’ป lyriccoder
    lyriccoder

    ๐Ÿ› marcelmore
    marcelmore

    ๐Ÿ› matchbox
    matchbox

    ๐Ÿ› matthiaskraaz
    matthiaskraaz

    ๐Ÿ› meandonlyme
    meandonlyme

    ๐Ÿ› mikesive
    mikesive

    ๐Ÿ› - milossesic
    milossesic

    ๐Ÿ› + milossesic
    milossesic

    ๐Ÿ› mluckam
    mluckam

    ๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
    mohan-chinnappan-n

    ๐Ÿ’ป mriddell95
    mriddell95

    ๐Ÿ› mrlzh
    mrlzh

    ๐Ÿ› msloan
    msloan

    ๐Ÿ› mucharlaravalika
    mucharlaravalika

    ๐Ÿ› - mvenneman
    mvenneman

    ๐Ÿ› + mvenneman
    mvenneman

    ๐Ÿ› nareshl119
    nareshl119

    ๐Ÿ› nicolas-harraudeau-sonarsource
    nicolas-harraudeau-sonarsource

    ๐Ÿ› noerremark
    noerremark

    ๐Ÿ› novsirion
    novsirion

    ๐Ÿ› nwcm
    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
    oggboy

    ๐Ÿ› - oinume
    oinume

    ๐Ÿ› + oinume
    oinume

    ๐Ÿ› orimarko
    orimarko

    ๐Ÿ’ป ๐Ÿ› pablogomez2197
    pablogomez2197

    ๐Ÿ› pacvz
    pacvz

    ๐Ÿ’ป pallavi agarwal
    pallavi agarwal

    ๐Ÿ› parksungrin
    parksungrin

    ๐Ÿ› patpatpat123
    patpatpat123

    ๐Ÿ› - patriksevallius
    patriksevallius

    ๐Ÿ› + patriksevallius
    patriksevallius

    ๐Ÿ› pbrajesh1
    pbrajesh1

    ๐Ÿ› phoenix384
    phoenix384

    ๐Ÿ› piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป plan3d
    plan3d

    ๐Ÿ› poojasix
    poojasix

    ๐Ÿ› prabhushrikant
    prabhushrikant

    ๐Ÿ› - pujitha8783
    pujitha8783

    ๐Ÿ› + pujitha8783
    pujitha8783

    ๐Ÿ› r-r-a-j
    r-r-a-j

    ๐Ÿ› raghujayjunk
    raghujayjunk

    ๐Ÿ› rajeshveera
    rajeshveera

    ๐Ÿ› rajeswarreddy88
    rajeswarreddy88

    ๐Ÿ› recdevs
    recdevs

    ๐Ÿ› reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ› - rijkt
    rijkt

    ๐Ÿ› + rijkt
    rijkt

    ๐Ÿ› rillig-tk
    rillig-tk

    ๐Ÿ› rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ› rnveach
    rnveach

    ๐Ÿ› rxmicro
    rxmicro

    ๐Ÿ› ryan-gustafson
    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ› sabi0
    sabi0

    ๐Ÿ› - samc-gearset
    samc-gearset

    ๐Ÿ“– + samc-gearset
    samc-gearset

    ๐Ÿ“– scais
    scais

    ๐Ÿ› schosin
    schosin

    ๐Ÿ› screamingfrog
    screamingfrog

    ๐Ÿ’ต sebbASF
    sebbASF

    ๐Ÿ› sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป shilko2013
    shilko2013

    ๐Ÿ› - shiomiyan
    shiomiyan

    ๐Ÿ“– + shiomiyan
    shiomiyan

    ๐Ÿ“– simeonKondr
    simeonKondr

    ๐Ÿ› snajberk
    snajberk

    ๐Ÿ› sniperrifle2004
    sniperrifle2004

    ๐Ÿ› snuyanzin
    snuyanzin

    ๐Ÿ› ๐Ÿ’ป soloturn
    soloturn

    ๐Ÿ› soyodream
    soyodream

    ๐Ÿ› - sratz
    sratz

    ๐Ÿ› + sratz
    sratz

    ๐Ÿ› stonio
    stonio

    ๐Ÿ› sturton
    sturton

    ๐Ÿ’ป ๐Ÿ› sudharmohan
    sudharmohan

    ๐Ÿ› suruchidawar
    suruchidawar

    ๐Ÿ› svenfinitiv
    svenfinitiv

    ๐Ÿ› szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป - tashiscool
    tashiscool

    ๐Ÿ› + tashiscool
    tashiscool

    ๐Ÿ› test-git-hook
    test-git-hook

    ๐Ÿ› testation21
    testation21

    ๐Ÿ’ป ๐Ÿ› thanosa
    thanosa

    ๐Ÿ› tiandiyixian
    tiandiyixian

    ๐Ÿ› tobwoerk
    tobwoerk

    ๐Ÿ› tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป - trentchilders
    trentchilders

    ๐Ÿ› + trentchilders
    trentchilders

    ๐Ÿ› triandicAnt
    triandicAnt

    ๐Ÿ› trishul14
    trishul14

    ๐Ÿ› tsui
    tsui

    ๐Ÿ› wangzitom12306
    wangzitom12306

    ๐Ÿ› winhkey
    winhkey

    ๐Ÿ› witherspore
    witherspore

    ๐Ÿ› - wjljack
    wjljack

    ๐Ÿ› + wjljack
    wjljack

    ๐Ÿ› wuchiuwong
    wuchiuwong

    ๐Ÿ› xingsong
    xingsong

    ๐Ÿ› xioayuge
    xioayuge

    ๐Ÿ› xnYi9wRezm
    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ› xuanuy
    xuanuy

    ๐Ÿ› xyf0921
    xyf0921

    ๐Ÿ› - yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› + yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› yasuharu-sato
    yasuharu-sato

    ๐Ÿ› zenglian
    zenglian

    ๐Ÿ› zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› zh3ng
    zh3ng

    ๐Ÿ› zt_soft
    zt_soft

    ๐Ÿ› ztt79
    ztt79

    ๐Ÿ› - zzzzfeng
    zzzzfeng

    ๐Ÿ› + zzzzfeng
    zzzzfeng

    ๐Ÿ› รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› ไปป่ดตๆฐ
    ไปป่ดตๆฐ

    ๐Ÿ› ๅคฉ็ƒญๅƒ่ฅฟ็“œ
    ๅคฉ็ƒญๅƒ่ฅฟ็“œ

    ๐Ÿ› From 6093efce99548254e01abe13f1b48c78ca248a37 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 6 Feb 2025 12:45:24 +0100 Subject: [PATCH 0500/1962] [java] UnusedPrivateMethod: Ignore lombok.EqualsAndHashCode.Include Fixes #3359 --- docs/pages/release_notes.md | 2 ++ .../UnusedPrivateMethodRule.java | 3 ++- .../bestpractices/xml/UnusedPrivateMethod.xml | 20 +++++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 9fe328e64fd..d62bd95f003 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -15,6 +15,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* java-bestpractices + * [#3359](https://github.com/pmd/pmd/issues/3359): \[java] UnusedPrivateMethod does not recognize Lombok @EqualsAndHashCode.Include annotation ### ๐Ÿšจ API Changes diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java index 0c739460af1..238b30d5c7b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java @@ -48,7 +48,8 @@ protected Collection defaultSuppressionAnnotations() { return listOf( "java.lang.Deprecated", "jakarta.annotation.PostConstruct", - "jakarta.annotation.PreDestroy" + "jakarta.annotation.PreDestroy", + "lombok.EqualsAndHashCode.Include" ); } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index c9ecabd130c..e4035b68cea 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2512,4 +2512,24 @@ public class PmdTestCase { } ]]>
    + + + #3359 [java] UnusedPrivateMethod does not recognize Lombok @EqualsAndHashCode.Include annotation + 0 + + From 365d82517bbc20919ad3617a3a69e683af212b97 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 6 Feb 2025 12:45:53 +0100 Subject: [PATCH 0501/1962] Add @mladjan-gadzic as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 125 +++++++++++++------------- 2 files changed, 72 insertions(+), 62 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 46b435c53b0..cbbb2151f0e 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7938,6 +7938,15 @@ "contributions": [ "doc" ] + }, + { + "login": "mladjan-gadzic", + "name": "Mladjan Gadzic", + "avatar_url": "https://avatars.githubusercontent.com/u/30688679?v=4", + "profile": "https://github.com/mladjan-gadzic", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 6182d0abf96..8dd625b7725 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -564,564 +564,565 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Mladjan Gadzic
    Mladjan Gadzic

    ๐Ÿ› + Mladjan Gadzic
    Mladjan Gadzic

    ๐Ÿ› MrAngry52
    MrAngry52

    ๐Ÿ› Muminur Choudhury
    Muminur Choudhury

    ๐Ÿ› Mykhailo Palahuta
    Mykhailo Palahuta

    ๐Ÿ’ป ๐Ÿ› Nagendra Kumar Singh
    Nagendra Kumar Singh

    ๐Ÿ› Nahuel Barrios
    Nahuel Barrios

    ๐Ÿ› Nakul Sharma
    Nakul Sharma

    ๐Ÿ› - Nathan Braun
    Nathan Braun

    ๐Ÿ› + Nathan Braun
    Nathan Braun

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› Nathanaรซl
    Nathanaรซl

    ๐Ÿ› Naveen
    Naveen

    ๐Ÿ’ป Nazdravi
    Nazdravi

    ๐Ÿ› Neha-Dhonde
    Neha-Dhonde

    ๐Ÿ› - Nicholas Doyle
    Nicholas Doyle

    ๐Ÿ› + Nicholas Doyle
    Nicholas Doyle

    ๐Ÿ› Nick Butcher
    Nick Butcher

    ๐Ÿ› Nico Gallinal
    Nico Gallinal

    ๐Ÿ› Nicola Dal Maso
    Nicola Dal Maso

    ๐Ÿ› Nicolas Filotto
    Nicolas Filotto

    ๐Ÿ’ป Nicolas Vervelle
    Nicolas Vervelle

    ๐Ÿ› Nicolas Vuillamy
    Nicolas Vuillamy

    ๐Ÿ“– - Nikita Chursin
    Nikita Chursin

    ๐Ÿ› + Nikita Chursin
    Nikita Chursin

    ๐Ÿ› Niklas Baudy
    Niklas Baudy

    ๐Ÿ› Nikolas Havrikov
    Nikolas Havrikov

    ๐Ÿ› Nilesh Virkar
    Nilesh Virkar

    ๐Ÿ› Nimit Patel
    Nimit Patel

    ๐Ÿ› Niranjan Harpale
    Niranjan Harpale

    ๐Ÿ› Nirvik Patel
    Nirvik Patel

    ๐Ÿ’ป - Noah Sussman
    Noah Sussman

    ๐Ÿ› + Noah Sussman
    Noah Sussman

    ๐Ÿ› Noah0120
    Noah0120

    ๐Ÿ› Noam Tamim
    Noam Tamim

    ๐Ÿ› Noel Grandin
    Noel Grandin

    ๐Ÿ› Olaf Haalstra
    Olaf Haalstra

    ๐Ÿ› Oleg Andreych
    Oleg Andreych

    ๐Ÿ’ป ๐Ÿ› Oleg Pavlenko
    Oleg Pavlenko

    ๐Ÿ› - Oleksii Dykov
    Oleksii Dykov

    ๐Ÿ’ป ๐Ÿ› + Oleksii Dykov
    Oleksii Dykov

    ๐Ÿ’ป ๐Ÿ› Oliver Eikemeier
    Oliver Eikemeier

    ๐Ÿ› Oliver Siegmar
    Oliver Siegmar

    ๐Ÿ’ต Olivier Parent
    Olivier Parent

    ๐Ÿ’ป ๐Ÿ› Ollie Abbey
    Ollie Abbey

    ๐Ÿ’ป ๐Ÿ› Ondrej Kratochvil
    Ondrej Kratochvil

    ๐Ÿ› OverDrone
    OverDrone

    ๐Ÿ› - Ozan Gulle
    Ozan Gulle

    ๐Ÿ’ป ๐Ÿ› + Ozan Gulle
    Ozan Gulle

    ๐Ÿ’ป ๐Ÿ› PUNEET JAIN
    PUNEET JAIN

    ๐Ÿ› Parbati Bose
    Parbati Bose

    ๐Ÿ› Paul Berg
    Paul Berg

    ๐Ÿ› Paul Guyot
    Paul Guyot

    ๐Ÿ’ป Pavel Bludov
    Pavel Bludov

    ๐Ÿ› Pavel Miฤka
    Pavel Miฤka

    ๐Ÿ› - Pedro Nuno Santos
    Pedro Nuno Santos

    ๐Ÿ› + Pedro Nuno Santos
    Pedro Nuno Santos

    ๐Ÿ› Pedro Rijo
    Pedro Rijo

    ๐Ÿ› Pelisse Romain
    Pelisse Romain

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Per Abich
    Per Abich

    ๐Ÿ’ป Pete Davids
    Pete Davids

    ๐Ÿ› Peter Bruin
    Peter Bruin

    ๐Ÿ› Peter Chittum
    Peter Chittum

    ๐Ÿ’ป ๐Ÿ› - Peter Cudmore
    Peter Cudmore

    ๐Ÿ› + Peter Cudmore
    Peter Cudmore

    ๐Ÿ› Peter Kasson
    Peter Kasson

    ๐Ÿ› Peter Kofler
    Peter Kofler

    ๐Ÿ› Peter Paul Bakker
    Peter Paul Bakker

    ๐Ÿ’ป Peter Rader
    Peter Rader

    ๐Ÿ› Pham Hai Trung
    Pham Hai Trung

    ๐Ÿ› Philip Graf
    Philip Graf

    ๐Ÿ’ป ๐Ÿ› - Philip Hachey
    Philip Hachey

    ๐Ÿ› + Philip Hachey
    Philip Hachey

    ๐Ÿ› Philippe Ozil
    Philippe Ozil

    ๐Ÿ› Phinehas Artemix
    Phinehas Artemix

    ๐Ÿ› Phokham Nonava
    Phokham Nonava

    ๐Ÿ› Pim van der Loos
    Pim van der Loos

    ๐Ÿ’ป โš ๏ธ Piotr Szymaล„ski
    Piotr Szymaล„ski

    ๐Ÿ› Piotrek ลปygieล‚o
    Piotrek ลปygieล‚o

    ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– - Pranay Jaiswal
    Pranay Jaiswal

    ๐Ÿ› + Pranay Jaiswal
    Pranay Jaiswal

    ๐Ÿ› Prasad Kamath
    Prasad Kamath

    ๐Ÿ› Prasanna
    Prasanna

    ๐Ÿ› Presh-AR
    Presh-AR

    ๐Ÿ› Puneet1726
    Puneet1726

    ๐Ÿ› RBRi
    RBRi

    ๐Ÿ› Rafael Cortรชs
    Rafael Cortรชs

    ๐Ÿ› - RaheemShaik999
    RaheemShaik999

    ๐Ÿ› + RaheemShaik999
    RaheemShaik999

    ๐Ÿ› RajeshR
    RajeshR

    ๐Ÿ’ป ๐Ÿ› Ramachandra Mohan
    Ramachandra Mohan

    ๐Ÿ› Ramel0921
    Ramel0921

    ๐Ÿ› Raquel Pau
    Raquel Pau

    ๐Ÿ› Ravikiran Janardhana
    Ravikiran Janardhana

    ๐Ÿ› Reda Benhemmouche
    Reda Benhemmouche

    ๐Ÿ› - Reinhard Schiedermeier
    Reinhard Schiedermeier

    ๐Ÿ› + Reinhard Schiedermeier
    Reinhard Schiedermeier

    ๐Ÿ› Renato Oliveira
    Renato Oliveira

    ๐Ÿ’ป ๐Ÿ› Rich DiCroce
    Rich DiCroce

    ๐Ÿ› Richard Corfield
    Richard Corfield

    ๐Ÿ’ป Richard Corfield
    Richard Corfield

    ๐Ÿ› ๐Ÿ’ป Riot R1cket
    Riot R1cket

    ๐Ÿ› Rishabh Jain
    Rishabh Jain

    ๐Ÿ› - RishabhDeep Singh
    RishabhDeep Singh

    ๐Ÿ› + RishabhDeep Singh
    RishabhDeep Singh

    ๐Ÿ› Rob Baillie
    Rob Baillie

    ๐Ÿ› Robbie Martinus
    Robbie Martinus

    ๐Ÿ’ป ๐Ÿ› Robert Henry
    Robert Henry

    ๐Ÿ› Robert Mihaly
    Robert Mihaly

    ๐Ÿ› Robert Painsi
    Robert Painsi

    ๐Ÿ› Robert Russell
    Robert Russell

    ๐Ÿ› - Robert Sรถsemann
    Robert Sรถsemann

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ› + Robert Sรถsemann
    Robert Sรถsemann

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ› Robert Whitebit
    Robert Whitebit

    ๐Ÿ› Robin Richtsfeld
    Robin Richtsfeld

    ๐Ÿ› Robin Stocker
    Robin Stocker

    ๐Ÿ’ป ๐Ÿ› Robin Wils
    Robin Wils

    ๐Ÿ› RochusOest
    RochusOest

    ๐Ÿ› Rodolfo Noviski
    Rodolfo Noviski

    ๐Ÿ› - Rodrigo Casara
    Rodrigo Casara

    ๐Ÿ› + Rodrigo Casara
    Rodrigo Casara

    ๐Ÿ› Rodrigo Fernandes
    Rodrigo Fernandes

    ๐Ÿ› Roman Salvador
    Roman Salvador

    ๐Ÿ’ป ๐Ÿ› Ronald Blaschke
    Ronald Blaschke

    ๐Ÿ› Rรณbert Papp
    Rรณbert Papp

    ๐Ÿ› Saikat Sengupta
    Saikat Sengupta

    ๐Ÿ› Saksham Handu
    Saksham Handu

    ๐Ÿ› - Saladoc
    Saladoc

    ๐Ÿ› + Saladoc
    Saladoc

    ๐Ÿ› Salesforce Bob Lightning
    Salesforce Bob Lightning

    ๐Ÿ› Sam Carlberg
    Sam Carlberg

    ๐Ÿ› Sascha Riemer
    Sascha Riemer

    ๐Ÿ› Sashko
    Sashko

    ๐Ÿ’ป Satoshi Kubo
    Satoshi Kubo

    ๐Ÿ› Scott Kennedy
    Scott Kennedy

    ๐Ÿ› - Scott Wells
    Scott Wells

    ๐Ÿ› ๐Ÿ’ป + Scott Wells
    Scott Wells

    ๐Ÿ› ๐Ÿ’ป Scrates1
    Scrates1

    ๐Ÿ› ๐Ÿ’ป Scrsloota
    Scrsloota

    ๐Ÿ’ป Sebastian Bรถgl
    Sebastian Bรถgl

    ๐Ÿ› Sebastian Davids
    Sebastian Davids

    ๐Ÿ› Sebastian Schuberth
    Sebastian Schuberth

    ๐Ÿ› Sebastian Schwarz
    Sebastian Schwarz

    ๐Ÿ› - Seren
    Seren

    ๐Ÿ› ๐Ÿ’ป + Seren
    Seren

    ๐Ÿ› ๐Ÿ’ป Sergey Gorbaty
    Sergey Gorbaty

    ๐Ÿ› Sergey Kozlov
    Sergey Kozlov

    ๐Ÿ› Sergey Yanzin
    Sergey Yanzin

    ๐Ÿ’ป ๐Ÿ› Seth Wilcox
    Seth Wilcox

    ๐Ÿ’ป Shai Bennathan
    Shai Bennathan

    ๐Ÿ› ๐Ÿ’ป Shubham
    Shubham

    ๐Ÿ’ป ๐Ÿ› - Simon Abykov
    Simon Abykov

    ๐Ÿ’ป ๐Ÿ› + Simon Abykov
    Simon Abykov

    ๐Ÿ’ป ๐Ÿ› Simon Xiao
    Simon Xiao

    ๐Ÿ› Srinivasan Venkatachalam
    Srinivasan Venkatachalam

    ๐Ÿ› Stanislav Gromov
    Stanislav Gromov

    ๐Ÿ› Stanislav Myachenkov
    Stanislav Myachenkov

    ๐Ÿ’ป Stefan Birkner
    Stefan Birkner

    ๐Ÿ› Stefan Bohn
    Stefan Bohn

    ๐Ÿ› - Stefan Endrullis
    Stefan Endrullis

    ๐Ÿ› + Stefan Endrullis
    Stefan Endrullis

    ๐Ÿ› Stefan Klรถss-Schuster
    Stefan Klรถss-Schuster

    ๐Ÿ› Stefan Wolf
    Stefan Wolf

    ๐Ÿ› Stephan H. Wissel
    Stephan H. Wissel

    ๐Ÿ› Stephen
    Stephen

    ๐Ÿ› Stephen Carter
    Stephen Carter

    ๐Ÿ› Stephen Friedrich
    Stephen Friedrich

    ๐Ÿ› - Steve Babula
    Steve Babula

    ๐Ÿ’ป + Steve Babula
    Steve Babula

    ๐Ÿ’ป Steven Stearns
    Steven Stearns

    ๐Ÿ› ๐Ÿ’ป Stexxe
    Stexxe

    ๐Ÿ› Stian Lรฅgstad
    Stian Lรฅgstad

    ๐Ÿ› StuartClayton5
    StuartClayton5

    ๐Ÿ› Supun Arunoda
    Supun Arunoda

    ๐Ÿ› Suren Abrahamyan
    Suren Abrahamyan

    ๐Ÿ› - Suvashri
    Suvashri

    ๐Ÿ“– + Suvashri
    Suvashri

    ๐Ÿ“– Sven Barden
    Sven Barden

    ๐Ÿ› SwatiBGupta1110
    SwatiBGupta1110

    ๐Ÿ› SyedThoufich
    SyedThoufich

    ๐Ÿ› Szymon Sasin
    Szymon Sasin

    ๐Ÿ› T-chuangxin
    T-chuangxin

    ๐Ÿ› TERAI Atsuhiro
    TERAI Atsuhiro

    ๐Ÿ› - TIOBE Software
    TIOBE Software

    ๐Ÿ’ป ๐Ÿ› + TIOBE Software
    TIOBE Software

    ๐Ÿ’ป ๐Ÿ› Tarush Singh
    Tarush Singh

    ๐Ÿ’ป Taylor Smock
    Taylor Smock

    ๐Ÿ› Techeira Damiรกn
    Techeira Damiรกn

    ๐Ÿ’ป ๐Ÿ› Ted Husted
    Ted Husted

    ๐Ÿ› TehBakker
    TehBakker

    ๐Ÿ› The Gitter Badger
    The Gitter Badger

    ๐Ÿ› - Theodoor
    Theodoor

    ๐Ÿ› + Theodoor
    Theodoor

    ๐Ÿ› Thiago Henrique Hรผpner
    Thiago Henrique Hรผpner

    ๐Ÿ› Thibault Meyer
    Thibault Meyer

    ๐Ÿ› Thomas Gรผttler
    Thomas Gรผttler

    ๐Ÿ› Thomas Jones-Low
    Thomas Jones-Low

    ๐Ÿ› Thomas Smith
    Thomas Smith

    ๐Ÿ’ป ๐Ÿ› ThrawnCA
    ThrawnCA

    ๐Ÿ› - Thu Vo
    Thu Vo

    ๐Ÿ› + Thu Vo
    Thu Vo

    ๐Ÿ› Thunderforge
    Thunderforge

    ๐Ÿ’ป ๐Ÿ› Tim van der Lippe
    Tim van der Lippe

    ๐Ÿ› Tobias Weimer
    Tobias Weimer

    ๐Ÿ’ป ๐Ÿ› Tom Copeland
    Tom Copeland

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– Tom Daly
    Tom Daly

    ๐Ÿ› Tomas
    Tomas

    ๐Ÿ› - Tomer Figenblat
    Tomer Figenblat

    ๐Ÿ› + Tomer Figenblat
    Tomer Figenblat

    ๐Ÿ› Tomi De Lucca
    Tomi De Lucca

    ๐Ÿ’ป ๐Ÿ› Tony
    Tony

    ๐Ÿ“– Torsten Kleiber
    Torsten Kleiber

    ๐Ÿ› TrackerSB
    TrackerSB

    ๐Ÿ› Tyson Stewart
    Tyson Stewart

    ๐Ÿ› Ullrich Hafner
    Ullrich Hafner

    ๐Ÿ› - Utku Cuhadaroglu
    Utku Cuhadaroglu

    ๐Ÿ’ป ๐Ÿ› + Utku Cuhadaroglu
    Utku Cuhadaroglu

    ๐Ÿ’ป ๐Ÿ› Valentin Brandl
    Valentin Brandl

    ๐Ÿ› Valeria
    Valeria

    ๐Ÿ› Valery Yatsynovich
    Valery Yatsynovich

    ๐Ÿ“– Vasily Anisimov
    Vasily Anisimov

    ๐Ÿ› Vedant Chokshi
    Vedant Chokshi

    ๐Ÿ› Vibhor Goyal
    Vibhor Goyal

    ๐Ÿ› - Vickenty Fesunov
    Vickenty Fesunov

    ๐Ÿ› + Vickenty Fesunov
    Vickenty Fesunov

    ๐Ÿ› Victor Noรซl
    Victor Noรซl

    ๐Ÿ› Vincent Galloy
    Vincent Galloy

    ๐Ÿ’ป Vincent HUYNH
    Vincent HUYNH

    ๐Ÿ› Vincent Maurin
    Vincent Maurin

    ๐Ÿ› Vincent Privat
    Vincent Privat

    ๐Ÿ› Vishhwas
    Vishhwas

    ๐Ÿ› - Vishv_Android
    Vishv_Android

    ๐Ÿ› + Vishv_Android
    Vishv_Android

    ๐Ÿ› Vitalii Yevtushenko
    Vitalii Yevtushenko

    ๐Ÿ› Vitaly
    Vitaly

    ๐Ÿ› Vitaly Polonetsky
    Vitaly Polonetsky

    ๐Ÿ› Vojtech Polivka
    Vojtech Polivka

    ๐Ÿ› Vsevolod Zholobov
    Vsevolod Zholobov

    ๐Ÿ› Vyom Yadav
    Vyom Yadav

    ๐Ÿ’ป - Wang Shidong
    Wang Shidong

    ๐Ÿ› + Wang Shidong
    Wang Shidong

    ๐Ÿ› Waqas Ahmed
    Waqas Ahmed

    ๐Ÿ› Wayne J. Earl
    Wayne J. Earl

    ๐Ÿ› Wchenghui
    Wchenghui

    ๐Ÿ› Wener
    Wener

    ๐Ÿ’ป Will Winder
    Will Winder

    ๐Ÿ› Willem A. Hajenius
    Willem A. Hajenius

    ๐Ÿ’ป - William Brockhus
    William Brockhus

    ๐Ÿ’ป ๐Ÿ› + William Brockhus
    William Brockhus

    ๐Ÿ’ป ๐Ÿ› Wilson Kurniawan
    Wilson Kurniawan

    ๐Ÿ› Wim Deblauwe
    Wim Deblauwe

    ๐Ÿ› Woongsik Choi
    Woongsik Choi

    ๐Ÿ› XenoAmess
    XenoAmess

    ๐Ÿ’ป ๐Ÿ› Yang
    Yang

    ๐Ÿ’ป YaroslavTER
    YaroslavTER

    ๐Ÿ› - Yasar Shaikh
    Yasar Shaikh

    ๐Ÿ’ป + Yasar Shaikh
    Yasar Shaikh

    ๐Ÿ’ป Young Chan
    Young Chan

    ๐Ÿ’ป ๐Ÿ› YuJin Kim
    YuJin Kim

    ๐Ÿ› Yuri Dolzhenko
    Yuri Dolzhenko

    ๐Ÿ› Yurii Dubinka
    Yurii Dubinka

    ๐Ÿ› Zoltan Farkas
    Zoltan Farkas

    ๐Ÿ› Zustin
    Zustin

    ๐Ÿ› - aaronhurst-google
    aaronhurst-google

    ๐Ÿ› ๐Ÿ’ป + aaronhurst-google
    aaronhurst-google

    ๐Ÿ› ๐Ÿ’ป alexmodis
    alexmodis

    ๐Ÿ› andreoss
    andreoss

    ๐Ÿ› andrey81inmd
    andrey81inmd

    ๐Ÿ’ป ๐Ÿ› anicoara
    anicoara

    ๐Ÿ› arunprasathav
    arunprasathav

    ๐Ÿ› asiercamara
    asiercamara

    ๐Ÿ› - astillich-igniti
    astillich-igniti

    ๐Ÿ’ป + astillich-igniti
    astillich-igniti

    ๐Ÿ’ป avesolovksyy
    avesolovksyy

    ๐Ÿ› avishvat
    avishvat

    ๐Ÿ› avivmu
    avivmu

    ๐Ÿ› axelbarfod1
    axelbarfod1

    ๐Ÿ› b-3-n
    b-3-n

    ๐Ÿ› balbhadra9
    balbhadra9

    ๐Ÿ› - base23de
    base23de

    ๐Ÿ› + base23de
    base23de

    ๐Ÿ› bergander
    bergander

    ๐Ÿ› ๐Ÿ’ป berkam
    berkam

    ๐Ÿ’ป ๐Ÿ› breizh31
    breizh31

    ๐Ÿ› caesarkim
    caesarkim

    ๐Ÿ› caiocarvalhotero
    caiocarvalhotero

    ๐Ÿ› carolyujing
    carolyujing

    ๐Ÿ› - cbfiddle
    cbfiddle

    ๐Ÿ› + cbfiddle
    cbfiddle

    ๐Ÿ› cesares-basilico
    cesares-basilico

    ๐Ÿ› chrite
    chrite

    ๐Ÿ› ciufudean
    ciufudean

    ๐Ÿ“– cobratbq
    cobratbq

    ๐Ÿ› coladict
    coladict

    ๐Ÿ› cosmoJFH
    cosmoJFH

    ๐Ÿ› - cristalp
    cristalp

    ๐Ÿ› + cristalp
    cristalp

    ๐Ÿ› crunsk
    crunsk

    ๐Ÿ› cwholmes
    cwholmes

    ๐Ÿ› cyberjj999
    cyberjj999

    ๐Ÿ› cyw3
    cyw3

    ๐Ÿ› ๐Ÿ“– d1ss0nanz
    d1ss0nanz

    ๐Ÿ› dague1
    dague1

    ๐Ÿ“– - dalizi007
    dalizi007

    ๐Ÿ’ป + dalizi007
    dalizi007

    ๐Ÿ’ป danbrycefairsailcom
    danbrycefairsailcom

    ๐Ÿ› dariansanity
    dariansanity

    ๐Ÿ› darrenmiliband
    darrenmiliband

    ๐Ÿ› davidburstrom
    davidburstrom

    ๐Ÿ› dbirkman-paloalto
    dbirkman-paloalto

    ๐Ÿ› deepak-patra
    deepak-patra

    ๐Ÿ› - dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› + dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› dinesh150
    dinesh150

    ๐Ÿ› diziaq
    diziaq

    ๐Ÿ› dreaminpast123
    dreaminpast123

    ๐Ÿ› duanyanan
    duanyanan

    ๐Ÿ› dutt-sanjay
    dutt-sanjay

    ๐Ÿ› duursma
    duursma

    ๐Ÿ’ป - dylanleung
    dylanleung

    ๐Ÿ› + dylanleung
    dylanleung

    ๐Ÿ› dzeigler
    dzeigler

    ๐Ÿ› eant60
    eant60

    ๐Ÿ› ekkirala
    ekkirala

    ๐Ÿ› emersonmoura
    emersonmoura

    ๐Ÿ› emouty
    emouty

    ๐Ÿ’ป ๐Ÿ› eugenepugach
    eugenepugach

    ๐Ÿ› - fairy
    fairy

    ๐Ÿ› + fairy
    fairy

    ๐Ÿ› filiprafalowicz
    filiprafalowicz

    ๐Ÿ’ป flxbl-io
    flxbl-io

    ๐Ÿ’ต foxmason
    foxmason

    ๐Ÿ› frankegabor
    frankegabor

    ๐Ÿ› frankl
    frankl

    ๐Ÿ› freafrea
    freafrea

    ๐Ÿ› - fsapatin
    fsapatin

    ๐Ÿ› + fsapatin
    fsapatin

    ๐Ÿ› gearsethenry
    gearsethenry

    ๐Ÿ› gracia19
    gracia19

    ๐Ÿ› gudzpoz
    gudzpoz

    ๐Ÿ› guo fei
    guo fei

    ๐Ÿ› gurmsc5
    gurmsc5

    ๐Ÿ› gwilymatgearset
    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ› - haigsn
    haigsn

    ๐Ÿ› + haigsn
    haigsn

    ๐Ÿ› hemanshu070
    hemanshu070

    ๐Ÿ› henrik242
    henrik242

    ๐Ÿ› hongpuwu
    hongpuwu

    ๐Ÿ› hvbtup
    hvbtup

    ๐Ÿ’ป ๐Ÿ› igniti GmbH
    igniti GmbH

    ๐Ÿ› ilovezfs
    ilovezfs

    ๐Ÿ› - imax-erik
    imax-erik

    ๐Ÿ› + imax-erik
    imax-erik

    ๐Ÿ› itaigilo
    itaigilo

    ๐Ÿ› jakivey32
    jakivey32

    ๐Ÿ› jbennett2091
    jbennett2091

    ๐Ÿ› jcamerin
    jcamerin

    ๐Ÿ› jkeener1
    jkeener1

    ๐Ÿ› jmetertea
    jmetertea

    ๐Ÿ› - johnra2
    johnra2

    ๐Ÿ’ป + johnra2
    johnra2

    ๐Ÿ’ป johnzhao9
    johnzhao9

    ๐Ÿ› josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ› kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ› karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“– karwer
    karwer

    ๐Ÿ› kaulonline
    kaulonline

    ๐Ÿ› - kdaemonv
    kdaemonv

    ๐Ÿ› + kdaemonv
    kdaemonv

    ๐Ÿ› kdebski85
    kdebski85

    ๐Ÿ› ๐Ÿ’ป kenji21
    kenji21

    ๐Ÿ’ป ๐Ÿ› kfranic
    kfranic

    ๐Ÿ› khalidkh
    khalidkh

    ๐Ÿ› koalalam
    koalalam

    ๐Ÿ› krzyk
    krzyk

    ๐Ÿ› - lasselindqvist
    lasselindqvist

    ๐Ÿ› + lasselindqvist
    lasselindqvist

    ๐Ÿ› lgemeinhardt
    lgemeinhardt

    ๐Ÿ› lihuaib
    lihuaib

    ๐Ÿ› liqingjun123
    liqingjun123

    ๐Ÿ› lonelyma1021
    lonelyma1021

    ๐Ÿ› lpeddy
    lpeddy

    ๐Ÿ› lujiefsi
    lujiefsi

    ๐Ÿ’ป - lukelukes
    lukelukes

    ๐Ÿ’ป + lukelukes
    lukelukes

    ๐Ÿ’ป lyriccoder
    lyriccoder

    ๐Ÿ› marcelmore
    marcelmore

    ๐Ÿ› matchbox
    matchbox

    ๐Ÿ› matthiaskraaz
    matthiaskraaz

    ๐Ÿ› meandonlyme
    meandonlyme

    ๐Ÿ› mikesive
    mikesive

    ๐Ÿ› - milossesic
    milossesic

    ๐Ÿ› + milossesic
    milossesic

    ๐Ÿ› mluckam
    mluckam

    ๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
    mohan-chinnappan-n

    ๐Ÿ’ป mriddell95
    mriddell95

    ๐Ÿ› mrlzh
    mrlzh

    ๐Ÿ› msloan
    msloan

    ๐Ÿ› mucharlaravalika
    mucharlaravalika

    ๐Ÿ› - mvenneman
    mvenneman

    ๐Ÿ› + mvenneman
    mvenneman

    ๐Ÿ› nareshl119
    nareshl119

    ๐Ÿ› nicolas-harraudeau-sonarsource
    nicolas-harraudeau-sonarsource

    ๐Ÿ› noerremark
    noerremark

    ๐Ÿ› novsirion
    novsirion

    ๐Ÿ› nwcm
    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
    oggboy

    ๐Ÿ› - oinume
    oinume

    ๐Ÿ› + oinume
    oinume

    ๐Ÿ› orimarko
    orimarko

    ๐Ÿ’ป ๐Ÿ› pablogomez2197
    pablogomez2197

    ๐Ÿ› pacvz
    pacvz

    ๐Ÿ’ป pallavi agarwal
    pallavi agarwal

    ๐Ÿ› parksungrin
    parksungrin

    ๐Ÿ› patpatpat123
    patpatpat123

    ๐Ÿ› - patriksevallius
    patriksevallius

    ๐Ÿ› + patriksevallius
    patriksevallius

    ๐Ÿ› pbrajesh1
    pbrajesh1

    ๐Ÿ› phoenix384
    phoenix384

    ๐Ÿ› piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป plan3d
    plan3d

    ๐Ÿ› poojasix
    poojasix

    ๐Ÿ› prabhushrikant
    prabhushrikant

    ๐Ÿ› - pujitha8783
    pujitha8783

    ๐Ÿ› + pujitha8783
    pujitha8783

    ๐Ÿ› r-r-a-j
    r-r-a-j

    ๐Ÿ› raghujayjunk
    raghujayjunk

    ๐Ÿ› rajeshveera
    rajeshveera

    ๐Ÿ› rajeswarreddy88
    rajeswarreddy88

    ๐Ÿ› recdevs
    recdevs

    ๐Ÿ› reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ› - rijkt
    rijkt

    ๐Ÿ› + rijkt
    rijkt

    ๐Ÿ› rillig-tk
    rillig-tk

    ๐Ÿ› rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ› rnveach
    rnveach

    ๐Ÿ› rxmicro
    rxmicro

    ๐Ÿ› ryan-gustafson
    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ› sabi0
    sabi0

    ๐Ÿ› - samc-gearset
    samc-gearset

    ๐Ÿ“– + samc-gearset
    samc-gearset

    ๐Ÿ“– scais
    scais

    ๐Ÿ› schosin
    schosin

    ๐Ÿ› screamingfrog
    screamingfrog

    ๐Ÿ’ต sebbASF
    sebbASF

    ๐Ÿ› sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป shilko2013
    shilko2013

    ๐Ÿ› - shiomiyan
    shiomiyan

    ๐Ÿ“– + shiomiyan
    shiomiyan

    ๐Ÿ“– simeonKondr
    simeonKondr

    ๐Ÿ› snajberk
    snajberk

    ๐Ÿ› sniperrifle2004
    sniperrifle2004

    ๐Ÿ› snuyanzin
    snuyanzin

    ๐Ÿ› ๐Ÿ’ป soloturn
    soloturn

    ๐Ÿ› soyodream
    soyodream

    ๐Ÿ› - sratz
    sratz

    ๐Ÿ› + sratz
    sratz

    ๐Ÿ› stonio
    stonio

    ๐Ÿ› sturton
    sturton

    ๐Ÿ’ป ๐Ÿ› sudharmohan
    sudharmohan

    ๐Ÿ› suruchidawar
    suruchidawar

    ๐Ÿ› svenfinitiv
    svenfinitiv

    ๐Ÿ› szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป - tashiscool
    tashiscool

    ๐Ÿ› + tashiscool
    tashiscool

    ๐Ÿ› test-git-hook
    test-git-hook

    ๐Ÿ› testation21
    testation21

    ๐Ÿ’ป ๐Ÿ› thanosa
    thanosa

    ๐Ÿ› tiandiyixian
    tiandiyixian

    ๐Ÿ› tobwoerk
    tobwoerk

    ๐Ÿ› tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป - trentchilders
    trentchilders

    ๐Ÿ› + trentchilders
    trentchilders

    ๐Ÿ› triandicAnt
    triandicAnt

    ๐Ÿ› trishul14
    trishul14

    ๐Ÿ› tsui
    tsui

    ๐Ÿ› wangzitom12306
    wangzitom12306

    ๐Ÿ› winhkey
    winhkey

    ๐Ÿ› witherspore
    witherspore

    ๐Ÿ› - wjljack
    wjljack

    ๐Ÿ› + wjljack
    wjljack

    ๐Ÿ› wuchiuwong
    wuchiuwong

    ๐Ÿ› xingsong
    xingsong

    ๐Ÿ› xioayuge
    xioayuge

    ๐Ÿ› xnYi9wRezm
    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ› xuanuy
    xuanuy

    ๐Ÿ› xyf0921
    xyf0921

    ๐Ÿ› - yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› + yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› yasuharu-sato
    yasuharu-sato

    ๐Ÿ› zenglian
    zenglian

    ๐Ÿ› zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› zh3ng
    zh3ng

    ๐Ÿ› zt_soft
    zt_soft

    ๐Ÿ› ztt79
    ztt79

    ๐Ÿ› - zzzzfeng
    zzzzfeng

    ๐Ÿ› + zzzzfeng
    zzzzfeng

    ๐Ÿ› รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› ไปป่ดตๆฐ
    ไปป่ดตๆฐ

    ๐Ÿ› ๅคฉ็ƒญๅƒ่ฅฟ็“œ
    ๅคฉ็ƒญๅƒ่ฅฟ็“œ

    ๐Ÿ› From dd54ddf5062f7f56afe589b7ac6043f253d006f9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 6 Feb 2025 15:56:51 +0100 Subject: [PATCH 0502/1962] [ci] Add signed releases --- .ci/build.sh | 22 ++++ docs/_data/sidebars/pmd_sidebar.yml | 3 + docs/pages/pmd/userdocs/signed_releases.md | 125 +++++++++++++++++++++ docs/pages/release_notes.md | 6 + 4 files changed, 156 insertions(+) create mode 100644 docs/pages/pmd/userdocs/signed_releases.md diff --git a/.ci/build.sh b/.ci/build.sh index fd811336054..36fb577936d 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -244,6 +244,11 @@ function pmd_ci_deploy_build_artifacts() { # Deploy SBOM pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.xml" pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.json" + # Sign and deploy the binary dist files + pmd_ci_gpg_sign_file "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip" + pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip.asc" + pmd_ci_gpg_sign_file "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-src.zip" + pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-src.zip.asc" fi # release build case a): everything without pmd-cli and pmd-dist is released @@ -261,6 +266,11 @@ function pmd_ci_deploy_build_artifacts() { # Deploy SBOM pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.xml" pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.json" + # Sign and deploy the binary dist files + pmd_ci_gpg_sign_file "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip" + pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip.asc" + pmd_ci_gpg_sign_file "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-src.zip" + pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-src.zip.asc" # draft release has already been created pmd_ci_gh_releases_getLatestDraftRelease @@ -272,6 +282,9 @@ function pmd_ci_deploy_build_artifacts() { # Deploy SBOM pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.xml" pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.json" + # Deploy signatures + pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip.asc" + pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-src.zip.asc" fi } @@ -287,9 +300,12 @@ function pmd_ci_build_and_upload_doc() { pmd_doc_create_archive pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "docs/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-doc.zip" + pmd_ci_gpg_sign_file "docs/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-doc.zip" + pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "docs/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-doc.zip.asc" if pmd_ci_maven_isReleaseBuild; then pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "docs/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-doc.zip" + pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "docs/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-doc.zip.asc" fi # Deploy doc to https://docs.pmd-code.org/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}/ @@ -366,6 +382,12 @@ function pmd_ci_dogfood() { git checkout -- pom.xml } +function pmd_ci_gpg_sign_file() { + local fileToSign="$1" + pmd_ci_log_info "Signing file ${fileToSign}..." + printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty --status-fd 1 --armor --detach-sign --sign "$fileToSign" +} + build exit 0 diff --git a/docs/_data/sidebars/pmd_sidebar.yml b/docs/_data/sidebars/pmd_sidebar.yml index 28f24d9ec96..3885f897f1d 100644 --- a/docs/_data/sidebars/pmd_sidebar.yml +++ b/docs/_data/sidebars/pmd_sidebar.yml @@ -68,6 +68,9 @@ entries: - title: 3rd party rulesets output: web, pdf url: /pmd_userdocs_3rdpartyrulesets.html + - title: Signed Releases + output: web, pdf + url: /pmd_userdocs_signed_releases.html - title: null output: web, pdf subfolders: diff --git a/docs/pages/pmd/userdocs/signed_releases.md b/docs/pages/pmd/userdocs/signed_releases.md new file mode 100644 index 00000000000..1ec5e331b87 --- /dev/null +++ b/docs/pages/pmd/userdocs/signed_releases.md @@ -0,0 +1,125 @@ +--- +title: Signed Releases +tags: [userdocs] +permalink: pmd_userdocs_signed_releases.html +author: Andreas Dangel +last_updated: February 2025 (7.11.0) +--- + +Since PMD 7.11.0 we provide GPG signatures along our binary distribution files on [GitHub Releases](https://github.com/pmd/pmd/releases). +You can use the signatures to verify that the downloads you have not been tampered with since we built them. + +## How to verify a release? + +Download the binary zip file and the corresponding `asc` file from the release assets from [GitHub Releases](https://github.com/pmd/pmd/releases) +into the same directory. Then use `gpg` to verify the download: + +```shell +gpg --verify pmd-dist-{{site.pmd.version}}-bin.zip.asc pmd-dist-{{site.pmd.version}}-bin.zip +``` + +If you do not currently have PMD's public release signing key you will get a message such as this: +``` +gpg: Signature made Thu Feb 6 14:58:22 2025 CET +gpg: using RSA key 1E046C19ED2873D8C08AF7B8A0632691B78E3422 +gpg: issuer "releases@pmd-code.org" +gpg: Can't check signature: No public key +``` + +You first need to acquire our public key to get rid of the "Can't check signature" message. +You can download it from a trusted GPG server, for example to use the Ubuntu key server +run this command: + +```shell +gpg --keyserver keyserver.ubuntu.com --recv-keys 1E046C19ED2873D8C08AF7B8A0632691B78E3422 +``` + +If you then run the verify command again you will get a message indicating the newly imported +key has not been trusted: + +``` +gpg: Signature made Thu Feb 6 14:58:22 2025 CET +gpg: using RSA key 1E046C19ED2873D8C08AF7B8A0632691B78E3422 +gpg: issuer "releases@pmd-code.org" +gpg: Good signature from "PMD Release Signing Key " [unknown] +gpg: WARNING: This key is not certified with a trusted signature! +gpg: There is no indication that the signature belongs to the owner. +Primary key fingerprint: 2EFA 55D0 785C 31F9 56F2 F87E A0B5 CA1A 4E08 6838 + Subkey fingerprint: 1E04 6C19 ED28 73D8 C08A F7B8 A063 2691 B78E 3422 +``` + +While the โ€œGood signatureโ€ message gives you some confidence that the download is valid, to fully trust the +certificate and remove the final warning you can run the following then follow the prompts to grant ultimate +trust to it: + +``` +gpg --edit-key 1E046C19ED2873D8C08AF7B8A0632691B78E3422 trust +``` + +The verification should then succeed as follows: + +``` +gpg: Signature made Thu Feb 6 14:58:22 2025 CET +gpg: using RSA key 1E046C19ED2873D8C08AF7B8A0632691B78E3422 +gpg: issuer "releases@pmd-code.org" +gpg: checking the trustdb +gpg: marginals needed: 3 completes needed: 1 trust model: pgp +gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u +gpg: Good signature from "PMD Release Signing Key " [ultimate] +``` + +## The Release Signing Key + +PMD's release signing key consists of the primary key with the fingerprint +`2EFA 55D0 785C 31F9 56F2 F87E A0B5 CA1A 4E08 6838`. + +It currently contains one subkey, that is used for signing. The subkey's fingerprint is +`1E04 6C19 ED28 73D8 C08A F7B8 A063 2691 B78E 3422`. + +```shell +gpg --list-keys --fingerprint --with-subkey-fingerprint releases@pmd-code.org +pub rsa4096 2025-01-04 [C] [expires: 2027-01-04] + 2EFA 55D0 785C 31F9 56F2 F87E A0B5 CA1A 4E08 6838 +uid [ultimate] PMD Release Signing Key +sub rsa4096 2025-01-04 [S] [expires: 2027-01-04] + 1E04 6C19 ED28 73D8 C08A F7B8 A063 2691 B78E 3422 +``` + +The public key is available under the identity `releases@pmd-code.org` at + +* +* + +{%capture note%} +The key `1E04 6C19 ED28 73D8 C08A F7B8 A063 2691 B78E 3422` is in use since 7.10.0 for signing artifacts +in Maven Central and since 7.11.0 to sign the binary distribution files. + +Before that, we used a different key for signing maven artifacts. We had to revoke the key because +the passphrase was compromised. See [GHSA-88m4-h43f-wx84](https://github.com/pmd/pmd/security/advisories/GHSA-88m4-h43f-wx84) +for more information. +{%endcapture%} +{%include note.html content=note%} + +## Maven Central + +The artifacts we deploy to maven central under the group id [net.sourceforge.pmd](https://repo.maven.apache.org/maven2/net/sourceforge/pmd/) +are signed with the same key. + +You can manually verify the artifacts with the same method: + +```shell +wget https://repo.maven.apache.org/maven2/net/sourceforge/pmd/pmd-core/{{site.pmd.version}}/pmd-core-{{site.pmd.version}}.jar +wget https://repo.maven.apache.org/maven2/net/sourceforge/pmd/pmd-core/{{site.pmd.version}}/pmd-core-{{site.pmd.version}}.jar.asc +gpg --verify pmd-core-{{site.pmd.version}}.jar.asc pmd-core-{{site.pmd.version}}.jar +``` + +This gives you e.g. + +``` +gpg: Signature made Fri Jan 31 10:45:52 2025 CET +gpg: using RSA key 1E046C19ED2873D8C08AF7B8A0632691B78E3422 +gpg: Good signature from "PMD Release Signing Key " [ultimate] +``` + +## References +This page is heavily inspired by . diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 9fe328e64fd..39a6e8ba427 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -14,6 +14,12 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy +#### Signed Releases + +We now not only sign the maven artifacts, but also our binary distribution files that you can +download from [GitHub Releases](https://github.com/pmd/pmd/releases). +See the page [Signed Releases](pmd_userdocs_signed_releases.html) in our documentation for how to verify the files. + ### ๐Ÿ› Fixed Issues ### ๐Ÿšจ API Changes From 25dd25926dba078a4a2fc5f3d9abf1e5b756824f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 7 Feb 2025 11:31:47 +0100 Subject: [PATCH 0503/1962] Fix shellcheck issue SC2038 - use find -print0 --- .ci/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/build.sh b/.ci/build.sh index 36fb577936d..1174cd393a2 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -90,7 +90,7 @@ function build() { # Trying to delete the files now, if they exist. # Alternatively, we could run maven with flag "-U" to force update all dependencies... pmd_ci_log_info "Cleanup local maven repo..." - find ~/.m2/repository -wholename "*/net/sourceforge/pmd/*/${PMD_CI_MAVEN_PROJECT_VERSION}/*.lastUpdated" | xargs rm -v + find ~/.m2/repository -print0 -wholename "*/net/sourceforge/pmd/*/${PMD_CI_MAVEN_PROJECT_VERSION}/*.lastUpdated" | xargs -0 rm -v pmd_ci_log_info "Cleanup local maven repo finished." ./mvnw clean verify -pl pmd-cli,pmd-dist --show-version --errors --batch-mode "${PMD_MAVEN_EXTRA_OPTS[@]}" From 2f2e7419a0650d9e3409551c2fc207aad787b42c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 03:43:18 +0000 Subject: [PATCH 0504/1962] Bump org.jetbrains:annotations from 26.0.1 to 26.0.2 Bumps [org.jetbrains:annotations](https://github.com/JetBrains/java-annotations) from 26.0.1 to 26.0.2. - [Release notes](https://github.com/JetBrains/java-annotations/releases) - [Changelog](https://github.com/JetBrains/java-annotations/blob/master/CHANGELOG.md) - [Commits](https://github.com/JetBrains/java-annotations/compare/26.0.1...26.0.2) --- updated-dependencies: - dependency-name: org.jetbrains:annotations dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ec47ce0e8f9..928ce819e3f 100644 --- a/pom.xml +++ b/pom.xml @@ -1082,7 +1082,7 @@ org.jetbrains annotations - 26.0.1 + 26.0.2 test From f94dc5b90a6c7188321775055ea5533060173548 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 03:43:31 +0000 Subject: [PATCH 0505/1962] Bump net.bytebuddy:byte-buddy from 1.15.11 to 1.17.0 Bumps [net.bytebuddy:byte-buddy](https://github.com/raphw/byte-buddy) from 1.15.11 to 1.17.0. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.15.11...byte-buddy-1.17.0) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ec47ce0e8f9..d26e5e0c893 100644 --- a/pom.xml +++ b/pom.xml @@ -994,7 +994,7 @@ net.bytebuddy byte-buddy - 1.15.11 + 1.17.0 test From c74b771e133efdcc5404b45382d024120efedc50 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 03:43:33 +0000 Subject: [PATCH 0506/1962] Bump org.junit.platform:junit-platform-suite from 1.11.3 to 1.11.4 Bumps [org.junit.platform:junit-platform-suite](https://github.com/junit-team/junit5) from 1.11.3 to 1.11.4. - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/commits) --- updated-dependencies: - dependency-name: org.junit.platform:junit-platform-suite dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ec47ce0e8f9..8bd434d92c1 100644 --- a/pom.xml +++ b/pom.xml @@ -969,7 +969,7 @@ org.junit.platform junit-platform-suite - 1.11.3 + 1.11.4 test From 2d8323251375b4b64d3ddd94e6f767d35c30a992 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 03:43:36 +0000 Subject: [PATCH 0507/1962] Bump org.checkerframework:checker-qual from 3.48.3 to 3.49.0 Bumps [org.checkerframework:checker-qual](https://github.com/typetools/checker-framework) from 3.48.3 to 3.49.0. - [Release notes](https://github.com/typetools/checker-framework/releases) - [Changelog](https://github.com/typetools/checker-framework/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/typetools/checker-framework/compare/checker-framework-3.48.3...checker-framework-3.49.0) --- updated-dependencies: - dependency-name: org.checkerframework:checker-qual dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ec47ce0e8f9..de92cb03982 100644 --- a/pom.xml +++ b/pom.xml @@ -852,7 +852,7 @@ org.checkerframework checker-qual - 3.48.3 + 3.49.0 net.sf.saxon From 62b633ae17d92786bd90b54fa7837701a9fe34ec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 03:43:39 +0000 Subject: [PATCH 0508/1962] Bump com.google.guava:guava from 33.0.0-jre to 33.4.0-jre Bumps [com.google.guava:guava](https://github.com/google/guava) from 33.0.0-jre to 33.4.0-jre. - [Release notes](https://github.com/google/guava/releases) - [Commits](https://github.com/google/guava/commits) --- updated-dependencies: - dependency-name: com.google.guava:guava dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ec47ce0e8f9..6224ecdce00 100644 --- a/pom.xml +++ b/pom.xml @@ -902,7 +902,7 @@ com.google.guava guava - 33.0.0-jre + 33.4.0-jre From 541dc5327e3df12aecc2bfefba302adf5d743eeb Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 13 Feb 2025 14:25:43 +0100 Subject: [PATCH 0509/1962] [ci] New optimized workflow for pull requests The goal is - to have faster feedback for PRs - better visibility which part of the workflow failed - have build artifacts available to verify/test locally The jobs are: - "compile": First a fast compile job. The result of this job is shared via compile-artifact with some of the following jobs. - Then in parallel a bunch of other jobs - verify: runs a complete `./mvnw verify` with all code checks, etc. This is only run on linux. - verify-unittests: just runs the unit tests on linux, windows and macos - dogfood: runs maven-pmd-plugin on PMD with the latest changes from the pull request - documentation: generates the rule documentation and builds PMD's documentation page with jekyll. - regressiontester: runs the pmdtester to produce the regression report Since most jobs can be run in parallel and not sequentially, the results of the PR build should be available faster. The concurrency control makes sure, that we cancel any in-progress jobs for the current pull request to avoid unnecessary builds. Only the latest build matters. Refs: #4328 --- .github/workflows/build.yml | 1 - .github/workflows/pull-requests.yml | 350 ++++++++++++++++++++++++++++ pom.xml | 49 ++++ 3 files changed, 399 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/pull-requests.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2c8dd8adf69..b016ccd354a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,7 +6,6 @@ on: - main tags: - '**' - pull_request: merge_group: schedule: # build it monthly: At 04:00 on day-of-month 1. diff --git a/.github/workflows/pull-requests.yml b/.github/workflows/pull-requests.yml new file mode 100644 index 00000000000..20dd182b333 --- /dev/null +++ b/.github/workflows/pull-requests.yml @@ -0,0 +1,350 @@ +name: Pull Request Build + +on: pull_request + +# if another commit is added to the PR (same github.head_ref), then cancel already running jobs +# and start a new build +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref }} + cancel-in-progress: true + +permissions: + contents: read # to fetch code (actions/checkout) + +env: + LANG: 'en_US.UTF-8' + +jobs: + compile: + runs-on: ubuntu-latest + timeout-minutes: 20 + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 2 + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '11' + - uses: actions/cache@v4 + with: + key: maven-${{ hashFiles('**/pom.xml') }} + restore-keys: maven- + path: ~/.m2/repository + enableCrossOsArchive: true + - name: Fast Build with Maven + run: | + ./mvnw --show-version --errors --batch-mode \ + verify -PfastSkip -DskipTests \ + deploy:deploy -DdogfoodStagingRepo="$(pwd)/target/staging" + - name: Cleanup local repository + run: | + # Cleanup local repository to not poison the shared cache with our SNAPSHOTS of the current build. + # Some information is stored in maven-metadata-*.xml files which tells maven which + # version exactly is available in the staging repo. But if we rerun the build using the + # older cache, it points to the old staging versions, which are not available anymore. + find ~/.m2/repository/net/sourceforge/pmd -type d -name "*-SNAPSHOT" -and -not -wholename "*/pmd-designer/*" | xargs rm -vrf + - uses: actions/upload-artifact@v4 + with: + name: compile-artifact + if-no-files-found: error + path: | + */target + */*/target + !pmd-dist/target/pmd-dist-*-bin.zip + !pmd-dist/target/pmd-dist-*-src.zip + - uses: actions/upload-artifact@v4 + with: + name: staging-repository + if-no-files-found: error + path: target/staging + - uses: actions/upload-artifact@v4 + with: + name: dist-artifact + if-no-files-found: error + path: | + pmd-dist/target/pmd-dist-*-bin.zip + pmd-dist/target/pmd-dist-*-src.zip + + verify: + needs: compile + timeout-minutes: 30 + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 2 + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '11' + - uses: actions/cache@v4 + with: + key: maven-${{ hashFiles('**/pom.xml') }} + restore-keys: maven- + path: ~/.m2/repository + enableCrossOsArchive: true + - uses: actions/download-artifact@v4 + with: + name: compile-artifact + - name: Full Build with Maven + run: | + ./mvnw --show-version --errors --batch-mode \ + verify \ + -DskipTests -Dmaven.test.skip=true + + verify-unittests: + needs: compile + timeout-minutes: 30 + runs-on: ${{ matrix.os }} + defaults: + run: + shell: bash + strategy: + # don't fail fast - we want to know the results of all runs + fail-fast: false + matrix: + os: [ ubuntu-latest, windows-latest, macos-latest ] + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 2 + - uses: actions/setup-java@v4 + # under linux we execute more extensive integration tests with various java versions + if: ${{ runner.os == 'Linux' }} + with: + distribution: 'temurin' + java-version: | + 8 + 17 + 21 + - uses: actions/setup-java@v4 + # default java version for all os is 11 + with: + distribution: 'temurin' + java-version: '11' + # only restore the cache, don't create a new cache + # under Windows, hashFiles('**/pom.xml') gives a different result due to line endings + - uses: actions/cache/restore@v4 + with: + key: maven-${{ hashFiles('**/pom.xml') }} + restore-keys: maven- + path: ~/.m2/repository + enableCrossOsArchive: true + - uses: actions/download-artifact@v4 + # we can only reuse compile-artifacts under linux due to file timestamp issues and + # platform specific line endings in test files. + if: ${{ runner.os == 'Linux' }} + with: + name: compile-artifact + - name: Build with Maven and run unit tests + run: | + ./mvnw --show-version --errors --batch-mode \ + verify \ + -PfastSkip -Dcyclonedx.skip=false \ + -Djava8.home="${JAVA_HOME_8_X64}" \ + -Djava17.home="${JAVA_HOME_17_X64}" \ + -Djava21.home="${JAVA_HOME_21_X64}" + + dogfood: + needs: compile + timeout-minutes: 30 + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 2 + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '11' + - uses: actions/cache@v4 + with: + key: maven-${{ hashFiles('**/pom.xml') }} + restore-keys: maven- + path: ~/.m2/repository + enableCrossOsArchive: true + - uses: actions/download-artifact@v4 + with: + name: compile-artifact + - uses: actions/download-artifact@v4 + with: + name: staging-repository + path: target/staging + - name: Run PMD on PMD + run: | + # this only works if the triggering event of this workflow is "pull_request" + pr_number="$(jq -r ".number" "${GITHUB_EVENT_PATH}")" + echo "Determined PR number: ${pr_number}" + + current_pmd_version=$(./mvnw --batch-mode --no-transfer-progress \ + help:evaluate -Dexpression=project.version -q -DforceStdout || echo "failed_to_determine_current_pmd_version") + echo "Determined current pmd version: ${current_pmd_version}" + + new_version="${current_pmd_version}-pr-${pr_number}-dogfood-SNAPSHOT" + echo "::group::Set version to ${new_version}" + ./mvnw versions:set --quiet -DnewVersion="${new_version}" -DgenerateBackupPoms=false + sed -i 's/[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}.*<\/version>\( *\)/'"${current_pmd_version}"'<\/version>\1/' pom.xml + echo "::endgroup::" + + echo "::group::Run ./mvnw verify" + ./mvnw --show-version --errors --batch-mode \ + verify \ + -PfastSkip \ + -DdogfoodStagingRepo="$(pwd)/target/staging" \ + -DskipTests \ + -Dpmd.skip=false \ + -Dcpd.skip=false + echo "::endgroup::" + + echo "::group::Restore version to ${current_pmd_version}" + ./mvnw versions:set --quiet -DnewVersion="${current_pmd_version}" -DgenerateBackupPoms=false + git checkout -- pom.xml + echo "::endgroup::" + + documentation: + needs: compile + timeout-minutes: 30 + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 2 + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '11' + - uses: actions/cache@v4 + with: + key: maven-${{ hashFiles('**/pom.xml') }} + restore-keys: maven- + path: ~/.m2/repository + enableCrossOsArchive: true + - uses: actions/download-artifact@v4 + with: + name: compile-artifact + - name: Generate rule docs + run: | + ./mvnw --show-version --errors --batch-mode \ + verify \ + -Pgenerate-rule-docs,fastSkip \ + -DskipTests -Dmaven.test.skip=true -Dassembly.skipAssembly=true + - name: Set up Ruby 3.3 + uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.3 + - name: Setup bundler + run: | + cd docs + bundle config set --local path vendor/bundle + bundle install + - name: Build documentation + run: | + cd docs + bundle exec jekyll build + - uses: actions/upload-artifact@v4 + with: + name: docs-artifact + if-no-files-found: error + path: docs/_site + + regressiontester: + needs: compile + timeout-minutes: 60 + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 2 + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '11' + - name: Set up Ruby 3.3 + uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.3 + - uses: actions/cache@v4 + with: + path: | + ~/.m2/repository + ~/.gradle/caches + ~/work/pmd/target/repositories + vendor/bundle + key: regressiontester-${{ hashFiles('.ci/files/project-list.xml', 'Gemfile.lock') }} + restore-keys: regressiontester- + - uses: actions/download-artifact@v4 + with: + name: dist-artifact + path: pmd-dist/target + - name: Setup bundler + run: | + bundle config set --local path vendor/bundle + bundle install + - name: Prepare HOME/openjdk11 + run: | + ln -sfn "${JAVA_HOME_11_X64}" "${HOME}/openjdk11" + - name: Run pmdtester + run: | + gpg --batch --yes --decrypt --passphrase="GnxdjywUEPveyCD1RLiTd7t8CImnefYr" \ + --output .ci/files/public-env .ci/files/public-env.gpg + # shellcheck disable=SC1091 + source .ci/files/public-env >/dev/null 2>&1 + rm .ci/files/public-env + + # this only works if the triggering event of this workflow is "pull_request" + PMD_CI_PULL_REQUEST_NUMBER="$(jq -r ".number" "${GITHUB_EVENT_PATH}")" + export PMD_CI_PULL_REQUEST_NUMBER + echo "Determined PR number: ${PMD_CI_PULL_REQUEST_NUMBER}" + + export PMD_CI_BRANCH="${GITHUB_BASE_REF}" + echo "Determined Branch: ${PMD_CI_BRANCH}" + + export PMD_CI_JOB_URL="https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" + echo "Determined Job Url: ${PMD_CI_JOB_URL}" + + echo "::group::Fetching additional commits" + # git clone initially only fetched with depth 2. Danger and regression tester + # need more history, so we'll fetch more here + # and create local branches as well (${PMD_CI_BRANCH} and pr-fetch) + + echo "Fetching 25 commits for ${PMD_CI_BRANCH} and pull/${PMD_CI_PULL_REQUEST_NUMBER}/head" + git fetch --no-tags --depth=25 origin "${PMD_CI_BRANCH}:${PMD_CI_BRANCH}" "pull/${PMD_CI_PULL_REQUEST_NUMBER}/head:pr-fetch" + + # if the PR is older, base might have advanced more than 25 commits... fetch more, up to 150 + for i in $(seq 1 3); do + if [ -z "$( git merge-base "${PMD_CI_BRANCH}" "pr-fetch" )" ]; then + echo "No merge-base yet - fetching more commits... (try $i)" + git fetch --no-tags --deepen=50 origin "${PMD_CI_BRANCH}:" "pull/${PMD_CI_PULL_REQUEST_NUMBER}/head:pr-fetch" + fi + done + echo "Merge base is: $( git merge-base "${PMD_CI_BRANCH}" "pr-fetch" )" + echo "::endgroup::" + + echo "::group::Running danger on branch ${PMD_CI_BRANCH}" + bundle exec danger --verbose + echo "::endgroup::" + - name: Workaround actions/upload-artifact#176 + run: | + echo "artifacts_path=$(realpath ..)" >> $GITHUB_ENV + - name: Upload regression tester report + uses: actions/upload-artifact@v4 + with: + name: pmd-regression-tester + path: ${{ env.artifacts_path }}/target/pr-*-diff-report-*.tar.gz + if-no-files-found: ignore diff --git a/pom.xml b/pom.xml index fb97283c173..72768fd44e9 100644 --- a/pom.xml +++ b/pom.xml @@ -186,6 +186,11 @@ maven-dependency-plugin 3.8.1 + + org.apache.maven.plugins + maven-help-plugin + 3.5.1 + org.apache.maven.plugins maven-release-plugin @@ -1323,6 +1328,50 @@ pmd-dist + + + dogfood + + + dogfoodStagingRepo + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + dogfood::file://${dogfoodStagingRepo} + + + + + + + dogfood + file://${dogfoodStagingRepo} + false + true + + + + sonatype-nexus-plugin-snapshots + Sonatype Nexus Snapshots + https://oss.sonatype.org/content/repositories/snapshots + false + false + + + + apache.snapshots + Apache Snapshot Repository + https://repository.apache.org/snapshots + false + false + + + From 7989eb85a1c2eceb2e87cd893a6d89baf1ddea5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 13 Feb 2025 15:41:13 +0100 Subject: [PATCH 0510/1962] Fix #5523 - problem with UnnecessaryCast and integer division --- .../java/rule/codestyle/UnnecessaryCastRule.java | 6 +++--- .../java/rule/codestyle/xml/UnnecessaryCast.xml | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java index 45427ee47c0..f972e344c29 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java @@ -178,9 +178,9 @@ private static boolean isCastDeterminingContext(ASTCastExpression castExpr, Expr // Eg in // int i; ((double) i) * i // the only reason the mult expr has type double is because of the cast - return TypeOps.isStrictSubtype(otherType, coercionType) - // but not for integers strictly smaller than int - && !TypeOps.isStrictSubtype(otherType.unbox(), otherType.getTypeSystem().INT); + JTypeMirror promotedTypeWithoutCast = TypeConversion.binaryNumericPromotion(operandType, otherType); + JTypeMirror promotedTypeWithCast = TypeConversion.binaryNumericPromotion(coercionType, otherType); + return !promotedTypeWithoutCast.equals(promotedTypeWithCast); } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml index b9d8381d875..b4aaca6326f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml @@ -909,4 +909,18 @@ class Tester { } ]]> + + #5523 [java] UnnecessaryCast FP with integer division + 0 + + From 2b06d6d4142c78c63464833e65bd9c9671cd4d02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 13 Feb 2025 15:42:50 +0100 Subject: [PATCH 0511/1962] Update release notes --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 9fe328e64fd..f2e20a5fd7f 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -16,6 +16,9 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿ› Fixed Issues +* java-codestyle + * [#5523](https://github.com/pmd/pmd/issues/5523): \[java] UnnecessaryCast false-positive for integer operations in floating-point context + ### ๐Ÿšจ API Changes ### โœจ Merged pull requests From 303f01f6be469535ab6d3903c56e1dd64a9781c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 13 Feb 2025 16:26:30 +0100 Subject: [PATCH 0512/1962] Fix #5442 - stackoverflow I wasn't able to create source that triggers the bug without going creating a new code path... --- .../sourceforge/pmd/lang/java/types/TypeOps.java | 8 ++++++++ .../pmd/lang/java/types/SubtypingTest.kt | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java index b4e5bf049be..22d893ef88d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java @@ -401,6 +401,11 @@ public static Convertibility isConvertible(@NonNull JTypeMirror t, @NonNull JTyp return SubtypeVisitor.INFERENCE.isConvertible(t, s, true); } + // test only + static Convertibility isConvertibleInferenceNoCapture(@NonNull JTypeMirror t, @NonNull JTypeMirror s) { + return SubtypeVisitor.INFERENCE.isConvertible(t, s, false); + } + @Deprecated // unused public static Convertibility isConvertible(@NonNull JTypeMirror t, @NonNull JTypeMirror s, boolean capture) { return SubtypeVisitor.PURE.isConvertible(t, s, capture); @@ -801,7 +806,10 @@ public Convertibility visit(JTypeMirror t, JTypeMirror s) { public Convertibility visitTypeVar(JTypeVar t, JTypeMirror s) { if (s instanceof JTypeVar && t.getSymbol() != null && Objects.equals(t.getSymbol(), s.getSymbol())) { return Convertibility.SUBTYPING; + } else if (s instanceof SentinelType) { + return Convertibility.SUBTYPING; } + if (isTypeRange(s)) { return isConvertible(t, lowerBoundRec(s)); } diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/SubtypingTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/SubtypingTest.kt index d3b3ba18c62..2ee2190c7f1 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/SubtypingTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/SubtypingTest.kt @@ -17,6 +17,7 @@ import net.sourceforge.pmd.lang.java.ast.ParserTestCtx import net.sourceforge.pmd.lang.java.symbols.internal.UnresolvedClassStore import net.sourceforge.pmd.lang.java.symbols.internal.asm.createUnresolvedAsmSymbol import net.sourceforge.pmd.lang.java.types.TypeConversion.capture +import net.sourceforge.pmd.lang.java.types.TypeOps.Convertibility import net.sourceforge.pmd.lang.java.types.TypeOps.Convertibility.UNCHECKED_NO_WARNING import net.sourceforge.pmd.lang.java.types.testdata.ComparableList import net.sourceforge.pmd.lang.java.types.testdata.SomeEnum @@ -329,5 +330,20 @@ class SubtypingTest : FunSpec({ } } + test("Capture of recursive types #5442 stackoverflow") { + val acu = javaParser.parse( + """ + abstract class AbstractResourceAssembler, UID, V> implements EntityResourceAssembler { + } + abstract class Resource> extends org.springframework.hateoas.RepresentationModel { + } + """.trimIndent() + ) + + val tvar = acu.typeVar("R") + + TypeOps.isConvertibleInferenceNoCapture(tvar, tvar.typeSystem.UNKNOWN) shouldBe Convertibility.SUBTYPING + } + }) From aec9575641aa7365a9067aeb94a8820ed01f94cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 14 Feb 2025 15:58:10 +0100 Subject: [PATCH 0513/1962] Fix #5493 - illegal wildcard This is a leftover from #5387. Additionally, lambda parameter types are now projected upwards. That means they are "clean", like inferred variable types, they don't mention capture variables. Since their uses are captured anyway where it matters, this shouldn't change anything to the precision of inferred types. --- .../pmd/lang/java/types/TypeVarImpl.java | 5 +- .../types/ast/internal/LazyTypeResolver.java | 4 +- .../pmd/lang/java/types/AstTestUtil.kt | 2 +- .../pmd/lang/java/types/CaptureTest.kt | 67 +++++++++++++++++++ 4 files changed, 74 insertions(+), 4 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeVarImpl.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeVarImpl.java index ca01e1bda31..8735245a806 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeVarImpl.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeVarImpl.java @@ -76,7 +76,7 @@ static TypeVarImpl.CapturedTypeVar freshCapture(@NonNull JWildcardType wildcard) */ static JTypeVar tvarCapture(@NonNull JTypeVar tv) { if (tv.isCaptured()) { - return tv; + return tv.withUpperBound(capture(tv.getUpperBound())); } // Need to capture the bounds because those bounds contributes the methods of the tvar. // Eg in `>` the methods available in C may mention the type @@ -331,7 +331,7 @@ public JTypeVar withAnnotations(PSet newTypeAnnots) { @Override public JTypeVar withUpperBound(@NonNull JTypeMirror newUB) { - throw new UnsupportedOperationException("This only needs to be implemented on regular type variables"); + return cloneWithBounds(upperBound, newUB); } @Override @@ -353,6 +353,7 @@ public JTypeVar withUpperBound(@NonNull JTypeMirror newUB) { public @NonNull String getName() { Object captureOrigin = wildcard == null ? tvar : wildcard; return "capture#" + hashCode() % PRIME + " of " + captureOrigin; + // + "[" + lowerBound + ".." + upperBound + "]"; } } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/LazyTypeResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/LazyTypeResolver.java index f607c386082..a57c88c213d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/LazyTypeResolver.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/LazyTypeResolver.java @@ -271,7 +271,9 @@ public JTypeMirror visit(ASTVariableId node, TypingContext ctx) { if (isUnresolved(mirror)) { return ts.UNKNOWN; } - return mirror.getFormalParameters().get(param.getIndexInParent()); + JTypeMirror parmty = mirror.getFormalParameters().get(param.getIndexInParent()); + // project upwards to remove captures + return TypeOps.projectUpwards(parmty); } else if (node.isEnumConstant()) { diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/AstTestUtil.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/AstTestUtil.kt index 61b2287ff69..485457cb00c 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/AstTestUtil.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/AstTestUtil.kt @@ -28,5 +28,5 @@ fun JavaNode.firstCtorCall() = ctorCalls().crossFindBoundaries().firstOrThrow() fun JavaNode.typeVariables(): MutableList = descendants(ASTTypeParameter::class.java).crossFindBoundaries().toList { it.typeMirror } fun JavaNode.varAccesses(name: String): NodeStream = descendants(ASTVariableAccess::class.java).crossFindBoundaries().filter { it.name == name } -fun JavaNode.varId(name: String) = descendants(ASTVariableId::class.java).filter { it.name == name }.firstOrThrow() +fun JavaNode.varId(name: String) = descendants(ASTVariableId::class.java).crossFindBoundaries().filter { it.name == name }.firstOrThrow() fun JavaNode.typeVar(name: String) = descendants(ASTTypeParameter::class.java).crossFindBoundaries().filter { it.name == name }.firstOrThrow().typeMirror diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/CaptureTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/CaptureTest.kt index d5168dba956..2f5138087c6 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/CaptureTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/CaptureTest.kt @@ -122,6 +122,73 @@ class CaptureTest : IntelliMarker, FunSpec({ } } + test("Capture of variable with capturable bound #5493") { + val acu = javaParser.parse( + """ + + interface ObservableList { + } + + interface EventStream { + Subscription subscribe(Consumer observer); + } + + interface BiFunction { + C apply(A a, B b); + } + + interface Subscription { + } + + interface Function { + B apply(A a); + } + + interface Supplier { + A get(); + } + + interface Consumer { + void accept(A a); + } + + class Ext { + + static ObservableList emptyList() { + } + + public static Subscription dynamic( + ObservableList elems, + BiFunction f) { + + } + } + + public class Something { + + ObservableList base; + Function> ticks; + + void notifyObservers(Supplier> f) { + } + + protected Subscription observeInputs() { + // ticks: Function> + // ticks.apply(e): capt#2 of ? extends EventStream + // capture(capt#2 of ...) should not return capt#2 unchanged, + // but should return a capture var with its upper bound captured: EventStream + return Ext.dynamic(base, (e, i) -> ticks.apply(e).subscribe(k -> this.notifyObservers(Ext::emptyList))); + } + } + """.trimIndent() + ) + + val subscribe = acu.firstMethodCall("subscribe") + subscribe.overloadSelectionInfo.isFailed shouldBe false + acu.varId("k") shouldHaveType ts.OBJECT // captureMatcher(`?`) // todo this should probably be projected upwards (and be Object) + } + + } From 0e160b2f1e19c2243458369c108d763d7e1a2a11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 14 Feb 2025 17:57:22 +0100 Subject: [PATCH 0514/1962] Fix #5073 - UnnecessaryCast FP with lambdas Fix #5440 too --- .../rule/codestyle/UnnecessaryCastRule.java | 107 ++++++++++++++++ .../lang/java/symbols/JExecutableSymbol.java | 9 ++ .../pmd/lang/java/types/JMethodSig.java | 28 +++++ .../java/types/OverloadSelectionResult.java | 4 +- .../pmd/lang/java/types/TypeOps.java | 12 +- .../lang/java/types/UnresolvedMethodSig.java | 5 + .../types/ast/internal/PolyResolution.java | 2 +- .../java/types/internal/infer/ExprMirror.java | 5 - .../rule/codestyle/xml/UnnecessaryCast.xml | 117 ++++++++++++++++++ 9 files changed, 281 insertions(+), 8 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java index 45427ee47c0..b6d945aeef0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java @@ -15,6 +15,10 @@ import static net.sourceforge.pmd.lang.java.ast.BinaryOp.SHIFT_OPS; import static net.sourceforge.pmd.lang.java.ast.BinaryOp.SUB; import static net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils.isInfixExprWithOperator; +import static net.sourceforge.pmd.util.OptionalBool.NO; +import static net.sourceforge.pmd.util.OptionalBool.UNKNOWN; +import static net.sourceforge.pmd.util.OptionalBool.YES; +import static net.sourceforge.pmd.util.OptionalBool.definitely; import java.util.EnumSet; import java.util.Set; @@ -28,16 +32,24 @@ import net.sourceforge.pmd.lang.java.ast.ASTInfixExpression; import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression; import net.sourceforge.pmd.lang.java.ast.ASTMethodReference; +import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement; import net.sourceforge.pmd.lang.java.ast.BinaryOp; +import net.sourceforge.pmd.lang.java.ast.InvocationNode; +import net.sourceforge.pmd.lang.java.ast.JavaNode; import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; import net.sourceforge.pmd.lang.java.ast.internal.PrettyPrintingUtil; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; +import net.sourceforge.pmd.lang.java.symbols.JExecutableSymbol; +import net.sourceforge.pmd.lang.java.types.JClassType; +import net.sourceforge.pmd.lang.java.types.JMethodSig; import net.sourceforge.pmd.lang.java.types.JTypeMirror; +import net.sourceforge.pmd.lang.java.types.OverloadSelectionResult; import net.sourceforge.pmd.lang.java.types.TypeConversion; import net.sourceforge.pmd.lang.java.types.TypeOps; import net.sourceforge.pmd.lang.java.types.TypeTestUtil; import net.sourceforge.pmd.lang.java.types.ast.ExprContext; import net.sourceforge.pmd.lang.java.types.ast.ExprContext.ExprContextKind; +import net.sourceforge.pmd.util.OptionalBool; /** * Detects casts where the operand is already a subtype of the context @@ -99,6 +111,10 @@ public Object visit(ASTCastExpression castExpr, Object data) { } private boolean isCastUnnecessary(ASTCastExpression castExpr, @NonNull ExprContext context, JTypeMirror coercionType, JTypeMirror operandType) { + if (isCastDeterminingReturnOfLambda(castExpr) != NO) { + return false; + } + if (operandType.equals(coercionType)) { // with the exception of the lambda thing above, casts to // the same type are always unnecessary @@ -187,4 +203,95 @@ private static boolean isCastDeterminingContext(ASTCastExpression castExpr, Expr return false; } + private static OptionalBool isCastDeterminingReturnOfLambda(ASTCastExpression castExpr) { + ASTLambdaExpression lambda = getLambdaParent(castExpr); + if (lambda == null) { + return NO; + } + + // The necessary conditions are: + // - The lambda return type mentions type vars that are missing from its arguments + // (lambda is context dependent) + // - The lambda type is inferred: + // 1. its context is missing, or + // 2. it is invocation and the parent method call + // a. is inferred (generic + no explicit arguments) + // b. mentions some of its type params in the argument type corresponding to the lambda + + JExecutableSymbol symbol = lambda.getFunctionalMethod().getSymbol(); + if (symbol.isUnresolved()) { + return UNKNOWN; + } + + // Note we don't test the functional method directly, because it has been instantiated + // We test its generic signature. + boolean contextDependent = TypeOps.isContextDependent(symbol); + if (!contextDependent) { + return NO; + } + + ExprContext lambdaCtx = lambda.getConversionContext(); + if (lambdaCtx.isMissing()) { + return YES; + } else if (lambdaCtx.hasKind(ExprContextKind.CAST)) { + return NO; + } else if (lambdaCtx.hasKind(ExprContextKind.INVOCATION)) { + InvocationNode parentCall = (InvocationNode) lambda.getParent().getParent(); + if (parentCall.getExplicitTypeArguments() != null) { + return NO; + } + OverloadSelectionResult overload = parentCall.getOverloadSelectionInfo(); + if (overload.isFailed()) { + return UNKNOWN; + } + JMethodSig parentMethod = overload.getMethodType(); + if (!parentMethod.getSymbol().isGeneric()) { + return NO; + } + + int argIdx = lambda.getIndexInParent(); + JMethodSig genericSig = parentMethod.getSymbol().getGenericSignature(); + // this is the generic lambda ty as mentioned in the formal parameters + JTypeMirror genericLambdaTy = genericSig.ithFormalParam(argIdx, overload.isVarargsCall()); + if (!(genericLambdaTy instanceof JClassType)) { + return NO; + } + // Note that we don't capture this type, which may make the method type malformed (eg mentioning a wildcard + // as return type). We need these bare wildcards for "mentionsAny" to work properly. + // The "correct" approach here to remove wildcards would be to infer the ground non-wildcard parameterization + // of the lambda but this is pretty deep inside the inference code and not readily usable. + JClassType lambdaTyCapture = (JClassType) genericLambdaTy; + + // This is the method signature of the lambda, given the formal parameter type of the parent call. + // The formal type is not instantiated, it may contain type variables of the parent method... + JMethodSig expectedLambdaMethod = genericLambdaTy.getTypeSystem().sigOf( + lambda.getFunctionalMethod().getSymbol(), + lambdaTyCapture.getTypeParamSubst() + ); + // but if the return type does not contain such tvars, then the parent method type does + // not depend on the lambda type :) + return definitely( + TypeOps.mentionsAny( + expectedLambdaMethod.getReturnType(), + parentMethod.getTypeParameters() + ) + ); + } + return UNKNOWN; + } + + private static @Nullable ASTLambdaExpression getLambdaParent(ASTCastExpression castExpr) { + if (castExpr.getParent() instanceof ASTLambdaExpression) { + return (ASTLambdaExpression) castExpr.getParent(); + } + if (castExpr.getParent() instanceof ASTReturnStatement) { + JavaNode returnTarget = JavaAstUtils.getReturnTarget((ASTReturnStatement) castExpr.getParent()); + + if (returnTarget instanceof ASTLambdaExpression) { + return (ASTLambdaExpression) returnTarget; + } + } + return null; + } + } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java index c8bbac2c0f3..732421616a8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java @@ -12,6 +12,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import net.sourceforge.pmd.lang.java.types.JMethodSig; import net.sourceforge.pmd.lang.java.types.JTypeMirror; import net.sourceforge.pmd.lang.java.types.Substitution; @@ -110,4 +111,12 @@ default boolean hasReceiver() { */ List getThrownExceptionTypes(Substitution subst); + /** + * Return a method sig corresponding to this symbol. + * The returned signature may contain type parameters + * of this method and of the enclosing classes. + */ + default JMethodSig getGenericSignature() { + return getTypeSystem().sigOf(this); + } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/JMethodSig.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/JMethodSig.java index d21012f9f91..e29a7e93b34 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/JMethodSig.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/JMethodSig.java @@ -162,6 +162,34 @@ default boolean isGeneric() { } + /** + * Returns the type of the i-th formal parameter of the method. + * This is relevant when the call is varargs: {@code i} can in + * that case be greater that the number of formal parameters. + * + * @param i Index for a formal + * @param varargs Whether this is a varags call + * + * @throws AssertionError If the parameter is negative, or + * greater than the number of argument + * expressions to the method + */ + default JTypeMirror ithFormalParam(int i, boolean varargs) { + assert !varargs || isVarargs() : "Method is not varargs " + this; + List formals = getFormalParameters(); + if (varargs) { + assert i >= 0 : "Argument index out of range: " + i; + if (i >= formals.size() - 1) { + JTypeMirror lastFormal = formals.get(formals.size() - 1); + return ((JArrayType) lastFormal).getComponentType(); + } + } else { + assert i >= 0 && i < formals.size() : "Argument index out of range: " + i; + } + return formals.get(i); + } + + @Override JMethodSig subst(Function subst); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java index c3076961c81..0b51baf5781 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java @@ -68,7 +68,9 @@ public interface OverloadSelectionResult { * greater than the number of argument * expressions to the method */ - JTypeMirror ithFormalParam(int i); + default JTypeMirror ithFormalParam(int i) { + return getMethodType().ithFormalParam(i, isVarargsCall()); + } /** * Returns true if the invocation of this method failed. This diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java index b4e5bf049be..23bc6dad247 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java @@ -2165,8 +2165,18 @@ public static boolean isUnresolvedOrNull(@Nullable JTypeMirror t) { * context during type inference. Generic constructors * are always context dependent. */ + @Deprecated public static boolean isContextDependent(JMethodSig sig) { - JExecutableSymbol symbol = sig.getSymbol(); + return isContextDependent(sig.getSymbol()); + } + + /** + * Return true if the method is context dependent. That + * means its return type is influenced by the surrounding + * context during type inference. Generic constructors + * are always context dependent. + */ + public static boolean isContextDependent(JExecutableSymbol symbol) { if (symbol.isGeneric() || symbol.getEnclosingClass().isGeneric()) { if (symbol instanceof JMethodSymbol) { JTypeMirror returnType = ((JMethodSymbol) symbol).getReturnType(EMPTY); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/UnresolvedMethodSig.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/UnresolvedMethodSig.java index bc2994f9770..cda8742e715 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/UnresolvedMethodSig.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/UnresolvedMethodSig.java @@ -195,5 +195,10 @@ public String getSimpleName() { public String toString() { return getSimpleName(); } + + @Override + public JMethodSig getGenericSignature() { + return getTypeSystem().UNRESOLVED_METHOD; + } } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/PolyResolution.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/PolyResolution.java index cbafde4470b..aeae5ab7f64 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/PolyResolution.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/PolyResolution.java @@ -535,7 +535,7 @@ private ExprContext conversionContextOf(JavaNode node, JavaNode papa) { JMethodSig fun = ((ASTLambdaExpression) papa).getFunctionalMethod(); - if (fun == null || TypeOps.isContextDependent(fun)) { + if (fun == null || TypeOps.isContextDependent(fun.getSymbol())) { // Missing context, because the expression type itself // is used to infer the context type. return ExprContext.getMissingInstance(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java index 9c21289e3af..216cc5a1471 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java @@ -508,11 +508,6 @@ public boolean isVarargsCall() { return resolvePhase.requiresVarargs(); } - @Override - public JTypeMirror ithFormalParam(int i) { - return resolvePhase.ithFormal(getMethodType().getFormalParameters(), i); - } - @Override public boolean isFailed() { return failed; diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml index b9d8381d875..8dfb443aede 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml @@ -909,4 +909,121 @@ class Tester { } ]]> + + + Cast in return position of lambda + 0 + someList) { + final Set set = Optional.ofNullable(someList) + .map(list -> (Set) new HashSet<>(list)) // Code Style | UnnecessaryCast reported here + .orElseGet(Collections::emptySet); + } + } + ]]> + + + + Cast in return position of lambda, true positives + 3 + 13,14,15 + { Object foo(X x); } + interface L2 { Q foo(X x); } + + + public class Foo { + void bar(L1 l) {} + void bar2(L2> l) {} + void bar4(L2> l) {} + void bar3(L2 l) {} + void foor(List someList) { + bar(x -> (Comparable) "something"); // redundant + bar2(x -> (Comparable) "something"); // redundant: lambda not context dependent + bar4(x -> (Comparable) "something"); // redundant: lambda not context dependent + bar3(x -> (Comparable) "something"); // not redundant: method uses lambda ret ty + } + } + ]]> + + + + + Cast in return position of lambda, types are unresolved + 0 + , String> loadAll() { + return load() + .mapLeft(it -> (Seq) Array.of(it)) + .map(foo -> "bar"); + } + + private Either load() { + return Either.left("hello"); + } + + } + ]]> + + + + Cast in return position of lambda, declare types here + 0 + { R apply(P p); } + interface Seq {} + interface Array extends Seq { + static Array of(U u) {} + } + interface Either { + Either mapLeft(Function f) {} + Either map(Function f) {} + } + + public class Main { + + public Either, String> loadAll() { + return load() + .mapLeft(it -> (Seq) Array.of(it)) + .map(foo -> "bar"); + } + + private Either load() { + // return Either.left("hello"); + } + + } + ]]> + + + + + Other example of cast in lambda return (#5440) + 0 + (Object) o.toString()) // <-- Unnecessary cast (Object) + .orElse(Boolean.FALSE); + } + } + ]]> + + From e97321d8f3ea99d419dc1939e6d05c7203ea7a39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sat, 15 Feb 2025 15:24:12 +0100 Subject: [PATCH 0515/1962] Add test case from #5505 --- .../pmd/lang/java/types/TypeOps.java | 5 ---- .../pmd/lang/java/types/SubtypingTest.kt | 27 ++++++++++++------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java index 22d893ef88d..bb69b3e2710 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java @@ -401,11 +401,6 @@ public static Convertibility isConvertible(@NonNull JTypeMirror t, @NonNull JTyp return SubtypeVisitor.INFERENCE.isConvertible(t, s, true); } - // test only - static Convertibility isConvertibleInferenceNoCapture(@NonNull JTypeMirror t, @NonNull JTypeMirror s) { - return SubtypeVisitor.INFERENCE.isConvertible(t, s, false); - } - @Deprecated // unused public static Convertibility isConvertible(@NonNull JTypeMirror t, @NonNull JTypeMirror s, boolean capture) { return SubtypeVisitor.PURE.isConvertible(t, s, capture); diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/SubtypingTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/SubtypingTest.kt index 2ee2190c7f1..62b3af14b47 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/SubtypingTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/SubtypingTest.kt @@ -17,17 +17,17 @@ import net.sourceforge.pmd.lang.java.ast.ParserTestCtx import net.sourceforge.pmd.lang.java.symbols.internal.UnresolvedClassStore import net.sourceforge.pmd.lang.java.symbols.internal.asm.createUnresolvedAsmSymbol import net.sourceforge.pmd.lang.java.types.TypeConversion.capture -import net.sourceforge.pmd.lang.java.types.TypeOps.Convertibility import net.sourceforge.pmd.lang.java.types.TypeOps.Convertibility.UNCHECKED_NO_WARNING import net.sourceforge.pmd.lang.java.types.testdata.ComparableList import net.sourceforge.pmd.lang.java.types.testdata.SomeEnum +import net.sourceforge.pmd.lang.test.ast.IntelliMarker import net.sourceforge.pmd.lang.test.ast.shouldBeA import kotlin.test.assertTrue /** * @author Clรฉment Fournier */ -class SubtypingTest : FunSpec({ +class SubtypingTest : IntelliMarker, FunSpec({ val ts = testTypeSystem with(TypeDslOf(ts)) { @@ -331,18 +331,27 @@ class SubtypingTest : FunSpec({ } test("Capture of recursive types #5442 stackoverflow") { - val acu = javaParser.parse( + javaParser.parse( """ - abstract class AbstractResourceAssembler, UID, V> implements EntityResourceAssembler { - } - abstract class Resource> extends org.springframework.hateoas.RepresentationModel { + package org.example; + + import java.util.Collection; + import java.util.Collections; + import java.util.Optional; + + public class Main { + + public static > Optional getMaxElementCausesStackoverflow(Collection collection) { + return collection == null || collection.isEmpty() ? Optional.empty() : Optional.of(Collections.max(collection)); + } + + public static > Optional getMaxElementIsFine(Collection collection) { + return Optional.ofNullable(collection).filter(c -> !c.isEmpty()).map(Collections::max); + } } """.trimIndent() ) - val tvar = acu.typeVar("R") - - TypeOps.isConvertibleInferenceNoCapture(tvar, tvar.typeSystem.UNKNOWN) shouldBe Convertibility.SUBTYPING } From 85a792395e0ec42ae8f1292aa4b35aa65d843458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 17 Feb 2025 19:03:15 +0100 Subject: [PATCH 0516/1962] [java] Fix #5504 - UnusedAssignment FP with continue in foreach loop --- .../lang/java/rule/internal/DataflowPass.java | 16 +++------- .../bestpractices/xml/UnusedAssignment.xml | 29 +++++++++++++++++++ 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/DataflowPass.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/DataflowPass.java index 183cd71fd0f..91b8952a582 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/DataflowPass.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/DataflowPass.java @@ -774,6 +774,9 @@ private SpanInfo handleLoop(ASTLoopStatement loop, // including itself SpanInfo iter = acceptOpt(body, before.fork()); + // Make assignments that reached a continue reach the condition block before next iteration + iter.absorb(continueTarget); + if (foreachVar != null && iter.hasVar(foreachVar)) { // in foreach loops, the loop variable is reassigned on each update iter.assign(foreachVar.getSymbol(), foreachVar); @@ -782,20 +785,9 @@ private SpanInfo handleLoop(ASTLoopStatement loop, } linkConditional(iter, cond, iter, breakTarget, true); + // do a second round to make sure assignments can reach themselves. iter = acceptOpt(body, iter); - - breakTarget = globalState.breakTargets.peek(); - continueTarget = globalState.continueTargets.peek(); - if (!continueTarget.symtable.isEmpty()) { - // make assignments before a continue reach the other parts of the loop - - linkConditional(continueTarget, cond, continueTarget, breakTarget, true); - - continueTarget = acceptOpt(body, continueTarget); - continueTarget = acceptOpt(update, continueTarget); - } - SpanInfo result = popTargets(loop, breakTarget, continueTarget); result.absorb(iter); if (checkFirstIter) { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedAssignment.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedAssignment.xml index eb78a510b82..690e759d91c 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedAssignment.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedAssignment.xml @@ -3952,6 +3952,35 @@ class Lock implements Autocloseable { } } } +]]> + + + [java] UnusedAssignment false-positive with continue in foreach #5504 + 0 + lines = Files.readAllLines("someFile"); + int lineNumber = 0; + boolean expectingAnotherLine = false; + for (String line : lines) + { + ++lineNumber; + if (line.endsWith("\\")) + { + expectingAnotherLine = true; // line 9 - false positive unused assignment + continue; + } + expectingAnotherLine = false; + } + if (expectingAnotherLine) + throw new IllegalArgumentException("Unexpected end of line: " + command); + + } +} ]]> From a946abbb1118389505267f4b152304c3d7cf898b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 17 Feb 2025 19:57:22 +0100 Subject: [PATCH 0517/1962] Fix PMD warning --- .../sourceforge/pmd/lang/java/rule/internal/DataflowPass.java | 1 - 1 file changed, 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/DataflowPass.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/DataflowPass.java index 91b8952a582..13dfed68e7a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/DataflowPass.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/DataflowPass.java @@ -744,7 +744,6 @@ private SpanInfo handleLoop(ASTLoopStatement loop, ASTStatement body, boolean checkFirstIter, ASTVariableId foreachVar) { - final GlobalAlgoState globalState = before.global; //todo while(true) and do {}while(true); are special-cased // by the compiler and there is no fork From db803ea832c64f3a3683e67e38002e19ec2b2b92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 18 Feb 2025 14:41:07 +0100 Subject: [PATCH 0518/1962] Add test case for explicit type args --- .../rule/codestyle/xml/UnnecessaryCast.xml | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml index 8dfb443aede..575dca5f327 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml @@ -1015,11 +1015,31 @@ class Tester { Other example of cast in lambda return (#5440) 0 (Object) o.toString()) // <-- Unnecessary cast (Object) + // necessary otherwise map would return Optional + .map(o -> (Object) o.toString()) + .orElse(Boolean.FALSE); + } + } + ]]> + + + + + Other example of cast in lambda return (#5440) - has explicit type args + 1 + map(o -> (Object) o.toString()) .orElse(Boolean.FALSE); } } From 01ca51f3a5acadfbf8d203a943d0f2a6227fcb48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 18 Feb 2025 14:46:02 +0100 Subject: [PATCH 0519/1962] Test for cast context --- .../rule/codestyle/UnnecessaryCastRule.java | 2 +- .../rule/codestyle/xml/UnnecessaryCast.xml | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java index b6d945aeef0..c1b695e183c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java @@ -224,7 +224,7 @@ private static OptionalBool isCastDeterminingReturnOfLambda(ASTCastExpression ca } // Note we don't test the functional method directly, because it has been instantiated - // We test its generic signature. + // We test its generic signature (the symbol). boolean contextDependent = TypeOps.isContextDependent(symbol); if (!contextDependent) { return NO; diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml index 575dca5f327..09391157d62 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml @@ -1046,4 +1046,24 @@ class Tester { ]]> + + + Other example of cast in lambda return (#5440) - has cast context + 1 + ) o -> (Object) o.toString()) + .orElse(Boolean.FALSE); + } + } + ]]> + + From 26cfdea71575f222262e4e5581f2d416fd9ed012 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 18 Feb 2025 20:01:49 +0100 Subject: [PATCH 0520/1962] [plsql] Add OracleDBUtils as regression testing project --- .ci/files/all-regression-rules.xml | 11 ++++++++++- .ci/files/project-list.xml | 7 +++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/.ci/files/all-regression-rules.xml b/.ci/files/all-regression-rules.xml index 95a1423ca09..00555c0d2d4 100644 --- a/.ci/files/all-regression-rules.xml +++ b/.ci/files/all-regression-rules.xml @@ -4,7 +4,7 @@ xmlns="http://pmd.sourceforge.net/ruleset/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd"> - Every apex and java rule in PMD which is used for the regression tests with pmdtester + Every apex, plsql and java rule in PMD which is used for the regression tests with pmdtester @@ -15,6 +15,15 @@ + + + + + + + + + diff --git a/.ci/files/project-list.xml b/.ci/files/project-list.xml index 50893c2df02..e6bc36e5e43 100644 --- a/.ci/files/project-list.xml +++ b/.ci/files/project-list.xml @@ -196,4 +196,11 @@ EOF main realpath java-regression-tests-*.jar + + + OracleDBUtils + git + https://github.com/Qualtagh/OracleDBUtils.git + 0513fe6b053b31e6c09ac6f86eb2064733ecf32d + From ad8773c4a5c62f31cd208968aafe7e1515f41d0e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 20:04:19 +0100 Subject: [PATCH 0521/1962] Bump net.bytebuddy:byte-buddy-agent from 1.17.0 to 1.17.1 (#5532) Bumps [net.bytebuddy:byte-buddy-agent](https://github.com/raphw/byte-buddy) from 1.17.0 to 1.17.1. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.17.0...byte-buddy-1.17.1) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy-agent dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fb97283c173..244ad5554db 100644 --- a/pom.xml +++ b/pom.xml @@ -1000,7 +1000,7 @@ net.bytebuddy byte-buddy-agent - 1.17.0 + 1.17.1 test From ab2c0f0d352ff18c9045edf182ff4e0437de02d3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 20:05:14 +0100 Subject: [PATCH 0522/1962] Bump log4j.version from 2.24.2 to 2.24.3 (#5533) Bumps `log4j.version` from 2.24.2 to 2.24.3. Updates `org.apache.logging.log4j:log4j-api` from 2.24.2 to 2.24.3 Updates `org.apache.logging.log4j:log4j-core` from 2.24.2 to 2.24.3 --- updated-dependencies: - dependency-name: org.apache.logging.log4j:log4j-api dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: org.apache.logging.log4j:log4j-core dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-java/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 5172893da6c..5128ffd6a15 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -12,7 +12,7 @@ - 2.24.2 + 2.24.3 From b962a159ebb577bf71973293d35703c379d398ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 20:06:02 +0100 Subject: [PATCH 0523/1962] Bump com.google.code.gson:gson from 2.11.0 to 2.12.1 (#5534) Bumps [com.google.code.gson:gson](https://github.com/google/gson) from 2.11.0 to 2.12.1. - [Release notes](https://github.com/google/gson/releases) - [Changelog](https://github.com/google/gson/blob/main/CHANGELOG.md) - [Commits](https://github.com/google/gson/compare/gson-parent-2.11.0...gson-parent-2.12.1) --- updated-dependencies: - dependency-name: com.google.code.gson:gson dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 244ad5554db..822b56f76f3 100644 --- a/pom.xml +++ b/pom.xml @@ -892,7 +892,7 @@ com.google.code.gson gson - 2.11.0 + 2.12.1 org.yaml From 134355d75a590d515e2c9da9ea9118a14156dcd6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 20:07:32 +0100 Subject: [PATCH 0524/1962] Bump scalameta.version from 4.12.7 to 4.13.1.1 (#5535) Bumps `scalameta.version` from 4.12.7 to 4.13.1.1. Updates `org.scalameta:parsers_2.13` from 4.12.7 to 4.13.1.1 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.12.7...v4.13.1.1) Updates `org.scalameta:trees_2.13` from 4.12.7 to 4.13.1.1 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.12.7...v4.13.1.1) Updates `org.scalameta:parsers_2.12` from 4.12.7 to 4.13.1.1 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.12.7...v4.13.1.1) Updates `org.scalameta:trees_2.12` from 4.12.7 to 4.13.1.1 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.12.7...v4.13.1.1) --- updated-dependencies: - dependency-name: org.scalameta:parsers_2.13 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.scalameta:trees_2.13 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.scalameta:parsers_2.12 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.scalameta:trees_2.12 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index 2a3cad064cf..4488103073c 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -13,7 +13,7 @@ - 4.12.7 + 4.13.1.1 From acc446e0c263e592a823e08146b5e8de9952029b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 20:08:03 +0100 Subject: [PATCH 0525/1962] Bump org.apache.groovy:groovy from 4.0.24 to 4.0.25 (#5536) Bumps [org.apache.groovy:groovy](https://github.com/apache/groovy) from 4.0.24 to 4.0.25. - [Commits](https://github.com/apache/groovy/commits) --- updated-dependencies: - dependency-name: org.apache.groovy:groovy dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 822b56f76f3..82ef4e20f3d 100644 --- a/pom.xml +++ b/pom.xml @@ -887,7 +887,7 @@ org.apache.groovy groovy - 4.0.24 + 4.0.25 com.google.code.gson From ebf78bfef01ec2ff3e4245597a5d5a75a7f978d6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 18 Feb 2025 20:30:35 +0100 Subject: [PATCH 0526/1962] some change to trigger regression tester --- pmd-core/src/main/java/net/sourceforge/pmd/PMDVersion.java | 1 + 1 file changed, 1 insertion(+) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PMDVersion.java b/pmd-core/src/main/java/net/sourceforge/pmd/PMDVersion.java index 19532bd99ec..a1aafdbeef9 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/PMDVersion.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PMDVersion.java @@ -18,6 +18,7 @@ public final class PMDVersion { private static final Logger LOG = LoggerFactory.getLogger(PMDVersion.class); + /** * Constant that contains always the current version of PMD. */ From 72b6d0639b61e360df0c3279c8b4d2186280b170 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Feb 2025 08:29:11 +0100 Subject: [PATCH 0527/1962] [plsql] Skip problematic file p_utils_tests.sql for now Refs #5521 --- .ci/files/all-regression-rules.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.ci/files/all-regression-rules.xml b/.ci/files/all-regression-rules.xml index 00555c0d2d4..0b5670384a9 100644 --- a/.ci/files/all-regression-rules.xml +++ b/.ci/files/all-regression-rules.xml @@ -6,6 +6,9 @@ xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd"> Every apex, plsql and java rule in PMD which is used for the regression tests with pmdtester + + .*/OracleDBUtils/p_utils_tests.sql + From e642898015d646b18e91145e3a24b9e7ba1ba23e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Feb 2025 09:31:28 +0100 Subject: [PATCH 0528/1962] Remove ".git" suffix from git url in .ci/files/project-list.xml --- .ci/files/project-list.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/files/project-list.xml b/.ci/files/project-list.xml index e6bc36e5e43..77c0ac8cd5f 100644 --- a/.ci/files/project-list.xml +++ b/.ci/files/project-list.xml @@ -200,7 +200,7 @@ EOF OracleDBUtils git - https://github.com/Qualtagh/OracleDBUtils.git + https://github.com/Qualtagh/OracleDBUtils 0513fe6b053b31e6c09ac6f86eb2064733ecf32d From a4867f7f987d70c086cc3b55832f4d8f999bc3f2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Feb 2025 11:09:26 +0100 Subject: [PATCH 0529/1962] Revert "some change to trigger regression tester" This reverts commit ebf78bfef01ec2ff3e4245597a5d5a75a7f978d6. --- pmd-core/src/main/java/net/sourceforge/pmd/PMDVersion.java | 1 - 1 file changed, 1 deletion(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PMDVersion.java b/pmd-core/src/main/java/net/sourceforge/pmd/PMDVersion.java index a1aafdbeef9..19532bd99ec 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/PMDVersion.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PMDVersion.java @@ -18,7 +18,6 @@ public final class PMDVersion { private static final Logger LOG = LoggerFactory.getLogger(PMDVersion.class); - /** * Constant that contains always the current version of PMD. */ From 46f25a17cbc3c0bb13e17484b3ba43633dbb65c8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Feb 2025 14:28:12 +0100 Subject: [PATCH 0530/1962] Update pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/SubtypingTest.kt --- .../kotlin/net/sourceforge/pmd/lang/java/types/SubtypingTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/SubtypingTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/SubtypingTest.kt index 62b3af14b47..b04535574ba 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/SubtypingTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/SubtypingTest.kt @@ -330,7 +330,7 @@ class SubtypingTest : IntelliMarker, FunSpec({ } } - test("Capture of recursive types #5442 stackoverflow") { + test("Capture of recursive types #5505 stackoverflow") { javaParser.parse( """ package org.example; From 8bfe328b0a12f154b7265e3863cf516492688c6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 20 Feb 2025 14:31:19 +0100 Subject: [PATCH 0531/1962] Update japicmp config --- pom.xml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pom.xml b/pom.xml index fb97283c173..4e659c4d916 100644 --- a/pom.xml +++ b/pom.xml @@ -666,6 +666,26 @@ @net.sourceforge.pmd.annotation.Experimental @net.sourceforge.pmd.annotation.InternalApi + + + + + + + + METHOD_NEW_DEFAULT + true + true + + + + + METHOD_ABSTRACT_NOW_DEFAULT + true + true + + From 3a577571713af9ae7d8f518c837c759430b2e0c9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Feb 2025 14:32:02 +0100 Subject: [PATCH 0532/1962] [doc] Update release notes (#5528, #5442, #5505) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 9fe328e64fd..f6355a54023 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -15,6 +15,9 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* java + * [#5505](https://github.com/pmd/pmd/issues/5505): \[java] java.lang.StackOverflowError while executing a PmdRunnable + * [#5442](https://github.com/pmd/pmd/issues/5442): \[java] StackOverflowError with recursive generic types ### ๐Ÿšจ API Changes From 124ad8a768980ec6936336370fa98698eac80f92 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Feb 2025 15:04:33 +0100 Subject: [PATCH 0533/1962] [doc] Update release notes (#5529, #5493) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 9fe328e64fd..aa86957f3c5 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -15,6 +15,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* java + * [#5493](https://github.com/pmd/pmd/issues/5493): \[java] IllegalArgumentException: cannot be a wildcard bound ### ๐Ÿšจ API Changes From 834b35ffe2e42cbdbb77d76377e036dfb2bc1091 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 20 Feb 2025 15:13:16 +0100 Subject: [PATCH 0534/1962] Fix IdenticalCatchBranch reporting branches that call different overloads --- .../codestyle/IdenticalCatchBranchesRule.java | 40 +++++++++++- .../codestyle/xml/IdenticalCatchBranches.xml | 64 +++++++++++++++++++ 2 files changed, 103 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesRule.java index 9be54e90ab7..bb9870b7109 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesRule.java @@ -7,13 +7,18 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.Objects; import java.util.Set; import net.sourceforge.pmd.lang.java.ast.ASTCatchClause; import net.sourceforge.pmd.lang.java.ast.ASTTryStatement; +import net.sourceforge.pmd.lang.java.ast.InvocationNode; +import net.sourceforge.pmd.lang.java.ast.JavaNode; import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; import net.sourceforge.pmd.lang.java.ast.internal.PrettyPrintingUtil; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; +import net.sourceforge.pmd.lang.java.symbols.JExecutableSymbol; +import net.sourceforge.pmd.util.OptionalBool; /** @@ -28,12 +33,45 @@ public IdenticalCatchBranchesRule() { super(ASTTryStatement.class); } + interface PartialEquivalenceRel { + OptionalBool test(T t1, T t2); + } private boolean areEquivalent(ASTCatchClause st1, ASTCatchClause st2) { String e1Name = st1.getParameter().getName(); String e2Name = st2.getParameter().getName(); - return JavaAstUtils.tokenEquals(st1.getBody(), st2.getBody(), name -> name.equals(e1Name) ? e2Name : name); + return JavaAstUtils.tokenEquals(st1.getBody(), st2.getBody(), name -> name.equals(e1Name) ? e2Name : name) + && areStructurallyEquivalent(st1.getBody(), st2.getBody(), + (n1, n2) -> { + if (n1 instanceof InvocationNode) { + JExecutableSymbol sym1 = ((InvocationNode) n1).getMethodType().getSymbol(); + JExecutableSymbol sym2 = ((InvocationNode) n2).getMethodType().getSymbol(); + if (!Objects.equals(sym1, sym2)) + return OptionalBool.NO; + } + return OptionalBool.UNKNOWN; + }); + } + + /** + * Check that both nodes have the same structure and that some semantic properties + * of the trees match (eg, methods that are being called). This is not a full + * equality routine, for instance we do not + */ + private static boolean areStructurallyEquivalent(JavaNode n1, JavaNode n2, PartialEquivalenceRel areEquivalent) { + if (n1.getNumChildren() != n2.getNumChildren() + || !n1.getClass().equals(n2.getClass()) + || areEquivalent.test(n1, n2) == OptionalBool.NO) { + return false; + } + + for (int i = 0; i < n1.getNumChildren(); i++) { + if (!areStructurallyEquivalent(n1.getChild(i), n2.getChild(i), areEquivalent)) { + return false; + } + } + return true; } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/IdenticalCatchBranches.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/IdenticalCatchBranches.xml index 82a3c4d2468..21709c6e5ee 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/IdenticalCatchBranches.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/IdenticalCatchBranches.xml @@ -145,4 +145,68 @@ class Foo { } ]]> + + + [java] IdenticalCatchBranches false positive with overloads (control test) + 1 + E report(E e, String parm, String other) { + return e; + } + + // this is not overloaded so the report is correct + static E wrap(E e) { + return e; + } + + public boolean classNameExists(String fullyQualifiedClassName) { + try { + Foo.class.getClassLoader().loadClass(fullyQualifiedClassName); + return true; // Class found + } catch (AssertionError e) { + return report(wrap(e), fullyQualifiedClassName, fullyQualifiedClassName); + } catch (LinkageError e2) { + return report(wrap(e2), fullyQualifiedClassName, fullyQualifiedClassName); + } + } + + + } + ]]> + + + + [java] IdenticalCatchBranches false positive with overloads + 0 + E report(E e, String parm, String other) { + return e; + } + + // these are overloaded so it would not work + static AssertionError wrap(AssertionError e) { + return e; + } + + static LinkageError wrap(LinkageError e) { + return e; + } + + public boolean classNameExists(String fullyQualifiedClassName) { + try { + Foo.class.getClassLoader().loadClass(fullyQualifiedClassName); + return true; // Class found + } catch (AssertionError e) { + return report(wrap(e), fullyQualifiedClassName, fullyQualifiedClassName); + } catch (LinkageError e2) { + return report(wrap(e2), fullyQualifiedClassName, fullyQualifiedClassName); + } + } + + + } + ]]> + From 002306af78f7e36fbc76b2eede9044f0da144262 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Feb 2025 16:05:48 +0100 Subject: [PATCH 0535/1962] Add GitHub issue links in IDEA git log --- .gitignore | 5 +++-- .idea/vcs.xml | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 .idea/vcs.xml diff --git a/.gitignore b/.gitignore index a4967e344f0..999dd73e95e 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,8 @@ bin/ .ruleset .settings/ *.iml -.idea +.idea/* +!.idea/vcs.xml *.patch */src/site/site.xml pmd-core/dependency-reduced-pom.xml @@ -21,4 +22,4 @@ node_modules # rule docs are generated docs/pages/pmd/rules -.history/* \ No newline at end of file +.history/* diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000000..13f1d386bbf --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + \ No newline at end of file From 8f9bae55afbeb916874f746f470a24139fe30d52 Mon Sep 17 00:00:00 2001 From: Vincent Potucek Date: Tue, 18 Feb 2025 19:44:30 +0100 Subject: [PATCH 0536/1962] icon --- .gitignore | 5 ++-- .idea/icon.svg | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 .idea/icon.svg diff --git a/.gitignore b/.gitignore index a4967e344f0..12798727d32 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,8 @@ bin/ .ruleset .settings/ *.iml -.idea +.idea/* +!.idea/icon.svg *.patch */src/site/site.xml pmd-core/dependency-reduced-pom.xml @@ -21,4 +22,4 @@ node_modules # rule docs are generated docs/pages/pmd/rules -.history/* \ No newline at end of file +.history/* diff --git a/.idea/icon.svg b/.idea/icon.svg new file mode 100644 index 00000000000..6782d8aaa76 --- /dev/null +++ b/.idea/icon.svg @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + From 98bac6ff5ccdea66bc99da9006fe357f1b5d5fb8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 21 Feb 2025 09:15:54 +0100 Subject: [PATCH 0537/1962] [doc] Add GitHub Actions Workflows page --- docs/_data/sidebars/pmd_sidebar.yml | 3 + .../pmd/devdocs/github_actions_workflows.md | 61 +++++++++++++++++++ .../projectdocs/committers/infrastructure.md | 40 ++++++------ 3 files changed, 81 insertions(+), 23 deletions(-) create mode 100644 docs/pages/pmd/devdocs/github_actions_workflows.md diff --git a/docs/_data/sidebars/pmd_sidebar.yml b/docs/_data/sidebars/pmd_sidebar.yml index 28f24d9ec96..ea877c46667 100644 --- a/docs/_data/sidebars/pmd_sidebar.yml +++ b/docs/_data/sidebars/pmd_sidebar.yml @@ -568,6 +568,9 @@ entries: - title: Roadmap url: /pmd_devdocs_roadmap.html output: web, pdf + - title: GitHub Actions Workflows + url: /pmd_devdocs_github_actions_workflows.html + output: web, pdf - title: How PMD works url: /pmd_devdocs_how_pmd_works.html output: web, pdf diff --git a/docs/pages/pmd/devdocs/github_actions_workflows.md b/docs/pages/pmd/devdocs/github_actions_workflows.md new file mode 100644 index 00000000000..303ced0a266 --- /dev/null +++ b/docs/pages/pmd/devdocs/github_actions_workflows.md @@ -0,0 +1,61 @@ +--- +title: GitHub Actions Workflows +permalink: pmd_devdocs_github_actions_workflows.html +summary: | + PMD uses GitHub Actions as the CI/CD infrastructure to build and release new versions. + This page gives an overview of how these workflows work and how to use them. +author: Andreas Dangel +last_updated: February 2025 (7.11.0) +--- + +{%include note.html content="This page is work in progress and does not yet describe all workflows."%} + +## Pull Request Build + +* Builds: +* Workflow file: + +This workflow is triggered whenever a pull request is created or synchronized. + +In order to avoid unnecessary builds, we use concurrency control to make sure, we cancel any in-progress jobs for +the current pull request when a new commit has been pushed. This means, only the latest commit is built, which +is enough, since only this will be merged in the end. Only the latest build matters. + +The workflow is self-contained, e.g. it doesn't depend on the shell scripts from PMD's build-tools. +It also uses only read permissions and doesn't need access to any secrets. It is safe to run also on +forks. + +During the build we create a couple of artifacts, that can be downloaded: + +* compile-artifact: contains all the built classes (everything in the `target/` directories). It is built under Linux, + so unfortunately it can only be used to speed up other Linux based builds, but not Windows or MacOS. +* staging-repository: contains all the artifacts of groupId `net.sourceforge.pmd`. Could be used as a local + repository to test against this built PMD version without the need to deploy the SNAPSHOTs anywhere. It is + actually used by the dogfood job. +* dist-artifact: contains the binary distribution files, ready to be downloaded. This can be used to test + PMD with the changes from the pull request without the need to build it locally. It is actually used by the + regression tester job to avoid building PMD another time. +* docs-artifact: contains the generated rule documentation. +* pmd-regression-tester: contains the generation regression report, if there were any changes to rules. + +In order to have fast feedback of the build results, we run a couple of jobs in parallel and not sequentially. +The jobs are: + +* "compile": First a fast compile job to sort out any basic problems at the beginning. If this job fails, nothing + else is executed. It also populates the build cache (maven dependencies) that is reused for the following jobs. + The created artifacts are: "compile-artifact", "staging-repository", "dist-artifact". +* After this first job, a bunch of other jobs are run in parallel: + - "verify": runs a complete `./mvnw verify` with all code checks like checkstyle, japicmp, javadoc, etc. + but excluding unit tests (these are run in a separate job). + This job is only run on linux. It reuses the already compiled artifacts from the first "compile" job. + - "verify-unittests": just runs the unit tests on Linux, Windows and MacOS. Only linux reuses the + "compile-artifact" from the first job. For Windows/MacOS we can't reuse this due to platform specific line + endings and timestamp issues. + - "dogfood": runs maven-pmd-plugin on PMD with the latest changes from this very pull request. It uses the + "staging-repository" artifact. + - "documentation": generates the rule documentations and builds PMD's documentation page using jekyll. + It also executes the verification for wrong rule tags and dead links. It creates the artifact "docs-artifact". + - "regressiontester": runs the [pmdtester](pmd_devdocs_pmdtester.html) to produce the regression report. + It reuses the artifact "dist-artifact" so that we don't need to build PMD again. It uses a different build + cache as the other jobs, as this cache now contains the test projects (like Spring Framework) and their + dependencies. It produces the artifact "pmd-regression-tester" with the regression report. diff --git a/docs/pages/pmd/projectdocs/committers/infrastructure.md b/docs/pages/pmd/projectdocs/committers/infrastructure.md index 51035b901ed..16c6752600e 100644 --- a/docs/pages/pmd/projectdocs/committers/infrastructure.md +++ b/docs/pages/pmd/projectdocs/committers/infrastructure.md @@ -2,12 +2,12 @@ title: Infrastructure permalink: pmd_projectdocs_committers_infrastructure.html author: Andreas Dangel -last_updated: April 2021 +last_updated: February 2025 (7.11.0) --- This page describes, which infrastructure and services is used by the pmd project. -## github +## GitHub The main repository is hosted on . We own the organization "pmd". @@ -16,19 +16,19 @@ The main repository is hosted on . We own the organizati * issue tracker * discussions * pull requests -* github actions for CI +* [GitHub Actions for CI](pmd_devdocs_github_actions_workflows.html) Also the [main landing page](pmd_projectdocs_committers_main_landing_page.html) () -is hosted using github pages. +is hosted using GitHub pages. -## sourceforge +## SourceForge -Before moving to github, sourceforge was the main place. It is still there: . +Before moving to GitHub, SourceForge was the main place. It is still there: . -Nowadays it is used for: +Nowadays, it is used for: -* hosting archive of binaries: https://sourceforge.net/projects/pmd/files/ -* hosting an archive of documentation: https://pmd.sourceforge.io/archive.html +* hosting an archive of binaries: +* hosting an archive of documentation: * mailing lists: * * @@ -36,7 +36,7 @@ Nowadays it is used for: It also contains the old issue tracker. -## domain, email and homepage +## Domain, mail and homepage We are using a webhosting package by [Netcup](https://www.netcup.de/). @@ -56,27 +56,21 @@ The homepage redirects to . Some docs are hosted at . -## other services +## Other services -* Deployment to maven central via and +* Deployment to Maven Central via and Uploading requires credentials (CI_DEPLOY_USERNAME, CI_DEPLOY_PASSWORD) and permissions. -* Hosting eclipse plugin update site via - Uploading requires credentials (BINTRAY_USER, BINTRAY_APIKEY) - Note: This service is retired and the update site is now hosted via Github Pages (). -* Hosting result reports from pmd-regression-tester via - Uploading requires credentials (PMD_CI_CHUNK_TOKEN) * Twitter: * Rubygems for pmd-regression-tester: Uploading requires credentials (GEM_HOST_API_KEY) -* sonarcloud: +* SonarCloud: We use the "CI-based Analysis method" with GitHub Actions. Documentation: Uploading new analysis results requires credentials (SONAR_TOKEN). - Login is via github. -* coveralls: - We don't use the [Coveralls Github Actions](https://github.com/marketplace/actions/coveralls-github-action) but the [coveralls-maven-plugin](https://github.com/trautonen/coveralls-maven-plugin). + Login is via GitHub. +* Coveralls: + We don't use the [Coveralls GitHub Actions](https://github.com/marketplace/actions/coveralls-github-action) but the [coveralls-maven-plugin](https://github.com/trautonen/coveralls-maven-plugin). Documentation: Uploading new results requires credentials (COVERALLS_REPO_TOKEN). - Login is via github. -* travis ci was used before github actions: + Login is via GitHub. From 92b5e864bd44af2aea9ea10db5a5f2eab213830f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 21 Feb 2025 12:37:33 +0100 Subject: [PATCH 0538/1962] Add @punkratz312 as a contributor --- .all-contributorsrc | 9 ++++ docs/pages/pmd/projectdocs/credits.md | 69 ++++++++++++++------------- 2 files changed, 44 insertions(+), 34 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 46b435c53b0..58d28c2fd8d 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7938,6 +7938,15 @@ "contributions": [ "doc" ] + }, + { + "login": "punkratz312", + "name": "Vincent Potucek", + "avatar_url": "https://avatars.githubusercontent.com/u/8830888?v=4", + "profile": "https://github.com/punkratz312", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 6182d0abf96..e58deb12dcb 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -820,308 +820,309 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Vincent Galloy
    Vincent Galloy

    ๐Ÿ’ป Vincent HUYNH
    Vincent HUYNH

    ๐Ÿ› Vincent Maurin
    Vincent Maurin

    ๐Ÿ› + Vincent Potucek
    Vincent Potucek

    ๐Ÿ’ป Vincent Privat
    Vincent Privat

    ๐Ÿ› Vishhwas
    Vishhwas

    ๐Ÿ› - Vishv_Android
    Vishv_Android

    ๐Ÿ› + Vishv_Android
    Vishv_Android

    ๐Ÿ› Vitalii Yevtushenko
    Vitalii Yevtushenko

    ๐Ÿ› Vitaly
    Vitaly

    ๐Ÿ› Vitaly Polonetsky
    Vitaly Polonetsky

    ๐Ÿ› Vojtech Polivka
    Vojtech Polivka

    ๐Ÿ› Vsevolod Zholobov
    Vsevolod Zholobov

    ๐Ÿ› Vyom Yadav
    Vyom Yadav

    ๐Ÿ’ป - Wang Shidong
    Wang Shidong

    ๐Ÿ› + Wang Shidong
    Wang Shidong

    ๐Ÿ› Waqas Ahmed
    Waqas Ahmed

    ๐Ÿ› Wayne J. Earl
    Wayne J. Earl

    ๐Ÿ› Wchenghui
    Wchenghui

    ๐Ÿ› Wener
    Wener

    ๐Ÿ’ป Will Winder
    Will Winder

    ๐Ÿ› Willem A. Hajenius
    Willem A. Hajenius

    ๐Ÿ’ป - William Brockhus
    William Brockhus

    ๐Ÿ’ป ๐Ÿ› + William Brockhus
    William Brockhus

    ๐Ÿ’ป ๐Ÿ› Wilson Kurniawan
    Wilson Kurniawan

    ๐Ÿ› Wim Deblauwe
    Wim Deblauwe

    ๐Ÿ› Woongsik Choi
    Woongsik Choi

    ๐Ÿ› XenoAmess
    XenoAmess

    ๐Ÿ’ป ๐Ÿ› Yang
    Yang

    ๐Ÿ’ป YaroslavTER
    YaroslavTER

    ๐Ÿ› - Yasar Shaikh
    Yasar Shaikh

    ๐Ÿ’ป + Yasar Shaikh
    Yasar Shaikh

    ๐Ÿ’ป Young Chan
    Young Chan

    ๐Ÿ’ป ๐Ÿ› YuJin Kim
    YuJin Kim

    ๐Ÿ› Yuri Dolzhenko
    Yuri Dolzhenko

    ๐Ÿ› Yurii Dubinka
    Yurii Dubinka

    ๐Ÿ› Zoltan Farkas
    Zoltan Farkas

    ๐Ÿ› Zustin
    Zustin

    ๐Ÿ› - aaronhurst-google
    aaronhurst-google

    ๐Ÿ› ๐Ÿ’ป + aaronhurst-google
    aaronhurst-google

    ๐Ÿ› ๐Ÿ’ป alexmodis
    alexmodis

    ๐Ÿ› andreoss
    andreoss

    ๐Ÿ› andrey81inmd
    andrey81inmd

    ๐Ÿ’ป ๐Ÿ› anicoara
    anicoara

    ๐Ÿ› arunprasathav
    arunprasathav

    ๐Ÿ› asiercamara
    asiercamara

    ๐Ÿ› - astillich-igniti
    astillich-igniti

    ๐Ÿ’ป + astillich-igniti
    astillich-igniti

    ๐Ÿ’ป avesolovksyy
    avesolovksyy

    ๐Ÿ› avishvat
    avishvat

    ๐Ÿ› avivmu
    avivmu

    ๐Ÿ› axelbarfod1
    axelbarfod1

    ๐Ÿ› b-3-n
    b-3-n

    ๐Ÿ› balbhadra9
    balbhadra9

    ๐Ÿ› - base23de
    base23de

    ๐Ÿ› + base23de
    base23de

    ๐Ÿ› bergander
    bergander

    ๐Ÿ› ๐Ÿ’ป berkam
    berkam

    ๐Ÿ’ป ๐Ÿ› breizh31
    breizh31

    ๐Ÿ› caesarkim
    caesarkim

    ๐Ÿ› caiocarvalhotero
    caiocarvalhotero

    ๐Ÿ› carolyujing
    carolyujing

    ๐Ÿ› - cbfiddle
    cbfiddle

    ๐Ÿ› + cbfiddle
    cbfiddle

    ๐Ÿ› cesares-basilico
    cesares-basilico

    ๐Ÿ› chrite
    chrite

    ๐Ÿ› ciufudean
    ciufudean

    ๐Ÿ“– cobratbq
    cobratbq

    ๐Ÿ› coladict
    coladict

    ๐Ÿ› cosmoJFH
    cosmoJFH

    ๐Ÿ› - cristalp
    cristalp

    ๐Ÿ› + cristalp
    cristalp

    ๐Ÿ› crunsk
    crunsk

    ๐Ÿ› cwholmes
    cwholmes

    ๐Ÿ› cyberjj999
    cyberjj999

    ๐Ÿ› cyw3
    cyw3

    ๐Ÿ› ๐Ÿ“– d1ss0nanz
    d1ss0nanz

    ๐Ÿ› dague1
    dague1

    ๐Ÿ“– - dalizi007
    dalizi007

    ๐Ÿ’ป + dalizi007
    dalizi007

    ๐Ÿ’ป danbrycefairsailcom
    danbrycefairsailcom

    ๐Ÿ› dariansanity
    dariansanity

    ๐Ÿ› darrenmiliband
    darrenmiliband

    ๐Ÿ› davidburstrom
    davidburstrom

    ๐Ÿ› dbirkman-paloalto
    dbirkman-paloalto

    ๐Ÿ› deepak-patra
    deepak-patra

    ๐Ÿ› - dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› + dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› dinesh150
    dinesh150

    ๐Ÿ› diziaq
    diziaq

    ๐Ÿ› dreaminpast123
    dreaminpast123

    ๐Ÿ› duanyanan
    duanyanan

    ๐Ÿ› dutt-sanjay
    dutt-sanjay

    ๐Ÿ› duursma
    duursma

    ๐Ÿ’ป - dylanleung
    dylanleung

    ๐Ÿ› + dylanleung
    dylanleung

    ๐Ÿ› dzeigler
    dzeigler

    ๐Ÿ› eant60
    eant60

    ๐Ÿ› ekkirala
    ekkirala

    ๐Ÿ› emersonmoura
    emersonmoura

    ๐Ÿ› emouty
    emouty

    ๐Ÿ’ป ๐Ÿ› eugenepugach
    eugenepugach

    ๐Ÿ› - fairy
    fairy

    ๐Ÿ› + fairy
    fairy

    ๐Ÿ› filiprafalowicz
    filiprafalowicz

    ๐Ÿ’ป flxbl-io
    flxbl-io

    ๐Ÿ’ต foxmason
    foxmason

    ๐Ÿ› frankegabor
    frankegabor

    ๐Ÿ› frankl
    frankl

    ๐Ÿ› freafrea
    freafrea

    ๐Ÿ› - fsapatin
    fsapatin

    ๐Ÿ› + fsapatin
    fsapatin

    ๐Ÿ› gearsethenry
    gearsethenry

    ๐Ÿ› gracia19
    gracia19

    ๐Ÿ› gudzpoz
    gudzpoz

    ๐Ÿ› guo fei
    guo fei

    ๐Ÿ› gurmsc5
    gurmsc5

    ๐Ÿ› gwilymatgearset
    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ› - haigsn
    haigsn

    ๐Ÿ› + haigsn
    haigsn

    ๐Ÿ› hemanshu070
    hemanshu070

    ๐Ÿ› henrik242
    henrik242

    ๐Ÿ› hongpuwu
    hongpuwu

    ๐Ÿ› hvbtup
    hvbtup

    ๐Ÿ’ป ๐Ÿ› igniti GmbH
    igniti GmbH

    ๐Ÿ› ilovezfs
    ilovezfs

    ๐Ÿ› - imax-erik
    imax-erik

    ๐Ÿ› + imax-erik
    imax-erik

    ๐Ÿ› itaigilo
    itaigilo

    ๐Ÿ› jakivey32
    jakivey32

    ๐Ÿ› jbennett2091
    jbennett2091

    ๐Ÿ› jcamerin
    jcamerin

    ๐Ÿ› jkeener1
    jkeener1

    ๐Ÿ› jmetertea
    jmetertea

    ๐Ÿ› - johnra2
    johnra2

    ๐Ÿ’ป + johnra2
    johnra2

    ๐Ÿ’ป johnzhao9
    johnzhao9

    ๐Ÿ› josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ› kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ› karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“– karwer
    karwer

    ๐Ÿ› kaulonline
    kaulonline

    ๐Ÿ› - kdaemonv
    kdaemonv

    ๐Ÿ› + kdaemonv
    kdaemonv

    ๐Ÿ› kdebski85
    kdebski85

    ๐Ÿ› ๐Ÿ’ป kenji21
    kenji21

    ๐Ÿ’ป ๐Ÿ› kfranic
    kfranic

    ๐Ÿ› khalidkh
    khalidkh

    ๐Ÿ› koalalam
    koalalam

    ๐Ÿ› krzyk
    krzyk

    ๐Ÿ› - lasselindqvist
    lasselindqvist

    ๐Ÿ› + lasselindqvist
    lasselindqvist

    ๐Ÿ› lgemeinhardt
    lgemeinhardt

    ๐Ÿ› lihuaib
    lihuaib

    ๐Ÿ› liqingjun123
    liqingjun123

    ๐Ÿ› lonelyma1021
    lonelyma1021

    ๐Ÿ› lpeddy
    lpeddy

    ๐Ÿ› lujiefsi
    lujiefsi

    ๐Ÿ’ป - lukelukes
    lukelukes

    ๐Ÿ’ป + lukelukes
    lukelukes

    ๐Ÿ’ป lyriccoder
    lyriccoder

    ๐Ÿ› marcelmore
    marcelmore

    ๐Ÿ› matchbox
    matchbox

    ๐Ÿ› matthiaskraaz
    matthiaskraaz

    ๐Ÿ› meandonlyme
    meandonlyme

    ๐Ÿ› mikesive
    mikesive

    ๐Ÿ› - milossesic
    milossesic

    ๐Ÿ› + milossesic
    milossesic

    ๐Ÿ› mluckam
    mluckam

    ๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
    mohan-chinnappan-n

    ๐Ÿ’ป mriddell95
    mriddell95

    ๐Ÿ› mrlzh
    mrlzh

    ๐Ÿ› msloan
    msloan

    ๐Ÿ› mucharlaravalika
    mucharlaravalika

    ๐Ÿ› - mvenneman
    mvenneman

    ๐Ÿ› + mvenneman
    mvenneman

    ๐Ÿ› nareshl119
    nareshl119

    ๐Ÿ› nicolas-harraudeau-sonarsource
    nicolas-harraudeau-sonarsource

    ๐Ÿ› noerremark
    noerremark

    ๐Ÿ› novsirion
    novsirion

    ๐Ÿ› nwcm
    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
    oggboy

    ๐Ÿ› - oinume
    oinume

    ๐Ÿ› + oinume
    oinume

    ๐Ÿ› orimarko
    orimarko

    ๐Ÿ’ป ๐Ÿ› pablogomez2197
    pablogomez2197

    ๐Ÿ› pacvz
    pacvz

    ๐Ÿ’ป pallavi agarwal
    pallavi agarwal

    ๐Ÿ› parksungrin
    parksungrin

    ๐Ÿ› patpatpat123
    patpatpat123

    ๐Ÿ› - patriksevallius
    patriksevallius

    ๐Ÿ› + patriksevallius
    patriksevallius

    ๐Ÿ› pbrajesh1
    pbrajesh1

    ๐Ÿ› phoenix384
    phoenix384

    ๐Ÿ› piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป plan3d
    plan3d

    ๐Ÿ› poojasix
    poojasix

    ๐Ÿ› prabhushrikant
    prabhushrikant

    ๐Ÿ› - pujitha8783
    pujitha8783

    ๐Ÿ› + pujitha8783
    pujitha8783

    ๐Ÿ› r-r-a-j
    r-r-a-j

    ๐Ÿ› raghujayjunk
    raghujayjunk

    ๐Ÿ› rajeshveera
    rajeshveera

    ๐Ÿ› rajeswarreddy88
    rajeswarreddy88

    ๐Ÿ› recdevs
    recdevs

    ๐Ÿ› reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ› - rijkt
    rijkt

    ๐Ÿ› + rijkt
    rijkt

    ๐Ÿ› rillig-tk
    rillig-tk

    ๐Ÿ› rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ› rnveach
    rnveach

    ๐Ÿ› rxmicro
    rxmicro

    ๐Ÿ› ryan-gustafson
    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ› sabi0
    sabi0

    ๐Ÿ› - samc-gearset
    samc-gearset

    ๐Ÿ“– + samc-gearset
    samc-gearset

    ๐Ÿ“– scais
    scais

    ๐Ÿ› schosin
    schosin

    ๐Ÿ› screamingfrog
    screamingfrog

    ๐Ÿ’ต sebbASF
    sebbASF

    ๐Ÿ› sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป shilko2013
    shilko2013

    ๐Ÿ› - shiomiyan
    shiomiyan

    ๐Ÿ“– + shiomiyan
    shiomiyan

    ๐Ÿ“– simeonKondr
    simeonKondr

    ๐Ÿ› snajberk
    snajberk

    ๐Ÿ› sniperrifle2004
    sniperrifle2004

    ๐Ÿ› snuyanzin
    snuyanzin

    ๐Ÿ› ๐Ÿ’ป soloturn
    soloturn

    ๐Ÿ› soyodream
    soyodream

    ๐Ÿ› - sratz
    sratz

    ๐Ÿ› + sratz
    sratz

    ๐Ÿ› stonio
    stonio

    ๐Ÿ› sturton
    sturton

    ๐Ÿ’ป ๐Ÿ› sudharmohan
    sudharmohan

    ๐Ÿ› suruchidawar
    suruchidawar

    ๐Ÿ› svenfinitiv
    svenfinitiv

    ๐Ÿ› szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป - tashiscool
    tashiscool

    ๐Ÿ› + tashiscool
    tashiscool

    ๐Ÿ› test-git-hook
    test-git-hook

    ๐Ÿ› testation21
    testation21

    ๐Ÿ’ป ๐Ÿ› thanosa
    thanosa

    ๐Ÿ› tiandiyixian
    tiandiyixian

    ๐Ÿ› tobwoerk
    tobwoerk

    ๐Ÿ› tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป - trentchilders
    trentchilders

    ๐Ÿ› + trentchilders
    trentchilders

    ๐Ÿ› triandicAnt
    triandicAnt

    ๐Ÿ› trishul14
    trishul14

    ๐Ÿ› tsui
    tsui

    ๐Ÿ› wangzitom12306
    wangzitom12306

    ๐Ÿ› winhkey
    winhkey

    ๐Ÿ› witherspore
    witherspore

    ๐Ÿ› - wjljack
    wjljack

    ๐Ÿ› + wjljack
    wjljack

    ๐Ÿ› wuchiuwong
    wuchiuwong

    ๐Ÿ› xingsong
    xingsong

    ๐Ÿ› xioayuge
    xioayuge

    ๐Ÿ› xnYi9wRezm
    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ› xuanuy
    xuanuy

    ๐Ÿ› xyf0921
    xyf0921

    ๐Ÿ› - yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› + yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› yasuharu-sato
    yasuharu-sato

    ๐Ÿ› zenglian
    zenglian

    ๐Ÿ› zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› zh3ng
    zh3ng

    ๐Ÿ› zt_soft
    zt_soft

    ๐Ÿ› ztt79
    ztt79

    ๐Ÿ› - zzzzfeng
    zzzzfeng

    ๐Ÿ› + zzzzfeng
    zzzzfeng

    ๐Ÿ› รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› ไปป่ดตๆฐ
    ไปป่ดตๆฐ

    ๐Ÿ› ๅคฉ็ƒญๅƒ่ฅฟ็“œ
    ๅคฉ็ƒญๅƒ่ฅฟ็“œ

    ๐Ÿ› From 18fa2f2bea1f120f7401651ec554555c7fdc2781 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 21 Feb 2025 12:39:54 +0100 Subject: [PATCH 0539/1962] [doc] Update release notes (#5538) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 9fe328e64fd..404e09a61a8 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -21,6 +21,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ Merged pull requests * [#5503](https://github.com/pmd/pmd/pull/5503): \[java] AvoidSynchronizedAtMethodLevel: Fixed error in code example - [Balazs Glatz](https://github.com/gbq6) (@gbq6) +* [#5538](https://github.com/pmd/pmd/pull/5538): Add project icon for IntelliJ IDEA - [Vincent Potucek](https://github.com/punkratz312) (@punkratz312) ### ๐Ÿ“ฆ Dependency updates From 86dda033fc3e3af2395811eafbf817ea1bb444d3 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 21 Feb 2025 17:59:21 +0100 Subject: [PATCH 0540/1962] [javacc] Move the grammar files to src/main/javacc --- javacc-wrapper.xml | 6 +++--- pmd-core/{etc/grammar => src/main/javacc}/dummy.jjt | 0 pmd-cpp/{etc/grammar => src/main/javacc}/Cpp.jj | 0 pmd-java/{etc/grammar => src/main/javacc}/Java.jjt | 0 .../{etc/grammar => src/main/javacc}/Ecmascript5.jj | 0 pmd-jsp/{etc/grammar => src/main/javacc}/Jsp.jjt | 0 pmd-matlab/{etc/grammar => src/main/javacc}/Matlab.jj | 0 pmd-modelica/{etc/grammar => src/main/javacc}/Modelica.jjt | 0 .../{etc/grammar => src/main/javacc}/ObjectiveC.jj | 0 pmd-plsql/{etc/grammar => src/main/javacc}/PLSQL.jjt | 0 pmd-python/{etc/grammar => src/main/javacc}/Python.jj | 0 pmd-velocity/{etc/grammar => src/main/javacc}/Vtl.jjt | 0 pmd-visualforce/{etc/grammar => src/main/javacc}/Vf.jjt | 0 13 files changed, 3 insertions(+), 3 deletions(-) rename pmd-core/{etc/grammar => src/main/javacc}/dummy.jjt (100%) rename pmd-cpp/{etc/grammar => src/main/javacc}/Cpp.jj (100%) rename pmd-java/{etc/grammar => src/main/javacc}/Java.jjt (100%) rename pmd-javascript/{etc/grammar => src/main/javacc}/Ecmascript5.jj (100%) rename pmd-jsp/{etc/grammar => src/main/javacc}/Jsp.jjt (100%) rename pmd-matlab/{etc/grammar => src/main/javacc}/Matlab.jj (100%) rename pmd-modelica/{etc/grammar => src/main/javacc}/Modelica.jjt (100%) rename pmd-objectivec/{etc/grammar => src/main/javacc}/ObjectiveC.jj (100%) rename pmd-plsql/{etc/grammar => src/main/javacc}/PLSQL.jjt (100%) rename pmd-python/{etc/grammar => src/main/javacc}/Python.jj (100%) rename pmd-velocity/{etc/grammar => src/main/javacc}/Vtl.jjt (100%) rename pmd-visualforce/{etc/grammar => src/main/javacc}/Vf.jjt (100%) diff --git a/javacc-wrapper.xml b/javacc-wrapper.xml index 1e782ca565f..0eb6e1a6de7 100644 --- a/javacc-wrapper.xml +++ b/javacc-wrapper.xml @@ -44,7 +44,7 @@ - + @@ -88,7 +88,7 @@ description="Checks the input files are up to date"> - + @@ -132,7 +132,7 @@ - + diff --git a/pmd-core/etc/grammar/dummy.jjt b/pmd-core/src/main/javacc/dummy.jjt similarity index 100% rename from pmd-core/etc/grammar/dummy.jjt rename to pmd-core/src/main/javacc/dummy.jjt diff --git a/pmd-cpp/etc/grammar/Cpp.jj b/pmd-cpp/src/main/javacc/Cpp.jj similarity index 100% rename from pmd-cpp/etc/grammar/Cpp.jj rename to pmd-cpp/src/main/javacc/Cpp.jj diff --git a/pmd-java/etc/grammar/Java.jjt b/pmd-java/src/main/javacc/Java.jjt similarity index 100% rename from pmd-java/etc/grammar/Java.jjt rename to pmd-java/src/main/javacc/Java.jjt diff --git a/pmd-javascript/etc/grammar/Ecmascript5.jj b/pmd-javascript/src/main/javacc/Ecmascript5.jj similarity index 100% rename from pmd-javascript/etc/grammar/Ecmascript5.jj rename to pmd-javascript/src/main/javacc/Ecmascript5.jj diff --git a/pmd-jsp/etc/grammar/Jsp.jjt b/pmd-jsp/src/main/javacc/Jsp.jjt similarity index 100% rename from pmd-jsp/etc/grammar/Jsp.jjt rename to pmd-jsp/src/main/javacc/Jsp.jjt diff --git a/pmd-matlab/etc/grammar/Matlab.jj b/pmd-matlab/src/main/javacc/Matlab.jj similarity index 100% rename from pmd-matlab/etc/grammar/Matlab.jj rename to pmd-matlab/src/main/javacc/Matlab.jj diff --git a/pmd-modelica/etc/grammar/Modelica.jjt b/pmd-modelica/src/main/javacc/Modelica.jjt similarity index 100% rename from pmd-modelica/etc/grammar/Modelica.jjt rename to pmd-modelica/src/main/javacc/Modelica.jjt diff --git a/pmd-objectivec/etc/grammar/ObjectiveC.jj b/pmd-objectivec/src/main/javacc/ObjectiveC.jj similarity index 100% rename from pmd-objectivec/etc/grammar/ObjectiveC.jj rename to pmd-objectivec/src/main/javacc/ObjectiveC.jj diff --git a/pmd-plsql/etc/grammar/PLSQL.jjt b/pmd-plsql/src/main/javacc/PLSQL.jjt similarity index 100% rename from pmd-plsql/etc/grammar/PLSQL.jjt rename to pmd-plsql/src/main/javacc/PLSQL.jjt diff --git a/pmd-python/etc/grammar/Python.jj b/pmd-python/src/main/javacc/Python.jj similarity index 100% rename from pmd-python/etc/grammar/Python.jj rename to pmd-python/src/main/javacc/Python.jj diff --git a/pmd-velocity/etc/grammar/Vtl.jjt b/pmd-velocity/src/main/javacc/Vtl.jjt similarity index 100% rename from pmd-velocity/etc/grammar/Vtl.jjt rename to pmd-velocity/src/main/javacc/Vtl.jjt diff --git a/pmd-visualforce/etc/grammar/Vf.jjt b/pmd-visualforce/src/main/javacc/Vf.jjt similarity index 100% rename from pmd-visualforce/etc/grammar/Vf.jjt rename to pmd-visualforce/src/main/javacc/Vf.jjt From 29c86c66568dfbae0eb87ce8fc2576f954a9ec13 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 21 Feb 2025 18:06:47 +0100 Subject: [PATCH 0541/1962] [core] Remove unused dummy.jjt Not in use anymore since #4044 --- pmd-core/src/main/javacc/dummy.jjt | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 pmd-core/src/main/javacc/dummy.jjt diff --git a/pmd-core/src/main/javacc/dummy.jjt b/pmd-core/src/main/javacc/dummy.jjt deleted file mode 100644 index 46a09e28319..00000000000 --- a/pmd-core/src/main/javacc/dummy.jjt +++ /dev/null @@ -1,22 +0,0 @@ -/* This is a dummy JJTree used to generate the reusable aspects of JavaCC parsers. */ -options { - USER_CHAR_STREAM = true; -} - -PARSER_BEGIN(DummyParser) -package net.sourceforge.pmd.lang.ast.dummy; -public class DummyParser -{ -} -PARSER_END(DummyParser) - -TOKEN : -{ - -} - -ASTDummy Dummy() : -{} -{ - -} From 6095fc235539ac8380e81d4b3046a3bc3dbd1929 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 21 Feb 2025 18:11:14 +0100 Subject: [PATCH 0542/1962] [javacc] Update documentation --- .../adding_a_new_javacc_based_language.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md index 73587280dd6..f6eea8acd9d 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md @@ -43,7 +43,8 @@ definitely don't come for free. It is much effort and requires perseverance to i is automatically available in the binary distribution (pmd-dist). ### 2. Implement an AST parser for your language -* Ideally an AST parser should be implemented as a JJT file *(see VmParser.jjt or Java.jjt for example)* +* Ideally an AST parser should be implemented as a JJT file *(see VmParser.jjt or Java.jjt for example)*. + The grammar files are placed in directory `src/main/javacc`. * There is nothing preventing any other parser implementation, as long as you have some way to convert an input stream into an AST tree. Doing it as a JJT simplifies maintenance down the road. * See this link for reference: [https://javacc.java.net/doc/JJTree.html](https://javacc.java.net/doc/JJTree.html) @@ -94,7 +95,7 @@ definitely don't come for free. It is much effort and requires perseverance to i * A parser visitor adapter is not needed anymore with PMD 7. The visitor interface now provides a default implementation. * The visitor for JavaCC based AST is generated along the parser from the grammar file. The - base interface for a visitor is [`AstVisitor`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AstVisitor.java). + base interface for a visitor is [`AstVisitor`](https://github.com/pmd/pmd/blob/main/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AstVisitor.java). * The generated visitor class for VM is called `VmVisitor`. * In order to help use this visitor later on, a base visitor class should be created. See `VmVisitorBase` as an example. From ee0f88031a4fc488e19c7c31b84a330ecee893ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 23 Feb 2025 17:11:40 +0100 Subject: [PATCH 0543/1962] Fix issue with tvar capture Capturing a tvar does not return a tvar with a changed bound anymore. The upper bound only needs to be captured if we are trying to find its methods, eg if it is the LHS of a method call expression. --- .../pmd/lang/java/types/TypeConversion.java | 4 +- .../pmd/lang/java/types/TypeOps.java | 13 ++ .../pmd/lang/java/types/TypeVarImpl.java | 40 ------ .../types/ast/internal/LazyTypeResolver.java | 2 +- .../internal/infer/ast/MethodInvocMirror.java | 3 +- .../pmd/lang/java/types/CaptureTest.kt | 80 +----------- .../internal/infer/CaptureInferenceTest.kt | 123 +++++++++++++++++- .../bestpractices/xml/UnusedPrivateMethod.xml | 20 +++ 8 files changed, 157 insertions(+), 128 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeConversion.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeConversion.java index e7180a949f8..f9c54aeb57b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeConversion.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeConversion.java @@ -145,12 +145,10 @@ private static boolean isConvertibleCommon(JTypeMirror t, JTypeMirror s, boolean * @return The capture conversion of t */ public static JTypeMirror capture(JTypeMirror t) { - if (t instanceof JTypeVar) { - return TypeVarImpl.tvarCapture((JTypeVar) t); - } return t instanceof JClassType ? capture((JClassType) t) : t; } + /** * Perform capture conversion on the type t. This replaces wildcards * with fresh type variables. Capture conversion is not applied recursively. diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java index bb69b3e2710..b9fb8887aa1 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java @@ -163,6 +163,19 @@ private static boolean areSameTypes(List ts, List ss, return true; } + /** + * Methods and fields of a type variable come from its upper bound, which must be captured. + * Capturing a type var does NOT capture its upper bound, so we must treat this + * case here. + */ + public static JTypeMirror getMemberSource(JTypeMirror t) { + if (t instanceof JTypeVar) { + JTypeVar tv = (JTypeVar) t; + return capture(tv.getUpperBound()); + } + return capture(t); + } + // note that this does not take type annotations into account private static final class SameTypeVisitor implements JTypeVisitor { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeVarImpl.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeVarImpl.java index 8735245a806..68e2e693730 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeVarImpl.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeVarImpl.java @@ -4,8 +4,6 @@ package net.sourceforge.pmd.lang.java.types; -import static net.sourceforge.pmd.lang.java.types.TypeConversion.capture; - import java.util.Objects; import java.util.function.Function; @@ -64,44 +62,6 @@ static TypeVarImpl.CapturedTypeVar freshCapture(@NonNull JWildcardType wildcard) return new CapturedTypeVar(wildcard, wildcard.getTypeAnnotations()); } - /** - * Capture a type variable, that is, capture its bounds if needed. - * This is necessary because those bounds contributes to the methods - * of the type variable. - * Eg in {@code >} the methods available - * in C may mention the type parameter of Collection. But this is a - * wildcard `? super X` that needs to be replaced by a capture variable. - * - * @param tv a type var - */ - static JTypeVar tvarCapture(@NonNull JTypeVar tv) { - if (tv.isCaptured()) { - return tv.withUpperBound(capture(tv.getUpperBound())); - } - // Need to capture the bounds because those bounds contributes the methods of the tvar. - // Eg in `>` the methods available in C may mention the type - // parameter of collection. But this is a wildcard `? super X` that needs to be captured. - JTypeMirror upperBoundCap = capture(tv.getUpperBound()); - JTypeMirror lowerBoundCap = capture(tv.getLowerBound()); - if (upperBoundCap == tv.getUpperBound() && lowerBoundCap == tv.getLowerBound()) { - // no change - return tv; - } - // We will return a new var. - CapturedTypeVar newTv = new CapturedTypeVar(tv, upperBoundCap, lowerBoundCap, tv.getTypeAnnotations()); - - // We have to update the bounds again, to uphold recursive bounds. Eg if you have the following: - // class C> - // then capturing T in the body of the class C should produce a new capture var, call it T2, - // which has captured bounds. The upper bound of T2 should be - // capture(C) - // and notice that here it's T2 and not T, otherwise the recursive bound is - // not preserved by capture. So this last update is there to map T to T2 (ie, tv to newTv). - newTv.upperBound = upperBoundCap.subst(sv -> updateBounds(tv, sv, newTv)); - newTv.lowerBound = lowerBoundCap.subst(sv -> updateBounds(tv, sv, newTv)); - return newTv; - } - private static SubstVar updateBounds(JTypeVar tv, SubstVar sv, CapturedTypeVar newTv) { if (sv == tv) { return newTv; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/LazyTypeResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/LazyTypeResolver.java index a57c88c213d..dfbe2ec3993 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/LazyTypeResolver.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/LazyTypeResolver.java @@ -643,7 +643,7 @@ public JTypeMirror visit(ASTVariableAccess node, TypingContext ctx) { @Override public JTypeMirror visit(ASTFieldAccess node, TypingContext ctx) { - JTypeMirror qualifierT = capture(node.getQualifier().getTypeMirror(ctx)); + JTypeMirror qualifierT = TypeOps.getMemberSource(node.getQualifier().getTypeMirror(ctx)); if (isUnresolved(qualifierT)) { return polyResolution.getContextTypeForStandaloneFallback(node); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/MethodInvocMirror.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/MethodInvocMirror.java index 34041475962..0b5d4e6a3d3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/MethodInvocMirror.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/MethodInvocMirror.java @@ -17,7 +17,6 @@ import net.sourceforge.pmd.lang.java.ast.ASTTypeExpression; import net.sourceforge.pmd.lang.java.types.JMethodSig; import net.sourceforge.pmd.lang.java.types.JTypeMirror; -import net.sourceforge.pmd.lang.java.types.TypeConversion; import net.sourceforge.pmd.lang.java.types.TypeOps; import net.sourceforge.pmd.lang.java.types.internal.InternalMethodTypeItf; import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror; @@ -67,7 +66,7 @@ public List getAccessibleCandidates() { } else { lhsType = lhs.getTypeMirror(getTypingContext()); } - lhsType = TypeConversion.capture(lhsType); + lhsType = TypeOps.getMemberSource(lhsType); boolean staticOnly = lhs instanceof ASTTypeExpression; return TypeOps.getMethodsOf(lhsType, getName(), staticOnly, myNode.getEnclosingType().getSymbol()); diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/CaptureTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/CaptureTest.kt index 2f5138087c6..6a96d7a7143 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/CaptureTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/CaptureTest.kt @@ -12,7 +12,6 @@ import net.sourceforge.pmd.lang.java.ast.ASTVariableId import net.sourceforge.pmd.lang.java.symbols.internal.asm.createUnresolvedAsmSymbol import net.sourceforge.pmd.lang.java.types.TypeConversion.capture import net.sourceforge.pmd.lang.test.ast.IntelliMarker -import net.sourceforge.pmd.lang.test.ast.shouldBeA /** * @author Clรฉment Fournier @@ -109,86 +108,9 @@ class CaptureTest : IntelliMarker, FunSpec({ parm shouldHaveType child.typeArgs[0] val captured = capture(parm.typeMirror) - captured.shouldBeA { - it.isCaptured shouldBe true // its bounds are captured - - it.upperBound.shouldBeA { - it.symbol shouldBe child.symbol - it.typeArgs[0].shouldBeA { cvar -> - cvar.isCaptured shouldBe true - cvar.upperBound.shouldBeSameInstanceAs(captured) - } - } - } + captured shouldBeSameInstanceAs parm.typeMirror } - test("Capture of variable with capturable bound #5493") { - val acu = javaParser.parse( - """ - - interface ObservableList { - } - - interface EventStream { - Subscription subscribe(Consumer observer); - } - - interface BiFunction { - C apply(A a, B b); - } - - interface Subscription { - } - - interface Function { - B apply(A a); - } - - interface Supplier { - A get(); - } - - interface Consumer { - void accept(A a); - } - - class Ext { - - static ObservableList emptyList() { - } - - public static Subscription dynamic( - ObservableList elems, - BiFunction f) { - - } - } - - public class Something { - - ObservableList base; - Function> ticks; - - void notifyObservers(Supplier> f) { - } - - protected Subscription observeInputs() { - // ticks: Function> - // ticks.apply(e): capt#2 of ? extends EventStream - // capture(capt#2 of ...) should not return capt#2 unchanged, - // but should return a capture var with its upper bound captured: EventStream - return Ext.dynamic(base, (e, i) -> ticks.apply(e).subscribe(k -> this.notifyObservers(Ext::emptyList))); - } - } - """.trimIndent() - ) - - val subscribe = acu.firstMethodCall("subscribe") - subscribe.overloadSelectionInfo.isFailed shouldBe false - acu.varId("k") shouldHaveType ts.OBJECT // captureMatcher(`?`) // todo this should probably be projected upwards (and be Object) - } - - } diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/CaptureInferenceTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/CaptureInferenceTest.kt index cb4620c2bb9..f73631c84c0 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/CaptureInferenceTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/CaptureInferenceTest.kt @@ -5,10 +5,10 @@ package net.sourceforge.pmd.lang.java.types.internal.infer import io.kotest.matchers.shouldBe -import net.sourceforge.pmd.lang.test.ast.shouldBe -import net.sourceforge.pmd.lang.test.ast.shouldMatchN import net.sourceforge.pmd.lang.java.ast.* import net.sourceforge.pmd.lang.java.types.* +import net.sourceforge.pmd.lang.test.ast.shouldBe +import net.sourceforge.pmd.lang.test.ast.shouldMatchN import java.util.* import java.util.function.Supplier import java.util.function.ToIntFunction @@ -424,7 +424,7 @@ class CompletableFuture { """ import java.lang.annotation.*; interface Iterator { Q next(); } -interface Function { +interface Function { V apply(U u); } @Target(ElementType.TYPE_USE) @@ -482,4 +482,121 @@ public class SubClass { call.overloadSelectionInfo::isFailed shouldBe false } } + + + parserTest("Capture of variable with capturable bound #5493") { + val acu = parser.parse( + """ + + interface ObservableList { + } + + interface EventStream { + Subscription subscribe(Consumer observer); + } + + interface BiFunction { + C apply(A a, B b); + } + + interface Subscription { + } + + interface Function { + B apply(A a); + } + + interface Supplier { + A get(); + } + + interface Consumer { + void accept(A a); + } + + class Ext { + + static ObservableList emptyList() { + } + + public static Subscription dynamic( + ObservableList elems, + BiFunction f) { + + } + } + + public class Something { + + ObservableList base; + Function> ticks; + + void notifyObservers(Supplier> f) { + } + + protected Subscription observeInputs() { + // ticks: Function> + // ticks.apply(e): capt#2 of ? extends EventStream + // capture(capt#2 of ...) should not return capt#2 unchanged, + // but should return a capture var with its upper bound captured: EventStream + return Ext.dynamic(base, (e, i) -> ticks.apply(e).subscribe(k -> this.notifyObservers(Ext::emptyList))); + } + } + """.trimIndent() + ) + + val subscribe = acu.firstMethodCall("subscribe") + subscribe.overloadSelectionInfo.isFailed shouldBe false + acu.varId("k") shouldHaveType acu.typeSystem.OBJECT + } + + parserTest("Problem with capture of type parametr that has wildcard parameterized bound") { + val (acu, spy) = parser.parseWithTypeInferenceSpy( + """ + class AJjtN {} + public final class JjtreeBuilder> { + + public void closeNodeScope(N n, boolean condition) { + closeImpl(n, condition); + } + + private void closeImpl(N n, boolean condition) {} + } + """.trimIndent() + ) + + val tvar = acu.typeVar("N") + + spy.shouldBeOk { + val call = acu.firstMethodCall() + + call.methodType.shouldMatchMethod( + named = "closeImpl", + withFormals = listOf(tvar, boolean), + ) + call.overloadSelectionInfo::isFailed shouldBe false + } + } + parserTest("Problem with capture of type parametr that has wildcard parameterized bound (field access)") { + val (acu, spy) = parser.parseWithTypeInferenceSpy( + """ + class AJjtN { + B field; + } + public final class JjtreeBuilder> { + public void closeNodeScope(N n, boolean condition) { + var v = n.field; + } + } + + """.trimIndent() + ) + + spy.shouldBeOk { + val access = acu.descendants(ASTFieldAccess::class.java).firstOrThrow() + access shouldHaveType captureMatcher(`?`) + val varV = acu.varId("v") + varV shouldHaveType ts.OBJECT + } + } }) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index c9ecabd130c..fba5d627078 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2512,4 +2512,24 @@ public class PmdTestCase { } ]]> + + Problem with capture of type parametr that has wildcard parameterized bound + 0 + {} + class JavaccToken {} + public final class JjtreeBuilder> { + + + public void closeNodeScope(N n, boolean condition, JavaccToken lastToken) { + closeImpl(n, lastToken); + } + + + private void closeImpl(N n, JavaccToken lastToken) { + + } + } + ]]> + From ab3240cf650269e95235488177c8d3c7f4736981 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 23 Feb 2025 19:55:24 +0100 Subject: [PATCH 0544/1962] Cleanup, fix warnings --- .../pmd/lang/java/types/TypeOps.java | 24 +++++++------- .../pmd/lang/java/types/TypeVarImpl.java | 32 ++----------------- 2 files changed, 15 insertions(+), 41 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java index b9fb8887aa1..966ad293456 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java @@ -163,18 +163,6 @@ private static boolean areSameTypes(List ts, List ss, return true; } - /** - * Methods and fields of a type variable come from its upper bound, which must be captured. - * Capturing a type var does NOT capture its upper bound, so we must treat this - * case here. - */ - public static JTypeMirror getMemberSource(JTypeMirror t) { - if (t instanceof JTypeVar) { - JTypeVar tv = (JTypeVar) t; - return capture(tv.getUpperBound()); - } - return capture(t); - } // note that this does not take type annotations into account private static final class SameTypeVisitor implements JTypeVisitor { @@ -1951,6 +1939,18 @@ public static List filterAccessible(List visible, @NonNu return CollectionUtil.mapNotNull(visible, m -> isAccessible(m.getSymbol(), accessSite) ? m : null); } + /** + * Methods and fields of a type variable come from its upper bound, which must be captured. + * Capturing a type var does NOT capture its upper bound, so we must treat this + * case here. + */ + public static JTypeMirror getMemberSource(JTypeMirror t) { + if (t instanceof JTypeVar) { + JTypeVar tv = (JTypeVar) t; + return capture(tv.getUpperBound()); + } + return capture(t); + } public static List getMethodsOf(JTypeMirror type, String name, boolean staticOnly, @NonNull JClassSymbol enclosing) { if (staticOnly && type.isInterface()) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeVarImpl.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeVarImpl.java index 68e2e693730..a26f978caf0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeVarImpl.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeVarImpl.java @@ -62,20 +62,6 @@ static TypeVarImpl.CapturedTypeVar freshCapture(@NonNull JWildcardType wildcard) return new CapturedTypeVar(wildcard, wildcard.getTypeAnnotations()); } - private static SubstVar updateBounds(JTypeVar tv, SubstVar sv, CapturedTypeVar newTv) { - if (sv == tv) { - return newTv; - } else if (sv instanceof JTypeVar) { - return ((JTypeVar) sv).substInBounds(sv2 -> { - if (sv2 == tv) { - return newTv; - } - return sv2; - }); - } - return sv; - } - static final class RegularTypeVar extends TypeVarImpl { private final @NonNull JTypeParameterSymbol symbol; @@ -205,22 +191,10 @@ private CapturedTypeVar(@NonNull JWildcardType wild, PSet typeAnnots) } private CapturedTypeVar(@Nullable JWildcardType wild, @NonNull JTypeMirror lower, @NonNull JTypeMirror upper, PSet typeAnnots) { - super(lower.getTypeSystem(), typeAnnots); - this.upperBound = upper; - this.lowerBound = lower; - this.wildcard = wild; - this.tvar = null; - } - - private CapturedTypeVar(@Nullable JTypeVar tvar, @NonNull JTypeMirror lower, @NonNull JTypeMirror upper, PSet typeAnnots) { - super(lower.getTypeSystem(), typeAnnots); - this.upperBound = upper; - this.lowerBound = lower; - this.tvar = tvar; - this.wildcard = null; + this(null, wild, lower, upper, typeAnnots); } - private CapturedTypeVar(@Nullable JTypeVar tvar, JWildcardType wild, @NonNull JTypeMirror lower, @NonNull JTypeMirror upper, PSet typeAnnots) { + private CapturedTypeVar(@Nullable JTypeVar tvar, @Nullable JWildcardType wild, @NonNull JTypeMirror lower, @NonNull JTypeMirror upper, PSet typeAnnots) { super(lower.getTypeSystem(), typeAnnots); this.upperBound = upper; this.lowerBound = lower; @@ -270,7 +244,7 @@ public JTypeVar substInBounds(Function Date: Mon, 24 Feb 2025 19:47:00 +0100 Subject: [PATCH 0545/1962] [doc] Update release notes (#5504) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 9fe328e64fd..a8337377d05 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -15,6 +15,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* java-bestpractices + * [#5504](https://github.com/pmd/pmd/issues/5504): \[java] UnusedAssignment false-positive in for-loop with continue ### ๐Ÿšจ API Changes From ea753df7e473bc03bd76de7bca31ea622b2230b8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 14 Feb 2025 12:25:53 +0100 Subject: [PATCH 0546/1962] [plsql] Allow arbitrary expressions for TRIM Fixes #5522 --- pmd-plsql/src/main/javacc/PLSQL.jjt | 11 +++- .../pmd/lang/plsql/ast/PlsqlTreeDumpTest.java | 5 ++ .../lang/plsql/ast/TrimCollectionFunction.pls | 10 ++++ .../lang/plsql/ast/TrimCollectionFunction.txt | 53 +++++++++++++++++++ 4 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimCollectionFunction.pls create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimCollectionFunction.txt diff --git a/pmd-plsql/src/main/javacc/PLSQL.jjt b/pmd-plsql/src/main/javacc/PLSQL.jjt index 78786616768..23b969bc0ca 100644 --- a/pmd-plsql/src/main/javacc/PLSQL.jjt +++ b/pmd-plsql/src/main/javacc/PLSQL.jjt @@ -3267,7 +3267,10 @@ ASTLikeExpression LikeExpression() : } /** - * https://docs.oracle.com/en/database/oracle/oracle-database/18/sqlrf/TRIM.html + * There are two variants of TRIM: + *

    + * 1. TRIM: https://docs.oracle.com/en//database/oracle/oracle-database/23/sqlrf/TRIM.html + * 2. TRIM Collection Method: https://docs.oracle.com/en/database/oracle/oracle-database/23/lnpls/collection-methods.html#GUID-6AF582B1-9C50-4858-AE6C-B14DD051ACD1 */ ASTTrimExpression TrimExpression() : { PLSQLNode simpleNode = null; StringBuilder sb = new StringBuilder() ; } @@ -3277,7 +3280,11 @@ ASTTrimExpression TrimExpression() : [ ( | | ) { sb.append(" "); sb.append(token.getImage()); } ] [ LOOKAHEAD(StringExpression() ) simpleNode = StringExpression() { sb.append(" "); sb.append(simpleNode.getImage()); } ] [ { sb.append(" ").append(token.getImage()); } ] - simpleNode = StringExpression() { sb.append(" "); sb.append(simpleNode.getImage()); } + ( + //LOOKAHEAD(StringExpression()) simpleNode = StringExpression() { sb.append(" "); sb.append(simpleNode.getImage()); } + //| + Expression() // TRIM Collection Method takes an arbitrary expression as argument + ) ")" { sb.append(")");} ) { diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/PlsqlTreeDumpTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/PlsqlTreeDumpTest.java index 78c4dbd4fed..ae84b703421 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/PlsqlTreeDumpTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/PlsqlTreeDumpTest.java @@ -76,4 +76,9 @@ void parseSelectExpression() { void issue5133SubTypeDefinition() { doTest("Issue5133SubTypeDefinition"); } + + @Test + void trimCollectionFunction() { + doTest("TrimCollectionFunction"); + } } diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimCollectionFunction.pls b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimCollectionFunction.pls new file mode 100644 index 00000000000..2a436f2c3df --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimCollectionFunction.pls @@ -0,0 +1,10 @@ +-- +-- See https://github.com/pmd/pmd/issues/5522 +-- + +function distinguishXML() return text is +begin + select trim(x + y) from dual; + return trim(x + y); +end; +/ diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimCollectionFunction.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimCollectionFunction.txt new file mode 100644 index 00000000000..eca57598ad7 --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimCollectionFunction.txt @@ -0,0 +1,53 @@ ++- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- Global[@CanonicalImage = null] + +- ProgramUnit[@CanonicalImage = null, @MethodName = "distinguishXML", @Name = "distinguishXML", @ObjectName = null] + +- MethodDeclarator[@CanonicalImage = "DISTINGUISHXML", @Image = "distinguishXML", @ParameterCount = 1] + | +- ObjectNameDeclaration[@CanonicalImage = "DISTINGUISHXML", @Image = "distinguishXML"] + | | +- ID[@CanonicalImage = "DISTINGUISHXML", @Image = "distinguishXML"] + | +- FormalParameters[@CanonicalImage = "()", @Image = "()"] + | +- Datatype[@CanonicalImage = "TEXT", @Image = "text", @TypeImage = "text"] + | +- QualifiedName[@CanonicalImage = "TEXT", @Image = "text"] + | +- UnqualifiedID[@CanonicalImage = "TEXT", @Image = "text"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "TRIM", @Image = "trim"] + | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] + | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] + | | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] + | | +- TrimExpression[@CanonicalImage = "()", @Image = "()"] + | | +- Expression[@CanonicalImage = "X + Y", @Image = "x + y"] + | | +- AdditiveExpression[@CanonicalImage = "X + Y", @Image = "x + y"] + | | +- PrimaryPrefix[@CanonicalImage = "X", @Image = "x", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "X", @Image = "x"] + | | | +- Column[@CanonicalImage = "X", @Image = "x"] + | | | +- ID[@CanonicalImage = "X", @Image = "x"] + | | +- PrimaryPrefix[@CanonicalImage = "Y", @Image = "y", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "Y", @Image = "y"] + | | +- Column[@CanonicalImage = "Y", @Image = "y"] + | | +- ID[@CanonicalImage = "Y", @Image = "y"] + | +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | +- TableName[@CanonicalImage = "DUAL", @Image = "dual"] + | +- ID[@CanonicalImage = "DUAL", @Image = "dual"] + +- Statement[@CanonicalImage = null] + +- UnlabelledStatement[@CanonicalImage = null] + +- ReturnStatement[@CanonicalImage = null] + +- Expression[@CanonicalImage = "TRIM", @Image = "trim"] + +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] + +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] + +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] + | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] + +- TrimExpression[@CanonicalImage = "()", @Image = "()"] + +- Expression[@CanonicalImage = "X + Y", @Image = "x + y"] + +- AdditiveExpression[@CanonicalImage = "X + Y", @Image = "x + y"] + +- PrimaryPrefix[@CanonicalImage = "X", @Image = "x", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "X", @Image = "x"] + | +- Column[@CanonicalImage = "X", @Image = "x"] + | +- ID[@CanonicalImage = "X", @Image = "x"] + +- PrimaryPrefix[@CanonicalImage = "Y", @Image = "y", @SelfModifier = false] + +- SimpleExpression[@CanonicalImage = "Y", @Image = "y"] + +- Column[@CanonicalImage = "Y", @Image = "y"] + +- ID[@CanonicalImage = "Y", @Image = "y"] From ac87f48f5f86fdf66913ce6f0a3f41b9f43416f6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Feb 2025 09:08:11 +0100 Subject: [PATCH 0547/1962] [plsql] Move existing trim function tests into PlsqlTreeDumpTest --- .../pmd/lang/plsql/ast/FunctionsTest.java | 5 - .../pmd/lang/plsql/ast/PlsqlTreeDumpTest.java | 10 + .../plsql/ast/TrimWithRecordTypeTest.java | 17 - .../pmd/lang/plsql/ast/TrimFunction.pls | 50 ++ .../pmd/lang/plsql/ast/TrimFunction.txt | 536 ++++++++++++++++++ .../pmd/lang/plsql/ast/TrimWithRecordType.txt | 39 ++ 6 files changed, 635 insertions(+), 22 deletions(-) delete mode 100644 pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TrimWithRecordTypeTest.java create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.txt create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimWithRecordType.txt diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/FunctionsTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/FunctionsTest.java index f745ceb878a..9fab0af243f 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/FunctionsTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/FunctionsTest.java @@ -10,11 +10,6 @@ class FunctionsTest extends AbstractPLSQLParserTst { - @Test - void parseTrimCall() { - plsql.parseResource("TrimFunction.pls"); - } - @Test void parseSelectExtractExpression() { plsql.parseResource("ExtractExpressions.pls"); diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/PlsqlTreeDumpTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/PlsqlTreeDumpTest.java index ae84b703421..40aeaf67761 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/PlsqlTreeDumpTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/PlsqlTreeDumpTest.java @@ -77,6 +77,16 @@ void issue5133SubTypeDefinition() { doTest("Issue5133SubTypeDefinition"); } + @Test + void trimFunction() { + doTest("TrimFunction"); + } + + @Test + void trimWithRecordType() { + doTest("TrimWithRecordType"); + } + @Test void trimCollectionFunction() { doTest("TrimCollectionFunction"); diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TrimWithRecordTypeTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TrimWithRecordTypeTest.java deleted file mode 100644 index 204d8056b2c..00000000000 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TrimWithRecordTypeTest.java +++ /dev/null @@ -1,17 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.plsql.ast; - -import org.junit.jupiter.api.Test; - -import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; - -class TrimWithRecordTypeTest extends AbstractPLSQLParserTst { - - @Test - void parseTrimWithRecordType() { - plsql.parseResource("TrimWithRecordType.pls"); - } -} diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.pls b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.pls index a2c0ca52cf8..9c15f7de32d 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.pls +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.pls @@ -1,11 +1,61 @@ BEGIN +-- see https://docs.oracle.com/en//database/oracle/oracle-database/23/sqlrf/TRIM.html + +-- If you specify LEADING, then Oracle Database removes any leading characters equal to trim_character. SELECT employee_id, TO_CHAR(TRIM(LEADING 0 FROM hire_date)) FROM employees WHERE department_id = 60 ORDER BY employee_id; +-- If you specify TRAILING, then Oracle removes any trailing characters equal to trim_character. +SELECT employee_id, + TO_CHAR(TRIM(TRAILING 0 FROM hire_date)) + FROM employees + WHERE department_id = 60 + ORDER BY employee_id; + +-- If you specify BOTH or none of the three, then Oracle removes leading and trailing characters equal to trim_character. +SELECT employee_id, + TO_CHAR(TRIM(BOTH 0 FROM hire_date)) + FROM employees + WHERE department_id = 60 + ORDER BY employee_id; + +-- If you specify BOTH or none of the three, then Oracle removes leading and trailing characters equal to trim_character. +SELECT employee_id, + TO_CHAR(TRIM(0 FROM hire_date)) + FROM employees + WHERE department_id = 60 + ORDER BY employee_id; + +-- If you do not specify trim_character, then the default value is a blank space. +SELECT employee_id, + TO_CHAR(TRIM(LEADING FROM hire_date)) + FROM employees + WHERE department_id = 60 + ORDER BY employee_id; + +-- If you specify only trim_source, then Oracle removes leading and trailing blank spaces. +SELECT employee_id, + TO_CHAR(TRIM(hire_date)) + FROM employees + WHERE department_id = 60 + ORDER BY employee_id; + +-- If either trim_source or trim_character is null, then the TRIM function returns null. +SELECT employee_id, + TO_CHAR(TRIM(NULL)) + FROM employees + WHERE department_id = 60 + ORDER BY employee_id; +SELECT employee_id, + TO_CHAR(TRIM(NULL FROM hire_date)) + FROM employees + WHERE department_id = 60 + ORDER BY employee_id; + select max(cmp_id) into v_cmp_id from companies diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.txt new file mode 100644 index 00000000000..847736e7d17 --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.txt @@ -0,0 +1,536 @@ ++- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- Global[@CanonicalImage = null] + +- Block[@CanonicalImage = null] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- TrimExpression[@CanonicalImage = "( LEADING 0 FROM HIRE_DATE)", @Image = "( LEADING 0 FROM hire_date)"] + | | +- StringExpression[@CanonicalImage = "0", @Image = "0"] + | | | +- PrimaryPrefix[@CanonicalImage = "0", @Image = "0", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "0", @Image = "0"] + | | | +- NumericLiteral[@CanonicalImage = "0", @Image = "0"] + | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- ID[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- WhereClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] + | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "60", @Image = "60"] + | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] + | +- OrderByClause[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- TrimExpression[@CanonicalImage = "( TRAILING 0 FROM HIRE_DATE)", @Image = "( TRAILING 0 FROM hire_date)"] + | | +- StringExpression[@CanonicalImage = "0", @Image = "0"] + | | | +- PrimaryPrefix[@CanonicalImage = "0", @Image = "0", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "0", @Image = "0"] + | | | +- NumericLiteral[@CanonicalImage = "0", @Image = "0"] + | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- ID[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- WhereClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] + | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "60", @Image = "60"] + | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] + | +- OrderByClause[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- TrimExpression[@CanonicalImage = "( BOTH 0 FROM HIRE_DATE)", @Image = "( BOTH 0 FROM hire_date)"] + | | +- StringExpression[@CanonicalImage = "0", @Image = "0"] + | | | +- PrimaryPrefix[@CanonicalImage = "0", @Image = "0", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "0", @Image = "0"] + | | | +- NumericLiteral[@CanonicalImage = "0", @Image = "0"] + | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- ID[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- WhereClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] + | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "60", @Image = "60"] + | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] + | +- OrderByClause[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- TrimExpression[@CanonicalImage = "( 0 FROM HIRE_DATE)", @Image = "( 0 FROM hire_date)"] + | | +- StringExpression[@CanonicalImage = "0", @Image = "0"] + | | | +- PrimaryPrefix[@CanonicalImage = "0", @Image = "0", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "0", @Image = "0"] + | | | +- NumericLiteral[@CanonicalImage = "0", @Image = "0"] + | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- ID[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- WhereClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] + | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "60", @Image = "60"] + | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] + | +- OrderByClause[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- TrimExpression[@CanonicalImage = "( LEADING FROM HIRE_DATE)", @Image = "( LEADING FROM hire_date)"] + | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- ID[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- WhereClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] + | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "60", @Image = "60"] + | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] + | +- OrderByClause[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- TrimExpression[@CanonicalImage = "( HIRE_DATE)", @Image = "( hire_date)"] + | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- ID[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- WhereClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] + | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "60", @Image = "60"] + | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] + | +- OrderByClause[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- TrimExpression[@CanonicalImage = "( NULL)", @Image = "( NULL)"] + | | +- StringExpression[@CanonicalImage = "NULL", @Image = "NULL"] + | | +- PrimaryPrefix[@CanonicalImage = "NULL", @Image = "NULL", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "NULL", @Image = "NULL"] + | | +- NullLiteral[@CanonicalImage = "NULL", @Image = "NULL"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- WhereClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] + | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "60", @Image = "60"] + | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] + | +- OrderByClause[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- TrimExpression[@CanonicalImage = "( NULL FROM HIRE_DATE)", @Image = "( NULL FROM hire_date)"] + | | +- StringExpression[@CanonicalImage = "NULL", @Image = "NULL"] + | | | +- PrimaryPrefix[@CanonicalImage = "NULL", @Image = "NULL", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "NULL", @Image = "NULL"] + | | | +- NullLiteral[@CanonicalImage = "NULL", @Image = "NULL"] + | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- ID[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- WhereClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] + | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "60", @Image = "60"] + | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] + | +- OrderByClause[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "MAX", @Image = "max"] + | | +- PrimaryPrefix[@CanonicalImage = "MAX", @Image = "max", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "MAX", @Image = "max"] + | | +- FunctionName[@CanonicalImage = "MAX", @Image = "max"] + | | | +- ID[@CanonicalImage = "MAX", @Image = "max"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | | +- PrimaryPrefix[@CanonicalImage = "CMP_ID", @Image = "cmp_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | | +- Column[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | | +- ID[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "V_CMP_ID", @Image = "v_cmp_id"] + | | +- ID[@CanonicalImage = "V_CMP_ID", @Image = "v_cmp_id"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "COMPANIES", @Image = "companies"] + | | +- ID[@CanonicalImage = "COMPANIES", @Image = "companies"] + | +- WhereClause[@CanonicalImage = null] + | +- Condition[@CanonicalImage = null] + | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | +- SqlExpression[@CanonicalImage = "TRIM", @Image = "trim"] + | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] + | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] + | | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] + | | +- TrimExpression[@CanonicalImage = "( LEADING \'0\' FROM SAP_NUMBER)", @Image = "( LEADING \'0\' FROM sap_number)"] + | | +- StringExpression[@CanonicalImage = "\'0\'", @Image = "\'0\'"] + | | | +- PrimaryPrefix[@CanonicalImage = "\'0\'", @Image = "\'0\'", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "\'0\'", @Image = "\'0\'"] + | | +- StringExpression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] + | | +- PrimaryPrefix[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] + | | +- Column[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] + | | +- ID[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] + | +- SqlExpression[@CanonicalImage = "TRIM", @Image = "trim"] + | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] + | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] + | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] + | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] + | +- TrimExpression[@CanonicalImage = "( LEADING \'0\' FROM V_SAP_NR)", @Image = "( LEADING \'0\' FROM v_sap_nr)"] + | +- StringExpression[@CanonicalImage = "\'0\'", @Image = "\'0\'"] + | | +- PrimaryPrefix[@CanonicalImage = "\'0\'", @Image = "\'0\'", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "\'0\'", @Image = "\'0\'"] + | +- StringExpression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] + | +- PrimaryPrefix[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] + | +- Column[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] + | +- ID[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] + +- Statement[@CanonicalImage = null] + +- UnlabelledStatement[@CanonicalImage = null] + +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + +- SelectList[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "MAX", @Image = "max"] + | +- PrimaryPrefix[@CanonicalImage = "MAX", @Image = "max", @SelfModifier = false] + | +- FunctionCall[@CanonicalImage = "MAX", @Image = "max"] + | +- FunctionName[@CanonicalImage = "MAX", @Image = "max"] + | | +- ID[@CanonicalImage = "MAX", @Image = "max"] + | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | +- ArgumentList[@CanonicalImage = null] + | +- Argument[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | +- PrimaryPrefix[@CanonicalImage = "CMP_ID", @Image = "cmp_id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | +- Column[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | +- ID[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + +- IntoClause[@CanonicalImage = null] + | +- VariableName[@CanonicalImage = "V_CMP_ID", @Image = "v_cmp_id"] + | +- ID[@CanonicalImage = "V_CMP_ID", @Image = "v_cmp_id"] + +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | +- TableName[@CanonicalImage = "COMPANIES", @Image = "companies"] + | +- ID[@CanonicalImage = "COMPANIES", @Image = "companies"] + +- WhereClause[@CanonicalImage = null] + +- Condition[@CanonicalImage = null] + +- CompoundCondition[@CanonicalImage = null, @Type = null] + +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + +- SqlExpression[@CanonicalImage = "TRIM", @Image = "trim"] + | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] + | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] + | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] + | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] + | +- TrimExpression[@CanonicalImage = "( SAP_NUMBER)", @Image = "( sap_number)"] + | +- StringExpression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] + | +- PrimaryPrefix[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] + | +- Column[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] + | +- ID[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] + +- SqlExpression[@CanonicalImage = "TRIM", @Image = "trim"] + +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] + +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] + +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] + | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] + +- TrimExpression[@CanonicalImage = "( V_SAP_NR)", @Image = "( v_sap_nr)"] + +- StringExpression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] + +- PrimaryPrefix[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr", @SelfModifier = false] + +- SimpleExpression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] + +- Column[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] + +- ID[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimWithRecordType.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimWithRecordType.txt new file mode 100644 index 00000000000..97c9a1d6832 --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimWithRecordType.txt @@ -0,0 +1,39 @@ ++- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- PackageBody[@CanonicalImage = "TRIM_TEST_PACKAGE", @Image = "trim_test_package", @ObjectName = "trim_test_package"] + +- ObjectNameDeclaration[@CanonicalImage = "TRIM_TEST_PACKAGE", @Image = "trim_test_package"] + | +- ID[@CanonicalImage = "TRIM_TEST_PACKAGE", @Image = "trim_test_package"] + +- DeclarativeSection[@CanonicalImage = null] + | +- DeclarativeUnit[@CanonicalImage = null] + | +- ProgramUnit[@CanonicalImage = null, @MethodName = "trim_test_procedure", @Name = "trim_test_procedure", @ObjectName = null] + | +- MethodDeclarator[@CanonicalImage = "TRIM_TEST_PROCEDURE", @Image = "trim_test_procedure", @ParameterCount = 1] + | | +- ObjectNameDeclaration[@CanonicalImage = "TRIM_TEST_PROCEDURE", @Image = "trim_test_procedure"] + | | +- ID[@CanonicalImage = "TRIM_TEST_PROCEDURE", @Image = "trim_test_procedure"] + | +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- IfStatement[@CanonicalImage = null, @Else = false] + | +- Expression[@CanonicalImage = "TRIM = \'TEST\'", @Image = "trim = \'TEST\'"] + | | +- EqualityExpression[@CanonicalImage = "TRIM = \'TEST\'", @Image = "trim = \'TEST\'"] + | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] + | | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] + | | | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] + | | | +- TrimExpression[@CanonicalImage = "( VAR_PACKAGE.RECORD.FIELD)", @Image = "( var_package.record.field)"] + | | | +- StringExpression[@CanonicalImage = "VAR_PACKAGE.RECORD.FIELD", @Image = "var_package.record.field"] + | | | +- PrimaryPrefix[@CanonicalImage = "VAR_PACKAGE.RECORD.FIELD", @Image = "var_package.record.field", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "VAR_PACKAGE.RECORD.FIELD", @Image = "var_package.record.field"] + | | | +- SchemaName[@CanonicalImage = "VAR_PACKAGE", @Image = "var_package"] + | | | | +- ID[@CanonicalImage = "VAR_PACKAGE", @Image = "var_package"] + | | | +- TableName[@CanonicalImage = "RECORD", @Image = "record"] + | | | | +- ID[@CanonicalImage = "RECORD", @Image = "record"] + | | | +- Column[@CanonicalImage = "FIELD", @Image = "field"] + | | | +- ID[@CanonicalImage = "FIELD", @Image = "field"] + | | +- PrimaryPrefix[@CanonicalImage = "\'TEST\'", @Image = "\'TEST\'", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "\'TEST\'", @Image = "\'TEST\'"] + | | +- StringLiteral[@CanonicalImage = "\'TEST\'", @Image = "\'TEST\'", @String = "TEST"] + | +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "NULL", @Image = "NULL"] + | +- PrimaryPrefix[@CanonicalImage = "NULL", @Image = "NULL", @SelfModifier = false] + | +- Literal[@CanonicalImage = "NULL", @Image = "NULL"] + | +- NullLiteral[@CanonicalImage = "NULL", @Image = "NULL"] + +- ID[@CanonicalImage = "TRIM_TEST_PACKAGE", @Image = "trim_test_package"] From bc9a3dae62adbd6dc36929c7dbe0c5c29029a188 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Feb 2025 09:21:49 +0100 Subject: [PATCH 0548/1962] [plsql] Update "image" of TrimExpression --- pmd-plsql/src/main/javacc/PLSQL.jjt | 2 +- .../lang/plsql/ast/TrimCollectionFunction.txt | 4 ++-- .../pmd/lang/plsql/ast/TrimFunction.txt | 24 +++++++++---------- .../pmd/lang/plsql/ast/TrimWithRecordType.txt | 2 +- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/pmd-plsql/src/main/javacc/PLSQL.jjt b/pmd-plsql/src/main/javacc/PLSQL.jjt index 23b969bc0ca..24d9bb8442f 100644 --- a/pmd-plsql/src/main/javacc/PLSQL.jjt +++ b/pmd-plsql/src/main/javacc/PLSQL.jjt @@ -3283,7 +3283,7 @@ ASTTrimExpression TrimExpression() : ( //LOOKAHEAD(StringExpression()) simpleNode = StringExpression() { sb.append(" "); sb.append(simpleNode.getImage()); } //| - Expression() // TRIM Collection Method takes an arbitrary expression as argument + simpleNode = Expression() { sb.append(" ").append(simpleNode.getImage()); } // TRIM Collection Method takes an arbitrary expression as argument ) ")" { sb.append(")");} ) diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimCollectionFunction.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimCollectionFunction.txt index eca57598ad7..f5aaea102a0 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimCollectionFunction.txt +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimCollectionFunction.txt @@ -17,7 +17,7 @@ | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] | | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] - | | +- TrimExpression[@CanonicalImage = "()", @Image = "()"] + | | +- TrimExpression[@CanonicalImage = "( X + Y)", @Image = "( x + y)"] | | +- Expression[@CanonicalImage = "X + Y", @Image = "x + y"] | | +- AdditiveExpression[@CanonicalImage = "X + Y", @Image = "x + y"] | | +- PrimaryPrefix[@CanonicalImage = "X", @Image = "x", @SelfModifier = false] @@ -40,7 +40,7 @@ +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] - +- TrimExpression[@CanonicalImage = "()", @Image = "()"] + +- TrimExpression[@CanonicalImage = "( X + Y)", @Image = "( x + y)"] +- Expression[@CanonicalImage = "X + Y", @Image = "x + y"] +- AdditiveExpression[@CanonicalImage = "X + Y", @Image = "x + y"] +- PrimaryPrefix[@CanonicalImage = "X", @Image = "x", @SelfModifier = false] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.txt index 847736e7d17..b8e8084d4e3 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.txt +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.txt @@ -28,7 +28,7 @@ | | | +- PrimaryPrefix[@CanonicalImage = "0", @Image = "0", @SelfModifier = false] | | | +- Literal[@CanonicalImage = "0", @Image = "0"] | | | +- NumericLiteral[@CanonicalImage = "0", @Image = "0"] - | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- Expression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] @@ -83,7 +83,7 @@ | | | +- PrimaryPrefix[@CanonicalImage = "0", @Image = "0", @SelfModifier = false] | | | +- Literal[@CanonicalImage = "0", @Image = "0"] | | | +- NumericLiteral[@CanonicalImage = "0", @Image = "0"] - | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- Expression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] @@ -138,7 +138,7 @@ | | | +- PrimaryPrefix[@CanonicalImage = "0", @Image = "0", @SelfModifier = false] | | | +- Literal[@CanonicalImage = "0", @Image = "0"] | | | +- NumericLiteral[@CanonicalImage = "0", @Image = "0"] - | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- Expression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] @@ -193,7 +193,7 @@ | | | +- PrimaryPrefix[@CanonicalImage = "0", @Image = "0", @SelfModifier = false] | | | +- Literal[@CanonicalImage = "0", @Image = "0"] | | | +- NumericLiteral[@CanonicalImage = "0", @Image = "0"] - | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- Expression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] @@ -244,7 +244,7 @@ | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] | | +- TrimExpression[@CanonicalImage = "( LEADING FROM HIRE_DATE)", @Image = "( LEADING FROM hire_date)"] - | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- Expression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] @@ -295,7 +295,7 @@ | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] | | +- TrimExpression[@CanonicalImage = "( HIRE_DATE)", @Image = "( hire_date)"] - | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- Expression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] @@ -346,7 +346,7 @@ | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] | | +- TrimExpression[@CanonicalImage = "( NULL)", @Image = "( NULL)"] - | | +- StringExpression[@CanonicalImage = "NULL", @Image = "NULL"] + | | +- Expression[@CanonicalImage = "NULL", @Image = "NULL"] | | +- PrimaryPrefix[@CanonicalImage = "NULL", @Image = "NULL", @SelfModifier = false] | | +- Literal[@CanonicalImage = "NULL", @Image = "NULL"] | | +- NullLiteral[@CanonicalImage = "NULL", @Image = "NULL"] @@ -400,7 +400,7 @@ | | | +- PrimaryPrefix[@CanonicalImage = "NULL", @Image = "NULL", @SelfModifier = false] | | | +- Literal[@CanonicalImage = "NULL", @Image = "NULL"] | | | +- NullLiteral[@CanonicalImage = "NULL", @Image = "NULL"] - | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- Expression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] @@ -465,7 +465,7 @@ | | +- StringExpression[@CanonicalImage = "\'0\'", @Image = "\'0\'"] | | | +- PrimaryPrefix[@CanonicalImage = "\'0\'", @Image = "\'0\'", @SelfModifier = false] | | | +- Literal[@CanonicalImage = "\'0\'", @Image = "\'0\'"] - | | +- StringExpression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] + | | +- Expression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] | | +- PrimaryPrefix[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number", @SelfModifier = false] | | +- SimpleExpression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] | | +- Column[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] @@ -479,7 +479,7 @@ | +- StringExpression[@CanonicalImage = "\'0\'", @Image = "\'0\'"] | | +- PrimaryPrefix[@CanonicalImage = "\'0\'", @Image = "\'0\'", @SelfModifier = false] | | +- Literal[@CanonicalImage = "\'0\'", @Image = "\'0\'"] - | +- StringExpression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] + | +- Expression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] | +- PrimaryPrefix[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr", @SelfModifier = false] | +- SimpleExpression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] | +- Column[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] @@ -518,7 +518,7 @@ | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] | +- TrimExpression[@CanonicalImage = "( SAP_NUMBER)", @Image = "( sap_number)"] - | +- StringExpression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] + | +- Expression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] | +- PrimaryPrefix[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number", @SelfModifier = false] | +- SimpleExpression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] | +- Column[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] @@ -529,7 +529,7 @@ +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] +- TrimExpression[@CanonicalImage = "( V_SAP_NR)", @Image = "( v_sap_nr)"] - +- StringExpression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] + +- Expression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] +- PrimaryPrefix[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr", @SelfModifier = false] +- SimpleExpression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] +- Column[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimWithRecordType.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimWithRecordType.txt index 97c9a1d6832..db6e73c54a6 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimWithRecordType.txt +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimWithRecordType.txt @@ -18,7 +18,7 @@ | | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] | | | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] | | | +- TrimExpression[@CanonicalImage = "( VAR_PACKAGE.RECORD.FIELD)", @Image = "( var_package.record.field)"] - | | | +- StringExpression[@CanonicalImage = "VAR_PACKAGE.RECORD.FIELD", @Image = "var_package.record.field"] + | | | +- Expression[@CanonicalImage = "VAR_PACKAGE.RECORD.FIELD", @Image = "var_package.record.field"] | | | +- PrimaryPrefix[@CanonicalImage = "VAR_PACKAGE.RECORD.FIELD", @Image = "var_package.record.field", @SelfModifier = false] | | | +- SimpleExpression[@CanonicalImage = "VAR_PACKAGE.RECORD.FIELD", @Image = "var_package.record.field"] | | | +- SchemaName[@CanonicalImage = "VAR_PACKAGE", @Image = "var_package"] From b903bbe3ef16b7eda185fae2b07163fe07b05877 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Feb 2025 10:56:12 +0100 Subject: [PATCH 0549/1962] [plsql] Parse TRIM Collection Method as FunctionCall with Arguments --- pmd-plsql/src/main/javacc/PLSQL.jjt | 24 +- .../lang/plsql/ast/TrimCollectionFunction.pls | 25 +- .../lang/plsql/ast/TrimCollectionFunction.txt | 252 +++++++++++++++--- .../pmd/lang/plsql/ast/TrimFunction.txt | 24 +- .../pmd/lang/plsql/ast/TrimWithRecordType.txt | 2 +- 5 files changed, 261 insertions(+), 66 deletions(-) diff --git a/pmd-plsql/src/main/javacc/PLSQL.jjt b/pmd-plsql/src/main/javacc/PLSQL.jjt index 24d9bb8442f..22f9f63201c 100644 --- a/pmd-plsql/src/main/javacc/PLSQL.jjt +++ b/pmd-plsql/src/main/javacc/PLSQL.jjt @@ -1773,6 +1773,9 @@ ASTOuterJoinExpression OuterJoinExpression() : * See https://docs.oracle.com/en/database/oracle/oracle-database/18/sqlrf/Functions.html#GUID-D079EFD3-C683-441F-977E-2C9503089982 * See https://docs.oracle.com/en/database/oracle/oracle-database/18/sqlrf/About-User-Defined-Functions.html#GUID-4EB3E236-8216-471C-BA44-23D87BDFEA67 * + * There are also Collection Methods like "TRIM", + * see https://docs.oracle.com/en/database/oracle/oracle-database/23/lnpls/collection-methods.html#GUID-6AF582B1-9C50-4858-AE6C-B14DD051ACD1 + * * XML Functions: * https://docs.oracle.com/en/database/oracle/oracle-database/18/sqlrf/XMLROOT.html#GUID-5BD300E2-7138-436D-87AF-21658840CF9D * https://docs.oracle.com/en/database/oracle/oracle-database/18/sqlrf/XMLFOREST.html#GUID-68E5C67E-CE97-4BF8-B7FF-2365E062C363 @@ -1791,7 +1794,7 @@ ASTFunctionCall FunctionCall() : { name = FunctionName() ( - LOOKAHEAD({"TRIM".equalsIgnoreCase(token.getImage())}) TrimExpression() + LOOKAHEAD({"TRIM".equalsIgnoreCase(token.getImage()) && !jjtree.peekNode().getImage().contains(".")}) TrimExpression() | LOOKAHEAD({"XMLCAST".equalsIgnoreCase(token.getImage())}) "(" Expression() Datatype() ")" | LOOKAHEAD({"XMLQUERY".equalsIgnoreCase(token.getImage())}) "(" StringLiteral() [ LOOKAHEAD({isKeyword("PASSING")}) XMLPassingClause() ] KEYWORD("CONTENT") [ ] ")" | LOOKAHEAD({"CAST".equalsIgnoreCase(token.getImage())}) "(" ( "(" Subquery() ")" | Expression() ) Datatype() ")" @@ -3267,26 +3270,21 @@ ASTLikeExpression LikeExpression() : } /** - * There are two variants of TRIM: + * This production is about the argument list of the TRIM function (https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TRIM.html). *

    - * 1. TRIM: https://docs.oracle.com/en//database/oracle/oracle-database/23/sqlrf/TRIM.html - * 2. TRIM Collection Method: https://docs.oracle.com/en/database/oracle/oracle-database/23/lnpls/collection-methods.html#GUID-6AF582B1-9C50-4858-AE6C-B14DD051ACD1 + * There is another TRIM function as a collection method, which can only be called on collection types + * (https://docs.oracle.com/en/database/oracle/oracle-database/23/lnpls/collection-methods.html#GUID-6AF582B1-9C50-4858-AE6C-B14DD051ACD1). + * This is parsed as a normal FunctionCall with Arguments. */ ASTTrimExpression TrimExpression() : { PLSQLNode simpleNode = null; StringBuilder sb = new StringBuilder() ; } { - ( - "(" { sb.append("(");} + "(" { sb.append('('); } [ ( | | ) { sb.append(" "); sb.append(token.getImage()); } ] [ LOOKAHEAD(StringExpression() ) simpleNode = StringExpression() { sb.append(" "); sb.append(simpleNode.getImage()); } ] [ { sb.append(" ").append(token.getImage()); } ] - ( - //LOOKAHEAD(StringExpression()) simpleNode = StringExpression() { sb.append(" "); sb.append(simpleNode.getImage()); } - //| - simpleNode = Expression() { sb.append(" ").append(simpleNode.getImage()); } // TRIM Collection Method takes an arbitrary expression as argument - ) - ")" { sb.append(")");} - ) + simpleNode = StringExpression() { sb.append(" "); sb.append(simpleNode.getImage()); } + ")" { sb.append(')'); } { jjtThis.setImage(sb.toString()); return jjtThis; } diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimCollectionFunction.pls b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimCollectionFunction.pls index 2a436f2c3df..30c594f5892 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimCollectionFunction.pls +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimCollectionFunction.pls @@ -2,9 +2,30 @@ -- See https://github.com/pmd/pmd/issues/5522 -- +-- https://docs.oracle.com/en/database/oracle/oracle-database/23/lnpls/collection-methods.html#GUID-6AF582B1-9C50-4858-AE6C-B14DD051ACD1 +DECLARE + nt nt_type := nt_type(11, 22, 33, 44, 55, 66); +BEGIN + print_nt(nt); + + nt.TRIM; -- Trim last element, pseudocolumn syntax + print_nt(nt); + + nt.DELETE(4); -- Delete fourth element + print_nt(nt); + + nt.TRIM(2); -- Trim last two elements + print_nt(nt); +END; +/ + +-- https://github.com/Qualtagh/OracleDBUtils/blob/master/p_utils.9.sql#241 function distinguishXML() return text is + retNodes XMLSequenceType := XMLSequenceType(); + capacity pls_integer := 32; + j pls_integer := 1; begin - select trim(x + y) from dual; - return trim(x + y); + retNodes.trim( capacity - j + 1 ); + return 'done'; end; / diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimCollectionFunction.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimCollectionFunction.txt index f5aaea102a0..92ff5701aaf 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimCollectionFunction.txt +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimCollectionFunction.txt @@ -1,4 +1,152 @@ +- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- Global[@CanonicalImage = null] + | +- Block[@CanonicalImage = null] + | +- DeclarativeSection[@CanonicalImage = null] + | | +- DeclarativeUnit[@CanonicalImage = null] + | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | +- VariableOrConstantDeclarator[@CanonicalImage = "NT NT_TYPE := NT_TYPE", @Image = "nt nt_type := nt_type"] + | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "NT", @Image = "nt"] + | | | +- ID[@CanonicalImage = "NT", @Image = "nt"] + | | +- Datatype[@CanonicalImage = "NT_TYPE", @Image = "nt_type", @TypeImage = "nt_type"] + | | | +- QualifiedName[@CanonicalImage = "NT_TYPE", @Image = "nt_type"] + | | | +- UnqualifiedID[@CanonicalImage = "NT_TYPE", @Image = "nt_type"] + | | +- VariableOrConstantInitializer[@CanonicalImage = "NT_TYPE", @Image = "nt_type"] + | | +- Expression[@CanonicalImage = "NT_TYPE", @Image = "nt_type"] + | | +- PrimaryPrefix[@CanonicalImage = "NT_TYPE", @Image = "nt_type", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "NT_TYPE", @Image = "nt_type"] + | | +- FunctionName[@CanonicalImage = "NT_TYPE", @Image = "nt_type"] + | | | +- ID[@CanonicalImage = "NT_TYPE", @Image = "nt_type"] + | | +- Arguments[@ArgumentCount = 6, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "11", @Image = "11"] + | | | +- PrimaryPrefix[@CanonicalImage = "11", @Image = "11", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "11", @Image = "11"] + | | | +- NumericLiteral[@CanonicalImage = "11", @Image = "11"] + | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "22", @Image = "22"] + | | | +- PrimaryPrefix[@CanonicalImage = "22", @Image = "22", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "22", @Image = "22"] + | | | +- NumericLiteral[@CanonicalImage = "22", @Image = "22"] + | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "33", @Image = "33"] + | | | +- PrimaryPrefix[@CanonicalImage = "33", @Image = "33", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "33", @Image = "33"] + | | | +- NumericLiteral[@CanonicalImage = "33", @Image = "33"] + | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "44", @Image = "44"] + | | | +- PrimaryPrefix[@CanonicalImage = "44", @Image = "44", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "44", @Image = "44"] + | | | +- NumericLiteral[@CanonicalImage = "44", @Image = "44"] + | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "55", @Image = "55"] + | | | +- PrimaryPrefix[@CanonicalImage = "55", @Image = "55", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "55", @Image = "55"] + | | | +- NumericLiteral[@CanonicalImage = "55", @Image = "55"] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "66", @Image = "66"] + | | +- PrimaryPrefix[@CanonicalImage = "66", @Image = "66", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "66", @Image = "66"] + | | +- NumericLiteral[@CanonicalImage = "66", @Image = "66"] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "PRINT_NT", @Image = "print_nt"] + | | +- PrimaryPrefix[@CanonicalImage = "PRINT_NT", @Image = "print_nt", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "PRINT_NT", @Image = "print_nt"] + | | +- FunctionName[@CanonicalImage = "PRINT_NT", @Image = "print_nt"] + | | | +- ID[@CanonicalImage = "PRINT_NT", @Image = "print_nt"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "NT", @Image = "nt"] + | | +- PrimaryPrefix[@CanonicalImage = "NT", @Image = "nt", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "NT", @Image = "nt"] + | | +- Column[@CanonicalImage = "NT", @Image = "nt"] + | | +- ID[@CanonicalImage = "NT", @Image = "nt"] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "NT.TRIM", @Image = "nt.TRIM"] + | | +- PrimaryPrefix[@CanonicalImage = "NT.TRIM", @Image = "nt.TRIM", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "NT.TRIM", @Image = "nt.TRIM"] + | | +- TableName[@CanonicalImage = "NT", @Image = "nt"] + | | | +- ID[@CanonicalImage = "NT", @Image = "nt"] + | | +- Column[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "PRINT_NT", @Image = "print_nt"] + | | +- PrimaryPrefix[@CanonicalImage = "PRINT_NT", @Image = "print_nt", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "PRINT_NT", @Image = "print_nt"] + | | +- FunctionName[@CanonicalImage = "PRINT_NT", @Image = "print_nt"] + | | | +- ID[@CanonicalImage = "PRINT_NT", @Image = "print_nt"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "NT", @Image = "nt"] + | | +- PrimaryPrefix[@CanonicalImage = "NT", @Image = "nt", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "NT", @Image = "nt"] + | | +- Column[@CanonicalImage = "NT", @Image = "nt"] + | | +- ID[@CanonicalImage = "NT", @Image = "nt"] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "NT.DELETE", @Image = "nt.DELETE"] + | | +- PrimaryPrefix[@CanonicalImage = "NT.DELETE", @Image = "nt.DELETE", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "NT.DELETE", @Image = "nt.DELETE"] + | | +- FunctionName[@CanonicalImage = "NT.DELETE", @Image = "nt.DELETE"] + | | | +- ID[@CanonicalImage = "NT", @Image = "nt"] + | | | +- ID[@CanonicalImage = "DELETE", @Image = "DELETE"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "4", @Image = "4"] + | | +- PrimaryPrefix[@CanonicalImage = "4", @Image = "4", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "4", @Image = "4"] + | | +- NumericLiteral[@CanonicalImage = "4", @Image = "4"] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "PRINT_NT", @Image = "print_nt"] + | | +- PrimaryPrefix[@CanonicalImage = "PRINT_NT", @Image = "print_nt", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "PRINT_NT", @Image = "print_nt"] + | | +- FunctionName[@CanonicalImage = "PRINT_NT", @Image = "print_nt"] + | | | +- ID[@CanonicalImage = "PRINT_NT", @Image = "print_nt"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "NT", @Image = "nt"] + | | +- PrimaryPrefix[@CanonicalImage = "NT", @Image = "nt", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "NT", @Image = "nt"] + | | +- Column[@CanonicalImage = "NT", @Image = "nt"] + | | +- ID[@CanonicalImage = "NT", @Image = "nt"] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "NT.TRIM", @Image = "nt.TRIM"] + | | +- PrimaryPrefix[@CanonicalImage = "NT.TRIM", @Image = "nt.TRIM", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "NT.TRIM", @Image = "nt.TRIM"] + | | +- FunctionName[@CanonicalImage = "NT.TRIM", @Image = "nt.TRIM"] + | | | +- ID[@CanonicalImage = "NT", @Image = "nt"] + | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "2", @Image = "2"] + | | +- PrimaryPrefix[@CanonicalImage = "2", @Image = "2", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "2", @Image = "2"] + | | +- NumericLiteral[@CanonicalImage = "2", @Image = "2"] + | +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "PRINT_NT", @Image = "print_nt"] + | +- PrimaryPrefix[@CanonicalImage = "PRINT_NT", @Image = "print_nt", @SelfModifier = false] + | +- FunctionCall[@CanonicalImage = "PRINT_NT", @Image = "print_nt"] + | +- FunctionName[@CanonicalImage = "PRINT_NT", @Image = "print_nt"] + | | +- ID[@CanonicalImage = "PRINT_NT", @Image = "print_nt"] + | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | +- ArgumentList[@CanonicalImage = null] + | +- Argument[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "NT", @Image = "nt"] + | +- PrimaryPrefix[@CanonicalImage = "NT", @Image = "nt", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "NT", @Image = "nt"] + | +- Column[@CanonicalImage = "NT", @Image = "nt"] + | +- ID[@CanonicalImage = "NT", @Image = "nt"] +- Global[@CanonicalImage = null] +- ProgramUnit[@CanonicalImage = null, @MethodName = "distinguishXML", @Name = "distinguishXML", @ObjectName = null] +- MethodDeclarator[@CanonicalImage = "DISTINGUISHXML", @Image = "distinguishXML", @ParameterCount = 1] @@ -8,46 +156,74 @@ | +- Datatype[@CanonicalImage = "TEXT", @Image = "text", @TypeImage = "text"] | +- QualifiedName[@CanonicalImage = "TEXT", @Image = "text"] | +- UnqualifiedID[@CanonicalImage = "TEXT", @Image = "text"] + +- DeclarativeSection[@CanonicalImage = null] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | +- VariableOrConstantDeclarator[@CanonicalImage = "RETNODES XMLSEQUENCETYPE := XMLSEQUENCETYPE", @Image = "retNodes XMLSequenceType := XMLSequenceType"] + | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "RETNODES", @Image = "retNodes"] + | | | +- ID[@CanonicalImage = "RETNODES", @Image = "retNodes"] + | | +- Datatype[@CanonicalImage = "XMLSEQUENCETYPE", @Image = "XMLSequenceType", @TypeImage = "XMLSequenceType"] + | | | +- QualifiedName[@CanonicalImage = "XMLSEQUENCETYPE", @Image = "XMLSequenceType"] + | | | +- UnqualifiedID[@CanonicalImage = "XMLSEQUENCETYPE", @Image = "XMLSequenceType"] + | | +- VariableOrConstantInitializer[@CanonicalImage = "XMLSEQUENCETYPE", @Image = "XMLSequenceType"] + | | +- Expression[@CanonicalImage = "XMLSEQUENCETYPE", @Image = "XMLSequenceType"] + | | +- PrimaryPrefix[@CanonicalImage = "XMLSEQUENCETYPE", @Image = "XMLSequenceType", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "XMLSEQUENCETYPE", @Image = "XMLSequenceType"] + | | +- FunctionName[@CanonicalImage = "XMLSEQUENCETYPE", @Image = "XMLSequenceType"] + | | | +- ID[@CanonicalImage = "XMLSEQUENCETYPE", @Image = "XMLSequenceType"] + | | +- Arguments[@ArgumentCount = 0, @CanonicalImage = null] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | +- VariableOrConstantDeclarator[@CanonicalImage = "CAPACITY PLS_INTEGER := 32", @Image = "capacity PLS_INTEGER := 32"] + | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "CAPACITY", @Image = "capacity"] + | | | +- ID[@CanonicalImage = "CAPACITY", @Image = "capacity"] + | | +- Datatype[@CanonicalImage = "PLS_INTEGER", @Image = "PLS_INTEGER", @TypeImage = "PLS_INTEGER"] + | | | +- ScalarDataTypeName[@CanonicalImage = "PLS_INTEGER", @Image = "PLS_INTEGER"] + | | +- VariableOrConstantInitializer[@CanonicalImage = "32", @Image = "32"] + | | +- Expression[@CanonicalImage = "32", @Image = "32"] + | | +- PrimaryPrefix[@CanonicalImage = "32", @Image = "32", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "32", @Image = "32"] + | | +- NumericLiteral[@CanonicalImage = "32", @Image = "32"] + | +- DeclarativeUnit[@CanonicalImage = null] + | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | +- VariableOrConstantDeclarator[@CanonicalImage = "J PLS_INTEGER := 1", @Image = "j PLS_INTEGER := 1"] + | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "J", @Image = "j"] + | | +- ID[@CanonicalImage = "J", @Image = "j"] + | +- Datatype[@CanonicalImage = "PLS_INTEGER", @Image = "PLS_INTEGER", @TypeImage = "PLS_INTEGER"] + | | +- ScalarDataTypeName[@CanonicalImage = "PLS_INTEGER", @Image = "PLS_INTEGER"] + | +- VariableOrConstantInitializer[@CanonicalImage = "1", @Image = "1"] + | +- Expression[@CanonicalImage = "1", @Image = "1"] + | +- PrimaryPrefix[@CanonicalImage = "1", @Image = "1", @SelfModifier = false] + | +- Literal[@CanonicalImage = "1", @Image = "1"] + | +- NumericLiteral[@CanonicalImage = "1", @Image = "1"] +- Statement[@CanonicalImage = null] | +- UnlabelledStatement[@CanonicalImage = null] - | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] - | +- SelectList[@CanonicalImage = null] - | | +- SqlExpression[@CanonicalImage = "TRIM", @Image = "trim"] - | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] - | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] - | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] - | | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] - | | +- TrimExpression[@CanonicalImage = "( X + Y)", @Image = "( x + y)"] - | | +- Expression[@CanonicalImage = "X + Y", @Image = "x + y"] - | | +- AdditiveExpression[@CanonicalImage = "X + Y", @Image = "x + y"] - | | +- PrimaryPrefix[@CanonicalImage = "X", @Image = "x", @SelfModifier = false] - | | | +- SimpleExpression[@CanonicalImage = "X", @Image = "x"] - | | | +- Column[@CanonicalImage = "X", @Image = "x"] - | | | +- ID[@CanonicalImage = "X", @Image = "x"] - | | +- PrimaryPrefix[@CanonicalImage = "Y", @Image = "y", @SelfModifier = false] - | | +- SimpleExpression[@CanonicalImage = "Y", @Image = "y"] - | | +- Column[@CanonicalImage = "Y", @Image = "y"] - | | +- ID[@CanonicalImage = "Y", @Image = "y"] - | +- FromClause[@CanonicalImage = null] - | +- TableReference[@CanonicalImage = null] - | +- TableName[@CanonicalImage = "DUAL", @Image = "dual"] - | +- ID[@CanonicalImage = "DUAL", @Image = "dual"] + | +- Expression[@CanonicalImage = "RETNODES.TRIM", @Image = "retNodes.trim"] + | +- PrimaryPrefix[@CanonicalImage = "RETNODES.TRIM", @Image = "retNodes.trim", @SelfModifier = false] + | +- FunctionCall[@CanonicalImage = "RETNODES.TRIM", @Image = "retNodes.trim"] + | +- FunctionName[@CanonicalImage = "RETNODES.TRIM", @Image = "retNodes.trim"] + | | +- ID[@CanonicalImage = "RETNODES", @Image = "retNodes"] + | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] + | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | +- ArgumentList[@CanonicalImage = null] + | +- Argument[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "CAPACITY - J + 1", @Image = "capacity - j + 1"] + | +- AdditiveExpression[@CanonicalImage = "CAPACITY - J + 1", @Image = "capacity - j + 1"] + | +- PrimaryPrefix[@CanonicalImage = "CAPACITY", @Image = "capacity", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "CAPACITY", @Image = "capacity"] + | | +- Column[@CanonicalImage = "CAPACITY", @Image = "capacity"] + | | +- ID[@CanonicalImage = "CAPACITY", @Image = "capacity"] + | +- PrimaryPrefix[@CanonicalImage = "J", @Image = "j", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "J", @Image = "j"] + | | +- Column[@CanonicalImage = "J", @Image = "j"] + | | +- ID[@CanonicalImage = "J", @Image = "j"] + | +- PrimaryPrefix[@CanonicalImage = "1", @Image = "1", @SelfModifier = false] + | +- Literal[@CanonicalImage = "1", @Image = "1"] + | +- NumericLiteral[@CanonicalImage = "1", @Image = "1"] +- Statement[@CanonicalImage = null] +- UnlabelledStatement[@CanonicalImage = null] +- ReturnStatement[@CanonicalImage = null] - +- Expression[@CanonicalImage = "TRIM", @Image = "trim"] - +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] - +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] - +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] - | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] - +- TrimExpression[@CanonicalImage = "( X + Y)", @Image = "( x + y)"] - +- Expression[@CanonicalImage = "X + Y", @Image = "x + y"] - +- AdditiveExpression[@CanonicalImage = "X + Y", @Image = "x + y"] - +- PrimaryPrefix[@CanonicalImage = "X", @Image = "x", @SelfModifier = false] - | +- SimpleExpression[@CanonicalImage = "X", @Image = "x"] - | +- Column[@CanonicalImage = "X", @Image = "x"] - | +- ID[@CanonicalImage = "X", @Image = "x"] - +- PrimaryPrefix[@CanonicalImage = "Y", @Image = "y", @SelfModifier = false] - +- SimpleExpression[@CanonicalImage = "Y", @Image = "y"] - +- Column[@CanonicalImage = "Y", @Image = "y"] - +- ID[@CanonicalImage = "Y", @Image = "y"] + +- Expression[@CanonicalImage = "\'DONE\'", @Image = "\'done\'"] + +- PrimaryPrefix[@CanonicalImage = "\'DONE\'", @Image = "\'done\'", @SelfModifier = false] + +- Literal[@CanonicalImage = "\'DONE\'", @Image = "\'done\'"] + +- StringLiteral[@CanonicalImage = "\'DONE\'", @Image = "\'done\'", @String = "done"] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.txt index b8e8084d4e3..847736e7d17 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.txt +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.txt @@ -28,7 +28,7 @@ | | | +- PrimaryPrefix[@CanonicalImage = "0", @Image = "0", @SelfModifier = false] | | | +- Literal[@CanonicalImage = "0", @Image = "0"] | | | +- NumericLiteral[@CanonicalImage = "0", @Image = "0"] - | | +- Expression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] @@ -83,7 +83,7 @@ | | | +- PrimaryPrefix[@CanonicalImage = "0", @Image = "0", @SelfModifier = false] | | | +- Literal[@CanonicalImage = "0", @Image = "0"] | | | +- NumericLiteral[@CanonicalImage = "0", @Image = "0"] - | | +- Expression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] @@ -138,7 +138,7 @@ | | | +- PrimaryPrefix[@CanonicalImage = "0", @Image = "0", @SelfModifier = false] | | | +- Literal[@CanonicalImage = "0", @Image = "0"] | | | +- NumericLiteral[@CanonicalImage = "0", @Image = "0"] - | | +- Expression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] @@ -193,7 +193,7 @@ | | | +- PrimaryPrefix[@CanonicalImage = "0", @Image = "0", @SelfModifier = false] | | | +- Literal[@CanonicalImage = "0", @Image = "0"] | | | +- NumericLiteral[@CanonicalImage = "0", @Image = "0"] - | | +- Expression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] @@ -244,7 +244,7 @@ | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] | | +- TrimExpression[@CanonicalImage = "( LEADING FROM HIRE_DATE)", @Image = "( LEADING FROM hire_date)"] - | | +- Expression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] @@ -295,7 +295,7 @@ | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] | | +- TrimExpression[@CanonicalImage = "( HIRE_DATE)", @Image = "( hire_date)"] - | | +- Expression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] @@ -346,7 +346,7 @@ | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] | | +- TrimExpression[@CanonicalImage = "( NULL)", @Image = "( NULL)"] - | | +- Expression[@CanonicalImage = "NULL", @Image = "NULL"] + | | +- StringExpression[@CanonicalImage = "NULL", @Image = "NULL"] | | +- PrimaryPrefix[@CanonicalImage = "NULL", @Image = "NULL", @SelfModifier = false] | | +- Literal[@CanonicalImage = "NULL", @Image = "NULL"] | | +- NullLiteral[@CanonicalImage = "NULL", @Image = "NULL"] @@ -400,7 +400,7 @@ | | | +- PrimaryPrefix[@CanonicalImage = "NULL", @Image = "NULL", @SelfModifier = false] | | | +- Literal[@CanonicalImage = "NULL", @Image = "NULL"] | | | +- NullLiteral[@CanonicalImage = "NULL", @Image = "NULL"] - | | +- Expression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] @@ -465,7 +465,7 @@ | | +- StringExpression[@CanonicalImage = "\'0\'", @Image = "\'0\'"] | | | +- PrimaryPrefix[@CanonicalImage = "\'0\'", @Image = "\'0\'", @SelfModifier = false] | | | +- Literal[@CanonicalImage = "\'0\'", @Image = "\'0\'"] - | | +- Expression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] + | | +- StringExpression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] | | +- PrimaryPrefix[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number", @SelfModifier = false] | | +- SimpleExpression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] | | +- Column[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] @@ -479,7 +479,7 @@ | +- StringExpression[@CanonicalImage = "\'0\'", @Image = "\'0\'"] | | +- PrimaryPrefix[@CanonicalImage = "\'0\'", @Image = "\'0\'", @SelfModifier = false] | | +- Literal[@CanonicalImage = "\'0\'", @Image = "\'0\'"] - | +- Expression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] + | +- StringExpression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] | +- PrimaryPrefix[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr", @SelfModifier = false] | +- SimpleExpression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] | +- Column[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] @@ -518,7 +518,7 @@ | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] | +- TrimExpression[@CanonicalImage = "( SAP_NUMBER)", @Image = "( sap_number)"] - | +- Expression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] + | +- StringExpression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] | +- PrimaryPrefix[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number", @SelfModifier = false] | +- SimpleExpression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] | +- Column[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] @@ -529,7 +529,7 @@ +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] +- TrimExpression[@CanonicalImage = "( V_SAP_NR)", @Image = "( v_sap_nr)"] - +- Expression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] + +- StringExpression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] +- PrimaryPrefix[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr", @SelfModifier = false] +- SimpleExpression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] +- Column[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimWithRecordType.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimWithRecordType.txt index db6e73c54a6..97c9a1d6832 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimWithRecordType.txt +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimWithRecordType.txt @@ -18,7 +18,7 @@ | | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] | | | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] | | | +- TrimExpression[@CanonicalImage = "( VAR_PACKAGE.RECORD.FIELD)", @Image = "( var_package.record.field)"] - | | | +- Expression[@CanonicalImage = "VAR_PACKAGE.RECORD.FIELD", @Image = "var_package.record.field"] + | | | +- StringExpression[@CanonicalImage = "VAR_PACKAGE.RECORD.FIELD", @Image = "var_package.record.field"] | | | +- PrimaryPrefix[@CanonicalImage = "VAR_PACKAGE.RECORD.FIELD", @Image = "var_package.record.field", @SelfModifier = false] | | | +- SimpleExpression[@CanonicalImage = "VAR_PACKAGE.RECORD.FIELD", @Image = "var_package.record.field"] | | | +- SchemaName[@CanonicalImage = "VAR_PACKAGE", @Image = "var_package"] From 52cc5d77cb8431a375165caceba5bbcd216791dc Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 21 Feb 2025 16:35:07 +0100 Subject: [PATCH 0550/1962] [plsql] Allow arbitrary expressions for TrimExpression --- pmd-plsql/src/main/javacc/PLSQL.jjt | 9 +- .../pmd/lang/plsql/ast/TrimFunction.pls | 31 + .../pmd/lang/plsql/ast/TrimFunction.txt | 1278 ++++++++++------- 3 files changed, 785 insertions(+), 533 deletions(-) diff --git a/pmd-plsql/src/main/javacc/PLSQL.jjt b/pmd-plsql/src/main/javacc/PLSQL.jjt index 22f9f63201c..b47cd60ab56 100644 --- a/pmd-plsql/src/main/javacc/PLSQL.jjt +++ b/pmd-plsql/src/main/javacc/PLSQL.jjt @@ -3274,7 +3274,7 @@ ASTLikeExpression LikeExpression() : *

    * There is another TRIM function as a collection method, which can only be called on collection types * (https://docs.oracle.com/en/database/oracle/oracle-database/23/lnpls/collection-methods.html#GUID-6AF582B1-9C50-4858-AE6C-B14DD051ACD1). - * This is parsed as a normal FunctionCall with Arguments. + * The TRIM collection method is parsed instead as a normal FunctionCall with Arguments and not using TrimExpression. */ ASTTrimExpression TrimExpression() : { PLSQLNode simpleNode = null; StringBuilder sb = new StringBuilder() ; } @@ -3283,7 +3283,12 @@ ASTTrimExpression TrimExpression() : [ ( | | ) { sb.append(" "); sb.append(token.getImage()); } ] [ LOOKAHEAD(StringExpression() ) simpleNode = StringExpression() { sb.append(" "); sb.append(simpleNode.getImage()); } ] [ { sb.append(" ").append(token.getImage()); } ] - simpleNode = StringExpression() { sb.append(" "); sb.append(simpleNode.getImage()); } + [ + // first try to parse as StringExpression() to produce a backwards compatible tree + LOOKAHEAD(StringExpression() ")") simpleNode = StringExpression() + // if it is not a simple string expression, you the more generic expression + | simpleNode = Expression() + ] { sb.append(" "); sb.append(simpleNode.getImage()); } ")" { sb.append(')'); } { jjtThis.setImage(sb.toString()); return jjtThis; diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.pls b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.pls index 9c15f7de32d..64073990c2e 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.pls +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.pls @@ -66,4 +66,35 @@ select max(cmp_id) from companies where trim(sap_number) = trim(v_sap_nr); + +-- outputs "3" in sqlplus +select trim(1+2) from dual; + +-- outputs col5="3" in sqlplus +select 'X' || trim(leading 1 from ' test ') || 'X' as col1, + 'X' || trim(leading ' ' from ' test ') || 'X' as col2, + 'X' || trim(both ' ' from ' test ') || 'X' as col3, + 'X' || trim(leading from ' test ') || 'X' as col4, + trim(1+2) as col5 + from dual; + END; + +create or replace package p_utils is + function distinguishXML(x in number, y in number) return varchar; +end; +/ +create or replace package body p_utils is + function distinguishXML(x in number, y in number) return varchar is + begin + return trim(x + y); + end; +end; +/ +SHOW ERRORS +SET SERVEROUTPUT ON +DECLARE + BEGIN + DBMS_OUTPUT.PUT_LINE(p_utils.distinguishXML(1, 2)); + END; +/ diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.txt index 847736e7d17..a6a1a42da03 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.txt +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TrimFunction.txt @@ -1,536 +1,752 @@ +- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- Global[@CanonicalImage = null] + | +- Block[@CanonicalImage = null] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | | +- SelectList[@CanonicalImage = null] + | | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | +- ArgumentList[@CanonicalImage = null] + | | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- TrimExpression[@CanonicalImage = "( LEADING 0 FROM HIRE_DATE)", @Image = "( LEADING 0 FROM hire_date)"] + | | | +- StringExpression[@CanonicalImage = "0", @Image = "0"] + | | | | +- PrimaryPrefix[@CanonicalImage = "0", @Image = "0", @SelfModifier = false] + | | | | +- Literal[@CanonicalImage = "0", @Image = "0"] + | | | | +- NumericLiteral[@CanonicalImage = "0", @Image = "0"] + | | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | | +- ID[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- FromClause[@CanonicalImage = null] + | | | +- TableReference[@CanonicalImage = null] + | | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- WhereClause[@CanonicalImage = null] + | | | +- Condition[@CanonicalImage = null] + | | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] + | | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "60", @Image = "60"] + | | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] + | | +- OrderByClause[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | | +- SelectList[@CanonicalImage = null] + | | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | +- ArgumentList[@CanonicalImage = null] + | | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- TrimExpression[@CanonicalImage = "( TRAILING 0 FROM HIRE_DATE)", @Image = "( TRAILING 0 FROM hire_date)"] + | | | +- StringExpression[@CanonicalImage = "0", @Image = "0"] + | | | | +- PrimaryPrefix[@CanonicalImage = "0", @Image = "0", @SelfModifier = false] + | | | | +- Literal[@CanonicalImage = "0", @Image = "0"] + | | | | +- NumericLiteral[@CanonicalImage = "0", @Image = "0"] + | | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | | +- ID[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- FromClause[@CanonicalImage = null] + | | | +- TableReference[@CanonicalImage = null] + | | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- WhereClause[@CanonicalImage = null] + | | | +- Condition[@CanonicalImage = null] + | | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] + | | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "60", @Image = "60"] + | | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] + | | +- OrderByClause[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | | +- SelectList[@CanonicalImage = null] + | | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | +- ArgumentList[@CanonicalImage = null] + | | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- TrimExpression[@CanonicalImage = "( BOTH 0 FROM HIRE_DATE)", @Image = "( BOTH 0 FROM hire_date)"] + | | | +- StringExpression[@CanonicalImage = "0", @Image = "0"] + | | | | +- PrimaryPrefix[@CanonicalImage = "0", @Image = "0", @SelfModifier = false] + | | | | +- Literal[@CanonicalImage = "0", @Image = "0"] + | | | | +- NumericLiteral[@CanonicalImage = "0", @Image = "0"] + | | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | | +- ID[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- FromClause[@CanonicalImage = null] + | | | +- TableReference[@CanonicalImage = null] + | | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- WhereClause[@CanonicalImage = null] + | | | +- Condition[@CanonicalImage = null] + | | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] + | | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "60", @Image = "60"] + | | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] + | | +- OrderByClause[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | | +- SelectList[@CanonicalImage = null] + | | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | +- ArgumentList[@CanonicalImage = null] + | | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- TrimExpression[@CanonicalImage = "( 0 FROM HIRE_DATE)", @Image = "( 0 FROM hire_date)"] + | | | +- StringExpression[@CanonicalImage = "0", @Image = "0"] + | | | | +- PrimaryPrefix[@CanonicalImage = "0", @Image = "0", @SelfModifier = false] + | | | | +- Literal[@CanonicalImage = "0", @Image = "0"] + | | | | +- NumericLiteral[@CanonicalImage = "0", @Image = "0"] + | | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | | +- ID[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- FromClause[@CanonicalImage = null] + | | | +- TableReference[@CanonicalImage = null] + | | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- WhereClause[@CanonicalImage = null] + | | | +- Condition[@CanonicalImage = null] + | | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] + | | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "60", @Image = "60"] + | | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] + | | +- OrderByClause[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | | +- SelectList[@CanonicalImage = null] + | | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | +- ArgumentList[@CanonicalImage = null] + | | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- TrimExpression[@CanonicalImage = "( LEADING FROM HIRE_DATE)", @Image = "( LEADING FROM hire_date)"] + | | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | | +- ID[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- FromClause[@CanonicalImage = null] + | | | +- TableReference[@CanonicalImage = null] + | | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- WhereClause[@CanonicalImage = null] + | | | +- Condition[@CanonicalImage = null] + | | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] + | | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "60", @Image = "60"] + | | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] + | | +- OrderByClause[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | | +- SelectList[@CanonicalImage = null] + | | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | +- ArgumentList[@CanonicalImage = null] + | | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- TrimExpression[@CanonicalImage = "( HIRE_DATE)", @Image = "( hire_date)"] + | | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | | +- ID[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- FromClause[@CanonicalImage = null] + | | | +- TableReference[@CanonicalImage = null] + | | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- WhereClause[@CanonicalImage = null] + | | | +- Condition[@CanonicalImage = null] + | | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] + | | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "60", @Image = "60"] + | | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] + | | +- OrderByClause[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | | +- SelectList[@CanonicalImage = null] + | | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | +- ArgumentList[@CanonicalImage = null] + | | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- TrimExpression[@CanonicalImage = "( NULL)", @Image = "( NULL)"] + | | | +- StringExpression[@CanonicalImage = "NULL", @Image = "NULL"] + | | | +- PrimaryPrefix[@CanonicalImage = "NULL", @Image = "NULL", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "NULL", @Image = "NULL"] + | | | +- NullLiteral[@CanonicalImage = "NULL", @Image = "NULL"] + | | +- FromClause[@CanonicalImage = null] + | | | +- TableReference[@CanonicalImage = null] + | | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- WhereClause[@CanonicalImage = null] + | | | +- Condition[@CanonicalImage = null] + | | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] + | | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "60", @Image = "60"] + | | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] + | | +- OrderByClause[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | | +- SelectList[@CanonicalImage = null] + | | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] + | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | +- ArgumentList[@CanonicalImage = null] + | | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] + | | | +- TrimExpression[@CanonicalImage = "( NULL FROM HIRE_DATE)", @Image = "( NULL FROM hire_date)"] + | | | +- StringExpression[@CanonicalImage = "NULL", @Image = "NULL"] + | | | | +- PrimaryPrefix[@CanonicalImage = "NULL", @Image = "NULL", @SelfModifier = false] + | | | | +- Literal[@CanonicalImage = "NULL", @Image = "NULL"] + | | | | +- NullLiteral[@CanonicalImage = "NULL", @Image = "NULL"] + | | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | | +- ID[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] + | | +- FromClause[@CanonicalImage = null] + | | | +- TableReference[@CanonicalImage = null] + | | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- WhereClause[@CanonicalImage = null] + | | | +- Condition[@CanonicalImage = null] + | | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] + | | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "60", @Image = "60"] + | | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] + | | +- OrderByClause[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | | +- SelectList[@CanonicalImage = null] + | | | +- SqlExpression[@CanonicalImage = "MAX", @Image = "max"] + | | | +- PrimaryPrefix[@CanonicalImage = "MAX", @Image = "max", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "MAX", @Image = "max"] + | | | +- FunctionName[@CanonicalImage = "MAX", @Image = "max"] + | | | | +- ID[@CanonicalImage = "MAX", @Image = "max"] + | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | +- ArgumentList[@CanonicalImage = null] + | | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "CMP_ID", @Image = "cmp_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | | | +- Column[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | | | +- ID[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | | +- IntoClause[@CanonicalImage = null] + | | | +- VariableName[@CanonicalImage = "V_CMP_ID", @Image = "v_cmp_id"] + | | | +- ID[@CanonicalImage = "V_CMP_ID", @Image = "v_cmp_id"] + | | +- FromClause[@CanonicalImage = null] + | | | +- TableReference[@CanonicalImage = null] + | | | +- TableName[@CanonicalImage = "COMPANIES", @Image = "companies"] + | | | +- ID[@CanonicalImage = "COMPANIES", @Image = "companies"] + | | +- WhereClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "TRIM", @Image = "trim"] + | | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] + | | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] + | | | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] + | | | +- TrimExpression[@CanonicalImage = "( LEADING \'0\' FROM SAP_NUMBER)", @Image = "( LEADING \'0\' FROM sap_number)"] + | | | +- StringExpression[@CanonicalImage = "\'0\'", @Image = "\'0\'"] + | | | | +- PrimaryPrefix[@CanonicalImage = "\'0\'", @Image = "\'0\'", @SelfModifier = false] + | | | | +- Literal[@CanonicalImage = "\'0\'", @Image = "\'0\'"] + | | | +- StringExpression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] + | | | +- PrimaryPrefix[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] + | | | +- Column[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] + | | | +- ID[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] + | | +- SqlExpression[@CanonicalImage = "TRIM", @Image = "trim"] + | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] + | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] + | | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] + | | +- TrimExpression[@CanonicalImage = "( LEADING \'0\' FROM V_SAP_NR)", @Image = "( LEADING \'0\' FROM v_sap_nr)"] + | | +- StringExpression[@CanonicalImage = "\'0\'", @Image = "\'0\'"] + | | | +- PrimaryPrefix[@CanonicalImage = "\'0\'", @Image = "\'0\'", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "\'0\'", @Image = "\'0\'"] + | | +- StringExpression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] + | | +- PrimaryPrefix[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] + | | +- Column[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] + | | +- ID[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | | +- SelectList[@CanonicalImage = null] + | | | +- SqlExpression[@CanonicalImage = "MAX", @Image = "max"] + | | | +- PrimaryPrefix[@CanonicalImage = "MAX", @Image = "max", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "MAX", @Image = "max"] + | | | +- FunctionName[@CanonicalImage = "MAX", @Image = "max"] + | | | | +- ID[@CanonicalImage = "MAX", @Image = "max"] + | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | +- ArgumentList[@CanonicalImage = null] + | | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "CMP_ID", @Image = "cmp_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | | | +- Column[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | | | +- ID[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | | +- IntoClause[@CanonicalImage = null] + | | | +- VariableName[@CanonicalImage = "V_CMP_ID", @Image = "v_cmp_id"] + | | | +- ID[@CanonicalImage = "V_CMP_ID", @Image = "v_cmp_id"] + | | +- FromClause[@CanonicalImage = null] + | | | +- TableReference[@CanonicalImage = null] + | | | +- TableName[@CanonicalImage = "COMPANIES", @Image = "companies"] + | | | +- ID[@CanonicalImage = "COMPANIES", @Image = "companies"] + | | +- WhereClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "TRIM", @Image = "trim"] + | | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] + | | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] + | | | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] + | | | +- TrimExpression[@CanonicalImage = "( SAP_NUMBER)", @Image = "( sap_number)"] + | | | +- StringExpression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] + | | | +- PrimaryPrefix[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] + | | | +- Column[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] + | | | +- ID[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] + | | +- SqlExpression[@CanonicalImage = "TRIM", @Image = "trim"] + | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] + | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] + | | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] + | | +- TrimExpression[@CanonicalImage = "( V_SAP_NR)", @Image = "( v_sap_nr)"] + | | +- StringExpression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] + | | +- PrimaryPrefix[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] + | | +- Column[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] + | | +- ID[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | | +- SelectList[@CanonicalImage = null] + | | | +- SqlExpression[@CanonicalImage = "TRIM", @Image = "trim"] + | | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] + | | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] + | | | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] + | | | +- TrimExpression[@CanonicalImage = "( 1 + 2)", @Image = "( 1 + 2)"] + | | | +- Expression[@CanonicalImage = "1 + 2", @Image = "1 + 2"] + | | | +- AdditiveExpression[@CanonicalImage = "1 + 2", @Image = "1 + 2"] + | | | +- PrimaryPrefix[@CanonicalImage = "1", @Image = "1", @SelfModifier = false] + | | | | +- Literal[@CanonicalImage = "1", @Image = "1"] + | | | | +- NumericLiteral[@CanonicalImage = "1", @Image = "1"] + | | | +- PrimaryPrefix[@CanonicalImage = "2", @Image = "2", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "2", @Image = "2"] + | | | +- NumericLiteral[@CanonicalImage = "2", @Image = "2"] + | | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "DUAL", @Image = "dual"] + | | +- ID[@CanonicalImage = "DUAL", @Image = "dual"] + | +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "\'X\' || TRIM || \'X\'", @Image = "\'X\' || trim || \'X\'"] + | | | +- AdditiveExpression[@CanonicalImage = "\'X\' || TRIM || \'X\'", @Image = "\'X\' || trim || \'X\'"] + | | | +- PrimaryPrefix[@CanonicalImage = "\'X\'", @Image = "\'X\'", @SelfModifier = false] + | | | | +- Literal[@CanonicalImage = "\'X\'", @Image = "\'X\'"] + | | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] + | | | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] + | | | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] + | | | | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] + | | | | +- TrimExpression[@CanonicalImage = "( LEADING 1 FROM \' TEST \')", @Image = "( LEADING 1 FROM \' test \')"] + | | | | +- StringExpression[@CanonicalImage = "1", @Image = "1"] + | | | | | +- PrimaryPrefix[@CanonicalImage = "1", @Image = "1", @SelfModifier = false] + | | | | | +- Literal[@CanonicalImage = "1", @Image = "1"] + | | | | | +- NumericLiteral[@CanonicalImage = "1", @Image = "1"] + | | | | +- StringExpression[@CanonicalImage = "\' TEST \'", @Image = "\' test \'"] + | | | | +- PrimaryPrefix[@CanonicalImage = "\' TEST \'", @Image = "\' test \'", @SelfModifier = false] + | | | | +- Literal[@CanonicalImage = "\' TEST \'", @Image = "\' test \'"] + | | | | +- StringLiteral[@CanonicalImage = "\' TEST \'", @Image = "\' test \'", @String = " test "] + | | | +- PrimaryPrefix[@CanonicalImage = "\'X\'", @Image = "\'X\'", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "\'X\'", @Image = "\'X\'"] + | | +- ColumnAlias[@CanonicalImage = "COL1", @Image = "col1"] + | | | +- ID[@CanonicalImage = "COL1", @Image = "col1"] + | | +- SqlExpression[@CanonicalImage = "\'X\' || TRIM || \'X\'", @Image = "\'X\' || trim || \'X\'"] + | | | +- AdditiveExpression[@CanonicalImage = "\'X\' || TRIM || \'X\'", @Image = "\'X\' || trim || \'X\'"] + | | | +- PrimaryPrefix[@CanonicalImage = "\'X\'", @Image = "\'X\'", @SelfModifier = false] + | | | | +- Literal[@CanonicalImage = "\'X\'", @Image = "\'X\'"] + | | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] + | | | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] + | | | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] + | | | | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] + | | | | +- TrimExpression[@CanonicalImage = "( LEADING \' \' FROM \' TEST \')", @Image = "( LEADING \' \' FROM \' test \')"] + | | | | +- StringExpression[@CanonicalImage = "\' \'", @Image = "\' \'"] + | | | | | +- PrimaryPrefix[@CanonicalImage = "\' \'", @Image = "\' \'", @SelfModifier = false] + | | | | | +- Literal[@CanonicalImage = "\' \'", @Image = "\' \'"] + | | | | +- StringExpression[@CanonicalImage = "\' TEST \'", @Image = "\' test \'"] + | | | | +- PrimaryPrefix[@CanonicalImage = "\' TEST \'", @Image = "\' test \'", @SelfModifier = false] + | | | | +- Literal[@CanonicalImage = "\' TEST \'", @Image = "\' test \'"] + | | | | +- StringLiteral[@CanonicalImage = "\' TEST \'", @Image = "\' test \'", @String = " test "] + | | | +- PrimaryPrefix[@CanonicalImage = "\'X\'", @Image = "\'X\'", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "\'X\'", @Image = "\'X\'"] + | | +- ColumnAlias[@CanonicalImage = "COL2", @Image = "col2"] + | | | +- ID[@CanonicalImage = "COL2", @Image = "col2"] + | | +- SqlExpression[@CanonicalImage = "\'X\' || TRIM || \'X\'", @Image = "\'X\' || trim || \'X\'"] + | | | +- AdditiveExpression[@CanonicalImage = "\'X\' || TRIM || \'X\'", @Image = "\'X\' || trim || \'X\'"] + | | | +- PrimaryPrefix[@CanonicalImage = "\'X\'", @Image = "\'X\'", @SelfModifier = false] + | | | | +- Literal[@CanonicalImage = "\'X\'", @Image = "\'X\'"] + | | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] + | | | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] + | | | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] + | | | | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] + | | | | +- TrimExpression[@CanonicalImage = "( BOTH \' \' FROM \' TEST \')", @Image = "( BOTH \' \' FROM \' test \')"] + | | | | +- StringExpression[@CanonicalImage = "\' \'", @Image = "\' \'"] + | | | | | +- PrimaryPrefix[@CanonicalImage = "\' \'", @Image = "\' \'", @SelfModifier = false] + | | | | | +- Literal[@CanonicalImage = "\' \'", @Image = "\' \'"] + | | | | +- StringExpression[@CanonicalImage = "\' TEST \'", @Image = "\' test \'"] + | | | | +- PrimaryPrefix[@CanonicalImage = "\' TEST \'", @Image = "\' test \'", @SelfModifier = false] + | | | | +- Literal[@CanonicalImage = "\' TEST \'", @Image = "\' test \'"] + | | | | +- StringLiteral[@CanonicalImage = "\' TEST \'", @Image = "\' test \'", @String = " test "] + | | | +- PrimaryPrefix[@CanonicalImage = "\'X\'", @Image = "\'X\'", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "\'X\'", @Image = "\'X\'"] + | | +- ColumnAlias[@CanonicalImage = "COL3", @Image = "col3"] + | | | +- ID[@CanonicalImage = "COL3", @Image = "col3"] + | | +- SqlExpression[@CanonicalImage = "\'X\' || TRIM || \'X\'", @Image = "\'X\' || trim || \'X\'"] + | | | +- AdditiveExpression[@CanonicalImage = "\'X\' || TRIM || \'X\'", @Image = "\'X\' || trim || \'X\'"] + | | | +- PrimaryPrefix[@CanonicalImage = "\'X\'", @Image = "\'X\'", @SelfModifier = false] + | | | | +- Literal[@CanonicalImage = "\'X\'", @Image = "\'X\'"] + | | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] + | | | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] + | | | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] + | | | | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] + | | | | +- TrimExpression[@CanonicalImage = "( LEADING FROM \' TEST \')", @Image = "( LEADING FROM \' test \')"] + | | | | +- StringExpression[@CanonicalImage = "\' TEST \'", @Image = "\' test \'"] + | | | | +- PrimaryPrefix[@CanonicalImage = "\' TEST \'", @Image = "\' test \'", @SelfModifier = false] + | | | | +- Literal[@CanonicalImage = "\' TEST \'", @Image = "\' test \'"] + | | | | +- StringLiteral[@CanonicalImage = "\' TEST \'", @Image = "\' test \'", @String = " test "] + | | | +- PrimaryPrefix[@CanonicalImage = "\'X\'", @Image = "\'X\'", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "\'X\'", @Image = "\'X\'"] + | | +- ColumnAlias[@CanonicalImage = "COL4", @Image = "col4"] + | | | +- ID[@CanonicalImage = "COL4", @Image = "col4"] + | | +- SqlExpression[@CanonicalImage = "TRIM", @Image = "trim"] + | | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] + | | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] + | | | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] + | | | +- TrimExpression[@CanonicalImage = "( 1 + 2)", @Image = "( 1 + 2)"] + | | | +- Expression[@CanonicalImage = "1 + 2", @Image = "1 + 2"] + | | | +- AdditiveExpression[@CanonicalImage = "1 + 2", @Image = "1 + 2"] + | | | +- PrimaryPrefix[@CanonicalImage = "1", @Image = "1", @SelfModifier = false] + | | | | +- Literal[@CanonicalImage = "1", @Image = "1"] + | | | | +- NumericLiteral[@CanonicalImage = "1", @Image = "1"] + | | | +- PrimaryPrefix[@CanonicalImage = "2", @Image = "2", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "2", @Image = "2"] + | | | +- NumericLiteral[@CanonicalImage = "2", @Image = "2"] + | | +- ColumnAlias[@CanonicalImage = "COL5", @Image = "col5"] + | | +- ID[@CanonicalImage = "COL5", @Image = "col5"] + | +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | +- TableName[@CanonicalImage = "DUAL", @Image = "dual"] + | +- ID[@CanonicalImage = "DUAL", @Image = "dual"] + +- PackageSpecification[@CanonicalImage = "P_UTILS", @Image = "p_utils", @ObjectName = "p_utils"] + | +- ObjectNameDeclaration[@CanonicalImage = "P_UTILS", @Image = "p_utils"] + | | +- ID[@CanonicalImage = "P_UTILS", @Image = "p_utils"] + | +- DeclarativeSection[@CanonicalImage = null] + | +- DeclarativeUnit[@CanonicalImage = null] + | +- ProgramUnit[@CanonicalImage = null, @MethodName = "distinguishXML", @Name = "distinguishXML", @ObjectName = null] + | +- MethodDeclarator[@CanonicalImage = "DISTINGUISHXML", @Image = "distinguishXML", @ParameterCount = 1] + | +- ObjectNameDeclaration[@CanonicalImage = "DISTINGUISHXML", @Image = "distinguishXML"] + | | +- ID[@CanonicalImage = "DISTINGUISHXML", @Image = "distinguishXML"] + | +- FormalParameters[@CanonicalImage = "(X,Y)", @Image = "(x,y)"] + | | +- FormalParameter[@CanonicalImage = "X", @Image = "x", @In = true, @NoCopy = false, @Out = false] + | | | +- ID[@CanonicalImage = "X", @Image = "x"] + | | | +- Datatype[@CanonicalImage = "NUMBER", @Image = "NUMBER", @TypeImage = "NUMBER"] + | | | +- ScalarDataTypeName[@CanonicalImage = "NUMBER", @Image = "NUMBER"] + | | +- FormalParameter[@CanonicalImage = "Y", @Image = "y", @In = true, @NoCopy = false, @Out = false] + | | +- ID[@CanonicalImage = "Y", @Image = "y"] + | | +- Datatype[@CanonicalImage = "NUMBER", @Image = "NUMBER", @TypeImage = "NUMBER"] + | | +- ScalarDataTypeName[@CanonicalImage = "NUMBER", @Image = "NUMBER"] + | +- Datatype[@CanonicalImage = "VARCHAR", @Image = "VARCHAR", @TypeImage = "VARCHAR"] + | +- ScalarDataTypeName[@CanonicalImage = "VARCHAR", @Image = "VARCHAR"] + +- PackageBody[@CanonicalImage = "P_UTILS", @Image = "p_utils", @ObjectName = "p_utils"] + | +- ObjectNameDeclaration[@CanonicalImage = "P_UTILS", @Image = "p_utils"] + | | +- ID[@CanonicalImage = "P_UTILS", @Image = "p_utils"] + | +- DeclarativeSection[@CanonicalImage = null] + | +- DeclarativeUnit[@CanonicalImage = null] + | +- ProgramUnit[@CanonicalImage = null, @MethodName = "distinguishXML", @Name = "distinguishXML", @ObjectName = null] + | +- MethodDeclarator[@CanonicalImage = "DISTINGUISHXML", @Image = "distinguishXML", @ParameterCount = 1] + | | +- ObjectNameDeclaration[@CanonicalImage = "DISTINGUISHXML", @Image = "distinguishXML"] + | | | +- ID[@CanonicalImage = "DISTINGUISHXML", @Image = "distinguishXML"] + | | +- FormalParameters[@CanonicalImage = "(X,Y)", @Image = "(x,y)"] + | | | +- FormalParameter[@CanonicalImage = "X", @Image = "x", @In = true, @NoCopy = false, @Out = false] + | | | | +- ID[@CanonicalImage = "X", @Image = "x"] + | | | | +- Datatype[@CanonicalImage = "NUMBER", @Image = "NUMBER", @TypeImage = "NUMBER"] + | | | | +- ScalarDataTypeName[@CanonicalImage = "NUMBER", @Image = "NUMBER"] + | | | +- FormalParameter[@CanonicalImage = "Y", @Image = "y", @In = true, @NoCopy = false, @Out = false] + | | | +- ID[@CanonicalImage = "Y", @Image = "y"] + | | | +- Datatype[@CanonicalImage = "NUMBER", @Image = "NUMBER", @TypeImage = "NUMBER"] + | | | +- ScalarDataTypeName[@CanonicalImage = "NUMBER", @Image = "NUMBER"] + | | +- Datatype[@CanonicalImage = "VARCHAR", @Image = "VARCHAR", @TypeImage = "VARCHAR"] + | | +- ScalarDataTypeName[@CanonicalImage = "VARCHAR", @Image = "VARCHAR"] + | +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- ReturnStatement[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "TRIM", @Image = "trim"] + | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] + | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] + | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] + | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] + | +- TrimExpression[@CanonicalImage = "( X + Y)", @Image = "( x + y)"] + | +- Expression[@CanonicalImage = "X + Y", @Image = "x + y"] + | +- AdditiveExpression[@CanonicalImage = "X + Y", @Image = "x + y"] + | +- PrimaryPrefix[@CanonicalImage = "X", @Image = "x", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "X", @Image = "x"] + | | +- Column[@CanonicalImage = "X", @Image = "x"] + | | +- ID[@CanonicalImage = "X", @Image = "x"] + | +- PrimaryPrefix[@CanonicalImage = "Y", @Image = "y", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "Y", @Image = "y"] + | +- Column[@CanonicalImage = "Y", @Image = "y"] + | +- ID[@CanonicalImage = "Y", @Image = "y"] + +- SqlPlusCommand[@CanonicalImage = "SHOW ERRORS", @Image = "SHOW ERRORS "] + +- SqlPlusCommand[@CanonicalImage = "SET SERVEROUTPUT ON", @Image = "SET SERVEROUTPUT ON "] +- Global[@CanonicalImage = null] +- Block[@CanonicalImage = null] - +- Statement[@CanonicalImage = null] - | +- UnlabelledStatement[@CanonicalImage = null] - | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] - | +- SelectList[@CanonicalImage = null] - | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] - | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] - | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] - | | +- ArgumentList[@CanonicalImage = null] - | | +- Argument[@CanonicalImage = null] - | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] - | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- TrimExpression[@CanonicalImage = "( LEADING 0 FROM HIRE_DATE)", @Image = "( LEADING 0 FROM hire_date)"] - | | +- StringExpression[@CanonicalImage = "0", @Image = "0"] - | | | +- PrimaryPrefix[@CanonicalImage = "0", @Image = "0", @SelfModifier = false] - | | | +- Literal[@CanonicalImage = "0", @Image = "0"] - | | | +- NumericLiteral[@CanonicalImage = "0", @Image = "0"] - | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] - | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | | +- ID[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | +- FromClause[@CanonicalImage = null] - | | +- TableReference[@CanonicalImage = null] - | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] - | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] - | +- WhereClause[@CanonicalImage = null] - | | +- Condition[@CanonicalImage = null] - | | +- CompoundCondition[@CanonicalImage = null, @Type = null] - | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] - | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] - | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] - | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] - | | +- Literal[@CanonicalImage = "60", @Image = "60"] - | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] - | +- OrderByClause[@CanonicalImage = null] - | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] - | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - +- Statement[@CanonicalImage = null] - | +- UnlabelledStatement[@CanonicalImage = null] - | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] - | +- SelectList[@CanonicalImage = null] - | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] - | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] - | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] - | | +- ArgumentList[@CanonicalImage = null] - | | +- Argument[@CanonicalImage = null] - | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] - | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- TrimExpression[@CanonicalImage = "( TRAILING 0 FROM HIRE_DATE)", @Image = "( TRAILING 0 FROM hire_date)"] - | | +- StringExpression[@CanonicalImage = "0", @Image = "0"] - | | | +- PrimaryPrefix[@CanonicalImage = "0", @Image = "0", @SelfModifier = false] - | | | +- Literal[@CanonicalImage = "0", @Image = "0"] - | | | +- NumericLiteral[@CanonicalImage = "0", @Image = "0"] - | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] - | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | | +- ID[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | +- FromClause[@CanonicalImage = null] - | | +- TableReference[@CanonicalImage = null] - | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] - | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] - | +- WhereClause[@CanonicalImage = null] - | | +- Condition[@CanonicalImage = null] - | | +- CompoundCondition[@CanonicalImage = null, @Type = null] - | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] - | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] - | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] - | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] - | | +- Literal[@CanonicalImage = "60", @Image = "60"] - | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] - | +- OrderByClause[@CanonicalImage = null] - | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] - | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - +- Statement[@CanonicalImage = null] - | +- UnlabelledStatement[@CanonicalImage = null] - | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] - | +- SelectList[@CanonicalImage = null] - | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] - | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] - | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] - | | +- ArgumentList[@CanonicalImage = null] - | | +- Argument[@CanonicalImage = null] - | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] - | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- TrimExpression[@CanonicalImage = "( BOTH 0 FROM HIRE_DATE)", @Image = "( BOTH 0 FROM hire_date)"] - | | +- StringExpression[@CanonicalImage = "0", @Image = "0"] - | | | +- PrimaryPrefix[@CanonicalImage = "0", @Image = "0", @SelfModifier = false] - | | | +- Literal[@CanonicalImage = "0", @Image = "0"] - | | | +- NumericLiteral[@CanonicalImage = "0", @Image = "0"] - | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] - | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | | +- ID[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | +- FromClause[@CanonicalImage = null] - | | +- TableReference[@CanonicalImage = null] - | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] - | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] - | +- WhereClause[@CanonicalImage = null] - | | +- Condition[@CanonicalImage = null] - | | +- CompoundCondition[@CanonicalImage = null, @Type = null] - | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] - | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] - | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] - | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] - | | +- Literal[@CanonicalImage = "60", @Image = "60"] - | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] - | +- OrderByClause[@CanonicalImage = null] - | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] - | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - +- Statement[@CanonicalImage = null] - | +- UnlabelledStatement[@CanonicalImage = null] - | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] - | +- SelectList[@CanonicalImage = null] - | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] - | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] - | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] - | | +- ArgumentList[@CanonicalImage = null] - | | +- Argument[@CanonicalImage = null] - | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] - | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- TrimExpression[@CanonicalImage = "( 0 FROM HIRE_DATE)", @Image = "( 0 FROM hire_date)"] - | | +- StringExpression[@CanonicalImage = "0", @Image = "0"] - | | | +- PrimaryPrefix[@CanonicalImage = "0", @Image = "0", @SelfModifier = false] - | | | +- Literal[@CanonicalImage = "0", @Image = "0"] - | | | +- NumericLiteral[@CanonicalImage = "0", @Image = "0"] - | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] - | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | | +- ID[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | +- FromClause[@CanonicalImage = null] - | | +- TableReference[@CanonicalImage = null] - | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] - | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] - | +- WhereClause[@CanonicalImage = null] - | | +- Condition[@CanonicalImage = null] - | | +- CompoundCondition[@CanonicalImage = null, @Type = null] - | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] - | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] - | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] - | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] - | | +- Literal[@CanonicalImage = "60", @Image = "60"] - | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] - | +- OrderByClause[@CanonicalImage = null] - | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] - | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - +- Statement[@CanonicalImage = null] - | +- UnlabelledStatement[@CanonicalImage = null] - | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] - | +- SelectList[@CanonicalImage = null] - | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] - | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] - | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] - | | +- ArgumentList[@CanonicalImage = null] - | | +- Argument[@CanonicalImage = null] - | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] - | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- TrimExpression[@CanonicalImage = "( LEADING FROM HIRE_DATE)", @Image = "( LEADING FROM hire_date)"] - | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] - | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | | +- ID[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | +- FromClause[@CanonicalImage = null] - | | +- TableReference[@CanonicalImage = null] - | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] - | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] - | +- WhereClause[@CanonicalImage = null] - | | +- Condition[@CanonicalImage = null] - | | +- CompoundCondition[@CanonicalImage = null, @Type = null] - | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] - | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] - | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] - | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] - | | +- Literal[@CanonicalImage = "60", @Image = "60"] - | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] - | +- OrderByClause[@CanonicalImage = null] - | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] - | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - +- Statement[@CanonicalImage = null] - | +- UnlabelledStatement[@CanonicalImage = null] - | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] - | +- SelectList[@CanonicalImage = null] - | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] - | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] - | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] - | | +- ArgumentList[@CanonicalImage = null] - | | +- Argument[@CanonicalImage = null] - | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] - | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- TrimExpression[@CanonicalImage = "( HIRE_DATE)", @Image = "( hire_date)"] - | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] - | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | | +- ID[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | +- FromClause[@CanonicalImage = null] - | | +- TableReference[@CanonicalImage = null] - | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] - | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] - | +- WhereClause[@CanonicalImage = null] - | | +- Condition[@CanonicalImage = null] - | | +- CompoundCondition[@CanonicalImage = null, @Type = null] - | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] - | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] - | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] - | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] - | | +- Literal[@CanonicalImage = "60", @Image = "60"] - | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] - | +- OrderByClause[@CanonicalImage = null] - | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] - | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - +- Statement[@CanonicalImage = null] - | +- UnlabelledStatement[@CanonicalImage = null] - | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] - | +- SelectList[@CanonicalImage = null] - | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] - | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] - | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] - | | +- ArgumentList[@CanonicalImage = null] - | | +- Argument[@CanonicalImage = null] - | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] - | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- TrimExpression[@CanonicalImage = "( NULL)", @Image = "( NULL)"] - | | +- StringExpression[@CanonicalImage = "NULL", @Image = "NULL"] - | | +- PrimaryPrefix[@CanonicalImage = "NULL", @Image = "NULL", @SelfModifier = false] - | | +- Literal[@CanonicalImage = "NULL", @Image = "NULL"] - | | +- NullLiteral[@CanonicalImage = "NULL", @Image = "NULL"] - | +- FromClause[@CanonicalImage = null] - | | +- TableReference[@CanonicalImage = null] - | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] - | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] - | +- WhereClause[@CanonicalImage = null] - | | +- Condition[@CanonicalImage = null] - | | +- CompoundCondition[@CanonicalImage = null, @Type = null] - | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] - | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] - | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] - | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] - | | +- Literal[@CanonicalImage = "60", @Image = "60"] - | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] - | +- OrderByClause[@CanonicalImage = null] - | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] - | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - +- Statement[@CanonicalImage = null] - | +- UnlabelledStatement[@CanonicalImage = null] - | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] - | +- SelectList[@CanonicalImage = null] - | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] - | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | | +- SqlExpression[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- PrimaryPrefix[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR", @SelfModifier = false] - | | +- FunctionCall[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- FunctionName[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | | +- ID[@CanonicalImage = "TO_CHAR", @Image = "TO_CHAR"] - | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] - | | +- ArgumentList[@CanonicalImage = null] - | | +- Argument[@CanonicalImage = null] - | | +- Expression[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "TRIM", @SelfModifier = false] - | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | | +- ID[@CanonicalImage = "TRIM", @Image = "TRIM"] - | | +- TrimExpression[@CanonicalImage = "( NULL FROM HIRE_DATE)", @Image = "( NULL FROM hire_date)"] - | | +- StringExpression[@CanonicalImage = "NULL", @Image = "NULL"] - | | | +- PrimaryPrefix[@CanonicalImage = "NULL", @Image = "NULL", @SelfModifier = false] - | | | +- Literal[@CanonicalImage = "NULL", @Image = "NULL"] - | | | +- NullLiteral[@CanonicalImage = "NULL", @Image = "NULL"] - | | +- StringExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | | +- PrimaryPrefix[@CanonicalImage = "HIRE_DATE", @Image = "hire_date", @SelfModifier = false] - | | +- SimpleExpression[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | | +- Column[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | | +- ID[@CanonicalImage = "HIRE_DATE", @Image = "hire_date"] - | +- FromClause[@CanonicalImage = null] - | | +- TableReference[@CanonicalImage = null] - | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] - | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] - | +- WhereClause[@CanonicalImage = null] - | | +- Condition[@CanonicalImage = null] - | | +- CompoundCondition[@CanonicalImage = null, @Type = null] - | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] - | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] - | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] - | | +- SqlExpression[@CanonicalImage = "60", @Image = "60"] - | | +- PrimaryPrefix[@CanonicalImage = "60", @Image = "60", @SelfModifier = false] - | | +- Literal[@CanonicalImage = "60", @Image = "60"] - | | +- NumericLiteral[@CanonicalImage = "60", @Image = "60"] - | +- OrderByClause[@CanonicalImage = null] - | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] - | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] - +- Statement[@CanonicalImage = null] - | +- UnlabelledStatement[@CanonicalImage = null] - | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] - | +- SelectList[@CanonicalImage = null] - | | +- SqlExpression[@CanonicalImage = "MAX", @Image = "max"] - | | +- PrimaryPrefix[@CanonicalImage = "MAX", @Image = "max", @SelfModifier = false] - | | +- FunctionCall[@CanonicalImage = "MAX", @Image = "max"] - | | +- FunctionName[@CanonicalImage = "MAX", @Image = "max"] - | | | +- ID[@CanonicalImage = "MAX", @Image = "max"] - | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] - | | +- ArgumentList[@CanonicalImage = null] - | | +- Argument[@CanonicalImage = null] - | | +- Expression[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] - | | +- PrimaryPrefix[@CanonicalImage = "CMP_ID", @Image = "cmp_id", @SelfModifier = false] - | | +- SimpleExpression[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] - | | +- Column[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] - | | +- ID[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] - | +- IntoClause[@CanonicalImage = null] - | | +- VariableName[@CanonicalImage = "V_CMP_ID", @Image = "v_cmp_id"] - | | +- ID[@CanonicalImage = "V_CMP_ID", @Image = "v_cmp_id"] - | +- FromClause[@CanonicalImage = null] - | | +- TableReference[@CanonicalImage = null] - | | +- TableName[@CanonicalImage = "COMPANIES", @Image = "companies"] - | | +- ID[@CanonicalImage = "COMPANIES", @Image = "companies"] - | +- WhereClause[@CanonicalImage = null] - | +- Condition[@CanonicalImage = null] - | +- CompoundCondition[@CanonicalImage = null, @Type = null] - | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] - | +- SqlExpression[@CanonicalImage = "TRIM", @Image = "trim"] - | | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] - | | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] - | | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] - | | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] - | | +- TrimExpression[@CanonicalImage = "( LEADING \'0\' FROM SAP_NUMBER)", @Image = "( LEADING \'0\' FROM sap_number)"] - | | +- StringExpression[@CanonicalImage = "\'0\'", @Image = "\'0\'"] - | | | +- PrimaryPrefix[@CanonicalImage = "\'0\'", @Image = "\'0\'", @SelfModifier = false] - | | | +- Literal[@CanonicalImage = "\'0\'", @Image = "\'0\'"] - | | +- StringExpression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] - | | +- PrimaryPrefix[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number", @SelfModifier = false] - | | +- SimpleExpression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] - | | +- Column[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] - | | +- ID[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] - | +- SqlExpression[@CanonicalImage = "TRIM", @Image = "trim"] - | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] - | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] - | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] - | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] - | +- TrimExpression[@CanonicalImage = "( LEADING \'0\' FROM V_SAP_NR)", @Image = "( LEADING \'0\' FROM v_sap_nr)"] - | +- StringExpression[@CanonicalImage = "\'0\'", @Image = "\'0\'"] - | | +- PrimaryPrefix[@CanonicalImage = "\'0\'", @Image = "\'0\'", @SelfModifier = false] - | | +- Literal[@CanonicalImage = "\'0\'", @Image = "\'0\'"] - | +- StringExpression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] - | +- PrimaryPrefix[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr", @SelfModifier = false] - | +- SimpleExpression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] - | +- Column[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] - | +- ID[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] +- Statement[@CanonicalImage = null] +- UnlabelledStatement[@CanonicalImage = null] - +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] - +- SelectList[@CanonicalImage = null] - | +- SqlExpression[@CanonicalImage = "MAX", @Image = "max"] - | +- PrimaryPrefix[@CanonicalImage = "MAX", @Image = "max", @SelfModifier = false] - | +- FunctionCall[@CanonicalImage = "MAX", @Image = "max"] - | +- FunctionName[@CanonicalImage = "MAX", @Image = "max"] - | | +- ID[@CanonicalImage = "MAX", @Image = "max"] - | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] - | +- ArgumentList[@CanonicalImage = null] - | +- Argument[@CanonicalImage = null] - | +- Expression[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] - | +- PrimaryPrefix[@CanonicalImage = "CMP_ID", @Image = "cmp_id", @SelfModifier = false] - | +- SimpleExpression[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] - | +- Column[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] - | +- ID[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] - +- IntoClause[@CanonicalImage = null] - | +- VariableName[@CanonicalImage = "V_CMP_ID", @Image = "v_cmp_id"] - | +- ID[@CanonicalImage = "V_CMP_ID", @Image = "v_cmp_id"] - +- FromClause[@CanonicalImage = null] - | +- TableReference[@CanonicalImage = null] - | +- TableName[@CanonicalImage = "COMPANIES", @Image = "companies"] - | +- ID[@CanonicalImage = "COMPANIES", @Image = "companies"] - +- WhereClause[@CanonicalImage = null] - +- Condition[@CanonicalImage = null] - +- CompoundCondition[@CanonicalImage = null, @Type = null] - +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] - +- SqlExpression[@CanonicalImage = "TRIM", @Image = "trim"] - | +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] - | +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] - | +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] - | | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] - | +- TrimExpression[@CanonicalImage = "( SAP_NUMBER)", @Image = "( sap_number)"] - | +- StringExpression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] - | +- PrimaryPrefix[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number", @SelfModifier = false] - | +- SimpleExpression[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] - | +- Column[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] - | +- ID[@CanonicalImage = "SAP_NUMBER", @Image = "sap_number"] - +- SqlExpression[@CanonicalImage = "TRIM", @Image = "trim"] - +- PrimaryPrefix[@CanonicalImage = "TRIM", @Image = "trim", @SelfModifier = false] - +- FunctionCall[@CanonicalImage = "TRIM", @Image = "trim"] - +- FunctionName[@CanonicalImage = "TRIM", @Image = "trim"] - | +- ID[@CanonicalImage = "TRIM", @Image = "trim"] - +- TrimExpression[@CanonicalImage = "( V_SAP_NR)", @Image = "( v_sap_nr)"] - +- StringExpression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] - +- PrimaryPrefix[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr", @SelfModifier = false] - +- SimpleExpression[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] - +- Column[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] - +- ID[@CanonicalImage = "V_SAP_NR", @Image = "v_sap_nr"] + +- Expression[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE"] + +- PrimaryPrefix[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE", @SelfModifier = false] + +- FunctionCall[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE"] + +- FunctionName[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE"] + | +- ID[@CanonicalImage = "DBMS_OUTPUT", @Image = "DBMS_OUTPUT"] + | +- ID[@CanonicalImage = "PUT_LINE", @Image = "PUT_LINE"] + +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + +- ArgumentList[@CanonicalImage = null] + +- Argument[@CanonicalImage = null] + +- Expression[@CanonicalImage = "P_UTILS.DISTINGUISHXML", @Image = "p_utils.distinguishXML"] + +- PrimaryPrefix[@CanonicalImage = "P_UTILS.DISTINGUISHXML", @Image = "p_utils.distinguishXML", @SelfModifier = false] + +- FunctionCall[@CanonicalImage = "P_UTILS.DISTINGUISHXML", @Image = "p_utils.distinguishXML"] + +- FunctionName[@CanonicalImage = "P_UTILS.DISTINGUISHXML", @Image = "p_utils.distinguishXML"] + | +- ID[@CanonicalImage = "P_UTILS", @Image = "p_utils"] + | +- ID[@CanonicalImage = "DISTINGUISHXML", @Image = "distinguishXML"] + +- Arguments[@ArgumentCount = 2, @CanonicalImage = null] + +- ArgumentList[@CanonicalImage = null] + +- Argument[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "1", @Image = "1"] + | +- PrimaryPrefix[@CanonicalImage = "1", @Image = "1", @SelfModifier = false] + | +- Literal[@CanonicalImage = "1", @Image = "1"] + | +- NumericLiteral[@CanonicalImage = "1", @Image = "1"] + +- Argument[@CanonicalImage = null] + +- Expression[@CanonicalImage = "2", @Image = "2"] + +- PrimaryPrefix[@CanonicalImage = "2", @Image = "2", @SelfModifier = false] + +- Literal[@CanonicalImage = "2", @Image = "2"] + +- NumericLiteral[@CanonicalImage = "2", @Image = "2"] From d0dd54332971c723a5c17b331e24172decc40652 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 24 Feb 2025 20:21:12 +0100 Subject: [PATCH 0551/1962] [doc] Update release notes (#5522) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index fae65e01d9c..cd701a77cbf 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -22,6 +22,8 @@ This is a {{ site.pmd.release_type }} release. * [#5504](https://github.com/pmd/pmd/issues/5504): \[java] UnusedAssignment false-positive in for-loop with continue * java-codestyle * [#5523](https://github.com/pmd/pmd/issues/5523): \[java] UnnecessaryCast false-positive for integer operations in floating-point context +* plsql + * [#5522](https://github.com/pmd/pmd/issues/5522): \[plsql] Parse error for operator in TRIM function call ### ๐Ÿšจ API Changes From cc224172849f395c4252151413626926cc590111 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 25 Feb 2025 22:38:59 +0100 Subject: [PATCH 0552/1962] Fix japicmp config --- pom.xml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 264e92609b3..ec32f97e0b9 100644 --- a/pom.xml +++ b/pom.xml @@ -674,14 +674,6 @@ - - - - - METHOD_NEW_DEFAULT - true - true - * [#5503](https://github.com/pmd/pmd/pull/5503): \[java] AvoidSynchronizedAtMethodLevel: Fixed error in code example - [Balazs Glatz](https://github.com/gbq6) (@gbq6) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java index 58e2344cdaa..013e2152d17 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java @@ -2167,6 +2167,8 @@ public static boolean isUnresolvedOrNull(@Nullable JTypeMirror t) { * means its return type is influenced by the surrounding * context during type inference. Generic constructors * are always context dependent. + * + * @deprecated Since 7.11.0. Use {@link #isContextDependent(JExecutableSymbol)} instead which is more flexible. */ @Deprecated public static boolean isContextDependent(JMethodSig sig) { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml index f2ce52d6019..593aed9d6d9 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml @@ -926,7 +926,7 @@ class Tester { - Cast in return position of lambda + Cast in return position of lambda (#5073) 0 - Cast in return position of lambda, types are unresolved + Cast in return position of lambda, types are unresolved (#5073) 0 - Cast in return position of lambda, declare types here + Cast in return position of lambda, declare types here (#5073) 0 { R apply(P p); } From c639f081393cc7205e21e5c745d1e5a4ac6ebf5a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Feb 2025 09:22:31 +0100 Subject: [PATCH 0555/1962] [apex] Apply fixes from review (#5425) --- .../AvoidStatefulDatabaseResultRule.java | 25 ++- .../resources/category/apex/errorprone.xml | 177 +++++++++--------- .../xml/AvoidStatefulDatabaseResult.xml | 31 ++- 3 files changed, 136 insertions(+), 97 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidStatefulDatabaseResultRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidStatefulDatabaseResultRule.java index 05b5a3be364..64a083b16b1 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidStatefulDatabaseResultRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidStatefulDatabaseResultRule.java @@ -7,20 +7,24 @@ import java.util.Locale; import java.util.Set; +import org.checkerframework.checker.nullness.qual.NonNull; + import net.sourceforge.pmd.lang.apex.ast.ASTField; import net.sourceforge.pmd.lang.apex.ast.ASTUserClass; import net.sourceforge.pmd.lang.apex.rule.AbstractApexRule; +import net.sourceforge.pmd.lang.rule.RuleTargetSelector; import net.sourceforge.pmd.util.CollectionUtil; /** - * Using stateful `Database.[x]Result` instance variables can cause odd + * Using stateful {@code Database.[x]Result} instance variables can cause odd * serialization errors between successive batch iterations. * - * https://issues.salesforce.com/issue/a028c00000qPwlqAAC/stateful-batch-job-that-stores-databasesaveresult-failed-after-validation-errors-throws-error-during-deserialization + *

    This rule scans classes which implement the {@code Database.Stateful} interface. If + * there are instance variables of type {@code Database.[x]Result} (ex: + * {@code Database.SaveResult}), then a violation will be added to those variables. * - * This rule scans classes which implement the `Database.Stateful` interface. If - * there are instance variables of type `Database.[x]Result` (ex: - * `Database.SaveResult`), then a violation will be added to those variables. + * @see Stateful batch job that stores Database.SaveResult (failed after validation errors) throws error during deserialization + * @since 7.11.0 */ public final class AvoidStatefulDatabaseResultRule extends AbstractApexRule { @@ -28,6 +32,11 @@ public final class AvoidStatefulDatabaseResultRule extends AbstractApexRule { "database.deleteresult", "database.emptyrecyclebinresult", "database.mergeresult", "database.saveresult", "database.undeleteresult", "database.upsertresult"); + @Override + protected @NonNull RuleTargetSelector buildTargetSelector() { + return RuleTargetSelector.forTypes(ASTUserClass.class); + } + @Override public Object visit(ASTUserClass theClass, Object data) { if (!implementsDatabaseStateful(theClass)) { @@ -43,7 +52,7 @@ public Object visit(ASTUserClass theClass, Object data) { return data; } - /** Determines if the class implements the `Database.Stateful` interface */ + /** Determines if the class implements the {@code Database.Stateful} interface. */ private boolean implementsDatabaseStateful(ASTUserClass theClass) { for (String interfaceName : theClass.getInterfaceNames()) { if ("database.stateful".equalsIgnoreCase(interfaceName)) { @@ -56,7 +65,7 @@ private boolean implementsDatabaseStateful(ASTUserClass theClass) { /** * Determines if a variable's definition may cause issues within batch * iteration by being: an instance variable, not transient, and a data type - * of `Database.[x]Result` (or collection of them). + * of {@code Database.[x]Result} (or collection of them). */ private boolean isNonTransientInstanceDatabaseResultField(ASTField theField) { return !theField.getModifiers().isStatic() && !theField.getModifiers().isTransient() @@ -66,7 +75,7 @@ private boolean isNonTransientInstanceDatabaseResultField(ASTField theField) { /** * Determines if any of the unsupported types contains the type. We check * containment even as a substring to check if the type is a collection of - * the result types ex: `List`. + * the result types ex: {@code List}. */ private boolean isDatabaseResultOrCollection(String type) { for (String databaseResultType : DATABASE_RESULT_TYPES) { diff --git a/pmd-apex/src/main/resources/category/apex/errorprone.xml b/pmd-apex/src/main/resources/category/apex/errorprone.xml index 21dcb8c08bb..e138241d759 100644 --- a/pmd-apex/src/main/resources/category/apex/errorprone.xml +++ b/pmd-apex/src/main/resources/category/apex/errorprone.xml @@ -133,7 +133,95 @@ public without sharing class Foo { ]]> - + + + + Using instance variables of the following types (or collections of these types) within a stateful batch class can cause serialization errors between batch iterations: + + - `Database.DeleteResult` + - `Database.EmptyRecycleBinResult` + - `Database.MergeResult` + - `Database.SaveResult` + - `Database.UndeleteResult` + - `Database.UpsertResult` + + This error occurs inconsistently and asynchronously with an obscure error message - making it particularly challenging to troubleshoot. + See [this issue](https://issues.salesforce.com/issue/a028c00000qPwlqAAC/stateful-batch-job-that-stores-databasesaveresult-failed-after-validation-errors-throws-error-during-deserialization) for more details. + + These errors can be avoided by marking the variable as static, transient, or using a different + data type that is safe to serialize. + + 2 + + , Database.Stateful { + List results = new List(); // This can cause failures + + public Database.Querylocator start(Database.BatchableContext context) { + return Database.getQueryLocator('SELECT Id FROM Account'); + } + + public void execute(Database.BatchableContext context, List scope) { + Database.SaveResult[] saveResults = Database.update(scope, false); + results.addAll(saveResults); + } + + public void finish(database.BatchableContext context) { + } +} + +// Compliant +public class Example implements Database.Batchable, Database.Stateful { + List results = new List(); // Use a different custom type to persist state + + public Database.Querylocator start(Database.BatchableContext context) { + return Database.getQueryLocator('SELECT Id FROM Account'); + } + + public void execute(Database.BatchableContext context, List scope) { + Database.SaveResult[] saveResults = Database.update(scope, false); + for (Database.SaveResult result : saveResults) { + results.add(new StatefulResult(result)); + } + } + + public void finish(database.BatchableContext context) { + } + +} + +public class StatefulResult { + private Boolean isSuccess; + private Id id; + private Database.Error[] errors; + + public StatefulResult(Database.SaveResult result) { + isSuccess = result.isSuccess(); + id = result.getId(); + errors = result.getErrors(); + } + + public Boolean isSuccess() { + return isSuccess; + } + + public Id getId() { + return id; + } + + public Database.Error[] getErrors() { + return errors; + } +} +]]> + + + - - - - - Using instance variables of the following types (or collections of these types) within a stateful batch class can cause serialization errors between batch iterations: - - - `Database.DeleteResult` - - `Database.EmptyRecycleBinResult` - - `Database.MergeResult` - - `Database.SaveResult` - - `Database.UndeleteResult` - - `Database.UpsertResult` - - This error occurs inconsistently and asynchronously with an obscure error message - making it particularly challenging to troubleshoot. - See [this issue](https://issues.salesforce.com/issue/a028c00000qPwlqAAC/stateful-batch-job-that-stores-databasesaveresult-failed-after-validation-errors-throws-error-during-deserialization) for more details. - - These errors can be avoided by marking the variable as static, transient, or using a different - data type that is safe to serialize. - - 2 - - , Database.Stateful { - List results = new List(); // This can cause failures - - public Database.Querylocator start(Database.BatchableContext context) { - return Database.getQueryLocator('SELECT Id FROM Account'); - } - - public void execute(Database.BatchableContext context, List scope) { - Database.SaveResult[] saveResults = Database.update(scope, false); - results.addAll(saveResults); - } - - public void finish(database.BatchableContext context) { - } -} - -// Compliant -public class Example implements Database.Batchable, Database.Stateful { - List results = new List(); // Use a different custom type to persist state - - public Database.Querylocator start(Database.BatchableContext context) { - return Database.getQueryLocator('SELECT Id FROM Account'); - } - - public void execute(Database.BatchableContext context, List scope) { - Database.SaveResult[] saveResults = Database.update(scope, false); - for (Database.SaveResult result : saveResults) { - results.add(new StatefulResult(result)); - } - } - - public void finish(database.BatchableContext context) { - } - -} - -public class StatefulResult { - private Boolean isSuccess; - private Id id; - private Database.Error[] errors; - - public StatefulResult(Database.SaveResult result) { - isSuccess = result.isSuccess(); - id = result.getId(); - errors = result.getErrors(); - } - - public Boolean isSuccess() { - return isSuccess; - } - - public Id getId() { - return id; - } - - public Database.Error[] getErrors() { - return errors; - } -} ]]> diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/AvoidStatefulDatabaseResult.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/AvoidStatefulDatabaseResult.xml index 81e352d268c..dd12c9fd3f1 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/AvoidStatefulDatabaseResult.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/AvoidStatefulDatabaseResult.xml @@ -7,6 +7,7 @@ Result instances in stateful class 7 + 2,3,4,5,6,7,8 , Database.Stateful { private Database.DeleteResult deleteResult; @@ -33,6 +34,7 @@ public class Example implements Database.Batchable, Database.Stateful { Result lists in stateful class 7 + 2,3,4,5,6,7,8 , Database.Stateful { private List deleteResults = new List(); @@ -59,6 +61,7 @@ public class Example implements Database.Batchable, Database.Stateful { Result sets in stateful class 7 + 2,3,4,5,6,7,8 , Database.Stateful { private Set deleteResults = new Set(); @@ -85,6 +88,7 @@ public class Example implements Database.Batchable, Database.Stateful { Result maps in stateful class 7 + 2,3,4,5,6,7,8 , Database.Stateful { private Map deleteResults = new Map(); @@ -107,7 +111,32 @@ public class Example implements Database.Batchable, Database.Stateful { } ]]> - + + + Compliant example + 0 + , Database.Stateful { + List results = new List(); // Use a different custom type to persist state + + public Database.Querylocator start(Database.BatchableContext context) { + return Database.getQueryLocator('SELECT Id FROM Account'); + } + + public void execute(Database.BatchableContext context, List scope) { + Database.SaveResult[] saveResults = Database.update(scope, false); + for (Database.SaveResult result : saveResults) { + results.add(new StatefulResult(result)); + } + } + + public void finish(database.BatchableContext context) { + } + +} + ]]> + + Transient result in stateful class 0 From 32bdbdb7ac46434ee3564898bc0269e64ed5434f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Feb 2025 09:27:57 +0100 Subject: [PATCH 0556/1962] [doc] Update release notes (#5425, #5305) --- docs/pages/release_notes.md | 9 +++++++++ pmd-apex/src/main/resources/rulesets/apex/quickstart.xml | 1 + 2 files changed, 10 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 26ec825d013..9bbfa3be240 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -14,12 +14,21 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy +#### โœจ New Rules + +* The new Apex rule {% rule apex/errorprone/AvoidStatefulDatabaseResult %} detects `Database.Stateful` implementations + that store database results in instance variables. This can cause serialization issues between successive batch + iterations. + ### ๐Ÿ› Fixed Issues +* apex-errorprone + * [#5305](https://github.com/pmd/pmd/issues/5305): \[apex] New Rule: Avoid Stateful Database Results ### ๐Ÿšจ API Changes ### โœจ Merged pull requests +* [#5425](https://github.com/pmd/pmd/pull/5425): \[apex] New Rule: Avoid Stateful Database Results - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) ### ๐Ÿ“ฆ Dependency updates diff --git a/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml b/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml index 53c63c7546f..c10db559eb7 100644 --- a/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml +++ b/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml @@ -212,5 +212,6 @@ + From 2de2c8c0b5f49de3fc451d1b238e3b2332805950 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Feb 2025 10:03:49 +0100 Subject: [PATCH 0557/1962] Bump commons-logging:commons-logging from 1.3.4 to 1.3.5 (#5545) Bumps commons-logging:commons-logging from 1.3.4 to 1.3.5. --- updated-dependencies: - dependency-name: commons-logging:commons-logging dependency-type: direct:development update-type: version-update:semver-patch ... [skip ci] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-java/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 5128ffd6a15..3b3b8debde3 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -286,7 +286,7 @@ commons-logging commons-logging - 1.3.4 + 1.3.5 test From 4c7a21c3ffd82cc57133f1314d00e8d6aa22955b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Feb 2025 10:04:25 +0100 Subject: [PATCH 0558/1962] Bump scalameta.version from 4.13.1.1 to 4.13.2 (#5546) Bumps `scalameta.version` from 4.13.1.1 to 4.13.2. Updates `org.scalameta:parsers_2.13` from 4.13.1.1 to 4.13.2 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.1.1...v4.13.2) Updates `org.scalameta:trees_2.13` from 4.13.1.1 to 4.13.2 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.1.1...v4.13.2) Updates `org.scalameta:parsers_2.12` from 4.13.1.1 to 4.13.2 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.1.1...v4.13.2) Updates `org.scalameta:trees_2.12` from 4.13.1.1 to 4.13.2 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.1.1...v4.13.2) --- updated-dependencies: - dependency-name: org.scalameta:parsers_2.13 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:trees_2.13 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:parsers_2.12 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:trees_2.12 dependency-type: direct:production update-type: version-update:semver-patch ... [skip ci] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index 4488103073c..c25ec6d41a7 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -13,7 +13,7 @@ - 4.13.1.1 + 4.13.2 From 437fa931d22d4ec2189fc1fb86d31b4c1f694dc7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Feb 2025 10:04:59 +0100 Subject: [PATCH 0559/1962] Bump net.bytebuddy:byte-buddy from 1.17.0 to 1.17.1 (#5547) Bumps [net.bytebuddy:byte-buddy](https://github.com/raphw/byte-buddy) from 1.17.0 to 1.17.1. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.17.0...byte-buddy-1.17.1) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-type: direct:development update-type: version-update:semver-patch ... [skip ci] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ec32f97e0b9..7334e968b1d 100644 --- a/pom.xml +++ b/pom.xml @@ -1012,7 +1012,7 @@ net.bytebuddy byte-buddy - 1.17.0 + 1.17.1 test From fc1f1407e612d548f3437e9e140d48b5471ab963 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Feb 2025 10:05:29 +0100 Subject: [PATCH 0560/1962] Bump com.puppycrawl.tools:checkstyle from 10.21.2 to 10.21.3 (#5548) Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.21.2 to 10.21.3. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.21.2...checkstyle-10.21.3) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... [skip ci] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7334e968b1d..95834bdde2c 100644 --- a/pom.xml +++ b/pom.xml @@ -99,7 +99,7 @@ 5.0 3.5.2 - 10.21.2 + 10.21.3 3.6.0 3.26.0 1.10.15 From b953f8f20a24fcf7544efbd3f7446585f5fd641e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Feb 2025 10:17:11 +0100 Subject: [PATCH 0561/1962] Bump org.apache.maven.plugins:maven-compiler-plugin from 3.13.0 to 3.14.0 (#5549) Bump org.apache.maven.plugins:maven-compiler-plugin Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.13.0 to 3.14.0. - [Release notes](https://github.com/apache/maven-compiler-plugin/releases) - [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.13.0...maven-compiler-plugin-3.14.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-compiler-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 95834bdde2c..5adb9b8c288 100644 --- a/pom.xml +++ b/pom.xml @@ -277,7 +277,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.13.0 + 3.14.0 ${java.version} From a8c779c19e8f8c72aee09f6a9b34d5c919255c32 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Feb 2025 11:22:55 +0100 Subject: [PATCH 0562/1962] [plsql] Convert more tests into treedump tests --- .../lang/plsql/AbstractPLSQLParserTst.java | 18 +- .../plsql/ast/AllPlsqlAstTreeDumpTest.java | 7 +- .../ast/ExecuteImmediateBulkCollectTest.java | 16 +- .../lang/plsql/ast/ParenthesisGroupTest.java | 16 +- .../pmd/lang/plsql/ast/PlsqlTreeDumpTest.java | 16 +- .../lang/plsql/ast/SelectExpressionsTest.java | 20 +- .../lang/plsql/ast/SelectForUpdateTest.java | 17 +- .../plsql/ast/SelectHierarchicalTest.java | 2 +- .../plsql/ast/SelectIntoStatementTest.java | 18 +- .../plsql/ast/SelectIntoWithGroupByTest.java | 26 +- .../pmd/lang/plsql/ast/SelectCount.txt | 175 ++++ .../pmd/lang/plsql/ast/SelectForUpdate.txt | 168 ++++ .../lang/plsql/ast/SelectForUpdateWait.txt | 227 +++++ .../pmd/lang/plsql/ast/SelectHierarchical.txt | 874 ++++++++++++++++++ .../lang/plsql/ast/SelectIntoStatement.txt | 777 ++++++++++++++++ .../plsql/ast/SelectIntoStatementExample1.txt | 49 + .../plsql/ast/SelectIntoStatementExample2.txt | 92 ++ .../plsql/ast/SelectIntoStatementExample3.txt | 216 +++++ .../plsql/ast/SelectIntoStatementExample4.txt | 133 +++ .../plsql/ast/SelectIntoStatementExample5.txt | 211 +++++ .../ast/SelectIntoStatementFunctionCall.txt | 71 ++ .../ast/SelectIntoStatementRecordField.txt | 32 + .../lang/plsql/ast/SelectIntoWithGroupBy1.txt | 57 ++ .../lang/plsql/ast/SelectIntoWithGroupBy2.txt | 70 ++ .../lang/plsql/ast/SelectIntoWithGroupBy3.txt | 150 +++ .../lang/plsql/ast/SelectIntoWithGroupBy4.txt | 230 +++++ .../lang/plsql/ast/SelectSimpleExpression.txt | 23 + .../plsql/ast/SelectSubqueryExpressions.txt | 140 +++ 28 files changed, 3743 insertions(+), 108 deletions(-) create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectCount.txt create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectForUpdate.txt create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectForUpdateWait.txt create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectHierarchical.txt create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatement.txt create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementExample1.txt create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementExample2.txt create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementExample3.txt create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementExample4.txt create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementExample5.txt create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementFunctionCall.txt create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementRecordField.txt create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupBy1.txt create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupBy2.txt create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupBy3.txt create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupBy4.txt create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectSimpleExpression.txt create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectSubqueryExpressions.txt diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/AbstractPLSQLParserTst.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/AbstractPLSQLParserTst.java index 058bcb21255..52aa2c8fbc2 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/AbstractPLSQLParserTst.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/AbstractPLSQLParserTst.java @@ -4,7 +4,23 @@ package net.sourceforge.pmd.lang.plsql; -public abstract class AbstractPLSQLParserTst { +import org.checkerframework.checker.nullness.qual.NonNull; + +import net.sourceforge.pmd.lang.plsql.ast.ASTInput; +import net.sourceforge.pmd.lang.test.ast.BaseParsingHelper; +import net.sourceforge.pmd.lang.test.ast.BaseTreeDumpTest; +import net.sourceforge.pmd.lang.test.ast.RelevantAttributePrinter; + +public abstract class AbstractPLSQLParserTst extends BaseTreeDumpTest { + + public AbstractPLSQLParserTst() { + super(new RelevantAttributePrinter(), ".pls"); + } + + @Override + public @NonNull BaseParsingHelper getParser() { + return plsql; + } protected final PlsqlParsingHelper plsql = PlsqlParsingHelper.DEFAULT.withResourceContext(getClass()); diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/AllPlsqlAstTreeDumpTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/AllPlsqlAstTreeDumpTest.java index f610cc5b9d6..e34c9ade3c8 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/AllPlsqlAstTreeDumpTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/AllPlsqlAstTreeDumpTest.java @@ -11,7 +11,12 @@ @SelectClasses({ PlsqlTreeDumpTest.class, ParenthesisGroupTest.class, - ExecuteImmediateBulkCollectTest.class + ExecuteImmediateBulkCollectTest.class, + SelectIntoStatementTest.class, + SelectExpressionsTest.class, + SelectForUpdateTest.class, + SelectHierarchicalTest.class, + SelectIntoWithGroupByTest.class }) class AllPlsqlAstTreeDumpTest { diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ExecuteImmediateBulkCollectTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ExecuteImmediateBulkCollectTest.java index 66204456675..09e47c86884 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ExecuteImmediateBulkCollectTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ExecuteImmediateBulkCollectTest.java @@ -6,21 +6,9 @@ import org.junit.jupiter.api.Test; -import net.sourceforge.pmd.lang.plsql.PlsqlParsingHelper; -import net.sourceforge.pmd.lang.test.ast.BaseParsingHelper; -import net.sourceforge.pmd.lang.test.ast.BaseTreeDumpTest; -import net.sourceforge.pmd.lang.test.ast.RelevantAttributePrinter; +import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; -class ExecuteImmediateBulkCollectTest extends BaseTreeDumpTest { - - ExecuteImmediateBulkCollectTest() { - super(new RelevantAttributePrinter(), ".pls"); - } - - @Override - public BaseParsingHelper getParser() { - return PlsqlParsingHelper.DEFAULT.withResourceContext(getClass()); - } +class ExecuteImmediateBulkCollectTest extends AbstractPLSQLParserTst { @Test void testExecuteImmediateBulkCollect1() { diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ParenthesisGroupTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ParenthesisGroupTest.java index 863189b4aa3..5547589c0d2 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ParenthesisGroupTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ParenthesisGroupTest.java @@ -6,21 +6,9 @@ import org.junit.jupiter.api.Test; -import net.sourceforge.pmd.lang.plsql.PlsqlParsingHelper; -import net.sourceforge.pmd.lang.test.ast.BaseParsingHelper; -import net.sourceforge.pmd.lang.test.ast.BaseTreeDumpTest; -import net.sourceforge.pmd.lang.test.ast.RelevantAttributePrinter; +import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; -class ParenthesisGroupTest extends BaseTreeDumpTest { - - ParenthesisGroupTest() { - super(new RelevantAttributePrinter(), ".pls"); - } - - @Override - public BaseParsingHelper getParser() { - return PlsqlParsingHelper.DEFAULT.withResourceContext(getClass()); - } +class ParenthesisGroupTest extends AbstractPLSQLParserTst { @Test void parseParenthesisGroup0() { diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/PlsqlTreeDumpTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/PlsqlTreeDumpTest.java index 40aeaf67761..056a1bb5336 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/PlsqlTreeDumpTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/PlsqlTreeDumpTest.java @@ -6,21 +6,9 @@ import org.junit.jupiter.api.Test; -import net.sourceforge.pmd.lang.plsql.PlsqlParsingHelper; -import net.sourceforge.pmd.lang.test.ast.BaseParsingHelper; -import net.sourceforge.pmd.lang.test.ast.BaseTreeDumpTest; -import net.sourceforge.pmd.lang.test.ast.RelevantAttributePrinter; +import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; -class PlsqlTreeDumpTest extends BaseTreeDumpTest { - - PlsqlTreeDumpTest() { - super(new RelevantAttributePrinter(), ".pls"); - } - - @Override - public BaseParsingHelper getParser() { - return PlsqlParsingHelper.DEFAULT.withResourceContext(getClass()); - } +class PlsqlTreeDumpTest extends AbstractPLSQLParserTst { @Test void sqlPlusLexicalVariables() { diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectExpressionsTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectExpressionsTest.java index 31057150198..3dad91dc8a6 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectExpressionsTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectExpressionsTest.java @@ -4,11 +4,6 @@ package net.sourceforge.pmd.lang.plsql.ast; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.util.List; - import org.junit.jupiter.api.Test; import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; @@ -17,25 +12,16 @@ class SelectExpressionsTest extends AbstractPLSQLParserTst { @Test void parseSelectSimpleExpression() { - ASTInput input = plsql.parseResource("SelectSimpleExpression.pls"); - assertNotNull(input); - - List simpleExpressions = input.descendants(ASTSimpleExpression.class).toList(); - assertEquals(1, simpleExpressions.size()); - ASTSimpleExpression exp = simpleExpressions.get(0); - assertEquals("e.first_name", exp.getImage()); - assertEquals(2, exp.getNumChildren()); - assertEquals(ASTTableName.class, exp.getChild(0).getClass()); - assertEquals(ASTColumn.class, exp.getChild(1).getClass()); + doTest("SelectSimpleExpression"); } @Test void parseSelectCount() { - plsql.parseResource("SelectCount.pls"); + doTest("SelectCount"); } @Test void parseSelectSubqueryExpression() { - plsql.parseResource("SelectSubqueryExpressions.pls"); + doTest("SelectSubqueryExpressions"); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectForUpdateTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectForUpdateTest.java index 98802741440..4f98fd3f0d3 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectForUpdateTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectForUpdateTest.java @@ -4,11 +4,6 @@ package net.sourceforge.pmd.lang.plsql.ast; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.util.List; - import org.junit.jupiter.api.Test; import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; @@ -17,19 +12,11 @@ class SelectForUpdateTest extends AbstractPLSQLParserTst { @Test void parseSelectForUpdateWait() { - ASTInput input = plsql.parseResource("SelectForUpdateWait.pls"); - assertNotNull(input); - assertEquals(5, input.descendants(ASTForUpdateClause.class).count()); + doTest("SelectForUpdateWait"); } @Test void parseSelectForUpdate() { - ASTInput input = plsql.parseResource("SelectForUpdate.pls"); - assertNotNull(input); - List forUpdateClauses = input.descendants(ASTForUpdateClause.class).toList(); - assertEquals(2, forUpdateClauses.size()); - assertEquals(2, forUpdateClauses.get(1).getNumChildren()); - assertEquals("e", forUpdateClauses.get(1).getChild(0).getImage()); - assertEquals("salary", forUpdateClauses.get(1).getChild(1).getImage()); + doTest("SelectForUpdate"); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectHierarchicalTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectHierarchicalTest.java index d871b7d4f61..07d74fbf164 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectHierarchicalTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectHierarchicalTest.java @@ -12,6 +12,6 @@ class SelectHierarchicalTest extends AbstractPLSQLParserTst { @Test void parseSelectHierarchicalQueries() { - plsql.parseResource("SelectHierarchical.pls"); + doTest("SelectHierarchical"); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementTest.java index 0daf6349b0d..3c522d7988c 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementTest.java @@ -15,46 +15,46 @@ class SelectIntoStatementTest extends AbstractPLSQLParserTst { @Test void testParsingComplex() { - plsql.parseResource("SelectIntoStatement.pls"); + doTest("SelectIntoStatement"); } @Test void testParsingExample1() { - plsql.parseResource("SelectIntoStatementExample1.pls"); + doTest("SelectIntoStatementExample1"); } @Test void testParsingExample2() { - plsql.parseResource("SelectIntoStatementExample2.pls"); + doTest("SelectIntoStatementExample2"); } @Test void testParsingExample3() { - plsql.parseResource("SelectIntoStatementExample3.pls"); + doTest("SelectIntoStatementExample3"); } @Test void testParsingExample4() { - plsql.parseResource("SelectIntoStatementExample4.pls"); + doTest("SelectIntoStatementExample4"); } @Test void testParsingExample5() { - plsql.parseResource("SelectIntoStatementExample5.pls"); + doTest("SelectIntoStatementExample5"); } @Test void testParsingExample6Invalid() { - assertThrows(ParseException.class, () -> plsql.parseResource("SelectIntoStatementExample6Invalid.pls")); + assertThrows(ParseException.class, () -> doTest("SelectIntoStatementExample6Invalid")); } @Test void testParsingWithFunctionCall() { - plsql.parseResource("SelectIntoStatementFunctionCall.pls"); + doTest("SelectIntoStatementFunctionCall"); } @Test void testParsingIntoRecordField() { - plsql.parseResource("SelectIntoStatementRecordField.pls"); + doTest("SelectIntoStatementRecordField"); } } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupByTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupByTest.java index 5dad4cdc40c..9c793e4dc64 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupByTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupByTest.java @@ -4,11 +4,6 @@ package net.sourceforge.pmd.lang.plsql.ast; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.util.List; - import org.junit.jupiter.api.Test; import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; @@ -17,34 +12,21 @@ class SelectIntoWithGroupByTest extends AbstractPLSQLParserTst { @Test void testExample1() { - ASTInput input = plsql.parseResource("SelectIntoWithGroupBy1.pls"); - ASTGroupByClause groupByClause = input.descendants(ASTGroupByClause.class).first(); - assertNotNull(groupByClause); + doTest("SelectIntoWithGroupBy1"); } @Test void testExample2() { - ASTInput input = plsql.parseResource("SelectIntoWithGroupBy2.pls"); - ASTGroupByClause groupByClause = input.descendants(ASTGroupByClause.class).first(); - assertNotNull(groupByClause); + doTest("SelectIntoWithGroupBy2"); } @Test void testExample3WithCube() { - ASTInput input = plsql.parseResource("SelectIntoWithGroupBy3.pls"); - ASTRollupCubeClause cubeClause = input.descendants(ASTRollupCubeClause.class).first(); - assertNotNull(cubeClause); - assertEquals("CUBE", cubeClause.getImage()); + doTest("SelectIntoWithGroupBy3"); } @Test void testExample4WithGroupingSets() { - ASTInput input = plsql.parseResource("SelectIntoWithGroupBy4.pls"); - ASTGroupingSetsClause groupingSetsClause = input.descendants(ASTGroupingSetsClause.class).first(); - assertNotNull(groupingSetsClause); - - List fromClauses = input.descendants(ASTFromClause.class).toList(); - assertEquals(1, fromClauses.size()); - assertEquals(5, fromClauses.get(0).getNumChildren()); + doTest("SelectIntoWithGroupBy4"); } } diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectCount.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectCount.txt new file mode 100644 index 00000000000..924e27f58ad --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectCount.txt @@ -0,0 +1,175 @@ ++- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- Global[@CanonicalImage = null] + +- Block[@CanonicalImage = null] + +- DeclarativeSection[@CanonicalImage = null] + | +- DeclarativeUnit[@CanonicalImage = null] + | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | +- VariableOrConstantDeclarator[@CanonicalImage = "BONUS NUMBER(8,2)", @Image = "bonus NUMBER(8,2)"] + | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "BONUS", @Image = "bonus"] + | | +- ID[@CanonicalImage = "BONUS", @Image = "bonus"] + | +- Datatype[@CanonicalImage = "NUMBER(8,2)", @Image = "NUMBER(8,2)", @TypeImage = "NUMBER(8,2)"] + | +- ScalarDataTypeName[@CanonicalImage = "NUMBER(8,2)", @Image = "NUMBER(8,2)"] + | +- NumericLiteral[@CanonicalImage = "8", @Image = "8"] + | +- PrimaryPrefix[@CanonicalImage = "2", @Image = "2", @SelfModifier = false] + | +- Literal[@CanonicalImage = "2", @Image = "2"] + | +- NumericLiteral[@CanonicalImage = "2", @Image = "2"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | +- PrimaryPrefix[@CanonicalImage = "COUNT", @Image = "COUNT", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | +- FunctionName[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | | +- ID[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | +- Arguments[@ArgumentCount = 0, @CanonicalImage = null] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "X", @Image = "x"] + | | +- ID[@CanonicalImage = "X", @Image = "x"] + | +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | +- TableName[@CanonicalImage = "Y1", @Image = "y1"] + | +- ID[@CanonicalImage = "Y1", @Image = "y1"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | +- PrimaryPrefix[@CanonicalImage = "COUNT", @Image = "COUNT", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | +- FunctionName[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | | +- ID[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | +- Arguments[@ArgumentCount = 0, @CanonicalImage = null] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "X", @Image = "x"] + | | +- ID[@CanonicalImage = "X", @Image = "x"] + | +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | +- TableName[@CanonicalImage = "Y2", @Image = "y2"] + | +- ID[@CanonicalImage = "Y2", @Image = "y2"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | +- PrimaryPrefix[@CanonicalImage = "COUNT", @Image = "COUNT", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | +- FunctionName[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | | +- ID[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | +- Arguments[@ArgumentCount = 0, @CanonicalImage = null] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "X", @Image = "x"] + | | +- ID[@CanonicalImage = "X", @Image = "x"] + | +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | +- TableName[@CanonicalImage = "Y2", @Image = "y2"] + | +- ID[@CanonicalImage = "Y2", @Image = "y2"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | +- PrimaryPrefix[@CanonicalImage = "COUNT", @Image = "COUNT", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | +- FunctionName[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | | +- ID[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "OTHER_ID", @Image = "other_id"] + | | +- PrimaryPrefix[@CanonicalImage = "OTHER_ID", @Image = "other_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "OTHER_ID", @Image = "other_id"] + | | +- Column[@CanonicalImage = "OTHER_ID", @Image = "other_id"] + | | +- ID[@CanonicalImage = "OTHER_ID", @Image = "other_id"] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "X", @Image = "x"] + | | +- ID[@CanonicalImage = "X", @Image = "x"] + | +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | +- TableName[@CanonicalImage = "Y3", @Image = "y3"] + | +- ID[@CanonicalImage = "Y3", @Image = "y3"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | +- PrimaryPrefix[@CanonicalImage = "COUNT", @Image = "COUNT", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | +- FunctionName[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | | +- ID[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "OTHER_ID", @Image = "other_id"] + | | +- PrimaryPrefix[@CanonicalImage = "OTHER_ID", @Image = "other_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "OTHER_ID", @Image = "other_id"] + | | +- Column[@CanonicalImage = "OTHER_ID", @Image = "other_id"] + | | +- ID[@CanonicalImage = "OTHER_ID", @Image = "other_id"] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "X", @Image = "x"] + | | +- ID[@CanonicalImage = "X", @Image = "x"] + | +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | +- TableName[@CanonicalImage = "Y3", @Image = "y3"] + | +- ID[@CanonicalImage = "Y3", @Image = "y3"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | +- PrimaryPrefix[@CanonicalImage = "COUNT", @Image = "COUNT", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | +- FunctionName[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | | +- ID[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "OTHER_ID", @Image = "other_id"] + | | +- PrimaryPrefix[@CanonicalImage = "OTHER_ID", @Image = "other_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "OTHER_ID", @Image = "other_id"] + | | +- Column[@CanonicalImage = "OTHER_ID", @Image = "other_id"] + | | +- ID[@CanonicalImage = "OTHER_ID", @Image = "other_id"] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "X", @Image = "x"] + | | +- ID[@CanonicalImage = "X", @Image = "x"] + | +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | +- TableName[@CanonicalImage = "Y3", @Image = "y3"] + | +- ID[@CanonicalImage = "Y3", @Image = "y3"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "SOME_COL", @Image = "some_col"] + | | | +- PrimaryPrefix[@CanonicalImage = "SOME_COL", @Image = "some_col", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "SOME_COL", @Image = "some_col"] + | | | +- Column[@CanonicalImage = "SOME_COL", @Image = "some_col"] + | | | +- ID[@CanonicalImage = "SOME_COL", @Image = "some_col"] + | | +- ColumnAlias[@CanonicalImage = "\"alias in quotes\"", @Image = "\"alias in quotes\""] + | | +- ID[@CanonicalImage = "\"alias in quotes\"", @Image = "\"alias in quotes\""] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "SOME_RECORD", @Image = "some_record"] + | | +- ID[@CanonicalImage = "SOME_RECORD", @Image = "some_record"] + | +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | +- TableName[@CanonicalImage = "SOME_TABLE", @Image = "some_table"] + | +- ID[@CanonicalImage = "SOME_TABLE", @Image = "some_table"] + +- Statement[@CanonicalImage = null] + +- UnlabelledStatement[@CanonicalImage = null] + +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + +- SelectList[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | +- PrimaryPrefix[@CanonicalImage = "COUNT", @Image = "COUNT", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | +- FunctionName[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | | +- ID[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | +- Arguments[@ArgumentCount = 0, @CanonicalImage = null] + | +- ColumnAlias[@CanonicalImage = "\"Total Empl\"", @Image = "\"Total Empl\""] + | +- ID[@CanonicalImage = "\"Total Empl\"", @Image = "\"Total Empl\""] + +- IntoClause[@CanonicalImage = null] + | +- VariableName[@CanonicalImage = "SOME_RECORD", @Image = "some_record"] + | +- ID[@CanonicalImage = "SOME_RECORD", @Image = "some_record"] + +- FromClause[@CanonicalImage = null] + +- TableReference[@CanonicalImage = null] + +- TableName[@CanonicalImage = "SOME_TABLE", @Image = "some_table"] + +- ID[@CanonicalImage = "SOME_TABLE", @Image = "some_table"] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectForUpdate.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectForUpdate.txt new file mode 100644 index 00000000000..08e5ec949a5 --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectForUpdate.txt @@ -0,0 +1,168 @@ ++- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- Global[@CanonicalImage = null] + +- Block[@CanonicalImage = null] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "E.EMPLOYEE_ID", @Image = "e.employee_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "E.EMPLOYEE_ID", @Image = "e.employee_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "E.EMPLOYEE_ID", @Image = "e.employee_id"] + | | | +- TableName[@CanonicalImage = "E", @Image = "e"] + | | | | +- ID[@CanonicalImage = "E", @Image = "e"] + | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- SqlExpression[@CanonicalImage = "E.SALARY", @Image = "e.salary"] + | | | +- PrimaryPrefix[@CanonicalImage = "E.SALARY", @Image = "e.salary", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "E.SALARY", @Image = "e.salary"] + | | | +- TableName[@CanonicalImage = "E", @Image = "e"] + | | | | +- ID[@CanonicalImage = "E", @Image = "e"] + | | | +- Column[@CanonicalImage = "SALARY", @Image = "salary"] + | | | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + | | +- SqlExpression[@CanonicalImage = "E.COMMISSION_PCT", @Image = "e.commission_pct"] + | | +- PrimaryPrefix[@CanonicalImage = "E.COMMISSION_PCT", @Image = "e.commission_pct", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "E.COMMISSION_PCT", @Image = "e.commission_pct"] + | | +- TableName[@CanonicalImage = "E", @Image = "e"] + | | | +- ID[@CanonicalImage = "E", @Image = "e"] + | | +- Column[@CanonicalImage = "COMMISSION_PCT", @Image = "commission_pct"] + | | +- ID[@CanonicalImage = "COMMISSION_PCT", @Image = "commission_pct"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | | +- TableAlias[@CanonicalImage = "E", @Image = "e"] + | | | +- ID[@CanonicalImage = "E", @Image = "e"] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "DEPARTMENTS", @Image = "departments"] + | | | +- ID[@CanonicalImage = "DEPARTMENTS", @Image = "departments"] + | | +- TableAlias[@CanonicalImage = "D", @Image = "d"] + | | +- ID[@CanonicalImage = "D", @Image = "d"] + | +- WhereClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = "AND"] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | | +- SqlExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "JOB_ID", @Image = "job_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | | | +- Column[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | | | +- ID[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | | +- SqlExpression[@CanonicalImage = "\'SA_REP\'", @Image = "\'SA_REP\'"] + | | | +- PrimaryPrefix[@CanonicalImage = "\'SA_REP\'", @Image = "\'SA_REP\'", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "\'SA_REP\'", @Image = "\'SA_REP\'"] + | | | +- StringLiteral[@CanonicalImage = "\'SA_REP\'", @Image = "\'SA_REP\'", @String = "SA_REP"] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = "AND"] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | | +- SqlExpression[@CanonicalImage = "E.DEPARTMENT_ID", @Image = "e.department_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "E.DEPARTMENT_ID", @Image = "e.department_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "E.DEPARTMENT_ID", @Image = "e.department_id"] + | | | | +- TableName[@CanonicalImage = "E", @Image = "e"] + | | | | | +- ID[@CanonicalImage = "E", @Image = "e"] + | | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- SqlExpression[@CanonicalImage = "D.DEPARTMENT_ID", @Image = "d.department_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "D.DEPARTMENT_ID", @Image = "d.department_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "D.DEPARTMENT_ID", @Image = "d.department_id"] + | | | +- TableName[@CanonicalImage = "D", @Image = "d"] + | | | | +- ID[@CanonicalImage = "D", @Image = "d"] + | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "LOCATION_ID", @Image = "location_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "LOCATION_ID", @Image = "location_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "LOCATION_ID", @Image = "location_id"] + | | | +- Column[@CanonicalImage = "LOCATION_ID", @Image = "location_id"] + | | | +- ID[@CanonicalImage = "LOCATION_ID", @Image = "location_id"] + | | +- SqlExpression[@CanonicalImage = "2500", @Image = "2500"] + | | +- PrimaryPrefix[@CanonicalImage = "2500", @Image = "2500", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "2500", @Image = "2500"] + | | +- NumericLiteral[@CanonicalImage = "2500", @Image = "2500"] + | +- OrderByClause[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "E.EMPLOYEE_ID", @Image = "e.employee_id"] + | | +- PrimaryPrefix[@CanonicalImage = "E.EMPLOYEE_ID", @Image = "e.employee_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "E.EMPLOYEE_ID", @Image = "e.employee_id"] + | | +- TableName[@CanonicalImage = "E", @Image = "e"] + | | | +- ID[@CanonicalImage = "E", @Image = "e"] + | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- ForUpdateClause[@CanonicalImage = null] + +- Statement[@CanonicalImage = null] + +- UnlabelledStatement[@CanonicalImage = null] + +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + +- SelectList[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "E.EMPLOYEE_ID", @Image = "e.employee_id"] + | | +- PrimaryPrefix[@CanonicalImage = "E.EMPLOYEE_ID", @Image = "e.employee_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "E.EMPLOYEE_ID", @Image = "e.employee_id"] + | | +- TableName[@CanonicalImage = "E", @Image = "e"] + | | | +- ID[@CanonicalImage = "E", @Image = "e"] + | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- SqlExpression[@CanonicalImage = "E.SALARY", @Image = "e.salary"] + | | +- PrimaryPrefix[@CanonicalImage = "E.SALARY", @Image = "e.salary", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "E.SALARY", @Image = "e.salary"] + | | +- TableName[@CanonicalImage = "E", @Image = "e"] + | | | +- ID[@CanonicalImage = "E", @Image = "e"] + | | +- Column[@CanonicalImage = "SALARY", @Image = "salary"] + | | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + | +- SqlExpression[@CanonicalImage = "E.COMMISSION_PCT", @Image = "e.commission_pct"] + | +- PrimaryPrefix[@CanonicalImage = "E.COMMISSION_PCT", @Image = "e.commission_pct", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "E.COMMISSION_PCT", @Image = "e.commission_pct"] + | +- TableName[@CanonicalImage = "E", @Image = "e"] + | | +- ID[@CanonicalImage = "E", @Image = "e"] + | +- Column[@CanonicalImage = "COMMISSION_PCT", @Image = "commission_pct"] + | +- ID[@CanonicalImage = "COMMISSION_PCT", @Image = "commission_pct"] + +- FromClause[@CanonicalImage = null] + | +- JoinClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- TableAlias[@CanonicalImage = "E", @Image = "e"] + | | +- ID[@CanonicalImage = "E", @Image = "e"] + | +- InnerCrossJoinClause[@CanonicalImage = null, @Cross = false, @Natural = false] + | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "DEPARTMENTS", @Image = "departments"] + | | | +- ID[@CanonicalImage = "DEPARTMENTS", @Image = "departments"] + | | +- TableAlias[@CanonicalImage = "D", @Image = "d"] + | | +- ID[@CanonicalImage = "D", @Image = "d"] + | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + +- WhereClause[@CanonicalImage = null] + | +- Condition[@CanonicalImage = null] + | +- CompoundCondition[@CanonicalImage = null, @Type = "AND"] + | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "JOB_ID", @Image = "job_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | | +- Column[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | | +- ID[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | +- SqlExpression[@CanonicalImage = "\'SA_REP\'", @Image = "\'SA_REP\'"] + | | +- PrimaryPrefix[@CanonicalImage = "\'SA_REP\'", @Image = "\'SA_REP\'", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "\'SA_REP\'", @Image = "\'SA_REP\'"] + | | +- StringLiteral[@CanonicalImage = "\'SA_REP\'", @Image = "\'SA_REP\'", @String = "SA_REP"] + | +- Condition[@CanonicalImage = null] + | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | +- SqlExpression[@CanonicalImage = "LOCATION_ID", @Image = "location_id"] + | | +- PrimaryPrefix[@CanonicalImage = "LOCATION_ID", @Image = "location_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "LOCATION_ID", @Image = "location_id"] + | | +- Column[@CanonicalImage = "LOCATION_ID", @Image = "location_id"] + | | +- ID[@CanonicalImage = "LOCATION_ID", @Image = "location_id"] + | +- SqlExpression[@CanonicalImage = "2500", @Image = "2500"] + | +- PrimaryPrefix[@CanonicalImage = "2500", @Image = "2500", @SelfModifier = false] + | +- Literal[@CanonicalImage = "2500", @Image = "2500"] + | +- NumericLiteral[@CanonicalImage = "2500", @Image = "2500"] + +- OrderByClause[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "E.EMPLOYEE_ID", @Image = "e.employee_id"] + | +- PrimaryPrefix[@CanonicalImage = "E.EMPLOYEE_ID", @Image = "e.employee_id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "E.EMPLOYEE_ID", @Image = "e.employee_id"] + | +- TableName[@CanonicalImage = "E", @Image = "e"] + | | +- ID[@CanonicalImage = "E", @Image = "e"] + | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + +- ForUpdateClause[@CanonicalImage = null] + +- SchemaName[@CanonicalImage = "E", @Image = "e"] + | +- ID[@CanonicalImage = "E", @Image = "e"] + +- Column[@CanonicalImage = "SALARY", @Image = "salary"] + +- ID[@CanonicalImage = "SALARY", @Image = "salary"] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectForUpdateWait.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectForUpdateWait.txt new file mode 100644 index 00000000000..99ba0b3f27d --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectForUpdateWait.txt @@ -0,0 +1,227 @@ ++- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- Global[@CanonicalImage = null] + | +- Block[@CanonicalImage = null] + | +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- CursorForLoopStatement[@CanonicalImage = null] + | +- ForIndex[@CanonicalImage = "R_EMP_TEST", @Image = "r_emp_test"] + | | +- ID[@CanonicalImage = "R_EMP_TEST", @Image = "r_emp_test"] + | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | | +- SelectList[@CanonicalImage = null] + | | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- SqlExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- SqlExpression[@CanonicalImage = "SALARY", @Image = "salary"] + | | | | +- PrimaryPrefix[@CanonicalImage = "SALARY", @Image = "salary", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "SALARY", @Image = "salary"] + | | | | +- Column[@CanonicalImage = "SALARY", @Image = "salary"] + | | | | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + | | | +- SqlExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "JOB_ID", @Image = "job_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | | +- Column[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | | +- ID[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | +- FromClause[@CanonicalImage = null] + | | | +- TableReference[@CanonicalImage = null] + | | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | | +- TableAlias[@CanonicalImage = "E", @Image = "e"] + | | | +- ID[@CanonicalImage = "E", @Image = "e"] + | | +- ForUpdateClause[@CanonicalImage = null] + | +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "NULL", @Image = "NULL"] + | +- PrimaryPrefix[@CanonicalImage = "NULL", @Image = "NULL", @SelfModifier = false] + | +- Literal[@CanonicalImage = "NULL", @Image = "NULL"] + | +- NullLiteral[@CanonicalImage = "NULL", @Image = "NULL"] + +- Global[@CanonicalImage = null] + | +- Block[@CanonicalImage = null] + | +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- CursorForLoopStatement[@CanonicalImage = null] + | +- ForIndex[@CanonicalImage = "R_EMP_TEST", @Image = "r_emp_test"] + | | +- ID[@CanonicalImage = "R_EMP_TEST", @Image = "r_emp_test"] + | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | | +- SelectList[@CanonicalImage = null] + | | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- SqlExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- SqlExpression[@CanonicalImage = "SALARY", @Image = "salary"] + | | | | +- PrimaryPrefix[@CanonicalImage = "SALARY", @Image = "salary", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "SALARY", @Image = "salary"] + | | | | +- Column[@CanonicalImage = "SALARY", @Image = "salary"] + | | | | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + | | | +- SqlExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "JOB_ID", @Image = "job_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | | +- Column[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | | +- ID[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | +- FromClause[@CanonicalImage = null] + | | | +- TableReference[@CanonicalImage = null] + | | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | | +- TableAlias[@CanonicalImage = "E", @Image = "e"] + | | | +- ID[@CanonicalImage = "E", @Image = "e"] + | | +- ForUpdateClause[@CanonicalImage = null] + | | +- Column[@CanonicalImage = "SALARY", @Image = "salary"] + | | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + | +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "NULL", @Image = "NULL"] + | +- PrimaryPrefix[@CanonicalImage = "NULL", @Image = "NULL", @SelfModifier = false] + | +- Literal[@CanonicalImage = "NULL", @Image = "NULL"] + | +- NullLiteral[@CanonicalImage = "NULL", @Image = "NULL"] + +- Global[@CanonicalImage = null] + | +- Block[@CanonicalImage = null] + | +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- CursorForLoopStatement[@CanonicalImage = null] + | +- ForIndex[@CanonicalImage = "R_EMP_TEST", @Image = "r_emp_test"] + | | +- ID[@CanonicalImage = "R_EMP_TEST", @Image = "r_emp_test"] + | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | | +- SelectList[@CanonicalImage = null] + | | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- SqlExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- SqlExpression[@CanonicalImage = "SALARY", @Image = "salary"] + | | | | +- PrimaryPrefix[@CanonicalImage = "SALARY", @Image = "salary", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "SALARY", @Image = "salary"] + | | | | +- Column[@CanonicalImage = "SALARY", @Image = "salary"] + | | | | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + | | | +- SqlExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "JOB_ID", @Image = "job_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | | +- Column[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | | +- ID[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | +- FromClause[@CanonicalImage = null] + | | | +- TableReference[@CanonicalImage = null] + | | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | | +- TableAlias[@CanonicalImage = "E", @Image = "e"] + | | | +- ID[@CanonicalImage = "E", @Image = "e"] + | | +- ForUpdateClause[@CanonicalImage = null] + | | +- SchemaName[@CanonicalImage = "E", @Image = "e"] + | | | +- ID[@CanonicalImage = "E", @Image = "e"] + | | +- Column[@CanonicalImage = "SALARY", @Image = "salary"] + | | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + | +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "NULL", @Image = "NULL"] + | +- PrimaryPrefix[@CanonicalImage = "NULL", @Image = "NULL", @SelfModifier = false] + | +- Literal[@CanonicalImage = "NULL", @Image = "NULL"] + | +- NullLiteral[@CanonicalImage = "NULL", @Image = "NULL"] + +- Global[@CanonicalImage = null] + | +- Block[@CanonicalImage = null] + | +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- CursorForLoopStatement[@CanonicalImage = null] + | +- ForIndex[@CanonicalImage = "R_EMP_TEST", @Image = "r_emp_test"] + | | +- ID[@CanonicalImage = "R_EMP_TEST", @Image = "r_emp_test"] + | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | | +- SelectList[@CanonicalImage = null] + | | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- SqlExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- SqlExpression[@CanonicalImage = "SALARY", @Image = "salary"] + | | | | +- PrimaryPrefix[@CanonicalImage = "SALARY", @Image = "salary", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "SALARY", @Image = "salary"] + | | | | +- Column[@CanonicalImage = "SALARY", @Image = "salary"] + | | | | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + | | | +- SqlExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "JOB_ID", @Image = "job_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | | +- Column[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | | +- ID[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | +- FromClause[@CanonicalImage = null] + | | | +- TableReference[@CanonicalImage = null] + | | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | | +- TableAlias[@CanonicalImage = "E", @Image = "e"] + | | | +- ID[@CanonicalImage = "E", @Image = "e"] + | | +- ForUpdateClause[@CanonicalImage = null] + | | +- SchemaName[@CanonicalImage = "E", @Image = "e"] + | | | +- ID[@CanonicalImage = "E", @Image = "e"] + | | +- Column[@CanonicalImage = "SALARY", @Image = "salary"] + | | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + | +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "NULL", @Image = "NULL"] + | +- PrimaryPrefix[@CanonicalImage = "NULL", @Image = "NULL", @SelfModifier = false] + | +- Literal[@CanonicalImage = "NULL", @Image = "NULL"] + | +- NullLiteral[@CanonicalImage = "NULL", @Image = "NULL"] + +- Global[@CanonicalImage = null] + +- Block[@CanonicalImage = null] + +- DeclarativeSection[@CanonicalImage = null] + | +- DeclarativeUnit[@CanonicalImage = null] + | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | +- VariableOrConstantDeclarator[@CanonicalImage = "W_FOUND NUMBER(10)", @Image = "w_found NUMBER(10)"] + | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "W_FOUND", @Image = "w_found"] + | | +- ID[@CanonicalImage = "W_FOUND", @Image = "w_found"] + | +- Datatype[@CanonicalImage = "NUMBER(10)", @Image = "NUMBER(10)", @TypeImage = "NUMBER(10)"] + | +- ScalarDataTypeName[@CanonicalImage = "NUMBER(10)", @Image = "NUMBER(10)"] + | +- NumericLiteral[@CanonicalImage = "10", @Image = "10"] + +- Statement[@CanonicalImage = null] + +- UnlabelledStatement[@CanonicalImage = null] + +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + +- SelectList[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "1", @Image = "1"] + | +- PrimaryPrefix[@CanonicalImage = "1", @Image = "1", @SelfModifier = false] + | +- Literal[@CanonicalImage = "1", @Image = "1"] + | +- NumericLiteral[@CanonicalImage = "1", @Image = "1"] + +- IntoClause[@CanonicalImage = null] + | +- VariableName[@CanonicalImage = "W_FOUND", @Image = "w_found"] + | +- ID[@CanonicalImage = "W_FOUND", @Image = "w_found"] + +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | +- SchemaName[@CanonicalImage = "HR", @Image = "hr"] + | | +- ID[@CanonicalImage = "HR", @Image = "hr"] + | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- TableAlias[@CanonicalImage = "E", @Image = "e"] + | +- ID[@CanonicalImage = "E", @Image = "e"] + +- WhereClause[@CanonicalImage = null] + | +- Condition[@CanonicalImage = null] + | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | +- ComparisonCondition[@CanonicalImage = null, @Operator = "<"] + | +- SqlExpression[@CanonicalImage = "ROWNUM", @Image = "ROWNUM"] + | | +- PrimaryPrefix[@CanonicalImage = "ROWNUM", @Image = "ROWNUM", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "ROWNUM", @Image = "ROWNUM"] + | +- SqlExpression[@CanonicalImage = "2", @Image = "2"] + | +- PrimaryPrefix[@CanonicalImage = "2", @Image = "2", @SelfModifier = false] + | +- Literal[@CanonicalImage = "2", @Image = "2"] + | +- NumericLiteral[@CanonicalImage = "2", @Image = "2"] + +- ForUpdateClause[@CanonicalImage = null] + +- SchemaName[@CanonicalImage = "HR", @Image = "hr"] + | +- ID[@CanonicalImage = "HR", @Image = "hr"] + +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + +- Column[@CanonicalImage = "SALARY", @Image = "salary"] + +- ID[@CanonicalImage = "SALARY", @Image = "salary"] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectHierarchical.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectHierarchical.txt new file mode 100644 index 00000000000..5f682d6aa2f --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectHierarchical.txt @@ -0,0 +1,874 @@ ++- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- Global[@CanonicalImage = null] + +- Block[@CanonicalImage = null] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "ID", @Image = "id"] + | | +- PrimaryPrefix[@CanonicalImage = "ID", @Image = "id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "ID", @Image = "id"] + | | +- Column[@CanonicalImage = "ID", @Image = "id"] + | | +- ID[@CanonicalImage = "ID", @Image = "id"] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "V_ID", @Image = "v_id"] + | | +- ID[@CanonicalImage = "V_ID", @Image = "v_id"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- QueryBlock[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | | +- SelectList[@CanonicalImage = null] + | | | +- SqlExpression[@CanonicalImage = "SEPARATOR_IN || STRING_IN || SEPARATOR_IN", @Image = "separator_in || string_in || separator_in"] + | | | | +- AdditiveExpression[@CanonicalImage = "SEPARATOR_IN || STRING_IN || SEPARATOR_IN", @Image = "separator_in || string_in || separator_in"] + | | | | +- PrimaryPrefix[@CanonicalImage = "SEPARATOR_IN", @Image = "separator_in", @SelfModifier = false] + | | | | | +- SimpleExpression[@CanonicalImage = "SEPARATOR_IN", @Image = "separator_in"] + | | | | | +- Column[@CanonicalImage = "SEPARATOR_IN", @Image = "separator_in"] + | | | | | +- ID[@CanonicalImage = "SEPARATOR_IN", @Image = "separator_in"] + | | | | +- PrimaryPrefix[@CanonicalImage = "STRING_IN", @Image = "string_in", @SelfModifier = false] + | | | | | +- SimpleExpression[@CanonicalImage = "STRING_IN", @Image = "string_in"] + | | | | | +- Column[@CanonicalImage = "STRING_IN", @Image = "string_in"] + | | | | | +- ID[@CanonicalImage = "STRING_IN", @Image = "string_in"] + | | | | +- PrimaryPrefix[@CanonicalImage = "SEPARATOR_IN", @Image = "separator_in", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "SEPARATOR_IN", @Image = "separator_in"] + | | | | +- Column[@CanonicalImage = "SEPARATOR_IN", @Image = "separator_in"] + | | | | +- ID[@CanonicalImage = "SEPARATOR_IN", @Image = "separator_in"] + | | | +- ColumnAlias[@CanonicalImage = "TOKEN_LIST", @Image = "token_list"] + | | | +- ID[@CanonicalImage = "TOKEN_LIST", @Image = "token_list"] + | | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "DUAL", @Image = "DUAL"] + | | +- ID[@CanonicalImage = "DUAL", @Image = "DUAL"] + | +- HierarchicalQueryClause[@CanonicalImage = null] + | +- Condition[@CanonicalImage = null] + | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | +- ComparisonCondition[@CanonicalImage = null, @Operator = "<="] + | +- SqlExpression[@CanonicalImage = "COL_LENGTH", @Image = "col_length"] + | | +- PrimaryPrefix[@CanonicalImage = "COL_LENGTH", @Image = "col_length", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "COL_LENGTH", @Image = "col_length"] + | | +- Column[@CanonicalImage = "COL_LENGTH", @Image = "col_length"] + | | +- ID[@CanonicalImage = "COL_LENGTH", @Image = "col_length"] + | +- SqlExpression[@CanonicalImage = "LENGTH - LENGTH", @Image = "LENGTH - LENGTH"] + | +- AdditiveExpression[@CanonicalImage = "LENGTH - LENGTH", @Image = "LENGTH - LENGTH"] + | +- PrimaryPrefix[@CanonicalImage = "LENGTH", @Image = "LENGTH", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "LENGTH", @Image = "LENGTH"] + | | +- FunctionName[@CanonicalImage = "LENGTH", @Image = "LENGTH"] + | | | +- ID[@CanonicalImage = "LENGTH", @Image = "LENGTH"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "STRING_IN", @Image = "string_in"] + | | +- PrimaryPrefix[@CanonicalImage = "STRING_IN", @Image = "string_in", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "STRING_IN", @Image = "string_in"] + | | +- Column[@CanonicalImage = "STRING_IN", @Image = "string_in"] + | | +- ID[@CanonicalImage = "STRING_IN", @Image = "string_in"] + | +- PrimaryPrefix[@CanonicalImage = "LENGTH", @Image = "LENGTH", @SelfModifier = false] + | +- FunctionCall[@CanonicalImage = "LENGTH", @Image = "LENGTH"] + | +- FunctionName[@CanonicalImage = "LENGTH", @Image = "LENGTH"] + | | +- ID[@CanonicalImage = "LENGTH", @Image = "LENGTH"] + | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | +- ArgumentList[@CanonicalImage = null] + | +- Argument[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "SEPARATOR_IN", @Image = "separator_in"] + | +- PrimaryPrefix[@CanonicalImage = "SEPARATOR_IN", @Image = "separator_in", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "SEPARATOR_IN", @Image = "separator_in"] + | +- Column[@CanonicalImage = "SEPARATOR_IN", @Image = "separator_in"] + | +- ID[@CanonicalImage = "SEPARATOR_IN", @Image = "separator_in"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- SqlExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- PrimaryPrefix[@CanonicalImage = "MANAGER_ID", @Image = "manager_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- Column[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- ID[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "TEST", @Image = "test"] + | | +- ID[@CanonicalImage = "TEST", @Image = "test"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- HierarchicalQueryClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- SqlExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- PrimaryPrefix[@CanonicalImage = "MANAGER_ID", @Image = "manager_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- Column[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- ID[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | +- OrderByClause[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- SqlExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- PrimaryPrefix[@CanonicalImage = "MANAGER_ID", @Image = "manager_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- Column[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- ID[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "TEST", @Image = "test"] + | | +- ID[@CanonicalImage = "TEST", @Image = "test"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- HierarchicalQueryClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = "AND"] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | | +- SqlExpression[@CanonicalImage = "PRIOR EMPLOYEE_ID", @Image = " PRIOR employee_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- SqlExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "MANAGER_ID", @Image = "manager_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | | +- Column[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | | +- ID[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = ">"] + | | +- SqlExpression[@CanonicalImage = "SALARY", @Image = "salary"] + | | | +- PrimaryPrefix[@CanonicalImage = "SALARY", @Image = "salary", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "SALARY", @Image = "salary"] + | | | +- Column[@CanonicalImage = "SALARY", @Image = "salary"] + | | | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + | | +- SqlExpression[@CanonicalImage = "COMMISSION_PCT", @Image = "commission_pct"] + | | +- PrimaryPrefix[@CanonicalImage = "COMMISSION_PCT", @Image = "commission_pct", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "COMMISSION_PCT", @Image = "commission_pct"] + | | +- Column[@CanonicalImage = "COMMISSION_PCT", @Image = "commission_pct"] + | | +- ID[@CanonicalImage = "COMMISSION_PCT", @Image = "commission_pct"] + | +- OrderByClause[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- SqlExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | +- SqlExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- PrimaryPrefix[@CanonicalImage = "MANAGER_ID", @Image = "manager_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- Column[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- ID[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "TEST", @Image = "test"] + | | +- ID[@CanonicalImage = "TEST", @Image = "test"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- HierarchicalQueryClause[@CanonicalImage = null] + | +- Condition[@CanonicalImage = null] + | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | +- SqlExpression[@CanonicalImage = "PRIOR EMPLOYEE_ID", @Image = " PRIOR employee_id"] + | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- SqlExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | +- PrimaryPrefix[@CanonicalImage = "MANAGER_ID", @Image = "manager_id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | +- Column[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | +- ID[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- SqlExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | +- SqlExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "MANAGER_ID", @Image = "manager_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | | +- Column[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | | +- ID[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- SqlExpression[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | +- PrimaryPrefix[@CanonicalImage = "LEVEL", @Image = "LEVEL", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | +- Column[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | +- ID[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "TEST", @Image = "test"] + | | +- ID[@CanonicalImage = "TEST", @Image = "test"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- HierarchicalQueryClause[@CanonicalImage = null] + | +- Condition[@CanonicalImage = null] + | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | +- SqlExpression[@CanonicalImage = "PRIOR EMPLOYEE_ID", @Image = " PRIOR employee_id"] + | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- SqlExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | +- PrimaryPrefix[@CanonicalImage = "MANAGER_ID", @Image = "manager_id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | +- Column[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | +- ID[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- SqlExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "MANAGER_ID", @Image = "manager_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | | +- Column[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | | +- ID[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- SqlExpression[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | +- PrimaryPrefix[@CanonicalImage = "LEVEL", @Image = "LEVEL", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | +- Column[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | +- ID[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "TEST", @Image = "test"] + | | +- ID[@CanonicalImage = "TEST", @Image = "test"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- HierarchicalQueryClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- SqlExpression[@CanonicalImage = "100", @Image = "100"] + | | | +- PrimaryPrefix[@CanonicalImage = "100", @Image = "100", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "100", @Image = "100"] + | | | +- NumericLiteral[@CanonicalImage = "100", @Image = "100"] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "PRIOR EMPLOYEE_ID", @Image = " PRIOR employee_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- SqlExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- PrimaryPrefix[@CanonicalImage = "MANAGER_ID", @Image = "manager_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- Column[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- ID[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | +- OrderByClause[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | +- ColumnAlias[@CanonicalImage = "\"Employee\"", @Image = "\"Employee\""] + | | | +- ID[@CanonicalImage = "\"Employee\"", @Image = "\"Employee\""] + | | +- SqlExpression[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | | +- PrimaryPrefix[@CanonicalImage = "LEVEL", @Image = "LEVEL", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | | +- Column[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | | +- ID[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | +- SqlExpression[@CanonicalImage = "SYS_CONNECT_BY_PATH", @Image = "SYS_CONNECT_BY_PATH"] + | | | +- PrimaryPrefix[@CanonicalImage = "SYS_CONNECT_BY_PATH", @Image = "SYS_CONNECT_BY_PATH", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "SYS_CONNECT_BY_PATH", @Image = "SYS_CONNECT_BY_PATH"] + | | | +- FunctionName[@CanonicalImage = "SYS_CONNECT_BY_PATH", @Image = "SYS_CONNECT_BY_PATH"] + | | | | +- ID[@CanonicalImage = "SYS_CONNECT_BY_PATH", @Image = "SYS_CONNECT_BY_PATH"] + | | | +- Arguments[@ArgumentCount = 2, @CanonicalImage = null] + | | | +- ArgumentList[@CanonicalImage = null] + | | | +- Argument[@CanonicalImage = null] + | | | | +- Expression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "\'/\'", @Image = "\'/\'"] + | | | +- PrimaryPrefix[@CanonicalImage = "\'/\'", @Image = "\'/\'", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "\'/\'", @Image = "\'/\'"] + | | +- ColumnAlias[@CanonicalImage = "\"Path\"", @Image = "\"Path\""] + | | +- ID[@CanonicalImage = "\"Path\"", @Image = "\"Path\""] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "TEST", @Image = "test"] + | | +- ID[@CanonicalImage = "TEST", @Image = "test"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- WhereClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = "AND"] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "<="] + | | | +- SqlExpression[@CanonicalImage = "LEVEL", @Image = "level"] + | | | | +- PrimaryPrefix[@CanonicalImage = "LEVEL", @Image = "level", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "LEVEL", @Image = "level"] + | | | | +- Column[@CanonicalImage = "LEVEL", @Image = "level"] + | | | | +- ID[@CanonicalImage = "LEVEL", @Image = "level"] + | | | +- SqlExpression[@CanonicalImage = "3", @Image = "3"] + | | | +- PrimaryPrefix[@CanonicalImage = "3", @Image = "3", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "3", @Image = "3"] + | | | +- NumericLiteral[@CanonicalImage = "3", @Image = "3"] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | +- SqlExpression[@CanonicalImage = "80", @Image = "80"] + | | +- PrimaryPrefix[@CanonicalImage = "80", @Image = "80", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "80", @Image = "80"] + | | +- NumericLiteral[@CanonicalImage = "80", @Image = "80"] + | +- HierarchicalQueryClause[@CanonicalImage = null] + | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | +- SqlExpression[@CanonicalImage = "\'KING\'", @Image = "\'King\'"] + | | +- PrimaryPrefix[@CanonicalImage = "\'KING\'", @Image = "\'King\'", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "\'KING\'", @Image = "\'King\'"] + | | +- StringLiteral[@CanonicalImage = "\'KING\'", @Image = "\'King\'", @String = "King"] + | +- Condition[@CanonicalImage = null] + | +- CompoundCondition[@CanonicalImage = null, @Type = "AND"] + | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "PRIOR EMPLOYEE_ID", @Image = " PRIOR employee_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- SqlExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- PrimaryPrefix[@CanonicalImage = "MANAGER_ID", @Image = "manager_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- Column[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- ID[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | +- Condition[@CanonicalImage = null] + | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | +- ComparisonCondition[@CanonicalImage = null, @Operator = "<="] + | +- SqlExpression[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | +- PrimaryPrefix[@CanonicalImage = "LEVEL", @Image = "LEVEL", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | +- Column[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | +- ID[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | +- SqlExpression[@CanonicalImage = "4", @Image = "4"] + | +- PrimaryPrefix[@CanonicalImage = "4", @Image = "4", @SelfModifier = false] + | +- Literal[@CanonicalImage = "4", @Image = "4"] + | +- NumericLiteral[@CanonicalImage = "4", @Image = "4"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | +- ColumnAlias[@CanonicalImage = "\"Employee\"", @Image = "\"Employee\""] + | | | +- ID[@CanonicalImage = "\"Employee\"", @Image = "\"Employee\""] + | | +- SqlExpression[@CanonicalImage = "CONNECT_BY_ISCYCLE", @Image = "CONNECT_BY_ISCYCLE"] + | | | +- PrimaryPrefix[@CanonicalImage = "CONNECT_BY_ISCYCLE", @Image = "CONNECT_BY_ISCYCLE", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "CONNECT_BY_ISCYCLE", @Image = "CONNECT_BY_ISCYCLE"] + | | | +- Column[@CanonicalImage = "CONNECT_BY_ISCYCLE", @Image = "CONNECT_BY_ISCYCLE"] + | | | +- ID[@CanonicalImage = "CONNECT_BY_ISCYCLE", @Image = "CONNECT_BY_ISCYCLE"] + | | +- ColumnAlias[@CanonicalImage = "\"Cycle\"", @Image = "\"Cycle\""] + | | | +- ID[@CanonicalImage = "\"Cycle\"", @Image = "\"Cycle\""] + | | +- SqlExpression[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | | +- PrimaryPrefix[@CanonicalImage = "LEVEL", @Image = "LEVEL", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | | +- Column[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | | +- ID[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | +- SqlExpression[@CanonicalImage = "SYS_CONNECT_BY_PATH", @Image = "SYS_CONNECT_BY_PATH"] + | | | +- PrimaryPrefix[@CanonicalImage = "SYS_CONNECT_BY_PATH", @Image = "SYS_CONNECT_BY_PATH", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "SYS_CONNECT_BY_PATH", @Image = "SYS_CONNECT_BY_PATH"] + | | | +- FunctionName[@CanonicalImage = "SYS_CONNECT_BY_PATH", @Image = "SYS_CONNECT_BY_PATH"] + | | | | +- ID[@CanonicalImage = "SYS_CONNECT_BY_PATH", @Image = "SYS_CONNECT_BY_PATH"] + | | | +- Arguments[@ArgumentCount = 2, @CanonicalImage = null] + | | | +- ArgumentList[@CanonicalImage = null] + | | | +- Argument[@CanonicalImage = null] + | | | | +- Expression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "\'/\'", @Image = "\'/\'"] + | | | +- PrimaryPrefix[@CanonicalImage = "\'/\'", @Image = "\'/\'", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "\'/\'", @Image = "\'/\'"] + | | +- ColumnAlias[@CanonicalImage = "\"Path\"", @Image = "\"Path\""] + | | +- ID[@CanonicalImage = "\"Path\"", @Image = "\"Path\""] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "TEST", @Image = "test"] + | | +- ID[@CanonicalImage = "TEST", @Image = "test"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- WhereClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = "AND"] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "<="] + | | | +- SqlExpression[@CanonicalImage = "LEVEL", @Image = "level"] + | | | | +- PrimaryPrefix[@CanonicalImage = "LEVEL", @Image = "level", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "LEVEL", @Image = "level"] + | | | | +- Column[@CanonicalImage = "LEVEL", @Image = "level"] + | | | | +- ID[@CanonicalImage = "LEVEL", @Image = "level"] + | | | +- SqlExpression[@CanonicalImage = "3", @Image = "3"] + | | | +- PrimaryPrefix[@CanonicalImage = "3", @Image = "3", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "3", @Image = "3"] + | | | +- NumericLiteral[@CanonicalImage = "3", @Image = "3"] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | +- SqlExpression[@CanonicalImage = "80", @Image = "80"] + | | +- PrimaryPrefix[@CanonicalImage = "80", @Image = "80", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "80", @Image = "80"] + | | +- NumericLiteral[@CanonicalImage = "80", @Image = "80"] + | +- HierarchicalQueryClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | | +- SqlExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- SqlExpression[@CanonicalImage = "\'KING\'", @Image = "\'King\'"] + | | | +- PrimaryPrefix[@CanonicalImage = "\'KING\'", @Image = "\'King\'", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "\'KING\'", @Image = "\'King\'"] + | | | +- StringLiteral[@CanonicalImage = "\'KING\'", @Image = "\'King\'", @String = "King"] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = "AND"] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | | +- SqlExpression[@CanonicalImage = "PRIOR EMPLOYEE_ID", @Image = " PRIOR employee_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- SqlExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "MANAGER_ID", @Image = "manager_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | | +- Column[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | | +- ID[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "<="] + | | +- SqlExpression[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | | +- PrimaryPrefix[@CanonicalImage = "LEVEL", @Image = "LEVEL", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | | +- Column[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | | +- ID[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | +- SqlExpression[@CanonicalImage = "4", @Image = "4"] + | | +- PrimaryPrefix[@CanonicalImage = "4", @Image = "4", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "4", @Image = "4"] + | | +- NumericLiteral[@CanonicalImage = "4", @Image = "4"] + | +- OrderByClause[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "\"Employee\"", @Image = "\"Employee\""] + | | +- PrimaryPrefix[@CanonicalImage = "\"Employee\"", @Image = "\"Employee\"", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "\"Employee\"", @Image = "\"Employee\""] + | | +- Column[@CanonicalImage = "\"Employee\"", @Image = "\"Employee\""] + | | +- ID[@CanonicalImage = "\"Employee\"", @Image = "\"Employee\""] + | +- SqlExpression[@CanonicalImage = "\"Cycle\"", @Image = "\"Cycle\""] + | | +- PrimaryPrefix[@CanonicalImage = "\"Cycle\"", @Image = "\"Cycle\"", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "\"Cycle\"", @Image = "\"Cycle\""] + | | +- Column[@CanonicalImage = "\"Cycle\"", @Image = "\"Cycle\""] + | | +- ID[@CanonicalImage = "\"Cycle\"", @Image = "\"Cycle\""] + | +- SqlExpression[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | +- PrimaryPrefix[@CanonicalImage = "LEVEL", @Image = "LEVEL", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | +- Column[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | +- ID[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | +- SqlExpression[@CanonicalImage = "\"Path\"", @Image = "\"Path\""] + | +- PrimaryPrefix[@CanonicalImage = "\"Path\"", @Image = "\"Path\"", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "\"Path\"", @Image = "\"Path\""] + | +- Column[@CanonicalImage = "\"Path\"", @Image = "\"Path\""] + | +- ID[@CanonicalImage = "\"Path\"", @Image = "\"Path\""] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "LTRIM", @Image = "LTRIM"] + | | +- PrimaryPrefix[@CanonicalImage = "LTRIM", @Image = "LTRIM", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "LTRIM", @Image = "LTRIM"] + | | +- FunctionName[@CanonicalImage = "LTRIM", @Image = "LTRIM"] + | | | +- ID[@CanonicalImage = "LTRIM", @Image = "LTRIM"] + | | +- Arguments[@ArgumentCount = 2, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "SYS_CONNECT_BY_PATH", @Image = "SYS_CONNECT_BY_PATH"] + | | | +- PrimaryPrefix[@CanonicalImage = "SYS_CONNECT_BY_PATH", @Image = "SYS_CONNECT_BY_PATH", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "SYS_CONNECT_BY_PATH", @Image = "SYS_CONNECT_BY_PATH"] + | | | +- FunctionName[@CanonicalImage = "SYS_CONNECT_BY_PATH", @Image = "SYS_CONNECT_BY_PATH"] + | | | | +- ID[@CanonicalImage = "SYS_CONNECT_BY_PATH", @Image = "SYS_CONNECT_BY_PATH"] + | | | +- Arguments[@ArgumentCount = 2, @CanonicalImage = null] + | | | +- ArgumentList[@CanonicalImage = null] + | | | +- Argument[@CanonicalImage = null] + | | | | +- Expression[@CanonicalImage = "WAREHOUSE_ID", @Image = "warehouse_id"] + | | | | +- PrimaryPrefix[@CanonicalImage = "WAREHOUSE_ID", @Image = "warehouse_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "WAREHOUSE_ID", @Image = "warehouse_id"] + | | | | +- Column[@CanonicalImage = "WAREHOUSE_ID", @Image = "warehouse_id"] + | | | | +- ID[@CanonicalImage = "WAREHOUSE_ID", @Image = "warehouse_id"] + | | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "\',\'", @Image = "\',\'"] + | | | +- PrimaryPrefix[@CanonicalImage = "\',\'", @Image = "\',\'", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "\',\'", @Image = "\',\'"] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "\',\'", @Image = "\',\'"] + | | +- PrimaryPrefix[@CanonicalImage = "\',\'", @Image = "\',\'", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "\',\'", @Image = "\',\'"] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "TEST", @Image = "test"] + | | +- ID[@CanonicalImage = "TEST", @Image = "test"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- QueryBlock[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | | +- SelectList[@CanonicalImage = null] + | | | +- SqlExpression[@CanonicalImage = "ROWNUM", @Image = "ROWNUM"] + | | | | +- PrimaryPrefix[@CanonicalImage = "ROWNUM", @Image = "ROWNUM", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "ROWNUM", @Image = "ROWNUM"] + | | | +- ColumnAlias[@CanonicalImage = "R", @Image = "r"] + | | | | +- ID[@CanonicalImage = "R", @Image = "r"] + | | | +- SqlExpression[@CanonicalImage = "WAREHOUSE_ID", @Image = "warehouse_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "WAREHOUSE_ID", @Image = "warehouse_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "WAREHOUSE_ID", @Image = "warehouse_id"] + | | | +- Column[@CanonicalImage = "WAREHOUSE_ID", @Image = "warehouse_id"] + | | | +- ID[@CanonicalImage = "WAREHOUSE_ID", @Image = "warehouse_id"] + | | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "WAREHOUSES", @Image = "warehouses"] + | | +- ID[@CanonicalImage = "WAREHOUSES", @Image = "warehouses"] + | +- WhereClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "CONNECT_BY_ISLEAF", @Image = "CONNECT_BY_ISLEAF"] + | | | +- PrimaryPrefix[@CanonicalImage = "CONNECT_BY_ISLEAF", @Image = "CONNECT_BY_ISLEAF", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "CONNECT_BY_ISLEAF", @Image = "CONNECT_BY_ISLEAF"] + | | | +- Column[@CanonicalImage = "CONNECT_BY_ISLEAF", @Image = "CONNECT_BY_ISLEAF"] + | | | +- ID[@CanonicalImage = "CONNECT_BY_ISLEAF", @Image = "CONNECT_BY_ISLEAF"] + | | +- SqlExpression[@CanonicalImage = "1", @Image = "1"] + | | +- PrimaryPrefix[@CanonicalImage = "1", @Image = "1", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "1", @Image = "1"] + | | +- NumericLiteral[@CanonicalImage = "1", @Image = "1"] + | +- HierarchicalQueryClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | | +- SqlExpression[@CanonicalImage = "R", @Image = "r"] + | | | | +- PrimaryPrefix[@CanonicalImage = "R", @Image = "r", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "R", @Image = "r"] + | | | | +- Column[@CanonicalImage = "R", @Image = "r"] + | | | | +- ID[@CanonicalImage = "R", @Image = "r"] + | | | +- SqlExpression[@CanonicalImage = "1", @Image = "1"] + | | | +- PrimaryPrefix[@CanonicalImage = "1", @Image = "1", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "1", @Image = "1"] + | | | +- NumericLiteral[@CanonicalImage = "1", @Image = "1"] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "R", @Image = "r"] + | | | +- PrimaryPrefix[@CanonicalImage = "R", @Image = "r", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "R", @Image = "r"] + | | | +- Column[@CanonicalImage = "R", @Image = "r"] + | | | +- ID[@CanonicalImage = "R", @Image = "r"] + | | +- SqlExpression[@CanonicalImage = "PRIOR R + 1", @Image = " PRIOR r + 1"] + | | +- AdditiveExpression[@CanonicalImage = "PRIOR R + 1", @Image = " PRIOR r + 1"] + | | +- PrimaryPrefix[@CanonicalImage = "R", @Image = "r", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "R", @Image = "r"] + | | | +- Column[@CanonicalImage = "R", @Image = "r"] + | | | +- ID[@CanonicalImage = "R", @Image = "r"] + | | +- PrimaryPrefix[@CanonicalImage = "1", @Image = "1", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "1", @Image = "1"] + | | +- NumericLiteral[@CanonicalImage = "1", @Image = "1"] + | +- OrderByClause[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "WAREHOUSE_ID", @Image = "warehouse_id"] + | +- PrimaryPrefix[@CanonicalImage = "WAREHOUSE_ID", @Image = "warehouse_id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "WAREHOUSE_ID", @Image = "warehouse_id"] + | +- Column[@CanonicalImage = "WAREHOUSE_ID", @Image = "warehouse_id"] + | +- ID[@CanonicalImage = "WAREHOUSE_ID", @Image = "warehouse_id"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | +- ColumnAlias[@CanonicalImage = "\"Employee\"", @Image = "\"Employee\""] + | | | +- ID[@CanonicalImage = "\"Employee\"", @Image = "\"Employee\""] + | | +- SqlExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | +- ColumnAlias[@CanonicalImage = "\"Manager\"", @Image = "\"Manager\""] + | | | +- ID[@CanonicalImage = "\"Manager\"", @Image = "\"Manager\""] + | | +- SqlExpression[@CanonicalImage = "LEVEL - 1", @Image = "LEVEL - 1"] + | | | +- AdditiveExpression[@CanonicalImage = "LEVEL - 1", @Image = "LEVEL - 1"] + | | | +- PrimaryPrefix[@CanonicalImage = "LEVEL", @Image = "LEVEL", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | | | +- Column[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | | | +- ID[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | | +- PrimaryPrefix[@CanonicalImage = "1", @Image = "1", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "1", @Image = "1"] + | | | +- NumericLiteral[@CanonicalImage = "1", @Image = "1"] + | | +- ColumnAlias[@CanonicalImage = "\"Pathlen\"", @Image = "\"Pathlen\""] + | | | +- ID[@CanonicalImage = "\"Pathlen\"", @Image = "\"Pathlen\""] + | | +- SqlExpression[@CanonicalImage = "SYS_CONNECT_BY_PATH", @Image = "SYS_CONNECT_BY_PATH"] + | | | +- PrimaryPrefix[@CanonicalImage = "SYS_CONNECT_BY_PATH", @Image = "SYS_CONNECT_BY_PATH", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "SYS_CONNECT_BY_PATH", @Image = "SYS_CONNECT_BY_PATH"] + | | | +- FunctionName[@CanonicalImage = "SYS_CONNECT_BY_PATH", @Image = "SYS_CONNECT_BY_PATH"] + | | | | +- ID[@CanonicalImage = "SYS_CONNECT_BY_PATH", @Image = "SYS_CONNECT_BY_PATH"] + | | | +- Arguments[@ArgumentCount = 2, @CanonicalImage = null] + | | | +- ArgumentList[@CanonicalImage = null] + | | | +- Argument[@CanonicalImage = null] + | | | | +- Expression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "\'/\'", @Image = "\'/\'"] + | | | +- PrimaryPrefix[@CanonicalImage = "\'/\'", @Image = "\'/\'", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "\'/\'", @Image = "\'/\'"] + | | +- ColumnAlias[@CanonicalImage = "\"Path\"", @Image = "\"Path\""] + | | +- ID[@CanonicalImage = "\"Path\"", @Image = "\"Path\""] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "TEST", @Image = "test"] + | | +- ID[@CanonicalImage = "TEST", @Image = "test"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- WhereClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = "AND"] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = ">"] + | | | +- SqlExpression[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | | | +- PrimaryPrefix[@CanonicalImage = "LEVEL", @Image = "LEVEL", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | | | +- Column[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | | | +- ID[@CanonicalImage = "LEVEL", @Image = "LEVEL"] + | | | +- SqlExpression[@CanonicalImage = "1", @Image = "1"] + | | | +- PrimaryPrefix[@CanonicalImage = "1", @Image = "1", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "1", @Image = "1"] + | | | +- NumericLiteral[@CanonicalImage = "1", @Image = "1"] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | +- SqlExpression[@CanonicalImage = "110", @Image = "110"] + | | +- PrimaryPrefix[@CanonicalImage = "110", @Image = "110", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "110", @Image = "110"] + | | +- NumericLiteral[@CanonicalImage = "110", @Image = "110"] + | +- HierarchicalQueryClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "PRIOR EMPLOYEE_ID", @Image = " PRIOR employee_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- SqlExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- PrimaryPrefix[@CanonicalImage = "MANAGER_ID", @Image = "manager_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- Column[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | | +- ID[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | +- OrderByClause[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "\"Employee\"", @Image = "\"Employee\""] + | | +- PrimaryPrefix[@CanonicalImage = "\"Employee\"", @Image = "\"Employee\"", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "\"Employee\"", @Image = "\"Employee\""] + | | +- Column[@CanonicalImage = "\"Employee\"", @Image = "\"Employee\""] + | | +- ID[@CanonicalImage = "\"Employee\"", @Image = "\"Employee\""] + | +- SqlExpression[@CanonicalImage = "\"Manager\"", @Image = "\"Manager\""] + | | +- PrimaryPrefix[@CanonicalImage = "\"Manager\"", @Image = "\"Manager\"", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "\"Manager\"", @Image = "\"Manager\""] + | | +- Column[@CanonicalImage = "\"Manager\"", @Image = "\"Manager\""] + | | +- ID[@CanonicalImage = "\"Manager\"", @Image = "\"Manager\""] + | +- SqlExpression[@CanonicalImage = "\"Pathlen\"", @Image = "\"Pathlen\""] + | | +- PrimaryPrefix[@CanonicalImage = "\"Pathlen\"", @Image = "\"Pathlen\"", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "\"Pathlen\"", @Image = "\"Pathlen\""] + | | +- Column[@CanonicalImage = "\"Pathlen\"", @Image = "\"Pathlen\""] + | | +- ID[@CanonicalImage = "\"Pathlen\"", @Image = "\"Pathlen\""] + | +- SqlExpression[@CanonicalImage = "\"Path\"", @Image = "\"Path\""] + | +- PrimaryPrefix[@CanonicalImage = "\"Path\"", @Image = "\"Path\"", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "\"Path\"", @Image = "\"Path\""] + | +- Column[@CanonicalImage = "\"Path\"", @Image = "\"Path\""] + | +- ID[@CanonicalImage = "\"Path\"", @Image = "\"Path\""] + +- Statement[@CanonicalImage = null] + +- UnlabelledStatement[@CanonicalImage = null] + +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + +- SelectList[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "NAME", @Image = "name"] + | | +- PrimaryPrefix[@CanonicalImage = "NAME", @Image = "name", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "NAME", @Image = "name"] + | | +- Column[@CanonicalImage = "NAME", @Image = "name"] + | | +- ID[@CanonicalImage = "NAME", @Image = "name"] + | +- SqlExpression[@CanonicalImage = "SUM", @Image = "SUM"] + | | +- PrimaryPrefix[@CanonicalImage = "SUM", @Image = "SUM", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "SUM", @Image = "SUM"] + | | +- FunctionName[@CanonicalImage = "SUM", @Image = "SUM"] + | | | +- ID[@CanonicalImage = "SUM", @Image = "SUM"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "SALARY", @Image = "salary"] + | | +- PrimaryPrefix[@CanonicalImage = "SALARY", @Image = "salary", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "SALARY", @Image = "salary"] + | | +- Column[@CanonicalImage = "SALARY", @Image = "salary"] + | | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + | +- ColumnAlias[@CanonicalImage = "\"Total_Salary\"", @Image = "\"Total_Salary\""] + | +- ID[@CanonicalImage = "\"Total_Salary\"", @Image = "\"Total_Salary\""] + +- IntoClause[@CanonicalImage = null] + | +- VariableName[@CanonicalImage = "TEST", @Image = "test"] + | +- ID[@CanonicalImage = "TEST", @Image = "test"] + +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | +- QueryBlock[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | +- ColumnAlias[@CanonicalImage = "NAME", @Image = "name"] + | | | +- ID[@CanonicalImage = "NAME", @Image = "name"] + | | +- SqlExpression[@CanonicalImage = "SALARY", @Image = "Salary"] + | | +- PrimaryPrefix[@CanonicalImage = "SALARY", @Image = "Salary", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "SALARY", @Image = "Salary"] + | | +- Column[@CanonicalImage = "SALARY", @Image = "Salary"] + | | +- ID[@CanonicalImage = "SALARY", @Image = "Salary"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- WhereClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | +- SqlExpression[@CanonicalImage = "110", @Image = "110"] + | | +- PrimaryPrefix[@CanonicalImage = "110", @Image = "110", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "110", @Image = "110"] + | | +- NumericLiteral[@CanonicalImage = "110", @Image = "110"] + | +- HierarchicalQueryClause[@CanonicalImage = null] + | +- Condition[@CanonicalImage = null] + | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | +- SqlExpression[@CanonicalImage = "PRIOR EMPLOYEE_ID", @Image = " PRIOR employee_id"] + | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- SqlExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | +- PrimaryPrefix[@CanonicalImage = "MANAGER_ID", @Image = "manager_id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | +- Column[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + | +- ID[@CanonicalImage = "MANAGER_ID", @Image = "manager_id"] + +- GroupByClause[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "NAME", @Image = "name"] + | +- PrimaryPrefix[@CanonicalImage = "NAME", @Image = "name", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "NAME", @Image = "name"] + | +- Column[@CanonicalImage = "NAME", @Image = "name"] + | +- ID[@CanonicalImage = "NAME", @Image = "name"] + +- OrderByClause[@CanonicalImage = null] + +- SqlExpression[@CanonicalImage = "NAME", @Image = "name"] + | +- PrimaryPrefix[@CanonicalImage = "NAME", @Image = "name", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "NAME", @Image = "name"] + | +- Column[@CanonicalImage = "NAME", @Image = "name"] + | +- ID[@CanonicalImage = "NAME", @Image = "name"] + +- SqlExpression[@CanonicalImage = "\"Total_Salary\"", @Image = "\"Total_Salary\""] + +- PrimaryPrefix[@CanonicalImage = "\"Total_Salary\"", @Image = "\"Total_Salary\"", @SelfModifier = false] + +- SimpleExpression[@CanonicalImage = "\"Total_Salary\"", @Image = "\"Total_Salary\""] + +- Column[@CanonicalImage = "\"Total_Salary\"", @Image = "\"Total_Salary\""] + +- ID[@CanonicalImage = "\"Total_Salary\"", @Image = "\"Total_Salary\""] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatement.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatement.txt new file mode 100644 index 00000000000..f4a46cdcd09 --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatement.txt @@ -0,0 +1,777 @@ ++- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- Global[@CanonicalImage = null] + +- Block[@CanonicalImage = null] + +- DeclarativeSection[@CanonicalImage = null] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- SubTypeDefinition[@CanonicalImage = "T_CMER_IDS", @Image = "t_cmer_ids"] + | | +- QualifiedID[@CanonicalImage = "T_CMER_IDS", @Image = "t_cmer_ids"] + | | +- Datatype[@CanonicalImage = "COMP_MPRC_EMP_ROLE.ID%TYPE", @Image = "comp_mprc_emp_role.id%TYPE", @TypeImage = "comp_mprc_emp_role.id%TYPE"] + | | +- QualifiedName[@CanonicalImage = "COMP_MPRC_EMP_ROLE.ID", @Image = "comp_mprc_emp_role.id"] + | | +- UnqualifiedID[@CanonicalImage = "COMP_MPRC_EMP_ROLE", @Image = "comp_mprc_emp_role"] + | | +- QualifiedID[@CanonicalImage = "ID", @Image = "id"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- SubTypeDefinition[@CanonicalImage = "T_VERSIONS", @Image = "t_versions"] + | | +- QualifiedID[@CanonicalImage = "T_VERSIONS", @Image = "t_versions"] + | | +- Datatype[@CanonicalImage = "COMP_MPRC_EMP_ROLE.VERSION%TYPE", @Image = "comp_mprc_emp_role.version%TYPE", @TypeImage = "comp_mprc_emp_role.version%TYPE"] + | | +- QualifiedName[@CanonicalImage = "COMP_MPRC_EMP_ROLE.VERSION", @Image = "comp_mprc_emp_role.version"] + | | +- UnqualifiedID[@CanonicalImage = "COMP_MPRC_EMP_ROLE", @Image = "comp_mprc_emp_role"] + | | +- QualifiedID[@CanonicalImage = "VERSION", @Image = "version"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- SubTypeDefinition[@CanonicalImage = "T_CMP_IDS", @Image = "t_cmp_ids"] + | | +- QualifiedID[@CanonicalImage = "T_CMP_IDS", @Image = "t_cmp_ids"] + | | +- Datatype[@CanonicalImage = "COMP_MPRC_EMP_ROLE.CMP_ID%TYPE", @Image = "comp_mprc_emp_role.cmp_id%TYPE", @TypeImage = "comp_mprc_emp_role.cmp_id%TYPE"] + | | +- QualifiedName[@CanonicalImage = "COMP_MPRC_EMP_ROLE.CMP_ID", @Image = "comp_mprc_emp_role.cmp_id"] + | | +- UnqualifiedID[@CanonicalImage = "COMP_MPRC_EMP_ROLE", @Image = "comp_mprc_emp_role"] + | | +- QualifiedID[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- SubTypeDefinition[@CanonicalImage = "T_MPRC_CODES", @Image = "t_mprc_codes"] + | | +- QualifiedID[@CanonicalImage = "T_MPRC_CODES", @Image = "t_mprc_codes"] + | | +- Datatype[@CanonicalImage = "COMP_MPRC_EMP_ROLE.MPRC_CODE%TYPE", @Image = "comp_mprc_emp_role.mprc_code%TYPE", @TypeImage = "comp_mprc_emp_role.mprc_code%TYPE"] + | | +- QualifiedName[@CanonicalImage = "COMP_MPRC_EMP_ROLE.MPRC_CODE", @Image = "comp_mprc_emp_role.mprc_code"] + | | +- UnqualifiedID[@CanonicalImage = "COMP_MPRC_EMP_ROLE", @Image = "comp_mprc_emp_role"] + | | +- QualifiedID[@CanonicalImage = "MPRC_CODE", @Image = "mprc_code"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- SubTypeDefinition[@CanonicalImage = "T_EMP_IDS", @Image = "t_emp_ids"] + | | +- QualifiedID[@CanonicalImage = "T_EMP_IDS", @Image = "t_emp_ids"] + | | +- Datatype[@CanonicalImage = "COMP_MPRC_EMP_ROLE.EMP_ID%TYPE", @Image = "comp_mprc_emp_role.emp_id%TYPE", @TypeImage = "comp_mprc_emp_role.emp_id%TYPE"] + | | +- QualifiedName[@CanonicalImage = "COMP_MPRC_EMP_ROLE.EMP_ID", @Image = "comp_mprc_emp_role.emp_id"] + | | +- UnqualifiedID[@CanonicalImage = "COMP_MPRC_EMP_ROLE", @Image = "comp_mprc_emp_role"] + | | +- QualifiedID[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- SubTypeDefinition[@CanonicalImage = "T_EMP_ROLE_CODES", @Image = "t_emp_role_codes"] + | | +- QualifiedID[@CanonicalImage = "T_EMP_ROLE_CODES", @Image = "t_emp_role_codes"] + | | +- Datatype[@CanonicalImage = "COMP_MPRC_EMP_ROLE.EMP_ROLE_CODE%TYPE", @Image = "comp_mprc_emp_role.emp_role_code%TYPE", @TypeImage = "comp_mprc_emp_role.emp_role_code%TYPE"] + | | +- QualifiedName[@CanonicalImage = "COMP_MPRC_EMP_ROLE.EMP_ROLE_CODE", @Image = "comp_mprc_emp_role.emp_role_code"] + | | +- UnqualifiedID[@CanonicalImage = "COMP_MPRC_EMP_ROLE", @Image = "comp_mprc_emp_role"] + | | +- QualifiedID[@CanonicalImage = "EMP_ROLE_CODE", @Image = "emp_role_code"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- SubTypeDefinition[@CanonicalImage = "T_GSN_IDS", @Image = "t_gsn_ids"] + | | +- QualifiedID[@CanonicalImage = "T_GSN_IDS", @Image = "t_gsn_ids"] + | | +- Datatype[@CanonicalImage = "COMP_MPRC_EMP_ROLE.GSN_ID%TYPE", @Image = "comp_mprc_emp_role.gsn_id%TYPE", @TypeImage = "comp_mprc_emp_role.gsn_id%TYPE"] + | | +- QualifiedName[@CanonicalImage = "COMP_MPRC_EMP_ROLE.GSN_ID", @Image = "comp_mprc_emp_role.gsn_id"] + | | +- UnqualifiedID[@CanonicalImage = "COMP_MPRC_EMP_ROLE", @Image = "comp_mprc_emp_role"] + | | +- QualifiedID[@CanonicalImage = "GSN_ID", @Image = "gsn_id"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- SubTypeDefinition[@CanonicalImage = "T_DEP_CODES", @Image = "t_dep_codes"] + | | +- QualifiedID[@CanonicalImage = "T_DEP_CODES", @Image = "t_dep_codes"] + | | +- Datatype[@CanonicalImage = "COMP_MPRC_EMP_ROLE.DEP_CODE%TYPE", @Image = "comp_mprc_emp_role.dep_code%TYPE", @TypeImage = "comp_mprc_emp_role.dep_code%TYPE"] + | | +- QualifiedName[@CanonicalImage = "COMP_MPRC_EMP_ROLE.DEP_CODE", @Image = "comp_mprc_emp_role.dep_code"] + | | +- UnqualifiedID[@CanonicalImage = "COMP_MPRC_EMP_ROLE", @Image = "comp_mprc_emp_role"] + | | +- QualifiedID[@CanonicalImage = "DEP_CODE", @Image = "dep_code"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- SubTypeDefinition[@CanonicalImage = "T_VALIDFROMS", @Image = "t_validfroms"] + | | +- QualifiedID[@CanonicalImage = "T_VALIDFROMS", @Image = "t_validfroms"] + | | +- Datatype[@CanonicalImage = "DATE", @Image = "DATE", @TypeImage = "DATE"] + | | +- ScalarDataTypeName[@CanonicalImage = "DATE", @Image = "DATE"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- SubTypeDefinition[@CanonicalImage = "T_VALIDTOS", @Image = "t_validtos"] + | | +- QualifiedID[@CanonicalImage = "T_VALIDTOS", @Image = "t_validtos"] + | | +- Datatype[@CanonicalImage = "DATE", @Image = "DATE", @TypeImage = "DATE"] + | | +- ScalarDataTypeName[@CanonicalImage = "DATE", @Image = "DATE"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- SubTypeDefinition[@CanonicalImage = "T_FL_ACTIVES", @Image = "t_fl_actives"] + | | +- QualifiedID[@CanonicalImage = "T_FL_ACTIVES", @Image = "t_fl_actives"] + | | +- Datatype[@CanonicalImage = "VARCHAR2(1)", @Image = "VARCHAR2(1)", @TypeImage = "VARCHAR2(1)"] + | | +- ScalarDataTypeName[@CanonicalImage = "VARCHAR2(1)", @Image = "VARCHAR2(1)"] + | | +- NumericLiteral[@CanonicalImage = "1", @Image = "1"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- SubTypeDefinition[@CanonicalImage = "T_REPORTING_LISTS", @Image = "t_reporting_lists"] + | | +- QualifiedID[@CanonicalImage = "T_REPORTING_LISTS", @Image = "t_reporting_lists"] + | | +- Datatype[@CanonicalImage = "V_SFM_EMP_ROLE_CNY_REPG.REPORTING_GROUPS%TYPE", @Image = "v_sfm_emp_role_cny_repg.reporting_groups%TYPE", @TypeImage = "v_sfm_emp_role_cny_repg.reporting_groups%TYPE"] + | | +- QualifiedName[@CanonicalImage = "V_SFM_EMP_ROLE_CNY_REPG.REPORTING_GROUPS", @Image = "v_sfm_emp_role_cny_repg.reporting_groups"] + | | +- UnqualifiedID[@CanonicalImage = "V_SFM_EMP_ROLE_CNY_REPG", @Image = "v_sfm_emp_role_cny_repg"] + | | +- QualifiedID[@CanonicalImage = "REPORTING_GROUPS", @Image = "reporting_groups"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | +- VariableOrConstantDeclarator[@CanonicalImage = "V_CMER_IDS T_CMER_IDS", @Image = "v_cmer_ids t_cmer_ids"] + | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "V_CMER_IDS", @Image = "v_cmer_ids"] + | | | +- ID[@CanonicalImage = "V_CMER_IDS", @Image = "v_cmer_ids"] + | | +- Datatype[@CanonicalImage = "T_CMER_IDS", @Image = "t_cmer_ids", @TypeImage = "t_cmer_ids"] + | | +- QualifiedName[@CanonicalImage = "T_CMER_IDS", @Image = "t_cmer_ids"] + | | +- UnqualifiedID[@CanonicalImage = "T_CMER_IDS", @Image = "t_cmer_ids"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | +- VariableOrConstantDeclarator[@CanonicalImage = "V_VERSIONS T_VERSIONS", @Image = "v_versions t_versions"] + | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "V_VERSIONS", @Image = "v_versions"] + | | | +- ID[@CanonicalImage = "V_VERSIONS", @Image = "v_versions"] + | | +- Datatype[@CanonicalImage = "T_VERSIONS", @Image = "t_versions", @TypeImage = "t_versions"] + | | +- QualifiedName[@CanonicalImage = "T_VERSIONS", @Image = "t_versions"] + | | +- UnqualifiedID[@CanonicalImage = "T_VERSIONS", @Image = "t_versions"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | +- VariableOrConstantDeclarator[@CanonicalImage = "V_CMP_IDS T_CMP_IDS", @Image = "v_cmp_ids t_cmp_ids"] + | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "V_CMP_IDS", @Image = "v_cmp_ids"] + | | | +- ID[@CanonicalImage = "V_CMP_IDS", @Image = "v_cmp_ids"] + | | +- Datatype[@CanonicalImage = "T_CMP_IDS", @Image = "t_cmp_ids", @TypeImage = "t_cmp_ids"] + | | +- QualifiedName[@CanonicalImage = "T_CMP_IDS", @Image = "t_cmp_ids"] + | | +- UnqualifiedID[@CanonicalImage = "T_CMP_IDS", @Image = "t_cmp_ids"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | +- VariableOrConstantDeclarator[@CanonicalImage = "V_MPRC_CODES T_MPRC_CODES", @Image = "v_mprc_codes t_mprc_codes"] + | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "V_MPRC_CODES", @Image = "v_mprc_codes"] + | | | +- ID[@CanonicalImage = "V_MPRC_CODES", @Image = "v_mprc_codes"] + | | +- Datatype[@CanonicalImage = "T_MPRC_CODES", @Image = "t_mprc_codes", @TypeImage = "t_mprc_codes"] + | | +- QualifiedName[@CanonicalImage = "T_MPRC_CODES", @Image = "t_mprc_codes"] + | | +- UnqualifiedID[@CanonicalImage = "T_MPRC_CODES", @Image = "t_mprc_codes"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | +- VariableOrConstantDeclarator[@CanonicalImage = "V_EMP_IDS T_EMP_IDS", @Image = "v_emp_ids t_emp_ids"] + | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "V_EMP_IDS", @Image = "v_emp_ids"] + | | | +- ID[@CanonicalImage = "V_EMP_IDS", @Image = "v_emp_ids"] + | | +- Datatype[@CanonicalImage = "T_EMP_IDS", @Image = "t_emp_ids", @TypeImage = "t_emp_ids"] + | | +- QualifiedName[@CanonicalImage = "T_EMP_IDS", @Image = "t_emp_ids"] + | | +- UnqualifiedID[@CanonicalImage = "T_EMP_IDS", @Image = "t_emp_ids"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | +- VariableOrConstantDeclarator[@CanonicalImage = "V_EMP_ROLE_CODES T_EMP_ROLE_CODES", @Image = "v_emp_role_codes t_emp_role_codes"] + | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "V_EMP_ROLE_CODES", @Image = "v_emp_role_codes"] + | | | +- ID[@CanonicalImage = "V_EMP_ROLE_CODES", @Image = "v_emp_role_codes"] + | | +- Datatype[@CanonicalImage = "T_EMP_ROLE_CODES", @Image = "t_emp_role_codes", @TypeImage = "t_emp_role_codes"] + | | +- QualifiedName[@CanonicalImage = "T_EMP_ROLE_CODES", @Image = "t_emp_role_codes"] + | | +- UnqualifiedID[@CanonicalImage = "T_EMP_ROLE_CODES", @Image = "t_emp_role_codes"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | +- VariableOrConstantDeclarator[@CanonicalImage = "V_GSN_IDS T_GSN_IDS", @Image = "v_gsn_ids t_gsn_ids"] + | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "V_GSN_IDS", @Image = "v_gsn_ids"] + | | | +- ID[@CanonicalImage = "V_GSN_IDS", @Image = "v_gsn_ids"] + | | +- Datatype[@CanonicalImage = "T_GSN_IDS", @Image = "t_gsn_ids", @TypeImage = "t_gsn_ids"] + | | +- QualifiedName[@CanonicalImage = "T_GSN_IDS", @Image = "t_gsn_ids"] + | | +- UnqualifiedID[@CanonicalImage = "T_GSN_IDS", @Image = "t_gsn_ids"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | +- VariableOrConstantDeclarator[@CanonicalImage = "V_DEP_CODES T_DEP_CODES", @Image = "v_dep_codes t_dep_codes"] + | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "V_DEP_CODES", @Image = "v_dep_codes"] + | | | +- ID[@CanonicalImage = "V_DEP_CODES", @Image = "v_dep_codes"] + | | +- Datatype[@CanonicalImage = "T_DEP_CODES", @Image = "t_dep_codes", @TypeImage = "t_dep_codes"] + | | +- QualifiedName[@CanonicalImage = "T_DEP_CODES", @Image = "t_dep_codes"] + | | +- UnqualifiedID[@CanonicalImage = "T_DEP_CODES", @Image = "t_dep_codes"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | +- VariableOrConstantDeclarator[@CanonicalImage = "V_VALIDFROMS T_VALIDFROMS", @Image = "v_validfroms t_validfroms"] + | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "V_VALIDFROMS", @Image = "v_validfroms"] + | | | +- ID[@CanonicalImage = "V_VALIDFROMS", @Image = "v_validfroms"] + | | +- Datatype[@CanonicalImage = "T_VALIDFROMS", @Image = "t_validfroms", @TypeImage = "t_validfroms"] + | | +- QualifiedName[@CanonicalImage = "T_VALIDFROMS", @Image = "t_validfroms"] + | | +- UnqualifiedID[@CanonicalImage = "T_VALIDFROMS", @Image = "t_validfroms"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | +- VariableOrConstantDeclarator[@CanonicalImage = "V_VALIDTOS T_VALIDTOS", @Image = "v_validtos t_validtos"] + | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "V_VALIDTOS", @Image = "v_validtos"] + | | | +- ID[@CanonicalImage = "V_VALIDTOS", @Image = "v_validtos"] + | | +- Datatype[@CanonicalImage = "T_VALIDTOS", @Image = "t_validtos", @TypeImage = "t_validtos"] + | | +- QualifiedName[@CanonicalImage = "T_VALIDTOS", @Image = "t_validtos"] + | | +- UnqualifiedID[@CanonicalImage = "T_VALIDTOS", @Image = "t_validtos"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | +- VariableOrConstantDeclarator[@CanonicalImage = "V_FL_ACTIVES T_FL_ACTIVES", @Image = "v_fl_actives t_fl_actives"] + | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "V_FL_ACTIVES", @Image = "v_fl_actives"] + | | | +- ID[@CanonicalImage = "V_FL_ACTIVES", @Image = "v_fl_actives"] + | | +- Datatype[@CanonicalImage = "T_FL_ACTIVES", @Image = "t_fl_actives", @TypeImage = "t_fl_actives"] + | | +- QualifiedName[@CanonicalImage = "T_FL_ACTIVES", @Image = "t_fl_actives"] + | | +- UnqualifiedID[@CanonicalImage = "T_FL_ACTIVES", @Image = "t_fl_actives"] + | +- DeclarativeUnit[@CanonicalImage = null] + | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | +- VariableOrConstantDeclarator[@CanonicalImage = "V_REPORTING_LISTS T_REPORTING_LISTS", @Image = "v_reporting_lists t_reporting_lists"] + | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "V_REPORTING_LISTS", @Image = "v_reporting_lists"] + | | +- ID[@CanonicalImage = "V_REPORTING_LISTS", @Image = "v_reporting_lists"] + | +- Datatype[@CanonicalImage = "T_REPORTING_LISTS", @Image = "t_reporting_lists", @TypeImage = "t_reporting_lists"] + | +- QualifiedName[@CanonicalImage = "T_REPORTING_LISTS", @Image = "t_reporting_lists"] + | +- UnqualifiedID[@CanonicalImage = "T_REPORTING_LISTS", @Image = "t_reporting_lists"] + +- Statement[@CanonicalImage = null] + +- UnlabelledStatement[@CanonicalImage = null] + +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + +- SelectList[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "CMER_ID", @Image = "cmer_id"] + | | +- PrimaryPrefix[@CanonicalImage = "CMER_ID", @Image = "cmer_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "CMER_ID", @Image = "cmer_id"] + | | +- Column[@CanonicalImage = "CMER_ID", @Image = "cmer_id"] + | | +- ID[@CanonicalImage = "CMER_ID", @Image = "cmer_id"] + | +- SqlExpression[@CanonicalImage = "VERSION", @Image = "version"] + | | +- PrimaryPrefix[@CanonicalImage = "VERSION", @Image = "version", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "VERSION", @Image = "version"] + | | +- Column[@CanonicalImage = "VERSION", @Image = "version"] + | | +- ID[@CanonicalImage = "VERSION", @Image = "version"] + | +- SqlExpression[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | | +- PrimaryPrefix[@CanonicalImage = "CMP_ID", @Image = "cmp_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | | +- Column[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | | +- ID[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | +- SqlExpression[@CanonicalImage = "MPRC_CODE", @Image = "mprc_code"] + | | +- PrimaryPrefix[@CanonicalImage = "MPRC_CODE", @Image = "mprc_code", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "MPRC_CODE", @Image = "mprc_code"] + | | +- Column[@CanonicalImage = "MPRC_CODE", @Image = "mprc_code"] + | | +- ID[@CanonicalImage = "MPRC_CODE", @Image = "mprc_code"] + | +- SqlExpression[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- PrimaryPrefix[@CanonicalImage = "EMP_ID", @Image = "emp_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- Column[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- ID[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | +- SqlExpression[@CanonicalImage = "EMP_ROLE_CODE", @Image = "emp_role_code"] + | | +- PrimaryPrefix[@CanonicalImage = "EMP_ROLE_CODE", @Image = "emp_role_code", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "EMP_ROLE_CODE", @Image = "emp_role_code"] + | | +- Column[@CanonicalImage = "EMP_ROLE_CODE", @Image = "emp_role_code"] + | | +- ID[@CanonicalImage = "EMP_ROLE_CODE", @Image = "emp_role_code"] + | +- SqlExpression[@CanonicalImage = "GSN_ID", @Image = "gsn_id"] + | | +- PrimaryPrefix[@CanonicalImage = "GSN_ID", @Image = "gsn_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "GSN_ID", @Image = "gsn_id"] + | | +- Column[@CanonicalImage = "GSN_ID", @Image = "gsn_id"] + | | +- ID[@CanonicalImage = "GSN_ID", @Image = "gsn_id"] + | +- SqlExpression[@CanonicalImage = "DEP_CODE", @Image = "dep_code"] + | | +- PrimaryPrefix[@CanonicalImage = "DEP_CODE", @Image = "dep_code", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "DEP_CODE", @Image = "dep_code"] + | | +- Column[@CanonicalImage = "DEP_CODE", @Image = "dep_code"] + | | +- ID[@CanonicalImage = "DEP_CODE", @Image = "dep_code"] + | +- SqlExpression[@CanonicalImage = "VALIDFROM", @Image = "validfrom"] + | | +- PrimaryPrefix[@CanonicalImage = "VALIDFROM", @Image = "validfrom", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "VALIDFROM", @Image = "validfrom"] + | | +- Column[@CanonicalImage = "VALIDFROM", @Image = "validfrom"] + | | +- ID[@CanonicalImage = "VALIDFROM", @Image = "validfrom"] + | +- SqlExpression[@CanonicalImage = "VALIDTO", @Image = "validto"] + | | +- PrimaryPrefix[@CanonicalImage = "VALIDTO", @Image = "validto", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "VALIDTO", @Image = "validto"] + | | +- Column[@CanonicalImage = "VALIDTO", @Image = "validto"] + | | +- ID[@CanonicalImage = "VALIDTO", @Image = "validto"] + | +- SqlExpression[@CanonicalImage = "FL_ACTIVE", @Image = "fl_active"] + | | +- PrimaryPrefix[@CanonicalImage = "FL_ACTIVE", @Image = "fl_active", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "FL_ACTIVE", @Image = "fl_active"] + | | +- Column[@CanonicalImage = "FL_ACTIVE", @Image = "fl_active"] + | | +- ID[@CanonicalImage = "FL_ACTIVE", @Image = "fl_active"] + | +- SqlExpression[@CanonicalImage = "REPORTING_LIST", @Image = "reporting_list"] + | +- PrimaryPrefix[@CanonicalImage = "REPORTING_LIST", @Image = "reporting_list", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "REPORTING_LIST", @Image = "reporting_list"] + | +- Column[@CanonicalImage = "REPORTING_LIST", @Image = "reporting_list"] + | +- ID[@CanonicalImage = "REPORTING_LIST", @Image = "reporting_list"] + +- BulkCollectIntoClause[@CanonicalImage = null] + | +- CollectionName[@CanonicalImage = "V_CMER_IDS", @Image = "v_cmer_ids"] + | | +- ID[@CanonicalImage = "V_CMER_IDS", @Image = "v_cmer_ids"] + | +- CollectionName[@CanonicalImage = "V_VERSIONS", @Image = "v_versions"] + | | +- ID[@CanonicalImage = "V_VERSIONS", @Image = "v_versions"] + | +- CollectionName[@CanonicalImage = "V_CMP_IDS", @Image = "v_cmp_ids"] + | | +- ID[@CanonicalImage = "V_CMP_IDS", @Image = "v_cmp_ids"] + | +- CollectionName[@CanonicalImage = "V_MPRC_CODES", @Image = "v_mprc_codes"] + | | +- ID[@CanonicalImage = "V_MPRC_CODES", @Image = "v_mprc_codes"] + | +- CollectionName[@CanonicalImage = "V_EMP_IDS", @Image = "v_emp_ids"] + | | +- ID[@CanonicalImage = "V_EMP_IDS", @Image = "v_emp_ids"] + | +- CollectionName[@CanonicalImage = "V_EMP_ROLE_CODES", @Image = "v_emp_role_codes"] + | | +- ID[@CanonicalImage = "V_EMP_ROLE_CODES", @Image = "v_emp_role_codes"] + | +- CollectionName[@CanonicalImage = "V_GSN_IDS", @Image = "v_gsn_ids"] + | | +- ID[@CanonicalImage = "V_GSN_IDS", @Image = "v_gsn_ids"] + | +- CollectionName[@CanonicalImage = "V_DEP_CODES", @Image = "v_dep_codes"] + | | +- ID[@CanonicalImage = "V_DEP_CODES", @Image = "v_dep_codes"] + | +- CollectionName[@CanonicalImage = "V_VALIDFROMS", @Image = "v_validfroms"] + | | +- ID[@CanonicalImage = "V_VALIDFROMS", @Image = "v_validfroms"] + | +- CollectionName[@CanonicalImage = "V_VALIDTOS", @Image = "v_validtos"] + | | +- ID[@CanonicalImage = "V_VALIDTOS", @Image = "v_validtos"] + | +- CollectionName[@CanonicalImage = "V_FL_ACTIVES", @Image = "v_fl_actives"] + | | +- ID[@CanonicalImage = "V_FL_ACTIVES", @Image = "v_fl_actives"] + | +- CollectionName[@CanonicalImage = "V_REPORTING_LISTS", @Image = "v_reporting_lists"] + | +- ID[@CanonicalImage = "V_REPORTING_LISTS", @Image = "v_reporting_lists"] + +- FromClause[@CanonicalImage = null] + +- TableReference[@CanonicalImage = null] + +- QueryBlock[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "CMER.CMER_ID", @Image = "cmer.cmer_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "CMER.CMER_ID", @Image = "cmer.cmer_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "CMER.CMER_ID", @Image = "cmer.cmer_id"] + | | | +- TableName[@CanonicalImage = "CMER", @Image = "cmer"] + | | | | +- ID[@CanonicalImage = "CMER", @Image = "cmer"] + | | | +- Column[@CanonicalImage = "CMER_ID", @Image = "cmer_id"] + | | | +- ID[@CanonicalImage = "CMER_ID", @Image = "cmer_id"] + | | +- SqlExpression[@CanonicalImage = "CMER.VERSION", @Image = "cmer.version"] + | | | +- PrimaryPrefix[@CanonicalImage = "CMER.VERSION", @Image = "cmer.version", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "CMER.VERSION", @Image = "cmer.version"] + | | | +- TableName[@CanonicalImage = "CMER", @Image = "cmer"] + | | | | +- ID[@CanonicalImage = "CMER", @Image = "cmer"] + | | | +- Column[@CanonicalImage = "VERSION", @Image = "version"] + | | | +- ID[@CanonicalImage = "VERSION", @Image = "version"] + | | +- SqlExpression[@CanonicalImage = "CMER.CMP_ID", @Image = "cmer.cmp_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "CMER.CMP_ID", @Image = "cmer.cmp_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "CMER.CMP_ID", @Image = "cmer.cmp_id"] + | | | +- TableName[@CanonicalImage = "CMER", @Image = "cmer"] + | | | | +- ID[@CanonicalImage = "CMER", @Image = "cmer"] + | | | +- Column[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | | | +- ID[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | | +- SqlExpression[@CanonicalImage = "CMER.MPRC_CODE", @Image = "cmer.mprc_code"] + | | | +- PrimaryPrefix[@CanonicalImage = "CMER.MPRC_CODE", @Image = "cmer.mprc_code", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "CMER.MPRC_CODE", @Image = "cmer.mprc_code"] + | | | +- TableName[@CanonicalImage = "CMER", @Image = "cmer"] + | | | | +- ID[@CanonicalImage = "CMER", @Image = "cmer"] + | | | +- Column[@CanonicalImage = "MPRC_CODE", @Image = "mprc_code"] + | | | +- ID[@CanonicalImage = "MPRC_CODE", @Image = "mprc_code"] + | | +- SqlExpression[@CanonicalImage = "CMER.EMP_ID", @Image = "cmer.emp_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "CMER.EMP_ID", @Image = "cmer.emp_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "CMER.EMP_ID", @Image = "cmer.emp_id"] + | | | +- TableName[@CanonicalImage = "CMER", @Image = "cmer"] + | | | | +- ID[@CanonicalImage = "CMER", @Image = "cmer"] + | | | +- Column[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | | +- ID[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- SqlExpression[@CanonicalImage = "CMER.EMP_ROLE_CODE", @Image = "cmer.emp_role_code"] + | | | +- PrimaryPrefix[@CanonicalImage = "CMER.EMP_ROLE_CODE", @Image = "cmer.emp_role_code", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "CMER.EMP_ROLE_CODE", @Image = "cmer.emp_role_code"] + | | | +- TableName[@CanonicalImage = "CMER", @Image = "cmer"] + | | | | +- ID[@CanonicalImage = "CMER", @Image = "cmer"] + | | | +- Column[@CanonicalImage = "EMP_ROLE_CODE", @Image = "emp_role_code"] + | | | +- ID[@CanonicalImage = "EMP_ROLE_CODE", @Image = "emp_role_code"] + | | +- SqlExpression[@CanonicalImage = "CMER.GSN_ID", @Image = "cmer.gsn_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "CMER.GSN_ID", @Image = "cmer.gsn_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "CMER.GSN_ID", @Image = "cmer.gsn_id"] + | | | +- TableName[@CanonicalImage = "CMER", @Image = "cmer"] + | | | | +- ID[@CanonicalImage = "CMER", @Image = "cmer"] + | | | +- Column[@CanonicalImage = "GSN_ID", @Image = "gsn_id"] + | | | +- ID[@CanonicalImage = "GSN_ID", @Image = "gsn_id"] + | | +- SqlExpression[@CanonicalImage = "CMER.DEP_CODE", @Image = "cmer.dep_code"] + | | | +- PrimaryPrefix[@CanonicalImage = "CMER.DEP_CODE", @Image = "cmer.dep_code", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "CMER.DEP_CODE", @Image = "cmer.dep_code"] + | | | +- TableName[@CanonicalImage = "CMER", @Image = "cmer"] + | | | | +- ID[@CanonicalImage = "CMER", @Image = "cmer"] + | | | +- Column[@CanonicalImage = "DEP_CODE", @Image = "dep_code"] + | | | +- ID[@CanonicalImage = "DEP_CODE", @Image = "dep_code"] + | | +- SqlExpression[@CanonicalImage = "TRUNC", @Image = "TRUNC"] + | | | +- PrimaryPrefix[@CanonicalImage = "TRUNC", @Image = "TRUNC", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "TRUNC", @Image = "TRUNC"] + | | | +- FunctionName[@CanonicalImage = "TRUNC", @Image = "TRUNC"] + | | | | +- ID[@CanonicalImage = "TRUNC", @Image = "TRUNC"] + | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | +- ArgumentList[@CanonicalImage = null] + | | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "INSERT_ENTRY.DMLTIME", @Image = "insert_entry.dmltime"] + | | | +- PrimaryPrefix[@CanonicalImage = "INSERT_ENTRY.DMLTIME", @Image = "insert_entry.dmltime", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "INSERT_ENTRY.DMLTIME", @Image = "insert_entry.dmltime"] + | | | +- TableName[@CanonicalImage = "INSERT_ENTRY", @Image = "insert_entry"] + | | | | +- ID[@CanonicalImage = "INSERT_ENTRY", @Image = "insert_entry"] + | | | +- Column[@CanonicalImage = "DMLTIME", @Image = "dmltime"] + | | | +- ID[@CanonicalImage = "DMLTIME", @Image = "dmltime"] + | | +- ColumnAlias[@CanonicalImage = "VALIDFROM", @Image = "validfrom"] + | | | +- ID[@CanonicalImage = "VALIDFROM", @Image = "validfrom"] + | | +- SqlExpression[@CanonicalImage = "NULL", @Image = "NULL"] + | | | +- PrimaryPrefix[@CanonicalImage = "NULL", @Image = "NULL", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "NULL", @Image = "NULL"] + | | | +- NullLiteral[@CanonicalImage = "NULL", @Image = "NULL"] + | | +- ColumnAlias[@CanonicalImage = "VALIDTO", @Image = "validto"] + | | | +- ID[@CanonicalImage = "VALIDTO", @Image = "validto"] + | | +- SqlExpression[@CanonicalImage = "\'Y\'", @Image = "\'Y\'"] + | | | +- PrimaryPrefix[@CanonicalImage = "\'Y\'", @Image = "\'Y\'", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "\'Y\'", @Image = "\'Y\'"] + | | +- ColumnAlias[@CanonicalImage = "FL_ACTIVE", @Image = "fl_active"] + | | | +- ID[@CanonicalImage = "FL_ACTIVE", @Image = "fl_active"] + | | +- SqlExpression[@CanonicalImage = "SFM.REPORTING_GROUPS", @Image = "sfm.reporting_groups"] + | | | +- PrimaryPrefix[@CanonicalImage = "SFM.REPORTING_GROUPS", @Image = "sfm.reporting_groups", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "SFM.REPORTING_GROUPS", @Image = "sfm.reporting_groups"] + | | | +- TableName[@CanonicalImage = "SFM", @Image = "sfm"] + | | | | +- ID[@CanonicalImage = "SFM", @Image = "sfm"] + | | | +- Column[@CanonicalImage = "REPORTING_GROUPS", @Image = "reporting_groups"] + | | | +- ID[@CanonicalImage = "REPORTING_GROUPS", @Image = "reporting_groups"] + | | +- ColumnAlias[@CanonicalImage = "REPORTING_LIST", @Image = "reporting_list"] + | | +- ID[@CanonicalImage = "REPORTING_LIST", @Image = "reporting_list"] + | +- FromClause[@CanonicalImage = null] + | +- JoinClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | | +- SchemaName[@CanonicalImage = "WEBCRM", @Image = "webcrm"] + | | | +- ID[@CanonicalImage = "WEBCRM", @Image = "webcrm"] + | | +- TableName[@CanonicalImage = "COMP_MPRC_EMP_ROLE", @Image = "comp_mprc_emp_role"] + | | | +- ID[@CanonicalImage = "COMP_MPRC_EMP_ROLE", @Image = "comp_mprc_emp_role"] + | | +- TableAlias[@CanonicalImage = "CMER", @Image = "cmer"] + | | +- ID[@CanonicalImage = "CMER", @Image = "cmer"] + | +- InnerCrossJoinClause[@CanonicalImage = null, @Cross = false, @Natural = false] + | | +- TableReference[@CanonicalImage = null] + | | | +- SchemaName[@CanonicalImage = "WEBCRM", @Image = "webcrm"] + | | | | +- ID[@CanonicalImage = "WEBCRM", @Image = "webcrm"] + | | | +- TableName[@CanonicalImage = "JCOMP_MPRC_EMP_ROLE", @Image = "jcomp_mprc_emp_role"] + | | | | +- ID[@CanonicalImage = "JCOMP_MPRC_EMP_ROLE", @Image = "jcomp_mprc_emp_role"] + | | | +- TableAlias[@CanonicalImage = "INSERT_ENTRY", @Image = "insert_entry"] + | | | +- ID[@CanonicalImage = "INSERT_ENTRY", @Image = "insert_entry"] + | | +- PrimaryPrefix[@CanonicalImage = "(INSERT_ENTRY.CMER_ID = CMER.CMER_ID AND INSERT_ENTRY.OPERATION = \'I\')", @Image = "(insert_entry.cmer_id = cmer.cmer_id AND insert_entry.operation = \'I\')", @SelfModifier = false] + | | +- Expression[@CanonicalImage = "INSERT_ENTRY.CMER_ID = CMER.CMER_ID AND INSERT_ENTRY.OPERATION = \'I\'", @Image = "insert_entry.cmer_id = cmer.cmer_id AND insert_entry.operation = \'I\'"] + | | +- ConditionalAndExpression[@CanonicalImage = "INSERT_ENTRY.CMER_ID = CMER.CMER_ID AND INSERT_ENTRY.OPERATION = \'I\'", @Image = "insert_entry.cmer_id = cmer.cmer_id AND insert_entry.operation = \'I\'"] + | | +- EqualityExpression[@CanonicalImage = "INSERT_ENTRY.CMER_ID = CMER.CMER_ID", @Image = "insert_entry.cmer_id = cmer.cmer_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "INSERT_ENTRY.CMER_ID", @Image = "insert_entry.cmer_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "INSERT_ENTRY.CMER_ID", @Image = "insert_entry.cmer_id"] + | | | | +- TableName[@CanonicalImage = "INSERT_ENTRY", @Image = "insert_entry"] + | | | | | +- ID[@CanonicalImage = "INSERT_ENTRY", @Image = "insert_entry"] + | | | | +- Column[@CanonicalImage = "CMER_ID", @Image = "cmer_id"] + | | | | +- ID[@CanonicalImage = "CMER_ID", @Image = "cmer_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "CMER.CMER_ID", @Image = "cmer.cmer_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "CMER.CMER_ID", @Image = "cmer.cmer_id"] + | | | +- TableName[@CanonicalImage = "CMER", @Image = "cmer"] + | | | | +- ID[@CanonicalImage = "CMER", @Image = "cmer"] + | | | +- Column[@CanonicalImage = "CMER_ID", @Image = "cmer_id"] + | | | +- ID[@CanonicalImage = "CMER_ID", @Image = "cmer_id"] + | | +- EqualityExpression[@CanonicalImage = "INSERT_ENTRY.OPERATION = \'I\'", @Image = "insert_entry.operation = \'I\'"] + | | +- PrimaryPrefix[@CanonicalImage = "INSERT_ENTRY.OPERATION", @Image = "insert_entry.operation", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "INSERT_ENTRY.OPERATION", @Image = "insert_entry.operation"] + | | | +- TableName[@CanonicalImage = "INSERT_ENTRY", @Image = "insert_entry"] + | | | | +- ID[@CanonicalImage = "INSERT_ENTRY", @Image = "insert_entry"] + | | | +- Column[@CanonicalImage = "OPERATION", @Image = "operation"] + | | | +- ID[@CanonicalImage = "OPERATION", @Image = "operation"] + | | +- PrimaryPrefix[@CanonicalImage = "\'I\'", @Image = "\'I\'", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "\'I\'", @Image = "\'I\'"] + | +- OuterJoinClause[@CanonicalImage = null, @Natural = false] + | | +- OuterJoinType[@CanonicalImage = "LEFT", @Full = false, @Image = "LEFT", @Left = true, @Right = false, @Type = Type.LEFT] + | | +- TableReference[@CanonicalImage = null] + | | | +- SchemaName[@CanonicalImage = "WEBCRM", @Image = "webcrm"] + | | | | +- ID[@CanonicalImage = "WEBCRM", @Image = "webcrm"] + | | | +- TableName[@CanonicalImage = "V_COMPANY_ADDRESS", @Image = "v_company_address"] + | | | | +- ID[@CanonicalImage = "V_COMPANY_ADDRESS", @Image = "v_company_address"] + | | | +- TableAlias[@CanonicalImage = "CADDR", @Image = "caddr"] + | | | +- ID[@CanonicalImage = "CADDR", @Image = "caddr"] + | | +- PrimaryPrefix[@CanonicalImage = "(CADDR.CMP_ID = CMER.CMP_ID)", @Image = "(caddr.cmp_id = cmer.cmp_id)", @SelfModifier = false] + | | +- Expression[@CanonicalImage = "CADDR.CMP_ID = CMER.CMP_ID", @Image = "caddr.cmp_id = cmer.cmp_id"] + | | +- EqualityExpression[@CanonicalImage = "CADDR.CMP_ID = CMER.CMP_ID", @Image = "caddr.cmp_id = cmer.cmp_id"] + | | +- PrimaryPrefix[@CanonicalImage = "CADDR.CMP_ID", @Image = "caddr.cmp_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "CADDR.CMP_ID", @Image = "caddr.cmp_id"] + | | | +- TableName[@CanonicalImage = "CADDR", @Image = "caddr"] + | | | | +- ID[@CanonicalImage = "CADDR", @Image = "caddr"] + | | | +- Column[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | | | +- ID[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | | +- PrimaryPrefix[@CanonicalImage = "CMER.CMP_ID", @Image = "cmer.cmp_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "CMER.CMP_ID", @Image = "cmer.cmp_id"] + | | +- TableName[@CanonicalImage = "CMER", @Image = "cmer"] + | | | +- ID[@CanonicalImage = "CMER", @Image = "cmer"] + | | +- Column[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | | +- ID[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | +- OuterJoinClause[@CanonicalImage = null, @Natural = false] + | +- OuterJoinType[@CanonicalImage = "LEFT", @Full = false, @Image = "LEFT", @Left = true, @Right = false, @Type = Type.LEFT] + | +- TableReference[@CanonicalImage = null] + | | +- SchemaName[@CanonicalImage = "WEBCRM", @Image = "webcrm"] + | | | +- ID[@CanonicalImage = "WEBCRM", @Image = "webcrm"] + | | +- TableName[@CanonicalImage = "V_SFM_EMP_ROLE_CNY_REPG", @Image = "v_sfm_emp_role_cny_repg"] + | | | +- ID[@CanonicalImage = "V_SFM_EMP_ROLE_CNY_REPG", @Image = "v_sfm_emp_role_cny_repg"] + | | +- TableAlias[@CanonicalImage = "SFM", @Image = "sfm"] + | | +- ID[@CanonicalImage = "SFM", @Image = "sfm"] + | +- PrimaryPrefix[@CanonicalImage = "(SFM.EMP_ID = CMER.EMP_ID AND SFM.EMP_ROLE_CODE = CMER.EMP_ROLE_CODE AND SFM.CNY_CODE = NVL)", @Image = "(sfm.emp_id = cmer.emp_id AND sfm.emp_role_code = cmer.emp_role_code AND sfm.cny_code = NVL)", @SelfModifier = false] + | +- Expression[@CanonicalImage = "SFM.EMP_ID = CMER.EMP_ID AND SFM.EMP_ROLE_CODE = CMER.EMP_ROLE_CODE AND SFM.CNY_CODE = NVL", @Image = "sfm.emp_id = cmer.emp_id AND sfm.emp_role_code = cmer.emp_role_code AND sfm.cny_code = NVL"] + | +- ConditionalAndExpression[@CanonicalImage = "SFM.EMP_ID = CMER.EMP_ID AND SFM.EMP_ROLE_CODE = CMER.EMP_ROLE_CODE AND SFM.CNY_CODE = NVL", @Image = "sfm.emp_id = cmer.emp_id AND sfm.emp_role_code = cmer.emp_role_code AND sfm.cny_code = NVL"] + | +- EqualityExpression[@CanonicalImage = "SFM.EMP_ID = CMER.EMP_ID", @Image = "sfm.emp_id = cmer.emp_id"] + | | +- PrimaryPrefix[@CanonicalImage = "SFM.EMP_ID", @Image = "sfm.emp_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "SFM.EMP_ID", @Image = "sfm.emp_id"] + | | | +- TableName[@CanonicalImage = "SFM", @Image = "sfm"] + | | | | +- ID[@CanonicalImage = "SFM", @Image = "sfm"] + | | | +- Column[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | | +- ID[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- PrimaryPrefix[@CanonicalImage = "CMER.EMP_ID", @Image = "cmer.emp_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "CMER.EMP_ID", @Image = "cmer.emp_id"] + | | +- TableName[@CanonicalImage = "CMER", @Image = "cmer"] + | | | +- ID[@CanonicalImage = "CMER", @Image = "cmer"] + | | +- Column[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- ID[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | +- EqualityExpression[@CanonicalImage = "SFM.EMP_ROLE_CODE = CMER.EMP_ROLE_CODE", @Image = "sfm.emp_role_code = cmer.emp_role_code"] + | | +- PrimaryPrefix[@CanonicalImage = "SFM.EMP_ROLE_CODE", @Image = "sfm.emp_role_code", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "SFM.EMP_ROLE_CODE", @Image = "sfm.emp_role_code"] + | | | +- TableName[@CanonicalImage = "SFM", @Image = "sfm"] + | | | | +- ID[@CanonicalImage = "SFM", @Image = "sfm"] + | | | +- Column[@CanonicalImage = "EMP_ROLE_CODE", @Image = "emp_role_code"] + | | | +- ID[@CanonicalImage = "EMP_ROLE_CODE", @Image = "emp_role_code"] + | | +- PrimaryPrefix[@CanonicalImage = "CMER.EMP_ROLE_CODE", @Image = "cmer.emp_role_code", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "CMER.EMP_ROLE_CODE", @Image = "cmer.emp_role_code"] + | | +- TableName[@CanonicalImage = "CMER", @Image = "cmer"] + | | | +- ID[@CanonicalImage = "CMER", @Image = "cmer"] + | | +- Column[@CanonicalImage = "EMP_ROLE_CODE", @Image = "emp_role_code"] + | | +- ID[@CanonicalImage = "EMP_ROLE_CODE", @Image = "emp_role_code"] + | +- EqualityExpression[@CanonicalImage = "SFM.CNY_CODE = NVL", @Image = "sfm.cny_code = NVL"] + | +- PrimaryPrefix[@CanonicalImage = "SFM.CNY_CODE", @Image = "sfm.cny_code", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "SFM.CNY_CODE", @Image = "sfm.cny_code"] + | | +- TableName[@CanonicalImage = "SFM", @Image = "sfm"] + | | | +- ID[@CanonicalImage = "SFM", @Image = "sfm"] + | | +- Column[@CanonicalImage = "CNY_CODE", @Image = "cny_code"] + | | +- ID[@CanonicalImage = "CNY_CODE", @Image = "cny_code"] + | +- PrimaryPrefix[@CanonicalImage = "NVL", @Image = "NVL", @SelfModifier = false] + | +- FunctionCall[@CanonicalImage = "NVL", @Image = "NVL"] + | +- FunctionName[@CanonicalImage = "NVL", @Image = "NVL"] + | | +- ID[@CanonicalImage = "NVL", @Image = "NVL"] + | +- Arguments[@ArgumentCount = 2, @CanonicalImage = null] + | +- ArgumentList[@CanonicalImage = null] + | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "CADDR.S_CNY_CODE", @Image = "caddr.s_cny_code"] + | | +- PrimaryPrefix[@CanonicalImage = "CADDR.S_CNY_CODE", @Image = "caddr.s_cny_code", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "CADDR.S_CNY_CODE", @Image = "caddr.s_cny_code"] + | | +- TableName[@CanonicalImage = "CADDR", @Image = "caddr"] + | | | +- ID[@CanonicalImage = "CADDR", @Image = "caddr"] + | | +- Column[@CanonicalImage = "S_CNY_CODE", @Image = "s_cny_code"] + | | +- ID[@CanonicalImage = "S_CNY_CODE", @Image = "s_cny_code"] + | +- Argument[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "CADDR.M_CNY_CODE", @Image = "caddr.m_cny_code"] + | +- PrimaryPrefix[@CanonicalImage = "CADDR.M_CNY_CODE", @Image = "caddr.m_cny_code", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "CADDR.M_CNY_CODE", @Image = "caddr.m_cny_code"] + | +- TableName[@CanonicalImage = "CADDR", @Image = "caddr"] + | | +- ID[@CanonicalImage = "CADDR", @Image = "caddr"] + | +- Column[@CanonicalImage = "M_CNY_CODE", @Image = "m_cny_code"] + | +- ID[@CanonicalImage = "M_CNY_CODE", @Image = "m_cny_code"] + +- SubqueryOperation[@All = false, @CanonicalImage = "UNION", @Image = "UNION", @Intersect = false, @Minus = false, @Union = true] + +- QueryBlock[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + +- SelectList[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "JCMER.CMER_ID", @Image = "jcmer.cmer_id"] + | | +- PrimaryPrefix[@CanonicalImage = "JCMER.CMER_ID", @Image = "jcmer.cmer_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "JCMER.CMER_ID", @Image = "jcmer.cmer_id"] + | | +- TableName[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | | +- ID[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | +- Column[@CanonicalImage = "CMER_ID", @Image = "cmer_id"] + | | +- ID[@CanonicalImage = "CMER_ID", @Image = "cmer_id"] + | +- SqlExpression[@CanonicalImage = "JCMER.VERSION", @Image = "jcmer.version"] + | | +- PrimaryPrefix[@CanonicalImage = "JCMER.VERSION", @Image = "jcmer.version", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "JCMER.VERSION", @Image = "jcmer.version"] + | | +- TableName[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | | +- ID[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | +- Column[@CanonicalImage = "VERSION", @Image = "version"] + | | +- ID[@CanonicalImage = "VERSION", @Image = "version"] + | +- SqlExpression[@CanonicalImage = "JCMER.CMP_ID", @Image = "jcmer.cmp_id"] + | | +- PrimaryPrefix[@CanonicalImage = "JCMER.CMP_ID", @Image = "jcmer.cmp_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "JCMER.CMP_ID", @Image = "jcmer.cmp_id"] + | | +- TableName[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | | +- ID[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | +- Column[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | | +- ID[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | +- SqlExpression[@CanonicalImage = "JCMER.MPRC_CODE", @Image = "jcmer.mprc_code"] + | | +- PrimaryPrefix[@CanonicalImage = "JCMER.MPRC_CODE", @Image = "jcmer.mprc_code", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "JCMER.MPRC_CODE", @Image = "jcmer.mprc_code"] + | | +- TableName[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | | +- ID[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | +- Column[@CanonicalImage = "MPRC_CODE", @Image = "mprc_code"] + | | +- ID[@CanonicalImage = "MPRC_CODE", @Image = "mprc_code"] + | +- SqlExpression[@CanonicalImage = "JCMER.EMP_ID", @Image = "jcmer.emp_id"] + | | +- PrimaryPrefix[@CanonicalImage = "JCMER.EMP_ID", @Image = "jcmer.emp_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "JCMER.EMP_ID", @Image = "jcmer.emp_id"] + | | +- TableName[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | | +- ID[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | +- Column[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- ID[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | +- SqlExpression[@CanonicalImage = "JCMER.EMP_ROLE_CODE", @Image = "jcmer.emp_role_code"] + | | +- PrimaryPrefix[@CanonicalImage = "JCMER.EMP_ROLE_CODE", @Image = "jcmer.emp_role_code", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "JCMER.EMP_ROLE_CODE", @Image = "jcmer.emp_role_code"] + | | +- TableName[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | | +- ID[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | +- Column[@CanonicalImage = "EMP_ROLE_CODE", @Image = "emp_role_code"] + | | +- ID[@CanonicalImage = "EMP_ROLE_CODE", @Image = "emp_role_code"] + | +- SqlExpression[@CanonicalImage = "JCMER.GSN_ID", @Image = "jcmer.gsn_id"] + | | +- PrimaryPrefix[@CanonicalImage = "JCMER.GSN_ID", @Image = "jcmer.gsn_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "JCMER.GSN_ID", @Image = "jcmer.gsn_id"] + | | +- TableName[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | | +- ID[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | +- Column[@CanonicalImage = "GSN_ID", @Image = "gsn_id"] + | | +- ID[@CanonicalImage = "GSN_ID", @Image = "gsn_id"] + | +- SqlExpression[@CanonicalImage = "JCMER.DEP_CODE", @Image = "jcmer.dep_code"] + | | +- PrimaryPrefix[@CanonicalImage = "JCMER.DEP_CODE", @Image = "jcmer.dep_code", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "JCMER.DEP_CODE", @Image = "jcmer.dep_code"] + | | +- TableName[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | | +- ID[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | +- Column[@CanonicalImage = "DEP_CODE", @Image = "dep_code"] + | | +- ID[@CanonicalImage = "DEP_CODE", @Image = "dep_code"] + | +- SqlExpression[@CanonicalImage = "TRUNC", @Image = "TRUNC"] + | | +- PrimaryPrefix[@CanonicalImage = "TRUNC", @Image = "TRUNC", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "TRUNC", @Image = "TRUNC"] + | | +- FunctionName[@CanonicalImage = "TRUNC", @Image = "TRUNC"] + | | | +- ID[@CanonicalImage = "TRUNC", @Image = "TRUNC"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "INSERT_ENTRY.DMLTIME", @Image = "insert_entry.dmltime"] + | | +- PrimaryPrefix[@CanonicalImage = "INSERT_ENTRY.DMLTIME", @Image = "insert_entry.dmltime", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "INSERT_ENTRY.DMLTIME", @Image = "insert_entry.dmltime"] + | | +- TableName[@CanonicalImage = "INSERT_ENTRY", @Image = "insert_entry"] + | | | +- ID[@CanonicalImage = "INSERT_ENTRY", @Image = "insert_entry"] + | | +- Column[@CanonicalImage = "DMLTIME", @Image = "dmltime"] + | | +- ID[@CanonicalImage = "DMLTIME", @Image = "dmltime"] + | +- ColumnAlias[@CanonicalImage = "VALIDFROM", @Image = "validfrom"] + | | +- ID[@CanonicalImage = "VALIDFROM", @Image = "validfrom"] + | +- SqlExpression[@CanonicalImage = "TRUNC", @Image = "TRUNC"] + | | +- PrimaryPrefix[@CanonicalImage = "TRUNC", @Image = "TRUNC", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "TRUNC", @Image = "TRUNC"] + | | +- FunctionName[@CanonicalImage = "TRUNC", @Image = "TRUNC"] + | | | +- ID[@CanonicalImage = "TRUNC", @Image = "TRUNC"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "JCMER.DMLTIME", @Image = "jcmer.dmltime"] + | | +- PrimaryPrefix[@CanonicalImage = "JCMER.DMLTIME", @Image = "jcmer.dmltime", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "JCMER.DMLTIME", @Image = "jcmer.dmltime"] + | | +- TableName[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | | +- ID[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | +- Column[@CanonicalImage = "DMLTIME", @Image = "dmltime"] + | | +- ID[@CanonicalImage = "DMLTIME", @Image = "dmltime"] + | +- ColumnAlias[@CanonicalImage = "VALIDFROM", @Image = "validfrom"] + | | +- ID[@CanonicalImage = "VALIDFROM", @Image = "validfrom"] + | +- SqlExpression[@CanonicalImage = "\'N\'", @Image = "\'N\'"] + | | +- PrimaryPrefix[@CanonicalImage = "\'N\'", @Image = "\'N\'", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "\'N\'", @Image = "\'N\'"] + | +- ColumnAlias[@CanonicalImage = "FL_ACTIVE", @Image = "fl_active"] + | | +- ID[@CanonicalImage = "FL_ACTIVE", @Image = "fl_active"] + | +- SqlExpression[@CanonicalImage = "SFM.REPORTING_GROUPS", @Image = "sfm.reporting_groups"] + | | +- PrimaryPrefix[@CanonicalImage = "SFM.REPORTING_GROUPS", @Image = "sfm.reporting_groups", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "SFM.REPORTING_GROUPS", @Image = "sfm.reporting_groups"] + | | +- TableName[@CanonicalImage = "SFM", @Image = "sfm"] + | | | +- ID[@CanonicalImage = "SFM", @Image = "sfm"] + | | +- Column[@CanonicalImage = "REPORTING_GROUPS", @Image = "reporting_groups"] + | | +- ID[@CanonicalImage = "REPORTING_GROUPS", @Image = "reporting_groups"] + | +- ColumnAlias[@CanonicalImage = "REPORTING_LIST", @Image = "reporting_list"] + | +- ID[@CanonicalImage = "REPORTING_LIST", @Image = "reporting_list"] + +- FromClause[@CanonicalImage = null] + | +- JoinClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | | +- SchemaName[@CanonicalImage = "WEBCRM", @Image = "webcrm"] + | | | +- ID[@CanonicalImage = "WEBCRM", @Image = "webcrm"] + | | +- TableName[@CanonicalImage = "JCOMP_MPRC_EMP_ROLE", @Image = "jcomp_mprc_emp_role"] + | | | +- ID[@CanonicalImage = "JCOMP_MPRC_EMP_ROLE", @Image = "jcomp_mprc_emp_role"] + | | +- TableAlias[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | +- ID[@CanonicalImage = "JCMER", @Image = "jcmer"] + | +- InnerCrossJoinClause[@CanonicalImage = null, @Cross = false, @Natural = false] + | | +- TableReference[@CanonicalImage = null] + | | | +- SchemaName[@CanonicalImage = "WEBCRM", @Image = "webcrm"] + | | | | +- ID[@CanonicalImage = "WEBCRM", @Image = "webcrm"] + | | | +- TableName[@CanonicalImage = "JCOMP_MPRC_EMP_ROLE", @Image = "jcomp_mprc_emp_role"] + | | | | +- ID[@CanonicalImage = "JCOMP_MPRC_EMP_ROLE", @Image = "jcomp_mprc_emp_role"] + | | | +- TableAlias[@CanonicalImage = "INSERT_ENTRY", @Image = "insert_entry"] + | | | +- ID[@CanonicalImage = "INSERT_ENTRY", @Image = "insert_entry"] + | | +- PrimaryPrefix[@CanonicalImage = "(INSERT_ENTRY.CMER_ID = JCMER.CMER_ID AND INSERT_ENTRY.OPERATION = \'I\')", @Image = "(insert_entry.cmer_id = jcmer.cmer_id AND insert_entry.operation = \'I\')", @SelfModifier = false] + | | +- Expression[@CanonicalImage = "INSERT_ENTRY.CMER_ID = JCMER.CMER_ID AND INSERT_ENTRY.OPERATION = \'I\'", @Image = "insert_entry.cmer_id = jcmer.cmer_id AND insert_entry.operation = \'I\'"] + | | +- ConditionalAndExpression[@CanonicalImage = "INSERT_ENTRY.CMER_ID = JCMER.CMER_ID AND INSERT_ENTRY.OPERATION = \'I\'", @Image = "insert_entry.cmer_id = jcmer.cmer_id AND insert_entry.operation = \'I\'"] + | | +- EqualityExpression[@CanonicalImage = "INSERT_ENTRY.CMER_ID = JCMER.CMER_ID", @Image = "insert_entry.cmer_id = jcmer.cmer_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "INSERT_ENTRY.CMER_ID", @Image = "insert_entry.cmer_id", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "INSERT_ENTRY.CMER_ID", @Image = "insert_entry.cmer_id"] + | | | | +- TableName[@CanonicalImage = "INSERT_ENTRY", @Image = "insert_entry"] + | | | | | +- ID[@CanonicalImage = "INSERT_ENTRY", @Image = "insert_entry"] + | | | | +- Column[@CanonicalImage = "CMER_ID", @Image = "cmer_id"] + | | | | +- ID[@CanonicalImage = "CMER_ID", @Image = "cmer_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "JCMER.CMER_ID", @Image = "jcmer.cmer_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "JCMER.CMER_ID", @Image = "jcmer.cmer_id"] + | | | +- TableName[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | | | +- ID[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | | +- Column[@CanonicalImage = "CMER_ID", @Image = "cmer_id"] + | | | +- ID[@CanonicalImage = "CMER_ID", @Image = "cmer_id"] + | | +- EqualityExpression[@CanonicalImage = "INSERT_ENTRY.OPERATION = \'I\'", @Image = "insert_entry.operation = \'I\'"] + | | +- PrimaryPrefix[@CanonicalImage = "INSERT_ENTRY.OPERATION", @Image = "insert_entry.operation", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "INSERT_ENTRY.OPERATION", @Image = "insert_entry.operation"] + | | | +- TableName[@CanonicalImage = "INSERT_ENTRY", @Image = "insert_entry"] + | | | | +- ID[@CanonicalImage = "INSERT_ENTRY", @Image = "insert_entry"] + | | | +- Column[@CanonicalImage = "OPERATION", @Image = "operation"] + | | | +- ID[@CanonicalImage = "OPERATION", @Image = "operation"] + | | +- PrimaryPrefix[@CanonicalImage = "\'I\'", @Image = "\'I\'", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "\'I\'", @Image = "\'I\'"] + | +- OuterJoinClause[@CanonicalImage = null, @Natural = false] + | | +- OuterJoinType[@CanonicalImage = "LEFT", @Full = false, @Image = "LEFT", @Left = true, @Right = false, @Type = Type.LEFT] + | | +- TableReference[@CanonicalImage = null] + | | | +- SchemaName[@CanonicalImage = "WEBCRM", @Image = "webcrm"] + | | | | +- ID[@CanonicalImage = "WEBCRM", @Image = "webcrm"] + | | | +- TableName[@CanonicalImage = "V_COMPANY_ADDRESS", @Image = "v_company_address"] + | | | | +- ID[@CanonicalImage = "V_COMPANY_ADDRESS", @Image = "v_company_address"] + | | | +- TableAlias[@CanonicalImage = "CADDR", @Image = "caddr"] + | | | +- ID[@CanonicalImage = "CADDR", @Image = "caddr"] + | | +- PrimaryPrefix[@CanonicalImage = "(CADDR.CMP_ID = JCMER.CMP_ID)", @Image = "(caddr.cmp_id = jcmer.cmp_id)", @SelfModifier = false] + | | +- Expression[@CanonicalImage = "CADDR.CMP_ID = JCMER.CMP_ID", @Image = "caddr.cmp_id = jcmer.cmp_id"] + | | +- EqualityExpression[@CanonicalImage = "CADDR.CMP_ID = JCMER.CMP_ID", @Image = "caddr.cmp_id = jcmer.cmp_id"] + | | +- PrimaryPrefix[@CanonicalImage = "CADDR.CMP_ID", @Image = "caddr.cmp_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "CADDR.CMP_ID", @Image = "caddr.cmp_id"] + | | | +- TableName[@CanonicalImage = "CADDR", @Image = "caddr"] + | | | | +- ID[@CanonicalImage = "CADDR", @Image = "caddr"] + | | | +- Column[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | | | +- ID[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | | +- PrimaryPrefix[@CanonicalImage = "JCMER.CMP_ID", @Image = "jcmer.cmp_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "JCMER.CMP_ID", @Image = "jcmer.cmp_id"] + | | +- TableName[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | | +- ID[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | +- Column[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | | +- ID[@CanonicalImage = "CMP_ID", @Image = "cmp_id"] + | +- OuterJoinClause[@CanonicalImage = null, @Natural = false] + | +- OuterJoinType[@CanonicalImage = "LEFT", @Full = false, @Image = "LEFT", @Left = true, @Right = false, @Type = Type.LEFT] + | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "V_SFM_EMP_ROLE_CNY_REPG", @Image = "v_sfm_emp_role_cny_repg"] + | | | +- ID[@CanonicalImage = "V_SFM_EMP_ROLE_CNY_REPG", @Image = "v_sfm_emp_role_cny_repg"] + | | +- TableAlias[@CanonicalImage = "SFM", @Image = "sfm"] + | | +- ID[@CanonicalImage = "SFM", @Image = "sfm"] + | +- PrimaryPrefix[@CanonicalImage = "(SFM.EMP_ID = JCMER.EMP_ID AND SFM.EMP_ROLE_CODE = JCMER.EMP_ROLE_CODE AND SFM.CNY_CODE = NVL)", @Image = "(sfm.emp_id = jcmer.emp_id AND sfm.emp_role_code = jcmer.emp_role_code AND sfm.cny_code = NVL)", @SelfModifier = false] + | +- Expression[@CanonicalImage = "SFM.EMP_ID = JCMER.EMP_ID AND SFM.EMP_ROLE_CODE = JCMER.EMP_ROLE_CODE AND SFM.CNY_CODE = NVL", @Image = "sfm.emp_id = jcmer.emp_id AND sfm.emp_role_code = jcmer.emp_role_code AND sfm.cny_code = NVL"] + | +- ConditionalAndExpression[@CanonicalImage = "SFM.EMP_ID = JCMER.EMP_ID AND SFM.EMP_ROLE_CODE = JCMER.EMP_ROLE_CODE AND SFM.CNY_CODE = NVL", @Image = "sfm.emp_id = jcmer.emp_id AND sfm.emp_role_code = jcmer.emp_role_code AND sfm.cny_code = NVL"] + | +- EqualityExpression[@CanonicalImage = "SFM.EMP_ID = JCMER.EMP_ID", @Image = "sfm.emp_id = jcmer.emp_id"] + | | +- PrimaryPrefix[@CanonicalImage = "SFM.EMP_ID", @Image = "sfm.emp_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "SFM.EMP_ID", @Image = "sfm.emp_id"] + | | | +- TableName[@CanonicalImage = "SFM", @Image = "sfm"] + | | | | +- ID[@CanonicalImage = "SFM", @Image = "sfm"] + | | | +- Column[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | | +- ID[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- PrimaryPrefix[@CanonicalImage = "JCMER.EMP_ID", @Image = "jcmer.emp_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "JCMER.EMP_ID", @Image = "jcmer.emp_id"] + | | +- TableName[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | | +- ID[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | +- Column[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- ID[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | +- EqualityExpression[@CanonicalImage = "SFM.EMP_ROLE_CODE = JCMER.EMP_ROLE_CODE", @Image = "sfm.emp_role_code = jcmer.emp_role_code"] + | | +- PrimaryPrefix[@CanonicalImage = "SFM.EMP_ROLE_CODE", @Image = "sfm.emp_role_code", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "SFM.EMP_ROLE_CODE", @Image = "sfm.emp_role_code"] + | | | +- TableName[@CanonicalImage = "SFM", @Image = "sfm"] + | | | | +- ID[@CanonicalImage = "SFM", @Image = "sfm"] + | | | +- Column[@CanonicalImage = "EMP_ROLE_CODE", @Image = "emp_role_code"] + | | | +- ID[@CanonicalImage = "EMP_ROLE_CODE", @Image = "emp_role_code"] + | | +- PrimaryPrefix[@CanonicalImage = "JCMER.EMP_ROLE_CODE", @Image = "jcmer.emp_role_code", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "JCMER.EMP_ROLE_CODE", @Image = "jcmer.emp_role_code"] + | | +- TableName[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | | +- ID[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | +- Column[@CanonicalImage = "EMP_ROLE_CODE", @Image = "emp_role_code"] + | | +- ID[@CanonicalImage = "EMP_ROLE_CODE", @Image = "emp_role_code"] + | +- EqualityExpression[@CanonicalImage = "SFM.CNY_CODE = NVL", @Image = "sfm.cny_code = NVL"] + | +- PrimaryPrefix[@CanonicalImage = "SFM.CNY_CODE", @Image = "sfm.cny_code", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "SFM.CNY_CODE", @Image = "sfm.cny_code"] + | | +- TableName[@CanonicalImage = "SFM", @Image = "sfm"] + | | | +- ID[@CanonicalImage = "SFM", @Image = "sfm"] + | | +- Column[@CanonicalImage = "CNY_CODE", @Image = "cny_code"] + | | +- ID[@CanonicalImage = "CNY_CODE", @Image = "cny_code"] + | +- PrimaryPrefix[@CanonicalImage = "NVL", @Image = "NVL", @SelfModifier = false] + | +- FunctionCall[@CanonicalImage = "NVL", @Image = "NVL"] + | +- FunctionName[@CanonicalImage = "NVL", @Image = "NVL"] + | | +- ID[@CanonicalImage = "NVL", @Image = "NVL"] + | +- Arguments[@ArgumentCount = 2, @CanonicalImage = null] + | +- ArgumentList[@CanonicalImage = null] + | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "CADDR.S_CNY_CODE", @Image = "caddr.s_cny_code"] + | | +- PrimaryPrefix[@CanonicalImage = "CADDR.S_CNY_CODE", @Image = "caddr.s_cny_code", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "CADDR.S_CNY_CODE", @Image = "caddr.s_cny_code"] + | | +- TableName[@CanonicalImage = "CADDR", @Image = "caddr"] + | | | +- ID[@CanonicalImage = "CADDR", @Image = "caddr"] + | | +- Column[@CanonicalImage = "S_CNY_CODE", @Image = "s_cny_code"] + | | +- ID[@CanonicalImage = "S_CNY_CODE", @Image = "s_cny_code"] + | +- Argument[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "CADDR.M_CNY_CODE", @Image = "caddr.m_cny_code"] + | +- PrimaryPrefix[@CanonicalImage = "CADDR.M_CNY_CODE", @Image = "caddr.m_cny_code", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "CADDR.M_CNY_CODE", @Image = "caddr.m_cny_code"] + | +- TableName[@CanonicalImage = "CADDR", @Image = "caddr"] + | | +- ID[@CanonicalImage = "CADDR", @Image = "caddr"] + | +- Column[@CanonicalImage = "M_CNY_CODE", @Image = "m_cny_code"] + | +- ID[@CanonicalImage = "M_CNY_CODE", @Image = "m_cny_code"] + +- WhereClause[@CanonicalImage = null] + +- Condition[@CanonicalImage = null] + +- CompoundCondition[@CanonicalImage = null, @Type = "AND"] + +- InCondition[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "JCMER.CMER_ID", @Image = "jcmer.cmer_id"] + | | +- PrimaryPrefix[@CanonicalImage = "JCMER.CMER_ID", @Image = "jcmer.cmer_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "JCMER.CMER_ID", @Image = "jcmer.cmer_id"] + | | +- TableName[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | | +- ID[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | +- Column[@CanonicalImage = "CMER_ID", @Image = "cmer_id"] + | | +- ID[@CanonicalImage = "CMER_ID", @Image = "cmer_id"] + | +- QueryBlock[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "CMER.CMER_ID", @Image = "cmer.cmer_id"] + | | +- PrimaryPrefix[@CanonicalImage = "CMER.CMER_ID", @Image = "cmer.cmer_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "CMER.CMER_ID", @Image = "cmer.cmer_id"] + | | +- TableName[@CanonicalImage = "CMER", @Image = "cmer"] + | | | +- ID[@CanonicalImage = "CMER", @Image = "cmer"] + | | +- Column[@CanonicalImage = "CMER_ID", @Image = "cmer_id"] + | | +- ID[@CanonicalImage = "CMER_ID", @Image = "cmer_id"] + | +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | +- SchemaName[@CanonicalImage = "WEBCRM", @Image = "webcrm"] + | | +- ID[@CanonicalImage = "WEBCRM", @Image = "webcrm"] + | +- TableName[@CanonicalImage = "COMP_MPRC_EMP_ROLE", @Image = "comp_mprc_emp_role"] + | | +- ID[@CanonicalImage = "COMP_MPRC_EMP_ROLE", @Image = "comp_mprc_emp_role"] + | +- TableAlias[@CanonicalImage = "CMER", @Image = "cmer"] + | +- ID[@CanonicalImage = "CMER", @Image = "cmer"] + +- Condition[@CanonicalImage = null] + +- CompoundCondition[@CanonicalImage = null, @Type = null] + +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + +- SqlExpression[@CanonicalImage = "JCMER.OPERATION", @Image = "jcmer.operation"] + | +- PrimaryPrefix[@CanonicalImage = "JCMER.OPERATION", @Image = "jcmer.operation", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "JCMER.OPERATION", @Image = "jcmer.operation"] + | +- TableName[@CanonicalImage = "JCMER", @Image = "jcmer"] + | | +- ID[@CanonicalImage = "JCMER", @Image = "jcmer"] + | +- Column[@CanonicalImage = "OPERATION", @Image = "operation"] + | +- ID[@CanonicalImage = "OPERATION", @Image = "operation"] + +- SqlExpression[@CanonicalImage = "\'D\'", @Image = "\'D\'"] + +- PrimaryPrefix[@CanonicalImage = "\'D\'", @Image = "\'D\'", @SelfModifier = false] + +- Literal[@CanonicalImage = "\'D\'", @Image = "\'D\'"] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementExample1.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementExample1.txt new file mode 100644 index 00000000000..184e4da4079 --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementExample1.txt @@ -0,0 +1,49 @@ ++- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- Global[@CanonicalImage = null] + | +- Block[@CanonicalImage = null] + | +- DeclarativeSection[@CanonicalImage = null] + | | +- DeclarativeUnit[@CanonicalImage = null] + | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | +- VariableOrConstantDeclarator[@CanonicalImage = "BONUS NUMBER(8,2)", @Image = "bonus NUMBER(8,2)"] + | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "BONUS", @Image = "bonus"] + | | | +- ID[@CanonicalImage = "BONUS", @Image = "bonus"] + | | +- Datatype[@CanonicalImage = "NUMBER(8,2)", @Image = "NUMBER(8,2)", @TypeImage = "NUMBER(8,2)"] + | | +- ScalarDataTypeName[@CanonicalImage = "NUMBER(8,2)", @Image = "NUMBER(8,2)"] + | | +- NumericLiteral[@CanonicalImage = "8", @Image = "8"] + | | +- PrimaryPrefix[@CanonicalImage = "2", @Image = "2", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "2", @Image = "2"] + | | +- NumericLiteral[@CanonicalImage = "2", @Image = "2"] + | +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "SALARY * 0.10", @Image = "salary * 0.10"] + | | +- MultiplicativeExpression[@CanonicalImage = "SALARY * 0.10", @Image = "salary * 0.10"] + | | +- PrimaryPrefix[@CanonicalImage = "SALARY", @Image = "salary", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "SALARY", @Image = "salary"] + | | | +- Column[@CanonicalImage = "SALARY", @Image = "salary"] + | | | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + | | +- PrimaryPrefix[@CanonicalImage = "0.10", @Image = "0.10", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "0.10", @Image = "0.10"] + | | +- NumericLiteral[@CanonicalImage = "0.10", @Image = "0.10"] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "BONUS", @Image = "bonus"] + | | +- ID[@CanonicalImage = "BONUS", @Image = "bonus"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- WhereClause[@CanonicalImage = null] + | +- Condition[@CanonicalImage = null] + | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- SqlExpression[@CanonicalImage = "100", @Image = "100"] + | +- PrimaryPrefix[@CanonicalImage = "100", @Image = "100", @SelfModifier = false] + | +- Literal[@CanonicalImage = "100", @Image = "100"] + | +- NumericLiteral[@CanonicalImage = "100", @Image = "100"] + +- SqlPlusCommand[@CanonicalImage = "EXEC DBMS_OUTPUT . PUT_LINE ( \'BONUS = \' || TO_CHAR ( BONUS ) )", @Image = "EXEC DBMS_OUTPUT . PUT_LINE ( \'bonus = \' || TO_CHAR ( BONUS ) ) "] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementExample2.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementExample2.txt new file mode 100644 index 00000000000..166056cc2c4 --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementExample2.txt @@ -0,0 +1,92 @@ ++- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- Global[@CanonicalImage = null] + +- Block[@CanonicalImage = null] + +- DeclarativeSection[@CanonicalImage = null] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- SubTypeDefinition[@CanonicalImage = "RECORDTYP", @Image = "RecordTyp"] + | | +- QualifiedID[@CanonicalImage = "RECORDTYP", @Image = "RecordTyp"] + | | +- FieldDeclaration[@CanonicalImage = "LAST", @Image = "last"] + | | | +- ID[@CanonicalImage = "LAST", @Image = "last"] + | | | +- Datatype[@CanonicalImage = "EMPLOYEES.LAST_NAME%TYPE", @Image = "employees.last_name%TYPE", @TypeImage = "employees.last_name%TYPE"] + | | | +- QualifiedName[@CanonicalImage = "EMPLOYEES.LAST_NAME", @Image = "employees.last_name"] + | | | +- UnqualifiedID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | | +- QualifiedID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | +- FieldDeclaration[@CanonicalImage = "ID", @Image = "id"] + | | +- ID[@CanonicalImage = "ID", @Image = "id"] + | | +- Datatype[@CanonicalImage = "EMPLOYEES.EMPLOYEE_ID%TYPE", @Image = "employees.employee_id%TYPE", @TypeImage = "employees.employee_id%TYPE"] + | | +- QualifiedName[@CanonicalImage = "EMPLOYEES.EMPLOYEE_ID", @Image = "employees.employee_id"] + | | +- UnqualifiedID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- QualifiedID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- DeclarativeUnit[@CanonicalImage = null] + | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | +- VariableOrConstantDeclarator[@CanonicalImage = "REC1 RECORDTYP", @Image = "rec1 RecordTyp"] + | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "REC1", @Image = "rec1"] + | | +- ID[@CanonicalImage = "REC1", @Image = "rec1"] + | +- Datatype[@CanonicalImage = "RECORDTYP", @Image = "RecordTyp", @TypeImage = "RecordTyp"] + | +- QualifiedName[@CanonicalImage = "RECORDTYP", @Image = "RecordTyp"] + | +- UnqualifiedID[@CanonicalImage = "RECORDTYP", @Image = "RecordTyp"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "REC1", @Image = "rec1"] + | | +- ID[@CanonicalImage = "REC1", @Image = "rec1"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- WhereClause[@CanonicalImage = null] + | +- Condition[@CanonicalImage = null] + | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | +- SqlExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | +- PrimaryPrefix[@CanonicalImage = "JOB_ID", @Image = "job_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | +- Column[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | +- ID[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | +- SqlExpression[@CanonicalImage = "\'AD_PRES\'", @Image = "\'AD_PRES\'"] + | +- PrimaryPrefix[@CanonicalImage = "\'AD_PRES\'", @Image = "\'AD_PRES\'", @SelfModifier = false] + | +- Literal[@CanonicalImage = "\'AD_PRES\'", @Image = "\'AD_PRES\'"] + | +- StringLiteral[@CanonicalImage = "\'AD_PRES\'", @Image = "\'AD_PRES\'", @String = "AD_PRES"] + +- Statement[@CanonicalImage = null] + +- UnlabelledStatement[@CanonicalImage = null] + +- Expression[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE"] + +- PrimaryPrefix[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE", @SelfModifier = false] + +- FunctionCall[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE"] + +- FunctionName[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE"] + | +- ID[@CanonicalImage = "DBMS_OUTPUT", @Image = "DBMS_OUTPUT"] + | +- ID[@CanonicalImage = "PUT_LINE", @Image = "PUT_LINE"] + +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + +- ArgumentList[@CanonicalImage = null] + +- Argument[@CanonicalImage = null] + +- Expression[@CanonicalImage = "\'EMPLOYEE #\' || REC1.ID || \' = \' || REC1.LAST", @Image = "\'Employee #\' || rec1.id || \' = \' || rec1.last"] + +- AdditiveExpression[@CanonicalImage = "\'EMPLOYEE #\' || REC1.ID || \' = \' || REC1.LAST", @Image = "\'Employee #\' || rec1.id || \' = \' || rec1.last"] + +- PrimaryPrefix[@CanonicalImage = "\'EMPLOYEE #\'", @Image = "\'Employee #\'", @SelfModifier = false] + | +- Literal[@CanonicalImage = "\'EMPLOYEE #\'", @Image = "\'Employee #\'"] + | +- StringLiteral[@CanonicalImage = "\'EMPLOYEE #\'", @Image = "\'Employee #\'", @String = "Employee #"] + +- PrimaryPrefix[@CanonicalImage = "REC1.ID", @Image = "rec1.id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "REC1.ID", @Image = "rec1.id"] + | +- TableName[@CanonicalImage = "REC1", @Image = "rec1"] + | | +- ID[@CanonicalImage = "REC1", @Image = "rec1"] + | +- Column[@CanonicalImage = "ID", @Image = "id"] + | +- ID[@CanonicalImage = "ID", @Image = "id"] + +- PrimaryPrefix[@CanonicalImage = "\' = \'", @Image = "\' = \'", @SelfModifier = false] + | +- Literal[@CanonicalImage = "\' = \'", @Image = "\' = \'"] + | +- StringLiteral[@CanonicalImage = "\' = \'", @Image = "\' = \'", @String = " = "] + +- PrimaryPrefix[@CanonicalImage = "REC1.LAST", @Image = "rec1.last", @SelfModifier = false] + +- SimpleExpression[@CanonicalImage = "REC1.LAST", @Image = "rec1.last"] + +- TableName[@CanonicalImage = "REC1", @Image = "rec1"] + | +- ID[@CanonicalImage = "REC1", @Image = "rec1"] + +- Column[@CanonicalImage = "LAST", @Image = "last"] + +- ID[@CanonicalImage = "LAST", @Image = "last"] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementExample3.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementExample3.txt new file mode 100644 index 00000000000..e6391074931 --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementExample3.txt @@ -0,0 +1,216 @@ ++- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- DDLCommand[@CanonicalImage = "DROP", @Image = "DROP"] + | +- DDLEvent[@CanonicalImage = "DROP", @Image = "DROP"] + | +- ReadPastNextOccurrence[@CanonicalImage = "TABLE EMP_NAME ;", @Image = "TABLE EMP_NAME ;"] + | +- Read2NextOccurrence[@CanonicalImage = "TABLE EMP_NAME", @Image = "TABLE EMP_NAME "] + +- DDLCommand[@CanonicalImage = "CREATE", @Image = "CREATE"] + | +- DDLEvent[@CanonicalImage = "CREATE", @Image = "CREATE"] + | +- ReadPastNextOccurrence[@CanonicalImage = "TABLE EMP_NAME AS SELECT EMPLOYEE_ID , LAST_NAME FROM EMPLOYEES ;", @Image = "TABLE EMP_NAME AS SELECT EMPLOYEE_ID , LAST_NAME FROM EMPLOYEES ;"] + | +- Read2NextOccurrence[@CanonicalImage = "TABLE EMP_NAME AS SELECT EMPLOYEE_ID , LAST_NAME FROM EMPLOYEES", @Image = "TABLE EMP_NAME AS SELECT EMPLOYEE_ID , LAST_NAME FROM EMPLOYEES "] + +- DDLCommand[@CanonicalImage = "CREATE", @Image = "CREATE"] + | +- DDLEvent[@CanonicalImage = "CREATE", @Image = "CREATE"] + | +- ReadPastNextOccurrence[@CanonicalImage = "UNIQUE INDEX EMPNAME_IX ON EMP_NAME ( EMPLOYEE_ID ) ;", @Image = "UNIQUE INDEX EMPNAME_IX ON EMP_NAME ( EMPLOYEE_ID ) ;"] + | +- Read2NextOccurrence[@CanonicalImage = "UNIQUE INDEX EMPNAME_IX ON EMP_NAME ( EMPLOYEE_ID )", @Image = "UNIQUE INDEX EMPNAME_IX ON EMP_NAME ( EMPLOYEE_ID ) "] + +- DDLCommand[@CanonicalImage = "DROP", @Image = "DROP"] + | +- DDLEvent[@CanonicalImage = "DROP", @Image = "DROP"] + | +- ReadPastNextOccurrence[@CanonicalImage = "TABLE EMP_SAL ;", @Image = "TABLE EMP_SAL ;"] + | +- Read2NextOccurrence[@CanonicalImage = "TABLE EMP_SAL", @Image = "TABLE EMP_SAL "] + +- DDLCommand[@CanonicalImage = "CREATE", @Image = "CREATE"] + | +- DDLEvent[@CanonicalImage = "CREATE", @Image = "CREATE"] + | +- ReadPastNextOccurrence[@CanonicalImage = "TABLE EMP_SAL AS SELECT EMPLOYEE_ID , SALARY FROM EMPLOYEES ;", @Image = "TABLE EMP_SAL AS SELECT EMPLOYEE_ID , SALARY FROM EMPLOYEES ;"] + | +- Read2NextOccurrence[@CanonicalImage = "TABLE EMP_SAL AS SELECT EMPLOYEE_ID , SALARY FROM EMPLOYEES", @Image = "TABLE EMP_SAL AS SELECT EMPLOYEE_ID , SALARY FROM EMPLOYEES "] + +- DDLCommand[@CanonicalImage = "CREATE", @Image = "CREATE"] + | +- DDLEvent[@CanonicalImage = "CREATE", @Image = "CREATE"] + | +- ReadPastNextOccurrence[@CanonicalImage = "UNIQUE INDEX EMPSAL_IX ON EMP_SAL ( EMPLOYEE_ID ) ;", @Image = "UNIQUE INDEX EMPSAL_IX ON EMP_SAL ( EMPLOYEE_ID ) ;"] + | +- Read2NextOccurrence[@CanonicalImage = "UNIQUE INDEX EMPSAL_IX ON EMP_SAL ( EMPLOYEE_ID )", @Image = "UNIQUE INDEX EMPSAL_IX ON EMP_SAL ( EMPLOYEE_ID ) "] + +- DDLCommand[@CanonicalImage = "DROP", @Image = "DROP"] + | +- DDLEvent[@CanonicalImage = "DROP", @Image = "DROP"] + | +- ReadPastNextOccurrence[@CanonicalImage = "TABLE EMP_JOB ;", @Image = "TABLE EMP_JOB ;"] + | +- Read2NextOccurrence[@CanonicalImage = "TABLE EMP_JOB", @Image = "TABLE EMP_JOB "] + +- DDLCommand[@CanonicalImage = "CREATE", @Image = "CREATE"] + | +- DDLEvent[@CanonicalImage = "CREATE", @Image = "CREATE"] + | +- ReadPastNextOccurrence[@CanonicalImage = "TABLE EMP_JOB AS SELECT EMPLOYEE_ID , JOB_ID FROM EMPLOYEES ;", @Image = "TABLE EMP_JOB AS SELECT EMPLOYEE_ID , JOB_ID FROM EMPLOYEES ;"] + | +- Read2NextOccurrence[@CanonicalImage = "TABLE EMP_JOB AS SELECT EMPLOYEE_ID , JOB_ID FROM EMPLOYEES", @Image = "TABLE EMP_JOB AS SELECT EMPLOYEE_ID , JOB_ID FROM EMPLOYEES "] + +- DDLCommand[@CanonicalImage = "CREATE", @Image = "CREATE"] + | +- DDLEvent[@CanonicalImage = "CREATE", @Image = "CREATE"] + | +- ReadPastNextOccurrence[@CanonicalImage = "UNIQUE INDEX EMPJOBID_IX ON EMP_JOB ( EMPLOYEE_ID ) ;", @Image = "UNIQUE INDEX EMPJOBID_IX ON EMP_JOB ( EMPLOYEE_ID ) ;"] + | +- Read2NextOccurrence[@CanonicalImage = "UNIQUE INDEX EMPJOBID_IX ON EMP_JOB ( EMPLOYEE_ID )", @Image = "UNIQUE INDEX EMPJOBID_IX ON EMP_JOB ( EMPLOYEE_ID ) "] + +- Global[@CanonicalImage = null] + +- Block[@CanonicalImage = null] + +- DeclarativeSection[@CanonicalImage = null] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | +- VariableOrConstantDeclarator[@CanonicalImage = "EMP_ID NUMBER(6)", @Image = "emp_id NUMBER(6)"] + | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | | +- ID[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- Datatype[@CanonicalImage = "NUMBER(6)", @Image = "NUMBER(6)", @TypeImage = "NUMBER(6)"] + | | +- ScalarDataTypeName[@CanonicalImage = "NUMBER(6)", @Image = "NUMBER(6)"] + | | +- NumericLiteral[@CanonicalImage = "6", @Image = "6"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | +- VariableOrConstantDeclarator[@CanonicalImage = "EMP_LASTNAME VARCHAR2(25)", @Image = "emp_lastname VARCHAR2(25)"] + | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "EMP_LASTNAME", @Image = "emp_lastname"] + | | | +- ID[@CanonicalImage = "EMP_LASTNAME", @Image = "emp_lastname"] + | | +- Datatype[@CanonicalImage = "VARCHAR2(25)", @Image = "VARCHAR2(25)", @TypeImage = "VARCHAR2(25)"] + | | +- ScalarDataTypeName[@CanonicalImage = "VARCHAR2(25)", @Image = "VARCHAR2(25)"] + | | +- NumericLiteral[@CanonicalImage = "25", @Image = "25"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | +- VariableOrConstantDeclarator[@CanonicalImage = "EMP_SALARY NUMBER(8,2)", @Image = "emp_salary NUMBER(8,2)"] + | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "EMP_SALARY", @Image = "emp_salary"] + | | | +- ID[@CanonicalImage = "EMP_SALARY", @Image = "emp_salary"] + | | +- Datatype[@CanonicalImage = "NUMBER(8,2)", @Image = "NUMBER(8,2)", @TypeImage = "NUMBER(8,2)"] + | | +- ScalarDataTypeName[@CanonicalImage = "NUMBER(8,2)", @Image = "NUMBER(8,2)"] + | | +- NumericLiteral[@CanonicalImage = "8", @Image = "8"] + | | +- PrimaryPrefix[@CanonicalImage = "2", @Image = "2", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "2", @Image = "2"] + | | +- NumericLiteral[@CanonicalImage = "2", @Image = "2"] + | +- DeclarativeUnit[@CanonicalImage = null] + | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | +- VariableOrConstantDeclarator[@CanonicalImage = "EMP_JOBID VARCHAR2(10)", @Image = "emp_jobid VARCHAR2(10)"] + | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "EMP_JOBID", @Image = "emp_jobid"] + | | +- ID[@CanonicalImage = "EMP_JOBID", @Image = "emp_jobid"] + | +- Datatype[@CanonicalImage = "VARCHAR2(10)", @Image = "VARCHAR2(10)", @TypeImage = "VARCHAR2(10)"] + | +- ScalarDataTypeName[@CanonicalImage = "VARCHAR2(10)", @Image = "VARCHAR2(10)"] + | +- NumericLiteral[@CanonicalImage = "10", @Image = "10"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- SqlExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | +- SqlExpression[@CanonicalImage = "SALARY", @Image = "salary"] + | | | +- PrimaryPrefix[@CanonicalImage = "SALARY", @Image = "salary", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "SALARY", @Image = "salary"] + | | | +- Column[@CanonicalImage = "SALARY", @Image = "salary"] + | | | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + | | +- SqlExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | +- PrimaryPrefix[@CanonicalImage = "JOB_ID", @Image = "job_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | +- Column[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | +- ID[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | | +- ID[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- VariableName[@CanonicalImage = "EMP_LASTNAME", @Image = "emp_lastname"] + | | | +- ID[@CanonicalImage = "EMP_LASTNAME", @Image = "emp_lastname"] + | | +- VariableName[@CanonicalImage = "EMP_SALARY", @Image = "emp_salary"] + | | | +- ID[@CanonicalImage = "EMP_SALARY", @Image = "emp_salary"] + | | +- VariableName[@CanonicalImage = "EMP_JOBID", @Image = "emp_jobid"] + | | +- ID[@CanonicalImage = "EMP_JOBID", @Image = "emp_jobid"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- WhereClause[@CanonicalImage = null] + | +- Condition[@CanonicalImage = null] + | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- SqlExpression[@CanonicalImage = "120", @Image = "120"] + | +- PrimaryPrefix[@CanonicalImage = "120", @Image = "120", @SelfModifier = false] + | +- Literal[@CanonicalImage = "120", @Image = "120"] + | +- NumericLiteral[@CanonicalImage = "120", @Image = "120"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- InsertStatement[@CanonicalImage = null] + | +- SingleTableInsert[@CanonicalImage = null] + | +- InsertIntoClause[@CanonicalImage = null] + | | +- DMLTableExpressionClause[@CanonicalImage = null] + | | | +- TableName[@CanonicalImage = "EMP_NAME", @Image = "emp_name"] + | | | +- ID[@CanonicalImage = "EMP_NAME", @Image = "emp_name"] + | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | +- ValuesClause[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- PrimaryPrefix[@CanonicalImage = "EMP_ID", @Image = "emp_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- Column[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- ID[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | +- Expression[@CanonicalImage = "EMP_LASTNAME", @Image = "emp_lastname"] + | +- PrimaryPrefix[@CanonicalImage = "EMP_LASTNAME", @Image = "emp_lastname", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "EMP_LASTNAME", @Image = "emp_lastname"] + | +- Column[@CanonicalImage = "EMP_LASTNAME", @Image = "emp_lastname"] + | +- ID[@CanonicalImage = "EMP_LASTNAME", @Image = "emp_lastname"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- InsertStatement[@CanonicalImage = null] + | +- SingleTableInsert[@CanonicalImage = null] + | +- InsertIntoClause[@CanonicalImage = null] + | | +- DMLTableExpressionClause[@CanonicalImage = null] + | | | +- TableName[@CanonicalImage = "EMP_SAL", @Image = "emp_sal"] + | | | +- ID[@CanonicalImage = "EMP_SAL", @Image = "emp_sal"] + | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- Column[@CanonicalImage = "SALARY", @Image = "salary"] + | | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + | +- ValuesClause[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- PrimaryPrefix[@CanonicalImage = "EMP_ID", @Image = "emp_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- Column[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- ID[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | +- Expression[@CanonicalImage = "EMP_SALARY", @Image = "emp_salary"] + | +- PrimaryPrefix[@CanonicalImage = "EMP_SALARY", @Image = "emp_salary", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "EMP_SALARY", @Image = "emp_salary"] + | +- Column[@CanonicalImage = "EMP_SALARY", @Image = "emp_salary"] + | +- ID[@CanonicalImage = "EMP_SALARY", @Image = "emp_salary"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- InsertStatement[@CanonicalImage = null] + | +- SingleTableInsert[@CanonicalImage = null] + | +- InsertIntoClause[@CanonicalImage = null] + | | +- DMLTableExpressionClause[@CanonicalImage = null] + | | | +- TableName[@CanonicalImage = "EMP_JOB", @Image = "emp_job"] + | | | +- ID[@CanonicalImage = "EMP_JOB", @Image = "emp_job"] + | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- Column[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | +- ID[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | +- ValuesClause[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- PrimaryPrefix[@CanonicalImage = "EMP_ID", @Image = "emp_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- Column[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- ID[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | +- Expression[@CanonicalImage = "EMP_JOBID", @Image = "emp_jobid"] + | +- PrimaryPrefix[@CanonicalImage = "EMP_JOBID", @Image = "emp_jobid", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "EMP_JOBID", @Image = "emp_jobid"] + | +- Column[@CanonicalImage = "EMP_JOBID", @Image = "emp_jobid"] + | +- ID[@CanonicalImage = "EMP_JOBID", @Image = "emp_jobid"] + +- ExceptionHandler[@CanonicalImage = null] + +- QualifiedName[@CanonicalImage = "DUP_VAL_ON_INDEX", @Image = "DUP_VAL_ON_INDEX"] + | +- UnqualifiedID[@CanonicalImage = "DUP_VAL_ON_INDEX", @Image = "DUP_VAL_ON_INDEX"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SqlStatement[@CanonicalImage = null, @Type = Type.ROLLBACK] + | +- Skip2NextTerminator[@CanonicalImage = null] + +- Statement[@CanonicalImage = null] + +- UnlabelledStatement[@CanonicalImage = null] + +- Expression[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE"] + +- PrimaryPrefix[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE", @SelfModifier = false] + +- FunctionCall[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE"] + +- FunctionName[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE"] + | +- ID[@CanonicalImage = "DBMS_OUTPUT", @Image = "DBMS_OUTPUT"] + | +- ID[@CanonicalImage = "PUT_LINE", @Image = "PUT_LINE"] + +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + +- ArgumentList[@CanonicalImage = null] + +- Argument[@CanonicalImage = null] + +- Expression[@CanonicalImage = "\'INSERTS WERE ROLLED BACK\'", @Image = "\'Inserts were rolled back\'"] + +- PrimaryPrefix[@CanonicalImage = "\'INSERTS WERE ROLLED BACK\'", @Image = "\'Inserts were rolled back\'", @SelfModifier = false] + +- Literal[@CanonicalImage = "\'INSERTS WERE ROLLED BACK\'", @Image = "\'Inserts were rolled back\'"] + +- StringLiteral[@CanonicalImage = "\'INSERTS WERE ROLLED BACK\'", @Image = "\'Inserts were rolled back\'", @String = "Inserts were rolled back"] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementExample4.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementExample4.txt new file mode 100644 index 00000000000..93c929fd6be --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementExample4.txt @@ -0,0 +1,133 @@ ++- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- PackageSpecification[@CanonicalImage = "EMP_ACTIONS", @Image = "emp_actions", @ObjectName = "emp_actions"] + | +- ObjectNameDeclaration[@CanonicalImage = "EMP_ACTIONS", @Image = "emp_actions"] + | | +- ID[@CanonicalImage = "EMP_ACTIONS", @Image = "emp_actions"] + | +- DeclarativeSection[@CanonicalImage = null] + | | +- DeclarativeUnit[@CanonicalImage = null] + | | +- ProgramUnit[@CanonicalImage = null, @MethodName = "raise_salary", @Name = "raise_salary", @ObjectName = null] + | | +- MethodDeclarator[@CanonicalImage = "RAISE_SALARY", @Image = "raise_salary", @ParameterCount = 1] + | | +- ObjectNameDeclaration[@CanonicalImage = "RAISE_SALARY", @Image = "raise_salary"] + | | | +- ID[@CanonicalImage = "RAISE_SALARY", @Image = "raise_salary"] + | | +- FormalParameters[@CanonicalImage = "(EMP_ID,SAL_RAISE)", @Image = "(emp_id,sal_raise)"] + | | | +- FormalParameter[@CanonicalImage = "EMP_ID", @Image = "emp_id", @In = false, @NoCopy = false, @Out = false] + | | | | +- ID[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | | | +- Datatype[@CanonicalImage = "NUMBER", @Image = "NUMBER", @TypeImage = "NUMBER"] + | | | | +- ScalarDataTypeName[@CanonicalImage = "NUMBER", @Image = "NUMBER"] + | | | +- FormalParameter[@CanonicalImage = "SAL_RAISE", @Image = "sal_raise", @In = false, @NoCopy = false, @Out = false] + | | | +- ID[@CanonicalImage = "SAL_RAISE", @Image = "sal_raise"] + | | | +- Datatype[@CanonicalImage = "NUMBER", @Image = "NUMBER", @TypeImage = "NUMBER"] + | | | +- ScalarDataTypeName[@CanonicalImage = "NUMBER", @Image = "NUMBER"] + | | +- Datatype[@CanonicalImage = "NUMBER", @Image = "NUMBER", @TypeImage = "NUMBER"] + | | +- ScalarDataTypeName[@CanonicalImage = "NUMBER", @Image = "NUMBER"] + | +- ID[@CanonicalImage = "EMP_ACTIONS", @Image = "emp_actions"] + +- PackageBody[@CanonicalImage = "EMP_ACTIONS", @Image = "emp_actions", @ObjectName = "emp_actions"] + +- ObjectNameDeclaration[@CanonicalImage = "EMP_ACTIONS", @Image = "emp_actions"] + | +- ID[@CanonicalImage = "EMP_ACTIONS", @Image = "emp_actions"] + +- DeclarativeSection[@CanonicalImage = null] + | +- DeclarativeUnit[@CanonicalImage = null] + | +- ProgramUnit[@CanonicalImage = null, @MethodName = "raise_salary", @Name = "raise_salary", @ObjectName = null] + | +- MethodDeclarator[@CanonicalImage = "RAISE_SALARY", @Image = "raise_salary", @ParameterCount = 1] + | | +- ObjectNameDeclaration[@CanonicalImage = "RAISE_SALARY", @Image = "raise_salary"] + | | | +- ID[@CanonicalImage = "RAISE_SALARY", @Image = "raise_salary"] + | | +- FormalParameters[@CanonicalImage = "(EMP_ID,SAL_RAISE)", @Image = "(emp_id,sal_raise)"] + | | | +- FormalParameter[@CanonicalImage = "EMP_ID", @Image = "emp_id", @In = false, @NoCopy = false, @Out = false] + | | | | +- ID[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | | | +- Datatype[@CanonicalImage = "NUMBER", @Image = "NUMBER", @TypeImage = "NUMBER"] + | | | | +- ScalarDataTypeName[@CanonicalImage = "NUMBER", @Image = "NUMBER"] + | | | +- FormalParameter[@CanonicalImage = "SAL_RAISE", @Image = "sal_raise", @In = false, @NoCopy = false, @Out = false] + | | | +- ID[@CanonicalImage = "SAL_RAISE", @Image = "sal_raise"] + | | | +- Datatype[@CanonicalImage = "NUMBER", @Image = "NUMBER", @TypeImage = "NUMBER"] + | | | +- ScalarDataTypeName[@CanonicalImage = "NUMBER", @Image = "NUMBER"] + | | +- Datatype[@CanonicalImage = "NUMBER", @Image = "NUMBER", @TypeImage = "NUMBER"] + | | +- ScalarDataTypeName[@CanonicalImage = "NUMBER", @Image = "NUMBER"] + | +- DeclarativeSection[@CanonicalImage = null] + | | +- DeclarativeUnit[@CanonicalImage = null] + | | | +- Pragma[@CanonicalImage = null] + | | +- DeclarativeUnit[@CanonicalImage = null] + | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | +- VariableOrConstantDeclarator[@CanonicalImage = "NEW_SAL NUMBER(8,2)", @Image = "new_sal NUMBER(8,2)"] + | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "NEW_SAL", @Image = "new_sal"] + | | | +- ID[@CanonicalImage = "NEW_SAL", @Image = "new_sal"] + | | +- Datatype[@CanonicalImage = "NUMBER(8,2)", @Image = "NUMBER(8,2)", @TypeImage = "NUMBER(8,2)"] + | | +- ScalarDataTypeName[@CanonicalImage = "NUMBER(8,2)", @Image = "NUMBER(8,2)"] + | | +- NumericLiteral[@CanonicalImage = "8", @Image = "8"] + | | +- PrimaryPrefix[@CanonicalImage = "2", @Image = "2", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "2", @Image = "2"] + | | +- NumericLiteral[@CanonicalImage = "2", @Image = "2"] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- UpdateStatement[@CanonicalImage = null] + | | +- DMLTableExpressionClause[@CanonicalImage = null] + | | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- UpdateSetClause[@CanonicalImage = null] + | | | +- Column[@CanonicalImage = "SALARY", @Image = "salary"] + | | | | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + | | | +- Expression[@CanonicalImage = "SALARY + SAL_RAISE", @Image = "salary + sal_raise"] + | | | +- AdditiveExpression[@CanonicalImage = "SALARY + SAL_RAISE", @Image = "salary + sal_raise"] + | | | +- PrimaryPrefix[@CanonicalImage = "SALARY", @Image = "salary", @SelfModifier = false] + | | | | +- SimpleExpression[@CanonicalImage = "SALARY", @Image = "salary"] + | | | | +- Column[@CanonicalImage = "SALARY", @Image = "salary"] + | | | | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + | | | +- PrimaryPrefix[@CanonicalImage = "SAL_RAISE", @Image = "sal_raise", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "SAL_RAISE", @Image = "sal_raise"] + | | | +- Column[@CanonicalImage = "SAL_RAISE", @Image = "sal_raise"] + | | | +- ID[@CanonicalImage = "SAL_RAISE", @Image = "sal_raise"] + | | +- WhereClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- SqlExpression[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- PrimaryPrefix[@CanonicalImage = "EMP_ID", @Image = "emp_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- Column[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- ID[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- SqlStatement[@CanonicalImage = null, @Type = Type.COMMIT] + | | +- Skip2NextTerminator[@CanonicalImage = null] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | | +- SelectList[@CanonicalImage = null] + | | | +- SqlExpression[@CanonicalImage = "SALARY", @Image = "salary"] + | | | +- PrimaryPrefix[@CanonicalImage = "SALARY", @Image = "salary", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "SALARY", @Image = "salary"] + | | | +- Column[@CanonicalImage = "SALARY", @Image = "salary"] + | | | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + | | +- IntoClause[@CanonicalImage = null] + | | | +- VariableName[@CanonicalImage = "NEW_SAL", @Image = "new_sal"] + | | | +- ID[@CanonicalImage = "NEW_SAL", @Image = "new_sal"] + | | +- FromClause[@CanonicalImage = null] + | | | +- TableReference[@CanonicalImage = null] + | | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- WhereClause[@CanonicalImage = null] + | | +- Condition[@CanonicalImage = null] + | | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- SqlExpression[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- PrimaryPrefix[@CanonicalImage = "EMP_ID", @Image = "emp_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- Column[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | | +- ID[@CanonicalImage = "EMP_ID", @Image = "emp_id"] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- ReturnStatement[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "NEW_SAL", @Image = "new_sal"] + | | +- PrimaryPrefix[@CanonicalImage = "NEW_SAL", @Image = "new_sal", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "NEW_SAL", @Image = "new_sal"] + | | +- Column[@CanonicalImage = "NEW_SAL", @Image = "new_sal"] + | | +- ID[@CanonicalImage = "NEW_SAL", @Image = "new_sal"] + | +- ID[@CanonicalImage = "RAISE_SALARY", @Image = "raise_salary"] + +- ID[@CanonicalImage = "EMP_ACTIONS", @Image = "emp_actions"] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementExample5.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementExample5.txt new file mode 100644 index 00000000000..ca1a2e4d8c0 --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementExample5.txt @@ -0,0 +1,211 @@ ++- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- Global[@CanonicalImage = null] + +- Block[@CanonicalImage = null] + +- DeclarativeSection[@CanonicalImage = null] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- SubTypeDefinition[@CanonicalImage = "NUMTAB", @Image = "NumTab"] + | | +- QualifiedID[@CanonicalImage = "NUMTAB", @Image = "NumTab"] + | | +- Datatype[@CanonicalImage = "EMPLOYEES.EMPLOYEE_ID%TYPE", @Image = "employees.employee_id%TYPE", @TypeImage = "employees.employee_id%TYPE"] + | | +- QualifiedName[@CanonicalImage = "EMPLOYEES.EMPLOYEE_ID", @Image = "employees.employee_id"] + | | +- UnqualifiedID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- QualifiedID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- SubTypeDefinition[@CanonicalImage = "NAMETAB", @Image = "NameTab"] + | | +- QualifiedID[@CanonicalImage = "NAMETAB", @Image = "NameTab"] + | | +- Datatype[@CanonicalImage = "EMPLOYEES.LAST_NAME%TYPE", @Image = "employees.last_name%TYPE", @TypeImage = "employees.last_name%TYPE"] + | | +- QualifiedName[@CanonicalImage = "EMPLOYEES.LAST_NAME", @Image = "employees.last_name"] + | | +- UnqualifiedID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- QualifiedID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | +- VariableOrConstantDeclarator[@CanonicalImage = "ENUMS NUMTAB", @Image = "enums NumTab"] + | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "ENUMS", @Image = "enums"] + | | | +- ID[@CanonicalImage = "ENUMS", @Image = "enums"] + | | +- Datatype[@CanonicalImage = "NUMTAB", @Image = "NumTab", @TypeImage = "NumTab"] + | | +- QualifiedName[@CanonicalImage = "NUMTAB", @Image = "NumTab"] + | | +- UnqualifiedID[@CanonicalImage = "NUMTAB", @Image = "NumTab"] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | +- VariableOrConstantDeclarator[@CanonicalImage = "NAMES NAMETAB", @Image = "names NameTab"] + | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "NAMES", @Image = "names"] + | | | +- ID[@CanonicalImage = "NAMES", @Image = "names"] + | | +- Datatype[@CanonicalImage = "NAMETAB", @Image = "NameTab", @TypeImage = "NameTab"] + | | +- QualifiedName[@CanonicalImage = "NAMETAB", @Image = "NameTab"] + | | +- UnqualifiedID[@CanonicalImage = "NAMETAB", @Image = "NameTab"] + | +- DeclarativeUnit[@CanonicalImage = null] + | +- ProgramUnit[@CanonicalImage = null, @MethodName = "print_first_n", @Name = "print_first_n", @ObjectName = null] + | +- MethodDeclarator[@CanonicalImage = "PRINT_FIRST_N", @Image = "print_first_n", @ParameterCount = 1] + | | +- ObjectNameDeclaration[@CanonicalImage = "PRINT_FIRST_N", @Image = "print_first_n"] + | | | +- ID[@CanonicalImage = "PRINT_FIRST_N", @Image = "print_first_n"] + | | +- FormalParameters[@CanonicalImage = "(N)", @Image = "(n)"] + | | +- FormalParameter[@CanonicalImage = "N", @Image = "n", @In = false, @NoCopy = false, @Out = false] + | | +- ID[@CanonicalImage = "N", @Image = "n"] + | | +- Datatype[@CanonicalImage = "POSITIVE", @Image = "POSITIVE", @TypeImage = "POSITIVE"] + | | +- ScalarDataTypeName[@CanonicalImage = "POSITIVE", @Image = "POSITIVE"] + | +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- IfStatement[@CanonicalImage = null, @Else = true] + | +- Expression[@CanonicalImage = "ENUMS.COUNT = 0", @Image = "enums.COUNT = 0"] + | | +- EqualityExpression[@CanonicalImage = "ENUMS.COUNT = 0", @Image = "enums.COUNT = 0"] + | | +- PrimaryPrefix[@CanonicalImage = "ENUMS.COUNT", @Image = "enums.COUNT", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "ENUMS.COUNT", @Image = "enums.COUNT"] + | | | +- TableName[@CanonicalImage = "ENUMS", @Image = "enums"] + | | | | +- ID[@CanonicalImage = "ENUMS", @Image = "enums"] + | | | +- Column[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | | +- ID[@CanonicalImage = "COUNT", @Image = "COUNT"] + | | +- PrimaryPrefix[@CanonicalImage = "0", @Image = "0", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "0", @Image = "0"] + | | +- NumericLiteral[@CanonicalImage = "0", @Image = "0"] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE"] + | | +- PrimaryPrefix[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE"] + | | +- FunctionName[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE"] + | | | +- ID[@CanonicalImage = "DBMS_OUTPUT", @Image = "DBMS_OUTPUT"] + | | | +- ID[@CanonicalImage = "PUT_LINE", @Image = "PUT_LINE"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "\'COLLECTIONS ARE EMPTY.\'", @Image = "\'Collections are empty.\'"] + | | +- PrimaryPrefix[@CanonicalImage = "\'COLLECTIONS ARE EMPTY.\'", @Image = "\'Collections are empty.\'", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "\'COLLECTIONS ARE EMPTY.\'", @Image = "\'Collections are empty.\'"] + | | +- StringLiteral[@CanonicalImage = "\'COLLECTIONS ARE EMPTY.\'", @Image = "\'Collections are empty.\'", @String = "Collections are empty."] + | +- ElseClause[@CanonicalImage = null] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE"] + | | +- PrimaryPrefix[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE"] + | | +- FunctionName[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE"] + | | | +- ID[@CanonicalImage = "DBMS_OUTPUT", @Image = "DBMS_OUTPUT"] + | | | +- ID[@CanonicalImage = "PUT_LINE", @Image = "PUT_LINE"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "\'FIRST \' || N || \' EMPLOYEES:\'", @Image = "\'First \' || n || \' employees:\'"] + | | +- AdditiveExpression[@CanonicalImage = "\'FIRST \' || N || \' EMPLOYEES:\'", @Image = "\'First \' || n || \' employees:\'"] + | | +- PrimaryPrefix[@CanonicalImage = "\'FIRST \'", @Image = "\'First \'", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "\'FIRST \'", @Image = "\'First \'"] + | | | +- StringLiteral[@CanonicalImage = "\'FIRST \'", @Image = "\'First \'", @String = "First "] + | | +- PrimaryPrefix[@CanonicalImage = "N", @Image = "n", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "N", @Image = "n"] + | | | +- Column[@CanonicalImage = "N", @Image = "n"] + | | | +- ID[@CanonicalImage = "N", @Image = "n"] + | | +- PrimaryPrefix[@CanonicalImage = "\' EMPLOYEES:\'", @Image = "\' employees:\'", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "\' EMPLOYEES:\'", @Image = "\' employees:\'"] + | | +- StringLiteral[@CanonicalImage = "\' EMPLOYEES:\'", @Image = "\' employees:\'", @String = " employees:"] + | +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- ForStatement[@CanonicalImage = null] + | +- ForIndex[@CanonicalImage = "I", @Image = "i"] + | | +- ID[@CanonicalImage = "I", @Image = "i"] + | +- Expression[@CanonicalImage = "1", @Image = "1"] + | | +- PrimaryPrefix[@CanonicalImage = "1", @Image = "1", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "1", @Image = "1"] + | | +- NumericLiteral[@CanonicalImage = "1", @Image = "1"] + | +- Expression[@CanonicalImage = "N", @Image = "n"] + | | +- PrimaryPrefix[@CanonicalImage = "N", @Image = "n", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "N", @Image = "n"] + | | +- Column[@CanonicalImage = "N", @Image = "n"] + | | +- ID[@CanonicalImage = "N", @Image = "n"] + | +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE"] + | +- PrimaryPrefix[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE", @SelfModifier = false] + | +- FunctionCall[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE"] + | +- FunctionName[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "DBMS_OUTPUT.PUT_LINE"] + | | +- ID[@CanonicalImage = "DBMS_OUTPUT", @Image = "DBMS_OUTPUT"] + | | +- ID[@CanonicalImage = "PUT_LINE", @Image = "PUT_LINE"] + | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | +- ArgumentList[@CanonicalImage = null] + | +- Argument[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "\' EMPLOYEE #\' || ENUMS || \': \' || NAMES", @Image = "\' Employee #\' || enums || \': \' || names"] + | +- AdditiveExpression[@CanonicalImage = "\' EMPLOYEE #\' || ENUMS || \': \' || NAMES", @Image = "\' Employee #\' || enums || \': \' || names"] + | +- PrimaryPrefix[@CanonicalImage = "\' EMPLOYEE #\'", @Image = "\' Employee #\'", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "\' EMPLOYEE #\'", @Image = "\' Employee #\'"] + | | +- StringLiteral[@CanonicalImage = "\' EMPLOYEE #\'", @Image = "\' Employee #\'", @String = " Employee #"] + | +- PrimaryPrefix[@CanonicalImage = "ENUMS", @Image = "enums", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "ENUMS", @Image = "enums"] + | | +- FunctionName[@CanonicalImage = "ENUMS", @Image = "enums"] + | | | +- ID[@CanonicalImage = "ENUMS", @Image = "enums"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "I", @Image = "i"] + | | +- PrimaryPrefix[@CanonicalImage = "I", @Image = "i", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "I", @Image = "i"] + | | +- Column[@CanonicalImage = "I", @Image = "i"] + | | +- ID[@CanonicalImage = "I", @Image = "i"] + | +- PrimaryPrefix[@CanonicalImage = "\': \'", @Image = "\': \'", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "\': \'", @Image = "\': \'"] + | | +- StringLiteral[@CanonicalImage = "\': \'", @Image = "\': \'", @String = ": "] + | +- PrimaryPrefix[@CanonicalImage = "NAMES", @Image = "names", @SelfModifier = false] + | +- FunctionCall[@CanonicalImage = "NAMES", @Image = "names"] + | +- FunctionName[@CanonicalImage = "NAMES", @Image = "names"] + | | +- ID[@CanonicalImage = "NAMES", @Image = "names"] + | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | +- ArgumentList[@CanonicalImage = null] + | +- Argument[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "I", @Image = "i"] + | +- PrimaryPrefix[@CanonicalImage = "I", @Image = "i", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "I", @Image = "i"] + | +- Column[@CanonicalImage = "I", @Image = "i"] + | +- ID[@CanonicalImage = "I", @Image = "i"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | | +- SqlExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | +- PrimaryPrefix[@CanonicalImage = "LAST_NAME", @Image = "last_name", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | +- Column[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | | +- ID[@CanonicalImage = "LAST_NAME", @Image = "last_name"] + | +- BulkCollectIntoClause[@CanonicalImage = null] + | | +- CollectionName[@CanonicalImage = "ENUMS", @Image = "enums"] + | | | +- ID[@CanonicalImage = "ENUMS", @Image = "enums"] + | | +- CollectionName[@CanonicalImage = "NAMES", @Image = "names"] + | | +- ID[@CanonicalImage = "NAMES", @Image = "names"] + | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- OrderByClause[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- PrimaryPrefix[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- Column[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + | +- ID[@CanonicalImage = "EMPLOYEE_ID", @Image = "employee_id"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "PRINT_FIRST_N", @Image = "print_first_n"] + | +- PrimaryPrefix[@CanonicalImage = "PRINT_FIRST_N", @Image = "print_first_n", @SelfModifier = false] + | +- FunctionCall[@CanonicalImage = "PRINT_FIRST_N", @Image = "print_first_n"] + | +- FunctionName[@CanonicalImage = "PRINT_FIRST_N", @Image = "print_first_n"] + | | +- ID[@CanonicalImage = "PRINT_FIRST_N", @Image = "print_first_n"] + | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | +- ArgumentList[@CanonicalImage = null] + | +- Argument[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "3", @Image = "3"] + | +- PrimaryPrefix[@CanonicalImage = "3", @Image = "3", @SelfModifier = false] + | +- Literal[@CanonicalImage = "3", @Image = "3"] + | +- NumericLiteral[@CanonicalImage = "3", @Image = "3"] + +- Statement[@CanonicalImage = null] + +- UnlabelledStatement[@CanonicalImage = null] + +- Expression[@CanonicalImage = "PRINT_FIRST_N", @Image = "print_first_n"] + +- PrimaryPrefix[@CanonicalImage = "PRINT_FIRST_N", @Image = "print_first_n", @SelfModifier = false] + +- FunctionCall[@CanonicalImage = "PRINT_FIRST_N", @Image = "print_first_n"] + +- FunctionName[@CanonicalImage = "PRINT_FIRST_N", @Image = "print_first_n"] + | +- ID[@CanonicalImage = "PRINT_FIRST_N", @Image = "print_first_n"] + +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + +- ArgumentList[@CanonicalImage = null] + +- Argument[@CanonicalImage = null] + +- Expression[@CanonicalImage = "6", @Image = "6"] + +- PrimaryPrefix[@CanonicalImage = "6", @Image = "6", @SelfModifier = false] + +- Literal[@CanonicalImage = "6", @Image = "6"] + +- NumericLiteral[@CanonicalImage = "6", @Image = "6"] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementFunctionCall.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementFunctionCall.txt new file mode 100644 index 00000000000..09dc61aed11 --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementFunctionCall.txt @@ -0,0 +1,71 @@ ++- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- Global[@CanonicalImage = null] + +- Block[@CanonicalImage = null] + +- DeclarativeSection[@CanonicalImage = null] + | +- DeclarativeUnit[@CanonicalImage = null] + | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | +- VariableOrConstantDeclarator[@CanonicalImage = "A NUMBER(8,2)", @Image = "a NUMBER(8,2)"] + | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "A", @Image = "a"] + | | | +- ID[@CanonicalImage = "A", @Image = "a"] + | | +- Datatype[@CanonicalImage = "NUMBER(8,2)", @Image = "NUMBER(8,2)", @TypeImage = "NUMBER(8,2)"] + | | +- ScalarDataTypeName[@CanonicalImage = "NUMBER(8,2)", @Image = "NUMBER(8,2)"] + | | +- NumericLiteral[@CanonicalImage = "8", @Image = "8"] + | | +- PrimaryPrefix[@CanonicalImage = "2", @Image = "2", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "2", @Image = "2"] + | | +- NumericLiteral[@CanonicalImage = "2", @Image = "2"] + | +- DeclarativeUnit[@CanonicalImage = null] + | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | +- VariableOrConstantDeclarator[@CanonicalImage = "B NUMBER(8,2)", @Image = "b NUMBER(8,2)"] + | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "B", @Image = "b"] + | | +- ID[@CanonicalImage = "B", @Image = "b"] + | +- Datatype[@CanonicalImage = "NUMBER(8,2)", @Image = "NUMBER(8,2)", @TypeImage = "NUMBER(8,2)"] + | +- ScalarDataTypeName[@CanonicalImage = "NUMBER(8,2)", @Image = "NUMBER(8,2)"] + | +- NumericLiteral[@CanonicalImage = "8", @Image = "8"] + | +- PrimaryPrefix[@CanonicalImage = "2", @Image = "2", @SelfModifier = false] + | +- Literal[@CanonicalImage = "2", @Image = "2"] + | +- NumericLiteral[@CanonicalImage = "2", @Image = "2"] + +- Statement[@CanonicalImage = null] + +- UnlabelledStatement[@CanonicalImage = null] + +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + +- SelectList[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "SUM", @Image = "SUM"] + | | +- PrimaryPrefix[@CanonicalImage = "SUM", @Image = "SUM", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "SUM", @Image = "SUM"] + | | +- FunctionName[@CanonicalImage = "SUM", @Image = "SUM"] + | | | +- ID[@CanonicalImage = "SUM", @Image = "SUM"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "FIELD1", @Image = "field1"] + | | +- PrimaryPrefix[@CanonicalImage = "FIELD1", @Image = "field1", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "FIELD1", @Image = "field1"] + | | +- Column[@CanonicalImage = "FIELD1", @Image = "field1"] + | | +- ID[@CanonicalImage = "FIELD1", @Image = "field1"] + | +- SqlExpression[@CanonicalImage = "MAX", @Image = "MAX"] + | +- PrimaryPrefix[@CanonicalImage = "MAX", @Image = "MAX", @SelfModifier = false] + | +- FunctionCall[@CanonicalImage = "MAX", @Image = "MAX"] + | +- FunctionName[@CanonicalImage = "MAX", @Image = "MAX"] + | | +- ID[@CanonicalImage = "MAX", @Image = "MAX"] + | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | +- ArgumentList[@CanonicalImage = null] + | +- Argument[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "FIELD2", @Image = "field2"] + | +- PrimaryPrefix[@CanonicalImage = "FIELD2", @Image = "field2", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "FIELD2", @Image = "field2"] + | +- Column[@CanonicalImage = "FIELD2", @Image = "field2"] + | +- ID[@CanonicalImage = "FIELD2", @Image = "field2"] + +- IntoClause[@CanonicalImage = null] + | +- VariableName[@CanonicalImage = "A", @Image = "a"] + | | +- ID[@CanonicalImage = "A", @Image = "a"] + | +- VariableName[@CanonicalImage = "B", @Image = "b"] + | +- ID[@CanonicalImage = "B", @Image = "b"] + +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | +- TableName[@CanonicalImage = "TEST_TBL", @Image = "test_tbl"] + | +- ID[@CanonicalImage = "TEST_TBL", @Image = "test_tbl"] + +- GroupByClause[@CanonicalImage = null] + +- Expression[@CanonicalImage = "FIELDX", @Image = "fieldx"] + +- PrimaryPrefix[@CanonicalImage = "FIELDX", @Image = "fieldx", @SelfModifier = false] + +- SimpleExpression[@CanonicalImage = "FIELDX", @Image = "fieldx"] + +- Column[@CanonicalImage = "FIELDX", @Image = "fieldx"] + +- ID[@CanonicalImage = "FIELDX", @Image = "fieldx"] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementRecordField.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementRecordField.txt new file mode 100644 index 00000000000..3527b802771 --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementRecordField.txt @@ -0,0 +1,32 @@ ++- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- Global[@CanonicalImage = null] + +- Block[@CanonicalImage = null] + +- Statement[@CanonicalImage = null] + +- UnlabelledStatement[@CanonicalImage = null] + +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + +- SelectList[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "THE_ID", @Image = "the_id"] + | +- PrimaryPrefix[@CanonicalImage = "THE_ID", @Image = "the_id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "THE_ID", @Image = "the_id"] + | +- Column[@CanonicalImage = "THE_ID", @Image = "the_id"] + | +- ID[@CanonicalImage = "THE_ID", @Image = "the_id"] + +- IntoClause[@CanonicalImage = null] + | +- VariableName[@CanonicalImage = "MY_RECORD.THE_ID", @Image = "my_record.the_id"] + | +- ID[@CanonicalImage = "MY_RECORD", @Image = "my_record"] + | +- ID[@CanonicalImage = "THE_ID", @Image = "the_id"] + +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | +- TableName[@CanonicalImage = "MY_TABLE", @Image = "my_table"] + | +- ID[@CanonicalImage = "MY_TABLE", @Image = "my_table"] + +- WhereClause[@CanonicalImage = null] + +- Condition[@CanonicalImage = null] + +- CompoundCondition[@CanonicalImage = null, @Type = null] + +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + +- SqlExpression[@CanonicalImage = "THE_ID", @Image = "the_id"] + | +- PrimaryPrefix[@CanonicalImage = "THE_ID", @Image = "the_id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "THE_ID", @Image = "the_id"] + | +- Column[@CanonicalImage = "THE_ID", @Image = "the_id"] + | +- ID[@CanonicalImage = "THE_ID", @Image = "the_id"] + +- SqlExpression[@CanonicalImage = "\'1\'", @Image = "\'1\'"] + +- PrimaryPrefix[@CanonicalImage = "\'1\'", @Image = "\'1\'", @SelfModifier = false] + +- Literal[@CanonicalImage = "\'1\'", @Image = "\'1\'"] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupBy1.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupBy1.txt new file mode 100644 index 00000000000..28f0940c3cd --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupBy1.txt @@ -0,0 +1,57 @@ ++- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- Global[@CanonicalImage = null] + +- Block[@CanonicalImage = null] + +- Statement[@CanonicalImage = null] + +- UnlabelledStatement[@CanonicalImage = null] + +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + +- SelectList[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | +- SqlExpression[@CanonicalImage = "MIN", @Image = "MIN"] + | | +- PrimaryPrefix[@CanonicalImage = "MIN", @Image = "MIN", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "MIN", @Image = "MIN"] + | | +- FunctionName[@CanonicalImage = "MIN", @Image = "MIN"] + | | | +- ID[@CanonicalImage = "MIN", @Image = "MIN"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "SALARY", @Image = "salary"] + | | +- PrimaryPrefix[@CanonicalImage = "SALARY", @Image = "salary", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "SALARY", @Image = "salary"] + | | +- Column[@CanonicalImage = "SALARY", @Image = "salary"] + | | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + | +- SqlExpression[@CanonicalImage = "MAX", @Image = "MAX"] + | +- PrimaryPrefix[@CanonicalImage = "MAX", @Image = "MAX", @SelfModifier = false] + | +- FunctionCall[@CanonicalImage = "MAX", @Image = "MAX"] + | +- FunctionName[@CanonicalImage = "MAX", @Image = "MAX"] + | | +- ID[@CanonicalImage = "MAX", @Image = "MAX"] + | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | +- ArgumentList[@CanonicalImage = null] + | +- Argument[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "SALARY", @Image = "salary"] + | +- PrimaryPrefix[@CanonicalImage = "SALARY", @Image = "salary", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "SALARY", @Image = "salary"] + | +- Column[@CanonicalImage = "SALARY", @Image = "salary"] + | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + +- IntoClause[@CanonicalImage = null] + | +- VariableName[@CanonicalImage = "SOME_RECORD", @Image = "some_record"] + | +- ID[@CanonicalImage = "SOME_RECORD", @Image = "some_record"] + +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + +- GroupByClause[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + +- OrderByClause[@CanonicalImage = null] + +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupBy2.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupBy2.txt new file mode 100644 index 00000000000..3789a68ed30 --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupBy2.txt @@ -0,0 +1,70 @@ ++- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- Global[@CanonicalImage = null] + +- Block[@CanonicalImage = null] + +- Statement[@CanonicalImage = null] + +- UnlabelledStatement[@CanonicalImage = null] + +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + +- SelectList[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | +- SqlExpression[@CanonicalImage = "MIN", @Image = "MIN"] + | | +- PrimaryPrefix[@CanonicalImage = "MIN", @Image = "MIN", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "MIN", @Image = "MIN"] + | | +- FunctionName[@CanonicalImage = "MIN", @Image = "MIN"] + | | | +- ID[@CanonicalImage = "MIN", @Image = "MIN"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "SALARY", @Image = "salary"] + | | +- PrimaryPrefix[@CanonicalImage = "SALARY", @Image = "salary", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "SALARY", @Image = "salary"] + | | +- Column[@CanonicalImage = "SALARY", @Image = "salary"] + | | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + | +- SqlExpression[@CanonicalImage = "MAX", @Image = "MAX"] + | +- PrimaryPrefix[@CanonicalImage = "MAX", @Image = "MAX", @SelfModifier = false] + | +- FunctionCall[@CanonicalImage = "MAX", @Image = "MAX"] + | +- FunctionName[@CanonicalImage = "MAX", @Image = "MAX"] + | | +- ID[@CanonicalImage = "MAX", @Image = "MAX"] + | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | +- ArgumentList[@CanonicalImage = null] + | +- Argument[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "SALARY", @Image = "salary"] + | +- PrimaryPrefix[@CanonicalImage = "SALARY", @Image = "salary", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "SALARY", @Image = "salary"] + | +- Column[@CanonicalImage = "SALARY", @Image = "salary"] + | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + +- IntoClause[@CanonicalImage = null] + | +- VariableName[@CanonicalImage = "SOME_RECORD", @Image = "some_record"] + | +- ID[@CanonicalImage = "SOME_RECORD", @Image = "some_record"] + +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + +- WhereClause[@CanonicalImage = null] + | +- Condition[@CanonicalImage = null] + | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | +- SqlExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | +- PrimaryPrefix[@CanonicalImage = "JOB_ID", @Image = "job_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | +- Column[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | +- ID[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | +- SqlExpression[@CanonicalImage = "\'PU_CLERK\'", @Image = "\'PU_CLERK\'"] + | +- PrimaryPrefix[@CanonicalImage = "\'PU_CLERK\'", @Image = "\'PU_CLERK\'", @SelfModifier = false] + | +- Literal[@CanonicalImage = "\'PU_CLERK\'", @Image = "\'PU_CLERK\'"] + | +- StringLiteral[@CanonicalImage = "\'PU_CLERK\'", @Image = "\'PU_CLERK\'", @String = "PU_CLERK"] + +- GroupByClause[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + +- OrderByClause[@CanonicalImage = null] + +- SqlExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id", @SelfModifier = false] + +- SimpleExpression[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupBy3.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupBy3.txt new file mode 100644 index 00000000000..feb251a123a --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupBy3.txt @@ -0,0 +1,150 @@ ++- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- Global[@CanonicalImage = null] + +- Block[@CanonicalImage = null] + +- Statement[@CanonicalImage = null] + +- UnlabelledStatement[@CanonicalImage = null] + +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + +- SelectList[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "DECODE", @Image = "DECODE"] + | | +- PrimaryPrefix[@CanonicalImage = "DECODE", @Image = "DECODE", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "DECODE", @Image = "DECODE"] + | | +- FunctionName[@CanonicalImage = "DECODE", @Image = "DECODE"] + | | | +- ID[@CanonicalImage = "DECODE", @Image = "DECODE"] + | | +- Arguments[@ArgumentCount = 4, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "GROUPING", @Image = "GROUPING"] + | | | +- PrimaryPrefix[@CanonicalImage = "GROUPING", @Image = "GROUPING", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "GROUPING", @Image = "GROUPING"] + | | | +- FunctionName[@CanonicalImage = "GROUPING", @Image = "GROUPING"] + | | | | +- ID[@CanonicalImage = "GROUPING", @Image = "GROUPING"] + | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | +- ArgumentList[@CanonicalImage = null] + | | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "DEPARTMENT_NAME", @Image = "department_name"] + | | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_NAME", @Image = "department_name", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_NAME", @Image = "department_name"] + | | | +- Column[@CanonicalImage = "DEPARTMENT_NAME", @Image = "department_name"] + | | | +- ID[@CanonicalImage = "DEPARTMENT_NAME", @Image = "department_name"] + | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "1", @Image = "1"] + | | | +- PrimaryPrefix[@CanonicalImage = "1", @Image = "1", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "1", @Image = "1"] + | | | +- NumericLiteral[@CanonicalImage = "1", @Image = "1"] + | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "\'ALL DEPARTMENTS\'", @Image = "\'All Departments\'"] + | | | +- PrimaryPrefix[@CanonicalImage = "\'ALL DEPARTMENTS\'", @Image = "\'All Departments\'", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "\'ALL DEPARTMENTS\'", @Image = "\'All Departments\'"] + | | | +- StringLiteral[@CanonicalImage = "\'ALL DEPARTMENTS\'", @Image = "\'All Departments\'", @String = "All Departments"] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "DEPARTMENT_NAME", @Image = "department_name"] + | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_NAME", @Image = "department_name", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_NAME", @Image = "department_name"] + | | +- Column[@CanonicalImage = "DEPARTMENT_NAME", @Image = "department_name"] + | | +- ID[@CanonicalImage = "DEPARTMENT_NAME", @Image = "department_name"] + | +- ColumnAlias[@CanonicalImage = "DEPARTMENT_NAME", @Image = "department_name"] + | | +- ID[@CanonicalImage = "DEPARTMENT_NAME", @Image = "department_name"] + | +- SqlExpression[@CanonicalImage = "DECODE", @Image = "DECODE"] + | | +- PrimaryPrefix[@CanonicalImage = "DECODE", @Image = "DECODE", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "DECODE", @Image = "DECODE"] + | | +- FunctionName[@CanonicalImage = "DECODE", @Image = "DECODE"] + | | | +- ID[@CanonicalImage = "DECODE", @Image = "DECODE"] + | | +- Arguments[@ArgumentCount = 4, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "GROUPING", @Image = "GROUPING"] + | | | +- PrimaryPrefix[@CanonicalImage = "GROUPING", @Image = "GROUPING", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "GROUPING", @Image = "GROUPING"] + | | | +- FunctionName[@CanonicalImage = "GROUPING", @Image = "GROUPING"] + | | | | +- ID[@CanonicalImage = "GROUPING", @Image = "GROUPING"] + | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | +- ArgumentList[@CanonicalImage = null] + | | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "JOB_ID", @Image = "job_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | | +- Column[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | | +- ID[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "1", @Image = "1"] + | | | +- PrimaryPrefix[@CanonicalImage = "1", @Image = "1", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "1", @Image = "1"] + | | | +- NumericLiteral[@CanonicalImage = "1", @Image = "1"] + | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "\'ALL JOBS\'", @Image = "\'All Jobs\'"] + | | | +- PrimaryPrefix[@CanonicalImage = "\'ALL JOBS\'", @Image = "\'All Jobs\'", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "\'ALL JOBS\'", @Image = "\'All Jobs\'"] + | | | +- StringLiteral[@CanonicalImage = "\'ALL JOBS\'", @Image = "\'All Jobs\'", @String = "All Jobs"] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | +- PrimaryPrefix[@CanonicalImage = "JOB_ID", @Image = "job_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | +- Column[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | +- ID[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | +- ColumnAlias[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | | +- ID[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | +- SqlExpression[@CanonicalImage = "COUNT", @Image = "count"] + | | +- PrimaryPrefix[@CanonicalImage = "COUNT", @Image = "count", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "COUNT", @Image = "count"] + | | +- Column[@CanonicalImage = "COUNT", @Image = "count"] + | | +- ID[@CanonicalImage = "COUNT", @Image = "count"] + | +- ColumnAlias[@CanonicalImage = "TOTAL_EMPL", @Image = "Total_Empl"] + | +- ID[@CanonicalImage = "TOTAL_EMPL", @Image = "Total_Empl"] + +- IntoClause[@CanonicalImage = null] + | +- VariableName[@CanonicalImage = "SOME_RECORD", @Image = "some_record"] + | +- ID[@CanonicalImage = "SOME_RECORD", @Image = "some_record"] + +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | | +- TableAlias[@CanonicalImage = "E", @Image = "e"] + | | +- ID[@CanonicalImage = "E", @Image = "e"] + | +- TableReference[@CanonicalImage = null] + | +- TableName[@CanonicalImage = "DEPARTMENTS", @Image = "departments"] + | | +- ID[@CanonicalImage = "DEPARTMENTS", @Image = "departments"] + | +- TableAlias[@CanonicalImage = "D", @Image = "d"] + | +- ID[@CanonicalImage = "D", @Image = "d"] + +- WhereClause[@CanonicalImage = null] + | +- Condition[@CanonicalImage = null] + | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | +- SqlExpression[@CanonicalImage = "D.DEPARTMENT_ID", @Image = "d.department_id"] + | | +- PrimaryPrefix[@CanonicalImage = "D.DEPARTMENT_ID", @Image = "d.department_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "D.DEPARTMENT_ID", @Image = "d.department_id"] + | | +- TableName[@CanonicalImage = "D", @Image = "d"] + | | | +- ID[@CanonicalImage = "D", @Image = "d"] + | | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | +- SqlExpression[@CanonicalImage = "E.DEPARTMENT_ID", @Image = "e.department_id"] + | +- PrimaryPrefix[@CanonicalImage = "E.DEPARTMENT_ID", @Image = "e.department_id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "E.DEPARTMENT_ID", @Image = "e.department_id"] + | +- TableName[@CanonicalImage = "E", @Image = "e"] + | | +- ID[@CanonicalImage = "E", @Image = "e"] + | +- Column[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + | +- ID[@CanonicalImage = "DEPARTMENT_ID", @Image = "department_id"] + +- GroupByClause[@CanonicalImage = null] + | +- RollupCubeClause[@CanonicalImage = "CUBE", @Image = "CUBE"] + | +- GroupingExpressionList[@CanonicalImage = null] + | +- ExpressionList[@CanonicalImage = null] + | +- ExpressionListSingle[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "DEPARTMENT_NAME", @Image = "department_name"] + | | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_NAME", @Image = "department_name", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_NAME", @Image = "department_name"] + | | +- Column[@CanonicalImage = "DEPARTMENT_NAME", @Image = "department_name"] + | | +- ID[@CanonicalImage = "DEPARTMENT_NAME", @Image = "department_name"] + | +- SqlExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | +- PrimaryPrefix[@CanonicalImage = "JOB_ID", @Image = "job_id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | +- Column[@CanonicalImage = "JOB_ID", @Image = "job_id"] + | +- ID[@CanonicalImage = "JOB_ID", @Image = "job_id"] + +- OrderByClause[@CanonicalImage = null] + +- SqlExpression[@CanonicalImage = "DEPARTMENT_NAME", @Image = "department_name"] + | +- PrimaryPrefix[@CanonicalImage = "DEPARTMENT_NAME", @Image = "department_name", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "DEPARTMENT_NAME", @Image = "department_name"] + | +- Column[@CanonicalImage = "DEPARTMENT_NAME", @Image = "department_name"] + | +- ID[@CanonicalImage = "DEPARTMENT_NAME", @Image = "department_name"] + +- SqlExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + +- PrimaryPrefix[@CanonicalImage = "JOB_ID", @Image = "job_id", @SelfModifier = false] + +- SimpleExpression[@CanonicalImage = "JOB_ID", @Image = "job_id"] + +- Column[@CanonicalImage = "JOB_ID", @Image = "job_id"] + +- ID[@CanonicalImage = "JOB_ID", @Image = "job_id"] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupBy4.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupBy4.txt new file mode 100644 index 00000000000..e60b30e61a4 --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupBy4.txt @@ -0,0 +1,230 @@ ++- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- Global[@CanonicalImage = null] + +- Block[@CanonicalImage = null] + +- Statement[@CanonicalImage = null] + +- UnlabelledStatement[@CanonicalImage = null] + +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + +- SelectList[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "CHANNEL_DESC", @Image = "channel_desc"] + | | +- PrimaryPrefix[@CanonicalImage = "CHANNEL_DESC", @Image = "channel_desc", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "CHANNEL_DESC", @Image = "channel_desc"] + | | +- Column[@CanonicalImage = "CHANNEL_DESC", @Image = "channel_desc"] + | | +- ID[@CanonicalImage = "CHANNEL_DESC", @Image = "channel_desc"] + | +- SqlExpression[@CanonicalImage = "CALENDAR_MONTH_DESC", @Image = "calendar_month_desc"] + | | +- PrimaryPrefix[@CanonicalImage = "CALENDAR_MONTH_DESC", @Image = "calendar_month_desc", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "CALENDAR_MONTH_DESC", @Image = "calendar_month_desc"] + | | +- Column[@CanonicalImage = "CALENDAR_MONTH_DESC", @Image = "calendar_month_desc"] + | | +- ID[@CanonicalImage = "CALENDAR_MONTH_DESC", @Image = "calendar_month_desc"] + | +- SqlExpression[@CanonicalImage = "CO.COUNTRY_ID", @Image = "co.country_id"] + | | +- PrimaryPrefix[@CanonicalImage = "CO.COUNTRY_ID", @Image = "co.country_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "CO.COUNTRY_ID", @Image = "co.country_id"] + | | +- TableName[@CanonicalImage = "CO", @Image = "co"] + | | | +- ID[@CanonicalImage = "CO", @Image = "co"] + | | +- Column[@CanonicalImage = "COUNTRY_ID", @Image = "country_id"] + | | +- ID[@CanonicalImage = "COUNTRY_ID", @Image = "country_id"] + | +- SqlExpression[@CanonicalImage = "AMOUNT_SOLD", @Image = "amount_sold"] + | | +- PrimaryPrefix[@CanonicalImage = "AMOUNT_SOLD", @Image = "amount_sold", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "AMOUNT_SOLD", @Image = "amount_sold"] + | | +- Column[@CanonicalImage = "AMOUNT_SOLD", @Image = "amount_sold"] + | | +- ID[@CanonicalImage = "AMOUNT_SOLD", @Image = "amount_sold"] + | +- ColumnAlias[@CanonicalImage = "SALES$", @Image = "SALES$"] + | +- ID[@CanonicalImage = "SALES$", @Image = "SALES$"] + +- IntoClause[@CanonicalImage = null] + | +- VariableName[@CanonicalImage = "SOME_RECORD", @Image = "some_record"] + | +- ID[@CanonicalImage = "SOME_RECORD", @Image = "some_record"] + +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "SALES", @Image = "sales"] + | | +- ID[@CanonicalImage = "SALES", @Image = "sales"] + | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "CUSTOMERS", @Image = "customers"] + | | +- ID[@CanonicalImage = "CUSTOMERS", @Image = "customers"] + | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "TIMES", @Image = "times"] + | | +- ID[@CanonicalImage = "TIMES", @Image = "times"] + | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "CHANNELS", @Image = "channels"] + | | +- ID[@CanonicalImage = "CHANNELS", @Image = "channels"] + | +- TableReference[@CanonicalImage = null] + | +- TableName[@CanonicalImage = "COUNTRIES", @Image = "countries"] + | | +- ID[@CanonicalImage = "COUNTRIES", @Image = "countries"] + | +- TableAlias[@CanonicalImage = "CO", @Image = "co"] + | +- ID[@CanonicalImage = "CO", @Image = "co"] + +- WhereClause[@CanonicalImage = null] + | +- Condition[@CanonicalImage = null] + | +- CompoundCondition[@CanonicalImage = null, @Type = "AND"] + | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "SALES.TIME_ID", @Image = "sales.time_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "SALES.TIME_ID", @Image = "sales.time_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "SALES.TIME_ID", @Image = "sales.time_id"] + | | | +- TableName[@CanonicalImage = "SALES", @Image = "sales"] + | | | | +- ID[@CanonicalImage = "SALES", @Image = "sales"] + | | | +- Column[@CanonicalImage = "TIME_ID", @Image = "time_id"] + | | | +- ID[@CanonicalImage = "TIME_ID", @Image = "time_id"] + | | +- SqlExpression[@CanonicalImage = "TIMES.TIME_ID", @Image = "times.time_id"] + | | +- PrimaryPrefix[@CanonicalImage = "TIMES.TIME_ID", @Image = "times.time_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "TIMES.TIME_ID", @Image = "times.time_id"] + | | +- TableName[@CanonicalImage = "TIMES", @Image = "times"] + | | | +- ID[@CanonicalImage = "TIMES", @Image = "times"] + | | +- Column[@CanonicalImage = "TIME_ID", @Image = "time_id"] + | | +- ID[@CanonicalImage = "TIME_ID", @Image = "time_id"] + | +- Condition[@CanonicalImage = null] + | +- CompoundCondition[@CanonicalImage = null, @Type = "AND"] + | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "SALES.CUST_ID", @Image = "sales.cust_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "SALES.CUST_ID", @Image = "sales.cust_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "SALES.CUST_ID", @Image = "sales.cust_id"] + | | | +- TableName[@CanonicalImage = "SALES", @Image = "sales"] + | | | | +- ID[@CanonicalImage = "SALES", @Image = "sales"] + | | | +- Column[@CanonicalImage = "CUST_ID", @Image = "cust_id"] + | | | +- ID[@CanonicalImage = "CUST_ID", @Image = "cust_id"] + | | +- SqlExpression[@CanonicalImage = "CUSTOMERS.CUST_ID", @Image = "customers.cust_id"] + | | +- PrimaryPrefix[@CanonicalImage = "CUSTOMERS.CUST_ID", @Image = "customers.cust_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "CUSTOMERS.CUST_ID", @Image = "customers.cust_id"] + | | +- TableName[@CanonicalImage = "CUSTOMERS", @Image = "customers"] + | | | +- ID[@CanonicalImage = "CUSTOMERS", @Image = "customers"] + | | +- Column[@CanonicalImage = "CUST_ID", @Image = "cust_id"] + | | +- ID[@CanonicalImage = "CUST_ID", @Image = "cust_id"] + | +- Condition[@CanonicalImage = null] + | +- CompoundCondition[@CanonicalImage = null, @Type = "AND"] + | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "SALES.CHANNEL_ID", @Image = "sales.channel_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "SALES.CHANNEL_ID", @Image = "sales.channel_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "SALES.CHANNEL_ID", @Image = "sales.channel_id"] + | | | +- TableName[@CanonicalImage = "SALES", @Image = "sales"] + | | | | +- ID[@CanonicalImage = "SALES", @Image = "sales"] + | | | +- Column[@CanonicalImage = "CHANNEL_ID", @Image = "channel_id"] + | | | +- ID[@CanonicalImage = "CHANNEL_ID", @Image = "channel_id"] + | | +- SqlExpression[@CanonicalImage = "CHANNELS.CHANNEL_ID", @Image = "channels.channel_id"] + | | +- PrimaryPrefix[@CanonicalImage = "CHANNELS.CHANNEL_ID", @Image = "channels.channel_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "CHANNELS.CHANNEL_ID", @Image = "channels.channel_id"] + | | +- TableName[@CanonicalImage = "CHANNELS", @Image = "channels"] + | | | +- ID[@CanonicalImage = "CHANNELS", @Image = "channels"] + | | +- Column[@CanonicalImage = "CHANNEL_ID", @Image = "channel_id"] + | | +- ID[@CanonicalImage = "CHANNEL_ID", @Image = "channel_id"] + | +- Condition[@CanonicalImage = null] + | +- CompoundCondition[@CanonicalImage = null, @Type = "AND"] + | +- ComparisonCondition[@CanonicalImage = null, @Operator = "="] + | | +- SqlExpression[@CanonicalImage = "CUSTOMERS.COUNTRY_ID", @Image = "customers.country_id"] + | | | +- PrimaryPrefix[@CanonicalImage = "CUSTOMERS.COUNTRY_ID", @Image = "customers.country_id", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "CUSTOMERS.COUNTRY_ID", @Image = "customers.country_id"] + | | | +- TableName[@CanonicalImage = "CUSTOMERS", @Image = "customers"] + | | | | +- ID[@CanonicalImage = "CUSTOMERS", @Image = "customers"] + | | | +- Column[@CanonicalImage = "COUNTRY_ID", @Image = "country_id"] + | | | +- ID[@CanonicalImage = "COUNTRY_ID", @Image = "country_id"] + | | +- SqlExpression[@CanonicalImage = "CO.COUNTRY_ID", @Image = "co.country_id"] + | | +- PrimaryPrefix[@CanonicalImage = "CO.COUNTRY_ID", @Image = "co.country_id", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "CO.COUNTRY_ID", @Image = "co.country_id"] + | | +- TableName[@CanonicalImage = "CO", @Image = "co"] + | | | +- ID[@CanonicalImage = "CO", @Image = "co"] + | | +- Column[@CanonicalImage = "COUNTRY_ID", @Image = "country_id"] + | | +- ID[@CanonicalImage = "COUNTRY_ID", @Image = "country_id"] + | +- Condition[@CanonicalImage = null] + | +- CompoundCondition[@CanonicalImage = null, @Type = "AND"] + | +- InCondition[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "CHANNELS.CHANNEL_DESC", @Image = "channels.channel_desc"] + | | | +- PrimaryPrefix[@CanonicalImage = "CHANNELS.CHANNEL_DESC", @Image = "channels.channel_desc", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "CHANNELS.CHANNEL_DESC", @Image = "channels.channel_desc"] + | | | +- TableName[@CanonicalImage = "CHANNELS", @Image = "channels"] + | | | | +- ID[@CanonicalImage = "CHANNELS", @Image = "channels"] + | | | +- Column[@CanonicalImage = "CHANNEL_DESC", @Image = "channel_desc"] + | | | +- ID[@CanonicalImage = "CHANNEL_DESC", @Image = "channel_desc"] + | | +- ExpressionListSingle[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "\'DIRECT SALES\'", @Image = "\'Direct Sales\'"] + | | | +- PrimaryPrefix[@CanonicalImage = "\'DIRECT SALES\'", @Image = "\'Direct Sales\'", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "\'DIRECT SALES\'", @Image = "\'Direct Sales\'"] + | | | +- StringLiteral[@CanonicalImage = "\'DIRECT SALES\'", @Image = "\'Direct Sales\'", @String = "Direct Sales"] + | | +- SqlExpression[@CanonicalImage = "\'INTERNET\'", @Image = "\'Internet\'"] + | | +- PrimaryPrefix[@CanonicalImage = "\'INTERNET\'", @Image = "\'Internet\'", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "\'INTERNET\'", @Image = "\'Internet\'"] + | | +- StringLiteral[@CanonicalImage = "\'INTERNET\'", @Image = "\'Internet\'", @String = "Internet"] + | +- Condition[@CanonicalImage = null] + | +- CompoundCondition[@CanonicalImage = null, @Type = "AND"] + | +- InCondition[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "TIMES.CALENDAR_MONTH_DESC", @Image = "times.calendar_month_desc"] + | | | +- PrimaryPrefix[@CanonicalImage = "TIMES.CALENDAR_MONTH_DESC", @Image = "times.calendar_month_desc", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "TIMES.CALENDAR_MONTH_DESC", @Image = "times.calendar_month_desc"] + | | | +- TableName[@CanonicalImage = "TIMES", @Image = "times"] + | | | | +- ID[@CanonicalImage = "TIMES", @Image = "times"] + | | | +- Column[@CanonicalImage = "CALENDAR_MONTH_DESC", @Image = "calendar_month_desc"] + | | | +- ID[@CanonicalImage = "CALENDAR_MONTH_DESC", @Image = "calendar_month_desc"] + | | +- ExpressionListSingle[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "\'2000-09\'", @Image = "\'2000-09\'"] + | | | +- PrimaryPrefix[@CanonicalImage = "\'2000-09\'", @Image = "\'2000-09\'", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "\'2000-09\'", @Image = "\'2000-09\'"] + | | | +- StringLiteral[@CanonicalImage = "\'2000-09\'", @Image = "\'2000-09\'", @String = "2000-09"] + | | +- SqlExpression[@CanonicalImage = "\'2000-10\'", @Image = "\'2000-10\'"] + | | +- PrimaryPrefix[@CanonicalImage = "\'2000-10\'", @Image = "\'2000-10\'", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "\'2000-10\'", @Image = "\'2000-10\'"] + | | +- StringLiteral[@CanonicalImage = "\'2000-10\'", @Image = "\'2000-10\'", @String = "2000-10"] + | +- Condition[@CanonicalImage = null] + | +- CompoundCondition[@CanonicalImage = null, @Type = null] + | +- InCondition[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "CO.COUNTRY_ISO_CODE", @Image = "co.country_iso_code"] + | | +- PrimaryPrefix[@CanonicalImage = "CO.COUNTRY_ISO_CODE", @Image = "co.country_iso_code", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "CO.COUNTRY_ISO_CODE", @Image = "co.country_iso_code"] + | | +- TableName[@CanonicalImage = "CO", @Image = "co"] + | | | +- ID[@CanonicalImage = "CO", @Image = "co"] + | | +- Column[@CanonicalImage = "COUNTRY_ISO_CODE", @Image = "country_iso_code"] + | | +- ID[@CanonicalImage = "COUNTRY_ISO_CODE", @Image = "country_iso_code"] + | +- ExpressionListSingle[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "\'UK\'", @Image = "\'UK\'"] + | | +- PrimaryPrefix[@CanonicalImage = "\'UK\'", @Image = "\'UK\'", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "\'UK\'", @Image = "\'UK\'"] + | | +- StringLiteral[@CanonicalImage = "\'UK\'", @Image = "\'UK\'", @String = "UK"] + | +- SqlExpression[@CanonicalImage = "\'US\'", @Image = "\'US\'"] + | +- PrimaryPrefix[@CanonicalImage = "\'US\'", @Image = "\'US\'", @SelfModifier = false] + | +- Literal[@CanonicalImage = "\'US\'", @Image = "\'US\'"] + | +- StringLiteral[@CanonicalImage = "\'US\'", @Image = "\'US\'", @String = "US"] + +- GroupByClause[@CanonicalImage = null] + +- GroupingSetsClause[@CanonicalImage = null] + +- GroupingExpressionList[@CanonicalImage = null] + +- ExpressionList[@CanonicalImage = null] + +- ExpressionListSingle[@CanonicalImage = null] + +- SqlExpression[@CanonicalImage = "(CHANNEL_DESC, CALENDAR_MONTH_DESC, CO.COUNTRY_ID)", @Image = "(channel_desc, calendar_month_desc, co.country_id)"] + | +- PrimaryPrefix[@CanonicalImage = "(CHANNEL_DESC, CALENDAR_MONTH_DESC, CO.COUNTRY_ID)", @Image = "(channel_desc, calendar_month_desc, co.country_id)", @SelfModifier = false] + | +- Expression[@CanonicalImage = "CHANNEL_DESC", @Image = "channel_desc"] + | | +- PrimaryPrefix[@CanonicalImage = "CHANNEL_DESC", @Image = "channel_desc", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "CHANNEL_DESC", @Image = "channel_desc"] + | | +- Column[@CanonicalImage = "CHANNEL_DESC", @Image = "channel_desc"] + | | +- ID[@CanonicalImage = "CHANNEL_DESC", @Image = "channel_desc"] + | +- Expression[@CanonicalImage = "CALENDAR_MONTH_DESC", @Image = "calendar_month_desc"] + | | +- PrimaryPrefix[@CanonicalImage = "CALENDAR_MONTH_DESC", @Image = "calendar_month_desc", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "CALENDAR_MONTH_DESC", @Image = "calendar_month_desc"] + | | +- Column[@CanonicalImage = "CALENDAR_MONTH_DESC", @Image = "calendar_month_desc"] + | | +- ID[@CanonicalImage = "CALENDAR_MONTH_DESC", @Image = "calendar_month_desc"] + | +- Expression[@CanonicalImage = "CO.COUNTRY_ID", @Image = "co.country_id"] + | +- PrimaryPrefix[@CanonicalImage = "CO.COUNTRY_ID", @Image = "co.country_id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "CO.COUNTRY_ID", @Image = "co.country_id"] + | +- TableName[@CanonicalImage = "CO", @Image = "co"] + | | +- ID[@CanonicalImage = "CO", @Image = "co"] + | +- Column[@CanonicalImage = "COUNTRY_ID", @Image = "country_id"] + | +- ID[@CanonicalImage = "COUNTRY_ID", @Image = "country_id"] + +- SqlExpression[@CanonicalImage = "(CHANNEL_DESC, CO.COUNTRY_ID)", @Image = "(channel_desc, co.country_id)"] + | +- PrimaryPrefix[@CanonicalImage = "(CHANNEL_DESC, CO.COUNTRY_ID)", @Image = "(channel_desc, co.country_id)", @SelfModifier = false] + | +- Expression[@CanonicalImage = "CHANNEL_DESC", @Image = "channel_desc"] + | | +- PrimaryPrefix[@CanonicalImage = "CHANNEL_DESC", @Image = "channel_desc", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "CHANNEL_DESC", @Image = "channel_desc"] + | | +- Column[@CanonicalImage = "CHANNEL_DESC", @Image = "channel_desc"] + | | +- ID[@CanonicalImage = "CHANNEL_DESC", @Image = "channel_desc"] + | +- Expression[@CanonicalImage = "CO.COUNTRY_ID", @Image = "co.country_id"] + | +- PrimaryPrefix[@CanonicalImage = "CO.COUNTRY_ID", @Image = "co.country_id", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "CO.COUNTRY_ID", @Image = "co.country_id"] + | +- TableName[@CanonicalImage = "CO", @Image = "co"] + | | +- ID[@CanonicalImage = "CO", @Image = "co"] + | +- Column[@CanonicalImage = "COUNTRY_ID", @Image = "country_id"] + | +- ID[@CanonicalImage = "COUNTRY_ID", @Image = "country_id"] + +- SqlExpression[@CanonicalImage = "(CALENDAR_MONTH_DESC, CO.COUNTRY_ID)", @Image = "(calendar_month_desc, co.country_id)"] + +- PrimaryPrefix[@CanonicalImage = "(CALENDAR_MONTH_DESC, CO.COUNTRY_ID)", @Image = "(calendar_month_desc, co.country_id)", @SelfModifier = false] + +- Expression[@CanonicalImage = "CALENDAR_MONTH_DESC", @Image = "calendar_month_desc"] + | +- PrimaryPrefix[@CanonicalImage = "CALENDAR_MONTH_DESC", @Image = "calendar_month_desc", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "CALENDAR_MONTH_DESC", @Image = "calendar_month_desc"] + | +- Column[@CanonicalImage = "CALENDAR_MONTH_DESC", @Image = "calendar_month_desc"] + | +- ID[@CanonicalImage = "CALENDAR_MONTH_DESC", @Image = "calendar_month_desc"] + +- Expression[@CanonicalImage = "CO.COUNTRY_ID", @Image = "co.country_id"] + +- PrimaryPrefix[@CanonicalImage = "CO.COUNTRY_ID", @Image = "co.country_id", @SelfModifier = false] + +- SimpleExpression[@CanonicalImage = "CO.COUNTRY_ID", @Image = "co.country_id"] + +- TableName[@CanonicalImage = "CO", @Image = "co"] + | +- ID[@CanonicalImage = "CO", @Image = "co"] + +- Column[@CanonicalImage = "COUNTRY_ID", @Image = "country_id"] + +- ID[@CanonicalImage = "COUNTRY_ID", @Image = "country_id"] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectSimpleExpression.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectSimpleExpression.txt new file mode 100644 index 00000000000..aeda7cdf4f6 --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectSimpleExpression.txt @@ -0,0 +1,23 @@ ++- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- Global[@CanonicalImage = null] + +- Block[@CanonicalImage = null] + +- Statement[@CanonicalImage = null] + +- UnlabelledStatement[@CanonicalImage = null] + +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + +- SelectList[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "E.FIRST_NAME", @Image = "e.first_name"] + | +- PrimaryPrefix[@CanonicalImage = "E.FIRST_NAME", @Image = "e.first_name", @SelfModifier = false] + | +- SimpleExpression[@CanonicalImage = "E.FIRST_NAME", @Image = "e.first_name"] + | +- TableName[@CanonicalImage = "E", @Image = "e"] + | | +- ID[@CanonicalImage = "E", @Image = "e"] + | +- Column[@CanonicalImage = "FIRST_NAME", @Image = "first_name"] + | +- ID[@CanonicalImage = "FIRST_NAME", @Image = "first_name"] + +- IntoClause[@CanonicalImage = null] + | +- VariableName[@CanonicalImage = "TEST", @Image = "test"] + | +- ID[@CanonicalImage = "TEST", @Image = "test"] + +- FromClause[@CanonicalImage = null] + +- TableReference[@CanonicalImage = null] + +- TableName[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + | +- ID[@CanonicalImage = "EMPLOYEES", @Image = "employees"] + +- TableAlias[@CanonicalImage = "E", @Image = "e"] + +- ID[@CanonicalImage = "E", @Image = "e"] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectSubqueryExpressions.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectSubqueryExpressions.txt new file mode 100644 index 00000000000..401ae1fdbbe --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/SelectSubqueryExpressions.txt @@ -0,0 +1,140 @@ ++- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- Global[@CanonicalImage = null] + +- Block[@CanonicalImage = null] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "", @Image = ""] + | | +- PrimaryPrefix[@CanonicalImage = "", @Image = "", @SelfModifier = false] + | | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | | +- SelectList[@CanonicalImage = null] + | | | +- SqlExpression[@CanonicalImage = "A", @Image = "a"] + | | | +- PrimaryPrefix[@CanonicalImage = "A", @Image = "a", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "A", @Image = "a"] + | | | +- Column[@CanonicalImage = "A", @Image = "a"] + | | | +- ID[@CanonicalImage = "A", @Image = "a"] + | | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "DUAL", @Image = "DUAL"] + | | +- ID[@CanonicalImage = "DUAL", @Image = "DUAL"] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "FOO", @Image = "foo"] + | | +- ID[@CanonicalImage = "FOO", @Image = "foo"] + | +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | +- TableName[@CanonicalImage = "DUAL", @Image = "DUAL"] + | +- ID[@CanonicalImage = "DUAL", @Image = "DUAL"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "", @Image = ""] + | | +- PrimaryPrefix[@CanonicalImage = "", @Image = "", @SelfModifier = false] + | | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | | +- SelectList[@CanonicalImage = null] + | | | +- SqlExpression[@CanonicalImage = "MAX", @Image = "MAX"] + | | | +- PrimaryPrefix[@CanonicalImage = "MAX", @Image = "MAX", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "MAX", @Image = "MAX"] + | | | +- FunctionName[@CanonicalImage = "MAX", @Image = "MAX"] + | | | | +- ID[@CanonicalImage = "MAX", @Image = "MAX"] + | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | +- ArgumentList[@CanonicalImage = null] + | | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "A", @Image = "a"] + | | | +- PrimaryPrefix[@CanonicalImage = "A", @Image = "a", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "A", @Image = "a"] + | | | +- Column[@CanonicalImage = "A", @Image = "a"] + | | | +- ID[@CanonicalImage = "A", @Image = "a"] + | | +- FromClause[@CanonicalImage = null] + | | +- TableReference[@CanonicalImage = null] + | | +- TableName[@CanonicalImage = "DUAL", @Image = "DUAL"] + | | +- ID[@CanonicalImage = "DUAL", @Image = "DUAL"] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "FOO", @Image = "foo"] + | | +- ID[@CanonicalImage = "FOO", @Image = "foo"] + | +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | +- TableName[@CanonicalImage = "DUAL", @Image = "DUAL"] + | +- ID[@CanonicalImage = "DUAL", @Image = "DUAL"] + +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- SelectIntoStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "(AVG * 2)", @Image = "(AVG * 2)"] + | | +- PrimaryPrefix[@CanonicalImage = "(AVG * 2)", @Image = "(AVG * 2)", @SelfModifier = false] + | | +- Expression[@CanonicalImage = "AVG * 2", @Image = "AVG * 2"] + | | +- MultiplicativeExpression[@CanonicalImage = "AVG * 2", @Image = "AVG * 2"] + | | +- PrimaryPrefix[@CanonicalImage = "AVG", @Image = "AVG", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "AVG", @Image = "AVG"] + | | | +- FunctionName[@CanonicalImage = "AVG", @Image = "AVG"] + | | | | +- ID[@CanonicalImage = "AVG", @Image = "AVG"] + | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | +- ArgumentList[@CanonicalImage = null] + | | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "SAL", @Image = "sal"] + | | | +- PrimaryPrefix[@CanonicalImage = "SAL", @Image = "sal", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "SAL", @Image = "sal"] + | | | +- Column[@CanonicalImage = "SAL", @Image = "sal"] + | | | +- ID[@CanonicalImage = "SAL", @Image = "sal"] + | | +- PrimaryPrefix[@CanonicalImage = "2", @Image = "2", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "2", @Image = "2"] + | | +- NumericLiteral[@CanonicalImage = "2", @Image = "2"] + | +- IntoClause[@CanonicalImage = null] + | | +- VariableName[@CanonicalImage = "FOO", @Image = "foo"] + | | +- ID[@CanonicalImage = "FOO", @Image = "foo"] + | +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | +- TableName[@CanonicalImage = "BAR", @Image = "bar"] + | +- ID[@CanonicalImage = "BAR", @Image = "bar"] + +- Statement[@CanonicalImage = null] + +- UnlabelledStatement[@CanonicalImage = null] + +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + +- SelectList[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "A.OBJECT_NAME", @Image = "a.object_name"] + | | +- PrimaryPrefix[@CanonicalImage = "A.OBJECT_NAME", @Image = "a.object_name", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "A.OBJECT_NAME", @Image = "a.object_name"] + | | +- TableName[@CanonicalImage = "A", @Image = "a"] + | | | +- ID[@CanonicalImage = "A", @Image = "a"] + | | +- Column[@CanonicalImage = "OBJECT_NAME", @Image = "object_name"] + | | +- ID[@CanonicalImage = "OBJECT_NAME", @Image = "object_name"] + | +- SqlExpression[@CanonicalImage = "", @Image = ""] + | +- PrimaryPrefix[@CanonicalImage = "", @Image = "", @SelfModifier = false] + | +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "MAX", @Image = "MAX"] + | | +- PrimaryPrefix[@CanonicalImage = "MAX", @Image = "MAX", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "MAX", @Image = "MAX"] + | | +- FunctionName[@CanonicalImage = "MAX", @Image = "MAX"] + | | | +- ID[@CanonicalImage = "MAX", @Image = "MAX"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "NVL", @Image = "NVL"] + | | +- PrimaryPrefix[@CanonicalImage = "NVL", @Image = "NVL", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "NVL", @Image = "NVL"] + | | +- FunctionName[@CanonicalImage = "NVL", @Image = "NVL"] + | | | +- ID[@CanonicalImage = "NVL", @Image = "NVL"] + | | +- Arguments[@ArgumentCount = 2, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "B.POSITION", @Image = "b.position"] + | | | +- PrimaryPrefix[@CanonicalImage = "B.POSITION", @Image = "b.position", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "B.POSITION", @Image = "b.position"] + | | | +- TableName[@CanonicalImage = "B", @Image = "b"] + | | | | +- ID[@CanonicalImage = "B", @Image = "b"] + | | | +- Column[@CanonicalImage = "POSITION", @Image = "position"] + | | | +- ID[@CanonicalImage = "POSITION", @Image = "position"] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "-1", @Image = " -1"] + | | +- PrimaryPrefix[@CanonicalImage = "1", @Image = "1", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "1", @Image = "1"] + | | +- NumericLiteral[@CanonicalImage = "1", @Image = "1"] + | +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | +- TableName[@CanonicalImage = "DUAL", @Image = "DUAL"] + | +- ID[@CanonicalImage = "DUAL", @Image = "DUAL"] + +- FromClause[@CanonicalImage = null] + +- TableReference[@CanonicalImage = null] + +- TableName[@CanonicalImage = "DUAL", @Image = "DUAL"] + +- ID[@CanonicalImage = "DUAL", @Image = "DUAL"] From 384f7b7470adea0483c4a6cfbb1cb4528f7a6300 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Feb 2025 12:38:33 +0100 Subject: [PATCH 0563/1962] [plsql] Avoid lookaheads to distinguish between SELECT and SELECT INTO This also fixes some wrong parsing results: some SELECT statements are now parsed as SELECT INTO statements. --- pmd-plsql/src/main/javacc/PLSQL.jjt | 64 +++++++++++-------- .../pmd/lang/plsql/ast/SelectExpressions.txt | 4 +- .../pmd/lang/plsql/ast/SelectHierarchical.txt | 2 +- .../lang/plsql/ast/SelectIntoStatement.txt | 2 +- .../plsql/ast/SelectIntoStatementExample5.txt | 2 +- 5 files changed, 44 insertions(+), 30 deletions(-) diff --git a/pmd-plsql/src/main/javacc/PLSQL.jjt b/pmd-plsql/src/main/javacc/PLSQL.jjt index b47cd60ab56..24b3d1c2d80 100644 --- a/pmd-plsql/src/main/javacc/PLSQL.jjt +++ b/pmd-plsql/src/main/javacc/PLSQL.jjt @@ -239,6 +239,15 @@ public class PLSQLParserImpl { && getToken(1).getText().charAt(0) != '"'; } + private boolean hasIntoClause() { + int arity = jjtree.nodeArity(); + while (--arity >= 0) { + if (jjtree.peekNode(arity) instanceof ASTIntoClause || jjtree.peekNode(arity) instanceof ASTBulkCollectIntoClause) { + return true; + } + } + return false; + } } PARSER_END(PLSQLParserImpl) @@ -1302,34 +1311,46 @@ ASTSqlStatement SqlStatement(String initiator, String terminator) : } } -void AbstractSelectStatement(AbstractSelectStatement node) #void : -{} -{ - + [ { node.setDistinct(true); } + | { node.setUnique(true); } + | { node.setAll(true); } + ] } void RestOfStatement() #void : @@ -2378,14 +2399,7 @@ ASTUnlabelledStatement UnlabelledStatement() : {} { ( - // small optimization: SelectIntoStatement and SelectStatement both begin with WITH or SELECT - // but to distinguish the two, a complete lookahead of SelectIntoStatement needs to be parsed. - // Using a lookahead of a single token first avoids this the syntatic lookahead for all other choices - // not related to SELECT statements. - LOOKAHEAD(| | -| github releases | A new release with 3 assets (bin, src, doc) is created | | | -| sourceforge files | The 3 assets (bin, src, doc) are uploaded, the new version is pre-selected as latest | | | -| homepage | Main landing page points to new version, doc for new version is available | | | -| homepage2 | New blogpost for the new release is posted | | | -| docs | New docs are uploaded | | | -| docs2 | New version in the docs is listed under "Version specific documentation" | | | -| docs-archive | New docs are also on archive site | | | -| javadoc | New javadocs are uploaded | | | -| news | New blogpost on sourceforge is posted | | | -| regression-tester | New release baseline is uploaded | | | -| mailing list | announcement on mailing list is sent | | | -| twitter | tweet about the new release | | | -| gitter | message about the new release | | | +| Task | Description | URL | โ˜ / โœ” | +|-------------------|--------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------|-------------------------| +| maven central | The new version of all artifacts are available in maven central | | | +| github releases | A new release with 3 assets (bin, src, doc) is created | | | +| sourceforge files | The 3 assets (bin, src, doc) are uploaded, the new version is pre-selected as latest | | | +| docker image | New docker images are available | / | | +| homepage | Main landing page points to new version, doc for new version is available | | | +| homepage2 | New blogpost for the new release is posted | | | +| docs | New docs are uploaded | | | +| docs2 | New version in the docs is listed under "Version specific documentation" | | | +| docs-archive | New docs are also on archive site | | | +| javadoc | New javadocs are uploaded | | | +| news | New blogpost on sourceforge is posted | | | +| regression-tester | New release baseline is uploaded | | | +| mailing list | announcement on mailing list is sent | | | +| twitter | tweet about the new release | | | +| gitter | message about the new release | | | ## Prepare the next release From a66732705b86ac8cd54d3d0f587b65174913098d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Apr 2025 11:51:17 +0200 Subject: [PATCH 0770/1962] Add docker badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 681f710fe73..aa1e7368367 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg)](code_of_conduct.md) [![Documentation (latest)](https://img.shields.io/badge/docs-latest-green)](https://docs.pmd-code.org/latest/) [![Gurubase](https://img.shields.io/badge/Gurubase-Ask%20PMD%20Guru-006BFF)](https://gurubase.io/g/pmd) +[![Docker Image Version](https://img.shields.io/docker/v/pmdcode/pmd?sort=semver&label=Docker)](https://hub.docker.com/r/pmdcode/pmd) **PMD** is an extensible multilanguage static code analyzer. It finds common programming flaws like unused variables, empty catch blocks, unnecessary object creation, and so forth. It's mainly concerned with **Java and From 4885650862c6746813bfe0795b991a8f229f2f52 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Apr 2025 11:56:46 +0200 Subject: [PATCH 0771/1962] [doc] Update release notes (#5448) --- docs/pages/release_notes.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 66047b07cd8..b232ff4f011 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -14,8 +14,22 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy +#### Docker images + +PMD is now providing official docker images at and +. + +You can now analyze your code with PMD by using docker like so: + +``` +docker run --rm --tty -v $PWD:/src pmdcode/pmd:latest check -d . -R rulesets/java/quickstart.xml` +``` + +More information is available at . + ### ๐Ÿ› Fixed Issues * core + * [#5448](https://github.com/pmd/pmd/issues/5448): Maintain a public PMD docker image * [#5623](https://github.com/pmd/pmd/issues/5623): \[dist] Make pmd launch script compatible with /bin/sh * java * [#5645](https://github.com/pmd/pmd/issues/5645): \[java] Parse error on switch with yield From 30ecc58fdcd1f91c028a103b3c2017c0329a4e11 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Apr 2025 12:09:12 +0200 Subject: [PATCH 0772/1962] Add @jetmore as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 169 +++++++++++++------------- 2 files changed, 94 insertions(+), 84 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 016e01a5037..53b25f8d3d0 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8038,6 +8038,15 @@ "contributions": [ "bug" ] + }, + { + "login": "jetmore", + "name": "John Jetmore", + "avatar_url": "https://avatars.githubusercontent.com/u/978659?v=4", + "profile": "https://jetmore.org/john/", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index dcef1032085..6ba43d24694 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -389,757 +389,758 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Joao Machado
    Joao Machado

    ๐Ÿ› Jochen Krauss
    Jochen Krauss

    ๐Ÿ› Johan Hammar
    Johan Hammar

    ๐Ÿ› + John Jetmore
    John Jetmore

    ๐Ÿ“– John Karp
    John Karp

    ๐Ÿ› - John Zhang
    John Zhang

    ๐Ÿ› + John Zhang
    John Zhang

    ๐Ÿ› John-Teng
    John-Teng

    ๐Ÿ’ป ๐Ÿ› Jon Moroney
    Jon Moroney

    ๐Ÿ’ป ๐Ÿ› Jonas Geiregat
    Jonas Geiregat

    ๐Ÿ› Jonas KeรŸler
    Jonas KeรŸler

    ๐Ÿ› Jonathan Wiesel
    Jonathan Wiesel

    ๐Ÿ’ป ๐Ÿ› Jordan
    Jordan

    ๐Ÿ› - Jordi Llach
    Jordi Llach

    ๐Ÿ› + Jordi Llach
    Jordi Llach

    ๐Ÿ› Jorge Solรณrzano
    Jorge Solรณrzano

    ๐Ÿ› JorneVL
    JorneVL

    ๐Ÿ› Jose Palafox
    Jose Palafox

    ๐Ÿ› Jose Stovall
    Jose Stovall

    ๐Ÿ› Joseph
    Joseph

    ๐Ÿ’ป Joseph Heenan
    Joseph Heenan

    ๐Ÿ› - Josh Feingold
    Josh Feingold

    ๐Ÿ’ป ๐Ÿ› + Josh Feingold
    Josh Feingold

    ๐Ÿ’ป ๐Ÿ› Josh Holthaus
    Josh Holthaus

    ๐Ÿ› Joshua S Arquilevich
    Joshua S Arquilevich

    ๐Ÿ› Joรฃo Dinis Ferreira
    Joรฃo Dinis Ferreira

    ๐Ÿ“– Joรฃo Ferreira
    Joรฃo Ferreira

    ๐Ÿ’ป ๐Ÿ› Joรฃo Pedro Schmitt
    Joรฃo Pedro Schmitt

    ๐Ÿ› Juan Martรญn Sotuyo Dodero
    Juan Martรญn Sotuyo Dodero

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง - Juan Pablo Civile
    Juan Pablo Civile

    ๐Ÿ› + Juan Pablo Civile
    Juan Pablo Civile

    ๐Ÿ› Julian Voronetsky
    Julian Voronetsky

    ๐Ÿ› Julien
    Julien

    ๐Ÿ› Julius
    Julius

    ๐Ÿ› JustPRV
    JustPRV

    ๐Ÿ› Justin Stroud
    Justin Stroud

    ๐Ÿ’ป Jรถrn Huxhorn
    Jรถrn Huxhorn

    ๐Ÿ› - KThompso
    KThompso

    ๐Ÿ› + KThompso
    KThompso

    ๐Ÿ› Kai Amundsen
    Kai Amundsen

    ๐Ÿ› Karel Vervaeke
    Karel Vervaeke

    ๐Ÿ› Karl-Andero Mere
    Karl-Andero Mere

    ๐Ÿ› Karl-Philipp Richter
    Karl-Philipp Richter

    ๐Ÿ› Karsten Silz
    Karsten Silz

    ๐Ÿ› Kazuma Watanabe
    Kazuma Watanabe

    ๐Ÿ› - Kev
    Kev

    ๐Ÿ› + Kev
    Kev

    ๐Ÿ› Keve Mรผller
    Keve Mรผller

    ๐Ÿ› Kevin Guerra
    Kevin Guerra

    ๐Ÿ’ป Kevin Jones
    Kevin Jones

    ๐Ÿ› ๐Ÿ’ป Kevin Poorman
    Kevin Poorman

    ๐Ÿ› Kevin Wayne
    Kevin Wayne

    ๐Ÿ› Kieran Black
    Kieran Black

    ๐Ÿ› - Kirill Zubov
    Kirill Zubov

    ๐Ÿ› + Kirill Zubov
    Kirill Zubov

    ๐Ÿ› Kirk Clemens
    Kirk Clemens

    ๐Ÿ’ป ๐Ÿ› Klaus Hartl
    Klaus Hartl

    ๐Ÿ› Koen Van Looveren
    Koen Van Looveren

    ๐Ÿ› Kris Scheibe
    Kris Scheibe

    ๐Ÿ’ป ๐Ÿ› Krystian Dabrowski
    Krystian Dabrowski

    ๐Ÿ› ๐Ÿ’ป Krzysztof Dymek
    Krzysztof Dymek

    ๐Ÿ› - Kunal Thanki
    Kunal Thanki

    ๐Ÿ› + Kunal Thanki
    Kunal Thanki

    ๐Ÿ› Kursat Aktas
    Kursat Aktas

    ๐Ÿ“– LaLucid
    LaLucid

    ๐Ÿ’ป Larry Diamond
    Larry Diamond

    ๐Ÿ’ป ๐Ÿ› Lars Knickrehm
    Lars Knickrehm

    ๐Ÿ› Laurent Bovet
    Laurent Bovet

    ๐Ÿ› ๐Ÿ’ป Leo Gutierrez
    Leo Gutierrez

    ๐Ÿ› - LiGaOg
    LiGaOg

    ๐Ÿ’ป + LiGaOg
    LiGaOg

    ๐Ÿ’ป Liam Sharp
    Liam Sharp

    ๐Ÿ› Lintsi
    Lintsi

    ๐Ÿ› Linus Fernandes
    Linus Fernandes

    ๐Ÿ› Lixon Lookose
    Lixon Lookose

    ๐Ÿ› Logesh
    Logesh

    ๐Ÿ› Lorenzo Gabriele
    Lorenzo Gabriele

    ๐Ÿ› - Loรฏc Ledoyen
    Loรฏc Ledoyen

    ๐Ÿ› + Loรฏc Ledoyen
    Loรฏc Ledoyen

    ๐Ÿ› Lucas
    Lucas

    ๐Ÿ› Lucas Silva
    Lucas Silva

    ๐Ÿ› Lucas Soncini
    Lucas Soncini

    ๐Ÿ’ป ๐Ÿ› Luis Alcantar
    Luis Alcantar

    ๐Ÿ’ป Lukas Grรคf
    Lukas Grรคf

    ๐Ÿ’ป Lukasz Slonina
    Lukasz Slonina

    ๐Ÿ› - Lukebray
    Lukebray

    ๐Ÿ› + Lukebray
    Lukebray

    ๐Ÿ› Lynn
    Lynn

    ๐Ÿ’ป ๐Ÿ› Lyor Goldstein
    Lyor Goldstein

    ๐Ÿ› MCMicS
    MCMicS

    ๐Ÿ› Macarse
    Macarse

    ๐Ÿ› Machine account for PMD
    Machine account for PMD

    ๐Ÿ’ป Maciek Siemczyk
    Maciek Siemczyk

    ๐Ÿ› - Maikel Steneker
    Maikel Steneker

    ๐Ÿ’ป ๐Ÿ› + Maikel Steneker
    Maikel Steneker

    ๐Ÿ’ป ๐Ÿ› Maksim Moiseikin
    Maksim Moiseikin

    ๐Ÿ› Manfred Koch
    Manfred Koch

    ๐Ÿ› Manuel Moya Ferrer
    Manuel Moya Ferrer

    ๐Ÿ’ป ๐Ÿ› Manuel Romeiro
    Manuel Romeiro

    ๐Ÿ› Manuel Ryan
    Manuel Ryan

    ๐Ÿ› Marat Vyshegorodtsev
    Marat Vyshegorodtsev

    ๐Ÿ› - Marcel Hรคrle
    Marcel Hรคrle

    ๐Ÿ› + Marcel Hรคrle
    Marcel Hรคrle

    ๐Ÿ› Marcello Fialho
    Marcello Fialho

    ๐Ÿ› Marcin Dฤ…browski
    Marcin Dฤ…browski

    ๐Ÿ’ป Marcin Rataj
    Marcin Rataj

    ๐Ÿ› Marcono1234
    Marcono1234

    ๐Ÿ› Mark Adamcin
    Mark Adamcin

    ๐Ÿ› Mark Hall
    Mark Hall

    ๐Ÿ’ป ๐Ÿ› - Mark Kolich
    Mark Kolich

    ๐Ÿ› + Mark Kolich
    Mark Kolich

    ๐Ÿ› Mark Pritchard
    Mark Pritchard

    ๐Ÿ› Markus Rathgeb
    Markus Rathgeb

    ๐Ÿ› Marquis Wang
    Marquis Wang

    ๐Ÿ› MartGit
    MartGit

    ๐Ÿ› Martin Feldsztejn
    Martin Feldsztejn

    ๐Ÿ› Martin Lehmann
    Martin Lehmann

    ๐Ÿ› - Martin Spamer
    Martin Spamer

    ๐Ÿ› + Martin Spamer
    Martin Spamer

    ๐Ÿ› Martin Tarjรกnyi
    Martin Tarjรกnyi

    ๐Ÿ› MatFl
    MatFl

    ๐Ÿ› Mateusz Stefanski
    Mateusz Stefanski

    ๐Ÿ› Mathias Lagerwall
    Mathias Lagerwall

    ๐Ÿ› Mathieu Gouin
    Mathieu Gouin

    ๐Ÿ› MatiasComercio
    MatiasComercio

    ๐Ÿ’ป ๐Ÿ› - Matt Benson
    Matt Benson

    ๐Ÿ› + Matt Benson
    Matt Benson

    ๐Ÿ› Matt De Poorter
    Matt De Poorter

    ๐Ÿ› Matt Hargett
    Matt Hargett

    ๐Ÿ’ป ๐Ÿ’ต Matt Harrah
    Matt Harrah

    ๐Ÿ› Matt Nelson
    Matt Nelson

    ๐Ÿ› Matthew Amos
    Matthew Amos

    ๐Ÿ› Matthew Duggan
    Matthew Duggan

    ๐Ÿ› - Matthew Hall
    Matthew Hall

    ๐Ÿ› + Matthew Hall
    Matthew Hall

    ๐Ÿ› Matthew Rossner
    Matthew Rossner

    ๐Ÿ› Matรญas Fraga
    Matรญas Fraga

    ๐Ÿ’ป ๐Ÿ› Maxime Robert
    Maxime Robert

    ๐Ÿ’ป ๐Ÿ› MetaBF
    MetaBF

    ๐Ÿ› Metin Dagcilar
    Metin Dagcilar

    ๐Ÿ› Michael
    Michael

    ๐Ÿ› - Michael Bell
    Michael Bell

    ๐Ÿ› + Michael Bell
    Michael Bell

    ๐Ÿ› Michael Bernstein
    Michael Bernstein

    ๐Ÿ› Michael Clay
    Michael Clay

    ๐Ÿ› Michael Dombrowski
    Michael Dombrowski

    ๐Ÿ› Michael Hausegger
    Michael Hausegger

    ๐Ÿ› Michael Hoefer
    Michael Hoefer

    ๐Ÿ› Michael Kolesnikov
    Michael Kolesnikov

    ๐Ÿ› - Michael Mรถbius
    Michael Mรถbius

    ๐Ÿ› + Michael Mรถbius
    Michael Mรถbius

    ๐Ÿ› Michael N. Lipp
    Michael N. Lipp

    ๐Ÿ› Michael Pellegrini
    Michael Pellegrini

    ๐Ÿ› Michal Kordas
    Michal Kordas

    ๐Ÿ› Michaล‚ Borek
    Michaล‚ Borek

    ๐Ÿ› Michaล‚ Kuliล„ski
    Michaล‚ Kuliล„ski

    ๐Ÿ› Miguel Nรบรฑez Dรญaz-Montes
    Miguel Nรบรฑez Dรญaz-Montes

    ๐Ÿ› - Mihai Ionut
    Mihai Ionut

    ๐Ÿ› + Mihai Ionut
    Mihai Ionut

    ๐Ÿ› Mikhail Kuchma
    Mikhail Kuchma

    ๐Ÿ› Mirek Hankus
    Mirek Hankus

    ๐Ÿ› Mitch Spano
    Mitch Spano

    ๐Ÿ’ป ๐Ÿ› Mladjan Gadzic
    Mladjan Gadzic

    ๐Ÿ› Mladjan Gadzic
    Mladjan Gadzic

    ๐Ÿ› MrAngry52
    MrAngry52

    ๐Ÿ› - Muminur Choudhury
    Muminur Choudhury

    ๐Ÿ› + Muminur Choudhury
    Muminur Choudhury

    ๐Ÿ› Mykhailo Palahuta
    Mykhailo Palahuta

    ๐Ÿ’ป ๐Ÿ› Nagendra Kumar Singh
    Nagendra Kumar Singh

    ๐Ÿ› Nahuel Barrios
    Nahuel Barrios

    ๐Ÿ› Nakul Sharma
    Nakul Sharma

    ๐Ÿ› Nathan Braun
    Nathan Braun

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› - Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› + Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› Nathanaรซl
    Nathanaรซl

    ๐Ÿ› Naveen
    Naveen

    ๐Ÿ’ป Nazdravi
    Nazdravi

    ๐Ÿ› Neha-Dhonde
    Neha-Dhonde

    ๐Ÿ› Nicholas Doyle
    Nicholas Doyle

    ๐Ÿ› Nick Butcher
    Nick Butcher

    ๐Ÿ› - Nico Gallinal
    Nico Gallinal

    ๐Ÿ› + Nico Gallinal
    Nico Gallinal

    ๐Ÿ› Nicola Dal Maso
    Nicola Dal Maso

    ๐Ÿ› Nicolas Filotto
    Nicolas Filotto

    ๐Ÿ’ป Nicolas Vervelle
    Nicolas Vervelle

    ๐Ÿ› Nicolas Vuillamy
    Nicolas Vuillamy

    ๐Ÿ“– Nikita Chursin
    Nikita Chursin

    ๐Ÿ› Niklas Baudy
    Niklas Baudy

    ๐Ÿ› - Nikolas Havrikov
    Nikolas Havrikov

    ๐Ÿ› + Nikolas Havrikov
    Nikolas Havrikov

    ๐Ÿ› Nilesh Virkar
    Nilesh Virkar

    ๐Ÿ› Nimit Patel
    Nimit Patel

    ๐Ÿ› Niranjan Harpale
    Niranjan Harpale

    ๐Ÿ› Nirvik Patel
    Nirvik Patel

    ๐Ÿ’ป Noah Sussman
    Noah Sussman

    ๐Ÿ› Noah0120
    Noah0120

    ๐Ÿ› - Noam Tamim
    Noam Tamim

    ๐Ÿ› + Noam Tamim
    Noam Tamim

    ๐Ÿ› Noel Grandin
    Noel Grandin

    ๐Ÿ› Olaf Haalstra
    Olaf Haalstra

    ๐Ÿ› Oleg Andreych
    Oleg Andreych

    ๐Ÿ’ป ๐Ÿ› Oleg Pavlenko
    Oleg Pavlenko

    ๐Ÿ› Oleksii Dykov
    Oleksii Dykov

    ๐Ÿ’ป ๐Ÿ› Oliver Eikemeier
    Oliver Eikemeier

    ๐Ÿ› - Oliver Siegmar
    Oliver Siegmar

    ๐Ÿ’ต + Oliver Siegmar
    Oliver Siegmar

    ๐Ÿ’ต Olivier Parent
    Olivier Parent

    ๐Ÿ’ป ๐Ÿ› Ollie Abbey
    Ollie Abbey

    ๐Ÿ’ป ๐Ÿ› Olof-Joachim Frahm (ๆฌง้›…็ฆ)
    Olof-Joachim Frahm (ๆฌง้›…็ฆ)

    ๐Ÿ› Ondrej Kratochvil
    Ondrej Kratochvil

    ๐Ÿ› OverDrone
    OverDrone

    ๐Ÿ› Ozan Gulle
    Ozan Gulle

    ๐Ÿ’ป ๐Ÿ› - PUNEET JAIN
    PUNEET JAIN

    ๐Ÿ› + PUNEET JAIN
    PUNEET JAIN

    ๐Ÿ› Parbati Bose
    Parbati Bose

    ๐Ÿ› Paul Berg
    Paul Berg

    ๐Ÿ› Paul Guyot
    Paul Guyot

    ๐Ÿ’ป Pavel Bludov
    Pavel Bludov

    ๐Ÿ› Pavel Miฤka
    Pavel Miฤka

    ๐Ÿ› Pedro Nuno Santos
    Pedro Nuno Santos

    ๐Ÿ› - Pedro Rijo
    Pedro Rijo

    ๐Ÿ› + Pedro Rijo
    Pedro Rijo

    ๐Ÿ› Pelisse Romain
    Pelisse Romain

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Per Abich
    Per Abich

    ๐Ÿ’ป Pete Davids
    Pete Davids

    ๐Ÿ› Peter Bruin
    Peter Bruin

    ๐Ÿ› Peter Chittum
    Peter Chittum

    ๐Ÿ’ป ๐Ÿ› Peter Cudmore
    Peter Cudmore

    ๐Ÿ› - Peter Kasson
    Peter Kasson

    ๐Ÿ› + Peter Kasson
    Peter Kasson

    ๐Ÿ› Peter Kofler
    Peter Kofler

    ๐Ÿ› Peter Paul Bakker
    Peter Paul Bakker

    ๐Ÿ’ป ๐Ÿ› Peter Rader
    Peter Rader

    ๐Ÿ› Pham Hai Trung
    Pham Hai Trung

    ๐Ÿ› Philip Graf
    Philip Graf

    ๐Ÿ’ป ๐Ÿ› Philip Hachey
    Philip Hachey

    ๐Ÿ› - Philippe Ozil
    Philippe Ozil

    ๐Ÿ› + Philippe Ozil
    Philippe Ozil

    ๐Ÿ› Phinehas Artemix
    Phinehas Artemix

    ๐Ÿ› Phokham Nonava
    Phokham Nonava

    ๐Ÿ› Pim van der Loos
    Pim van der Loos

    ๐Ÿ’ป โš ๏ธ Piotr Szymaล„ski
    Piotr Szymaล„ski

    ๐Ÿ› Piotrek ลปygieล‚o
    Piotrek ลปygieล‚o

    ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– Pranay Jaiswal
    Pranay Jaiswal

    ๐Ÿ› - Prasad Kamath
    Prasad Kamath

    ๐Ÿ› + Prasad Kamath
    Prasad Kamath

    ๐Ÿ› Prasanna
    Prasanna

    ๐Ÿ› Presh-AR
    Presh-AR

    ๐Ÿ› Puneet1726
    Puneet1726

    ๐Ÿ› RBRi
    RBRi

    ๐Ÿ› Rafael Cortรชs
    Rafael Cortรชs

    ๐Ÿ› RaheemShaik999
    RaheemShaik999

    ๐Ÿ› - RajeshR
    RajeshR

    ๐Ÿ’ป ๐Ÿ› + RajeshR
    RajeshR

    ๐Ÿ’ป ๐Ÿ› Ramachandra Mohan
    Ramachandra Mohan

    ๐Ÿ› Ramel0921
    Ramel0921

    ๐Ÿ› Raquel Pau
    Raquel Pau

    ๐Ÿ› Ravikiran Janardhana
    Ravikiran Janardhana

    ๐Ÿ› Reda Benhemmouche
    Reda Benhemmouche

    ๐Ÿ› Reinhard Schiedermeier
    Reinhard Schiedermeier

    ๐Ÿ› - Renato Oliveira
    Renato Oliveira

    ๐Ÿ’ป ๐Ÿ› + Renato Oliveira
    Renato Oliveira

    ๐Ÿ’ป ๐Ÿ› Rich DiCroce
    Rich DiCroce

    ๐Ÿ› Richard Corfield
    Richard Corfield

    ๐Ÿ’ป Richard Corfield
    Richard Corfield

    ๐Ÿ› ๐Ÿ’ป Riot R1cket
    Riot R1cket

    ๐Ÿ› Rishabh Jain
    Rishabh Jain

    ๐Ÿ› RishabhDeep Singh
    RishabhDeep Singh

    ๐Ÿ› - Rob Baillie
    Rob Baillie

    ๐Ÿ› + Rob Baillie
    Rob Baillie

    ๐Ÿ› Robbie Martinus
    Robbie Martinus

    ๐Ÿ’ป ๐Ÿ› Robert Henry
    Robert Henry

    ๐Ÿ› Robert Mihaly
    Robert Mihaly

    ๐Ÿ› Robert Painsi
    Robert Painsi

    ๐Ÿ› Robert Russell
    Robert Russell

    ๐Ÿ› Robert Sรถsemann
    Robert Sรถsemann

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ› - Robert Whitebit
    Robert Whitebit

    ๐Ÿ› + Robert Whitebit
    Robert Whitebit

    ๐Ÿ› Robin Richtsfeld
    Robin Richtsfeld

    ๐Ÿ› Robin Stocker
    Robin Stocker

    ๐Ÿ’ป ๐Ÿ› Robin Wils
    Robin Wils

    ๐Ÿ› RochusOest
    RochusOest

    ๐Ÿ› Rodolfo Noviski
    Rodolfo Noviski

    ๐Ÿ› Rodrigo Casara
    Rodrigo Casara

    ๐Ÿ› - Rodrigo Fernandes
    Rodrigo Fernandes

    ๐Ÿ› + Rodrigo Fernandes
    Rodrigo Fernandes

    ๐Ÿ› Roman Salvador
    Roman Salvador

    ๐Ÿ’ป ๐Ÿ› Ronald Blaschke
    Ronald Blaschke

    ๐Ÿ› Rรณbert Papp
    Rรณbert Papp

    ๐Ÿ› Saikat Sengupta
    Saikat Sengupta

    ๐Ÿ› Saksham Handu
    Saksham Handu

    ๐Ÿ› Saladoc
    Saladoc

    ๐Ÿ› - Salesforce Bob Lightning
    Salesforce Bob Lightning

    ๐Ÿ› + Salesforce Bob Lightning
    Salesforce Bob Lightning

    ๐Ÿ› Sam Carlberg
    Sam Carlberg

    ๐Ÿ› Sascha Riemer
    Sascha Riemer

    ๐Ÿ› Sashko
    Sashko

    ๐Ÿ’ป Satoshi Kubo
    Satoshi Kubo

    ๐Ÿ› Scott Kennedy
    Scott Kennedy

    ๐Ÿ› Scott Wells
    Scott Wells

    ๐Ÿ› ๐Ÿ’ป - Scrates1
    Scrates1

    ๐Ÿ› ๐Ÿ’ป + Scrates1
    Scrates1

    ๐Ÿ› ๐Ÿ’ป Scrsloota
    Scrsloota

    ๐Ÿ’ป Sebastian Bรถgl
    Sebastian Bรถgl

    ๐Ÿ› Sebastian Davids
    Sebastian Davids

    ๐Ÿ› Sebastian Lรถvdahl
    Sebastian Lรถvdahl

    ๐Ÿ› Sebastian Schuberth
    Sebastian Schuberth

    ๐Ÿ› Sebastian Schwarz
    Sebastian Schwarz

    ๐Ÿ› - Seren
    Seren

    ๐Ÿ› ๐Ÿ’ป + Seren
    Seren

    ๐Ÿ› ๐Ÿ’ป Sergey Gorbaty
    Sergey Gorbaty

    ๐Ÿ› Sergey Kozlov
    Sergey Kozlov

    ๐Ÿ› Sergey Yanzin
    Sergey Yanzin

    ๐Ÿ’ป ๐Ÿ› Seth Wilcox
    Seth Wilcox

    ๐Ÿ’ป Shai Bennathan
    Shai Bennathan

    ๐Ÿ› ๐Ÿ’ป Shubham
    Shubham

    ๐Ÿ’ป ๐Ÿ› - Simon Abykov
    Simon Abykov

    ๐Ÿ’ป ๐Ÿ› + Simon Abykov
    Simon Abykov

    ๐Ÿ’ป ๐Ÿ› Simon Xiao
    Simon Xiao

    ๐Ÿ› Srinivasan Venkatachalam
    Srinivasan Venkatachalam

    ๐Ÿ› Stanislav Gromov
    Stanislav Gromov

    ๐Ÿ› Stanislav Myachenkov
    Stanislav Myachenkov

    ๐Ÿ’ป Stefan Birkner
    Stefan Birkner

    ๐Ÿ› Stefan Bohn
    Stefan Bohn

    ๐Ÿ› - Stefan Endrullis
    Stefan Endrullis

    ๐Ÿ› + Stefan Endrullis
    Stefan Endrullis

    ๐Ÿ› Stefan Klรถss-Schuster
    Stefan Klรถss-Schuster

    ๐Ÿ› Stefan Wolf
    Stefan Wolf

    ๐Ÿ› Stephan H. Wissel
    Stephan H. Wissel

    ๐Ÿ› Stephen
    Stephen

    ๐Ÿ› Stephen Carter
    Stephen Carter

    ๐Ÿ› Stephen Friedrich
    Stephen Friedrich

    ๐Ÿ› - Steve Babula
    Steve Babula

    ๐Ÿ’ป + Steve Babula
    Steve Babula

    ๐Ÿ’ป Steven Stearns
    Steven Stearns

    ๐Ÿ› ๐Ÿ’ป Stexxe
    Stexxe

    ๐Ÿ› Stian Lรฅgstad
    Stian Lรฅgstad

    ๐Ÿ› StuartClayton5
    StuartClayton5

    ๐Ÿ› Supun Arunoda
    Supun Arunoda

    ๐Ÿ› Suren Abrahamyan
    Suren Abrahamyan

    ๐Ÿ› - Suvashri
    Suvashri

    ๐Ÿ“– + Suvashri
    Suvashri

    ๐Ÿ“– Sven Barden
    Sven Barden

    ๐Ÿ› SwatiBGupta1110
    SwatiBGupta1110

    ๐Ÿ› SyedThoufich
    SyedThoufich

    ๐Ÿ› Szymon Sasin
    Szymon Sasin

    ๐Ÿ› T-chuangxin
    T-chuangxin

    ๐Ÿ› TERAI Atsuhiro
    TERAI Atsuhiro

    ๐Ÿ› - TIOBE Software
    TIOBE Software

    ๐Ÿ’ป ๐Ÿ› + TIOBE Software
    TIOBE Software

    ๐Ÿ’ป ๐Ÿ› Tarush Singh
    Tarush Singh

    ๐Ÿ’ป Taylor Smock
    Taylor Smock

    ๐Ÿ› Techeira Damiรกn
    Techeira Damiรกn

    ๐Ÿ’ป ๐Ÿ› Ted Husted
    Ted Husted

    ๐Ÿ› TehBakker
    TehBakker

    ๐Ÿ› The Gitter Badger
    The Gitter Badger

    ๐Ÿ› - Theodoor
    Theodoor

    ๐Ÿ› + Theodoor
    Theodoor

    ๐Ÿ› Thiago Henrique Hรผpner
    Thiago Henrique Hรผpner

    ๐Ÿ› Thibault Meyer
    Thibault Meyer

    ๐Ÿ› Thomas Gรผttler
    Thomas Gรผttler

    ๐Ÿ› Thomas Jones-Low
    Thomas Jones-Low

    ๐Ÿ› Thomas Smith
    Thomas Smith

    ๐Ÿ’ป ๐Ÿ› ThrawnCA
    ThrawnCA

    ๐Ÿ› - Thu Vo
    Thu Vo

    ๐Ÿ› + Thu Vo
    Thu Vo

    ๐Ÿ› Thunderforge
    Thunderforge

    ๐Ÿ’ป ๐Ÿ› Tim van der Lippe
    Tim van der Lippe

    ๐Ÿ› Tobias Weimer
    Tobias Weimer

    ๐Ÿ’ป ๐Ÿ› Tom Copeland
    Tom Copeland

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– Tom Daly
    Tom Daly

    ๐Ÿ› Tomas
    Tomas

    ๐Ÿ› - Tomer Figenblat
    Tomer Figenblat

    ๐Ÿ› + Tomer Figenblat
    Tomer Figenblat

    ๐Ÿ› Tomi De Lucca
    Tomi De Lucca

    ๐Ÿ’ป ๐Ÿ› Tony
    Tony

    ๐Ÿ“– Torsten Kleiber
    Torsten Kleiber

    ๐Ÿ› Torsten Krause
    Torsten Krause

    ๐Ÿ› TrackerSB
    TrackerSB

    ๐Ÿ› Tyson Stewart
    Tyson Stewart

    ๐Ÿ› - Ullrich Hafner
    Ullrich Hafner

    ๐Ÿ› + Ullrich Hafner
    Ullrich Hafner

    ๐Ÿ› Utku Cuhadaroglu
    Utku Cuhadaroglu

    ๐Ÿ’ป ๐Ÿ› Valentin Brandl
    Valentin Brandl

    ๐Ÿ› Valeria
    Valeria

    ๐Ÿ› Valery Yatsynovich
    Valery Yatsynovich

    ๐Ÿ“– Vasily Anisimov
    Vasily Anisimov

    ๐Ÿ› Vedant Chokshi
    Vedant Chokshi

    ๐Ÿ› - Vibhor Goyal
    Vibhor Goyal

    ๐Ÿ› + Vibhor Goyal
    Vibhor Goyal

    ๐Ÿ› Vickenty Fesunov
    Vickenty Fesunov

    ๐Ÿ› Victor Noรซl
    Victor Noรซl

    ๐Ÿ› Vincent Galloy
    Vincent Galloy

    ๐Ÿ’ป Vincent HUYNH
    Vincent HUYNH

    ๐Ÿ› Vincent Maurin
    Vincent Maurin

    ๐Ÿ› Vincent Potucek
    Vincent Potucek

    ๐Ÿ’ป - Vincent Privat
    Vincent Privat

    ๐Ÿ› + Vincent Privat
    Vincent Privat

    ๐Ÿ› Vishhwas
    Vishhwas

    ๐Ÿ› Vishv_Android
    Vishv_Android

    ๐Ÿ› Vitalii Yevtushenko
    Vitalii Yevtushenko

    ๐Ÿ› Vitaly
    Vitaly

    ๐Ÿ› Vitaly Polonetsky
    Vitaly Polonetsky

    ๐Ÿ› Vojtech Polivka
    Vojtech Polivka

    ๐Ÿ› - Vsevolod Zholobov
    Vsevolod Zholobov

    ๐Ÿ› + Vsevolod Zholobov
    Vsevolod Zholobov

    ๐Ÿ› Vyom Yadav
    Vyom Yadav

    ๐Ÿ’ป Wang Shidong
    Wang Shidong

    ๐Ÿ› Waqas Ahmed
    Waqas Ahmed

    ๐Ÿ› Wayne J. Earl
    Wayne J. Earl

    ๐Ÿ› Wchenghui
    Wchenghui

    ๐Ÿ› Wener
    Wener

    ๐Ÿ’ป - Will Winder
    Will Winder

    ๐Ÿ› + Will Winder
    Will Winder

    ๐Ÿ› Willem A. Hajenius
    Willem A. Hajenius

    ๐Ÿ’ป William Brockhus
    William Brockhus

    ๐Ÿ’ป ๐Ÿ› Wilson Kurniawan
    Wilson Kurniawan

    ๐Ÿ› Wim Deblauwe
    Wim Deblauwe

    ๐Ÿ› Wolf2323
    Wolf2323

    ๐Ÿ› Woongsik Choi
    Woongsik Choi

    ๐Ÿ› - XenoAmess
    XenoAmess

    ๐Ÿ’ป ๐Ÿ› + XenoAmess
    XenoAmess

    ๐Ÿ’ป ๐Ÿ› Yang
    Yang

    ๐Ÿ’ป YaroslavTER
    YaroslavTER

    ๐Ÿ› Yasar Shaikh
    Yasar Shaikh

    ๐Ÿ’ป Young Chan
    Young Chan

    ๐Ÿ’ป ๐Ÿ› YuJin Kim
    YuJin Kim

    ๐Ÿ› Yuri Dolzhenko
    Yuri Dolzhenko

    ๐Ÿ› - Yurii Dubinka
    Yurii Dubinka

    ๐Ÿ› + Yurii Dubinka
    Yurii Dubinka

    ๐Ÿ› Zoltan Farkas
    Zoltan Farkas

    ๐Ÿ› Zustin
    Zustin

    ๐Ÿ› aaronhurst-google
    aaronhurst-google

    ๐Ÿ› ๐Ÿ’ป alexmodis
    alexmodis

    ๐Ÿ› andreoss
    andreoss

    ๐Ÿ› andrey81inmd
    andrey81inmd

    ๐Ÿ’ป ๐Ÿ› - anicoara
    anicoara

    ๐Ÿ› + anicoara
    anicoara

    ๐Ÿ› arunprasathav
    arunprasathav

    ๐Ÿ› asiercamara
    asiercamara

    ๐Ÿ› astillich-igniti
    astillich-igniti

    ๐Ÿ’ป avesolovksyy
    avesolovksyy

    ๐Ÿ› avishvat
    avishvat

    ๐Ÿ› avivmu
    avivmu

    ๐Ÿ› - axelbarfod1
    axelbarfod1

    ๐Ÿ› + axelbarfod1
    axelbarfod1

    ๐Ÿ› b-3-n
    b-3-n

    ๐Ÿ› balbhadra9
    balbhadra9

    ๐Ÿ› base23de
    base23de

    ๐Ÿ› bergander
    bergander

    ๐Ÿ› ๐Ÿ’ป berkam
    berkam

    ๐Ÿ’ป ๐Ÿ› breizh31
    breizh31

    ๐Ÿ› - caesarkim
    caesarkim

    ๐Ÿ› + caesarkim
    caesarkim

    ๐Ÿ› caiocarvalhotero
    caiocarvalhotero

    ๐Ÿ› carolyujing
    carolyujing

    ๐Ÿ› cbfiddle
    cbfiddle

    ๐Ÿ› cesares-basilico
    cesares-basilico

    ๐Ÿ› chrite
    chrite

    ๐Ÿ› ciufudean
    ciufudean

    ๐Ÿ“– - cobratbq
    cobratbq

    ๐Ÿ› + cobratbq
    cobratbq

    ๐Ÿ› coladict
    coladict

    ๐Ÿ› cosmoJFH
    cosmoJFH

    ๐Ÿ› cristalp
    cristalp

    ๐Ÿ› crunsk
    crunsk

    ๐Ÿ› cwholmes
    cwholmes

    ๐Ÿ› cyberjj999
    cyberjj999

    ๐Ÿ› - cyw3
    cyw3

    ๐Ÿ› ๐Ÿ“– + cyw3
    cyw3

    ๐Ÿ› ๐Ÿ“– d1ss0nanz
    d1ss0nanz

    ๐Ÿ› dague1
    dague1

    ๐Ÿ“– dalizi007
    dalizi007

    ๐Ÿ’ป danbrycefairsailcom
    danbrycefairsailcom

    ๐Ÿ› dariansanity
    dariansanity

    ๐Ÿ› darrenmiliband
    darrenmiliband

    ๐Ÿ› - davidburstrom
    davidburstrom

    ๐Ÿ› + davidburstrom
    davidburstrom

    ๐Ÿ› dbirkman-paloalto
    dbirkman-paloalto

    ๐Ÿ› deepak-patra
    deepak-patra

    ๐Ÿ› dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› dinesh150
    dinesh150

    ๐Ÿ› diziaq
    diziaq

    ๐Ÿ› dreaminpast123
    dreaminpast123

    ๐Ÿ› - duanyanan
    duanyanan

    ๐Ÿ› + duanyanan
    duanyanan

    ๐Ÿ› dutt-sanjay
    dutt-sanjay

    ๐Ÿ› duursma
    duursma

    ๐Ÿ’ป dylanleung
    dylanleung

    ๐Ÿ› dzeigler
    dzeigler

    ๐Ÿ› eant60
    eant60

    ๐Ÿ› ekkirala
    ekkirala

    ๐Ÿ› - emersonmoura
    emersonmoura

    ๐Ÿ› + emersonmoura
    emersonmoura

    ๐Ÿ› emouty
    emouty

    ๐Ÿ’ป ๐Ÿ› eugenepugach
    eugenepugach

    ๐Ÿ› fairy
    fairy

    ๐Ÿ› filiprafalowicz
    filiprafalowicz

    ๐Ÿ’ป flxbl-io
    flxbl-io

    ๐Ÿ’ต foxmason
    foxmason

    ๐Ÿ› - frankegabor
    frankegabor

    ๐Ÿ› + frankegabor
    frankegabor

    ๐Ÿ› frankl
    frankl

    ๐Ÿ› freafrea
    freafrea

    ๐Ÿ› fsapatin
    fsapatin

    ๐Ÿ› gearsethenry
    gearsethenry

    ๐Ÿ› gracia19
    gracia19

    ๐Ÿ› gudzpoz
    gudzpoz

    ๐Ÿ› - guo fei
    guo fei

    ๐Ÿ› + guo fei
    guo fei

    ๐Ÿ› gurmsc5
    gurmsc5

    ๐Ÿ› gwilymatgearset
    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ› haigsn
    haigsn

    ๐Ÿ› hemanshu070
    hemanshu070

    ๐Ÿ› henrik242
    henrik242

    ๐Ÿ› hongpuwu
    hongpuwu

    ๐Ÿ› - hvbtup
    hvbtup

    ๐Ÿ’ป ๐Ÿ› + hvbtup
    hvbtup

    ๐Ÿ’ป ๐Ÿ› igniti GmbH
    igniti GmbH

    ๐Ÿ› ilovezfs
    ilovezfs

    ๐Ÿ› imax-erik
    imax-erik

    ๐Ÿ› itaigilo
    itaigilo

    ๐Ÿ› jakivey32
    jakivey32

    ๐Ÿ› jbennett2091
    jbennett2091

    ๐Ÿ› - jcamerin
    jcamerin

    ๐Ÿ› + jcamerin
    jcamerin

    ๐Ÿ› jkeener1
    jkeener1

    ๐Ÿ› jmetertea
    jmetertea

    ๐Ÿ› johnra2
    johnra2

    ๐Ÿ’ป johnzhao9
    johnzhao9

    ๐Ÿ› josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ› kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ› - karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“– + karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“– karwer
    karwer

    ๐Ÿ› kaulonline
    kaulonline

    ๐Ÿ› kdaemonv
    kdaemonv

    ๐Ÿ› kdebski85
    kdebski85

    ๐Ÿ› ๐Ÿ’ป kenji21
    kenji21

    ๐Ÿ’ป ๐Ÿ› kfranic
    kfranic

    ๐Ÿ› - khalidkh
    khalidkh

    ๐Ÿ› + khalidkh
    khalidkh

    ๐Ÿ› koalalam
    koalalam

    ๐Ÿ› krzyk
    krzyk

    ๐Ÿ› lasselindqvist
    lasselindqvist

    ๐Ÿ› lgemeinhardt
    lgemeinhardt

    ๐Ÿ› lihuaib
    lihuaib

    ๐Ÿ› liqingjun123
    liqingjun123

    ๐Ÿ› - lonelyma1021
    lonelyma1021

    ๐Ÿ› + lonelyma1021
    lonelyma1021

    ๐Ÿ› lpeddy
    lpeddy

    ๐Ÿ› lujiefsi
    lujiefsi

    ๐Ÿ’ป lukelukes
    lukelukes

    ๐Ÿ’ป lyriccoder
    lyriccoder

    ๐Ÿ› marcelmore
    marcelmore

    ๐Ÿ› matchbox
    matchbox

    ๐Ÿ› - matthiaskraaz
    matthiaskraaz

    ๐Ÿ› + matthiaskraaz
    matthiaskraaz

    ๐Ÿ› meandonlyme
    meandonlyme

    ๐Ÿ› mikesive
    mikesive

    ๐Ÿ› milossesic
    milossesic

    ๐Ÿ› mluckam
    mluckam

    ๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
    mohan-chinnappan-n

    ๐Ÿ’ป mriddell95
    mriddell95

    ๐Ÿ› - mrlzh
    mrlzh

    ๐Ÿ› + mrlzh
    mrlzh

    ๐Ÿ› msloan
    msloan

    ๐Ÿ› mucharlaravalika
    mucharlaravalika

    ๐Ÿ› mvenneman
    mvenneman

    ๐Ÿ› nareshl119
    nareshl119

    ๐Ÿ› nicolas-harraudeau-sonarsource
    nicolas-harraudeau-sonarsource

    ๐Ÿ› noerremark
    noerremark

    ๐Ÿ› - novsirion
    novsirion

    ๐Ÿ› + novsirion
    novsirion

    ๐Ÿ› nwcm
    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
    oggboy

    ๐Ÿ› oinume
    oinume

    ๐Ÿ› orimarko
    orimarko

    ๐Ÿ’ป ๐Ÿ› pablogomez2197
    pablogomez2197

    ๐Ÿ› pacvz
    pacvz

    ๐Ÿ’ป - pallavi agarwal
    pallavi agarwal

    ๐Ÿ› + pallavi agarwal
    pallavi agarwal

    ๐Ÿ› pankratz76
    pankratz76

    ๐Ÿ› parksungrin
    parksungrin

    ๐Ÿ› patpatpat123
    patpatpat123

    ๐Ÿ› patriksevallius
    patriksevallius

    ๐Ÿ› pbrajesh1
    pbrajesh1

    ๐Ÿ› phoenix384
    phoenix384

    ๐Ÿ› - piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป + piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป plan3d
    plan3d

    ๐Ÿ› poojasix
    poojasix

    ๐Ÿ› prabhushrikant
    prabhushrikant

    ๐Ÿ› pujitha8783
    pujitha8783

    ๐Ÿ› r-r-a-j
    r-r-a-j

    ๐Ÿ› raghujayjunk
    raghujayjunk

    ๐Ÿ› - rajeshveera
    rajeshveera

    ๐Ÿ› + rajeshveera
    rajeshveera

    ๐Ÿ› rajeswarreddy88
    rajeswarreddy88

    ๐Ÿ› recdevs
    recdevs

    ๐Ÿ› reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ› rijkt
    rijkt

    ๐Ÿ› rillig-tk
    rillig-tk

    ๐Ÿ› rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ› - rnveach
    rnveach

    ๐Ÿ› + rnveach
    rnveach

    ๐Ÿ› rxmicro
    rxmicro

    ๐Ÿ› ryan-gustafson
    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ› sabi0
    sabi0

    ๐Ÿ› samc-gearset
    samc-gearset

    ๐Ÿ“– scais
    scais

    ๐Ÿ› schosin
    schosin

    ๐Ÿ› - screamingfrog
    screamingfrog

    ๐Ÿ’ต + screamingfrog
    screamingfrog

    ๐Ÿ’ต sebbASF
    sebbASF

    ๐Ÿ› sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป shilko2013
    shilko2013

    ๐Ÿ› shiomiyan
    shiomiyan

    ๐Ÿ“– simeonKondr
    simeonKondr

    ๐Ÿ› snajberk
    snajberk

    ๐Ÿ› - sniperrifle2004
    sniperrifle2004

    ๐Ÿ› + sniperrifle2004
    sniperrifle2004

    ๐Ÿ› snuyanzin
    snuyanzin

    ๐Ÿ› ๐Ÿ’ป soloturn
    soloturn

    ๐Ÿ› soyodream
    soyodream

    ๐Ÿ› sratz
    sratz

    ๐Ÿ› stonio
    stonio

    ๐Ÿ› sturton
    sturton

    ๐Ÿ’ป ๐Ÿ› - sudharmohan
    sudharmohan

    ๐Ÿ› + sudharmohan
    sudharmohan

    ๐Ÿ› suruchidawar
    suruchidawar

    ๐Ÿ› svenfinitiv
    svenfinitiv

    ๐Ÿ› szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป tashiscool
    tashiscool

    ๐Ÿ› test-git-hook
    test-git-hook

    ๐Ÿ› testation21
    testation21

    ๐Ÿ’ป ๐Ÿ› - thanosa
    thanosa

    ๐Ÿ› + thanosa
    thanosa

    ๐Ÿ› tiandiyixian
    tiandiyixian

    ๐Ÿ› tobwoerk
    tobwoerk

    ๐Ÿ› tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป trentchilders
    trentchilders

    ๐Ÿ› triandicAnt
    triandicAnt

    ๐Ÿ› trishul14
    trishul14

    ๐Ÿ› - tsui
    tsui

    ๐Ÿ› + tsui
    tsui

    ๐Ÿ› wangzitom12306
    wangzitom12306

    ๐Ÿ› winhkey
    winhkey

    ๐Ÿ› witherspore
    witherspore

    ๐Ÿ› wjljack
    wjljack

    ๐Ÿ› wuchiuwong
    wuchiuwong

    ๐Ÿ› xingsong
    xingsong

    ๐Ÿ› - xioayuge
    xioayuge

    ๐Ÿ› + xioayuge
    xioayuge

    ๐Ÿ› xnYi9wRezm
    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ› xuanuy
    xuanuy

    ๐Ÿ› xyf0921
    xyf0921

    ๐Ÿ› yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› yasuharu-sato
    yasuharu-sato

    ๐Ÿ› zenglian
    zenglian

    ๐Ÿ› - zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› + zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› zh3ng
    zh3ng

    ๐Ÿ› zt_soft
    zt_soft

    ๐Ÿ› ztt79
    ztt79

    ๐Ÿ› zzzzfeng
    zzzzfeng

    ๐Ÿ› รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› ไปป่ดตๆฐ
    ไปป่ดตๆฐ

    ๐Ÿ› - ๅคฉ็ƒญๅƒ่ฅฟ็“œ
    ๅคฉ็ƒญๅƒ่ฅฟ็“œ

    ๐Ÿ› + ๅคฉ็ƒญๅƒ่ฅฟ็“œ
    ๅคฉ็ƒญๅƒ่ฅฟ็“œ

    ๐Ÿ› ่Œ…ๅปถๅฎ‰
    ่Œ…ๅปถๅฎ‰

    ๐Ÿ’ป From 6770714f80cd6eebab769885176ea7945bf5787f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Apr 2025 12:09:56 +0200 Subject: [PATCH 0773/1962] [doc] Update release notes (#5672) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 66047b07cd8..d03c68bc63c 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -24,6 +24,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ Merged pull requests +* [#5672](https://github.com/pmd/pmd/pull/5672): \[doc] Fix its/it's and doable/double typos - [John Jetmore](https://github.com/jetmore) (@jetmore) ### ๐Ÿ“ฆ Dependency updates From f1d403f3883605ebd9143f9e85d19bbbe844a5e2 Mon Sep 17 00:00:00 2001 From: Thomas Prouvot Date: Mon, 14 Apr 2025 11:09:47 +0200 Subject: [PATCH 0774/1962] - Updated `ApexUnitTestShouldNotUseSeeAllDataTrueRule.java` to check for `SEE_ALL_DATA` parameter value being `true`. - Added a new test case in `ApexUnitTestShouldNotUseSeeAllDataTrue.xml` to validate the updated rule. --- ...nitTestShouldNotUseSeeAllDataTrueRule.java | 9 ++++++--- ...ApexUnitTestShouldNotUseSeeAllDataTrue.xml | 20 +++++++++++++++++-- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestShouldNotUseSeeAllDataTrueRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestShouldNotUseSeeAllDataTrueRule.java index 77689215819..589513264fd 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestShouldNotUseSeeAllDataTrueRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestShouldNotUseSeeAllDataTrueRule.java @@ -45,13 +45,16 @@ private Object checkForSeeAllData(final ApexNode node, final Object data) { if (modifierNode != null) { for (ASTAnnotationParameter parameter : modifierNode.descendants(ASTAnnotationParameter.class)) { - if (parameter.hasName(ASTAnnotationParameter.SEE_ALL_DATA) && parameter.getBooleanValue()) { - asCtx(data).addViolation(node); - return data; + if (parameter.hasName(ASTAnnotationParameter.SEE_ALL_DATA)) { + if (parameter.getBooleanValue() || "true".equalsIgnoreCase(parameter.getValue())) { + asCtx(data).addViolation(node); + return data; + } } } } return data; } + } diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/bestpractices/xml/ApexUnitTestShouldNotUseSeeAllDataTrue.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/bestpractices/xml/ApexUnitTestShouldNotUseSeeAllDataTrue.xml index 943542c1e07..5d053c84ed7 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/bestpractices/xml/ApexUnitTestShouldNotUseSeeAllDataTrue.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/bestpractices/xml/ApexUnitTestShouldNotUseSeeAllDataTrue.xml @@ -34,7 +34,7 @@ public class Foo { } ]]>
    - + [apex] ApexUnitTestShouldNotUseSeeAllDataTrue false negative due to casing (regression in PMD 7) #5095 9 @@ -85,4 +85,20 @@ public class SomeTest { } ]]>
    - + + + [apex] ApexUnitTestShouldNotUseSeeAllDataTrue seeAllData boolean enclosed in quote #5667 + 2 + 2,5 + + + \ No newline at end of file From 3a7ee5d15bd67d07320ee986e531b7196ef1b7c9 Mon Sep 17 00:00:00 2001 From: Thomas Prouvot Date: Mon, 14 Apr 2025 11:18:27 +0200 Subject: [PATCH 0775/1962] Refactor test --- .../ApexUnitTestShouldNotUseSeeAllDataTrueRule.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestShouldNotUseSeeAllDataTrueRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestShouldNotUseSeeAllDataTrueRule.java index 589513264fd..b0aa61c6b95 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestShouldNotUseSeeAllDataTrueRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestShouldNotUseSeeAllDataTrueRule.java @@ -45,11 +45,10 @@ private Object checkForSeeAllData(final ApexNode node, final Object data) { if (modifierNode != null) { for (ASTAnnotationParameter parameter : modifierNode.descendants(ASTAnnotationParameter.class)) { - if (parameter.hasName(ASTAnnotationParameter.SEE_ALL_DATA)) { - if (parameter.getBooleanValue() || "true".equalsIgnoreCase(parameter.getValue())) { - asCtx(data).addViolation(node); - return data; - } + if (parameter.hasName(ASTAnnotationParameter.SEE_ALL_DATA) && + (parameter.getBooleanValue() || "true".equalsIgnoreCase(parameter.getValue()))) { + asCtx(data).addViolation(node); + return data; } } } From 01a9125485a564df4b7c8768d5687ca35a3e33fb Mon Sep 17 00:00:00 2001 From: Thomas Prouvot Date: Mon, 14 Apr 2025 14:43:02 +0200 Subject: [PATCH 0776/1962] fix checkstyle: OperatorWrap: '&&' should be on a new line. --- .../ApexUnitTestShouldNotUseSeeAllDataTrueRule.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestShouldNotUseSeeAllDataTrueRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestShouldNotUseSeeAllDataTrueRule.java index b0aa61c6b95..c5a5912a134 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestShouldNotUseSeeAllDataTrueRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestShouldNotUseSeeAllDataTrueRule.java @@ -45,8 +45,8 @@ private Object checkForSeeAllData(final ApexNode node, final Object data) { if (modifierNode != null) { for (ASTAnnotationParameter parameter : modifierNode.descendants(ASTAnnotationParameter.class)) { - if (parameter.hasName(ASTAnnotationParameter.SEE_ALL_DATA) && - (parameter.getBooleanValue() || "true".equalsIgnoreCase(parameter.getValue()))) { + if (parameter.hasName(ASTAnnotationParameter.SEE_ALL_DATA) + && (parameter.getBooleanValue() || "true".equalsIgnoreCase(parameter.getValue()))) { asCtx(data).addViolation(node); return data; } From 94049d4aa48f4d6ae46d26bc56e10ae6307c85e8 Mon Sep 17 00:00:00 2001 From: julees7 Date: Mon, 14 Apr 2025 14:57:33 +0200 Subject: [PATCH 0777/1962] #5525 clean up requested by @Pankraz76 --- .../renderers/internal/sarif/SarifLog.java | 126 ++++++++++-------- 1 file changed, 72 insertions(+), 54 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java index bbb08e5b334..217a28b7e17 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java @@ -979,29 +979,35 @@ public java.lang.String toString() { * A result produced by an analysis tool. */ public static class Result { + /** * The stable, unique identifier of the rule, if any, to which this result is relevant. */ private String ruleId; + /** * The index link the rule, if any, to which this result is relevant. */ private Integer ruleIndex; + /** * A message that describes the result. The first sentence of the message only will be displayed when visible * space is limited. */ private Message message; + /** * The severeness of a found bug. Is derived from PMDs defined Priorities (1,2 = error, 3 = warning, 4,5 = note). * @see net.sourceforge.pmd.lang.rule.RulePriority */ private String level; + /** * The set of locations where the result was detected. Specify only one location unless the problem indicated by * the result can only be corrected by making a change at every specified location. */ private List locations; + /** * Key/value pairs that provide additional information about the address. */ @@ -1026,7 +1032,7 @@ public static class ResultBuilder { private Integer ruleIndex; @java.lang.SuppressWarnings("all") private Message message; - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") private String level; @java.lang.SuppressWarnings("all") private List locations; @@ -1072,7 +1078,7 @@ public SarifLog.Result.ResultBuilder message(final Message message) { * The severeness of a found bug. Is derived from PMDs defined Priorities (1,2 = error, 3 = warning, 4,5 = note). * @return {@code this}. */ - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") public SarifLog.Result.ResultBuilder level(final String level) { this.level = level; return this; @@ -1144,7 +1150,7 @@ public Message getMessage() { /** * The severeness of a found bug. Is derived from PMDs defined Priorities (1,2 = error, 3 = warning, 4,5 = note). */ - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") public String getLevel() { return this.level; } @@ -1201,7 +1207,7 @@ public SarifLog.Result setMessage(final Message message) { * The severeness of a found bug. Is derived from PMDs defined Priorities (1,2 = error, 3 = warning, 4,5 = note). * @return {@code this}. */ - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") public SarifLog.Result setLevel(final String level) { this.level = level; return this; @@ -1256,8 +1262,8 @@ public boolean equals(final java.lang.Object o) { if (this$message == null ? other$message != null : !this$message.equals(other$message)) { return false; } - final java.lang.Object this$level = this.getLevel(); - final java.lang.Object other$level = other.getLevel(); + final Object this$level = this.getLevel(); + final Object other$level = other.getLevel(); if (this$level == null ? other$level != null : !this$level.equals(other$level)) { return false; } @@ -1290,7 +1296,7 @@ public int hashCode() { result = result * PRIME + ($ruleIndex == null ? 43 : $ruleIndex.hashCode()); final java.lang.Object $message = this.getMessage(); result = result * PRIME + ($message == null ? 43 : $message.hashCode()); - final java.lang.Object $level = this.getLevel(); + final Object $level = this.getLevel(); result = result * PRIME + ($level == null ? 43 : $level.hashCode()); final java.lang.Object $locations = this.getLocations(); result = result * PRIME + ($locations == null ? 43 : $locations.hashCode()); @@ -2533,27 +2539,32 @@ public java.lang.String toString() { * Can also be used in configurationOverride to override those defaults. */ public static class ReportingConfiguration { + + /** * Boolean, to dis- and enable the config based on matching a rule (through the Descriptor). * Default: true. */ private boolean enabled; + /** * Takes the levelProperty of the Descriptor (if present) or provides a default/override. * Default: warning. */ private String level; + /** * Takes the rank/priority of the Descriptor (if present) or provides a default/override value between 1.0 and 100.0. * Default: -1.0. */ private double rank; + /** * Define configuration information (propertyBag) specific to the Descriptor. */ private PropertyBag parameters; - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") ReportingConfiguration(final boolean enabled, final String level, final double rank, final PropertyBag parameters) { this.enabled = enabled; this.level = level; @@ -2562,25 +2573,25 @@ public static class ReportingConfiguration { } - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") public static class ReportingConfigurationBuilder { - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") private boolean enabled; - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") private String level; - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") private double rank; - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") private PropertyBag parameters; - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") ReportingConfigurationBuilder() { } /** * Boolean, to dis- and enable the config based on matching a rule (through the Descriptor). */ - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") public SarifLog.ReportingConfiguration.ReportingConfigurationBuilder enabled(final boolean enabled) { this.enabled = enabled; return this; @@ -2589,7 +2600,7 @@ public SarifLog.ReportingConfiguration.ReportingConfigurationBuilder enabled(fin /** * Takes the levelProperty of the Descriptor (if present) or provides a default/override. */ - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") public SarifLog.ReportingConfiguration.ReportingConfigurationBuilder level(final String level) { this.level = level; return this; @@ -2598,33 +2609,34 @@ public SarifLog.ReportingConfiguration.ReportingConfigurationBuilder level(final /** * Takes the rank/priority of the Descriptor (if present) or provides a default/override value between 1.0 and 100.0. */ - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") public SarifLog.ReportingConfiguration.ReportingConfigurationBuilder rank(final double rank) { this.rank = rank; return this; } + /** * Define configuration information (propertyBag) specific to the Descriptor. */ - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") public SarifLog.ReportingConfiguration.ReportingConfigurationBuilder parameters(final PropertyBag parameters) { this.parameters = parameters; return this; } - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") public SarifLog.ReportingConfiguration build() { return new SarifLog.ReportingConfiguration(this.enabled, this.level, this.rank, this.parameters); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + @SuppressWarnings("all") + public String toString() { return "SarifLog.ReportingConfiguration.ReportingConfigurationBuilder(enabled=" + this.enabled + ", level=" + this.level + ", rank=" + this.rank +", parameters=" + this.parameters + ")"; } } - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") public static SarifLog.ReportingConfiguration.ReportingConfigurationBuilder builder() { return new SarifLog.ReportingConfiguration.ReportingConfigurationBuilder(); } @@ -2632,28 +2644,31 @@ public static SarifLog.ReportingConfiguration.ReportingConfigurationBuilder buil /** * Boolean, to dis- and enable the config based on matching a rule (through the Descriptor). */ - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") public boolean getEnabled() { return this.enabled; } + /** * Takes the levelProperty of the Descriptor (if present) or provides a default/override. */ - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") public String getLevel() { return this.level; } + /** * Takes the rank/priority of the Descriptor (if present) or provides a default/override value between 1.0 and 100.0. */ - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") public double getRank() { return this.rank; } + /** * Define configuration information (propertyBag) specific to the Descriptor. */ - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") public PropertyBag getParameters() { return this.parameters; } @@ -2662,42 +2677,45 @@ public PropertyBag getParameters() { * Boolean, to dis- and enable the config based on matching a rule (through the Descriptor). * @return {@code this}. */ - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") public SarifLog.ReportingConfiguration setEnabled(final boolean enabled) { this.enabled = enabled; return this; } + /** * Takes the levelProperty of the Descriptor (if present) or provides a default/override. * @return {@code this}. */ - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") public SarifLog.ReportingConfiguration setLevel(final String level) { this.level = level; return this; } + /** * Takes the rank/priority of the Descriptor (if present) or provides a default/override value between 1.0 and 100.0. * @return {@code this}. */ - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") public SarifLog.ReportingConfiguration setRank(final double rank) { this.rank = rank; return this; } + /** * Define configuration information (propertyBag) specific to the Descriptor. * @return {@code this}. */ - @java.lang.SuppressWarnings("all") + @SuppressWarnings("all") public SarifLog.ReportingConfiguration setParameters(final PropertyBag parameters) { this.parameters = parameters; return this; } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public boolean equals(final java.lang.Object o) { + @Override + @SuppressWarnings("all") + public boolean equals(final Object o) { if (o == this) { return true; } @@ -2705,56 +2723,56 @@ public boolean equals(final java.lang.Object o) { return false; } final SarifLog.ReportingConfiguration other = (SarifLog.ReportingConfiguration) o; - if (!other.canEqual((java.lang.Object) this)) { + if (!other.canEqual((Object) this)) { return false; } - final java.lang.Object this$enabled = this.getEnabled(); - final java.lang.Object other$enabled = other.getEnabled(); + final Object this$enabled = this.getEnabled(); + final Object other$enabled = other.getEnabled(); if (this$enabled == null ? other$enabled != null : !this$enabled.equals(other$enabled)) { return false; } - final java.lang.Object this$level = this.getLevel(); - final java.lang.Object other$level = other.getLevel(); + final Object this$level = this.getLevel(); + final Object other$level = other.getLevel(); if (this$level == null ? other$level != null : !this$level.equals(other$level)) { return false; } - final java.lang.Object this$rank = this.getRank(); - final java.lang.Object other$rank = other.getRank(); + final Object this$rank = this.getRank(); + final Object other$rank = other.getRank(); if (this$rank == null ? other$rank != null : !this$rank.equals(other$rank)) { return false; } - final java.lang.Object this$parameters = this.getParameters(); - final java.lang.Object other$parameters = other.getParameters(); + final Object this$parameters = this.getParameters(); + final Object other$parameters = other.getParameters(); if (this$parameters == null ? other$parameters != null : !this$parameters.equals(other$parameters)) { return false; } return true; } - @java.lang.SuppressWarnings("all") - protected boolean canEqual(final java.lang.Object other) { + @SuppressWarnings("all") + protected boolean canEqual(final Object other) { return other instanceof SarifLog.ReportingConfiguration; } - @java.lang.Override - @java.lang.SuppressWarnings("all") + @Override + @SuppressWarnings("all") public int hashCode() { final int PRIME = 59; int result = 1; - final java.lang.Object $enabled = this.getEnabled(); + final Object $enabled = this.getEnabled(); result = result * PRIME + ($enabled == null ? 43 : $enabled.hashCode()); - final java.lang.Object $level = this.getLevel(); + final Object $level = this.getLevel(); result = result * PRIME + ($level == null ? 43 : $level.hashCode()); - final java.lang.Object $rank = this.getRank(); + final Object $rank = this.getRank(); result = result * PRIME + ($rank == null ? 43 : $rank.hashCode()); - final java.lang.Object $parameters = this.getParameters(); + final Object $parameters = this.getParameters(); result = result * PRIME + ($parameters == null ? 43 : $parameters.hashCode()); return result; } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + @SuppressWarnings("all") + public String toString() { return "SarifLog.ReportingConfiguration(enabled=" + this.getEnabled() + ", level=" + this.getLevel() + ", rank=" + this.getRank() +", parameters=" + this.getParameters() + ")"; } } From 1d83b2616143c3d05f04b5e06987e75a20e07820 Mon Sep 17 00:00:00 2001 From: julees7 Date: Mon, 14 Apr 2025 15:43:06 +0200 Subject: [PATCH 0778/1962] #5525 filled defaultConfig --- .../renderers/internal/sarif/SarifLog.java | 73 +++++++++++++++---- .../internal/sarif/SarifLogBuilder.java | 9 +++ 2 files changed, 66 insertions(+), 16 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java index 217a28b7e17..252bc024cab 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java @@ -2150,9 +2150,13 @@ public static class ReportingDescriptor { * Key/value pairs that provide additional information about the report. */ private PropertyBag properties; + /** + * The default configuration of a rule, can contain a default level and other properties. + */ + private ReportingConfiguration defaultConfiguration; @java.lang.SuppressWarnings("all") - ReportingDescriptor(final String id, final String name, final MultiformatMessage shortDescription, final MultiformatMessage fullDescription, final MultiformatMessage messageStrings, final String helpUri, final MultiformatMessage help, final PropertyBag properties) { + ReportingDescriptor(final String id, final String name, final MultiformatMessage shortDescription, final MultiformatMessage fullDescription, final MultiformatMessage messageStrings, final String helpUri, final MultiformatMessage help, final PropertyBag properties, final ReportingConfiguration defaultConfiguration) { this.id = id; this.name = name; this.shortDescription = shortDescription; @@ -2161,6 +2165,7 @@ public static class ReportingDescriptor { this.helpUri = helpUri; this.help = help; this.properties = properties; + this.defaultConfiguration = defaultConfiguration; } @@ -2182,6 +2187,8 @@ public static class ReportingDescriptorBuilder { private MultiformatMessage help; @java.lang.SuppressWarnings("all") private PropertyBag properties; + @SuppressWarnings("all") + private ReportingConfiguration defaultConfiguration; @java.lang.SuppressWarnings("all") ReportingDescriptorBuilder() { @@ -2271,15 +2278,24 @@ public SarifLog.ReportingDescriptor.ReportingDescriptorBuilder properties(final return this; } + /** + * The default configuration of a rule, can contain a default level and other properties. + * @return {@code this}. + */ + public SarifLog.ReportingDescriptor.ReportingDescriptorBuilder defaultConfiguration(final ReportingConfiguration defaultConfiguration) { + this.defaultConfiguration = defaultConfiguration; + return this; + } + @java.lang.SuppressWarnings("all") public SarifLog.ReportingDescriptor build() { - return new SarifLog.ReportingDescriptor(this.id, this.name, this.shortDescription, this.fullDescription, this.messageStrings, this.helpUri, this.help, this.properties); + return new SarifLog.ReportingDescriptor(this.id, this.name, this.shortDescription, this.fullDescription, this.messageStrings, this.helpUri, this.help, this.properties, this.defaultConfiguration); } @java.lang.Override @java.lang.SuppressWarnings("all") public java.lang.String toString() { - return "SarifLog.ReportingDescriptor.ReportingDescriptorBuilder(id=" + this.id + ", name=" + this.name + ", shortDescription=" + this.shortDescription + ", fullDescription=" + this.fullDescription + ", messageStrings=" + this.messageStrings + ", helpUri=" + this.helpUri + ", help=" + this.help + ", properties=" + this.properties + ")"; + return "SarifLog.ReportingDescriptor.ReportingDescriptorBuilder(id=" + this.id + ", name=" + this.name + ", shortDescription=" + this.shortDescription + ", fullDescription=" + this.fullDescription + ", messageStrings=" + this.messageStrings + ", helpUri=" + this.helpUri + ", help=" + this.help + ", properties=" + this.properties + ", defaultConfiguration=" + this.defaultConfiguration + ")"; } } @@ -2356,6 +2372,14 @@ public PropertyBag getProperties() { return this.properties; } + /** + * The default configuration of a rule, can contain a default level and other properties. + */ + @SuppressWarnings("all") + public ReportingConfiguration getDefaultConfiguration() { + return this.defaultConfiguration; + } + /** * A stable, opaque identifier for the report. * @return {@code this}. @@ -2440,6 +2464,16 @@ public SarifLog.ReportingDescriptor setProperties(final PropertyBag properties) return this; } + /** + * The default configuration of a rule, can contain a default level and other properties. + * @return {@code this}. + */ + @SuppressWarnings("all") + public SarifLog.ReportingDescriptor setDefaultConfiguration(final ReportingConfiguration defaultConfiguration) { + this.defaultConfiguration = defaultConfiguration; + return this; + } + @java.lang.Override @java.lang.SuppressWarnings("all") public boolean equals(final java.lang.Object o) { @@ -2493,6 +2527,11 @@ public boolean equals(final java.lang.Object o) { if (this$properties == null ? other$properties != null : !this$properties.equals(other$properties)) { return false; } + final Object this$defaultConfiguration = this.getDefaultConfiguration(); + final Object other$defaultConfiguration = other.getDefaultConfiguration(); + if (this$defaultConfiguration == null ? other$defaultConfiguration != null : !this$defaultConfiguration.equals(other$defaultConfiguration)) { + return false; + } return true; } @@ -2522,13 +2561,15 @@ public int hashCode() { result = result * PRIME + ($help == null ? 43 : $help.hashCode()); final java.lang.Object $properties = this.getProperties(); result = result * PRIME + ($properties == null ? 43 : $properties.hashCode()); + final Object $defaultConfiguration = this.getDefaultConfiguration(); + result = result * PRIME + ($defaultConfiguration == null ? 43 : $defaultConfiguration.hashCode()); return result; } @java.lang.Override @java.lang.SuppressWarnings("all") public java.lang.String toString() { - return "SarifLog.ReportingDescriptor(id=" + this.getId() + ", name=" + this.getName() + ", shortDescription=" + this.getShortDescription() + ", fullDescription=" + this.getFullDescription() + ", messageStrings=" + this.getMessageStrings() + ", helpUri=" + this.getHelpUri() + ", help=" + this.getHelp() + ", properties=" + this.getProperties() + ")"; + return "SarifLog.ReportingDescriptor(id=" + this.getId() + ", name=" + this.getName() + ", shortDescription=" + this.getShortDescription() + ", fullDescription=" + this.getFullDescription() + ", messageStrings=" + this.getMessageStrings() + ", helpUri=" + this.getHelpUri() + ", help=" + this.getHelp() + ", properties=" + this.getProperties() + ", defaultConfiguration=" + this.getDefaultConfiguration() + ")"; } } @@ -2545,7 +2586,7 @@ public static class ReportingConfiguration { * Boolean, to dis- and enable the config based on matching a rule (through the Descriptor). * Default: true. */ - private boolean enabled; + private Boolean enabled; /** * Takes the levelProperty of the Descriptor (if present) or provides a default/override. @@ -2557,7 +2598,7 @@ public static class ReportingConfiguration { * Takes the rank/priority of the Descriptor (if present) or provides a default/override value between 1.0 and 100.0. * Default: -1.0. */ - private double rank; + private Double rank; /** * Define configuration information (propertyBag) specific to the Descriptor. @@ -2565,7 +2606,7 @@ public static class ReportingConfiguration { private PropertyBag parameters; @SuppressWarnings("all") - ReportingConfiguration(final boolean enabled, final String level, final double rank, final PropertyBag parameters) { + ReportingConfiguration(final Boolean enabled, final String level, final Double rank, final PropertyBag parameters) { this.enabled = enabled; this.level = level; this.rank = rank; @@ -2580,7 +2621,7 @@ public static class ReportingConfigurationBuilder { @SuppressWarnings("all") private String level; @SuppressWarnings("all") - private double rank; + private Double rank; @SuppressWarnings("all") private PropertyBag parameters; @@ -2610,7 +2651,7 @@ public SarifLog.ReportingConfiguration.ReportingConfigurationBuilder level(final * Takes the rank/priority of the Descriptor (if present) or provides a default/override value between 1.0 and 100.0. */ @SuppressWarnings("all") - public SarifLog.ReportingConfiguration.ReportingConfigurationBuilder rank(final double rank) { + public SarifLog.ReportingConfiguration.ReportingConfigurationBuilder rank(final Double rank) { this.rank = rank; return this; } @@ -2645,7 +2686,7 @@ public static SarifLog.ReportingConfiguration.ReportingConfigurationBuilder buil * Boolean, to dis- and enable the config based on matching a rule (through the Descriptor). */ @SuppressWarnings("all") - public boolean getEnabled() { + public Boolean getEnabled() { return this.enabled; } @@ -2661,7 +2702,7 @@ public String getLevel() { * Takes the rank/priority of the Descriptor (if present) or provides a default/override value between 1.0 and 100.0. */ @SuppressWarnings("all") - public double getRank() { + public Double getRank() { return this.rank; } @@ -2678,7 +2719,7 @@ public PropertyBag getParameters() { * @return {@code this}. */ @SuppressWarnings("all") - public SarifLog.ReportingConfiguration setEnabled(final boolean enabled) { + public SarifLog.ReportingConfiguration setEnabled(final Boolean enabled) { this.enabled = enabled; return this; } @@ -2698,7 +2739,7 @@ public SarifLog.ReportingConfiguration setLevel(final String level) { * @return {@code this}. */ @SuppressWarnings("all") - public SarifLog.ReportingConfiguration setRank(final double rank) { + public SarifLog.ReportingConfiguration setRank(final Double rank) { this.rank = rank; return this; } @@ -2942,7 +2983,7 @@ public MultiformatMessage(final String text, final String markdown) { /** - * A exception information object, for the tool runtime errors. + * An exception information object, for the tool runtime errors. */ public static class Exception { /** @@ -3060,7 +3101,7 @@ public java.lang.String toString() { /** - * A associated rule to the toolConfigurationNotification. + * An associated rule to the toolConfigurationNotification. */ public static class AssociatedRule { /** @@ -3350,7 +3391,7 @@ public static class ToolExecutionNotification { */ private Message message; /** - * A exception component to detail the tool exception + * An exception component to detail the tool exception */ private Exception exception; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java index f4721be51c0..64398b16735 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java @@ -22,6 +22,7 @@ import net.sourceforge.pmd.renderers.internal.sarif.SarifLog.PhysicalLocation; import net.sourceforge.pmd.renderers.internal.sarif.SarifLog.PropertyBag; import net.sourceforge.pmd.renderers.internal.sarif.SarifLog.Region; +import net.sourceforge.pmd.renderers.internal.sarif.SarifLog.ReportingConfiguration; import net.sourceforge.pmd.renderers.internal.sarif.SarifLog.ReportingDescriptor; import net.sourceforge.pmd.renderers.internal.sarif.SarifLog.Result; import net.sourceforge.pmd.renderers.internal.sarif.SarifLog.Run; @@ -176,9 +177,17 @@ private ReportingDescriptor getReportingDescriptor(RuleViolation rv) { .helpUri(rv.getRule().getExternalInfoUrl()) .help(new MultiformatMessage(rv.getRule().getDescription())) .properties(getRuleProperties(rv)) + .defaultConfiguration(getDefaultConfigForRuleViolation(rv)) .build(); } + private ReportingConfiguration getDefaultConfigForRuleViolation(RuleViolation rv){ + return ReportingConfiguration.builder() + // get pmd level from rv and translate it to sarif level (for the config) + .level(pmdPriorityToSarifErrorLevel(rv.getRule().getPriority().getPriority())) + .build(); + } + private PropertyBag getRuleProperties(RuleViolation rv) { return PropertyBag.builder() .ruleset(rv.getRule().getRuleSetName()) From 16ab5d2a8fd84bb41e5eaaf86b47bffbf149ef3c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Apr 2025 20:13:08 +0200 Subject: [PATCH 0779/1962] Bump org.checkerframework:checker-qual from 3.49.1 to 3.49.2 (#5676) Bumps [org.checkerframework:checker-qual](https://github.com/typetools/checker-framework) from 3.49.1 to 3.49.2. - [Release notes](https://github.com/typetools/checker-framework/releases) - [Changelog](https://github.com/typetools/checker-framework/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/typetools/checker-framework/compare/checker-framework-3.49.1...checker-framework-3.49.2) --- updated-dependencies: - dependency-name: org.checkerframework:checker-qual dependency-version: 3.49.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 24bb716ae7a..9b5f87e8c66 100644 --- a/pom.xml +++ b/pom.xml @@ -880,7 +880,7 @@ org.checkerframework checker-qual - 3.49.1 + 3.49.2 net.sf.saxon From 0c3bb3162bd479bdeed19317b35b125d5748ea75 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Apr 2025 20:13:42 +0200 Subject: [PATCH 0780/1962] Bump org.apache.commons:commons-text from 1.13.0 to 1.13.1 (#5678) Bumps org.apache.commons:commons-text from 1.13.0 to 1.13.1. --- updated-dependencies: - dependency-name: org.apache.commons:commons-text dependency-version: 1.13.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9b5f87e8c66..75f56428272 100644 --- a/pom.xml +++ b/pom.xml @@ -895,7 +895,7 @@ org.apache.commons commons-text - 1.13.0 + 1.13.1 org.slf4j From 480e3efc23a3bff95dd748332b41bd50069ae473 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Apr 2025 20:14:04 +0200 Subject: [PATCH 0781/1962] Bump com.google.guava:guava from 33.4.6-jre to 33.4.7-jre (#5679) Bumps [com.google.guava:guava](https://github.com/google/guava) from 33.4.6-jre to 33.4.7-jre. - [Release notes](https://github.com/google/guava/releases) - [Commits](https://github.com/google/guava/commits) --- updated-dependencies: - dependency-name: com.google.guava:guava dependency-version: 33.4.7-jre dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 75f56428272..7dc63cd321a 100644 --- a/pom.xml +++ b/pom.xml @@ -930,7 +930,7 @@ com.google.guava guava - 33.4.6-jre + 33.4.7-jre From b10cd69e0948d4716396bc99eb9bd37efba086ee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Apr 2025 20:15:16 +0200 Subject: [PATCH 0782/1962] Bump org.mockito:mockito-core from 5.16.1 to 5.17.0 (#5680) Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.16.1 to 5.17.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.16.1...v5.17.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-version: 5.17.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7dc63cd321a..c47eace809a 100644 --- a/pom.xml +++ b/pom.xml @@ -1004,7 +1004,7 @@ org.mockito mockito-core - 5.16.1 + 5.17.0 test From b9b1fc1770cbe58b1a60c9eb724d81b07b7df633 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Apr 2025 20:15:31 +0200 Subject: [PATCH 0783/1962] Bump org.jacoco:jacoco-maven-plugin from 0.8.12 to 0.8.13 (#5681) Bumps [org.jacoco:jacoco-maven-plugin](https://github.com/jacoco/jacoco) from 0.8.12 to 0.8.13. - [Release notes](https://github.com/jacoco/jacoco/releases) - [Commits](https://github.com/jacoco/jacoco/compare/v0.8.12...v0.8.13) --- updated-dependencies: - dependency-name: org.jacoco:jacoco-maven-plugin dependency-version: 0.8.13 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c47eace809a..067807cd911 100644 --- a/pom.xml +++ b/pom.xml @@ -632,7 +632,7 @@ org.jacoco jacoco-maven-plugin - 0.8.12 + 0.8.13 org.cyclonedx From 890f73d22834a3e08a1c34e020f808e8ff470dee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Apr 2025 20:16:00 +0200 Subject: [PATCH 0784/1962] Bump net.bytebuddy:byte-buddy-agent from 1.17.4 to 1.17.5 (#5682) Bumps [net.bytebuddy:byte-buddy-agent](https://github.com/raphw/byte-buddy) from 1.17.4 to 1.17.5. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.17.4...byte-buddy-1.17.5) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy-agent dependency-version: 1.17.5 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 067807cd911..a4bd914fee1 100644 --- a/pom.xml +++ b/pom.xml @@ -1021,7 +1021,7 @@ net.bytebuddy byte-buddy-agent - 1.17.4 + 1.17.5 test From d0a57228480bb511f26c27e42cfbe35b15bd58de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Apr 2025 20:16:30 +0200 Subject: [PATCH 0785/1962] Bump the all-gems group across 2 directories with 2 updates (#5683) Bumps the all-gems group with 1 update in the /.ci/files directory: [liquid](https://github.com/Shopify/liquid). Bumps the all-gems group with 1 update in the /docs directory: [csv](https://github.com/ruby/csv). Updates `liquid` from 5.8.2 to 5.8.4 - [Release notes](https://github.com/Shopify/liquid/releases) - [Changelog](https://github.com/Shopify/liquid/blob/main/History.md) - [Commits](https://github.com/Shopify/liquid/compare/v5.8.2...v5.8.4) Updates `csv` from 3.3.3 to 3.3.4 - [Release notes](https://github.com/ruby/csv/releases) - [Changelog](https://github.com/ruby/csv/blob/main/NEWS.md) - [Commits](https://github.com/ruby/csv/compare/v3.3.3...v3.3.4) --- updated-dependencies: - dependency-name: liquid dependency-version: 5.8.4 dependency-type: indirect update-type: version-update:semver-patch dependency-group: all-gems - dependency-name: csv dependency-version: 3.3.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all-gems ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .ci/files/Gemfile.lock | 4 ++-- docs/Gemfile.lock | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.ci/files/Gemfile.lock b/.ci/files/Gemfile.lock index c25257fbff8..f70b618d267 100644 --- a/.ci/files/Gemfile.lock +++ b/.ci/files/Gemfile.lock @@ -10,7 +10,7 @@ GEM fugit (1.11.1) et-orbi (~> 1, >= 1.2.11) raabro (~> 1.4) - liquid (5.8.2) + liquid (5.8.4) bigdecimal strscan (>= 3.1.1) logger (1.7.0) @@ -30,7 +30,7 @@ GEM rufus-scheduler (3.9.2) fugit (~> 1.1, >= 1.11.1) slop (4.10.1) - strscan (3.1.2) + strscan (3.1.3) tzinfo (2.0.6) concurrent-ruby (~> 1.0) diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index ac4b4f27841..a4b72b43116 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -27,7 +27,7 @@ GEM commonmarker (0.23.11) concurrent-ruby (1.3.5) connection_pool (2.5.0) - csv (3.3.3) + csv (3.3.4) dnsruby (1.72.4) base64 (~> 0.2.0) logger (~> 1.6.5) From ad0d8d76c6fe7856d029b1460b109f93911db069 Mon Sep 17 00:00:00 2001 From: julees7 Date: Mon, 14 Apr 2025 21:58:47 +0200 Subject: [PATCH 0786/1962] #5525 fixed failing tests --- .../pmd/renderers/internal/sarif/SarifLog.java | 6 +++--- .../pmd/renderers/internal/sarif/SarifLogBuilder.java | 2 +- .../sarif/expected-multiple-locations.sarif.json | 8 ++++++++ .../pmd/renderers/sarif/expected-multiple.sarif.json | 8 ++++++++ .../sourceforge/pmd/renderers/sarif/expected.sarif.json | 4 ++++ 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java index 252bc024cab..b1e1fc75ea2 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java @@ -2295,7 +2295,7 @@ public SarifLog.ReportingDescriptor build() { @java.lang.Override @java.lang.SuppressWarnings("all") public java.lang.String toString() { - return "SarifLog.ReportingDescriptor.ReportingDescriptorBuilder(id=" + this.id + ", name=" + this.name + ", shortDescription=" + this.shortDescription + ", fullDescription=" + this.fullDescription + ", messageStrings=" + this.messageStrings + ", helpUri=" + this.helpUri + ", help=" + this.help + ", properties=" + this.properties + ", defaultConfiguration=" + this.defaultConfiguration + ")"; + return "SarifLog.ReportingDescriptor.ReportingDescriptorBuilder(id=" + this.id + ", name=" + this.name + ", shortDescription=" + this.shortDescription + ", fullDescription=" + this.fullDescription + ", messageStrings=" + this.messageStrings + ", helpUri=" + this.helpUri + ", help=" + this.help + ", properties=" + this.properties + ", defaultConfiguration=" + this.defaultConfiguration + ")"; } } @@ -2673,7 +2673,7 @@ public SarifLog.ReportingConfiguration build() { @Override @SuppressWarnings("all") public String toString() { - return "SarifLog.ReportingConfiguration.ReportingConfigurationBuilder(enabled=" + this.enabled + ", level=" + this.level + ", rank=" + this.rank +", parameters=" + this.parameters + ")"; + return "SarifLog.ReportingConfiguration.ReportingConfigurationBuilder(enabled=" + this.enabled + ", level=" + this.level + ", rank=" + this.rank + ", parameters=" + this.parameters + ")"; } } @@ -2814,7 +2814,7 @@ public int hashCode() { @Override @SuppressWarnings("all") public String toString() { - return "SarifLog.ReportingConfiguration(enabled=" + this.getEnabled() + ", level=" + this.getLevel() + ", rank=" + this.getRank() +", parameters=" + this.getParameters() + ")"; + return "SarifLog.ReportingConfiguration(enabled=" + this.getEnabled() + ", level=" + this.getLevel() + ", rank=" + this.getRank() + ", parameters=" + this.getParameters() + ")"; } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java index 64398b16735..308fb81e984 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java @@ -181,7 +181,7 @@ private ReportingDescriptor getReportingDescriptor(RuleViolation rv) { .build(); } - private ReportingConfiguration getDefaultConfigForRuleViolation(RuleViolation rv){ + private ReportingConfiguration getDefaultConfigForRuleViolation(RuleViolation rv) { return ReportingConfiguration.builder() // get pmd level from rv and translate it to sarif level (for the config) .level(pmdPriorityToSarifErrorLevel(rv.getRule().getPriority().getPriority())) diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple-locations.sarif.json b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple-locations.sarif.json index 94038176b28..70fe0b4e313 100644 --- a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple-locations.sarif.json +++ b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple-locations.sarif.json @@ -26,6 +26,10 @@ "tags": [ "RuleSet" ] + }, + "defaultConfiguration": { + "enabled": false, + "level": "note" } }, { @@ -45,6 +49,10 @@ "tags": [ "RuleSet" ] + }, + "defaultConfiguration": { + "enabled": false, + "level": "error" } } ] diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple.sarif.json b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple.sarif.json index 672497821b1..dcd10f535fb 100644 --- a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple.sarif.json +++ b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple.sarif.json @@ -26,6 +26,10 @@ "tags": [ "RuleSet" ] + }, + "defaultConfiguration": { + "enabled": false, + "level": "note" } }, { @@ -45,6 +49,10 @@ "tags": [ "RuleSet" ] + }, + "defaultConfiguration": { + "enabled": false, + "level": "error" } } ] diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected.sarif.json b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected.sarif.json index 01976419b8f..93526a71f32 100644 --- a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected.sarif.json +++ b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected.sarif.json @@ -26,6 +26,10 @@ "tags": [ "RuleSet" ] + }, + "defaultConfiguration": { + "enabled": false, + "level": "note" } } ] From 8f2df74d07e681006d90eb43b022eb2d7248c435 Mon Sep 17 00:00:00 2001 From: Douglas Griffith Date: Tue, 15 Apr 2025 10:37:32 -0400 Subject: [PATCH 0787/1962] typo fix --- docs/pages/pmd/userdocs/extending/designer_reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/pmd/userdocs/extending/designer_reference.md b/docs/pages/pmd/userdocs/extending/designer_reference.md index db29ee1183b..7cf0a07662c 100644 --- a/docs/pages/pmd/userdocs/extending/designer_reference.md +++ b/docs/pages/pmd/userdocs/extending/designer_reference.md @@ -89,7 +89,7 @@ You can enter source code in the middle zone. There are several ways to focus a node for inspection: * **From the tree view:** just click on an item - * Since 6.16.0, the tree view is also searchable: press Ctlr+F when it's focused, + * Since 6.16.0, the tree view is also searchable: press Ctrl+F when it's focused, or click on the `Search` button and enter a search query. You can cycle through results with Ctrl+Tab or Ctrl+F3, and cycle back with Ctrl+Shift+Tab or Ctrl+Shift+F3. From 4e1b9e39bbbe8f55a8771bc4e0a5212226b6f7c6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 15 Apr 2025 18:45:38 +0200 Subject: [PATCH 0788/1962] [plsql] Support TREAT function with specified datatype Fixes #5675 --- docs/pages/release_notes.md | 2 + pmd-plsql/src/main/javacc/PLSQL.jjt | 12 ++ .../pmd/lang/plsql/ast/TreatFunctionTest.java | 21 ++ .../pmd/lang/plsql/ast/TreatFunctionBasic.pls | 13 ++ .../pmd/lang/plsql/ast/TreatFunctionBasic.txt | 122 +++++++++++ .../lang/plsql/ast/TreatFunctionNested.pls | 27 +++ .../lang/plsql/ast/TreatFunctionNested.txt | 197 ++++++++++++++++++ 7 files changed, 394 insertions(+) create mode 100644 pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionTest.java create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionBasic.pls create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionBasic.txt create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionNested.pls create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionNested.txt diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 33e9a3f172c..7a5d828ae52 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -27,6 +27,8 @@ This is a {{ site.pmd.release_type }} release. * [#3184](https://github.com/pmd/pmd/issues/3184): \[apex] Prevent classes from shadowing System Namespace * java * [#5645](https://github.com/pmd/pmd/issues/5645): \[java] Parse error on switch with yield +* plsql + * [#5675](https://github.com/pmd/pmd/issues/5675): \[plsql] Parse error with TREAT function ### ๐Ÿšจ API Changes diff --git a/pmd-plsql/src/main/javacc/PLSQL.jjt b/pmd-plsql/src/main/javacc/PLSQL.jjt index f916e29c197..46ba17242f0 100644 --- a/pmd-plsql/src/main/javacc/PLSQL.jjt +++ b/pmd-plsql/src/main/javacc/PLSQL.jjt @@ -3916,6 +3916,18 @@ ASTArguments Arguments() : // Note: OrderByClause is only allowed for XMLAGG function, but this grammar allows it for all functions. // https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/XMLAGG.html [ OrderByClause() ] + // Note: "AS" is only allowed for TREAT function, but this grammar allows it for all functions. + // https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TREAT.html + [ + + { String typeImage = ""; } + ( + ( + LOOKAHEAD({isKeyword("JSON")}) KEYWORD("JSON") { typeImage = token.getImage(); } + | ([ "REF" ] { PLSQLNode name; } name = QualifiedName() { typeImage = name.getImage();} ) + ) { jjtThis.setImage(typeImage); } + ) #Datatype + ] ")" { return jjtThis; } diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionTest.java new file mode 100644 index 00000000000..9a39d22c9c7 --- /dev/null +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionTest.java @@ -0,0 +1,21 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.plsql.ast; + +import org.junit.jupiter.api.Test; + +import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; + +public class TreatFunctionTest extends AbstractPLSQLParserTst { + @Test + void treatFunctionBasic() { + doTest("TreatFunctionBasic"); + } + + @Test + void treatFunctionNested() { + doTest("TreatFunctionNested"); + } +} diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionBasic.pls b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionBasic.pls new file mode 100644 index 00000000000..c2ce5f22f80 --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionBasic.pls @@ -0,0 +1,13 @@ +-- +-- Example from https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TREAT.html +-- + +SELECT name, TREAT(VALUE(p) AS employee_t).salary salary + FROM persons p; + +SELECT name, TREAT(VALUE(p) AS REF employee_t).salary salary + FROM persons p; + +SELECT name, TREAT(VALUE(p) AS JSON) salary + FROM persons p; + diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionBasic.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionBasic.txt new file mode 100644 index 00000000000..7d0bee4c0a5 --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionBasic.txt @@ -0,0 +1,122 @@ ++- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "NAME", @Image = "name"] + | | | +- PrimaryPrefix[@CanonicalImage = "NAME", @Image = "name", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "NAME", @Image = "name"] + | | | +- Column[@CanonicalImage = "NAME", @Image = "name"] + | | | +- ID[@CanonicalImage = "NAME", @Image = "name"] + | | +- SqlExpression[@CanonicalImage = "TREAT.SALARY", @Image = "TREAT.salary"] + | | | +- PrimaryExpression[@CanonicalImage = "TREAT.SALARY", @Image = "TREAT.salary"] + | | | +- PrimaryPrefix[@CanonicalImage = "TREAT", @Image = "TREAT", @SelfModifier = false] + | | | | +- FunctionCall[@CanonicalImage = "TREAT", @Image = "TREAT"] + | | | | +- FunctionName[@CanonicalImage = "TREAT", @Image = "TREAT"] + | | | | | +- ID[@CanonicalImage = "TREAT", @Image = "TREAT"] + | | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | | +- ArgumentList[@CanonicalImage = null] + | | | | | +- Argument[@CanonicalImage = null] + | | | | | +- Expression[@CanonicalImage = "VALUE", @Image = "VALUE"] + | | | | | +- PrimaryPrefix[@CanonicalImage = "VALUE", @Image = "VALUE", @SelfModifier = false] + | | | | | +- FunctionCall[@CanonicalImage = "VALUE", @Image = "VALUE"] + | | | | | +- FunctionName[@CanonicalImage = "VALUE", @Image = "VALUE"] + | | | | | | +- ID[@CanonicalImage = "VALUE", @Image = "VALUE"] + | | | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | | | +- ArgumentList[@CanonicalImage = null] + | | | | | +- Argument[@CanonicalImage = null] + | | | | | +- Expression[@CanonicalImage = "P", @Image = "p"] + | | | | | +- PrimaryPrefix[@CanonicalImage = "P", @Image = "p", @SelfModifier = false] + | | | | | +- SimpleExpression[@CanonicalImage = "P", @Image = "p"] + | | | | | +- Column[@CanonicalImage = "P", @Image = "p"] + | | | | | +- ID[@CanonicalImage = "P", @Image = "p"] + | | | | +- Datatype[@CanonicalImage = "EMPLOYEE_T", @Image = "employee_t", @TypeImage = "employee_t"] + | | | | +- QualifiedName[@CanonicalImage = "EMPLOYEE_T", @Image = "employee_t"] + | | | | +- UnqualifiedID[@CanonicalImage = "EMPLOYEE_T", @Image = "employee_t"] + | | | +- PrimarySuffix[@ArgumentCount = -1, @Arguments = false, @ArrayDereference = false, @CanonicalImage = ".SALARY", @Image = ".salary"] + | | | +- QualifiedID[@CanonicalImage = "SALARY", @Image = "salary"] + | | +- ColumnAlias[@CanonicalImage = "SALARY", @Image = "salary"] + | | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + | +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | +- TableName[@CanonicalImage = "PERSONS", @Image = "persons"] + | | +- ID[@CanonicalImage = "PERSONS", @Image = "persons"] + | +- TableAlias[@CanonicalImage = "P", @Image = "p"] + | +- ID[@CanonicalImage = "P", @Image = "p"] + +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + | +- SelectList[@CanonicalImage = null] + | | +- SqlExpression[@CanonicalImage = "NAME", @Image = "name"] + | | | +- PrimaryPrefix[@CanonicalImage = "NAME", @Image = "name", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "NAME", @Image = "name"] + | | | +- Column[@CanonicalImage = "NAME", @Image = "name"] + | | | +- ID[@CanonicalImage = "NAME", @Image = "name"] + | | +- SqlExpression[@CanonicalImage = "TREAT.SALARY", @Image = "TREAT.salary"] + | | | +- PrimaryExpression[@CanonicalImage = "TREAT.SALARY", @Image = "TREAT.salary"] + | | | +- PrimaryPrefix[@CanonicalImage = "TREAT", @Image = "TREAT", @SelfModifier = false] + | | | | +- FunctionCall[@CanonicalImage = "TREAT", @Image = "TREAT"] + | | | | +- FunctionName[@CanonicalImage = "TREAT", @Image = "TREAT"] + | | | | | +- ID[@CanonicalImage = "TREAT", @Image = "TREAT"] + | | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | | +- ArgumentList[@CanonicalImage = null] + | | | | | +- Argument[@CanonicalImage = null] + | | | | | +- Expression[@CanonicalImage = "VALUE", @Image = "VALUE"] + | | | | | +- PrimaryPrefix[@CanonicalImage = "VALUE", @Image = "VALUE", @SelfModifier = false] + | | | | | +- FunctionCall[@CanonicalImage = "VALUE", @Image = "VALUE"] + | | | | | +- FunctionName[@CanonicalImage = "VALUE", @Image = "VALUE"] + | | | | | | +- ID[@CanonicalImage = "VALUE", @Image = "VALUE"] + | | | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | | | +- ArgumentList[@CanonicalImage = null] + | | | | | +- Argument[@CanonicalImage = null] + | | | | | +- Expression[@CanonicalImage = "P", @Image = "p"] + | | | | | +- PrimaryPrefix[@CanonicalImage = "P", @Image = "p", @SelfModifier = false] + | | | | | +- SimpleExpression[@CanonicalImage = "P", @Image = "p"] + | | | | | +- Column[@CanonicalImage = "P", @Image = "p"] + | | | | | +- ID[@CanonicalImage = "P", @Image = "p"] + | | | | +- Datatype[@CanonicalImage = "EMPLOYEE_T", @Image = "employee_t", @TypeImage = "employee_t"] + | | | | +- QualifiedName[@CanonicalImage = "EMPLOYEE_T", @Image = "employee_t"] + | | | | +- UnqualifiedID[@CanonicalImage = "EMPLOYEE_T", @Image = "employee_t"] + | | | +- PrimarySuffix[@ArgumentCount = -1, @Arguments = false, @ArrayDereference = false, @CanonicalImage = ".SALARY", @Image = ".salary"] + | | | +- QualifiedID[@CanonicalImage = "SALARY", @Image = "salary"] + | | +- ColumnAlias[@CanonicalImage = "SALARY", @Image = "salary"] + | | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + | +- FromClause[@CanonicalImage = null] + | +- TableReference[@CanonicalImage = null] + | +- TableName[@CanonicalImage = "PERSONS", @Image = "persons"] + | | +- ID[@CanonicalImage = "PERSONS", @Image = "persons"] + | +- TableAlias[@CanonicalImage = "P", @Image = "p"] + | +- ID[@CanonicalImage = "P", @Image = "p"] + +- SelectStatement[@All = false, @CanonicalImage = null, @Distinct = false, @Unique = false] + +- SelectList[@CanonicalImage = null] + | +- SqlExpression[@CanonicalImage = "NAME", @Image = "name"] + | | +- PrimaryPrefix[@CanonicalImage = "NAME", @Image = "name", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "NAME", @Image = "name"] + | | +- Column[@CanonicalImage = "NAME", @Image = "name"] + | | +- ID[@CanonicalImage = "NAME", @Image = "name"] + | +- SqlExpression[@CanonicalImage = "TREAT", @Image = "TREAT"] + | | +- PrimaryPrefix[@CanonicalImage = "TREAT", @Image = "TREAT", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "TREAT", @Image = "TREAT"] + | | +- FunctionName[@CanonicalImage = "TREAT", @Image = "TREAT"] + | | | +- ID[@CanonicalImage = "TREAT", @Image = "TREAT"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "VALUE", @Image = "VALUE"] + | | | +- PrimaryPrefix[@CanonicalImage = "VALUE", @Image = "VALUE", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "VALUE", @Image = "VALUE"] + | | | +- FunctionName[@CanonicalImage = "VALUE", @Image = "VALUE"] + | | | | +- ID[@CanonicalImage = "VALUE", @Image = "VALUE"] + | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | +- ArgumentList[@CanonicalImage = null] + | | | +- Argument[@CanonicalImage = null] + | | | +- Expression[@CanonicalImage = "P", @Image = "p"] + | | | +- PrimaryPrefix[@CanonicalImage = "P", @Image = "p", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "P", @Image = "p"] + | | | +- Column[@CanonicalImage = "P", @Image = "p"] + | | | +- ID[@CanonicalImage = "P", @Image = "p"] + | | +- Datatype[@CanonicalImage = "JSON", @Image = "JSON", @TypeImage = "JSON"] + | +- ColumnAlias[@CanonicalImage = "SALARY", @Image = "salary"] + | +- ID[@CanonicalImage = "SALARY", @Image = "salary"] + +- FromClause[@CanonicalImage = null] + +- TableReference[@CanonicalImage = null] + +- TableName[@CanonicalImage = "PERSONS", @Image = "persons"] + | +- ID[@CanonicalImage = "PERSONS", @Image = "persons"] + +- TableAlias[@CanonicalImage = "P", @Image = "p"] + +- ID[@CanonicalImage = "P", @Image = "p"] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionNested.pls b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionNested.pls new file mode 100644 index 00000000000..b70521c32d6 --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionNested.pls @@ -0,0 +1,27 @@ +-- +-- From https://github.com/utPLSQL/utPLSQL/blob/develop/examples/developer_examples/RunExampleTestAnnotationsParsingTimeHugePackage.sql +-- See https://github.com/pmd/pmd/issues/5675 +-- + +--Shows that even a very large package specification can be parsed quite quickly +--Clear Screen +set serveroutput on +set echo off +--install the example unit test packages +@@tst_pkg_huge.pks + +declare + l_suites ut_suite_items; + l_items ut_suite_items; +begin + l_suites := ut_suite_manager.configure_execution_by_path(ut_varchar2_list(USER||'.TST_PKG_HUGE')); + l_items := treat( + treat( treat( l_suites( 1 ) as ut_logical_suite ).items( 1 ) as ut_logical_suite ).items( 1 ) + as ut_logical_suite + ).items; + dbms_output.put_line('Created '||l_items.count||' tests in suite'); + dbms_output.put_line(' Last test name='||l_items(l_items.last).name); +end; +/ + +drop package tst_pkg_huge; diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionNested.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionNested.txt new file mode 100644 index 00000000000..221ce9ae136 --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionNested.txt @@ -0,0 +1,197 @@ ++- Input[@CanonicalImage = null, @ExcludedLinesCount = 0, @ExcludedRangesCount = 0] + +- SqlPlusCommand[@CanonicalImage = "SET SERVEROUTPUT ON", @Image = "SET SERVEROUTPUT ON "] + +- SqlPlusCommand[@CanonicalImage = "SET ECHO OFF", @Image = "SET ECHO OFF "] + +- SqlPlusCommand[@CanonicalImage = "@@ TST_PKG_HUGE . PKS", @Image = "@@ TST_PKG_HUGE . PKS "] + +- Global[@CanonicalImage = null] + | +- Block[@CanonicalImage = null] + | +- DeclarativeSection[@CanonicalImage = null] + | | +- DeclarativeUnit[@CanonicalImage = null] + | | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | | +- VariableOrConstantDeclarator[@CanonicalImage = "L_SUITES UT_SUITE_ITEMS", @Image = "l_suites ut_suite_items"] + | | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "L_SUITES", @Image = "l_suites"] + | | | | +- ID[@CanonicalImage = "L_SUITES", @Image = "l_suites"] + | | | +- Datatype[@CanonicalImage = "UT_SUITE_ITEMS", @Image = "ut_suite_items", @TypeImage = "ut_suite_items"] + | | | +- QualifiedName[@CanonicalImage = "UT_SUITE_ITEMS", @Image = "ut_suite_items"] + | | | +- UnqualifiedID[@CanonicalImage = "UT_SUITE_ITEMS", @Image = "ut_suite_items"] + | | +- DeclarativeUnit[@CanonicalImage = null] + | | +- VariableOrConstantDeclaration[@CanonicalImage = null] + | | +- VariableOrConstantDeclarator[@CanonicalImage = "L_ITEMS UT_SUITE_ITEMS", @Image = "l_items ut_suite_items"] + | | +- VariableOrConstantDeclaratorId[@Array = false, @ArrayDepth = 0, @CanonicalImage = "L_ITEMS", @Image = "l_items"] + | | | +- ID[@CanonicalImage = "L_ITEMS", @Image = "l_items"] + | | +- Datatype[@CanonicalImage = "UT_SUITE_ITEMS", @Image = "ut_suite_items", @TypeImage = "ut_suite_items"] + | | +- QualifiedName[@CanonicalImage = "UT_SUITE_ITEMS", @Image = "ut_suite_items"] + | | +- UnqualifiedID[@CanonicalImage = "UT_SUITE_ITEMS", @Image = "ut_suite_items"] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "L_SUITES := UT_SUITE_MANAGER.CONFIGURE_EXECUTION_BY_PATH", @Image = "l_suites := ut_suite_manager.configure_execution_by_path"] + | | +- Assignment[@CanonicalImage = "L_SUITES := UT_SUITE_MANAGER.CONFIGURE_EXECUTION_BY_PATH", @Image = "l_suites := ut_suite_manager.configure_execution_by_path"] + | | +- PrimaryPrefix[@CanonicalImage = "L_SUITES", @Image = "l_suites", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "L_SUITES", @Image = "l_suites"] + | | | +- Column[@CanonicalImage = "L_SUITES", @Image = "l_suites"] + | | | +- ID[@CanonicalImage = "L_SUITES", @Image = "l_suites"] + | | +- Expression[@CanonicalImage = "UT_SUITE_MANAGER.CONFIGURE_EXECUTION_BY_PATH", @Image = "ut_suite_manager.configure_execution_by_path"] + | | +- PrimaryPrefix[@CanonicalImage = "UT_SUITE_MANAGER.CONFIGURE_EXECUTION_BY_PATH", @Image = "ut_suite_manager.configure_execution_by_path", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "UT_SUITE_MANAGER.CONFIGURE_EXECUTION_BY_PATH", @Image = "ut_suite_manager.configure_execution_by_path"] + | | +- FunctionName[@CanonicalImage = "UT_SUITE_MANAGER.CONFIGURE_EXECUTION_BY_PATH", @Image = "ut_suite_manager.configure_execution_by_path"] + | | | +- ID[@CanonicalImage = "UT_SUITE_MANAGER", @Image = "ut_suite_manager"] + | | | +- ID[@CanonicalImage = "CONFIGURE_EXECUTION_BY_PATH", @Image = "configure_execution_by_path"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "UT_VARCHAR2_LIST", @Image = "ut_varchar2_list"] + | | +- PrimaryPrefix[@CanonicalImage = "UT_VARCHAR2_LIST", @Image = "ut_varchar2_list", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "UT_VARCHAR2_LIST", @Image = "ut_varchar2_list"] + | | +- FunctionName[@CanonicalImage = "UT_VARCHAR2_LIST", @Image = "ut_varchar2_list"] + | | | +- ID[@CanonicalImage = "UT_VARCHAR2_LIST", @Image = "ut_varchar2_list"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "USER || \'.TST_PKG_HUGE\'", @Image = "USER || \'.TST_PKG_HUGE\'"] + | | +- AdditiveExpression[@CanonicalImage = "USER || \'.TST_PKG_HUGE\'", @Image = "USER || \'.TST_PKG_HUGE\'"] + | | +- PrimaryPrefix[@CanonicalImage = "USER", @Image = "USER", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "USER", @Image = "USER"] + | | | +- Column[@CanonicalImage = "USER", @Image = "USER"] + | | | +- ID[@CanonicalImage = "USER", @Image = "USER"] + | | +- PrimaryPrefix[@CanonicalImage = "\'.TST_PKG_HUGE\'", @Image = "\'.TST_PKG_HUGE\'", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "\'.TST_PKG_HUGE\'", @Image = "\'.TST_PKG_HUGE\'"] + | | +- StringLiteral[@CanonicalImage = "\'.TST_PKG_HUGE\'", @Image = "\'.TST_PKG_HUGE\'", @String = ".TST_PKG_HUGE"] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "L_ITEMS := TREAT.ITEMS", @Image = "l_items := treat.items"] + | | +- Assignment[@CanonicalImage = "L_ITEMS := TREAT.ITEMS", @Image = "l_items := treat.items"] + | | +- PrimaryPrefix[@CanonicalImage = "L_ITEMS", @Image = "l_items", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "L_ITEMS", @Image = "l_items"] + | | | +- Column[@CanonicalImage = "L_ITEMS", @Image = "l_items"] + | | | +- ID[@CanonicalImage = "L_ITEMS", @Image = "l_items"] + | | +- Expression[@CanonicalImage = "TREAT.ITEMS", @Image = "treat.items"] + | | +- PrimaryExpression[@CanonicalImage = "TREAT.ITEMS", @Image = "treat.items"] + | | +- PrimaryPrefix[@CanonicalImage = "TREAT", @Image = "treat", @SelfModifier = false] + | | | +- FunctionCall[@CanonicalImage = "TREAT", @Image = "treat"] + | | | +- FunctionName[@CanonicalImage = "TREAT", @Image = "treat"] + | | | | +- ID[@CanonicalImage = "TREAT", @Image = "treat"] + | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | +- ArgumentList[@CanonicalImage = null] + | | | | +- Argument[@CanonicalImage = null] + | | | | +- Expression[@CanonicalImage = "TREAT.ITEMSARGUMENTS", @Image = "treat.itemsArguments"] + | | | | +- PrimaryExpression[@CanonicalImage = "TREAT.ITEMSARGUMENTS", @Image = "treat.itemsArguments"] + | | | | +- PrimaryPrefix[@CanonicalImage = "TREAT", @Image = "treat", @SelfModifier = false] + | | | | | +- FunctionCall[@CanonicalImage = "TREAT", @Image = "treat"] + | | | | | +- FunctionName[@CanonicalImage = "TREAT", @Image = "treat"] + | | | | | | +- ID[@CanonicalImage = "TREAT", @Image = "treat"] + | | | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | | | +- ArgumentList[@CanonicalImage = null] + | | | | | | +- Argument[@CanonicalImage = null] + | | | | | | +- Expression[@CanonicalImage = "TREAT.ITEMSARGUMENTS", @Image = "treat.itemsArguments"] + | | | | | | +- PrimaryExpression[@CanonicalImage = "TREAT.ITEMSARGUMENTS", @Image = "treat.itemsArguments"] + | | | | | | +- PrimaryPrefix[@CanonicalImage = "TREAT", @Image = "treat", @SelfModifier = false] + | | | | | | | +- FunctionCall[@CanonicalImage = "TREAT", @Image = "treat"] + | | | | | | | +- FunctionName[@CanonicalImage = "TREAT", @Image = "treat"] + | | | | | | | | +- ID[@CanonicalImage = "TREAT", @Image = "treat"] + | | | | | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | | | | | +- ArgumentList[@CanonicalImage = null] + | | | | | | | | +- Argument[@CanonicalImage = null] + | | | | | | | | +- Expression[@CanonicalImage = "L_SUITES", @Image = "l_suites"] + | | | | | | | | +- PrimaryPrefix[@CanonicalImage = "L_SUITES", @Image = "l_suites", @SelfModifier = false] + | | | | | | | | +- FunctionCall[@CanonicalImage = "L_SUITES", @Image = "l_suites"] + | | | | | | | | +- FunctionName[@CanonicalImage = "L_SUITES", @Image = "l_suites"] + | | | | | | | | | +- ID[@CanonicalImage = "L_SUITES", @Image = "l_suites"] + | | | | | | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | | | | | | +- ArgumentList[@CanonicalImage = null] + | | | | | | | | +- Argument[@CanonicalImage = null] + | | | | | | | | +- Expression[@CanonicalImage = "1", @Image = "1"] + | | | | | | | | +- PrimaryPrefix[@CanonicalImage = "1", @Image = "1", @SelfModifier = false] + | | | | | | | | +- Literal[@CanonicalImage = "1", @Image = "1"] + | | | | | | | | +- NumericLiteral[@CanonicalImage = "1", @Image = "1"] + | | | | | | | +- Datatype[@CanonicalImage = "UT_LOGICAL_SUITE", @Image = "ut_logical_suite", @TypeImage = "ut_logical_suite"] + | | | | | | | +- QualifiedName[@CanonicalImage = "UT_LOGICAL_SUITE", @Image = "ut_logical_suite"] + | | | | | | | +- UnqualifiedID[@CanonicalImage = "UT_LOGICAL_SUITE", @Image = "ut_logical_suite"] + | | | | | | +- PrimarySuffix[@ArgumentCount = -1, @Arguments = false, @ArrayDereference = false, @CanonicalImage = ".ITEMS", @Image = ".items"] + | | | | | | | +- QualifiedID[@CanonicalImage = "ITEMS", @Image = "items"] + | | | | | | +- PrimarySuffix[@ArgumentCount = -1, @Arguments = false, @ArrayDereference = false, @CanonicalImage = "ARGUMENTS", @Image = "Arguments"] + | | | | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | | | | +- ArgumentList[@CanonicalImage = null] + | | | | | | +- Argument[@CanonicalImage = null] + | | | | | | +- Expression[@CanonicalImage = "1", @Image = "1"] + | | | | | | +- PrimaryPrefix[@CanonicalImage = "1", @Image = "1", @SelfModifier = false] + | | | | | | +- Literal[@CanonicalImage = "1", @Image = "1"] + | | | | | | +- NumericLiteral[@CanonicalImage = "1", @Image = "1"] + | | | | | +- Datatype[@CanonicalImage = "UT_LOGICAL_SUITE", @Image = "ut_logical_suite", @TypeImage = "ut_logical_suite"] + | | | | | +- QualifiedName[@CanonicalImage = "UT_LOGICAL_SUITE", @Image = "ut_logical_suite"] + | | | | | +- UnqualifiedID[@CanonicalImage = "UT_LOGICAL_SUITE", @Image = "ut_logical_suite"] + | | | | +- PrimarySuffix[@ArgumentCount = -1, @Arguments = false, @ArrayDereference = false, @CanonicalImage = ".ITEMS", @Image = ".items"] + | | | | | +- QualifiedID[@CanonicalImage = "ITEMS", @Image = "items"] + | | | | +- PrimarySuffix[@ArgumentCount = -1, @Arguments = false, @ArrayDereference = false, @CanonicalImage = "ARGUMENTS", @Image = "Arguments"] + | | | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | | | +- ArgumentList[@CanonicalImage = null] + | | | | +- Argument[@CanonicalImage = null] + | | | | +- Expression[@CanonicalImage = "1", @Image = "1"] + | | | | +- PrimaryPrefix[@CanonicalImage = "1", @Image = "1", @SelfModifier = false] + | | | | +- Literal[@CanonicalImage = "1", @Image = "1"] + | | | | +- NumericLiteral[@CanonicalImage = "1", @Image = "1"] + | | | +- Datatype[@CanonicalImage = "UT_LOGICAL_SUITE", @Image = "ut_logical_suite", @TypeImage = "ut_logical_suite"] + | | | +- QualifiedName[@CanonicalImage = "UT_LOGICAL_SUITE", @Image = "ut_logical_suite"] + | | | +- UnqualifiedID[@CanonicalImage = "UT_LOGICAL_SUITE", @Image = "ut_logical_suite"] + | | +- PrimarySuffix[@ArgumentCount = -1, @Arguments = false, @ArrayDereference = false, @CanonicalImage = ".ITEMS", @Image = ".items"] + | | +- QualifiedID[@CanonicalImage = "ITEMS", @Image = "items"] + | +- Statement[@CanonicalImage = null] + | | +- UnlabelledStatement[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "dbms_output.put_line"] + | | +- PrimaryPrefix[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "dbms_output.put_line", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "dbms_output.put_line"] + | | +- FunctionName[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "dbms_output.put_line"] + | | | +- ID[@CanonicalImage = "DBMS_OUTPUT", @Image = "dbms_output"] + | | | +- ID[@CanonicalImage = "PUT_LINE", @Image = "put_line"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "\'CREATED \' || L_ITEMS.COUNT || \' TESTS IN SUITE\'", @Image = "\'Created \' || l_items.count || \' tests in suite\'"] + | | +- AdditiveExpression[@CanonicalImage = "\'CREATED \' || L_ITEMS.COUNT || \' TESTS IN SUITE\'", @Image = "\'Created \' || l_items.count || \' tests in suite\'"] + | | +- PrimaryPrefix[@CanonicalImage = "\'CREATED \'", @Image = "\'Created \'", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "\'CREATED \'", @Image = "\'Created \'"] + | | | +- StringLiteral[@CanonicalImage = "\'CREATED \'", @Image = "\'Created \'", @String = "Created "] + | | +- PrimaryPrefix[@CanonicalImage = "L_ITEMS.COUNT", @Image = "l_items.count", @SelfModifier = false] + | | | +- SimpleExpression[@CanonicalImage = "L_ITEMS.COUNT", @Image = "l_items.count"] + | | | +- TableName[@CanonicalImage = "L_ITEMS", @Image = "l_items"] + | | | | +- ID[@CanonicalImage = "L_ITEMS", @Image = "l_items"] + | | | +- Column[@CanonicalImage = "COUNT", @Image = "count"] + | | | +- ID[@CanonicalImage = "COUNT", @Image = "count"] + | | +- PrimaryPrefix[@CanonicalImage = "\' TESTS IN SUITE\'", @Image = "\' tests in suite\'", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "\' TESTS IN SUITE\'", @Image = "\' tests in suite\'"] + | | +- StringLiteral[@CanonicalImage = "\' TESTS IN SUITE\'", @Image = "\' tests in suite\'", @String = " tests in suite"] + | +- Statement[@CanonicalImage = null] + | +- UnlabelledStatement[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "dbms_output.put_line"] + | +- PrimaryPrefix[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "dbms_output.put_line", @SelfModifier = false] + | +- FunctionCall[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "dbms_output.put_line"] + | +- FunctionName[@CanonicalImage = "DBMS_OUTPUT.PUT_LINE", @Image = "dbms_output.put_line"] + | | +- ID[@CanonicalImage = "DBMS_OUTPUT", @Image = "dbms_output"] + | | +- ID[@CanonicalImage = "PUT_LINE", @Image = "put_line"] + | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | +- ArgumentList[@CanonicalImage = null] + | +- Argument[@CanonicalImage = null] + | +- Expression[@CanonicalImage = "\' LAST TEST NAME=\' || L_ITEMS.NAME", @Image = "\' Last test name=\' || l_items.name"] + | +- AdditiveExpression[@CanonicalImage = "\' LAST TEST NAME=\' || L_ITEMS.NAME", @Image = "\' Last test name=\' || l_items.name"] + | +- PrimaryPrefix[@CanonicalImage = "\' LAST TEST NAME=\'", @Image = "\' Last test name=\'", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "\' LAST TEST NAME=\'", @Image = "\' Last test name=\'"] + | | +- StringLiteral[@CanonicalImage = "\' LAST TEST NAME=\'", @Image = "\' Last test name=\'", @String = " Last test name="] + | +- PrimaryExpression[@CanonicalImage = "L_ITEMS.NAME", @Image = "l_items.name"] + | +- PrimaryPrefix[@CanonicalImage = "L_ITEMS", @Image = "l_items", @SelfModifier = false] + | | +- FunctionCall[@CanonicalImage = "L_ITEMS", @Image = "l_items"] + | | +- FunctionName[@CanonicalImage = "L_ITEMS", @Image = "l_items"] + | | | +- ID[@CanonicalImage = "L_ITEMS", @Image = "l_items"] + | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] + | | +- ArgumentList[@CanonicalImage = null] + | | +- Argument[@CanonicalImage = null] + | | +- Expression[@CanonicalImage = "L_ITEMS.LAST", @Image = "l_items.last"] + | | +- PrimaryPrefix[@CanonicalImage = "L_ITEMS.LAST", @Image = "l_items.last", @SelfModifier = false] + | | +- SimpleExpression[@CanonicalImage = "L_ITEMS.LAST", @Image = "l_items.last"] + | | +- TableName[@CanonicalImage = "L_ITEMS", @Image = "l_items"] + | | | +- ID[@CanonicalImage = "L_ITEMS", @Image = "l_items"] + | | +- Column[@CanonicalImage = "LAST", @Image = "last"] + | | +- ID[@CanonicalImage = "LAST", @Image = "last"] + | +- PrimarySuffix[@ArgumentCount = -1, @Arguments = false, @ArrayDereference = false, @CanonicalImage = ".NAME", @Image = ".name"] + | +- QualifiedID[@CanonicalImage = "NAME", @Image = "name"] + +- DDLCommand[@CanonicalImage = "DROP", @Image = "DROP"] + +- DDLEvent[@CanonicalImage = "DROP", @Image = "DROP"] + +- ReadPastNextOccurrence[@CanonicalImage = "PACKAGE TST_PKG_HUGE ;", @Image = "PACKAGE TST_PKG_HUGE ;"] + +- Read2NextOccurrence[@CanonicalImage = "PACKAGE TST_PKG_HUGE", @Image = "PACKAGE TST_PKG_HUGE "] From 2329361ba810959bfae00f27614bc3297b9fa5f8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 15 Apr 2025 19:03:38 +0200 Subject: [PATCH 0789/1962] Make TreatFunctionTest package-private Fixes PMD JUnit5TestShouldBePackagePrivate --- .../net/sourceforge/pmd/lang/plsql/ast/TreatFunctionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionTest.java index 9a39d22c9c7..ea872e69802 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TreatFunctionTest.java @@ -8,7 +8,7 @@ import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; -public class TreatFunctionTest extends AbstractPLSQLParserTst { +class TreatFunctionTest extends AbstractPLSQLParserTst { @Test void treatFunctionBasic() { doTest("TreatFunctionBasic"); From 1bd0f205e01dec6b6064c2fa6bed73c6b0a7ea82 Mon Sep 17 00:00:00 2001 From: Gili Tzabari Date: Wed, 16 Apr 2025 17:15:21 -0400 Subject: [PATCH 0790/1962] UnusedPrivateMethodRule: exclude serialization method readObjectNoData() UnusedPrivateMethodRule should exclude Serializable.readObjectNoData() which is defined at https://docs.oracle.com/en/java/javase/11/docs/specs/serialization/input.html#the-readobjectnodata-method --- .../lang/java/rule/bestpractices/UnusedPrivateMethodRule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java index 93667e63443..b2fa36d1c46 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java @@ -37,7 +37,7 @@ public class UnusedPrivateMethodRule extends AbstractIgnoredAnnotationRule { private static final Set SERIALIZATION_METHODS = - setOf("readObject", "writeObject", "readResolve", "writeReplace"); + setOf("readObject", "readObjectNoData", "writeObject", "readResolve", "writeReplace"); @Override protected Collection defaultSuppressionAnnotations() { From 2c801519c4e7e5d6e6cf07c3b153f9e32437a498 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 17 Apr 2025 17:35:29 +0200 Subject: [PATCH 0791/1962] [java] Fix Double Literal for Java19+ compatibility Seems the value 0x4P60 also hits the bug, that was fixed in Java 19. See #4401, https://bugs.openjdk.org/browse/JDK-4511638, https://bugs.openjdk.org/browse/JDK-8291475 and https://inside.java/2022/09/23/quality-heads-up/ We now use "0x4P61", which doesn't hit this bug... --- .../lang/java/ast/jdkversiontests/java14/YieldStatements.java | 2 +- .../lang/java/ast/jdkversiontests/java14/YieldStatements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.java index 397886e5e06..f33e2dae71d 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.java +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.java @@ -47,7 +47,7 @@ public class YieldStatements { yield 004; yield 2e74; yield 0b01; - yield 0x4P60; + yield 0x4P61; yield new Object(); yield (new Object()); yield switch(foo) { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.txt index 533823f1291..ef4b5b1b57c 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.txt @@ -137,7 +137,7 @@ +- YieldStatement[] | +- NumericLiteral[@Base = 2, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0b01", @IntLiteral = true, @Integral = true, @LiteralText = "0b01", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] +- YieldStatement[] - | +- NumericLiteral[@Base = 16, @CompileTimeConstant = true, @DoubleLiteral = true, @FloatLiteral = false, @Image = "0x4P60", @IntLiteral = false, @Integral = false, @LiteralText = "0x4P60", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 4.6116860184273879E18, @ValueAsFloat = 4.611686E18, @ValueAsInt = 0, @ValueAsLong = 4611686018427387904] + | +- NumericLiteral[@Base = 16, @CompileTimeConstant = true, @DoubleLiteral = true, @FloatLiteral = false, @Image = "0x4P61", @IntLiteral = false, @Integral = false, @LiteralText = "0x4P61", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 9.223372036854776E18, @ValueAsFloat = 9.223372E18, @ValueAsInt = -1, @ValueAsLong = 9223372036854775807] +- YieldStatement[] | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] From 388185498efa39d773e8ff67cbf0ed4532c97541 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Thu, 17 Apr 2025 19:20:04 -0300 Subject: [PATCH 0792/1962] XPath functions needs equals/hashCode - They are used in collections, but always assuming they are singletons. - In practice this is true, but inherently, we actually expect QNames to be unique (that is how Saxon finds them underneath), so let's make that explicit in the implementation. --- .../rule/xpath/impl/XPathFunctionDefinition.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/impl/XPathFunctionDefinition.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/impl/XPathFunctionDefinition.java index a684f835bcb..72584695111 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/impl/XPathFunctionDefinition.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/impl/XPathFunctionDefinition.java @@ -4,6 +4,7 @@ package net.sourceforge.pmd.lang.rule.xpath.impl; +import java.util.Objects; import javax.xml.namespace.QName; import org.checkerframework.checker.nullness.qual.Nullable; @@ -67,6 +68,19 @@ public boolean dependsOnContext() { */ public abstract FunctionCall makeCallExpression(); + @Override + public int hashCode() { + return Objects.hashCode(qname); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + XPathFunctionDefinition that = (XPathFunctionDefinition) o; + return Objects.equals(qname, that.qname); + } + /** * Supported types of a custom XPath function. These can be used as {@link #getResultType() result types} * or {@link #getArgumentTypes() argument types}. From 423e4b63d82fc2a571513e7aa28a3413e8446f1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Thu, 17 Apr 2025 19:21:29 -0300 Subject: [PATCH 0793/1962] Have the DummyLanguage define an xpath fn - Make it readily available for all tests instead of defined outside of it only for Saxon tests. --- .../pmd/lang/DummyLanguageModule.java | 29 +++++++++++++++++++ .../internal/SaxonXPathRuleQueryTest.java | 25 +--------------- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java index 5d51ead4294..ce41670d6d6 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java @@ -6,6 +6,9 @@ import java.util.Objects; +import org.apache.commons.lang3.StringUtils; +import org.checkerframework.checker.nullness.qual.NonNull; + import net.sourceforge.pmd.cpd.AnyCpdLexer; import net.sourceforge.pmd.cpd.CpdCapableLanguage; import net.sourceforge.pmd.cpd.CpdLanguageProperties; @@ -22,6 +25,8 @@ import net.sourceforge.pmd.lang.document.TextPos2d; import net.sourceforge.pmd.lang.document.TextRegion; import net.sourceforge.pmd.lang.impl.SimpleLanguageModuleBase; +import net.sourceforge.pmd.lang.rule.xpath.impl.XPathFunctionDefinition; +import net.sourceforge.pmd.lang.rule.xpath.impl.XPathHandler; import net.sourceforge.pmd.reporting.RuleViolation; import net.sourceforge.pmd.reporting.ViolationDecorator; @@ -107,6 +112,11 @@ public Parser getParser() { public ViolationDecorator getViolationDecorator() { return (node, data) -> data.put(RuleViolation.PACKAGE_NAME, "foo"); } + + @Override + public XPathHandler getXPathHandler() { + return XPathHandler.getHandlerForFunctionDefs(imageIsFunction()); + } } /** @@ -176,4 +186,23 @@ public static DummyRootNode readLispNode(ParserTask task) { return root; } + @NonNull + public static XPathFunctionDefinition imageIsFunction() { + return new XPathFunctionDefinition("imageIs", DummyLanguageModule.getInstance()) { + @Override + public Type[] getArgumentTypes() { + return new Type[] {Type.SINGLE_STRING}; + } + + @Override + public Type getResultType() { + return Type.SINGLE_BOOLEAN; + } + + @Override + public FunctionCall makeCallExpression() { + return (contextNode, arguments) -> StringUtils.equals(arguments[0].toString(), contextNode.getImage()); + } + }; + } } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/internal/SaxonXPathRuleQueryTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/internal/SaxonXPathRuleQueryTest.java index a53ffe4b91b..a1c8cd355bd 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/internal/SaxonXPathRuleQueryTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/internal/SaxonXPathRuleQueryTest.java @@ -18,8 +18,6 @@ import java.util.List; import java.util.Map; -import org.apache.commons.lang3.StringUtils; -import org.checkerframework.checker.nullness.qual.NonNull; import org.hamcrest.CoreMatchers; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -32,7 +30,6 @@ import net.sourceforge.pmd.lang.ast.RootNode; import net.sourceforge.pmd.lang.rule.xpath.PmdXPathException; import net.sourceforge.pmd.lang.rule.xpath.XPathVersion; -import net.sourceforge.pmd.lang.rule.xpath.impl.XPathFunctionDefinition; import net.sourceforge.pmd.lang.rule.xpath.impl.XPathHandler; import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.properties.PropertyFactory; @@ -420,28 +417,8 @@ private static SaxonXPathRuleQuery createQuery(String xpath, PropertyDescriptor< xpath, XPathVersion.DEFAULT, props, - XPathHandler.getHandlerForFunctionDefs(imageIsFunction()), + XPathHandler.getHandlerForFunctionDefs(DummyLanguageModule.imageIsFunction()), DeprecatedAttrLogger.noop() ); } - - @NonNull - private static XPathFunctionDefinition imageIsFunction() { - return new XPathFunctionDefinition("imageIs", DummyLanguageModule.getInstance()) { - @Override - public Type[] getArgumentTypes() { - return new Type[] {Type.SINGLE_STRING}; - } - - @Override - public Type getResultType() { - return Type.SINGLE_BOOLEAN; - } - - @Override - public FunctionCall makeCallExpression() { - return (contextNode, arguments) -> StringUtils.equals(arguments[0].toString(), contextNode.getImage()); - } - }; - } } From de1c8503c46e61f63fb1cb5bdc613ac46a880411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Thu, 17 Apr 2025 19:22:20 -0300 Subject: [PATCH 0794/1962] Continue testing dialect promises - Add a dialect-level xpath fn, ensure it's available. - Add skeletons for other promises to be tested --- .../pmd/lang/DummyLanguageDialectModule.java | 36 ++++++++++++++++++- .../SimpleDialectLanguageModuleBaseTest.java | 27 ++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageDialectModule.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageDialectModule.java index e28c68af980..14c267be3b7 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageDialectModule.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageDialectModule.java @@ -2,7 +2,13 @@ import java.util.Objects; +import org.apache.commons.lang3.StringUtils; +import org.checkerframework.checker.nullness.qual.NonNull; + +import net.sourceforge.pmd.lang.impl.BasePmdDialectLanguageVersionHandler; import net.sourceforge.pmd.lang.impl.SimpleDialectLanguageModuleBase; +import net.sourceforge.pmd.lang.rule.xpath.impl.XPathFunctionDefinition; +import net.sourceforge.pmd.lang.rule.xpath.impl.XPathHandler; public class DummyLanguageDialectModule extends SimpleDialectLanguageModuleBase { @@ -12,10 +18,38 @@ public class DummyLanguageDialectModule extends SimpleDialectLanguageModuleBase public DummyLanguageDialectModule() { super(LanguageMetadata.withId(TERSE_NAME).name(NAME) .extensions("txt", "dummydlc") - .addDefaultVersion("1.0").asDialectOf(DummyLanguageModule.TERSE_NAME)); + .addDefaultVersion("1.0").asDialectOf(DummyLanguageModule.TERSE_NAME), new Handler()); } public static DummyLanguageDialectModule getInstance() { return (DummyLanguageDialectModule) Objects.requireNonNull(LanguageRegistry.PMD.getLanguageByFullName(NAME)); } + + public static class Handler extends BasePmdDialectLanguageVersionHandler { + + @Override + public XPathHandler getXPathHandler() { + return XPathHandler.getHandlerForFunctionDefs(dummyDialectFunction()); + } + } + + @NonNull + public static XPathFunctionDefinition dummyDialectFunction() { + return new XPathFunctionDefinition("dummyDialectFn", DummyLanguageDialectModule.getInstance()) { + @Override + public Type[] getArgumentTypes() { + return new Type[] {Type.SINGLE_STRING}; + } + + @Override + public Type getResultType() { + return Type.SINGLE_BOOLEAN; + } + + @Override + public FunctionCall makeCallExpression() { + return (contextNode, arguments) -> StringUtils.equals(arguments[0].toString(), contextNode.getImage()); + } + }; + } } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java index 9cf59625628..7fc0c933c9c 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java @@ -30,6 +30,33 @@ void baseLanguageXPathFunctionAvailable() throws Exception { @Test void dialectSpecificXPathFunctionAvailable() throws Exception { + DummyLanguageDialectModule dialect = DummyLanguageDialectModule.getInstance(); + + try (LanguageProcessor dialectProcessor = dialect.createProcessor(dialect.newPropertyBundle())) { + Set dialectFunctions = dialectProcessor.services().getXPathHandler().getRegisteredExtensionFunctions(); + + XPathFunctionDefinition dummyDialectFunction = DummyLanguageDialectModule.dummyDialectFunction(); + assertTrue(dialectFunctions.contains(dummyDialectFunction), "The function " + dummyDialectFunction.getQName() + " is not available in the dialect."); + } + } + + @Test + void baseLanguagePropertiesAreAvailable() { + // TODO + } + + @Test + void dialectSpecificPropertiesAreAvailable() { + // TODO + } + + @Test + void baseLanguageMetricsAreAvailable() { + // TODO + } + + @Test + void dialectSpecificMetricsAreAvailable() { // TODO } } From 9ec8ee7b1aa1286ff754414a66dde89fd8a5e85d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Thu, 17 Apr 2025 19:55:17 -0300 Subject: [PATCH 0795/1962] Properly test dialect properties --- .../pmd/lang/DummyLanguageDialectModule.java | 15 +++++++++++++++ .../SimpleDialectLanguageModuleBaseTest.java | 17 +++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageDialectModule.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageDialectModule.java index 14c267be3b7..3f0a4dc27e5 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageDialectModule.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageDialectModule.java @@ -9,12 +9,20 @@ import net.sourceforge.pmd.lang.impl.SimpleDialectLanguageModuleBase; import net.sourceforge.pmd.lang.rule.xpath.impl.XPathFunctionDefinition; import net.sourceforge.pmd.lang.rule.xpath.impl.XPathHandler; +import net.sourceforge.pmd.properties.PropertyDescriptor; +import net.sourceforge.pmd.properties.PropertyFactory; public class DummyLanguageDialectModule extends SimpleDialectLanguageModuleBase { public static final String NAME = "DummyDialect"; public static final String TERSE_NAME = "dummydialect"; + public static final PropertyDescriptor DUMMY_DIALECT_PROP = + PropertyFactory.booleanProperty("dummyDialectProperty") + .defaultValue(false) + .desc("Some dummy boolean without purpose") + .build(); + public DummyLanguageDialectModule() { super(LanguageMetadata.withId(TERSE_NAME).name(NAME) .extensions("txt", "dummydlc") @@ -25,6 +33,13 @@ public static DummyLanguageDialectModule getInstance() { return (DummyLanguageDialectModule) Objects.requireNonNull(LanguageRegistry.PMD.getLanguageByFullName(NAME)); } + @Override + protected @NonNull LanguagePropertyBundle newDialectPropertyBundle() { + LanguagePropertyBundle bundle = super.newDialectPropertyBundle(); + bundle.definePropertyDescriptor(DUMMY_DIALECT_PROP); + return bundle; + } + public static class Handler extends BasePmdDialectLanguageVersionHandler { @Override diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java index 7fc0c933c9c..e9962a2d908 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java @@ -9,7 +9,9 @@ import net.sourceforge.pmd.lang.DummyLanguageDialectModule; import net.sourceforge.pmd.lang.DummyLanguageModule; import net.sourceforge.pmd.lang.LanguageProcessor; +import net.sourceforge.pmd.lang.LanguagePropertyBundle; import net.sourceforge.pmd.lang.rule.xpath.impl.XPathFunctionDefinition; +import net.sourceforge.pmd.properties.PropertyDescriptor; class SimpleDialectLanguageModuleBaseTest { @@ -42,12 +44,23 @@ void dialectSpecificXPathFunctionAvailable() throws Exception { @Test void baseLanguagePropertiesAreAvailable() { - // TODO + DummyLanguageModule lang = DummyLanguageModule.getInstance(); + DummyLanguageDialectModule dialect = DummyLanguageDialectModule.getInstance(); + + LanguagePropertyBundle languagePropertyBundle = lang.newPropertyBundle(); + LanguagePropertyBundle dialectPropertyBundle = dialect.newPropertyBundle(); + + for (PropertyDescriptor pd : languagePropertyBundle.getPropertyDescriptors()) { + assertTrue(dialectPropertyBundle.hasDescriptor(pd), "The property " + pd.name() + " is not available in the dialect."); + } } @Test void dialectSpecificPropertiesAreAvailable() { - // TODO + DummyLanguageDialectModule dialect = DummyLanguageDialectModule.getInstance(); + + LanguagePropertyBundle dialectPropertyBundle = dialect.newPropertyBundle(); + assertTrue(dialectPropertyBundle.hasDescriptor(DummyLanguageDialectModule.DUMMY_DIALECT_PROP), "The property " + DummyLanguageDialectModule.DUMMY_DIALECT_PROP.name() + " is not available in the dialect."); } @Test From 97c7b70784077a069cd993f20128fedd42b7d859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Thu, 17 Apr 2025 20:11:17 -0300 Subject: [PATCH 0796/1962] Add tests for dialect metric guarantees --- .../pmd/lang/DummyLanguageDialectModule.java | 13 +++++++ .../pmd/lang/DummyLanguageModule.java | 10 ++++++ .../SimpleDialectLanguageModuleBaseTest.java | 36 ++++++++++++++----- 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageDialectModule.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageDialectModule.java index 3f0a4dc27e5..aed27a1ee6f 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageDialectModule.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageDialectModule.java @@ -5,18 +5,26 @@ import org.apache.commons.lang3.StringUtils; import org.checkerframework.checker.nullness.qual.NonNull; +import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.impl.BasePmdDialectLanguageVersionHandler; import net.sourceforge.pmd.lang.impl.SimpleDialectLanguageModuleBase; +import net.sourceforge.pmd.lang.metrics.LanguageMetricsProvider; +import net.sourceforge.pmd.lang.metrics.Metric; import net.sourceforge.pmd.lang.rule.xpath.impl.XPathFunctionDefinition; import net.sourceforge.pmd.lang.rule.xpath.impl.XPathHandler; import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.properties.PropertyFactory; +import net.sourceforge.pmd.util.CollectionUtil; public class DummyLanguageDialectModule extends SimpleDialectLanguageModuleBase { public static final String NAME = "DummyDialect"; public static final String TERSE_NAME = "dummydialect"; + public static final Metric DUMMY_DIALECT_METRIC = + Metric.of((node, options) -> null, (node) -> node, + "Constant NULL metric", "null"); + public static final PropertyDescriptor DUMMY_DIALECT_PROP = PropertyFactory.booleanProperty("dummyDialectProperty") .defaultValue(false) @@ -46,6 +54,11 @@ public static class Handler extends BasePmdDialectLanguageVersionHandler { public XPathHandler getXPathHandler() { return XPathHandler.getHandlerForFunctionDefs(dummyDialectFunction()); } + + @Override + public LanguageMetricsProvider getLanguageMetricsProvider() { + return () -> CollectionUtil.setOf(DUMMY_DIALECT_METRIC); + } } @NonNull diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java index ce41670d6d6..4138100bb8d 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java @@ -25,10 +25,13 @@ import net.sourceforge.pmd.lang.document.TextPos2d; import net.sourceforge.pmd.lang.document.TextRegion; import net.sourceforge.pmd.lang.impl.SimpleLanguageModuleBase; +import net.sourceforge.pmd.lang.metrics.LanguageMetricsProvider; +import net.sourceforge.pmd.lang.metrics.Metric; import net.sourceforge.pmd.lang.rule.xpath.impl.XPathFunctionDefinition; import net.sourceforge.pmd.lang.rule.xpath.impl.XPathHandler; import net.sourceforge.pmd.reporting.RuleViolation; import net.sourceforge.pmd.reporting.ViolationDecorator; +import net.sourceforge.pmd.util.CollectionUtil; /** * Dummy language used for testing PMD. @@ -117,6 +120,13 @@ public ViolationDecorator getViolationDecorator() { public XPathHandler getXPathHandler() { return XPathHandler.getHandlerForFunctionDefs(imageIsFunction()); } + + @Override + public LanguageMetricsProvider getLanguageMetricsProvider() { + return () -> CollectionUtil.setOf( + Metric.of((node, options) -> 1, (node) -> node, + "Constant value metric", "const1")); + } } /** diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java index e9962a2d908..b07a4b12ce8 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java @@ -1,5 +1,6 @@ package net.sourceforge.pmd.lang.impl; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Set; @@ -10,6 +11,7 @@ import net.sourceforge.pmd.lang.DummyLanguageModule; import net.sourceforge.pmd.lang.LanguageProcessor; import net.sourceforge.pmd.lang.LanguagePropertyBundle; +import net.sourceforge.pmd.lang.metrics.Metric; import net.sourceforge.pmd.lang.rule.xpath.impl.XPathFunctionDefinition; import net.sourceforge.pmd.properties.PropertyDescriptor; @@ -25,7 +27,8 @@ void baseLanguageXPathFunctionAvailable() throws Exception { Set dialectFunctions = dialectProcessor.services().getXPathHandler().getRegisteredExtensionFunctions(); for (XPathFunctionDefinition fn : baseProcessor.services().getXPathHandler().getRegisteredExtensionFunctions()) { - assertTrue(dialectFunctions.contains(fn), "The function " + fn.getQName() + " is not available in the dialect."); + assertTrue(dialectFunctions.contains(fn), + "The function " + fn.getQName() + " is not available in the dialect."); } } } @@ -38,7 +41,8 @@ void dialectSpecificXPathFunctionAvailable() throws Exception { Set dialectFunctions = dialectProcessor.services().getXPathHandler().getRegisteredExtensionFunctions(); XPathFunctionDefinition dummyDialectFunction = DummyLanguageDialectModule.dummyDialectFunction(); - assertTrue(dialectFunctions.contains(dummyDialectFunction), "The function " + dummyDialectFunction.getQName() + " is not available in the dialect."); + assertTrue(dialectFunctions.contains(dummyDialectFunction), + "The function " + dummyDialectFunction.getQName() + " is not available in the dialect."); } } @@ -51,7 +55,8 @@ void baseLanguagePropertiesAreAvailable() { LanguagePropertyBundle dialectPropertyBundle = dialect.newPropertyBundle(); for (PropertyDescriptor pd : languagePropertyBundle.getPropertyDescriptors()) { - assertTrue(dialectPropertyBundle.hasDescriptor(pd), "The property " + pd.name() + " is not available in the dialect."); + assertTrue(dialectPropertyBundle.hasDescriptor(pd), + "The property " + pd.name() + " is not available in the dialect."); } } @@ -60,16 +65,31 @@ void dialectSpecificPropertiesAreAvailable() { DummyLanguageDialectModule dialect = DummyLanguageDialectModule.getInstance(); LanguagePropertyBundle dialectPropertyBundle = dialect.newPropertyBundle(); - assertTrue(dialectPropertyBundle.hasDescriptor(DummyLanguageDialectModule.DUMMY_DIALECT_PROP), "The property " + DummyLanguageDialectModule.DUMMY_DIALECT_PROP.name() + " is not available in the dialect."); + assertTrue(dialectPropertyBundle.hasDescriptor(DummyLanguageDialectModule.DUMMY_DIALECT_PROP), + "The property " + DummyLanguageDialectModule.DUMMY_DIALECT_PROP.name() + " is not available in the dialect."); } @Test - void baseLanguageMetricsAreAvailable() { - // TODO + void baseLanguageMetricsAreAvailable() throws Exception { + DummyLanguageModule lang = DummyLanguageModule.getInstance(); + DummyLanguageDialectModule dialect = DummyLanguageDialectModule.getInstance(); + + try (LanguageProcessor baseProcessor = lang.createProcessor(lang.newPropertyBundle()); + LanguageProcessor dialectProcessor = dialect.createProcessor(dialect.newPropertyBundle())) { + for (Metric metric : baseProcessor.services().getLanguageMetricsProvider().getMetrics()) { + assertNotNull(dialectProcessor.services().getLanguageMetricsProvider().getMetricWithName(metric.displayName()), + "The metric " + metric.displayName() + " is not available in the dialect."); + } + } } @Test - void dialectSpecificMetricsAreAvailable() { - // TODO + void dialectSpecificMetricsAreAvailable() throws Exception { + DummyLanguageDialectModule dialect = DummyLanguageDialectModule.getInstance(); + + try (LanguageProcessor dialectProcessor = dialect.createProcessor(dialect.newPropertyBundle())) { + assertTrue(dialectProcessor.services().getLanguageMetricsProvider().getMetrics().contains(DummyLanguageDialectModule.DUMMY_DIALECT_METRIC), + "The metric " + DummyLanguageDialectModule.DUMMY_DIALECT_METRIC.displayName() + "is not available in the dialect"); + } } } From a8516890b1d398397646c60656fb38529e808db0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Thu, 17 Apr 2025 20:15:36 -0300 Subject: [PATCH 0797/1962] Fix style issues and add license headers --- .../pmd/lang/rule/xpath/impl/XPathFunctionDefinition.java | 8 ++++++-- .../sourceforge/pmd/lang/DummyLanguageDialectModule.java | 4 ++++ .../pmd/lang/LanguageVersionDiscovererTest.java | 4 ++++ .../lang/impl/SimpleDialectLanguageModuleBaseTest.java | 4 ++++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/impl/XPathFunctionDefinition.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/impl/XPathFunctionDefinition.java index 72584695111..e8411eb3b6d 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/impl/XPathFunctionDefinition.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/impl/XPathFunctionDefinition.java @@ -75,8 +75,12 @@ public int hashCode() { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } XPathFunctionDefinition that = (XPathFunctionDefinition) o; return Objects.equals(qname, that.qname); } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageDialectModule.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageDialectModule.java index aed27a1ee6f..380ec1356f9 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageDialectModule.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageDialectModule.java @@ -1,3 +1,7 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + package net.sourceforge.pmd.lang; import java.util.Objects; diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/LanguageVersionDiscovererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/LanguageVersionDiscovererTest.java index a34db639976..db639a1dbf5 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/LanguageVersionDiscovererTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/LanguageVersionDiscovererTest.java @@ -1,3 +1,7 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + package net.sourceforge.pmd.lang; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java index b07a4b12ce8..4106fbe67e3 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java @@ -1,3 +1,7 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + package net.sourceforge.pmd.lang.impl; import static org.junit.jupiter.api.Assertions.assertNotNull; From 067501916851635efc39e93a057209a78e3d5378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Thu, 17 Apr 2025 20:16:50 -0300 Subject: [PATCH 0798/1962] Update the @since docs to reflect current version --- .../pmd/lang/impl/BasePmdDialectLanguageVersionHandler.java | 2 +- .../pmd/lang/impl/SimpleDialectLanguageModuleBase.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/BasePmdDialectLanguageVersionHandler.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/BasePmdDialectLanguageVersionHandler.java index 7f29bd6e1f6..d725df43d79 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/BasePmdDialectLanguageVersionHandler.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/BasePmdDialectLanguageVersionHandler.java @@ -13,7 +13,7 @@ * and support AST processing stages. * * @author Juan Martรญn Sotuyo Dodero - * @since 7.10.0 + * @since 7.13.0 */ @Experimental public class BasePmdDialectLanguageVersionHandler extends AbstractPmdLanguageVersionHandler { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java index b0aa80ae07f..6c9941f8c45 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java @@ -39,7 +39,7 @@ * with all dialect extension applied. * * @author Juan Martรญn Sotuyo Dodero - * @since 7.10.0 + * @since 7.13.0 */ @Experimental public class SimpleDialectLanguageModuleBase extends LanguageModuleBase implements PmdCapableLanguage, CpdCapableLanguage { From d70a56ac9b9c73aeb10a3dcdbb54afe455a7337f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Thu, 17 Apr 2025 20:26:08 -0300 Subject: [PATCH 0799/1962] Reorder statements for short-circuit exit --- .../src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java index 59f28d218ff..f6b1431ae2a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java @@ -628,8 +628,6 @@ boolean applies(FileId qualFileName) { * @apiNote This is internal API. */ static boolean applies(Rule rule, LanguageVersion languageVersion) { - final LanguageVersion min = rule.getMinimumLanguageVersion(); - final LanguageVersion max = rule.getMaximumLanguageVersion(); assert rule.getLanguage() != null : "Rule has no language " + rule; if (languageVersion.getLanguage().isDialectOf(rule.getLanguage())) { @@ -637,6 +635,9 @@ static boolean applies(Rule rule, LanguageVersion languageVersion) { return true; } + final LanguageVersion min = rule.getMinimumLanguageVersion(); + final LanguageVersion max = rule.getMaximumLanguageVersion(); + // All rules from base languages also apply to dialects. They // have to share a parser for that to work. return rule.getLanguage().equals(languageVersion.getLanguage()) From c2adfbe597dd386803f0c4b9f7e4aa8ef1b7eebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Thu, 17 Apr 2025 20:47:10 -0300 Subject: [PATCH 0800/1962] Rename language modules to explicitly call them dialects --- ...{PomLanguageModule.java => PomDialectModule.java} | 8 ++++---- ...sdlLanguageModule.java => WsdlDialectModule.java} | 8 ++++---- ...{XslLanguageModule.java => XslDialectModule.java} | 8 ++++---- .../services/net.sourceforge.pmd.lang.Language | 6 +++--- .../pmd/lang/xml/LanguageVersionTest.java | 12 ++++++------ 5 files changed, 21 insertions(+), 21 deletions(-) rename pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/{PomLanguageModule.java => PomDialectModule.java} (69%) rename pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/{WsdlLanguageModule.java => WsdlDialectModule.java} (72%) rename pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/{XslLanguageModule.java => XslDialectModule.java} (74%) diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomDialectModule.java similarity index 69% rename from pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java rename to pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomDialectModule.java index 5e73f2bfa5e..54b6c48602f 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomDialectModule.java @@ -7,18 +7,18 @@ import net.sourceforge.pmd.lang.LanguageRegistry; import net.sourceforge.pmd.lang.impl.SimpleDialectLanguageModuleBase; -public class PomLanguageModule extends SimpleDialectLanguageModuleBase { +public class PomDialectModule extends SimpleDialectLanguageModuleBase { private static final String ID = "pom"; - public PomLanguageModule() { + public PomDialectModule() { super(LanguageMetadata.withId(ID).name("Maven POM") .extensions("pom") .addDefaultVersion("4.0.0") .asDialectOf("xml")); } - public static PomLanguageModule getInstance() { - return (PomLanguageModule) LanguageRegistry.PMD.getLanguageById(ID); + public static PomDialectModule getInstance() { + return (PomDialectModule) LanguageRegistry.PMD.getLanguageById(ID); } } diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlDialectModule.java similarity index 72% rename from pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java rename to pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlDialectModule.java index b8acf0c7705..a977d2cc0cd 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlDialectModule.java @@ -10,10 +10,10 @@ /** * Created by bernardo-macedo on 24.06.15. */ -public class WsdlLanguageModule extends SimpleDialectLanguageModuleBase { +public class WsdlDialectModule extends SimpleDialectLanguageModuleBase { private static final String ID = "wsdl"; - public WsdlLanguageModule() { + public WsdlDialectModule() { super(LanguageMetadata.withId(ID).name("WSDL") .extensions("wsdl") .addVersion("1.1") @@ -21,7 +21,7 @@ public WsdlLanguageModule() { .asDialectOf("xml")); } - public static WsdlLanguageModule getInstance() { - return (WsdlLanguageModule) LanguageRegistry.PMD.getLanguageById(ID); + public static WsdlDialectModule getInstance() { + return (WsdlDialectModule) LanguageRegistry.PMD.getLanguageById(ID); } } diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslDialectModule.java similarity index 74% rename from pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java rename to pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslDialectModule.java index d6c92686bfb..d83723eb21a 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslDialectModule.java @@ -10,10 +10,10 @@ /** * Created by christoferdutz on 20.09.14. */ -public class XslLanguageModule extends SimpleDialectLanguageModuleBase { +public class XslDialectModule extends SimpleDialectLanguageModuleBase { private static final String ID = "xsl"; - public XslLanguageModule() { + public XslDialectModule() { super(LanguageMetadata.withId(ID).name("XSL") .extensions("xsl", "xslt") .addVersion("1.0") @@ -22,7 +22,7 @@ public XslLanguageModule() { .asDialectOf("xml")); } - public static XslLanguageModule getInstance() { - return (XslLanguageModule) LanguageRegistry.PMD.getLanguageById(ID); + public static XslDialectModule getInstance() { + return (XslDialectModule) LanguageRegistry.PMD.getLanguageById(ID); } } diff --git a/pmd-xml/src/main/resources/META-INF/services/net.sourceforge.pmd.lang.Language b/pmd-xml/src/main/resources/META-INF/services/net.sourceforge.pmd.lang.Language index 68439b0d58e..fe85986fe76 100644 --- a/pmd-xml/src/main/resources/META-INF/services/net.sourceforge.pmd.lang.Language +++ b/pmd-xml/src/main/resources/META-INF/services/net.sourceforge.pmd.lang.Language @@ -1,4 +1,4 @@ net.sourceforge.pmd.lang.xml.XmlLanguageModule -net.sourceforge.pmd.lang.xml.xsl.XslLanguageModule -net.sourceforge.pmd.lang.xml.wsdl.WsdlLanguageModule -net.sourceforge.pmd.lang.xml.pom.PomLanguageModule +net.sourceforge.pmd.lang.xml.xsl.XslDialectModule +net.sourceforge.pmd.lang.xml.wsdl.WsdlDialectModule +net.sourceforge.pmd.lang.xml.pom.PomDialectModule diff --git a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/LanguageVersionTest.java b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/LanguageVersionTest.java index e0bc29110d1..8dc8ff2d055 100644 --- a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/LanguageVersionTest.java +++ b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/LanguageVersionTest.java @@ -7,9 +7,9 @@ import java.util.Arrays; import java.util.Collection; -import net.sourceforge.pmd.lang.xml.pom.PomLanguageModule; -import net.sourceforge.pmd.lang.xml.wsdl.WsdlLanguageModule; -import net.sourceforge.pmd.lang.xml.xsl.XslLanguageModule; +import net.sourceforge.pmd.lang.xml.pom.PomDialectModule; +import net.sourceforge.pmd.lang.xml.wsdl.WsdlDialectModule; +import net.sourceforge.pmd.lang.xml.xsl.XslDialectModule; import net.sourceforge.pmd.test.AbstractLanguageVersionTest; class LanguageVersionTest extends AbstractLanguageVersionTest { @@ -17,9 +17,9 @@ class LanguageVersionTest extends AbstractLanguageVersionTest { static Collection data() { return Arrays.asList( TestDescriptor.defaultVersionIs(XmlLanguageModule.getInstance(), "1.1"), - TestDescriptor.defaultVersionIs(XslLanguageModule.getInstance(), "3.0"), - TestDescriptor.defaultVersionIs(WsdlLanguageModule.getInstance(), "2.0"), - TestDescriptor.defaultVersionIs(PomLanguageModule.getInstance(), "4.0.0") + TestDescriptor.defaultVersionIs(XslDialectModule.getInstance(), "3.0"), + TestDescriptor.defaultVersionIs(WsdlDialectModule.getInstance(), "2.0"), + TestDescriptor.defaultVersionIs(PomDialectModule.getInstance(), "4.0.0") ); } } From 55336e71aa6f42ed40689caaeca0c6b1432a73c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Thu, 17 Apr 2025 20:51:50 -0300 Subject: [PATCH 0801/1962] Restore the old language module as deprecated - Avoid any binary incompatibility. The classes remain, but unused. --- .../pmd/lang/xml/pom/PomLanguageModule.java | 37 ++++++++++++++++++ .../pmd/lang/xml/wsdl/WsdlLanguageModule.java | 38 ++++++++++++++++++ .../pmd/lang/xml/xsl/XslLanguageModule.java | 39 +++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java create mode 100644 pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java create mode 100644 pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java new file mode 100644 index 00000000000..311898f48bd --- /dev/null +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java @@ -0,0 +1,37 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.xml.pom; + +import net.sourceforge.pmd.cpd.CpdLexer; +import net.sourceforge.pmd.lang.LanguagePropertyBundle; +import net.sourceforge.pmd.lang.LanguageRegistry; +import net.sourceforge.pmd.lang.impl.SimpleLanguageModuleBase; +import net.sourceforge.pmd.lang.xml.XmlHandler; +import net.sourceforge.pmd.lang.xml.cpd.XmlCpdLexer; + +/** + * This language module is deprecated. POM is now a dialect of XML. + * @deprecated Use @link{PomDialectModule} instead. + */ +@Deprecated +public class PomLanguageModule extends SimpleLanguageModuleBase { + private static final String ID = "pom"; + + public PomLanguageModule() { + super(LanguageMetadata.withId(ID).name("Maven POM") + .extensions("pom") + .addDefaultVersion("4.0.0"), + new XmlHandler()); + } + + public static PomLanguageModule getInstance() { + return (PomLanguageModule) LanguageRegistry.PMD.getLanguageById(ID); + } + + @Override + public CpdLexer createCpdLexer(LanguagePropertyBundle bundle) { + return new XmlCpdLexer(); + } +} diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java new file mode 100644 index 00000000000..5126fd1b769 --- /dev/null +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java @@ -0,0 +1,38 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.xml.wsdl; + +import net.sourceforge.pmd.cpd.CpdLexer; +import net.sourceforge.pmd.lang.LanguagePropertyBundle; +import net.sourceforge.pmd.lang.LanguageRegistry; +import net.sourceforge.pmd.lang.impl.SimpleLanguageModuleBase; +import net.sourceforge.pmd.lang.xml.XmlHandler; +import net.sourceforge.pmd.lang.xml.cpd.XmlCpdLexer; + +/** + * This language module is deprecated. WSDL is now a dialect of XML. + * @deprecated Use @link{WsdlDialectModule} instead. + */ +@Deprecated +public class WsdlLanguageModule extends SimpleLanguageModuleBase { + private static final String ID = "wsdl"; + + public WsdlLanguageModule() { + super(LanguageMetadata.withId(ID).name("WSDL") + .extensions("wsdl") + .addVersion("1.1") + .addDefaultVersion("2.0"), + new XmlHandler()); + } + + public static WsdlLanguageModule getInstance() { + return (WsdlLanguageModule) LanguageRegistry.PMD.getLanguageById(ID); + } + + @Override + public CpdLexer createCpdLexer(LanguagePropertyBundle bundle) { + return new XmlCpdLexer(); + } +} diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java new file mode 100644 index 00000000000..0b8178dfc78 --- /dev/null +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java @@ -0,0 +1,39 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.xml.xsl; + +import net.sourceforge.pmd.cpd.CpdLexer; +import net.sourceforge.pmd.lang.LanguagePropertyBundle; +import net.sourceforge.pmd.lang.LanguageRegistry; +import net.sourceforge.pmd.lang.impl.SimpleLanguageModuleBase; +import net.sourceforge.pmd.lang.xml.XmlHandler; +import net.sourceforge.pmd.lang.xml.cpd.XmlCpdLexer; + +/** + * This language module is deprecated. XSL is now a dialect of XML. + * @deprecated Use @link{XslDialectModule} instead. + */ +@Deprecated +public class XslLanguageModule extends SimpleLanguageModuleBase { + private static final String ID = "xsl"; + + public XslLanguageModule() { + super(LanguageMetadata.withId(ID).name("XSL") + .extensions("xsl", "xslt") + .addVersion("1.0") + .addVersion("2.0") + .addDefaultVersion("3.0"), + new XmlHandler()); + } + + public static XslLanguageModule getInstance() { + return (XslLanguageModule) LanguageRegistry.PMD.getLanguageById(ID); + } + + @Override + public CpdLexer createCpdLexer(LanguagePropertyBundle bundle) { + return new XmlCpdLexer(); + } +} From 11f47df7b4dde034cde7d868a4767f45d8cc0b70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Fri, 18 Apr 2025 01:05:24 -0300 Subject: [PATCH 0802/1962] Add documentation on creating a dialect --- .../major_contributions/adding_a_dialect.md | 113 ++++++++++++++++++ .../adding_a_new_antlr_based_language.md | 10 ++ .../adding_a_new_javacc_based_language.md | 10 ++ 3 files changed, 133 insertions(+) create mode 100644 docs/pages/pmd/devdocs/major_contributions/adding_a_dialect.md diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_dialect.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_dialect.md new file mode 100644 index 00000000000..9bbf95577aa --- /dev/null +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_dialect.md @@ -0,0 +1,113 @@ +--- +title: Adding PMD support for a new dialect for an already existing language +short_title: Adding a new dialect +tags: [devdocs, extending] +summary: "How to add a new dialect." +last_updated: April 2025 (7.13.0) +sidebar: pmd_sidebar +permalink: pmd_devdocs_major_adding_dialect.html +folder: pmd/devdocs +--- + +{% include callout.html type="info" content=" + +**What is a dialect?**

    + +A dialect is a particular form of another supported language. For example, an XSLT is a particular form of an XML. +Even though the dialect has it's own seantics and uses, the contents are still readable by any tool capable of understanding the base language. + +In PMD, a dialect allows to set up completely custom rules, XPath functions, properties and metrics for these files; +while retaining the full support of the underlaying language. That means: + +- All rules applicable to the base language are automatically applicable to all files processed as a dialect. +- All XPath functions existing in the base language are available when creating new rules. +- All metrics supported by the base language are available when creating new rules. +- All properties (ie: support to suppress literals in CPD) supported by the base language are supported by the dialect. + +" %} + +## Steps + +### 1. Create a dialect module +* Dialects usually reside in the same module of the base language they leverage; but can technically live standalone in a separate module if needed. +* Create your subclass of `net.sourceforge.pmd.lang.impl.SimpleDialectLanguageModuleBase`, see XSL as an example: [`XslDialectModule`](https://github.com/pmd/pmd/blob/main/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslDialectModule.java). +* For a minimal implementation, it just needs a constructor calling supper with the required metadata. + Dialect metadata is created through the builder obtained `LanguageMetadata.withId` + * Define the human readable name of the language by calling `name` + * Define all extensions PMD should consider when applying this dialect by calling `extensions` + * Add for each version of your language a call to `addVersion` in your language moduleโ€™s constructor. + Use `addDefaultVersion` for defining the default version. + * Finalize the metadata construiction by calling `asDialectOf` to reference the base language by id. +* Create the service registration via the text file `src/main/resources/META-INF/services/net.sourceforge.pmd.lang.Language`. + Add your fully qualified class name as a single line into it. + +### 2. Create a language handler (Optional) +* This step is only required if you either want the dialect to: + * expose additional XPath functions + * compute additional metrics + * customize violation suppress logic + * define {% jdoc core::reporting.ViolationDecorator %}s, to add additional dialect specific information to the + created violations. The [Java language module](pmd_languages_java.html#violation-decorators) uses this to + provide the method name or class name, where the violation occurred. +* To do this, create a new class extending from [`BasePmdDialectLanguageVersionHandler`](https://github.com/pmd/pmd/blob/main/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/BasePmdDialectLanguageVersionHandler.java), and override the getter corresponding to what you want to extend. + You don't need to worry about including anything from the base language, only include your extensions. PMD will take care of merging everything together. +* Ensure to pass a new instance of your dialect handler as a second parameter in your dialect module (see Step 1) when calling `super`. + +### 3. Create rules +* Creating rules is already pretty well documented in PMD - and itโ€™s no different for a new dialect. +* PMD supports 2 types of rules, through visitors or XPath. +* To add a visitor rule: + * You need to extend the abstract rule provided by the base language, for instance in XML dialects, you would extend [`AbstractXmlRule`](https://github.com/pmd/pmd/blob/main/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/rule/AbstractXmlRule.java). + Note, that all rule classes should be suffixed with `Rule` and should be placed + in a package the corresponds to their dialect and category. +* To add an XPath rule you can follow our guide [Writing XPath Rules](pmd_userdocs_extending_writing_xpath_rules.html). +* When creating the category ruleset XML file, the XML can reference build properties that are replaced + during the build. This is used for the `externalInfoUrl` attribute of a rule. E.g. we use `${pmd.website.baseurl}` + to point to the correct webpage (depending on the PMD version). + +### 4. Test the rules +* Testing rules is described in depth in [Testing your rules](pmd_userdocs_extending_testing.html). + * Each rule has its own test class: Create a test class for your rule extending `PmdRuleTst` + *(see + [`UnavailableFunctionTest`](https://github.com/pmd/pmd/blob/main/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionTest.java) + for example)* + * Create a category rule set for your dialect *(see + [`pmd-swift/src/main/resources/bestpractices.xml`](https://github.com/pmd/pmd/blob/main/pmd-swift/src/main/resources/category/swift/bestpractices.xml) + for example)* + * Place the test XML file with the test cases in the correct location + * When executing the test class + * this triggers the unit test to read the corresponding XML file with the rule test data + *(see + [`UnavailableFunction.xml`](https://github.com/pmd/pmd/blob/main/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/rule/bestpractices/xml/UnavailableFunction.xml) + for example)* + * This test XML file contains sample pieces of code which should trigger a specified number of + violations of this rule. The unit test will execute the rule on this piece of code, and verify + that the number of violations matches. +* To verify the validity of all the created rulesets, create a subclass of `AbstractRuleSetFactoryTest` + (*see `RuleSetFactoryTest` in pmd-swift for example)*. + This will load all rulesets and verify, that all required attributes are provided. + + *Note:* You'll need to add your ruleset to `categories.properties`, so that it can be found. + +### 5. Create documentation page +Finishing up your new dialect by adding a page in the documentation. Create a new markdown file +`.md` in `docs/pages/pmd/languages/`. This file should have the following frontmatter: + +``` +--- +title: +permalink: pmd_languages_.html +last_updated: () +tags: [languages, PmdCapableLanguage, CpdCapableLanguage] +--- +``` + +On this page, language specifics can be documented, e.g. when the language was first supported by PMD. +There is also the following Jekyll Include, that creates summary box for the language: + +``` +{% raw %} +{% include language_info.html name='' id='' implementation='::lang..LanguageModule' supports_cpd=true supports_pmd=true %} +{% endraw %} +``` + diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md index adc76418e4f..9dfe8974daa 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md @@ -9,6 +9,16 @@ permalink: pmd_devdocs_major_adding_new_language_antlr.html folder: pmd/devdocs --- +{% include callout.html type="info" content=" + +**Do you really need a new language?**

    + +This document describes how to add a new full-fledged language, with it's own grammar and parser. +If what you are trying to support is "a specific type" of files for a grammar that already exists +(ie: a specific type of XML or HTML file) you may want to consider [creating a **dialect**](pmd_devdocs_major_adding_dialect.html) instead. + +" %} + {% include callout.html type="warning" content=" **Before you start...**

    diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md index 73587280dd6..f736d26f9bb 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md @@ -9,6 +9,16 @@ permalink: pmd_devdocs_major_adding_new_language_javacc.html folder: pmd/devdocs --- +{% include callout.html type="info" content=" + +**Do you really need a new language?**

    + +This document describes how to add a new full-fledged language, with it's own grammar and parser. +If what you are trying to support is "a specific type" of files for a grammar that already exists +(ie: a specific type of XML or HTML file) you may want to consider [creating a **dialect**](pmd_devdocs_major_adding_dialect.html) instead. + +" %} + {% include callout.html type="warning" content=" **Before you start...**

    From c02dfd0f012715e85a6ebdc44182e06e48a2cfb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Fri, 18 Apr 2025 01:38:57 -0300 Subject: [PATCH 0803/1962] Review and fix docs --- docs/_data/sidebars/pmd_sidebar.yml | 3 +++ .../devdocs/major_contributions/adding_a_dialect.md | 12 ++++++------ .../adding_a_new_antlr_based_language.md | 2 +- .../adding_a_new_javacc_based_language.md | 2 +- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/_data/sidebars/pmd_sidebar.yml b/docs/_data/sidebars/pmd_sidebar.yml index 1a59e19ae65..372016a22e5 100644 --- a/docs/_data/sidebars/pmd_sidebar.yml +++ b/docs/_data/sidebars/pmd_sidebar.yml @@ -556,6 +556,9 @@ entries: - title: Rule Guidelines url: /pmd_devdocs_major_rule_guidelines.html output: web, pdf + - title: Adding a new dialect + url: /pmd_devdocs_major_adding_dialect.html + output: web, pdf - title: Adding a new language (JavaCC) url: /pmd_devdocs_major_adding_new_language_javacc.html output: web, pdf diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_dialect.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_dialect.md index 9bbf95577aa..0df155b496a 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_a_dialect.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_dialect.md @@ -14,15 +14,15 @@ folder: pmd/devdocs **What is a dialect?**

    A dialect is a particular form of another supported language. For example, an XSLT is a particular form of an XML. -Even though the dialect has it's own seantics and uses, the contents are still readable by any tool capable of understanding the base language. +Even though the dialect has it's own seantics and uses, the contents are still readable by any tool capable of understanding the base language.

    In PMD, a dialect allows to set up completely custom rules, XPath functions, properties and metrics for these files; -while retaining the full support of the underlaying language. That means: +while retaining the full support of the underlaying language. That means:

    -- All rules applicable to the base language are automatically applicable to all files processed as a dialect. -- All XPath functions existing in the base language are available when creating new rules. -- All metrics supported by the base language are available when creating new rules. -- All properties (ie: support to suppress literals in CPD) supported by the base language are supported by the dialect. +- All rules applicable to the base language are automatically applicable to all files processed as a dialect.
    +- All XPath functions existing in the base language are available when creating new rules.
    +- All metrics supported by the base language are available when creating new rules.
    +- All properties (ie: support to suppress literals in CPD) supported by the base language are supported by the dialect.
    " %} diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md index 9dfe8974daa..605d135c2e3 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md @@ -14,7 +14,7 @@ folder: pmd/devdocs **Do you really need a new language?**

    This document describes how to add a new full-fledged language, with it's own grammar and parser. -If what you are trying to support is "a specific type" of files for a grammar that already exists +If what you are trying to support is โ€œa specific typeโ€ of files for a grammar that already exists (ie: a specific type of XML or HTML file) you may want to consider [creating a **dialect**](pmd_devdocs_major_adding_dialect.html) instead. " %} diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md index f736d26f9bb..bf9172f3c5d 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md @@ -14,7 +14,7 @@ folder: pmd/devdocs **Do you really need a new language?**

    This document describes how to add a new full-fledged language, with it's own grammar and parser. -If what you are trying to support is "a specific type" of files for a grammar that already exists +If what you are trying to support is โ€œa specific typeโ€ of files for a grammar that already exists (ie: a specific type of XML or HTML file) you may want to consider [creating a **dialect**](pmd_devdocs_major_adding_dialect.html) instead. " %} From 18ce6ddbbcf52ca02c430ad041b07d62201e32e6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Apr 2025 10:13:07 +0200 Subject: [PATCH 0804/1962] [core] Sarif: fix default value for ReportConfiguration.enabled --- .../sourceforge/pmd/renderers/internal/sarif/SarifLog.java | 4 ++-- .../renderers/sarif/expected-multiple-locations.sarif.json | 2 -- .../pmd/renderers/sarif/expected-multiple.sarif.json | 2 -- .../net/sourceforge/pmd/renderers/sarif/expected.sarif.json | 1 - 4 files changed, 2 insertions(+), 7 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java index b1e1fc75ea2..a0ce2b9b836 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java @@ -2617,7 +2617,7 @@ public static class ReportingConfiguration { @SuppressWarnings("all") public static class ReportingConfigurationBuilder { @SuppressWarnings("all") - private boolean enabled; + private Boolean enabled; @SuppressWarnings("all") private String level; @SuppressWarnings("all") @@ -2633,7 +2633,7 @@ public static class ReportingConfigurationBuilder { * Boolean, to dis- and enable the config based on matching a rule (through the Descriptor). */ @SuppressWarnings("all") - public SarifLog.ReportingConfiguration.ReportingConfigurationBuilder enabled(final boolean enabled) { + public SarifLog.ReportingConfiguration.ReportingConfigurationBuilder enabled(final Boolean enabled) { this.enabled = enabled; return this; } diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple-locations.sarif.json b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple-locations.sarif.json index 70fe0b4e313..02b906e69da 100644 --- a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple-locations.sarif.json +++ b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple-locations.sarif.json @@ -28,7 +28,6 @@ ] }, "defaultConfiguration": { - "enabled": false, "level": "note" } }, @@ -51,7 +50,6 @@ ] }, "defaultConfiguration": { - "enabled": false, "level": "error" } } diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple.sarif.json b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple.sarif.json index dcd10f535fb..adfe0773423 100644 --- a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple.sarif.json +++ b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple.sarif.json @@ -28,7 +28,6 @@ ] }, "defaultConfiguration": { - "enabled": false, "level": "note" } }, @@ -51,7 +50,6 @@ ] }, "defaultConfiguration": { - "enabled": false, "level": "error" } } diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected.sarif.json b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected.sarif.json index 93526a71f32..495ca95ef32 100644 --- a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected.sarif.json +++ b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected.sarif.json @@ -28,7 +28,6 @@ ] }, "defaultConfiguration": { - "enabled": false, "level": "note" } } From f9c3bcb0aba622707833d19b25042f506873f1e0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Apr 2025 10:15:44 +0200 Subject: [PATCH 0805/1962] [doc] Add defaultConfiguration to example sarif report --- docs/report-examples/pmd-report.sarif.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/report-examples/pmd-report.sarif.json b/docs/report-examples/pmd-report.sarif.json index e21d48fb88f..ce9dbc39cc9 100644 --- a/docs/report-examples/pmd-report.sarif.json +++ b/docs/report-examples/pmd-report.sarif.json @@ -27,6 +27,9 @@ "tags":[ "Security" ] + }, + "defaultConfiguration": { + "level": "warning" } }, { @@ -47,6 +50,9 @@ "tags": [ "Documentation" ] + }, + "defaultConfiguration": { + "level": "warning" } } ] From 89195d139a46035a40f8cbd33ada2a7a418cc9ff Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Apr 2025 10:21:58 +0200 Subject: [PATCH 0806/1962] [core] SarifLogBuilder - use RulePriority --- .../renderers/internal/sarif/SarifLog.java | 11 ++++--- .../internal/sarif/SarifLogBuilder.java | 33 ++++++++++--------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java index a0ce2b9b836..5318ad492a7 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java @@ -997,7 +997,7 @@ public static class Result { private Message message; /** - * The severeness of a found bug. Is derived from PMDs defined Priorities (1,2 = error, 3 = warning, 4,5 = note). + * Specifies the severity level of the result. It is derived from PMD's defined rule priorities (1,2 = error, 3 = warning, 4,5 = note). * @see net.sourceforge.pmd.lang.rule.RulePriority */ private String level; @@ -1075,8 +1075,9 @@ public SarifLog.Result.ResultBuilder message(final Message message) { } /** - * The severeness of a found bug. Is derived from PMDs defined Priorities (1,2 = error, 3 = warning, 4,5 = note). + * Specifies the severity level of the result. It is derived from PMD's defined rule priorities (1,2 = error, 3 = warning, 4,5 = note). * @return {@code this}. + * @see net.sourceforge.pmd.lang.rule.RulePriority */ @SuppressWarnings("all") public SarifLog.Result.ResultBuilder level(final String level) { @@ -1148,7 +1149,8 @@ public Message getMessage() { } /** - * The severeness of a found bug. Is derived from PMDs defined Priorities (1,2 = error, 3 = warning, 4,5 = note). + * Specifies the severity level of the result. It is derived from PMD's defined rule priorities (1,2 = error, 3 = warning, 4,5 = note). + * @see net.sourceforge.pmd.lang.rule.RulePriority */ @SuppressWarnings("all") public String getLevel() { @@ -1204,8 +1206,9 @@ public SarifLog.Result setMessage(final Message message) { } /** - * The severeness of a found bug. Is derived from PMDs defined Priorities (1,2 = error, 3 = warning, 4,5 = note). + * Specifies the severity level of the result. It is derived from PMD's defined rule priorities (1,2 = error, 3 = warning, 4,5 = note). * @return {@code this}. + * @see net.sourceforge.pmd.lang.rule.RulePriority */ @SuppressWarnings("all") public SarifLog.Result setLevel(final String level) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java index 308fb81e984..fcb825b12e0 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java @@ -11,6 +11,7 @@ import java.util.List; import net.sourceforge.pmd.PMDVersion; +import net.sourceforge.pmd.lang.rule.RulePriority; import net.sourceforge.pmd.renderers.internal.sarif.SarifLog.ArtifactLocation; import net.sourceforge.pmd.renderers.internal.sarif.SarifLog.AssociatedRule; import net.sourceforge.pmd.renderers.internal.sarif.SarifLog.Component; @@ -51,7 +52,7 @@ public SarifLogBuilder add(RuleViolation violation) { } final Location location = getRuleViolationLocation(violation); - final Result result = resultFrom(ruleDescriptor, ruleIndex, location); + final Result result = resultFrom(ruleDescriptor, ruleIndex, location, violation.getRule().getPriority()); results.add(result); return this; @@ -130,11 +131,11 @@ private boolean isExecutionSuccessful() { return toolExecutionNotifications.isEmpty() && toolConfigurationNotifications.isEmpty(); } - private Result resultFrom(ReportingDescriptor rule, Integer ruleIndex, Location location) { + private Result resultFrom(ReportingDescriptor rule, Integer ruleIndex, Location location, RulePriority rulePriority) { final Result result = Result.builder() .ruleId(rule.getId()) .ruleIndex(ruleIndex) - .level(pmdPriorityToSarifErrorLevel(rule.getProperties().getPriority())) + .level(pmdPriorityToSarifSeverityLevel(rulePriority)) .build(); final Message message = Message.builder() @@ -184,7 +185,7 @@ private ReportingDescriptor getReportingDescriptor(RuleViolation rv) { private ReportingConfiguration getDefaultConfigForRuleViolation(RuleViolation rv) { return ReportingConfiguration.builder() // get pmd level from rv and translate it to sarif level (for the config) - .level(pmdPriorityToSarifErrorLevel(rv.getRule().getPriority().getPriority())) + .level(pmdPriorityToSarifSeverityLevel(rv.getRule().getPriority())) .build(); } @@ -206,21 +207,23 @@ private Component getDriverComponent() { /** - * Converts Pmd's Priority levels into the Sarif options. - * @param pmdPriority of a found bug. - * @return sarif's error level. + * Converts PMD's rule priority into the corresponding Sarif severity level. + * @param rulePriority of a rule violation. + * @return sarif's severity level. * @see net.sourceforge.pmd.lang.rule.RulePriority */ - private String pmdPriorityToSarifErrorLevel(int pmdPriority) { - switch (pmdPriority) { - case 1: // High - case 2: // Medium_High + private String pmdPriorityToSarifSeverityLevel(RulePriority rulePriority) { + switch (rulePriority) { + case HIGH: + case MEDIUM_HIGH: return "error"; - case 3: return "warning"; // Medium - case 4: // Medium_Low - case 5: // Low + case MEDIUM: + return "warning"; + case MEDIUM_LOW: + case LOW: return "note"; - default: return "none"; // should not occur + default: + return "none"; // should not occur } } } From 77e2518f523ad7cef7c78d11d6a909abf5974673 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Apr 2025 10:29:22 +0200 Subject: [PATCH 0807/1962] Add @julees7 as a contributor --- .all-contributorsrc | 10 ++++++++ docs/pages/pmd/projectdocs/credits.md | 35 ++++++++++++++------------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 48c8895cc47..2bde4b193f0 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8010,6 +8010,16 @@ "contributions": [ "bug" ] + }, + { + "login": "julees7", + "name": "julees7", + "avatar_url": "https://avatars.githubusercontent.com/u/98476761?v=4", + "profile": "https://github.com/julees7", + "contributions": [ + "code", + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 9103d1e1eca..c5390461c01 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -981,156 +981,157 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d johnra2
    johnra2

    ๐Ÿ’ป johnzhao9
    johnzhao9

    ๐Ÿ› josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ› + julees7
    julees7

    ๐Ÿ’ป ๐Ÿ› kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ› karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“– karwer
    karwer

    ๐Ÿ› - kaulonline
    kaulonline

    ๐Ÿ› + kaulonline
    kaulonline

    ๐Ÿ› kdaemonv
    kdaemonv

    ๐Ÿ› kdebski85
    kdebski85

    ๐Ÿ› ๐Ÿ’ป kenji21
    kenji21

    ๐Ÿ’ป ๐Ÿ› kfranic
    kfranic

    ๐Ÿ› khalidkh
    khalidkh

    ๐Ÿ› koalalam
    koalalam

    ๐Ÿ› - krzyk
    krzyk

    ๐Ÿ› + krzyk
    krzyk

    ๐Ÿ› lasselindqvist
    lasselindqvist

    ๐Ÿ› lgemeinhardt
    lgemeinhardt

    ๐Ÿ› lihuaib
    lihuaib

    ๐Ÿ› liqingjun123
    liqingjun123

    ๐Ÿ› lonelyma1021
    lonelyma1021

    ๐Ÿ› lpeddy
    lpeddy

    ๐Ÿ› - lujiefsi
    lujiefsi

    ๐Ÿ’ป + lujiefsi
    lujiefsi

    ๐Ÿ’ป lukelukes
    lukelukes

    ๐Ÿ’ป lyriccoder
    lyriccoder

    ๐Ÿ› marcelmore
    marcelmore

    ๐Ÿ› matchbox
    matchbox

    ๐Ÿ› matthiaskraaz
    matthiaskraaz

    ๐Ÿ› meandonlyme
    meandonlyme

    ๐Ÿ› - mikesive
    mikesive

    ๐Ÿ› + mikesive
    mikesive

    ๐Ÿ› milossesic
    milossesic

    ๐Ÿ› mluckam
    mluckam

    ๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
    mohan-chinnappan-n

    ๐Ÿ’ป mriddell95
    mriddell95

    ๐Ÿ› mrlzh
    mrlzh

    ๐Ÿ› msloan
    msloan

    ๐Ÿ› - mucharlaravalika
    mucharlaravalika

    ๐Ÿ› + mucharlaravalika
    mucharlaravalika

    ๐Ÿ› mvenneman
    mvenneman

    ๐Ÿ› nareshl119
    nareshl119

    ๐Ÿ› nicolas-harraudeau-sonarsource
    nicolas-harraudeau-sonarsource

    ๐Ÿ› noerremark
    noerremark

    ๐Ÿ› novsirion
    novsirion

    ๐Ÿ› nwcm
    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป - oggboy
    oggboy

    ๐Ÿ› + oggboy
    oggboy

    ๐Ÿ› oinume
    oinume

    ๐Ÿ› orimarko
    orimarko

    ๐Ÿ’ป ๐Ÿ› pablogomez2197
    pablogomez2197

    ๐Ÿ› pacvz
    pacvz

    ๐Ÿ’ป pallavi agarwal
    pallavi agarwal

    ๐Ÿ› parksungrin
    parksungrin

    ๐Ÿ› - patpatpat123
    patpatpat123

    ๐Ÿ› + patpatpat123
    patpatpat123

    ๐Ÿ› patriksevallius
    patriksevallius

    ๐Ÿ› pbrajesh1
    pbrajesh1

    ๐Ÿ› phoenix384
    phoenix384

    ๐Ÿ› piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป plan3d
    plan3d

    ๐Ÿ› poojasix
    poojasix

    ๐Ÿ› - prabhushrikant
    prabhushrikant

    ๐Ÿ› + prabhushrikant
    prabhushrikant

    ๐Ÿ› pujitha8783
    pujitha8783

    ๐Ÿ› r-r-a-j
    r-r-a-j

    ๐Ÿ› raghujayjunk
    raghujayjunk

    ๐Ÿ› rajeshveera
    rajeshveera

    ๐Ÿ› rajeswarreddy88
    rajeswarreddy88

    ๐Ÿ› recdevs
    recdevs

    ๐Ÿ› - reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ› + reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ› rijkt
    rijkt

    ๐Ÿ› rillig-tk
    rillig-tk

    ๐Ÿ› rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ› rnveach
    rnveach

    ๐Ÿ› rxmicro
    rxmicro

    ๐Ÿ› ryan-gustafson
    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ› - sabi0
    sabi0

    ๐Ÿ› + sabi0
    sabi0

    ๐Ÿ› samc-gearset
    samc-gearset

    ๐Ÿ“– scais
    scais

    ๐Ÿ› schosin
    schosin

    ๐Ÿ› screamingfrog
    screamingfrog

    ๐Ÿ’ต sebbASF
    sebbASF

    ๐Ÿ› sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป - shilko2013
    shilko2013

    ๐Ÿ› + shilko2013
    shilko2013

    ๐Ÿ› shiomiyan
    shiomiyan

    ๐Ÿ“– simeonKondr
    simeonKondr

    ๐Ÿ› snajberk
    snajberk

    ๐Ÿ› sniperrifle2004
    sniperrifle2004

    ๐Ÿ› snuyanzin
    snuyanzin

    ๐Ÿ› ๐Ÿ’ป soloturn
    soloturn

    ๐Ÿ› - soyodream
    soyodream

    ๐Ÿ› + soyodream
    soyodream

    ๐Ÿ› sratz
    sratz

    ๐Ÿ› stonio
    stonio

    ๐Ÿ› sturton
    sturton

    ๐Ÿ’ป ๐Ÿ› sudharmohan
    sudharmohan

    ๐Ÿ› suruchidawar
    suruchidawar

    ๐Ÿ› svenfinitiv
    svenfinitiv

    ๐Ÿ› - szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป + szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป tashiscool
    tashiscool

    ๐Ÿ› test-git-hook
    test-git-hook

    ๐Ÿ› testation21
    testation21

    ๐Ÿ’ป ๐Ÿ› thanosa
    thanosa

    ๐Ÿ› tiandiyixian
    tiandiyixian

    ๐Ÿ› tobwoerk
    tobwoerk

    ๐Ÿ› - tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป + tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป trentchilders
    trentchilders

    ๐Ÿ› triandicAnt
    triandicAnt

    ๐Ÿ› trishul14
    trishul14

    ๐Ÿ› tsui
    tsui

    ๐Ÿ› wangzitom12306
    wangzitom12306

    ๐Ÿ› winhkey
    winhkey

    ๐Ÿ› - witherspore
    witherspore

    ๐Ÿ› + witherspore
    witherspore

    ๐Ÿ› wjljack
    wjljack

    ๐Ÿ› wuchiuwong
    wuchiuwong

    ๐Ÿ› xingsong
    xingsong

    ๐Ÿ› xioayuge
    xioayuge

    ๐Ÿ› xnYi9wRezm
    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ› xuanuy
    xuanuy

    ๐Ÿ› - xyf0921
    xyf0921

    ๐Ÿ› + xyf0921
    xyf0921

    ๐Ÿ› yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› yasuharu-sato
    yasuharu-sato

    ๐Ÿ› zenglian
    zenglian

    ๐Ÿ› zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› zh3ng
    zh3ng

    ๐Ÿ› zt_soft
    zt_soft

    ๐Ÿ› - ztt79
    ztt79

    ๐Ÿ› + ztt79
    ztt79

    ๐Ÿ› zzzzfeng
    zzzzfeng

    ๐Ÿ› รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› ไปป่ดตๆฐ
    ไปป่ดตๆฐ

    ๐Ÿ› From 88ac8d58bab44ce817b89f9012e662858891f8b6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Apr 2025 10:30:15 +0200 Subject: [PATCH 0808/1962] [doc] Update release notes (#5525, #5573) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 26ec825d013..0b786205ef0 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -15,11 +15,14 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* core + * [#5525](https://github.com/pmd/pmd/issues/5525): \[core] Add rule priority as level to Sarif report ### ๐Ÿšจ API Changes ### โœจ Merged pull requests +* [#5573](https://github.com/pmd/pmd/pull/5573): Fix #5525: \[core] Add Sarif Level Property - [julees7](https://github.com/julees7) (@julees7) ### ๐Ÿ“ฆ Dependency updates From 5098e0996b53921a8f08a7ad40a69887c4507ed1 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Apr 2025 10:41:14 +0200 Subject: [PATCH 0809/1962] .ci/tools/release-notes: use login name if no name is found --- .ci/tools/release-notes-add-pr.sh | 2 +- .ci/tools/release-notes-generate.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/tools/release-notes-add-pr.sh b/.ci/tools/release-notes-add-pr.sh index dbc34dd4bd2..723f3aa2550 100755 --- a/.ci/tools/release-notes-add-pr.sh +++ b/.ci/tools/release-notes-add-pr.sh @@ -30,7 +30,7 @@ USER_JSON="$(curl "${CURL_API_HEADER[@]}" "${CURL_AUTH_HEADER[@]}" -s "https://a #DEBUG ONLY #USER_JSON="{\"login\": \"$USER\", \"name\": \"foo $USER\"}" #DEBUG_ONLY -USER_NAME="$(echo "$USER_JSON" | jq --raw-output .name)" +USER_NAME="$(echo "$USER_JSON" | jq --raw-output ".name // \"$USER\"")" search=" - \@$USER" replacement=" - [$USER_NAME](https://github.com/$USER) (@$USER)" PULL_ITEM="${PULL_ITEM//${search}/${replacement}}" diff --git a/.ci/tools/release-notes-generate.sh b/.ci/tools/release-notes-generate.sh index 2bce824ba3b..9fe7711e5cc 100755 --- a/.ci/tools/release-notes-generate.sh +++ b/.ci/tools/release-notes-generate.sh @@ -100,7 +100,7 @@ for login in $AUTHORS; do #DEBUG ONLY #USER_JSON="{\"login\": \"$login\", \"name\": \"foo $login\"}" #DEBUG_ONLY - USER_NAME="$(echo "$USER_JSON" | jq --raw-output .name)" + USER_NAME="$(echo "$USER_JSON" | jq --raw-output ".name // \"$login\"")" search=" - \@$login" replacement=" - [$USER_NAME](https://github.com/$login) (@$login)" PULL_REQUESTS="${PULL_REQUESTS//${search}/${replacement}}" From bad0d81301ab228c5aa1645c5137d68c3287cf6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 22 Apr 2025 18:17:48 +0200 Subject: [PATCH 0810/1962] [java] Add synthetic field for Slf4j logger Ref #3119 --- .../lang/java/internal/JavaAstProcessor.java | 1 + .../internal/ImplicitMemberSymbols.java | 13 ++++++++++ .../symbols/internal/ast/AstClassSym.java | 24 ++++++++++++------- .../internal/ast/SymbolResolutionPass.java | 8 +++++++ .../table/internal/SymbolTableResolver.java | 4 ++++ .../xml/InvalidLogMessageFormat.xml | 14 +++++++++++ 6 files changed, 56 insertions(+), 8 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAstProcessor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAstProcessor.java index c5cc67f7d79..1946ee81d8b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAstProcessor.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAstProcessor.java @@ -130,6 +130,7 @@ public void process() { InternalApiBridge.initTypeResolver(acu, this, typeInferenceLogger); TimeTracker.bench("Symbol table resolution", () -> SymbolTableResolver.traverse(this, acu)); + TimeTracker.bench("AST disambiguation", () -> InternalApiBridge.disambigWithCtx(NodeStream.of(acu), ReferenceCtx.root(this, acu))); if (globalProc.getProperties().getProperty(JavaLanguageProperties.INTERNAL_DO_STRICT_TYPERES)) { TimeTracker.bench("Force type resolution", () -> InternalApiBridge.forceTypeResolutionPhase(this, acu)); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ImplicitMemberSymbols.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ImplicitMemberSymbols.java index abee69b5bee..d3a475e1ea3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ImplicitMemberSymbols.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ImplicitMemberSymbols.java @@ -16,6 +16,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import net.sourceforge.pmd.lang.java.ast.ASTVariableId; +import net.sourceforge.pmd.lang.java.internal.JavaAstProcessor; import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; import net.sourceforge.pmd.lang.java.symbols.JConstructorSymbol; import net.sourceforge.pmd.lang.java.symbols.JExecutableSymbol; @@ -152,6 +153,18 @@ public static JFieldSymbol arrayLengthField(JClassSymbol arraySym) { ); } + public static JFieldSymbol lombokSlf4jLoggerField(JClassSymbol classSym, JavaAstProcessor processor) { + // https://javadoc.io/doc/org.projectlombok/lombok/1.16.18/lombok/extern/slf4j/Slf4j.html + + return new FakeFieldSym( + classSym, + "log", + Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL, + (ts, s) -> + ts.declaration(processor.findSymbolCannotFail("org.slf4j.Logger")) + ); + } + private abstract static class FakeExecutableSymBase implements JExecutableSymbol { private final JClassSymbol owner; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstClassSym.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstClassSym.java index 3e72a96b44e..60f66ae9fa8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstClassSym.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstClassSym.java @@ -30,6 +30,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTVariableId; import net.sourceforge.pmd.lang.java.ast.InternalApiBridge; import net.sourceforge.pmd.lang.java.ast.JModifier; +import net.sourceforge.pmd.lang.java.internal.JavaAstProcessor; import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; import net.sourceforge.pmd.lang.java.symbols.JConstructorSymbol; import net.sourceforge.pmd.lang.java.symbols.JElementSymbol; @@ -142,10 +143,11 @@ final class AstClassSym myMethods.add(ImplicitMemberSymbols.enumValueOf(this)); } - this.declaredClasses = Collections.unmodifiableList(myClasses); - this.declaredMethods = Collections.unmodifiableList(myMethods); - this.declaredCtors = Collections.unmodifiableList(myCtors); - this.declaredFields = Collections.unmodifiableList(myFields); + + this.declaredClasses = myClasses; + this.declaredMethods = myMethods; + this.declaredCtors = myCtors; + this.declaredFields = myFields; this.enumConstants = CollectionUtil.makeUnmodifiableAndNonNull(enumConstants); this.recordComponents = CollectionUtil.makeUnmodifiableAndNonNull(recordComponents); this.annotAttributes = isAnnotation() @@ -153,6 +155,12 @@ final class AstClassSym : HashTreePSet.empty(); } + public void processLombok(JavaAstProcessor processor) { + if (node.isAnnotationPresent("lombok.extern.slf4j.Slf4j")) { + declaredFields.add(ImplicitMemberSymbols.lombokSlf4jLoggerField(this, processor)); + } + } + private List mapComponentsToMutableList(AstSymFactory factory, ASTRecordComponentList components, @@ -204,22 +212,22 @@ public boolean isUnresolved() { @Override public List getDeclaredClasses() { - return declaredClasses; + return Collections.unmodifiableList(declaredClasses); } @Override public List getDeclaredMethods() { - return declaredMethods; + return Collections.unmodifiableList(declaredMethods); } @Override public List getConstructors() { - return declaredCtors; + return Collections.unmodifiableList(declaredCtors); } @Override public List getDeclaredFields() { - return declaredFields; + return Collections.unmodifiableList(declaredFields); } @Override diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/SymbolResolutionPass.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/SymbolResolutionPass.java index c7d14d80c7f..af7432f7642 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/SymbolResolutionPass.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/SymbolResolutionPass.java @@ -12,6 +12,7 @@ import net.sourceforge.pmd.lang.ast.NodeStream; import net.sourceforge.pmd.lang.java.ast.ASTAnnotation; import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; +import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration; import net.sourceforge.pmd.lang.java.ast.InternalApiBridge; import net.sourceforge.pmd.lang.java.ast.SymbolDeclaratorNode; import net.sourceforge.pmd.lang.java.internal.JavaAstProcessor; @@ -47,6 +48,13 @@ public static SymbolResolver traverse(JavaAstProcessor processor, ASTCompilation return visitor.makeKnownSymbolResolver(); } + public static void desugarLombokMembers(JavaAstProcessor processor, ASTTypeDeclaration type) { + JClassSymbol symbol = type.getSymbol(); + if (symbol instanceof AstClassSym) { + ((AstClassSym) symbol).processLombok(processor); + } + } + /** * Converts between nodes to {@link SymAnnot}. Annotations that could not be converted, * eg because they are written with invalid code, are discarded. diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java index 10768ed1ec4..b37827757a7 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java @@ -73,6 +73,7 @@ import net.sourceforge.pmd.lang.java.ast.JavaVisitorBase; import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; import net.sourceforge.pmd.lang.java.internal.JavaAstProcessor; +import net.sourceforge.pmd.lang.java.symbols.internal.ast.SymbolResolutionPass; import net.sourceforge.pmd.lang.java.symbols.table.JSymbolTable; import net.sourceforge.pmd.lang.java.symbols.table.internal.PatternBindingsUtil.BindSet; import net.sourceforge.pmd.lang.java.types.JClassType; @@ -264,6 +265,9 @@ private void processTypeHeader(ASTTypeDeclaration node, ReferenceCtx ctx) { } popStack(pushed - 1); + // resolve annotations, necessary for lombok + f.disambig(node.getModifiers().asStream(), ctx); + SymbolResolutionPass.desugarLombokMembers(ctx.processor, node); // resolve the supertypes, necessary for TypeMemberSymTable f.disambig(notBody, ctx); // extends/implements diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml index a25d5b28240..802f44831b1 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml @@ -1316,4 +1316,18 @@ public class InvalidLogMessageFormat{ } ]]>
    + + + [java] False negative with Slf4j lombok annotation rule #3119 + 1 + + From 8ab293f60535393181b06dc4c2ca01d8bba750fa Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 22 Apr 2025 19:28:44 +0200 Subject: [PATCH 0811/1962] Add @yarlpavaworkday as a contributor --- .all-contributorsrc | 9 +++++++++ docs/pages/pmd/projectdocs/credits.md | 5 +++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 53b25f8d3d0..766a660d2fa 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8047,6 +8047,15 @@ "contributions": [ "doc" ] + }, + { + "login": "yarlpavaworkday", + "name": "yarlpavaworkday", + "avatar_url": "https://avatars.githubusercontent.com/u/73499430?v=4", + "profile": "https://github.com/yarlpavaworkday", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 6ba43d24694..ac1fbce51fe 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -1127,19 +1127,20 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d xuanuy
    xuanuy

    ๐Ÿ› xyf0921
    xyf0921

    ๐Ÿ› yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› + yarlpavaworkday
    yarlpavaworkday

    ๐Ÿ› yasuharu-sato
    yasuharu-sato

    ๐Ÿ› - zenglian
    zenglian

    ๐Ÿ› + zenglian
    zenglian

    ๐Ÿ› zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› zh3ng
    zh3ng

    ๐Ÿ› zt_soft
    zt_soft

    ๐Ÿ› ztt79
    ztt79

    ๐Ÿ› zzzzfeng
    zzzzfeng

    ๐Ÿ› รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› - ไปป่ดตๆฐ
    ไปป่ดตๆฐ

    ๐Ÿ› + ไปป่ดตๆฐ
    ไปป่ดตๆฐ

    ๐Ÿ› ๅคฉ็ƒญๅƒ่ฅฟ็“œ
    ๅคฉ็ƒญๅƒ่ฅฟ็“œ

    ๐Ÿ› ่Œ…ๅปถๅฎ‰
    ่Œ…ๅปถๅฎ‰

    ๐Ÿ’ป From 2edadbe09d4c450e6033c134e24653d6b13c1d0b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 22 Apr 2025 19:30:14 +0200 Subject: [PATCH 0812/1962] [doc] Update release notes (#5667, #5684) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 33e9a3f172c..8273f58d266 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -23,6 +23,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿ› Fixed Issues * core * [#5623](https://github.com/pmd/pmd/issues/5623): \[dist] Make pmd launch script compatible with /bin/sh +* apex-bestpractices + * [#5667](https://github.com/pmd/pmd/issues/5667): \[apex] ApexUnitTestShouldNotUseSeeAllDataTrue false negative when seeAllData parameter is a string * apex-errorprone * [#3184](https://github.com/pmd/pmd/issues/3184): \[apex] Prevent classes from shadowing System Namespace * java @@ -34,6 +36,7 @@ This is a {{ site.pmd.release_type }} release. * [#5450](https://github.com/pmd/pmd/pull/5450): Fix #3184: \[apex] New Rule: TypeShadowsBuiltInNamespace - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) * [#5672](https://github.com/pmd/pmd/pull/5672): \[doc] Fix its/it's and doable/double typos - [John Jetmore](https://github.com/jetmore) (@jetmore) +* [#5684](https://github.com/pmd/pmd/pull/5684): Fix #5667: \[apex] ApexUnitTestShouldNotUseSeeAllDataTrue false negative when seeAllDate parameter is a string - [Thomas Prouvot](https://github.com/tprouvot) (@tprouvot) ### ๐Ÿ“ฆ Dependency updates From cebc7b2fa04c270af291285bba32af5f61aaad9f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 22 Apr 2025 20:00:18 +0200 Subject: [PATCH 0813/1962] Add @dwgrth as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 199 +++++++++++++------------- 2 files changed, 109 insertions(+), 99 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 53b25f8d3d0..cd2c1beec16 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8047,6 +8047,15 @@ "contributions": [ "doc" ] + }, + { + "login": "dwgrth", + "name": "Douglas Griffith", + "avatar_url": "https://avatars.githubusercontent.com/u/37941350?v=4", + "profile": "https://github.com/dwgrth", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 6ba43d24694..abe4b8e71eb 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -250,896 +250,897 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Dmytro Dashenkov
    Dmytro Dashenkov

    ๐Ÿ› + Douglas Griffith
    Douglas Griffith

    ๐Ÿ“– Dr. Christian Kohlschรผtter
    Dr. Christian Kohlschรผtter

    ๐Ÿ› Drew Hall
    Drew Hall

    ๐Ÿ› Dumitru Postoronca
    Dumitru Postoronca

    ๐Ÿ› Dylan Adams
    Dylan Adams

    ๐Ÿ› Eden Hao
    Eden Hao

    ๐Ÿ› - Edward Klimoshenko
    Edward Klimoshenko

    ๐Ÿ› ๐Ÿ’ป + Edward Klimoshenko
    Edward Klimoshenko

    ๐Ÿ› ๐Ÿ’ป Egor Bredikhin
    Egor Bredikhin

    ๐Ÿ› Elan P. Kugelmass
    Elan P. Kugelmass

    ๐Ÿ› Elder S.
    Elder S.

    ๐Ÿ› Eldrick Wega
    Eldrick Wega

    ๐Ÿ“– Emile
    Emile

    ๐Ÿ› Eric
    Eric

    ๐Ÿ› - Eric Kintzer
    Eric Kintzer

    ๐Ÿ› + Eric Kintzer
    Eric Kintzer

    ๐Ÿ› Eric Perret
    Eric Perret

    ๐Ÿ› Eric Squires
    Eric Squires

    ๐Ÿ› Erich L Foster
    Erich L Foster

    ๐Ÿ› Erik Bleske
    Erik Bleske

    ๐Ÿ› Erik C. Thauvin
    Erik C. Thauvin

    ๐Ÿ“– Ernst Reissner
    Ernst Reissner

    ๐Ÿ› - Ethan Sargent
    Ethan Sargent

    ๐Ÿ› + Ethan Sargent
    Ethan Sargent

    ๐Ÿ› Ewan Tempero
    Ewan Tempero

    ๐Ÿ› F.W. Dekker
    F.W. Dekker

    ๐Ÿ› FSchliephacke
    FSchliephacke

    ๐Ÿ› Facundo
    Facundo

    ๐Ÿ› Federico Giust
    Federico Giust

    ๐Ÿ› Fedor Sherstobitov
    Fedor Sherstobitov

    ๐Ÿ› - Felix Lampe
    Felix Lampe

    ๐Ÿ› + Felix Lampe
    Felix Lampe

    ๐Ÿ› Filip Golonka
    Filip Golonka

    ๐Ÿ› Filipe Esperandio
    Filipe Esperandio

    ๐Ÿ’ป ๐Ÿ› Filippo Nova
    Filippo Nova

    ๐Ÿ› Francesco la Torre
    Francesco la Torre

    ๐Ÿ› Francisco Duarte
    Francisco Duarte

    ๐Ÿ› Frieder Bluemle
    Frieder Bluemle

    ๐Ÿ› - Frits Jalvingh
    Frits Jalvingh

    ๐Ÿ’ป ๐Ÿ› + Frits Jalvingh
    Frits Jalvingh

    ๐Ÿ’ป ๐Ÿ› G. Bazior
    G. Bazior

    ๐Ÿ› Gabe Henkes
    Gabe Henkes

    ๐Ÿ› Gary Gregory
    Gary Gregory

    ๐Ÿ› Genoud Magloire
    Genoud Magloire

    ๐Ÿ› Geoffrey555
    Geoffrey555

    ๐Ÿ› Georg Romstorfer
    Georg Romstorfer

    ๐Ÿ› - Gili Tzabari
    Gili Tzabari

    ๐Ÿ› + Gili Tzabari
    Gili Tzabari

    ๐Ÿ› Gio
    Gio

    ๐Ÿ› Gol
    Gol

    ๐Ÿ› Gold856
    Gold856

    ๐Ÿ› ๐Ÿ’ป Gonzalo Exequiel Ibars Ingman
    Gonzalo Exequiel Ibars Ingman

    ๐Ÿ’ป ๐Ÿ› GooDer
    GooDer

    ๐Ÿ› Gregor Riegler
    Gregor Riegler

    ๐Ÿ› - Grzegorz Olszewski
    Grzegorz Olszewski

    ๐Ÿ› + Grzegorz Olszewski
    Grzegorz Olszewski

    ๐Ÿ› Gunther Schrijvers
    Gunther Schrijvers

    ๐Ÿ’ป ๐Ÿ› Gustavo Krieger
    Gustavo Krieger

    ๐Ÿ› Guy Elsmore-Paddock
    Guy Elsmore-Paddock

    ๐Ÿ› Gรถrkem Mรผlayim
    Gรถrkem Mรผlayim

    ๐Ÿ› Hanzel Godinez
    Hanzel Godinez

    ๐Ÿ› Haoliang Chen
    Haoliang Chen

    ๐Ÿ› - Harsh Kukreja
    Harsh Kukreja

    ๐Ÿ› + Harsh Kukreja
    Harsh Kukreja

    ๐Ÿ› Hassan ALAMI
    Hassan ALAMI

    ๐Ÿ› Heber
    Heber

    ๐Ÿ› Hector Miuler Malpica Gallegos
    Hector Miuler Malpica Gallegos

    ๐Ÿ› Henning Schmiedehausen
    Henning Schmiedehausen

    ๐Ÿ’ป ๐Ÿ› Henning von Bargen
    Henning von Bargen

    ๐Ÿ’ป Hervรฉ Boutemy
    Hervรฉ Boutemy

    ๐Ÿ› - Himanshu Pandey
    Himanshu Pandey

    ๐Ÿ› + Himanshu Pandey
    Himanshu Pandey

    ๐Ÿ› Hokwang Lee
    Hokwang Lee

    ๐Ÿ› Hooperbloob
    Hooperbloob

    ๐Ÿ’ป Hung PHAN
    Hung PHAN

    ๐Ÿ› IDoCodingStuffs
    IDoCodingStuffs

    ๐Ÿ’ป ๐Ÿ› Iccen Gan
    Iccen Gan

    ๐Ÿ› Ignacio Mariano Tirabasso
    Ignacio Mariano Tirabasso

    ๐Ÿ› - Igor Melnichenko
    Igor Melnichenko

    ๐Ÿ› + Igor Melnichenko
    Igor Melnichenko

    ๐Ÿ› Igor Moreno
    Igor Moreno

    ๐Ÿ› Intelesis-MS
    Intelesis-MS

    ๐Ÿ› Iroha_
    Iroha_

    ๐Ÿ› Ishan Srivastava
    Ishan Srivastava

    ๐Ÿ› Iskren Stanislavov
    Iskren Stanislavov

    ๐Ÿ› Ivan Vakhrushev
    Ivan Vakhrushev

    ๐Ÿ› - Ivano Guerini
    Ivano Guerini

    ๐Ÿ› + Ivano Guerini
    Ivano Guerini

    ๐Ÿ› Ivar Andreas Bonsaksen
    Ivar Andreas Bonsaksen

    ๐Ÿ› Ivo ล mรญd
    Ivo ล mรญd

    ๐Ÿ› JJengility
    JJengility

    ๐Ÿ› Jake Hemmerle
    Jake Hemmerle

    ๐Ÿ› Jakub Dupak
    Jakub Dupak

    ๐Ÿ’ป James Harrison
    James Harrison

    ๐Ÿ› ๐Ÿ’ป - Jamie Bisotti
    Jamie Bisotti

    ๐Ÿ› + Jamie Bisotti
    Jamie Bisotti

    ๐Ÿ› Jan
    Jan

    ๐Ÿ› Jan Aertgeerts
    Jan Aertgeerts

    ๐Ÿ’ป ๐Ÿ› Jan Brรผmmer
    Jan Brรผmmer

    ๐Ÿ› Jan Tล™รญska
    Jan Tล™รญska

    ๐Ÿ› Jan-Lukas Else
    Jan-Lukas Else

    ๐Ÿ› Jason Qiu
    Jason Qiu

    ๐Ÿ’ป ๐Ÿ“– - Jason Williams
    Jason Williams

    ๐Ÿ› + Jason Williams
    Jason Williams

    ๐Ÿ› Javier Spagnoletti
    Javier Spagnoletti

    ๐Ÿ› Jean-Paul Mayer
    Jean-Paul Mayer

    ๐Ÿ› Jean-Simon Larochelle
    Jean-Simon Larochelle

    ๐Ÿ› Jeff Bartolotta
    Jeff Bartolotta

    ๐Ÿ’ป ๐Ÿ› Jeff Hube
    Jeff Hube

    ๐Ÿ’ป ๐Ÿ› Jeff Jensen
    Jeff Jensen

    ๐Ÿ› - Jeff May
    Jeff May

    ๐Ÿ› + Jeff May
    Jeff May

    ๐Ÿ› Jens Gerdes
    Jens Gerdes

    ๐Ÿ› Jeroen Borgers
    Jeroen Borgers

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข Jeroen Meijer
    Jeroen Meijer

    ๐Ÿ› Jeroen van Wilgenburg
    Jeroen van Wilgenburg

    ๐Ÿ“– Jerome Russ
    Jerome Russ

    ๐Ÿ› JerritEic
    JerritEic

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› - Jiri Pejchal
    Jiri Pejchal

    ๐Ÿ› + Jiri Pejchal
    Jiri Pejchal

    ๐Ÿ› Jithin Sunny
    Jithin Sunny

    ๐Ÿ› Jiล™รญ ล korpil
    Jiล™รญ ล korpil

    ๐Ÿ› Joao Machado
    Joao Machado

    ๐Ÿ› Jochen Krauss
    Jochen Krauss

    ๐Ÿ› Johan Hammar
    Johan Hammar

    ๐Ÿ› John Jetmore
    John Jetmore

    ๐Ÿ“– - John Karp
    John Karp

    ๐Ÿ› + John Karp
    John Karp

    ๐Ÿ› John Zhang
    John Zhang

    ๐Ÿ› John-Teng
    John-Teng

    ๐Ÿ’ป ๐Ÿ› Jon Moroney
    Jon Moroney

    ๐Ÿ’ป ๐Ÿ› Jonas Geiregat
    Jonas Geiregat

    ๐Ÿ› Jonas KeรŸler
    Jonas KeรŸler

    ๐Ÿ› Jonathan Wiesel
    Jonathan Wiesel

    ๐Ÿ’ป ๐Ÿ› - Jordan
    Jordan

    ๐Ÿ› + Jordan
    Jordan

    ๐Ÿ› Jordi Llach
    Jordi Llach

    ๐Ÿ› Jorge Solรณrzano
    Jorge Solรณrzano

    ๐Ÿ› JorneVL
    JorneVL

    ๐Ÿ› Jose Palafox
    Jose Palafox

    ๐Ÿ› Jose Stovall
    Jose Stovall

    ๐Ÿ› Joseph
    Joseph

    ๐Ÿ’ป - Joseph Heenan
    Joseph Heenan

    ๐Ÿ› + Joseph Heenan
    Joseph Heenan

    ๐Ÿ› Josh Feingold
    Josh Feingold

    ๐Ÿ’ป ๐Ÿ› Josh Holthaus
    Josh Holthaus

    ๐Ÿ› Joshua S Arquilevich
    Joshua S Arquilevich

    ๐Ÿ› Joรฃo Dinis Ferreira
    Joรฃo Dinis Ferreira

    ๐Ÿ“– Joรฃo Ferreira
    Joรฃo Ferreira

    ๐Ÿ’ป ๐Ÿ› Joรฃo Pedro Schmitt
    Joรฃo Pedro Schmitt

    ๐Ÿ› - Juan Martรญn Sotuyo Dodero
    Juan Martรญn Sotuyo Dodero

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง + Juan Martรญn Sotuyo Dodero
    Juan Martรญn Sotuyo Dodero

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง Juan Pablo Civile
    Juan Pablo Civile

    ๐Ÿ› Julian Voronetsky
    Julian Voronetsky

    ๐Ÿ› Julien
    Julien

    ๐Ÿ› Julius
    Julius

    ๐Ÿ› JustPRV
    JustPRV

    ๐Ÿ› Justin Stroud
    Justin Stroud

    ๐Ÿ’ป - Jรถrn Huxhorn
    Jรถrn Huxhorn

    ๐Ÿ› + Jรถrn Huxhorn
    Jรถrn Huxhorn

    ๐Ÿ› KThompso
    KThompso

    ๐Ÿ› Kai Amundsen
    Kai Amundsen

    ๐Ÿ› Karel Vervaeke
    Karel Vervaeke

    ๐Ÿ› Karl-Andero Mere
    Karl-Andero Mere

    ๐Ÿ› Karl-Philipp Richter
    Karl-Philipp Richter

    ๐Ÿ› Karsten Silz
    Karsten Silz

    ๐Ÿ› - Kazuma Watanabe
    Kazuma Watanabe

    ๐Ÿ› + Kazuma Watanabe
    Kazuma Watanabe

    ๐Ÿ› Kev
    Kev

    ๐Ÿ› Keve Mรผller
    Keve Mรผller

    ๐Ÿ› Kevin Guerra
    Kevin Guerra

    ๐Ÿ’ป Kevin Jones
    Kevin Jones

    ๐Ÿ› ๐Ÿ’ป Kevin Poorman
    Kevin Poorman

    ๐Ÿ› Kevin Wayne
    Kevin Wayne

    ๐Ÿ› - Kieran Black
    Kieran Black

    ๐Ÿ› + Kieran Black
    Kieran Black

    ๐Ÿ› Kirill Zubov
    Kirill Zubov

    ๐Ÿ› Kirk Clemens
    Kirk Clemens

    ๐Ÿ’ป ๐Ÿ› Klaus Hartl
    Klaus Hartl

    ๐Ÿ› Koen Van Looveren
    Koen Van Looveren

    ๐Ÿ› Kris Scheibe
    Kris Scheibe

    ๐Ÿ’ป ๐Ÿ› Krystian Dabrowski
    Krystian Dabrowski

    ๐Ÿ› ๐Ÿ’ป - Krzysztof Dymek
    Krzysztof Dymek

    ๐Ÿ› + Krzysztof Dymek
    Krzysztof Dymek

    ๐Ÿ› Kunal Thanki
    Kunal Thanki

    ๐Ÿ› Kursat Aktas
    Kursat Aktas

    ๐Ÿ“– LaLucid
    LaLucid

    ๐Ÿ’ป Larry Diamond
    Larry Diamond

    ๐Ÿ’ป ๐Ÿ› Lars Knickrehm
    Lars Knickrehm

    ๐Ÿ› Laurent Bovet
    Laurent Bovet

    ๐Ÿ› ๐Ÿ’ป - Leo Gutierrez
    Leo Gutierrez

    ๐Ÿ› + Leo Gutierrez
    Leo Gutierrez

    ๐Ÿ› LiGaOg
    LiGaOg

    ๐Ÿ’ป Liam Sharp
    Liam Sharp

    ๐Ÿ› Lintsi
    Lintsi

    ๐Ÿ› Linus Fernandes
    Linus Fernandes

    ๐Ÿ› Lixon Lookose
    Lixon Lookose

    ๐Ÿ› Logesh
    Logesh

    ๐Ÿ› - Lorenzo Gabriele
    Lorenzo Gabriele

    ๐Ÿ› + Lorenzo Gabriele
    Lorenzo Gabriele

    ๐Ÿ› Loรฏc Ledoyen
    Loรฏc Ledoyen

    ๐Ÿ› Lucas
    Lucas

    ๐Ÿ› Lucas Silva
    Lucas Silva

    ๐Ÿ› Lucas Soncini
    Lucas Soncini

    ๐Ÿ’ป ๐Ÿ› Luis Alcantar
    Luis Alcantar

    ๐Ÿ’ป Lukas Grรคf
    Lukas Grรคf

    ๐Ÿ’ป - Lukasz Slonina
    Lukasz Slonina

    ๐Ÿ› + Lukasz Slonina
    Lukasz Slonina

    ๐Ÿ› Lukebray
    Lukebray

    ๐Ÿ› Lynn
    Lynn

    ๐Ÿ’ป ๐Ÿ› Lyor Goldstein
    Lyor Goldstein

    ๐Ÿ› MCMicS
    MCMicS

    ๐Ÿ› Macarse
    Macarse

    ๐Ÿ› Machine account for PMD
    Machine account for PMD

    ๐Ÿ’ป - Maciek Siemczyk
    Maciek Siemczyk

    ๐Ÿ› + Maciek Siemczyk
    Maciek Siemczyk

    ๐Ÿ› Maikel Steneker
    Maikel Steneker

    ๐Ÿ’ป ๐Ÿ› Maksim Moiseikin
    Maksim Moiseikin

    ๐Ÿ› Manfred Koch
    Manfred Koch

    ๐Ÿ› Manuel Moya Ferrer
    Manuel Moya Ferrer

    ๐Ÿ’ป ๐Ÿ› Manuel Romeiro
    Manuel Romeiro

    ๐Ÿ› Manuel Ryan
    Manuel Ryan

    ๐Ÿ› - Marat Vyshegorodtsev
    Marat Vyshegorodtsev

    ๐Ÿ› + Marat Vyshegorodtsev
    Marat Vyshegorodtsev

    ๐Ÿ› Marcel Hรคrle
    Marcel Hรคrle

    ๐Ÿ› Marcello Fialho
    Marcello Fialho

    ๐Ÿ› Marcin Dฤ…browski
    Marcin Dฤ…browski

    ๐Ÿ’ป Marcin Rataj
    Marcin Rataj

    ๐Ÿ› Marcono1234
    Marcono1234

    ๐Ÿ› Mark Adamcin
    Mark Adamcin

    ๐Ÿ› - Mark Hall
    Mark Hall

    ๐Ÿ’ป ๐Ÿ› + Mark Hall
    Mark Hall

    ๐Ÿ’ป ๐Ÿ› Mark Kolich
    Mark Kolich

    ๐Ÿ› Mark Pritchard
    Mark Pritchard

    ๐Ÿ› Markus Rathgeb
    Markus Rathgeb

    ๐Ÿ› Marquis Wang
    Marquis Wang

    ๐Ÿ› MartGit
    MartGit

    ๐Ÿ› Martin Feldsztejn
    Martin Feldsztejn

    ๐Ÿ› - Martin Lehmann
    Martin Lehmann

    ๐Ÿ› + Martin Lehmann
    Martin Lehmann

    ๐Ÿ› Martin Spamer
    Martin Spamer

    ๐Ÿ› Martin Tarjรกnyi
    Martin Tarjรกnyi

    ๐Ÿ› MatFl
    MatFl

    ๐Ÿ› Mateusz Stefanski
    Mateusz Stefanski

    ๐Ÿ› Mathias Lagerwall
    Mathias Lagerwall

    ๐Ÿ› Mathieu Gouin
    Mathieu Gouin

    ๐Ÿ› - MatiasComercio
    MatiasComercio

    ๐Ÿ’ป ๐Ÿ› + MatiasComercio
    MatiasComercio

    ๐Ÿ’ป ๐Ÿ› Matt Benson
    Matt Benson

    ๐Ÿ› Matt De Poorter
    Matt De Poorter

    ๐Ÿ› Matt Hargett
    Matt Hargett

    ๐Ÿ’ป ๐Ÿ’ต Matt Harrah
    Matt Harrah

    ๐Ÿ› Matt Nelson
    Matt Nelson

    ๐Ÿ› Matthew Amos
    Matthew Amos

    ๐Ÿ› - Matthew Duggan
    Matthew Duggan

    ๐Ÿ› + Matthew Duggan
    Matthew Duggan

    ๐Ÿ› Matthew Hall
    Matthew Hall

    ๐Ÿ› Matthew Rossner
    Matthew Rossner

    ๐Ÿ› Matรญas Fraga
    Matรญas Fraga

    ๐Ÿ’ป ๐Ÿ› Maxime Robert
    Maxime Robert

    ๐Ÿ’ป ๐Ÿ› MetaBF
    MetaBF

    ๐Ÿ› Metin Dagcilar
    Metin Dagcilar

    ๐Ÿ› - Michael
    Michael

    ๐Ÿ› + Michael
    Michael

    ๐Ÿ› Michael Bell
    Michael Bell

    ๐Ÿ› Michael Bernstein
    Michael Bernstein

    ๐Ÿ› Michael Clay
    Michael Clay

    ๐Ÿ› Michael Dombrowski
    Michael Dombrowski

    ๐Ÿ› Michael Hausegger
    Michael Hausegger

    ๐Ÿ› Michael Hoefer
    Michael Hoefer

    ๐Ÿ› - Michael Kolesnikov
    Michael Kolesnikov

    ๐Ÿ› + Michael Kolesnikov
    Michael Kolesnikov

    ๐Ÿ› Michael Mรถbius
    Michael Mรถbius

    ๐Ÿ› Michael N. Lipp
    Michael N. Lipp

    ๐Ÿ› Michael Pellegrini
    Michael Pellegrini

    ๐Ÿ› Michal Kordas
    Michal Kordas

    ๐Ÿ› Michaล‚ Borek
    Michaล‚ Borek

    ๐Ÿ› Michaล‚ Kuliล„ski
    Michaล‚ Kuliล„ski

    ๐Ÿ› - Miguel Nรบรฑez Dรญaz-Montes
    Miguel Nรบรฑez Dรญaz-Montes

    ๐Ÿ› + Miguel Nรบรฑez Dรญaz-Montes
    Miguel Nรบรฑez Dรญaz-Montes

    ๐Ÿ› Mihai Ionut
    Mihai Ionut

    ๐Ÿ› Mikhail Kuchma
    Mikhail Kuchma

    ๐Ÿ› Mirek Hankus
    Mirek Hankus

    ๐Ÿ› Mitch Spano
    Mitch Spano

    ๐Ÿ’ป ๐Ÿ› Mladjan Gadzic
    Mladjan Gadzic

    ๐Ÿ› Mladjan Gadzic
    Mladjan Gadzic

    ๐Ÿ› - MrAngry52
    MrAngry52

    ๐Ÿ› + MrAngry52
    MrAngry52

    ๐Ÿ› Muminur Choudhury
    Muminur Choudhury

    ๐Ÿ› Mykhailo Palahuta
    Mykhailo Palahuta

    ๐Ÿ’ป ๐Ÿ› Nagendra Kumar Singh
    Nagendra Kumar Singh

    ๐Ÿ› Nahuel Barrios
    Nahuel Barrios

    ๐Ÿ› Nakul Sharma
    Nakul Sharma

    ๐Ÿ› Nathan Braun
    Nathan Braun

    ๐Ÿ› - Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› + Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› Nathanaรซl
    Nathanaรซl

    ๐Ÿ› Naveen
    Naveen

    ๐Ÿ’ป Nazdravi
    Nazdravi

    ๐Ÿ› Neha-Dhonde
    Neha-Dhonde

    ๐Ÿ› Nicholas Doyle
    Nicholas Doyle

    ๐Ÿ› - Nick Butcher
    Nick Butcher

    ๐Ÿ› + Nick Butcher
    Nick Butcher

    ๐Ÿ› Nico Gallinal
    Nico Gallinal

    ๐Ÿ› Nicola Dal Maso
    Nicola Dal Maso

    ๐Ÿ› Nicolas Filotto
    Nicolas Filotto

    ๐Ÿ’ป Nicolas Vervelle
    Nicolas Vervelle

    ๐Ÿ› Nicolas Vuillamy
    Nicolas Vuillamy

    ๐Ÿ“– Nikita Chursin
    Nikita Chursin

    ๐Ÿ› - Niklas Baudy
    Niklas Baudy

    ๐Ÿ› + Niklas Baudy
    Niklas Baudy

    ๐Ÿ› Nikolas Havrikov
    Nikolas Havrikov

    ๐Ÿ› Nilesh Virkar
    Nilesh Virkar

    ๐Ÿ› Nimit Patel
    Nimit Patel

    ๐Ÿ› Niranjan Harpale
    Niranjan Harpale

    ๐Ÿ› Nirvik Patel
    Nirvik Patel

    ๐Ÿ’ป Noah Sussman
    Noah Sussman

    ๐Ÿ› - Noah0120
    Noah0120

    ๐Ÿ› + Noah0120
    Noah0120

    ๐Ÿ› Noam Tamim
    Noam Tamim

    ๐Ÿ› Noel Grandin
    Noel Grandin

    ๐Ÿ› Olaf Haalstra
    Olaf Haalstra

    ๐Ÿ› Oleg Andreych
    Oleg Andreych

    ๐Ÿ’ป ๐Ÿ› Oleg Pavlenko
    Oleg Pavlenko

    ๐Ÿ› Oleksii Dykov
    Oleksii Dykov

    ๐Ÿ’ป ๐Ÿ› - Oliver Eikemeier
    Oliver Eikemeier

    ๐Ÿ› + Oliver Eikemeier
    Oliver Eikemeier

    ๐Ÿ› Oliver Siegmar
    Oliver Siegmar

    ๐Ÿ’ต Olivier Parent
    Olivier Parent

    ๐Ÿ’ป ๐Ÿ› Ollie Abbey
    Ollie Abbey

    ๐Ÿ’ป ๐Ÿ› Olof-Joachim Frahm (ๆฌง้›…็ฆ)
    Olof-Joachim Frahm (ๆฌง้›…็ฆ)

    ๐Ÿ› Ondrej Kratochvil
    Ondrej Kratochvil

    ๐Ÿ› OverDrone
    OverDrone

    ๐Ÿ› - Ozan Gulle
    Ozan Gulle

    ๐Ÿ’ป ๐Ÿ› + Ozan Gulle
    Ozan Gulle

    ๐Ÿ’ป ๐Ÿ› PUNEET JAIN
    PUNEET JAIN

    ๐Ÿ› Parbati Bose
    Parbati Bose

    ๐Ÿ› Paul Berg
    Paul Berg

    ๐Ÿ› Paul Guyot
    Paul Guyot

    ๐Ÿ’ป Pavel Bludov
    Pavel Bludov

    ๐Ÿ› Pavel Miฤka
    Pavel Miฤka

    ๐Ÿ› - Pedro Nuno Santos
    Pedro Nuno Santos

    ๐Ÿ› + Pedro Nuno Santos
    Pedro Nuno Santos

    ๐Ÿ› Pedro Rijo
    Pedro Rijo

    ๐Ÿ› Pelisse Romain
    Pelisse Romain

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Per Abich
    Per Abich

    ๐Ÿ’ป Pete Davids
    Pete Davids

    ๐Ÿ› Peter Bruin
    Peter Bruin

    ๐Ÿ› Peter Chittum
    Peter Chittum

    ๐Ÿ’ป ๐Ÿ› - Peter Cudmore
    Peter Cudmore

    ๐Ÿ› + Peter Cudmore
    Peter Cudmore

    ๐Ÿ› Peter Kasson
    Peter Kasson

    ๐Ÿ› Peter Kofler
    Peter Kofler

    ๐Ÿ› Peter Paul Bakker
    Peter Paul Bakker

    ๐Ÿ’ป ๐Ÿ› Peter Rader
    Peter Rader

    ๐Ÿ› Pham Hai Trung
    Pham Hai Trung

    ๐Ÿ› Philip Graf
    Philip Graf

    ๐Ÿ’ป ๐Ÿ› - Philip Hachey
    Philip Hachey

    ๐Ÿ› + Philip Hachey
    Philip Hachey

    ๐Ÿ› Philippe Ozil
    Philippe Ozil

    ๐Ÿ› Phinehas Artemix
    Phinehas Artemix

    ๐Ÿ› Phokham Nonava
    Phokham Nonava

    ๐Ÿ› Pim van der Loos
    Pim van der Loos

    ๐Ÿ’ป โš ๏ธ Piotr Szymaล„ski
    Piotr Szymaล„ski

    ๐Ÿ› Piotrek ลปygieล‚o
    Piotrek ลปygieล‚o

    ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– - Pranay Jaiswal
    Pranay Jaiswal

    ๐Ÿ› + Pranay Jaiswal
    Pranay Jaiswal

    ๐Ÿ› Prasad Kamath
    Prasad Kamath

    ๐Ÿ› Prasanna
    Prasanna

    ๐Ÿ› Presh-AR
    Presh-AR

    ๐Ÿ› Puneet1726
    Puneet1726

    ๐Ÿ› RBRi
    RBRi

    ๐Ÿ› Rafael Cortรชs
    Rafael Cortรชs

    ๐Ÿ› - RaheemShaik999
    RaheemShaik999

    ๐Ÿ› + RaheemShaik999
    RaheemShaik999

    ๐Ÿ› RajeshR
    RajeshR

    ๐Ÿ’ป ๐Ÿ› Ramachandra Mohan
    Ramachandra Mohan

    ๐Ÿ› Ramel0921
    Ramel0921

    ๐Ÿ› Raquel Pau
    Raquel Pau

    ๐Ÿ› Ravikiran Janardhana
    Ravikiran Janardhana

    ๐Ÿ› Reda Benhemmouche
    Reda Benhemmouche

    ๐Ÿ› - Reinhard Schiedermeier
    Reinhard Schiedermeier

    ๐Ÿ› + Reinhard Schiedermeier
    Reinhard Schiedermeier

    ๐Ÿ› Renato Oliveira
    Renato Oliveira

    ๐Ÿ’ป ๐Ÿ› Rich DiCroce
    Rich DiCroce

    ๐Ÿ› Richard Corfield
    Richard Corfield

    ๐Ÿ’ป Richard Corfield
    Richard Corfield

    ๐Ÿ› ๐Ÿ’ป Riot R1cket
    Riot R1cket

    ๐Ÿ› Rishabh Jain
    Rishabh Jain

    ๐Ÿ› - RishabhDeep Singh
    RishabhDeep Singh

    ๐Ÿ› + RishabhDeep Singh
    RishabhDeep Singh

    ๐Ÿ› Rob Baillie
    Rob Baillie

    ๐Ÿ› Robbie Martinus
    Robbie Martinus

    ๐Ÿ’ป ๐Ÿ› Robert Henry
    Robert Henry

    ๐Ÿ› Robert Mihaly
    Robert Mihaly

    ๐Ÿ› Robert Painsi
    Robert Painsi

    ๐Ÿ› Robert Russell
    Robert Russell

    ๐Ÿ› - Robert Sรถsemann
    Robert Sรถsemann

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ› + Robert Sรถsemann
    Robert Sรถsemann

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ› Robert Whitebit
    Robert Whitebit

    ๐Ÿ› Robin Richtsfeld
    Robin Richtsfeld

    ๐Ÿ› Robin Stocker
    Robin Stocker

    ๐Ÿ’ป ๐Ÿ› Robin Wils
    Robin Wils

    ๐Ÿ› RochusOest
    RochusOest

    ๐Ÿ› Rodolfo Noviski
    Rodolfo Noviski

    ๐Ÿ› - Rodrigo Casara
    Rodrigo Casara

    ๐Ÿ› + Rodrigo Casara
    Rodrigo Casara

    ๐Ÿ› Rodrigo Fernandes
    Rodrigo Fernandes

    ๐Ÿ› Roman Salvador
    Roman Salvador

    ๐Ÿ’ป ๐Ÿ› Ronald Blaschke
    Ronald Blaschke

    ๐Ÿ› Rรณbert Papp
    Rรณbert Papp

    ๐Ÿ› Saikat Sengupta
    Saikat Sengupta

    ๐Ÿ› Saksham Handu
    Saksham Handu

    ๐Ÿ› - Saladoc
    Saladoc

    ๐Ÿ› + Saladoc
    Saladoc

    ๐Ÿ› Salesforce Bob Lightning
    Salesforce Bob Lightning

    ๐Ÿ› Sam Carlberg
    Sam Carlberg

    ๐Ÿ› Sascha Riemer
    Sascha Riemer

    ๐Ÿ› Sashko
    Sashko

    ๐Ÿ’ป Satoshi Kubo
    Satoshi Kubo

    ๐Ÿ› Scott Kennedy
    Scott Kennedy

    ๐Ÿ› - Scott Wells
    Scott Wells

    ๐Ÿ› ๐Ÿ’ป + Scott Wells
    Scott Wells

    ๐Ÿ› ๐Ÿ’ป Scrates1
    Scrates1

    ๐Ÿ› ๐Ÿ’ป Scrsloota
    Scrsloota

    ๐Ÿ’ป Sebastian Bรถgl
    Sebastian Bรถgl

    ๐Ÿ› Sebastian Davids
    Sebastian Davids

    ๐Ÿ› Sebastian Lรถvdahl
    Sebastian Lรถvdahl

    ๐Ÿ› Sebastian Schuberth
    Sebastian Schuberth

    ๐Ÿ› - Sebastian Schwarz
    Sebastian Schwarz

    ๐Ÿ› + Sebastian Schwarz
    Sebastian Schwarz

    ๐Ÿ› Seren
    Seren

    ๐Ÿ› ๐Ÿ’ป Sergey Gorbaty
    Sergey Gorbaty

    ๐Ÿ› Sergey Kozlov
    Sergey Kozlov

    ๐Ÿ› Sergey Yanzin
    Sergey Yanzin

    ๐Ÿ’ป ๐Ÿ› Seth Wilcox
    Seth Wilcox

    ๐Ÿ’ป Shai Bennathan
    Shai Bennathan

    ๐Ÿ› ๐Ÿ’ป - Shubham
    Shubham

    ๐Ÿ’ป ๐Ÿ› + Shubham
    Shubham

    ๐Ÿ’ป ๐Ÿ› Simon Abykov
    Simon Abykov

    ๐Ÿ’ป ๐Ÿ› Simon Xiao
    Simon Xiao

    ๐Ÿ› Srinivasan Venkatachalam
    Srinivasan Venkatachalam

    ๐Ÿ› Stanislav Gromov
    Stanislav Gromov

    ๐Ÿ› Stanislav Myachenkov
    Stanislav Myachenkov

    ๐Ÿ’ป Stefan Birkner
    Stefan Birkner

    ๐Ÿ› - Stefan Bohn
    Stefan Bohn

    ๐Ÿ› + Stefan Bohn
    Stefan Bohn

    ๐Ÿ› Stefan Endrullis
    Stefan Endrullis

    ๐Ÿ› Stefan Klรถss-Schuster
    Stefan Klรถss-Schuster

    ๐Ÿ› Stefan Wolf
    Stefan Wolf

    ๐Ÿ› Stephan H. Wissel
    Stephan H. Wissel

    ๐Ÿ› Stephen
    Stephen

    ๐Ÿ› Stephen Carter
    Stephen Carter

    ๐Ÿ› - Stephen Friedrich
    Stephen Friedrich

    ๐Ÿ› + Stephen Friedrich
    Stephen Friedrich

    ๐Ÿ› Steve Babula
    Steve Babula

    ๐Ÿ’ป Steven Stearns
    Steven Stearns

    ๐Ÿ› ๐Ÿ’ป Stexxe
    Stexxe

    ๐Ÿ› Stian Lรฅgstad
    Stian Lรฅgstad

    ๐Ÿ› StuartClayton5
    StuartClayton5

    ๐Ÿ› Supun Arunoda
    Supun Arunoda

    ๐Ÿ› - Suren Abrahamyan
    Suren Abrahamyan

    ๐Ÿ› + Suren Abrahamyan
    Suren Abrahamyan

    ๐Ÿ› Suvashri
    Suvashri

    ๐Ÿ“– Sven Barden
    Sven Barden

    ๐Ÿ› SwatiBGupta1110
    SwatiBGupta1110

    ๐Ÿ› SyedThoufich
    SyedThoufich

    ๐Ÿ› Szymon Sasin
    Szymon Sasin

    ๐Ÿ› T-chuangxin
    T-chuangxin

    ๐Ÿ› - TERAI Atsuhiro
    TERAI Atsuhiro

    ๐Ÿ› + TERAI Atsuhiro
    TERAI Atsuhiro

    ๐Ÿ› TIOBE Software
    TIOBE Software

    ๐Ÿ’ป ๐Ÿ› Tarush Singh
    Tarush Singh

    ๐Ÿ’ป Taylor Smock
    Taylor Smock

    ๐Ÿ› Techeira Damiรกn
    Techeira Damiรกn

    ๐Ÿ’ป ๐Ÿ› Ted Husted
    Ted Husted

    ๐Ÿ› TehBakker
    TehBakker

    ๐Ÿ› - The Gitter Badger
    The Gitter Badger

    ๐Ÿ› + The Gitter Badger
    The Gitter Badger

    ๐Ÿ› Theodoor
    Theodoor

    ๐Ÿ› Thiago Henrique Hรผpner
    Thiago Henrique Hรผpner

    ๐Ÿ› Thibault Meyer
    Thibault Meyer

    ๐Ÿ› Thomas Gรผttler
    Thomas Gรผttler

    ๐Ÿ› Thomas Jones-Low
    Thomas Jones-Low

    ๐Ÿ› Thomas Smith
    Thomas Smith

    ๐Ÿ’ป ๐Ÿ› - ThrawnCA
    ThrawnCA

    ๐Ÿ› + ThrawnCA
    ThrawnCA

    ๐Ÿ› Thu Vo
    Thu Vo

    ๐Ÿ› Thunderforge
    Thunderforge

    ๐Ÿ’ป ๐Ÿ› Tim van der Lippe
    Tim van der Lippe

    ๐Ÿ› Tobias Weimer
    Tobias Weimer

    ๐Ÿ’ป ๐Ÿ› Tom Copeland
    Tom Copeland

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– Tom Daly
    Tom Daly

    ๐Ÿ› - Tomas
    Tomas

    ๐Ÿ› + Tomas
    Tomas

    ๐Ÿ› Tomer Figenblat
    Tomer Figenblat

    ๐Ÿ› Tomi De Lucca
    Tomi De Lucca

    ๐Ÿ’ป ๐Ÿ› Tony
    Tony

    ๐Ÿ“– Torsten Kleiber
    Torsten Kleiber

    ๐Ÿ› Torsten Krause
    Torsten Krause

    ๐Ÿ› TrackerSB
    TrackerSB

    ๐Ÿ› - Tyson Stewart
    Tyson Stewart

    ๐Ÿ› + Tyson Stewart
    Tyson Stewart

    ๐Ÿ› Ullrich Hafner
    Ullrich Hafner

    ๐Ÿ› Utku Cuhadaroglu
    Utku Cuhadaroglu

    ๐Ÿ’ป ๐Ÿ› Valentin Brandl
    Valentin Brandl

    ๐Ÿ› Valeria
    Valeria

    ๐Ÿ› Valery Yatsynovich
    Valery Yatsynovich

    ๐Ÿ“– Vasily Anisimov
    Vasily Anisimov

    ๐Ÿ› - Vedant Chokshi
    Vedant Chokshi

    ๐Ÿ› + Vedant Chokshi
    Vedant Chokshi

    ๐Ÿ› Vibhor Goyal
    Vibhor Goyal

    ๐Ÿ› Vickenty Fesunov
    Vickenty Fesunov

    ๐Ÿ› Victor Noรซl
    Victor Noรซl

    ๐Ÿ› Vincent Galloy
    Vincent Galloy

    ๐Ÿ’ป Vincent HUYNH
    Vincent HUYNH

    ๐Ÿ› Vincent Maurin
    Vincent Maurin

    ๐Ÿ› - Vincent Potucek
    Vincent Potucek

    ๐Ÿ’ป + Vincent Potucek
    Vincent Potucek

    ๐Ÿ’ป Vincent Privat
    Vincent Privat

    ๐Ÿ› Vishhwas
    Vishhwas

    ๐Ÿ› Vishv_Android
    Vishv_Android

    ๐Ÿ› Vitalii Yevtushenko
    Vitalii Yevtushenko

    ๐Ÿ› Vitaly
    Vitaly

    ๐Ÿ› Vitaly Polonetsky
    Vitaly Polonetsky

    ๐Ÿ› - Vojtech Polivka
    Vojtech Polivka

    ๐Ÿ› + Vojtech Polivka
    Vojtech Polivka

    ๐Ÿ› Vsevolod Zholobov
    Vsevolod Zholobov

    ๐Ÿ› Vyom Yadav
    Vyom Yadav

    ๐Ÿ’ป Wang Shidong
    Wang Shidong

    ๐Ÿ› Waqas Ahmed
    Waqas Ahmed

    ๐Ÿ› Wayne J. Earl
    Wayne J. Earl

    ๐Ÿ› Wchenghui
    Wchenghui

    ๐Ÿ› - Wener
    Wener

    ๐Ÿ’ป + Wener
    Wener

    ๐Ÿ’ป Will Winder
    Will Winder

    ๐Ÿ› Willem A. Hajenius
    Willem A. Hajenius

    ๐Ÿ’ป William Brockhus
    William Brockhus

    ๐Ÿ’ป ๐Ÿ› Wilson Kurniawan
    Wilson Kurniawan

    ๐Ÿ› Wim Deblauwe
    Wim Deblauwe

    ๐Ÿ› Wolf2323
    Wolf2323

    ๐Ÿ› - Woongsik Choi
    Woongsik Choi

    ๐Ÿ› + Woongsik Choi
    Woongsik Choi

    ๐Ÿ› XenoAmess
    XenoAmess

    ๐Ÿ’ป ๐Ÿ› Yang
    Yang

    ๐Ÿ’ป YaroslavTER
    YaroslavTER

    ๐Ÿ› Yasar Shaikh
    Yasar Shaikh

    ๐Ÿ’ป Young Chan
    Young Chan

    ๐Ÿ’ป ๐Ÿ› YuJin Kim
    YuJin Kim

    ๐Ÿ› - Yuri Dolzhenko
    Yuri Dolzhenko

    ๐Ÿ› + Yuri Dolzhenko
    Yuri Dolzhenko

    ๐Ÿ› Yurii Dubinka
    Yurii Dubinka

    ๐Ÿ› Zoltan Farkas
    Zoltan Farkas

    ๐Ÿ› Zustin
    Zustin

    ๐Ÿ› aaronhurst-google
    aaronhurst-google

    ๐Ÿ› ๐Ÿ’ป alexmodis
    alexmodis

    ๐Ÿ› andreoss
    andreoss

    ๐Ÿ› - andrey81inmd
    andrey81inmd

    ๐Ÿ’ป ๐Ÿ› + andrey81inmd
    andrey81inmd

    ๐Ÿ’ป ๐Ÿ› anicoara
    anicoara

    ๐Ÿ› arunprasathav
    arunprasathav

    ๐Ÿ› asiercamara
    asiercamara

    ๐Ÿ› astillich-igniti
    astillich-igniti

    ๐Ÿ’ป avesolovksyy
    avesolovksyy

    ๐Ÿ› avishvat
    avishvat

    ๐Ÿ› - avivmu
    avivmu

    ๐Ÿ› + avivmu
    avivmu

    ๐Ÿ› axelbarfod1
    axelbarfod1

    ๐Ÿ› b-3-n
    b-3-n

    ๐Ÿ› balbhadra9
    balbhadra9

    ๐Ÿ› base23de
    base23de

    ๐Ÿ› bergander
    bergander

    ๐Ÿ› ๐Ÿ’ป berkam
    berkam

    ๐Ÿ’ป ๐Ÿ› - breizh31
    breizh31

    ๐Ÿ› + breizh31
    breizh31

    ๐Ÿ› caesarkim
    caesarkim

    ๐Ÿ› caiocarvalhotero
    caiocarvalhotero

    ๐Ÿ› carolyujing
    carolyujing

    ๐Ÿ› cbfiddle
    cbfiddle

    ๐Ÿ› cesares-basilico
    cesares-basilico

    ๐Ÿ› chrite
    chrite

    ๐Ÿ› - ciufudean
    ciufudean

    ๐Ÿ“– + ciufudean
    ciufudean

    ๐Ÿ“– cobratbq
    cobratbq

    ๐Ÿ› coladict
    coladict

    ๐Ÿ› cosmoJFH
    cosmoJFH

    ๐Ÿ› cristalp
    cristalp

    ๐Ÿ› crunsk
    crunsk

    ๐Ÿ› cwholmes
    cwholmes

    ๐Ÿ› - cyberjj999
    cyberjj999

    ๐Ÿ› + cyberjj999
    cyberjj999

    ๐Ÿ› cyw3
    cyw3

    ๐Ÿ› ๐Ÿ“– d1ss0nanz
    d1ss0nanz

    ๐Ÿ› dague1
    dague1

    ๐Ÿ“– dalizi007
    dalizi007

    ๐Ÿ’ป danbrycefairsailcom
    danbrycefairsailcom

    ๐Ÿ› dariansanity
    dariansanity

    ๐Ÿ› - darrenmiliband
    darrenmiliband

    ๐Ÿ› + darrenmiliband
    darrenmiliband

    ๐Ÿ› davidburstrom
    davidburstrom

    ๐Ÿ› dbirkman-paloalto
    dbirkman-paloalto

    ๐Ÿ› deepak-patra
    deepak-patra

    ๐Ÿ› dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› dinesh150
    dinesh150

    ๐Ÿ› diziaq
    diziaq

    ๐Ÿ› - dreaminpast123
    dreaminpast123

    ๐Ÿ› + dreaminpast123
    dreaminpast123

    ๐Ÿ› duanyanan
    duanyanan

    ๐Ÿ› dutt-sanjay
    dutt-sanjay

    ๐Ÿ› duursma
    duursma

    ๐Ÿ’ป dylanleung
    dylanleung

    ๐Ÿ› dzeigler
    dzeigler

    ๐Ÿ› eant60
    eant60

    ๐Ÿ› - ekkirala
    ekkirala

    ๐Ÿ› + ekkirala
    ekkirala

    ๐Ÿ› emersonmoura
    emersonmoura

    ๐Ÿ› emouty
    emouty

    ๐Ÿ’ป ๐Ÿ› eugenepugach
    eugenepugach

    ๐Ÿ› fairy
    fairy

    ๐Ÿ› filiprafalowicz
    filiprafalowicz

    ๐Ÿ’ป flxbl-io
    flxbl-io

    ๐Ÿ’ต - foxmason
    foxmason

    ๐Ÿ› + foxmason
    foxmason

    ๐Ÿ› frankegabor
    frankegabor

    ๐Ÿ› frankl
    frankl

    ๐Ÿ› freafrea
    freafrea

    ๐Ÿ› fsapatin
    fsapatin

    ๐Ÿ› gearsethenry
    gearsethenry

    ๐Ÿ› gracia19
    gracia19

    ๐Ÿ› - gudzpoz
    gudzpoz

    ๐Ÿ› + gudzpoz
    gudzpoz

    ๐Ÿ› guo fei
    guo fei

    ๐Ÿ› gurmsc5
    gurmsc5

    ๐Ÿ› gwilymatgearset
    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ› haigsn
    haigsn

    ๐Ÿ› hemanshu070
    hemanshu070

    ๐Ÿ› henrik242
    henrik242

    ๐Ÿ› - hongpuwu
    hongpuwu

    ๐Ÿ› + hongpuwu
    hongpuwu

    ๐Ÿ› hvbtup
    hvbtup

    ๐Ÿ’ป ๐Ÿ› igniti GmbH
    igniti GmbH

    ๐Ÿ› ilovezfs
    ilovezfs

    ๐Ÿ› imax-erik
    imax-erik

    ๐Ÿ› itaigilo
    itaigilo

    ๐Ÿ› jakivey32
    jakivey32

    ๐Ÿ› - jbennett2091
    jbennett2091

    ๐Ÿ› + jbennett2091
    jbennett2091

    ๐Ÿ› jcamerin
    jcamerin

    ๐Ÿ› jkeener1
    jkeener1

    ๐Ÿ› jmetertea
    jmetertea

    ๐Ÿ› johnra2
    johnra2

    ๐Ÿ’ป johnzhao9
    johnzhao9

    ๐Ÿ› josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ› - kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ› + kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ› karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“– karwer
    karwer

    ๐Ÿ› kaulonline
    kaulonline

    ๐Ÿ› kdaemonv
    kdaemonv

    ๐Ÿ› kdebski85
    kdebski85

    ๐Ÿ› ๐Ÿ’ป kenji21
    kenji21

    ๐Ÿ’ป ๐Ÿ› - kfranic
    kfranic

    ๐Ÿ› + kfranic
    kfranic

    ๐Ÿ› khalidkh
    khalidkh

    ๐Ÿ› koalalam
    koalalam

    ๐Ÿ› krzyk
    krzyk

    ๐Ÿ› lasselindqvist
    lasselindqvist

    ๐Ÿ› lgemeinhardt
    lgemeinhardt

    ๐Ÿ› lihuaib
    lihuaib

    ๐Ÿ› - liqingjun123
    liqingjun123

    ๐Ÿ› + liqingjun123
    liqingjun123

    ๐Ÿ› lonelyma1021
    lonelyma1021

    ๐Ÿ› lpeddy
    lpeddy

    ๐Ÿ› lujiefsi
    lujiefsi

    ๐Ÿ’ป lukelukes
    lukelukes

    ๐Ÿ’ป lyriccoder
    lyriccoder

    ๐Ÿ› marcelmore
    marcelmore

    ๐Ÿ› - matchbox
    matchbox

    ๐Ÿ› + matchbox
    matchbox

    ๐Ÿ› matthiaskraaz
    matthiaskraaz

    ๐Ÿ› meandonlyme
    meandonlyme

    ๐Ÿ› mikesive
    mikesive

    ๐Ÿ› milossesic
    milossesic

    ๐Ÿ› mluckam
    mluckam

    ๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
    mohan-chinnappan-n

    ๐Ÿ’ป - mriddell95
    mriddell95

    ๐Ÿ› + mriddell95
    mriddell95

    ๐Ÿ› mrlzh
    mrlzh

    ๐Ÿ› msloan
    msloan

    ๐Ÿ› mucharlaravalika
    mucharlaravalika

    ๐Ÿ› mvenneman
    mvenneman

    ๐Ÿ› nareshl119
    nareshl119

    ๐Ÿ› nicolas-harraudeau-sonarsource
    nicolas-harraudeau-sonarsource

    ๐Ÿ› - noerremark
    noerremark

    ๐Ÿ› + noerremark
    noerremark

    ๐Ÿ› novsirion
    novsirion

    ๐Ÿ› nwcm
    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
    oggboy

    ๐Ÿ› oinume
    oinume

    ๐Ÿ› orimarko
    orimarko

    ๐Ÿ’ป ๐Ÿ› pablogomez2197
    pablogomez2197

    ๐Ÿ› - pacvz
    pacvz

    ๐Ÿ’ป + pacvz
    pacvz

    ๐Ÿ’ป pallavi agarwal
    pallavi agarwal

    ๐Ÿ› pankratz76
    pankratz76

    ๐Ÿ› parksungrin
    parksungrin

    ๐Ÿ› patpatpat123
    patpatpat123

    ๐Ÿ› patriksevallius
    patriksevallius

    ๐Ÿ› pbrajesh1
    pbrajesh1

    ๐Ÿ› - phoenix384
    phoenix384

    ๐Ÿ› + phoenix384
    phoenix384

    ๐Ÿ› piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป plan3d
    plan3d

    ๐Ÿ› poojasix
    poojasix

    ๐Ÿ› prabhushrikant
    prabhushrikant

    ๐Ÿ› pujitha8783
    pujitha8783

    ๐Ÿ› r-r-a-j
    r-r-a-j

    ๐Ÿ› - raghujayjunk
    raghujayjunk

    ๐Ÿ› + raghujayjunk
    raghujayjunk

    ๐Ÿ› rajeshveera
    rajeshveera

    ๐Ÿ› rajeswarreddy88
    rajeswarreddy88

    ๐Ÿ› recdevs
    recdevs

    ๐Ÿ› reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ› rijkt
    rijkt

    ๐Ÿ› rillig-tk
    rillig-tk

    ๐Ÿ› - rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ› + rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ› rnveach
    rnveach

    ๐Ÿ› rxmicro
    rxmicro

    ๐Ÿ› ryan-gustafson
    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ› sabi0
    sabi0

    ๐Ÿ› samc-gearset
    samc-gearset

    ๐Ÿ“– scais
    scais

    ๐Ÿ› - schosin
    schosin

    ๐Ÿ› + schosin
    schosin

    ๐Ÿ› screamingfrog
    screamingfrog

    ๐Ÿ’ต sebbASF
    sebbASF

    ๐Ÿ› sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป shilko2013
    shilko2013

    ๐Ÿ› shiomiyan
    shiomiyan

    ๐Ÿ“– simeonKondr
    simeonKondr

    ๐Ÿ› - snajberk
    snajberk

    ๐Ÿ› + snajberk
    snajberk

    ๐Ÿ› sniperrifle2004
    sniperrifle2004

    ๐Ÿ› snuyanzin
    snuyanzin

    ๐Ÿ› ๐Ÿ’ป soloturn
    soloturn

    ๐Ÿ› soyodream
    soyodream

    ๐Ÿ› sratz
    sratz

    ๐Ÿ› stonio
    stonio

    ๐Ÿ› - sturton
    sturton

    ๐Ÿ’ป ๐Ÿ› + sturton
    sturton

    ๐Ÿ’ป ๐Ÿ› sudharmohan
    sudharmohan

    ๐Ÿ› suruchidawar
    suruchidawar

    ๐Ÿ› svenfinitiv
    svenfinitiv

    ๐Ÿ› szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป tashiscool
    tashiscool

    ๐Ÿ› test-git-hook
    test-git-hook

    ๐Ÿ› - testation21
    testation21

    ๐Ÿ’ป ๐Ÿ› + testation21
    testation21

    ๐Ÿ’ป ๐Ÿ› thanosa
    thanosa

    ๐Ÿ› tiandiyixian
    tiandiyixian

    ๐Ÿ› tobwoerk
    tobwoerk

    ๐Ÿ› tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป trentchilders
    trentchilders

    ๐Ÿ› triandicAnt
    triandicAnt

    ๐Ÿ› - trishul14
    trishul14

    ๐Ÿ› + trishul14
    trishul14

    ๐Ÿ› tsui
    tsui

    ๐Ÿ› wangzitom12306
    wangzitom12306

    ๐Ÿ› winhkey
    winhkey

    ๐Ÿ› witherspore
    witherspore

    ๐Ÿ› wjljack
    wjljack

    ๐Ÿ› wuchiuwong
    wuchiuwong

    ๐Ÿ› - xingsong
    xingsong

    ๐Ÿ› + xingsong
    xingsong

    ๐Ÿ› xioayuge
    xioayuge

    ๐Ÿ› xnYi9wRezm
    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ› xuanuy
    xuanuy

    ๐Ÿ› xyf0921
    xyf0921

    ๐Ÿ› yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› yasuharu-sato
    yasuharu-sato

    ๐Ÿ› - zenglian
    zenglian

    ๐Ÿ› + zenglian
    zenglian

    ๐Ÿ› zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› zh3ng
    zh3ng

    ๐Ÿ› zt_soft
    zt_soft

    ๐Ÿ› ztt79
    ztt79

    ๐Ÿ› zzzzfeng
    zzzzfeng

    ๐Ÿ› รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› - ไปป่ดตๆฐ
    ไปป่ดตๆฐ

    ๐Ÿ› + ไปป่ดตๆฐ
    ไปป่ดตๆฐ

    ๐Ÿ› ๅคฉ็ƒญๅƒ่ฅฟ็“œ
    ๅคฉ็ƒญๅƒ่ฅฟ็“œ

    ๐Ÿ› ่Œ…ๅปถๅฎ‰
    ่Œ…ๅปถๅฎ‰

    ๐Ÿ’ป From f27a15e40ce65ba93fcd981068a5b87b8cd0e43a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 22 Apr 2025 20:00:57 +0200 Subject: [PATCH 0814/1962] [doc] Update release notes (#5685) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 33e9a3f172c..91bd322b309 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -34,6 +34,7 @@ This is a {{ site.pmd.release_type }} release. * [#5450](https://github.com/pmd/pmd/pull/5450): Fix #3184: \[apex] New Rule: TypeShadowsBuiltInNamespace - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) * [#5672](https://github.com/pmd/pmd/pull/5672): \[doc] Fix its/it's and doable/double typos - [John Jetmore](https://github.com/jetmore) (@jetmore) +* [#5685](https://github.com/pmd/pmd/pull/5685): \[doc] typo fix in PMD Designer reference - [Douglas Griffith](https://github.com/dwgrth) (@dwgrth) ### ๐Ÿ“ฆ Dependency updates From 64a693779f00040e91818f233353b3f67345f3e5 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 22 Apr 2025 20:07:58 +0200 Subject: [PATCH 0815/1962] [java] UnusedPrivateMethod - add test for readObjectNoData --- .../rule/bestpractices/xml/UnusedPrivateMethod.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index d36b402fce4..333d0b8d18e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2605,6 +2605,17 @@ class Foo { System.out.println(a); } } +]]> + + + + #5687 [java] UnusedPrivateMethodRule: exclude serialization method readObjectNoData() + 0 + From 3a8acc9acd45e1eb20f87658e9f988aa8494827a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 22 Apr 2025 20:08:33 +0200 Subject: [PATCH 0816/1962] Update @cowwoc as a contributor --- .all-contributorsrc | 3 ++- docs/pages/pmd/projectdocs/credits.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 53b25f8d3d0..e100ac37b61 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7546,7 +7546,8 @@ "avatar_url": "https://avatars.githubusercontent.com/u/633348?v=4", "profile": "https://github.com/cowwoc", "contributions": [ - "bug" + "bug", + "code" ] }, { diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 6ba43d24694..177a121f449 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -300,7 +300,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Genoud Magloire
    Genoud Magloire

    ๐Ÿ› Geoffrey555
    Geoffrey555

    ๐Ÿ› Georg Romstorfer
    Georg Romstorfer

    ๐Ÿ› - Gili Tzabari
    Gili Tzabari

    ๐Ÿ› + Gili Tzabari
    Gili Tzabari

    ๐Ÿ› ๐Ÿ’ป Gio
    Gio

    ๐Ÿ› From e06ca277487ccf4e6a157f29b234046aeec0dccf Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 22 Apr 2025 20:09:47 +0200 Subject: [PATCH 0817/1962] [doc] Update release notes (#5687) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 33e9a3f172c..3ea37b644af 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -27,6 +27,8 @@ This is a {{ site.pmd.release_type }} release. * [#3184](https://github.com/pmd/pmd/issues/3184): \[apex] Prevent classes from shadowing System Namespace * java * [#5645](https://github.com/pmd/pmd/issues/5645): \[java] Parse error on switch with yield +* java-bestpractices + * [#5687](https://github.com/pmd/pmd/issues/5687): \[java] UnusedPrivateMethodRule: exclude serialization method readObjectNoData() ### ๐Ÿšจ API Changes @@ -34,6 +36,7 @@ This is a {{ site.pmd.release_type }} release. * [#5450](https://github.com/pmd/pmd/pull/5450): Fix #3184: \[apex] New Rule: TypeShadowsBuiltInNamespace - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) * [#5672](https://github.com/pmd/pmd/pull/5672): \[doc] Fix its/it's and doable/double typos - [John Jetmore](https://github.com/jetmore) (@jetmore) +* [#5687](https://github.com/pmd/pmd/pull/5687): \[java] UnusedPrivateMethodRule: exclude serialization method readObjectNoData() - [Gili Tzabari](https://github.com/cowwoc) (@cowwoc) ### ๐Ÿ“ฆ Dependency updates From b42844b872942852a9e7e86894013209528567e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 20:18:53 +0200 Subject: [PATCH 0818/1962] Bump com.google.code.gson:gson from 2.12.1 to 2.13.0 (#5691) Bumps [com.google.code.gson:gson](https://github.com/google/gson) from 2.12.1 to 2.13.0. - [Release notes](https://github.com/google/gson/releases) - [Changelog](https://github.com/google/gson/blob/main/CHANGELOG.md) - [Commits](https://github.com/google/gson/compare/gson-parent-2.12.1...gson-parent-2.13.0) --- updated-dependencies: - dependency-name: com.google.code.gson:gson dependency-version: 2.13.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a4bd914fee1..76a50eb9a3d 100644 --- a/pom.xml +++ b/pom.xml @@ -920,7 +920,7 @@ com.google.code.gson gson - 2.12.1 + 2.13.0 org.yaml From dc3cdf9b24cf1840d5442c3f0423bfde30d96fc5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 20:19:16 +0200 Subject: [PATCH 0819/1962] Bump com.google.guava:guava from 33.4.7-jre to 33.4.8-jre (#5692) Bumps [com.google.guava:guava](https://github.com/google/guava) from 33.4.7-jre to 33.4.8-jre. - [Release notes](https://github.com/google/guava/releases) - [Commits](https://github.com/google/guava/commits) --- updated-dependencies: - dependency-name: com.google.guava:guava dependency-version: 33.4.8-jre dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 76a50eb9a3d..439c3cfd518 100644 --- a/pom.xml +++ b/pom.xml @@ -930,7 +930,7 @@ com.google.guava guava - 33.4.7-jre + 33.4.8-jre From 61a368715adf3b332771bf481c6ea210a12b90ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 20:19:47 +0200 Subject: [PATCH 0820/1962] Bump net.bytebuddy:byte-buddy from 1.17.4 to 1.17.5 (#5693) Bumps [net.bytebuddy:byte-buddy](https://github.com/raphw/byte-buddy) from 1.17.4 to 1.17.5. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.17.4...byte-buddy-1.17.5) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-version: 1.17.5 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 439c3cfd518..56dba420803 100644 --- a/pom.xml +++ b/pom.xml @@ -1015,7 +1015,7 @@ net.bytebuddy byte-buddy - 1.17.4 + 1.17.5 test From 18377a2aef6955768224d69a66d7e431c074366e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 20:20:42 +0200 Subject: [PATCH 0821/1962] Bump info.picocli:picocli from 4.7.6 to 4.7.7 (#5696) Bumps [info.picocli:picocli](https://github.com/remkop/picocli) from 4.7.6 to 4.7.7. - [Release notes](https://github.com/remkop/picocli/releases) - [Changelog](https://github.com/remkop/picocli/blob/main/RELEASE-NOTES.md) - [Commits](https://github.com/remkop/picocli/compare/v4.7.6...v4.7.7) --- updated-dependencies: - dependency-name: info.picocli:picocli dependency-version: 4.7.7 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 56dba420803..44b30d591c3 100644 --- a/pom.xml +++ b/pom.xml @@ -845,7 +845,7 @@ info.picocli picocli - 4.7.6 + 4.7.7 me.tongfei From b55cd8c1be33b774711f6c7e3a3e694a34918139 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 20:23:48 +0200 Subject: [PATCH 0822/1962] Bump org.junit:junit-bom from 5.12.1 to 5.12.2 (#5694) Bumps [org.junit:junit-bom](https://github.com/junit-team/junit5) from 5.12.1 to 5.12.2. - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.12.1...r5.12.2) --- updated-dependencies: - dependency-name: org.junit:junit-bom dependency-version: 5.12.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 44b30d591c3..b880982472b 100644 --- a/pom.xml +++ b/pom.xml @@ -94,7 +94,7 @@ ${maven.compiler.test.target} 1.9.24 5.9.1 - 5.12.1 + 5.12.2 1.12.1 2.0.0 From 1bd5facdc57c094b3b78c43d0ce294babfcce836 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 20:25:46 +0200 Subject: [PATCH 0823/1962] Bump junit5.platform.version from 1.12.1 to 1.12.2 (#5677) Bumps `junit5.platform.version` from 1.12.1 to 1.12.2. Updates `org.junit.platform:junit-platform-launcher` from 1.12.1 to 1.12.2 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/commits) Updates `org.junit.platform:junit-platform-commons` from 1.12.1 to 1.12.2 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/commits) --- updated-dependencies: - dependency-name: org.junit.platform:junit-platform-launcher dependency-version: 1.12.2 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.junit.platform:junit-platform-commons dependency-version: 1.12.2 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b880982472b..e905b1ffe0b 100644 --- a/pom.xml +++ b/pom.xml @@ -95,7 +95,7 @@ 1.9.24 5.9.1 5.12.2 - 1.12.1 + 1.12.2 2.0.0 5.0 From 9ea567989cf5eb41cd2b02e0928ddf73c728936e Mon Sep 17 00:00:00 2001 From: Elliotte Rusty Harold Date: Wed, 23 Apr 2025 07:42:05 -0400 Subject: [PATCH 0824/1962] Don't accidentally catch unexpected runtime exceptions --- .../src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java | 6 +++--- .../main/java/net/sourceforge/pmd/cpd/SourceManager.java | 4 ++-- .../test/java/net/sourceforge/pmd/cpd/CpdAnalysisTest.java | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java index 6117998e4a2..c5a154bf047 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java @@ -183,8 +183,8 @@ public void performAnalysis(Consumer consumer) { } } if (!processingErrors.isEmpty() && !configuration.isSkipLexicalErrors()) { - // will be caught by CPD command - throw new IllegalStateException("Errors were detected while lexing source, exiting because --skip-lexical-errors is unset."); + reporter.error("Errors were detected while lexing source, exiting because --skip-lexical-errors is unset."); + return; } LOGGER.debug("Running match algorithm on {} files...", sourceManager.size()); @@ -202,7 +202,7 @@ public void performAnalysis(Consumer consumer) { } consumer.accept(cpdReport); - } catch (Exception e) { + } catch (IOException e) { reporter.errorEx("Exception while running CPD", e); } // source manager is closed and closes all text files now. diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceManager.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceManager.java index bf3e7ec0e0a..86630d7ae7a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceManager.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceManager.java @@ -68,10 +68,10 @@ public int size() { @Override - public void close() throws Exception { + public void close() throws IOException { Exception exception = IOUtil.closeAll(textFiles); if (exception != null) { - throw exception; + throw new IOException(exception); } } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CpdAnalysisTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CpdAnalysisTest.java index 0238b76fa35..857d61d7ceb 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CpdAnalysisTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CpdAnalysisTest.java @@ -213,7 +213,7 @@ void testNoSkipLexicalErrors() throws IOException { } verify(reporter).errorEx(eq("Error while tokenizing"), any(LexException.class)); verify(reporter).errorEx(eq("Error while tokenizing"), any(MalformedSourceException.class)); - verify(reporter).errorEx(eq("Exception while running CPD"), any(IllegalStateException.class)); + verify(reporter).error(eq("Errors were detected while lexing source, exiting because --skip-lexical-errors is unset.")); verifyNoMoreInteractions(reporter); } From d9819e8f72019ba71aa7775448843cba57e1464d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 23 Apr 2025 15:35:24 +0200 Subject: [PATCH 0825/1962] Add test, disable using lang property --- .../lang/java/internal/JavaAstProcessor.java | 4 ++ .../internal/ast/SymbolResolutionPass.java | 4 ++ .../table/internal/SymbolTableResolver.java | 1 + .../java/types/internal/infer/LombokTest.kt | 43 ++++++++++++++++--- 4 files changed, 45 insertions(+), 7 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAstProcessor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAstProcessor.java index 1946ee81d8b..935409115cc 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAstProcessor.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAstProcessor.java @@ -60,6 +60,10 @@ private JavaAstProcessor(JavaLanguageProcessor globalProc, this.acu = acu; } + public boolean hasFirstClassLombokSupport() { + return globalProc.hasFirstClassLombokSupport(); + } + public UnresolvedClassStore getUnresolvedStore() { return unresolvedTypes; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/SymbolResolutionPass.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/SymbolResolutionPass.java index af7432f7642..d5995a882fd 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/SymbolResolutionPass.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/SymbolResolutionPass.java @@ -49,6 +49,10 @@ public static SymbolResolver traverse(JavaAstProcessor processor, ASTCompilation } public static void desugarLombokMembers(JavaAstProcessor processor, ASTTypeDeclaration type) { + if (!processor.hasFirstClassLombokSupport()) { + return; + } + JClassSymbol symbol = type.getSymbol(); if (symbol instanceof AstClassSym) { ((AstClassSym) symbol).processLombok(processor); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java index b37827757a7..7310d3259ae 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java @@ -265,6 +265,7 @@ private void processTypeHeader(ASTTypeDeclaration node, ReferenceCtx ctx) { } popStack(pushed - 1); + // resolve annotations, necessary for lombok f.disambig(node.getModifiers().asStream(), ctx); SymbolResolutionPass.desugarLombokMembers(ctx.processor, node); diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/LombokTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/LombokTest.kt index 26831fcc162..deb7db12f87 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/LombokTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/LombokTest.kt @@ -6,15 +6,10 @@ package net.sourceforge.pmd.lang.java.types.internal.infer import io.kotest.matchers.shouldBe import net.sourceforge.pmd.lang.java.JavaParsingHelper -import net.sourceforge.pmd.lang.java.ast.ASTLocalVariableDeclaration -import net.sourceforge.pmd.lang.java.ast.JavaVersion +import net.sourceforge.pmd.lang.java.ast.* import net.sourceforge.pmd.lang.java.ast.JavaVersion.J9 -import net.sourceforge.pmd.lang.java.ast.ProcessorTestSpec import net.sourceforge.pmd.lang.java.internal.JavaLanguageProperties -import net.sourceforge.pmd.lang.java.types.JClassType -import net.sourceforge.pmd.lang.java.types.shouldHaveType -import net.sourceforge.pmd.lang.java.types.varId -import net.sourceforge.pmd.lang.java.types.withTypeDsl +import net.sourceforge.pmd.lang.java.types.* import net.sourceforge.pmd.lang.test.ast.IntelliMarker import net.sourceforge.pmd.lang.test.ast.shouldBeA @@ -138,4 +133,38 @@ class LombokTest : IntelliMarker, ProcessorTestSpec({ } + + parserTestContainer("Lombok @Slf4j annotation") { + + val code = + """ + import lombok.extern.slf4j.Slf4j; + @Slf4j + public class Book { + public void logMe() { + log.info("Hello, %s!"); + } + } + """.trimIndent() + + + doTest("Creates a log field when supported") { + val acu = parser.parse(code) + acu.withTypeDsl { + val qualifier = acu.firstMethodCall().qualifier!! + qualifier shouldHaveType org.slf4j.Logger::class.decl + qualifier.shouldBeA() + } + } + + doTest("Do nothing when lombok support is disabled") { + val acu = parser.disableLombok().parse(code) + acu.withTypeDsl { + val qualifier = acu.firstMethodCall().qualifier!! + qualifier shouldHaveType ts.UNKNOWN + qualifier.shouldBeA() + } + } + } + }) From ffbd260c4d0cdc4299b4eb2354586d03cf5a374c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 23 Apr 2025 15:40:13 +0200 Subject: [PATCH 0826/1962] Update release notes --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 26ec825d013..893aeaa5656 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -16,6 +16,9 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿ› Fixed Issues +- java + - [#5702](https://github.com/pmd/pmd/issue/5702): Lombok `@Slf4j` annotation is not interpreted by PMD + ### ๐Ÿšจ API Changes ### โœจ Merged pull requests From 5e2e2a3729b6e531b2ff46d4ef6d4562ca853304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 23 Apr 2025 16:18:03 +0200 Subject: [PATCH 0827/1962] fix release notes --- docs/pages/release_notes.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 8a9ba1ed249..b3ee40e1d94 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -30,12 +30,10 @@ This is a {{ site.pmd.release_type }} release. * [#3184](https://github.com/pmd/pmd/issues/3184): \[apex] Prevent classes from shadowing System Namespace * java * [#5645](https://github.com/pmd/pmd/issues/5645): \[java] Parse error on switch with yield + * [#5702](https://github.com/pmd/pmd/issue/5702): \[java] Lombok `@Slf4j` annotation is not interpreted by PMD * java-bestpractices * [#5687](https://github.com/pmd/pmd/issues/5687): \[java] UnusedPrivateMethodRule: exclude serialization method readObjectNoData() -- java - - [#5702](https://github.com/pmd/pmd/issue/5702): Lombok `@Slf4j` annotation is not interpreted by PMD - ### ๐Ÿšจ API Changes ### โœจ Merged pull requests From af69222eb11ec111949b931e6a42090050fbae73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 23 Apr 2025 17:09:56 +0200 Subject: [PATCH 0828/1962] Update NPath documentation --- .../lang/java/ast/internal/JavaAstUtils.java | 6 +- .../pmd/lang/java/metrics/JavaMetrics.java | 89 +++++++++++++------ 2 files changed, 65 insertions(+), 30 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java index 54fd80451be..5ee9098842f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java @@ -826,13 +826,13 @@ public static boolean isInStaticCtx(JavaNode node) { } /** - * Return the target of the return. May be any {@link ReturnScopeNode}. - * + * Return the target of the return. */ - public static @Nullable JavaNode getReturnTarget(ASTReturnStatement stmt) { + public static @Nullable ReturnScopeNode getReturnTarget(ASTReturnStatement stmt) { return stmt.ancestors().first(ReturnScopeNode.class); } + /** * Return true if the variable is effectively final. This means * the variable is never reassigned. diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java index 0feb7554dab..4e368ed379d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java @@ -317,33 +317,68 @@ public final class JavaMetrics { * Methods with an NPath complexity over 200 are generally considered * too complex. * - *

    We compute NPath recursively, with the following set of rules: - *

      - *
    • An empty block has a complexity of 1. - *
    • The complexity of a block is the product of the NPath complexity - * of its statements, calculated as follows: - *
        - *
      • The complexity of for, do and while statements is 1, plus the - * complexity of the block, plus the complexity of the guard condition. - *
      • The complexity of a cascading if statement ({@code if .. else if ..}) - * is the number of if statements in the chain, plus the complexity of - * their guard condition, plus the complexity of the unguarded else block - * (or 1 if there is none). - *
      • The complexity of a switch statement is the number of cases, - * plus the complexity of each case block. Itโ€™s equivalent to the - * complexity of the equivalent cascade of if statements. - *
      • The complexity of a ternary expression ({@code ? :}) is the complexity - * of the guard condition, plus the complexity of both expressions. - * Itโ€™s equivalent to the complexity of the equivalent {@code if .. else} construct. - *
      • The complexity of a {@code try .. catch} statement is the complexity - * of the {@code try} block, plus the complexity of each catch block. - *
      • The complexity of a return statement is the complexity of the - * expression (or 1 if there is none). - *
      • All other statements have a complexity of 1 and are discarded - * from the product. - *
      - *
    • - *
    + *

    NPath is computed through control flow analysis. We walk a block + * and keep track of how many control flow paths lead to the current + * program point. We make sure to separate paths that end abruptly + * (for instance because of a throw, or return). This accurately counts + * the number of paths that lead out of a given method. For instance: + *

    {@code
    +     *  // entry
    +     *  if (foo)
    +     *     return foo;
    +     *  doSomething();
    +     *  // exit
    +     * }
    + * Here there are two paths from the entry to the exit of the method: + * one that ends after doSomething(), and another that ends with the + * return statement. Complexity can snowball rapidly. For instance: + *
    {@code
    +     *  // entry
    +     *  if (foo) a = 1; else a = 2;
    +     *  // join
    +     *  if (bar) b = 3; else b = 4;
    +     *  // exit
    +     * }
    + * Here there are two paths from {@code entry} to {@code join}: one + * that goes through each branch of the if/else. Then there are two + * paths from {@code join} to {@code exit}, for the same reason. The + * total number of paths from {@code entry} to {@code exit} is + * {@code 2 * 2 = 4}. Since complexities multiply in this way, it + * can grow exponentially. This is not the case with early-return + * patterns for instance: + *
    {@code
    +     *  // entry
    +     *  if (foo) return x;
    +     *  // join
    +     *  if (bar) = 3;
    +     *  // exit
    +     * }
    + * Here there is only one path from {@code entry} to {@code join}, + * because the {@code if} branch returns early. There are two paths + * from {@code join} to {@code exit} (and notice, that's true even if + * there is no else branch, because the path where the if condition is + * falso must be taken into account anyway). So in total there are {@code 1*2 + 1 = 3} + * paths from {@code entry} to the end of the block or function (the + * return statement still counts). + * + *

    Note that shortcut boolean operators are counted as control flow + * branches, especially if they happen in the condition of a control flow + * statement. For instance + *

    {@code
    +     *  // entry
    +     *  if (foo || bar)
    +     *     return foo ? a() : b();
    +     *  doSomething();
    +     *  // exit
    +     * }
    + * How many paths are there here? There is one path that goes from {@code entry} + * to {@code exit}, which is taken if {@code !foo && !bar}. There is + * one path that leads to the return statement if foo is true, and + * another if foo is false and bar is true. In the return statement, + * there is one path that executes a() and another that executes b(). + * In total, there are 2 * 2 paths that start at {@code entry} and + * end at the return statement, and 1 path that goes from {@code entry} + * to {@code exit}, so the total is 5 paths. */ public static final Metric NPATH_COMP = Metric.of(JavaMetrics::computeNpath, NodeStream.asInstanceOf(ReturnScopeNode.class), From c70fe3c5fae6be37723ff8b9851c1b665de5a5fd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 24 Apr 2025 08:32:53 +0200 Subject: [PATCH 0829/1962] Bump com.github.hazendaz.maven:coveralls-maven-plugin from 4.5.0-M6 to 4.7.0 (#5697) * Bump com.github.hazendaz.maven:coveralls-maven-plugin Bumps [com.github.hazendaz.maven:coveralls-maven-plugin](https://github.com/hazendaz/coveralls-maven-plugin) from 4.5.0-M6 to 4.7.0. - [Release notes](https://github.com/hazendaz/coveralls-maven-plugin/releases) - [Changelog](https://github.com/hazendaz/coveralls-maven-plugin/blob/master/CHANGELOG.md) - [Commits](https://github.com/hazendaz/coveralls-maven-plugin/compare/coveralls-maven-plugin-4.5.0-M6...coveralls-maven-plugin-4.7.0) --- updated-dependencies: - dependency-name: com.github.hazendaz.maven:coveralls-maven-plugin dependency-version: 4.7.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * [ci] Use Java 17 for coveralls --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andreas Dangel --- .ci/build.sh | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/build.sh b/.ci/build.sh index ceba5cbbf0c..eb2902096e9 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -169,7 +169,7 @@ function build() { pmd_ci_log_group_end pmd_ci_log_group_start "Executing build with coveralls" - pmd_ci_openjdk_setdefault 11 + pmd_ci_openjdk_setdefault 17 export CI_NAME="github actions" export CI_BUILD_URL="${PMD_CI_JOB_URL}" export CI_BRANCH="${PMD_CI_BRANCH}" diff --git a/pom.xml b/pom.xml index e905b1ffe0b..e1cf34b9723 100644 --- a/pom.xml +++ b/pom.xml @@ -1288,7 +1288,7 @@ com.github.hazendaz.maven coveralls-maven-plugin - 4.5.0-M6 + 4.7.0 From 86ba73b5f2c7d1a9ba0ea1a23de21482ace5d7d2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Apr 2025 15:02:56 +0200 Subject: [PATCH 0830/1962] [doc] Support doc links in release notes --- do-release.sh | 10 ++++++++++ docs/pages/pmd/projectdocs/committers/releasing.md | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/do-release.sh b/do-release.sh index 73f8dfbd13e..b24af68fe7b 100755 --- a/do-release.sh +++ b/do-release.sh @@ -256,6 +256,16 @@ permalink: pmd_release_notes.html keywords: changelog, release notes --- +{% if is_release_notes_processor %} +{% comment %} +This allows to use links like [Page]({{ basedir }}pmd_devdocs_page.html) that work both in the release notes +on GitHub (as an absolute url) and on the rendered documentation page (as a relative url). +{% endcomment %} +{% capture baseurl %}https://docs.pmd-code.org/pmd-doc-{{ site.pmd.version }}/{% endcapture %} +{% else %} +{% assign baseurl = "" %} +{% endif %} + ## {{ site.pmd.date | date: "%d-%B-%Y" }} - {{ site.pmd.version }} The PMD team is pleased to announce PMD {{ site.pmd.version }}. diff --git a/docs/pages/pmd/projectdocs/committers/releasing.md b/docs/pages/pmd/projectdocs/committers/releasing.md index 5882b8b10a9..4a56bab2e1e 100644 --- a/docs/pages/pmd/projectdocs/committers/releasing.md +++ b/docs/pages/pmd/projectdocs/committers/releasing.md @@ -339,6 +339,16 @@ permalink: pmd_release_notes.html keywords: changelog, release notes --- +{% if is_release_notes_processor %} +{% comment %} +This allows to use links like [Page]({{ basedir }}pmd_devdocs_page.html) that work both in the release notes +on GitHub (as an absolute url) and on the rendered documentation page (as a relative url). +{% endcomment %} +{% capture baseurl %}https://docs.pmd-code.org/pmd-doc-{{ site.pmd.version }}/{% endcapture %} +{% else %} +{% assign baseurl = "" %} +{% endif %} + ## {{ site.pmd.date | date: "%d-%B-%Y" }} - {{ site.pmd.version }} The PMD team is pleased to announce PMD {{ site.pmd.version }}. From c8c6bf842a365a845d10be1cca81340bc17ad08f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Apr 2025 15:09:31 +0200 Subject: [PATCH 0831/1962] Fix condition when docker images are built --- .ci/build.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.ci/build.sh b/.ci/build.sh index 2fd64833343..97195f0ec07 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -150,8 +150,9 @@ function build() { pmd_ci_log_group_end fi - # Trigger docker workflow to build new images - if pmd_ci_maven_isSnapshotBuild || [ "${BUILD_CLI_DIST_ONLY}" = "true" ]; then + # Trigger docker workflow to build new images for release builds + # but only for case b) pmd-cli/pmd-dist release + if pmd_ci_maven_isReleaseBuild && [ "${BUILD_CLI_DIST_ONLY}" = "true" ]; then pmd_ci_log_group_start "Trigger docker workflow" # split semantic version by dot IFS="." read -ra VERSION_ARRAY <<< "${PMD_CI_MAVEN_PROJECT_VERSION}" From c9a0c6f4eae5da22a7fa027f52d953ddcb43dd2b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Apr 2025 15:17:19 +0200 Subject: [PATCH 0832/1962] Add @MiladSadinam as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 129 +++++++++++++------------- 2 files changed, 74 insertions(+), 64 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 559807dede6..6e58551feec 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8076,6 +8076,15 @@ "contributions": [ "doc" ] + }, + { + "login": "MiladSadinam", + "name": "MiladSadinam", + "avatar_url": "https://avatars.githubusercontent.com/u/8689490?v=4", + "profile": "https://github.com/MiladSadinam", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 794ca3f8646..699c0c97b1c 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -567,579 +567,580 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Miguel Nรบรฑez Dรญaz-Montes
    Miguel Nรบรฑez Dรญaz-Montes

    ๐Ÿ› Mihai Ionut
    Mihai Ionut

    ๐Ÿ› Mikhail Kuchma
    Mikhail Kuchma

    ๐Ÿ› + MiladSadinam
    MiladSadinam

    ๐Ÿ› Mirek Hankus
    Mirek Hankus

    ๐Ÿ› Mitch Spano
    Mitch Spano

    ๐Ÿ’ป ๐Ÿ› Mladjan Gadzic
    Mladjan Gadzic

    ๐Ÿ› - Mladjan Gadzic
    Mladjan Gadzic

    ๐Ÿ› + Mladjan Gadzic
    Mladjan Gadzic

    ๐Ÿ› MrAngry52
    MrAngry52

    ๐Ÿ› Muminur Choudhury
    Muminur Choudhury

    ๐Ÿ› Mykhailo Palahuta
    Mykhailo Palahuta

    ๐Ÿ’ป ๐Ÿ› Nagendra Kumar Singh
    Nagendra Kumar Singh

    ๐Ÿ› Nahuel Barrios
    Nahuel Barrios

    ๐Ÿ› Nakul Sharma
    Nakul Sharma

    ๐Ÿ› - Nathan Braun
    Nathan Braun

    ๐Ÿ› + Nathan Braun
    Nathan Braun

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› Nathan Reynolds
    Nathan Reynolds

    ๐Ÿ› Nathanaรซl
    Nathanaรซl

    ๐Ÿ› Naveen
    Naveen

    ๐Ÿ’ป Nazdravi
    Nazdravi

    ๐Ÿ› Neha-Dhonde
    Neha-Dhonde

    ๐Ÿ› - Nicholas Doyle
    Nicholas Doyle

    ๐Ÿ› + Nicholas Doyle
    Nicholas Doyle

    ๐Ÿ› Nick Butcher
    Nick Butcher

    ๐Ÿ› Nico Gallinal
    Nico Gallinal

    ๐Ÿ› Nicola Dal Maso
    Nicola Dal Maso

    ๐Ÿ› Nicolas Filotto
    Nicolas Filotto

    ๐Ÿ’ป Nicolas Vervelle
    Nicolas Vervelle

    ๐Ÿ› Nicolas Vuillamy
    Nicolas Vuillamy

    ๐Ÿ“– - Nikita Chursin
    Nikita Chursin

    ๐Ÿ› + Nikita Chursin
    Nikita Chursin

    ๐Ÿ› Niklas Baudy
    Niklas Baudy

    ๐Ÿ› Nikolas Havrikov
    Nikolas Havrikov

    ๐Ÿ› Nilesh Virkar
    Nilesh Virkar

    ๐Ÿ› Nimit Patel
    Nimit Patel

    ๐Ÿ› Niranjan Harpale
    Niranjan Harpale

    ๐Ÿ› Nirvik Patel
    Nirvik Patel

    ๐Ÿ’ป - Noah Sussman
    Noah Sussman

    ๐Ÿ› + Noah Sussman
    Noah Sussman

    ๐Ÿ› Noah0120
    Noah0120

    ๐Ÿ› Noam Tamim
    Noam Tamim

    ๐Ÿ› Noel Grandin
    Noel Grandin

    ๐Ÿ› Olaf Haalstra
    Olaf Haalstra

    ๐Ÿ› Oleg Andreych
    Oleg Andreych

    ๐Ÿ’ป ๐Ÿ› Oleg Pavlenko
    Oleg Pavlenko

    ๐Ÿ› - Oleksii Dykov
    Oleksii Dykov

    ๐Ÿ’ป ๐Ÿ› + Oleksii Dykov
    Oleksii Dykov

    ๐Ÿ’ป ๐Ÿ› Oliver Eikemeier
    Oliver Eikemeier

    ๐Ÿ› Oliver Siegmar
    Oliver Siegmar

    ๐Ÿ’ต Olivier Parent
    Olivier Parent

    ๐Ÿ’ป ๐Ÿ› Ollie Abbey
    Ollie Abbey

    ๐Ÿ’ป ๐Ÿ› Olof-Joachim Frahm (ๆฌง้›…็ฆ)
    Olof-Joachim Frahm (ๆฌง้›…็ฆ)

    ๐Ÿ› Ondrej Kratochvil
    Ondrej Kratochvil

    ๐Ÿ› - OverDrone
    OverDrone

    ๐Ÿ› + OverDrone
    OverDrone

    ๐Ÿ› Ozan Gulle
    Ozan Gulle

    ๐Ÿ’ป ๐Ÿ› PUNEET JAIN
    PUNEET JAIN

    ๐Ÿ› Parbati Bose
    Parbati Bose

    ๐Ÿ› Paul Berg
    Paul Berg

    ๐Ÿ› Paul Guyot
    Paul Guyot

    ๐Ÿ’ป Pavel Bludov
    Pavel Bludov

    ๐Ÿ› - Pavel Miฤka
    Pavel Miฤka

    ๐Ÿ› + Pavel Miฤka
    Pavel Miฤka

    ๐Ÿ› Pedro Nuno Santos
    Pedro Nuno Santos

    ๐Ÿ› Pedro Rijo
    Pedro Rijo

    ๐Ÿ› Pelisse Romain
    Pelisse Romain

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Per Abich
    Per Abich

    ๐Ÿ’ป Pete Davids
    Pete Davids

    ๐Ÿ› Peter Bruin
    Peter Bruin

    ๐Ÿ› - Peter Chittum
    Peter Chittum

    ๐Ÿ’ป ๐Ÿ› + Peter Chittum
    Peter Chittum

    ๐Ÿ’ป ๐Ÿ› Peter Cudmore
    Peter Cudmore

    ๐Ÿ› Peter Kasson
    Peter Kasson

    ๐Ÿ› Peter Kofler
    Peter Kofler

    ๐Ÿ› Peter Paul Bakker
    Peter Paul Bakker

    ๐Ÿ’ป ๐Ÿ› Peter Rader
    Peter Rader

    ๐Ÿ› Pham Hai Trung
    Pham Hai Trung

    ๐Ÿ› - Philip Graf
    Philip Graf

    ๐Ÿ’ป ๐Ÿ› + Philip Graf
    Philip Graf

    ๐Ÿ’ป ๐Ÿ› Philip Hachey
    Philip Hachey

    ๐Ÿ› Philippe Ozil
    Philippe Ozil

    ๐Ÿ› Phinehas Artemix
    Phinehas Artemix

    ๐Ÿ› Phokham Nonava
    Phokham Nonava

    ๐Ÿ› Pim van der Loos
    Pim van der Loos

    ๐Ÿ’ป โš ๏ธ Piotr Szymaล„ski
    Piotr Szymaล„ski

    ๐Ÿ› - Piotrek ลปygieล‚o
    Piotrek ลปygieล‚o

    ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– + Piotrek ลปygieล‚o
    Piotrek ลปygieล‚o

    ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– Pranay Jaiswal
    Pranay Jaiswal

    ๐Ÿ› Prasad Kamath
    Prasad Kamath

    ๐Ÿ› Prasanna
    Prasanna

    ๐Ÿ› Presh-AR
    Presh-AR

    ๐Ÿ› Puneet1726
    Puneet1726

    ๐Ÿ› RBRi
    RBRi

    ๐Ÿ› - Rafael Cortรชs
    Rafael Cortรชs

    ๐Ÿ› + Rafael Cortรชs
    Rafael Cortรชs

    ๐Ÿ› RaheemShaik999
    RaheemShaik999

    ๐Ÿ› RajeshR
    RajeshR

    ๐Ÿ’ป ๐Ÿ› Ramachandra Mohan
    Ramachandra Mohan

    ๐Ÿ› Ramel0921
    Ramel0921

    ๐Ÿ› Raquel Pau
    Raquel Pau

    ๐Ÿ› Ravikiran Janardhana
    Ravikiran Janardhana

    ๐Ÿ› - Reda Benhemmouche
    Reda Benhemmouche

    ๐Ÿ› + Reda Benhemmouche
    Reda Benhemmouche

    ๐Ÿ› Reinhard Schiedermeier
    Reinhard Schiedermeier

    ๐Ÿ› Renato Oliveira
    Renato Oliveira

    ๐Ÿ’ป ๐Ÿ› Rich DiCroce
    Rich DiCroce

    ๐Ÿ› Richard Corfield
    Richard Corfield

    ๐Ÿ’ป Richard Corfield
    Richard Corfield

    ๐Ÿ› ๐Ÿ’ป Riot R1cket
    Riot R1cket

    ๐Ÿ› - Rishabh Jain
    Rishabh Jain

    ๐Ÿ› + Rishabh Jain
    Rishabh Jain

    ๐Ÿ› RishabhDeep Singh
    RishabhDeep Singh

    ๐Ÿ› Rob Baillie
    Rob Baillie

    ๐Ÿ› Robbie Martinus
    Robbie Martinus

    ๐Ÿ’ป ๐Ÿ› Robert Henry
    Robert Henry

    ๐Ÿ› Robert Mihaly
    Robert Mihaly

    ๐Ÿ› Robert Painsi
    Robert Painsi

    ๐Ÿ› - Robert Russell
    Robert Russell

    ๐Ÿ› + Robert Russell
    Robert Russell

    ๐Ÿ› Robert Sรถsemann
    Robert Sรถsemann

    ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ› Robert Whitebit
    Robert Whitebit

    ๐Ÿ› Robin Richtsfeld
    Robin Richtsfeld

    ๐Ÿ› Robin Stocker
    Robin Stocker

    ๐Ÿ’ป ๐Ÿ› Robin Wils
    Robin Wils

    ๐Ÿ› RochusOest
    RochusOest

    ๐Ÿ› - Rodolfo Noviski
    Rodolfo Noviski

    ๐Ÿ› + Rodolfo Noviski
    Rodolfo Noviski

    ๐Ÿ› Rodrigo Casara
    Rodrigo Casara

    ๐Ÿ› Rodrigo Fernandes
    Rodrigo Fernandes

    ๐Ÿ› Roman Salvador
    Roman Salvador

    ๐Ÿ’ป ๐Ÿ› Ronald Blaschke
    Ronald Blaschke

    ๐Ÿ› Rรณbert Papp
    Rรณbert Papp

    ๐Ÿ› Saikat Sengupta
    Saikat Sengupta

    ๐Ÿ› - Saksham Handu
    Saksham Handu

    ๐Ÿ› + Saksham Handu
    Saksham Handu

    ๐Ÿ› Saladoc
    Saladoc

    ๐Ÿ› Salesforce Bob Lightning
    Salesforce Bob Lightning

    ๐Ÿ› Sam Carlberg
    Sam Carlberg

    ๐Ÿ› Sascha Riemer
    Sascha Riemer

    ๐Ÿ› Sashko
    Sashko

    ๐Ÿ’ป Satoshi Kubo
    Satoshi Kubo

    ๐Ÿ› - Scott Kennedy
    Scott Kennedy

    ๐Ÿ› + Scott Kennedy
    Scott Kennedy

    ๐Ÿ› Scott Wells
    Scott Wells

    ๐Ÿ› ๐Ÿ’ป Scrates1
    Scrates1

    ๐Ÿ› ๐Ÿ’ป Scrsloota
    Scrsloota

    ๐Ÿ’ป Sebastian Bรถgl
    Sebastian Bรถgl

    ๐Ÿ› Sebastian Davids
    Sebastian Davids

    ๐Ÿ› Sebastian Lรถvdahl
    Sebastian Lรถvdahl

    ๐Ÿ› - Sebastian Schuberth
    Sebastian Schuberth

    ๐Ÿ› + Sebastian Schuberth
    Sebastian Schuberth

    ๐Ÿ› Sebastian Schwarz
    Sebastian Schwarz

    ๐Ÿ› Seren
    Seren

    ๐Ÿ› ๐Ÿ’ป Sergey Gorbaty
    Sergey Gorbaty

    ๐Ÿ› Sergey Kozlov
    Sergey Kozlov

    ๐Ÿ› Sergey Yanzin
    Sergey Yanzin

    ๐Ÿ’ป ๐Ÿ› Seth Wilcox
    Seth Wilcox

    ๐Ÿ’ป - Shai Bennathan
    Shai Bennathan

    ๐Ÿ› ๐Ÿ’ป + Shai Bennathan
    Shai Bennathan

    ๐Ÿ› ๐Ÿ’ป Shubham
    Shubham

    ๐Ÿ’ป ๐Ÿ› Simon Abykov
    Simon Abykov

    ๐Ÿ’ป ๐Ÿ› Simon Xiao
    Simon Xiao

    ๐Ÿ› Srinivasan Venkatachalam
    Srinivasan Venkatachalam

    ๐Ÿ› Stanislav Gromov
    Stanislav Gromov

    ๐Ÿ› Stanislav Myachenkov
    Stanislav Myachenkov

    ๐Ÿ’ป - Stefan Birkner
    Stefan Birkner

    ๐Ÿ› + Stefan Birkner
    Stefan Birkner

    ๐Ÿ› Stefan Bohn
    Stefan Bohn

    ๐Ÿ› Stefan Endrullis
    Stefan Endrullis

    ๐Ÿ› Stefan Klรถss-Schuster
    Stefan Klรถss-Schuster

    ๐Ÿ› Stefan Wolf
    Stefan Wolf

    ๐Ÿ› Stephan H. Wissel
    Stephan H. Wissel

    ๐Ÿ› Stephen
    Stephen

    ๐Ÿ› - Stephen Carter
    Stephen Carter

    ๐Ÿ› + Stephen Carter
    Stephen Carter

    ๐Ÿ› Stephen Friedrich
    Stephen Friedrich

    ๐Ÿ› Steve Babula
    Steve Babula

    ๐Ÿ’ป Steven Stearns
    Steven Stearns

    ๐Ÿ› ๐Ÿ’ป Stexxe
    Stexxe

    ๐Ÿ› Stian Lรฅgstad
    Stian Lรฅgstad

    ๐Ÿ› StuartClayton5
    StuartClayton5

    ๐Ÿ› - Supun Arunoda
    Supun Arunoda

    ๐Ÿ› + Supun Arunoda
    Supun Arunoda

    ๐Ÿ› Suren Abrahamyan
    Suren Abrahamyan

    ๐Ÿ› Suvashri
    Suvashri

    ๐Ÿ“– Sven Barden
    Sven Barden

    ๐Ÿ› SwatiBGupta1110
    SwatiBGupta1110

    ๐Ÿ› SyedThoufich
    SyedThoufich

    ๐Ÿ› Szymon Sasin
    Szymon Sasin

    ๐Ÿ› - T-chuangxin
    T-chuangxin

    ๐Ÿ› + T-chuangxin
    T-chuangxin

    ๐Ÿ› TERAI Atsuhiro
    TERAI Atsuhiro

    ๐Ÿ› TIOBE Software
    TIOBE Software

    ๐Ÿ’ป ๐Ÿ› Tarush Singh
    Tarush Singh

    ๐Ÿ’ป Taylor Smock
    Taylor Smock

    ๐Ÿ› Techeira Damiรกn
    Techeira Damiรกn

    ๐Ÿ’ป ๐Ÿ› Ted Husted
    Ted Husted

    ๐Ÿ› - TehBakker
    TehBakker

    ๐Ÿ› + TehBakker
    TehBakker

    ๐Ÿ› The Gitter Badger
    The Gitter Badger

    ๐Ÿ› Theodoor
    Theodoor

    ๐Ÿ› Thiago Henrique Hรผpner
    Thiago Henrique Hรผpner

    ๐Ÿ› Thibault Meyer
    Thibault Meyer

    ๐Ÿ› Thomas Gรผttler
    Thomas Gรผttler

    ๐Ÿ› Thomas Jones-Low
    Thomas Jones-Low

    ๐Ÿ› - Thomas Smith
    Thomas Smith

    ๐Ÿ’ป ๐Ÿ› + Thomas Smith
    Thomas Smith

    ๐Ÿ’ป ๐Ÿ› ThrawnCA
    ThrawnCA

    ๐Ÿ› Thu Vo
    Thu Vo

    ๐Ÿ› Thunderforge
    Thunderforge

    ๐Ÿ’ป ๐Ÿ› Tim van der Lippe
    Tim van der Lippe

    ๐Ÿ› Tobias Weimer
    Tobias Weimer

    ๐Ÿ’ป ๐Ÿ› Tom Copeland
    Tom Copeland

    ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– - Tom Daly
    Tom Daly

    ๐Ÿ› + Tom Daly
    Tom Daly

    ๐Ÿ› Tomas
    Tomas

    ๐Ÿ› Tomer Figenblat
    Tomer Figenblat

    ๐Ÿ› Tomi De Lucca
    Tomi De Lucca

    ๐Ÿ’ป ๐Ÿ› Tony
    Tony

    ๐Ÿ“– Torsten Kleiber
    Torsten Kleiber

    ๐Ÿ› Torsten Krause
    Torsten Krause

    ๐Ÿ› - TrackerSB
    TrackerSB

    ๐Ÿ› + TrackerSB
    TrackerSB

    ๐Ÿ› Tyson Stewart
    Tyson Stewart

    ๐Ÿ› Ullrich Hafner
    Ullrich Hafner

    ๐Ÿ› Utku Cuhadaroglu
    Utku Cuhadaroglu

    ๐Ÿ’ป ๐Ÿ› Valentin Brandl
    Valentin Brandl

    ๐Ÿ› Valeria
    Valeria

    ๐Ÿ› Valery Yatsynovich
    Valery Yatsynovich

    ๐Ÿ“– - Vasily Anisimov
    Vasily Anisimov

    ๐Ÿ› + Vasily Anisimov
    Vasily Anisimov

    ๐Ÿ› Vedant Chokshi
    Vedant Chokshi

    ๐Ÿ› Vibhor Goyal
    Vibhor Goyal

    ๐Ÿ› Vickenty Fesunov
    Vickenty Fesunov

    ๐Ÿ› Victor Noรซl
    Victor Noรซl

    ๐Ÿ› Vincent Galloy
    Vincent Galloy

    ๐Ÿ’ป Vincent HUYNH
    Vincent HUYNH

    ๐Ÿ› - Vincent Maurin
    Vincent Maurin

    ๐Ÿ› + Vincent Maurin
    Vincent Maurin

    ๐Ÿ› Vincent Potucek
    Vincent Potucek

    ๐Ÿ’ป Vincent Privat
    Vincent Privat

    ๐Ÿ› Vishhwas
    Vishhwas

    ๐Ÿ› Vishv_Android
    Vishv_Android

    ๐Ÿ› Vitalii Yevtushenko
    Vitalii Yevtushenko

    ๐Ÿ› Vitaly
    Vitaly

    ๐Ÿ› - Vitaly Polonetsky
    Vitaly Polonetsky

    ๐Ÿ› + Vitaly Polonetsky
    Vitaly Polonetsky

    ๐Ÿ› Vojtech Polivka
    Vojtech Polivka

    ๐Ÿ› Vsevolod Zholobov
    Vsevolod Zholobov

    ๐Ÿ› Vyom Yadav
    Vyom Yadav

    ๐Ÿ’ป Wang Shidong
    Wang Shidong

    ๐Ÿ› Waqas Ahmed
    Waqas Ahmed

    ๐Ÿ› Wayne J. Earl
    Wayne J. Earl

    ๐Ÿ› - Wchenghui
    Wchenghui

    ๐Ÿ› + Wchenghui
    Wchenghui

    ๐Ÿ› Wener
    Wener

    ๐Ÿ’ป Will Winder
    Will Winder

    ๐Ÿ› Willem A. Hajenius
    Willem A. Hajenius

    ๐Ÿ’ป William Brockhus
    William Brockhus

    ๐Ÿ’ป ๐Ÿ› Wilson Kurniawan
    Wilson Kurniawan

    ๐Ÿ› Wim Deblauwe
    Wim Deblauwe

    ๐Ÿ› - Wolf2323
    Wolf2323

    ๐Ÿ› + Wolf2323
    Wolf2323

    ๐Ÿ› Woongsik Choi
    Woongsik Choi

    ๐Ÿ› XenoAmess
    XenoAmess

    ๐Ÿ’ป ๐Ÿ› Yang
    Yang

    ๐Ÿ’ป YaroslavTER
    YaroslavTER

    ๐Ÿ› Yasar Shaikh
    Yasar Shaikh

    ๐Ÿ’ป Young Chan
    Young Chan

    ๐Ÿ’ป ๐Ÿ› - YuJin Kim
    YuJin Kim

    ๐Ÿ› + YuJin Kim
    YuJin Kim

    ๐Ÿ› Yuri Dolzhenko
    Yuri Dolzhenko

    ๐Ÿ› Yurii Dubinka
    Yurii Dubinka

    ๐Ÿ› Zoltan Farkas
    Zoltan Farkas

    ๐Ÿ› Zustin
    Zustin

    ๐Ÿ› aaronhurst-google
    aaronhurst-google

    ๐Ÿ› ๐Ÿ’ป alexmodis
    alexmodis

    ๐Ÿ› - andreoss
    andreoss

    ๐Ÿ› + andreoss
    andreoss

    ๐Ÿ› andrey81inmd
    andrey81inmd

    ๐Ÿ’ป ๐Ÿ› anicoara
    anicoara

    ๐Ÿ› arunprasathav
    arunprasathav

    ๐Ÿ› asiercamara
    asiercamara

    ๐Ÿ› astillich-igniti
    astillich-igniti

    ๐Ÿ’ป avesolovksyy
    avesolovksyy

    ๐Ÿ› - avishvat
    avishvat

    ๐Ÿ› + avishvat
    avishvat

    ๐Ÿ› avivmu
    avivmu

    ๐Ÿ› axelbarfod1
    axelbarfod1

    ๐Ÿ› b-3-n
    b-3-n

    ๐Ÿ› balbhadra9
    balbhadra9

    ๐Ÿ› base23de
    base23de

    ๐Ÿ› bergander
    bergander

    ๐Ÿ› ๐Ÿ’ป - berkam
    berkam

    ๐Ÿ’ป ๐Ÿ› + berkam
    berkam

    ๐Ÿ’ป ๐Ÿ› breizh31
    breizh31

    ๐Ÿ› caesarkim
    caesarkim

    ๐Ÿ› caiocarvalhotero
    caiocarvalhotero

    ๐Ÿ› carolyujing
    carolyujing

    ๐Ÿ› cbfiddle
    cbfiddle

    ๐Ÿ› cesares-basilico
    cesares-basilico

    ๐Ÿ› - chrite
    chrite

    ๐Ÿ› + chrite
    chrite

    ๐Ÿ› ciufudean
    ciufudean

    ๐Ÿ“– cobratbq
    cobratbq

    ๐Ÿ› coladict
    coladict

    ๐Ÿ› cosmoJFH
    cosmoJFH

    ๐Ÿ› cristalp
    cristalp

    ๐Ÿ› crunsk
    crunsk

    ๐Ÿ› - cwholmes
    cwholmes

    ๐Ÿ› + cwholmes
    cwholmes

    ๐Ÿ› cyberjj999
    cyberjj999

    ๐Ÿ› cyw3
    cyw3

    ๐Ÿ› ๐Ÿ“– d1ss0nanz
    d1ss0nanz

    ๐Ÿ› dague1
    dague1

    ๐Ÿ“– dalizi007
    dalizi007

    ๐Ÿ’ป danbrycefairsailcom
    danbrycefairsailcom

    ๐Ÿ› - dariansanity
    dariansanity

    ๐Ÿ› + dariansanity
    dariansanity

    ๐Ÿ› darrenmiliband
    darrenmiliband

    ๐Ÿ› davidburstrom
    davidburstrom

    ๐Ÿ› dbirkman-paloalto
    dbirkman-paloalto

    ๐Ÿ› deepak-patra
    deepak-patra

    ๐Ÿ› dependabot[bot]
    dependabot[bot]

    ๐Ÿ’ป ๐Ÿ› dinesh150
    dinesh150

    ๐Ÿ› - diziaq
    diziaq

    ๐Ÿ› + diziaq
    diziaq

    ๐Ÿ› dreaminpast123
    dreaminpast123

    ๐Ÿ› duanyanan
    duanyanan

    ๐Ÿ› dutt-sanjay
    dutt-sanjay

    ๐Ÿ› duursma
    duursma

    ๐Ÿ’ป dylanleung
    dylanleung

    ๐Ÿ› dzeigler
    dzeigler

    ๐Ÿ› - eant60
    eant60

    ๐Ÿ› + eant60
    eant60

    ๐Ÿ› ekkirala
    ekkirala

    ๐Ÿ› emersonmoura
    emersonmoura

    ๐Ÿ› emouty
    emouty

    ๐Ÿ’ป ๐Ÿ› eugenepugach
    eugenepugach

    ๐Ÿ› fairy
    fairy

    ๐Ÿ› filiprafalowicz
    filiprafalowicz

    ๐Ÿ’ป - flxbl-io
    flxbl-io

    ๐Ÿ’ต + flxbl-io
    flxbl-io

    ๐Ÿ’ต foxmason
    foxmason

    ๐Ÿ› frankegabor
    frankegabor

    ๐Ÿ› frankl
    frankl

    ๐Ÿ› freafrea
    freafrea

    ๐Ÿ› fsapatin
    fsapatin

    ๐Ÿ› gearsethenry
    gearsethenry

    ๐Ÿ› - gracia19
    gracia19

    ๐Ÿ› + gracia19
    gracia19

    ๐Ÿ› gudzpoz
    gudzpoz

    ๐Ÿ› guo fei
    guo fei

    ๐Ÿ› gurmsc5
    gurmsc5

    ๐Ÿ› gwilymatgearset
    gwilymatgearset

    ๐Ÿ’ป ๐Ÿ› haigsn
    haigsn

    ๐Ÿ› hemanshu070
    hemanshu070

    ๐Ÿ› - henrik242
    henrik242

    ๐Ÿ› + henrik242
    henrik242

    ๐Ÿ› hongpuwu
    hongpuwu

    ๐Ÿ› hvbtup
    hvbtup

    ๐Ÿ’ป ๐Ÿ› igniti GmbH
    igniti GmbH

    ๐Ÿ› ilovezfs
    ilovezfs

    ๐Ÿ› imax-erik
    imax-erik

    ๐Ÿ› itaigilo
    itaigilo

    ๐Ÿ› - jakivey32
    jakivey32

    ๐Ÿ› + jakivey32
    jakivey32

    ๐Ÿ› jbennett2091
    jbennett2091

    ๐Ÿ› jcamerin
    jcamerin

    ๐Ÿ› jkeener1
    jkeener1

    ๐Ÿ› jmetertea
    jmetertea

    ๐Ÿ› johnra2
    johnra2

    ๐Ÿ’ป johnzhao9
    johnzhao9

    ๐Ÿ› - josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ› + josemanuelrolon
    josemanuelrolon

    ๐Ÿ’ป ๐Ÿ› julees7
    julees7

    ๐Ÿ’ป ๐Ÿ› kabroxiko
    kabroxiko

    ๐Ÿ’ป ๐Ÿ› karthikaiyasamy
    karthikaiyasamy

    ๐Ÿ“– karwer
    karwer

    ๐Ÿ› kaulonline
    kaulonline

    ๐Ÿ› kdaemonv
    kdaemonv

    ๐Ÿ› - kdebski85
    kdebski85

    ๐Ÿ› ๐Ÿ’ป + kdebski85
    kdebski85

    ๐Ÿ› ๐Ÿ’ป kenji21
    kenji21

    ๐Ÿ’ป ๐Ÿ› kfranic
    kfranic

    ๐Ÿ› khalidkh
    khalidkh

    ๐Ÿ› koalalam
    koalalam

    ๐Ÿ› krzyk
    krzyk

    ๐Ÿ› lasselindqvist
    lasselindqvist

    ๐Ÿ› - lgemeinhardt
    lgemeinhardt

    ๐Ÿ› + lgemeinhardt
    lgemeinhardt

    ๐Ÿ› lihuaib
    lihuaib

    ๐Ÿ› liqingjun123
    liqingjun123

    ๐Ÿ› lonelyma1021
    lonelyma1021

    ๐Ÿ› lpeddy
    lpeddy

    ๐Ÿ› lujiefsi
    lujiefsi

    ๐Ÿ’ป lukelukes
    lukelukes

    ๐Ÿ’ป - lyriccoder
    lyriccoder

    ๐Ÿ› + lyriccoder
    lyriccoder

    ๐Ÿ› marcelmore
    marcelmore

    ๐Ÿ› matchbox
    matchbox

    ๐Ÿ› matthiaskraaz
    matthiaskraaz

    ๐Ÿ› meandonlyme
    meandonlyme

    ๐Ÿ› mikesive
    mikesive

    ๐Ÿ› milossesic
    milossesic

    ๐Ÿ› - mluckam
    mluckam

    ๐Ÿ’ป ๐Ÿ› + mluckam
    mluckam

    ๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
    mohan-chinnappan-n

    ๐Ÿ’ป mriddell95
    mriddell95

    ๐Ÿ› mrlzh
    mrlzh

    ๐Ÿ› msloan
    msloan

    ๐Ÿ› mucharlaravalika
    mucharlaravalika

    ๐Ÿ› mvenneman
    mvenneman

    ๐Ÿ› - nareshl119
    nareshl119

    ๐Ÿ› + nareshl119
    nareshl119

    ๐Ÿ› nicolas-harraudeau-sonarsource
    nicolas-harraudeau-sonarsource

    ๐Ÿ› noerremark
    noerremark

    ๐Ÿ› novsirion
    novsirion

    ๐Ÿ› nwcm
    nwcm

    ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
    oggboy

    ๐Ÿ› oinume
    oinume

    ๐Ÿ› - orimarko
    orimarko

    ๐Ÿ’ป ๐Ÿ› + orimarko
    orimarko

    ๐Ÿ’ป ๐Ÿ› pablogomez2197
    pablogomez2197

    ๐Ÿ› pacvz
    pacvz

    ๐Ÿ’ป pallavi agarwal
    pallavi agarwal

    ๐Ÿ› pankratz76
    pankratz76

    ๐Ÿ› parksungrin
    parksungrin

    ๐Ÿ› patpatpat123
    patpatpat123

    ๐Ÿ› - patriksevallius
    patriksevallius

    ๐Ÿ› + patriksevallius
    patriksevallius

    ๐Ÿ› pbrajesh1
    pbrajesh1

    ๐Ÿ› phoenix384
    phoenix384

    ๐Ÿ› piotrszymanski-sc
    piotrszymanski-sc

    ๐Ÿ’ป plan3d
    plan3d

    ๐Ÿ› poojasix
    poojasix

    ๐Ÿ› prabhushrikant
    prabhushrikant

    ๐Ÿ› - pujitha8783
    pujitha8783

    ๐Ÿ› + pujitha8783
    pujitha8783

    ๐Ÿ› r-r-a-j
    r-r-a-j

    ๐Ÿ› raghujayjunk
    raghujayjunk

    ๐Ÿ› rajeshveera
    rajeshveera

    ๐Ÿ› rajeswarreddy88
    rajeswarreddy88

    ๐Ÿ› recdevs
    recdevs

    ๐Ÿ› reudismam
    reudismam

    ๐Ÿ’ป ๐Ÿ› - rijkt
    rijkt

    ๐Ÿ› + rijkt
    rijkt

    ๐Ÿ› rillig-tk
    rillig-tk

    ๐Ÿ› rmohan20
    rmohan20

    ๐Ÿ’ป ๐Ÿ› rnveach
    rnveach

    ๐Ÿ› rxmicro
    rxmicro

    ๐Ÿ› ryan-gustafson
    ryan-gustafson

    ๐Ÿ’ป ๐Ÿ› sabi0
    sabi0

    ๐Ÿ› - samc-gearset
    samc-gearset

    ๐Ÿ“– + samc-gearset
    samc-gearset

    ๐Ÿ“– scais
    scais

    ๐Ÿ› schosin
    schosin

    ๐Ÿ› screamingfrog
    screamingfrog

    ๐Ÿ’ต sebbASF
    sebbASF

    ๐Ÿ› sergeygorbaty
    sergeygorbaty

    ๐Ÿ’ป shilko2013
    shilko2013

    ๐Ÿ› - shiomiyan
    shiomiyan

    ๐Ÿ“– + shiomiyan
    shiomiyan

    ๐Ÿ“– simeonKondr
    simeonKondr

    ๐Ÿ› snajberk
    snajberk

    ๐Ÿ› sniperrifle2004
    sniperrifle2004

    ๐Ÿ› snuyanzin
    snuyanzin

    ๐Ÿ› ๐Ÿ’ป soloturn
    soloturn

    ๐Ÿ› soyodream
    soyodream

    ๐Ÿ› - sratz
    sratz

    ๐Ÿ› + sratz
    sratz

    ๐Ÿ› stonio
    stonio

    ๐Ÿ› sturton
    sturton

    ๐Ÿ’ป ๐Ÿ› sudharmohan
    sudharmohan

    ๐Ÿ› suruchidawar
    suruchidawar

    ๐Ÿ› svenfinitiv
    svenfinitiv

    ๐Ÿ› szymanp23
    szymanp23

    ๐Ÿ› ๐Ÿ’ป - tashiscool
    tashiscool

    ๐Ÿ› + tashiscool
    tashiscool

    ๐Ÿ› test-git-hook
    test-git-hook

    ๐Ÿ› testation21
    testation21

    ๐Ÿ’ป ๐Ÿ› thanosa
    thanosa

    ๐Ÿ› tiandiyixian
    tiandiyixian

    ๐Ÿ› tobwoerk
    tobwoerk

    ๐Ÿ› tprouvot
    tprouvot

    ๐Ÿ› ๐Ÿ’ป - trentchilders
    trentchilders

    ๐Ÿ› + trentchilders
    trentchilders

    ๐Ÿ› triandicAnt
    triandicAnt

    ๐Ÿ› trishul14
    trishul14

    ๐Ÿ› tsui
    tsui

    ๐Ÿ› wangzitom12306
    wangzitom12306

    ๐Ÿ› winhkey
    winhkey

    ๐Ÿ› witherspore
    witherspore

    ๐Ÿ› - wjljack
    wjljack

    ๐Ÿ› + wjljack
    wjljack

    ๐Ÿ› wuchiuwong
    wuchiuwong

    ๐Ÿ› xingsong
    xingsong

    ๐Ÿ› xioayuge
    xioayuge

    ๐Ÿ› xnYi9wRezm
    xnYi9wRezm

    ๐Ÿ’ป ๐Ÿ› xuanuy
    xuanuy

    ๐Ÿ› xyf0921
    xyf0921

    ๐Ÿ› - yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› + yalechen-cyw3
    yalechen-cyw3

    ๐Ÿ› yarlpavaworkday
    yarlpavaworkday

    ๐Ÿ› yasuharu-sato
    yasuharu-sato

    ๐Ÿ› zenglian
    zenglian

    ๐Ÿ› zgrzyt93
    zgrzyt93

    ๐Ÿ’ป ๐Ÿ› zh3ng
    zh3ng

    ๐Ÿ› zt_soft
    zt_soft

    ๐Ÿ› - ztt79
    ztt79

    ๐Ÿ› + ztt79
    ztt79

    ๐Ÿ› zzzzfeng
    zzzzfeng

    ๐Ÿ› รrpรกd Magosรกnyi
    รrpรกd Magosรกnyi

    ๐Ÿ› ไปป่ดตๆฐ
    ไปป่ดตๆฐ

    ๐Ÿ› From 229c0848d1ecd802fa644d5f7ee0c8e0620da8dd Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Apr 2025 15:25:03 +0200 Subject: [PATCH 0833/1962] Bump nokogiri from 1.18.5 to 1.18.8 (#5704) Fixes https://github.com/pmd/pmd/security/dependabot/80 Fixes https://github.com/pmd/pmd/security/dependabot/81 --- .ci/files/Gemfile.lock | 4 ++-- docs/Gemfile.lock | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.ci/files/Gemfile.lock b/.ci/files/Gemfile.lock index f70b618d267..8d3b87d7eb2 100644 --- a/.ci/files/Gemfile.lock +++ b/.ci/files/Gemfile.lock @@ -10,12 +10,12 @@ GEM fugit (1.11.1) et-orbi (~> 1, >= 1.2.11) raabro (~> 1.4) - liquid (5.8.4) + liquid (5.8.6) bigdecimal strscan (>= 3.1.1) logger (1.7.0) logger-colors (1.0.0) - nokogiri (1.18.5-x86_64-linux-gnu) + nokogiri (1.18.8-x86_64-linux-gnu) racc (~> 1.4) ostruct (0.6.1) pmdtester (1.5.5) diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index a4b72b43116..c48e4cfd195 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -26,7 +26,7 @@ GEM colorator (1.1.0) commonmarker (0.23.11) concurrent-ruby (1.3.5) - connection_pool (2.5.0) + connection_pool (2.5.2) csv (3.3.4) dnsruby (1.72.4) base64 (~> 0.2.0) @@ -40,13 +40,13 @@ GEM ffi (>= 1.15.0) eventmachine (1.2.7) execjs (2.10.0) - faraday (2.12.2) + faraday (2.13.0) faraday-net_http (>= 2.0, < 3.5) json logger faraday-net_http (3.4.0) net-http (>= 0.5.0) - ffi (1.17.1-x86_64-linux-gnu) + ffi (1.17.2-x86_64-linux-gnu) forwardable-extended (2.6.0) gemoji (4.1.0) github-pages (232) @@ -217,7 +217,7 @@ GEM gemoji (>= 3, < 5) html-pipeline (~> 2.2) jekyll (>= 3.0, < 5.0) - json (2.10.2) + json (2.11.0) kramdown (2.4.0) rexml kramdown-parser-gfm (1.1.0) @@ -235,7 +235,7 @@ GEM minitest (5.25.5) net-http (0.6.0) uri - nokogiri (1.18.5-x86_64-linux-gnu) + nokogiri (1.18.8-x86_64-linux-gnu) racc (~> 1.4) octokit (4.25.1) faraday (>= 1, < 3) From 9df4fdfd82f6ceb5a626442d64bfa4fb9baa3622 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Apr 2025 15:31:17 +0200 Subject: [PATCH 0834/1962] [ci] Do not run step pmd-actions-helper-app-token on forks --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 21f4f4adb4d..26b3deba981 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -69,6 +69,8 @@ jobs: .ci/$f - uses: actions/create-github-app-token@v2 id: pmd-actions-helper-app-token + # only run in the official pmd repo, where we have access to the secrets and not on forks + if: github.repository == 'pmd/pmd' with: app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} private-key: ${{ secrets.PMD_ACTIONS_HELPER_PRIVATE_KEY }} From 8aa7b5f5d66ff5521f6de0d181543d0e54029839 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Apr 2025 15:38:28 +0200 Subject: [PATCH 0835/1962] [doc] Support doc links in release notes Use an existing page as an example due to DeadLinksChecker --- do-release.sh | 4 ++-- docs/pages/pmd/projectdocs/committers/releasing.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/do-release.sh b/do-release.sh index 975baa306dc..509188bc836 100755 --- a/do-release.sh +++ b/do-release.sh @@ -258,8 +258,8 @@ keywords: changelog, release notes {% if is_release_notes_processor %} {% comment %} -This allows to use links like [Page]({{ basedir }}pmd_devdocs_page.html) that work both in the release notes -on GitHub (as an absolute url) and on the rendered documentation page (as a relative url). +This allows to use links e.g. [Basic CLI usage]({{ basedir }}pmd_userdocs_installation.html) that work both +in the release notes on GitHub (as an absolute url) and on the rendered documentation page (as a relative url). {% endcomment %} {% capture baseurl %}https://docs.pmd-code.org/pmd-doc-{{ site.pmd.version }}/{% endcapture %} {% else %} diff --git a/docs/pages/pmd/projectdocs/committers/releasing.md b/docs/pages/pmd/projectdocs/committers/releasing.md index c7b95ca20fd..2c81c40167a 100644 --- a/docs/pages/pmd/projectdocs/committers/releasing.md +++ b/docs/pages/pmd/projectdocs/committers/releasing.md @@ -344,8 +344,8 @@ keywords: changelog, release notes {% if is_release_notes_processor %} {% comment %} -This allows to use links like [Page]({{ basedir }}pmd_devdocs_page.html) that work both in the release notes -on GitHub (as an absolute url) and on the rendered documentation page (as a relative url). +This allows to use links e.g. [Basic CLI usage]({{ basedir }}pmd_userdocs_installation.html) that work both +in the release notes on GitHub (as an absolute url) and on the rendered documentation page (as a relative url). {% endcomment %} {% capture baseurl %}https://docs.pmd-code.org/pmd-doc-{{ site.pmd.version }}/{% endcapture %} {% else %} From 95c3c12c19fbb9a7f8a6ea98900001e1321abaee Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Apr 2025 16:03:48 +0200 Subject: [PATCH 0836/1962] [doc] Support doc links in release notes Fix the example. The variable is named "baseurl"... --- do-release.sh | 2 +- docs/pages/pmd/projectdocs/committers/releasing.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/do-release.sh b/do-release.sh index 509188bc836..34175530973 100755 --- a/do-release.sh +++ b/do-release.sh @@ -258,7 +258,7 @@ keywords: changelog, release notes {% if is_release_notes_processor %} {% comment %} -This allows to use links e.g. [Basic CLI usage]({{ basedir }}pmd_userdocs_installation.html) that work both +This allows to use links e.g. [Basic CLI usage]({{ baseurl }}pmd_userdocs_installation.html) that work both in the release notes on GitHub (as an absolute url) and on the rendered documentation page (as a relative url). {% endcomment %} {% capture baseurl %}https://docs.pmd-code.org/pmd-doc-{{ site.pmd.version }}/{% endcapture %} diff --git a/docs/pages/pmd/projectdocs/committers/releasing.md b/docs/pages/pmd/projectdocs/committers/releasing.md index 2c81c40167a..4ff39f433eb 100644 --- a/docs/pages/pmd/projectdocs/committers/releasing.md +++ b/docs/pages/pmd/projectdocs/committers/releasing.md @@ -344,7 +344,7 @@ keywords: changelog, release notes {% if is_release_notes_processor %} {% comment %} -This allows to use links e.g. [Basic CLI usage]({{ basedir }}pmd_userdocs_installation.html) that work both +This allows to use links e.g. [Basic CLI usage]({{ baseurl }}pmd_userdocs_installation.html) that work both in the release notes on GitHub (as an absolute url) and on the rendered documentation page (as a relative url). {% endcomment %} {% capture baseurl %}https://docs.pmd-code.org/pmd-doc-{{ site.pmd.version }}/{% endcapture %} From 9201cc977022227ff299ab79ebd2cda80d40dee6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Apr 2025 12:01:59 +0200 Subject: [PATCH 0837/1962] Fix typos and nitpicks --- .../major_contributions/adding_a_dialect.md | 14 +++++------ .../java/net/sourceforge/pmd/PmdAnalysis.java | 4 +-- .../net/sourceforge/pmd/lang/Language.java | 4 ++- .../pmd/lang/LanguageModuleBase.java | 25 +++++++++++-------- .../BasePmdDialectLanguageVersionHandler.java | 1 + .../impl/SimpleDialectLanguageModuleBase.java | 1 + .../lang/rule/xpath/impl/XPathHandler.java | 3 ++- .../pmd/lang/xml/pom/PomDialectModule.java | 4 +++ .../pmd/lang/xml/pom/PomLanguageModule.java | 2 +- .../pmd/lang/xml/wsdl/WsdlDialectModule.java | 3 +++ .../pmd/lang/xml/wsdl/WsdlLanguageModule.java | 2 +- .../pmd/lang/xml/xsl/XslDialectModule.java | 3 +++ .../pmd/lang/xml/xsl/XslLanguageModule.java | 2 +- 13 files changed, 44 insertions(+), 24 deletions(-) diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_dialect.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_dialect.md index 0df155b496a..5c40da53678 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_a_dialect.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_dialect.md @@ -1,7 +1,7 @@ --- title: Adding PMD support for a new dialect for an already existing language short_title: Adding a new dialect -tags: [devdocs, extending] +tags: [devdocs, extending, experimental] summary: "How to add a new dialect." last_updated: April 2025 (7.13.0) sidebar: pmd_sidebar @@ -14,10 +14,10 @@ folder: pmd/devdocs **What is a dialect?**

    A dialect is a particular form of another supported language. For example, an XSLT is a particular form of an XML. -Even though the dialect has it's own seantics and uses, the contents are still readable by any tool capable of understanding the base language.

    +Even though the dialect has its own semantics and uses, the contents are still readable by any tool capable of understanding the base language.

    In PMD, a dialect allows to set up completely custom rules, XPath functions, properties and metrics for these files; -while retaining the full support of the underlaying language. That means:

    +while retaining the full support of the underlying language. That means:

    - All rules applicable to the base language are automatically applicable to all files processed as a dialect.
    - All XPath functions existing in the base language are available when creating new rules.
    @@ -31,13 +31,13 @@ while retaining the full support of the underlaying language. That means:


    getApplicableLanguages(boolean quiet) { changed = false; for (Language lang : reg) { if (lang.getBaseLanguageId() != null) { - Language depLang = reg.getLanguageById(lang.getBaseLanguageId()); - if (depLang != null && languages.contains(depLang)) { + Language baseLang = reg.getLanguageById(lang.getBaseLanguageId()); + if (baseLang != null && languages.contains(baseLang)) { changed |= languages.add(lang); } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java index e2dadee2fa3..c47312ddef9 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java @@ -69,6 +69,7 @@ public interface Language extends Comparable { * Dialects are for example different flavors of XML. Dialects must share * the same AST as their base language. This makes it so that rules written * for the base language can be applied files of all dialects uniformly. + * @experimental Since 7.13.0. See [core] Support language dialects #5438. */ @Experimental default @Nullable String getBaseLanguageId() { @@ -76,9 +77,10 @@ public interface Language extends Comparable { } /** - * Return true if this language is the given language, or a dialect thereof. + * Return true if this language is a dialect of the given language. * * @param language A language (not null) + * @experimental Since 7.13.0. See [core] Support language dialects #5438. */ @Experimental @SuppressWarnings("PMD.SimplifyBooleanReturns") diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageModuleBase.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageModuleBase.java index c2ac58d5a5c..b3d095c123f 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageModuleBase.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageModuleBase.java @@ -54,6 +54,14 @@ protected LanguageModuleBase(LanguageMetadata metadata) { this(metadata, null); } + /** + * @experimental Since 7.13.0. See [core] Support language dialects #5438. + */ + @Experimental + protected LanguageModuleBase(DialectLanguageMetadata metadata) { + this(metadata.metadata, metadata.baseLanguageId); + } + private LanguageModuleBase(LanguageMetadata metadata, String baseLanguageId) { this.meta = metadata; metadata.validate(); @@ -102,11 +110,6 @@ private LanguageModuleBase(LanguageMetadata metadata, String baseLanguageId) { this.defaultVersion = Objects.requireNonNull(defaultVersion, "No default version for " + getId()); } - @Experimental - protected LanguageModuleBase(DialectLanguageMetadata metadata) { - this(metadata.metadata, metadata.baseLanguageId); - } - private static void checkNotPresent(Map map, String alias) { if (map.containsKey(alias)) { throw new IllegalArgumentException("Version key '" + alias + "' is duplicated"); @@ -370,14 +373,15 @@ public LanguageMetadata addAllVersionsOf(Language language) { /** * Defines the language as a dialect of another language. * - * @param id The id of the base language this is a dialect of. + * @param baseLanguageId The id of the base language this is a dialect of. * @return A new dialect language metadata model. + * @experimental Since 7.13.0. See [core] Support language dialects #5438. */ @Experimental - public DialectLanguageMetadata asDialectOf(String id) { - checkValidLangId(id); - dependsOnLanguage(id); // a dialect automatically depends on it's base language at runtime - return new DialectLanguageMetadata(this, id); + public DialectLanguageMetadata asDialectOf(String baseLanguageId) { + checkValidLangId(baseLanguageId); + dependsOnLanguage(baseLanguageId); // a dialect automatically depends on it's base language at runtime + return new DialectLanguageMetadata(this, baseLanguageId); } private static void checkValidLangId(String id) { @@ -438,6 +442,7 @@ private static void checkVersionName(String name) { /** * Expresses the language as a dialect of another language. + * @experimental Since 7.13.0. See [core] Support language dialects #5438. */ @Experimental public static final class DialectLanguageMetadata { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/BasePmdDialectLanguageVersionHandler.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/BasePmdDialectLanguageVersionHandler.java index d725df43d79..2fe55b0f615 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/BasePmdDialectLanguageVersionHandler.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/BasePmdDialectLanguageVersionHandler.java @@ -14,6 +14,7 @@ * * @author Juan Martรญn Sotuyo Dodero * @since 7.13.0 + * @experimental Since 7.13.0. See [core] Support language dialects #5438. */ @Experimental public class BasePmdDialectLanguageVersionHandler extends AbstractPmdLanguageVersionHandler { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java index 6c9941f8c45..4b703e4db38 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java @@ -40,6 +40,7 @@ * * @author Juan Martรญn Sotuyo Dodero * @since 7.13.0 + * @experimental Since 7.13.0. See [core] Support language dialects #5438. */ @Experimental public class SimpleDialectLanguageModuleBase extends LanguageModuleBase implements PmdCapableLanguage, CpdCapableLanguage { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/impl/XPathHandler.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/impl/XPathHandler.java index fe71b8305e0..0849b955702 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/impl/XPathHandler.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/impl/XPathHandler.java @@ -42,7 +42,8 @@ static XPathHandler getHandlerForFunctionDefs(XPathFunctionDefinition first, XPa /** * Return a new XPath handler combining all available functions from this and another handler. * @param other The handler whose functions to merge with this one. - * @return Anew handler exposing all functions from both XPath handlers. + * @return A new handler exposing all functions from both XPath handlers. + * @since 7.13.0 */ default XPathHandler combine(XPathHandler other) { Set set = new HashSet<>(getRegisteredExtensionFunctions()); diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomDialectModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomDialectModule.java index 54b6c48602f..59aa1ae790d 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomDialectModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomDialectModule.java @@ -7,6 +7,10 @@ import net.sourceforge.pmd.lang.LanguageRegistry; import net.sourceforge.pmd.lang.impl.SimpleDialectLanguageModuleBase; +/** + * Since PMD 7.13.0 this is a dialect of XML. Before that, POM was a language module on its own. + * @since 7.13.0 + */ public class PomDialectModule extends SimpleDialectLanguageModuleBase { private static final String ID = "pom"; diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java index 311898f48bd..aca61a68b96 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java @@ -13,7 +13,7 @@ /** * This language module is deprecated. POM is now a dialect of XML. - * @deprecated Use @link{PomDialectModule} instead. + * @deprecated Since 7.13.0. Use @link{PomDialectModule} instead. */ @Deprecated public class PomLanguageModule extends SimpleLanguageModuleBase { diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlDialectModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlDialectModule.java index a977d2cc0cd..a1745811dc0 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlDialectModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlDialectModule.java @@ -9,6 +9,9 @@ /** * Created by bernardo-macedo on 24.06.15. + * + *

    Since PMD 7.13.0 this is a dialect of XML. Before that, WSDL was a language module on its own. + * @since 7.13.0 */ public class WsdlDialectModule extends SimpleDialectLanguageModuleBase { private static final String ID = "wsdl"; diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java index 5126fd1b769..b849bd79d9d 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java @@ -13,7 +13,7 @@ /** * This language module is deprecated. WSDL is now a dialect of XML. - * @deprecated Use @link{WsdlDialectModule} instead. + * @deprecated Since 7.13.0. Use @link{WsdlDialectModule} instead. */ @Deprecated public class WsdlLanguageModule extends SimpleLanguageModuleBase { diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslDialectModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslDialectModule.java index d83723eb21a..94d9f7afa95 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslDialectModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslDialectModule.java @@ -9,6 +9,9 @@ /** * Created by christoferdutz on 20.09.14. + * + *

    Since PMD 7.13.0 this is a dialect of XML. Before that, XSL was a language module on its own. + * @since 7.13.0 */ public class XslDialectModule extends SimpleDialectLanguageModuleBase { private static final String ID = "xsl"; diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java index 0b8178dfc78..1dd2e7efbd6 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java @@ -13,7 +13,7 @@ /** * This language module is deprecated. XSL is now a dialect of XML. - * @deprecated Use @link{XslDialectModule} instead. + * @deprecated Since 7.13.0. Use @link{XslDialectModule} instead. */ @Deprecated public class XslLanguageModule extends SimpleLanguageModuleBase { From 63bc45a905444523bee6e5de6d38ac4edba1e399 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 25 Apr 2025 08:53:58 +0200 Subject: [PATCH 0838/1962] [doc] Update release notes (#5438) --- docs/pages/release_notes.md | 38 +++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index dcd67d4ce7a..c8a533106c6 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -4,6 +4,12 @@ permalink: pmd_release_notes.html keywords: changelog, release notes --- +{% if is_release_notes_processor %} +{% capture baseurl %}https://docs.pmd-code.org/pmd-doc-{{ site.pmd.version }}/{% endcapture %} +{% else %} +{% assign baseurl = "" %} +{% endif %} + ## {{ site.pmd.date | date: "%d-%B-%Y" }} - {{ site.pmd.version }} The PMD team is pleased to announce PMD {{ site.pmd.version }}. @@ -27,6 +33,19 @@ docker run --rm --tty -v $PWD:/src pmdcode/pmd:latest check -d . -R rulesets/jav More information is available at . +#### Experimental support for language dialects + +A dialect is a particular form of another supported language. For example, an XSLT is a particular +form of an XML. Even though the dialect has its own semantics and uses, the contents are still readable +by any tool capable of understanding the base language. + +In PMD, a dialect allows to set up completely custom rules, XPath functions, properties and metrics +for these files; while retaining the full support of the underlying base language including +already existing rules and XPath functions. + +See [[core] Support language dialects #5438](https://github.com/pmd/pmd/pull/5438) and +[Adding a new dialect]({{ baseurl }}pmd_devdocs_major_adding_dialect.html) for more information. + #### โœจ New Rules * The new Apex rule {% rule apex/errorprone/TypeShadowsBuiltInNamespace %} finds Apex classes, enums, and interfaces @@ -35,6 +54,7 @@ More information is available at . ### ๐Ÿ› Fixed Issues * core + * [#5438](https://github.com/pmd/pmd/issues/5438): \[core] Support language dialects * [#5448](https://github.com/pmd/pmd/issues/5448): Maintain a public PMD docker image * [#5525](https://github.com/pmd/pmd/issues/5525): \[core] Add rule priority as level to Sarif report * [#5623](https://github.com/pmd/pmd/issues/5623): \[dist] Make pmd launch script compatible with /bin/sh @@ -51,6 +71,24 @@ More information is available at . ### ๐Ÿšจ API Changes +#### Deprecations +* {%jdoc !!xml::lang.xml.pom.PomLanguageModule %} is deprecated. POM is now a dialect of XML. + Use {%jdoc xml::lang.xml.pom.PomDialectModule %} instead. +* {%jdoc !!xml::lang.xml.wsdl.WsdlLanguageModule %} is deprecated. WSDL is now a dialect of XML. + Use {%jdoc xml::lang.xml.wsdl.WsdlDialectModule %} instead. +* {%jdoc !!xml::lang.xml.xsl.XslLanguageModule %} is deprecated. XSL is now a dialect of XML. + Use {%jdoc xml::lang.xml.xsl.XslDialectModule %} instead. + +#### Experimental API +* The core API around support for language dialects: + * {%jdoc !!core::lang.Language#getBaseLanguageId() %} + * {%jdoc !!core::lang.Language#isDialectOf(core::lang.Language) %} + * {%jdoc !!core::lang.LanguageModuleBase#(core::lang.LanguageModuleBase.DialectLanguageMetadata) %} + * {%jdoc !!core::lang.LanguageModuleBase#asDialectOf(java.lang.String) %} + * {%jdoc core::lang.LanguageModuleBase.DialectLanguageMetadata %} + * {%jdoc core::lang.impl.BasePmdDialectLanguageVersionHandler %} + * {%jdoc core::lang.impl.SimpleDialectLanguageModuleBase %} + ### โœจ Merged pull requests * [#5450](https://github.com/pmd/pmd/pull/5450): Fix #3184: \[apex] New Rule: TypeShadowsBuiltInNamespace - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) From fe82db328851693aef75e18fb0399525cc145c90 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 25 Apr 2025 09:36:29 +0200 Subject: [PATCH 0839/1962] Prepare pmd release 7.13.0 --- docs/_config.yml | 2 +- docs/pages/release_notes.md | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 50f986a8e48..8dc95511771 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,7 +1,7 @@ repository: pmd/pmd pmd: - version: 7.13.0-SNAPSHOT + version: 7.13.0 previous_version: 7.12.0 date: 2025-04-25 # release types: major, minor, bugfix diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index c8a533106c6..86a3f36e102 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -91,18 +91,51 @@ See [[core] Support language dialects #5438](https://github.com/pmd/pmd/pull/543 ### โœจ Merged pull requests +* [#5438](https://github.com/pmd/pmd/pull/5438): \[core] Support language dialects - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) * [#5450](https://github.com/pmd/pmd/pull/5450): Fix #3184: \[apex] New Rule: TypeShadowsBuiltInNamespace - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) * [#5573](https://github.com/pmd/pmd/pull/5573): Fix #5525: \[core] Add Sarif Level Property - [julees7](https://github.com/julees7) (@julees7) +* [#5623](https://github.com/pmd/pmd/pull/5623): \[dist] Make pmd launch script compatible with /bin/sh - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5648](https://github.com/pmd/pmd/pull/5648): Fix #5645: \[java] Parse error with yield statement - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5652](https://github.com/pmd/pmd/pull/5652): \[java] Cleanup `AccessorClassGenerationRule` implementation - [Pankraz76](https://github.com/Pankraz76) (@Pankraz76) * [#5672](https://github.com/pmd/pmd/pull/5672): \[doc] Fix its/it's and doable/double typos - [John Jetmore](https://github.com/jetmore) (@jetmore) +* [#5674](https://github.com/pmd/pmd/pull/5674): Fix #5448: \[ci] Maintain public Docker image - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5684](https://github.com/pmd/pmd/pull/5684): Fix #5667: \[apex] ApexUnitTestShouldNotUseSeeAllDataTrue false negative when seeAllDate parameter is a string - [Thomas Prouvot](https://github.com/tprouvot) (@tprouvot) * [#5685](https://github.com/pmd/pmd/pull/5685): \[doc] typo fix in PMD Designer reference - [Douglas Griffith](https://github.com/dwgrth) (@dwgrth) +* [#5686](https://github.com/pmd/pmd/pull/5686): Fix #5675: \[plsql] Support TREAT function with specified datatype - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5687](https://github.com/pmd/pmd/pull/5687): \[java] UnusedPrivateMethodRule: exclude serialization method readObjectNoData() - [Gili Tzabari](https://github.com/cowwoc) (@cowwoc) +* [#5688](https://github.com/pmd/pmd/pull/5688): \[java] Fix Double Literal for Java19+ compatibility - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ Dependency updates +* [#5607](https://github.com/pmd/pmd/pull/5607): Bump org.junit:junit-bom from 5.11.4 to 5.12.1 +* [#5641](https://github.com/pmd/pmd/pull/5641): Bump PMD from 7.11.0 to 7.12.0 +* [#5653](https://github.com/pmd/pmd/pull/5653): Bump org.sonarsource.scanner.maven:sonar-maven-plugin from 5.0.0.4389 to 5.1.0.4751 +* [#5654](https://github.com/pmd/pmd/pull/5654): Bump surefire.version from 3.5.2 to 3.5.3 +* [#5655](https://github.com/pmd/pmd/pull/5655): Bump com.google.guava:guava from 33.4.5-jre to 33.4.6-jre +* [#5656](https://github.com/pmd/pmd/pull/5656): Bump org.ow2.asm:asm from 9.7.1 to 9.8 +* [#5657](https://github.com/pmd/pmd/pull/5657): Bump com.google.protobuf:protobuf-java from 4.30.1 to 4.30.2 +* [#5658](https://github.com/pmd/pmd/pull/5658): Bump logger from 1.6.6 to 1.7.0 in /.ci/files in the all-gems group across 1 directory +* [#5671](https://github.com/pmd/pmd/pull/5671): Bump checkstyle from 10.21.4 to 10.23.0 +* [#5676](https://github.com/pmd/pmd/pull/5676): Bump org.checkerframework:checker-qual from 3.49.1 to 3.49.2 +* [#5677](https://github.com/pmd/pmd/pull/5677): Bump junit5.platform.version from 1.12.1 to 1.12.2 +* [#5678](https://github.com/pmd/pmd/pull/5678): Bump org.apache.commons:commons-text from 1.13.0 to 1.13.1 +* [#5679](https://github.com/pmd/pmd/pull/5679): Bump com.google.guava:guava from 33.4.6-jre to 33.4.7-jre +* [#5680](https://github.com/pmd/pmd/pull/5680): Bump org.mockito:mockito-core from 5.16.1 to 5.17.0 +* [#5681](https://github.com/pmd/pmd/pull/5681): Bump org.jacoco:jacoco-maven-plugin from 0.8.12 to 0.8.13 +* [#5682](https://github.com/pmd/pmd/pull/5682): Bump net.bytebuddy:byte-buddy-agent from 1.17.4 to 1.17.5 +* [#5683](https://github.com/pmd/pmd/pull/5683): Bump the all-gems group across 2 directories with 2 updates +* [#5691](https://github.com/pmd/pmd/pull/5691): Bump com.google.code.gson:gson from 2.12.1 to 2.13.0 +* [#5692](https://github.com/pmd/pmd/pull/5692): Bump com.google.guava:guava from 33.4.7-jre to 33.4.8-jre +* [#5693](https://github.com/pmd/pmd/pull/5693): Bump net.bytebuddy:byte-buddy from 1.17.4 to 1.17.5 +* [#5694](https://github.com/pmd/pmd/pull/5694): Bump org.junit:junit-bom from 5.12.1 to 5.12.2 +* [#5696](https://github.com/pmd/pmd/pull/5696): Bump info.picocli:picocli from 4.7.6 to 4.7.7 +* [#5697](https://github.com/pmd/pmd/pull/5697): Bump com.github.hazendaz.maven:coveralls-maven-plugin from 4.5.0-M6 to 4.7.0 +* [#5704](https://github.com/pmd/pmd/pull/5704): Bump nokogiri from 1.18.5 to 1.18.8 ### ๐Ÿ“ˆ Stats +* 117 commits +* 19 closed tickets & PRs +* Days since last release: 27 {% endtocmaker %} - From d83c182d3e05d3edf727214d0b95c5fd56a28aee Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 25 Apr 2025 09:55:01 +0200 Subject: [PATCH 0840/1962] [release] prepare release pmd_releases/7.13.0 --- pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-rust/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 6 +++--- 43 files changed, 45 insertions(+), 45 deletions(-) diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index b906189239c..c0adab851c1 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.13.0-SNAPSHOT + 7.13.0 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 3a8d357f1cb..07c34d3d8c6 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index c4f15231614..eaee38896e0 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index 4c13d61659d..fcdba79e8bd 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index 5ca0a720746..a2a8aa008b7 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index 72e9cb54d70..027c5c34d8d 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index 9740bb4f140..2452946d3e5 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index 6ba266b69ff..68ada41d8c6 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index e53281eeb54..e253110025d 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index d6c88b57dd8..204c42fe5da 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index 20fcc80e090..8027565a5a9 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index 5143ea4ca5d..d2e6fadb441 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index 7bcabf98a7d..4715cfddd65 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index db3f7e3565f..f03f4a8ede5 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index 4f1001668a3..c911e13868e 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 25b694f8c43..fdc7fe7896e 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index 941c426c69f..75c97ec2684 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index d643e5e61cc..a9e128f2000 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index a2f84bc3892..62b3dbbacde 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index 5b101c3e834..3e2c4bb8432 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index fcbaaf0bcc2..493b92e796e 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index fe80ca8b3c3..345022f7f55 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index faafa913d42..a88863ed7c0 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index 74da11164b5..9777410725a 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index b2ffd931ec8..d412494e70f 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index 37191395781..769db2e7ece 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index 327d1ecdfa9..f006ab8e250 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index 2955ffe5f15..7444c4f58f5 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index 6ed4d943531..dc83d57d556 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index 1d2764a5cb0..908ae08f176 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index 7738bd59c9d..11fd1b96b05 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index bff8f329247..7c42bd68589 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index e0d9fb00dba..3adcf4d74e8 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index 821b1e079d4..24c308485d2 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.13.0-SNAPSHOT + 7.13.0 ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index b6ad8a0fae9..a0c6bd42c69 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.13.0-SNAPSHOT + 7.13.0 ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index 0b6554fdd20..ad1bd5c1c36 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index 0ab022ea37f..d442a7f96f2 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index 42f6df8822c..6e1de287c45 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index 433ddd8e70f..55ee423dc02 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index 2f383fc2043..b545b476284 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index 83ea2f92d41..de7918f4cf1 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index 7f0975f412b..77db17b43ac 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 ../pom.xml diff --git a/pom.xml b/pom.xml index e1cf34b9723..dc0aa03b747 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.13.0-SNAPSHOT + 7.13.0 pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - HEAD + pmd_releases/7.13.0 @@ -83,7 +83,7 @@ - 2025-03-28T07:27:05Z + 2025-04-25T07:36:41Z 8 From f62f8af12bab3eda802954b85de8d0e6af7ed8df Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 25 Apr 2025 10:25:24 +0200 Subject: [PATCH 0841/1962] [release] Prepare next development version [skip ci] --- docs/_config.yml | 6 +- docs/pages/release_notes.md | 110 +--------------- docs/pages/release_notes_old.md | 142 +++++++++++++++++++++ pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-rust/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 4 +- 46 files changed, 194 insertions(+), 152 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 8dc95511771..c47ee3dfa4e 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,9 +1,9 @@ repository: pmd/pmd pmd: - version: 7.13.0 - previous_version: 7.12.0 - date: 2025-04-25 + version: 7.14.0-SNAPSHOT + previous_version: 7.13.0 + date: 2025-05-30 # release types: major, minor, bugfix release_type: minor diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 86a3f36e102..0c9c0dd3524 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -5,6 +5,10 @@ keywords: changelog, release notes --- {% if is_release_notes_processor %} +{% comment %} +This allows to use links e.g. [Basic CLI usage]({{ baseurl }}pmd_userdocs_installation.html) that work both +in the release notes on GitHub (as an absolute url) and on the rendered documentation page (as a relative url). +{% endcomment %} {% capture baseurl %}https://docs.pmd-code.org/pmd-doc-{{ site.pmd.version }}/{% endcapture %} {% else %} {% assign baseurl = "" %} @@ -20,122 +24,18 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy -#### Docker images - -PMD is now providing official docker images at and -. - -You can now analyze your code with PMD by using docker like so: - -``` -docker run --rm --tty -v $PWD:/src pmdcode/pmd:latest check -d . -R rulesets/java/quickstart.xml` -``` - -More information is available at . - -#### Experimental support for language dialects - -A dialect is a particular form of another supported language. For example, an XSLT is a particular -form of an XML. Even though the dialect has its own semantics and uses, the contents are still readable -by any tool capable of understanding the base language. - -In PMD, a dialect allows to set up completely custom rules, XPath functions, properties and metrics -for these files; while retaining the full support of the underlying base language including -already existing rules and XPath functions. - -See [[core] Support language dialects #5438](https://github.com/pmd/pmd/pull/5438) and -[Adding a new dialect]({{ baseurl }}pmd_devdocs_major_adding_dialect.html) for more information. - -#### โœจ New Rules - -* The new Apex rule {% rule apex/errorprone/TypeShadowsBuiltInNamespace %} finds Apex classes, enums, and interfaces - that have the same name as a class, enum, or interface in the `System` or `Schema` namespace. - Shadowing these namespaces in this way can lead to confusion and unexpected behavior. - ### ๐Ÿ› Fixed Issues -* core - * [#5438](https://github.com/pmd/pmd/issues/5438): \[core] Support language dialects - * [#5448](https://github.com/pmd/pmd/issues/5448): Maintain a public PMD docker image - * [#5525](https://github.com/pmd/pmd/issues/5525): \[core] Add rule priority as level to Sarif report - * [#5623](https://github.com/pmd/pmd/issues/5623): \[dist] Make pmd launch script compatible with /bin/sh -* apex-bestpractices - * [#5667](https://github.com/pmd/pmd/issues/5667): \[apex] ApexUnitTestShouldNotUseSeeAllDataTrue false negative when seeAllData parameter is a string -* apex-errorprone - * [#3184](https://github.com/pmd/pmd/issues/3184): \[apex] Prevent classes from shadowing System Namespace -* java - * [#5645](https://github.com/pmd/pmd/issues/5645): \[java] Parse error on switch with yield -* java-bestpractices - * [#5687](https://github.com/pmd/pmd/issues/5687): \[java] UnusedPrivateMethodRule: exclude serialization method readObjectNoData() -* plsql - * [#5675](https://github.com/pmd/pmd/issues/5675): \[plsql] Parse error with TREAT function ### ๐Ÿšจ API Changes -#### Deprecations -* {%jdoc !!xml::lang.xml.pom.PomLanguageModule %} is deprecated. POM is now a dialect of XML. - Use {%jdoc xml::lang.xml.pom.PomDialectModule %} instead. -* {%jdoc !!xml::lang.xml.wsdl.WsdlLanguageModule %} is deprecated. WSDL is now a dialect of XML. - Use {%jdoc xml::lang.xml.wsdl.WsdlDialectModule %} instead. -* {%jdoc !!xml::lang.xml.xsl.XslLanguageModule %} is deprecated. XSL is now a dialect of XML. - Use {%jdoc xml::lang.xml.xsl.XslDialectModule %} instead. - -#### Experimental API -* The core API around support for language dialects: - * {%jdoc !!core::lang.Language#getBaseLanguageId() %} - * {%jdoc !!core::lang.Language#isDialectOf(core::lang.Language) %} - * {%jdoc !!core::lang.LanguageModuleBase#(core::lang.LanguageModuleBase.DialectLanguageMetadata) %} - * {%jdoc !!core::lang.LanguageModuleBase#asDialectOf(java.lang.String) %} - * {%jdoc core::lang.LanguageModuleBase.DialectLanguageMetadata %} - * {%jdoc core::lang.impl.BasePmdDialectLanguageVersionHandler %} - * {%jdoc core::lang.impl.SimpleDialectLanguageModuleBase %} - ### โœจ Merged pull requests -* [#5438](https://github.com/pmd/pmd/pull/5438): \[core] Support language dialects - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) -* [#5450](https://github.com/pmd/pmd/pull/5450): Fix #3184: \[apex] New Rule: TypeShadowsBuiltInNamespace - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) -* [#5573](https://github.com/pmd/pmd/pull/5573): Fix #5525: \[core] Add Sarif Level Property - [julees7](https://github.com/julees7) (@julees7) -* [#5623](https://github.com/pmd/pmd/pull/5623): \[dist] Make pmd launch script compatible with /bin/sh - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5648](https://github.com/pmd/pmd/pull/5648): Fix #5645: \[java] Parse error with yield statement - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5652](https://github.com/pmd/pmd/pull/5652): \[java] Cleanup `AccessorClassGenerationRule` implementation - [Pankraz76](https://github.com/Pankraz76) (@Pankraz76) -* [#5672](https://github.com/pmd/pmd/pull/5672): \[doc] Fix its/it's and doable/double typos - [John Jetmore](https://github.com/jetmore) (@jetmore) -* [#5674](https://github.com/pmd/pmd/pull/5674): Fix #5448: \[ci] Maintain public Docker image - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5684](https://github.com/pmd/pmd/pull/5684): Fix #5667: \[apex] ApexUnitTestShouldNotUseSeeAllDataTrue false negative when seeAllDate parameter is a string - [Thomas Prouvot](https://github.com/tprouvot) (@tprouvot) -* [#5685](https://github.com/pmd/pmd/pull/5685): \[doc] typo fix in PMD Designer reference - [Douglas Griffith](https://github.com/dwgrth) (@dwgrth) -* [#5686](https://github.com/pmd/pmd/pull/5686): Fix #5675: \[plsql] Support TREAT function with specified datatype - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5687](https://github.com/pmd/pmd/pull/5687): \[java] UnusedPrivateMethodRule: exclude serialization method readObjectNoData() - [Gili Tzabari](https://github.com/cowwoc) (@cowwoc) -* [#5688](https://github.com/pmd/pmd/pull/5688): \[java] Fix Double Literal for Java19+ compatibility - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ Dependency updates -* [#5607](https://github.com/pmd/pmd/pull/5607): Bump org.junit:junit-bom from 5.11.4 to 5.12.1 -* [#5641](https://github.com/pmd/pmd/pull/5641): Bump PMD from 7.11.0 to 7.12.0 -* [#5653](https://github.com/pmd/pmd/pull/5653): Bump org.sonarsource.scanner.maven:sonar-maven-plugin from 5.0.0.4389 to 5.1.0.4751 -* [#5654](https://github.com/pmd/pmd/pull/5654): Bump surefire.version from 3.5.2 to 3.5.3 -* [#5655](https://github.com/pmd/pmd/pull/5655): Bump com.google.guava:guava from 33.4.5-jre to 33.4.6-jre -* [#5656](https://github.com/pmd/pmd/pull/5656): Bump org.ow2.asm:asm from 9.7.1 to 9.8 -* [#5657](https://github.com/pmd/pmd/pull/5657): Bump com.google.protobuf:protobuf-java from 4.30.1 to 4.30.2 -* [#5658](https://github.com/pmd/pmd/pull/5658): Bump logger from 1.6.6 to 1.7.0 in /.ci/files in the all-gems group across 1 directory -* [#5671](https://github.com/pmd/pmd/pull/5671): Bump checkstyle from 10.21.4 to 10.23.0 -* [#5676](https://github.com/pmd/pmd/pull/5676): Bump org.checkerframework:checker-qual from 3.49.1 to 3.49.2 -* [#5677](https://github.com/pmd/pmd/pull/5677): Bump junit5.platform.version from 1.12.1 to 1.12.2 -* [#5678](https://github.com/pmd/pmd/pull/5678): Bump org.apache.commons:commons-text from 1.13.0 to 1.13.1 -* [#5679](https://github.com/pmd/pmd/pull/5679): Bump com.google.guava:guava from 33.4.6-jre to 33.4.7-jre -* [#5680](https://github.com/pmd/pmd/pull/5680): Bump org.mockito:mockito-core from 5.16.1 to 5.17.0 -* [#5681](https://github.com/pmd/pmd/pull/5681): Bump org.jacoco:jacoco-maven-plugin from 0.8.12 to 0.8.13 -* [#5682](https://github.com/pmd/pmd/pull/5682): Bump net.bytebuddy:byte-buddy-agent from 1.17.4 to 1.17.5 -* [#5683](https://github.com/pmd/pmd/pull/5683): Bump the all-gems group across 2 directories with 2 updates -* [#5691](https://github.com/pmd/pmd/pull/5691): Bump com.google.code.gson:gson from 2.12.1 to 2.13.0 -* [#5692](https://github.com/pmd/pmd/pull/5692): Bump com.google.guava:guava from 33.4.7-jre to 33.4.8-jre -* [#5693](https://github.com/pmd/pmd/pull/5693): Bump net.bytebuddy:byte-buddy from 1.17.4 to 1.17.5 -* [#5694](https://github.com/pmd/pmd/pull/5694): Bump org.junit:junit-bom from 5.12.1 to 5.12.2 -* [#5696](https://github.com/pmd/pmd/pull/5696): Bump info.picocli:picocli from 4.7.6 to 4.7.7 -* [#5697](https://github.com/pmd/pmd/pull/5697): Bump com.github.hazendaz.maven:coveralls-maven-plugin from 4.5.0-M6 to 4.7.0 -* [#5704](https://github.com/pmd/pmd/pull/5704): Bump nokogiri from 1.18.5 to 1.18.8 ### ๐Ÿ“ˆ Stats -* 117 commits -* 19 closed tickets & PRs -* Days since last release: 27 {% endtocmaker %} + diff --git a/docs/pages/release_notes_old.md b/docs/pages/release_notes_old.md index 07458f9bedc..42b29db63ed 100644 --- a/docs/pages/release_notes_old.md +++ b/docs/pages/release_notes_old.md @@ -5,6 +5,148 @@ permalink: pmd_release_notes_old.html Previous versions of PMD can be downloaded here: [Releases - pmd/pmd (GitHub)](https://github.com/pmd/pmd/releases) + + +## 25-April-2025 - 7.13.0 + +The PMD team is pleased to announce PMD 7.13.0. + +This is a minor release. + +### Table Of Contents + +* [๐Ÿš€ New and noteworthy](#new-and-noteworthy) + * [Docker images](#docker-images) + * [Experimental support for language dialects](#experimental-support-for-language-dialects) + * [โœจ New Rules](#new-rules) +* [๐Ÿ› Fixed Issues](#fixed-issues) +* [๐Ÿšจ API Changes](#api-changes) + * [Deprecations](#deprecations) + * [Experimental API](#experimental-api) +* [โœจ Merged pull requests](#merged-pull-requests) +* [๐Ÿ“ฆ Dependency updates](#dependency-updates) +* [๐Ÿ“ˆ Stats](#stats) + +### ๐Ÿš€ New and noteworthy + +#### Docker images + +PMD is now providing official docker images at and +. + +You can now analyze your code with PMD by using docker like so: + +``` +docker run --rm --tty -v $PWD:/src pmdcode/pmd:latest check -d . -R rulesets/java/quickstart.xml` +``` + +More information is available at . + +#### Experimental support for language dialects + +A dialect is a particular form of another supported language. For example, an XSLT is a particular +form of an XML. Even though the dialect has its own semantics and uses, the contents are still readable +by any tool capable of understanding the base language. + +In PMD, a dialect allows to set up completely custom rules, XPath functions, properties and metrics +for these files; while retaining the full support of the underlying base language including +already existing rules and XPath functions. + +See [[core] Support language dialects #5438](https://github.com/pmd/pmd/pull/5438) and +[Adding a new dialect](https://docs.pmd-code.org/pmd-doc-7.13.0/pmd_devdocs_major_adding_dialect.html) for more information. + +#### โœจ New Rules + +* The new Apex rule [`TypeShadowsBuiltInNamespace`](https://docs.pmd-code.org/pmd-doc-7.13.0/pmd_rules_apex_errorprone.html#typeshadowsbuiltinnamespace) finds Apex classes, enums, and interfaces + that have the same name as a class, enum, or interface in the `System` or `Schema` namespace. + Shadowing these namespaces in this way can lead to confusion and unexpected behavior. + +### ๐Ÿ› Fixed Issues +* core + * [#5438](https://github.com/pmd/pmd/issues/5438): \[core] Support language dialects + * [#5448](https://github.com/pmd/pmd/issues/5448): Maintain a public PMD docker image + * [#5525](https://github.com/pmd/pmd/issues/5525): \[core] Add rule priority as level to Sarif report + * [#5623](https://github.com/pmd/pmd/issues/5623): \[dist] Make pmd launch script compatible with /bin/sh +* apex-bestpractices + * [#5667](https://github.com/pmd/pmd/issues/5667): \[apex] ApexUnitTestShouldNotUseSeeAllDataTrue false negative when seeAllData parameter is a string +* apex-errorprone + * [#3184](https://github.com/pmd/pmd/issues/3184): \[apex] Prevent classes from shadowing System Namespace +* java + * [#5645](https://github.com/pmd/pmd/issues/5645): \[java] Parse error on switch with yield +* java-bestpractices + * [#5687](https://github.com/pmd/pmd/issues/5687): \[java] UnusedPrivateMethodRule: exclude serialization method readObjectNoData() +* plsql + * [#5675](https://github.com/pmd/pmd/issues/5675): \[plsql] Parse error with TREAT function + +### ๐Ÿšจ API Changes + +#### Deprecations +* net.sourceforge.pmd.lang.xml.pom.PomLanguageModule is deprecated. POM is now a dialect of XML. + Use PomDialectModule instead. +* net.sourceforge.pmd.lang.xml.wsdl.WsdlLanguageModule is deprecated. WSDL is now a dialect of XML. + Use WsdlDialectModule instead. +* net.sourceforge.pmd.lang.xml.xsl.XslLanguageModule is deprecated. XSL is now a dialect of XML. + Use XslDialectModule instead. + +#### Experimental API +* The core API around support for language dialects: + * Language#getBaseLanguageId + * Language#isDialectOf + * LanguageModuleBase#<init> + * LanguageModuleBase#asDialectOf + * LanguageModuleBase.DialectLanguageMetadata + * BasePmdDialectLanguageVersionHandler + * SimpleDialectLanguageModuleBase + +### โœจ Merged pull requests + +* [#5438](https://github.com/pmd/pmd/pull/5438): \[core] Support language dialects - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#5450](https://github.com/pmd/pmd/pull/5450): Fix #3184: \[apex] New Rule: TypeShadowsBuiltInNamespace - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) +* [#5573](https://github.com/pmd/pmd/pull/5573): Fix #5525: \[core] Add Sarif Level Property - [julees7](https://github.com/julees7) (@julees7) +* [#5623](https://github.com/pmd/pmd/pull/5623): \[dist] Make pmd launch script compatible with /bin/sh - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5648](https://github.com/pmd/pmd/pull/5648): Fix #5645: \[java] Parse error with yield statement - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5652](https://github.com/pmd/pmd/pull/5652): \[java] Cleanup `AccessorClassGenerationRule` implementation - [Pankraz76](https://github.com/Pankraz76) (@Pankraz76) +* [#5672](https://github.com/pmd/pmd/pull/5672): \[doc] Fix its/it's and doable/double typos - [John Jetmore](https://github.com/jetmore) (@jetmore) +* [#5674](https://github.com/pmd/pmd/pull/5674): Fix #5448: \[ci] Maintain public Docker image - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5684](https://github.com/pmd/pmd/pull/5684): Fix #5667: \[apex] ApexUnitTestShouldNotUseSeeAllDataTrue false negative when seeAllDate parameter is a string - [Thomas Prouvot](https://github.com/tprouvot) (@tprouvot) +* [#5685](https://github.com/pmd/pmd/pull/5685): \[doc] typo fix in PMD Designer reference - [Douglas Griffith](https://github.com/dwgrth) (@dwgrth) +* [#5686](https://github.com/pmd/pmd/pull/5686): Fix #5675: \[plsql] Support TREAT function with specified datatype - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5687](https://github.com/pmd/pmd/pull/5687): \[java] UnusedPrivateMethodRule: exclude serialization method readObjectNoData() - [Gili Tzabari](https://github.com/cowwoc) (@cowwoc) +* [#5688](https://github.com/pmd/pmd/pull/5688): \[java] Fix Double Literal for Java19+ compatibility - [Andreas Dangel](https://github.com/adangel) (@adangel) + +### ๐Ÿ“ฆ Dependency updates + +* [#5607](https://github.com/pmd/pmd/pull/5607): Bump org.junit:junit-bom from 5.11.4 to 5.12.1 +* [#5641](https://github.com/pmd/pmd/pull/5641): Bump PMD from 7.11.0 to 7.12.0 +* [#5653](https://github.com/pmd/pmd/pull/5653): Bump org.sonarsource.scanner.maven:sonar-maven-plugin from 5.0.0.4389 to 5.1.0.4751 +* [#5654](https://github.com/pmd/pmd/pull/5654): Bump surefire.version from 3.5.2 to 3.5.3 +* [#5655](https://github.com/pmd/pmd/pull/5655): Bump com.google.guava:guava from 33.4.5-jre to 33.4.6-jre +* [#5656](https://github.com/pmd/pmd/pull/5656): Bump org.ow2.asm:asm from 9.7.1 to 9.8 +* [#5657](https://github.com/pmd/pmd/pull/5657): Bump com.google.protobuf:protobuf-java from 4.30.1 to 4.30.2 +* [#5658](https://github.com/pmd/pmd/pull/5658): Bump logger from 1.6.6 to 1.7.0 in /.ci/files in the all-gems group across 1 directory +* [#5671](https://github.com/pmd/pmd/pull/5671): Bump checkstyle from 10.21.4 to 10.23.0 +* [#5676](https://github.com/pmd/pmd/pull/5676): Bump org.checkerframework:checker-qual from 3.49.1 to 3.49.2 +* [#5677](https://github.com/pmd/pmd/pull/5677): Bump junit5.platform.version from 1.12.1 to 1.12.2 +* [#5678](https://github.com/pmd/pmd/pull/5678): Bump org.apache.commons:commons-text from 1.13.0 to 1.13.1 +* [#5679](https://github.com/pmd/pmd/pull/5679): Bump com.google.guava:guava from 33.4.6-jre to 33.4.7-jre +* [#5680](https://github.com/pmd/pmd/pull/5680): Bump org.mockito:mockito-core from 5.16.1 to 5.17.0 +* [#5681](https://github.com/pmd/pmd/pull/5681): Bump org.jacoco:jacoco-maven-plugin from 0.8.12 to 0.8.13 +* [#5682](https://github.com/pmd/pmd/pull/5682): Bump net.bytebuddy:byte-buddy-agent from 1.17.4 to 1.17.5 +* [#5683](https://github.com/pmd/pmd/pull/5683): Bump the all-gems group across 2 directories with 2 updates +* [#5691](https://github.com/pmd/pmd/pull/5691): Bump com.google.code.gson:gson from 2.12.1 to 2.13.0 +* [#5692](https://github.com/pmd/pmd/pull/5692): Bump com.google.guava:guava from 33.4.7-jre to 33.4.8-jre +* [#5693](https://github.com/pmd/pmd/pull/5693): Bump net.bytebuddy:byte-buddy from 1.17.4 to 1.17.5 +* [#5694](https://github.com/pmd/pmd/pull/5694): Bump org.junit:junit-bom from 5.12.1 to 5.12.2 +* [#5696](https://github.com/pmd/pmd/pull/5696): Bump info.picocli:picocli from 4.7.6 to 4.7.7 +* [#5697](https://github.com/pmd/pmd/pull/5697): Bump com.github.hazendaz.maven:coveralls-maven-plugin from 4.5.0-M6 to 4.7.0 +* [#5704](https://github.com/pmd/pmd/pull/5704): Bump nokogiri from 1.18.5 to 1.18.8 + +### ๐Ÿ“ˆ Stats + +* 117 commits +* 19 closed tickets & PRs +* Days since last release: 27 + ## 28-March-2025 - 7.12.0 The PMD team is pleased to announce PMD 7.12.0. diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index c0adab851c1..3effe5aeff4 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.13.0 + 7.14.0-SNAPSHOT 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 07c34d3d8c6..7f7d47f71ac 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index eaee38896e0..324fb2cf720 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index fcdba79e8bd..e018fe4af6f 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index a2a8aa008b7..b10c5dc39f8 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index 027c5c34d8d..fb6d3edf254 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index 2452946d3e5..85a719013ad 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index 68ada41d8c6..5c5e1d64ec6 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index e253110025d..7395d95aa7b 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index 204c42fe5da..63ed6a09199 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index 8027565a5a9..1e4eaa42b54 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index d2e6fadb441..c0224206a73 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index 4715cfddd65..cf79f224b68 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index f03f4a8ede5..3d06e2697b5 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index c911e13868e..3f684e3d441 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index fdc7fe7896e..ed0e53a70be 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index 75c97ec2684..b791a3ad1f8 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index a9e128f2000..f4cbe3bc36f 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index 62b3dbbacde..402cbdfc4cd 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index 3e2c4bb8432..f68145b433e 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index 493b92e796e..133a2506c0e 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index 345022f7f55..a70b65e7ea6 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index a88863ed7c0..e20f426fec7 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index 9777410725a..568765f344c 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index d412494e70f..7e4520ca666 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index 769db2e7ece..bc8896f1efe 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index f006ab8e250..a13ff806c7e 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index 7444c4f58f5..3ba991d54b4 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index dc83d57d556..8cb6cafca4f 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index 908ae08f176..bd99c081919 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index 11fd1b96b05..d3cd173f925 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index 7c42bd68589..1247675bc22 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index 3adcf4d74e8..cb6e5c1290a 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index 24c308485d2..be8b5fc3c51 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.13.0 + 7.14.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index a0c6bd42c69..51e08a8eeeb 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.13.0 + 7.14.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index ad1bd5c1c36..ec297e45321 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index d442a7f96f2..1b991f6e8ec 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index 6e1de287c45..4cdf84678b6 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index 55ee423dc02..73be90e60b0 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index b545b476284..4bb174c5491 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index de7918f4cf1..d463f771a79 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index 77db17b43ac..4c19b9fafa0 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index dc0aa03b747..82fb709b5cc 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.13.0 + 7.14.0-SNAPSHOT pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - pmd_releases/7.13.0 + HEAD From 2522d2a060d2e4f6982203fa3ed27bd1e9c51b49 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 25 Apr 2025 11:34:04 +0200 Subject: [PATCH 0842/1962] Bump PMD from 7.12.0 to 7.13.0 Dogfood update --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 82fb709b5cc..7daadbbaef6 100644 --- a/pom.xml +++ b/pom.xml @@ -589,22 +589,22 @@ net.sourceforge.pmd pmd-core - 7.12.0 + 7.13.0 net.sourceforge.pmd pmd-java - 7.12.0 + 7.13.0 net.sourceforge.pmd pmd-jsp - 7.12.0 + 7.13.0 net.sourceforge.pmd pmd-javascript - 7.12.0 + 7.13.0 From 2db392bdd734e3b3615deac0fc9d4a6d8e4c8587 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 30 Apr 2025 16:03:08 +0200 Subject: [PATCH 0843/1962] Fix #5711: [java] UseArrayAsList - only consider List.add Collection.add was too broad and included Set.add as well. But this rule should only report, if values are added to a List. --- docs/pages/release_notes.md | 2 ++ .../resources/category/java/performance.xml | 4 ++-- .../rule/performance/xml/UseArraysAsList.xml | 22 +++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 0c9c0dd3524..a53e8dd4a71 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,6 +25,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* java-performance + * [#5711](https://github.com/pmd/pmd/issues/5711): [java] UseArraysAsList false positive with Sets ### ๐Ÿšจ API Changes diff --git a/pmd-java/src/main/resources/category/java/performance.xml b/pmd-java/src/main/resources/category/java/performance.xml index 7cbce5dbf27..af8256b43b2 100644 --- a/pmd-java/src/main/resources/category/java/performance.xml +++ b/pmd-java/src/main/resources/category/java/performance.xml @@ -720,7 +720,7 @@ You must use `new ArrayList<>(Arrays.asList(...))` if that is inconvenient for y [*[2]//FieldAccess[@Name = 'length']/VariableAccess[pmd-java:typeIs("java.lang.Object[]")]] /*[last()]/ExpressionStatement/ MethodCall - [pmd-java:matchesSig('java.util.Collection#add(_)')] + [pmd-java:matchesSig('java.util.List#add(_)')] [ArgumentList/ArrayAccess [VariableAccess[@Name = ancestor::ForStatement/ForInit/LocalVariableDeclaration/VariableDeclarator/VariableId/@Name]] ] @@ -728,7 +728,7 @@ You must use `new ArrayList<>(Arrays.asList(...))` if that is inconvenient for y //ForeachStatement [VariableAccess[pmd-java:typeIs("java.lang.Object[]")]] /*[last()]/ExpressionStatement/MethodCall - [pmd-java:matchesSig('java.util.Collection#add(_)')] + [pmd-java:matchesSig('java.util.List#add(_)')] [ArgumentList [VariableAccess[@Name = ancestor::ForeachStatement/LocalVariableDeclaration/VariableDeclarator/VariableId/@Name]] ] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseArraysAsList.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseArraysAsList.xml index a3ad5af636a..c561f360107 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseArraysAsList.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseArraysAsList.xml @@ -252,6 +252,28 @@ class Test { } } } +]]> + + + + [java] UseArraysAsList false positive with Sets #5711 + 0 + hashSet = new HashSet<>(); + + public void parseData(final String dataString) { + final String[] myArray = dataString.split(","); + + for (final String element : myArray) { + this.hashSet.add(element); // line 11 - false positive + } + // e.g. this.hashSet = Arrays.asList(myArray); won't compile + } +} ]]> From d020f2fb6107761a22245a08c1dc45a3ea2aa1fc Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 1 May 2025 19:53:44 +0200 Subject: [PATCH 0844/1962] Fix #5476: [visualforce] Resolve data types of standard object fields --- docs/pages/release_notes.md | 2 + .../visualforce/ast/ObjectFieldTypes.java | 48 ++++++++++++++++++- .../ast/VfExpressionTypeVisitorTest.java | 13 +++++ .../Case/fields/Description.field-meta.xml | 4 ++ .../metadata/sfdx/pages/CasePrintPage.page | 4 ++ .../sfdx/pages/CasePrintPage.page-meta.xml | 8 ++++ 6 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 pmd-visualforce/src/test/resources/net/sourceforge/pmd/lang/visualforce/ast/VfExpressionTypeVisitor/metadata/sfdx/objects/Case/fields/Description.field-meta.xml create mode 100644 pmd-visualforce/src/test/resources/net/sourceforge/pmd/lang/visualforce/ast/VfExpressionTypeVisitor/metadata/sfdx/pages/CasePrintPage.page create mode 100644 pmd-visualforce/src/test/resources/net/sourceforge/pmd/lang/visualforce/ast/VfExpressionTypeVisitor/metadata/sfdx/pages/CasePrintPage.page-meta.xml diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 0c9c0dd3524..1e149d7cb31 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,6 +25,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* visualforce + * [#5476](https://github.com/pmd/pmd/issues/5476): \[visualforce] NPE when analyzing standard field references in visualforce page ### ๐Ÿšจ API Changes diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/ObjectFieldTypes.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/ObjectFieldTypes.java index 99024924cdf..ce3720cb10f 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/ObjectFieldTypes.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/ObjectFieldTypes.java @@ -5,15 +5,19 @@ package net.sourceforge.pmd.lang.visualforce.ast; import java.io.IOException; +import java.lang.reflect.Field; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; @@ -33,6 +37,8 @@ import net.sourceforge.pmd.lang.visualforce.DataType; +import com.google.common.reflect.ClassPath; + /** * Responsible for storing a mapping of Fields that can be referenced from Visualforce to the type of the field. */ @@ -45,6 +51,7 @@ class ObjectFieldTypes extends SalesforceFieldTypes { private static final String SFDX_FIELD_FILE_SUFFIX = ".field-meta.xml"; private static final Map STANDARD_FIELD_TYPES; + private static final Map SOBJECTS; static { STANDARD_FIELD_TYPES = new HashMap<>(); @@ -56,6 +63,18 @@ class ObjectFieldTypes extends SalesforceFieldTypes { STANDARD_FIELD_TYPES.put("lastmodifieddate", DataType.DateTime); STANDARD_FIELD_TYPES.put("name", DataType.Text); STANDARD_FIELD_TYPES.put("systemmodstamp", DataType.DateTime); + + try { + SOBJECTS = Collections.unmodifiableMap( + ClassPath.from(ClassLoader.getSystemClassLoader()) + .getTopLevelClasses(com.nawforce.runforce.SObjects.Account.class.getPackage().getName()) + .stream() + .collect(Collectors.toMap(c -> c.getSimpleName().toLowerCase(Locale.ROOT), + Function.identity())) + ); + } catch (IOException e) { + throw new RuntimeException(e); + } } /** @@ -172,8 +191,33 @@ private void parseSfdxCustomField(String customObjectName, Path sfdxCustomFieldP Document document = documentBuilder.parse(sfdxCustomFieldPath.toFile()); Node fullNameNode = (Node) sfdxCustomFieldFullNameExpression.evaluate(document, XPathConstants.NODE); Node typeNode = (Node) sfdxCustomFieldTypeExpression.evaluate(document, XPathConstants.NODE); - String type = typeNode.getNodeValue(); - DataType dataType = DataType.fromString(type); + + DataType dataType = null; + + if (typeNode != null) { + // custom field with a defined type + String type = typeNode.getNodeValue(); + dataType = DataType.fromString(type); + } else { + // maybe a field from a standard object - the type is then not explicitly in field-meta.xml provided + ClassPath.ClassInfo classInfo = SOBJECTS.get(customObjectName.toLowerCase(Locale.ROOT)); + if (classInfo != null) { + Field[] fields = classInfo.load().getFields(); + for (Field f : fields) { + if (f.getName().equalsIgnoreCase(fullNameNode.getNodeValue())) { + dataType = DataType.fromTypeName(f.getType().getSimpleName()); + break; + } + } + if (dataType == null) { + LOG.warn("Couldn't determine data type of customObjectName={} from {}", customObjectName, sfdxCustomFieldPath); + dataType = DataType.Unknown; + } + } else { + LOG.warn("Couldn't determine data type of customObjectName={} - no sobject definition found", customObjectName); + dataType = DataType.Unknown; + } + } String key = customObjectName + "." + fullNameNode.getNodeValue(); putDataType(key, dataType); diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/VfExpressionTypeVisitorTest.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/VfExpressionTypeVisitorTest.java index bbce49d8db2..9ef552cd366 100644 --- a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/VfExpressionTypeVisitorTest.java +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/VfExpressionTypeVisitorTest.java @@ -158,6 +158,19 @@ void testDataTypeForApexPropertiesNotFound() { .filterMatching(ASTIdentifier::getImage, "NotFoundProp")); } + /** + * @see [visualforce] NPE when analyzing standard field references in visualforce page #5476 + */ + @Test + void standardFieldsOnlyHaveFullName() { + Node rootNode = compile("CasePrintPage.page"); + + ASTIdentifier description = rootNode.descendants(ASTIdentifier.class) + .filterMatching(ASTIdentifier::getImage, "Description") + .firstOrThrow(); + assertEquals(DataType.Text, description.getDataType()); + } + private Node compile(String pageName) { return compile(pageName, false); } diff --git a/pmd-visualforce/src/test/resources/net/sourceforge/pmd/lang/visualforce/ast/VfExpressionTypeVisitor/metadata/sfdx/objects/Case/fields/Description.field-meta.xml b/pmd-visualforce/src/test/resources/net/sourceforge/pmd/lang/visualforce/ast/VfExpressionTypeVisitor/metadata/sfdx/objects/Case/fields/Description.field-meta.xml new file mode 100644 index 00000000000..054471b8e1b --- /dev/null +++ b/pmd-visualforce/src/test/resources/net/sourceforge/pmd/lang/visualforce/ast/VfExpressionTypeVisitor/metadata/sfdx/objects/Case/fields/Description.field-meta.xml @@ -0,0 +1,4 @@ + + + Description + diff --git a/pmd-visualforce/src/test/resources/net/sourceforge/pmd/lang/visualforce/ast/VfExpressionTypeVisitor/metadata/sfdx/pages/CasePrintPage.page b/pmd-visualforce/src/test/resources/net/sourceforge/pmd/lang/visualforce/ast/VfExpressionTypeVisitor/metadata/sfdx/pages/CasePrintPage.page new file mode 100644 index 00000000000..3eb768d8150 --- /dev/null +++ b/pmd-visualforce/src/test/resources/net/sourceforge/pmd/lang/visualforce/ast/VfExpressionTypeVisitor/metadata/sfdx/pages/CasePrintPage.page @@ -0,0 +1,4 @@ + + + + diff --git a/pmd-visualforce/src/test/resources/net/sourceforge/pmd/lang/visualforce/ast/VfExpressionTypeVisitor/metadata/sfdx/pages/CasePrintPage.page-meta.xml b/pmd-visualforce/src/test/resources/net/sourceforge/pmd/lang/visualforce/ast/VfExpressionTypeVisitor/metadata/sfdx/pages/CasePrintPage.page-meta.xml new file mode 100644 index 00000000000..c6032a7e05b --- /dev/null +++ b/pmd-visualforce/src/test/resources/net/sourceforge/pmd/lang/visualforce/ast/VfExpressionTypeVisitor/metadata/sfdx/pages/CasePrintPage.page-meta.xml @@ -0,0 +1,8 @@ + + + 32.0 + false + false + A generic case print page in pdf format + + From 2f4ed13eb817da5dd3943fc488fe713aa3cb680f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 1 May 2025 20:27:44 +0200 Subject: [PATCH 0845/1962] [visualforce] Refactor/Add documentation - rename standard fields -> system fields --- .../visualforce/ast/ObjectFieldTypes.java | 41 ++++++++++++------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/ObjectFieldTypes.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/ObjectFieldTypes.java index ce3720cb10f..8218ab6a0ef 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/ObjectFieldTypes.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/ObjectFieldTypes.java @@ -41,6 +41,9 @@ /** * Responsible for storing a mapping of Fields that can be referenced from Visualforce to the type of the field. + * + *

    SFDX and MDAPI project formats are supported. + * @see Salesforce DX Project Structure and Source Format */ class ObjectFieldTypes extends SalesforceFieldTypes { private static final Logger LOG = LoggerFactory.getLogger(ObjectFieldTypes.class); @@ -50,21 +53,25 @@ class ObjectFieldTypes extends SalesforceFieldTypes { private static final String MDAPI_OBJECT_FILE_SUFFIX = ".object"; private static final String SFDX_FIELD_FILE_SUFFIX = ".field-meta.xml"; - private static final Map STANDARD_FIELD_TYPES; + private static final Map SYSTEM_FIELDS; private static final Map SOBJECTS; static { - STANDARD_FIELD_TYPES = new HashMap<>(); - STANDARD_FIELD_TYPES.put("createdbyid", DataType.Lookup); - STANDARD_FIELD_TYPES.put("createddate", DataType.DateTime); - STANDARD_FIELD_TYPES.put("id", DataType.Lookup); - STANDARD_FIELD_TYPES.put("isdeleted", DataType.Checkbox); - STANDARD_FIELD_TYPES.put("lastmodifiedbyid", DataType.Lookup); - STANDARD_FIELD_TYPES.put("lastmodifieddate", DataType.DateTime); - STANDARD_FIELD_TYPES.put("name", DataType.Text); - STANDARD_FIELD_TYPES.put("systemmodstamp", DataType.DateTime); + // see https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/system_fields.htm + SYSTEM_FIELDS = new HashMap<>(); + SYSTEM_FIELDS.put("id", DataType.Lookup); + SYSTEM_FIELDS.put("isdeleted", DataType.Checkbox); + SYSTEM_FIELDS.put("createdbyid", DataType.Lookup); + SYSTEM_FIELDS.put("createddate", DataType.DateTime); + SYSTEM_FIELDS.put("lastmodifiedbyid", DataType.Lookup); + SYSTEM_FIELDS.put("lastmodifieddate", DataType.DateTime); + SYSTEM_FIELDS.put("systemmodstamp", DataType.DateTime); + // name is not defined as systemfield, but might occur frequently + SYSTEM_FIELDS.put("name", DataType.Text); try { + // see https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_list.htm + // and https://github.com/apex-dev-tools/sobject-types SOBJECTS = Collections.unmodifiableMap( ClassPath.from(ClassLoader.getSystemClassLoader()) .getTopLevelClasses(com.nawforce.runforce.SObjects.Account.class.getPackage().getName()) @@ -135,7 +142,7 @@ protected void findDataType(String expression, List objectsDirectories) { String objectName = parts[0]; String fieldName = parts[1]; - addStandardFields(objectName); + addSystemFields(objectName); // Attempt to find a metadata file that contains the custom field. The information will be located in a // file located at /.object or in an file located at @@ -170,6 +177,10 @@ protected void findDataType(String expression, List objectsDirectories) { * Sfdx projects decompose custom fields into individual files. This method will return the individual file that * corresponds to <objectName>.<fieldName> if it exists. * + *

    Note: these metadata files are created not only for custom fields, but also for standard fields that + * are used within the project. The metadata of these standard fields (fields of standard objects) provide + * less explicit information. E.g. the type is not available the metadata file for these standard fields. + * * @return path to the metadata file for the Custom Field or null if not found */ private Path getSfdxCustomFieldPath(Path objectsDirectory, String objectName, String fieldName) { @@ -267,11 +278,13 @@ private void parseMdapiCustomObject(Path mdapiObjectFile) { } /** - * Add the set of standard fields which aren't present in the metadata file, but may be refernced from the + * Add the set of system fields which aren't present in the metadata file, but may be referenced from the * visualforce page. + * + * @see Overview of Salesforce Objects and Fields / System Fields */ - private void addStandardFields(String customObjectName) { - for (Map.Entry entry : STANDARD_FIELD_TYPES.entrySet()) { + private void addSystemFields(String customObjectName) { + for (Map.Entry entry : SYSTEM_FIELDS.entrySet()) { putDataType(customObjectName + "." + entry.getKey(), entry.getValue()); } } From b789fc36e6edae50f6a7ccd1b90e5247b4c58046 Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Sat, 3 May 2025 14:08:52 +0200 Subject: [PATCH 0846/1962] Fix issue 5634: CommentDefaultAccessModifier doesn't recognize comment --- .../pmd/lang/java/ast/JavaComment.java | 6 ++---- .../xml/CommentDefaultAccessModifier.xml | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaComment.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaComment.java index 47a556f780a..ad3f6a23e2a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaComment.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaComment.java @@ -132,9 +132,9 @@ private static Stream getSpecialTokensIn(JjtreeNode node) { } public static Stream getLeadingComments(JavaNode node) { - Stream specialTokens; + Stream specialTokens = getSpecialTokensIn(node); - if (node instanceof ModifierOwner) { + if (node instanceof ModifierOwner && !(node instanceof ASTConstructorDeclaration)) { node = ((ModifierOwner) node).getModifiers(); specialTokens = getSpecialTokensIn(node); @@ -142,8 +142,6 @@ public static Stream getLeadingComments(JavaNode node) { if (!node.getFirstToken().isImplicit()) { specialTokens = Stream.concat(specialTokens, getSpecialTokensIn(node.getNextSibling())); } - } else { - specialTokens = getSpecialTokensIn(node); } return specialTokens.filter(JavaComment::isComment) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/CommentDefaultAccessModifier.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/CommentDefaultAccessModifier.xml index b3c02a841e5..c856252c0ba 100755 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/CommentDefaultAccessModifier.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/CommentDefaultAccessModifier.xml @@ -583,4 +583,22 @@ public class Test { } ]]> + + + #5634: Annotated constructors with comment + 0 + + + From cec2fd03276a757f0f290bb265a8e67c40995879 Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Sat, 3 May 2025 14:15:38 +0200 Subject: [PATCH 0847/1962] Issue 5634: Add additional unit tests --- .../pmd/lang/java/ast/JavaCommentTest.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JavaCommentTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JavaCommentTest.java index b83a8a97cf8..78907b9b562 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JavaCommentTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JavaCommentTest.java @@ -14,6 +14,7 @@ import java.util.List; import java.util.stream.Collectors; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import net.sourceforge.pmd.lang.document.Chars; @@ -77,6 +78,26 @@ void getLeadingComments() { checkCommentMatches(docCommentOwners.get(1), "/** b */"); } + @Test + void getLeadingCommentsAnnotatedMethod() { + ASTCompilationUnit parsed = java.parse("/* a */ class Foo { /* b */ @SuppressWarnings(\"\") /* c */ void noOp() {}; }"); + + assertLeadingCommentsMatch(parsed, "/* a */", "/* b */", "/* c */"); + } + + @Test + void getLeadingCommentsAnnotatedConstructor() { + ASTCompilationUnit parsed = java.parse("/* a */ class Foo { /* b */ @SuppressWarnings(\"\") /* c */ Foo() /* d */ {}; }"); + + assertLeadingCommentsMatch(parsed, "/* a */", "/* b */", "/* c */", "/* d */"); + } + + private static void assertLeadingCommentsMatch(ASTCompilationUnit parsed, String... expectedComments) { + Assertions.assertThat(JavaComment.getLeadingComments(parsed)) + .extracting(c -> c.getText().toString()) + .containsExactly(expectedComments); + } + private static void checkCommentMatches(JavadocCommentOwner commentOwner, String expectedText) { // this is preassigned by the comment assignment pass JavadocComment comment = commentOwner.getJavadocComment(); From 625acd8f0f62bdf3bf7052fcd853c9c4b361ae46 Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Mon, 5 May 2025 19:17:48 +0200 Subject: [PATCH 0848/1962] Issue 5634: Adapt assert --- .../net/sourceforge/pmd/lang/java/ast/JavaCommentTest.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JavaCommentTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JavaCommentTest.java index 78907b9b562..e5b6d00fdd3 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JavaCommentTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JavaCommentTest.java @@ -89,11 +89,12 @@ void getLeadingCommentsAnnotatedMethod() { void getLeadingCommentsAnnotatedConstructor() { ASTCompilationUnit parsed = java.parse("/* a */ class Foo { /* b */ @SuppressWarnings(\"\") /* c */ Foo() /* d */ {}; }"); - assertLeadingCommentsMatch(parsed, "/* a */", "/* b */", "/* c */", "/* d */"); + final ASTConstructorDeclaration constructorNode = parsed.descendants(ASTConstructorDeclaration.class).first(); + assertLeadingCommentsMatch(constructorNode, "/* b */", "/* c */", "/* d */"); } - private static void assertLeadingCommentsMatch(ASTCompilationUnit parsed, String... expectedComments) { - Assertions.assertThat(JavaComment.getLeadingComments(parsed)) + private static void assertLeadingCommentsMatch(JavaNode javaNode, String... expectedComments) { + Assertions.assertThat(JavaComment.getLeadingComments(javaNode)) .extracting(c -> c.getText().toString()) .containsExactly(expectedComments); } From 630a54c9d598f550f24e8d61b18f5a689c0388ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 May 2025 21:00:48 +0200 Subject: [PATCH 0849/1962] Bump com.puppycrawl.tools:checkstyle from 10.23.0 to 10.23.1 (#5710) Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.23.0 to 10.23.1. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.23.0...checkstyle-10.23.1) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-version: 10.23.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7daadbbaef6..a6fe4ad1823 100644 --- a/pom.xml +++ b/pom.xml @@ -100,7 +100,7 @@ 5.0 3.5.3 - 10.23.0 + 10.23.1 3.6.0 3.26.0 1.10.15 From 861fa172c135503930aea2e618ddaef9f50347b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 May 2025 21:02:08 +0200 Subject: [PATCH 0850/1962] Bump com.google.code.gson:gson from 2.13.0 to 2.13.1 (#5709) Bumps [com.google.code.gson:gson](https://github.com/google/gson) from 2.13.0 to 2.13.1. - [Release notes](https://github.com/google/gson/releases) - [Changelog](https://github.com/google/gson/blob/main/CHANGELOG.md) - [Commits](https://github.com/google/gson/compare/gson-parent-2.13.0...gson-parent-2.13.1) --- updated-dependencies: - dependency-name: com.google.code.gson:gson dependency-version: 2.13.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a6fe4ad1823..58574e8cf34 100644 --- a/pom.xml +++ b/pom.xml @@ -920,7 +920,7 @@ com.google.code.gson gson - 2.13.0 + 2.13.1 org.yaml From 9378005ef2d082d010d681d71fbc6b10ac6647cb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 May 2025 21:07:41 +0200 Subject: [PATCH 0851/1962] Bump org.checkerframework:checker-qual from 3.49.2 to 3.49.3 (#5718) Bumps [org.checkerframework:checker-qual](https://github.com/typetools/checker-framework) from 3.49.2 to 3.49.3. - [Release notes](https://github.com/typetools/checker-framework/releases) - [Changelog](https://github.com/typetools/checker-framework/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/typetools/checker-framework/compare/checker-framework-3.49.2...checker-framework-3.49.3) --- updated-dependencies: - dependency-name: org.checkerframework:checker-qual dependency-version: 3.49.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 58574e8cf34..53bfef8b4fc 100644 --- a/pom.xml +++ b/pom.xml @@ -880,7 +880,7 @@ org.checkerframework checker-qual - 3.49.2 + 3.49.3 net.sf.saxon From 9cc52374fa40eb24963427f854aff51654ee6ce9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 May 2025 21:08:16 +0200 Subject: [PATCH 0852/1962] Bump scalameta.version from 4.13.4 to 4.13.5 (#5717) Bumps `scalameta.version` from 4.13.4 to 4.13.5. Updates `org.scalameta:parsers_2.13` from 4.13.4 to 4.13.5 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.4...v4.13.5) Updates `org.scalameta:trees_2.13` from 4.13.4 to 4.13.5 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.4...v4.13.5) Updates `org.scalameta:parsers_2.12` from 4.13.4 to 4.13.5 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.4...v4.13.5) Updates `org.scalameta:trees_2.12` from 4.13.4 to 4.13.5 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.4...v4.13.5) --- updated-dependencies: - dependency-name: org.scalameta:parsers_2.13 dependency-version: 4.13.5 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:trees_2.13 dependency-version: 4.13.5 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:parsers_2.12 dependency-version: 4.13.5 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:trees_2.12 dependency-version: 4.13.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index cb6e5c1290a..131354ac1bd 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -13,7 +13,7 @@ - 4.13.4 + 4.13.5 From 96160fad9b0e25ed88a0247a82e872cb13118a23 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 May 2025 21:09:12 +0200 Subject: [PATCH 0853/1962] Bump org.jsoup:jsoup from 1.19.1 to 1.20.1 (#5719) Bumps [org.jsoup:jsoup](https://github.com/jhy/jsoup) from 1.19.1 to 1.20.1. - [Release notes](https://github.com/jhy/jsoup/releases) - [Changelog](https://github.com/jhy/jsoup/blob/master/CHANGES.md) - [Commits](https://github.com/jhy/jsoup/compare/jsoup-1.19.1...jsoup-1.20.1) --- updated-dependencies: - dependency-name: org.jsoup:jsoup dependency-version: 1.20.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-html/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index 3f684e3d441..bf0ecbb67d8 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -31,7 +31,7 @@ org.jsoup jsoup - 1.19.1 + 1.20.1 From 567301fb9b1b66da84abbe72aaeedadfb89b8d9c Mon Sep 17 00:00:00 2001 From: Thomas Prouvot Date: Wed, 7 May 2025 16:52:07 +0200 Subject: [PATCH 0854/1962] Add PMD CSS module and lexer support - Introduced a new PMD module for CSS, including the necessary POM configuration. - Added ANTLR grammar for CSS to support syntax parsing. - Implemented the `CssLanguageModule` and `CssCpdLexer` for code duplication detection. - Created unit tests for the CSS lexer functionality. - Updated the binary distribution to include CSS as a supported language. --- pmd-css/pom.xml | 77 ++++++ .../net/sourceforge/pmd/lang/css/ast/css.g4 | 256 ++++++++++++++++++ .../pmd/lang/css/CssLanguageModule.java | 28 ++ .../pmd/lang/css/cpd/CssCpdLexer.java | 32 +++ .../net.sourceforge.pmd.lang.Language | 1 + .../pmd/lang/css/cpd/CssCpdLexerTest.java | 27 ++ .../pmd/lang/css/cpd/testdata/literals.css | 15 + .../pmd/dist/BinaryDistributionIT.java | 2 +- pom.xml | 3 +- 9 files changed, 439 insertions(+), 2 deletions(-) create mode 100644 pmd-css/pom.xml create mode 100644 pmd-css/src/main/antlr4/net/sourceforge/pmd/lang/css/ast/css.g4 create mode 100644 pmd-css/src/main/java/net/sourceforge/pmd/lang/css/CssLanguageModule.java create mode 100644 pmd-css/src/main/java/net/sourceforge/pmd/lang/css/cpd/CssCpdLexer.java create mode 100644 pmd-css/src/main/resources/META-INF/services/net.sourceforge.pmd.lang.Language create mode 100644 pmd-css/src/test/java/net/sourceforge/pmd/lang/css/cpd/CssCpdLexerTest.java create mode 100644 pmd-css/src/test/resources/net/sourceforge/pmd/lang/css/cpd/testdata/literals.css diff --git a/pmd-css/pom.xml b/pmd-css/pom.xml new file mode 100644 index 00000000000..221661a6c04 --- /dev/null +++ b/pmd-css/pom.xml @@ -0,0 +1,77 @@ + + + 4.0.0 + pmd-css + PMD CSS + + + net.sourceforge.pmd + pmd + 7.14.0-SNAPSHOT + ../pom.xml + + + + + + org.antlr + antlr4-maven-plugin + + + org.apache.maven.plugins + maven-antrun-plugin + + + antlr-cleanup + generate-sources + + run + + + + + + + + + + + + + + maven-resources-plugin + + false + + ${*} + + + + + + + + net.sourceforge.pmd + pmd-core + + + org.antlr + antlr4-runtime + + + org.junit.jupiter + junit-jupiter + test + + + net.sourceforge.pmd + pmd-test + test + + + net.sourceforge.pmd + pmd-lang-test + test + + + \ No newline at end of file diff --git a/pmd-css/src/main/antlr4/net/sourceforge/pmd/lang/css/ast/css.g4 b/pmd-css/src/main/antlr4/net/sourceforge/pmd/lang/css/ast/css.g4 new file mode 100644 index 00000000000..0494a4fe260 --- /dev/null +++ b/pmd-css/src/main/antlr4/net/sourceforge/pmd/lang/css/ast/css.g4 @@ -0,0 +1,256 @@ +// $antlr-format alignTrailingComments true, columnLimit 150, maxEmptyLinesToKeep 1, reflowComments false, useTab false +// $antlr-format allowShortRulesOnASingleLine true, allowShortBlocksOnASingleLine true, minEmptyLines 0, alignSemicolons ownLine +// $antlr-format alignColons trailing, singleLineOverrulesHangingColon true, alignLexerCommands true, alignLabels true, alignTrailers true + +lexer grammar CSS; + +channels { + ERROR +} + +OpenBracket : '['; +CloseBracket : ']'; +OpenParen : '('; +CloseParen : ')'; +OpenBrace : '{'; +CloseBrace : '}'; +SemiColon : ';'; +Equal : '='; +Colon : ':'; +Dot : '.'; +Multiply : '*'; +Divide : '/'; +Pipe : '|'; +Underscore : '_'; + +fragment At: '@'; + +fragment Hex: [0-9a-fA-F]; + +fragment NewlineOrSpace: '\r\n' | [ \t\r\n\f] |; + +fragment Unicode: '\\' Hex Hex? Hex? Hex? Hex? Hex? NewlineOrSpace; + +fragment Escape: Unicode | '\\' ~[\r\n\f0-9a-fA-F]; + +fragment Nmstart: [_a-zA-Z] | Nonascii | Escape; + +fragment Nmchar: [_a-zA-Z0-9\-] | Nonascii | Escape; + +// CSS2.2 Grammar defines the following, but I'm not sure how to add them to parser for error handling +// BadString : +// BadUri : +// BadComment : +// BadUri : + +Comment: '/*' ~'*'* '*'+ ( ~[/*] ~'*'* '*'+)* '/'; + +fragment Name: Nmchar+; + +Url: U R L '(' Whitespace ( [!#$%&*-~] | Nonascii | Escape)* Whitespace ')'; + +Space: [ \t\r\n\f]+; + +fragment Whitespace: Space |; + +fragment Newline: '\n' | '\r\n' | '\r' | '\f'; + +fragment ZeroToFourZeros: '0'? '0'? '0'? '0'?; + +fragment A: 'a' | 'A' | '\\' ZeroToFourZeros ('41' | '61') NewlineOrSpace; + +fragment B: 'b' | 'B' | '\\' ZeroToFourZeros ('42' | '62') NewlineOrSpace; + +fragment C: 'c' | 'C' | '\\' ZeroToFourZeros ('43' | '63') NewlineOrSpace; + +fragment D: 'd' | 'D' | '\\' ZeroToFourZeros ('44' | '64') NewlineOrSpace; + +fragment E: 'e' | 'E' | '\\' ZeroToFourZeros ('45' | '65') NewlineOrSpace; + +fragment F: 'f' | 'F' | '\\' ZeroToFourZeros ('46' | '66') NewlineOrSpace; + +fragment G: 'g' | 'G' | '\\' ZeroToFourZeros ('47' | '67') NewlineOrSpace | '\\g' | '\\G'; + +fragment H: 'h' | 'H' | '\\' ZeroToFourZeros ('48' | '68') NewlineOrSpace | '\\h' | '\\H'; + +fragment I: 'i' | 'I' | '\\' ZeroToFourZeros ('49' | '69') NewlineOrSpace | '\\i' | '\\I'; + +fragment K: 'k' | 'K' | '\\' ZeroToFourZeros ('4b' | '6b') NewlineOrSpace | '\\k' | '\\K'; + +fragment L: 'l' | 'L' | '\\' ZeroToFourZeros ('4c' | '6c') NewlineOrSpace | '\\l' | '\\L'; + +fragment M: 'm' | 'M' | '\\' ZeroToFourZeros ('4d' | '6d') NewlineOrSpace | '\\m' | '\\M'; + +fragment N: 'n' | 'N' | '\\' ZeroToFourZeros ('4e' | '6e') NewlineOrSpace | '\\n' | '\\N'; + +fragment O: 'o' | 'O' | '\\' ZeroToFourZeros ('4f' | '6f') NewlineOrSpace | '\\o' | '\\O'; + +fragment P: 'p' | 'P' | '\\' ZeroToFourZeros ('50' | '70') NewlineOrSpace | '\\p' | '\\P'; + +fragment Q: 'q' | 'Q' | '\\' ZeroToFourZeros ('51' | '71') NewlineOrSpace | '\\q' | '\\Q'; + +fragment R: 'r' | 'R' | '\\' ZeroToFourZeros ('52' | '72') NewlineOrSpace | '\\r' | '\\R'; + +fragment S: 's' | 'S' | '\\' ZeroToFourZeros ('53' | '73') NewlineOrSpace | '\\s' | '\\S'; + +fragment T: 't' | 'T' | '\\' ZeroToFourZeros ('54' | '74') NewlineOrSpace | '\\t' | '\\T'; + +fragment U: 'u' | 'U' | '\\' ZeroToFourZeros ('55' | '75') NewlineOrSpace | '\\u' | '\\U'; + +fragment V: 'v' | 'V' | '\\' ZeroToFourZeros ('56' | '76') NewlineOrSpace | '\\v' | '\\V'; + +fragment W: 'w' | 'W' | '\\' ZeroToFourZeros ('57' | '77') NewlineOrSpace | '\\w' | '\\W'; + +fragment X: 'x' | 'X' | '\\' ZeroToFourZeros ('58' | '78') NewlineOrSpace | '\\x' | '\\X'; + +fragment Y: 'y' | 'Y' | '\\' ZeroToFourZeros ('59' | '79') NewlineOrSpace | '\\y' | '\\Y'; + +fragment Z: 'z' | 'Z' | '\\' ZeroToFourZeros ('5a' | '7a') NewlineOrSpace | '\\z' | '\\Z'; + +fragment DashChar: '-' | '\\' ZeroToFourZeros '2d' NewlineOrSpace; + +Cdo: ''; + +Includes: '~='; + +DashMatch: '|='; + +Hash: '#' Name; + +Import: At I M P O R T; + +Page: At P A G E; + +Media: At M E D I A; + +Namespace: At N A M E S P A C E; + +Charset: '@charset '; + +Important: '!' ( Space | Comment)* I M P O R T A N T; + +fragment FontRelative: Number E M | Number E X | Number C H | Number R E M; + +// https://www.w3.org/TR/css3-values/#viewport-relative-lengths +fragment ViewportRelative: Number V W | Number V H | Number V M I N | Number V M A X; + +fragment AbsLength: + Number P X + | Number C M + | Number M M + | Number I N + | Number P T + | Number P C + | Number Q +; + +fragment Angle: Number D E G | Number R A D | Number G R A D | Number T U R N; + +fragment Time: Number M S | Number S; + +fragment Freq: Number H Z | Number K H Z; + +Percentage: Number '%'; + +Url_: 'url('; + +UnicodeRange: + [u|U] '+?' '?'? '?'? '?'? '?'? '?'? + | [u|U] '+' Hex '?'? '?'? '?'? '?'? '?'? + | [u|U] '+' Hex Hex '?'? '?'? '?'? '?'? + | [u|U] '+' Hex Hex Hex '?'? '?'? '?'? + | [u|U] '+' Hex Hex Hex Hex '?'? '?'? + | [u|U] '+' Hex Hex Hex Hex Hex '?'? +; + +// https://www.w3.org/TR/css3-mediaqueries/ +MediaOnly: O N L Y; + +Not: N O T; + +And: A N D; + +fragment Resolution: Number D P I | Number D P C M | Number D P P X; + +fragment Length: AbsLength | FontRelative | ViewportRelative; + +Dimension: Length | Time | Freq | Resolution | Angle; + +UnknownDimension: Number Ident; + +// https://www.w3.org/TR/css3-selectors/ +fragment Nonascii: ~[\u0000-\u007f]; + +Plus: '+'; + +Minus: '-'; + +Greater: '>'; + +Comma: ','; + +Tilde: '~'; + +PseudoNot: ':' N O T '('; + +Number: [0-9]+ | [0-9]* '.' [0-9]+; + +String_: + '"' (~[\n\r\f\\"] | '\\' Newline | Nonascii | Escape)* '"' + | '\'' ( ~[\n\r\f\\'] | '\\' Newline | Nonascii | Escape)* '\'' +; + +PrefixMatch: '^='; + +SuffixMatch: '$='; + +SubstringMatch: '*='; + +// https://www.w3.org/TR/css-fonts-3/#font-face-rule +FontFace: At F O N T DashChar F A C E; + +// https://www.w3.org/TR/css3-conditional/ +Supports: At S U P P O R T S; + +Or: O R; + +// https://www.w3.org/TR/css3-animations/ +fragment VendorPrefix: '-' M O Z '-' | '-' W E B K I T '-' | '-' O '-'; + +Keyframes: At VendorPrefix? K E Y F R A M E S; + +From: F R O M; + +To: T O; + +// https://www.w3.org/TR/css3-values/#calc-syntax +Calc: 'calc('; + +// https://www.w3.org/TR/css-device-adapt-1/ +Viewport: At V I E W P O R T; + +// https://www.w3.org/TR/css-counter-styles-3/ +CounterStyle: At C O U N T E R DashChar S T Y L E; + +// https://www.w3.org/TR/css-fonts-3/ +FontFeatureValues: At F O N T DashChar F E A T U R E DashChar V A L U E S; + +// https://msdn.microsoft.com/en-us/library/ms532847.aspx +DxImageTransform: 'progid:DXImageTransform.Microsoft.' Function_; + +AtKeyword: At Ident; + +// Variables +// https://www.w3.org/TR/css-variables-1 +Variable: '--' Nmstart Nmchar*; + +Var: 'var('; + +// Give Ident least priority so that more specific rules matches first +Ident: '-'? Nmstart Nmchar*; + +Function_: Ident '('; + +UnexpectedCharacter: . -> channel(ERROR); \ No newline at end of file diff --git a/pmd-css/src/main/java/net/sourceforge/pmd/lang/css/CssLanguageModule.java b/pmd-css/src/main/java/net/sourceforge/pmd/lang/css/CssLanguageModule.java new file mode 100644 index 00000000000..d2118f5485c --- /dev/null +++ b/pmd-css/src/main/java/net/sourceforge/pmd/lang/css/CssLanguageModule.java @@ -0,0 +1,28 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.css; + +import net.sourceforge.pmd.cpd.CpdLexer; +import net.sourceforge.pmd.lang.LanguagePropertyBundle; +import net.sourceforge.pmd.lang.LanguageRegistry; +import net.sourceforge.pmd.lang.css.cpd.CssCpdLexer; +import net.sourceforge.pmd.lang.impl.CpdOnlyLanguageModuleBase; + +public class CssLanguageModule extends CpdOnlyLanguageModuleBase { + private static final String ID = "css"; + + public CssLanguageModule() { + super(LanguageMetadata.withId(ID).name("CSS").extensions("css")); + } + + public static CssLanguageModule getInstance() { + return (CssLanguageModule) LanguageRegistry.CPD.getLanguageById(ID); + } + + @Override + public CpdLexer createCpdLexer(LanguagePropertyBundle bundle) { + return new CssCpdLexer(); + } +} diff --git a/pmd-css/src/main/java/net/sourceforge/pmd/lang/css/cpd/CssCpdLexer.java b/pmd-css/src/main/java/net/sourceforge/pmd/lang/css/cpd/CssCpdLexer.java new file mode 100644 index 00000000000..faccfa97083 --- /dev/null +++ b/pmd-css/src/main/java/net/sourceforge/pmd/lang/css/cpd/CssCpdLexer.java @@ -0,0 +1,32 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.css.cpd; + +import net.sourceforge.pmd.cpd.impl.AntlrCpdLexer; +import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrToken; +import net.sourceforge.pmd.lang.css.ast.CssLexer; + +import java.util.Locale; + +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Lexer; + +public class CssCpdLexer extends AntlrCpdLexer { + + @Override + protected Lexer getLexerForSource(CharStream charStream) { + return new CssLexer(charStream); + } + + @Override + protected String getImage(AntlrToken token) { + if (token.getKind() == CssLexer.STRING) { + // This path is for case-sensitive tokens + return token.getImage(); + } + // normalize case-insensitive tokens + return token.getImage().toUpperCase(Locale.ROOT); + } +} \ No newline at end of file diff --git a/pmd-css/src/main/resources/META-INF/services/net.sourceforge.pmd.lang.Language b/pmd-css/src/main/resources/META-INF/services/net.sourceforge.pmd.lang.Language new file mode 100644 index 00000000000..330a7bc7f93 --- /dev/null +++ b/pmd-css/src/main/resources/META-INF/services/net.sourceforge.pmd.lang.Language @@ -0,0 +1 @@ +net.sourceforge.pmd.lang.css.CssLanguageModule diff --git a/pmd-css/src/test/java/net/sourceforge/pmd/lang/css/cpd/CssCpdLexerTest.java b/pmd-css/src/test/java/net/sourceforge/pmd/lang/css/cpd/CssCpdLexerTest.java new file mode 100644 index 00000000000..b8e768343d9 --- /dev/null +++ b/pmd-css/src/test/java/net/sourceforge/pmd/lang/css/cpd/CssCpdLexerTest.java @@ -0,0 +1,27 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.css.cpd; + +import org.junit.jupiter.api.Test; + +import net.sourceforge.pmd.lang.test.cpd.CpdTextComparisonTest; + +class CssCpdLexerTest extends CpdTextComparisonTest { + + public CssCpdLexerTest() { + super("css", ".css"); + } + + @Override + protected String getResourcePrefix() { + return "testdata"; + } + + @Test + public void testLiterals() { + doTest("literals"); + } + +} diff --git a/pmd-css/src/test/resources/net/sourceforge/pmd/lang/css/cpd/testdata/literals.css b/pmd-css/src/test/resources/net/sourceforge/pmd/lang/css/cpd/testdata/literals.css new file mode 100644 index 00000000000..4e1798429a4 --- /dev/null +++ b/pmd-css/src/test/resources/net/sourceforge/pmd/lang/css/cpd/testdata/literals.css @@ -0,0 +1,15 @@ +/* All elements with class="spacious" */ +.spacious { + margin: 2em; +} + +/* All

  • elements with class="spacious" */ +li.spacious { + margin: 2em; +} + +/* All
  • elements with a class list that includes both "spacious" and "elegant" */ +/* For example, class="elegant retro spacious" */ +li.spacious.elegant { + margin: 2em; +} diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java b/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java index a0f6f453f32..05fa56798fe 100644 --- a/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java +++ b/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java @@ -29,7 +29,7 @@ class BinaryDistributionIT extends AbstractBinaryDistributionTest { private static final List SUPPORTED_LANGUAGES_CPD = listOf( - "apex", "coco", "cpp", "cs", "dart", "ecmascript", + "apex", "coco", "cpp", "cs", "css", "dart", "ecmascript", "fortran", "gherkin", "go", "groovy", "html", "java", "jsp", "julia", "kotlin", "lua", "matlab", "modelica", "objectivec", "perl", diff --git a/pom.xml b/pom.xml index 53bfef8b4fc..d8c71cb27fe 100644 --- a/pom.xml +++ b/pom.xml @@ -1396,6 +1396,7 @@ pmd-core pmd-cpp pmd-cs + pmd-css pmd-dart pmd-doc pmd-fortran @@ -1432,4 +1433,4 @@ pmd-ant pmd-languages-deps - + \ No newline at end of file From 91b146843a31750072da326a293d055d9a31687e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 8 May 2025 20:40:22 +0200 Subject: [PATCH 0855/1962] [java] Fix #5724 - implicit functional interface FP with sealed interface --- .../ImplicitFunctionalInterfaceRule.java | 5 +++- .../xml/ImplicitFunctionalInterface.xml | 24 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ImplicitFunctionalInterfaceRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ImplicitFunctionalInterfaceRule.java index 00e8e23df0e..a77e66789b8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ImplicitFunctionalInterfaceRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ImplicitFunctionalInterfaceRule.java @@ -5,6 +5,7 @@ package net.sourceforge.pmd.lang.java.rule.bestpractices; import net.sourceforge.pmd.lang.java.ast.ASTClassDeclaration; +import net.sourceforge.pmd.lang.java.ast.JModifier; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; import net.sourceforge.pmd.lang.java.types.JMethodSig; import net.sourceforge.pmd.lang.java.types.TypeOps; @@ -16,7 +17,9 @@ public ImplicitFunctionalInterfaceRule() { @Override public Object visit(ASTClassDeclaration node, Object data) { - if (node.isInterface() && !node.isAnnotationPresent(FunctionalInterface.class)) { + if (node.isRegularInterface() + && !node.isAnnotationPresent(FunctionalInterface.class) + && !node.hasModifiers(JModifier.SEALED)) { JMethodSig fun = TypeOps.findFunctionalInterfaceMethod(node.getTypeMirror()); if (fun != null) { asCtx(data).addViolation(node); diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/ImplicitFunctionalInterface.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/ImplicitFunctionalInterface.xml index 83b5fd47327..11ebc203339 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/ImplicitFunctionalInterface.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/ImplicitFunctionalInterface.xml @@ -39,4 +39,28 @@ interface Bar extends Foo { // warn ]]> + + + ImplicitFunctionalInterface should not be reported on sealed interfaces #5724 + 0 + + + + + Annotation + 0 + + + + From 6fec7aa1c4dcab06be0cee5ad026cb1902a38487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 8 May 2025 23:18:21 +0200 Subject: [PATCH 0856/1962] Add test case from #5664 - unreproducible --- .../bestpractices/xml/UnusedPrivateMethod.xml | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index 2cc045c16a0..b8f68513b96 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2665,4 +2665,27 @@ class Foo { } ]]> + + + [java] UnusedPrivateMethod false-positive #5664 + 0 + + From 806f88edac8376b553fb905b50c6ba5d703437b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 8 May 2025 23:28:15 +0200 Subject: [PATCH 0857/1962] Save expr in ctdecl --- .../lang/java/types/internal/infer/ExprMirror.java | 12 +++++++++--- .../pmd/lang/java/types/internal/infer/Infer.java | 3 ++- .../rule/bestpractices/xml/UnusedPrivateMethod.xml | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java index 40f550e4a1d..22af0941196 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java @@ -451,17 +451,20 @@ class MethodCtDecl implements OverloadSelectionResult { private final boolean canSkipInvocation; private final boolean needsUncheckedConversion; private final boolean failed; + private final @Nullable InvocationMirror expr; MethodCtDecl(JMethodSig methodType, MethodResolutionPhase resolvePhase, boolean canSkipInvocation, boolean needsUncheckedConversion, - boolean failed) { + boolean failed, + @Nullable InvocationMirror expr) { this.methodType = methodType; this.resolvePhase = resolvePhase; this.canSkipInvocation = canSkipInvocation; this.needsUncheckedConversion = needsUncheckedConversion; this.failed = failed; + this.expr = expr; } // package-private: @@ -471,7 +474,10 @@ MethodCtDecl withMethod(JMethodSig method) { } MethodCtDecl withMethod(JMethodSig method, boolean failed) { - return new MethodCtDecl(method, resolvePhase, canSkipInvocation, needsUncheckedConversion, failed); + return new MethodCtDecl(method, resolvePhase, canSkipInvocation, needsUncheckedConversion, failed, expr); + } + MethodCtDecl withExpr(InvocationMirror expr) { + return new MethodCtDecl(methodType, resolvePhase, canSkipInvocation, needsUncheckedConversion, failed, expr); } MethodCtDecl asFailed() { @@ -487,7 +493,7 @@ MethodResolutionPhase getResolvePhase() { } static MethodCtDecl unresolved(TypeSystem ts) { - return new MethodCtDecl(ts.UNRESOLVED_METHOD, STRICT, true, false, true); + return new MethodCtDecl(ts.UNRESOLVED_METHOD, STRICT, true, false, true, null); } // public: diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java index 0016cc60560..e840b631df3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java @@ -375,7 +375,8 @@ private boolean assertReturnIsGround(JMethodSig t) { phase, site.canSkipInvocation(), site.needsUncheckedConversion(), - false); + false, + site.getExpr()); } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index 103c5a1646d..76511722bd9 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2672,7 +2672,7 @@ class Foo { } private void handleRequest(RoutingContext rc) { } -// private void handleRequest(String rc) { } + private void handleRequest(String rc) { } } ]]> From b893145da209065e5789e4c857d5fde773fb4b2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 9 May 2025 00:09:43 +0200 Subject: [PATCH 0858/1962] Make AstMethodReference have access to overload selection info --- .../pmd/lang/java/ast/ASTMethodReference.java | 12 ++++-- .../pmd/lang/java/ast/InternalApiBridge.java | 2 +- .../pmd/lang/java/ast/InvocationNode.java | 7 ---- .../pmd/lang/java/ast/MethodUsage.java | 10 ++++- .../codestyle/UseDiamondOperatorRule.java | 4 +- .../java/types/OverloadSelectionResult.java | 15 +++++++ .../types/internal/infer/ExprCheckHelper.java | 34 ++++++++------- .../java/types/internal/infer/ExprMirror.java | 41 ++++++++++++++----- .../java/types/internal/infer/ExprOps.java | 2 +- .../lang/java/types/internal/infer/Infer.java | 21 +++++++--- .../internal/infer/ast/BaseInvocMirror.java | 2 +- .../internal/infer/ast/CtorInvocMirror.java | 2 +- .../infer/ast/MethodRefMirrorImpl.java | 12 +++--- 13 files changed, 111 insertions(+), 53 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodReference.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodReference.java index 71064685632..31eb9145891 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodReference.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodReference.java @@ -10,6 +10,7 @@ import net.sourceforge.pmd.lang.java.symbols.JConstructorSymbol; import net.sourceforge.pmd.lang.java.types.JMethodSig; import net.sourceforge.pmd.lang.java.types.JTypeMirror; +import net.sourceforge.pmd.lang.java.types.OverloadSelectionResult; import net.sourceforge.pmd.lang.java.types.TypeSystem; /** @@ -29,7 +30,7 @@ public final class ASTMethodReference extends AbstractJavaExpr FunctionalExpression { private JMethodSig functionalMethod; - private JMethodSig compileTimeDecl; + private OverloadSelectionResult compileTimeDecl; private String methodName; @@ -152,6 +153,11 @@ public JMethodSig getFunctionalMethod() { * @see #getTypeMirror() */ public JMethodSig getReferencedMethod() { + return getOverloadSelectionInfo().getMethodType(); + } + + @Override + public OverloadSelectionResult getOverloadSelectionInfo() { forceTypeResolution(); return assertNonNullAfterTypeRes(compileTimeDecl); } @@ -160,8 +166,8 @@ void setFunctionalMethod(JMethodSig methodType) { this.functionalMethod = methodType; } - void setCompileTimeDecl(JMethodSig methodType) { - this.compileTimeDecl = methodType; + void setCompileTimeDecl(OverloadSelectionResult ctdecl) { + this.compileTimeDecl = ctdecl; } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalApiBridge.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalApiBridge.java index 5c237aec699..bdaf9e89724 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalApiBridge.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalApiBridge.java @@ -142,7 +142,7 @@ public static void setFunctionalMethod(FunctionalExpression node, JMethodSig met } } - public static void setCompileTimeDecl(ASTMethodReference methodReference, JMethodSig methodType) { + public static void setCompileTimeDecl(ASTMethodReference methodReference, OverloadSelectionResult methodType) { methodReference.setCompileTimeDecl(methodType); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InvocationNode.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InvocationNode.java index 80563b665b1..54ba92cacf4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InvocationNode.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InvocationNode.java @@ -49,11 +49,4 @@ default JMethodSig getMethodType() { } - /** - * Returns information about the overload selection for this call. - * Be aware, that selection might have failed ({@link OverloadSelectionResult#isFailed()}). - */ - OverloadSelectionResult getOverloadSelectionInfo(); - - } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/MethodUsage.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/MethodUsage.java index d85602411ca..cbb473a6381 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/MethodUsage.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/MethodUsage.java @@ -7,6 +7,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import net.sourceforge.pmd.lang.java.symbols.JConstructorSymbol; +import net.sourceforge.pmd.lang.java.types.OverloadSelectionResult; /** * A node that uses another method or constructor. Those are @@ -22,6 +23,13 @@ public interface MethodUsage extends JavaNode { * call, returns {@link JConstructorSymbol#CTOR_NAME}. */ default @NonNull String getMethodName() { - return JConstructorSymbol.CTOR_NAME; + return JConstructorSymbol.CTOR_NAME; // todo remove this default } + + /** + * Returns information about the overload selection for this call. + * Be aware, that selection might have failed ({@link OverloadSelectionResult#isFailed()}). + */ + OverloadSelectionResult getOverloadSelectionInfo(); + } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseDiamondOperatorRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseDiamondOperatorRule.java index fad61d36f8f..9e0df8176da 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseDiamondOperatorRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseDiamondOperatorRule.java @@ -218,8 +218,8 @@ public JTypeMirror getInferredType() { } @Override - public void setCtDecl(MethodCtDecl methodType) { - base.setCtDecl(methodType); + public void setCompileTimeDecl(MethodCtDecl methodType) { + base.setCompileTimeDecl(methodType); } @Override diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java index 544d008d6b2..6cee7f2b6c0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java @@ -82,4 +82,19 @@ default JTypeMirror ithFormalParam(int i) { * one was chosen. */ boolean isFailed(); + + + /** + * Whether there were several candidates for this method resolution. + * + *

    Candidates are not necessarily overloads of each other, they are + * just all the methods with the right name that could possibly be + * called at the invocation site because they're in scope. For instance + * in {@code call(1)}, maybe the method {@code call} is imported, + * inherited, defined in an outer class. In {@code a.call(1)}, the + * candidates are just the methods named {@code call} visible from + * the type of {@code a}. If some overloads are not visible at the + * call site, they are also not candidates. + */ + boolean hadUniqueAccessibleCandidate(); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java index 3aededfa5ea..0b7dd29f3fc 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java @@ -40,6 +40,7 @@ import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.MethodRefMirror; import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.PolyExprMirror; import net.sourceforge.pmd.util.CollectionUtil; +import net.sourceforge.pmd.util.OptionalBool; @SuppressWarnings("PMD.CompareObjectsWithEquals") final class ExprCheckHelper { @@ -164,7 +165,7 @@ private boolean isInvocationCompatible(JTypeMirror targetType, InvocationMirror if (argCtDecl == infer.FAILED_INVOCATION) { throw ResolutionFailedException.incompatibleFormal(infer.LOG, invoc, ts.ERROR, targetType); - } else if (argCtDecl == infer.NO_CTDECL) { + } else if (argCtDecl == infer.getMissingCtDecl()) { JTypeMirror fallback = invoc.unresolvedType(); if (fallback != null) { actualType = fallback; @@ -172,7 +173,7 @@ private boolean isInvocationCompatible(JTypeMirror targetType, InvocationMirror // else it's ts.UNRESOLVED if (mayMutateExpr()) { invoc.setInferredType(fallback); - invoc.setCtDecl(infer.NO_CTDECL); + invoc.setCompileTimeDecl(infer.getMissingCtDecl()); } } @@ -197,7 +198,7 @@ private boolean isInvocationCompatible(JTypeMirror targetType, InvocationMirror solved -> { JMethodSig ground = solved.ground(mostSpecific); invoc.setInferredType(ground.getReturnType()); - invoc.setCtDecl(argCtDecl.withMethod(ground)); + invoc.setCompileTimeDecl(argCtDecl.withMethod(ground)); } ); } @@ -372,14 +373,14 @@ private boolean isMethodRefCompatible(@NonNull JClassType functionalItf, MethodR // type of the potentially applicable compile-time declaration. checker.checkExprConstraint(infCtx, capture(r2), r); } - completeMethodRefInference(mref, nonWildcard, fun, exactMethod, true); + completeMethodRefInference(mref, nonWildcard, fun, mrefSigAsCtDecl(exactMethod), true); } else if (TypeOps.isUnresolved(mref.getTypeToSearch())) { // Then this is neither an exact nor inexact method ref, // we just don't know what it is. // The return values of the mref are assimilated to an (*unknown*) type. checker.checkExprConstraint(infCtx, ts.UNKNOWN, fun.getReturnType()); - completeMethodRefInference(mref, nonWildcard, fun, ts.UNRESOLVED_METHOD, false); + completeMethodRefInference(mref, nonWildcard, fun, infer.getMissingCtDecl(), false); } else { // Otherwise, the method reference is inexact, and: @@ -414,7 +415,7 @@ private void solveInexactMethodRefCompatibility(MethodRefMirror mref, JClassType JTypeMirror r = fun.getReturnType(); if (r == ts.NO_TYPE) { // If R is void, the constraint reduces to true. - completeMethodRefInference(mref, nonWildcard, fun, ctdecl, false); + completeMethodRefInference(mref, nonWildcard, fun, mrefSigAsCtDecl(ctdecl), false); return; } @@ -453,11 +454,13 @@ private void solveInexactMethodRefCompatibility(MethodRefMirror mref, JClassType // as dependencies between these new variables and the inference variables in T. if (phase.isInvocation()) { - JMethodSig sig = inferMethodRefInvocation(mref, fun, ctdecl0); + MethodCtDecl sig = inferMethodRefInvocation(mref, fun, ctdecl0); if (fixInstantiation) { // We know that fun & sig have the same type params // We need to fix those that are out-of-scope - sig = sig.subst(Substitution.mapping(fun.getTypeParameters(), sig.getTypeParameters())); + JMethodSig inferred = sig.getMethodType(); + inferred = inferred.subst(Substitution.mapping(fun.getTypeParameters(), inferred.getTypeParameters())); + sig = sig.withMethod(inferred); } completeMethodRefInference(mref, nonWildcard, fun, sig, false); } @@ -469,12 +472,12 @@ private void solveInexactMethodRefCompatibility(MethodRefMirror mref, JClassType throw ResolutionFailedException.incompatibleReturn(infer.LOG, mref, ctdecl.getReturnType(), r); } else { checker.checkExprConstraint(infCtx, capture(ctdecl.getReturnType()), r); - completeMethodRefInference(mref, nonWildcard, fun, ctdecl, false); + completeMethodRefInference(mref, nonWildcard, fun, mrefSigAsCtDecl(ctdecl), false); } } } - private void completeMethodRefInference(MethodRefMirror mref, JClassType groundTargetType, JMethodSig functionalMethod, JMethodSig ctDecl, boolean isExactMethod) { + private void completeMethodRefInference(MethodRefMirror mref, JClassType groundTargetType, JMethodSig functionalMethod, MethodCtDecl ctDecl, boolean isExactMethod) { if ((phase.isInvocation() || isExactMethod) && mayMutateExpr()) { // if exact, then the arg is relevant to applicability and there // may not be an invocation round @@ -483,18 +486,21 @@ private void completeMethodRefInference(MethodRefMirror mref, JClassType groundT solved -> { mref.setInferredType(solved.ground(groundTargetType)); mref.setFunctionalMethod(cast(solved.ground(functionalMethod)).withOwner(solved.ground(functionalMethod.getDeclaringType()))); - mref.setCompileTimeDecl(solved.ground(ctDecl)); + mref.setCompileTimeDecl(ctDecl.withMethod(solved.ground(ctDecl.getMethodType()))); } ); } } + MethodCtDecl mrefSigAsCtDecl(JMethodSig sig) { + return new MethodCtDecl(sig, MethodResolutionPhase.INVOC_LOOSE, false, OptionalBool.UNKNOWN, false, null); + } - JMethodSig inferMethodRefInvocation(MethodRefMirror mref, JMethodSig targetType, MethodCtDecl ctdecl) { + MethodCtDecl inferMethodRefInvocation(MethodRefMirror mref, JMethodSig targetType, MethodCtDecl ctdecl) { InvocationMirror wrapper = methodRefAsInvocation(mref, targetType, false); - wrapper.setCtDecl(ctdecl); + wrapper.setCompileTimeDecl(ctdecl); MethodCallSite mockSite = infer.newCallSite(wrapper, /* expected */ targetType.getReturnType(), site, infCtx, isSpecificityCheck()); - return infer.determineInvocationTypeOrFail(mockSite).getMethodType(); + return infer.determineInvocationTypeOrFail(mockSite); } /** diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java index 22af0941196..b60adbd1a86 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java @@ -8,6 +8,7 @@ import static net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.TypeSpecies.getSpecies; import static net.sourceforge.pmd.lang.java.types.internal.infer.MethodResolutionPhase.STRICT; +import java.util.Iterator; import java.util.List; import java.util.function.Predicate; @@ -24,6 +25,7 @@ import net.sourceforge.pmd.lang.java.types.TypeOps; import net.sourceforge.pmd.lang.java.types.TypeSystem; import net.sourceforge.pmd.lang.java.types.TypingContext; +import net.sourceforge.pmd.util.OptionalBool; /** * Adapter class to manipulate expressions. The framework @@ -240,10 +242,15 @@ interface FunctionalExprMirror extends PolyExprMirror { void finishFailedInference(@Nullable JTypeMirror targetType); } + interface MethodUsageMirror extends PolyExprMirror { + + void setCompileTimeDecl(InvocationMirror.MethodCtDecl methodType); + } + /** * Mirror of a method reference expression. */ - interface MethodRefMirror extends FunctionalExprMirror { + interface MethodRefMirror extends FunctionalExprMirror, MethodUsageMirror { /** True if this references a ctor. */ boolean isConstructorRef(); @@ -286,7 +293,8 @@ interface MethodRefMirror extends FunctionalExprMirror { * E.g. in {@code stringStream.map(String::isEmpty)}, this is * {@code java.lang.String.isEmpty() -> boolean} */ - void setCompileTimeDecl(JMethodSig methodType); + @Override + void setCompileTimeDecl(InvocationMirror.MethodCtDecl methodType); /** @@ -369,7 +377,7 @@ default boolean isExplicitlyTyped() { /** * Adapter over a method or constructor invocation expression. */ - interface InvocationMirror extends PolyExprMirror { + interface InvocationMirror extends PolyExprMirror, MethodUsageMirror { /** * Enumerates *accessible* method (or ctor) signatures with @@ -427,11 +435,12 @@ interface InvocationMirror extends PolyExprMirror { int getArgumentCount(); - void setCtDecl(MethodCtDecl methodType); + @Override + void setCompileTimeDecl(MethodCtDecl methodType); /** - * Returns the method type set with {@link #setCtDecl(MethodCtDecl)} + * Returns the method type set with {@link #setCompileTimeDecl(MethodCtDecl)} * or null if that method was never called. This is used to perform * overload resolution exactly once per call site. */ @@ -449,14 +458,14 @@ class MethodCtDecl implements OverloadSelectionResult { private final JMethodSig methodType; private final MethodResolutionPhase resolvePhase; private final boolean canSkipInvocation; - private final boolean needsUncheckedConversion; + private final OptionalBool needsUncheckedConversion; private final boolean failed; private final @Nullable InvocationMirror expr; MethodCtDecl(JMethodSig methodType, MethodResolutionPhase resolvePhase, boolean canSkipInvocation, - boolean needsUncheckedConversion, + OptionalBool needsUncheckedConversion, boolean failed, @Nullable InvocationMirror expr) { this.methodType = methodType; @@ -469,7 +478,7 @@ class MethodCtDecl implements OverloadSelectionResult { // package-private: - MethodCtDecl withMethod(JMethodSig method) { + public MethodCtDecl withMethod(JMethodSig method) { return withMethod(method, failed); } @@ -493,7 +502,7 @@ MethodResolutionPhase getResolvePhase() { } static MethodCtDecl unresolved(TypeSystem ts) { - return new MethodCtDecl(ts.UNRESOLVED_METHOD, STRICT, true, false, true, null); + return new MethodCtDecl(ts.UNRESOLVED_METHOD, STRICT, true, OptionalBool.UNKNOWN, true, null); } // public: @@ -506,7 +515,7 @@ public JMethodSig getMethodType() { @Override public boolean needsUncheckedConversion() { - return needsUncheckedConversion; + return needsUncheckedConversion.isTrue(); } @Override @@ -524,6 +533,18 @@ public String toString() { return "CtDecl[phase=" + resolvePhase + ", method=" + methodType + ']'; } + @Override + public boolean hadUniqueAccessibleCandidate() { + if (expr == null) { + return false; + } + Iterator candidates = expr.getAccessibleCandidates().iterator(); + if (candidates.hasNext()) { + candidates.next(); + return !candidates.hasNext(); + } + return false; + } } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java index 287faa28661..cdcaa9078fa 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java @@ -412,7 +412,7 @@ public int getArgumentCount() { } @Override - public void setCtDecl(MethodCtDecl methodType) { + public void setCompileTimeDecl(MethodCtDecl methodType) { this.mt = methodType; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java index e840b631df3..db45bd3ddaf 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java @@ -39,6 +39,7 @@ import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.PolyExprMirror; import net.sourceforge.pmd.lang.java.types.internal.infer.InferenceVar.BoundKind; import net.sourceforge.pmd.util.CollectionUtil; +import net.sourceforge.pmd.util.OptionalBool; /** * Main entry point for type inference. @@ -53,7 +54,7 @@ public final class Infer { private final boolean isPreJava8; private final TypeSystem ts; - final MethodCtDecl NO_CTDECL; // SUPPRESS CHECKSTYLE same + private final MethodCtDecl NO_CTDECL; // SUPPRESS CHECKSTYLE same /** This is a sentinel for when the CTDecl was resolved, but invocation failed. */ final MethodCtDecl FAILED_INVOCATION; // SUPPRESS CHECKSTYLE same @@ -91,6 +92,10 @@ public TypeInferenceLogger getLogger() { return LOG; } + public MethodCtDecl getMissingCtDecl() { + return NO_CTDECL; + } + public PolySite newFunctionalSite(FunctionalExprMirror mirror, @Nullable JTypeMirror expectedType) { return new PolySite<>(mirror, expectedType); } @@ -164,7 +169,7 @@ public void inferFunctionalExprInUnambiguousContext(PolySite implements MethodRefMirror { private JMethodSig exactMethod; - private JMethodSig ctdecl; + private MethodCtDecl ctdecl; MethodRefMirrorImpl(JavaExprMirrors mirrors, ASTMethodReference lambda, ExprMirror parent, MirrorMaker subexprMaker) { super(mirrors, lambda, parent, subexprMaker); @@ -38,8 +39,6 @@ final class MethodRefMirrorImpl extends BaseFunctionalMirror // this is in case of failure: if the inference doesn't succeed // and doesn't end up calling those, then we still have a non-null // result in there. - setFunctionalMethod(mirrors.ts.UNRESOLVED_METHOD); - setCompileTimeDecl(mirrors.ts.UNRESOLVED_METHOD); // don't call this one as it would mean to the node "don't recompute my type" // even if a parent conditional failed its standalone test // setInferredType(mirrors.ts.UNKNOWN); @@ -48,16 +47,17 @@ final class MethodRefMirrorImpl extends BaseFunctionalMirror @Override public void finishFailedInference(@Nullable JTypeMirror targetType) { super.finishFailedInference(targetType); + MethodCtDecl noCtDecl = factory.infer.getMissingCtDecl(); if (!TypeOps.isUnresolved(getTypeToSearch())) { JMethodSig exactMethod = ExprOps.getExactMethod(this); if (exactMethod != null) { // as a fallback, if the method reference is exact, // we populate the compile time decl anyway. - setCompileTimeDecl(exactMethod); + setCompileTimeDecl(noCtDecl.withMethod(exactMethod)); return; } } - setCompileTimeDecl(factory.ts.UNRESOLVED_METHOD); + setCompileTimeDecl(noCtDecl); } @Override @@ -92,7 +92,7 @@ public String getMethodName() { } @Override - public void setCompileTimeDecl(JMethodSig methodType) { + public void setCompileTimeDecl(MethodCtDecl methodType) { this.ctdecl = methodType; if (mayMutateAst()) { InternalApiBridge.setCompileTimeDecl(myNode, methodType); From a23bff3f25d4f9e210e586d15b6b40957db584b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 9 May 2025 00:51:08 +0200 Subject: [PATCH 0859/1962] Improve UnusedPrivateMethod with method ref when types unresolved --- .../UnusedPrivateMethodRule.java | 29 +++++++--- .../java/types/OverloadSelectionResult.java | 18 ++----- .../java/types/internal/infer/ExprMirror.java | 26 +++++---- .../infer/ast/MethodRefMirrorImpl.java | 2 +- .../bestpractices/xml/UnusedPrivateMethod.xml | 54 +++++++++++++++++++ 5 files changed, 93 insertions(+), 36 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java index b2fa36d1c46..0095fae7e51 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodRule.java @@ -28,6 +28,9 @@ import net.sourceforge.pmd.lang.java.ast.internal.PrettyPrintingUtil; import net.sourceforge.pmd.lang.java.rule.internal.AbstractIgnoredAnnotationRule; import net.sourceforge.pmd.lang.java.symbols.JExecutableSymbol; +import net.sourceforge.pmd.lang.java.types.JTypeMirror; +import net.sourceforge.pmd.lang.java.types.OverloadSelectionResult; +import net.sourceforge.pmd.lang.java.types.TypeOps; import net.sourceforge.pmd.lang.java.types.TypeTestUtil; /** @@ -62,7 +65,12 @@ public Object visit(ASTCompilationUnit file, Object param) { .crossFindBoundaries() .map(asInstanceOf(ASTMethodCall.class, ASTMethodReference.class)) .forEach(ref -> { - JExecutableSymbol calledMethod = getMethodSymbol(ref); + OverloadSelectionResult selectionInfo = ref.getOverloadSelectionInfo(); + JExecutableSymbol calledMethod = selectionInfo.getMethodType().getSymbol(); + if (calledMethod.isUnresolved()) { + handleUnresolvedCall(ref, selectionInfo, candidates); + return; + } candidates.compute(calledMethod, (sym2, reffed) -> { if (reffed != null && ref.ancestors(ASTMethodDeclaration.class).first() != reffed) { // remove mapping, but only if it is called from outside itself @@ -78,16 +86,21 @@ public Object visit(ASTCompilationUnit file, Object param) { return null; } - private static JExecutableSymbol getMethodSymbol(MethodUsage ref) { - if (ref instanceof ASTMethodCall) { - return ((ASTMethodCall) ref).getMethodType().getSymbol(); - } else if (ref instanceof ASTMethodReference) { - return ((ASTMethodReference) ref).getReferencedMethod().getSymbol(); + private static void handleUnresolvedCall(MethodUsage ref, OverloadSelectionResult selectionInfo, Map candidates) { + // If the type is may be an instance of this class, then the method may be + // a call to a private method here. In that case we whitelist all methods + // with that name. + JTypeMirror receive = selectionInfo.getTypeToSearch(); + boolean receiverMayBeInstanceOfThisClass = + receive == null + || TypeOps.isSpecialUnresolved(receive) + || receive.equals(ref.getEnclosingType().getTypeMirror()); + + if (receiverMayBeInstanceOfThisClass) { + candidates.values().removeIf(it -> it.getName().equals(ref.getMethodName())); } - throw new IllegalStateException("unknown type: " + ref); } - /** * Collect potential unused private methods and index them by their symbol. * We don't use {@link JExecutableSymbol#tryGetNode()} because it may return diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java index 6cee7f2b6c0..e903c079a32 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java @@ -4,6 +4,9 @@ package net.sourceforge.pmd.lang.java.types; +import org.checkerframework.checker.nullness.qual.Nullable; + +import net.sourceforge.pmd.annotation.Experimental; import net.sourceforge.pmd.lang.java.ast.ASTConstructorCall; import net.sourceforge.pmd.lang.java.ast.ASTEnumConstant; import net.sourceforge.pmd.lang.java.ast.InvocationNode; @@ -84,17 +87,6 @@ default JTypeMirror ithFormalParam(int i) { boolean isFailed(); - /** - * Whether there were several candidates for this method resolution. - * - *

    Candidates are not necessarily overloads of each other, they are - * just all the methods with the right name that could possibly be - * called at the invocation site because they're in scope. For instance - * in {@code call(1)}, maybe the method {@code call} is imported, - * inherited, defined in an outer class. In {@code a.call(1)}, the - * candidates are just the methods named {@code call} visible from - * the type of {@code a}. If some overloads are not visible at the - * call site, they are also not candidates. - */ - boolean hadUniqueAccessibleCandidate(); + @Experimental + @Nullable JTypeMirror getTypeToSearch(); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java index b60adbd1a86..08efc350bfe 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java @@ -8,7 +8,6 @@ import static net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.TypeSpecies.getSpecies; import static net.sourceforge.pmd.lang.java.types.internal.infer.MethodResolutionPhase.STRICT; -import java.util.Iterator; import java.util.List; import java.util.function.Predicate; @@ -245,6 +244,8 @@ interface FunctionalExprMirror extends PolyExprMirror { interface MethodUsageMirror extends PolyExprMirror { void setCompileTimeDecl(InvocationMirror.MethodCtDecl methodType); + + @Nullable JTypeMirror getTypeToSearch(); } /** @@ -379,6 +380,7 @@ default boolean isExplicitlyTyped() { */ interface InvocationMirror extends PolyExprMirror, MethodUsageMirror { + /** * Enumerates *accessible* method (or ctor) signatures with * *the same name* as this invocation. Name and accessibility @@ -446,6 +448,9 @@ interface InvocationMirror extends PolyExprMirror, MethodUsageMirror { */ @Nullable MethodCtDecl getCtDecl(); + default @Nullable JTypeMirror getTypeToSearch() { + return getReceiverType(); + } /** * Information about the overload-resolution for a specific method. @@ -460,14 +465,14 @@ class MethodCtDecl implements OverloadSelectionResult { private final boolean canSkipInvocation; private final OptionalBool needsUncheckedConversion; private final boolean failed; - private final @Nullable InvocationMirror expr; + private final @Nullable MethodUsageMirror expr; MethodCtDecl(JMethodSig methodType, MethodResolutionPhase resolvePhase, boolean canSkipInvocation, OptionalBool needsUncheckedConversion, boolean failed, - @Nullable InvocationMirror expr) { + @Nullable MethodUsageMirror expr) { this.methodType = methodType; this.resolvePhase = resolvePhase; this.canSkipInvocation = canSkipInvocation; @@ -485,7 +490,8 @@ public MethodCtDecl withMethod(JMethodSig method) { MethodCtDecl withMethod(JMethodSig method, boolean failed) { return new MethodCtDecl(method, resolvePhase, canSkipInvocation, needsUncheckedConversion, failed, expr); } - MethodCtDecl withExpr(InvocationMirror expr) { + + public MethodCtDecl withExpr(MethodUsageMirror expr) { return new MethodCtDecl(methodType, resolvePhase, canSkipInvocation, needsUncheckedConversion, failed, expr); } @@ -534,16 +540,8 @@ public String toString() { } @Override - public boolean hadUniqueAccessibleCandidate() { - if (expr == null) { - return false; - } - Iterator candidates = expr.getAccessibleCandidates().iterator(); - if (candidates.hasNext()) { - candidates.next(); - return !candidates.hasNext(); - } - return false; + public @Nullable JTypeMirror getTypeToSearch() { + return expr != null ? expr.getTypeToSearch() : null; } } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/MethodRefMirrorImpl.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/MethodRefMirrorImpl.java index b9c05b617a0..2e8ba5e8d87 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/MethodRefMirrorImpl.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/MethodRefMirrorImpl.java @@ -47,7 +47,7 @@ final class MethodRefMirrorImpl extends BaseFunctionalMirror @Override public void finishFailedInference(@Nullable JTypeMirror targetType) { super.finishFailedInference(targetType); - MethodCtDecl noCtDecl = factory.infer.getMissingCtDecl(); + MethodCtDecl noCtDecl = factory.infer.getMissingCtDecl().withExpr(this); if (!TypeOps.isUnresolved(getTypeToSearch())) { JMethodSig exactMethod = ExprOps.getExactMethod(this); if (exactMethod != null) { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index 76511722bd9..427523856a1 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2677,6 +2677,60 @@ class Foo { ]]> + + + Verify that if the method ref is obviously in another class our methods are still flagged + 4 + + Avoid unused private methods such as 'alala(RoutingContext)'. + Avoid unused private methods such as 'alala(String)'. + Avoid unused private methods such as 'elelel(RoutingContext)'. + Avoid unused private methods such as 'elelel(String)'. + + > routes() { + return List.of( + // Other is an ambiguous name and it may be var or type, + // therefore it has a fully unknown type + r -> r.post("/some/path").handler(Other::handleRequest) + ); + return List.of( + // This is an unresolved type but unambiguous thanks to the + // import. That means we know that Bar::alala cannot + // be a reference to one of Foo's alala methods. + r -> r.post("/some/path").handler(Bar::alala) + ); + return List.of( + // This is a fully known type, same thing + r -> r.post("/some/path").handler(String::elelel) + ); + } + + private void handleRequest(RoutingContext rc) { } + private void handleRequest(String rc) { } + + private void alala(RoutingContext rc) { } + private void alala(String rc) { } + + private void elelel(RoutingContext rc) { } + private void elelel(String rc) { } +} +]]> + + [java] UnusedPrivateMethod false-positive #5664 0 From ac2eb2961e3244f0c8d5ded1569bde93283f0823 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 9 May 2025 01:34:22 +0200 Subject: [PATCH 0860/1962] Add new test --- .../bestpractices/xml/UnusedPrivateMethod.xml | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index 427523856a1..00a462f93a5 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2754,4 +2754,29 @@ class Foo { ]]> + + + FP with lambda + 0 + { + method(unresolved); + }); + } + } + } + ]]> + + + + From 2131e5e2a2281b49f846678e3a59f081eafcf758 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 1 May 2025 10:49:50 +0200 Subject: [PATCH 0861/1962] [ci] publish-pull-requests: add timestamp of last update --- .github/workflows/publish-pull-requests.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/publish-pull-requests.yml b/.github/workflows/publish-pull-requests.yml index 1ab63e5d310..dedbfc05c0f 100644 --- a/.github/workflows/publish-pull-requests.yml +++ b/.github/workflows/publish-pull-requests.yml @@ -156,9 +156,12 @@ jobs: comment="[Documentation Preview](https://pull-requests.pmd-code.org/pr-${PR_NUMBER}/${PR_SHA}/docs) ${summary} + + (comment created at $(date -u --rfc-3339=seconds) for ${PR_SHA}) " echo "${comment}" > comment.txt - uses: marocchino/sticky-pull-request-comment@v2 with: + header: pmd-publish-pull-requests number: ${{ env.PR_NUMBER }} path: comment.txt From 98ca69d4a231727020a22a15faf9071bd731dd81 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 1 May 2025 11:27:13 +0200 Subject: [PATCH 0862/1962] [ci] publish-pull-requests: document robots.txt --- .../pmd/devdocs/github_actions_workflows.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/pages/pmd/devdocs/github_actions_workflows.md b/docs/pages/pmd/devdocs/github_actions_workflows.md index 0ba0053cc25..ee9698d945b 100644 --- a/docs/pages/pmd/devdocs/github_actions_workflows.md +++ b/docs/pages/pmd/devdocs/github_actions_workflows.md @@ -101,3 +101,19 @@ to create or update a comment on the pull request which shows the regression tes This workflow is in that sense optional, as the docs-artifact and pmd-regression-tester artifacts can be manually downloaded from the "Pull Request Build" workflow run. It merely adds convenience by giving easy access to a preview of the documentation and to the regression tester results. + +In the end, this workflow adds additional links to a pull request page. For the comment, GitHub seems +to automatically add "rel=nofollow" to the links in the text. This is also applied for the check status +pages. However, the links in the commit status are plain links. This might lead to unnecessary +crawling by search engines. To avoid this, the following robots.txt is used +at to disallow any (search engine) bot: + +``` +User-agent: * +Disallow: / +``` + +The reasons, why we don't want to have the pages there indexed: They are short-lived and only +temporary. These temporary created documentation pages should not end up in any search result. +This also helps to avoid unnecessary traffic and load for both the hosting side and the +crawling side. From 4084b24b5167f50606f9cf416fc5547ded76f6ec Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 1 May 2025 11:42:12 +0200 Subject: [PATCH 0863/1962] [ci] publish-pull-requests: add better job summary --- .github/workflows/publish-pull-requests.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/publish-pull-requests.yml b/.github/workflows/publish-pull-requests.yml index dedbfc05c0f..33ef5c48254 100644 --- a/.github/workflows/publish-pull-requests.yml +++ b/.github/workflows/publish-pull-requests.yml @@ -39,7 +39,18 @@ jobs: echo "PR_NUMBER=${PR_NUMBER}" >> "${GITHUB_ENV}" echo "PR_BRANCH=${PR_BRANCH}" >> "${GITHUB_ENV}" echo "PR_SHA=${PR_SHA}" >> "${GITHUB_ENV}" + - name: Add Job Summary + env: + WORKFLOW_RUN_DISPLAY_TITLE: ${{ github.event.workflow_run.display_title }} + WORKFLOW_RUN_NAME: ${{ github.event.workflow_run.name }} + WORKFLOW_RUN_NUMBER: ${{ github.event.workflow_run.run_number }} + WORKFLOW_RUN_HTML_URL: ${{ github.event.workflow_run.html_url }} + run: | + echo "### Run Info" >> "${GITHUB_STEP_SUMMARY}" echo "Triggered for PR [#${PR_NUMBER}](https://github.com/pmd/pmd/pull/${PR_NUMBER})" >> "${GITHUB_STEP_SUMMARY}" + echo "" >> "${GITHUB_STEP_SUMMARY}" + echo "Called by [${WORKFLOW_RUN_DISPLAY_TITLE} (${WORKFLOW_RUN_NAME} #${WORKFLOW_RUN_NUMBER})](${WORKFLOW_RUN_HTML_URL})" >> "${GITHUB_STEP_SUMMARY}" + echo "" >> "${GITHUB_STEP_SUMMARY}" - name: Download docs-artifact env: # Token required for GH CLI: @@ -160,6 +171,9 @@ jobs: (comment created at $(date -u --rfc-3339=seconds) for ${PR_SHA}) " echo "${comment}" > comment.txt + + echo "### Result" >> "${GITHUB_STEP_SUMMARY}" + echo "${comment}" >> "${GITHUB_STEP_SUMMARY}" - uses: marocchino/sticky-pull-request-comment@v2 with: header: pmd-publish-pull-requests From acda8eca4e6c9b1744b81122e0f385a35bf757a4 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 1 May 2025 11:59:51 +0200 Subject: [PATCH 0864/1962] [ci] publish-pull-requests: use SHA1 for sticky-pull-request-comment --- .github/workflows/publish-pull-requests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-pull-requests.yml b/.github/workflows/publish-pull-requests.yml index 33ef5c48254..1d2c263fe64 100644 --- a/.github/workflows/publish-pull-requests.yml +++ b/.github/workflows/publish-pull-requests.yml @@ -174,7 +174,7 @@ jobs: echo "### Result" >> "${GITHUB_STEP_SUMMARY}" echo "${comment}" >> "${GITHUB_STEP_SUMMARY}" - - uses: marocchino/sticky-pull-request-comment@v2 + - uses: marocchino/sticky-pull-request-comment@67d0dec7b07ed060a405f9b2a64b8ab319fdd7db #v2.9.2 with: header: pmd-publish-pull-requests number: ${{ env.PR_NUMBER }} From 03d8d357a2ea6edc0be2e6bede9562a8ad38dcf8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 7 Mar 2025 16:47:23 +0100 Subject: [PATCH 0865/1962] [ci] Use same workflow "Build" for snapshot and pull requests - Rename build -> old-build - Rename pull-requests -> build --- .github/workflows/build.yml | 399 ++++++++++++++---- .github/workflows/old-build.yml | 92 ++++ .github/workflows/publish-pull-requests.yml | 15 +- .github/workflows/pull-requests.yml | 338 --------------- do-release.sh | 4 +- .../pmd/devdocs/github_actions_workflows.md | 13 +- 6 files changed, 429 insertions(+), 432 deletions(-) create mode 100644 .github/workflows/old-build.yml delete mode 100644 .github/workflows/pull-requests.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 26b3deba981..e8089f03039 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,98 +1,337 @@ -name: build +name: Build on: + pull_request: + merge_group: push: branches: - main - tags: - - '**' - merge_group: + workflow_dispatch: schedule: # build it monthly: At 04:00 on day-of-month 1. - cron: '0 4 1 * *' - workflow_dispatch: - inputs: - build_cli_dist_only: - description: "Build only modules cli and dist" - required: true - type: boolean - default: false + +# if another commit is added to the PR (same github.head_ref), then cancel already running jobs +# and start a new build +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref }} + cancel-in-progress: true permissions: contents: read # to fetch code (actions/checkout) +env: + LANG: 'en_US.UTF-8' + jobs: - build: + compile: + runs-on: ubuntu-latest + timeout-minutes: 20 + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '11' + - uses: actions/cache@v4 + with: + key: maven-${{ hashFiles('**/pom.xml') }} + restore-keys: maven- + path: ~/.m2/repository + enableCrossOsArchive: true + - name: Fast Build with Maven + run: | + ./mvnw --show-version --errors --batch-mode \ + verify -PfastSkip -DskipTests \ + deploy:deploy -DdogfoodStagingRepo="$(pwd)/target/staging" + - name: Cleanup local repository + run: | + # Cleanup local repository to not poison the shared cache with our SNAPSHOTS of the current build. + # Some information is stored in maven-metadata-*.xml files which tells maven which + # version exactly is available in the staging repo. But if we rerun the build using the + # older cache, it points to the old staging versions, which are not available anymore. + find ~/.m2/repository/net/sourceforge/pmd -type d -name "*-SNAPSHOT" -and -not -wholename "*/pmd-designer/*" | xargs rm -vrf + - uses: actions/upload-artifact@v4 + with: + name: compile-artifact + if-no-files-found: error + path: | + */target + */*/target + !pmd-dist/target/pmd-dist-*-bin.zip + !pmd-dist/target/pmd-dist-*-src.zip + - uses: actions/upload-artifact@v4 + with: + name: staging-repository + if-no-files-found: error + path: target/staging + - uses: actions/upload-artifact@v4 + with: + name: dist-artifact + if-no-files-found: error + path: | + pmd-dist/target/pmd-dist-*-bin.zip + pmd-dist/target/pmd-dist-*-src.zip + + verify: + needs: compile + timeout-minutes: 30 + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '11' + - uses: actions/cache@v4 + with: + key: maven-${{ hashFiles('**/pom.xml') }} + restore-keys: maven- + path: ~/.m2/repository + enableCrossOsArchive: true + - uses: actions/download-artifact@v4 + with: + name: compile-artifact + - name: Full Build with Maven + run: | + ./mvnw --show-version --errors --batch-mode \ + verify \ + -DskipTests -Dmaven.test.skip=true + + verify-unittests: + needs: compile + timeout-minutes: 30 runs-on: ${{ matrix.os }} - permissions: - # read to fetch code (actions/checkout) - # write to push code to gh-pages, create releases - # note: forked repositories will have maximum read access - contents: write - continue-on-error: false + defaults: + run: + shell: bash strategy: + # don't fail fast - we want to know the results of all runs + fail-fast: false matrix: os: [ ubuntu-latest, windows-latest, macos-latest ] - if: ${{ !contains(github.event.head_commit.message, '[skip ci]') }} steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 2 - - uses: actions/cache@v4 - with: - path: | - ~/.m2/repository - ~/.gradle/caches - ~/.cache - ~/work/pmd/target/repositories - vendor/bundle - key: v3-${{ runner.os }}-${{ hashFiles('**/pom.xml') }} - restore-keys: | - v3-${{ runner.os }}- - - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@v1 - with: - ruby-version: 3.3 - - name: Setup Environment - shell: bash - run: | - echo "LANG=en_US.UTF-8" >> $GITHUB_ENV - echo "MAVEN_OPTS=-Daether.connector.http.connectionMaxTtl=180 -DautoReleaseAfterClose=true -DstagingProgressTimeoutMinutes=30" >> $GITHUB_ENV - echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/30/scripts" >> $GITHUB_ENV - - name: Check Environment - shell: bash - run: | - f=check-environment.sh; \ - mkdir -p .ci && \ - ( [ -e .ci/$f ] || curl -sSL "${PMD_CI_SCRIPTS_URL}/$f" > ".ci/$f" ) && \ - chmod 755 .ci/$f && \ - .ci/$f - - uses: actions/create-github-app-token@v2 - id: pmd-actions-helper-app-token - # only run in the official pmd repo, where we have access to the secrets and not on forks - if: github.repository == 'pmd/pmd' - with: - app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} - private-key: ${{ secrets.PMD_ACTIONS_HELPER_PRIVATE_KEY }} - owner: ${{ github.repository_owner }} - repositories: docker - permission-actions: write - - name: Build - run: .ci/build.sh - shell: bash - env: - BUILD_CLI_DIST_ONLY: ${{ inputs.build_cli_dist_only }} - PMD_CI_SECRET_PASSPHRASE: ${{ secrets.PMD_CI_SECRET_PASSPHRASE }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PMD_CI_GPG_PRIVATE_KEY: ${{ secrets.PMD_CI_GPG_PRIVATE_KEY }} - MAVEN_GPG_PASSPHRASE: ${{ secrets.PMD_CI_GPG_PASSPHRASE }} - PMD_ACTIONS_HELPER_TOKEN: ${{ steps.pmd-actions-helper-app-token.outputs.token }} - - name: Workaround actions/upload-artifact#176 - run: | - echo "artifacts_path=$(realpath ..)" >> $GITHUB_ENV - - name: Upload regression tester report - uses: actions/upload-artifact@v4 - with: - name: pmd-regression-tester - path: ${{ env.artifacts_path }}/target/pr-*-diff-report-*.tar.gz - if-no-files-found: ignore + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + # under linux we execute more extensive integration tests with various java versions + if: ${{ runner.os == 'Linux' }} + with: + distribution: 'temurin' + java-version: | + 8 + 17 + 21 + - uses: actions/setup-java@v4 + # default java version for all os is 11 + with: + distribution: 'temurin' + java-version: '11' + # only restore the cache, don't create a new cache + # under Windows, hashFiles('**/pom.xml') gives a different result due to line endings + - uses: actions/cache/restore@v4 + with: + key: maven-${{ hashFiles('**/pom.xml') }} + restore-keys: maven- + path: ~/.m2/repository + enableCrossOsArchive: true + - uses: actions/download-artifact@v4 + # we can only reuse compile-artifacts under linux due to file timestamp issues and + # platform specific line endings in test files. + if: ${{ runner.os == 'Linux' }} + with: + name: compile-artifact + - name: Build with Maven and run unit tests + run: | + ./mvnw --show-version --errors --batch-mode \ + verify \ + -PfastSkip -Dcyclonedx.skip=false \ + -Djava8.home="${JAVA_HOME_8_X64}" \ + -Djava17.home="${JAVA_HOME_17_X64}" \ + -Djava21.home="${JAVA_HOME_21_X64}" + + dogfood: + needs: compile + timeout-minutes: 30 + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '11' + - uses: actions/cache@v4 + with: + key: maven-${{ hashFiles('**/pom.xml') }} + restore-keys: maven- + path: ~/.m2/repository + enableCrossOsArchive: true + - uses: actions/download-artifact@v4 + with: + name: compile-artifact + - uses: actions/download-artifact@v4 + with: + name: staging-repository + path: target/staging + - name: Run PMD on PMD + run: | + # this only works if the triggering event of this workflow is "pull_request" + pr_number="$(jq -r ".number" "${GITHUB_EVENT_PATH}")" + echo "Determined PR number: ${pr_number}" + + current_pmd_version=$(./mvnw --batch-mode --no-transfer-progress \ + help:evaluate -Dexpression=project.version -q -DforceStdout || echo "failed_to_determine_current_pmd_version") + echo "Determined current pmd version: ${current_pmd_version}" + + new_version="${current_pmd_version}-pr-${pr_number}-dogfood-SNAPSHOT" + echo "::group::Set version to ${new_version}" + ./mvnw versions:set --quiet -DnewVersion="${new_version}" -DgenerateBackupPoms=false + sed -i 's/[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}.*<\/version>\( *\)/'"${current_pmd_version}"'<\/version>\1/' pom.xml + echo "::endgroup::" + + echo "::group::Run ./mvnw verify" + ./mvnw --show-version --errors --batch-mode \ + verify \ + -PfastSkip \ + -DdogfoodStagingRepo="$(pwd)/target/staging" \ + -DskipTests \ + -Dpmd.skip=false \ + -Dcpd.skip=false + echo "::endgroup::" + + echo "::group::Restore version to ${current_pmd_version}" + ./mvnw versions:set --quiet -DnewVersion="${current_pmd_version}" -DgenerateBackupPoms=false + git checkout -- pom.xml + echo "::endgroup::" + + documentation: + needs: compile + timeout-minutes: 30 + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '11' + - uses: actions/cache@v4 + with: + key: maven-${{ hashFiles('**/pom.xml') }} + restore-keys: maven- + path: ~/.m2/repository + enableCrossOsArchive: true + - uses: actions/download-artifact@v4 + with: + name: compile-artifact + - name: Generate rule docs + run: | + ./mvnw --show-version --errors --batch-mode \ + verify \ + -Pgenerate-rule-docs,fastSkip \ + -DskipTests -Dmaven.test.skip=true -Dassembly.skipAssembly=true + - name: Set up Ruby 3.3 + uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.3 + - name: Setup bundler + run: | + cd docs + bundle config set --local path vendor/bundle + bundle install + - name: Build documentation + run: | + cd docs + bundle exec jekyll build + - uses: actions/upload-artifact@v4 + with: + name: docs-artifact + if-no-files-found: error + path: docs/_site + + regressiontester: + needs: compile + timeout-minutes: 60 + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 2 + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '11' + - name: Set up Ruby 3.3 + uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.3 + - uses: actions/cache@v4 + with: + path: | + ~/.m2/repository + ~/.gradle/caches + ~/work/pmd/target/repositories + vendor/bundle + key: regressiontester-${{ hashFiles('.ci/files/project-list.xml', 'Gemfile.lock') }} + restore-keys: regressiontester- + - uses: actions/download-artifact@v4 + with: + name: dist-artifact + path: pmd-dist/target + - name: Setup bundler + run: | + bundle config set --local gemfile .ci/files/Gemfile + bundle config set --local path vendor/bundle + bundle install + - name: Prepare HOME/openjdk11 + run: | + ln -sfn "${JAVA_HOME_11_X64}" "${HOME}/openjdk11" + - name: Run pmdtester + env: + # this only works if the triggering event of this workflow is "pull_request" + PMD_CI_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} + PMD_CI_BRANCH: ${{ github.base_ref }} + run: | + echo "::group::Fetching additional commits" + # git clone initially only fetched with depth 2. Regression tester + # needs more history, so we'll fetch more here + # and create local branches as well (${PMD_CI_BRANCH} and pr-fetch) + + echo "Fetching 25 commits for ${PMD_CI_BRANCH} and pull/${PMD_CI_PULL_REQUEST_NUMBER}/head" + git fetch --no-tags --depth=25 origin "${PMD_CI_BRANCH}:${PMD_CI_BRANCH}" "pull/${PMD_CI_PULL_REQUEST_NUMBER}/head:pr-fetch" + + # if the PR is older, base might have advanced more than 25 commits... fetch more, up to 150 + for i in $(seq 1 3); do + if [ -z "$( git merge-base "${PMD_CI_BRANCH}" "pr-fetch" )" ]; then + echo "No merge-base yet - fetching more commits... (try $i)" + git fetch --no-tags --deepen=50 origin "${PMD_CI_BRANCH}:" "pull/${PMD_CI_PULL_REQUEST_NUMBER}/head:pr-fetch" + fi + done + echo "Merge base is: $( git merge-base "${PMD_CI_BRANCH}" "pr-fetch" )" + echo "::endgroup::" + + echo "::group::Running pmdtester on branch ${PMD_CI_BRANCH}" + bundle exec ruby .ci/files/pmdtester.rb + echo "::endgroup::" + - name: Workaround actions/upload-artifact#176 + run: | + echo "artifacts_path=$(realpath ..)" >> "${GITHUB_ENV}" + - name: Upload regression tester report + uses: actions/upload-artifact@v4 + with: + name: pmd-regression-tester + if-no-files-found: error + path: ${{ env.artifacts_path }}/target/reports/diff diff --git a/.github/workflows/old-build.yml b/.github/workflows/old-build.yml new file mode 100644 index 00000000000..48402116089 --- /dev/null +++ b/.github/workflows/old-build.yml @@ -0,0 +1,92 @@ +name: old-build + +on: + push: + tags: + - '**' + workflow_dispatch: + inputs: + build_cli_dist_only: + description: "Build only modules cli and dist" + required: true + type: boolean + default: false + +permissions: + contents: read # to fetch code (actions/checkout) + +jobs: + build: + runs-on: ${{ matrix.os }} + permissions: + # read to fetch code (actions/checkout) + # write to push code to gh-pages, create releases + # note: forked repositories will have maximum read access + contents: write + continue-on-error: false + strategy: + matrix: + os: [ ubuntu-latest, windows-latest, macos-latest ] + if: ${{ !contains(github.event.head_commit.message, '[skip ci]') }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 2 + - uses: actions/cache@v4 + with: + path: | + ~/.m2/repository + ~/.gradle/caches + ~/.cache + ~/work/pmd/target/repositories + vendor/bundle + key: v3-${{ runner.os }}-${{ hashFiles('**/pom.xml') }} + restore-keys: | + v3-${{ runner.os }}- + - name: Set up Ruby 3.3 + uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.3 + - name: Setup Environment + shell: bash + run: | + echo "LANG=en_US.UTF-8" >> $GITHUB_ENV + echo "MAVEN_OPTS=-Daether.connector.http.connectionMaxTtl=180 -DautoReleaseAfterClose=true -DstagingProgressTimeoutMinutes=30" >> $GITHUB_ENV + echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/30/scripts" >> $GITHUB_ENV + - name: Check Environment + shell: bash + run: | + f=check-environment.sh; \ + mkdir -p .ci && \ + ( [ -e .ci/$f ] || curl -sSL "${PMD_CI_SCRIPTS_URL}/$f" > ".ci/$f" ) && \ + chmod 755 .ci/$f && \ + .ci/$f + - uses: actions/create-github-app-token@v2 + id: pmd-actions-helper-app-token + # only run in the official pmd repo, where we have access to the secrets and not on forks + if: github.repository == 'pmd/pmd' + with: + app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} + private-key: ${{ secrets.PMD_ACTIONS_HELPER_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + repositories: docker + permission-actions: write + - name: Build + run: .ci/build.sh + shell: bash + env: + BUILD_CLI_DIST_ONLY: ${{ inputs.build_cli_dist_only }} + PMD_CI_SECRET_PASSPHRASE: ${{ secrets.PMD_CI_SECRET_PASSPHRASE }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PMD_CI_GPG_PRIVATE_KEY: ${{ secrets.PMD_CI_GPG_PRIVATE_KEY }} + MAVEN_GPG_PASSPHRASE: ${{ secrets.PMD_CI_GPG_PASSPHRASE }} + PMD_ACTIONS_HELPER_TOKEN: ${{ steps.pmd-actions-helper-app-token.outputs.token }} + - name: Workaround actions/upload-artifact#176 + run: | + echo "artifacts_path=$(realpath ..)" >> $GITHUB_ENV + - name: Upload regression tester report + uses: actions/upload-artifact@v4 + with: + name: pmd-regression-tester + path: ${{ env.artifacts_path }}/target/pr-*-diff-report-*.tar.gz + if-no-files-found: ignore diff --git a/.github/workflows/publish-pull-requests.yml b/.github/workflows/publish-pull-requests.yml index 1d2c263fe64..a4e7f056a56 100644 --- a/.github/workflows/publish-pull-requests.yml +++ b/.github/workflows/publish-pull-requests.yml @@ -2,7 +2,7 @@ name: Publish Results from Pull Requests run-name: Publish Results for "${{ github.event.workflow_run.display_title }}" on: workflow_run: - workflows: [Pull Request Build] + workflows: [Build] types: - completed @@ -13,8 +13,11 @@ permissions: jobs: publish: - # only run in the official pmd repo, where we have access to the secrets - if: github.repository == 'pmd/pmd' + # only run in the official pmd repo, where we have access to the secrets and not on forks + # and only run for _successful_ pull requests workflow runs. + if: ${{ github.repository == 'pmd/pmd' + && github.event.workflow_run.event == 'pull_request' + && github.event.workflow_run.conclusion == 'success' }} runs-on: ubuntu-latest timeout-minutes: 10 defaults: @@ -132,7 +135,7 @@ jobs: -f "state=success" -f "target_url=https://pull-requests.pmd-code.org/pr-${PR_NUMBER}/${PR_SHA}/regression" \ -f "description=PMD Regression Tester Report" -f "context=Published Results / Regression Tester" - name: Prepare regression summary - run: |- + run: | summary="$(cat pmd-regression-tester/summary.txt)" if [ "$REGRESSION_REPORT_UPLOADED" = "1" ]; then summary=" @@ -146,7 +149,7 @@ jobs: env: # Token required for GH CLI: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: |- + run: | timestamp="$(date -uIs)" summary="$(cat pmd-regression-tester/summary.txt)" @@ -162,7 +165,7 @@ jobs: -f "started_at=${timestamp}" -f "conclusion=${conclusion}" -f "completed_at=${timestamp}" \ -f "output[title]=Regression Tester Report" -f "output[summary]=${summary}" - name: Prepare comment text - run: |- + run: | summary="$(cat pmd-regression-tester/summary.txt)" comment="[Documentation Preview](https://pull-requests.pmd-code.org/pr-${PR_NUMBER}/${PR_SHA}/docs) diff --git a/.github/workflows/pull-requests.yml b/.github/workflows/pull-requests.yml deleted file mode 100644 index a9313c319c2..00000000000 --- a/.github/workflows/pull-requests.yml +++ /dev/null @@ -1,338 +0,0 @@ -name: Pull Request Build - -on: pull_request - -# if another commit is added to the PR (same github.head_ref), then cancel already running jobs -# and start a new build -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref }} - cancel-in-progress: true - -permissions: - contents: read # to fetch code (actions/checkout) - -env: - LANG: 'en_US.UTF-8' - -jobs: - compile: - runs-on: ubuntu-latest - timeout-minutes: 20 - defaults: - run: - shell: bash - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 2 - - uses: actions/setup-java@v4 - with: - distribution: 'temurin' - java-version: '11' - - uses: actions/cache@v4 - with: - key: maven-${{ hashFiles('**/pom.xml') }} - restore-keys: maven- - path: ~/.m2/repository - enableCrossOsArchive: true - - name: Fast Build with Maven - run: | - ./mvnw --show-version --errors --batch-mode \ - verify -PfastSkip -DskipTests \ - deploy:deploy -DdogfoodStagingRepo="$(pwd)/target/staging" - - name: Cleanup local repository - run: | - # Cleanup local repository to not poison the shared cache with our SNAPSHOTS of the current build. - # Some information is stored in maven-metadata-*.xml files which tells maven which - # version exactly is available in the staging repo. But if we rerun the build using the - # older cache, it points to the old staging versions, which are not available anymore. - find ~/.m2/repository/net/sourceforge/pmd -type d -name "*-SNAPSHOT" -and -not -wholename "*/pmd-designer/*" | xargs rm -vrf - - uses: actions/upload-artifact@v4 - with: - name: compile-artifact - if-no-files-found: error - path: | - */target - */*/target - !pmd-dist/target/pmd-dist-*-bin.zip - !pmd-dist/target/pmd-dist-*-src.zip - - uses: actions/upload-artifact@v4 - with: - name: staging-repository - if-no-files-found: error - path: target/staging - - uses: actions/upload-artifact@v4 - with: - name: dist-artifact - if-no-files-found: error - path: | - pmd-dist/target/pmd-dist-*-bin.zip - pmd-dist/target/pmd-dist-*-src.zip - - verify: - needs: compile - timeout-minutes: 30 - runs-on: ubuntu-latest - defaults: - run: - shell: bash - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 2 - - uses: actions/setup-java@v4 - with: - distribution: 'temurin' - java-version: '11' - - uses: actions/cache@v4 - with: - key: maven-${{ hashFiles('**/pom.xml') }} - restore-keys: maven- - path: ~/.m2/repository - enableCrossOsArchive: true - - uses: actions/download-artifact@v4 - with: - name: compile-artifact - - name: Full Build with Maven - run: | - ./mvnw --show-version --errors --batch-mode \ - verify \ - -DskipTests -Dmaven.test.skip=true - - verify-unittests: - needs: compile - timeout-minutes: 30 - runs-on: ${{ matrix.os }} - defaults: - run: - shell: bash - strategy: - # don't fail fast - we want to know the results of all runs - fail-fast: false - matrix: - os: [ ubuntu-latest, windows-latest, macos-latest ] - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 2 - - uses: actions/setup-java@v4 - # under linux we execute more extensive integration tests with various java versions - if: ${{ runner.os == 'Linux' }} - with: - distribution: 'temurin' - java-version: | - 8 - 17 - 21 - - uses: actions/setup-java@v4 - # default java version for all os is 11 - with: - distribution: 'temurin' - java-version: '11' - # only restore the cache, don't create a new cache - # under Windows, hashFiles('**/pom.xml') gives a different result due to line endings - - uses: actions/cache/restore@v4 - with: - key: maven-${{ hashFiles('**/pom.xml') }} - restore-keys: maven- - path: ~/.m2/repository - enableCrossOsArchive: true - - uses: actions/download-artifact@v4 - # we can only reuse compile-artifacts under linux due to file timestamp issues and - # platform specific line endings in test files. - if: ${{ runner.os == 'Linux' }} - with: - name: compile-artifact - - name: Build with Maven and run unit tests - run: | - ./mvnw --show-version --errors --batch-mode \ - verify \ - -PfastSkip -Dcyclonedx.skip=false \ - -Djava8.home="${JAVA_HOME_8_X64}" \ - -Djava17.home="${JAVA_HOME_17_X64}" \ - -Djava21.home="${JAVA_HOME_21_X64}" - - dogfood: - needs: compile - timeout-minutes: 30 - runs-on: ubuntu-latest - defaults: - run: - shell: bash - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 2 - - uses: actions/setup-java@v4 - with: - distribution: 'temurin' - java-version: '11' - - uses: actions/cache@v4 - with: - key: maven-${{ hashFiles('**/pom.xml') }} - restore-keys: maven- - path: ~/.m2/repository - enableCrossOsArchive: true - - uses: actions/download-artifact@v4 - with: - name: compile-artifact - - uses: actions/download-artifact@v4 - with: - name: staging-repository - path: target/staging - - name: Run PMD on PMD - run: | - # this only works if the triggering event of this workflow is "pull_request" - pr_number="$(jq -r ".number" "${GITHUB_EVENT_PATH}")" - echo "Determined PR number: ${pr_number}" - - current_pmd_version=$(./mvnw --batch-mode --no-transfer-progress \ - help:evaluate -Dexpression=project.version -q -DforceStdout || echo "failed_to_determine_current_pmd_version") - echo "Determined current pmd version: ${current_pmd_version}" - - new_version="${current_pmd_version}-pr-${pr_number}-dogfood-SNAPSHOT" - echo "::group::Set version to ${new_version}" - ./mvnw versions:set --quiet -DnewVersion="${new_version}" -DgenerateBackupPoms=false - sed -i 's/[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}.*<\/version>\( *\)/'"${current_pmd_version}"'<\/version>\1/' pom.xml - echo "::endgroup::" - - echo "::group::Run ./mvnw verify" - ./mvnw --show-version --errors --batch-mode \ - verify \ - -PfastSkip \ - -DdogfoodStagingRepo="$(pwd)/target/staging" \ - -DskipTests \ - -Dpmd.skip=false \ - -Dcpd.skip=false - echo "::endgroup::" - - echo "::group::Restore version to ${current_pmd_version}" - ./mvnw versions:set --quiet -DnewVersion="${current_pmd_version}" -DgenerateBackupPoms=false - git checkout -- pom.xml - echo "::endgroup::" - - documentation: - needs: compile - timeout-minutes: 30 - runs-on: ubuntu-latest - defaults: - run: - shell: bash - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 2 - - uses: actions/setup-java@v4 - with: - distribution: 'temurin' - java-version: '11' - - uses: actions/cache@v4 - with: - key: maven-${{ hashFiles('**/pom.xml') }} - restore-keys: maven- - path: ~/.m2/repository - enableCrossOsArchive: true - - uses: actions/download-artifact@v4 - with: - name: compile-artifact - - name: Generate rule docs - run: | - ./mvnw --show-version --errors --batch-mode \ - verify \ - -Pgenerate-rule-docs,fastSkip \ - -DskipTests -Dmaven.test.skip=true -Dassembly.skipAssembly=true - - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@v1 - with: - ruby-version: 3.3 - - name: Setup bundler - run: | - cd docs - bundle config set --local path vendor/bundle - bundle install - - name: Build documentation - run: | - cd docs - bundle exec jekyll build - - uses: actions/upload-artifact@v4 - with: - name: docs-artifact - if-no-files-found: error - path: docs/_site - - regressiontester: - needs: compile - timeout-minutes: 60 - runs-on: ubuntu-latest - defaults: - run: - shell: bash - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 2 - - uses: actions/setup-java@v4 - with: - distribution: 'temurin' - java-version: '11' - - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@v1 - with: - ruby-version: 3.3 - - uses: actions/cache@v4 - with: - path: | - ~/.m2/repository - ~/.gradle/caches - ~/work/pmd/target/repositories - vendor/bundle - key: regressiontester-${{ hashFiles('.ci/files/project-list.xml', 'Gemfile.lock') }} - restore-keys: regressiontester- - - uses: actions/download-artifact@v4 - with: - name: dist-artifact - path: pmd-dist/target - - name: Setup bundler - run: | - bundle config set --local gemfile .ci/files/Gemfile - bundle config set --local path vendor/bundle - bundle install - - name: Prepare HOME/openjdk11 - run: | - ln -sfn "${JAVA_HOME_11_X64}" "${HOME}/openjdk11" - - name: Run pmdtester - env: - # this only works if the triggering event of this workflow is "pull_request" - PMD_CI_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} - PMD_CI_BRANCH: ${{ github.base_ref }} - run: | - echo "::group::Fetching additional commits" - # git clone initially only fetched with depth 2. Regression tester - # needs more history, so we'll fetch more here - # and create local branches as well (${PMD_CI_BRANCH} and pr-fetch) - - echo "Fetching 25 commits for ${PMD_CI_BRANCH} and pull/${PMD_CI_PULL_REQUEST_NUMBER}/head" - git fetch --no-tags --depth=25 origin "${PMD_CI_BRANCH}:${PMD_CI_BRANCH}" "pull/${PMD_CI_PULL_REQUEST_NUMBER}/head:pr-fetch" - - # if the PR is older, base might have advanced more than 25 commits... fetch more, up to 150 - for i in $(seq 1 3); do - if [ -z "$( git merge-base "${PMD_CI_BRANCH}" "pr-fetch" )" ]; then - echo "No merge-base yet - fetching more commits... (try $i)" - git fetch --no-tags --deepen=50 origin "${PMD_CI_BRANCH}:" "pull/${PMD_CI_PULL_REQUEST_NUMBER}/head:pr-fetch" - fi - done - echo "Merge base is: $( git merge-base "${PMD_CI_BRANCH}" "pr-fetch" )" - echo "::endgroup::" - - echo "::group::Running pmdtester on branch ${PMD_CI_BRANCH}" - bundle exec ruby .ci/files/pmdtester.rb - echo "::endgroup::" - - name: Workaround actions/upload-artifact#176 - run: | - echo "artifacts_path=$(realpath ..)" >> "${GITHUB_ENV}" - - name: Upload regression tester report - uses: actions/upload-artifact@v4 - with: - name: pmd-regression-tester - if-no-files-found: error - path: ${{ env.artifacts_path }}/target/reports/diff diff --git a/do-release.sh b/do-release.sh index 34175530973..df730632918 100755 --- a/do-release.sh +++ b/do-release.sh @@ -320,9 +320,9 @@ echo echo "Continuing with release of pmd-cli and pmd-dist..." echo "Before proceeding however, wait another 10 minutes, so that the freshly released artefacts" echo "are indeed available from maven central. The GitHub runners might not yet see them..." -echo "If that happens, the build job needs to be started again, maybe the runner cache needs to be cleared as well." +echo "If that happens, the old-build job needs to be started again, maybe the runner cache needs to be cleared as well." echo -echo "Go to and manually trigger a new build" +echo "Go to and manually trigger a new old-build job" echo "from tag 'pmd_releases/${RELEASE_VERSION}' and with option 'Build only modules cli and dist' checked." echo echo "This triggers the second stage release and eventually publishes the release on GitHub." diff --git a/docs/pages/pmd/devdocs/github_actions_workflows.md b/docs/pages/pmd/devdocs/github_actions_workflows.md index ee9698d945b..7fb22eb1b9a 100644 --- a/docs/pages/pmd/devdocs/github_actions_workflows.md +++ b/docs/pages/pmd/devdocs/github_actions_workflows.md @@ -5,17 +5,18 @@ summary: | PMD uses GitHub Actions as the CI/CD infrastructure to build and release new versions. This page gives an overview of how these workflows work and how to use them. author: Andreas Dangel -last_updated: March 2025 (7.12.0) +last_updated: April 2025 (7.13.0) --- {%include note.html content="This page is work in progress and does not yet describe all workflows."%} -## Pull Request Build +## Build -* Builds: -* Workflow file: +* Builds: +* Workflow file: -This workflow is triggered whenever a pull request is created or synchronized. +This workflow is triggered whenever a pull request is created or synchronized or new commits are pushed. +It is designed to run on the main repository in PMD's GitHub organization as well as for forks. In order to avoid unnecessary builds, we use concurrency control to make sure, we cancel any in-progress jobs for the current pull request when a new commit has been pushed. This means, only the latest commit is built, which @@ -65,7 +66,7 @@ The jobs are: * Builds: * Workflow file: -This workflow runs after "Pull Request Build" is completed. It runs in the context of our own +This workflow runs after "Build" on a pull request is completed. It runs in the context of our own repository and has write permissions and complete access to the configured secrets. For security reasons, this workflow won't checkout the pull request code and it won't build anything. From 1a64ba4421a8d73abee1f0d18ee81e2c029314fe Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 11 Apr 2025 16:58:16 +0200 Subject: [PATCH 0866/1962] [ci] build: Run for any branch --- .github/workflows/build.yml | 4 +++- docs/pages/pmd/devdocs/github_actions_workflows.md | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e8089f03039..6e3efd2355a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,7 +5,9 @@ on: merge_group: push: branches: - - main + - '**' + # don't run on dependabot branches. Dependabot will create a pull requests, which will then be run instead + - '!dependabot/**' workflow_dispatch: schedule: # build it monthly: At 04:00 on day-of-month 1. diff --git a/docs/pages/pmd/devdocs/github_actions_workflows.md b/docs/pages/pmd/devdocs/github_actions_workflows.md index 7fb22eb1b9a..ca7e0e5be95 100644 --- a/docs/pages/pmd/devdocs/github_actions_workflows.md +++ b/docs/pages/pmd/devdocs/github_actions_workflows.md @@ -15,7 +15,7 @@ last_updated: April 2025 (7.13.0) * Builds: * Workflow file: -This workflow is triggered whenever a pull request is created or synchronized or new commits are pushed. +This workflow is triggered whenever a pull request is created or synchronized or new commits are pushed to any branch. It is designed to run on the main repository in PMD's GitHub organization as well as for forks. In order to avoid unnecessary builds, we use concurrency control to make sure, we cancel any in-progress jobs for From 53195658642db3498ad3b6741c36ad7e8a7e0a84 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 14 Apr 2025 20:08:00 +0200 Subject: [PATCH 0867/1962] [ci] build: Add pmdtester_start.sh to run regression tester This is now more flexible and supporting to fetch additional commits not only from PRs but also from branches. This means, a push on a branch other than main will create a report diffing the branch against main, just like a PR. This should be handy for forks/local branch developments. And a push on the main branch will create a regression report by looking ath the pushed commits only (using github.event.push.before as base). This should create a report showing the differencs caused by the push. Note: Since we use the last created regression tester baseline, this might not be accurate, though. We need to really use "main" as the base branch, as pmd-regression-tester will download the baseline using this base branch name as the filename. --- .ci/files/pmdtester_start.sh | 82 ++++++++++++++++++++++++++++++++++++ .github/workflows/build.yml | 29 ++----------- 2 files changed, 86 insertions(+), 25 deletions(-) create mode 100755 .ci/files/pmdtester_start.sh diff --git a/.ci/files/pmdtester_start.sh b/.ci/files/pmdtester_start.sh new file mode 100755 index 00000000000..8e98ecd3b64 --- /dev/null +++ b/.ci/files/pmdtester_start.sh @@ -0,0 +1,82 @@ +#!/bin/bash + +set -e + +case "${GITHUB_EVENT_NAME}" in + pull_request) + echo "Detected pull request..." + PMD_REGRESSION_TESTER_BASE_BRANCH="${GITHUB_BASE_REF}" + PMD_REGRESSION_TESTER_HEAD_BRANCH="pull/${GITHUB_REF_NAME%/merge}/head" + PMD_REGRESSION_TESTER_2ND_REF="${PMD_REGRESSION_TESTER_HEAD_BRANCH}_HEAD_FETCH" + ;; + push) + echo "Detected push onto branch ${GITHUB_REF_NAME}...." + case "${GITHUB_REF_NAME}" in + main) + PMD_REGRESSION_TESTER_BASE_BRANCH=main + PMD_REGRESSION_TESTER_HEAD_BRANCH=main + PMD_REGRESSION_TESTER_2ND_REF="${PMD_REGRESSION_TESTER_PUSH_BEFORE}" + ;; + *) + PMD_REGRESSION_TESTER_BASE_BRANCH=main + PMD_REGRESSION_TESTER_HEAD_BRANCH="${GITHUB_REF_NAME}" + PMD_REGRESSION_TESTER_2ND_REF="${PMD_REGRESSION_TESTER_HEAD_BRANCH}_HEAD_FETCH" + ;; + esac + ;; + *) + echo "Unsupported event: ${GITHUB_EVENT_NAME}" + exit 1 +esac + + +echo "PMD_REGRESSION_TESTER_BASE_BRANCH=${PMD_REGRESSION_TESTER_BASE_BRANCH}" +echo "PMD_REGRESSION_TESTER_HEAD_BRANCH=${PMD_REGRESSION_TESTER_HEAD_BRANCH}" +echo "PMD_REGRESSION_TESTER_2ND_REF=${PMD_REGRESSION_TESTER_2ND_REF}" + +if [ "${PMD_REGRESSION_TESTER_BASE_BRANCH}" != "main" ]; then + echo "Only main is supported as base branch, and not: ${PMD_REGRESSION_TESTER_BASE_BRANCH}" + exit 1 +fi + + +echo "::group::Fetching additional commits" +# actions/checkout (git clone) initially only fetched with depth 2. Regression tester +# needs more history, so we'll fetch more here +# we also create local branches, so that we can use them in "merge-base" calls +# the local branches are: +# - ${PMD_REGRESSION_TESTER_BASE_BRANCH}_BASE_FETCH +# - ${PMD_REGRESSION_TESTER_HEAD_BRANCH}_HEAD_FETCH + +echo "Fetching 25 commits for ${PMD_REGRESSION_TESTER_BASE_BRANCH} and ${PMD_REGRESSION_TESTER_HEAD_BRANCH}" +git fetch --no-tags --depth=25 origin \ + "${PMD_REGRESSION_TESTER_BASE_BRANCH}:${PMD_REGRESSION_TESTER_BASE_BRANCH}_BASE_FETCH" \ + "${PMD_REGRESSION_TESTER_HEAD_BRANCH}:${PMD_REGRESSION_TESTER_HEAD_BRANCH}_HEAD_FETCH" + +# if the PR/branch is older, base might have advanced more than 25 commits... fetch more, up to 150 +# until we find a merge base, so that we are sure, regression tester can find all the changed files on +# the branch/pull request. +for i in $(seq 1 3); do + if [ -z "$( git merge-base "${PMD_REGRESSION_TESTER_BASE_BRANCH}_BASE_FETCH" "${PMD_REGRESSION_TESTER_2ND_REF}" )" ]; then + echo "No merge-base yet - fetching more commits... (try $i)" + git fetch --no-tags --deepen=50 origin \ + "${PMD_REGRESSION_TESTER_BASE_BRANCH}:${PMD_REGRESSION_TESTER_BASE_BRANCH}_BASE_FETCH" \ + "${PMD_REGRESSION_TESTER_HEAD_BRANCH}:${PMD_REGRESSION_TESTER_HEAD_BRANCH}_HEAD_FETCH" + fi +done +merge_base="$( git merge-base "${PMD_REGRESSION_TESTER_BASE_BRANCH}_BASE_FETCH" "${PMD_REGRESSION_TESTER_2ND_REF}" )" +echo "Found merge base: ${merge_base}" +if [ "$(git symbolic-ref HEAD 2>/dev/null)" = "refs/heads/main" ]; then + # rename main branch to free up the name "main" + git branch -m "original_main" +fi +git branch "main" "${merge_base}" +echo "::endgroup::" + +echo "::group::Running pmdtester on branch ${PMD_CI_BRANCH}" +export PMD_CI_BRANCH="main" +if [ "${GITHUB_EVENT_NAME}" = "pull_request" ]; then + export PMD_CI_PULL_REQUEST_NUMBER="${GITHUB_REF_NAME%/merge}" +fi +bundle exec ruby .ci/files/pmdtester.rb +echo "::endgroup::" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6e3efd2355a..ebe09962005 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -263,6 +263,7 @@ jobs: regressiontester: needs: compile + if: ${{ github.event_name == 'pull_request' || github.event_name == 'push' }} timeout-minutes: 60 runs-on: ubuntu-latest defaults: @@ -303,31 +304,9 @@ jobs: ln -sfn "${JAVA_HOME_11_X64}" "${HOME}/openjdk11" - name: Run pmdtester env: - # this only works if the triggering event of this workflow is "pull_request" - PMD_CI_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} - PMD_CI_BRANCH: ${{ github.base_ref }} - run: | - echo "::group::Fetching additional commits" - # git clone initially only fetched with depth 2. Regression tester - # needs more history, so we'll fetch more here - # and create local branches as well (${PMD_CI_BRANCH} and pr-fetch) - - echo "Fetching 25 commits for ${PMD_CI_BRANCH} and pull/${PMD_CI_PULL_REQUEST_NUMBER}/head" - git fetch --no-tags --depth=25 origin "${PMD_CI_BRANCH}:${PMD_CI_BRANCH}" "pull/${PMD_CI_PULL_REQUEST_NUMBER}/head:pr-fetch" - - # if the PR is older, base might have advanced more than 25 commits... fetch more, up to 150 - for i in $(seq 1 3); do - if [ -z "$( git merge-base "${PMD_CI_BRANCH}" "pr-fetch" )" ]; then - echo "No merge-base yet - fetching more commits... (try $i)" - git fetch --no-tags --deepen=50 origin "${PMD_CI_BRANCH}:" "pull/${PMD_CI_PULL_REQUEST_NUMBER}/head:pr-fetch" - fi - done - echo "Merge base is: $( git merge-base "${PMD_CI_BRANCH}" "pr-fetch" )" - echo "::endgroup::" - - echo "::group::Running pmdtester on branch ${PMD_CI_BRANCH}" - bundle exec ruby .ci/files/pmdtester.rb - echo "::endgroup::" + # this variable is available for "push" builds only, otherwise it's empty + PMD_REGRESSION_TESTER_PUSH_BEFORE: ${{ github.event.push.before }} + run: .ci/files/pmdtester_start.sh - name: Workaround actions/upload-artifact#176 run: | echo "artifacts_path=$(realpath ..)" >> "${GITHUB_ENV}" From 2e09449baee41f380885a27e5459668b203d4757 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 1 May 2025 12:44:37 +0200 Subject: [PATCH 0868/1962] [ci] build: fix dogfood job for push builds --- .github/workflows/build.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ebe09962005..b821fe14e3c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -185,15 +185,17 @@ jobs: path: target/staging - name: Run PMD on PMD run: | - # this only works if the triggering event of this workflow is "pull_request" - pr_number="$(jq -r ".number" "${GITHUB_EVENT_PATH}")" - echo "Determined PR number: ${pr_number}" + if [ "${GITHUB_EVENT_NAME}" = "pull_request" ]; then + dogfood_name="pr-$(jq -r ".number" "${GITHUB_EVENT_PATH}")" + else + dogfood_name="sha-${GITHUB_SHA}" + fi current_pmd_version=$(./mvnw --batch-mode --no-transfer-progress \ help:evaluate -Dexpression=project.version -q -DforceStdout || echo "failed_to_determine_current_pmd_version") echo "Determined current pmd version: ${current_pmd_version}" - new_version="${current_pmd_version}-pr-${pr_number}-dogfood-SNAPSHOT" + new_version="${current_pmd_version}-dogfood-${dogfood_name}-SNAPSHOT" echo "::group::Set version to ${new_version}" ./mvnw versions:set --quiet -DnewVersion="${new_version}" -DgenerateBackupPoms=false sed -i 's/[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}.*<\/version>\( *\)/'"${current_pmd_version}"'<\/version>\1/' pom.xml From ee3e7fb72e0701f12cf8f51fd72c3ea009040459 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 1 May 2025 12:45:19 +0200 Subject: [PATCH 0869/1962] [ci] build: better cross-os caching for local maven repo "~" would be expanded to different absolute paths on windows/mac and thus the maven repo is not really reused. Now maven is using the local directory ".m2/repository" for the repo cache. This directory is within the current workspace of the runner and a relative path is used for the cache. Now we also need to exclude ".m2" from the src distribution. --- .gitattributes | 3 ++ .github/workflows/build.yml | 31 ++++++++++++------- .../src/main/resources/assemblies/pmd-src.xml | 1 + 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/.gitattributes b/.gitattributes index 7b1011705c7..bf1d63a518a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -12,3 +12,6 @@ mvnw.cmd text eol=crlf *.jpg -text *.svgz -text *.jar -text +# always use LF for pom.xml to be able to reuse github action caching +# see .github/workflows/build.yml +pom.xml text eol=lf diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b821fe14e3c..75422dacf98 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,7 +6,7 @@ on: push: branches: - '**' - # don't run on dependabot branches. Dependabot will create a pull requests, which will then be run instead + # don't run on dependabot branches. Dependabot will create pull requests, which will then be run instead - '!dependabot/**' workflow_dispatch: schedule: @@ -42,11 +42,12 @@ jobs: with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- - path: ~/.m2/repository + path: .m2/repository enableCrossOsArchive: true - name: Fast Build with Maven run: | ./mvnw --show-version --errors --batch-mode \ + -Dmaven.repo.local=.m2/repository \ verify -PfastSkip -DskipTests \ deploy:deploy -DdogfoodStagingRepo="$(pwd)/target/staging" - name: Cleanup local repository @@ -55,7 +56,7 @@ jobs: # Some information is stored in maven-metadata-*.xml files which tells maven which # version exactly is available in the staging repo. But if we rerun the build using the # older cache, it points to the old staging versions, which are not available anymore. - find ~/.m2/repository/net/sourceforge/pmd -type d -name "*-SNAPSHOT" -and -not -wholename "*/pmd-designer/*" | xargs rm -vrf + find .m2/repository/net/sourceforge/pmd -type d -name "*-SNAPSHOT" -and -not -path "*/pmd-designer/*" -print0 | xargs -0 rm -vrf - uses: actions/upload-artifact@v4 with: name: compile-artifact @@ -95,7 +96,7 @@ jobs: with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- - path: ~/.m2/repository + path: .m2/repository enableCrossOsArchive: true - uses: actions/download-artifact@v4 with: @@ -103,6 +104,7 @@ jobs: - name: Full Build with Maven run: | ./mvnw --show-version --errors --batch-mode \ + -Dmaven.repo.local=.m2/repository \ verify \ -DskipTests -Dmaven.test.skip=true @@ -135,22 +137,25 @@ jobs: distribution: 'temurin' java-version: '11' # only restore the cache, don't create a new cache - # under Windows, hashFiles('**/pom.xml') gives a different result due to line endings + # Note: this works under Windows only if pom.xml files use LF, so that hashFiles('**/pom.xml') + # gives the same result (line endings...). + # see .gitattributes for pom.xml - it should always be using lf. - uses: actions/cache/restore@v4 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- - path: ~/.m2/repository + path: .m2/repository enableCrossOsArchive: true - uses: actions/download-artifact@v4 # we can only reuse compile-artifacts under linux due to file timestamp issues and - # platform specific line endings in test files. + # platform specific line endings in test resource files. if: ${{ runner.os == 'Linux' }} with: name: compile-artifact - name: Build with Maven and run unit tests run: | ./mvnw --show-version --errors --batch-mode \ + -Dmaven.repo.local=.m2/repository \ verify \ -PfastSkip -Dcyclonedx.skip=false \ -Djava8.home="${JAVA_HOME_8_X64}" \ @@ -174,7 +179,7 @@ jobs: with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- - path: ~/.m2/repository + path: .m2/repository enableCrossOsArchive: true - uses: actions/download-artifact@v4 with: @@ -197,12 +202,14 @@ jobs: new_version="${current_pmd_version}-dogfood-${dogfood_name}-SNAPSHOT" echo "::group::Set version to ${new_version}" - ./mvnw versions:set --quiet -DnewVersion="${new_version}" -DgenerateBackupPoms=false + ./mvnw -Dmaven.repo.local=.m2/repository \ + versions:set --quiet -DnewVersion="${new_version}" -DgenerateBackupPoms=false sed -i 's/[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}.*<\/version>\( *\)/'"${current_pmd_version}"'<\/version>\1/' pom.xml echo "::endgroup::" echo "::group::Run ./mvnw verify" ./mvnw --show-version --errors --batch-mode \ + -Dmaven.repo.local=.m2/repository \ verify \ -PfastSkip \ -DdogfoodStagingRepo="$(pwd)/target/staging" \ @@ -212,7 +219,8 @@ jobs: echo "::endgroup::" echo "::group::Restore version to ${current_pmd_version}" - ./mvnw versions:set --quiet -DnewVersion="${current_pmd_version}" -DgenerateBackupPoms=false + ./mvnw -Dmaven.repo.local=.m2/repository \ + versions:set --quiet -DnewVersion="${current_pmd_version}" -DgenerateBackupPoms=false git checkout -- pom.xml echo "::endgroup::" @@ -233,7 +241,7 @@ jobs: with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- - path: ~/.m2/repository + path: .m2/repository enableCrossOsArchive: true - uses: actions/download-artifact@v4 with: @@ -241,6 +249,7 @@ jobs: - name: Generate rule docs run: | ./mvnw --show-version --errors --batch-mode \ + -Dmaven.repo.local=.m2/repository \ verify \ -Pgenerate-rule-docs,fastSkip \ -DskipTests -Dmaven.test.skip=true -Dassembly.skipAssembly=true diff --git a/pmd-dist/src/main/resources/assemblies/pmd-src.xml b/pmd-dist/src/main/resources/assemblies/pmd-src.xml index 3b49591b745..f7650fe3e37 100644 --- a/pmd-dist/src/main/resources/assemblies/pmd-src.xml +++ b/pmd-dist/src/main/resources/assemblies/pmd-src.xml @@ -27,6 +27,7 @@ mvnw .git/** + .m2/** **/target/** **/bin/** From efa9367dbc086b2e7da8ba87ab6cb6216438ff1e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 1 May 2025 16:36:42 +0200 Subject: [PATCH 0870/1962] [ci] build: cancel based on github.ref This should work both for pushes and pull_requests. --- .github/workflows/build.yml | 6 +++--- docs/pages/pmd/devdocs/github_actions_workflows.md | 12 +++++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 75422dacf98..5b6798e7384 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,10 +13,10 @@ on: # build it monthly: At 04:00 on day-of-month 1. - cron: '0 4 1 * *' -# if another commit is added to the PR (same github.head_ref), then cancel already running jobs -# and start a new build +# if another commit is added to the same branch or PR (same github.ref), +# then cancel already running jobs and start a new build. concurrency: - group: ${{ github.workflow }}-${{ github.head_ref }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: diff --git a/docs/pages/pmd/devdocs/github_actions_workflows.md b/docs/pages/pmd/devdocs/github_actions_workflows.md index ca7e0e5be95..7cef48a608f 100644 --- a/docs/pages/pmd/devdocs/github_actions_workflows.md +++ b/docs/pages/pmd/devdocs/github_actions_workflows.md @@ -15,12 +15,14 @@ last_updated: April 2025 (7.13.0) * Builds: * Workflow file: -This workflow is triggered whenever a pull request is created or synchronized or new commits are pushed to any branch. -It is designed to run on the main repository in PMD's GitHub organization as well as for forks. +This workflow is triggered whenever new commits are pushed to a branch (including the default branch and +including forks) or whenever a pull request is created or synchronized. +It is designed to run on the main repository in PMD's GitHub organization as well as for forks, as it does +not require any secrets. In order to avoid unnecessary builds, we use concurrency control to make sure, we cancel any in-progress jobs for -the current pull request when a new commit has been pushed. This means, only the latest commit is built, which -is enough, since only this will be merged in the end. Only the latest build matters. +the current branch or pull request when a new commit has been pushed. This means, only the latest commit is built, +which is enough, since only this will be released or merged in the end. Only the latest build matters. The workflow is self-contained, e.g. it doesn't depend on the shell scripts from PMD's build-tools. It also uses only read permissions and doesn't need access to any secrets. It is safe to run also on @@ -68,7 +70,7 @@ The jobs are: This workflow runs after "Build" on a pull request is completed. It runs in the context of our own repository and has write permissions and complete access to the configured secrets. -For security reasons, this workflow won't checkout the pull request code and it won't build anything. +For security reasons, this workflow won't check out the pull request code and won't build anything. It just uses the artifacts from the pull request build, uploads it as static website and adds a commit status and check status to the PR and finally adds a PR comment. From 7b2d8b71b266a26fc5a04c7e0a5a137a1cbcae52 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 8 May 2025 09:21:34 +0200 Subject: [PATCH 0871/1962] [ci] build: include sbom in dist-artifact Also enable cyclonedx during compile so that we get the SBOMs generated for the dist-artifact. --- .github/workflows/build.yml | 6 +++++- docs/pages/pmd/devdocs/github_actions_workflows.md | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5b6798e7384..96ed54c057d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -48,7 +48,7 @@ jobs: run: | ./mvnw --show-version --errors --batch-mode \ -Dmaven.repo.local=.m2/repository \ - verify -PfastSkip -DskipTests \ + verify -PfastSkip -DskipTests -Dcyclonedx.skip=false \ deploy:deploy -DdogfoodStagingRepo="$(pwd)/target/staging" - name: Cleanup local repository run: | @@ -66,6 +66,8 @@ jobs: */*/target !pmd-dist/target/pmd-dist-*-bin.zip !pmd-dist/target/pmd-dist-*-src.zip + !pmd-dist/target/pmd-*-cyclonedx.xml + !pmd-dist/target/pmd-*-cyclonedx.json - uses: actions/upload-artifact@v4 with: name: staging-repository @@ -78,6 +80,8 @@ jobs: path: | pmd-dist/target/pmd-dist-*-bin.zip pmd-dist/target/pmd-dist-*-src.zip + pmd-dist/target/pmd-*-cyclonedx.xml + pmd-dist/target/pmd-*-cyclonedx.json verify: needs: compile diff --git a/docs/pages/pmd/devdocs/github_actions_workflows.md b/docs/pages/pmd/devdocs/github_actions_workflows.md index 7cef48a608f..ceac5196266 100644 --- a/docs/pages/pmd/devdocs/github_actions_workflows.md +++ b/docs/pages/pmd/devdocs/github_actions_workflows.md @@ -37,7 +37,7 @@ During the build we create a couple of artifacts, that can be downloaded: actually used by the dogfood job. * dist-artifact: contains the binary distribution files, ready to be downloaded. This can be used to test PMD with the changes from the pull request without the need to build it locally. It is actually used by the - regression tester job to avoid building PMD another time. + regression tester job to avoid building PMD another time. It also includes the SBOM files (in json and xml format). * docs-artifact: contains the generated rule documentation. * pmd-regression-tester: contains the generation regression report, if there were any changes to rules. From cff9356a6a49080bf89311fe0eda548b1dc654aa Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 8 May 2025 09:45:49 +0200 Subject: [PATCH 0872/1962] [ci] build: include release notes in markdown format --- .github/workflows/build.yml | 4 ++++ docs/pages/pmd/devdocs/github_actions_workflows.md | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 96ed54c057d..64690b3bbb3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -270,6 +270,10 @@ jobs: run: | cd docs bundle exec jekyll build + - name: Create Markdown formatted Release Notes + run: | + cd docs + bundle exec render_release_notes.rb pages/release_notes.md | tail -n +6 > _site/pmd_release_notes.md - uses: actions/upload-artifact@v4 with: name: docs-artifact diff --git a/docs/pages/pmd/devdocs/github_actions_workflows.md b/docs/pages/pmd/devdocs/github_actions_workflows.md index ceac5196266..88a6d85a9cd 100644 --- a/docs/pages/pmd/devdocs/github_actions_workflows.md +++ b/docs/pages/pmd/devdocs/github_actions_workflows.md @@ -38,7 +38,7 @@ During the build we create a couple of artifacts, that can be downloaded: * dist-artifact: contains the binary distribution files, ready to be downloaded. This can be used to test PMD with the changes from the pull request without the need to build it locally. It is actually used by the regression tester job to avoid building PMD another time. It also includes the SBOM files (in json and xml format). -* docs-artifact: contains the generated rule documentation. +* docs-artifact: contains the generated PMD documentation including rule descriptions. * pmd-regression-tester: contains the generation regression report, if there were any changes to rules. In order to have fast feedback of the build results, we run a couple of jobs in parallel and not sequentially. @@ -57,7 +57,8 @@ The jobs are: - "dogfood": runs maven-pmd-plugin on PMD with the latest changes from this very pull request. It uses the "staging-repository" artifact. - "documentation": generates the rule documentations and builds PMD's documentation page using jekyll. - It also executes the verification for wrong rule tags and dead links. It creates the artifact "docs-artifact". + It also executes the verification for wrong rule tags and dead links. Additional it contains the release + notes in markdown format, to be used for release publishing. It creates the artifact "docs-artifact". - "regressiontester": runs the [pmdtester](pmd_devdocs_pmdtester.html) to produce the regression report. It reuses the artifact "dist-artifact" so that we don't need to build PMD again. It uses a different build cache as the other jobs, as this cache now contains the test projects (like Spring Framework) and their From 40a7086f99af870563594bb63561f570aa2b2bd5 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 8 May 2025 10:54:57 +0200 Subject: [PATCH 0873/1962] [ci] build: create javadocs-artifact --- .github/workflows/build.yml | 7 +++++++ docs/pages/pmd/devdocs/github_actions_workflows.md | 2 ++ 2 files changed, 9 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 64690b3bbb3..64401265a75 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -111,6 +111,13 @@ jobs: -Dmaven.repo.local=.m2/repository \ verify \ -DskipTests -Dmaven.test.skip=true + - uses: actions/upload-artifact@v4 + with: + name: javadocs-artifact + if-no-files-found: error + path: | + */target/*-javadoc.jar + */*/target/*-javadoc.jar verify-unittests: needs: compile diff --git a/docs/pages/pmd/devdocs/github_actions_workflows.md b/docs/pages/pmd/devdocs/github_actions_workflows.md index 88a6d85a9cd..c693bfb5f6b 100644 --- a/docs/pages/pmd/devdocs/github_actions_workflows.md +++ b/docs/pages/pmd/devdocs/github_actions_workflows.md @@ -39,6 +39,7 @@ During the build we create a couple of artifacts, that can be downloaded: PMD with the changes from the pull request without the need to build it locally. It is actually used by the regression tester job to avoid building PMD another time. It also includes the SBOM files (in json and xml format). * docs-artifact: contains the generated PMD documentation including rule descriptions. +* javadocs-artifact: contains the javadoc jars of all PMD modules generated during build. * pmd-regression-tester: contains the generation regression report, if there were any changes to rules. In order to have fast feedback of the build results, we run a couple of jobs in parallel and not sequentially. @@ -51,6 +52,7 @@ The jobs are: - "verify": runs a complete `./mvnw verify` with all code checks like checkstyle, japicmp, javadoc, etc. but excluding unit tests (these are run in a separate job). This job is only run on linux. It reuses the already compiled artifacts from the first "compile" job. + Since it runs javadoc, it creates the javadocs-artifact. - "verify-unittests": just runs the unit tests on Linux, Windows and MacOS. Only linux reuses the "compile-artifact" from the first job. For Windows/MacOS we can't reuse this due to platform specific line endings and timestamp issues. From ef5c62dccbaa80b1b3057eedc21fddb23173eaa6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 9 May 2025 09:19:01 +0200 Subject: [PATCH 0874/1962] [ci] publish-snapshot: add new workflow --- .github/workflows/publish-snapshot.yml | 109 +++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 .github/workflows/publish-snapshot.yml diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml new file mode 100644 index 00000000000..7a0c95ffd8e --- /dev/null +++ b/.github/workflows/publish-snapshot.yml @@ -0,0 +1,109 @@ +name: Publish Snapshot + +on: + workflow_run: + workflows: [Build] + types: + - completed + +permissions: + contents: read # to fetch code (actions/checkout) + +env: + LANG: 'en_US.UTF-8' + +jobs: + check-version: + # only run in the official pmd repo, where we have access to the secrets and not on forks + # and only run for _successful_ push workflow runs on branch "main". + if: ${{ github.repository == 'pmd/pmd' + && github.event.workflow_run.event == 'push' + && github.event.workflow_run.head_branch == 'main' + && github.event.workflow_run.conclusion == 'success' }} + runs-on: ubuntu-latest + timeout-minutes: 10 + defaults: + run: + shell: bash + outputs: + PMD_VERSION: ${{ steps.version.outputs.PMD_VERSION }} + steps: + - uses: actions/checkout@v4 + with: + ref: main + - name: Determine Version + id: version + run: | + PMD_VERSION=$(./mvnw --batch-mode --no-transfer-progress help:evaluate -Dexpression=project.version -q -DforceStdout) + echo "Determined PMD_VERSION=$PMD_VERSION" + if [[ "$PMD_VERSION" != *-SNAPSHOT ]]; then + echo "::error ::PMD_VERSION=$PMD_VERSION is not a snapshot version, aborting." + exit 1 + fi + echo "PMD_VERSION=$PMD_VERSION" >> "$GITHUB_OUTPUT" + + deploy-to-maven-central: + needs: check-version + # use environment maven-central, where secrets are configured for OSSRH_* + environment: maven-central + runs-on: ubuntu-latest + timeout-minutes: 20 + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + with: + ref: main + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '11' + server-id: ossrh + server-username: MAVEN_USERNAME + server-password: MAVEN_PASSWORD + gpg-passphrase: MAVEN_GPG_PASSPHRASE + gpg-private-key: ${{ secrets.PMD_CI_GPG_PRIVATE_KEY }} + - uses: actions/cache@v4 + with: + key: maven-${{ hashFiles('**/pom.xml') }} + restore-keys: maven- + path: .m2/repository + enableCrossOsArchive: true + - uses: actions/download-artifact@v4 + with: + name: compile-artifact + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + - name: Build and publish + env: + MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} + MAVEN_GPG_PASSPHRASE: ${{ secrets.PMD_CI_GPG_PASSPHRASE }} + # note: we can't use artifact staging-repository, as the jars are unsigned. + run: | + ./mvnw --show-version --errors --batch-mode \ + -Dmaven.repo.local=.m2/repository \ + deploy \ + -DskipTests \ + -PfastSkip,sign,pmd-release -Dcyclonedx.skip=false + +# TODO +# deploy-to-sourceforge: +# -> https://sourceforge.net/projects/pmd/files/pmd/ +# - pmd-dist bin+src+doc + release notes +# - use environment with secrets +# - deploy doc to sourceforge (https://pmd.sourceforge.io/snapshot) +# deploy-documentation: +# -> https://docs.pmd-code.org/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}/ +# - also api docs https://docs.pmd-code.org/apidocs/*/${PMD_CI_MAVEN_PROJECT_VERSION}/ +# - also symlink https://docs.pmd-code.org/snapshot -> pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION} +# - use environment with secrets +# update-github-pages: +# -> (https://pmd.github.io/pmd/) +# - just updates branch gh_pages +# - needs write permissions +# regression-tester-baseline: +# - create new baseline -> https://pmd-code.org/pmd-regression-tester/ +# run-sonar: -> https://sonarcloud.io/dashboard?id=net.sourceforge.pmd%3Apmd +# run-coveralls: -> https://coveralls.io/github/pmd/pmd From 25ad600317614ebd56c62fb752110a6235195ac7 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 1 May 2025 18:13:10 +0200 Subject: [PATCH 0875/1962] [ci] publish-snapshot: deploy dist to sourceforge files --- .github/workflows/publish-snapshot.yml | 123 ++++++++++++++++++++++++- 1 file changed, 121 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 7a0c95ffd8e..4195600b6b4 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -88,11 +88,130 @@ jobs: -DskipTests \ -PfastSkip,sign,pmd-release -Dcyclonedx.skip=false + deploy-to-sourceforge-files: + needs: check-version + # use environment sourceforge, where secrets are configured for PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY + environment: + name: sourceforge + url: ${{ steps.upload.outputs.url_output }} + runs-on: ubuntu-latest + timeout-minutes: 10 + defaults: + run: + shell: bash + steps: + - uses: actions/download-artifact@v4 + with: + name: dist-artifact + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + path: dist + + - uses: actions/download-artifact@v4 + with: + name: docs-artifact + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + path: docs + + - name: Setup GPG + env: + PMD_CI_GPG_PRIVATE_KEY: ${{ secrets.PMD_CI_GPG_PRIVATE_KEY }} + run: | + mkdir -p "${HOME}/.gpg" + chmod 700 "${HOME}/.gpg" + printenv PMD_CI_GPG_PRIVATE_KEY | gpg --batch --import + + gpg --list-keys --fingerprint --keyid-format=long + gpg --list-secret-keys --fingerprint --keyid-format=long + + - name: Setup ssh key for sourceforge + env: + WEB_SF_DEPLOY_KEY: ${{ secrets.PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY }} + run: | + mkdir -p "${HOME}/.ssh" + chmod 700 "${HOME}/.ssh" + printenv WEB_SF_DEPLOY_KEY > "${HOME}/.ssh/web.sourceforge.net_deploy_key" + chmod 600 "${HOME}/.ssh/web.sourceforge.net_deploy_key" + echo " + Host web.sourceforge.net + IdentityFile=$HOME/.ssh/web.sourceforge.net_deploy_key + " > "$HOME/.ssh/config" + { + # + # web.sourceforge.net (https://sourceforge.net/p/forge/documentation/SSH%20Key%20Fingerprints/) + # + # run locally: + # ssh-keyscan web.sourceforge.net | tee -a sf_known_hosts + # + # verify fingerprints: + # ssh-keygen -F web.sourceforge.net -l -f sf_known_hosts + # # Host web.sourceforge.net found: line 1 + # web.sourceforge.net RSA SHA256:xB2rnn0NUjZ/E0IXQp4gyPqc7U7gjcw7G26RhkDyk90 + # # Host web.sourceforge.net found: line 2 + # web.sourceforge.net ECDSA SHA256:QAAxYkf0iI/tc9oGa0xSsVOAzJBZstcO8HqGKfjpxcY + # # Host web.sourceforge.net found: line 3 + # web.sourceforge.net ED25519 SHA256:209BDmH3jsRyO9UeGPPgLWPSegKmYCBIya0nR/AWWCY + # + # then add output of `ssh-keygen -F web.sourceforge.net -f sf_known_hosts` + # + echo 'web.sourceforge.net ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2uifHZbNexw6cXbyg1JnzDitL5VhYs0E65Hk/tLAPmcmm5GuiGeUoI/B0eUSNFsbqzwgwrttjnzKMKiGLN5CWVmlN1IXGGAfLYsQwK6wAu7kYFzkqP4jcwc5Jr9UPRpJdYIK733tSEmzab4qc5Oq8izKQKIaxXNe7FgmL15HjSpatFt9w/ot/CHS78FUAr3j3RwekHCm/jhPeqhlMAgC+jUgNJbFt3DlhDaRMa0NYamVzmX8D47rtmBbEDU3ld6AezWBPUR5Lh7ODOwlfVI58NAf/aYNlmvl2TZiauBCTa7OPYSyXJnIPbQXg6YQlDknNCr0K769EjeIlAfY87Z4tw==' + echo 'web.sourceforge.net ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCwsY6sZT4MTTkHfpRzYjxG7mnXrGL74RCT2cO/NFvRrZVNB5XNwKNn7G5fHbYLdJ6UzpURDRae1eMg92JG0+yo=' + echo 'web.sourceforge.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOQD35Ujalhh+JJkPvMckDlhu4dS7WH6NsOJ15iGCJLC' + } > "$HOME/.ssh/known_hosts" + + - name: Create docs zip + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + run: | + mv docs "pmd-doc-${PMD_VERSION}" + zip -qr "pmd-dist-${PMD_VERSION}-doc.zip" "pmd-doc-${PMD_VERSION}/" + + - name: Sign files + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + MAVEN_GPG_PASSPHRASE: ${{ secrets.PMD_CI_GPG_PASSPHRASE }} + run: | + printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ + --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-bin.zip" + printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ + --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-src.zip" + printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ + --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-doc.zip" + + - name: Upload to sourceforge + id: upload + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + PMD_SF_USER: adangel + run: | + # Deploy to sourceforge files https://sourceforge.net/projects/pmd/files/pmd/ + basePath="pmd/${PMD_VERSION}" + targetUrl="https://sourceforge.net/projects/pmd/files/${basePath}" + uploadUrl="${PMD_SF_USER}@web.sourceforge.net:/home/frs/project/pmd/${basePath}/" + + rsync -avh "dist/pmd-dist-${PMD_VERSION}-bin.zip" "${uploadUrl}" + rsync -avh "dist/pmd-dist-${PMD_VERSION}-bin.zip.asc" "${uploadUrl}" + rsync -avh "dist/pmd-dist-${PMD_VERSION}-src.zip" "${uploadUrl}" + rsync -avh "dist/pmd-dist-${PMD_VERSION}-src.zip.asc" "${uploadUrl}" + rsync -avh "dist/pmd-dist-${PMD_VERSION}-doc.zip" "${uploadUrl}" + rsync -avh "dist/pmd-dist-${PMD_VERSION}-doc.zip.asc" "${uploadUrl}" + rsync -avh "dist/pmd-${PMD_VERSION}-cyclonedx.xml" "${uploadUrl}" + rsync -avh "dist/pmd-${PMD_VERSION}-cyclonedx.json" "${uploadUrl}" + rsync -avh "pmd-doc-${PMD_VERSION}/pmd_release_notes.md" "${uploadUrl}/ReadMe.md" + + echo "TargetUrl: ${targetUrl}" + echo "url_output=${targetUrl}" >> "$GITHUB_OUTPUT" + + - name: Cleanup ssh and gpg + if: ${{ always() }} + run: | + rm -rf "${HOME}/.ssh" + rm -rf "${HOME}/.gpg" + # TODO # deploy-to-sourceforge: # -> https://sourceforge.net/projects/pmd/files/pmd/ -# - pmd-dist bin+src+doc + release notes -# - use environment with secrets # - deploy doc to sourceforge (https://pmd.sourceforge.io/snapshot) # deploy-documentation: # -> https://docs.pmd-code.org/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}/ From a69e146cb082fcc979a3d64d90b085ceffe23083 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 8 May 2025 10:07:50 +0200 Subject: [PATCH 0876/1962] [ci] publish-snapshot: upload docs to sourceforge.io hosting --- .github/workflows/publish-snapshot.yml | 74 ++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 4195600b6b4..1fad21308d4 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -209,10 +209,78 @@ jobs: rm -rf "${HOME}/.ssh" rm -rf "${HOME}/.gpg" + deploy-to-sourceforge-io: + needs: check-version + # use environment sourceforge, where secrets are configured for PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY + environment: + name: sourceforge + url: ${{ steps.upload.outputs.url_output }} + runs-on: ubuntu-latest + timeout-minutes: 10 + defaults: + run: + shell: bash + steps: + - uses: actions/download-artifact@v4 + with: + name: docs-artifact + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + path: docs + + - name: Setup ssh key for sourceforge + env: + WEB_SF_DEPLOY_KEY: ${{ secrets.PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY }} + run: | + mkdir -p "${HOME}/.ssh" + chmod 700 "${HOME}/.ssh" + printenv WEB_SF_DEPLOY_KEY > "${HOME}/.ssh/web.sourceforge.net_deploy_key" + chmod 600 "${HOME}/.ssh/web.sourceforge.net_deploy_key" + echo " + Host web.sourceforge.net + IdentityFile=$HOME/.ssh/web.sourceforge.net_deploy_key + " > "$HOME/.ssh/config" + { + # + # web.sourceforge.net (https://sourceforge.net/p/forge/documentation/SSH%20Key%20Fingerprints/) + # + # run locally: + # ssh-keyscan web.sourceforge.net | tee -a sf_known_hosts + # + # verify fingerprints: + # ssh-keygen -F web.sourceforge.net -l -f sf_known_hosts + # # Host web.sourceforge.net found: line 1 + # web.sourceforge.net RSA SHA256:xB2rnn0NUjZ/E0IXQp4gyPqc7U7gjcw7G26RhkDyk90 + # # Host web.sourceforge.net found: line 2 + # web.sourceforge.net ECDSA SHA256:QAAxYkf0iI/tc9oGa0xSsVOAzJBZstcO8HqGKfjpxcY + # # Host web.sourceforge.net found: line 3 + # web.sourceforge.net ED25519 SHA256:209BDmH3jsRyO9UeGPPgLWPSegKmYCBIya0nR/AWWCY + # + # then add output of `ssh-keygen -F web.sourceforge.net -f sf_known_hosts` + # + echo 'web.sourceforge.net ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2uifHZbNexw6cXbyg1JnzDitL5VhYs0E65Hk/tLAPmcmm5GuiGeUoI/B0eUSNFsbqzwgwrttjnzKMKiGLN5CWVmlN1IXGGAfLYsQwK6wAu7kYFzkqP4jcwc5Jr9UPRpJdYIK733tSEmzab4qc5Oq8izKQKIaxXNe7FgmL15HjSpatFt9w/ot/CHS78FUAr3j3RwekHCm/jhPeqhlMAgC+jUgNJbFt3DlhDaRMa0NYamVzmX8D47rtmBbEDU3ld6AezWBPUR5Lh7ODOwlfVI58NAf/aYNlmvl2TZiauBCTa7OPYSyXJnIPbQXg6YQlDknNCr0K769EjeIlAfY87Z4tw==' + echo 'web.sourceforge.net ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCwsY6sZT4MTTkHfpRzYjxG7mnXrGL74RCT2cO/NFvRrZVNB5XNwKNn7G5fHbYLdJ6UzpURDRae1eMg92JG0+yo=' + echo 'web.sourceforge.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOQD35Ujalhh+JJkPvMckDlhu4dS7WH6NsOJ15iGCJLC' + } > "$HOME/.ssh/known_hosts" + + - name: Upload to sourceforge + id: upload + env: + PMD_SF_USER: adangel + run: | + targetPath="snapshot" + targetUrl="https://pmd.sourceforge.io/${targetPath}/" + rsync -ah --stats --delete "docs/" "${PMD_SF_USER}@web.sourceforge.net:/home/project-web/pmd/htdocs/${targetPath}/" + + echo "TargetUrl: ${targetUrl}" + echo "url_output=${targetUrl}" >> "$GITHUB_OUTPUT" + + - name: Cleanup ssh + if: ${{ always() }} + run: | + rm -rf "${HOME}/.ssh" + # TODO -# deploy-to-sourceforge: -# -> https://sourceforge.net/projects/pmd/files/pmd/ -# - deploy doc to sourceforge (https://pmd.sourceforge.io/snapshot) # deploy-documentation: # -> https://docs.pmd-code.org/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}/ # - also api docs https://docs.pmd-code.org/apidocs/*/${PMD_CI_MAVEN_PROJECT_VERSION}/ From 9b10c125d3a08bb5042475b5ce36a606eb3a3eac Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 8 May 2025 10:29:42 +0200 Subject: [PATCH 0877/1962] [ci] publish-snapshot: deploy docs to docs.pmd-code.org --- .github/workflows/publish-snapshot.yml | 87 ++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 1fad21308d4..16b8b30a5fb 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -280,6 +280,93 @@ jobs: run: | rm -rf "${HOME}/.ssh" + deploy-to-pmd-code-doc: + needs: check-version + # use environment pmd-code, where secrets are configured for PMD_CODE_ORG_DEPLOY_KEY + environment: + name: pmd-code + url: ${{ steps.upload.outputs.url_output }} + runs-on: ubuntu-latest + timeout-minutes: 10 + defaults: + run: + shell: bash + steps: + - uses: actions/download-artifact@v4 + with: + name: docs-artifact + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + path: docs + + - name: Setup ssh key for pmd-code + env: + PMD_CODE_ORG_DEPLOY_KEY: ${{ secrets.PMD_CODE_ORG_DEPLOY_KEY }} + run: | + mkdir -p "${HOME}/.ssh" + chmod 700 "${HOME}/.ssh" + printenv PMD_CODE_ORG_DEPLOY_KEY > "${HOME}/.ssh/pmd-code.org_deploy_key" + chmod 600 "${HOME}/.ssh/pmd-code.org_deploy_key" + echo " + Host pmd-code.org + IdentityFile=$HOME/.ssh/pmd-code.org_deploy_key + " > "$HOME/.ssh/config" + { + # + # pmd-code.org + # + # ssh-keyscan pmd-code.org | tee -a pmd_known_hosts + # ssh-keygen -F pmd-code.org -l -f pmd_known_hosts + # # Host pmd-code.org found: line 1 + # pmd-code.org RSA SHA256:/uKehVNumCNvJL8C5CziwV9KkUUxHfggq0C4GTrUhwg + # # Host pmd-code.org found: line 2 + # pmd-code.org ECDSA SHA256:6aD1r1XuIoc/zgBT3bt1S9L5ToyJzdQ9rrcMchnqiRA + # # Host pmd-code.org found: line 3 + # pmd-code.org ED25519 SHA256:nvkIAzZhYTxXqSU3DWvos83A0EocZ5dsxNkx1LoMZhg + # ssh-keygen -F pmd-code.org -f pmd_known_hosts + echo 'pmd-code.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDVsIeF6xU0oPb/bMbxG1nU1NDyBpR/cBEPZcm/PuJwdI9B0ydPHA6FysqAnt32fNFznC2SWisnWyY3iNsP3pa8RQJVwmnnv9OboGFlW2/61o3iRyydcpPbgl+ADdt8iU9fmMI7dC04UqgHGBoqOwVNna9VylTjp5709cK2qHnwU450F6YcOEiOKeZfJvV4PmpJCz/JcsUVqft6StviR31jKnqbnkZdP8qNoTbds6WmGKyXkhHdLSZE7X1CFQH28tk8XFqditX93ezeCiThFL7EleDexV/3+2+cs5878sDMUMzHS5KShTjkxzhHaodhtIEdNesinq/hOPbxAGkQ0FbD' + echo 'pmd-code.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMfSJtZcJCeENSZMvdngr+Hwe7oUVQWWKwC4HnfiOoAh/NSIlzJyQvpoPZxnEFid6Y3ntDK+rnx04Japo63zD8Q=' + echo 'pmd-code.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFa88nqfMavMH/tGeS5DNrSeM5AVHmZQGHh98vC1717o' + } > "$HOME/.ssh/known_hosts" + + - name: Create docs zip + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + run: | + mv docs "pmd-doc-${PMD_VERSION}" + zip -qr "pmd-dist-${PMD_VERSION}-doc.zip" "pmd-doc-${PMD_VERSION}/" + + - name: Upload to pmd-code.org + id: upload + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + PMD_CODE_SSH_USER: pmd + PMD_CODE_DOCS_PATH: /docs.pmd-code.org/ + run: | + targetUrl="https://docs.pmd-code.org/pmd-doc-${PMD_VERSION}/" + filename="pmd-dist-${PMD_VERSION}-doc.zip" + + scp "${filename}" ${PMD_CODE_SSH_USER}@pmd-code.org:${PMD_CODE_DOCS_PATH} + # shellcheck disable=SC2029 + ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \ + ( test -h pmd-doc-${PMD_VERSION} && rm pmd-doc-${PMD_VERSION} || true ) && \ + unzip -qo \"${filename}\" && \ + rm \"${filename}\"" + + # only for snapshot builds from branch main: https://docs.pmd-code.org/snapshot -> pmd-doc-${PMD_VERSION} + # shellcheck disable=SC2029 + ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \ + rm -f \"snapshot\" && \ + ln -s \"pmd-doc-${PMD_VERSION}\" \"snapshot\"" + + echo "TargetUrl: ${targetUrl}" + echo "url_output=${targetUrl}" >> "$GITHUB_OUTPUT" + + - name: Cleanup ssh + if: ${{ always() }} + run: | + rm -rf "${HOME}/.ssh" + # TODO # deploy-documentation: # -> https://docs.pmd-code.org/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}/ From 26b941fdcbaee68bbe599ed2a50b435b516b2fe5 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 8 May 2025 11:02:24 +0200 Subject: [PATCH 0878/1962] [ci] publish-snapshot: deploy javadoc to docs.pmd-code.org/apidocs/ --- .github/workflows/publish-snapshot.yml | 89 ++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 16b8b30a5fb..d1d9039cb20 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -80,7 +80,7 @@ jobs: MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} MAVEN_GPG_PASSPHRASE: ${{ secrets.PMD_CI_GPG_PASSPHRASE }} - # note: we can't use artifact staging-repository, as the jars are unsigned. + # note: we can't use artifact staging-repository, as the jars are unsigned and javadoc+sources are missing. run: | ./mvnw --show-version --errors --batch-mode \ -Dmaven.repo.local=.m2/repository \ @@ -367,12 +367,89 @@ jobs: run: | rm -rf "${HOME}/.ssh" + deploy-to-pmd-code-javadoc: + needs: check-version + # use environment pmd-code, where secrets are configured for PMD_CODE_ORG_DEPLOY_KEY + environment: + name: pmd-code + url: ${{ steps.upload.outputs.url_output }} + runs-on: ubuntu-latest + timeout-minutes: 10 + defaults: + run: + shell: bash + steps: + - uses: actions/download-artifact@v4 + with: + name: javadocs-artifact + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + + - name: Setup ssh key for pmd-code + env: + PMD_CODE_ORG_DEPLOY_KEY: ${{ secrets.PMD_CODE_ORG_DEPLOY_KEY }} + run: | + mkdir -p "${HOME}/.ssh" + chmod 700 "${HOME}/.ssh" + printenv PMD_CODE_ORG_DEPLOY_KEY > "${HOME}/.ssh/pmd-code.org_deploy_key" + chmod 600 "${HOME}/.ssh/pmd-code.org_deploy_key" + echo " + Host pmd-code.org + IdentityFile=$HOME/.ssh/pmd-code.org_deploy_key + " > "$HOME/.ssh/config" + { + # + # pmd-code.org + # + # ssh-keyscan pmd-code.org | tee -a pmd_known_hosts + # ssh-keygen -F pmd-code.org -l -f pmd_known_hosts + # # Host pmd-code.org found: line 1 + # pmd-code.org RSA SHA256:/uKehVNumCNvJL8C5CziwV9KkUUxHfggq0C4GTrUhwg + # # Host pmd-code.org found: line 2 + # pmd-code.org ECDSA SHA256:6aD1r1XuIoc/zgBT3bt1S9L5ToyJzdQ9rrcMchnqiRA + # # Host pmd-code.org found: line 3 + # pmd-code.org ED25519 SHA256:nvkIAzZhYTxXqSU3DWvos83A0EocZ5dsxNkx1LoMZhg + # ssh-keygen -F pmd-code.org -f pmd_known_hosts + echo 'pmd-code.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDVsIeF6xU0oPb/bMbxG1nU1NDyBpR/cBEPZcm/PuJwdI9B0ydPHA6FysqAnt32fNFznC2SWisnWyY3iNsP3pa8RQJVwmnnv9OboGFlW2/61o3iRyydcpPbgl+ADdt8iU9fmMI7dC04UqgHGBoqOwVNna9VylTjp5709cK2qHnwU450F6YcOEiOKeZfJvV4PmpJCz/JcsUVqft6StviR31jKnqbnkZdP8qNoTbds6WmGKyXkhHdLSZE7X1CFQH28tk8XFqditX93ezeCiThFL7EleDexV/3+2+cs5878sDMUMzHS5KShTjkxzhHaodhtIEdNesinq/hOPbxAGkQ0FbD' + echo 'pmd-code.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMfSJtZcJCeENSZMvdngr+Hwe7oUVQWWKwC4HnfiOoAh/NSIlzJyQvpoPZxnEFid6Y3ntDK+rnx04Japo63zD8Q=' + echo 'pmd-code.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFa88nqfMavMH/tGeS5DNrSeM5AVHmZQGHh98vC1717o' + } > "$HOME/.ssh/known_hosts" + + - name: Upload javadocs to pmd-code.org + id: upload + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + PMD_CODE_SSH_USER: pmd + PMD_CODE_DOCS_PATH: /docs.pmd-code.org/ + run: | + targetUrl="https://docs.pmd-code.org/apidocs/" + + for moduleJavadocJar in */target/*-javadoc.jar */*/target/*-javadoc.jar; do + moduleJavadocJarBasename="$(basename "$moduleJavadocJar")" + module=${moduleJavadocJarBasename%%-${PMD_VERSION}-javadoc.jar} + + scp "$moduleJavadocJar" ${PMD_CODE_SSH_USER}@pmd-code.org:${PMD_CODE_DOCS_PATH} + # shellcheck disable=SC2029 + ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \ + mkdir -p \"apidocs/${module}/${PMD_VERSION}\" && \ + unzip -qo -d \"apidocs/${module}/${PMD_VERSION}\" \"${moduleJavadocJarBasename}\" && \ + rm \"${moduleJavadocJarBasename}\"" + done + + # make sure https://docs.pmd-code.org/apidocs/ shows directory index + # shellcheck disable=SC2029 + ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}/apidocs\" && \ + echo 'Options +Indexes' > .htaccess" + + echo "TargetUrl: ${targetUrl}" + echo "url_output=${targetUrl}" >> "$GITHUB_OUTPUT" + + - name: Cleanup ssh + if: ${{ always() }} + run: | + rm -rf "${HOME}/.ssh" + # TODO -# deploy-documentation: -# -> https://docs.pmd-code.org/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}/ -# - also api docs https://docs.pmd-code.org/apidocs/*/${PMD_CI_MAVEN_PROJECT_VERSION}/ -# - also symlink https://docs.pmd-code.org/snapshot -> pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION} -# - use environment with secrets # update-github-pages: # -> (https://pmd.github.io/pmd/) # - just updates branch gh_pages From 02146fff821e7d64943eaba23cc587a10e8f4583 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 8 May 2025 11:35:17 +0200 Subject: [PATCH 0879/1962] [ci] publish-snapshot: update github pages --- .github/workflows/publish-snapshot.yml | 44 +++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index d1d9039cb20..7dbfd2a9fd7 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -449,11 +449,47 @@ jobs: run: | rm -rf "${HOME}/.ssh" + deploy-to-github-pages: + needs: check-version + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: write # to push to branch gh-pages + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + with: + ref: gh-pages + - name: Clear old files + run: rm -rf * + - uses: actions/download-artifact@v4 + with: + name: docs-artifact + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + - name: Commit and push new page + env: + WORKFLOW_RUN_HTML_URL: ${{ github.event.workflow_run.html_url }} + run: | + # https://api.github.com/users/pmd-actions-helper[bot] + git config user.name "pmd-actions-helper[bot]" + git config user.email "207160486+pmd-actions-helper[bot]@users.noreply.github.com" + git add -A + MSG="Update documentation + + Updated by: https://github.com/pmd/pmd/actions/runs/$GITHUB_RUN_ID + Triggered by: ${WORKFLOW_RUN_HTML_URL}" + git commit -q -m "$MSG" + git push + + targetUrl="https://pmd.github.io/pmd/" + echo "TargetUrl: ${targetUrl}" + echo "url_output=${targetUrl}" >> "$GITHUB_OUTPUT" + + # TODO -# update-github-pages: -# -> (https://pmd.github.io/pmd/) -# - just updates branch gh_pages -# - needs write permissions # regression-tester-baseline: # - create new baseline -> https://pmd-code.org/pmd-regression-tester/ # run-sonar: -> https://sonarcloud.io/dashboard?id=net.sourceforge.pmd%3Apmd From 7dd97dcee4d18512d38b508b0dea7c282d8fa4bc Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 8 May 2025 11:50:43 +0200 Subject: [PATCH 0880/1962] [ci] publish-snapshot: create regression tester baseline --- .github/workflows/publish-snapshot.yml | 101 ++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 7dbfd2a9fd7..5dff65fb81b 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -488,9 +488,106 @@ jobs: echo "TargetUrl: ${targetUrl}" echo "url_output=${targetUrl}" >> "$GITHUB_OUTPUT" + create-regression-tester-baseline: + needs: check-version + runs-on: ubuntu-latest + # use environment pmd-code, where secrets are configured for PMD_CODE_ORG_DEPLOY_KEY + environment: + name: pmd-code + url: ${{ steps.upload.outputs.url_output }} + timeout-minutes: 60 + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + with: + ref: main + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '11' + - name: Set up Ruby 3.3 + uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.3 + - uses: actions/cache@v4 + with: + path: | + ~/.m2/repository + ~/.gradle/caches + ~/work/pmd/target/repositories + vendor/bundle + key: regressiontester-${{ hashFiles('.ci/files/project-list.xml', 'Gemfile.lock') }} + restore-keys: regressiontester- + - uses: actions/download-artifact@v4 + with: + name: dist-artifact + path: pmd-dist/target + - name: Setup bundler + run: | + bundle config set --local gemfile .ci/files/Gemfile + bundle config set --local path vendor/bundle + bundle install + - name: Prepare HOME/openjdk11 + run: | + ln -sfn "${JAVA_HOME_11_X64}" "${HOME}/openjdk11" + - name: Run pmdtester + run: | + cd .. + bundle exec pmdtester \ + --mode single \ + --local-git-repo ./pmd \ + --patch-branch "main" \ + --patch-config ./pmd/.ci/files/all-regression-rules.xml \ + --list-of-project ./pmd/.ci/files/project-list.xml --html-flag \ + --threads "$(nproc)" \ + --error-recovery + pushd target/reports || { echo "Directory 'target/reports' doesn't exist"; exit 1; } + - name: Setup ssh key for pmd-code + env: + PMD_CODE_ORG_DEPLOY_KEY: ${{ secrets.PMD_CODE_ORG_DEPLOY_KEY }} + run: | + mkdir -p "${HOME}/.ssh" + chmod 700 "${HOME}/.ssh" + printenv PMD_CODE_ORG_DEPLOY_KEY > "${HOME}/.ssh/pmd-code.org_deploy_key" + chmod 600 "${HOME}/.ssh/pmd-code.org_deploy_key" + echo " + Host pmd-code.org + IdentityFile=$HOME/.ssh/pmd-code.org_deploy_key + " > "$HOME/.ssh/config" + { + # + # pmd-code.org + # + # ssh-keyscan pmd-code.org | tee -a pmd_known_hosts + # ssh-keygen -F pmd-code.org -l -f pmd_known_hosts + # # Host pmd-code.org found: line 1 + # pmd-code.org RSA SHA256:/uKehVNumCNvJL8C5CziwV9KkUUxHfggq0C4GTrUhwg + # # Host pmd-code.org found: line 2 + # pmd-code.org ECDSA SHA256:6aD1r1XuIoc/zgBT3bt1S9L5ToyJzdQ9rrcMchnqiRA + # # Host pmd-code.org found: line 3 + # pmd-code.org ED25519 SHA256:nvkIAzZhYTxXqSU3DWvos83A0EocZ5dsxNkx1LoMZhg + # ssh-keygen -F pmd-code.org -f pmd_known_hosts + echo 'pmd-code.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDVsIeF6xU0oPb/bMbxG1nU1NDyBpR/cBEPZcm/PuJwdI9B0ydPHA6FysqAnt32fNFznC2SWisnWyY3iNsP3pa8RQJVwmnnv9OboGFlW2/61o3iRyydcpPbgl+ADdt8iU9fmMI7dC04UqgHGBoqOwVNna9VylTjp5709cK2qHnwU450F6YcOEiOKeZfJvV4PmpJCz/JcsUVqft6StviR31jKnqbnkZdP8qNoTbds6WmGKyXkhHdLSZE7X1CFQH28tk8XFqditX93ezeCiThFL7EleDexV/3+2+cs5878sDMUMzHS5KShTjkxzhHaodhtIEdNesinq/hOPbxAGkQ0FbD' + echo 'pmd-code.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMfSJtZcJCeENSZMvdngr+Hwe7oUVQWWKwC4HnfiOoAh/NSIlzJyQvpoPZxnEFid6Y3ntDK+rnx04Japo63zD8Q=' + echo 'pmd-code.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFa88nqfMavMH/tGeS5DNrSeM5AVHmZQGHh98vC1717o' + } > "$HOME/.ssh/known_hosts" + - name: Upload report + id: upload + run: | + cd ../target/reports + zip -q -r "main-baseline.zip" "main/" + scp "main-baseline.zip" pmd@pmd-code.org:/httpdocs/pmd-regression-tester/ + + targetUrl="https://pmd-code.org/pmd-regression-tester/" + echo "TargetUrl: ${targetUrl}" + echo "url_output=${targetUrl}" >> "$GITHUB_OUTPUT" + - name: Cleanup ssh + if: ${{ always() }} + run: | + rm -rf "${HOME}/.ssh" # TODO -# regression-tester-baseline: -# - create new baseline -> https://pmd-code.org/pmd-regression-tester/ # run-sonar: -> https://sonarcloud.io/dashboard?id=net.sourceforge.pmd%3Apmd # run-coveralls: -> https://coveralls.io/github/pmd/pmd From 557b937f5bfc58f12ab9b603e3d0630294dc60ec Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 8 May 2025 12:17:16 +0200 Subject: [PATCH 0881/1962] [ci] publish-snapshot: add sonar and coveralls --- .github/workflows/publish-snapshot.yml | 97 +++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 5dff65fb81b..fd78aa537c5 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -588,6 +588,97 @@ jobs: run: | rm -rf "${HOME}/.ssh" -# TODO -# run-sonar: -> https://sonarcloud.io/dashboard?id=net.sourceforge.pmd%3Apmd -# run-coveralls: -> https://coveralls.io/github/pmd/pmd + run-sonar: + needs: check-version + runs-on: ubuntu-latest + # use environment sonarcloud, where secrets are configured for SONAR_TOKEN + environment: + name: sonarcloud + url: ${{ steps.upload.outputs.url_output }} + timeout-minutes: 20 + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + with: + ref: main + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '17' # sonar requires java 17 + - uses: actions/cache@v4 + with: + key: maven-${{ hashFiles('**/pom.xml') }} + restore-keys: maven- + path: .m2/repository + enableCrossOsArchive: true + - name: Build and upload to sonar cloud + id: upload + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + # Note: Sonar also needs GITHUB_TOKEN (!) + ./mvnw \ + --show-version --errors --batch-mode \ + -Dmaven.repo.local=.m2/repository \ + clean package \ + sonar:sonar -Psonar,fastSkip + + targetUrl="https://sonarcloud.io/dashboard?id=net.sourceforge.pmd%3Apmd" + echo "TargetUrl: ${targetUrl}" + echo "url_output=${targetUrl}" >> "$GITHUB_OUTPUT" + + run-coveralls: + needs: check-version + runs-on: ubuntu-latest + # use environment sonarcloud, where secrets are configured for COVERALLS_REPO_TOKEN + environment: + name: coveralls + url: ${{ steps.upload.outputs.url_output }} + timeout-minutes: 20 + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + with: + ref: main + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '17' # coveralls requires java 17 + - uses: actions/cache@v4 + with: + key: maven-${{ hashFiles('**/pom.xml') }} + restore-keys: maven- + path: .m2/repository + enableCrossOsArchive: true + - name: Create Jacoco Report + run: | + ./mvnw \ + --show-version --errors --batch-mode \ + -Dmaven.repo.local=.m2/repository \ + clean package \ + jacoco:report -Pcoveralls,fastSkip + + # workaround, maybe https://github.com/jacoco/jacoco/issues/654 + # we use $ as a regex separator, not a shell variable, so no expansion + # shellcheck disable=SC2016 + sed -i 's$Comparisons.kt$ApexTreeBuilder.kt$g' pmd-apex/target/site/jacoco/jacoco.xml + - name: Build and upload to coveralls report + id: upload + env: + COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} + run: | + # note: generate-sources is needed, so that antlr4 generated directories are on the compileSourceRoots + ./mvnw \ + --show-version --errors --batch-mode \ + -Dmaven.repo.local=.m2/repository \ + generate-sources \ + coveralls:report -DrepoToken="${COVERALLS_REPO_TOKEN}" -Pcoveralls,fastSkip + + targetUrl="https://coveralls.io/github/pmd/pmd" + echo "TargetUrl: ${targetUrl}" + echo "url_output=${targetUrl}" >> "$GITHUB_OUTPUT" From a9828f76a1394466d4682ff8ad2ba0c13516c175 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 8 May 2025 17:20:10 +0200 Subject: [PATCH 0882/1962] [ci] publish-snapshot: simplify environment urls --- .github/workflows/publish-snapshot.yml | 54 +++++++------------------- 1 file changed, 14 insertions(+), 40 deletions(-) diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index fd78aa537c5..8c85d71d3b2 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -45,7 +45,9 @@ jobs: deploy-to-maven-central: needs: check-version # use environment maven-central, where secrets are configured for OSSRH_* - environment: maven-central + environment: + name: maven-central + url: https://oss.sonatype.org/content/repositories/snapshots/net/sourceforge/pmd/ runs-on: ubuntu-latest timeout-minutes: 20 defaults: @@ -187,7 +189,6 @@ jobs: run: | # Deploy to sourceforge files https://sourceforge.net/projects/pmd/files/pmd/ basePath="pmd/${PMD_VERSION}" - targetUrl="https://sourceforge.net/projects/pmd/files/${basePath}" uploadUrl="${PMD_SF_USER}@web.sourceforge.net:/home/frs/project/pmd/${basePath}/" rsync -avh "dist/pmd-dist-${PMD_VERSION}-bin.zip" "${uploadUrl}" @@ -200,6 +201,7 @@ jobs: rsync -avh "dist/pmd-${PMD_VERSION}-cyclonedx.json" "${uploadUrl}" rsync -avh "pmd-doc-${PMD_VERSION}/pmd_release_notes.md" "${uploadUrl}/ReadMe.md" + targetUrl="https://sourceforge.net/projects/pmd/files/${basePath}" echo "TargetUrl: ${targetUrl}" echo "url_output=${targetUrl}" >> "$GITHUB_OUTPUT" @@ -214,7 +216,7 @@ jobs: # use environment sourceforge, where secrets are configured for PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY environment: name: sourceforge - url: ${{ steps.upload.outputs.url_output }} + url: https://pmd.sourceforge.io/snapshot/ runs-on: ubuntu-latest timeout-minutes: 10 defaults: @@ -264,16 +266,10 @@ jobs: } > "$HOME/.ssh/known_hosts" - name: Upload to sourceforge - id: upload env: PMD_SF_USER: adangel run: | - targetPath="snapshot" - targetUrl="https://pmd.sourceforge.io/${targetPath}/" - rsync -ah --stats --delete "docs/" "${PMD_SF_USER}@web.sourceforge.net:/home/project-web/pmd/htdocs/${targetPath}/" - - echo "TargetUrl: ${targetUrl}" - echo "url_output=${targetUrl}" >> "$GITHUB_OUTPUT" + rsync -ah --stats --delete "docs/" "${PMD_SF_USER}@web.sourceforge.net:/home/project-web/pmd/htdocs/snapshot/" - name: Cleanup ssh if: ${{ always() }} @@ -343,7 +339,6 @@ jobs: PMD_CODE_SSH_USER: pmd PMD_CODE_DOCS_PATH: /docs.pmd-code.org/ run: | - targetUrl="https://docs.pmd-code.org/pmd-doc-${PMD_VERSION}/" filename="pmd-dist-${PMD_VERSION}-doc.zip" scp "${filename}" ${PMD_CODE_SSH_USER}@pmd-code.org:${PMD_CODE_DOCS_PATH} @@ -359,6 +354,7 @@ jobs: rm -f \"snapshot\" && \ ln -s \"pmd-doc-${PMD_VERSION}\" \"snapshot\"" + targetUrl="https://docs.pmd-code.org/pmd-doc-${PMD_VERSION}/" echo "TargetUrl: ${targetUrl}" echo "url_output=${targetUrl}" >> "$GITHUB_OUTPUT" @@ -372,7 +368,7 @@ jobs: # use environment pmd-code, where secrets are configured for PMD_CODE_ORG_DEPLOY_KEY environment: name: pmd-code - url: ${{ steps.upload.outputs.url_output }} + url: https://docs.pmd-code.org/apidocs/ runs-on: ubuntu-latest timeout-minutes: 10 defaults: @@ -416,14 +412,11 @@ jobs: } > "$HOME/.ssh/known_hosts" - name: Upload javadocs to pmd-code.org - id: upload env: PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} PMD_CODE_SSH_USER: pmd PMD_CODE_DOCS_PATH: /docs.pmd-code.org/ run: | - targetUrl="https://docs.pmd-code.org/apidocs/" - for moduleJavadocJar in */target/*-javadoc.jar */*/target/*-javadoc.jar; do moduleJavadocJarBasename="$(basename "$moduleJavadocJar")" module=${moduleJavadocJarBasename%%-${PMD_VERSION}-javadoc.jar} @@ -441,9 +434,6 @@ jobs: ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}/apidocs\" && \ echo 'Options +Indexes' > .htaccess" - echo "TargetUrl: ${targetUrl}" - echo "url_output=${targetUrl}" >> "$GITHUB_OUTPUT" - - name: Cleanup ssh if: ${{ always() }} run: | @@ -452,6 +442,9 @@ jobs: deploy-to-github-pages: needs: check-version runs-on: ubuntu-latest + environment: + name: github-pages + url: https://pmd.github.io/pmd/ timeout-minutes: 10 permissions: contents: write # to push to branch gh-pages @@ -484,17 +477,13 @@ jobs: git commit -q -m "$MSG" git push - targetUrl="https://pmd.github.io/pmd/" - echo "TargetUrl: ${targetUrl}" - echo "url_output=${targetUrl}" >> "$GITHUB_OUTPUT" - create-regression-tester-baseline: needs: check-version runs-on: ubuntu-latest # use environment pmd-code, where secrets are configured for PMD_CODE_ORG_DEPLOY_KEY environment: name: pmd-code - url: ${{ steps.upload.outputs.url_output }} + url: https://pmd-code.org/pmd-regression-tester/ timeout-minutes: 60 defaults: run: @@ -574,15 +563,10 @@ jobs: echo 'pmd-code.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFa88nqfMavMH/tGeS5DNrSeM5AVHmZQGHh98vC1717o' } > "$HOME/.ssh/known_hosts" - name: Upload report - id: upload run: | cd ../target/reports zip -q -r "main-baseline.zip" "main/" scp "main-baseline.zip" pmd@pmd-code.org:/httpdocs/pmd-regression-tester/ - - targetUrl="https://pmd-code.org/pmd-regression-tester/" - echo "TargetUrl: ${targetUrl}" - echo "url_output=${targetUrl}" >> "$GITHUB_OUTPUT" - name: Cleanup ssh if: ${{ always() }} run: | @@ -594,7 +578,7 @@ jobs: # use environment sonarcloud, where secrets are configured for SONAR_TOKEN environment: name: sonarcloud - url: ${{ steps.upload.outputs.url_output }} + url: https://sonarcloud.io/dashboard?id=net.sourceforge.pmd%3Apmd timeout-minutes: 20 defaults: run: @@ -614,7 +598,6 @@ jobs: path: .m2/repository enableCrossOsArchive: true - name: Build and upload to sonar cloud - id: upload env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -626,17 +609,13 @@ jobs: clean package \ sonar:sonar -Psonar,fastSkip - targetUrl="https://sonarcloud.io/dashboard?id=net.sourceforge.pmd%3Apmd" - echo "TargetUrl: ${targetUrl}" - echo "url_output=${targetUrl}" >> "$GITHUB_OUTPUT" - run-coveralls: needs: check-version runs-on: ubuntu-latest # use environment sonarcloud, where secrets are configured for COVERALLS_REPO_TOKEN environment: name: coveralls - url: ${{ steps.upload.outputs.url_output }} + url: https://coveralls.io/github/pmd/pmd timeout-minutes: 20 defaults: run: @@ -668,7 +647,6 @@ jobs: # shellcheck disable=SC2016 sed -i 's$Comparisons.kt$ApexTreeBuilder.kt$g' pmd-apex/target/site/jacoco/jacoco.xml - name: Build and upload to coveralls report - id: upload env: COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} run: | @@ -678,7 +656,3 @@ jobs: -Dmaven.repo.local=.m2/repository \ generate-sources \ coveralls:report -DrepoToken="${COVERALLS_REPO_TOKEN}" -Pcoveralls,fastSkip - - targetUrl="https://coveralls.io/github/pmd/pmd" - echo "TargetUrl: ${targetUrl}" - echo "url_output=${targetUrl}" >> "$GITHUB_OUTPUT" From 6ae66051367f9b02ede6ac99745ff7d47f01de9a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 8 May 2025 17:20:31 +0200 Subject: [PATCH 0883/1962] [ci] publish-snapshot: document --- .../pmd/devdocs/github_actions_workflows.md | 57 ++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/docs/pages/pmd/devdocs/github_actions_workflows.md b/docs/pages/pmd/devdocs/github_actions_workflows.md index c693bfb5f6b..d6dde920a4b 100644 --- a/docs/pages/pmd/devdocs/github_actions_workflows.md +++ b/docs/pages/pmd/devdocs/github_actions_workflows.md @@ -5,7 +5,7 @@ summary: | PMD uses GitHub Actions as the CI/CD infrastructure to build and release new versions. This page gives an overview of how these workflows work and how to use them. author: Andreas Dangel -last_updated: April 2025 (7.13.0) +last_updated: May 2025 (7.14.0) --- {%include note.html content="This page is work in progress and does not yet describe all workflows."%} @@ -108,6 +108,7 @@ This workflow is in that sense optional, as the docs-artifact and pmd-regression be manually downloaded from the "Pull Request Build" workflow run. It merely adds convenience by giving easy access to a preview of the documentation and to the regression tester results. +<<<<<<< HEAD In the end, this workflow adds additional links to a pull request page. For the comment, GitHub seems to automatically add "rel=nofollow" to the links in the text. This is also applied for the check status pages. However, the links in the commit status are plain links. This might lead to unnecessary @@ -123,3 +124,57 @@ The reasons, why we don't want to have the pages there indexed: They are short-l temporary. These temporary created documentation pages should not end up in any search result. This also helps to avoid unnecessary traffic and load for both the hosting side and the crawling side. + +## Publish Snapshot + +* Builds: +* Workflow file: + +This runs after "Build" of a push on the `main` branch is finished. +It runs in the context of our own repository and has access to all secrets. In order +to have a nicer display in GitHub actions, we leverage "environments", which also +contain secrets. + +There is a first job "check-version" that just determines the version of PMD we are building. This is to ensure, +we are actually building a SNAPSHOT version. Then a couple of other jobs are being executed in parallel: + +* deploy-to-maven-central: Rebuilds PMD from branch main and deploys the snapshot artifacts to + . Rebuilding is necessary in + order to produce all necessary artifacts (sources, javadoc) and also gpg-sign the artifacts. This + is not available from the build artifacts of the "Build" workflow. + * Environment: maven-central + * Secrets: OSSRH_TOKEN, OSSRH_USERNAME +* deploy-to-sourceforge-files: Downloads the "dist-artifact" and "docs-artifact" from the "Build" workflow, + gpg-signs the files and uploads them to . + * Environment: sourceforge + * Secrets: PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY +* deploy-to-sourceforge-io: Uploads the documentation page to be hosted at + . + * Environment: sourceforge + * Secrets: PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY +* deploy-to-pmd-code-doc: Uploads the documentation page to be hosted at + . + * Environment: pmd-code + * Secrets: PMD_CODE_ORG_DEPLOY_KEY +* deploy-to-pmd-code-javadoc: Uploads the javadoc of PMD's modules to be hosted at + . + * Environment: pmd-code + * Secrets: PMD_CODE_ORG_DEPLOY_KEY +* deploy-to-github-pages: Updates the branch "gh-pages" wit the new documentation page + and pushes a new commit onto that branch. This will trigger a new github pages deployment, + so that the new documentation page is available at + . + * Environment: github-pages + * Secrets: no additional secrets +* create-regression-tester-baseline: Creates a new baseline to be used by the pull request builds + for regression testing. The baseline is uploaded to . + * Environment: pmd-code + * Secrets: PMD_CODE_ORG_DEPLOY_KEY +* run-sonar: Executes [sonar-scanner-plugin](https://github.com/SonarSource/sonar-scanner-maven) and + uploads the results to sonarcloud at . + * Environment: sonarcloud + * Secrets: SONAR_TOKEN +* run-coveralls: Executes [coveralls-maven-plugin](https://github.com/hazendaz/coveralls-maven-plugin) and + uploads the results to coveralls at . + * Environment: coveralls + * Secrets: COVERALLS_REPO_TOKEN From f629f2f36742466da2119a2ff9bd81685aaa1954 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 9 May 2025 10:05:00 +0200 Subject: [PATCH 0884/1962] [ci] publish-snapshot: avoid duplication for known_hosts Moved this now to the environment. As this doesn't contain sensitive data, it is a simple variable. --- .github/workflows/publish-snapshot.yml | 120 +++--------------- .../pmd/devdocs/github_actions_workflows.md | 5 + 2 files changed, 25 insertions(+), 100 deletions(-) diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 8c85d71d3b2..6942f306e8b 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -92,7 +92,8 @@ jobs: deploy-to-sourceforge-files: needs: check-version - # use environment sourceforge, where secrets are configured for PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY + # use environment sourceforge, where secrets/vars are configured for PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY + # and PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS environment: name: sourceforge url: ${{ steps.upload.outputs.url_output }} @@ -130,6 +131,7 @@ jobs: - name: Setup ssh key for sourceforge env: WEB_SF_DEPLOY_KEY: ${{ secrets.PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY }} + WEB_SF_KNOWN_HOSTS: ${{ vars.PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS }} run: | mkdir -p "${HOME}/.ssh" chmod 700 "${HOME}/.ssh" @@ -139,28 +141,7 @@ jobs: Host web.sourceforge.net IdentityFile=$HOME/.ssh/web.sourceforge.net_deploy_key " > "$HOME/.ssh/config" - { - # - # web.sourceforge.net (https://sourceforge.net/p/forge/documentation/SSH%20Key%20Fingerprints/) - # - # run locally: - # ssh-keyscan web.sourceforge.net | tee -a sf_known_hosts - # - # verify fingerprints: - # ssh-keygen -F web.sourceforge.net -l -f sf_known_hosts - # # Host web.sourceforge.net found: line 1 - # web.sourceforge.net RSA SHA256:xB2rnn0NUjZ/E0IXQp4gyPqc7U7gjcw7G26RhkDyk90 - # # Host web.sourceforge.net found: line 2 - # web.sourceforge.net ECDSA SHA256:QAAxYkf0iI/tc9oGa0xSsVOAzJBZstcO8HqGKfjpxcY - # # Host web.sourceforge.net found: line 3 - # web.sourceforge.net ED25519 SHA256:209BDmH3jsRyO9UeGPPgLWPSegKmYCBIya0nR/AWWCY - # - # then add output of `ssh-keygen -F web.sourceforge.net -f sf_known_hosts` - # - echo 'web.sourceforge.net ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2uifHZbNexw6cXbyg1JnzDitL5VhYs0E65Hk/tLAPmcmm5GuiGeUoI/B0eUSNFsbqzwgwrttjnzKMKiGLN5CWVmlN1IXGGAfLYsQwK6wAu7kYFzkqP4jcwc5Jr9UPRpJdYIK733tSEmzab4qc5Oq8izKQKIaxXNe7FgmL15HjSpatFt9w/ot/CHS78FUAr3j3RwekHCm/jhPeqhlMAgC+jUgNJbFt3DlhDaRMa0NYamVzmX8D47rtmBbEDU3ld6AezWBPUR5Lh7ODOwlfVI58NAf/aYNlmvl2TZiauBCTa7OPYSyXJnIPbQXg6YQlDknNCr0K769EjeIlAfY87Z4tw==' - echo 'web.sourceforge.net ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCwsY6sZT4MTTkHfpRzYjxG7mnXrGL74RCT2cO/NFvRrZVNB5XNwKNn7G5fHbYLdJ6UzpURDRae1eMg92JG0+yo=' - echo 'web.sourceforge.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOQD35Ujalhh+JJkPvMckDlhu4dS7WH6NsOJ15iGCJLC' - } > "$HOME/.ssh/known_hosts" + echo "${WEB_SF_KNOWN_HOSTS}" > "$HOME/.ssh/known_hosts" - name: Create docs zip env: @@ -213,7 +194,8 @@ jobs: deploy-to-sourceforge-io: needs: check-version - # use environment sourceforge, where secrets are configured for PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY + # use environment sourceforge, where secrets/vars are configured for PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY + # and PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS environment: name: sourceforge url: https://pmd.sourceforge.io/snapshot/ @@ -233,6 +215,7 @@ jobs: - name: Setup ssh key for sourceforge env: WEB_SF_DEPLOY_KEY: ${{ secrets.PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY }} + WEB_SF_KNOWN_HOSTS: ${{ vars.PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS }} run: | mkdir -p "${HOME}/.ssh" chmod 700 "${HOME}/.ssh" @@ -242,28 +225,7 @@ jobs: Host web.sourceforge.net IdentityFile=$HOME/.ssh/web.sourceforge.net_deploy_key " > "$HOME/.ssh/config" - { - # - # web.sourceforge.net (https://sourceforge.net/p/forge/documentation/SSH%20Key%20Fingerprints/) - # - # run locally: - # ssh-keyscan web.sourceforge.net | tee -a sf_known_hosts - # - # verify fingerprints: - # ssh-keygen -F web.sourceforge.net -l -f sf_known_hosts - # # Host web.sourceforge.net found: line 1 - # web.sourceforge.net RSA SHA256:xB2rnn0NUjZ/E0IXQp4gyPqc7U7gjcw7G26RhkDyk90 - # # Host web.sourceforge.net found: line 2 - # web.sourceforge.net ECDSA SHA256:QAAxYkf0iI/tc9oGa0xSsVOAzJBZstcO8HqGKfjpxcY - # # Host web.sourceforge.net found: line 3 - # web.sourceforge.net ED25519 SHA256:209BDmH3jsRyO9UeGPPgLWPSegKmYCBIya0nR/AWWCY - # - # then add output of `ssh-keygen -F web.sourceforge.net -f sf_known_hosts` - # - echo 'web.sourceforge.net ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2uifHZbNexw6cXbyg1JnzDitL5VhYs0E65Hk/tLAPmcmm5GuiGeUoI/B0eUSNFsbqzwgwrttjnzKMKiGLN5CWVmlN1IXGGAfLYsQwK6wAu7kYFzkqP4jcwc5Jr9UPRpJdYIK733tSEmzab4qc5Oq8izKQKIaxXNe7FgmL15HjSpatFt9w/ot/CHS78FUAr3j3RwekHCm/jhPeqhlMAgC+jUgNJbFt3DlhDaRMa0NYamVzmX8D47rtmBbEDU3ld6AezWBPUR5Lh7ODOwlfVI58NAf/aYNlmvl2TZiauBCTa7OPYSyXJnIPbQXg6YQlDknNCr0K769EjeIlAfY87Z4tw==' - echo 'web.sourceforge.net ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCwsY6sZT4MTTkHfpRzYjxG7mnXrGL74RCT2cO/NFvRrZVNB5XNwKNn7G5fHbYLdJ6UzpURDRae1eMg92JG0+yo=' - echo 'web.sourceforge.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOQD35Ujalhh+JJkPvMckDlhu4dS7WH6NsOJ15iGCJLC' - } > "$HOME/.ssh/known_hosts" + echo "${WEB_SF_KNOWN_HOSTS}" > "$HOME/.ssh/known_hosts" - name: Upload to sourceforge env: @@ -278,7 +240,8 @@ jobs: deploy-to-pmd-code-doc: needs: check-version - # use environment pmd-code, where secrets are configured for PMD_CODE_ORG_DEPLOY_KEY + # use environment pmd-code, where secrets/vars are configured for PMD_CODE_ORG_DEPLOY_KEY + # and PMD_CODE_ORG_KNOWN_HOSTS environment: name: pmd-code url: ${{ steps.upload.outputs.url_output }} @@ -298,6 +261,7 @@ jobs: - name: Setup ssh key for pmd-code env: PMD_CODE_ORG_DEPLOY_KEY: ${{ secrets.PMD_CODE_ORG_DEPLOY_KEY }} + PMD_CODE_ORG_KNOWN_HOSTS: ${{ vars.PMD_CODE_ORG_KNOWN_HOSTS }} run: | mkdir -p "${HOME}/.ssh" chmod 700 "${HOME}/.ssh" @@ -307,23 +271,7 @@ jobs: Host pmd-code.org IdentityFile=$HOME/.ssh/pmd-code.org_deploy_key " > "$HOME/.ssh/config" - { - # - # pmd-code.org - # - # ssh-keyscan pmd-code.org | tee -a pmd_known_hosts - # ssh-keygen -F pmd-code.org -l -f pmd_known_hosts - # # Host pmd-code.org found: line 1 - # pmd-code.org RSA SHA256:/uKehVNumCNvJL8C5CziwV9KkUUxHfggq0C4GTrUhwg - # # Host pmd-code.org found: line 2 - # pmd-code.org ECDSA SHA256:6aD1r1XuIoc/zgBT3bt1S9L5ToyJzdQ9rrcMchnqiRA - # # Host pmd-code.org found: line 3 - # pmd-code.org ED25519 SHA256:nvkIAzZhYTxXqSU3DWvos83A0EocZ5dsxNkx1LoMZhg - # ssh-keygen -F pmd-code.org -f pmd_known_hosts - echo 'pmd-code.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDVsIeF6xU0oPb/bMbxG1nU1NDyBpR/cBEPZcm/PuJwdI9B0ydPHA6FysqAnt32fNFznC2SWisnWyY3iNsP3pa8RQJVwmnnv9OboGFlW2/61o3iRyydcpPbgl+ADdt8iU9fmMI7dC04UqgHGBoqOwVNna9VylTjp5709cK2qHnwU450F6YcOEiOKeZfJvV4PmpJCz/JcsUVqft6StviR31jKnqbnkZdP8qNoTbds6WmGKyXkhHdLSZE7X1CFQH28tk8XFqditX93ezeCiThFL7EleDexV/3+2+cs5878sDMUMzHS5KShTjkxzhHaodhtIEdNesinq/hOPbxAGkQ0FbD' - echo 'pmd-code.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMfSJtZcJCeENSZMvdngr+Hwe7oUVQWWKwC4HnfiOoAh/NSIlzJyQvpoPZxnEFid6Y3ntDK+rnx04Japo63zD8Q=' - echo 'pmd-code.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFa88nqfMavMH/tGeS5DNrSeM5AVHmZQGHh98vC1717o' - } > "$HOME/.ssh/known_hosts" + echo "${PMD_CODE_ORG_KNOWN_HOSTS}" > "$HOME/.ssh/known_hosts" - name: Create docs zip env: @@ -365,7 +313,8 @@ jobs: deploy-to-pmd-code-javadoc: needs: check-version - # use environment pmd-code, where secrets are configured for PMD_CODE_ORG_DEPLOY_KEY + # use environment pmd-code, where secrets/vars are configured for PMD_CODE_ORG_DEPLOY_KEY + # and PMD_CODE_ORG_KNOWN_HOSTS environment: name: pmd-code url: https://docs.pmd-code.org/apidocs/ @@ -384,6 +333,7 @@ jobs: - name: Setup ssh key for pmd-code env: PMD_CODE_ORG_DEPLOY_KEY: ${{ secrets.PMD_CODE_ORG_DEPLOY_KEY }} + PMD_CODE_ORG_KNOWN_HOSTS: ${{ vars.PMD_CODE_ORG_KNOWN_HOSTS }} run: | mkdir -p "${HOME}/.ssh" chmod 700 "${HOME}/.ssh" @@ -393,23 +343,7 @@ jobs: Host pmd-code.org IdentityFile=$HOME/.ssh/pmd-code.org_deploy_key " > "$HOME/.ssh/config" - { - # - # pmd-code.org - # - # ssh-keyscan pmd-code.org | tee -a pmd_known_hosts - # ssh-keygen -F pmd-code.org -l -f pmd_known_hosts - # # Host pmd-code.org found: line 1 - # pmd-code.org RSA SHA256:/uKehVNumCNvJL8C5CziwV9KkUUxHfggq0C4GTrUhwg - # # Host pmd-code.org found: line 2 - # pmd-code.org ECDSA SHA256:6aD1r1XuIoc/zgBT3bt1S9L5ToyJzdQ9rrcMchnqiRA - # # Host pmd-code.org found: line 3 - # pmd-code.org ED25519 SHA256:nvkIAzZhYTxXqSU3DWvos83A0EocZ5dsxNkx1LoMZhg - # ssh-keygen -F pmd-code.org -f pmd_known_hosts - echo 'pmd-code.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDVsIeF6xU0oPb/bMbxG1nU1NDyBpR/cBEPZcm/PuJwdI9B0ydPHA6FysqAnt32fNFznC2SWisnWyY3iNsP3pa8RQJVwmnnv9OboGFlW2/61o3iRyydcpPbgl+ADdt8iU9fmMI7dC04UqgHGBoqOwVNna9VylTjp5709cK2qHnwU450F6YcOEiOKeZfJvV4PmpJCz/JcsUVqft6StviR31jKnqbnkZdP8qNoTbds6WmGKyXkhHdLSZE7X1CFQH28tk8XFqditX93ezeCiThFL7EleDexV/3+2+cs5878sDMUMzHS5KShTjkxzhHaodhtIEdNesinq/hOPbxAGkQ0FbD' - echo 'pmd-code.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMfSJtZcJCeENSZMvdngr+Hwe7oUVQWWKwC4HnfiOoAh/NSIlzJyQvpoPZxnEFid6Y3ntDK+rnx04Japo63zD8Q=' - echo 'pmd-code.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFa88nqfMavMH/tGeS5DNrSeM5AVHmZQGHh98vC1717o' - } > "$HOME/.ssh/known_hosts" + echo "${PMD_CODE_ORG_KNOWN_HOSTS}" > "$HOME/.ssh/known_hosts" - name: Upload javadocs to pmd-code.org env: @@ -480,7 +414,8 @@ jobs: create-regression-tester-baseline: needs: check-version runs-on: ubuntu-latest - # use environment pmd-code, where secrets are configured for PMD_CODE_ORG_DEPLOY_KEY + # use environment pmd-code, where secrets/vars are configured for PMD_CODE_ORG_DEPLOY_KEY + # and PMD_CODE_ORG_KNOWN_HOSTS environment: name: pmd-code url: https://pmd-code.org/pmd-regression-tester/ @@ -536,6 +471,7 @@ jobs: - name: Setup ssh key for pmd-code env: PMD_CODE_ORG_DEPLOY_KEY: ${{ secrets.PMD_CODE_ORG_DEPLOY_KEY }} + PMD_CODE_ORG_KNOWN_HOSTS: ${{ vars.PMD_CODE_ORG_KNOWN_HOSTS }} run: | mkdir -p "${HOME}/.ssh" chmod 700 "${HOME}/.ssh" @@ -545,23 +481,7 @@ jobs: Host pmd-code.org IdentityFile=$HOME/.ssh/pmd-code.org_deploy_key " > "$HOME/.ssh/config" - { - # - # pmd-code.org - # - # ssh-keyscan pmd-code.org | tee -a pmd_known_hosts - # ssh-keygen -F pmd-code.org -l -f pmd_known_hosts - # # Host pmd-code.org found: line 1 - # pmd-code.org RSA SHA256:/uKehVNumCNvJL8C5CziwV9KkUUxHfggq0C4GTrUhwg - # # Host pmd-code.org found: line 2 - # pmd-code.org ECDSA SHA256:6aD1r1XuIoc/zgBT3bt1S9L5ToyJzdQ9rrcMchnqiRA - # # Host pmd-code.org found: line 3 - # pmd-code.org ED25519 SHA256:nvkIAzZhYTxXqSU3DWvos83A0EocZ5dsxNkx1LoMZhg - # ssh-keygen -F pmd-code.org -f pmd_known_hosts - echo 'pmd-code.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDVsIeF6xU0oPb/bMbxG1nU1NDyBpR/cBEPZcm/PuJwdI9B0ydPHA6FysqAnt32fNFznC2SWisnWyY3iNsP3pa8RQJVwmnnv9OboGFlW2/61o3iRyydcpPbgl+ADdt8iU9fmMI7dC04UqgHGBoqOwVNna9VylTjp5709cK2qHnwU450F6YcOEiOKeZfJvV4PmpJCz/JcsUVqft6StviR31jKnqbnkZdP8qNoTbds6WmGKyXkhHdLSZE7X1CFQH28tk8XFqditX93ezeCiThFL7EleDexV/3+2+cs5878sDMUMzHS5KShTjkxzhHaodhtIEdNesinq/hOPbxAGkQ0FbD' - echo 'pmd-code.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMfSJtZcJCeENSZMvdngr+Hwe7oUVQWWKwC4HnfiOoAh/NSIlzJyQvpoPZxnEFid6Y3ntDK+rnx04Japo63zD8Q=' - echo 'pmd-code.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFa88nqfMavMH/tGeS5DNrSeM5AVHmZQGHh98vC1717o' - } > "$HOME/.ssh/known_hosts" + echo "${PMD_CODE_ORG_KNOWN_HOSTS}" > "$HOME/.ssh/known_hosts" - name: Upload report run: | cd ../target/reports diff --git a/docs/pages/pmd/devdocs/github_actions_workflows.md b/docs/pages/pmd/devdocs/github_actions_workflows.md index d6dde920a4b..dcee2d81bc8 100644 --- a/docs/pages/pmd/devdocs/github_actions_workflows.md +++ b/docs/pages/pmd/devdocs/github_actions_workflows.md @@ -148,18 +148,22 @@ we are actually building a SNAPSHOT version. Then a couple of other jobs are bei gpg-signs the files and uploads them to . * Environment: sourceforge * Secrets: PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY + * Vars: PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS * deploy-to-sourceforge-io: Uploads the documentation page to be hosted at . * Environment: sourceforge * Secrets: PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY + * Vars: PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS * deploy-to-pmd-code-doc: Uploads the documentation page to be hosted at . * Environment: pmd-code * Secrets: PMD_CODE_ORG_DEPLOY_KEY + * Vars: PMD_CODE_ORG_KNOWN_HOSTS * deploy-to-pmd-code-javadoc: Uploads the javadoc of PMD's modules to be hosted at . * Environment: pmd-code * Secrets: PMD_CODE_ORG_DEPLOY_KEY + * Vars: PMD_CODE_ORG_KNOWN_HOSTS * deploy-to-github-pages: Updates the branch "gh-pages" wit the new documentation page and pushes a new commit onto that branch. This will trigger a new github pages deployment, so that the new documentation page is available at @@ -170,6 +174,7 @@ we are actually building a SNAPSHOT version. Then a couple of other jobs are bei for regression testing. The baseline is uploaded to . * Environment: pmd-code * Secrets: PMD_CODE_ORG_DEPLOY_KEY + * Vars: PMD_CODE_ORG_KNOWN_HOSTS * run-sonar: Executes [sonar-scanner-plugin](https://github.com/SonarSource/sonar-scanner-maven) and uploads the results to sonarcloud at . * Environment: sonarcloud From 3e6c80c1a6049ac59180bcdb920a63e48482a89c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 9 May 2025 13:21:59 +0200 Subject: [PATCH 0885/1962] [ci] publish-snapshot: limit to main branch --- .github/workflows/publish-snapshot.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 6942f306e8b..5aa9615b07e 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -5,6 +5,8 @@ on: workflows: [Build] types: - completed + branches: + - main permissions: contents: read # to fetch code (actions/checkout) From 91994031fa59c0a3bc6d3b772c31e65751ab2646 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 9 May 2025 14:52:41 +0200 Subject: [PATCH 0886/1962] [ci] publish-snapshot: add missing setup-java --- .github/workflows/publish-snapshot.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 5aa9615b07e..debadb985bf 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -33,6 +33,10 @@ jobs: - uses: actions/checkout@v4 with: ref: main + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '11' - name: Determine Version id: version run: | From e38c75527eb591292a2a626d0ada4278c8e77308 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 9 May 2025 19:31:37 +0200 Subject: [PATCH 0887/1962] [ci] publish-snapshot: add job summary --- .github/workflows/publish-snapshot.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index debadb985bf..079049934b5 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -47,6 +47,22 @@ jobs: exit 1 fi echo "PMD_VERSION=$PMD_VERSION" >> "$GITHUB_OUTPUT" + - name: Add Job Summary + env: + WORKFLOW_RUN_DISPLAY_TITLE: ${{ github.event.workflow_run.display_title }} + WORKFLOW_RUN_NAME: ${{ github.event.workflow_run.name }} + WORKFLOW_RUN_NUMBER: ${{ github.event.workflow_run.run_number }} + WORKFLOW_RUN_HTML_URL: ${{ github.event.workflow_run.html_url }} + VERSION: ${{ steps.version.outputs.PMD_VERSION }} + BRANCH: ${{ github.event.workflow_run.head_branch }} + run: | + echo "### Run Info" >> "${GITHUB_STEP_SUMMARY}" + echo "Building Version: ${VERSION}" >> "${GITHUB_STEP_SUMMARY}" + echo "" >> "${GITHUB_STEP_SUMMARY}" + echo "Branch: ${BRANCH}" >> "${GITHUB_STEP_SUMMARY}" + echo "" >> "${GITHUB_STEP_SUMMARY}" + echo "Called by [${WORKFLOW_RUN_DISPLAY_TITLE} (${WORKFLOW_RUN_NAME} #${WORKFLOW_RUN_NUMBER})](${WORKFLOW_RUN_HTML_URL})" >> "${GITHUB_STEP_SUMMARY}" + echo "" >> "${GITHUB_STEP_SUMMARY}" deploy-to-maven-central: needs: check-version From 5806906fb0452bcb61f36d9e69511421ff3ff1fa Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 9 May 2025 20:02:08 +0200 Subject: [PATCH 0888/1962] [ci] publish-snapshot: Run also for workflow_dispatch --- .github/workflows/publish-snapshot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 079049934b5..1cdaecb99a3 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -19,7 +19,7 @@ jobs: # only run in the official pmd repo, where we have access to the secrets and not on forks # and only run for _successful_ push workflow runs on branch "main". if: ${{ github.repository == 'pmd/pmd' - && github.event.workflow_run.event == 'push' + && contains(fromJSON('["push", "workflow_dispatch", "schedule"]'), github.event.workflow_run.event) && github.event.workflow_run.head_branch == 'main' && github.event.workflow_run.conclusion == 'success' }} runs-on: ubuntu-latest From ed8206399b664c4ea8bc3f16d9f8402c9a7f7126 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 10 May 2025 12:17:29 +0200 Subject: [PATCH 0889/1962] [doc] github actions: documentation current secrets --- .../pmd/devdocs/github_actions_workflows.md | 352 ++++++++++++++++++ 1 file changed, 352 insertions(+) diff --git a/docs/pages/pmd/devdocs/github_actions_workflows.md b/docs/pages/pmd/devdocs/github_actions_workflows.md index dcee2d81bc8..5b4137b5d3e 100644 --- a/docs/pages/pmd/devdocs/github_actions_workflows.md +++ b/docs/pages/pmd/devdocs/github_actions_workflows.md @@ -183,3 +183,355 @@ we are actually building a SNAPSHOT version. Then a couple of other jobs are bei uploads the results to coveralls at . * Environment: coveralls * Secrets: COVERALLS_REPO_TOKEN + +## Secrets and Variables +The "Build" workflow doesn't need any secrets or additional permissions, it just builds and creates artifacts. +This is necessary, so that this workflow can also run on forks, so that contributors can develop in their +own fork and have their build validated already. All branches (not only main) are built. The same workflow is +also used for pull request builds. + +On the main PMD repository () additional workflows are triggered after "Build". +These additional workflows run with privileged mode, so that they have access to all secrets and can +elevate permissions as needed. + +Secrets and variables are organized in a hierarchy, beginning at the organization level (those secrets are +available in all repositories), repository level and environment level (environments can be created at the +repository level). + +At time of this writing (2025-05-10), the following secrets and variables are configured: + +### Organization +See + +* `PMD_ACTIONS_HELPER_ID` and `PMD_ACTIONS_HELPER_PRIVATE_KEY`: These are the app id and private key for our + custom GitHub App [PMD Actions Helper](https://github.com/organizations/pmd/settings/apps/pmd-actions-helper). + This is a private app defined at our organization and can only be installed within our organization. With these two + secrets and the action [create-github-app-token](https://github.com/actions/create-github-app-token) we can + create a temporary github token, that has more permissions to access other repositories. + This is used to trigger the workflow in pmd/docker from pmd/pmd to create and upload a new docker image and + also in "publish-snapshot" to push to repository pmd/pmd-eclipse-plugin-p2-site during the build + of pmd/pmd-eclipse-plugin. + A new private key can be generated through GitHub organization settings. + +* `PMD_CI_GPG_PASSPHRASE` and `PMD_CI_GPG_PRIVATE_KEY`: That's the secret GPG key used to sign our releases, + see [Signed Releases](pmd_userdocs_signed_releases.html). The key is exported in armored format + (beginning with "-----BEGIN PGP PRIVATE KEY BLOCK-----"). The key is imported during the build either with + the option "gpg-private-key" of [setup-java](https://github.com/actions/setup-java) action or manually + via a small shell script ("gpg --import ..."). + The release signing key is created in such a way, that we use the primary key only for certifying our own + subkeys (capability C) and we have a separate subkey that is used only for signing releases + (capability S). In case the signing subkey gets compromised, we can add a new subkey, but keep the + primary key. The idea is, that only the private key of the subkey is exported and put into the + secret variable `PMD_CI_GPG_PRIVATE_KEY`. This can be achieved through + `gpg --armor --export-secret-subkeys 2EFA55D0785C31F956F2F87EA0B5CA1A4E086838 | wl-copy`. + More information about creating and renewing this key, see below [Release Signing Keys](#release-signing-keys). + +### Repository pmd/pmd +See + +* `AWS_S3_PMD_PULL_REQUESTS_ACCESS_KEY_ID` and `AWS_S3_PMD_PULL_REQUESTS_SECRET_ACCESS_KEY`: Used by + "Publish Results From Pull Request" to upload the regression report and documentation to the AWS S3 + bucket "pmd-pull-requests": http://pmd-pull-requests.s3-website.eu-central-1.amazonaws.com/. + This access key corresponds to the user "arn:aws:iam::624352026855:user/pmd-pull-requests", which is + granted write access to this bucket via the following permission policy: + + ```json + { + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "VisualEditor0", + "Effect": "Allow", + "Action": [ + "s3:Get*", + "s3:List*", + "s3:PutObject", + "s3:DeleteObject" + ], + "Resource": [ + "arn:aws:s3:::pmd-pull-requests/*", + "arn:aws:s3:::pmd-pull-requests" + ] + } + ] + } + ``` + New access key/users need to be created via AWS. + +### Repository pmd/docker +See + +* `DOCKER_USERNAME` and `DOCKER_PASSWORD`: Used by repo pmd/docker to push new images to + . This is actually a personal access token of user [andreasdangel](https://hub.docker.com/u/andreasdangel), + who is the only member of the community organization [pmdcode](https://hub.docker.com/u/pmdcode). + +### Repository pmd/pmd-regression-tester +See + +* `GEM_HOST_API_KEY`: Used to publish a new version into . + The key can be generated at . + +### Repository pmd/pmd - Environment "maven-central" + +* `OSSRH_USERNAME` and `OSSRH_TOKEN`: Used to deploy artifacts to maven central via OSSRH to our namespace + [net.sourceforge.pmd](https://repo.maven.apache.org/maven2/net/sourceforge/pmd). + Login on , go to your user profile, select "User Token" and "Access User Token". + You'll see the tokens to be used for username and password. + Note: This will soon be migrated to use . + +### Repository pmd/pmd - Environment "coveralls" +* `COVERALLS_REPO_TOKEN`: Used to upload coverage results to . + When you log in via GitHub on coveralls.io, the token is displayed on that page. + +### Repository pmd/pmd - Environment "sonarcloud" +* `SONAR_TOKEN`: Used to upload new results to . + The token can be configured here: . Login via GitHub. + +### Repository pmd/pmd - Environment "sourceforge" +* `PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY`: The private ssh key used to access web.sourceforge.net to + upload files and web pages. + It is created with `ssh-keygen -t ed25519 -C "ssh key for pmd. used for github actions push to web.sourceforge.net" -f web.sourceforge.net_deploy_key`. + You need to configure the public key part here: . The user is your + sourceforge user id. + The key should begin with "-----BEGIN OPENSSH PRIVATE KEY-----". + +* `PMD_SF_BEARER_TOKEN`: This is needed to access sourceforge API (https://sourceforge.net/p/forge/documentation/Allura%20API/) + to create new blog entries. The token is created at . + +* `PMD_SF_APIKEY`: This is needed to select the latest release on sourceforge files, see + . The key is created at + under "Releases API Key". + + +This environment also has a variable, which is the known_hosts content as `PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS`: + +``` +# +# web.sourceforge.net (https://sourceforge.net/p/forge/documentation/SSH%20Key%20Fingerprints/) +# +# run locally: +# ssh-keyscan web.sourceforge.net | tee -a sf_known_hosts +# +# verify fingerprints: +# ssh-keygen -F web.sourceforge.net -l -f sf_known_hosts +# # Host web.sourceforge.net found: line 1 +# web.sourceforge.net RSA SHA256:xB2rnn0NUjZ/E0IXQp4gyPqc7U7gjcw7G26RhkDyk90 +# # Host web.sourceforge.net found: line 2 +# web.sourceforge.net ECDSA SHA256:QAAxYkf0iI/tc9oGa0xSsVOAzJBZstcO8HqGKfjpxcY +# # Host web.sourceforge.net found: line 3 +# web.sourceforge.net ED25519 SHA256:209BDmH3jsRyO9UeGPPgLWPSegKmYCBIya0nR/AWWCY +# +# then add output of `ssh-keygen -F web.sourceforge.net -f sf_known_hosts` +# +web.sourceforge.net ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2uifHZbNexw6cXbyg1JnzDitL5VhYs0E65Hk/tLAPmcmm5GuiGeUoI/B0eUSNFsbqzwgwrttjnzKMKiGLN5CWVmlN1IXGGAfLYsQwK6wAu7kYFzkqP4jcwc5Jr9UPRpJdYIK733tSEmzab4qc5Oq8izKQKIaxXNe7FgmL15HjSpatFt9w/ot/CHS78FUAr3j3RwekHCm/jhPeqhlMAgC+jUgNJbFt3DlhDaRMa0NYamVzmX8D47rtmBbEDU3ld6AezWBPUR5Lh7ODOwlfVI58NAf/aYNlmvl2TZiauBCTa7OPYSyXJnIPbQXg6YQlDknNCr0K769EjeIlAfY87Z4tw== +web.sourceforge.net ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCwsY6sZT4MTTkHfpRzYjxG7mnXrGL74RCT2cO/NFvRrZVNB5XNwKNn7G5fHbYLdJ6UzpURDRae1eMg92JG0+yo= +web.sourceforge.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOQD35Ujalhh+JJkPvMckDlhu4dS7WH6NsOJ15iGCJLC +``` + +### Repository pmd/pmd - Environment "pmd-code" + +* `PMD_CODE_ORG_DEPLOY_KEY`: The private ssh key used to access docs.pmd-code.org. + It is created with `ssh-keygen -t ed25519 -C "ssh key for pmd. used for github actions push to pmd-code.org" -f pmd-code.org_deploy_key`. + The public key is configured in `~/.ssh/authorized_keys` on pmd@pmd-code.org. That means, the user is "pmd". + The key should begin with "-----BEGIN OPENSSH PRIVATE KEY-----". + +This environment also has a variable, which is the known_hosts content as `PMD_CODE_ORG_KNOWN_HOSTS`: + +``` +# +# pmd-code.org +# +# ssh-keyscan pmd-code.org | tee -a pmd_known_hosts +# ssh-keygen -F pmd-code.org -l -f pmd_known_hosts +# # Host pmd-code.org found: line 1 +# pmd-code.org RSA SHA256:/uKehVNumCNvJL8C5CziwV9KkUUxHfggq0C4GTrUhwg +# # Host pmd-code.org found: line 2 +# pmd-code.org ECDSA SHA256:6aD1r1XuIoc/zgBT3bt1S9L5ToyJzdQ9rrcMchnqiRA +# # Host pmd-code.org found: line 3 +# pmd-code.org ED25519 SHA256:nvkIAzZhYTxXqSU3DWvos83A0EocZ5dsxNkx1LoMZhg +# ssh-keygen -F pmd-code.org -f pmd_known_hosts +pmd-code.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDVsIeF6xU0oPb/bMbxG1nU1NDyBpR/cBEPZcm/PuJwdI9B0ydPHA6FysqAnt32fNFznC2SWisnWyY3iNsP3pa8RQJVwmnnv9OboGFlW2/61o3iRyydcpPbgl+ADdt8iU9fmMI7dC04UqgHGBoqOwVNna9VylTjp5709cK2qHnwU450F6YcOEiOKeZfJvV4PmpJCz/JcsUVqft6StviR31jKnqbnkZdP8qNoTbds6WmGKyXkhHdLSZE7X1CFQH28tk8XFqditX93ezeCiThFL7EleDexV/3+2+cs5878sDMUMzHS5KShTjkxzhHaodhtIEdNesinq/hOPbxAGkQ0FbD +pmd-code.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMfSJtZcJCeENSZMvdngr+Hwe7oUVQWWKwC4HnfiOoAh/NSIlzJyQvpoPZxnEFid6Y3ntDK+rnx04Japo63zD8Q= +pmd-code.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFa88nqfMavMH/tGeS5DNrSeM5AVHmZQGHh98vC1717o +``` + + +## Release Signing Keys + +### Creating a new key +In general, a key created once should be reused. However, if the key is (potentially) compromised, a new +key needs to be generated. A gpg key consists of a primary key and one or more subkeys. The primary key +defines the identity (fingerprint, key ID) and subkeys can be used for actual signing. The primary key is +then only used to create new subkeys or renew subkeys. For a more safe operation, the primary key should +be kept offline and only the subkeys should be used for signing. A Release Signing Key also doesn't need +a subkey for encryption. In case a signing key gets compromised, the subkey can be revoked and a new key +can be generated. But the primary key still is safe. + +Creating such a key is not straightforward, hence this how to (there are a couple of guides +in the internet about best practices): + +``` +$ gpg --expert --full-generate-key +... +Please select what kind of key you want: +> 8 (RSA (set your own capabilities) +> S (Toggle Sign) +> E (Toggle Encrypt) +> Q +Current allowed actions: Certify +What keysize do you want? +> 4096 +Please specify how long the key should be valid. +> 2y +Real name: +> PMD Release Signing Key +Email address: +> releases@pmd-code.org +... +pub rsa4096 2025-01-04 [C] [expires: 2027-01-04] + 2EFA55D0785C31F956F2F87EA0B5CA1A4E086838 +uid PMD Release Signing Key +``` + +Then we create a subkey for signing: +``` +$ gpg --edit-key 2EFA55D0785C31F956F2F87EA0B5CA1A4E086838 +gpg> addkey +> 4 (RSA (sign only)) +keysize: +> 4096 +Expiration +> 2y +... +> save +``` + +Now let's publish the public key: +``` +$ gpg --armor --export 2EFA55D0785C31F956F2F87EA0B5CA1A4E086838 | curl -T - https://keys.openpgp.org +Key successfully uploaded. Proceed with verification here: +https://keys.openpgp.org/upload/.... +``` + +Export the key to upload it to : +`gpg --armor --export 2EFA55D0785C31F956F2F87EA0B5CA1A4E086838 | wl-copy` +Also upload it to . + +Verify the uploaded (public) key (and expiration date): + +``` +gpg --armor --export 2EFA55D0785C31F956F2F87EA0B5CA1A4E086838 > release-signing-key-2EFA55D0785C31F956F2F87EA0B5CA1A4E086838-public.asc +gpg --show-keys release-signing-key-2EFA55D0785C31F956F2F87EA0B5CA1A4E086838-public.asc +curl 'https://keys.openpgp.org/vks/v1/by-fingerprint/2EFA55D0785C31F956F2F87EA0B5CA1A4E086838' | gpg --show-keys +curl 'https://keyserver.ubuntu.com/pks/lookup?search=0x2EFA55D0785C31F956F2F87EA0B5CA1A4E086838&fingerprint=on&exact=on&options=mr&op=get' | gpg --show-keys +curl 'http://pgp.mit.edu/pks/lookup?op=get&search=0x2EFA55D0785C31F956F2F87EA0B5CA1A4E086838' | gpg --show-keys +``` + +### Current Key + +* Used since January 2025 +* Fingerprint `2EFA 55D0 785C 31F9 56F2 F87E A0B5 CA1A 4E08 6838` +* Used for signing artifacts in Maven Central + +``` +$ gpg --list-keys --fingerprint --with-subkey-fingerprint 2EFA55D0785C31F956F2F87EA0B5CA1A4E086838 +pub rsa4096 2025-01-04 [C] [verfรคllt: 2027-01-04] + 2EFA 55D0 785C 31F9 56F2 F87E A0B5 CA1A 4E08 6838 +uid [ ultimativ ] PMD Release Signing Key +sub rsa4096 2025-01-04 [S] [verfรคllt: 2027-01-04] + 1E04 6C19 ED28 73D8 C08A F7B8 A063 2691 B78E 3422 +``` + +The public key is available here: +* +* +* +* + + +### Old keys + +* Fingerprint `EBB2 41A5 45CB 17C8 7FAC B2EB D0BF 1D73 7C9A 1C22` + * Used until December 2024 + * Replaced as the passphrase has been compromised and therefore the key is potentially + compromised. Note - as until now (January 2025) we don't have any indication that the key + actually has been misused. + * Revoked 2025-01-04. + * see file `release-signing-key-D0BF1D737C9A1C22-public.asc`. + +* Fingerprint `94A5 2756 9CAF 7A47 AFCA BDE4 86D3 7ECA 8C2E 4C5B` + * Old key used to sign PMD Designer + * Revoked 2025-01-04. + +### Private key + +In order for GitHub Actions to automatically sign the artifacts for snapshot builds and release builds, +we need to make the private key along with the passphrase available. This is done using +multiple [`secrets`](https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets). +The secrets are configured on the organization level of PMD, so that the Release Signing key is available +for all repositories. + +To not expose the master key, we only export the subkeys we use for signing and store this in the secret +`PMD_CI_GPG_PRIVATE_KEY`. + +For setting up, export the secret key and copy-paste it into a new secret: + +``` +gpg --armor --export-secret-subkeys 2EFA55D0785C31F956F2F87EA0B5CA1A4E086838 | wl-copy +``` + +(instead of wl-copy, use xclip or pbcopy, depending on your os). + +This private key will be imported by setup-java or a small shell script. + +**Note 1:** We use option `--export-secret-subkeys` to only export the subkey and not the master key. +That way, we don't need to transfer the master key. + +**Note 2:** In order to use the key later on, the passphrase is needed. This is also setup as a secret: +`PMD_CI_GPG_PASSPHRASE`. This secret is then exported as "MAVEN_GPG_PASSPHRASE" where needed +(`MAVEN_GPG_PASSPHRASE: ${{ secrets.PMD_CI_GPG_PASSPHRASE }}`) in github actions workflows. +See also . + +**Note 3:** The private key is now only secured by the passphrase. It is stored as a GitHub Actions +secret and available in an environment variable. It is not committed as a file anywhere. Note: +When importing the key, it is stored on disk in "~/.gnupg" - hence the GitHub Actions should make sure +to delete this directory on the runner after the workflow is finished in order to not leak +the key to following users of the runner. + +### Updating the key + +From time to time the key needs to be renewed, passphrase needs to be changed or a whole (sub)key needs to +be replaced. + +For renewing or changing the passphrase, import the private master key and public key into your local gpg keystore +(if you don't have it already in your keyring) and renew it. +Make sure to renew all subkeys. Then export the public key again. + +For replacing, generate a new (sub) key, just export it. + +You can verify the expiration date with `gpg --fingerprint --list-key 2EFA55D0785C31F956F2F87EA0B5CA1A4E086838`: + +``` +pub rsa4096 2025-01-04 [C] [expires: 2027-01-04] + 2EFA 55D0 785C 31F9 56F2 F87E A0B5 CA1A 4E08 6838 +uid [ultimate] PMD Release Signing Key +sub rsa4096 2025-01-04 [S] [expires: 2027-01-04] + +``` + +Upload the exported *public* key to + +* +* +* + +Verify the uploaded key expiration date: + +``` +gpg --show-keys release-signing-key-2EFA55D0785C31F956F2F87EA0B5CA1A4E086838-public.asc +curl 'https://keys.openpgp.org/vks/v1/by-fingerprint/2EFA55D0785C31F956F2F87EA0B5CA1A4E086838' | gpg --show-keys +curl 'https://keyserver.ubuntu.com/pks/lookup?search=0x2EFA55D0785C31F956F2F87EA0B5CA1A4E086838&fingerprint=on&exact=on&options=mr&op=get' | gpg --show-keys +curl 'http://pgp.mit.edu/pks/lookup?op=get&search=0x2EFA55D0785C31F956F2F87EA0B5CA1A4E086838' | gpg --show-keys +``` + +Don't forget to update the secret `PMD_CI_GPG_PRIVATE_KEY` with the renewed private signing subkey. From 7f0ff428fe188c21125cfab94bc217630134d2d7 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 10 May 2025 19:47:45 +0200 Subject: [PATCH 0890/1962] [doc] github actions: documentation - rubygems This is now moved into an own environment. --- docs/pages/pmd/devdocs/github_actions_workflows.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/pmd/devdocs/github_actions_workflows.md b/docs/pages/pmd/devdocs/github_actions_workflows.md index 5b4137b5d3e..8cebc4e65bf 100644 --- a/docs/pages/pmd/devdocs/github_actions_workflows.md +++ b/docs/pages/pmd/devdocs/github_actions_workflows.md @@ -265,7 +265,7 @@ See . This is actually a personal access token of user [andreasdangel](https://hub.docker.com/u/andreasdangel), who is the only member of the community organization [pmdcode](https://hub.docker.com/u/pmdcode). -### Repository pmd/pmd-regression-tester +### Repository pmd/pmd-regression-tester - Environment "rubygems" See * `GEM_HOST_API_KEY`: Used to publish a new version into . From 02c4e58374b8202ad8e9b2cb5b4966c5a9e2b6a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 11 May 2025 08:13:59 +0200 Subject: [PATCH 0891/1962] Doc and lint --- .idea/vcs.xml | 1 + .../java/types/internal/infer/ExprMirror.java | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 13f1d386bbf..39eb3fa282f 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -23,5 +23,6 @@ + \ No newline at end of file diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java index 08efc350bfe..67a8f8e395f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java @@ -15,6 +15,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import net.sourceforge.pmd.lang.java.ast.JavaNode; +import net.sourceforge.pmd.lang.java.ast.MethodUsage; import net.sourceforge.pmd.lang.java.symbols.JConstructorSymbol; import net.sourceforge.pmd.lang.java.types.JClassType; import net.sourceforge.pmd.lang.java.types.JMethodSig; @@ -241,10 +242,24 @@ interface FunctionalExprMirror extends PolyExprMirror { void finishFailedInference(@Nullable JTypeMirror targetType); } + /** + * Common interface for {@link InvocationMirror} and {@link MethodRefMirror}, + * both of which wrap nods that implement {@link MethodUsage}. + */ interface MethodUsageMirror extends PolyExprMirror { + /** + * Set the compile-time declaration that was resolved for this method usage. + */ void setCompileTimeDecl(InvocationMirror.MethodCtDecl methodType); + /** + * Return the type in which the search for accessible methods start. + * For method references it is the type of the LHS and is specified by + * the JLS. For method invocations it is the type of the receiver, or + * the type of the enclosing type. For constructor invocations this + * is not defined and will return null. + */ @Nullable JTypeMirror getTypeToSearch(); } @@ -434,9 +449,16 @@ interface InvocationMirror extends PolyExprMirror, MethodUsageMirror { List getArgumentExpressions(); + /** Return the size of the argument list. */ int getArgumentCount(); + /** + * {@inheritDoc} + * + * @implSpec Should cache this value and return it when {@link #getCtDecl()} + * is called. + */ @Override void setCompileTimeDecl(MethodCtDecl methodType); @@ -448,6 +470,7 @@ interface InvocationMirror extends PolyExprMirror, MethodUsageMirror { */ @Nullable MethodCtDecl getCtDecl(); + @Override default @Nullable JTypeMirror getTypeToSearch() { return getReceiverType(); } From 460be10cb14114d5783b4b787caccbcf6702434d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 11 May 2025 08:21:44 +0200 Subject: [PATCH 0892/1962] Add test for UseDiamondOperatorFP --- .../rule/codestyle/xml/UseDiamondOperator.xml | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UseDiamondOperator.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UseDiamondOperator.xml index 00f84aec612..fb228c108cb 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UseDiamondOperator.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UseDiamondOperator.xml @@ -528,4 +528,50 @@ public class Foo { }]]> + + Make sure collectors are supported + 1 + + Explicit type arguments can be replaced by a diamond: `new ArrayList<>()` + + joining() { + return new CollectorImpl( + StringBuilder::new, StringBuilder::append, + (r1, r2) -> { r1.append(r2); return r1; }, + StringBuilder::toString); + } + + interface Collector { + + } + interface Collector { + + } + interface Supplier { A get(); } + interface BiConsumer { void accept(A a, T t); } + interface BinaryOperator { T apply(T t, T t); } + interface Function { R apply(T t); } + static class CollectorImpl implements Collector { + private final Supplier supplier; + private final BiConsumer accumulator; + private final BinaryOperator combiner; + private final Function finisher; + + CollectorImpl(Supplier supplier, + BiConsumer accumulator, + BinaryOperator combiner, + Function finisher) { + this.supplier = supplier; + this.accumulator = accumulator; + this.combiner = combiner; + this.finisher = finisher; + } + } + }]]> + + + From bd1ebfe5ac6ca9e7380365a35dfe8b3112e98c3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 11 May 2025 08:28:47 +0200 Subject: [PATCH 0893/1962] Fix new FN with UseDiamondOperator --- .../java/types/internal/infer/ast/MethodRefMirrorImpl.java | 2 +- .../pmd/lang/java/rule/codestyle/xml/UseDiamondOperator.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/MethodRefMirrorImpl.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/MethodRefMirrorImpl.java index 2e8ba5e8d87..b4aa4bcba1b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/MethodRefMirrorImpl.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/MethodRefMirrorImpl.java @@ -65,7 +65,7 @@ public boolean isEquivalentToUnderlyingAst() { AssertionUtil.validateState(ctdecl != null, "overload resolution is not complete"); // must bind to the same ctdecl. - return myNode.getReferencedMethod().equals(ctdecl); + return myNode.getReferencedMethod().equals(ctdecl.getMethodType()); } @Override diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UseDiamondOperator.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UseDiamondOperator.xml index fb228c108cb..aff3ab31ee1 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UseDiamondOperator.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UseDiamondOperator.xml @@ -529,10 +529,10 @@ public class Foo { - Make sure collectors are supported + Test case with collectors 1 - Explicit type arguments can be replaced by a diamond: `new ArrayList<>()` + Explicit type arguments can be replaced by a diamond: `new CollectorImpl<>(...)` Date: Sun, 11 May 2025 08:32:11 +0200 Subject: [PATCH 0894/1962] Doc --- .../pmd/lang/java/types/OverloadSelectionResult.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java index e903c079a32..76bf6b10f7c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java @@ -11,6 +11,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTEnumConstant; import net.sourceforge.pmd.lang.java.ast.InvocationNode; import net.sourceforge.pmd.lang.java.ast.TypeNode; +import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror; /** * Information about the overload-resolution for a specific @@ -87,6 +88,17 @@ default JTypeMirror ithFormalParam(int i) { boolean isFailed(); + /** + * Return the type from which the search for accessible candidates + * for overload resolution starts. This is just a hint as to where + * the candidates come from. There may actually be candidates that + * don't come from this type, eg in the case where this is an + * unqualified method call, and some candidate methods are imported. + * The type is null in some cases, eg, this is not implemented for + * constructor call expressions. + * + * @see ExprMirror.MethodUsageMirror#getTypeToSearch() + */ @Experimental @Nullable JTypeMirror getTypeToSearch(); } From bd73d3787b2a08e71cf98ab1c8d6893958e3f013 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 11 May 2025 08:36:39 +0200 Subject: [PATCH 0895/1962] Update release notes, ref #5700 --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 0c9c0dd3524..a5fbe3cd8b3 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -26,6 +26,9 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿ› Fixed Issues +* core + * [#5700](https://github.com/pmd/pmd/pull/5700): \[core] Don't accidentally catch unexpected runtime exceptions in CpdAnalysis + ### ๐Ÿšจ API Changes ### โœจ Merged pull requests From 9861b86dfb3c7952a1ee24cb8d3fadb7f6465f6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 11 May 2025 11:54:31 +0200 Subject: [PATCH 0896/1962] Missing override annotation --- .../pmd/lang/java/types/internal/infer/ExprMirror.java | 1 + 1 file changed, 1 insertion(+) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java index 67a8f8e395f..f32c8c1ab3d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java @@ -278,6 +278,7 @@ interface MethodRefMirror extends FunctionalExprMirror, MethodUsageMirror { * , except it may also return an array type (the jls makes an exception for it, * while we don't). */ + @Override JTypeMirror getTypeToSearch(); From d76968858c47e79bca881246472587eadd4552ae Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 11 May 2025 12:32:55 +0200 Subject: [PATCH 0897/1962] [ci] build: fix regression tester For pushes, the commit before the push wasn't correctly determined. Additionally, it can be "000...", e.g. when a tag has been pushed. Refs #5584 --- .ci/files/pmdtester_start.sh | 10 +++++++++- .github/workflows/build.yml | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.ci/files/pmdtester_start.sh b/.ci/files/pmdtester_start.sh index 8e98ecd3b64..27cc5f6a42b 100755 --- a/.ci/files/pmdtester_start.sh +++ b/.ci/files/pmdtester_start.sh @@ -39,6 +39,14 @@ if [ "${PMD_REGRESSION_TESTER_BASE_BRANCH}" != "main" ]; then exit 1 fi +if [ "${PMD_REGRESSION_TESTER_2ND_REF}" == "0000000000000000000000000000000000000000" ]; then + echo "No changes has been pushed." + # create files that are added to artifact "pmd-regression-tester" + mkdir -p ../target/reports/diff + echo -n "No regression tested rules have been changed." > ../target/reports/diff/summary.txt + echo -n "skipped" > ../target/reports/diff/conclusion.txt + exit 0 +fi echo "::group::Fetching additional commits" # actions/checkout (git clone) initially only fetched with depth 2. Regression tester @@ -73,8 +81,8 @@ fi git branch "main" "${merge_base}" echo "::endgroup::" -echo "::group::Running pmdtester on branch ${PMD_CI_BRANCH}" export PMD_CI_BRANCH="main" +echo "::group::Running pmdtester against base branch ${PMD_CI_BRANCH}" if [ "${GITHUB_EVENT_NAME}" = "pull_request" ]; then export PMD_CI_PULL_REQUEST_NUMBER="${GITHUB_REF_NAME%/merge}" fi diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 64401265a75..b7a2a6f779a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -331,7 +331,7 @@ jobs: - name: Run pmdtester env: # this variable is available for "push" builds only, otherwise it's empty - PMD_REGRESSION_TESTER_PUSH_BEFORE: ${{ github.event.push.before }} + PMD_REGRESSION_TESTER_PUSH_BEFORE: ${{ github.event.before }} run: .ci/files/pmdtester_start.sh - name: Workaround actions/upload-artifact#176 run: | From a8514368e31ab068383e4d7bfee75f7a7d9b7754 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 11 May 2025 13:03:29 +0200 Subject: [PATCH 0898/1962] [ci] publish-snapshot: Fix usage of dist-artifact - deploy-to-sourceforge-files: it's extracted into dist subdirectory. - deploy-to-pmd-code-javadoc: add logging - create-regression-tester-baseline: download dist-artifact from previous workflow run Refs #5584 --- .github/workflows/publish-snapshot.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 1cdaecb99a3..8402e385bf3 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -170,13 +170,14 @@ jobs: PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} run: | mv docs "pmd-doc-${PMD_VERSION}" - zip -qr "pmd-dist-${PMD_VERSION}-doc.zip" "pmd-doc-${PMD_VERSION}/" + zip -qr "dist/pmd-dist-${PMD_VERSION}-doc.zip" "pmd-doc-${PMD_VERSION}/" - name: Sign files env: PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} MAVEN_GPG_PASSPHRASE: ${{ secrets.PMD_CI_GPG_PASSPHRASE }} run: | + cd dist printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-bin.zip" printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ @@ -377,7 +378,9 @@ jobs: moduleJavadocJarBasename="$(basename "$moduleJavadocJar")" module=${moduleJavadocJarBasename%%-${PMD_VERSION}-javadoc.jar} + echo "Copying module ${moduleJavadocJar}..." scp "$moduleJavadocJar" ${PMD_CODE_SSH_USER}@pmd-code.org:${PMD_CODE_DOCS_PATH} + echo "Extracting remotely ${module}..." # shellcheck disable=SC2029 ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \ mkdir -p \"apidocs/${module}/${PMD_VERSION}\" && \ @@ -385,6 +388,7 @@ jobs: rm \"${moduleJavadocJarBasename}\"" done + echo "(Re)creating .htaccess" # make sure https://docs.pmd-code.org/apidocs/ shows directory index # shellcheck disable=SC2029 ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}/apidocs\" && \ @@ -430,6 +434,10 @@ jobs: Updated by: https://github.com/pmd/pmd/actions/runs/$GITHUB_RUN_ID Triggered by: ${WORKFLOW_RUN_HTML_URL}" + + echo "Commit Message:" + echo "$MSG" + git commit -q -m "$MSG" git push @@ -469,6 +477,8 @@ jobs: - uses: actions/download-artifact@v4 with: name: dist-artifact + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} path: pmd-dist/target - name: Setup bundler run: | From 1463fd0575f47c3a8f93cd7b23c1b3b1c1ffc094 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 11 May 2025 13:33:34 +0200 Subject: [PATCH 0899/1962] [ci] publish-snapshot: Fix creating regression baseline - reuse bundle config in parent directory - fix caching Refs #5584 --- .github/workflows/build.yml | 2 +- .github/workflows/publish-snapshot.yml | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b7a2a6f779a..cf3f8ba8cd3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -313,7 +313,7 @@ jobs: ~/.m2/repository ~/.gradle/caches ~/work/pmd/target/repositories - vendor/bundle + .ci/files/vendor/bundle key: regressiontester-${{ hashFiles('.ci/files/project-list.xml', 'Gemfile.lock') }} restore-keys: regressiontester- - uses: actions/download-artifact@v4 diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 8402e385bf3..883314b4dd8 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -471,7 +471,7 @@ jobs: ~/.m2/repository ~/.gradle/caches ~/work/pmd/target/repositories - vendor/bundle + .ci/files/vendor/bundle key: regressiontester-${{ hashFiles('.ci/files/project-list.xml', 'Gemfile.lock') }} restore-keys: regressiontester- - uses: actions/download-artifact@v4 @@ -491,6 +491,9 @@ jobs: - name: Run pmdtester run: | cd .. + rm -f .bundle/config + bundle config set --local gemfile pmd/.ci/files/Gemfile + bundle config set --local path vendor/bundle bundle exec pmdtester \ --mode single \ --local-git-repo ./pmd \ From 3cd1f3c9e876b4ca5b91033268b3ac685abdfd32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 11 May 2025 13:16:19 +0200 Subject: [PATCH 0900/1962] Share more CLI options between CPD and PMD CPD now supports --report-file (-r) and --ignore-list. PMD now supports --exclude and --non-recursive --- .../AbstractAnalysisPmdSubcommand.java | 66 ++++++++++++++++--- .../pmd/cli/commands/internal/CpdCommand.java | 27 +------- .../pmd/cli/commands/internal/PmdCommand.java | 35 +--------- .../pmd/AbstractConfiguration.java | 25 +++++++ .../net/sourceforge/pmd/PMDConfiguration.java | 19 ------ .../net/sourceforge/pmd/cpd/CpdAnalysis.java | 5 +- .../sourceforge/pmd/internal/util/IOUtil.java | 2 +- .../sourceforge/pmd/cpd/CpdAnalysisTest.java | 47 +++++++++++++ 8 files changed, 141 insertions(+), 85 deletions(-) diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java index 02a090ab3ff..787e3dd6057 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java @@ -7,14 +7,18 @@ import java.net.URI; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; +import org.slf4j.LoggerFactory; + import net.sourceforge.pmd.AbstractConfiguration; import net.sourceforge.pmd.cli.commands.mixins.internal.EncodingMixin; import net.sourceforge.pmd.cli.internal.CliExitCode; import net.sourceforge.pmd.cli.internal.PmdRootLogger; +import net.sourceforge.pmd.util.log.internal.SimpleMessageReporter; import picocli.CommandLine.Mixin; import picocli.CommandLine.Option; @@ -24,37 +28,52 @@ public abstract class AbstractAnalysisPmdSubcommand extends AbstractPmdSubcommand { @Mixin - protected EncodingMixin encoding; + private EncodingMixin encoding; // see the setters #setInputPaths and setPositionalInputPaths for @Option and @Parameters annotations // Note: can't use annotations on the fields here, as otherwise the complete list would be replaced // rather than accumulated. - protected Set inputPaths; + private Set inputPaths; + + @Option(names = "--file-list", description = "Path to a file containing a list of files to analyze, one path per line. " + "One of --dir, --file-list or --uri must be provided.") - protected Path fileListPath; + private Path fileListPath; @Option(names = { "--uri", "-u" }, description = "Database URI for sources. " + "One of --dir, --file-list or --uri must be provided.") - protected URI uri; - + private URI uri; + + @Option(names = "--ignore-list", + description = "Path to a file containing a list of files to exclude from the analysis, one path per line. " + + "This option can be combined with --dir, --file-list and --uri.") + private Path ignoreListPath; + + @Option(names = "--no-fail-on-violation", description = "By default PMD exits with status 4 if violations or duplications are found. " + "Disable this option with '--no-fail-on-violation' to exit with 0 instead. In any case a report with the found violations or duplications will be written.", defaultValue = "true", negatable = true) - protected boolean failOnViolation; + private boolean failOnViolation; @Option(names = "--no-fail-on-error", description = "By default PMD exits with status 5 if recoverable errors occurred (whether or not there are violations or duplications). " + "Disable this option with '--no-fail-on-error' to exit with 0 instead. In any case, a report with the found violations or duplications will be written.", defaultValue = "true", negatable = true) - protected boolean failOnError; + private boolean failOnError; + + + @Option(names = { "--report-file", "-r" }, + description = "Path to a file to which report output is written. " + + "The file is created if it does not exist. " + + "If this option is not specified, the report is rendered to standard output.") + private Path reportFile; - protected List relativizeRootPaths; + private List relativizeRootPaths; @Option(names = { "--relativize-paths-with", "-z"}, description = "Path relative to which directories are rendered in the report. " + "This option allows shortening directories in the report; " @@ -88,6 +107,12 @@ protected void setInputPaths(final List inputPaths) { this.inputPaths.addAll(inputPaths); } + @Option(names = "--exclude", arity = "1..*", description = "Files to be excluded from the analysis") + private List excludes = new ArrayList<>(); + + @Option(names = "--non-recursive", description = "Don't scan subdirectiories when using the --d (-dir) option.") + private boolean nonRecursive; + @Parameters(arity = "*", description = "Path to a source file, or directory containing source files to analyze. " + "Equivalent to using --dir.") protected void setPositionalInputPaths(final List inputPaths) { @@ -119,4 +144,29 @@ protected CliExitCode execute() { this::doExecute); } + protected final void setCommonConfigProperties(C configuration) { + // Configure input paths + if (inputPaths != null) { + configuration.setInputPathList(new ArrayList<>(inputPaths)); + } + configuration.setExcludes(excludes); + configuration.collectFilesRecursively(!nonRecursive); + configuration.setInputFilePath(fileListPath); + configuration.setIgnoreFilePath(ignoreListPath); + configuration.setInputUri(uri); + if (relativizeRootPaths != null) { + configuration.addRelativizeRoots(relativizeRootPaths); + } + configuration.setSourceEncoding(encoding.getEncoding()); + + // reporting logic + configuration.setReportFile(reportFile); + // configuration.setReportProperties(properties); + configuration.setFailOnViolation(failOnViolation); + configuration.setFailOnError(failOnError); + + // Setup CLI message reporter + configuration.setReporter(new SimpleMessageReporter(LoggerFactory.getLogger(PmdCommand.class))); + } + } diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java index f823aa3ab9a..f27b390f4f8 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java @@ -5,10 +5,7 @@ package net.sourceforge.pmd.cli.commands.internal; import java.io.IOException; -import java.nio.file.Path; -import java.util.ArrayList; import java.util.Iterator; -import java.util.List; import org.apache.commons.lang3.mutable.MutableBoolean; import org.checkerframework.checker.nullness.qual.NonNull; @@ -69,7 +66,7 @@ public class CpdCommand extends AbstractAnalysisPmdSubcommand private boolean ignoreIdentifierAndLiteralSequences; /** - * @deprecated Use {@link #failOnError} instead. + * @deprecated Use --[no-]fail-on-error instead. */ @Option(names = "--skip-lexical-errors", description = "Skip files which can't be tokenized due to invalid characters, instead of aborting with an error. Deprecated - use --[no-]fail-on-error instead.") @@ -85,13 +82,6 @@ public class CpdCommand extends AbstractAnalysisPmdSubcommand defaultValue = CpdLanguagePropertiesDefaults.DEFAULT_SKIP_BLOCKS_PATTERN) private String skipBlocksPattern; - @Option(names = "--exclude", arity = "1..*", description = "Files to be excluded from the analysis") - private List excludes = new ArrayList<>(); - - @Option(names = "--non-recursive", description = "Don't scan subdirectiories.") - private boolean nonRecursive; - - /** * Converts these parameters into a configuration. * @@ -102,16 +92,8 @@ public class CpdCommand extends AbstractAnalysisPmdSubcommand @Override protected CPDConfiguration toConfiguration() { final CPDConfiguration configuration = new CPDConfiguration(); - configuration.setExcludes(excludes); - if (relativizeRootPaths != null) { - configuration.addRelativizeRoots(relativizeRootPaths); - } - configuration.setFailOnViolation(failOnViolation); - configuration.setFailOnError(failOnError); - configuration.setInputFilePath(fileListPath); - if (inputPaths != null) { - configuration.setInputPathList(new ArrayList<>(inputPaths)); - } + setCommonConfigProperties(configuration); + configuration.setIgnoreAnnotations(ignoreAnnotations); configuration.setIgnoreIdentifiers(ignoreIdentifiers); configuration.setIgnoreLiterals(ignoreLiterals); @@ -119,13 +101,10 @@ protected CPDConfiguration toConfiguration() { configuration.setIgnoreUsings(ignoreUsings); configuration.setOnlyRecognizeLanguage(language); configuration.setMinimumTileSize(minimumTokens); - configuration.collectFilesRecursively(!nonRecursive); configuration.setNoSkipBlocks(noSkipBlocks); configuration.setRendererName(rendererName); configuration.setSkipBlocksPattern(skipBlocksPattern); configuration.setSkipDuplicates(skipDuplicates); - configuration.setSourceEncoding(encoding.getEncoding()); - configuration.setInputUri(uri); if (skipLexicalErrors) { configuration.getReporter().warn("--skip-lexical-errors is deprecated. Use --no-fail-on-error instead."); diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java index de3fe49ec3c..8587f1d7976 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java @@ -78,7 +78,6 @@ public class PmdCommand extends AbstractAnalysisPmdSubcommand private List rulesets; - private Path ignoreListPath; private String format; @@ -94,8 +93,6 @@ public class PmdCommand extends AbstractAnalysisPmdSubcommand private Properties properties = new Properties(); - private Path reportFile; - private List languageVersion; private Language forceLanguage; @@ -117,12 +114,6 @@ public void setRulesets(final List rulesets) { this.rulesets = rulesets; } - @Option(names = "--ignore-list", - description = "Path to a file containing a list of files to exclude from the analysis, one path per line. " - + "This option can be combined with --dir, --file-list and --uri.") - public void setIgnoreListPath(final Path ignoreListPath) { - this.ignoreListPath = ignoreListPath; - } @Option(names = { "--format", "-f" }, description = "Report format.%nValid values: ${COMPLETION-CANDIDATES}%n" @@ -166,14 +157,6 @@ public void setProperties(final Properties properties) { this.properties = properties; } - @Option(names = { "--report-file", "-r" }, - description = "Path to a file to which report output is written. " - + "The file is created if it does not exist. " - + "If this option is not specified, the report is rendered to standard output.") - public void setReportFile(final Path reportFile) { - this.reportFile = reportFile; - } - @Option(names = "--use-version", description = "The language version PMD should use when parsing source code.%nValid values: ${COMPLETION-CANDIDATES}", completionCandidates = PmdLanguageVersionTypeSupport.class, converter = PmdLanguageVersionTypeSupport.class) @@ -251,26 +234,14 @@ public void setShowProgressBar(final boolean showProgressBar) { @Override protected PMDConfiguration toConfiguration() { final PMDConfiguration configuration = new PMDConfiguration(); - if (inputPaths != null) { - configuration.setInputPathList(new ArrayList<>(inputPaths)); - } - configuration.setInputFilePath(fileListPath); - configuration.setIgnoreFilePath(ignoreListPath); - configuration.setInputUri(uri); + setCommonConfigProperties(configuration); + configuration.setReportFormat(format); - configuration.setSourceEncoding(encoding.getEncoding()); configuration.setMinimumPriority(minimumPriority); - configuration.setReportFile(reportFile); configuration.setReportProperties(properties); - if (relativizeRootPaths != null) { - configuration.addRelativizeRoots(relativizeRootPaths); - } configuration.setRuleSets(rulesets); configuration.setShowSuppressedViolations(showSuppressed); configuration.setSuppressMarker(suppressMarker); - configuration.setThreads(threads); - configuration.setFailOnViolation(failOnViolation); - configuration.setFailOnError(failOnError); configuration.setAnalysisCacheLocation(cacheLocation != null ? cacheLocation.toString() : null); configuration.setIgnoreIncrementalAnalysis(noCache); @@ -319,7 +290,7 @@ protected CliExitCode doExecute(PMDConfiguration configuration) { LOG.debug("Aux classpath: {}", configuration.getClassLoader()); if (showProgressBar) { - if (reportFile == null) { + if (configuration.getReportFilePath() == null) { pmdReporter.warn("Progressbar rendering conflicts with reporting to STDOUT. " + "No progressbar will be shown. Try running with argument '-r ' to output the report to a file instead."); } else { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/AbstractConfiguration.java b/pmd-core/src/main/java/net/sourceforge/pmd/AbstractConfiguration.java index 562599a0053..e52b68a8c7b 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/AbstractConfiguration.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/AbstractConfiguration.java @@ -41,11 +41,15 @@ public abstract class AbstractConfiguration { private PmdReporter reporter; private final LanguageVersionDiscoverer languageVersionDiscoverer; private LanguageVersion forceLanguageVersion; + private @NonNull List inputPaths = new ArrayList<>(); private Path inputFilePath; private Path ignoreFilePath; private List excludes = new ArrayList<>(); private boolean collectRecursive = true; + + private Path reportFile; + private boolean failOnViolation = true; private boolean failOnError = true; @@ -380,6 +384,27 @@ public void collectFilesRecursively(boolean collectRecursive) { this.collectRecursive = collectRecursive; } + + /** + * Get the file to which the report should render. If null, the + * report is rendered on stdout. + * + * @return The file to which to render. + */ + public @Nullable Path getReportFilePath() { + return reportFile; + } + + /** + * Set the file to which the report should render. + * + * @param reportFile the file to set + */ + public void setReportFile(@Nullable Path reportFile) { + this.reportFile = reportFile; + } + + /** * Whether PMD should exit with status 4 (the default behavior, true) if * violations are found or just with 0 (to not break the build, e.g.). diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java index 287d001f2ab..b2bf76402e6 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java @@ -93,7 +93,6 @@ public class PMDConfiguration extends AbstractConfiguration { /** The default suppress marker string. */ public static final String DEFAULT_SUPPRESS_MARKER = "NOPMD"; - private Path reportFile; // General behavior options private String suppressMarker = DEFAULT_SUPPRESS_MARKER; @@ -434,24 +433,6 @@ public boolean isIgnoreIncrementalAnalysis() { return ignoreIncrementalAnalysis; } - /** - * Get the file to which the report should render. - * - * @return The file to which to render. - */ - public Path getReportFilePath() { - return reportFile; - } - - /** - * Set the file to which the report should render. - * - * @param reportFile the file to set - */ - public void setReportFile(Path reportFile) { - this.reportFile = reportFile; - } - @Override protected void checkLanguageIsAcceptable(Language lang) throws UnsupportedOperationException { if (!(lang instanceof PmdCapableLanguage)) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java index c5a154bf047..8ce548c8189 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java @@ -7,6 +7,7 @@ import java.io.IOException; import java.io.Writer; import java.nio.charset.Charset; +import java.nio.file.Path; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -196,7 +197,9 @@ public void performAnalysis(Consumer consumer) { CPDReport cpdReport = new CPDReport(sourceManager, matches, numberOfTokensPerFile, processingErrors); if (renderer != null) { - try (Writer writer = IOUtil.createWriter(Charset.defaultCharset(), null)) { + Path reportFilePath = configuration.getReportFilePath(); + String reportFileAsString = reportFilePath != null ? reportFilePath.toAbsolutePath().toString() : null; + try (Writer writer = IOUtil.createWriter(Charset.defaultCharset(), reportFileAsString)) { renderer.render(cpdReport, writer); } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/IOUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/IOUtil.java index 61e3ff1f912..853ae6ef928 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/IOUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/IOUtil.java @@ -109,7 +109,7 @@ public static Writer createWriter(String reportFile) { * @param reportFile the file name (optional) * @return */ - public static Writer createWriter(Charset charset, String reportFile) { + public static Writer createWriter(Charset charset, @Nullable String reportFile) { try { if (StringUtils.isBlank(reportFile)) { return new OutputStreamWriter(new FilterOutputStream(System.out) { diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CpdAnalysisTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CpdAnalysisTest.java index 857d61d7ceb..f390e7c760a 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CpdAnalysisTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CpdAnalysisTest.java @@ -6,6 +6,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -33,6 +34,7 @@ import org.junit.jupiter.api.condition.OS; import org.junit.jupiter.api.io.TempDir; +import net.sourceforge.pmd.internal.util.IOUtil; import net.sourceforge.pmd.lang.DummyLanguageModule; import net.sourceforge.pmd.lang.ast.LexException; import net.sourceforge.pmd.lang.ast.impl.javacc.MalformedSourceException; @@ -246,6 +248,51 @@ void reportShouldContainProcessingErrors() throws IOException { verifyNoMoreInteractions(reporter); } + @Test + void reportToNonExistentFile(@TempDir Path tmpDir) throws IOException { + Path reportFile = tmpDir.resolve("cpd.txt"); + assertFalse(Files.exists(reportFile), "Report file " + reportFile + " should not exist"); + + testReportFile(reportFile); + } + + @Test + void reportToExistingFileShouldOverwrite(@TempDir Path tmpDir) throws IOException { + Path reportFile = tmpDir.resolve("cpd.txt"); + assertFalse(Files.exists(reportFile), "Report file " + reportFile + " should not exist"); + final String sentinel = "EMPTY_FILE"; + Files.write(reportFile, sentinel.getBytes()); + assertTrue(Files.exists(reportFile), "Report file " + reportFile + " should have been created"); + + String reportContents = testReportFile(reportFile); + assertThat(reportContents, not(containsString(sentinel))); + } + + private String testReportFile(Path reportFile) throws IOException { + PmdReporter reporter = mock(PmdReporter.class); + config.setReporter(reporter); + config.setRendererName("text"); + config.setReportFile(reportFile); + + Path dup1 = Paths.get("./" + BASE_TEST_RESOURCE_PATH, "dup1.txt"); + Path dup2 = Paths.get("./" + BASE_TEST_RESOURCE_PATH, "dup2.txt"); + + try (CpdAnalysis cpd = CpdAnalysis.create(config)) { + assertTrue(cpd.files().addFile(dup2)); + assertTrue(cpd.files().addFile(dup1)); + cpd.performAnalysis(); + } + + assertTrue(Files.exists(reportFile), "Report file " + reportFile + " should have been created"); + + String reportContents = IOUtil.readFileToString(reportFile.toFile()); + assertThat(reportContents, containsString("duplication in the following files")); + assertThat(reportContents, containsString(dup1.toAbsolutePath().normalize().toString())); + assertThat(reportContents, containsString(dup2.toAbsolutePath().normalize().toString())); + return reportContents; + } + + @Test void testSkipLexicalErrors() throws IOException { PmdReporter reporter = mock(PmdReporter.class); From 616fd88c64b63b9bec363e61b7f5fb2488120199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 11 May 2025 14:06:41 +0200 Subject: [PATCH 0901/1962] Rename --exclude to --ignore to match --ignore-list --- docs/pages/pmd/userdocs/cli_reference.md | 20 ++++++++++++++++++- .../AbstractAnalysisPmdSubcommand.java | 14 ++++++++++--- .../pmd/cli/commands/internal/CpdCommand.java | 17 ++++++++++++++++ 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/docs/pages/pmd/userdocs/cli_reference.md b/docs/pages/pmd/userdocs/cli_reference.md index 535a5fa9456..963d9bfa6ad 100644 --- a/docs/pages/pmd/userdocs/cli_reference.md +++ b/docs/pages/pmd/userdocs/cli_reference.md @@ -79,6 +79,13 @@ The tool comes with a rather extensive help text, simply running with `--help`! The valid values are the standard character sets of `java.nio.charset.Charset`." default="UTF-8" %} + {% include custom/cli_option_row.html options="--exclude" + option_arg="path+" + description="Files to be excluded from the analysis. This takes one or more path names as an argument. It is combinable with --exclude-file." + %} + {% include custom/cli_option_row.html options="--non-recursive" + description="Don't scan subdirectories. By default, subdirectories are considered." + %} {% include custom/cli_option_row.html options="--[no-]fail-on-error" description="Specifies whether PMD exits with non-zero status if recoverable errors occurred. By default PMD exits with status 5 if recoverable errors occurred (whether there are violations or not). @@ -106,10 +113,17 @@ The tool comes with a rather extensive help text, simply running with `--help`!

    This option allows to use the xml language for files, that don't use xml as extension. See [example](#analyze-other-xml-formats) below.

    " %} + {% include custom/cli_option_row.html options="--ignore" + option_arg="filepath+" + description="Specify one or more paths to files that will be ignored. + This option overrides files included by any of `--dir`, `--file-list` and `--uri`. + It can combine with `--ignore-list`." + %} {% include custom/cli_option_row.html options="--ignore-list" option_arg="filepath" description="Path to file containing a list of files to ignore, one path per line. - This option overrides files included by any of `--dir`, `--file-list` and `--uri`." + This option overrides files included by any of `--dir`, `--file-list` and `--uri`. + It can combine with `--ignore`" %} {% include custom/cli_option_row.html options="--help,-h" description="Display help on usage." @@ -142,6 +156,10 @@ The tool comes with a rather extensive help text, simply running with `--help`! {% include custom/cli_option_row.html options="--[no-]progress" description="Enables / disable progress bar indicator of live analysis progress. This ie enabled by default." %} + {% include custom/cli_option_row.html options="--non-recursive" + description="When specified, any directory mentioned with `--dir` or in the `--file-list` will only be searched for files that are direct children. + By default, subdirectories are recursively included." + %} {% include custom/cli_option_row.html options="--property,-P" option_arg="name>=<value" description="Specifies a property for the report renderer. The option can be specified several times. diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java index 787e3dd6057..ed1fb5537fc 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java @@ -48,6 +48,17 @@ public abstract class AbstractAnalysisPmdSubcommand excludes = new ArrayList<>(); + @Option(names = "--ignore", arity = "1..*", description = "Files to be excluded from the analysis") + protected void setIgnoreSpecificPaths(List rootPaths) { + if (rootPaths != null) { + this.excludes = rootPaths; + } else { + this.excludes = new ArrayList<>(); + } + } + @Option(names = "--ignore-list", description = "Path to a file containing a list of files to exclude from the analysis, one path per line. " + "This option can be combined with --dir, --file-list and --uri.") @@ -107,9 +118,6 @@ protected void setInputPaths(final List inputPaths) { this.inputPaths.addAll(inputPaths); } - @Option(names = "--exclude", arity = "1..*", description = "Files to be excluded from the analysis") - private List excludes = new ArrayList<>(); - @Option(names = "--non-recursive", description = "Don't scan subdirectiories when using the --d (-dir) option.") private boolean nonRecursive; diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java index f27b390f4f8..d8538c27373 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java @@ -5,7 +5,9 @@ package net.sourceforge.pmd.cli.commands.internal; import java.io.IOException; +import java.nio.file.Path; import java.util.Iterator; +import java.util.List; import org.apache.commons.lang3.mutable.MutableBoolean; import org.checkerframework.checker.nullness.qual.NonNull; @@ -39,6 +41,17 @@ public class CpdCommand extends AbstractAnalysisPmdSubcommand description = "Ignore multiple copies of files of the same name and length in comparison.") private boolean skipDuplicates; + private boolean usedDeprecatedExcludeName = false; + + // this option name is deprecated + @Option(names = "--exclude", + description = "Files to be excluded from the analysis") + @Override + protected void setIgnoreSpecificPaths(List rootPaths) { + super.setIgnoreSpecificPaths(rootPaths); + this.usedDeprecatedExcludeName = true; + } + @Option(names = { "--format", "-f" }, description = "Report format.%nValid values: ${COMPLETION-CANDIDATES}%n" + "Alternatively, you can provide the fully qualified name of a custom CpdRenderer in the classpath.", @@ -111,6 +124,10 @@ protected CPDConfiguration toConfiguration() { configuration.setFailOnError(false); } + if (usedDeprecatedExcludeName) { + configuration.getReporter().warn("Option name --exclude is deprecated. Use --ignore instead."); + } + return configuration; } From 5444ad38ccdf315ec1b727ee17d205dae03d661e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 11 May 2025 14:30:55 +0200 Subject: [PATCH 0902/1962] Refactor CLI options into a group with heading --- .../AbstractAnalysisPmdSubcommand.java | 200 ++++++++++-------- .../pmd/cli/commands/internal/CpdCommand.java | 35 ++- .../pmd/cli/commands/internal/PmdCommand.java | 12 ++ 3 files changed, 147 insertions(+), 100 deletions(-) diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java index ed1fb5537fc..fd256b186a6 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java @@ -20,51 +20,114 @@ import net.sourceforge.pmd.cli.internal.PmdRootLogger; import net.sourceforge.pmd.util.log.internal.SimpleMessageReporter; +import picocli.CommandLine; import picocli.CommandLine.Mixin; +import picocli.CommandLine.Model.CommandSpec; import picocli.CommandLine.Option; import picocli.CommandLine.ParameterException; import picocli.CommandLine.Parameters; public abstract class AbstractAnalysisPmdSubcommand extends AbstractPmdSubcommand { - @Mixin - private EncodingMixin encoding; + @CommandLine.Spec + protected CommandSpec spec; // injected by PicoCli, needed for validations + + protected static final String FILE_COLLECTION_OPTION_HEADER = "File collection options"; + - // see the setters #setInputPaths and setPositionalInputPaths for @Option and @Parameters annotations - // Note: can't use annotations on the fields here, as otherwise the complete list would be replaced - // rather than accumulated. - private Set inputPaths; + protected static class FileCollectionOptions { + @Option(names = "--file-list", + description = + "Path to a file containing a list of files to analyze, one path per line. " + + "One of --dir, --file-list or --uri must be provided.") + private Path fileListPath; + @Option(names = {"--uri", "-u"}, + description = "Database URI for sources. " + + "One of --dir, --file-list or --uri must be provided.") + private URI uri; - @Option(names = "--file-list", - description = - "Path to a file containing a list of files to analyze, one path per line. " - + "One of --dir, --file-list or --uri must be provided.") - private Path fileListPath; - - @Option(names = { "--uri", "-u" }, - description = "Database URI for sources. " - + "One of --dir, --file-list or --uri must be provided.") - private URI uri; + private List excludes = new ArrayList<>(); - private List excludes = new ArrayList<>(); - @Option(names = "--ignore", arity = "1..*", description = "Files to be excluded from the analysis") - protected void setIgnoreSpecificPaths(List rootPaths) { - if (rootPaths != null) { - this.excludes = rootPaths; - } else { - this.excludes = new ArrayList<>(); + @Option(names = "--ignore", arity = "1..*", description = "Files to be excluded from the analysis") + protected void setIgnoreSpecificPaths(List rootPaths) { + if (rootPaths != null) { + this.excludes = rootPaths; + } else { + this.excludes = new ArrayList<>(); + } } - } - @Option(names = "--ignore-list", - description = "Path to a file containing a list of files to exclude from the analysis, one path per line. " - + "This option can be combined with --dir, --file-list and --uri.") - private Path ignoreListPath; + @Option(names = "--ignore-list", + description = "Path to a file containing a list of files to exclude from the analysis, one path per line. " + + "This option can be combined with --dir, --file-list and --uri.") + private Path ignoreListPath; + + + @Option(names = {"--relativize-paths-with", "-z"}, description = "Path relative to which directories are rendered in the report. " + + "This option allows shortening directories in the report; " + + "without it, paths are rendered as mentioned in the source directory (option \"--dir\"). " + + "The option can be repeated, in which case the shortest relative path will be used. " + + "If the root path is mentioned (e.g. \"/\" or \"C:\\\"), then the paths will be rendered as absolute.", + arity = "1..*", split = ",") + private List relativizeRootPaths; + + // see the setters #setInputPaths and setPositionalInputPaths for @Option and @Parameters annotations + // Note: can't use annotations on the fields here, as otherwise the complete list would be replaced + // rather than accumulated. + private Set inputPaths; + + @Option(names = {"--dir", "-d"}, + description = "Path to a source file, or directory containing source files to analyze. " + + "Zip and Jar files are also supported, if they are specified directly " + + "(archive files found while exploring a directory are not recursively expanded). " + + "This option can be repeated, and multiple arguments can be provided to a single occurrence of the option. " + + "One of --dir, --file-list or --uri must be provided.", + arity = "1..*", split = ",") + protected void setInputPaths(final List inputPaths) { + if (this.inputPaths == null) { + this.inputPaths = new LinkedHashSet<>(); // linked hashSet in order to maintain order + } + + this.inputPaths.addAll(inputPaths); + } + + @Option(names = "--non-recursive", description = "Don't scan subdirectiories when using the --d (-dir) option.") + private boolean nonRecursive; + + + @Parameters(arity = "*", description = "Path to a source file, or directory containing source files to analyze. " + + "Equivalent to using --dir.") + protected void setPositionalInputPaths(final List inputPaths) { + this.setInputPaths(inputPaths); + } + protected void validate(CommandSpec spec) throws ParameterException { + + if ((inputPaths == null || inputPaths.isEmpty()) && uri == null && fileListPath == null) { + throw new ParameterException(spec.commandLine(), + "Please provide a parameter for source root directory (--dir or -d), " + + "database URI (--uri or -u), or file list path (--file-list)"); + } + + if (relativizeRootPaths != null) { + for (Path path : this.relativizeRootPaths) { + if (Files.isRegularFile(path)) { + throw new ParameterException(spec.commandLine(), + "Expected a directory path for option '--relativize-paths-with', found a file: " + path); + } + } + } + } + + } + + @Mixin + private EncodingMixin encoding; + @Option(names = "--no-fail-on-violation", description = "By default PMD exits with status 4 if violations or duplications are found. " + "Disable this option with '--no-fail-on-violation' to exit with 0 instead. In any case a report with the found violations or duplications will be written.", @@ -84,59 +147,6 @@ protected void setIgnoreSpecificPaths(List rootPaths) { + "If this option is not specified, the report is rendered to standard output.") private Path reportFile; - private List relativizeRootPaths; - - @Option(names = { "--relativize-paths-with", "-z"}, description = "Path relative to which directories are rendered in the report. " - + "This option allows shortening directories in the report; " - + "without it, paths are rendered as mentioned in the source directory (option \"--dir\"). " - + "The option can be repeated, in which case the shortest relative path will be used. " - + "If the root path is mentioned (e.g. \"/\" or \"C:\\\"), then the paths will be rendered as absolute.", - arity = "1..*", split = ",") - protected void setRelativizePathsWith(List rootPaths) { - this.relativizeRootPaths = rootPaths; - - for (Path path : this.relativizeRootPaths) { - if (Files.isRegularFile(path)) { - throw new ParameterException(spec.commandLine(), - "Expected a directory path for option '--relativize-paths-with', found a file: " + path); - } - } - } - - @Option(names = { "--dir", "-d" }, - description = "Path to a source file, or directory containing source files to analyze. " - + "Zip and Jar files are also supported, if they are specified directly " - + "(archive files found while exploring a directory are not recursively expanded). " - + "This option can be repeated, and multiple arguments can be provided to a single occurrence of the option. " - + "One of --dir, --file-list or --uri must be provided.", - arity = "1..*", split = ",") - protected void setInputPaths(final List inputPaths) { - if (this.inputPaths == null) { - this.inputPaths = new LinkedHashSet<>(); // linked hashSet in order to maintain order - } - - this.inputPaths.addAll(inputPaths); - } - - @Option(names = "--non-recursive", description = "Don't scan subdirectiories when using the --d (-dir) option.") - private boolean nonRecursive; - - @Parameters(arity = "*", description = "Path to a source file, or directory containing source files to analyze. " - + "Equivalent to using --dir.") - protected void setPositionalInputPaths(final List inputPaths) { - this.setInputPaths(inputPaths); - } - - @Override - protected final void validate() throws ParameterException { - super.validate(); - - if ((inputPaths == null || inputPaths.isEmpty()) && uri == null && fileListPath == null) { - throw new ParameterException(spec.commandLine(), - "Please provide a parameter for source root directory (--dir or -d), " - + "database URI (--uri or -u), or file list path (--file-list)"); - } - } protected abstract C toConfiguration(); @@ -152,18 +162,28 @@ protected CliExitCode execute() { this::doExecute); } + protected abstract FileCollectionOptions getFileCollectionOptions(); + + @Override + protected void validate() throws ParameterException { + super.validate(); + getFileCollectionOptions().validate(spec); + } + protected final void setCommonConfigProperties(C configuration) { + FileCollectionOptions files = getFileCollectionOptions(); + // Configure input paths - if (inputPaths != null) { - configuration.setInputPathList(new ArrayList<>(inputPaths)); + if (files.inputPaths != null) { + configuration.setInputPathList(new ArrayList<>(files.inputPaths)); } - configuration.setExcludes(excludes); - configuration.collectFilesRecursively(!nonRecursive); - configuration.setInputFilePath(fileListPath); - configuration.setIgnoreFilePath(ignoreListPath); - configuration.setInputUri(uri); - if (relativizeRootPaths != null) { - configuration.addRelativizeRoots(relativizeRootPaths); + configuration.setExcludes(files.excludes); + configuration.collectFilesRecursively(!files.nonRecursive); + configuration.setInputFilePath(files.fileListPath); + configuration.setIgnoreFilePath(files.ignoreListPath); + configuration.setInputUri(files.uri); + if (files.relativizeRootPaths != null) { + configuration.addRelativizeRoots(files.relativizeRootPaths); } configuration.setSourceEncoding(encoding.getEncoding()); diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java index d8538c27373..13393c54238 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java @@ -21,6 +21,7 @@ import net.sourceforge.pmd.lang.Language; import net.sourceforge.pmd.util.StringUtil; +import picocli.CommandLine; import picocli.CommandLine.Command; import picocli.CommandLine.Option; import picocli.CommandLine.ParameterException; @@ -29,6 +30,23 @@ description = "Copy/Paste Detector - find duplicate code") public class CpdCommand extends AbstractAnalysisPmdSubcommand { + + @CommandLine.ArgGroup(heading = FILE_COLLECTION_OPTION_HEADER, exclusive = false) + CpdFileCollectionOptions files = new CpdFileCollectionOptions(); + + static class CpdFileCollectionOptions extends FileCollectionOptions { + private boolean usedDeprecatedExcludeName = false; + + // this option name is deprecated + @Option(names = "--exclude", arity = "1..*", description = "Files to be excluded from the analysis") + @Override + protected void setIgnoreSpecificPaths(List rootPaths) { + super.setIgnoreSpecificPaths(rootPaths); + this.usedDeprecatedExcludeName = true; + } + + } + @Option(names = { "--language", "-l" }, description = "The source code language.%nValid values: ${COMPLETION-CANDIDATES}", defaultValue = CPDConfiguration.DEFAULT_LANGUAGE, converter = CpdLanguageTypeSupport.class, completionCandidates = CpdLanguageTypeSupport.class) private Language language; @@ -41,16 +59,8 @@ public class CpdCommand extends AbstractAnalysisPmdSubcommand description = "Ignore multiple copies of files of the same name and length in comparison.") private boolean skipDuplicates; - private boolean usedDeprecatedExcludeName = false; - // this option name is deprecated - @Option(names = "--exclude", - description = "Files to be excluded from the analysis") - @Override - protected void setIgnoreSpecificPaths(List rootPaths) { - super.setIgnoreSpecificPaths(rootPaths); - this.usedDeprecatedExcludeName = true; - } + @Option(names = { "--format", "-f" }, description = "Report format.%nValid values: ${COMPLETION-CANDIDATES}%n" @@ -95,6 +105,11 @@ protected void setIgnoreSpecificPaths(List rootPaths) { defaultValue = CpdLanguagePropertiesDefaults.DEFAULT_SKIP_BLOCKS_PATTERN) private String skipBlocksPattern; + @Override + protected FileCollectionOptions getFileCollectionOptions() { + return files; + } + /** * Converts these parameters into a configuration. * @@ -124,7 +139,7 @@ protected CPDConfiguration toConfiguration() { configuration.setFailOnError(false); } - if (usedDeprecatedExcludeName) { + if (files.usedDeprecatedExcludeName) { configuration.getReporter().warn("Option name --exclude is deprecated. Use --ignore instead."); } diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java index 8587f1d7976..80006d5df16 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java @@ -41,6 +41,7 @@ import net.sourceforge.pmd.util.log.PmdReporter; import net.sourceforge.pmd.util.log.internal.SimpleMessageReporter; +import picocli.CommandLine; import picocli.CommandLine.Command; import picocli.CommandLine.Option; import picocli.CommandLine.ParameterException; @@ -105,6 +106,10 @@ public class PmdCommand extends AbstractAnalysisPmdSubcommand private boolean showProgressBar; + + @CommandLine.ArgGroup(heading = FILE_COLLECTION_OPTION_HEADER, exclusive = false) + FileCollectionOptions files = new FileCollectionOptions(); + @Option(names = { "--rulesets", "-R" }, description = "Path to a ruleset xml file. " + "The path may reference a resource on the classpath of the application, be a local file system path, or a URL. " @@ -224,6 +229,12 @@ public void setShowProgressBar(final boolean showProgressBar) { this.showProgressBar = showProgressBar; } + + @Override + protected FileCollectionOptions getFileCollectionOptions() { + return files; + } + /** * Converts these parameters into a configuration. * @@ -244,6 +255,7 @@ protected PMDConfiguration toConfiguration() { configuration.setSuppressMarker(suppressMarker); configuration.setAnalysisCacheLocation(cacheLocation != null ? cacheLocation.toString() : null); configuration.setIgnoreIncrementalAnalysis(noCache); + configuration.setThreads(threads); if (languageVersion != null) { configuration.setDefaultLanguageVersions(languageVersion); From 8b0433f30ff674cbec9284fecdd0d82eaf3a849a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 11 May 2025 14:43:44 +0200 Subject: [PATCH 0903/1962] Cleanup logic and documentation --- docs/pages/pmd/userdocs/cli_reference.md | 116 ++++++++++-------- docs/pages/pmd/userdocs/cpd/cpd.md | 50 +------- .../AbstractAnalysisPmdSubcommand.java | 54 ++++---- .../pmd/cli/commands/internal/CpdCommand.java | 4 +- .../pmd/cli/commands/internal/PmdCommand.java | 4 +- 5 files changed, 100 insertions(+), 128 deletions(-) diff --git a/docs/pages/pmd/userdocs/cli_reference.md b/docs/pages/pmd/userdocs/cli_reference.md index 963d9bfa6ad..9cddd903612 100644 --- a/docs/pages/pmd/userdocs/cli_reference.md +++ b/docs/pages/pmd/userdocs/cli_reference.md @@ -30,17 +30,6 @@ The tool comes with a rather extensive help text, simply running with `--help`! of the option." required="yes" %} - {% include custom/cli_option_row.html options="--dir,-d" - option_arg="path" - description="Path to a source file, or directory containing - source files to analyze. Zip and Jar files are - also supported, if they are specified directly - (archive files found while exploring a directory - are not recursively expanded). This option can be - repeated, and multiple arguments can be provided - to a single occurrence of the option. One of - `--dir`, `--file-list` or `--uri` must be provided." - %} {% include custom/cli_option_row.html options="--format,-f" option_arg="format" description="Output format of the analysis report. The available formats @@ -73,19 +62,6 @@ The tool comes with a rather extensive help text, simply running with `--help`! {% include custom/cli_option_row.html options="--debug,--verbose,-D,-v" description="Debug mode. Prints more log output. See also [Logging](#logging)." %} - {% include custom/cli_option_row.html options="--encoding,-e" - option_arg="charset" - description="Specifies the character set encoding of the source code files PMD is reading. - The valid values are the standard character sets of `java.nio.charset.Charset`." - default="UTF-8" - %} - {% include custom/cli_option_row.html options="--exclude" - option_arg="path+" - description="Files to be excluded from the analysis. This takes one or more path names as an argument. It is combinable with --exclude-file." - %} - {% include custom/cli_option_row.html options="--non-recursive" - description="Don't scan subdirectories. By default, subdirectories are considered." - %} {% include custom/cli_option_row.html options="--[no-]fail-on-error" description="Specifies whether PMD exits with non-zero status if recoverable errors occurred. By default PMD exits with status 5 if recoverable errors occurred (whether there are violations or not). @@ -96,12 +72,6 @@ The tool comes with a rather extensive help text, simply running with `--help`! By default PMD exits with status 4 if violations are found. Disable this feature with `--no-fail-on-violation` to exit with 0 instead. In any case a report with the found violations will be written." %} - {% include custom/cli_option_row.html options="--file-list" - option_arg="filepath" - description="Path to a file containing a list of files to - analyze, one path per line. One of `--dir`, - `--file-list` or `--uri` must be provided." - %} {% include custom/cli_option_row.html options="--force-language" option_arg="lang" description="Force a language to be used for all input files, irrespective of @@ -113,18 +83,6 @@ The tool comes with a rather extensive help text, simply running with `--help`!

    This option allows to use the xml language for files, that don't use xml as extension. See [example](#analyze-other-xml-formats) below.

    " %} - {% include custom/cli_option_row.html options="--ignore" - option_arg="filepath+" - description="Specify one or more paths to files that will be ignored. - This option overrides files included by any of `--dir`, `--file-list` and `--uri`. - It can combine with `--ignore-list`." - %} - {% include custom/cli_option_row.html options="--ignore-list" - option_arg="filepath" - description="Path to file containing a list of files to ignore, one path per line. - This option overrides files included by any of `--dir`, `--file-list` and `--uri`. - It can combine with `--ignore`" - %} {% include custom/cli_option_row.html options="--help,-h" description="Display help on usage." %} @@ -156,22 +114,11 @@ The tool comes with a rather extensive help text, simply running with `--help`! {% include custom/cli_option_row.html options="--[no-]progress" description="Enables / disable progress bar indicator of live analysis progress. This ie enabled by default." %} - {% include custom/cli_option_row.html options="--non-recursive" - description="When specified, any directory mentioned with `--dir` or in the `--file-list` will only be searched for files that are direct children. - By default, subdirectories are recursively included." - %} {% include custom/cli_option_row.html options="--property,-P" option_arg="name>=<value" description="Specifies a property for the report renderer. The option can be specified several times.

    Using `--help` will provide a complete list of supported properties for each report format

    " %} - {% include custom/cli_option_row.html options="--relativize-paths-with,-z" - option_arg="path" - description="Path relative to which directories are rendered in the report. This option allows - shortening directories in the report; without it, paths are rendered as mentioned in the source directory (option \"--dir\"). - The option can be repeated, in which case the shortest relative path will be used. - If the root path is mentioned (e.g. \"/\" or \"C:\\\"), then the paths will be rendered as absolute." - %} {% include custom/cli_option_row.html options="--report-file,-r" option_arg="path" description="Path to a file to which report output is written. The file is created if it does not exist. If this option is not specified, the report is rendered to standard output." @@ -190,13 +137,76 @@ The tool comes with a rather extensive help text, simply running with `--help`! Set threads to `0` to disable multi-threading processing." default="1" %} + + +### File collection options + +PMD and CPD use the same set of options to specify the files that are to be +processed by the analyzer. There are different ways to specify files, but at +least one of `--dir`, `--file-list` or `--uri` must be provided. + + + + + + + + + {% include custom/cli_option_row.html options="--dir,-d" + option_arg="path" + description="Path to a source file, or directory containing + source files to analyze. Zip and Jar files are + also supported, if they are specified directly + (archive files found while exploring a directory + are not recursively expanded). This option can be + repeated, and multiple arguments can be provided + to a single occurrence of the option. One of + `--dir`, `--file-list` or `--uri` must be provided." + %} + {% include custom/cli_option_row.html options="--file-list" + option_arg="filepath" + description="Path to a file containing a list of files to + analyze, one path per line. One of `--dir`, + `--file-list` or `--uri` must be provided." + %} + {% include custom/cli_option_row.html options="--ignore" + option_arg="filepath+" + description="Specify one or more paths to files that will be ignored. + This option overrides files included by any of `--dir`, `--file-list` and `--uri`. + It can combine with `--ignore-list`." + %} + {% include custom/cli_option_row.html options="--ignore-list" + option_arg="filepath" + description="Path to file containing a list of files to ignore, one path per line. + This option overrides files included by any of `--dir`, `--file-list` and `--uri`. + It can combine with `--ignore`" + %} + {% include custom/cli_option_row.html options="--non-recursive" + description="When specified, any directory mentioned with `--dir` or in the `--file-list` will only be searched for files that are direct children. + By default, subdirectories are recursively included." + %} + {% include custom/cli_option_row.html options="--relativize-paths-with,-z" + option_arg="path" + description="Path relative to which directories are rendered in the report. This option allows + shortening directories in the report; without it, paths are rendered as mentioned in the source directory (option \"--dir\"). + The option can be repeated, in which case the shortest relative path will be used. + If the root path is mentioned (e.g. \"/\" or \"C:\\\"), then the paths will be rendered as absolute." + %} {% include custom/cli_option_row.html options="--uri,-u" option_arg="uri" description="Database URI for sources. One of `--dir`, `--file-list` or `--uri` must be provided." languages="PLSQL" %} + {% include custom/cli_option_row.html options="--encoding,-e" + option_arg="charset" + description="Specifies the character set encoding of the source code files the tool is reading. + The valid values are the standard character sets of `java.nio.charset.Charset`." + default="UTF-8" + %}
    OptionDescriptionDefault valueApplies to
    + + ## Additional Java Runtime Options PMD is executed via a Java runtime. In some cases, you might need to set additional runtime options, e.g. diff --git a/docs/pages/pmd/userdocs/cpd/cpd.md b/docs/pages/pmd/userdocs/cpd/cpd.md index 410e3be413b..7818ac1490f 100644 --- a/docs/pages/pmd/userdocs/cpd/cpd.md +++ b/docs/pages/pmd/userdocs/cpd/cpd.md @@ -75,6 +75,10 @@ exactly identical. ### CLI options reference +{% include callout.html + type="primary" + content="The file collection options are common to PMD and CPD and [described over there](pmd_userdocs_cli_reference.html#file-collection-options)." %} + @@ -87,24 +91,6 @@ exactly identical. description="The minimum token length which should be reported as a duplicate." required="yes" %} - {% include custom/cli_option_row.html options="--dir,-d" - option_arg="path" - description="Path to a source file, or directory containing - source files to analyze. Zip and Jar files are - also supported, if they are specified directly - (archive files found while exploring a directory - are not recursively expanded). This option can - be repeated, and multiple arguments can be - provided to a single occurrence of the option. - One of `--dir`, `--file-list` or `--uri` must be - provided." - %} - {% include custom/cli_option_row.html options="--file-list" - option_arg="filepath" - description="Path to a file containing a list of files to - analyze, one path per line. One of `--dir`, - `--file-list` or `--uri` must be provided." - %} {% include custom/cli_option_row.html options="--language,-l" option_arg="lang" description="The source code language. @@ -115,22 +101,9 @@ exactly identical. {% include custom/cli_option_row.html options="--debug,--verbose,-D,-v" description="Debug mode. Prints more log output. See also [Logging](#logging)." %} - {% include custom/cli_option_row.html options="--encoding,-e" - option_arg="charset" - description="Specifies the character set encoding of the source code files PMD is reading. - The valid values are the standard character sets of `java.nio.charset.Charset`." - default="UTF-8" - %} {% include custom/cli_option_row.html options="--skip-duplicate-files" description="Ignore multiple copies of files of the same name and length in comparison." %} - {% include custom/cli_option_row.html options="--exclude" - option_arg="path" - description="Files to be excluded from the analysis" - %} - {% include custom/cli_option_row.html options="--non-recursive" - description="Don't scan subdirectories. By default, subdirectories are considered." - %} {% include custom/cli_option_row.html options="--skip-lexical-errors" description="Deprecated Skip files which can't be tokenized due to invalid characters instead of aborting CPD. By default, CPD analysis is stopped on the first error. This is deprecated. Use `--fail-on-error` instead." @@ -141,15 +114,6 @@ exactly identical. are described [here](#available-report-formats)." default="text" %} - {% include custom/cli_option_row.html options="--relativize-paths-with,-z" - option_arg="path" - description="Path relative to which directories are rendered in the report. This option allows - shortening directories in the report; without it, paths are rendered as mentioned in the - source directory (option \"--dir\"). - The option can be repeated, in which case the shortest relative path will be used. - If the root path is mentioned (e.g. \"/\" or \"C:\\\"), then the paths will be rendered - as absolute." - %} {% include custom/cli_option_row.html options="--[no-]fail-on-error" description="Specifies whether CPD exits with non-zero status if recoverable errors occurred. By default CPD exits with status 5 if recoverable errors occurred (whether there are duplications or not). @@ -200,12 +164,6 @@ exactly identical. default="#if 0|#endif" languages="C++" %} - {% include custom/cli_option_row.html options="--uri,-u" - option_arg="uri" - description="Database URI for sources. One of `--dir`, - `--file-list` or `--uri` must be provided." - languages="PLSQL" - %} {% include custom/cli_option_row.html options="--help,-h" description="Print help text" %} diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java index fd256b186a6..daf9a3ecc20 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java @@ -5,6 +5,7 @@ package net.sourceforge.pmd.cli.commands.internal; import java.net.URI; +import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; @@ -15,13 +16,11 @@ import org.slf4j.LoggerFactory; import net.sourceforge.pmd.AbstractConfiguration; -import net.sourceforge.pmd.cli.commands.mixins.internal.EncodingMixin; import net.sourceforge.pmd.cli.internal.CliExitCode; import net.sourceforge.pmd.cli.internal.PmdRootLogger; import net.sourceforge.pmd.util.log.internal.SimpleMessageReporter; import picocli.CommandLine; -import picocli.CommandLine.Mixin; import picocli.CommandLine.Model.CommandSpec; import picocli.CommandLine.Option; import picocli.CommandLine.ParameterException; @@ -35,7 +34,12 @@ public abstract class AbstractAnalysisPmdSubcommand { + + @Option(names = {"--encoding", "-e"}, description = "Specifies the character set encoding of the source code files", + defaultValue = "UTF-8") + private Charset encoding; + @Option(names = "--file-list", description = @@ -49,14 +53,14 @@ protected static class FileCollectionOptions { private URI uri; - private List excludes = new ArrayList<>(); + private List ignoreFiles = new ArrayList<>(); @Option(names = "--ignore", arity = "1..*", description = "Files to be excluded from the analysis") protected void setIgnoreSpecificPaths(List rootPaths) { if (rootPaths != null) { - this.excludes = rootPaths; + this.ignoreFiles = rootPaths; } else { - this.excludes = new ArrayList<>(); + this.ignoreFiles = new ArrayList<>(); } } @@ -105,6 +109,23 @@ protected void setPositionalInputPaths(final List inputPaths) { } + protected void configureFilesToAnalyze(C configuration) { + // Configure input paths + if (inputPaths != null) { + configuration.setInputPathList(new ArrayList<>(inputPaths)); + } + configuration.setExcludes(ignoreFiles); + configuration.collectFilesRecursively(!nonRecursive); + configuration.setInputFilePath(fileListPath); + configuration.setIgnoreFilePath(ignoreListPath); + configuration.setInputUri(uri); + if (relativizeRootPaths != null) { + configuration.addRelativizeRoots(relativizeRootPaths); + } + configuration.setSourceEncoding(encoding); + } + + protected void validate(CommandSpec spec) throws ParameterException { if ((inputPaths == null || inputPaths.isEmpty()) && uri == null && fileListPath == null) { @@ -125,9 +146,6 @@ protected void validate(CommandSpec spec) throws ParameterException { } - @Mixin - private EncodingMixin encoding; - @Option(names = "--no-fail-on-violation", description = "By default PMD exits with status 4 if violations or duplications are found. " + "Disable this option with '--no-fail-on-violation' to exit with 0 instead. In any case a report with the found violations or duplications will be written.", @@ -162,7 +180,7 @@ protected CliExitCode execute() { this::doExecute); } - protected abstract FileCollectionOptions getFileCollectionOptions(); + protected abstract FileCollectionOptions getFileCollectionOptions(); @Override protected void validate() throws ParameterException { @@ -171,21 +189,7 @@ protected void validate() throws ParameterException { } protected final void setCommonConfigProperties(C configuration) { - FileCollectionOptions files = getFileCollectionOptions(); - - // Configure input paths - if (files.inputPaths != null) { - configuration.setInputPathList(new ArrayList<>(files.inputPaths)); - } - configuration.setExcludes(files.excludes); - configuration.collectFilesRecursively(!files.nonRecursive); - configuration.setInputFilePath(files.fileListPath); - configuration.setIgnoreFilePath(files.ignoreListPath); - configuration.setInputUri(files.uri); - if (files.relativizeRootPaths != null) { - configuration.addRelativizeRoots(files.relativizeRootPaths); - } - configuration.setSourceEncoding(encoding.getEncoding()); + getFileCollectionOptions().configureFilesToAnalyze(configuration); // reporting logic configuration.setReportFile(reportFile); diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java index 13393c54238..4419579ba95 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java @@ -34,7 +34,7 @@ public class CpdCommand extends AbstractAnalysisPmdSubcommand @CommandLine.ArgGroup(heading = FILE_COLLECTION_OPTION_HEADER, exclusive = false) CpdFileCollectionOptions files = new CpdFileCollectionOptions(); - static class CpdFileCollectionOptions extends FileCollectionOptions { + static class CpdFileCollectionOptions extends FileCollectionOptions { private boolean usedDeprecatedExcludeName = false; // this option name is deprecated @@ -106,7 +106,7 @@ protected void setIgnoreSpecificPaths(List rootPaths) { private String skipBlocksPattern; @Override - protected FileCollectionOptions getFileCollectionOptions() { + protected FileCollectionOptions getFileCollectionOptions() { return files; } diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java index 80006d5df16..aaf8d3aa1e1 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java @@ -108,7 +108,7 @@ public class PmdCommand extends AbstractAnalysisPmdSubcommand @CommandLine.ArgGroup(heading = FILE_COLLECTION_OPTION_HEADER, exclusive = false) - FileCollectionOptions files = new FileCollectionOptions(); + FileCollectionOptions files = new FileCollectionOptions<>(); @Option(names = { "--rulesets", "-R" }, description = "Path to a ruleset xml file. " @@ -231,7 +231,7 @@ public void setShowProgressBar(final boolean showProgressBar) { @Override - protected FileCollectionOptions getFileCollectionOptions() { + protected FileCollectionOptions getFileCollectionOptions() { return files; } From fa9a7b06e3acd16189a15fa3fb7dded342d113c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 12 May 2025 06:06:04 +0200 Subject: [PATCH 0904/1962] [cli] Replace --ignore[-list] with --exclude[-file-list] --- docs/pages/pmd/userdocs/cli_reference.md | 20 +++++++- .../AbstractAnalysisPmdSubcommand.java | 47 ++++++++++++++----- .../pmd/cli/commands/internal/CpdCommand.java | 20 +------- 3 files changed, 53 insertions(+), 34 deletions(-) diff --git a/docs/pages/pmd/userdocs/cli_reference.md b/docs/pages/pmd/userdocs/cli_reference.md index 9cddd903612..f154fafedd7 100644 --- a/docs/pages/pmd/userdocs/cli_reference.md +++ b/docs/pages/pmd/userdocs/cli_reference.md @@ -169,15 +169,31 @@ least one of `--dir`, `--file-list` or `--uri` must be provided. analyze, one path per line. One of `--dir`, `--file-list` or `--uri` must be provided." %} - {% include custom/cli_option_row.html options="--ignore" + {% include custom/cli_option_row.html options="--exclude" option_arg="filepath+" description="Specify one or more paths to files that will be ignored. This option overrides files included by any of `--dir`, `--file-list` and `--uri`. It can combine with `--ignore-list`." %} + {% include custom/cli_option_row.html options="--exclude-file-list" + option_arg="filepath" + description="Path to a file containing a list of files to ignore, one path per line. + This option overrides files included by any of `--dir`, `--file-list` and `--uri`. + It can combine with `--ignore`" + %} + {% include custom/cli_option_row.html options="--ignore" + option_arg="filepath+" + description="Deprecated (6.14.0) + This option has been renamed `--exclude`. + Specify one or more paths to files that will be ignored. + This option overrides files included by any of `--dir`, `--file-list` and `--uri`. + It can combine with `--ignore-list`." + %} {% include custom/cli_option_row.html options="--ignore-list" option_arg="filepath" - description="Path to file containing a list of files to ignore, one path per line. + description="Deprecated (6.14.0) + This option has been renamed `--exclude-file-list`. + Path to file containing a list of files to ignore, one path per line. This option overrides files included by any of `--dir`, `--file-list` and `--uri`. It can combine with `--ignore`" %} diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java index daf9a3ecc20..799ad819fc4 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java @@ -18,6 +18,7 @@ import net.sourceforge.pmd.AbstractConfiguration; import net.sourceforge.pmd.cli.internal.CliExitCode; import net.sourceforge.pmd.cli.internal.PmdRootLogger; +import net.sourceforge.pmd.util.CollectionUtil; import net.sourceforge.pmd.util.log.internal.SimpleMessageReporter; import picocli.CommandLine; @@ -31,7 +32,7 @@ public abstract class AbstractAnalysisPmdSubcommand { @@ -53,21 +54,32 @@ protected static class FileCollectionOptions { private URI uri; - private List ignoreFiles = new ArrayList<>(); + boolean usesDeprecatedIgnoreOption = false; + boolean usesDeprecatedIgnoreListOption = false; - @Option(names = "--ignore", arity = "1..*", description = "Files to be excluded from the analysis") + @Option(names = "--ignore", arity = "1..*", description = "(DEPRECATED: use --exclude) Files to be excluded from the analysis") + @Deprecated protected void setIgnoreSpecificPaths(List rootPaths) { - if (rootPaths != null) { - this.ignoreFiles = rootPaths; - } else { - this.ignoreFiles = new ArrayList<>(); - } + this.excludeFiles = CollectionUtil.makeUnmodifiableAndNonNull(rootPaths); + this.usesDeprecatedIgnoreOption = true; } @Option(names = "--ignore-list", + description = "(DEPRECATED: use --exclude-file-list) Path to a file containing a list of files to exclude from the analysis, one path per line. " + + "This option can be combined with --dir, --file-list and --uri.") + @Deprecated + protected void setExcludeFileList(Path path) { + this.excludeFileListPath = path; + this.usesDeprecatedIgnoreListOption = true; + } + + @Option(names = "--exclude", arity = "1..*", description = "Files to be excluded from the analysis") + private List excludeFiles = new ArrayList<>(); + + @Option(names = "--exclude-file-list", description = "Path to a file containing a list of files to exclude from the analysis, one path per line. " + "This option can be combined with --dir, --file-list and --uri.") - private Path ignoreListPath; + private Path excludeFileListPath; @Option(names = {"--relativize-paths-with", "-z"}, description = "Path relative to which directories are rendered in the report. " @@ -114,15 +126,22 @@ protected void configureFilesToAnalyze(C configuration) { if (inputPaths != null) { configuration.setInputPathList(new ArrayList<>(inputPaths)); } - configuration.setExcludes(ignoreFiles); + configuration.setExcludes(excludeFiles); configuration.collectFilesRecursively(!nonRecursive); configuration.setInputFilePath(fileListPath); - configuration.setIgnoreFilePath(ignoreListPath); + configuration.setIgnoreFilePath(excludeFileListPath); configuration.setInputUri(uri); if (relativizeRootPaths != null) { configuration.addRelativizeRoots(relativizeRootPaths); } configuration.setSourceEncoding(encoding); + + if (usesDeprecatedIgnoreOption) { + configuration.getReporter().warn("Option name --ignore is deprecated. Use --exclude instead."); + } + if (usesDeprecatedIgnoreListOption) { + configuration.getReporter().warn("Option name --ignore-list is deprecated. Use --exclude-file-list instead."); + } } @@ -189,6 +208,10 @@ protected void validate() throws ParameterException { } protected final void setCommonConfigProperties(C configuration) { + SimpleMessageReporter reporter = new SimpleMessageReporter(LoggerFactory.getLogger(PmdCommand.class)); + // Setup CLI message reporter + configuration.setReporter(reporter); + getFileCollectionOptions().configureFilesToAnalyze(configuration); // reporting logic @@ -197,8 +220,6 @@ protected final void setCommonConfigProperties(C configuration) { configuration.setFailOnViolation(failOnViolation); configuration.setFailOnError(failOnError); - // Setup CLI message reporter - configuration.setReporter(new SimpleMessageReporter(LoggerFactory.getLogger(PmdCommand.class))); } } diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java index 4419579ba95..91122673ee0 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java @@ -5,9 +5,7 @@ package net.sourceforge.pmd.cli.commands.internal; import java.io.IOException; -import java.nio.file.Path; import java.util.Iterator; -import java.util.List; import org.apache.commons.lang3.mutable.MutableBoolean; import org.checkerframework.checker.nullness.qual.NonNull; @@ -32,20 +30,7 @@ public class CpdCommand extends AbstractAnalysisPmdSubcommand @CommandLine.ArgGroup(heading = FILE_COLLECTION_OPTION_HEADER, exclusive = false) - CpdFileCollectionOptions files = new CpdFileCollectionOptions(); - - static class CpdFileCollectionOptions extends FileCollectionOptions { - private boolean usedDeprecatedExcludeName = false; - - // this option name is deprecated - @Option(names = "--exclude", arity = "1..*", description = "Files to be excluded from the analysis") - @Override - protected void setIgnoreSpecificPaths(List rootPaths) { - super.setIgnoreSpecificPaths(rootPaths); - this.usedDeprecatedExcludeName = true; - } - - } + FileCollectionOptions files = new FileCollectionOptions<>(); @Option(names = { "--language", "-l" }, description = "The source code language.%nValid values: ${COMPLETION-CANDIDATES}", defaultValue = CPDConfiguration.DEFAULT_LANGUAGE, converter = CpdLanguageTypeSupport.class, completionCandidates = CpdLanguageTypeSupport.class) @@ -139,9 +124,6 @@ protected CPDConfiguration toConfiguration() { configuration.setFailOnError(false); } - if (files.usedDeprecatedExcludeName) { - configuration.getReporter().warn("Option name --exclude is deprecated. Use --ignore instead."); - } return configuration; } From 563b3106fca13ea0342a174351f09e59bff4091c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 12 May 2025 06:20:31 +0200 Subject: [PATCH 0905/1962] Add CLI tests --- .../net/sourceforge/pmd/cli/CpdCliTest.java | 106 ++++++++++++++++++ .../pmd/cli/cpd/excludeFileList.txt | 1 + .../net/sourceforge/pmd/cli/cpd/fileList.txt | 2 + .../pmd/lang/document/FileCollector.java | 2 +- 4 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 pmd-cli/src/test/resources/net/sourceforge/pmd/cli/cpd/excludeFileList.txt create mode 100644 pmd-cli/src/test/resources/net/sourceforge/pmd/cli/cpd/fileList.txt diff --git a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/CpdCliTest.java b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/CpdCliTest.java index acbdc1db6f9..e73bc2d740d 100644 --- a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/CpdCliTest.java +++ b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/CpdCliTest.java @@ -9,6 +9,7 @@ import static net.sourceforge.pmd.cli.internal.CliExitCode.VIOLATIONS_FOUND; import static net.sourceforge.pmd.util.CollectionUtil.listOf; import static org.hamcrest.CoreMatchers.startsWith; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.emptyString; import static org.hamcrest.Matchers.not; @@ -29,6 +30,7 @@ import net.sourceforge.pmd.cli.internal.CliExitCode; import net.sourceforge.pmd.internal.Slf4jSimpleConfiguration; +import net.sourceforge.pmd.internal.util.IOUtil; import com.github.stefanbirkner.systemlambda.SystemLambda; @@ -227,6 +229,110 @@ void testEncodingOption() throws Exception { }); } + @Test + void testFileList() throws Exception { + runCli(VIOLATIONS_FOUND, + "--minimum-tokens", "10", + "--file-list", BASE_RES_PATH + "fileList.txt", + "--format", "text") + .verify(r -> { + r.checkStdErr(not(containsString("deprecated"))); + r.checkStdOut(containsString("Found a 5 line (13 tokens) duplication")); + }); + } + + @Test + void testExcludeFileList() throws Exception { + runCli(OK, + "--minimum-tokens", "10", + "--file-list", BASE_RES_PATH + "fileList.txt", + "--exclude-file-list", BASE_RES_PATH + "excludeFileList.txt", + "--format", "text", "--debug") + .verify(r -> { + r.checkStdErr(containsPattern("Adding regular file .*GoodFile.java")); + r.checkStdErr(containsPattern("Adding regular file .*GoodFile2.java")); + r.checkStdErr(containsPattern("Excluding file .*GoodFile2.java")); + r.checkStdErr(not(containsString("deprecated"))); + + r.checkStdOut(not(containsString("Found a 5 line (13 tokens) duplication"))); + }); + } + + @Test + void testExcludeFile() throws Exception { + runCli(OK, + "--minimum-tokens", "10", + "--file-list", BASE_RES_PATH + "fileList.txt", + "--exclude", BASE_RES_PATH + "badandgood/GoodFile.java", BASE_RES_PATH + "badandgood/GoodFile2.java", + "--format", "text", "--debug") + .verify(r -> { + r.checkStdErr(containsPattern("Adding regular file .*GoodFile.java")); + r.checkStdErr(containsPattern("Adding regular file .*GoodFile2.java")); + r.checkStdErr(containsPattern("Excluding file .*GoodFile.java")); + r.checkStdErr(containsPattern("Excluding file .*GoodFile2.java")); + r.checkStdErr(not(containsString("deprecated"))); + + r.checkStdOut(not(containsString("Found a 5 line (13 tokens) duplication"))); + }); + } + + @Test + void testExcludeFileListDeprecated() throws Exception { + runCli(OK, + "--minimum-tokens", "10", + "--file-list", BASE_RES_PATH + "fileList.txt", + "--ignore-list", BASE_RES_PATH + "excludeFileList.txt", + "--format", "text", "--debug") + .verify(r -> { + r.checkStdErr(containsPattern("Adding regular file .*GoodFile.java")); + r.checkStdErr(containsPattern("Adding regular file .*GoodFile2.java")); + r.checkStdErr(containsPattern("Excluding file .*GoodFile2.java")); + + r.checkStdErr(containsString("deprecated. Use --exclude-file-list")); + + r.checkStdOut(not(containsString("Found a 5 line (13 tokens) duplication"))); + }); + } + + @Test + void testExcludeFileDeprecated() throws Exception { + runCli(OK, + "--minimum-tokens", "10", + "--file-list", BASE_RES_PATH + "fileList.txt", + "--ignore", BASE_RES_PATH + "badandgood/GoodFile.java", BASE_RES_PATH + "badandgood/GoodFile2.java", + "--format", "text", "--debug") + .verify(r -> { + r.checkStdErr(containsPattern("Adding regular file .*GoodFile.java")); + r.checkStdErr(containsPattern("Adding regular file .*GoodFile2.java")); + r.checkStdErr(containsPattern("Excluding file .*GoodFile.java")); + r.checkStdErr(containsPattern("Excluding file .*GoodFile2.java")); + + r.checkStdErr(containsString("deprecated. Use --exclude")); + + r.checkStdOut(not(containsString("Found a 5 line (13 tokens) duplication"))); + }); + } + + + @Test + void testReportFile(@TempDir Path tmp) throws Exception { + Path reportFile = tmp.resolve("report.txt"); + runCli(VIOLATIONS_FOUND, + "--minimum-tokens", "10", + "--file-list", BASE_RES_PATH + "fileList.txt", + "--format", "text", "--debug", "-r", reportFile.toString()) + .verify(r -> { + r.checkStdErr(containsPattern("Adding regular file .*GoodFile.java")); + r.checkStdErr(containsPattern("Adding regular file .*GoodFile2.java")); + r.checkStdErr(not(containsString("Excluding file"))); + + r.checkStdOut(not(containsString("Found a 5 line (13 tokens) duplication"))); + + String report = IOUtil.readFileToString(reportFile.toFile()); + assertThat(report, containsString("Found a 5 line (13 tokens) duplication")); + }); + } + /** * See: https://sourceforge.net/p/pmd/bugs/1178/ */ diff --git a/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/cpd/excludeFileList.txt b/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/cpd/excludeFileList.txt new file mode 100644 index 00000000000..e1650dfdaa9 --- /dev/null +++ b/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/cpd/excludeFileList.txt @@ -0,0 +1 @@ +src/test/resources/net/sourceforge/pmd/cli/cpd/badandgood/GoodFile2.java diff --git a/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/cpd/fileList.txt b/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/cpd/fileList.txt new file mode 100644 index 00000000000..2ff9d7f44bb --- /dev/null +++ b/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/cpd/fileList.txt @@ -0,0 +1,2 @@ +src/test/resources/net/sourceforge/pmd/cli/cpd/badandgood/GoodFile.java +src/test/resources/net/sourceforge/pmd/cli/cpd/badandgood/GoodFile2.java diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java index ccd668156ac..86865c7ffc6 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java @@ -407,7 +407,7 @@ public void exclude(FileCollector excludeCollector) { for (Iterator iterator = allFilesToProcess.iterator(); iterator.hasNext();) { TextFile file = iterator.next(); if (toExclude.contains(file)) { - LOG.trace("Excluding file {}", file.getFileId()); + LOG.trace("Excluding file {}", file.getFileId().getAbsolutePath()); iterator.remove(); } } From 9119a20c7f0b9792e14f8a9728464d5babae05bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 12 May 2025 06:32:25 +0200 Subject: [PATCH 0906/1962] Add warning when no files are collected --- .../java/net/sourceforge/pmd/cli/PmdCliTest.java | 16 ++++++++++++++++ .../java/net/sourceforge/pmd/PmdAnalysis.java | 4 ++++ .../net/sourceforge/pmd/cpd/CpdAnalysis.java | 5 +++++ .../net/sourceforge/pmd/cpd/SourceManager.java | 4 ++++ 4 files changed, 29 insertions(+) diff --git a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java index fd77c97b42f..043e6538391 100644 --- a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java +++ b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java @@ -13,6 +13,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsStringIgnoringCase; +import static org.hamcrest.Matchers.emptyString; import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.not; @@ -145,6 +146,21 @@ void testFileCollectionWithUnknownFiles() throws Exception { assertThat(reportText, not(containsStringIgnoringCase("error"))); } + @Test + void testExcludeFile() throws Exception { + + // restoring system properties: --debug might change logging properties + SystemLambda.restoreSystemProperties(() -> { + runCli(OK, + "--dir", srcDir.toString(), "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "--ignore", srcDir.toString(), "--debug") + .verify(r -> { + r.checkStdErr(containsString("No files to analyze")); + r.checkStdOut(emptyString()); + }); + }); + } + + /** * This tests to create the report file in the current working directory. * diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PmdAnalysis.java b/pmd-core/src/main/java/net/sourceforge/pmd/PmdAnalysis.java index 0b48593d46e..985c5e233dc 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/PmdAnalysis.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PmdAnalysis.java @@ -384,6 +384,10 @@ void performAnalysisImpl(List extraListen } void performAnalysisImpl(List extraListeners, List textFiles) { + if (textFiles.isEmpty()) { + reporter.warn("No files to analyze. Check input paths and exclude parameters, use --debug to see file collection traces."); + } + RuleSets rulesets = new RuleSets(this.ruleSets); GlobalAnalysisListener listener; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java index 8ce548c8189..1d9faf23ce4 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java @@ -154,7 +154,12 @@ public void performAnalysis() { @SuppressWarnings("PMD.CloseResource") public void performAnalysis(Consumer consumer) { + try (SourceManager sourceManager = new SourceManager(files.getCollectedFiles())) { + if (sourceManager.isEmpty()) { + reporter.warn("No files to analyze. Check input paths and exclude parameters, use --debug to see file collection traces."); + } + Map tokenizers = sourceManager.getTextFiles().stream() .map(it -> it.getLanguageVersion().getLanguage()) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceManager.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceManager.java index 86630d7ae7a..c7c9d469faf 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceManager.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceManager.java @@ -43,6 +43,10 @@ List getTextFiles() { return textFiles; } + boolean isEmpty() { + return textFiles.isEmpty(); + } + private TextDocument load(TextFile file) { try { return TextDocument.create(file); From eabfd4d21f565c66ace94f240894ab67655f026f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 12 May 2025 15:31:12 +0200 Subject: [PATCH 0907/1962] Doc, support unused thing in java rule --- .../UnnecessaryPmdSuppressionRule.java | 7 +++++-- .../AbstractAnnotationSuppressor.java | 16 +++++++++++++++- .../internal/JavaAnnotationSuppressor.java | 19 +++++++++++++++++++ .../xml/UnnecessaryWarningSuppression.xml | 17 +++++++++++++++++ 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/UnnecessaryPmdSuppressionRule.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/UnnecessaryPmdSuppressionRule.java index da8abb81feb..b3da33a1976 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/UnnecessaryPmdSuppressionRule.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/UnnecessaryPmdSuppressionRule.java @@ -20,11 +20,14 @@ /** * A rule that reports unused suppression annotations and comments. + * This rule class supports any PMD language, but language-specific behavior + * needs to be implemented to avoid false positives for some languages. + * Violations of this rule cannot be suppressed. It is special cased + * by {@link RuleSets} to execute after all other rules, so that whether + * those produce warnings or not is known to this rule. */ @Experimental public class UnnecessaryPmdSuppressionRule extends AbstractRule { - // it is in this package because it uses privileged API of RuleContex - @Override public void apply(Node rootNode, RuleContext ctx) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/AbstractAnnotationSuppressor.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/AbstractAnnotationSuppressor.java index 9512979a792..9c32b4f0ea7 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/AbstractAnnotationSuppressor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/AbstractAnnotationSuppressor.java @@ -19,10 +19,12 @@ import net.sourceforge.pmd.lang.ast.NodeStream; import net.sourceforge.pmd.lang.ast.RootNode; import net.sourceforge.pmd.lang.rule.Rule; +import net.sourceforge.pmd.lang.rule.internal.UnnecessaryPmdSuppressionRule; import net.sourceforge.pmd.reporting.Report.SuppressedViolation; import net.sourceforge.pmd.util.AssertionUtil; import net.sourceforge.pmd.util.DataMap; import net.sourceforge.pmd.util.DataMap.SimpleDataKey; +import net.sourceforge.pmd.util.OptionalBool; public abstract class AbstractAnnotationSuppressor implements ViolationSuppressor { @@ -151,6 +153,18 @@ protected boolean annotationParamSuppresses(String stringVal, Rule rule) { return "PMD".equals(stringVal) || ("PMD." + rule.getName()).equals(stringVal) || "all".equals(stringVal); } + /** + * Return whether the annotation param may be suppressing warnings from other tools. + * If this returns NO, then the parameter may be marked as unused and reported by the + * rule {@link UnnecessaryPmdSuppressionRule}. + */ + protected OptionalBool isSuppressingNonPmdWarnings(String stringVal, A annotation) { + if (isPmdSuppressor(stringVal)) { + return OptionalBool.NO; + } + return OptionalBool.UNKNOWN; + } + /** Callbacks for a walk over an annotation. */ protected interface AnnotationWalkCallbacks { @@ -182,7 +196,7 @@ private Set getUnusedSuppressorNodes(A annotation) { if (suppressedAny) { entireAnnotationIsUnused.setFalse(); } else { - if (isPmdSuppressor(stringValue)) { + if (isSuppressingNonPmdWarnings(stringValue, annotation) == OptionalBool.NO) { unusedParts.add(makeAnnotationPartSuppressor(annotation, annotationParam, stringValue)); } else { entireAnnotationIsUnused.setFalse(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java index 75a61b36bb8..122328b6d2a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java @@ -16,12 +16,16 @@ import net.sourceforge.pmd.lang.java.ast.ASTAnnotation; import net.sourceforge.pmd.lang.java.ast.ASTMemberValue; import net.sourceforge.pmd.lang.java.ast.ASTMemberValuePair; +import net.sourceforge.pmd.lang.java.ast.ASTModifierList; +import net.sourceforge.pmd.lang.java.ast.ASTVariableId; import net.sourceforge.pmd.lang.java.ast.Annotatable; +import net.sourceforge.pmd.lang.java.ast.JavaNode; import net.sourceforge.pmd.lang.java.rule.errorprone.ImplicitSwitchFallThroughRule; import net.sourceforge.pmd.lang.java.types.TypeTestUtil; import net.sourceforge.pmd.lang.rule.Rule; import net.sourceforge.pmd.reporting.AbstractAnnotationSuppressor; import net.sourceforge.pmd.reporting.ViolationSuppressor; +import net.sourceforge.pmd.util.OptionalBool; /** * Helper methods to suppress violations based on annotations. @@ -86,4 +90,19 @@ protected boolean walkAnnotation(ASTAnnotation annotation, AnnotationWalkCallbac return false; } + JavaNode getAnnotationScope(ASTAnnotation a) { + if (a.getParent() instanceof ASTModifierList) return a.getParent().getParent(); + return null; + } + + @Override + protected OptionalBool isSuppressingNonPmdWarnings(String stringVal, ASTAnnotation annotation) { + if ("unused".equals(stringVal)) { + JavaNode scope = getAnnotationScope(annotation); + if (scope != null && scope.descendants(ASTVariableId.class).crossFindBoundaries().none(it -> it.getLocalUsages().isEmpty())) { + return OptionalBool.NO; + } + } + return super.isSuppressingNonPmdWarnings(stringVal, annotation); + } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnnecessaryWarningSuppression.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnnecessaryWarningSuppression.xml index 34968959aff..db819d18d7f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnnecessaryWarningSuppression.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnnecessaryWarningSuppression.xml @@ -264,4 +264,21 @@ } ]]> + + Suppresswarnings unused + 1 + 6 + + From 86c8c46fbd16a05dd6df14a2d3c0fe23e442d69e Mon Sep 17 00:00:00 2001 From: Thomas Prouvot Date: Tue, 13 May 2025 09:14:28 +0200 Subject: [PATCH 0908/1962] fix test --- docs/pages/pmd/languages/css.md | 7 ++ pmd-css/pom.xml | 2 +- .../pmd/lang/css/ast/{css.g4 => CssLexer.g4} | 2 +- .../pmd/lang/css/CssLanguageModule.java | 2 +- .../pmd/lang/css/cpd/CssCpdLexer.java | 14 ++-- .../pmd/lang/css/cpd/package-info.java | 8 +++ .../pmd/lang/css/cpd/CssCpdLexerTest.java | 13 ++-- .../pmd/lang/css/cpd/testdata/literals.txt | 66 +++++++++++++++++++ pmd-languages-deps/pom.xml | 5 ++ 9 files changed, 98 insertions(+), 21 deletions(-) create mode 100644 docs/pages/pmd/languages/css.md rename pmd-css/src/main/antlr4/net/sourceforge/pmd/lang/css/ast/{css.g4 => CssLexer.g4} (99%) create mode 100644 pmd-css/src/main/java/net/sourceforge/pmd/lang/css/cpd/package-info.java create mode 100644 pmd-css/src/test/resources/net/sourceforge/pmd/lang/css/cpd/testdata/literals.txt diff --git a/docs/pages/pmd/languages/css.md b/docs/pages/pmd/languages/css.md new file mode 100644 index 00000000000..7c498e6c70f --- /dev/null +++ b/docs/pages/pmd/languages/css.md @@ -0,0 +1,7 @@ +--- +title: CSS support +permalink: pmd_languages_css.html +last_updated: May 2025 (7.14.0) +tags: [languages, CpdCapableLanguage] +summary: "CSS-specific features and guidance" +--- \ No newline at end of file diff --git a/pmd-css/pom.xml b/pmd-css/pom.xml index 221661a6c04..ed9daa1235d 100644 --- a/pmd-css/pom.xml +++ b/pmd-css/pom.xml @@ -30,7 +30,7 @@ - + diff --git a/pmd-css/src/main/antlr4/net/sourceforge/pmd/lang/css/ast/css.g4 b/pmd-css/src/main/antlr4/net/sourceforge/pmd/lang/css/ast/CssLexer.g4 similarity index 99% rename from pmd-css/src/main/antlr4/net/sourceforge/pmd/lang/css/ast/css.g4 rename to pmd-css/src/main/antlr4/net/sourceforge/pmd/lang/css/ast/CssLexer.g4 index 0494a4fe260..c6ec193f0cf 100644 --- a/pmd-css/src/main/antlr4/net/sourceforge/pmd/lang/css/ast/css.g4 +++ b/pmd-css/src/main/antlr4/net/sourceforge/pmd/lang/css/ast/CssLexer.g4 @@ -2,7 +2,7 @@ // $antlr-format allowShortRulesOnASingleLine true, allowShortBlocksOnASingleLine true, minEmptyLines 0, alignSemicolons ownLine // $antlr-format alignColons trailing, singleLineOverrulesHangingColon true, alignLexerCommands true, alignLabels true, alignTrailers true -lexer grammar CSS; +lexer grammar CssLexer; channels { ERROR diff --git a/pmd-css/src/main/java/net/sourceforge/pmd/lang/css/CssLanguageModule.java b/pmd-css/src/main/java/net/sourceforge/pmd/lang/css/CssLanguageModule.java index d2118f5485c..bf6cc160490 100644 --- a/pmd-css/src/main/java/net/sourceforge/pmd/lang/css/CssLanguageModule.java +++ b/pmd-css/src/main/java/net/sourceforge/pmd/lang/css/CssLanguageModule.java @@ -14,7 +14,7 @@ public class CssLanguageModule extends CpdOnlyLanguageModuleBase { private static final String ID = "css"; public CssLanguageModule() { - super(LanguageMetadata.withId(ID).name("CSS").extensions("css")); + super(LanguageMetadata.withId(ID).name("Css").extensions("css")); } public static CssLanguageModule getInstance() { diff --git a/pmd-css/src/main/java/net/sourceforge/pmd/lang/css/cpd/CssCpdLexer.java b/pmd-css/src/main/java/net/sourceforge/pmd/lang/css/cpd/CssCpdLexer.java index faccfa97083..697f43db34f 100644 --- a/pmd-css/src/main/java/net/sourceforge/pmd/lang/css/cpd/CssCpdLexer.java +++ b/pmd-css/src/main/java/net/sourceforge/pmd/lang/css/cpd/CssCpdLexer.java @@ -4,15 +4,15 @@ package net.sourceforge.pmd.lang.css.cpd; -import net.sourceforge.pmd.cpd.impl.AntlrCpdLexer; -import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrToken; -import net.sourceforge.pmd.lang.css.ast.CssLexer; - import java.util.Locale; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.Lexer; +import net.sourceforge.pmd.cpd.impl.AntlrCpdLexer; +import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrToken; +import net.sourceforge.pmd.lang.css.ast.CssLexer; + public class CssCpdLexer extends AntlrCpdLexer { @Override @@ -22,11 +22,7 @@ protected Lexer getLexerForSource(CharStream charStream) { @Override protected String getImage(AntlrToken token) { - if (token.getKind() == CssLexer.STRING) { - // This path is for case-sensitive tokens - return token.getImage(); - } // normalize case-insensitive tokens return token.getImage().toUpperCase(Locale.ROOT); } -} \ No newline at end of file +} diff --git a/pmd-css/src/main/java/net/sourceforge/pmd/lang/css/cpd/package-info.java b/pmd-css/src/main/java/net/sourceforge/pmd/lang/css/cpd/package-info.java new file mode 100644 index 00000000000..cdd81adf60b --- /dev/null +++ b/pmd-css/src/main/java/net/sourceforge/pmd/lang/css/cpd/package-info.java @@ -0,0 +1,8 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +/** + * Contains Css tokenizer and language classes. + */ +package net.sourceforge.pmd.lang.css.cpd; diff --git a/pmd-css/src/test/java/net/sourceforge/pmd/lang/css/cpd/CssCpdLexerTest.java b/pmd-css/src/test/java/net/sourceforge/pmd/lang/css/cpd/CssCpdLexerTest.java index b8e768343d9..4e3767fc398 100644 --- a/pmd-css/src/test/java/net/sourceforge/pmd/lang/css/cpd/CssCpdLexerTest.java +++ b/pmd-css/src/test/java/net/sourceforge/pmd/lang/css/cpd/CssCpdLexerTest.java @@ -6,22 +6,17 @@ import org.junit.jupiter.api.Test; +import net.sourceforge.pmd.lang.css.CssLanguageModule; import net.sourceforge.pmd.lang.test.cpd.CpdTextComparisonTest; class CssCpdLexerTest extends CpdTextComparisonTest { - public CssCpdLexerTest() { - super("css", ".css"); - } - - @Override - protected String getResourcePrefix() { - return "testdata"; + CssCpdLexerTest() { + super(CssLanguageModule.getInstance(), ".css"); } @Test - public void testLiterals() { + void testLiterals() { doTest("literals"); } - } diff --git a/pmd-css/src/test/resources/net/sourceforge/pmd/lang/css/cpd/testdata/literals.txt b/pmd-css/src/test/resources/net/sourceforge/pmd/lang/css/cpd/testdata/literals.txt new file mode 100644 index 00000000000..ea9abad9c53 --- /dev/null +++ b/pmd-css/src/test/resources/net/sourceforge/pmd/lang/css/cpd/testdata/literals.txt @@ -0,0 +1,66 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [/* ALL ELEMENTS WITH CLASS="SPACIO[ 1 41 + [\n] 41 42 +L2 + [.] 1 2 + [SPACIOUS] 2 10 + [ ] 10 11 + [{] 11 12 + [\n ] 12 3 +L3 + [MARGIN] 3 9 + [:] 9 10 + [ ] 10 11 + [2EM] 11 14 + [;] 14 15 + [\n] 15 16 +L4 + [}] 1 2 + [\n\n] 2 2 +L6 + [/* ALL
  • ELEMENTS WITH CLASS="S[ 1 46 + [\n] 46 47 +L7 + [LI] 1 3 + [.] 3 4 + [SPACIOUS] 4 12 + [ ] 12 13 + [{] 13 14 + [\n ] 14 3 +L8 + [MARGIN] 3 9 + [:] 9 10 + [ ] 10 11 + [2EM] 11 14 + [;] 14 15 + [\n] 15 16 +L9 + [}] 1 2 + [\n\n] 2 2 +L11 + [/* ALL
  • ELEMENTS WITH A CLASS [ 1 86 + [\n] 86 87 +L12 + [/* FOR EXAMPLE, CLASS="ELEGANT RET[ 1 50 + [\n] 50 51 +L13 + [LI] 1 3 + [.] 3 4 + [SPACIOUS] 4 12 + [.] 12 13 + [ELEGANT] 13 20 + [ ] 20 21 + [{] 21 22 + [\n ] 22 3 +L14 + [MARGIN] 3 9 + [:] 9 10 + [ ] 10 11 + [2EM] 11 14 + [;] 14 15 + [\n] 15 16 +L15 + [}] 1 2 + [\n] 2 3 +EOF diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index a70b65e7ea6..269ed835aef 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -32,6 +32,11 @@ pmd-cs ${project.version} + + net.sourceforge.pmd + pmd-css + ${project.version} + net.sourceforge.pmd pmd-dart From 8fd84f2749f44b2458e974a00e6d05394c51715f Mon Sep 17 00:00:00 2001 From: Thomas Prouvot Date: Tue, 13 May 2025 09:38:38 +0200 Subject: [PATCH 0909/1962] fix error when no previous version of the module was found --- pmd-css/pom.xml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pmd-css/pom.xml b/pmd-css/pom.xml index ed9daa1235d..b528cba82b7 100644 --- a/pmd-css/pom.xml +++ b/pmd-css/pom.xml @@ -1,5 +1,7 @@ - + 4.0.0 pmd-css PMD CSS @@ -47,6 +49,13 @@ + + com.github.siom79.japicmp + japicmp-maven-plugin + + true + + From 39234c5d3801d678aef5b3562c8c90cbc2a62481 Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Tue, 13 May 2025 22:14:51 +0200 Subject: [PATCH 0910/1962] Fix #5061: [java] UnusedLocalVariable FP when using compound assignment --- .../lang/java/ast/internal/JavaAstUtils.java | 10 ++++++++-- .../bestpractices/xml/UnusedLocalVariable.xml | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java index 9de709b90fb..bb4f0aaf19c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java @@ -244,8 +244,14 @@ public static boolean isNeverUsed(ASTVariableId varId) { private static boolean isReadUsage(ASTNamedReferenceExpr expr) { return expr.getAccessType() == AccessType.READ // x++ as a method argument or used in other expression - || expr.getParent() instanceof ASTUnaryExpression - && !(expr.getParent().getParent() instanceof ASTExpressionStatement); + || ((expr.getParent() instanceof ASTUnaryExpression + // compound assignments like '+=' have AccessType.WRITE, but can also be used in another expression + || isCompoundAssignment(expr)) + && !(expr.getParent().getParent() instanceof ASTExpressionStatement)); + } + + private static boolean isCompoundAssignment(ASTNamedReferenceExpr expr) { + return expr.getParent() instanceof ASTAssignmentExpression && ((ASTAssignmentExpression) expr.getParent()).isCompound(); } /** diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml index 5729e8ea8e8..834601948a9 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml @@ -540,4 +540,22 @@ public class UnusedLocalVarsMultiple { } ]]> + + + Issues 5061/5081: Compound assignment used in another expression + 0 + + + From 365874c29ecd809f14ce6564e74662ee6796e034 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 14 May 2025 15:46:40 +0200 Subject: [PATCH 0911/1962] Update release notes --- docs/pages/release_notes.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index a5fbe3cd8b3..156f87a713d 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -24,6 +24,16 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy +#### PMD CLI now uses threaded execution by default + +In the PMD CLI, the `--threads` (`-t`) option can now accept a thread +count given relative to the number of cores of the machine. For instance, +it is now possible to write `-t 1C` to spawn one thread per core, or `-t 0.5C` +to spawn one thread for every other core. + +The thread count option now defaults to `1C`, meaning parallel execution +is used by default. You can disable this by using `-t 1`. + ### ๐Ÿ› Fixed Issues * core From 716701718a44d21b998ea3cf50ab9744a46afbf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 14 May 2025 18:33:32 +0200 Subject: [PATCH 0912/1962] Add header --- .../commands/typesupport/internal/NumThreadsConverter.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/NumThreadsConverter.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/NumThreadsConverter.java index 87fd948bf75..1085922f71d 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/NumThreadsConverter.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/NumThreadsConverter.java @@ -1,3 +1,7 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + package net.sourceforge.pmd.cli.commands.typesupport.internal; import picocli.CommandLine.ITypeConverter; From b664502d30e39ea223c5309b397afd805d9788a2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 15 May 2025 14:16:05 +0200 Subject: [PATCH 0913/1962] [cli] Always determine PMD_HOME based on script location Fixes #5705 --- pmd-dist/src/main/resources/scripts/pmd | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/pmd-dist/src/main/resources/scripts/pmd b/pmd-dist/src/main/resources/scripts/pmd index 9a9e3430351..fe1e7e6fa74 100755 --- a/pmd-dist/src/main/resources/scripts/pmd +++ b/pmd-dist/src/main/resources/scripts/pmd @@ -47,13 +47,11 @@ java_heapsize_settings() { } set_pmd_home_dir() { - if [ -z "$PMD_HOME" ]; then - script_real_loc="$0" + script_real_loc="$0" - # see #4723 - allow calling as "bash pmd", when pmd is on the PATH - if [ ! -e "$script_real_loc" ]; then - script_real_loc=$(which "$script_real_loc") - fi + # see #4723 - allow calling as "bash pmd", when pmd is on the PATH + if [ ! -e "$script_real_loc" ]; then + script_real_loc=$(which "$script_real_loc") fi if [ ! -e "$script_real_loc" ]; then From 689cd8bf9dec1d1cb1fc8f038bedb4f980296325 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 15 May 2025 14:29:57 +0200 Subject: [PATCH 0914/1962] Apply suggestions from code review --- docs/pages/release_notes.md | 2 +- .../lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index b3ee40e1d94..f5e8ddacd8b 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -30,7 +30,7 @@ This is a {{ site.pmd.release_type }} release. * [#3184](https://github.com/pmd/pmd/issues/3184): \[apex] Prevent classes from shadowing System Namespace * java * [#5645](https://github.com/pmd/pmd/issues/5645): \[java] Parse error on switch with yield - * [#5702](https://github.com/pmd/pmd/issue/5702): \[java] Lombok `@Slf4j` annotation is not interpreted by PMD + * [#5702](https://github.com/pmd/pmd/issues/5702): \[java] InvalidLogMessageFormat: Lombok @Slf4j annotation is not interpreted by PMD * java-bestpractices * [#5687](https://github.com/pmd/pmd/issues/5687): \[java] UnusedPrivateMethodRule: exclude serialization method readObjectNoData() diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml index 802f44831b1..4b75a2d375e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml @@ -1318,7 +1318,7 @@ public class InvalidLogMessageFormat{ - [java] False negative with Slf4j lombok annotation rule #3119 + [java] InvalidLogMessageFormat: Lombok @Slf4j annotation is not interpreted by PMD #5702 1 Date: Thu, 15 May 2025 14:33:13 +0200 Subject: [PATCH 0915/1962] Add @Frederick888 as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 191 +++++++++++++------------- 2 files changed, 105 insertions(+), 95 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 559807dede6..3e225ddb62f 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8076,6 +8076,15 @@ "contributions": [ "doc" ] + }, + { + "login": "Frederick888", + "name": "Frederick Zhang", + "avatar_url": "https://avatars.githubusercontent.com/u/4507647?v=4", + "profile": "https://onee3.org/", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 794ca3f8646..620be3ad0db 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -291,855 +291,856 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
  • - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + From 893fad24d9fd9e69567179a3e68b0df58bf1d55f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 15 May 2025 14:36:49 +0200 Subject: [PATCH 0916/1962] Add @elharo as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 199 +++++++++++++------------- 2 files changed, 110 insertions(+), 98 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 9d1d8632f6b..76bfe853119 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8094,6 +8094,15 @@ "contributions": [ "bug" ] + }, + { + "login": "elharo", + "name": "Elliotte Rusty Harold", + "avatar_url": "https://avatars.githubusercontent.com/u/1005544?v=4", + "profile": "https://www.elharo.com/blog/", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 28c0065bd41..ba5548f6d3a 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -263,889 +263,892 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + From 6a38dbe7fe5ec97392614d8640bdaa69d3f885c8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 15 May 2025 14:37:43 +0200 Subject: [PATCH 0917/1962] [doc] Update release notes (#5700) --- docs/pages/release_notes.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 42d2815dffe..c154bc1340f 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -27,7 +27,7 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿ› Fixed Issues * core - * [#5700](https://github.com/pmd/pmd/pull/5700): \[core] Don't accidentally catch unexpected runtime exceptions in CpdAnalysis + * [#5700](https://github.com/pmd/pmd/pull/5700): \[core] Don't accidentally catch unexpected runtime exceptions in CpdAnalysis * java-errorprone * [#5702](https://github.com/pmd/pmd/issues/5702): \[java] InvalidLogMessageFormat: Lombok @Slf4j annotation is not interpreted by PMD @@ -35,6 +35,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ Merged pull requests +* [#5700](https://github.com/pmd/pmd/pull/5700): \[core] Don't accidentally catch unexpected runtime exceptions in CpdAnalysis - [Elliotte Rusty Harold](https://github.com/elharo) (@elharo) ### ๐Ÿ“ฆ Dependency updates From 64c89580d9b09a602df82c3c5b16b99676047e75 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 15 May 2025 15:04:47 +0200 Subject: [PATCH 0918/1962] [doc] Update release notes (#5716, #5634) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 0c9c0dd3524..b86e4b64eb5 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,11 +25,14 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* java-codestyle + * [#5634](https://github.com/pmd/pmd/issues/5634): \[java] CommentDefaultAccessModifier doesn't recognize /* package */ comment at expected location for constructors ### ๐Ÿšจ API Changes ### โœจ Merged pull requests +* [#5716](https://github.com/pmd/pmd/pull/5716): Fix #5634: \[java] CommentDefaultAccessModifier: Comment between annotation and constructor not recognized - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) ### ๐Ÿ“ฆ Dependency updates From b9dc6fefaa3d851c7d70f8bfdadf18105a14a490 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 15 May 2025 15:05:24 +0200 Subject: [PATCH 0919/1962] Add @ax-lothas as a contributor --- .all-contributorsrc | 9 ++++++++ docs/pages/pmd/projectdocs/credits.md | 31 ++++++++++++++------------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 6e58551feec..11a8e6a7d08 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8085,6 +8085,15 @@ "contributions": [ "bug" ] + }, + { + "login": "ax-lothas", + "name": "lothas", + "avatar_url": "https://avatars.githubusercontent.com/u/98159917?v=4", + "profile": "https://github.com/ax-lothas", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 699c0c97b1c..e18a203b9b7 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -1009,137 +1009,138 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + From 124f42dd07f5b1795457e00beeef713b00a4439a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 15 May 2025 15:17:48 +0200 Subject: [PATCH 0920/1962] [doc] Update release notes (#5724, #5726) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 0c9c0dd3524..d1f16ed34a2 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,6 +25,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* java-bestpractices + * [#5724](https://github.com/pmd/pmd/issues/5724): \[java] ImplicitFunctionalInterface should not be reported on sealed interfaces ### ๐Ÿšจ API Changes From f081c74e68615b93f0dad625e0292a6a20a4d75c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 15 May 2025 15:18:22 +0200 Subject: [PATCH 0921/1962] Update @marcindabrowski as a contributor --- .all-contributorsrc | 3 ++- docs/pages/pmd/projectdocs/credits.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 6e58551feec..6c329583dcc 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7354,7 +7354,8 @@ "avatar_url": "https://avatars.githubusercontent.com/u/3007876?v=4", "profile": "https://github.com/marcindabrowski", "contributions": [ - "code" + "code", + "bug" ] }, { diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 699c0c97b1c..4a721437ae7 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -504,7 +504,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d - + From 6256d032aed447dbe6b3d785ac017b982841261a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 15 May 2025 17:35:58 +0200 Subject: [PATCH 0922/1962] [ci] Make build a reuseable workflow (#5743) This should avoid triggering unnecessary publish-* workflows, as we can now filter on the events beforehand. The additional filter is still kept for additional safety. Refs pmd/pmd#4328 --- .github/workflows/build-pr.yml | 11 ++++++++ .github/workflows/build-snapshot.yml | 17 ++++++++++++ .github/workflows/build.yml | 12 +-------- .github/workflows/publish-pull-requests.yml | 2 +- .github/workflows/publish-snapshot.yml | 2 +- .../pmd/devdocs/github_actions_workflows.md | 27 +++++++++++++------ 6 files changed, 50 insertions(+), 21 deletions(-) create mode 100644 .github/workflows/build-pr.yml create mode 100644 .github/workflows/build-snapshot.yml diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml new file mode 100644 index 00000000000..194ac4d6b03 --- /dev/null +++ b/.github/workflows/build-pr.yml @@ -0,0 +1,11 @@ +name: Build Pull Request + +on: + pull_request: + merge_group: + types: [checks_requested] + +jobs: + build: + name: Build Pull Request + uses: ./.github/workflows/build.yml diff --git a/.github/workflows/build-snapshot.yml b/.github/workflows/build-snapshot.yml new file mode 100644 index 00000000000..00e2bd6d865 --- /dev/null +++ b/.github/workflows/build-snapshot.yml @@ -0,0 +1,17 @@ +name: Build Snapshot + +on: + push: + branches: + - '**' + # don't run on dependabot branches. Dependabot will create pull requests, which will then be run instead + - '!dependabot/**' + workflow_dispatch: + schedule: + # build it monthly: At 04:00 on day-of-month 1. + - cron: '0 4 1 * *' + +jobs: + build: + name: Build Snapshot + uses: ./.github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cf3f8ba8cd3..8625d42dbcb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,17 +1,7 @@ name: Build on: - pull_request: - merge_group: - push: - branches: - - '**' - # don't run on dependabot branches. Dependabot will create pull requests, which will then be run instead - - '!dependabot/**' - workflow_dispatch: - schedule: - # build it monthly: At 04:00 on day-of-month 1. - - cron: '0 4 1 * *' + workflow_call: # if another commit is added to the same branch or PR (same github.ref), # then cancel already running jobs and start a new build. diff --git a/.github/workflows/publish-pull-requests.yml b/.github/workflows/publish-pull-requests.yml index a4e7f056a56..4fd43105b8a 100644 --- a/.github/workflows/publish-pull-requests.yml +++ b/.github/workflows/publish-pull-requests.yml @@ -2,7 +2,7 @@ name: Publish Results from Pull Requests run-name: Publish Results for "${{ github.event.workflow_run.display_title }}" on: workflow_run: - workflows: [Build] + workflows: [Build Pull Request] types: - completed diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 883314b4dd8..b8c8245883a 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -2,7 +2,7 @@ name: Publish Snapshot on: workflow_run: - workflows: [Build] + workflows: [Build Snapshot] types: - completed branches: diff --git a/docs/pages/pmd/devdocs/github_actions_workflows.md b/docs/pages/pmd/devdocs/github_actions_workflows.md index 8cebc4e65bf..7f7446aa185 100644 --- a/docs/pages/pmd/devdocs/github_actions_workflows.md +++ b/docs/pages/pmd/devdocs/github_actions_workflows.md @@ -10,16 +10,28 @@ last_updated: May 2025 (7.14.0) {%include note.html content="This page is work in progress and does not yet describe all workflows."%} -## Build +## Build, Build Pull Request, Build Snapshot -* Builds: -* Workflow file: +"Build" itself is a [reuseable workflow](https://docs.github.com/en/actions/sharing-automations/reusing-workflows), +that is called by "Build Pull Request" and "Build Snapshot". -This workflow is triggered whenever new commits are pushed to a branch (including the default branch and -including forks) or whenever a pull request is created or synchronized. +* Workflow files: + * + * + * +* Builds: + * Build Pull Request: + * Build Snapshot: + +All these workflows execute exactly the same steps. But only the triggering event is different. It is designed to run on the main repository in PMD's GitHub organization as well as for forks, as it does not require any secrets. +"Build Pull Request" is triggered, whenever a pull request is created or synchronized. + +"Build Snapshot" is triggered, whenever new commits are pushed to a branch (including the default branch and +including forks). + In order to avoid unnecessary builds, we use concurrency control to make sure, we cancel any in-progress jobs for the current branch or pull request when a new commit has been pushed. This means, only the latest commit is built, which is enough, since only this will be released or merged in the end. Only the latest build matters. @@ -71,7 +83,7 @@ The jobs are: * Builds: * Workflow file: -This workflow runs after "Build" on a pull request is completed. It runs in the context of our own +This workflow runs after "Build Pull Request", when it is completed. It runs in the context of our own repository and has write permissions and complete access to the configured secrets. For security reasons, this workflow won't check out the pull request code and won't build anything. @@ -108,7 +120,6 @@ This workflow is in that sense optional, as the docs-artifact and pmd-regression be manually downloaded from the "Pull Request Build" workflow run. It merely adds convenience by giving easy access to a preview of the documentation and to the regression tester results. -<<<<<<< HEAD In the end, this workflow adds additional links to a pull request page. For the comment, GitHub seems to automatically add "rel=nofollow" to the links in the text. This is also applied for the check status pages. However, the links in the commit status are plain links. This might lead to unnecessary @@ -130,7 +141,7 @@ crawling side. * Builds: * Workflow file: -This runs after "Build" of a push on the `main` branch is finished. +This runs after "Build Snapshot" of a push on the `main` branch is finished. It runs in the context of our own repository and has access to all secrets. In order to have a nicer display in GitHub actions, we leverage "environments", which also contain secrets. From e6bbd138a75ba5ca60d0ed9d57f2a81e7f026029 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 15 May 2025 17:41:25 +0200 Subject: [PATCH 0923/1962] [ci] Refactor git-repo-sync (#5730) Not using build-tools anymore. Refs #4328 --- .ci/git-repo-sync.sh | 81 ------------------------ .github/workflows/git-repo-sync.yml | 97 ++++++++++++++++++++++++++--- 2 files changed, 87 insertions(+), 91 deletions(-) delete mode 100755 .ci/git-repo-sync.sh diff --git a/.ci/git-repo-sync.sh b/.ci/git-repo-sync.sh deleted file mode 100755 index af0635d9baa..00000000000 --- a/.ci/git-repo-sync.sh +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env bash - -# Exit this script immediately if a command/function exits with a non-zero status. -set -e - -SCRIPT_INCLUDES="log.bash utils.bash setup-secrets.bash" -# shellcheck source=inc/fetch_ci_scripts.bash -source "$(dirname "$0")/inc/fetch_ci_scripts.bash" && fetch_ci_scripts - -function git_repo_sync() { - echo - pmd_ci_utils_determine_build_env pmd/pmd - echo - - if pmd_ci_utils_is_fork_or_pull_request; then - pmd_ci_log_error "This should not run on forked repositories or pull requests" - exit 0 - fi - - # only builds on pmd/pmd continue here - pmd_ci_log_group_start "Setup environment" - pmd_ci_setup_secrets_private_env - pmd_ci_setup_secrets_gpg_key - pmd_ci_setup_secrets_ssh - pmd_ci_log_group_end - - pmd_ci_log_group_start "Git Sync" - git remote add pmd-sf "${PMD_SF_USER}@git.code.sf.net:/p/pmd/code" - if [ -n "${PMD_CI_BRANCH}" ]; then - retry 5 git push pmd-sf "${PMD_CI_BRANCH}:${PMD_CI_BRANCH}" - pmd_ci_log_success "Successfully pushed ${PMD_CI_BRANCH} to sourceforge" - elif [ -n "${PMD_CI_TAG}" ]; then - git push pmd-sf tag "${PMD_CI_TAG}" - pmd_ci_log_success "Successfully pushed tag ${PMD_CI_TAG} to sourceforge" - else - pmd_ci_log_error "Don't know what to do: neither PMD_CI_BRANCH nor PMD_CI_TAG is set" - exit 1 - fi - pmd_ci_log_group_end -} - - -# -# From: https://gist.github.com/sj26/88e1c6584397bb7c13bd11108a579746 -# -# Retry a command up to a specific number of times until it exits successfully, -# with exponential back off. -# -# $ retry 5 echo Hello -# Hello -# -# $ retry 5 false -# Retry 1/5 exited 1, retrying in 1 seconds... -# Retry 2/5 exited 1, retrying in 2 seconds... -# Retry 3/5 exited 1, retrying in 4 seconds... -# Retry 4/5 exited 1, retrying in 8 seconds... -# Retry 5/5 exited 1, no more retries left. -# -function retry { - local retries=$1 - shift - - local count=0 - until "$@"; do - exit=$? - wait=$((2 ** $count)) - count=$(($count + 1)) - if [ $count -lt $retries ]; then - echo "Retry $count/$retries exited $exit, retrying in $wait seconds..." - sleep $wait - else - echo "Retry $count/$retries exited $exit, no more retries left." - return $exit - fi - done - return 0 -} - -git_repo_sync - -exit 0 diff --git a/.github/workflows/git-repo-sync.yml b/.github/workflows/git-repo-sync.yml index 4da3140f85c..27a90342887 100644 --- a/.github/workflows/git-repo-sync.yml +++ b/.github/workflows/git-repo-sync.yml @@ -14,20 +14,97 @@ permissions: jobs: build: runs-on: ubuntu-latest + timeout-minutes: 20 + # use environment sourceforge, where secrets/vars are configured for PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY + # and PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS + environment: + name: sourceforge + url: https://sourceforge.net/p/pmd/code/ci/main/tree/ + defaults: + run: + shell: bash continue-on-error: false steps: - uses: actions/checkout@v4 with: fetch-depth: 100 - - name: Setup Environment - shell: bash + - name: Setup ssh key for sourceforge + env: + WEB_SF_DEPLOY_KEY: ${{ secrets.PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY }} + WEB_SF_KNOWN_HOSTS: ${{ vars.PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS }} run: | - echo "LANG=en_US.UTF-8" >> $GITHUB_ENV - echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/30/scripts" >> $GITHUB_ENV - - name: Sync - run: .ci/git-repo-sync.sh - shell: bash + mkdir -p "${HOME}/.ssh" + chmod 700 "${HOME}/.ssh" + printenv WEB_SF_DEPLOY_KEY > "${HOME}/.ssh/web.sourceforge.net_deploy_key" + chmod 600 "${HOME}/.ssh/web.sourceforge.net_deploy_key" + echo " + Host web.sourceforge.net + IdentityFile=$HOME/.ssh/web.sourceforge.net_deploy_key + " > "$HOME/.ssh/config" + echo "${WEB_SF_KNOWN_HOSTS}" > "$HOME/.ssh/known_hosts" + - name: Git Sync env: - PMD_CI_SECRET_PASSPHRASE: ${{ secrets.PMD_CI_SECRET_PASSPHRASE }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PMD_CI_GPG_PRIVATE_KEY: ${{ secrets.PMD_CI_GPG_PRIVATE_KEY }} + PMD_SF_USER: adangel + run: | + # + # From: https://gist.github.com/sj26/88e1c6584397bb7c13bd11108a579746 + # + # Retry a command up to a specific number of times until it exits successfully, + # with exponential back off. + # + # $ retry 5 echo Hello + # Hello + # + # $ retry 5 false + # Retry 1/5 exited 1, retrying in 1 seconds... + # Retry 2/5 exited 1, retrying in 2 seconds... + # Retry 3/5 exited 1, retrying in 4 seconds... + # Retry 4/5 exited 1, retrying in 8 seconds... + # Retry 5/5 exited 1, no more retries left. + # + function retry { + local retries=$1 + shift + + local count=0 + until "$@"; do + exit=$? + wait=$((2 ** $count)) + count=$(($count + 1)) + if [ $count -lt $retries ]; then + echo "Retry $count/$retries exited $exit, retrying in $wait seconds..." + sleep $wait + else + echo "Retry $count/$retries exited $exit, no more retries left." + return $exit + fi + done + return 0 + } + + if [[ "${GITHUB_REF}" == refs/heads/* ]]; then + PMD_CI_BRANCH=${GITHUB_REF##refs/heads/} + elif [[ "${GITHUB_REF}" == refs/tags/* ]]; then + PMD_CI_TAG=${GITHUB_REF##refs/tags/} + else + echo "::error ::Unknown branch/tag: GITHUB_REF=${GITHUB_REF}" + exit 1 + fi + + + git remote add pmd-sf "${PMD_SF_USER}@git.code.sf.net:/p/pmd/code" + if [ -n "${PMD_CI_BRANCH}" ]; then + retry 5 git push pmd-sf "${PMD_CI_BRANCH}:${PMD_CI_BRANCH}" + echo "Successfully pushed ${PMD_CI_BRANCH} to sourceforge" + elif [ -n "${PMD_CI_TAG}" ]; then + git push pmd-sf tag "${PMD_CI_TAG}" + echo "Successfully pushed tag ${PMD_CI_TAG} to sourceforge" + else + echo "::error ::Don't know what to do: neither PMD_CI_BRANCH nor PMD_CI_TAG is set" + exit 1 + fi + + - name: Cleanup ssh + if: ${{ always() }} + run: | + rm -rf "${HOME}/.ssh" From 9b24afec33fb448818e64aa79d3d90345e59e3ef Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 15 May 2025 17:46:09 +0200 Subject: [PATCH 0924/1962] [ci] Fix git-repo-sync - use correct key Refs #5730 --- .github/workflows/git-repo-sync.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/git-repo-sync.yml b/.github/workflows/git-repo-sync.yml index 27a90342887..ddd2e2ebc93 100644 --- a/.github/workflows/git-repo-sync.yml +++ b/.github/workflows/git-repo-sync.yml @@ -38,7 +38,7 @@ jobs: printenv WEB_SF_DEPLOY_KEY > "${HOME}/.ssh/web.sourceforge.net_deploy_key" chmod 600 "${HOME}/.ssh/web.sourceforge.net_deploy_key" echo " - Host web.sourceforge.net + Host git.code.sf.net IdentityFile=$HOME/.ssh/web.sourceforge.net_deploy_key " > "$HOME/.ssh/config" echo "${WEB_SF_KNOWN_HOSTS}" > "$HOME/.ssh/known_hosts" From 7634608981cb17ae41102c0c39f905577f518645 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 15 May 2025 17:54:41 +0200 Subject: [PATCH 0925/1962] [ci] Fix git-repo-sync - use correct known hosts Refs #5730 --- .github/workflows/git-repo-sync.yml | 4 ++-- .../pmd/devdocs/github_actions_workflows.md | 24 +++++++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/.github/workflows/git-repo-sync.yml b/.github/workflows/git-repo-sync.yml index ddd2e2ebc93..239954826a5 100644 --- a/.github/workflows/git-repo-sync.yml +++ b/.github/workflows/git-repo-sync.yml @@ -31,7 +31,7 @@ jobs: - name: Setup ssh key for sourceforge env: WEB_SF_DEPLOY_KEY: ${{ secrets.PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY }} - WEB_SF_KNOWN_HOSTS: ${{ vars.PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS }} + GIT_CODE_SF_NET_KNOWN_HOSTS: ${{ vars.PMD_GIT_CODE_SF_NET_KNOWN_HOSTS }} run: | mkdir -p "${HOME}/.ssh" chmod 700 "${HOME}/.ssh" @@ -41,7 +41,7 @@ jobs: Host git.code.sf.net IdentityFile=$HOME/.ssh/web.sourceforge.net_deploy_key " > "$HOME/.ssh/config" - echo "${WEB_SF_KNOWN_HOSTS}" > "$HOME/.ssh/known_hosts" + echo "${GIT_CODE_SF_NET_KNOWN_HOSTS}" > "$HOME/.ssh/known_hosts" - name: Git Sync env: PMD_SF_USER: adangel diff --git a/docs/pages/pmd/devdocs/github_actions_workflows.md b/docs/pages/pmd/devdocs/github_actions_workflows.md index 7f7446aa185..f480c75c94f 100644 --- a/docs/pages/pmd/devdocs/github_actions_workflows.md +++ b/docs/pages/pmd/devdocs/github_actions_workflows.md @@ -159,7 +159,7 @@ we are actually building a SNAPSHOT version. Then a couple of other jobs are bei gpg-signs the files and uploads them to . * Environment: sourceforge * Secrets: PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY - * Vars: PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS + * Vars: PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS, PMD_GIT_CODE_SF_NET_KNOWN_HOSTS * deploy-to-sourceforge-io: Uploads the documentation page to be hosted at . * Environment: sourceforge @@ -300,7 +300,7 @@ See ### Repository pmd/pmd - Environment "sourceforge" * `PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY`: The private ssh key used to access web.sourceforge.net to - upload files and web pages. + upload files and web pages. It is also used to push to sourceforge's git repository at "git.code.sf.net". It is created with `ssh-keygen -t ed25519 -C "ssh key for pmd. used for github actions push to web.sourceforge.net" -f web.sourceforge.net_deploy_key`. You need to configure the public key part here: . The user is your sourceforge user id. @@ -339,6 +339,26 @@ web.sourceforge.net ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlz web.sourceforge.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOQD35Ujalhh+JJkPvMckDlhu4dS7WH6NsOJ15iGCJLC ``` +Another variable `PMD_GIT_CODE_SF_NET_KNOWN_HOSTS` contains the known_hosts for "git.code.sf.net": + +``` +# +# git.code.sf.net (https://sourceforge.net/p/forge/documentation/SSH%20Key%20Fingerprints/) +# +# ssh-keyscan git.code.sf.net | tee -a sf-git_known_hosts +# ssh-keygen -F git.code.sf.net -l -f sf-git_known_hosts +# # Host git.code.sf.net found: line 1 +# git.code.sf.net RSA SHA256:3WhEqJaBPKb69eT5dfgYcPJTgqc9rq1Y9saZlXqkbWg +# # Host git.code.sf.net found: line 2 +# git.code.sf.net ECDSA SHA256:FeVkoYYBjuQzb5QVAgm3BkmeN5TTgL2qfmqz9tCPRL4 +# # Host git.code.sf.net found: line 3 +# git.code.sf.net ED25519 SHA256:vDwNztsrZFViJXWpUTSKGo8cF6n79iKAURNiK68n/yE +# ssh-keygen -F git.code.sf.net -f sf-git_known_hosts +git.code.sf.net ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAoMesJ60dow5VqNsIqIQMBNmSYz6txSC5YSUXzPNWV4VIWTWdqbQoQuIu+oYGhBMoeaSWWCiVIDTwFDzQXrq8CwmyxWp+2TTuscKiOw830N2ycIVmm3ha0x6VpRGm37yo+z+bkQS3m/sE7bkfTU72GbeKufFHSv1VLnVy9nmJKFOraeKSHP/kjmatj9aC7Q2n8QzFWWjzMxVGg79TUs7sjm5KrtytbxfbLbKtrkn8OXsRy1ib9hKgOwg+8cRjwKbSXVrNw/HM+MJJWp9fHv2yzWmL8B6fKoskslA0EjNxa6d76gvIxwti89/8Y6xlhR0u65u1AiHTX9Q4BVsXcBZUDw== +git.code.sf.net ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPAa5MFfMaXyT3Trf/Av/laAvIhUzZJUnvPZAd9AC6bKWAhVl+A3s2+M6SlhF/Tn/W0akN03GyNviBtqJKtx0RU= +git.code.sf.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGObtXLh/mZom0pXjE5Mu211O+JvtzolqdNKVA+XJ466 +``` + ### Repository pmd/pmd - Environment "pmd-code" * `PMD_CODE_ORG_DEPLOY_KEY`: The private ssh key used to access docs.pmd-code.org. From 6214ca2e10ece4a4ba984e508a7e9b2df23c7a5c Mon Sep 17 00:00:00 2001 From: Vincent Potucek Date: Thu, 15 May 2025 21:32:28 +0200 Subject: [PATCH 0926/1962] [RSPEC-S1144] Remove unused private methods --- .../sourceforge/pmd/cpd/AnyCpdLexerTest.java | 4 ---- .../symbols/internal/TypeAnnotTestUtil.java | 18 ------------------ .../resolver/ModelicaResolverTest.java | 10 ---------- 3 files changed, 32 deletions(-) diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/AnyCpdLexerTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/AnyCpdLexerTest.java index c91e3ebd338..d2ec5f54327 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/AnyCpdLexerTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/AnyCpdLexerTest.java @@ -78,10 +78,6 @@ private Tokens compareResult(AnyCpdLexer tokenizer, String source, List return tokens; } - private String getTokenImage(TokenEntry t) { - return t.toString(); - } - private static final List EXPECTED = listOf( "using", "System", ";", "namespace", "HelloNameSpace", "{", diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/TypeAnnotTestUtil.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/TypeAnnotTestUtil.java index 6eb7d092d80..b486ac27a24 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/TypeAnnotTestUtil.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/TypeAnnotTestUtil.java @@ -17,15 +17,11 @@ import java.util.stream.Collectors; import org.apache.commons.lang3.AnnotationUtils; -import org.hamcrest.BaseMatcher; -import org.hamcrest.Description; -import org.hamcrest.Matcher; import net.sourceforge.pmd.lang.java.symbols.AnnotableSymbol; import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; import net.sourceforge.pmd.lang.java.symbols.JMethodSymbol; import net.sourceforge.pmd.lang.java.symbols.SymbolicValue; -import net.sourceforge.pmd.lang.java.symbols.SymbolicValue.SymAnnot; import net.sourceforge.pmd.lang.java.symbols.testdata.ClassWithTypeAnnotationsInside; import net.sourceforge.pmd.lang.java.types.JClassType; import net.sourceforge.pmd.lang.java.types.JMethodSig; @@ -106,19 +102,5 @@ public static A createAnnotationInstance(Class annotat }); } - private static Matcher matchesAnnot(Annotation o) { - return new BaseMatcher() { - @Override - public boolean matches(Object actual) { - return actual instanceof SymAnnot && ((SymAnnot) actual).valueEquals(o); - } - - @Override - public void describeTo(Description description) { - description.appendText("an annotation like " + o); - } - }; - } - } diff --git a/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaResolverTest.java b/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaResolverTest.java index a84eb3c7184..2808e058445 100644 --- a/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaResolverTest.java +++ b/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaResolverTest.java @@ -30,22 +30,12 @@ private void ensureCounts(ResolutionResult result, int best, int hidden) { assertEquals(hidden, result.getHiddenCandidates().size()); } - private ResolutionResult resolveIn(int best, int hidden, ResolutionState state, SubcomponentResolver resolver, boolean absolute, String[] names) { - ResolutionResult result = resolver.safeResolveComponent(ResolvableEntity.class, state, CompositeName.create(absolute, names)); - ensureCounts(result, best, hidden); - return result; - } - private ResolutionResult resolveIn(int best, int hidden, ResolutionState state, ModelicaScope resolver, boolean absolute, String[] names) { ResolutionResult result = resolver.safeResolveLexically(ResolvableEntity.class, state, CompositeName.create(absolute, names)); ensureCounts(result, best, hidden); return result; } - private ResolutionResult testResolvedTypeCount(int best, int hidden, SubcomponentResolver scope, boolean absolute, String... names) { - return resolveIn(best, hidden, ResolutionState.forType(), scope, absolute, names); - } - private ResolutionResult testResolvedTypeCount(int best, int hidden, ModelicaScope scope, boolean absolute, String... names) { return resolveIn(best, hidden, ResolutionState.forType(), scope, absolute, names); } From e9843a97bf6d796f8b467866faa56df98978be9b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 16 May 2025 09:05:34 +0200 Subject: [PATCH 0927/1962] [ci] publish-snapshot/old build: migrate to central portal (#5742) OSSRH is being shut down, we now need to use central portal for publish artifacts to maven central. See https://central.sonatype.org/publish/publish-portal-guide/ See https://central.sonatype.org/news/20250326_ossrh_sunset/ Note: The whole namespace `net.sourceforge.pmd:*` will need to be migrated at once, so we need to migrate pmd-designer and pmd at the same time. --- .ci/build.sh | 32 ++++- .github/workflows/build.yml | 5 +- .github/workflows/publish-snapshot.yml | 10 +- .../pmd/devdocs/building/building_general.md | 24 ++-- .../pmd/devdocs/github_actions_workflows.md | 16 +-- pom.xml | 132 ++++++------------ 6 files changed, 99 insertions(+), 120 deletions(-) diff --git a/.ci/build.sh b/.ci/build.sh index 15b275d98dd..3220dbb9d85 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -110,7 +110,7 @@ function build() { pmd_ci_setup_secrets_private_env pmd_ci_setup_secrets_gpg_key pmd_ci_setup_secrets_ssh - pmd_ci_maven_setup_settings + pmd_ci_build_setup_maven_settings pmd_ci_log_group_end pmd_ci_log_group_start "Build and Deploy" @@ -236,6 +236,36 @@ function pmd_ci_build_setup_bundler() { bundle --version } +function pmd_ci_build_setup_maven_settings() { + pmd_ci_log_info "Setting up maven at ${HOME}/.m2/settings.xml..." + mkdir -p "${HOME}/.m2" + cat > "${HOME}/.m2/settings.xml" < + + + + + + org.sonarsource.scanner.maven + + + + central + \${env.CI_DEPLOY_USERNAME} + \${env.CI_DEPLOY_PASSWORD} + + + + + + + +EOF +} + # # Performs the actual build. # Deploys the artifacts to maven central. diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8625d42dbcb..afd000f68c0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -99,8 +99,7 @@ jobs: run: | ./mvnw --show-version --errors --batch-mode \ -Dmaven.repo.local=.m2/repository \ - verify \ - -DskipTests -Dmaven.test.skip=true + verify -DskipTests - uses: actions/upload-artifact@v4 with: name: javadocs-artifact @@ -253,7 +252,7 @@ jobs: -Dmaven.repo.local=.m2/repository \ verify \ -Pgenerate-rule-docs,fastSkip \ - -DskipTests -Dmaven.test.skip=true -Dassembly.skipAssembly=true + -DskipTests -Dassembly.skipAssembly=true - name: Set up Ruby 3.3 uses: ruby/setup-ruby@v1 with: diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index b8c8245883a..80d4217f420 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -66,10 +66,10 @@ jobs: deploy-to-maven-central: needs: check-version - # use environment maven-central, where secrets are configured for OSSRH_* + # use environment maven-central, where secrets are configured for MAVEN_CENTRAL_PORTAL_* environment: name: maven-central - url: https://oss.sonatype.org/content/repositories/snapshots/net/sourceforge/pmd/ + url: https://central.sonatype.com/service/rest/repository/browse/maven-snapshots/net/sourceforge/pmd/ runs-on: ubuntu-latest timeout-minutes: 20 defaults: @@ -83,7 +83,7 @@ jobs: with: distribution: 'temurin' java-version: '11' - server-id: ossrh + server-id: central server-username: MAVEN_USERNAME server-password: MAVEN_PASSWORD gpg-passphrase: MAVEN_GPG_PASSPHRASE @@ -101,8 +101,8 @@ jobs: run-id: ${{ github.event.workflow_run.id }} - name: Build and publish env: - MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} - MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} + MAVEN_USERNAME: ${{ secrets.MAVEN_CENTRAL_PORTAL_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PORTAL_PASSWORD }} MAVEN_GPG_PASSPHRASE: ${{ secrets.PMD_CI_GPG_PASSPHRASE }} # note: we can't use artifact staging-repository, as the jars are unsigned and javadoc+sources are missing. run: | diff --git a/docs/pages/pmd/devdocs/building/building_general.md b/docs/pages/pmd/devdocs/building/building_general.md index 0cd39196631..ce9fdea1d04 100644 --- a/docs/pages/pmd/devdocs/building/building_general.md +++ b/docs/pages/pmd/devdocs/building/building_general.md @@ -76,23 +76,29 @@ If you integrate PMD as a dependency in your own project, you can also reference version. However, you also need to configure an additional Maven Repository, as the SNAPSHOTS are not published in Maven Central. -Use the OSSRH snapshot repository url: `https://oss.sonatype.org/content/repositories/snapshots`. For Maven +Use the Central Portal Snapshot repository url: `https://central.sonatype.com/repository/maven-snapshots/`. For Maven projects, this can be configured like: ```xml - - sonatype-nexus-snapshots - Sonatype Nexus Snapshots - https://oss.sonatype.org/content/repositories/snapshots - false - true - + + Central Portal Snapshots + central-portal-snapshots + https://central.sonatype.com/repository/maven-snapshots/ + + false + + + true + + ``` -Have a look at to see which +Have a look at to see which SNAPSHOT versions are available. Note that old SNAPSHOT versions might be removed without prior notice. +See also . + ## General Development Tips * Use a IDE, see one of the other guides diff --git a/docs/pages/pmd/devdocs/github_actions_workflows.md b/docs/pages/pmd/devdocs/github_actions_workflows.md index f480c75c94f..3c141babd14 100644 --- a/docs/pages/pmd/devdocs/github_actions_workflows.md +++ b/docs/pages/pmd/devdocs/github_actions_workflows.md @@ -150,11 +150,11 @@ There is a first job "check-version" that just determines the version of PMD we we are actually building a SNAPSHOT version. Then a couple of other jobs are being executed in parallel: * deploy-to-maven-central: Rebuilds PMD from branch main and deploys the snapshot artifacts to - . Rebuilding is necessary in - order to produce all necessary artifacts (sources, javadoc) and also gpg-sign the artifacts. This - is not available from the build artifacts of the "Build" workflow. + . + Rebuilding is necessary in order to produce all necessary artifacts (sources, javadoc) and also gpg-sign the + artifacts. This is not available from the build artifacts of the "Build" workflow. * Environment: maven-central - * Secrets: OSSRH_TOKEN, OSSRH_USERNAME + * Secrets: MAVEN_CENTRAL_PORTAL_USERNAME, MAVEN_CENTRAL_PORTAL_PASSWORD * deploy-to-sourceforge-files: Downloads the "dist-artifact" and "docs-artifact" from the "Build" workflow, gpg-signs the files and uploads them to . * Environment: sourceforge @@ -284,11 +284,9 @@ See ### Repository pmd/pmd - Environment "maven-central" -* `OSSRH_USERNAME` and `OSSRH_TOKEN`: Used to deploy artifacts to maven central via OSSRH to our namespace - [net.sourceforge.pmd](https://repo.maven.apache.org/maven2/net/sourceforge/pmd). - Login on , go to your user profile, select "User Token" and "Access User Token". - You'll see the tokens to be used for username and password. - Note: This will soon be migrated to use . +* `MAVEN_CENTRAL_PORTAL_USERNAME` and `MAVEN_CENTRAL_PORTAL_PASSWORD`: Used to deploy artifacts to maven + central via . See for the documentation. + The upload uses token-based authentication, you can generate a user token on . ### Repository pmd/pmd - Environment "coveralls" * `COVERALLS_REPO_TOKEN`: Used to upload coverage results to . diff --git a/pom.xml b/pom.xml index 53bfef8b4fc..862446e709a 100644 --- a/pom.xml +++ b/pom.xml @@ -64,16 +64,6 @@ https://github.com/pmd/pmd HEAD - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - PMD https://pmd.github.io/ @@ -625,9 +615,9 @@ 2.18.0 - org.sonatype.plugins - nexus-staging-maven-plugin - 1.7.0 + org.sonatype.central + central-publishing-maven-plugin + 0.7.0 org.jacoco @@ -790,12 +780,14 @@ - org.sonatype.plugins - nexus-staging-maven-plugin + org.sonatype.central + central-publishing-maven-plugin true - ossrh - https://oss.sonatype.org/ + central + true + published + ${project.artifactId} @@ -808,6 +800,8 @@ makeAggregateBom + + false @@ -1370,21 +1302,35 @@ false true - - - sonatype-nexus-plugin-snapshots - Sonatype Nexus Snapshots - https://oss.sonatype.org/content/repositories/snapshots - false - false - - + + + + + central-portal-snapshots + + + Central Portal Snapshots + central-portal-snapshots + https://central.sonatype.com/repository/maven-snapshots/ + + false + + + true + + + + - apache.snapshots - Apache Snapshot Repository - https://repository.apache.org/snapshots - false - false + Central Portal Snapshots + central-portal-snapshots + https://central.sonatype.com/repository/maven-snapshots/ + + false + + + true + From a4c0c4e326ce8f5acc8178567a2d166d88570072 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 16 May 2025 10:38:26 +0200 Subject: [PATCH 0928/1962] [ci] Fix publish-snapshot after central migration - increase timeout for "deploy-to-maven-central". It seems, that snapshot deployment takes longer now. - since removal of the snapshot repo, "run-coveralls" fails. We need to call maven twice in order to fix a jacoco/coveralls problem. Adding phase "compile" seems to work. Refs #5742 --- .github/workflows/publish-snapshot.yml | 9 +++++---- docs/pages/release_notes.md | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 80d4217f420..ee9a1025e31 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -71,7 +71,7 @@ jobs: name: maven-central url: https://central.sonatype.com/service/rest/repository/browse/maven-snapshots/net/sourceforge/pmd/ runs-on: ubuntu-latest - timeout-minutes: 20 + timeout-minutes: 40 defaults: run: shell: bash @@ -561,7 +561,7 @@ jobs: ./mvnw \ --show-version --errors --batch-mode \ -Dmaven.repo.local=.m2/repository \ - clean package \ + package \ sonar:sonar -Psonar,fastSkip run-coveralls: @@ -594,7 +594,7 @@ jobs: ./mvnw \ --show-version --errors --batch-mode \ -Dmaven.repo.local=.m2/repository \ - clean package \ + package \ jacoco:report -Pcoveralls,fastSkip # workaround, maybe https://github.com/jacoco/jacoco/issues/654 @@ -606,8 +606,9 @@ jobs: COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} run: | # note: generate-sources is needed, so that antlr4 generated directories are on the compileSourceRoots + # compile is needed to that dependency resolution within this multi-module build works ./mvnw \ --show-version --errors --batch-mode \ -Dmaven.repo.local=.m2/repository \ - generate-sources \ + generate-sources compile \ coveralls:report -DrepoToken="${COVERALLS_REPO_TOKEN}" -Pcoveralls,fastSkip diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 6d5c06f6ee3..924cf4694c7 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -24,6 +24,30 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy +#### Migrating to Central Publisher Portal + +We've now migrated to [Central Publisher Portal](https://central.sonatype.org/publish/publish-portal-guide/). +Snapshots of PMD are still available, however the repository URL changed. To consume these with maven, you can +use the following snippet: + +```xml + + + Central Portal Snapshots + central-portal-snapshots + https://central.sonatype.com/repository/maven-snapshots/ + + false + + + true + + + +``` + +Releases of PMD are available on [Maven Central](https://central.sonatype.com/) as before without change. + ### ๐Ÿ› Fixed Issues * core * [#5700](https://github.com/pmd/pmd/pull/5700): \[core] Don't accidentally catch unexpected runtime exceptions in CpdAnalysis From 2b27004152e729db599aa85b64ca50bcf5bb482c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 16 May 2025 10:43:16 +0200 Subject: [PATCH 0929/1962] [ci] git-repo-sync - only run on main pmd repo Skip for forks Refs #5730 --- .github/workflows/git-repo-sync.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/git-repo-sync.yml b/.github/workflows/git-repo-sync.yml index 239954826a5..32d01fb48a5 100644 --- a/.github/workflows/git-repo-sync.yml +++ b/.github/workflows/git-repo-sync.yml @@ -13,6 +13,8 @@ permissions: jobs: build: + # only run in the official pmd repo, where we have access to the secrets and not on forks + if: ${{ github.repository == 'pmd/pmd' }} runs-on: ubuntu-latest timeout-minutes: 20 # use environment sourceforge, where secrets/vars are configured for PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY From 0d5249e01a6572675968452bf078bc5b5ce71d50 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 16 May 2025 11:21:08 +0200 Subject: [PATCH 0930/1962] [java] UnusedLocalVariable - improve tests Refs #5061 #5747 --- .../bestpractices/xml/UnusedLocalVariable.xml | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml index 834601948a9..a6e111800cc 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml @@ -558,4 +558,57 @@ public class Foo { ]]> + + #5061/5081: Compound assignment used in another expression + 0 + = 0 && totalBytesRead < length) { + totalBytesRead += read; + } + } +} + ]]> + + + + [java] UnusedLocalVariable false positive with try-with-resource #5747 - workaround + 0 + 0) { + position += read; + } + return position; + } + } +} +]]> + From 11e78e5ffa377a498811866bb073a564c7e963e2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 16 May 2025 11:23:56 +0200 Subject: [PATCH 0931/1962] [doc] Update release notes (#5736, #5061) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index a5fbe3cd8b3..90560432c5d 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -28,11 +28,14 @@ This is a {{ site.pmd.release_type }} release. * core * [#5700](https://github.com/pmd/pmd/pull/5700): \[core] Don't accidentally catch unexpected runtime exceptions in CpdAnalysis +* java-bestpractices + * [#5061](https://github.com/pmd/pmd/issues/5061): \[java] UnusedLocalVariable false positive when variable is read as side effect of an assignment ### ๐Ÿšจ API Changes ### โœจ Merged pull requests +* [#5736](https://github.com/pmd/pmd/pull/5736): Fix #5061: \[java] UnusedLocalVariable FP when using compound assignment - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) ### ๐Ÿ“ฆ Dependency updates From c928e129c9f4ce9270cb6597aeac81f04dd7854b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 16 May 2025 20:40:56 +0200 Subject: [PATCH 0932/1962] [core] Reformat SarifLog to comply to coding standards - removed SuppressWarnings - use imports instead of fqcn - regenerate equals/hashCode with Objects.equals and Objects.hashCode - classes are final now - removed javadoc on private fields Refs #5662 --- .../renderers/internal/sarif/SarifLog.java | 2112 ++++------------- 1 file changed, 490 insertions(+), 1622 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java index 5318ad492a7..17c9d255cad 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLog.java @@ -4,65 +4,55 @@ package net.sourceforge.pmd.renderers.internal.sarif; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.Set; import com.google.gson.annotations.SerializedName; -// Generated by delombok at Mon Jan 25 09:12:45 CET 2021 -// CPD-OFF -public class SarifLog { - /** - * The URI of the JSON schema corresponding to the version. - */ +/** + * This class represents a SARIF report that can be serialized with Gson into Json. + * + *

    To create a new log, use the builders, e.g. {@link SarifLog#builder()}. + *

    This class tries to use the same names as in the official specification for + * Sarif. + * + * @see Static Analysis Results Interchange Format (SARIF) Version 2.1.0 + */ +public final class SarifLog { @SerializedName("$schema") private String schema; - /** - * The SARIF format version of this log file. - */ private String version; - /** - * The set of runs contained in this log file. - */ private List runs; - /** * A location within a programming artifact. */ - public static class Location { - /** - * Value that distinguishes this location from all other locations within a single result object. - */ + public static final class Location { private Integer id; - /** - * Identifies the artifact and region. - */ private PhysicalLocation physicalLocation; - @java.lang.SuppressWarnings("all") - Location(final Integer id, final PhysicalLocation physicalLocation) { + private Location(final Integer id, final PhysicalLocation physicalLocation) { this.id = id; this.physicalLocation = physicalLocation; } - - @java.lang.SuppressWarnings("all") - public static class LocationBuilder { - @java.lang.SuppressWarnings("all") + public static final class LocationBuilder { private Integer id; - @java.lang.SuppressWarnings("all") private PhysicalLocation physicalLocation; - @java.lang.SuppressWarnings("all") - LocationBuilder() { + private LocationBuilder() { + // make default ctor private; factory method Location#builder() should be used. } /** * Value that distinguishes this location from all other locations within a single result object. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Location.LocationBuilder id(final Integer id) { this.id = id; return this; @@ -70,27 +60,24 @@ public SarifLog.Location.LocationBuilder id(final Integer id) { /** * Identifies the artifact and region. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Location.LocationBuilder physicalLocation(final PhysicalLocation physicalLocation) { this.physicalLocation = physicalLocation; return this; } - @java.lang.SuppressWarnings("all") public SarifLog.Location build() { return new SarifLog.Location(this.id, this.physicalLocation); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.Location.LocationBuilder(id=" + this.id + ", physicalLocation=" + this.physicalLocation + ")"; } } - @java.lang.SuppressWarnings("all") public static SarifLog.Location.LocationBuilder builder() { return new SarifLog.Location.LocationBuilder(); } @@ -98,7 +85,6 @@ public static SarifLog.Location.LocationBuilder builder() { /** * Value that distinguishes this location from all other locations within a single result object. */ - @java.lang.SuppressWarnings("all") public Integer getId() { return this.id; } @@ -106,16 +92,15 @@ public Integer getId() { /** * Identifies the artifact and region. */ - @java.lang.SuppressWarnings("all") public PhysicalLocation getPhysicalLocation() { return this.physicalLocation; } /** * Value that distinguishes this location from all other locations within a single result object. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Location setId(final Integer id) { this.id = id; return this; @@ -123,60 +108,30 @@ public SarifLog.Location setId(final Integer id) { /** * Identifies the artifact and region. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Location setPhysicalLocation(final PhysicalLocation physicalLocation) { this.physicalLocation = physicalLocation; return this; } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public boolean equals(final java.lang.Object o) { - if (o == this) { - return true; - } - if (!(o instanceof SarifLog.Location)) { - return false; - } - final SarifLog.Location other = (SarifLog.Location) o; - if (!other.canEqual((java.lang.Object) this)) { - return false; - } - final java.lang.Object this$id = this.getId(); - final java.lang.Object other$id = other.getId(); - if (this$id == null ? other$id != null : !this$id.equals(other$id)) { - return false; - } - final java.lang.Object this$physicalLocation = this.getPhysicalLocation(); - final java.lang.Object other$physicalLocation = other.getPhysicalLocation(); - if (this$physicalLocation == null ? other$physicalLocation != null : !this$physicalLocation.equals(other$physicalLocation)) { + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { return false; } - return true; + Location location = (Location) o; + return Objects.equals(id, location.id) && Objects.equals(physicalLocation, location.physicalLocation); } - @java.lang.SuppressWarnings("all") - protected boolean canEqual(final java.lang.Object other) { - return other instanceof SarifLog.Location; + @Override + public int hashCode() { + return Objects.hash(id, physicalLocation); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public int hashCode() { - final int PRIME = 59; - int result = 1; - final java.lang.Object $id = this.getId(); - result = result * PRIME + ($id == null ? 43 : $id.hashCode()); - final java.lang.Object $physicalLocation = this.getPhysicalLocation(); - result = result * PRIME + ($physicalLocation == null ? 43 : $physicalLocation.hashCode()); - return result; - } - - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.Location(id=" + this.getId() + ", physicalLocation=" + this.getPhysicalLocation() + ")"; } } @@ -185,47 +140,31 @@ public java.lang.String toString() { /** * Specifies the location of an artifact. */ - public static class ArtifactLocation { - /** - * A string containing a valid relative or absolute URI. - */ + public static final class ArtifactLocation { private String uri; - /** - * A string which indirectly specifies the absolute URI with respect to which a relative URI in the "uri" property - * is interpreted. - */ private String uriBaseId; - /** - * The index within the run artifacts array of the artifact object associated with the artifact location. - */ private Integer index; - @java.lang.SuppressWarnings("all") - ArtifactLocation(final String uri, final String uriBaseId, final Integer index) { + private ArtifactLocation(final String uri, final String uriBaseId, final Integer index) { this.uri = uri; this.uriBaseId = uriBaseId; this.index = index; } - - @java.lang.SuppressWarnings("all") - public static class ArtifactLocationBuilder { - @java.lang.SuppressWarnings("all") + public static final class ArtifactLocationBuilder { private String uri; - @java.lang.SuppressWarnings("all") private String uriBaseId; - @java.lang.SuppressWarnings("all") private Integer index; - @java.lang.SuppressWarnings("all") - ArtifactLocationBuilder() { + private ArtifactLocationBuilder() { + // make default ctor private. Use factory method ArtifactLocation#builder() instead. } /** * A string containing a valid relative or absolute URI. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ArtifactLocation.ArtifactLocationBuilder uri(final String uri) { this.uri = uri; return this; @@ -234,9 +173,9 @@ public SarifLog.ArtifactLocation.ArtifactLocationBuilder uri(final String uri) { /** * A string which indirectly specifies the absolute URI with respect to which a relative URI in the "uri" property * is interpreted. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ArtifactLocation.ArtifactLocationBuilder uriBaseId(final String uriBaseId) { this.uriBaseId = uriBaseId; return this; @@ -244,27 +183,24 @@ public SarifLog.ArtifactLocation.ArtifactLocationBuilder uriBaseId(final String /** * The index within the run artifacts array of the artifact object associated with the artifact location. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ArtifactLocation.ArtifactLocationBuilder index(final Integer index) { this.index = index; return this; } - @java.lang.SuppressWarnings("all") public SarifLog.ArtifactLocation build() { return new SarifLog.ArtifactLocation(this.uri, this.uriBaseId, this.index); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.ArtifactLocation.ArtifactLocationBuilder(uri=" + this.uri + ", uriBaseId=" + this.uriBaseId + ", index=" + this.index + ")"; } } - @java.lang.SuppressWarnings("all") public static SarifLog.ArtifactLocation.ArtifactLocationBuilder builder() { return new SarifLog.ArtifactLocation.ArtifactLocationBuilder(); } @@ -272,7 +208,6 @@ public static SarifLog.ArtifactLocation.ArtifactLocationBuilder builder() { /** * A string containing a valid relative or absolute URI. */ - @java.lang.SuppressWarnings("all") public String getUri() { return this.uri; } @@ -281,7 +216,6 @@ public String getUri() { * A string which indirectly specifies the absolute URI with respect to which a relative URI in the "uri" property * is interpreted. */ - @java.lang.SuppressWarnings("all") public String getUriBaseId() { return this.uriBaseId; } @@ -289,16 +223,15 @@ public String getUriBaseId() { /** * The index within the run artifacts array of the artifact object associated with the artifact location. */ - @java.lang.SuppressWarnings("all") public Integer getIndex() { return this.index; } /** * A string containing a valid relative or absolute URI. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ArtifactLocation setUri(final String uri) { this.uri = uri; return this; @@ -307,9 +240,9 @@ public SarifLog.ArtifactLocation setUri(final String uri) { /** * A string which indirectly specifies the absolute URI with respect to which a relative URI in the "uri" property * is interpreted. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ArtifactLocation setUriBaseId(final String uriBaseId) { this.uriBaseId = uriBaseId; return this; @@ -317,67 +250,30 @@ public SarifLog.ArtifactLocation setUriBaseId(final String uriBaseId) { /** * The index within the run artifacts array of the artifact object associated with the artifact location. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ArtifactLocation setIndex(final Integer index) { this.index = index; return this; } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public boolean equals(final java.lang.Object o) { - if (o == this) { - return true; - } - if (!(o instanceof SarifLog.ArtifactLocation)) { - return false; - } - final SarifLog.ArtifactLocation other = (SarifLog.ArtifactLocation) o; - if (!other.canEqual((java.lang.Object) this)) { - return false; - } - final java.lang.Object this$uri = this.getUri(); - final java.lang.Object other$uri = other.getUri(); - if (this$uri == null ? other$uri != null : !this$uri.equals(other$uri)) { - return false; - } - final java.lang.Object this$uriBaseId = this.getUriBaseId(); - final java.lang.Object other$uriBaseId = other.getUriBaseId(); - if (this$uriBaseId == null ? other$uriBaseId != null : !this$uriBaseId.equals(other$uriBaseId)) { - return false; - } - final java.lang.Object this$index = this.getIndex(); - final java.lang.Object other$index = other.getIndex(); - if (this$index == null ? other$index != null : !this$index.equals(other$index)) { + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { return false; } - return true; + ArtifactLocation that = (ArtifactLocation) o; + return Objects.equals(uri, that.uri) && Objects.equals(uriBaseId, that.uriBaseId) && Objects.equals(index, that.index); } - @java.lang.SuppressWarnings("all") - protected boolean canEqual(final java.lang.Object other) { - return other instanceof SarifLog.ArtifactLocation; + @Override + public int hashCode() { + return Objects.hash(uri, uriBaseId, index); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public int hashCode() { - final int PRIME = 59; - int result = 1; - final java.lang.Object $uri = this.getUri(); - result = result * PRIME + ($uri == null ? 43 : $uri.hashCode()); - final java.lang.Object $uriBaseId = this.getUriBaseId(); - result = result * PRIME + ($uriBaseId == null ? 43 : $uriBaseId.hashCode()); - final java.lang.Object $index = this.getIndex(); - result = result * PRIME + ($index == null ? 43 : $index.hashCode()); - return result; - } - - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.ArtifactLocation(uri=" + this.getUri() + ", uriBaseId=" + this.getUriBaseId() + ", index=" + this.getIndex() + ")"; } } @@ -387,39 +283,29 @@ public java.lang.String toString() { * A physical location relevant to a result. Specifies a reference to a programming artifact together with a range * of bytes or characters within that artifact. */ - public static class PhysicalLocation { - /** - * The location of the artifact. - */ + public static final class PhysicalLocation { private ArtifactLocation artifactLocation; - /** - * Specifies a portion of the artifact. - */ private Region region; - @java.lang.SuppressWarnings("all") - PhysicalLocation(final ArtifactLocation artifactLocation, final Region region) { + private PhysicalLocation(final ArtifactLocation artifactLocation, final Region region) { this.artifactLocation = artifactLocation; this.region = region; } - @java.lang.SuppressWarnings("all") - public static class PhysicalLocationBuilder { - @java.lang.SuppressWarnings("all") + public static final class PhysicalLocationBuilder { private ArtifactLocation artifactLocation; - @java.lang.SuppressWarnings("all") private Region region; - @java.lang.SuppressWarnings("all") - PhysicalLocationBuilder() { + private PhysicalLocationBuilder() { + // make default ctor private; use factory method PhysicalLocation#builder() instead. } /** * The location of the artifact. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.PhysicalLocation.PhysicalLocationBuilder artifactLocation(final ArtifactLocation artifactLocation) { this.artifactLocation = artifactLocation; return this; @@ -427,27 +313,24 @@ public SarifLog.PhysicalLocation.PhysicalLocationBuilder artifactLocation(final /** * Specifies a portion of the artifact. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.PhysicalLocation.PhysicalLocationBuilder region(final Region region) { this.region = region; return this; } - @java.lang.SuppressWarnings("all") public SarifLog.PhysicalLocation build() { return new SarifLog.PhysicalLocation(this.artifactLocation, this.region); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.PhysicalLocation.PhysicalLocationBuilder(artifactLocation=" + this.artifactLocation + ", region=" + this.region + ")"; } } - @java.lang.SuppressWarnings("all") public static SarifLog.PhysicalLocation.PhysicalLocationBuilder builder() { return new SarifLog.PhysicalLocation.PhysicalLocationBuilder(); } @@ -455,7 +338,6 @@ public static SarifLog.PhysicalLocation.PhysicalLocationBuilder builder() { /** * The location of the artifact. */ - @java.lang.SuppressWarnings("all") public ArtifactLocation getArtifactLocation() { return this.artifactLocation; } @@ -463,16 +345,15 @@ public ArtifactLocation getArtifactLocation() { /** * Specifies a portion of the artifact. */ - @java.lang.SuppressWarnings("all") public Region getRegion() { return this.region; } /** * The location of the artifact. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.PhysicalLocation setArtifactLocation(final ArtifactLocation artifactLocation) { this.artifactLocation = artifactLocation; return this; @@ -480,108 +361,63 @@ public SarifLog.PhysicalLocation setArtifactLocation(final ArtifactLocation arti /** * Specifies a portion of the artifact. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.PhysicalLocation setRegion(final Region region) { this.region = region; return this; } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public boolean equals(final java.lang.Object o) { - if (o == this) { - return true; - } - if (!(o instanceof SarifLog.PhysicalLocation)) { - return false; - } - final SarifLog.PhysicalLocation other = (SarifLog.PhysicalLocation) o; - if (!other.canEqual((java.lang.Object) this)) { - return false; - } - final java.lang.Object this$artifactLocation = this.getArtifactLocation(); - final java.lang.Object other$artifactLocation = other.getArtifactLocation(); - if (this$artifactLocation == null ? other$artifactLocation != null : !this$artifactLocation.equals(other$artifactLocation)) { - return false; - } - final java.lang.Object this$region = this.getRegion(); - final java.lang.Object other$region = other.getRegion(); - if (this$region == null ? other$region != null : !this$region.equals(other$region)) { + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { return false; } - return true; + PhysicalLocation that = (PhysicalLocation) o; + return Objects.equals(artifactLocation, that.artifactLocation) && Objects.equals(region, that.region); } - @java.lang.SuppressWarnings("all") - protected boolean canEqual(final java.lang.Object other) { - return other instanceof SarifLog.PhysicalLocation; + @Override + public int hashCode() { + return Objects.hash(artifactLocation, region); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public int hashCode() { - final int PRIME = 59; - int result = 1; - final java.lang.Object $artifactLocation = this.getArtifactLocation(); - result = result * PRIME + ($artifactLocation == null ? 43 : $artifactLocation.hashCode()); - final java.lang.Object $region = this.getRegion(); - result = result * PRIME + ($region == null ? 43 : $region.hashCode()); - return result; - } - - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.PhysicalLocation(artifactLocation=" + this.getArtifactLocation() + ", region=" + this.getRegion() + ")"; } } - /** * Key/value pairs that provide additional information about the object. */ - public static class PropertyBag { - /** - * The name of the rule set. - */ + public static final class PropertyBag { private String ruleset; - /** - * The pmd priority of the rule. - */ private Integer priority; - /** - * A set of distinct strings that provide additional information. This is SARIF 2.1.0 Schema. - */ private Set tags; - @java.lang.SuppressWarnings("all") - PropertyBag(final String ruleset, final Integer priority, final Set tags) { + private PropertyBag(final String ruleset, final Integer priority, final Set tags) { this.ruleset = ruleset; this.priority = priority; this.tags = tags; } - @java.lang.SuppressWarnings("all") - public static class PropertyBagBuilder { - @java.lang.SuppressWarnings("all") + public static final class PropertyBagBuilder { private String ruleset; - @java.lang.SuppressWarnings("all") private Integer priority; - @java.lang.SuppressWarnings("all") private Set tags; - @java.lang.SuppressWarnings("all") - PropertyBagBuilder() { + private PropertyBagBuilder() { + // make default ctor private; use factoy method PropertyBag#builder() instead. } /** * The name of the rule set. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.PropertyBag.PropertyBagBuilder ruleset(final String ruleset) { this.ruleset = ruleset; return this; @@ -589,9 +425,9 @@ public SarifLog.PropertyBag.PropertyBagBuilder ruleset(final String ruleset) { /** * The pmd priority of the rule. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.PropertyBag.PropertyBagBuilder priority(final Integer priority) { this.priority = priority; return this; @@ -599,27 +435,24 @@ public SarifLog.PropertyBag.PropertyBagBuilder priority(final Integer priority) /** * A set of distinct strings that provide additional information. This is SARIF 2.1.0 Schema. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.PropertyBag.PropertyBagBuilder tags(final Set tags) { this.tags = tags; return this; } - @java.lang.SuppressWarnings("all") public SarifLog.PropertyBag build() { return new SarifLog.PropertyBag(this.ruleset, this.priority, this.tags); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.PropertyBag.PropertyBagBuilder(ruleset=" + this.ruleset + ", priority=" + this.priority + ", tags=" + this.tags + ")"; } } - @java.lang.SuppressWarnings("all") public static SarifLog.PropertyBag.PropertyBagBuilder builder() { return new SarifLog.PropertyBag.PropertyBagBuilder(); } @@ -627,7 +460,6 @@ public static SarifLog.PropertyBag.PropertyBagBuilder builder() { /** * The name of the rule set. */ - @java.lang.SuppressWarnings("all") public String getRuleset() { return this.ruleset; } @@ -635,7 +467,6 @@ public String getRuleset() { /** * The pmd priority of the rule. */ - @java.lang.SuppressWarnings("all") public Integer getPriority() { return this.priority; } @@ -643,16 +474,15 @@ public Integer getPriority() { /** * A set of distinct strings that provide additional information. This is SARIF 2.1.0 Schema. */ - @java.lang.SuppressWarnings("all") public Set getTags() { return this.tags; } /** * The name of the rule set. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.PropertyBag setRuleset(final String ruleset) { this.ruleset = ruleset; return this; @@ -660,9 +490,9 @@ public SarifLog.PropertyBag setRuleset(final String ruleset) { /** * The pmd priority of the rule. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.PropertyBag setPriority(final Integer priority) { this.priority = priority; return this; @@ -670,67 +500,30 @@ public SarifLog.PropertyBag setPriority(final Integer priority) { /** * The set of distinct strings that provide additional information. This is SARIF 2.1.0 Schema. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.PropertyBag setTags(final Set tags) { this.tags = tags; return this; } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public boolean equals(final java.lang.Object o) { - if (o == this) { - return true; - } - if (!(o instanceof SarifLog.PropertyBag)) { - return false; - } - final SarifLog.PropertyBag other = (SarifLog.PropertyBag) o; - if (!other.canEqual((java.lang.Object) this)) { - return false; - } - final java.lang.Object this$ruleset = this.getRuleset(); - final java.lang.Object other$ruleset = other.getRuleset(); - if (this$ruleset == null ? other$ruleset != null : !this$ruleset.equals(other$ruleset)) { - return false; - } - final java.lang.Object this$priority = this.getPriority(); - final java.lang.Object other$priority = other.getPriority(); - if (this$priority == null ? other$priority != null : !this$priority.equals(other$priority)) { - return false; - } - final java.lang.Object this$tags = this.getTags(); - final java.lang.Object other$tags = other.getTags(); - if (this$tags == null ? other$tags != null : !this$tags.equals(other$tags)) { + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { return false; } - return true; + PropertyBag that = (PropertyBag) o; + return Objects.equals(ruleset, that.ruleset) && Objects.equals(priority, that.priority) && Objects.equals(tags, that.tags); } - @java.lang.SuppressWarnings("all") - protected boolean canEqual(final java.lang.Object other) { - return other instanceof SarifLog.PropertyBag; + @Override + public int hashCode() { + return Objects.hash(ruleset, priority, tags); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public int hashCode() { - final int PRIME = 59; - int result = 1; - final java.lang.Object $ruleset = this.getRuleset(); - result = result * PRIME + ($ruleset == null ? 43 : $ruleset.hashCode()); - final java.lang.Object $priority = this.getPriority(); - result = result * PRIME + ($priority == null ? 43 : $priority.hashCode()); - final java.lang.Object $tags = this.getTags(); - result = result * PRIME + ($tags == null ? 43 : $tags.hashCode()); - return result; - } - - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.PropertyBag(ruleset=" + this.getRuleset() + ", priority=" + this.getPriority() + ", tags=" + this.getTags() + ")"; } } @@ -739,26 +532,13 @@ public java.lang.String toString() { /** * A region within an artifact where a result was detected. */ - public static class Region { - /** - * The line number of the first character in the region. - */ + public static final class Region { private Integer startLine; - /** - * The column number of the first character in the region. - */ private Integer startColumn; - /** - * The line number of the last character in the region. - */ private Integer endLine; - /** - * The column number of the character following the end of the region. - */ private Integer endColumn; - @java.lang.SuppressWarnings("all") - Region(final Integer startLine, final Integer startColumn, final Integer endLine, final Integer endColumn) { + private Region(final Integer startLine, final Integer startColumn, final Integer endLine, final Integer endColumn) { this.startLine = startLine; this.startColumn = startColumn; this.endLine = endLine; @@ -766,26 +546,21 @@ public static class Region { } - @java.lang.SuppressWarnings("all") - public static class RegionBuilder { - @java.lang.SuppressWarnings("all") + public static final class RegionBuilder { private Integer startLine; - @java.lang.SuppressWarnings("all") private Integer startColumn; - @java.lang.SuppressWarnings("all") private Integer endLine; - @java.lang.SuppressWarnings("all") private Integer endColumn; - @java.lang.SuppressWarnings("all") - RegionBuilder() { + private RegionBuilder() { + // make default ctor private; use factory method Region#builder() instead. } /** * The line number of the first character in the region. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Region.RegionBuilder startLine(final Integer startLine) { this.startLine = startLine; return this; @@ -793,9 +568,9 @@ public SarifLog.Region.RegionBuilder startLine(final Integer startLine) { /** * The column number of the first character in the region. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Region.RegionBuilder startColumn(final Integer startColumn) { this.startColumn = startColumn; return this; @@ -803,9 +578,9 @@ public SarifLog.Region.RegionBuilder startColumn(final Integer startColumn) { /** * The line number of the last character in the region. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Region.RegionBuilder endLine(final Integer endLine) { this.endLine = endLine; return this; @@ -813,27 +588,24 @@ public SarifLog.Region.RegionBuilder endLine(final Integer endLine) { /** * The column number of the character following the end of the region. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Region.RegionBuilder endColumn(final Integer endColumn) { this.endColumn = endColumn; return this; } - @java.lang.SuppressWarnings("all") public SarifLog.Region build() { return new SarifLog.Region(this.startLine, this.startColumn, this.endLine, this.endColumn); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.Region.RegionBuilder(startLine=" + this.startLine + ", startColumn=" + this.startColumn + ", endLine=" + this.endLine + ", endColumn=" + this.endColumn + ")"; } } - @java.lang.SuppressWarnings("all") public static SarifLog.Region.RegionBuilder builder() { return new SarifLog.Region.RegionBuilder(); } @@ -841,7 +613,6 @@ public static SarifLog.Region.RegionBuilder builder() { /** * The line number of the first character in the region. */ - @java.lang.SuppressWarnings("all") public Integer getStartLine() { return this.startLine; } @@ -849,7 +620,6 @@ public Integer getStartLine() { /** * The column number of the first character in the region. */ - @java.lang.SuppressWarnings("all") public Integer getStartColumn() { return this.startColumn; } @@ -857,7 +627,6 @@ public Integer getStartColumn() { /** * The line number of the last character in the region. */ - @java.lang.SuppressWarnings("all") public Integer getEndLine() { return this.endLine; } @@ -865,16 +634,15 @@ public Integer getEndLine() { /** * The column number of the character following the end of the region. */ - @java.lang.SuppressWarnings("all") public Integer getEndColumn() { return this.endColumn; } /** * The line number of the first character in the region. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Region setStartLine(final Integer startLine) { this.startLine = startLine; return this; @@ -882,9 +650,9 @@ public SarifLog.Region setStartLine(final Integer startLine) { /** * The column number of the first character in the region. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Region setStartColumn(final Integer startColumn) { this.startColumn = startColumn; return this; @@ -892,9 +660,9 @@ public SarifLog.Region setStartColumn(final Integer startColumn) { /** * The line number of the last character in the region. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Region setEndLine(final Integer endLine) { this.endLine = endLine; return this; @@ -902,74 +670,30 @@ public SarifLog.Region setEndLine(final Integer endLine) { /** * The column number of the character following the end of the region. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Region setEndColumn(final Integer endColumn) { this.endColumn = endColumn; return this; } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public boolean equals(final java.lang.Object o) { - if (o == this) { - return true; - } - if (!(o instanceof SarifLog.Region)) { - return false; - } - final SarifLog.Region other = (SarifLog.Region) o; - if (!other.canEqual((java.lang.Object) this)) { - return false; - } - final java.lang.Object this$startLine = this.getStartLine(); - final java.lang.Object other$startLine = other.getStartLine(); - if (this$startLine == null ? other$startLine != null : !this$startLine.equals(other$startLine)) { - return false; - } - final java.lang.Object this$startColumn = this.getStartColumn(); - final java.lang.Object other$startColumn = other.getStartColumn(); - if (this$startColumn == null ? other$startColumn != null : !this$startColumn.equals(other$startColumn)) { - return false; - } - final java.lang.Object this$endLine = this.getEndLine(); - final java.lang.Object other$endLine = other.getEndLine(); - if (this$endLine == null ? other$endLine != null : !this$endLine.equals(other$endLine)) { - return false; - } - final java.lang.Object this$endColumn = this.getEndColumn(); - final java.lang.Object other$endColumn = other.getEndColumn(); - if (this$endColumn == null ? other$endColumn != null : !this$endColumn.equals(other$endColumn)) { + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { return false; } - return true; + Region region = (Region) o; + return Objects.equals(startLine, region.startLine) && Objects.equals(startColumn, region.startColumn) && Objects.equals(endLine, region.endLine) && Objects.equals(endColumn, region.endColumn); } - @java.lang.SuppressWarnings("all") - protected boolean canEqual(final java.lang.Object other) { - return other instanceof SarifLog.Region; + @Override + public int hashCode() { + return Objects.hash(startLine, startColumn, endLine, endColumn); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public int hashCode() { - final int PRIME = 59; - int result = 1; - final java.lang.Object $startLine = this.getStartLine(); - result = result * PRIME + ($startLine == null ? 43 : $startLine.hashCode()); - final java.lang.Object $startColumn = this.getStartColumn(); - result = result * PRIME + ($startColumn == null ? 43 : $startColumn.hashCode()); - final java.lang.Object $endLine = this.getEndLine(); - result = result * PRIME + ($endLine == null ? 43 : $endLine.hashCode()); - final java.lang.Object $endColumn = this.getEndColumn(); - result = result * PRIME + ($endColumn == null ? 43 : $endColumn.hashCode()); - return result; - } - - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.Region(startLine=" + this.getStartLine() + ", startColumn=" + this.getStartColumn() + ", endLine=" + this.getEndLine() + ", endColumn=" + this.getEndColumn() + ")"; } } @@ -978,43 +702,15 @@ public java.lang.String toString() { /** * A result produced by an analysis tool. */ - public static class Result { - - /** - * The stable, unique identifier of the rule, if any, to which this result is relevant. - */ + public static final class Result { private String ruleId; - - /** - * The index link the rule, if any, to which this result is relevant. - */ private Integer ruleIndex; - - /** - * A message that describes the result. The first sentence of the message only will be displayed when visible - * space is limited. - */ private Message message; - - /** - * Specifies the severity level of the result. It is derived from PMD's defined rule priorities (1,2 = error, 3 = warning, 4,5 = note). - * @see net.sourceforge.pmd.lang.rule.RulePriority - */ private String level; - - /** - * The set of locations where the result was detected. Specify only one location unless the problem indicated by - * the result can only be corrected by making a change at every specified location. - */ private List locations; - - /** - * Key/value pairs that provide additional information about the address. - */ private PropertyBag properties; - @java.lang.SuppressWarnings("all") - Result(final String ruleId, final Integer ruleIndex, final Message message, final String level, final List locations, final PropertyBag properties) { + private Result(final String ruleId, final Integer ruleIndex, final Message message, final String level, final List locations, final PropertyBag properties) { this.ruleId = ruleId; this.ruleIndex = ruleIndex; this.message = message; @@ -1024,30 +720,23 @@ public static class Result { } - @java.lang.SuppressWarnings("all") - public static class ResultBuilder { - @java.lang.SuppressWarnings("all") + public static final class ResultBuilder { private String ruleId; - @java.lang.SuppressWarnings("all") private Integer ruleIndex; - @java.lang.SuppressWarnings("all") private Message message; - @SuppressWarnings("all") private String level; - @java.lang.SuppressWarnings("all") private List locations; - @java.lang.SuppressWarnings("all") private PropertyBag properties; - @java.lang.SuppressWarnings("all") - ResultBuilder() { + private ResultBuilder() { + // make default ctor private; use factory method Result#builder() instead. } /** * The stable, unique identifier of the rule, if any, to which this result is relevant. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Result.ResultBuilder ruleId(final String ruleId) { this.ruleId = ruleId; return this; @@ -1055,9 +744,9 @@ public SarifLog.Result.ResultBuilder ruleId(final String ruleId) { /** * The index link the rule, if any, to which this result is relevant. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Result.ResultBuilder ruleIndex(final Integer ruleIndex) { this.ruleIndex = ruleIndex; return this; @@ -1066,9 +755,9 @@ public SarifLog.Result.ResultBuilder ruleIndex(final Integer ruleIndex) { /** * A message that describes the result. The first sentence of the message only will be displayed when visible * space is limited. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Result.ResultBuilder message(final Message message) { this.message = message; return this; @@ -1076,10 +765,10 @@ public SarifLog.Result.ResultBuilder message(final Message message) { /** * Specifies the severity level of the result. It is derived from PMD's defined rule priorities (1,2 = error, 3 = warning, 4,5 = note). + * * @return {@code this}. * @see net.sourceforge.pmd.lang.rule.RulePriority */ - @SuppressWarnings("all") public SarifLog.Result.ResultBuilder level(final String level) { this.level = level; return this; @@ -1088,9 +777,9 @@ public SarifLog.Result.ResultBuilder level(final String level) { /** * The set of locations where the result was detected. Specify only one location unless the problem indicated by * the result can only be corrected by making a change at every specified location. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Result.ResultBuilder locations(final List locations) { this.locations = locations; return this; @@ -1098,27 +787,24 @@ public SarifLog.Result.ResultBuilder locations(final List locations) { /** * Key/value pairs that provide additional information about the address. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Result.ResultBuilder properties(final PropertyBag properties) { this.properties = properties; return this; } - @java.lang.SuppressWarnings("all") public SarifLog.Result build() { return new SarifLog.Result(this.ruleId, this.ruleIndex, this.message, this.level, this.locations, this.properties); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.Result.ResultBuilder(ruleId=" + this.ruleId + ", ruleIndex=" + this.ruleIndex + ", message=" + this.message + ", level=" + this.level + ", locations=" + this.locations + ", properties=" + this.properties + ")"; } } - @java.lang.SuppressWarnings("all") public static SarifLog.Result.ResultBuilder builder() { return new SarifLog.Result.ResultBuilder(); } @@ -1126,7 +812,6 @@ public static SarifLog.Result.ResultBuilder builder() { /** * The stable, unique identifier of the rule, if any, to which this result is relevant. */ - @java.lang.SuppressWarnings("all") public String getRuleId() { return this.ruleId; } @@ -1134,7 +819,6 @@ public String getRuleId() { /** * The index link the rule, if any, to which this result is relevant. */ - @java.lang.SuppressWarnings("all") public Integer getRuleIndex() { return this.ruleIndex; } @@ -1143,16 +827,15 @@ public Integer getRuleIndex() { * A message that describes the result. The first sentence of the message only will be displayed when visible * space is limited. */ - @java.lang.SuppressWarnings("all") public Message getMessage() { return this.message; } /** * Specifies the severity level of the result. It is derived from PMD's defined rule priorities (1,2 = error, 3 = warning, 4,5 = note). + * * @see net.sourceforge.pmd.lang.rule.RulePriority */ - @SuppressWarnings("all") public String getLevel() { return this.level; } @@ -1161,7 +844,6 @@ public String getLevel() { * The set of locations where the result was detected. Specify only one location unless the problem indicated by * the result can only be corrected by making a change at every specified location. */ - @java.lang.SuppressWarnings("all") public List getLocations() { return this.locations; } @@ -1169,16 +851,15 @@ public List getLocations() { /** * Key/value pairs that provide additional information about the address. */ - @java.lang.SuppressWarnings("all") public PropertyBag getProperties() { return this.properties; } /** * The stable, unique identifier of the rule, if any, to which this result is relevant. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Result setRuleId(final String ruleId) { this.ruleId = ruleId; return this; @@ -1186,9 +867,9 @@ public SarifLog.Result setRuleId(final String ruleId) { /** * The index link the rule, if any, to which this result is relevant. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Result setRuleIndex(final Integer ruleIndex) { this.ruleIndex = ruleIndex; return this; @@ -1197,9 +878,9 @@ public SarifLog.Result setRuleIndex(final Integer ruleIndex) { /** * A message that describes the result. The first sentence of the message only will be displayed when visible * space is limited. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Result setMessage(final Message message) { this.message = message; return this; @@ -1207,10 +888,10 @@ public SarifLog.Result setMessage(final Message message) { /** * Specifies the severity level of the result. It is derived from PMD's defined rule priorities (1,2 = error, 3 = warning, 4,5 = note). + * * @return {@code this}. * @see net.sourceforge.pmd.lang.rule.RulePriority */ - @SuppressWarnings("all") public SarifLog.Result setLevel(final String level) { this.level = level; return this; @@ -1219,9 +900,9 @@ public SarifLog.Result setLevel(final String level) { /** * The set of locations where the result was detected. Specify only one location unless the problem indicated by * the result can only be corrected by making a change at every specified location. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Result setLocations(final List locations) { this.locations = locations; return this; @@ -1229,88 +910,30 @@ public SarifLog.Result setLocations(final List locations) { /** * Key/value pairs that provide additional information about the address. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Result setProperties(final PropertyBag properties) { this.properties = properties; return this; } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public boolean equals(final java.lang.Object o) { - if (o == this) { - return true; - } - if (!(o instanceof SarifLog.Result)) { - return false; - } - final SarifLog.Result other = (SarifLog.Result) o; - if (!other.canEqual((java.lang.Object) this)) { - return false; - } - final java.lang.Object this$ruleId = this.getRuleId(); - final java.lang.Object other$ruleId = other.getRuleId(); - if (this$ruleId == null ? other$ruleId != null : !this$ruleId.equals(other$ruleId)) { - return false; - } - final java.lang.Object this$ruleIndex = this.getRuleIndex(); - final java.lang.Object other$ruleIndex = other.getRuleIndex(); - if (this$ruleIndex == null ? other$ruleIndex != null : !this$ruleIndex.equals(other$ruleIndex)) { - return false; - } - final java.lang.Object this$message = this.getMessage(); - final java.lang.Object other$message = other.getMessage(); - if (this$message == null ? other$message != null : !this$message.equals(other$message)) { - return false; - } - final Object this$level = this.getLevel(); - final Object other$level = other.getLevel(); - if (this$level == null ? other$level != null : !this$level.equals(other$level)) { - return false; - } - final java.lang.Object this$locations = this.getLocations(); - final java.lang.Object other$locations = other.getLocations(); - if (this$locations == null ? other$locations != null : !this$locations.equals(other$locations)) { - return false; - } - final java.lang.Object this$properties = this.getProperties(); - final java.lang.Object other$properties = other.getProperties(); - if (this$properties == null ? other$properties != null : !this$properties.equals(other$properties)) { + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { return false; } - return true; + Result result = (Result) o; + return Objects.equals(ruleId, result.ruleId) && Objects.equals(ruleIndex, result.ruleIndex) && Objects.equals(message, result.message) && Objects.equals(level, result.level) && Objects.equals(locations, result.locations) && Objects.equals(properties, result.properties); } - @java.lang.SuppressWarnings("all") - protected boolean canEqual(final java.lang.Object other) { - return other instanceof SarifLog.Result; + @Override + public int hashCode() { + return Objects.hash(ruleId, ruleIndex, message, level, locations, properties); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public int hashCode() { - final int PRIME = 59; - int result = 1; - final java.lang.Object $ruleId = this.getRuleId(); - result = result * PRIME + ($ruleId == null ? 43 : $ruleId.hashCode()); - final java.lang.Object $ruleIndex = this.getRuleIndex(); - result = result * PRIME + ($ruleIndex == null ? 43 : $ruleIndex.hashCode()); - final java.lang.Object $message = this.getMessage(); - result = result * PRIME + ($message == null ? 43 : $message.hashCode()); - final Object $level = this.getLevel(); - result = result * PRIME + ($level == null ? 43 : $level.hashCode()); - final java.lang.Object $locations = this.getLocations(); - result = result * PRIME + ($locations == null ? 43 : $locations.hashCode()); - final java.lang.Object $properties = this.getProperties(); - result = result * PRIME + ($properties == null ? 43 : $properties.hashCode()); - return result; - } - - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.Result(ruleId=" + this.getRuleId() + ", ruleIndex=" + this.getRuleIndex() + ", message=" + this.getMessage() + ", level=" + this.getLevel() + ", locations=" + this.getLocations() + ", properties=" + this.getProperties() + ")"; } } @@ -1319,46 +942,32 @@ public java.lang.String toString() { /** * Encapsulates a message intended to be read by the end user. */ - public static class Message { - /** - * A plain text message string. - */ + public static final class Message { private String text; - /** - * A Markdown message string. - */ private String markdown; - /** - * The identifier for this message. - */ private String id; - @java.lang.SuppressWarnings("all") - Message(final String text, final String markdown, final String id) { + private Message(final String text, final String markdown, final String id) { this.text = text; this.markdown = markdown; this.id = id; } - @java.lang.SuppressWarnings("all") - public static class MessageBuilder { - @java.lang.SuppressWarnings("all") + public static final class MessageBuilder { private String text; - @java.lang.SuppressWarnings("all") private String markdown; - @java.lang.SuppressWarnings("all") private String id; - @java.lang.SuppressWarnings("all") - MessageBuilder() { + private MessageBuilder() { + // make default ctor private; use factory method Message#builder() instead. } /** * A plain text message string. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Message.MessageBuilder text(final String text) { this.text = text; return this; @@ -1366,9 +975,9 @@ public SarifLog.Message.MessageBuilder text(final String text) { /** * A Markdown message string. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Message.MessageBuilder markdown(final String markdown) { this.markdown = markdown; return this; @@ -1376,27 +985,24 @@ public SarifLog.Message.MessageBuilder markdown(final String markdown) { /** * The identifier for this message. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Message.MessageBuilder id(final String id) { this.id = id; return this; } - @java.lang.SuppressWarnings("all") public SarifLog.Message build() { return new SarifLog.Message(this.text, this.markdown, this.id); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.Message.MessageBuilder(text=" + this.text + ", markdown=" + this.markdown + ", id=" + this.id + ")"; } } - @java.lang.SuppressWarnings("all") public static SarifLog.Message.MessageBuilder builder() { return new SarifLog.Message.MessageBuilder(); } @@ -1404,7 +1010,6 @@ public static SarifLog.Message.MessageBuilder builder() { /** * A plain text message string. */ - @java.lang.SuppressWarnings("all") public String getText() { return this.text; } @@ -1412,7 +1017,6 @@ public String getText() { /** * A Markdown message string. */ - @java.lang.SuppressWarnings("all") public String getMarkdown() { return this.markdown; } @@ -1420,16 +1024,15 @@ public String getMarkdown() { /** * The identifier for this message. */ - @java.lang.SuppressWarnings("all") public String getId() { return this.id; } /** * A plain text message string. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Message setText(final String text) { this.text = text; return this; @@ -1437,9 +1040,9 @@ public SarifLog.Message setText(final String text) { /** * A Markdown message string. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Message setMarkdown(final String markdown) { this.markdown = markdown; return this; @@ -1447,67 +1050,30 @@ public SarifLog.Message setMarkdown(final String markdown) { /** * The identifier for this message. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Message setId(final String id) { this.id = id; return this; } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public boolean equals(final java.lang.Object o) { - if (o == this) { - return true; - } - if (!(o instanceof SarifLog.Message)) { - return false; - } - final SarifLog.Message other = (SarifLog.Message) o; - if (!other.canEqual((java.lang.Object) this)) { - return false; - } - final java.lang.Object this$text = this.getText(); - final java.lang.Object other$text = other.getText(); - if (this$text == null ? other$text != null : !this$text.equals(other$text)) { - return false; - } - final java.lang.Object this$markdown = this.getMarkdown(); - final java.lang.Object other$markdown = other.getMarkdown(); - if (this$markdown == null ? other$markdown != null : !this$markdown.equals(other$markdown)) { - return false; - } - final java.lang.Object this$id = this.getId(); - final java.lang.Object other$id = other.getId(); - if (this$id == null ? other$id != null : !this$id.equals(other$id)) { + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { return false; } - return true; + Message message = (Message) o; + return Objects.equals(text, message.text) && Objects.equals(markdown, message.markdown) && Objects.equals(id, message.id); } - @java.lang.SuppressWarnings("all") - protected boolean canEqual(final java.lang.Object other) { - return other instanceof SarifLog.Message; + @Override + public int hashCode() { + return Objects.hash(text, markdown, id); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public int hashCode() { - final int PRIME = 59; - int result = 1; - final java.lang.Object $text = this.getText(); - result = result * PRIME + ($text == null ? 43 : $text.hashCode()); - final java.lang.Object $markdown = this.getMarkdown(); - result = result * PRIME + ($markdown == null ? 43 : $markdown.hashCode()); - final java.lang.Object $id = this.getId(); - result = result * PRIME + ($id == null ? 43 : $id.hashCode()); - return result; - } - - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.Message(text=" + this.getText() + ", markdown=" + this.getMarkdown() + ", id=" + this.getId() + ")"; } } @@ -1516,79 +1082,71 @@ public java.lang.String toString() { /** * Describes a single run of an analysis tool, and contains the reported output of that run. */ - public static class Run { - /** - * Information about the tool or tool pipeline that generated the results in this run. A run can only contain - * results produced by a single tool or tool pipeline. A run can aggregate results from multiple log files, as long - * as context around the tool run (tool command-line arguments and the like) is identical for all aggregated files. - */ + public static final class Run { private Tool tool; - /** - * The set of results contained in an SARIF log. The results array can be omitted when a run is solely exporting - * rules metadata. It must be present (but may be empty) if a log file represents an actual scan. - */ private List results; - /** - * The set of invocations providing information about the tool execution such as configuration errors or runtime - * exceptions - */ private List invocations; - @java.lang.SuppressWarnings("all") - Run(final Tool tool, final List results, final List invocations) { + private Run(final Tool tool, final List results, final List invocations) { this.tool = tool; this.results = results; this.invocations = invocations; } - @java.lang.SuppressWarnings("all") - public static class RunBuilder { - @java.lang.SuppressWarnings("all") + public static final class RunBuilder { private Tool tool; - @java.lang.SuppressWarnings("all") - private java.util.ArrayList results; - @java.lang.SuppressWarnings("all") + private List results; private List invocations; - @java.lang.SuppressWarnings("all") - RunBuilder() { + private RunBuilder() { + // make default ctor private; use factory method Run#builder() instead. } /** * Information about the tool or tool pipeline that generated the results in this run. A run can only contain * results produced by a single tool or tool pipeline. A run can aggregate results from multiple log files, as long * as context around the tool run (tool command-line arguments and the like) is identical for all aggregated files. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Run.RunBuilder tool(final Tool tool) { this.tool = tool; return this; } - @java.lang.SuppressWarnings("all") + /** + * Adds a result to the set of results contained in an SARIF log. The results array can be omitted when + * a run is solely exporting rules metadata. It must be present (but may be empty) if a log file + * represents an actual scan. + * + * @return {@code this}. + */ public SarifLog.Run.RunBuilder result(final Result result) { if (this.results == null) { - this.results = new java.util.ArrayList(); + this.results = new ArrayList<>(); } this.results.add(result); return this; } - @java.lang.SuppressWarnings("all") - public SarifLog.Run.RunBuilder results(final java.util.Collection results) { + /** + * The set of results contained in an SARIF log. The results array can be omitted when a run is solely exporting + * rules metadata. It must be present (but may be empty) if a log file represents an actual scan. + * + * @return {@code this}. + */ + public SarifLog.Run.RunBuilder results(final Collection results) { if (results == null) { throw new java.lang.NullPointerException("results cannot be null"); } if (this.results == null) { - this.results = new java.util.ArrayList(); + this.results = new ArrayList<>(); } this.results.addAll(results); return this; } - @java.lang.SuppressWarnings("all") public SarifLog.Run.RunBuilder clearResults() { if (this.results != null) { this.results.clear(); @@ -1598,39 +1156,36 @@ public SarifLog.Run.RunBuilder clearResults() { /** * The set of invocations providing information about the tool execution such as configuration errors or runtime - * exceptions + * exceptions. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Run.RunBuilder invocations(final List invocations) { this.invocations = invocations; return this; } - @java.lang.SuppressWarnings("all") public SarifLog.Run build() { - java.util.List results; + List results; switch (this.results == null ? 0 : this.results.size()) { case 0: - results = java.util.Collections.emptyList(); + results = Collections.emptyList(); break; case 1: - results = java.util.Collections.singletonList(this.results.get(0)); + results = Collections.singletonList(this.results.get(0)); break; default: - results = java.util.Collections.unmodifiableList(new java.util.ArrayList(this.results)); + results = Collections.unmodifiableList(new ArrayList<>(this.results)); } return new SarifLog.Run(this.tool, results, this.invocations); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.Run.RunBuilder(tool=" + this.tool + ", results=" + this.results + ", invocations=" + this.invocations + ")"; } } - @java.lang.SuppressWarnings("all") public static SarifLog.Run.RunBuilder builder() { return new SarifLog.Run.RunBuilder(); } @@ -1640,7 +1195,6 @@ public static SarifLog.Run.RunBuilder builder() { * results produced by a single tool or tool pipeline. A run can aggregate results from multiple log files, as long * as context around the tool run (tool command-line arguments and the like) is identical for all aggregated files. */ - @java.lang.SuppressWarnings("all") public Tool getTool() { return this.tool; } @@ -1649,16 +1203,14 @@ public Tool getTool() { * The set of results contained in an SARIF log. The results array can be omitted when a run is solely exporting * rules metadata. It must be present (but may be empty) if a log file represents an actual scan. */ - @java.lang.SuppressWarnings("all") public List getResults() { return this.results; } /** * The set of invocations providing information about the tool execution such as configuration errors or runtime - * exceptions + * exceptions. */ - @java.lang.SuppressWarnings("all") public List getInvocations() { return this.invocations; } @@ -1667,9 +1219,9 @@ public List getInvocations() { * Information about the tool or tool pipeline that generated the results in this run. A run can only contain * results produced by a single tool or tool pipeline. A run can aggregate results from multiple log files, as long * as context around the tool run (tool command-line arguments and the like) is identical for all aggregated files. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Run setTool(final Tool tool) { this.tool = tool; return this; @@ -1678,9 +1230,9 @@ public SarifLog.Run setTool(final Tool tool) { /** * The set of results contained in an SARIF log. The results array can be omitted when a run is solely exporting * rules metadata. It must be present (but may be empty) if a log file represents an actual scan. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Run setResults(final List results) { this.results = results; return this; @@ -1688,68 +1240,31 @@ public SarifLog.Run setResults(final List results) { /** * The set of invocations providing information about the tool execution such as configuration errors or runtime - * exceptions + * exceptions. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Run setInvocations(final List invocations) { this.invocations = invocations; return this; } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public boolean equals(final java.lang.Object o) { - if (o == this) { - return true; - } - if (!(o instanceof SarifLog.Run)) { - return false; - } - final SarifLog.Run other = (SarifLog.Run) o; - if (!other.canEqual((java.lang.Object) this)) { - return false; - } - final java.lang.Object this$tool = this.getTool(); - final java.lang.Object other$tool = other.getTool(); - if (this$tool == null ? other$tool != null : !this$tool.equals(other$tool)) { - return false; - } - final java.lang.Object this$results = this.getResults(); - final java.lang.Object other$results = other.getResults(); - if (this$results == null ? other$results != null : !this$results.equals(other$results)) { - return false; - } - final java.lang.Object this$invocations = this.getInvocations(); - final java.lang.Object other$invocations = other.getInvocations(); - if (this$invocations == null ? other$invocations != null : !this$invocations.equals(other$invocations)) { + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { return false; } - return true; + Run run = (Run) o; + return Objects.equals(tool, run.tool) && Objects.equals(results, run.results) && Objects.equals(invocations, run.invocations); } - @java.lang.SuppressWarnings("all") - protected boolean canEqual(final java.lang.Object other) { - return other instanceof SarifLog.Run; + @Override + public int hashCode() { + return Objects.hash(tool, results, invocations); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public int hashCode() { - final int PRIME = 59; - int result = 1; - final java.lang.Object $tool = this.getTool(); - result = result * PRIME + ($tool == null ? 43 : $tool.hashCode()); - final java.lang.Object $results = this.getResults(); - result = result * PRIME + ($results == null ? 43 : $results.hashCode()); - final java.lang.Object $invocations = this.getInvocations(); - result = result * PRIME + ($invocations == null ? 43 : $invocations.hashCode()); - return result; - } - - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.Run(tool=" + this.getTool() + ", results=" + this.getResults() + ", invocations=" + this.getInvocations() + ")"; } } @@ -1758,50 +1273,41 @@ public java.lang.String toString() { /** * The analysis tool that was run. */ - public static class Tool { - /** - * The analysis tool that was run. - */ + public static final class Tool { private Component driver; - @java.lang.SuppressWarnings("all") - Tool(final Component driver) { + private Tool(final Component driver) { this.driver = driver; } - @java.lang.SuppressWarnings("all") - public static class ToolBuilder { - @java.lang.SuppressWarnings("all") + public static final class ToolBuilder { private Component driver; - @java.lang.SuppressWarnings("all") - ToolBuilder() { + private ToolBuilder() { + // make default ctor private; use factory method Tool#builder() instead. } /** * The analysis tool that was run. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Tool.ToolBuilder driver(final Component driver) { this.driver = driver; return this; } - @java.lang.SuppressWarnings("all") public SarifLog.Tool build() { return new SarifLog.Tool(this.driver); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.Tool.ToolBuilder(driver=" + this.driver + ")"; } } - @java.lang.SuppressWarnings("all") public static SarifLog.Tool.ToolBuilder builder() { return new SarifLog.Tool.ToolBuilder(); } @@ -1809,60 +1315,36 @@ public static SarifLog.Tool.ToolBuilder builder() { /** * The analysis tool that was run. */ - @java.lang.SuppressWarnings("all") public Component getDriver() { return this.driver; } /** * The analysis tool that was run. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Tool setDriver(final Component driver) { this.driver = driver; return this; } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public boolean equals(final java.lang.Object o) { - if (o == this) { - return true; - } - if (!(o instanceof SarifLog.Tool)) { - return false; - } - final SarifLog.Tool other = (SarifLog.Tool) o; - if (!other.canEqual((java.lang.Object) this)) { - return false; - } - final java.lang.Object this$driver = this.getDriver(); - final java.lang.Object other$driver = other.getDriver(); - if (this$driver == null ? other$driver != null : !this$driver.equals(other$driver)) { + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { return false; } - return true; - } - - @java.lang.SuppressWarnings("all") - protected boolean canEqual(final java.lang.Object other) { - return other instanceof SarifLog.Tool; + Tool tool = (Tool) o; + return Objects.equals(driver, tool.driver); } - @java.lang.Override - @java.lang.SuppressWarnings("all") + @Override public int hashCode() { - final int PRIME = 59; - int result = 1; - final java.lang.Object $driver = this.getDriver(); - result = result * PRIME + ($driver == null ? 43 : $driver.hashCode()); - return result; + return Objects.hashCode(driver); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.Tool(driver=" + this.getDriver() + ")"; } } @@ -1871,53 +1353,34 @@ public java.lang.String toString() { /** * A component, such as a plug-in or the driver, of the analysis tool that was run. */ - public static class Component { - /** - * The name of the tool component. - */ + public static final class Component { private String name; - /** - * The tool component version, in whatever format the component natively provides. - */ private String version; - /** - * The absolute URI at which information about this version of the tool component can be found. - */ private String informationUri; - /** - * An array of reportingDescriptor objects relevant to the analysis performed by the tool component. - */ private List rules; - @java.lang.SuppressWarnings("all") - Component(final String name, final String version, final String informationUri, final List rules) { + private Component(final String name, final String version, final String informationUri, final List rules) { this.name = name; this.version = version; this.informationUri = informationUri; this.rules = rules; } - - @java.lang.SuppressWarnings("all") - public static class ComponentBuilder { - @java.lang.SuppressWarnings("all") + public static final class ComponentBuilder { private String name; - @java.lang.SuppressWarnings("all") private String version; - @java.lang.SuppressWarnings("all") private String informationUri; - @java.lang.SuppressWarnings("all") private List rules; - @java.lang.SuppressWarnings("all") - ComponentBuilder() { + private ComponentBuilder() { + // make default ctor private; use factory method Component#builder() instead. } /** * The name of the tool component. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Component.ComponentBuilder name(final String name) { this.name = name; return this; @@ -1925,9 +1388,9 @@ public SarifLog.Component.ComponentBuilder name(final String name) { /** * The tool component version, in whatever format the component natively provides. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Component.ComponentBuilder version(final String version) { this.version = version; return this; @@ -1935,9 +1398,9 @@ public SarifLog.Component.ComponentBuilder version(final String version) { /** * The absolute URI at which information about this version of the tool component can be found. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Component.ComponentBuilder informationUri(final String informationUri) { this.informationUri = informationUri; return this; @@ -1945,32 +1408,28 @@ public SarifLog.Component.ComponentBuilder informationUri(final String informati /** * An array of reportingDescriptor objects relevant to the analysis performed by the tool component. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Component.ComponentBuilder rules(final List rules) { this.rules = rules; return this; } - @java.lang.SuppressWarnings("all") public SarifLog.Component build() { return new SarifLog.Component(this.name, this.version, this.informationUri, this.rules); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.Component.ComponentBuilder(name=" + this.name + ", version=" + this.version + ", informationUri=" + this.informationUri + ", rules=" + this.rules + ")"; } } - @java.lang.SuppressWarnings("all") public static SarifLog.Component.ComponentBuilder builder() { return new SarifLog.Component.ComponentBuilder(); } - @java.lang.SuppressWarnings("all") public SarifLog.Component.ComponentBuilder toBuilder() { return new SarifLog.Component.ComponentBuilder().name(this.name).version(this.version).informationUri(this.informationUri).rules(this.rules); } @@ -1978,7 +1437,6 @@ public SarifLog.Component.ComponentBuilder toBuilder() { /** * The name of the tool component. */ - @java.lang.SuppressWarnings("all") public String getName() { return this.name; } @@ -1986,7 +1444,6 @@ public String getName() { /** * The tool component version, in whatever format the component natively provides. */ - @java.lang.SuppressWarnings("all") public String getVersion() { return this.version; } @@ -1994,7 +1451,6 @@ public String getVersion() { /** * The absolute URI at which information about this version of the tool component can be found. */ - @java.lang.SuppressWarnings("all") public String getInformationUri() { return this.informationUri; } @@ -2002,16 +1458,15 @@ public String getInformationUri() { /** * An array of reportingDescriptor objects relevant to the analysis performed by the tool component. */ - @java.lang.SuppressWarnings("all") public List getRules() { return this.rules; } /** * The name of the tool component. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Component setName(final String name) { this.name = name; return this; @@ -2019,9 +1474,9 @@ public SarifLog.Component setName(final String name) { /** * The tool component version, in whatever format the component natively provides. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Component setVersion(final String version) { this.version = version; return this; @@ -2029,9 +1484,9 @@ public SarifLog.Component setVersion(final String version) { /** * The absolute URI at which information about this version of the tool component can be found. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Component setInformationUri(final String informationUri) { this.informationUri = informationUri; return this; @@ -2039,74 +1494,30 @@ public SarifLog.Component setInformationUri(final String informationUri) { /** * An array of reportingDescriptor objects relevant to the analysis performed by the tool component. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Component setRules(final List rules) { this.rules = rules; return this; } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public boolean equals(final java.lang.Object o) { - if (o == this) { - return true; - } - if (!(o instanceof SarifLog.Component)) { - return false; - } - final SarifLog.Component other = (SarifLog.Component) o; - if (!other.canEqual((java.lang.Object) this)) { - return false; - } - final java.lang.Object this$name = this.getName(); - final java.lang.Object other$name = other.getName(); - if (this$name == null ? other$name != null : !this$name.equals(other$name)) { - return false; - } - final java.lang.Object this$version = this.getVersion(); - final java.lang.Object other$version = other.getVersion(); - if (this$version == null ? other$version != null : !this$version.equals(other$version)) { - return false; - } - final java.lang.Object this$informationUri = this.getInformationUri(); - final java.lang.Object other$informationUri = other.getInformationUri(); - if (this$informationUri == null ? other$informationUri != null : !this$informationUri.equals(other$informationUri)) { - return false; - } - final java.lang.Object this$rules = this.getRules(); - final java.lang.Object other$rules = other.getRules(); - if (this$rules == null ? other$rules != null : !this$rules.equals(other$rules)) { + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { return false; } - return true; + Component component = (Component) o; + return Objects.equals(name, component.name) && Objects.equals(version, component.version) && Objects.equals(informationUri, component.informationUri) && Objects.equals(rules, component.rules); } - @java.lang.SuppressWarnings("all") - protected boolean canEqual(final java.lang.Object other) { - return other instanceof SarifLog.Component; + @Override + public int hashCode() { + return Objects.hash(name, version, informationUri, rules); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public int hashCode() { - final int PRIME = 59; - int result = 1; - final java.lang.Object $name = this.getName(); - result = result * PRIME + ($name == null ? 43 : $name.hashCode()); - final java.lang.Object $version = this.getVersion(); - result = result * PRIME + ($version == null ? 43 : $version.hashCode()); - final java.lang.Object $informationUri = this.getInformationUri(); - result = result * PRIME + ($informationUri == null ? 43 : $informationUri.hashCode()); - final java.lang.Object $rules = this.getRules(); - result = result * PRIME + ($rules == null ? 43 : $rules.hashCode()); - return result; - } - - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.Component(name=" + this.getName() + ", version=" + this.getVersion() + ", informationUri=" + this.getInformationUri() + ", rules=" + this.getRules() + ")"; } } @@ -2116,50 +1527,18 @@ public java.lang.String toString() { * Metadata that describes a specific report produced by the tool, as part of the analysis it provides or its runtime * reporting. */ - public static class ReportingDescriptor { - /** - * A stable, opaque identifier for the report. - */ + public static final class ReportingDescriptor { private String id; - /** - * A report identifier that is understandable to an end user. - */ private String name; - /** - * A concise description of the report. Should be a single sentence that is understandable when visible space is - * limited to a single line of text. - */ private MultiformatMessage shortDescription; - /** - * A description of the report. Should, as far as possible, provide details sufficient to enable resolution of any - * problem indicated by the result. - */ private MultiformatMessage fullDescription; - /** - * A set of name/value pairs with arbitrary names. Each value is a multiformatMessageString object, which holds - * message strings in plain text and (optionally) Markdown format. The strings can include placeholders, which can - * be used to construct a message in combination with an arbitrary number of additional string arguments. - */ private MultiformatMessage messageStrings; - /** - * A URI where the primary documentation for the report can be found. - */ private String helpUri; - /** - * Provides the primary documentation for the report, useful when there is no online documentation. - */ private MultiformatMessage help; - /** - * Key/value pairs that provide additional information about the report. - */ private PropertyBag properties; - /** - * The default configuration of a rule, can contain a default level and other properties. - */ private ReportingConfiguration defaultConfiguration; - @java.lang.SuppressWarnings("all") - ReportingDescriptor(final String id, final String name, final MultiformatMessage shortDescription, final MultiformatMessage fullDescription, final MultiformatMessage messageStrings, final String helpUri, final MultiformatMessage help, final PropertyBag properties, final ReportingConfiguration defaultConfiguration) { + private ReportingDescriptor(final String id, final String name, final MultiformatMessage shortDescription, final MultiformatMessage fullDescription, final MultiformatMessage messageStrings, final String helpUri, final MultiformatMessage help, final PropertyBag properties, final ReportingConfiguration defaultConfiguration) { this.id = id; this.name = name; this.shortDescription = shortDescription; @@ -2172,36 +1551,26 @@ public static class ReportingDescriptor { } - @java.lang.SuppressWarnings("all") - public static class ReportingDescriptorBuilder { - @java.lang.SuppressWarnings("all") + public static final class ReportingDescriptorBuilder { private String id; - @java.lang.SuppressWarnings("all") private String name; - @java.lang.SuppressWarnings("all") private MultiformatMessage shortDescription; - @java.lang.SuppressWarnings("all") private MultiformatMessage fullDescription; - @java.lang.SuppressWarnings("all") private MultiformatMessage messageStrings; - @java.lang.SuppressWarnings("all") private String helpUri; - @java.lang.SuppressWarnings("all") private MultiformatMessage help; - @java.lang.SuppressWarnings("all") private PropertyBag properties; - @SuppressWarnings("all") private ReportingConfiguration defaultConfiguration; - @java.lang.SuppressWarnings("all") - ReportingDescriptorBuilder() { + private ReportingDescriptorBuilder() { + // make default ctor private; use factory method ReportingDescriptor#builder() instead. } /** * A stable, opaque identifier for the report. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ReportingDescriptor.ReportingDescriptorBuilder id(final String id) { this.id = id; return this; @@ -2209,9 +1578,9 @@ public SarifLog.ReportingDescriptor.ReportingDescriptorBuilder id(final String i /** * A report identifier that is understandable to an end user. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ReportingDescriptor.ReportingDescriptorBuilder name(final String name) { this.name = name; return this; @@ -2220,9 +1589,9 @@ public SarifLog.ReportingDescriptor.ReportingDescriptorBuilder name(final String /** * A concise description of the report. Should be a single sentence that is understandable when visible space is * limited to a single line of text. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ReportingDescriptor.ReportingDescriptorBuilder shortDescription(final MultiformatMessage shortDescription) { this.shortDescription = shortDescription; return this; @@ -2231,9 +1600,9 @@ public SarifLog.ReportingDescriptor.ReportingDescriptorBuilder shortDescription( /** * A description of the report. Should, as far as possible, provide details sufficient to enable resolution of any * problem indicated by the result. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ReportingDescriptor.ReportingDescriptorBuilder fullDescription(final MultiformatMessage fullDescription) { this.fullDescription = fullDescription; return this; @@ -2243,9 +1612,9 @@ public SarifLog.ReportingDescriptor.ReportingDescriptorBuilder fullDescription(f * A set of name/value pairs with arbitrary names. Each value is a multiformatMessageString object, which holds * message strings in plain text and (optionally) Markdown format. The strings can include placeholders, which can * be used to construct a message in combination with an arbitrary number of additional string arguments. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ReportingDescriptor.ReportingDescriptorBuilder messageStrings(final MultiformatMessage messageStrings) { this.messageStrings = messageStrings; return this; @@ -2253,9 +1622,9 @@ public SarifLog.ReportingDescriptor.ReportingDescriptorBuilder messageStrings(fi /** * A URI where the primary documentation for the report can be found. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ReportingDescriptor.ReportingDescriptorBuilder helpUri(final String helpUri) { this.helpUri = helpUri; return this; @@ -2263,9 +1632,9 @@ public SarifLog.ReportingDescriptor.ReportingDescriptorBuilder helpUri(final Str /** * Provides the primary documentation for the report, useful when there is no online documentation. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ReportingDescriptor.ReportingDescriptorBuilder help(final MultiformatMessage help) { this.help = help; return this; @@ -2273,9 +1642,9 @@ public SarifLog.ReportingDescriptor.ReportingDescriptorBuilder help(final Multif /** * Key/value pairs that provide additional information about the report. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ReportingDescriptor.ReportingDescriptorBuilder properties(final PropertyBag properties) { this.properties = properties; return this; @@ -2283,6 +1652,7 @@ public SarifLog.ReportingDescriptor.ReportingDescriptorBuilder properties(final /** * The default configuration of a rule, can contain a default level and other properties. + * * @return {@code this}. */ public SarifLog.ReportingDescriptor.ReportingDescriptorBuilder defaultConfiguration(final ReportingConfiguration defaultConfiguration) { @@ -2290,19 +1660,16 @@ public SarifLog.ReportingDescriptor.ReportingDescriptorBuilder defaultConfigurat return this; } - @java.lang.SuppressWarnings("all") public SarifLog.ReportingDescriptor build() { return new SarifLog.ReportingDescriptor(this.id, this.name, this.shortDescription, this.fullDescription, this.messageStrings, this.helpUri, this.help, this.properties, this.defaultConfiguration); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.ReportingDescriptor.ReportingDescriptorBuilder(id=" + this.id + ", name=" + this.name + ", shortDescription=" + this.shortDescription + ", fullDescription=" + this.fullDescription + ", messageStrings=" + this.messageStrings + ", helpUri=" + this.helpUri + ", help=" + this.help + ", properties=" + this.properties + ", defaultConfiguration=" + this.defaultConfiguration + ")"; } } - @java.lang.SuppressWarnings("all") public static SarifLog.ReportingDescriptor.ReportingDescriptorBuilder builder() { return new SarifLog.ReportingDescriptor.ReportingDescriptorBuilder(); } @@ -2310,7 +1677,6 @@ public static SarifLog.ReportingDescriptor.ReportingDescriptorBuilder builder() /** * A stable, opaque identifier for the report. */ - @java.lang.SuppressWarnings("all") public String getId() { return this.id; } @@ -2318,7 +1684,6 @@ public String getId() { /** * A report identifier that is understandable to an end user. */ - @java.lang.SuppressWarnings("all") public String getName() { return this.name; } @@ -2327,7 +1692,6 @@ public String getName() { * A concise description of the report. Should be a single sentence that is understandable when visible space is * limited to a single line of text. */ - @java.lang.SuppressWarnings("all") public MultiformatMessage getShortDescription() { return this.shortDescription; } @@ -2336,7 +1700,6 @@ public MultiformatMessage getShortDescription() { * A description of the report. Should, as far as possible, provide details sufficient to enable resolution of any * problem indicated by the result. */ - @java.lang.SuppressWarnings("all") public MultiformatMessage getFullDescription() { return this.fullDescription; } @@ -2346,7 +1709,6 @@ public MultiformatMessage getFullDescription() { * message strings in plain text and (optionally) Markdown format. The strings can include placeholders, which can * be used to construct a message in combination with an arbitrary number of additional string arguments. */ - @java.lang.SuppressWarnings("all") public MultiformatMessage getMessageStrings() { return this.messageStrings; } @@ -2354,7 +1716,6 @@ public MultiformatMessage getMessageStrings() { /** * A URI where the primary documentation for the report can be found. */ - @java.lang.SuppressWarnings("all") public String getHelpUri() { return this.helpUri; } @@ -2362,7 +1723,6 @@ public String getHelpUri() { /** * Provides the primary documentation for the report, useful when there is no online documentation. */ - @java.lang.SuppressWarnings("all") public MultiformatMessage getHelp() { return this.help; } @@ -2370,7 +1730,6 @@ public MultiformatMessage getHelp() { /** * Key/value pairs that provide additional information about the report. */ - @java.lang.SuppressWarnings("all") public PropertyBag getProperties() { return this.properties; } @@ -2378,16 +1737,15 @@ public PropertyBag getProperties() { /** * The default configuration of a rule, can contain a default level and other properties. */ - @SuppressWarnings("all") public ReportingConfiguration getDefaultConfiguration() { return this.defaultConfiguration; } /** * A stable, opaque identifier for the report. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ReportingDescriptor setId(final String id) { this.id = id; return this; @@ -2395,9 +1753,9 @@ public SarifLog.ReportingDescriptor setId(final String id) { /** * A report identifier that is understandable to an end user. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ReportingDescriptor setName(final String name) { this.name = name; return this; @@ -2406,9 +1764,9 @@ public SarifLog.ReportingDescriptor setName(final String name) { /** * A concise description of the report. Should be a single sentence that is understandable when visible space is * limited to a single line of text. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ReportingDescriptor setShortDescription(final MultiformatMessage shortDescription) { this.shortDescription = shortDescription; return this; @@ -2417,9 +1775,9 @@ public SarifLog.ReportingDescriptor setShortDescription(final MultiformatMessage /** * A description of the report. Should, as far as possible, provide details sufficient to enable resolution of any * problem indicated by the result. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ReportingDescriptor setFullDescription(final MultiformatMessage fullDescription) { this.fullDescription = fullDescription; return this; @@ -2429,9 +1787,9 @@ public SarifLog.ReportingDescriptor setFullDescription(final MultiformatMessage * A set of name/value pairs with arbitrary names. Each value is a multiformatMessageString object, which holds * message strings in plain text and (optionally) Markdown format. The strings can include placeholders, which can * be used to construct a message in combination with an arbitrary number of additional string arguments. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ReportingDescriptor setMessageStrings(final MultiformatMessage messageStrings) { this.messageStrings = messageStrings; return this; @@ -2439,9 +1797,9 @@ public SarifLog.ReportingDescriptor setMessageStrings(final MultiformatMessage m /** * A URI where the primary documentation for the report can be found. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ReportingDescriptor setHelpUri(final String helpUri) { this.helpUri = helpUri; return this; @@ -2449,9 +1807,9 @@ public SarifLog.ReportingDescriptor setHelpUri(final String helpUri) { /** * Provides the primary documentation for the report, useful when there is no online documentation. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ReportingDescriptor setHelp(final MultiformatMessage help) { this.help = help; return this; @@ -2459,9 +1817,9 @@ public SarifLog.ReportingDescriptor setHelp(final MultiformatMessage help) { /** * Key/value pairs that provide additional information about the report. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ReportingDescriptor setProperties(final PropertyBag properties) { this.properties = properties; return this; @@ -2469,109 +1827,30 @@ public SarifLog.ReportingDescriptor setProperties(final PropertyBag properties) /** * The default configuration of a rule, can contain a default level and other properties. + * * @return {@code this}. */ - @SuppressWarnings("all") public SarifLog.ReportingDescriptor setDefaultConfiguration(final ReportingConfiguration defaultConfiguration) { this.defaultConfiguration = defaultConfiguration; return this; } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public boolean equals(final java.lang.Object o) { - if (o == this) { - return true; - } - if (!(o instanceof SarifLog.ReportingDescriptor)) { - return false; - } - final SarifLog.ReportingDescriptor other = (SarifLog.ReportingDescriptor) o; - if (!other.canEqual((java.lang.Object) this)) { - return false; - } - final java.lang.Object this$id = this.getId(); - final java.lang.Object other$id = other.getId(); - if (this$id == null ? other$id != null : !this$id.equals(other$id)) { - return false; - } - final java.lang.Object this$name = this.getName(); - final java.lang.Object other$name = other.getName(); - if (this$name == null ? other$name != null : !this$name.equals(other$name)) { - return false; - } - final java.lang.Object this$shortDescription = this.getShortDescription(); - final java.lang.Object other$shortDescription = other.getShortDescription(); - if (this$shortDescription == null ? other$shortDescription != null : !this$shortDescription.equals(other$shortDescription)) { - return false; - } - final java.lang.Object this$fullDescription = this.getFullDescription(); - final java.lang.Object other$fullDescription = other.getFullDescription(); - if (this$fullDescription == null ? other$fullDescription != null : !this$fullDescription.equals(other$fullDescription)) { - return false; - } - final java.lang.Object this$messageStrings = this.getMessageStrings(); - final java.lang.Object other$messageStrings = other.getMessageStrings(); - if (this$messageStrings == null ? other$messageStrings != null : !this$messageStrings.equals(other$messageStrings)) { - return false; - } - final java.lang.Object this$helpUri = this.getHelpUri(); - final java.lang.Object other$helpUri = other.getHelpUri(); - if (this$helpUri == null ? other$helpUri != null : !this$helpUri.equals(other$helpUri)) { - return false; - } - final java.lang.Object this$help = this.getHelp(); - final java.lang.Object other$help = other.getHelp(); - if (this$help == null ? other$help != null : !this$help.equals(other$help)) { - return false; - } - final java.lang.Object this$properties = this.getProperties(); - final java.lang.Object other$properties = other.getProperties(); - if (this$properties == null ? other$properties != null : !this$properties.equals(other$properties)) { - return false; - } - final Object this$defaultConfiguration = this.getDefaultConfiguration(); - final Object other$defaultConfiguration = other.getDefaultConfiguration(); - if (this$defaultConfiguration == null ? other$defaultConfiguration != null : !this$defaultConfiguration.equals(other$defaultConfiguration)) { + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { return false; } - return true; + ReportingDescriptor that = (ReportingDescriptor) o; + return Objects.equals(id, that.id) && Objects.equals(name, that.name) && Objects.equals(shortDescription, that.shortDescription) && Objects.equals(fullDescription, that.fullDescription) && Objects.equals(messageStrings, that.messageStrings) && Objects.equals(helpUri, that.helpUri) && Objects.equals(help, that.help) && Objects.equals(properties, that.properties) && Objects.equals(defaultConfiguration, that.defaultConfiguration); } - @java.lang.SuppressWarnings("all") - protected boolean canEqual(final java.lang.Object other) { - return other instanceof SarifLog.ReportingDescriptor; + @Override + public int hashCode() { + return Objects.hash(id, name, shortDescription, fullDescription, messageStrings, helpUri, help, properties, defaultConfiguration); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public int hashCode() { - final int PRIME = 59; - int result = 1; - final java.lang.Object $id = this.getId(); - result = result * PRIME + ($id == null ? 43 : $id.hashCode()); - final java.lang.Object $name = this.getName(); - result = result * PRIME + ($name == null ? 43 : $name.hashCode()); - final java.lang.Object $shortDescription = this.getShortDescription(); - result = result * PRIME + ($shortDescription == null ? 43 : $shortDescription.hashCode()); - final java.lang.Object $fullDescription = this.getFullDescription(); - result = result * PRIME + ($fullDescription == null ? 43 : $fullDescription.hashCode()); - final java.lang.Object $messageStrings = this.getMessageStrings(); - result = result * PRIME + ($messageStrings == null ? 43 : $messageStrings.hashCode()); - final java.lang.Object $helpUri = this.getHelpUri(); - result = result * PRIME + ($helpUri == null ? 43 : $helpUri.hashCode()); - final java.lang.Object $help = this.getHelp(); - result = result * PRIME + ($help == null ? 43 : $help.hashCode()); - final java.lang.Object $properties = this.getProperties(); - result = result * PRIME + ($properties == null ? 43 : $properties.hashCode()); - final Object $defaultConfiguration = this.getDefaultConfiguration(); - result = result * PRIME + ($defaultConfiguration == null ? 43 : $defaultConfiguration.hashCode()); - return result; - } - - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.ReportingDescriptor(id=" + this.getId() + ", name=" + this.getName() + ", shortDescription=" + this.getShortDescription() + ", fullDescription=" + this.getFullDescription() + ", messageStrings=" + this.getMessageStrings() + ", helpUri=" + this.getHelpUri() + ", help=" + this.getHelp() + ", properties=" + this.getProperties() + ", defaultConfiguration=" + this.getDefaultConfiguration() + ")"; } } @@ -2582,60 +1861,34 @@ public java.lang.String toString() { * Can be used as the defaultConfiguration of a reportingDescriptor. * Can also be used in configurationOverride to override those defaults. */ - public static class ReportingConfiguration { - - - /** - * Boolean, to dis- and enable the config based on matching a rule (through the Descriptor). - * Default: true. - */ + public static final class ReportingConfiguration { private Boolean enabled; - - /** - * Takes the levelProperty of the Descriptor (if present) or provides a default/override. - * Default: warning. - */ private String level; - - /** - * Takes the rank/priority of the Descriptor (if present) or provides a default/override value between 1.0 and 100.0. - * Default: -1.0. - */ private Double rank; - - /** - * Define configuration information (propertyBag) specific to the Descriptor. - */ private PropertyBag parameters; - @SuppressWarnings("all") - ReportingConfiguration(final Boolean enabled, final String level, final Double rank, final PropertyBag parameters) { + private ReportingConfiguration(final Boolean enabled, final String level, final Double rank, final PropertyBag parameters) { this.enabled = enabled; this.level = level; this.rank = rank; this.parameters = parameters; } - - @SuppressWarnings("all") - public static class ReportingConfigurationBuilder { - @SuppressWarnings("all") + public static final class ReportingConfigurationBuilder { private Boolean enabled; - @SuppressWarnings("all") private String level; - @SuppressWarnings("all") private Double rank; - @SuppressWarnings("all") private PropertyBag parameters; - @SuppressWarnings("all") - ReportingConfigurationBuilder() { + private ReportingConfigurationBuilder() { + // make default ctor private; use factory method ReportingConfiguration#builder() instead. } /** * Boolean, to dis- and enable the config based on matching a rule (through the Descriptor). + * + *

    Default: true */ - @SuppressWarnings("all") public SarifLog.ReportingConfiguration.ReportingConfigurationBuilder enabled(final Boolean enabled) { this.enabled = enabled; return this; @@ -2643,8 +1896,9 @@ public SarifLog.ReportingConfiguration.ReportingConfigurationBuilder enabled(fin /** * Takes the levelProperty of the Descriptor (if present) or provides a default/override. + * + *

    Default: warning */ - @SuppressWarnings("all") public SarifLog.ReportingConfiguration.ReportingConfigurationBuilder level(final String level) { this.level = level; return this; @@ -2652,8 +1906,9 @@ public SarifLog.ReportingConfiguration.ReportingConfigurationBuilder level(final /** * Takes the rank/priority of the Descriptor (if present) or provides a default/override value between 1.0 and 100.0. + * + *

    Default: -1.0 */ - @SuppressWarnings("all") public SarifLog.ReportingConfiguration.ReportingConfigurationBuilder rank(final Double rank) { this.rank = rank; return this; @@ -2662,25 +1917,21 @@ public SarifLog.ReportingConfiguration.ReportingConfigurationBuilder rank(final /** * Define configuration information (propertyBag) specific to the Descriptor. */ - @SuppressWarnings("all") public SarifLog.ReportingConfiguration.ReportingConfigurationBuilder parameters(final PropertyBag parameters) { this.parameters = parameters; return this; } - @SuppressWarnings("all") public SarifLog.ReportingConfiguration build() { return new SarifLog.ReportingConfiguration(this.enabled, this.level, this.rank, this.parameters); } @Override - @SuppressWarnings("all") public String toString() { return "SarifLog.ReportingConfiguration.ReportingConfigurationBuilder(enabled=" + this.enabled + ", level=" + this.level + ", rank=" + this.rank + ", parameters=" + this.parameters + ")"; } } - @SuppressWarnings("all") public static SarifLog.ReportingConfiguration.ReportingConfigurationBuilder builder() { return new SarifLog.ReportingConfiguration.ReportingConfigurationBuilder(); } @@ -2688,7 +1939,6 @@ public static SarifLog.ReportingConfiguration.ReportingConfigurationBuilder buil /** * Boolean, to dis- and enable the config based on matching a rule (through the Descriptor). */ - @SuppressWarnings("all") public Boolean getEnabled() { return this.enabled; } @@ -2696,7 +1946,6 @@ public Boolean getEnabled() { /** * Takes the levelProperty of the Descriptor (if present) or provides a default/override. */ - @SuppressWarnings("all") public String getLevel() { return this.level; } @@ -2704,7 +1953,6 @@ public String getLevel() { /** * Takes the rank/priority of the Descriptor (if present) or provides a default/override value between 1.0 and 100.0. */ - @SuppressWarnings("all") public Double getRank() { return this.rank; } @@ -2712,16 +1960,15 @@ public Double getRank() { /** * Define configuration information (propertyBag) specific to the Descriptor. */ - @SuppressWarnings("all") public PropertyBag getParameters() { return this.parameters; } /** * Boolean, to dis- and enable the config based on matching a rule (through the Descriptor). + * * @return {@code this}. */ - @SuppressWarnings("all") public SarifLog.ReportingConfiguration setEnabled(final Boolean enabled) { this.enabled = enabled; return this; @@ -2729,9 +1976,9 @@ public SarifLog.ReportingConfiguration setEnabled(final Boolean enabled) { /** * Takes the levelProperty of the Descriptor (if present) or provides a default/override. + * * @return {@code this}. */ - @SuppressWarnings("all") public SarifLog.ReportingConfiguration setLevel(final String level) { this.level = level; return this; @@ -2739,9 +1986,9 @@ public SarifLog.ReportingConfiguration setLevel(final String level) { /** * Takes the rank/priority of the Descriptor (if present) or provides a default/override value between 1.0 and 100.0. + * * @return {@code this}. */ - @SuppressWarnings("all") public SarifLog.ReportingConfiguration setRank(final Double rank) { this.rank = rank; return this; @@ -2749,73 +1996,29 @@ public SarifLog.ReportingConfiguration setRank(final Double rank) { /** * Define configuration information (propertyBag) specific to the Descriptor. + * * @return {@code this}. */ - @SuppressWarnings("all") public SarifLog.ReportingConfiguration setParameters(final PropertyBag parameters) { this.parameters = parameters; return this; } @Override - @SuppressWarnings("all") - public boolean equals(final Object o) { - if (o == this) { - return true; - } - if (!(o instanceof SarifLog.ReportingConfiguration)) { - return false; - } - final SarifLog.ReportingConfiguration other = (SarifLog.ReportingConfiguration) o; - if (!other.canEqual((Object) this)) { - return false; - } - final Object this$enabled = this.getEnabled(); - final Object other$enabled = other.getEnabled(); - if (this$enabled == null ? other$enabled != null : !this$enabled.equals(other$enabled)) { + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { return false; } - final Object this$level = this.getLevel(); - final Object other$level = other.getLevel(); - if (this$level == null ? other$level != null : !this$level.equals(other$level)) { - return false; - } - final Object this$rank = this.getRank(); - final Object other$rank = other.getRank(); - if (this$rank == null ? other$rank != null : !this$rank.equals(other$rank)) { - return false; - } - final Object this$parameters = this.getParameters(); - final Object other$parameters = other.getParameters(); - if (this$parameters == null ? other$parameters != null : !this$parameters.equals(other$parameters)) { - return false; - } - return true; - } - - @SuppressWarnings("all") - protected boolean canEqual(final Object other) { - return other instanceof SarifLog.ReportingConfiguration; + ReportingConfiguration that = (ReportingConfiguration) o; + return Objects.equals(enabled, that.enabled) && Objects.equals(level, that.level) && Objects.equals(rank, that.rank) && Objects.equals(parameters, that.parameters); } @Override - @SuppressWarnings("all") public int hashCode() { - final int PRIME = 59; - int result = 1; - final Object $enabled = this.getEnabled(); - result = result * PRIME + ($enabled == null ? 43 : $enabled.hashCode()); - final Object $level = this.getLevel(); - result = result * PRIME + ($level == null ? 43 : $level.hashCode()); - final Object $rank = this.getRank(); - result = result * PRIME + ($rank == null ? 43 : $rank.hashCode()); - final Object $parameters = this.getParameters(); - result = result * PRIME + ($parameters == null ? 43 : $parameters.hashCode()); - return result; + return Objects.hash(enabled, level, rank, parameters); } @Override - @SuppressWarnings("all") public String toString() { return "SarifLog.ReportingConfiguration(enabled=" + this.getEnabled() + ", level=" + this.getLevel() + ", rank=" + this.getRank() + ", parameters=" + this.getParameters() + ")"; } @@ -2825,37 +2028,32 @@ public String toString() { /** * A message string or message format string rendered in multiple formats. */ - public static class MultiformatMessage { - /** - * A plain text message string or format string. - */ + public static final class MultiformatMessage { private String text; - /** - * A Markdown message string or format string. - */ private String markdown; public MultiformatMessage(String text) { this.text = text; } + public MultiformatMessage(final String text, final String markdown) { + this.text = text; + this.markdown = markdown; + } - @java.lang.SuppressWarnings("all") - public static class MultiformatMessageBuilder { - @java.lang.SuppressWarnings("all") + public static final class MultiformatMessageBuilder { private String text; - @java.lang.SuppressWarnings("all") private String markdown; - @java.lang.SuppressWarnings("all") - MultiformatMessageBuilder() { + private MultiformatMessageBuilder() { + // make default ctor private; use factory method MultiformatMessage#builder() instead. } /** * A plain text message string or format string. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.MultiformatMessage.MultiformatMessageBuilder text(final String text) { this.text = text; return this; @@ -2863,27 +2061,24 @@ public SarifLog.MultiformatMessage.MultiformatMessageBuilder text(final String t /** * A Markdown message string or format string. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.MultiformatMessage.MultiformatMessageBuilder markdown(final String markdown) { this.markdown = markdown; return this; } - @java.lang.SuppressWarnings("all") public SarifLog.MultiformatMessage build() { return new SarifLog.MultiformatMessage(this.text, this.markdown); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.MultiformatMessage.MultiformatMessageBuilder(text=" + this.text + ", markdown=" + this.markdown + ")"; } } - @java.lang.SuppressWarnings("all") public static SarifLog.MultiformatMessage.MultiformatMessageBuilder builder() { return new SarifLog.MultiformatMessage.MultiformatMessageBuilder(); } @@ -2891,7 +2086,6 @@ public static SarifLog.MultiformatMessage.MultiformatMessageBuilder builder() { /** * A plain text message string or format string. */ - @java.lang.SuppressWarnings("all") public String getText() { return this.text; } @@ -2899,16 +2093,15 @@ public String getText() { /** * A Markdown message string or format string. */ - @java.lang.SuppressWarnings("all") public String getMarkdown() { return this.markdown; } /** * A plain text message string or format string. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.MultiformatMessage setText(final String text) { this.text = text; return this; @@ -2916,71 +2109,31 @@ public SarifLog.MultiformatMessage setText(final String text) { /** * A Markdown message string or format string. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.MultiformatMessage setMarkdown(final String markdown) { this.markdown = markdown; return this; } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public boolean equals(final java.lang.Object o) { - if (o == this) { - return true; - } - if (!(o instanceof SarifLog.MultiformatMessage)) { - return false; - } - final SarifLog.MultiformatMessage other = (SarifLog.MultiformatMessage) o; - if (!other.canEqual((java.lang.Object) this)) { - return false; - } - final java.lang.Object this$text = this.getText(); - final java.lang.Object other$text = other.getText(); - if (this$text == null ? other$text != null : !this$text.equals(other$text)) { - return false; - } - final java.lang.Object this$markdown = this.getMarkdown(); - final java.lang.Object other$markdown = other.getMarkdown(); - if (this$markdown == null ? other$markdown != null : !this$markdown.equals(other$markdown)) { + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { return false; } - return true; - } - - @java.lang.SuppressWarnings("all") - protected boolean canEqual(final java.lang.Object other) { - return other instanceof SarifLog.MultiformatMessage; + MultiformatMessage that = (MultiformatMessage) o; + return Objects.equals(text, that.text) && Objects.equals(markdown, that.markdown); } - @java.lang.Override - @java.lang.SuppressWarnings("all") + @Override public int hashCode() { - final int PRIME = 59; - int result = 1; - final java.lang.Object $text = this.getText(); - result = result * PRIME + ($text == null ? 43 : $text.hashCode()); - final java.lang.Object $markdown = this.getMarkdown(); - result = result * PRIME + ($markdown == null ? 43 : $markdown.hashCode()); - return result; - } - - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { - return "SarifLog.MultiformatMessage(text=" + this.getText() + ", markdown=" + this.getMarkdown() + ")"; + return Objects.hash(text, markdown); } - @java.lang.SuppressWarnings("all") - public MultiformatMessage() { - } - - @java.lang.SuppressWarnings("all") - public MultiformatMessage(final String text, final String markdown) { - this.text = text; - this.markdown = markdown; + @Override + public String toString() { + return "SarifLog.MultiformatMessage(text=" + this.getText() + ", markdown=" + this.getMarkdown() + ")"; } } @@ -2988,55 +2141,44 @@ public MultiformatMessage(final String text, final String markdown) { /** * An exception information object, for the tool runtime errors. */ - public static class Exception { - /** - * A plain text message string or format string. - */ + public static final class Exception { private String message; - @java.lang.SuppressWarnings("all") - Exception(final String message) { + private Exception(final String message) { this.message = message; } - - @java.lang.SuppressWarnings("all") - public static class ExceptionBuilder { - @java.lang.SuppressWarnings("all") + public static final class ExceptionBuilder { private String message; - @java.lang.SuppressWarnings("all") - ExceptionBuilder() { + private ExceptionBuilder() { + // make default ctor private; use factory method Exception#builder() instead. } /** * A plain text message string or format string. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Exception.ExceptionBuilder message(final String message) { this.message = message; return this; } - @java.lang.SuppressWarnings("all") public SarifLog.Exception build() { return new SarifLog.Exception(this.message); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.Exception.ExceptionBuilder(message=" + this.message + ")"; } } - @java.lang.SuppressWarnings("all") public static SarifLog.Exception.ExceptionBuilder builder() { return new SarifLog.Exception.ExceptionBuilder(); } - @java.lang.SuppressWarnings("all") public SarifLog.Exception.ExceptionBuilder toBuilder() { return new SarifLog.Exception.ExceptionBuilder().message(this.message); } @@ -3044,60 +2186,36 @@ public SarifLog.Exception.ExceptionBuilder toBuilder() { /** * A plain text message string or format string. */ - @java.lang.SuppressWarnings("all") public String getMessage() { return this.message; } /** * A plain text message string or format string. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.Exception setMessage(final String message) { this.message = message; return this; } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public boolean equals(final java.lang.Object o) { - if (o == this) { - return true; - } - if (!(o instanceof SarifLog.Exception)) { - return false; - } - final SarifLog.Exception other = (SarifLog.Exception) o; - if (!other.canEqual((java.lang.Object) this)) { - return false; - } - final java.lang.Object this$message = this.getMessage(); - final java.lang.Object other$message = other.getMessage(); - if (this$message == null ? other$message != null : !this$message.equals(other$message)) { + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { return false; } - return true; - } - - @java.lang.SuppressWarnings("all") - protected boolean canEqual(final java.lang.Object other) { - return other instanceof SarifLog.Exception; + Exception exception = (Exception) o; + return Objects.equals(message, exception.message); } - @java.lang.Override - @java.lang.SuppressWarnings("all") + @Override public int hashCode() { - final int PRIME = 59; - int result = 1; - final java.lang.Object $message = this.getMessage(); - result = result * PRIME + ($message == null ? 43 : $message.hashCode()); - return result; + return Objects.hashCode(message); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.Exception(message=" + this.getMessage() + ")"; } } @@ -3106,55 +2224,44 @@ public java.lang.String toString() { /** * An associated rule to the toolConfigurationNotification. */ - public static class AssociatedRule { - /** - * The stable, unique identifier of the rule, if any, to which this result is relevant. - */ + public static final class AssociatedRule { private String id; - @java.lang.SuppressWarnings("all") - AssociatedRule(final String id) { + private AssociatedRule(final String id) { this.id = id; } - - @java.lang.SuppressWarnings("all") - public static class AssociatedRuleBuilder { - @java.lang.SuppressWarnings("all") + public static final class AssociatedRuleBuilder { private String id; - @java.lang.SuppressWarnings("all") - AssociatedRuleBuilder() { + private AssociatedRuleBuilder() { + // make default ctor private; use factory method AssociatedRule#builder() instead. } /** * The stable, unique identifier of the rule, if any, to which this result is relevant. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.AssociatedRule.AssociatedRuleBuilder id(final String id) { this.id = id; return this; } - @java.lang.SuppressWarnings("all") public SarifLog.AssociatedRule build() { return new SarifLog.AssociatedRule(this.id); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.AssociatedRule.AssociatedRuleBuilder(id=" + this.id + ")"; } } - @java.lang.SuppressWarnings("all") public static SarifLog.AssociatedRule.AssociatedRuleBuilder builder() { return new SarifLog.AssociatedRule.AssociatedRuleBuilder(); } - @java.lang.SuppressWarnings("all") public SarifLog.AssociatedRule.AssociatedRuleBuilder toBuilder() { return new SarifLog.AssociatedRule.AssociatedRuleBuilder().id(this.id); } @@ -3162,60 +2269,36 @@ public SarifLog.AssociatedRule.AssociatedRuleBuilder toBuilder() { /** * The stable, unique identifier of the rule, if any, to which this result is relevant. */ - @java.lang.SuppressWarnings("all") public String getId() { return this.id; } /** * The stable, unique identifier of the rule, if any, to which this result is relevant. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.AssociatedRule setId(final String id) { this.id = id; return this; } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public boolean equals(final java.lang.Object o) { - if (o == this) { - return true; - } - if (!(o instanceof SarifLog.AssociatedRule)) { - return false; - } - final SarifLog.AssociatedRule other = (SarifLog.AssociatedRule) o; - if (!other.canEqual((java.lang.Object) this)) { - return false; - } - final java.lang.Object this$id = this.getId(); - final java.lang.Object other$id = other.getId(); - if (this$id == null ? other$id != null : !this$id.equals(other$id)) { + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { return false; } - return true; - } - - @java.lang.SuppressWarnings("all") - protected boolean canEqual(final java.lang.Object other) { - return other instanceof SarifLog.AssociatedRule; + AssociatedRule that = (AssociatedRule) o; + return Objects.equals(id, that.id); } - @java.lang.Override - @java.lang.SuppressWarnings("all") + @Override public int hashCode() { - final int PRIME = 59; - int result = 1; - final java.lang.Object $id = this.getId(); - result = result * PRIME + ($id == null ? 43 : $id.hashCode()); - return result; + return Objects.hashCode(id); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.AssociatedRule(id=" + this.getId() + ")"; } } @@ -3224,158 +2307,111 @@ public java.lang.String toString() { /** * An invocation property to specify tool configuration errors. */ - public static class ToolConfigurationNotification { - /** - * An associated rule - */ + public static final class ToolConfigurationNotification { private AssociatedRule associatedRule; - /** - * A message component to detail the configuration error - */ private Message message; - @java.lang.SuppressWarnings("all") - ToolConfigurationNotification(final AssociatedRule associatedRule, final Message message) { + private ToolConfigurationNotification(final AssociatedRule associatedRule, final Message message) { this.associatedRule = associatedRule; this.message = message; } - - @java.lang.SuppressWarnings("all") - public static class ToolConfigurationNotificationBuilder { - @java.lang.SuppressWarnings("all") + public static final class ToolConfigurationNotificationBuilder { private AssociatedRule associatedRule; - @java.lang.SuppressWarnings("all") private Message message; - @java.lang.SuppressWarnings("all") - ToolConfigurationNotificationBuilder() { + private ToolConfigurationNotificationBuilder() { + // make default ctor private; use factory method ToolConfigurationNotification#builder() instead. } /** - * An associated rule + * An associated rule. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ToolConfigurationNotification.ToolConfigurationNotificationBuilder associatedRule(final AssociatedRule associatedRule) { this.associatedRule = associatedRule; return this; } /** - * A message component to detail the configuration error + * A message component to detail the configuration error. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ToolConfigurationNotification.ToolConfigurationNotificationBuilder message(final Message message) { this.message = message; return this; } - @java.lang.SuppressWarnings("all") public SarifLog.ToolConfigurationNotification build() { return new SarifLog.ToolConfigurationNotification(this.associatedRule, this.message); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.ToolConfigurationNotification.ToolConfigurationNotificationBuilder(associatedRule=" + this.associatedRule + ", message=" + this.message + ")"; } } - @java.lang.SuppressWarnings("all") public static SarifLog.ToolConfigurationNotification.ToolConfigurationNotificationBuilder builder() { return new SarifLog.ToolConfigurationNotification.ToolConfigurationNotificationBuilder(); } - @java.lang.SuppressWarnings("all") public SarifLog.ToolConfigurationNotification.ToolConfigurationNotificationBuilder toBuilder() { return new SarifLog.ToolConfigurationNotification.ToolConfigurationNotificationBuilder().associatedRule(this.associatedRule).message(this.message); } /** - * An associated rule + * An associated rule. */ - @java.lang.SuppressWarnings("all") public AssociatedRule getAssociatedRule() { return this.associatedRule; } /** - * A message component to detail the configuration error + * A message component to detail the configuration error. */ - @java.lang.SuppressWarnings("all") public Message getMessage() { return this.message; } /** - * An associated rule + * An associated rule. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ToolConfigurationNotification setAssociatedRule(final AssociatedRule associatedRule) { this.associatedRule = associatedRule; return this; } /** - * A message component to detail the configuration error + * A message component to detail the configuration error. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ToolConfigurationNotification setMessage(final Message message) { this.message = message; return this; } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public boolean equals(final java.lang.Object o) { - if (o == this) { - return true; - } - if (!(o instanceof SarifLog.ToolConfigurationNotification)) { - return false; - } - final SarifLog.ToolConfigurationNotification other = (SarifLog.ToolConfigurationNotification) o; - if (!other.canEqual((java.lang.Object) this)) { - return false; - } - final java.lang.Object this$associatedRule = this.getAssociatedRule(); - final java.lang.Object other$associatedRule = other.getAssociatedRule(); - if (this$associatedRule == null ? other$associatedRule != null : !this$associatedRule.equals(other$associatedRule)) { - return false; - } - final java.lang.Object this$message = this.getMessage(); - final java.lang.Object other$message = other.getMessage(); - if (this$message == null ? other$message != null : !this$message.equals(other$message)) { + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { return false; } - return true; + ToolConfigurationNotification that = (ToolConfigurationNotification) o; + return Objects.equals(associatedRule, that.associatedRule) && Objects.equals(message, that.message); } - @java.lang.SuppressWarnings("all") - protected boolean canEqual(final java.lang.Object other) { - return other instanceof SarifLog.ToolConfigurationNotification; + @Override + public int hashCode() { + return Objects.hash(associatedRule, message); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public int hashCode() { - final int PRIME = 59; - int result = 1; - final java.lang.Object $associatedRule = this.getAssociatedRule(); - result = result * PRIME + ($associatedRule == null ? 43 : $associatedRule.hashCode()); - final java.lang.Object $message = this.getMessage(); - result = result * PRIME + ($message == null ? 43 : $message.hashCode()); - return result; - } - - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.ToolConfigurationNotification(associatedRule=" + this.getAssociatedRule() + ", message=" + this.getMessage() + ")"; } } @@ -3384,200 +2420,141 @@ public java.lang.String toString() { /** * An invocation property to specify tool runtime errors. */ - public static class ToolExecutionNotification { - /** - * A list of related locations to the error - */ + public static final class ToolExecutionNotification { private List locations; - /** - * A message component to detail the runtime error - */ private Message message; - /** - * An exception component to detail the tool exception - */ private Exception exception; - @java.lang.SuppressWarnings("all") - ToolExecutionNotification(final List locations, final Message message, final Exception exception) { + private ToolExecutionNotification(final List locations, final Message message, final Exception exception) { this.locations = locations; this.message = message; this.exception = exception; } - - @java.lang.SuppressWarnings("all") - public static class ToolExecutionNotificationBuilder { - @java.lang.SuppressWarnings("all") + public static final class ToolExecutionNotificationBuilder { private List locations; - @java.lang.SuppressWarnings("all") private Message message; - @java.lang.SuppressWarnings("all") private Exception exception; - @java.lang.SuppressWarnings("all") - ToolExecutionNotificationBuilder() { + private ToolExecutionNotificationBuilder() { + // make default ctor private; use factory method ToolExecutionNotification#builder() instead. } /** - * A list of related locations to the error + * A list of related locations to the error. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ToolExecutionNotification.ToolExecutionNotificationBuilder locations(final List locations) { this.locations = locations; return this; } /** - * A message component to detail the runtime error + * A message component to detail the runtime error. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ToolExecutionNotification.ToolExecutionNotificationBuilder message(final Message message) { this.message = message; return this; } /** - * A exception component to detail the tool exception + * A exception component to detail the tool exception. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ToolExecutionNotification.ToolExecutionNotificationBuilder exception(final Exception exception) { this.exception = exception; return this; } - @java.lang.SuppressWarnings("all") public SarifLog.ToolExecutionNotification build() { return new SarifLog.ToolExecutionNotification(this.locations, this.message, this.exception); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.ToolExecutionNotification.ToolExecutionNotificationBuilder(locations=" + this.locations + ", message=" + this.message + ", exception=" + this.exception + ")"; } } - @java.lang.SuppressWarnings("all") public static SarifLog.ToolExecutionNotification.ToolExecutionNotificationBuilder builder() { return new SarifLog.ToolExecutionNotification.ToolExecutionNotificationBuilder(); } - @java.lang.SuppressWarnings("all") public SarifLog.ToolExecutionNotification.ToolExecutionNotificationBuilder toBuilder() { return new SarifLog.ToolExecutionNotification.ToolExecutionNotificationBuilder().locations(this.locations).message(this.message).exception(this.exception); } /** - * A list of related locations to the error + * A list of related locations to the error. */ - @java.lang.SuppressWarnings("all") public List getLocations() { return this.locations; } /** - * A message component to detail the runtime error + * A message component to detail the runtime error. */ - @java.lang.SuppressWarnings("all") public Message getMessage() { return this.message; } /** - * A exception component to detail the tool exception + * A exception component to detail the tool exception. */ - @java.lang.SuppressWarnings("all") public Exception getException() { return this.exception; } /** - * A list of related locations to the error + * A list of related locations to the error. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ToolExecutionNotification setLocations(final List locations) { this.locations = locations; return this; } /** - * A message component to detail the runtime error + * A message component to detail the runtime error. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ToolExecutionNotification setMessage(final Message message) { this.message = message; return this; } /** - * A exception component to detail the tool exception + * A exception component to detail the tool exception. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.ToolExecutionNotification setException(final Exception exception) { this.exception = exception; return this; } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public boolean equals(final java.lang.Object o) { - if (o == this) { - return true; - } - if (!(o instanceof SarifLog.ToolExecutionNotification)) { - return false; - } - final SarifLog.ToolExecutionNotification other = (SarifLog.ToolExecutionNotification) o; - if (!other.canEqual((java.lang.Object) this)) { - return false; - } - final java.lang.Object this$locations = this.getLocations(); - final java.lang.Object other$locations = other.getLocations(); - if (this$locations == null ? other$locations != null : !this$locations.equals(other$locations)) { - return false; - } - final java.lang.Object this$message = this.getMessage(); - final java.lang.Object other$message = other.getMessage(); - if (this$message == null ? other$message != null : !this$message.equals(other$message)) { - return false; - } - final java.lang.Object this$exception = this.getException(); - final java.lang.Object other$exception = other.getException(); - if (this$exception == null ? other$exception != null : !this$exception.equals(other$exception)) { + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { return false; } - return true; + ToolExecutionNotification that = (ToolExecutionNotification) o; + return Objects.equals(locations, that.locations) && Objects.equals(message, that.message) && Objects.equals(exception, that.exception); } - @java.lang.SuppressWarnings("all") - protected boolean canEqual(final java.lang.Object other) { - return other instanceof SarifLog.ToolExecutionNotification; + @Override + public int hashCode() { + return Objects.hash(locations, message, exception); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public int hashCode() { - final int PRIME = 59; - int result = 1; - final java.lang.Object $locations = this.getLocations(); - result = result * PRIME + ($locations == null ? 43 : $locations.hashCode()); - final java.lang.Object $message = this.getMessage(); - result = result * PRIME + ($message == null ? 43 : $message.hashCode()); - final java.lang.Object $exception = this.getException(); - result = result * PRIME + ($exception == null ? 43 : $exception.hashCode()); - return result; - } - - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.ToolExecutionNotification(locations=" + this.getLocations() + ", message=" + this.getMessage() + ", exception=" + this.getException() + ")"; } } @@ -3586,211 +2563,146 @@ public java.lang.String toString() { /** * An invocation component to specify tool invocation details/errors. */ - public static class Invocation { - /** - * An indicator of execution status - */ + public static final class Invocation { private Boolean executionSuccessful; - /** - * A list of associated tool configuration errors - */ private List toolConfigurationNotifications; - /** - * A list of associated tool runtime errors - */ private List toolExecutionNotifications; - @java.lang.SuppressWarnings("all") - Invocation(final Boolean executionSuccessful, final List toolConfigurationNotifications, final List toolExecutionNotifications) { + private Invocation(final Boolean executionSuccessful, final List toolConfigurationNotifications, final List toolExecutionNotifications) { this.executionSuccessful = executionSuccessful; this.toolConfigurationNotifications = toolConfigurationNotifications; this.toolExecutionNotifications = toolExecutionNotifications; } - - @java.lang.SuppressWarnings("all") - public static class InvocationBuilder { - @java.lang.SuppressWarnings("all") + public static final class InvocationBuilder { private Boolean executionSuccessful; - @java.lang.SuppressWarnings("all") private List toolConfigurationNotifications; - @java.lang.SuppressWarnings("all") private List toolExecutionNotifications; - @java.lang.SuppressWarnings("all") - InvocationBuilder() { + private InvocationBuilder() { + // make default ctor private; use factory method Invocation#builder() instead. } - @java.lang.SuppressWarnings("all") + /** + * An indicator of execution status. + */ public SarifLog.Invocation.InvocationBuilder executionSuccessful(final Boolean executionSuccessful) { this.executionSuccessful = executionSuccessful; return this; } - @java.lang.SuppressWarnings("all") + /** + * A list of associated tool configuration errors. + */ public SarifLog.Invocation.InvocationBuilder toolConfigurationNotifications(final List toolConfigurationNotifications) { this.toolConfigurationNotifications = toolConfigurationNotifications; return this; } - @java.lang.SuppressWarnings("all") + /** + * A list of associated tool runtime errors. + */ public SarifLog.Invocation.InvocationBuilder toolExecutionNotifications(final List toolExecutionNotifications) { this.toolExecutionNotifications = toolExecutionNotifications; return this; } - @java.lang.SuppressWarnings("all") public SarifLog.Invocation build() { return new SarifLog.Invocation(this.executionSuccessful, this.toolConfigurationNotifications, this.toolExecutionNotifications); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.Invocation.InvocationBuilder(executionSuccessful=" + this.executionSuccessful + ", toolConfigurationNotifications=" + this.toolConfigurationNotifications + ", toolExecutionNotifications=" + this.toolExecutionNotifications + ")"; } } - @java.lang.SuppressWarnings("all") public static SarifLog.Invocation.InvocationBuilder builder() { return new SarifLog.Invocation.InvocationBuilder(); } - @java.lang.SuppressWarnings("all") public SarifLog.Invocation.InvocationBuilder toBuilder() { return new SarifLog.Invocation.InvocationBuilder().executionSuccessful(this.executionSuccessful).toolConfigurationNotifications(this.toolConfigurationNotifications).toolExecutionNotifications(this.toolExecutionNotifications); } - @java.lang.SuppressWarnings("all") public Boolean getExecutionSuccessful() { return this.executionSuccessful; } - @java.lang.SuppressWarnings("all") public List getToolConfigurationNotifications() { return this.toolConfigurationNotifications; } - @java.lang.SuppressWarnings("all") public List getToolExecutionNotifications() { return this.toolExecutionNotifications; } - @java.lang.SuppressWarnings("all") public SarifLog.Invocation setExecutionSuccessful(final Boolean executionSuccessful) { this.executionSuccessful = executionSuccessful; return this; } - @java.lang.SuppressWarnings("all") public SarifLog.Invocation setToolConfigurationNotifications(final List toolConfigurationNotifications) { this.toolConfigurationNotifications = toolConfigurationNotifications; return this; } - @java.lang.SuppressWarnings("all") public SarifLog.Invocation setToolExecutionNotifications(final List toolExecutionNotifications) { this.toolExecutionNotifications = toolExecutionNotifications; return this; } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public boolean equals(final java.lang.Object o) { - if (o == this) { - return true; - } - if (!(o instanceof SarifLog.Invocation)) { - return false; - } - final SarifLog.Invocation other = (SarifLog.Invocation) o; - if (!other.canEqual((java.lang.Object) this)) { - return false; - } - final java.lang.Object this$executionSuccessful = this.getExecutionSuccessful(); - final java.lang.Object other$executionSuccessful = other.getExecutionSuccessful(); - if (this$executionSuccessful == null ? other$executionSuccessful != null : !this$executionSuccessful.equals(other$executionSuccessful)) { - return false; - } - final java.lang.Object this$toolConfigurationNotifications = this.getToolConfigurationNotifications(); - final java.lang.Object other$toolConfigurationNotifications = other.getToolConfigurationNotifications(); - if (this$toolConfigurationNotifications == null ? other$toolConfigurationNotifications != null : !this$toolConfigurationNotifications.equals(other$toolConfigurationNotifications)) { - return false; - } - final java.lang.Object this$toolExecutionNotifications = this.getToolExecutionNotifications(); - final java.lang.Object other$toolExecutionNotifications = other.getToolExecutionNotifications(); - if (this$toolExecutionNotifications == null ? other$toolExecutionNotifications != null : !this$toolExecutionNotifications.equals(other$toolExecutionNotifications)) { + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { return false; } - return true; + Invocation that = (Invocation) o; + return Objects.equals(executionSuccessful, that.executionSuccessful) && Objects.equals(toolConfigurationNotifications, that.toolConfigurationNotifications) && Objects.equals(toolExecutionNotifications, that.toolExecutionNotifications); } - @java.lang.SuppressWarnings("all") - protected boolean canEqual(final java.lang.Object other) { - return other instanceof SarifLog.Invocation; + @Override + public int hashCode() { + return Objects.hash(executionSuccessful, toolConfigurationNotifications, toolExecutionNotifications); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public int hashCode() { - final int PRIME = 59; - int result = 1; - final java.lang.Object $executionSuccessful = this.getExecutionSuccessful(); - result = result * PRIME + ($executionSuccessful == null ? 43 : $executionSuccessful.hashCode()); - final java.lang.Object $toolConfigurationNotifications = this.getToolConfigurationNotifications(); - result = result * PRIME + ($toolConfigurationNotifications == null ? 43 : $toolConfigurationNotifications.hashCode()); - final java.lang.Object $toolExecutionNotifications = this.getToolExecutionNotifications(); - result = result * PRIME + ($toolExecutionNotifications == null ? 43 : $toolExecutionNotifications.hashCode()); - return result; - } - - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.Invocation(executionSuccessful=" + this.getExecutionSuccessful() + ", toolConfigurationNotifications=" + this.getToolConfigurationNotifications() + ", toolExecutionNotifications=" + this.getToolExecutionNotifications() + ")"; } } - @java.lang.SuppressWarnings("all") private static String defaultSchema() { return "https://json.schemastore.org/sarif-2.1.0.json"; } - @java.lang.SuppressWarnings("all") private static String defaultVersion() { return "2.1.0"; } - @java.lang.SuppressWarnings("all") - SarifLog(final String schema, final String version, final List runs) { + private SarifLog(final String schema, final String version, final List runs) { this.schema = schema; this.version = version; this.runs = runs; } - @java.lang.SuppressWarnings("all") - public static class SarifLogBuilder { - @java.lang.SuppressWarnings("all") + public static final class SarifLogBuilder { private boolean schemaSet; - @java.lang.SuppressWarnings("all") private String schemaValue; - @java.lang.SuppressWarnings("all") private boolean versionSet; - @java.lang.SuppressWarnings("all") private String versionValue; - @java.lang.SuppressWarnings("all") private List runs; - @java.lang.SuppressWarnings("all") - SarifLogBuilder() { + private SarifLogBuilder() { + // make default ctor private; use factory method SarifLog#builder() instead. } /** * The URI of the JSON schema corresponding to the version. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.SarifLogBuilder schema(final String schema) { this.schemaValue = schema; schemaSet = true; @@ -3799,9 +2711,9 @@ public SarifLog.SarifLogBuilder schema(final String schema) { /** * The SARIF format version of this log file. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.SarifLogBuilder version(final String version) { this.versionValue = version; versionSet = true; @@ -3810,15 +2722,14 @@ public SarifLog.SarifLogBuilder version(final String version) { /** * The set of runs contained in this log file. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog.SarifLogBuilder runs(final List runs) { this.runs = runs; return this; } - @java.lang.SuppressWarnings("all") public SarifLog build() { String schemaValue = this.schemaValue; if (!this.schemaSet) { @@ -3831,14 +2742,12 @@ public SarifLog build() { return new SarifLog(schemaValue, versionValue, this.runs); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog.SarifLogBuilder(schema$value=" + this.schemaValue + ", version$value=" + this.versionValue + ", runs=" + this.runs + ")"; } } - @java.lang.SuppressWarnings("all") public static SarifLog.SarifLogBuilder builder() { return new SarifLog.SarifLogBuilder(); } @@ -3846,7 +2755,6 @@ public static SarifLog.SarifLogBuilder builder() { /** * The URI of the JSON schema corresponding to the version. */ - @java.lang.SuppressWarnings("all") public String getSchema() { return this.schema; } @@ -3854,7 +2762,6 @@ public String getSchema() { /** * The SARIF format version of this log file. */ - @java.lang.SuppressWarnings("all") public String getVersion() { return this.version; } @@ -3862,16 +2769,15 @@ public String getVersion() { /** * The set of runs contained in this log file. */ - @java.lang.SuppressWarnings("all") public List getRuns() { return this.runs; } /** * The URI of the JSON schema corresponding to the version. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog setSchema(final String schema) { this.schema = schema; return this; @@ -3879,9 +2785,9 @@ public SarifLog setSchema(final String schema) { /** * The SARIF format version of this log file. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog setVersion(final String version) { this.version = version; return this; @@ -3889,68 +2795,30 @@ public SarifLog setVersion(final String version) { /** * The set of runs contained in this log file. + * * @return {@code this}. */ - @java.lang.SuppressWarnings("all") public SarifLog setRuns(final List runs) { this.runs = runs; return this; } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public boolean equals(final java.lang.Object o) { - if (o == this) { - return true; - } - if (!(o instanceof SarifLog)) { - return false; - } - final SarifLog other = (SarifLog) o; - if (!other.canEqual((java.lang.Object) this)) { + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { return false; } - final java.lang.Object this$schema = this.getSchema(); - final java.lang.Object other$schema = other.getSchema(); - if (this$schema == null ? other$schema != null : !this$schema.equals(other$schema)) { - return false; - } - final java.lang.Object this$version = this.getVersion(); - final java.lang.Object other$version = other.getVersion(); - if (this$version == null ? other$version != null : !this$version.equals(other$version)) { - return false; - } - final java.lang.Object this$runs = this.getRuns(); - final java.lang.Object other$runs = other.getRuns(); - if (this$runs == null ? other$runs != null : !this$runs.equals(other$runs)) { - return false; - } - return true; - } - - @java.lang.SuppressWarnings("all") - protected boolean canEqual(final java.lang.Object other) { - return other instanceof SarifLog; + SarifLog sarifLog = (SarifLog) o; + return Objects.equals(schema, sarifLog.schema) && Objects.equals(version, sarifLog.version) && Objects.equals(runs, sarifLog.runs); } - @java.lang.Override - @java.lang.SuppressWarnings("all") + @Override public int hashCode() { - final int PRIME = 59; - int result = 1; - final java.lang.Object $schema = this.getSchema(); - result = result * PRIME + ($schema == null ? 43 : $schema.hashCode()); - final java.lang.Object $version = this.getVersion(); - result = result * PRIME + ($version == null ? 43 : $version.hashCode()); - final java.lang.Object $runs = this.getRuns(); - result = result * PRIME + ($runs == null ? 43 : $runs.hashCode()); - return result; + return Objects.hash(schema, version, runs); } - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { + @Override + public String toString() { return "SarifLog(schema=" + this.getSchema() + ", version=" + this.getVersion() + ", runs=" + this.getRuns() + ")"; } } -// CPD-ON From 3fb06885de75ad86bfab1c565e655e1d01aebc6b Mon Sep 17 00:00:00 2001 From: Thomas Prouvot <35368290+tprouvot@users.noreply.github.com> Date: Mon, 19 May 2025 14:31:40 +0200 Subject: [PATCH 0933/1962] Update pmd-css/pom.xml Co-authored-by: Andreas Dangel --- pmd-css/pom.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pmd-css/pom.xml b/pmd-css/pom.xml index b528cba82b7..d3ea9bc0472 100644 --- a/pmd-css/pom.xml +++ b/pmd-css/pom.xml @@ -53,7 +53,9 @@ com.github.siom79.japicmp japicmp-maven-plugin - true + + true + From 2e981e3e500bf788522cd795701fb7c4d98267a9 Mon Sep 17 00:00:00 2001 From: Thomas Prouvot <35368290+tprouvot@users.noreply.github.com> Date: Mon, 19 May 2025 14:32:06 +0200 Subject: [PATCH 0934/1962] Update docs/pages/pmd/languages/css.md Co-authored-by: Andreas Dangel --- docs/pages/pmd/languages/css.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/pages/pmd/languages/css.md b/docs/pages/pmd/languages/css.md index 7c498e6c70f..cf484020e6f 100644 --- a/docs/pages/pmd/languages/css.md +++ b/docs/pages/pmd/languages/css.md @@ -4,4 +4,8 @@ permalink: pmd_languages_css.html last_updated: May 2025 (7.14.0) tags: [languages, CpdCapableLanguage] summary: "CSS-specific features and guidance" ---- \ No newline at end of file +--- + +> [CSS](https://www.w3.org/TR/css/) is a language for describing the rendering of structured documents (such as HTML and XML) on screen, on paper, etc. + +{% include language_info.html name='Css' id='css' implementation='css::lang.css.CssLanguageModule' supports_cpd=true since='7.14.0' %} From 3e4fb7dcaedb94a2e9821ccc3415b7d0f6be90d5 Mon Sep 17 00:00:00 2001 From: Thomas Prouvot Date: Mon, 19 May 2025 14:42:53 +0200 Subject: [PATCH 0935/1962] Documenting the new entry required in pmd-sidebar.yml --- docs/_data/sidebars/pmd_sidebar.yml | 3 +++ .../adding_new_cpd_language.md | 17 ++++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/docs/_data/sidebars/pmd_sidebar.yml b/docs/_data/sidebars/pmd_sidebar.yml index 825cc5c799e..5596665211f 100644 --- a/docs/_data/sidebars/pmd_sidebar.yml +++ b/docs/_data/sidebars/pmd_sidebar.yml @@ -443,6 +443,9 @@ entries: - title: C# url: /pmd_languages_cs.html output: web, pdf + - title: CSS + url: /pmd_languages_css.html + output: web, pdf - title: Coco url: /pmd_languages_coco.html output: web, pdf diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md index 43fe65edaab..a6a5c63c8a9 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md @@ -45,7 +45,7 @@ Use the following guide to set up a new language module that supports CPD. } } ``` - + - If your language is case-insensitive, then you might want to overwrite `getImage(AntlrToken)`. There you can change each token e.g. into uppercase, so that CPD sees the same strings and can find duplicates even when the casing differs. See {% jdoc tsql::lang.tsql.cpd.TSqlCpdLexer %} for an example. You will also need a @@ -59,13 +59,13 @@ Use the following guide to set up a new language module that supports CPD. 3. Create a {% jdoc core::lang.Language %} implementation, and make it implement {% jdoc core::cpd.CpdCapableLanguage %}. If your language only supports CPD, then you can subclass {% jdoc core::lang.impl.CpdOnlyLanguageModuleBase %} to get going: - + ```java // mind the package convention if you are going to make a PR package net.sourceforge.pmd.lang.go; public class GoLanguageModule extends CpdOnlyLanguageModuleBase { - + // A public noarg constructor is required. public GoLanguageModule() { super(LanguageMetadata.withId("go").name("Go").extensions("go")); @@ -76,7 +76,7 @@ If your language only supports CPD, then you can subclass {% jdoc core::lang.imp // This method should return an instance of the CpdLexer you created. return new GoCpdLexer(); } - } + } ``` To make PMD find the language module at runtime, write the fully-qualified name of your language class into the file `src/main/resources/META-INF/services/net.sourceforge.pmd.lang.Language`. @@ -87,7 +87,7 @@ If your language only supports CPD, then you can subclass {% jdoc core::lang.imp 5. Add some tests for your CpdLexer by following the [section below](#testing-your-implementation). -6. Finishing up your new language module by adding a page in the documentation. Create a new markdown file +6. Add a page in the documentation. Create a new markdown file `.md` in `docs/pages/pmd/languages/`. This file should have the following frontmatter: ``` @@ -108,6 +108,13 @@ If your language only supports CPD, then you can subclass {% jdoc core::lang.imp {% endraw %} ``` +7. Finishing up your new language module by adding a menu entry in [PMD Sidebar](https://github.com/pmd/pmd/blob/main/docs/_data/sidebars/pmd_sidebar.yml). + ``` + - title: + url: /pmd_languages_.html + output: web, pdf + ``` + ### Declaring CpdLexer options To make the CpdLexer configurable, first define some property descriptors using From 40d7597406ed8876587eca3f3412bd802f5fdb47 Mon Sep 17 00:00:00 2001 From: Thomas Prouvot Date: Mon, 19 May 2025 14:49:12 +0200 Subject: [PATCH 0936/1962] Mention lexer source --- .../main/antlr4/net/sourceforge/pmd/lang/css/ast/CssLexer.g4 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pmd-css/src/main/antlr4/net/sourceforge/pmd/lang/css/ast/CssLexer.g4 b/pmd-css/src/main/antlr4/net/sourceforge/pmd/lang/css/ast/CssLexer.g4 index c6ec193f0cf..ac1746e60cc 100644 --- a/pmd-css/src/main/antlr4/net/sourceforge/pmd/lang/css/ast/CssLexer.g4 +++ b/pmd-css/src/main/antlr4/net/sourceforge/pmd/lang/css/ast/CssLexer.g4 @@ -1,3 +1,8 @@ +/* + Lexer source: https://github.com/antlr/grammars-v4/blob/master/css3/css3Lexer.g4 + Note: the lexer grammar definition was updated from 'css3Lexer' to 'CssLexer' +*/ + // $antlr-format alignTrailingComments true, columnLimit 150, maxEmptyLinesToKeep 1, reflowComments false, useTab false // $antlr-format allowShortRulesOnASingleLine true, allowShortBlocksOnASingleLine true, minEmptyLines 0, alignSemicolons ownLine // $antlr-format alignColons trailing, singleLineOverrulesHangingColon true, alignLexerCommands true, alignLabels true, alignTrailers true From 26beedcf1d497af1df2991886b4d89a9711429a5 Mon Sep 17 00:00:00 2001 From: Thomas Prouvot Date: Mon, 19 May 2025 14:55:11 +0200 Subject: [PATCH 0937/1962] keep the new line --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d8c71cb27fe..bdd45aa870e 100644 --- a/pom.xml +++ b/pom.xml @@ -1433,4 +1433,4 @@ pmd-ant pmd-languages-deps - \ No newline at end of file + From 244e5937e0c9a66ee71dc10e09ca4438c640e434 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 21 May 2025 12:14:36 +0200 Subject: [PATCH 0938/1962] Apply suggestions from code review Co-authored-by: Andreas Dangel --- .../java/net/sourceforge/pmd/lang/ast/AstInfo.java | 10 +++++++--- .../pmd/lang/ast/impl/SuppressionCommentImpl.java | 2 ++ .../pmd/lang/ast/impl/javacc/AbstractTokenManager.java | 3 +++ .../java/net/sourceforge/pmd/lang/rule/RuleSet.java | 3 +++ .../pmd/reporting/AbstractAnnotationSuppressor.java | 6 +++++- .../sourceforge/pmd/reporting/ViolationSuppressor.java | 3 +++ .../java/net/sourceforge/pmd/util/CollectionUtil.java | 1 + .../lang/java/internal/JavaAnnotationSuppressor.java | 2 ++ .../src/main/resources/category/java/bestpractices.xml | 2 +- 9 files changed, 27 insertions(+), 5 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AstInfo.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AstInfo.java index 77011125993..ff75ce6a06b 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AstInfo.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AstInfo.java @@ -86,7 +86,7 @@ public LanguageProcessor getLanguageProcessor() { * It is suppressed, if the line of the violation is contained in this suppress map. * * @return map of the suppress lines with the corresponding review comments. - * @deprecated Use {@link #getAllSuppressionComments()} or {@link #getSuppressionComment(int)} + * @deprecated Since 7.13.0. Use {@link #getAllSuppressionComments()} or {@link #getSuppressionComment(int)} */ @Deprecated public Map getSuppressionComments() { @@ -96,6 +96,8 @@ public Map getSuppressionComments() { /** * Return the suppresson comment at the given line, or null if there is none. + * + * @since 7.14.0 */ public @Nullable SuppressionCommentWrapper getSuppressionComment(int lineNumber) { return suppressionComments.get(lineNumber); @@ -106,6 +108,8 @@ public Map getSuppressionComments() { * Only single line comments are considered, that start with the configured * "suppress marker", which by default is {@link PMDConfiguration#DEFAULT_SUPPRESS_MARKER}. * The text after the suppress marker is used as a "review comment" and included in this map. + * + * @since 7.14.0 */ public Collection getAllSuppressionComments() { return Collections.unmodifiableCollection(suppressionComments.values()); @@ -116,7 +120,7 @@ public Collection getAllSuppressionComments() { * * @return The user data map of this node * - * @since 7.12.0 + * @since 7.14.0 */ public DataMap> getUserMap() { return userMap; @@ -124,7 +128,7 @@ public Collection getAllSuppressionComments() { /** - * @deprecated Use {@link #withSuppressionComments(Collection)} + * @deprecated Since 7.14.0. Use {@link #withSuppressionComments(Collection)} */ @Deprecated public AstInfo withSuppressMap(Map map) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/SuppressionCommentImpl.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/SuppressionCommentImpl.java index 51571555465..c82c50ad32f 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/SuppressionCommentImpl.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/SuppressionCommentImpl.java @@ -14,6 +14,8 @@ * Simple implementation of {@link SuppressionCommentWrapper}. * * @param Type of Reportable (node, token, lambda) + * + * @since 7.14.0 */ @Experimental public class SuppressionCommentImpl implements SuppressionCommentWrapper { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/AbstractTokenManager.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/AbstractTokenManager.java index 107abffbeb5..c487e432c67 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/AbstractTokenManager.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/AbstractTokenManager.java @@ -29,6 +29,9 @@ public void setSuppressMarker(String marker) { this.suppressMarker = marker; } + /** + * @deprecated since 7.14.0. Use {@link #getSuppressionComments()} instead. + */ @Deprecated public Map getSuppressMap() { return suppressMap; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java index de18afe53f7..eb95fda13f1 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java @@ -183,6 +183,9 @@ public RuleSetBuilder toBuilder() { return new RuleSetBuilder(this); } + /** + * @since 7.14.0 + */ public static class RuleSetBuilder { public String description; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/AbstractAnnotationSuppressor.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/AbstractAnnotationSuppressor.java index 9c32b4f0ea7..47079e536a5 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/AbstractAnnotationSuppressor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/AbstractAnnotationSuppressor.java @@ -26,9 +26,13 @@ import net.sourceforge.pmd.util.DataMap.SimpleDataKey; import net.sourceforge.pmd.util.OptionalBool; +/** + * + * @since 7.14.0 + */ public abstract class AbstractAnnotationSuppressor implements ViolationSuppressor { - private final Class annotationClass; + private final Class annotationNodeType; protected AbstractAnnotationSuppressor(Class annotationClass) { this.annotationClass = annotationClass; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ViolationSuppressor.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ViolationSuppressor.java index 1c5a015303f..5ecb450840a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ViolationSuppressor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ViolationSuppressor.java @@ -178,6 +178,8 @@ public int size() { * @param tree Root node of a file * * @return A set + * + * @since 7.14.0 */ default Set getUnusedSuppressors(RootNode tree) { return Collections.emptySet(); @@ -206,6 +208,7 @@ default Set getUnusedSuppressors(RootNode tree) { * Represents an instance of a "suppressor" that didn't suppress anything. * This could be a suppression annotation, or part of an annotation, a * comment, etc. + * @since 7.14.0 */ interface UnusedSuppressorNode { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java index 27c9b07dd9f..0c3baa6fcaa 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java @@ -82,6 +82,7 @@ public static List concatView(List head, List t /** * Returns a view over the given map, where values are mapped using the given function. + * @since 7.14.0 */ public static Map mapView(Map map, Function valueMapper) { return new AbstractMap() { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java index 122328b6d2a..c329874c625 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java @@ -45,6 +45,8 @@ *

  • {@code "serial"}: suppresses BeanMembersShouldSerialize, NonSerializableClass and MissingSerialVersionUID; *
  • {@code "fallthrough"}: suppresses ImplicitSwitchFallthrough #1899 * + * + * @see JLS 9.6.4.5. @SuppressWarnings */ final class JavaAnnotationSuppressor extends AbstractAnnotationSuppressor { diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 9ac80346127..fad0298babe 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -1636,7 +1636,7 @@ class C { From a9cd6c230e39d8bb46d2a8506dc6762cf106932c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 21 May 2025 12:24:47 +0200 Subject: [PATCH 0939/1962] More cleanups --- .../net/sourceforge/pmd/lang/rule/RuleSet.java | 10 ++++++++-- .../UnnecessaryPmdSuppressionRule.java | 5 +++-- .../pmd/lang/rule/internal/RuleSets.java | 1 + .../reporting/AbstractAnnotationSuppressor.java | 16 +++++++++++++--- .../resources/category/java/bestpractices.xml | 2 +- .../lang/rule/AbstractRuleSetFactoryTest.java | 2 +- 6 files changed, 27 insertions(+), 9 deletions(-) rename pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/{internal => impl}/UnnecessaryPmdSuppressionRule.java (95%) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java index eb95fda13f1..9b580c206a7 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java @@ -184,7 +184,10 @@ public RuleSetBuilder toBuilder() { } /** + * A builder class to create a ruleset. + * * @since 7.14.0 + * @see #toBuilder() */ public static class RuleSetBuilder { @@ -239,8 +242,11 @@ public RuleSetBuilder addRule(final Rule newRule) { return this; } - public boolean removeIf(Predicate rule) { - return rules.removeIf(rule); + /** + * Remove all rules that matched the predicate. + */ + public boolean removeIf(Predicate filter) { + return rules.removeIf(filter); } /** diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/UnnecessaryPmdSuppressionRule.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/impl/UnnecessaryPmdSuppressionRule.java similarity index 95% rename from pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/UnnecessaryPmdSuppressionRule.java rename to pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/impl/UnnecessaryPmdSuppressionRule.java index b3da33a1976..a4e07119ebe 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/UnnecessaryPmdSuppressionRule.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/impl/UnnecessaryPmdSuppressionRule.java @@ -1,8 +1,8 @@ -/* +/** * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ -package net.sourceforge.pmd.lang.rule.internal; +package net.sourceforge.pmd.lang.rule.impl; import java.util.List; import java.util.Set; @@ -12,6 +12,7 @@ import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.ast.RootNode; import net.sourceforge.pmd.lang.rule.AbstractRule; +import net.sourceforge.pmd.lang.rule.internal.RuleSets; import net.sourceforge.pmd.reporting.InternalApiBridge; import net.sourceforge.pmd.reporting.RuleContext; import net.sourceforge.pmd.reporting.ViolationSuppressor; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/RuleSets.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/RuleSets.java index 9ac6ab3b45d..1c8b2b956c4 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/RuleSets.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/RuleSets.java @@ -23,6 +23,7 @@ import net.sourceforge.pmd.lang.rule.RuleReference; import net.sourceforge.pmd.lang.rule.RuleSet; import net.sourceforge.pmd.lang.rule.RuleSet.RuleSetBuilder; +import net.sourceforge.pmd.lang.rule.impl.UnnecessaryPmdSuppressionRule; import net.sourceforge.pmd.reporting.FileAnalysisListener; import net.sourceforge.pmd.util.log.PmdReporter; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/AbstractAnnotationSuppressor.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/AbstractAnnotationSuppressor.java index 47079e536a5..79bcbee3f13 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/AbstractAnnotationSuppressor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/AbstractAnnotationSuppressor.java @@ -19,7 +19,7 @@ import net.sourceforge.pmd.lang.ast.NodeStream; import net.sourceforge.pmd.lang.ast.RootNode; import net.sourceforge.pmd.lang.rule.Rule; -import net.sourceforge.pmd.lang.rule.internal.UnnecessaryPmdSuppressionRule; +import net.sourceforge.pmd.lang.rule.impl.UnnecessaryPmdSuppressionRule; import net.sourceforge.pmd.reporting.Report.SuppressedViolation; import net.sourceforge.pmd.util.AssertionUtil; import net.sourceforge.pmd.util.DataMap; @@ -27,7 +27,11 @@ import net.sourceforge.pmd.util.OptionalBool; /** + * Base class for a {@link ViolationSuppressor} that uses annotations + * of the source language to suppress some warnings. * + * @param Class of the node type that models annotations in the AST + * of the language * @since 7.14.0 */ public abstract class AbstractAnnotationSuppressor implements ViolationSuppressor { @@ -35,7 +39,7 @@ public abstract class AbstractAnnotationSuppressor implements Vi private final Class annotationNodeType; protected AbstractAnnotationSuppressor(Class annotationClass) { - this.annotationClass = annotationClass; + this.annotationNodeType = annotationClass; } @Override @@ -53,7 +57,7 @@ public Report.SuppressedViolation suppressOrNull(RuleViolation rv, @NonNull Node @Override public Set getUnusedSuppressors(RootNode tree) { - return tree.descendants(annotationClass).crossFindBoundaries().toStream().map(this::getUnusedSuppressorNodes).flatMap(Set::stream).collect(Collectors.toSet()); + return tree.descendants(annotationNodeType).crossFindBoundaries().toStream().map(this::getUnusedSuppressorNodes).flatMap(Set::stream).collect(Collectors.toSet()); } @@ -63,6 +67,12 @@ private boolean contextSuppresses(Node node, Rule rule) { } if (node instanceof RootNode) { + // This logic is here to suppress violations on the root node + // based on an annotation of its child. In Java for instance + // you cannot annotate the root node, because you can only annotate + // declarations. But an annotation on a toplevel class, or on + // the package declaration, would suppress violations on the root + // node as well. for (int i = 0; i < node.getNumChildren(); i++) { if (suppresses(node.getChild(i), rule)) { return true; diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index fad0298babe..3f40ad75535 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -1638,7 +1638,7 @@ class C { language="java" since="7.14.0" message="Unused suppression {0}." - class="net.sourceforge.pmd.lang.rule.internal.UnnecessaryPmdSuppressionRule" + class="net.sourceforge.pmd.lang.rule.impl.UnnecessaryPmdSuppressionRule" externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unnecessarywarningsuppression"> This rule reports suppression comments and annotations that did not suppress any PMD violation. diff --git a/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java b/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java index e515b819a1d..d9118bb40d3 100644 --- a/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java +++ b/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java @@ -51,7 +51,7 @@ import net.sourceforge.pmd.lang.rule.RuleSet; import net.sourceforge.pmd.lang.rule.RuleSetLoader; import net.sourceforge.pmd.lang.rule.RuleSetWriter; -import net.sourceforge.pmd.lang.rule.internal.UnnecessaryPmdSuppressionRule; +import net.sourceforge.pmd.lang.rule.impl.UnnecessaryPmdSuppressionRule; import net.sourceforge.pmd.lang.rule.xpath.XPathRule; import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.util.log.internal.MessageReporterBase; From db05234549adda37d04bf12e4ccd64cbf049a646 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 May 2025 09:41:08 +0200 Subject: [PATCH 0940/1962] Bump scalameta.version from 4.13.5 to 4.13.6 (#5751) Bumps `scalameta.version` from 4.13.5 to 4.13.6. Updates `org.scalameta:parsers_2.13` from 4.13.5 to 4.13.6 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.5...v4.13.6) Updates `org.scalameta:trees_2.13` from 4.13.5 to 4.13.6 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.5...v4.13.6) Updates `org.scalameta:parsers_2.12` from 4.13.5 to 4.13.6 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.5...v4.13.6) Updates `org.scalameta:trees_2.12` from 4.13.5 to 4.13.6 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.5...v4.13.6) --- updated-dependencies: - dependency-name: org.scalameta:parsers_2.13 dependency-version: 4.13.6 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:trees_2.13 dependency-version: 4.13.6 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:parsers_2.12 dependency-version: 4.13.6 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:trees_2.12 dependency-version: 4.13.6 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index 131354ac1bd..480bec51497 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -13,7 +13,7 @@ - 4.13.5 + 4.13.6 From caff8607bda7c4cb1ef68eafaa9d3f396219cbe7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 May 2025 09:41:37 +0200 Subject: [PATCH 0941/1962] Bump com.google.protobuf:protobuf-java from 4.30.2 to 4.31.0 (#5754) Bumps [com.google.protobuf:protobuf-java](https://github.com/protocolbuffers/protobuf) from 4.30.2 to 4.31.0. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl) - [Commits](https://github.com/protocolbuffers/protobuf/compare/v4.30.2...v4.31.0) --- updated-dependencies: - dependency-name: com.google.protobuf:protobuf-java dependency-version: 4.31.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 862446e709a..ea09ca3f432 100644 --- a/pom.xml +++ b/pom.xml @@ -1105,7 +1105,7 @@ com.google.protobuf protobuf-java - 4.30.2 + 4.31.0 + 0 + + + + From 3776737e3b8ebca7b18b85ea5661175dd2a213f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 20 Mar 2025 14:30:49 +0100 Subject: [PATCH 0945/1962] Support annotated ctor return type Ref #4334 --- .../lang/java/symbols/JConstructorSymbol.java | 8 +++++ .../lang/java/symbols/JExecutableSymbol.java | 16 ++++++++++ .../pmd/lang/java/symbols/JMethodSymbol.java | 6 ---- .../internal/ImplicitMemberSymbols.java | 1 + .../symbols/internal/asm/ExecutableStub.java | 11 +++---- .../symbols/internal/asm/GenericSigBase.java | 8 +++++ .../internal/ast/AbstractAstAnnotableSym.java | 1 + .../internal/ast/AbstractAstExecSymbol.java | 23 ++++++++++++++ .../java/symbols/internal/ast/AstCtorSym.java | 9 ++++++ .../symbols/internal/ast/AstMethodSym.java | 2 +- .../lang/java/types/ClassMethodSigImpl.java | 12 ++----- .../TypeAnnotReflectionOnMethodsTest.java | 31 +++++++++++++++++++ .../symbols/internal/TypeAnnotTestUtil.java | 3 ++ .../ClassWithTypeAnnotationsOnMethods.java | 6 ++-- 14 files changed, 112 insertions(+), 25 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JConstructorSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JConstructorSymbol.java index 7f8037e582f..527901e1dbc 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JConstructorSymbol.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JConstructorSymbol.java @@ -6,6 +6,9 @@ package net.sourceforge.pmd.lang.java.symbols; import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration; +import net.sourceforge.pmd.lang.java.types.JTypeMirror; +import net.sourceforge.pmd.lang.java.types.Substitution; +import net.sourceforge.pmd.lang.java.types.TypeSystem; /** @@ -25,6 +28,11 @@ default String getSimpleName() { return CTOR_NAME; } + @Override + default JTypeMirror getReturnType(Substitution subst) { + TypeSystem ts = getTypeSystem(); + return ts.declaration(getEnclosingClass()).subst(subst); + } @Override default R acceptVisitor(SymbolVisitor visitor, P param) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java index 732421616a8..6b5d7341e31 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java @@ -15,6 +15,7 @@ import net.sourceforge.pmd.lang.java.types.JMethodSig; import net.sourceforge.pmd.lang.java.types.JTypeMirror; import net.sourceforge.pmd.lang.java.types.Substitution; +import net.sourceforge.pmd.lang.java.types.TypeSystem; /** * Common supertype for {@linkplain JMethodSymbol method} @@ -31,6 +32,21 @@ public interface JExecutableSymbol extends JTypeParameterOwnerSymbol { */ List getFormalParameters(); + /** + * Return the return type under the given substitution. + * For a constructor, return the type of the owner. This type + * may be annotated. + */ + default JTypeMirror getReturnType(Substitution subst) { + if (this instanceof JConstructorSymbol) { + TypeSystem ts = getTypeSystem(); + return ts.declaration(getEnclosingClass()).subst(subst); + } + // JMethodSymbol has always had this method abstract so this branch + // should never be taken. + throw new UnsupportedOperationException("Default method was added for compatibility, will be removed"); + } + default boolean isDefaultMethod() { // Default methods are public non-abstract instance methods diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JMethodSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JMethodSymbol.java index 81f93e1cc36..916602cce89 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JMethodSymbol.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JMethodSymbol.java @@ -10,8 +10,6 @@ import org.checkerframework.checker.nullness.qual.Nullable; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; -import net.sourceforge.pmd.lang.java.types.JTypeMirror; -import net.sourceforge.pmd.lang.java.types.Substitution; /** @@ -31,10 +29,6 @@ default boolean isStatic() { return Modifier.isStatic(getModifiers()); } - - /** Returns the return type under the given substitution. */ - JTypeMirror getReturnType(Substitution subst); - /** * Returns the default value, if this is a constant method. See * {@link SymbolicValue} for current limitations diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ImplicitMemberSymbols.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ImplicitMemberSymbols.java index d3a475e1ea3..77f42834d34 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ImplicitMemberSymbols.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ImplicitMemberSymbols.java @@ -289,6 +289,7 @@ private static final class FakeCtorSym extends FakeExecutableSymBase getFormalParameters() { return params; } + @Override + public JTypeMirror getReturnType(Substitution subst) { + return type.getReturnType().subst(subst); + } + @Override public boolean isVarargs() { return (getModifiers() & Opcodes.ACC_VARARGS) != 0; @@ -194,12 +199,6 @@ public boolean isBridge() { return (getModifiers() & Opcodes.ACC_BRIDGE) != 0; } - @Override - public JTypeMirror getReturnType(Substitution subst) { - return type.getReturnType().subst(subst); - } - - @Override public String toString() { return SymbolToStrings.ASM.toString(this); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java index 87ca425dc41..86b25d847e6 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java @@ -21,6 +21,7 @@ import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; import net.sourceforge.pmd.lang.java.symbols.JTypeParameterOwnerSymbol; import net.sourceforge.pmd.lang.java.symbols.SymbolicValue.SymAnnot; +import net.sourceforge.pmd.lang.java.symbols.internal.asm.ExecutableStub.CtorStub; import net.sourceforge.pmd.lang.java.symbols.internal.asm.TypeAnnotationHelper.TypeAnnotationSet; import net.sourceforge.pmd.lang.java.symbols.internal.asm.TypeAnnotationHelper.TypeAnnotationSetWithReferences; import net.sourceforge.pmd.lang.java.types.JClassType; @@ -270,6 +271,13 @@ protected void doParse() { .map(ctx.getTypeSystem()::rawType) .collect(CollectionUtil.toUnmodifiableList()); } + if (ctx instanceof CtorStub) { + // Is a constructor, return type of the descriptor is void. + // We replace the return type with the owner type. This must + // be done before type annotations are applied. + assert this.returnType.isVoid(); + this.returnType = ctx.getTypeSystem().declaration(ctx.getEnclosingClass()); + } if (typeAnnots != null) { // apply type annotations here // this may change type parameters diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AbstractAstAnnotableSym.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AbstractAstAnnotableSym.java index 88da82cee13..a857ab77f8f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AbstractAstAnnotableSym.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AbstractAstAnnotableSym.java @@ -27,6 +27,7 @@ abstract class AbstractAstAnnotableSym getDeclaredAnnotations() { if (annots == null) { + // todo filter out type annotations annots = SymbolResolutionPass.buildSymbolicAnnotations(node.getDeclaredAnnotations()); } return annots; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AbstractAstExecSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AbstractAstExecSymbol.java index 7cdca0311dd..ee303f2bc37 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AbstractAstExecSymbol.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AbstractAstExecSymbol.java @@ -4,10 +4,12 @@ package net.sourceforge.pmd.lang.java.symbols.internal.ast; +import java.lang.annotation.ElementType; import java.util.List; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import org.pcollections.PSet; import net.sourceforge.pmd.lang.java.ast.ASTExecutableDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTList; @@ -15,6 +17,7 @@ import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; import net.sourceforge.pmd.lang.java.symbols.JExecutableSymbol; import net.sourceforge.pmd.lang.java.symbols.JFormalParamSymbol; +import net.sourceforge.pmd.lang.java.symbols.SymbolicValue.SymAnnot; import net.sourceforge.pmd.lang.java.types.JTypeMirror; import net.sourceforge.pmd.lang.java.types.Substitution; import net.sourceforge.pmd.util.CollectionUtil; @@ -28,6 +31,8 @@ abstract class AbstractAstExecSymbol private final JClassSymbol owner; private final List formals; + // these are ambiguous as they can apply to both the return type or the declaration + private PSet returnTypeAnnots; protected AbstractAstExecSymbol(T node, AstSymFactory factory, JClassSymbol owner) { super(node, factory); @@ -70,6 +75,24 @@ public List getThrownExceptionTypes(Substitution subst) { return receiver.getReceiverType().getTypeMirror().subst(subst); } + @Override + public final JTypeMirror getReturnType(Substitution subst) { + JTypeMirror mirror = makeReturnType(subst); + if (returnTypeAnnots == null) { + returnTypeAnnots = + SymbolResolutionPass.buildSymbolicAnnotations(node.getDeclaredAnnotations()) + .stream() + .filter(it -> it.getAnnotationSymbol().annotationAppliesTo(ElementType.TYPE_USE)) + .collect(CollectionUtil.toPersistentSet()); + } + if (returnTypeAnnots.isEmpty()) { + return mirror; + } + return mirror.withAnnotations(mirror.getTypeAnnotations().plusAll(returnTypeAnnots)); + } + + protected abstract JTypeMirror makeReturnType(Substitution subst); + @Override public @NonNull JClassSymbol getEnclosingClass() { return owner; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstCtorSym.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstCtorSym.java index 47302dfe766..f27cd2276bf 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstCtorSym.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstCtorSym.java @@ -7,14 +7,23 @@ import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration; import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; import net.sourceforge.pmd.lang.java.symbols.JConstructorSymbol; +import net.sourceforge.pmd.lang.java.types.JTypeMirror; +import net.sourceforge.pmd.lang.java.types.Substitution; +import net.sourceforge.pmd.lang.java.types.TypeSystem; /** * @author Clรฉment Fournier */ final class AstCtorSym extends AbstractAstExecSymbol implements JConstructorSymbol { + AstCtorSym(ASTConstructorDeclaration node, AstSymFactory factory, JClassSymbol owner) { super(node, factory, owner); } + @Override + protected JTypeMirror makeReturnType(Substitution subst) { + TypeSystem ts = getTypeSystem(); + return ts.declaration(getEnclosingClass()).subst(subst); + } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstMethodSym.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstMethodSym.java index 9be3396d7a3..762bc0424d1 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstMethodSym.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstMethodSym.java @@ -32,7 +32,7 @@ public boolean isBridge() { } @Override - public JTypeMirror getReturnType(Substitution subst) { + protected JTypeMirror makeReturnType(Substitution subst) { ASTType rt = node.getResultTypeNode(); return TypeOps.subst(rt.getTypeMirror(), subst); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ClassMethodSigImpl.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ClassMethodSigImpl.java index 33c6b9d2c78..1bdc31da80f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ClassMethodSigImpl.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ClassMethodSigImpl.java @@ -17,7 +17,6 @@ import org.checkerframework.checker.nullness.qual.Nullable; import net.sourceforge.pmd.lang.java.symbols.JExecutableSymbol; -import net.sourceforge.pmd.lang.java.symbols.JMethodSymbol; import net.sourceforge.pmd.lang.java.types.internal.InternalMethodTypeItf; class ClassMethodSigImpl implements JMethodSig, InternalMethodTypeItf { @@ -92,15 +91,10 @@ public JMethodSig getErasure() { @Override public JTypeMirror getReturnType() { if (resultType == null) { - if (symbol instanceof JMethodSymbol) { - if (owner.isRaw()) { - resultType = ClassTypeImpl.eraseToRaw(((JMethodSymbol) symbol).getReturnType(EMPTY), getTypeParamSubst()); - } else { - resultType = ((JMethodSymbol) symbol).getReturnType(getTypeParamSubst()); - } + if (owner.isRaw()) { + resultType = ClassTypeImpl.eraseToRaw(symbol.getReturnType(EMPTY), getTypeParamSubst()); } else { - // constructor - resultType = owner; + resultType = symbol.getReturnType(getTypeParamSubst()); } } return resultType; diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/TypeAnnotReflectionOnMethodsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/TypeAnnotReflectionOnMethodsTest.java index d66b719c0f2..c7d0b4674a5 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/TypeAnnotReflectionOnMethodsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/TypeAnnotReflectionOnMethodsTest.java @@ -9,6 +9,7 @@ import static net.sourceforge.pmd.lang.java.symbols.internal.TypeAnnotTestUtil.ANNOT_B; import static net.sourceforge.pmd.lang.java.symbols.internal.TypeAnnotTestUtil.assertHasAnnots; import static net.sourceforge.pmd.lang.java.symbols.internal.TypeAnnotTestUtil.assertHasTypeAnnots; +import static net.sourceforge.pmd.lang.java.symbols.internal.TypeAnnotTestUtil.getCtorType; import static net.sourceforge.pmd.lang.java.symbols.internal.TypeAnnotTestUtil.getMethodType; import static net.sourceforge.pmd.util.CollectionUtil.emptyList; import static org.hamcrest.MatcherAssert.assertThat; @@ -171,5 +172,35 @@ void testTypeAnnotOnReceiver(SymImplementation impl) { } } + @ParameterizedTest + @EnumSource + void testTypeAnnotOnCtor(SymImplementation impl) { + JClassType sym = impl.getDeclaration(ClassWithTypeAnnotationsOnMethods.CtorOwner.class); + + /* + CtorOwner(@A @B int i) { } + + @A CtorOwner() { } + + CtorOwner(String i, int x) throws @A Exception {} + */ + + { + JMethodSig t = getCtorType(sym, 1); + assertHasTypeAnnots(t.getFormalParameters().get(0), ANNOTS_A_B); + assertHasTypeAnnots(t.getReturnType(), emptyList()); + } + { + JMethodSig t = getCtorType(sym, 0); + assertHasTypeAnnots(t.getReturnType(), ANNOT_A); + } + { + JMethodSig t = getCtorType(sym, 2); + assertHasTypeAnnots(t.getFormalParameters().get(0), emptyList()); + assertHasTypeAnnots(t.getFormalParameters().get(0), emptyList()); + assertHasTypeAnnots(t.getThrownExceptions().get(0), ANNOT_A); + } + } + } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/TypeAnnotTestUtil.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/TypeAnnotTestUtil.java index 6eb7d092d80..dfce61d403b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/TypeAnnotTestUtil.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/TypeAnnotTestUtil.java @@ -54,6 +54,9 @@ public static JMethodSig getMethodType(JClassType sym, String fieldName) { return sym.streamMethods(it -> it.nameEquals(fieldName)).findFirst().get(); } + public static JMethodSig getCtorType(JClassType sym, int arity) { + return sym.getConstructors().stream().filter(it -> it.getArity() == arity).findFirst().get(); + } public static JMethodSymbol getMethodSym(JClassSymbol sym, String fieldName) { return sym.getDeclaredMethods().stream().filter(it -> it.nameEquals(fieldName)).findFirst().get(); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/testdata/ClassWithTypeAnnotationsOnMethods.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/testdata/ClassWithTypeAnnotationsOnMethods.java index b337ab857c2..4987e9e8f78 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/testdata/ClassWithTypeAnnotationsOnMethods.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/testdata/ClassWithTypeAnnotationsOnMethods.java @@ -11,7 +11,7 @@ import net.sourceforge.pmd.lang.java.symbols.testdata.ClassWithTypeAnnotationsInside.B; /** - * See {@link TypeAnnotReflectionOnMethodsTest}. + * See {TypeAnnotReflectionOnMethodsTest}. * * @author Clรฉment Fournier */ @@ -40,13 +40,13 @@ public abstract class ClassWithTypeAnnotationsOnMethods { abstract void abOnReceiver(@A @B ClassWithTypeAnnotationsOnMethods this); - static class CtorOwner { + public static class CtorOwner { CtorOwner(@A @B int i) { } @A CtorOwner() { } - CtorOwner(String i) throws @A Exception {} + CtorOwner(String i, int x) throws @A Exception {} } } From e42144582a19738b4830d717554f9c9dd8c0d67e Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Sat, 17 May 2025 19:23:42 +0200 Subject: [PATCH 0946/1962] Fix #2462: [java] LinguisticNaming should ignore setters for Builders --- .../rule/codestyle/LinguisticNamingRule.java | 6 +++++- .../rule/codestyle/xml/LinguisticNaming.xml | 21 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LinguisticNamingRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LinguisticNamingRule.java index b571bfd5f3f..c198a950ab6 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LinguisticNamingRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LinguisticNamingRule.java @@ -140,12 +140,16 @@ private void checkGetters(ASTMethodDeclaration node, Object data, String nameOfM } private void checkSetters(ASTMethodDeclaration node, Object data, String nameOfMethod) { - if (startsWithCamelCaseWord(nameOfMethod, "set") && !node.isVoid()) { + if (startsWithCamelCaseWord(nameOfMethod, "set") && !node.isVoid() && returnsEnclosingType(node)) { asCtx(data).addViolationWithMessage(node, "Linguistics Antipattern - The setter ''{0}'' should not return any type except void linguistically", nameOfMethod); } } + private static boolean returnsEnclosingType(ASTMethodDeclaration node) { + return !node.getResultTypeNode().getTypeMirror().equals(node.getEnclosingType().getTypeMirror()); + } + private boolean isBooleanType(ASTType node) { return node.getTypeMirror().unbox().isPrimitive(PrimitiveTypeKind.BOOLEAN) || TypeTestUtil.isA("java.util.concurrent.atomic.AtomicBoolean", node) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LinguisticNaming.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LinguisticNaming.xml index e04efa2d289..4ca0a62d42a 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LinguisticNaming.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LinguisticNaming.xml @@ -613,6 +613,27 @@ public class SomeClass { public Predicate isEmptyPredicate() { return String::isEmpty; } +} + ]]> + + + + #2462 LinguisticNaming must ignore setters that returns current type + 0 + From 77133f1349a41905b69d4d93fa933367eeff6f01 Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Sun, 25 May 2025 16:57:25 +0200 Subject: [PATCH 0947/1962] #2462: Add additional testcase --- .../rule/codestyle/xml/LinguisticNaming.xml | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LinguisticNaming.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LinguisticNaming.xml index 4ca0a62d42a..4e1c1daf7ef 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LinguisticNaming.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LinguisticNaming.xml @@ -618,7 +618,7 @@ public class SomeClass { - #2462 LinguisticNaming must ignore setters that returns current type + #2462 LinguisticNaming must ignore setters that returns current type - Simple Builder 0 + + + #2462 LinguisticNaming must ignore setters that returns current type - Builder as inner class + 0 + + From b2b08910761ef195d2a8d1f5b587fb40b7bb6d25 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 May 2025 11:35:03 +0200 Subject: [PATCH 0948/1962] Bump com.puppycrawl.tools:checkstyle from 10.23.1 to 10.24.0 (#5768) Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.23.1 to 10.24.0. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.23.1...checkstyle-10.24.0) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-version: 10.24.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ea09ca3f432..d88fd91568b 100644 --- a/pom.xml +++ b/pom.xml @@ -90,7 +90,7 @@ 5.0 3.5.3 - 10.23.1 + 10.24.0 3.6.0 3.26.0 1.10.15 From cb0625a9c7d32836a8c0fe9d7294ffb5556e850e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 May 2025 11:35:39 +0200 Subject: [PATCH 0949/1962] Bump io.github.git-commit-id:git-commit-id-maven-plugin from 9.0.1 to 9.0.2 (#5766) Bump io.github.git-commit-id:git-commit-id-maven-plugin Bumps [io.github.git-commit-id:git-commit-id-maven-plugin](https://github.com/git-commit-id/git-commit-id-maven-plugin) from 9.0.1 to 9.0.2. - [Release notes](https://github.com/git-commit-id/git-commit-id-maven-plugin/releases) - [Commits](https://github.com/git-commit-id/git-commit-id-maven-plugin/compare/v9.0.1...v9.0.2) --- updated-dependencies: - dependency-name: io.github.git-commit-id:git-commit-id-maven-plugin dependency-version: 9.0.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index b10c5dc39f8..8941e0e9b43 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -29,7 +29,7 @@ io.github.git-commit-id git-commit-id-maven-plugin - 9.0.1 + 9.0.2 get-the-git-infos From d47399067ce9842ecabc526e0c0687a7eb9182ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 May 2025 11:36:31 +0200 Subject: [PATCH 0950/1962] Bump org.mockito:mockito-core from 5.17.0 to 5.18.0 (#5767) Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.17.0 to 5.18.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.17.0...v5.18.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-version: 5.18.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d88fd91568b..d5cc3f4edd2 100644 --- a/pom.xml +++ b/pom.xml @@ -998,7 +998,7 @@ org.mockito mockito-core - 5.17.0 + 5.18.0 test From 2d6ccea0c0e037aca3b5f3f1eddf54a7b4405648 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 29 May 2025 17:24:38 +0200 Subject: [PATCH 0951/1962] [java] Update javadoc (since, deprecated) --- .../pmd/lang/java/ast/ASTCompactConstructorDeclaration.java | 3 +++ .../net/sourceforge/pmd/lang/java/ast/JavaVisitorBase.java | 3 +++ .../net/sourceforge/pmd/lang/java/ast/ReturnScopeNode.java | 2 ++ .../net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java | 2 +- .../pmd/lang/java/metrics/internal/NPathMetricCalculator.java | 3 +++ .../pmd/lang/java/metrics/internal/NpathBaseVisitor.java | 2 +- 6 files changed, 13 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompactConstructorDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompactConstructorDeclaration.java index 3071e143053..7c33d284e16 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompactConstructorDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompactConstructorDeclaration.java @@ -63,6 +63,9 @@ protected R acceptVisitor(JavaVisitor visitor, P return Objects.requireNonNull(firstChild(ASTBlock.class)); } + /** + * @deprecated Since 7.14.0. This method just returns `this` and isn't useful. + */ @Deprecated public ASTCompactConstructorDeclaration getDeclarationNode() { return this; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaVisitorBase.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaVisitorBase.java index 78e774e7531..984523e9ee8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaVisitorBase.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaVisitorBase.java @@ -399,6 +399,9 @@ public R visit(ASTYieldStatement node, P data) { } + /** + * @since 7.14.0 + */ public R visitLoop(ASTLoopStatement node, P data) { return visitStatement(node, data); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ReturnScopeNode.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ReturnScopeNode.java index a90dba040fa..acdb6108e11 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ReturnScopeNode.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ReturnScopeNode.java @@ -21,6 +21,8 @@ * | {@link ASTCompactConstructorDeclaration CompactConstructorDeclaration} * * + * + * @since 7.14.0 */ public interface ReturnScopeNode extends JavaNode { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java index 4e368ed379d..2fa30bf8a40 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java @@ -385,7 +385,7 @@ public final class JavaMetrics { "NPath Complexity", "NPath"); /** - * @deprecated Use {@link #NPATH_COMP}, which is available on more nodes, + * @deprecated Since 7.14.0. Use {@link #NPATH_COMP}, which is available on more nodes, * and uses Long instead of BigInteger. */ @Deprecated diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/NPathMetricCalculator.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/NPathMetricCalculator.java index 7a473a42716..d1ac42a47a0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/NPathMetricCalculator.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/NPathMetricCalculator.java @@ -44,6 +44,9 @@ import net.sourceforge.pmd.lang.java.ast.ReturnScopeNode; import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; +/** + * @since 7.14.0. + */ public final class NPathMetricCalculator { private NPathMetricCalculator() { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/NpathBaseVisitor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/NpathBaseVisitor.java index 4c7b17b18dc..82e52e151eb 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/NpathBaseVisitor.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/NpathBaseVisitor.java @@ -35,7 +35,7 @@ * * @author Clรฉment Fournier * @author Jason Bennett - * @deprecated Has been replaced by {@link NPathMetricCalculator} + * @deprecated Since 7.14.0. Has been replaced by {@link NPathMetricCalculator} */ @Deprecated public class NpathBaseVisitor extends JavaVisitorBase { From 4c43fc0cfdc1dc7d55150e2231a1ee6448d30346 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 29 May 2025 17:25:15 +0200 Subject: [PATCH 0952/1962] [doc] Update release notes (#5599, #5568, #5647) --- docs/pages/release_notes.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 6cf2dcb3c1b..670f68c7c45 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -32,9 +32,18 @@ This is a {{ site.pmd.release_type }} release. * [#5645](https://github.com/pmd/pmd/issues/5645): \[java] Parse error on switch with yield * java-bestpractices * [#5687](https://github.com/pmd/pmd/issues/5687): \[java] UnusedPrivateMethodRule: exclude serialization method readObjectNoData() +* java-design + * [#5568](https://github.com/pmd/pmd/issues/5568): \[java] High NPathComplexity in `switch` expression + * [#5647](https://github.com/pmd/pmd/issues/5647): \[java] NPathComplexity does not account for `return`s ### ๐Ÿšจ API Changes +#### Deprecations +* pmd-java + * {% jdoc !!java::lang.java.ast.ASTCompactConstructorDeclaration#getDeclarationNode() %}: This method just returns `this` and isn't useful. + * {% jdoc !!java::lang.java.metrics.JavaMetrics#NPATH %}: Use {% jdoc java::lang.java.metrics.JavaMetrics#NPATH_COMP %}, which is available on more nodes, + and uses Long instead of BigInteger. + ### โœจ Merged pull requests * [#5450](https://github.com/pmd/pmd/pull/5450): Fix #3184: \[apex] New Rule: TypeShadowsBuiltInNamespace - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) @@ -43,6 +52,7 @@ This is a {{ site.pmd.release_type }} release. * [#5684](https://github.com/pmd/pmd/pull/5684): Fix #5667: \[apex] ApexUnitTestShouldNotUseSeeAllDataTrue false negative when seeAllDate parameter is a string - [Thomas Prouvot](https://github.com/tprouvot) (@tprouvot) * [#5685](https://github.com/pmd/pmd/pull/5685): \[doc] typo fix in PMD Designer reference - [Douglas Griffith](https://github.com/dwgrth) (@dwgrth) * [#5687](https://github.com/pmd/pmd/pull/5687): \[java] UnusedPrivateMethodRule: exclude serialization method readObjectNoData() - [Gili Tzabari](https://github.com/cowwoc) (@cowwoc) +* [#5599](https://github.com/pmd/pmd/pull/5599): \[java] Rewrite NPath complexity metric - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) ### ๐Ÿ“ฆ Dependency updates From 77ca4a29825e38be79c2bf6770393a3531390db6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 29 May 2025 18:19:54 +0200 Subject: [PATCH 0953/1962] [doc] Update release notes (#5727, #5621) --- docs/pages/release_notes.md | 7 +++++++ .../net/sourceforge/pmd/lang/java/ast/MethodUsage.java | 2 ++ .../pmd/lang/java/types/OverloadSelectionResult.java | 1 + .../java/rule/bestpractices/xml/UnusedPrivateMethod.xml | 2 +- 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 0c9c0dd3524..4914da30815 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,11 +25,18 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* java-bestpractices + * [#5621](https://github.com/pmd/pmd/issues/5621): \[java] UnusedPrivateMethod with method ref ### ๐Ÿšจ API Changes +#### Experimental +* pmd-java + * {%jdoc !!java::lang.java.types.OverloadSelectionResult#getTypeToSearch() %} + ### โœจ Merged pull requests +* [#5727](https://github.com/pmd/pmd/pull/5727): Fix #5621: \[java] Fix FPs with UnusedPrivateMethod - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) ### ๐Ÿ“ฆ Dependency updates diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/MethodUsage.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/MethodUsage.java index cbb473a6381..dcd9a8ceabb 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/MethodUsage.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/MethodUsage.java @@ -29,6 +29,8 @@ public interface MethodUsage extends JavaNode { /** * Returns information about the overload selection for this call. * Be aware, that selection might have failed ({@link OverloadSelectionResult#isFailed()}). + * + * @since 7.14.0 */ OverloadSelectionResult getOverloadSelectionInfo(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java index 76bf6b10f7c..b9094c898bf 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java @@ -98,6 +98,7 @@ default JTypeMirror ithFormalParam(int i) { * constructor call expressions. * * @see ExprMirror.MethodUsageMirror#getTypeToSearch() + * @experimental Since 7.14.0 */ @Experimental @Nullable JTypeMirror getTypeToSearch(); diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index 00a462f93a5..f138aedb176 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2732,7 +2732,7 @@ class Foo { - [java] UnusedPrivateMethod false-positive #5664 + [java] UnusedPrivateMethod false-positive #5664 (not reproducible) 0 Date: Thu, 29 May 2025 19:55:32 +0200 Subject: [PATCH 0954/1962] [cli] Remove --ignore again --- docs/pages/pmd/userdocs/cli_reference.md | 24 ++++++++----------- .../AbstractAnalysisPmdSubcommand.java | 12 ---------- .../net/sourceforge/pmd/cli/CpdCliTest.java | 19 --------------- .../net/sourceforge/pmd/cli/PmdCliTest.java | 2 +- 4 files changed, 11 insertions(+), 46 deletions(-) diff --git a/docs/pages/pmd/userdocs/cli_reference.md b/docs/pages/pmd/userdocs/cli_reference.md index f154fafedd7..46ee9730175 100644 --- a/docs/pages/pmd/userdocs/cli_reference.md +++ b/docs/pages/pmd/userdocs/cli_reference.md @@ -5,7 +5,7 @@ tags: [userdocs] keywords: [command, line, options, help, formats, renderers] permalink: pmd_userdocs_cli_reference.html author: Tom Copeland , Xavier Le Vourch , Juan Martรญn Sotuyo Dodero -last_updated: June 2024 (7.3.0) +last_updated: May 2025 (7.14.0) --- @@ -173,33 +173,29 @@ least one of `--dir`, `--file-list` or `--uri` must be provided. option_arg="filepath+" description="Specify one or more paths to files that will be ignored. This option overrides files included by any of `--dir`, `--file-list` and `--uri`. - It can combine with `--ignore-list`." + It can combine with `--exclude-file-list`. + Available for PMD since 7.14.0, for CPD since 7.0.0." %} {% include custom/cli_option_row.html options="--exclude-file-list" option_arg="filepath" description="Path to a file containing a list of files to ignore, one path per line. This option overrides files included by any of `--dir`, `--file-list` and `--uri`. - It can combine with `--ignore`" - %} - {% include custom/cli_option_row.html options="--ignore" - option_arg="filepath+" - description="Deprecated (6.14.0) - This option has been renamed `--exclude`. - Specify one or more paths to files that will be ignored. - This option overrides files included by any of `--dir`, `--file-list` and `--uri`. - It can combine with `--ignore-list`." + It can combine with `--exclude`. + Available for PMD since 7.14.0, for CPD since 7.14.0. + For PMD, this option was called `--ignore-list`." %} {% include custom/cli_option_row.html options="--ignore-list" option_arg="filepath" - description="Deprecated (6.14.0) + description="Deprecated (Since 7.14.0) This option has been renamed `--exclude-file-list`. Path to file containing a list of files to ignore, one path per line. This option overrides files included by any of `--dir`, `--file-list` and `--uri`. - It can combine with `--ignore`" + It can combine with `--exclude`." %} {% include custom/cli_option_row.html options="--non-recursive" description="When specified, any directory mentioned with `--dir` or in the `--file-list` will only be searched for files that are direct children. - By default, subdirectories are recursively included." + By default, subdirectories are recursively included. + Available for PMD since 7.14.0, for CPD since 7.0.0." %} {% include custom/cli_option_row.html options="--relativize-paths-with,-z" option_arg="path" diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java index 799ad819fc4..801f7e5bc3f 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java @@ -18,7 +18,6 @@ import net.sourceforge.pmd.AbstractConfiguration; import net.sourceforge.pmd.cli.internal.CliExitCode; import net.sourceforge.pmd.cli.internal.PmdRootLogger; -import net.sourceforge.pmd.util.CollectionUtil; import net.sourceforge.pmd.util.log.internal.SimpleMessageReporter; import picocli.CommandLine; @@ -54,16 +53,8 @@ protected static class FileCollectionOptions { private URI uri; - boolean usesDeprecatedIgnoreOption = false; boolean usesDeprecatedIgnoreListOption = false; - @Option(names = "--ignore", arity = "1..*", description = "(DEPRECATED: use --exclude) Files to be excluded from the analysis") - @Deprecated - protected void setIgnoreSpecificPaths(List rootPaths) { - this.excludeFiles = CollectionUtil.makeUnmodifiableAndNonNull(rootPaths); - this.usesDeprecatedIgnoreOption = true; - } - @Option(names = "--ignore-list", description = "(DEPRECATED: use --exclude-file-list) Path to a file containing a list of files to exclude from the analysis, one path per line. " + "This option can be combined with --dir, --file-list and --uri.") @@ -136,9 +127,6 @@ protected void configureFilesToAnalyze(C configuration) { } configuration.setSourceEncoding(encoding); - if (usesDeprecatedIgnoreOption) { - configuration.getReporter().warn("Option name --ignore is deprecated. Use --exclude instead."); - } if (usesDeprecatedIgnoreListOption) { configuration.getReporter().warn("Option name --ignore-list is deprecated. Use --exclude-file-list instead."); } diff --git a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/CpdCliTest.java b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/CpdCliTest.java index e73bc2d740d..d9b0975fab9 100644 --- a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/CpdCliTest.java +++ b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/CpdCliTest.java @@ -294,25 +294,6 @@ void testExcludeFileListDeprecated() throws Exception { }); } - @Test - void testExcludeFileDeprecated() throws Exception { - runCli(OK, - "--minimum-tokens", "10", - "--file-list", BASE_RES_PATH + "fileList.txt", - "--ignore", BASE_RES_PATH + "badandgood/GoodFile.java", BASE_RES_PATH + "badandgood/GoodFile2.java", - "--format", "text", "--debug") - .verify(r -> { - r.checkStdErr(containsPattern("Adding regular file .*GoodFile.java")); - r.checkStdErr(containsPattern("Adding regular file .*GoodFile2.java")); - r.checkStdErr(containsPattern("Excluding file .*GoodFile.java")); - r.checkStdErr(containsPattern("Excluding file .*GoodFile2.java")); - - r.checkStdErr(containsString("deprecated. Use --exclude")); - - r.checkStdOut(not(containsString("Found a 5 line (13 tokens) duplication"))); - }); - } - @Test void testReportFile(@TempDir Path tmp) throws Exception { diff --git a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java index 043e6538391..027cd767a8c 100644 --- a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java +++ b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java @@ -152,7 +152,7 @@ void testExcludeFile() throws Exception { // restoring system properties: --debug might change logging properties SystemLambda.restoreSystemProperties(() -> { runCli(OK, - "--dir", srcDir.toString(), "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "--ignore", srcDir.toString(), "--debug") + "--dir", srcDir.toString(), "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "--exclude", srcDir.toString(), "--debug") .verify(r -> { r.checkStdErr(containsString("No files to analyze")); r.checkStdOut(emptyString()); From c2c499d8cccddf9d548a5d45b7230f6ffec40fa5 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 29 May 2025 19:57:14 +0200 Subject: [PATCH 0955/1962] [doc] Update javadoc + release notes (#5731) --- docs/pages/pmd/userdocs/cpd/cpd.md | 4 ++-- docs/pages/release_notes.md | 13 +++++++++++++ .../pmd/cli/commands/internal/CpdCommand.java | 2 +- .../net/sourceforge/pmd/AbstractConfiguration.java | 2 ++ 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/docs/pages/pmd/userdocs/cpd/cpd.md b/docs/pages/pmd/userdocs/cpd/cpd.md index 7818ac1490f..67fe51ff9ee 100644 --- a/docs/pages/pmd/userdocs/cpd/cpd.md +++ b/docs/pages/pmd/userdocs/cpd/cpd.md @@ -4,7 +4,7 @@ tags: [cpd, userdocs] summary: "Learn how to use CPD, the copy-paste detector shipped with PMD." permalink: pmd_userdocs_cpd.html author: Tom Copeland -last_updated: June 2024 (7.3.0) +last_updated: May 2025 (7.14.0) --- ## Overview @@ -105,7 +105,7 @@ exactly identical. description="Ignore multiple copies of files of the same name and length in comparison." %} {% include custom/cli_option_row.html options="--skip-lexical-errors" - description="Deprecated Skip files which can't be tokenized due to invalid characters instead of aborting CPD. + description="Deprecated (Since 7.3.0) Skip files which can't be tokenized due to invalid characters instead of aborting CPD. By default, CPD analysis is stopped on the first error. This is deprecated. Use `--fail-on-error` instead." %} {% include custom/cli_option_row.html options="--format,-f" diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index eeca05e4906..100f5187a62 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -48,6 +48,12 @@ use the following snippet: Releases of PMD are available on [Maven Central](https://central.sonatype.com/) as before without change. +#### More CLI parameters shared between PMD and CPD + +When executing PMD or CPD, the same parameters are now understood for selecting which files should +be analyzed. See [File collection options]({{ baseurl }}pmd_userdocs_cli_reference.html#file-collection-options) +for a list of common, shared parameters that are valid for both commands. + ### ๐Ÿ› Fixed Issues * core * [#5700](https://github.com/pmd/pmd/pull/5700): \[core] Don't accidentally catch unexpected runtime exceptions in CpdAnalysis @@ -64,8 +70,14 @@ Releases of PMD are available on [Maven Central](https://central.sonatype.com/) * [#5702](https://github.com/pmd/pmd/issues/5702): \[java] InvalidLogMessageFormat: Lombok @Slf4j annotation is not interpreted by PMD ### ๐Ÿšจ API Changes +#### CLI +* CPD now supports `--report-file` (-r) and `--exclude-file-list`. +* PMD now supports `--exclude` and `--non-recursive`. +* The option `--ignore-list` in PMD is renamed to `--exclude-file-list`. #### Deprecations +* CLI + * The option `--ignore-list` has been deprecated. Use `--exclude-file-list` instead. * pmd-java * {% jdoc !!java::lang.java.ast.ASTCompactConstructorDeclaration#getDeclarationNode() %}: This method just returns `this` and isn't useful. * {% jdoc !!java::lang.java.metrics.JavaMetrics#NPATH %}: Use {% jdoc java::lang.java.metrics.JavaMetrics#NPATH_COMP %}, which is available on more nodes, @@ -81,6 +93,7 @@ Releases of PMD are available on [Maven Central](https://central.sonatype.com/) * [#5700](https://github.com/pmd/pmd/pull/5700): \[core] Don't accidentally catch unexpected runtime exceptions in CpdAnalysis - [Elliotte Rusty Harold](https://github.com/elharo) (@elharo) * [#5716](https://github.com/pmd/pmd/pull/5716): Fix #5634: \[java] CommentDefaultAccessModifier: Comment between annotation and constructor not recognized - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#5727](https://github.com/pmd/pmd/pull/5727): Fix #5621: \[java] Fix FPs with UnusedPrivateMethod - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5731](https://github.com/pmd/pmd/pull/5731): \[cli] Share more CLI options between CPD and PMD - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5736](https://github.com/pmd/pmd/pull/5736): Fix #5061: \[java] UnusedLocalVariable FP when using compound assignment - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) ### ๐Ÿ“ฆ Dependency updates diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java index 91122673ee0..7f22bb57174 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java @@ -74,7 +74,7 @@ public class CpdCommand extends AbstractAnalysisPmdSubcommand private boolean ignoreIdentifierAndLiteralSequences; /** - * @deprecated Use --[no-]fail-on-error instead. + * @deprecated Since 7.3.0. Use --[no-]fail-on-error instead. */ @Option(names = "--skip-lexical-errors", description = "Skip files which can't be tokenized due to invalid characters, instead of aborting with an error. Deprecated - use --[no-]fail-on-error instead.") diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/AbstractConfiguration.java b/pmd-core/src/main/java/net/sourceforge/pmd/AbstractConfiguration.java index e52b68a8c7b..848203ca3b6 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/AbstractConfiguration.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/AbstractConfiguration.java @@ -390,6 +390,7 @@ public void collectFilesRecursively(boolean collectRecursive) { * report is rendered on stdout. * * @return The file to which to render. + * @since 7.14.0 (was previously only available on {@link PMDConfiguration}) */ public @Nullable Path getReportFilePath() { return reportFile; @@ -399,6 +400,7 @@ public void collectFilesRecursively(boolean collectRecursive) { * Set the file to which the report should render. * * @param reportFile the file to set + * @since 7.14.0 (was previously only available on {@link PMDConfiguration}) */ public void setReportFile(@Nullable Path reportFile) { this.reportFile = reportFile; From c64e8105a8792de3a5e989e4e09568b8ee008ff7 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 29 May 2025 20:03:05 +0200 Subject: [PATCH 0956/1962] [doc] Update release notes (#5764, #2462) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 852a10b98a0..973358cd98a 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -55,6 +55,7 @@ Releases of PMD are available on [Maven Central](https://central.sonatype.com/) * [#5061](https://github.com/pmd/pmd/issues/5061): \[java] UnusedLocalVariable false positive when variable is read as side effect of an assignment * [#5724](https://github.com/pmd/pmd/issues/5724): \[java] ImplicitFunctionalInterface should not be reported on sealed interfaces * java-codestyle + * [#2462](https://github.com/pmd/pmd/issues/2462): \[java] LinguisticNaming must ignore setters that returns current type (Builder pattern) * [#5634](https://github.com/pmd/pmd/issues/5634): \[java] CommentDefaultAccessModifier doesn't recognize /* package */ comment at expected location for constructors * java-errorprone * [#5702](https://github.com/pmd/pmd/issues/5702): \[java] InvalidLogMessageFormat: Lombok @Slf4j annotation is not interpreted by PMD @@ -66,6 +67,7 @@ Releases of PMD are available on [Maven Central](https://central.sonatype.com/) * [#5700](https://github.com/pmd/pmd/pull/5700): \[core] Don't accidentally catch unexpected runtime exceptions in CpdAnalysis - [Elliotte Rusty Harold](https://github.com/elharo) (@elharo) * [#5716](https://github.com/pmd/pmd/pull/5716): Fix #5634: \[java] CommentDefaultAccessModifier: Comment between annotation and constructor not recognized - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#5736](https://github.com/pmd/pmd/pull/5736): Fix #5061: \[java] UnusedLocalVariable FP when using compound assignment - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#5764](https://github.com/pmd/pmd/pull/5764): Fix #2462: \[java] LinguisticNaming should ignore setters for Builders - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) ### ๐Ÿ“ฆ Dependency updates From 952207131b9895a8ef5cd131a606f67b3fa9c48c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 29 May 2025 20:05:16 +0200 Subject: [PATCH 0957/1962] [doc] Update release notes (#5763) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 852a10b98a0..1ca1a8a4a53 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -66,6 +66,7 @@ Releases of PMD are available on [Maven Central](https://central.sonatype.com/) * [#5700](https://github.com/pmd/pmd/pull/5700): \[core] Don't accidentally catch unexpected runtime exceptions in CpdAnalysis - [Elliotte Rusty Harold](https://github.com/elharo) (@elharo) * [#5716](https://github.com/pmd/pmd/pull/5716): Fix #5634: \[java] CommentDefaultAccessModifier: Comment between annotation and constructor not recognized - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#5736](https://github.com/pmd/pmd/pull/5736): Fix #5061: \[java] UnusedLocalVariable FP when using compound assignment - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#5763](https://github.com/pmd/pmd/pull/5763): \[java] Support annotated constructor return type in symbol API - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) ### ๐Ÿ“ฆ Dependency updates From 043370cf38e1826af2092aa0c43d10637ec03e76 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 29 May 2025 20:10:11 +0200 Subject: [PATCH 0958/1962] [java] Remove redundant impl for JConstructorSymbol#getReturnType --- .../sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java index 6b5d7341e31..a277d8a16cf 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java @@ -36,12 +36,9 @@ public interface JExecutableSymbol extends JTypeParameterOwnerSymbol { * Return the return type under the given substitution. * For a constructor, return the type of the owner. This type * may be annotated. + * @see JConstructorSymbol */ default JTypeMirror getReturnType(Substitution subst) { - if (this instanceof JConstructorSymbol) { - TypeSystem ts = getTypeSystem(); - return ts.declaration(getEnclosingClass()).subst(subst); - } // JMethodSymbol has always had this method abstract so this branch // should never be taken. throw new UnsupportedOperationException("Default method was added for compatibility, will be removed"); From d3311c0b04167312f958e1a16f8c0eeeb5a0811b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 29 May 2025 20:28:15 +0200 Subject: [PATCH 0959/1962] Fix checkstyle --- .../net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java | 1 - 1 file changed, 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java index a277d8a16cf..e38c18ee5c4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JExecutableSymbol.java @@ -15,7 +15,6 @@ import net.sourceforge.pmd.lang.java.types.JMethodSig; import net.sourceforge.pmd.lang.java.types.JTypeMirror; import net.sourceforge.pmd.lang.java.types.Substitution; -import net.sourceforge.pmd.lang.java.types.TypeSystem; /** * Common supertype for {@linkplain JMethodSymbol method} From cb0b42fbd20478ecc771c7654d86d49da24428e5 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 May 2025 10:17:06 +0200 Subject: [PATCH 0960/1962] Add/update javadoc tags (since, experimental, deprecated) --- .../pmd/lang/apex/ApexAnnotationSuppressor.java | 3 +++ .../main/java/net/sourceforge/pmd/lang/ast/AstInfo.java | 7 +++++-- .../pmd/lang/ast/impl/SuppressionCommentImpl.java | 2 +- .../pmd/lang/ast/impl/javacc/AbstractTokenManager.java | 9 +++++++++ .../lang/rule/impl/UnnecessaryPmdSuppressionRule.java | 2 ++ .../java/net/sourceforge/pmd/reporting/RuleContext.java | 3 +++ .../sourceforge/pmd/reporting/ViolationSuppressor.java | 3 +++ .../pmd/lang/java/internal/JavaAnnotationSuppressor.java | 1 + 8 files changed, 27 insertions(+), 3 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexAnnotationSuppressor.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexAnnotationSuppressor.java index 91e3fd508b9..ec727c48b10 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexAnnotationSuppressor.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexAnnotationSuppressor.java @@ -16,6 +16,9 @@ import net.sourceforge.pmd.reporting.AbstractAnnotationSuppressor; import net.sourceforge.pmd.reporting.ViolationSuppressor; +/** + * @since 7.14.0 + */ final class ApexAnnotationSuppressor extends AbstractAnnotationSuppressor { static final List ALL_APEX_SUPPRESSORS = listOf(new ApexAnnotationSuppressor()); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AstInfo.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AstInfo.java index ff75ce6a06b..718aa16b3b7 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AstInfo.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AstInfo.java @@ -85,8 +85,8 @@ public LanguageProcessor getLanguageProcessor() { *

    This map is later used to determine, if a violation is being suppressed. * It is suppressed, if the line of the violation is contained in this suppress map. * - * @return map of the suppress lines with the corresponding review comments. - * @deprecated Since 7.13.0. Use {@link #getAllSuppressionComments()} or {@link #getSuppressionComment(int)} + * @return map of the suppressed lines with the corresponding review comments. + * @deprecated Since 7.14.0. Use {@link #getAllSuppressionComments()} or {@link #getSuppressionComment(int)} */ @Deprecated public Map getSuppressionComments() { @@ -152,6 +152,9 @@ public Reportable getLocation() { } + /** + * @since 7.14.0 + */ public AstInfo withSuppressionComments(Collection suppressionComments) { Map suppressMap = new HashMap<>(suppressionComments.size()); for (SuppressionCommentWrapper comment : suppressionComments) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/SuppressionCommentImpl.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/SuppressionCommentImpl.java index c82c50ad32f..b38d06597c4 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/SuppressionCommentImpl.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/SuppressionCommentImpl.java @@ -15,7 +15,7 @@ * * @param Type of Reportable (node, token, lambda) * - * @since 7.14.0 + * @experimental Since 7.14.0. See [core] Add rule to report unnecessary suppression comments/annotations #5609 */ @Experimental public class SuppressionCommentImpl implements SuppressionCommentWrapper { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/AbstractTokenManager.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/AbstractTokenManager.java index c487e432c67..7d22db054c3 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/AbstractTokenManager.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/AbstractTokenManager.java @@ -21,6 +21,9 @@ public abstract class AbstractTokenManager implements TokenManager { private final List suppressionComments = new ArrayList<>(); + /** + * @deprecated Since 7.14.0. Don't use this map directly anymore. Instead, use {@link #getSuppressionComments()}. + */ @Deprecated protected Map suppressMap = new HashMap<>(); protected String suppressMarker = PMDConfiguration.DEFAULT_SUPPRESS_MARKER; @@ -37,6 +40,9 @@ public Map getSuppressMap() { return suppressMap; } + /** + * @since 7.14.0 + */ protected void processCommentForSuppression(JavaccToken token) { String suppressMarker = this.suppressMarker; int startOfNOPMD = token.getImageCs().indexOf(suppressMarker, 0); @@ -47,6 +53,9 @@ protected void processCommentForSuppression(JavaccToken token) { } } + /** + * @since 7.14.0 + */ public Collection getSuppressionComments() { return suppressionComments; } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/impl/UnnecessaryPmdSuppressionRule.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/impl/UnnecessaryPmdSuppressionRule.java index a4e07119ebe..0ef159e7072 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/impl/UnnecessaryPmdSuppressionRule.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/impl/UnnecessaryPmdSuppressionRule.java @@ -26,6 +26,8 @@ * Violations of this rule cannot be suppressed. It is special cased * by {@link RuleSets} to execute after all other rules, so that whether * those produce warnings or not is known to this rule. + * + * @experimental Since 7.14.0. See [core] Add rule to report unnecessary suppression comments/annotations #5609 */ @Experimental public class UnnecessaryPmdSuppressionRule extends AbstractRule { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java index 73580a0c528..3840d0835fc 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java @@ -185,6 +185,9 @@ public void addViolationWithPosition(Reportable reportable, AstInfo astInfo, } } + /** + * @experimental Since 7.14.0. See [core] Add rule to report unnecessary suppression comments/annotations #5609 + */ @Experimental public void addViolationNoSuppress(Reportable reportable, AstInfo astInfo, String message, Object... formatArgs) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ViolationSuppressor.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ViolationSuppressor.java index 5ecb450840a..6f7f0a926f6 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ViolationSuppressor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ViolationSuppressor.java @@ -208,6 +208,7 @@ default Set getUnusedSuppressors(RootNode tree) { * Represents an instance of a "suppressor" that didn't suppress anything. * This could be a suppression annotation, or part of an annotation, a * comment, etc. + * * @since 7.14.0 */ interface UnusedSuppressorNode { @@ -219,6 +220,8 @@ interface UnusedSuppressorNode { /** * Wrapper around a suppression comment. + * + * @experimental Since 7.14.0. See [core] Add rule to report unnecessary suppression comments/annotations #5609 */ @Experimental interface SuppressionCommentWrapper { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java index 4244a2d9e50..7655696607a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java @@ -56,6 +56,7 @@ * * * @see JLS 9.6.4.5. @SuppressWarnings + * @since 7.14.0 */ final class JavaAnnotationSuppressor extends AbstractAnnotationSuppressor { From cbdf76ad009aeefe1995894d450bffdf57458c06 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 May 2025 12:20:48 +0200 Subject: [PATCH 0961/1962] [java] UnneccesaryWarningsSuppressions: Don't report used methods This is not ready yet - we need to figure out whether the private methods are used or not. --- .../internal/JavaAnnotationSuppressor.java | 80 ++++++++++++++----- .../xml/UnnecessaryWarningSuppression.xml | 70 ++++++++++++---- 2 files changed, 117 insertions(+), 33 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java index 7655696607a..a0ae703dc6a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java @@ -9,13 +9,16 @@ import java.util.Arrays; import java.util.HashSet; import java.util.List; +import java.util.Objects; import java.util.Set; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.ast.NodeStream; import net.sourceforge.pmd.lang.java.ast.ASTAnnotation; +import net.sourceforge.pmd.lang.java.ast.ASTClassDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTClassType; import net.sourceforge.pmd.lang.java.ast.ASTExecutableDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTMemberValue; import net.sourceforge.pmd.lang.java.ast.ASTMemberValuePair; import net.sourceforge.pmd.lang.java.ast.ASTModifierList; @@ -109,21 +112,61 @@ JavaNode getAnnotationScope(ASTAnnotation a) { return null; } + @SuppressWarnings("unused") + public static void foo1(int i) { + i = 2; + foo2(i); + } + + @SuppressWarnings("unused") + private static void foo2(int i) { + System.out.println("i = " + i); + } + private static OptionalBool hasUnusedWarning(JavaNode node) { if (node == null) { return OptionalBool.UNKNOWN; } - if (node.descendants(ASTVariableId.class) - .crossFindBoundaries() - .any(it -> it.getLocalUsages().isEmpty())) { + if (hasUnusedVariables(node)) { return OptionalBool.YES; - } else if (hasUnusedTypeParam(node)) { return OptionalBool.YES; + } else if (hasUnusedMethod(node)) { + return OptionalBool.YES; } - return hasUnusedMethod(node); + if (node instanceof ASTFieldDeclaration) { + // for annotated fields, "unused" annotation is unambiguous - it only is used for this field. + return OptionalBool.NO; + } + + if (node instanceof ASTClassDeclaration) { + ASTClassDeclaration classDecl = (ASTClassDeclaration) node; + if (classDecl.getEffectiveVisibility() == Visibility.V_PRIVATE) { + // is this private class is used in this compilation unit? + boolean used = node.getRoot().descendants(ASTClassType.class) + .toStream() + .map(ASTClassType::getTypeMirror) + .map(JTypeMirror::getSymbol) + .filter(Objects::nonNull) + .anyMatch(s -> s.equals(classDecl.getSymbol())); + if (used) { + return OptionalBool.NO; + } + } + } + + return OptionalBool.UNKNOWN; + } + + /** + * Searches for local variables, fields, formal parameters. + */ + private static boolean hasUnusedVariables(JavaNode node) { + return node.descendants(ASTVariableId.class) + .crossFindBoundaries() + .any(it -> it.getLocalUsages().isEmpty()); } private static boolean hasUnusedTypeParam(JavaNode node) { @@ -159,28 +202,29 @@ public Void visit(ASTModifierList node, Void data) { return !unusedTypeParams.isEmpty(); } - private static OptionalBool hasUnusedMethod(JavaNode node) { - Set declarations = new HashSet<>(); + private static boolean hasUnusedMethod(JavaNode node) { + Set privateMethods = new HashSet<>(); for (ASTExecutableDeclaration decl : node.descendantsOrSelf() .crossFindBoundaries() .filterIs(ASTExecutableDeclaration.class)) { Visibility visibility = decl.getEffectiveVisibility(); - if (visibility == Visibility.V_PACKAGE) { - // We cannot know if a package-private method is effectively used - return OptionalBool.UNKNOWN; - } else if (visibility.isAtMost(Visibility.V_PRIVATE)) { - declarations.add(decl.getSymbol()); + if (visibility.isAtMost(Visibility.V_PRIVATE)) { + privateMethods.add(decl.getSymbol()); + } else { + // We cannot know if non-private (package-private, protected, public) method is effectively used + return false; } } - if (declarations.isEmpty()) { - return OptionalBool.NO; + if (!privateMethods.isEmpty()) { + // node is a private method/ctor or is a class decl that contains only private methods + // TODO we need to somehow sync this with UnusedPrivateMethod and check, if these private + // methods are indeed unused or not. See also #5727. + // for now, we give up and assume, all private methods are used + return false; } - // TODO for now we give up unless the node doesn't contain any method. - // -> we need to somehow sync this with UnusedPrivateMethod - // -> This is pushed back until #5727 is merged - return OptionalBool.UNKNOWN; + return false; } @Override diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnnecessaryWarningSuppression.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnnecessaryWarningSuppression.xml index 2bdeba1f049..ef247160d95 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnnecessaryWarningSuppression.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnnecessaryWarningSuppression.xml @@ -264,18 +264,33 @@ } ]]> - - Suppresswarnings unused + + Suppresswarnings unused on methods 1 - 6 + 12 violation: parameter i is used and method is used as well (in #foo2) + private static void foo3(int i) { + i = 2; + } + + @SuppressWarnings("unused") // no violation: both parameter and method are unused - suppression is necessary + private static void foo4(int i) { + } + + @SuppressWarnings("unused") // no violation: parameter is used but method is unused - suppression is necessary + private static void foo5(int i) { i = 2; } } @@ -293,7 +308,7 @@ private String sessionId; - @SuppressWarnings("unused") + @SuppressWarnings("unused") // --> violation - this field is actually used in #handleTransportRequest private String transport; private WebSocketHandler handler; @@ -324,16 +339,27 @@ Suppresswarnings unused on type param 1 - 5 + 12 { - } + public class OuterClass { + @SuppressWarnings("unused") // no violation: type parameter "T" is not used - necessary suppression + public static class Foo1 { + } - @SuppressWarnings("unused") // type parm is used - public class Foo { + @SuppressWarnings("unused") // no violation: type parameter "T" is used, class Foo2 is public and might or might not be used + public static class Foo2 { + class Bar extends Foo2 { + } + } - class Bar extends Foo { + @SuppressWarnings("unused") // -> violation: type parameter "T" is used, class Foo3 is used - nothing is unused -> suppression is unnecessary + private static class Foo3 { + class Bar extends Foo3 { + } + } + + public static void main(String[] args) { + Foo3 f = new Foo3<>(); } } ]]> @@ -369,4 +395,18 @@ } ]]> + + + Do not report on entire inner class as unused + 0 + + From ddb826a282349fc0cfc2a3b36dc34d3252f80fb0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 May 2025 12:31:04 +0200 Subject: [PATCH 0962/1962] [core] Refactor RuleContext --- .../pmd/reporting/RuleContext.java | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java index 3840d0835fc..19800b125a0 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java @@ -168,15 +168,9 @@ public void addViolationWithPosition(Reportable reportable, AstInfo astInfo, Objects.requireNonNull(message, "Message was null"); Objects.requireNonNull(formatArgs, "Format arguments were null, use an empty array"); - LanguageVersionHandler handler = astInfo.getLanguageProcessor().services(); - Node suppressionNode = getNearestNode(reportable, astInfo); - - Map extraVariables = ViolationDecorator.apply(handler.getViolationDecorator(), suppressionNode); - String description = makeMessage(message, formatArgs, extraVariables); - RuleViolation violation = new ParametricRuleViolation(rule, location, description, extraVariables); - - SuppressedViolation suppressed = suppressOrNull(suppressionNode, violation, handler); + RuleViolation violation = createViolation(reportable, astInfo, suppressionNode, message, formatArgs); + SuppressedViolation suppressed = suppressOrNull(suppressionNode, violation, astInfo); if (suppressed != null) { listener.onSuppressedRuleViolation(suppressed); @@ -195,16 +189,17 @@ public void addViolationNoSuppress(Reportable reportable, AstInfo astInfo, Objects.requireNonNull(message, "Message was null"); Objects.requireNonNull(formatArgs, "Format arguments were null, use an empty array"); - LanguageVersionHandler handler = astInfo.getLanguageProcessor().services(); - - Node nearestNode = getNearestNode(reportable, astInfo); + RuleViolation violation = createViolation(reportable, astInfo, nearestNode, message, formatArgs); + listener.onRuleViolation(violation); + } + + private RuleViolation createViolation(Reportable reportable, AstInfo astInfo, Node nearestNode, String message, Object... formatArgs) { + LanguageVersionHandler handler = astInfo.getLanguageProcessor().services(); Map extraVariables = ViolationDecorator.apply(handler.getViolationDecorator(), nearestNode); String description = makeMessage(message, formatArgs, extraVariables); FileLocation location = reportable.getReportLocation(); - RuleViolation violation = new ParametricRuleViolation(rule, location, description, extraVariables); - - listener.onRuleViolation(violation); + return new ParametricRuleViolation(rule, location, description, extraVariables); } private Node getNearestNode(Reportable reportable, AstInfo astInfo) { @@ -225,7 +220,8 @@ private static int getStartOffset(Reportable reportable, AstInfo astInfo) { return astInfo.getTextDocument().offsetAtLineColumn(loc.getStartPos()); } - private static @Nullable SuppressedViolation suppressOrNull(Node location, RuleViolation rv, LanguageVersionHandler handler) { + private static @Nullable SuppressedViolation suppressOrNull(Node location, RuleViolation rv, AstInfo astInfo) { + LanguageVersionHandler handler = astInfo.getLanguageProcessor().services(); SuppressedViolation suppressed = ViolationSuppressor.suppressOrNull(handler.getExtraViolationSuppressors(), rv, location); if (suppressed == null) { suppressed = ViolationSuppressor.suppressOrNull(DEFAULT_SUPPRESSORS, rv, location); From db2daee4e360ff95c058fc97efbb05637701fc75 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 May 2025 12:45:28 +0200 Subject: [PATCH 0963/1962] [core] Add test for BaseMappedDocument#offsetAtLine --- .../document/FragmentedTextDocumentTest.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/FragmentedTextDocumentTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/FragmentedTextDocumentTest.java index 8e97eaa6479..bb123982c88 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/FragmentedTextDocumentTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/FragmentedTextDocumentTest.java @@ -74,4 +74,22 @@ void testToLocationWithCaretBetweenEscapes() throws IOException { } } + @Test + void offsetAtLineColumn() throws IOException { + try (TextDocument base = TextDocument.readOnlyString("ABC\n123\n", dummyVersion)) { + FragmentedDocBuilder builder = new FragmentedDocBuilder(base); + builder.recordDelta(3, 3, Chars.wrap("X")); + builder.recordDelta(7, 7, Chars.wrap("Y")); + try (TextDocument doc = builder.build()) { + assertEquals("ABCX\n123Y\n", doc.getText().toString()); + + assertEquals(0, doc.offsetAtLineColumn(pos2d(1, 1))); + assertEquals(0, base.offsetAtLineColumn(pos2d(1, 1))); + // pos2d is always in the coordinate system of the base document + assertEquals(4, doc.offsetAtLineColumn(pos2d(2, 1))); + assertEquals(4, base.offsetAtLineColumn(pos2d(2, 1))); + } + + } + } } From 86ed0d4304ac6cc63033069fa8376d55fd000850 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 May 2025 13:10:33 +0200 Subject: [PATCH 0964/1962] [doc] Update release notes (#5609, #648) --- .../pmd/userdocs/suppressing_warnings.md | 12 +++++++ docs/pages/release_notes.md | 36 +++++++++++++++++++ .../resources/rulesets/java/quickstart.xml | 1 + 3 files changed, 49 insertions(+) diff --git a/docs/pages/pmd/userdocs/suppressing_warnings.md b/docs/pages/pmd/userdocs/suppressing_warnings.md index 18b5f35888e..d281e7d864b 100644 --- a/docs/pages/pmd/userdocs/suppressing_warnings.md +++ b/docs/pages/pmd/userdocs/suppressing_warnings.md @@ -5,6 +5,7 @@ tags: [userdocs] summary: "Learn how to suppress some rule violations, from the source code using annotations or comments, or globally from the ruleset" permalink: pmd_userdocs_suppressing_warnings.html author: Tom Copeland +last_updated: May 2025 (7.14.0) --- PMD provides several methods by which Rule violations can be suppressed. @@ -242,3 +243,14 @@ Note for XPath based suppression to work, you must know how to write an XPath query that matches the AST structure of the nodes of the violations you wish to suppress. XPath queries are explained in [XPath Rule tutorial](pmd_userdocs_extending_writing_xpath_rules.html). + + +## Finding unused suppressions + +After one has added a suppression annotation or comment, the code or the suppressed rule might change. +Often this goes unnoticed and the suppression is still in the code, but it is not necessary anymore. + +With PMD 7.14.0, there is an experimental rule for Java, that finds such unnecessary suppressions: +{% rule java/bestpractices/UnnecessaryWarningSuppression %}. + +It will report a violation for unnecessary suppressions. diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index c7f936ca051..6602a34df01 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -24,6 +24,27 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy +#### New Rule UnnecessaryWarningSuppression (experimental) + +This new Java rule {% rule java/bestpractices/UnnecessaryWarningSuppression %} reports unused suppression +annotations and comments. The rule class supports any PMD language, +but language-specific behavior needs to be implemented to avoid false positives for some languages. +Violations of this rule cannot be suppressed. It is special cased rule that is executed after all +other rules, so that whether those produce warnings or not is known to this rule. + +How to use it? Just include it in your ruleset: + +```xml + +``` + +Note: This rule is currently experimental. It is available for now only for Java. +The rule for now only reports annotations specific to PMD, like `@SuppressWarnings("PMD")`. +In the future we might be able to check for other common ones like `@SuppressWarnings("unchecked")` or `"fallthrough"`. +Since violations of this rule cannot be suppressed, we opted here on the side of false-negatives and +don't report such unused cases yet. +However, suppressing specific PMD rules is working as expected. + #### Migrating to Central Publisher Portal We've now migrated to [Central Publisher Portal](https://central.sonatype.org/publish/publish-portal-guide/). @@ -56,6 +77,7 @@ for a list of common, shared parameters that are valid for both commands. ### ๐Ÿ› Fixed Issues * core + * [#648](https://github.com/pmd/pmd/issues/648): \[core] Warn on unneeded suppression * [#5700](https://github.com/pmd/pmd/pull/5700): \[core] Don't accidentally catch unexpected runtime exceptions in CpdAnalysis * java-bestpractices * [#5061](https://github.com/pmd/pmd/issues/5061): \[java] UnusedLocalVariable false positive when variable is read as side effect of an assignment @@ -79,18 +101,32 @@ for a list of common, shared parameters that are valid for both commands. #### Deprecations * CLI * The option `--ignore-list` has been deprecated. Use `--exclude-file-list` instead. +* core + * {% jdoc !!core::lang.ast.AstInfo#getSuppressionComments() %}: Use {% jdoc core::lang.ast.AstInfo#getAllSuppressionComments() %} + or {% jdoc core::lang.ast.AstInfo#getSuppressionComment(int) %}. + * {% jdoc !!core::lang.ast.AstInfo#withSuppressMap() %}: Use {%jdoc core::lang.ast.AstInfo#withSuppressionComments(java.util.Collection) %} + * {% jdoc !!core::lang.ast.impl.javacc.AbstractTokenManager#suppressMap %}: Don't use this map directly anymore. Instead, + use {%jdoc core::lang.ast.impl.javacc.AbstractTokenManager#getSuppressionComments() %}. + * {% jdoc !!core::lang.ast.impl.javacc.AbstractTokenManager#getSuppressMap() %}: Use + {% jdoc core::lang.ast.impl.javacc.AbstractTokenManager#getSuppressionComments() %} instead. * pmd-java * {% jdoc !!java::lang.java.ast.ASTCompactConstructorDeclaration#getDeclarationNode() %}: This method just returns `this` and isn't useful. * {% jdoc !!java::lang.java.metrics.JavaMetrics#NPATH %}: Use {% jdoc java::lang.java.metrics.JavaMetrics#NPATH_COMP %}, which is available on more nodes, and uses Long instead of BigInteger. #### Experimental +* core + * {%jdoc core::lang.ast.impl.SuppressionCommentImpl %} + * {%jdoc core::lang.rule.impl.UnnecessaryPmdSuppressionRule %} + * {%jdoc !!core::reporting.RuleContext#addViolationNoSuppress(core::reporting.Reportable,core::lang.ast.AstInfo,java.lang.String,java.lang.Object...) %} + * {%jdoc core::reporting.ViolationSuppressor.SuppressionCommentWrapper %} * pmd-java * {%jdoc !!java::lang.java.types.OverloadSelectionResult#getTypeToSearch() %} ### โœจ Merged pull requests * [#5599](https://github.com/pmd/pmd/pull/5599): \[java] Rewrite NPath complexity metric - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5609](https://github.com/pmd/pmd/pull/5609): \[core] Add rule to report unnecessary suppression comments/annotations - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5700](https://github.com/pmd/pmd/pull/5700): \[core] Don't accidentally catch unexpected runtime exceptions in CpdAnalysis - [Elliotte Rusty Harold](https://github.com/elharo) (@elharo) * [#5716](https://github.com/pmd/pmd/pull/5716): Fix #5634: \[java] CommentDefaultAccessModifier: Comment between annotation and constructor not recognized - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#5727](https://github.com/pmd/pmd/pull/5727): Fix #5621: \[java] Fix FPs with UnusedPrivateMethod - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) diff --git a/pmd-java/src/main/resources/rulesets/java/quickstart.xml b/pmd-java/src/main/resources/rulesets/java/quickstart.xml index f110646ad82..5f32089a1d9 100644 --- a/pmd-java/src/main/resources/rulesets/java/quickstart.xml +++ b/pmd-java/src/main/resources/rulesets/java/quickstart.xml @@ -48,6 +48,7 @@ + From 40c539efc615a826989e8b09f5f7acfdf3081fc3 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 May 2025 14:07:56 +0200 Subject: [PATCH 0965/1962] Fix RuleContext location --- .../main/java/net/sourceforge/pmd/reporting/RuleContext.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java index 19800b125a0..a86feb993e1 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java @@ -169,7 +169,7 @@ public void addViolationWithPosition(Reportable reportable, AstInfo astInfo, Objects.requireNonNull(formatArgs, "Format arguments were null, use an empty array"); Node suppressionNode = getNearestNode(reportable, astInfo); - RuleViolation violation = createViolation(reportable, astInfo, suppressionNode, message, formatArgs); + RuleViolation violation = createViolation(() -> location, astInfo, suppressionNode, message, formatArgs); SuppressedViolation suppressed = suppressOrNull(suppressionNode, violation, astInfo); if (suppressed != null) { From 7f363d054bd9aeb10ed7962e370d094925ea8888 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 May 2025 14:24:49 +0200 Subject: [PATCH 0966/1962] Fix PMD SimplifyBooleanReturns --- .../java/internal/JavaAnnotationSuppressor.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java index a0ae703dc6a..9bb6b18e694 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java @@ -216,15 +216,15 @@ private static boolean hasUnusedMethod(JavaNode node) { } } - if (!privateMethods.isEmpty()) { - // node is a private method/ctor or is a class decl that contains only private methods - // TODO we need to somehow sync this with UnusedPrivateMethod and check, if these private - // methods are indeed unused or not. See also #5727. - // for now, we give up and assume, all private methods are used - return false; - } - return false; + + // if (!privateMethods.isEmpty()) { + // node is a private method/ctor or is a class decl that contains only private methods + // TODO we need to somehow sync this with UnusedPrivateMethod and check, if these private + // methods are indeed unused or not. See also #5727. + // for now, we give up and assume, all private methods are used + // and always return false... + // } } @Override From 6e6cecb6992505cf5f52be7f27c83063c2cb617e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 May 2025 15:10:53 +0200 Subject: [PATCH 0967/1962] [java] UnnecessaryWarningSuppression: write-only fields are unused --- .../internal/JavaAnnotationSuppressor.java | 11 +++++-- .../xml/UnnecessaryWarningSuppression.xml | 29 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java index 9bb6b18e694..abc10cf7966 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java @@ -11,10 +11,12 @@ import java.util.List; import java.util.Objects; import java.util.Set; +import java.util.stream.Collectors; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.ast.NodeStream; import net.sourceforge.pmd.lang.java.ast.ASTAnnotation; +import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr; import net.sourceforge.pmd.lang.java.ast.ASTClassDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTClassType; import net.sourceforge.pmd.lang.java.ast.ASTExecutableDeclaration; @@ -164,9 +166,14 @@ private static OptionalBool hasUnusedWarning(JavaNode node) { * Searches for local variables, fields, formal parameters. */ private static boolean hasUnusedVariables(JavaNode node) { - return node.descendants(ASTVariableId.class) + Set varAccesses = node.descendants(ASTVariableId.class) .crossFindBoundaries() - .any(it -> it.getLocalUsages().isEmpty()); + .toStream() + .flatMap(it -> it.getLocalUsages().stream()) + .map(ASTAssignableExpr::getAccessType) + .collect(Collectors.toSet()); + return !varAccesses.isEmpty() && varAccesses.stream() + .noneMatch(it -> it == ASTAssignableExpr.AccessType.READ); } private static boolean hasUnusedTypeParam(JavaNode node) { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnnecessaryWarningSuppression.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnnecessaryWarningSuppression.xml index ef247160d95..bd5140524d8 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnnecessaryWarningSuppression.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnnecessaryWarningSuppression.xml @@ -330,11 +330,40 @@ this.transport = transport; this.handler = handler; } + + public String getTransport() { + return transport; + } } } ]]> + + Suppresswarnings unused on field - 2 + 1 + 9 + violation: the field is used in the getter + private String field2; + + public void setField2(String field2) { + this.field2 = field2; + } + public String getField2() { + return field2; + } +} + ]]> + Suppresswarnings unused on type param From fb1e5b04dbf7fe435814a833160ae1c161e92044 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 May 2025 15:17:52 +0200 Subject: [PATCH 0968/1962] [doc] Update release notes (#5705) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index a5fbe3cd8b3..587d4cc1c9d 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -28,6 +28,7 @@ This is a {{ site.pmd.release_type }} release. * core * [#5700](https://github.com/pmd/pmd/pull/5700): \[core] Don't accidentally catch unexpected runtime exceptions in CpdAnalysis + * [#5705](https://github.com/pmd/pmd/issues/5705): \[cli] PMD's start script fails if PMD_HOME is set ### ๐Ÿšจ API Changes From c2619813dd79bc5cfe517ba88cbf7859e4bac0ed Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 May 2025 16:01:25 +0200 Subject: [PATCH 0969/1962] Fix unused field handling --- .../internal/JavaAnnotationSuppressor.java | 18 ++++++++++-------- .../xml/UnnecessaryWarningSuppression.xml | 13 +++++++++++++ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java index abc10cf7966..8b91bec8df5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java @@ -11,7 +11,6 @@ import java.util.List; import java.util.Objects; import java.util.Set; -import java.util.stream.Collectors; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.ast.NodeStream; @@ -166,14 +165,17 @@ private static OptionalBool hasUnusedWarning(JavaNode node) { * Searches for local variables, fields, formal parameters. */ private static boolean hasUnusedVariables(JavaNode node) { - Set varAccesses = node.descendants(ASTVariableId.class) + return node.descendants(ASTVariableId.class) .crossFindBoundaries() - .toStream() - .flatMap(it -> it.getLocalUsages().stream()) - .map(ASTAssignableExpr::getAccessType) - .collect(Collectors.toSet()); - return !varAccesses.isEmpty() && varAccesses.stream() - .noneMatch(it -> it == ASTAssignableExpr.AccessType.READ); + .any(it -> { + if (it.getLocalUsages().isEmpty()) { + return true; + } + return it.getLocalUsages().stream() + .map(ASTAssignableExpr::getAccessType) + .noneMatch(a -> a == ASTAssignableExpr.AccessType.READ); + }); + } private static boolean hasUnusedTypeParam(JavaNode node) { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnnecessaryWarningSuppression.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnnecessaryWarningSuppression.xml index bd5140524d8..f0fce0b88ff 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnnecessaryWarningSuppression.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnnecessaryWarningSuppression.xml @@ -364,6 +364,19 @@ public class Foo { } ]]> + + Suppresswarnings unused on fields - 3 + 0 + + Suppresswarnings unused on type param From 0f56e128311dd48f27cc4edfa35937545226b1a9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 May 2025 16:02:54 +0200 Subject: [PATCH 0970/1962] Update release notes --- docs/pages/release_notes.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 6602a34df01..361ff499deb 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -27,10 +27,7 @@ This is a {{ site.pmd.release_type }} release. #### New Rule UnnecessaryWarningSuppression (experimental) This new Java rule {% rule java/bestpractices/UnnecessaryWarningSuppression %} reports unused suppression -annotations and comments. The rule class supports any PMD language, -but language-specific behavior needs to be implemented to avoid false positives for some languages. -Violations of this rule cannot be suppressed. It is special cased rule that is executed after all -other rules, so that whether those produce warnings or not is known to this rule. +annotations and comments. Violations of this rule cannot be suppressed. How to use it? Just include it in your ruleset: @@ -42,7 +39,7 @@ Note: This rule is currently experimental. It is available for now only for Java The rule for now only reports annotations specific to PMD, like `@SuppressWarnings("PMD")`. In the future we might be able to check for other common ones like `@SuppressWarnings("unchecked")` or `"fallthrough"`. Since violations of this rule cannot be suppressed, we opted here on the side of false-negatives and -don't report such unused cases yet. +don't report every unused case yet. However, suppressing specific PMD rules is working as expected. #### Migrating to Central Publisher Portal From d24775bac7594f38253a4fc5996a4228c308c73b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 May 2025 16:16:30 +0200 Subject: [PATCH 0971/1962] Update pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java --- .../pmd/lang/java/internal/JavaAnnotationSuppressor.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java index 8b91bec8df5..84c66dcb6a1 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaAnnotationSuppressor.java @@ -168,10 +168,7 @@ private static boolean hasUnusedVariables(JavaNode node) { return node.descendants(ASTVariableId.class) .crossFindBoundaries() .any(it -> { - if (it.getLocalUsages().isEmpty()) { - return true; - } - return it.getLocalUsages().stream() + return it.getLocalUsages().isEmpty() || it.getLocalUsages().stream() .map(ASTAssignableExpr::getAccessType) .noneMatch(a -> a == ASTAssignableExpr.AccessType.READ); }); From e12041c6e26b6cab64bef92788413fd8b1e1837d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 May 2025 16:32:54 +0200 Subject: [PATCH 0972/1962] [cli] Add tests for --threads parameters --- .../net/sourceforge/pmd/cli/PmdCliTest.java | 19 ++++++++++ .../internal/NumThreadsConverterTest.java | 36 +++++++++++++++++++ .../pmd/lang/impl/MonoThreadProcessor.java | 3 ++ .../pmd/lang/impl/MultiThreadProcessor.java | 11 ++++-- 4 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 pmd-cli/src/test/java/net/sourceforge/pmd/cli/commands/typesupport/internal/NumThreadsConverterTest.java diff --git a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java index fd77c97b42f..da707cd60fb 100644 --- a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java +++ b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java @@ -525,6 +525,25 @@ void minimumPriorityOptionNumeric() throws Exception { runCliSuccessfully("-d", srcDir.toString(), "-f", "text", "-R", RULESET_WITH_VIOLATION, "--minimum-priority", "2"); } + @Test + void defaultThreadCount() throws Exception { + CliExecutionResult result = runCliSuccessfully("--debug", "--dir", srcDir.toString(), "--rulesets", RULESET_NO_VIOLATIONS); + result.checkStdErr(containsString("[DEBUG] Using " + Runtime.getRuntime().availableProcessors() + " threads for analysis")); + } + + @Test + void monoThreadCount() throws Exception { + CliExecutionResult result = runCliSuccessfully("--debug", "--threads", "0", "--dir", srcDir.toString(), "--rulesets", RULESET_NO_VIOLATIONS); + result.checkStdErr(containsString("[DEBUG] Using single thread for analysis")); + } + + @Test + void oneThreadCount() throws Exception { + CliExecutionResult result = runCliSuccessfully("--debug", "--threads", "1", "--dir", srcDir.toString(), "--rulesets", RULESET_NO_VIOLATIONS); + result.checkStdErr(containsString("[DEBUG] Using 1 thread for analysis")); + } + + // utilities private Path tempRoot() { return tempDir; diff --git a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/commands/typesupport/internal/NumThreadsConverterTest.java b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/commands/typesupport/internal/NumThreadsConverterTest.java new file mode 100644 index 00000000000..e187d19cfa0 --- /dev/null +++ b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/commands/typesupport/internal/NumThreadsConverterTest.java @@ -0,0 +1,36 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.cli.commands.typesupport.internal; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.params.provider.Arguments.of; + +import java.util.Arrays; +import java.util.Collection; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class NumThreadsConverterTest { + @ParameterizedTest + @MethodSource + void convertToThreadCount(String parameter, int expectedThreadCount) { + NumThreadsConverter converter = new NumThreadsConverter(); + int actualThreadCount = converter.convert(parameter); + assertEquals(expectedThreadCount, actualThreadCount); + } + + private static Collection convertToThreadCount() { + return Arrays.asList( + of("0", 0), + of("0C", 0), + of("1", 1), + of("1C", Runtime.getRuntime().availableProcessors()), + of("2C", 2 * Runtime.getRuntime().availableProcessors()), + of("0.5C", (int) (0.5 * Runtime.getRuntime().availableProcessors())) + ); + } +} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/MonoThreadProcessor.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/MonoThreadProcessor.java index 8e629fb06d9..c94c2da9856 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/MonoThreadProcessor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/MonoThreadProcessor.java @@ -4,6 +4,8 @@ package net.sourceforge.pmd.lang.impl; +import org.slf4j.event.Level; + import net.sourceforge.pmd.lang.LanguageProcessor.AnalysisTask; import net.sourceforge.pmd.lang.document.TextFile; import net.sourceforge.pmd.lang.rule.internal.RuleSets; @@ -15,6 +17,7 @@ final class MonoThreadProcessor extends AbstractPMDProcessor { MonoThreadProcessor(AnalysisTask task) { super(task); + task.getMessageReporter().log(Level.DEBUG, "Using single thread for analysis"); } @Override diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/MultiThreadProcessor.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/MultiThreadProcessor.java index 138c6c39810..9d279ec4c62 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/MultiThreadProcessor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/MultiThreadProcessor.java @@ -12,6 +12,8 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import org.slf4j.event.Level; + import net.sourceforge.pmd.lang.LanguageProcessor.AnalysisTask; import net.sourceforge.pmd.lang.document.TextFile; import net.sourceforge.pmd.lang.rule.internal.RuleSets; @@ -28,8 +30,13 @@ final class MultiThreadProcessor extends AbstractPMDProcessor { MultiThreadProcessor(final AnalysisTask task) { super(task); - - executor = Executors.newFixedThreadPool(task.getThreadCount(), new PmdThreadFactory()); + int threadCount = task.getThreadCount(); + if (threadCount == 1) { + task.getMessageReporter().log(Level.DEBUG, "Using 1 thread for analysis"); + } else { + task.getMessageReporter().log(Level.DEBUG, "Using {0} threads for analysis", threadCount); + } + executor = Executors.newFixedThreadPool(threadCount, new PmdThreadFactory()); futureList = new LinkedList<>(); } From c69c881bc5fb3be73c5ff331b3d804c348b191e1 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 May 2025 17:25:54 +0200 Subject: [PATCH 0973/1962] Fix unit tests --- .../pmd/lang/impl/AbstractPMDProcessorTest.java | 13 ++++++++++--- .../pmd/lang/impl/MonoThreadProcessorTest.java | 4 +++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/AbstractPMDProcessorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/AbstractPMDProcessorTest.java index 074e0cd4a91..f7ebf8030b0 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/AbstractPMDProcessorTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/AbstractPMDProcessorTest.java @@ -12,6 +12,7 @@ import org.junit.jupiter.api.Test; import org.mockito.Mockito; +import org.slf4j.event.Level; import net.sourceforge.pmd.PMDConfiguration; import net.sourceforge.pmd.PmdAnalysis; @@ -48,7 +49,7 @@ void shouldUseCorrectProcessorImpl() { } private LanguageProcessor.AnalysisTask createTask(int threads) { - return InternalApiBridge.createAnalysisTask(null, null, null, threads, null, null, null); + return InternalApiBridge.createAnalysisTask(null, null, null, threads, null, Mockito.mock(PmdReporter.class), null); } @Test @@ -58,17 +59,23 @@ void exceptionsShouldBeLogged() { pmd.performAnalysis(); } + // note: two executions for dummy and dummydialect assertEquals(2, reportListener.files.get()); assertEquals(2, reportListener.errors.get()); + if (getThreads() == 0) { + Mockito.verify(reporter, Mockito.times(2)).log(Level.DEBUG, "Using single thread for analysis"); + } else { + Mockito.verify(reporter, Mockito.times(2)).log(Level.DEBUG, "Using {0} threads for analysis", getThreads()); + } // exceptions are reported as processing errors - Mockito.verifyNoInteractions(reporter); + Mockito.verifyNoMoreInteractions(reporter); } protected PmdAnalysis createPmdAnalysis() { PMDConfiguration configuration = new PMDConfiguration(); configuration.setThreads(getThreads()); configuration.setIgnoreIncrementalAnalysis(true); - reporter = Mockito.spy(configuration.getReporter()); + reporter = Mockito.mock(PmdReporter.class); configuration.setReporter(reporter); PmdAnalysis pmd = PmdAnalysis.create(configuration); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/MonoThreadProcessorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/MonoThreadProcessorTest.java index 0a3f628f349..d3a2b92eca9 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/MonoThreadProcessorTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/MonoThreadProcessorTest.java @@ -9,6 +9,7 @@ import org.junit.jupiter.api.Test; import org.mockito.Mockito; +import org.slf4j.event.Level; import net.sourceforge.pmd.PmdAnalysis; import net.sourceforge.pmd.lang.rule.RuleSet; @@ -37,7 +38,8 @@ void errorsShouldBeThrown() { // in case of error, we abort at the first error, so in this test case // we abort at the first file, so only 1 file is processed. assertEquals(1, reportListener.files.get()); + Mockito.verify(reporter, Mockito.times(1)).log(Level.DEBUG, "Using single thread for analysis"); // in mono thread, the error just falls through, we don't additionally catch and log it. - Mockito.verifyNoInteractions(reporter); + Mockito.verifyNoMoreInteractions(reporter); } } From f479b7de272453108e7b7adef045605619767bcc Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 May 2025 17:33:10 +0200 Subject: [PATCH 0974/1962] Apply suggestions from review --- .../commands/typesupport/internal/NumThreadsConverter.java | 5 +++-- .../src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java | 2 +- .../net/sourceforge/pmd/lang/impl/MonoThreadProcessor.java | 2 +- .../sourceforge/pmd/lang/impl/AbstractPMDProcessorTest.java | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/NumThreadsConverter.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/NumThreadsConverter.java index 1085922f71d..e0f4e90a46d 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/NumThreadsConverter.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/NumThreadsConverter.java @@ -5,6 +5,7 @@ package net.sourceforge.pmd.cli.commands.typesupport.internal; import picocli.CommandLine.ITypeConverter; +import picocli.CommandLine.TypeConversionException; /** * Parses a number of threads, either an integer or a float followed by the letter C. @@ -19,13 +20,13 @@ public Integer convert(String s) { float f = Float.parseFloat(s); return (int) (f * Runtime.getRuntime().availableProcessors()); } catch (NumberFormatException e) { - throw new IllegalArgumentException("'" + s + "' is not a float or integer"); + throw new TypeConversionException("'" + s + "' is not a float or integer"); } } try { return Integer.parseInt(s); } catch (NumberFormatException e) { - throw new IllegalArgumentException("'" + s + "' is not an integer"); + throw new TypeConversionException("'" + s + "' is not an integer"); } } } diff --git a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java index da707cd60fb..6cce04760d9 100644 --- a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java +++ b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java @@ -534,7 +534,7 @@ void defaultThreadCount() throws Exception { @Test void monoThreadCount() throws Exception { CliExecutionResult result = runCliSuccessfully("--debug", "--threads", "0", "--dir", srcDir.toString(), "--rulesets", RULESET_NO_VIOLATIONS); - result.checkStdErr(containsString("[DEBUG] Using single thread for analysis")); + result.checkStdErr(containsString("[DEBUG] Using main thread for analysis")); } @Test diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/MonoThreadProcessor.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/MonoThreadProcessor.java index c94c2da9856..001dee94592 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/MonoThreadProcessor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/MonoThreadProcessor.java @@ -17,7 +17,7 @@ final class MonoThreadProcessor extends AbstractPMDProcessor { MonoThreadProcessor(AnalysisTask task) { super(task); - task.getMessageReporter().log(Level.DEBUG, "Using single thread for analysis"); + task.getMessageReporter().log(Level.DEBUG, "Using main thread for analysis"); } @Override diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/AbstractPMDProcessorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/AbstractPMDProcessorTest.java index f7ebf8030b0..d1bd1c09ca0 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/AbstractPMDProcessorTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/AbstractPMDProcessorTest.java @@ -63,7 +63,7 @@ void exceptionsShouldBeLogged() { assertEquals(2, reportListener.files.get()); assertEquals(2, reportListener.errors.get()); if (getThreads() == 0) { - Mockito.verify(reporter, Mockito.times(2)).log(Level.DEBUG, "Using single thread for analysis"); + Mockito.verify(reporter, Mockito.times(2)).log(Level.DEBUG, "Using main thread for analysis"); } else { Mockito.verify(reporter, Mockito.times(2)).log(Level.DEBUG, "Using {0} threads for analysis", getThreads()); } From 1924d235964cc987f32b9b8fc108eda7a36e157f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 May 2025 17:36:37 +0200 Subject: [PATCH 0975/1962] Fix unit tests --- .../net/sourceforge/pmd/lang/impl/MonoThreadProcessorTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/MonoThreadProcessorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/MonoThreadProcessorTest.java index d3a2b92eca9..f02f3f23b30 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/MonoThreadProcessorTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/MonoThreadProcessorTest.java @@ -38,7 +38,7 @@ void errorsShouldBeThrown() { // in case of error, we abort at the first error, so in this test case // we abort at the first file, so only 1 file is processed. assertEquals(1, reportListener.files.get()); - Mockito.verify(reporter, Mockito.times(1)).log(Level.DEBUG, "Using single thread for analysis"); + Mockito.verify(reporter, Mockito.times(1)).log(Level.DEBUG, "Using main thread for analysis"); // in mono thread, the error just falls through, we don't additionally catch and log it. Mockito.verifyNoMoreInteractions(reporter); } From 49a321dd5472430d4ad6e9cf9568748e8730063a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 May 2025 18:31:39 +0200 Subject: [PATCH 0976/1962] Add @Daniel-Ventura-25 as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 209 +++++++++++++------------- 2 files changed, 114 insertions(+), 104 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 8ff3f0e4e86..3666a0d389b 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8113,6 +8113,15 @@ "contributions": [ "bug" ] + }, + { + "login": "Daniel-Ventura-25", + "name": "Daniel Ventura", + "avatar_url": "https://avatars.githubusercontent.com/u/194499410?v=4", + "profile": "https://github.com/Daniel-Ventura-25", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 84a97f8987e..b7e0ba547cc 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -215,940 +215,941 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d

  • + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + From 1c1ef837b7ee523e4cbd8a21d939ba72f3e0882d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 May 2025 18:32:03 +0200 Subject: [PATCH 0977/1962] Add @Ledmington as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 193 +++++++++++++------------- 2 files changed, 106 insertions(+), 96 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 3666a0d389b..a0757f1e2ba 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8122,6 +8122,15 @@ "contributions": [ "bug" ] + }, + { + "login": "Ledmington", + "name": "Filippo Barbari", + "avatar_url": "https://avatars.githubusercontent.com/u/68538713?v=4", + "profile": "https://github.com/Ledmington", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index b7e0ba547cc..4de08edd91f 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -290,865 +290,866 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + From 0cdb9c8795f227abc8d63cfa64617453c0a4c9f4 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 May 2025 18:37:52 +0200 Subject: [PATCH 0978/1962] Prepare pmd release 7.14.0 --- .idea/vcs.xml | 1 - docs/_config.yml | 2 +- docs/pages/release_notes.md | 27 ++++++++++++++++++++++++++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 39eb3fa282f..13f1d386bbf 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -23,6 +23,5 @@ - \ No newline at end of file diff --git a/docs/_config.yml b/docs/_config.yml index c47ee3dfa4e..78864494b54 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,7 +1,7 @@ repository: pmd/pmd pmd: - version: 7.14.0-SNAPSHOT + version: 7.14.0 previous_version: 7.13.0 date: 2025-05-30 # release types: major, minor, bugfix diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index e837816a8fa..540d234afb9 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -137,21 +137,46 @@ for a list of common, shared parameters that are valid for both commands. ### โœจ Merged pull requests +* [#5584](https://github.com/pmd/pmd/pull/5584): \[ci] New workflow "Publish Snapshot" - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5599](https://github.com/pmd/pmd/pull/5599): \[java] Rewrite NPath complexity metric - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5609](https://github.com/pmd/pmd/pull/5609): \[core] Add rule to report unnecessary suppression comments/annotations - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5699](https://github.com/pmd/pmd/pull/5699): Fix #5702: \[java] First-class support for lombok @Slf4j - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5700](https://github.com/pmd/pmd/pull/5700): \[core] Don't accidentally catch unexpected runtime exceptions in CpdAnalysis - [Elliotte Rusty Harold](https://github.com/elharo) (@elharo) +* [#5712](https://github.com/pmd/pmd/pull/5712): Fix #5711: \[java] UseArrayAsList - only consider List.add - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5715](https://github.com/pmd/pmd/pull/5715): Fix #5476: \[visualforce] Resolve data types of standard object fields - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5716](https://github.com/pmd/pmd/pull/5716): Fix #5634: \[java] CommentDefaultAccessModifier: Comment between annotation and constructor not recognized - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#5726](https://github.com/pmd/pmd/pull/5726): Fix #5724: \[java] Implicit functional interface FP with sealed interface - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5727](https://github.com/pmd/pmd/pull/5727): Fix #5621: \[java] Fix FPs with UnusedPrivateMethod - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5728](https://github.com/pmd/pmd/pull/5728): \[ci] Improvements for "Publish Pull Requests" - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5730](https://github.com/pmd/pmd/pull/5730): \[ci] Refactor git-repo-sync - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5731](https://github.com/pmd/pmd/pull/5731): \[cli] Share more CLI options between CPD and PMD - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5736](https://github.com/pmd/pmd/pull/5736): Fix #5061: \[java] UnusedLocalVariable FP when using compound assignment - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#5741](https://github.com/pmd/pmd/pull/5741): \[cli] Make CLI default to multithreaded - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5742](https://github.com/pmd/pmd/pull/5742): \[ci] publish-snapshot/old build: migrate to central portal - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5743](https://github.com/pmd/pmd/pull/5743): \[ci] Make build a reuseable workflow - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5744](https://github.com/pmd/pmd/pull/5744): Fix #5705: \[cli] Always determine PMD_HOME based on script location - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5748](https://github.com/pmd/pmd/pull/5748): \[core] Reformat SarifLog to comply to coding standards - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5763](https://github.com/pmd/pmd/pull/5763): \[java] Support annotated constructor return type in symbol API - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5764](https://github.com/pmd/pmd/pull/5764): Fix #2462: \[java] LinguisticNaming should ignore setters for Builders - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) ### ๐Ÿ“ฆ Dependency updates +* [#5706](https://github.com/pmd/pmd/pull/5706): Bump PMD from 7.12.0 to 7.13.0 +* [#5709](https://github.com/pmd/pmd/pull/5709): Bump com.google.code.gson:gson from 2.13.0 to 2.13.1 +* [#5710](https://github.com/pmd/pmd/pull/5710): Bump com.puppycrawl.tools:checkstyle from 10.23.0 to 10.23.1 +* [#5717](https://github.com/pmd/pmd/pull/5717): Bump scalameta.version from 4.13.4 to 4.13.5 +* [#5718](https://github.com/pmd/pmd/pull/5718): Bump org.checkerframework:checker-qual from 3.49.2 to 3.49.3 +* [#5719](https://github.com/pmd/pmd/pull/5719): Bump org.jsoup:jsoup from 1.19.1 to 1.20.1 +* [#5751](https://github.com/pmd/pmd/pull/5751): Bump scalameta.version from 4.13.5 to 4.13.6 +* [#5754](https://github.com/pmd/pmd/pull/5754): Bump com.google.protobuf:protobuf-java from 4.30.2 to 4.31.0 +* [#5766](https://github.com/pmd/pmd/pull/5766): Bump io.github.git-commit-id:git-commit-id-maven-plugin from 9.0.1 to 9.0.2 +* [#5767](https://github.com/pmd/pmd/pull/5767): Bump org.mockito:mockito-core from 5.17.0 to 5.18.0 +* [#5768](https://github.com/pmd/pmd/pull/5768): Bump com.puppycrawl.tools:checkstyle from 10.23.1 to 10.24.0 ### ๐Ÿ“ˆ Stats +* 165 commits +* 33 closed tickets & PRs +* Days since last release: 35 {% endtocmaker %} - From 3a6e7a464dc14fa3315ced668680f442160db18b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 May 2025 18:57:10 +0200 Subject: [PATCH 0979/1962] [release] prepare release pmd_releases/7.14.0 --- pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-rust/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 6 +++--- 43 files changed, 45 insertions(+), 45 deletions(-) diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index 3effe5aeff4..073d1f71515 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.14.0-SNAPSHOT + 7.14.0 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 7f7d47f71ac..0872fba9db7 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index 324fb2cf720..049d5a37fc1 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index e018fe4af6f..077744594c6 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index 8941e0e9b43..7fb3d5de3ab 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index fb6d3edf254..621fbe874ac 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index 85a719013ad..aac319d2b75 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index 5c5e1d64ec6..9bbdd76f918 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index 7395d95aa7b..67db605adf8 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index 63ed6a09199..195006c07b3 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index 1e4eaa42b54..f033d82b044 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index c0224206a73..45107ef97cd 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index cf79f224b68..8f956def526 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index 3d06e2697b5..e74bbfcfb91 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index bf0ecbb67d8..ba1885e6c80 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index ed0e53a70be..6ca317a8a3a 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index b791a3ad1f8..0b646398683 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index f4cbe3bc36f..26241e5d15f 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index 402cbdfc4cd..a8197bf7ad9 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index f68145b433e..a6c444d13a7 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index 133a2506c0e..746ad1fc003 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index a70b65e7ea6..32ca123f669 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index e20f426fec7..7c7da3b1818 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index 568765f344c..811e242fbb0 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index 7e4520ca666..d65b67a928c 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index bc8896f1efe..638335990c8 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index a13ff806c7e..a529fb049f1 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index 3ba991d54b4..96513b80458 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index 8cb6cafca4f..40409e508df 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index bd99c081919..b0d9c91eae0 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index d3cd173f925..202635fedf1 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index 1247675bc22..97376d1de49 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index 480bec51497..45852620c62 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index be8b5fc3c51..549d92eec8a 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.14.0-SNAPSHOT + 7.14.0 ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index 51e08a8eeeb..60d92652964 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.14.0-SNAPSHOT + 7.14.0 ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index ec297e45321..0d8f2693d3e 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index 1b991f6e8ec..f643e5bce5a 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index 4cdf84678b6..5e3faf2e4a4 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index 73be90e60b0..f5a40c1b1b3 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index 4bb174c5491..b7d97d992df 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index d463f771a79..92ff2dfc062 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index 4c19b9fafa0..ec68d13796f 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 ../pom.xml diff --git a/pom.xml b/pom.xml index d5cc3f4edd2..985c8e63726 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.14.0 pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - HEAD + pmd_releases/7.14.0 PMD @@ -73,7 +73,7 @@ - 2025-04-25T07:36:41Z + 2025-05-30T16:37:58Z 8 From 876d4ab8ac5fb0940cd545b9c7a41866029cd519 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 May 2025 19:32:40 +0200 Subject: [PATCH 0980/1962] [ci] Use correct credentials for central deployment --- .ci/build.sh | 4 ++-- .github/workflows/old-build.yml | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.ci/build.sh b/.ci/build.sh index 3220dbb9d85..7c24a458807 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -254,8 +254,8 @@ function pmd_ci_build_setup_maven_settings() { central - \${env.CI_DEPLOY_USERNAME} - \${env.CI_DEPLOY_PASSWORD} + \${env.MAVEN_CENTRAL_PORTAL_USERNAME} + \${env.MAVEN_CENTRAL_PORTAL_PASSWORD} diff --git a/.github/workflows/old-build.yml b/.github/workflows/old-build.yml index 48402116089..23f5604fafb 100644 --- a/.github/workflows/old-build.yml +++ b/.github/workflows/old-build.yml @@ -81,6 +81,8 @@ jobs: PMD_CI_GPG_PRIVATE_KEY: ${{ secrets.PMD_CI_GPG_PRIVATE_KEY }} MAVEN_GPG_PASSPHRASE: ${{ secrets.PMD_CI_GPG_PASSPHRASE }} PMD_ACTIONS_HELPER_TOKEN: ${{ steps.pmd-actions-helper-app-token.outputs.token }} + MAVEN_CENTRAL_PORTAL_USERNAME: ${{ secrets.MAVEN_CENTRAL_PORTAL_USERNAME }} + MAVEN_CENTRAL_PORTAL_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PORTAL_PASSWORD }} - name: Workaround actions/upload-artifact#176 run: | echo "artifacts_path=$(realpath ..)" >> $GITHUB_ENV From 94a22a0343984188cf989b8aee8b6800f7e4ce9f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 May 2025 20:33:22 +0200 Subject: [PATCH 0981/1962] [release] Prepare next development version [skip ci] --- docs/_config.yml | 6 +- docs/pages/release_notes.md | 143 +--------------- docs/pages/release_notes_old.md | 181 +++++++++++++++++++++ pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-rust/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 4 +- 46 files changed, 229 insertions(+), 189 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 78864494b54..92a893edacc 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,9 +1,9 @@ repository: pmd/pmd pmd: - version: 7.14.0 - previous_version: 7.13.0 - date: 2025-05-30 + version: 7.15.0-SNAPSHOT + previous_version: 7.14.0 + date: 2025-06-27 # release types: major, minor, bugfix release_type: minor diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 540d234afb9..0c9c0dd3524 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -24,159 +24,18 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy -#### PMD CLI now uses threaded execution by default - -In the PMD CLI, the `--threads` (`-t`) option can now accept a thread -count given relative to the number of cores of the machine. For instance, -it is now possible to write `-t 1C` to spawn one thread per core, or `-t 0.5C` -to spawn one thread for every other core. - -The thread count option now defaults to `1C`, meaning parallel execution -is used by default. You can disable this by using `-t 1`. - -#### New Rule UnnecessaryWarningSuppression (experimental) - -This new Java rule {% rule java/bestpractices/UnnecessaryWarningSuppression %} reports unused suppression -annotations and comments. Violations of this rule cannot be suppressed. - -How to use it? Just include it in your ruleset: - -```xml - -``` - -Note: This rule is currently experimental. It is available for now only for Java. -The rule for now only reports annotations specific to PMD, like `@SuppressWarnings("PMD")`. -In the future we might be able to check for other common ones like `@SuppressWarnings("unchecked")` or `"fallthrough"`. -Since violations of this rule cannot be suppressed, we opted here on the side of false-negatives and -don't report every unused case yet. -However, suppressing specific PMD rules is working as expected. - -#### Migrating to Central Publisher Portal - -We've now migrated to [Central Publisher Portal](https://central.sonatype.org/publish/publish-portal-guide/). -Snapshots of PMD are still available, however the repository URL changed. To consume these with maven, you can -use the following snippet: - -```xml - - - Central Portal Snapshots - central-portal-snapshots - https://central.sonatype.com/repository/maven-snapshots/ - - false - - - true - - - -``` - -Releases of PMD are available on [Maven Central](https://central.sonatype.com/) as before without change. - -#### More CLI parameters shared between PMD and CPD - -When executing PMD or CPD, the same parameters are now understood for selecting which files should -be analyzed. See [File collection options]({{ baseurl }}pmd_userdocs_cli_reference.html#file-collection-options) -for a list of common, shared parameters that are valid for both commands. - ### ๐Ÿ› Fixed Issues -* core - * [#648](https://github.com/pmd/pmd/issues/648): \[core] Warn on unneeded suppression - * [#5700](https://github.com/pmd/pmd/pull/5700): \[core] Don't accidentally catch unexpected runtime exceptions in CpdAnalysis - * [#5705](https://github.com/pmd/pmd/issues/5705): \[cli] PMD's start script fails if PMD_HOME is set -* java-bestpractices - * [#5061](https://github.com/pmd/pmd/issues/5061): \[java] UnusedLocalVariable false positive when variable is read as side effect of an assignment - * [#5621](https://github.com/pmd/pmd/issues/5621): \[java] UnusedPrivateMethod with method ref - * [#5724](https://github.com/pmd/pmd/issues/5724): \[java] ImplicitFunctionalInterface should not be reported on sealed interfaces -* java-codestyle - * [#2462](https://github.com/pmd/pmd/issues/2462): \[java] LinguisticNaming must ignore setters that returns current type (Builder pattern) - * [#5634](https://github.com/pmd/pmd/issues/5634): \[java] CommentDefaultAccessModifier doesn't recognize /* package */ comment at expected location for constructors -* java-design - * [#5568](https://github.com/pmd/pmd/issues/5568): \[java] High NPathComplexity in `switch` expression - * [#5647](https://github.com/pmd/pmd/issues/5647): \[java] NPathComplexity does not account for `return`s -* java-errorprone - * [#5702](https://github.com/pmd/pmd/issues/5702): \[java] InvalidLogMessageFormat: Lombok @Slf4j annotation is not interpreted by PMD -* java-performance - * [#5711](https://github.com/pmd/pmd/issues/5711): \[java] UseArraysAsList false positive with Sets -* visualforce - * [#5476](https://github.com/pmd/pmd/issues/5476): \[visualforce] NPE when analyzing standard field references in visualforce page ### ๐Ÿšจ API Changes -#### CLI -* CPD now supports `--report-file` (-r) and `--exclude-file-list`. -* PMD now supports `--exclude` and `--non-recursive`. -* The option `--ignore-list` in PMD is renamed to `--exclude-file-list`. - -#### Deprecations -* CLI - * The option `--ignore-list` has been deprecated. Use `--exclude-file-list` instead. -* core - * {% jdoc !!core::lang.ast.AstInfo#getSuppressionComments() %}: Use {% jdoc core::lang.ast.AstInfo#getAllSuppressionComments() %} - or {% jdoc core::lang.ast.AstInfo#getSuppressionComment(int) %}. - * {% jdoc !!core::lang.ast.AstInfo#withSuppressMap() %}: Use {%jdoc core::lang.ast.AstInfo#withSuppressionComments(java.util.Collection) %} - * {% jdoc !!core::lang.ast.impl.javacc.AbstractTokenManager#suppressMap %}: Don't use this map directly anymore. Instead, - use {%jdoc core::lang.ast.impl.javacc.AbstractTokenManager#getSuppressionComments() %}. - * {% jdoc !!core::lang.ast.impl.javacc.AbstractTokenManager#getSuppressMap() %}: Use - {% jdoc core::lang.ast.impl.javacc.AbstractTokenManager#getSuppressionComments() %} instead. -* pmd-java - * {% jdoc !!java::lang.java.ast.ASTCompactConstructorDeclaration#getDeclarationNode() %}: This method just returns `this` and isn't useful. - * {% jdoc !!java::lang.java.metrics.JavaMetrics#NPATH %}: Use {% jdoc java::lang.java.metrics.JavaMetrics#NPATH_COMP %}, which is available on more nodes, - and uses Long instead of BigInteger. - -#### Experimental -* core - * {%jdoc core::lang.ast.impl.SuppressionCommentImpl %} - * {%jdoc core::lang.rule.impl.UnnecessaryPmdSuppressionRule %} - * {%jdoc !!core::reporting.RuleContext#addViolationNoSuppress(core::reporting.Reportable,core::lang.ast.AstInfo,java.lang.String,java.lang.Object...) %} - * {%jdoc core::reporting.ViolationSuppressor.SuppressionCommentWrapper %} -* pmd-java - * {%jdoc !!java::lang.java.types.OverloadSelectionResult#getTypeToSearch() %} ### โœจ Merged pull requests -* [#5584](https://github.com/pmd/pmd/pull/5584): \[ci] New workflow "Publish Snapshot" - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5599](https://github.com/pmd/pmd/pull/5599): \[java] Rewrite NPath complexity metric - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5609](https://github.com/pmd/pmd/pull/5609): \[core] Add rule to report unnecessary suppression comments/annotations - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5699](https://github.com/pmd/pmd/pull/5699): Fix #5702: \[java] First-class support for lombok @Slf4j - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5700](https://github.com/pmd/pmd/pull/5700): \[core] Don't accidentally catch unexpected runtime exceptions in CpdAnalysis - [Elliotte Rusty Harold](https://github.com/elharo) (@elharo) -* [#5712](https://github.com/pmd/pmd/pull/5712): Fix #5711: \[java] UseArrayAsList - only consider List.add - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5715](https://github.com/pmd/pmd/pull/5715): Fix #5476: \[visualforce] Resolve data types of standard object fields - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5716](https://github.com/pmd/pmd/pull/5716): Fix #5634: \[java] CommentDefaultAccessModifier: Comment between annotation and constructor not recognized - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) -* [#5726](https://github.com/pmd/pmd/pull/5726): Fix #5724: \[java] Implicit functional interface FP with sealed interface - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5727](https://github.com/pmd/pmd/pull/5727): Fix #5621: \[java] Fix FPs with UnusedPrivateMethod - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5728](https://github.com/pmd/pmd/pull/5728): \[ci] Improvements for "Publish Pull Requests" - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5730](https://github.com/pmd/pmd/pull/5730): \[ci] Refactor git-repo-sync - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5731](https://github.com/pmd/pmd/pull/5731): \[cli] Share more CLI options between CPD and PMD - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5736](https://github.com/pmd/pmd/pull/5736): Fix #5061: \[java] UnusedLocalVariable FP when using compound assignment - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) -* [#5741](https://github.com/pmd/pmd/pull/5741): \[cli] Make CLI default to multithreaded - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5742](https://github.com/pmd/pmd/pull/5742): \[ci] publish-snapshot/old build: migrate to central portal - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5743](https://github.com/pmd/pmd/pull/5743): \[ci] Make build a reuseable workflow - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5744](https://github.com/pmd/pmd/pull/5744): Fix #5705: \[cli] Always determine PMD_HOME based on script location - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5748](https://github.com/pmd/pmd/pull/5748): \[core] Reformat SarifLog to comply to coding standards - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5763](https://github.com/pmd/pmd/pull/5763): \[java] Support annotated constructor return type in symbol API - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5764](https://github.com/pmd/pmd/pull/5764): Fix #2462: \[java] LinguisticNaming should ignore setters for Builders - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) ### ๐Ÿ“ฆ Dependency updates -* [#5706](https://github.com/pmd/pmd/pull/5706): Bump PMD from 7.12.0 to 7.13.0 -* [#5709](https://github.com/pmd/pmd/pull/5709): Bump com.google.code.gson:gson from 2.13.0 to 2.13.1 -* [#5710](https://github.com/pmd/pmd/pull/5710): Bump com.puppycrawl.tools:checkstyle from 10.23.0 to 10.23.1 -* [#5717](https://github.com/pmd/pmd/pull/5717): Bump scalameta.version from 4.13.4 to 4.13.5 -* [#5718](https://github.com/pmd/pmd/pull/5718): Bump org.checkerframework:checker-qual from 3.49.2 to 3.49.3 -* [#5719](https://github.com/pmd/pmd/pull/5719): Bump org.jsoup:jsoup from 1.19.1 to 1.20.1 -* [#5751](https://github.com/pmd/pmd/pull/5751): Bump scalameta.version from 4.13.5 to 4.13.6 -* [#5754](https://github.com/pmd/pmd/pull/5754): Bump com.google.protobuf:protobuf-java from 4.30.2 to 4.31.0 -* [#5766](https://github.com/pmd/pmd/pull/5766): Bump io.github.git-commit-id:git-commit-id-maven-plugin from 9.0.1 to 9.0.2 -* [#5767](https://github.com/pmd/pmd/pull/5767): Bump org.mockito:mockito-core from 5.17.0 to 5.18.0 -* [#5768](https://github.com/pmd/pmd/pull/5768): Bump com.puppycrawl.tools:checkstyle from 10.23.1 to 10.24.0 ### ๐Ÿ“ˆ Stats -* 165 commits -* 33 closed tickets & PRs -* Days since last release: 35 {% endtocmaker %} + diff --git a/docs/pages/release_notes_old.md b/docs/pages/release_notes_old.md index 42b29db63ed..45ef7c403c8 100644 --- a/docs/pages/release_notes_old.md +++ b/docs/pages/release_notes_old.md @@ -7,6 +7,187 @@ Previous versions of PMD can be downloaded here: [Releases - pmd/pmd (GitHub)](h +## 30-May-2025 - 7.14.0 + +The PMD team is pleased to announce PMD 7.14.0. + +This is a minor release. + +### Table Of Contents + +* [๐Ÿš€ New and noteworthy](#new-and-noteworthy) + * [PMD CLI now uses threaded execution by default](#pmd-cli-now-uses-threaded-execution-by-default) + * [New Rule UnnecessaryWarningSuppression (experimental)](#new-rule-unnecessarywarningsuppression-experimental) + * [Migrating to Central Publisher Portal](#migrating-to-central-publisher-portal) + * [More CLI parameters shared between PMD and CPD](#more-cli-parameters-shared-between-pmd-and-cpd) +* [๐Ÿ› Fixed Issues](#fixed-issues) +* [๐Ÿšจ API Changes](#api-changes) + * [CLI](#cli) + * [Deprecations](#deprecations) + * [Experimental](#experimental) +* [โœจ Merged pull requests](#merged-pull-requests) +* [๐Ÿ“ฆ Dependency updates](#dependency-updates) +* [๐Ÿ“ˆ Stats](#stats) + +### ๐Ÿš€ New and noteworthy + +#### PMD CLI now uses threaded execution by default + +In the PMD CLI, the `--threads` (`-t`) option can now accept a thread +count given relative to the number of cores of the machine. For instance, +it is now possible to write `-t 1C` to spawn one thread per core, or `-t 0.5C` +to spawn one thread for every other core. + +The thread count option now defaults to `1C`, meaning parallel execution +is used by default. You can disable this by using `-t 1`. + +#### New Rule UnnecessaryWarningSuppression (experimental) + +This new Java rule [`UnnecessaryWarningSuppression`](https://docs.pmd-code.org/pmd-doc-7.14.0/pmd_rules_java_bestpractices.html#unnecessarywarningsuppression) reports unused suppression +annotations and comments. Violations of this rule cannot be suppressed. + +How to use it? Just include it in your ruleset: + +```xml + +``` + +Note: This rule is currently experimental. It is available for now only for Java. +The rule for now only reports annotations specific to PMD, like `@SuppressWarnings("PMD")`. +In the future we might be able to check for other common ones like `@SuppressWarnings("unchecked")` or `"fallthrough"`. +Since violations of this rule cannot be suppressed, we opted here on the side of false-negatives and +don't report every unused case yet. +However, suppressing specific PMD rules is working as expected. + +#### Migrating to Central Publisher Portal + +We've now migrated to [Central Publisher Portal](https://central.sonatype.org/publish/publish-portal-guide/). +Snapshots of PMD are still available, however the repository URL changed. To consume these with maven, you can +use the following snippet: + +```xml + + + Central Portal Snapshots + central-portal-snapshots + https://central.sonatype.com/repository/maven-snapshots/ + + false + + + true + + + +``` + +Releases of PMD are available on [Maven Central](https://central.sonatype.com/) as before without change. + +#### More CLI parameters shared between PMD and CPD + +When executing PMD or CPD, the same parameters are now understood for selecting which files should +be analyzed. See [File collection options](https://docs.pmd-code.org/pmd-doc-7.14.0/pmd_userdocs_cli_reference.html#file-collection-options) +for a list of common, shared parameters that are valid for both commands. + +### ๐Ÿ› Fixed Issues +* core + * [#648](https://github.com/pmd/pmd/issues/648): \[core] Warn on unneeded suppression + * [#5700](https://github.com/pmd/pmd/pull/5700): \[core] Don't accidentally catch unexpected runtime exceptions in CpdAnalysis + * [#5705](https://github.com/pmd/pmd/issues/5705): \[cli] PMD's start script fails if PMD_HOME is set +* java-bestpractices + * [#5061](https://github.com/pmd/pmd/issues/5061): \[java] UnusedLocalVariable false positive when variable is read as side effect of an assignment + * [#5621](https://github.com/pmd/pmd/issues/5621): \[java] UnusedPrivateMethod with method ref + * [#5724](https://github.com/pmd/pmd/issues/5724): \[java] ImplicitFunctionalInterface should not be reported on sealed interfaces +* java-codestyle + * [#2462](https://github.com/pmd/pmd/issues/2462): \[java] LinguisticNaming must ignore setters that returns current type (Builder pattern) + * [#5634](https://github.com/pmd/pmd/issues/5634): \[java] CommentDefaultAccessModifier doesn't recognize /* package */ comment at expected location for constructors +* java-design + * [#5568](https://github.com/pmd/pmd/issues/5568): \[java] High NPathComplexity in `switch` expression + * [#5647](https://github.com/pmd/pmd/issues/5647): \[java] NPathComplexity does not account for `return`s +* java-errorprone + * [#5702](https://github.com/pmd/pmd/issues/5702): \[java] InvalidLogMessageFormat: Lombok @Slf4j annotation is not interpreted by PMD +* java-performance + * [#5711](https://github.com/pmd/pmd/issues/5711): \[java] UseArraysAsList false positive with Sets +* visualforce + * [#5476](https://github.com/pmd/pmd/issues/5476): \[visualforce] NPE when analyzing standard field references in visualforce page + +### ๐Ÿšจ API Changes +#### CLI +* CPD now supports `--report-file` (-r) and `--exclude-file-list`. +* PMD now supports `--exclude` and `--non-recursive`. +* The option `--ignore-list` in PMD is renamed to `--exclude-file-list`. + +#### Deprecations +* CLI + * The option `--ignore-list` has been deprecated. Use `--exclude-file-list` instead. +* core + * AstInfo#getSuppressionComments: Use getAllSuppressionComments + or getSuppressionComment. + * AstInfo#withSuppressMap: Use withSuppressionComments + * AbstractTokenManager#suppressMap: Don't use this map directly anymore. Instead, + use getSuppressionComments. + * AbstractTokenManager#getSuppressMap: Use + getSuppressionComments instead. +* pmd-java + * ASTCompactConstructorDeclaration#getDeclarationNode: This method just returns `this` and isn't useful. + * JavaMetrics#NPATH: Use NPATH_COMP, which is available on more nodes, + and uses Long instead of BigInteger. + +#### Experimental +* core + * SuppressionCommentImpl + * UnnecessaryPmdSuppressionRule + * RuleContext#addViolationNoSuppress + * ViolationSuppressor.SuppressionCommentWrapper +* pmd-java + * OverloadSelectionResult#getTypeToSearch + +### โœจ Merged pull requests + +* [#5584](https://github.com/pmd/pmd/pull/5584): \[ci] New workflow "Publish Snapshot" - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5599](https://github.com/pmd/pmd/pull/5599): \[java] Rewrite NPath complexity metric - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5609](https://github.com/pmd/pmd/pull/5609): \[core] Add rule to report unnecessary suppression comments/annotations - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5699](https://github.com/pmd/pmd/pull/5699): Fix #5702: \[java] First-class support for lombok @Slf4j - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5700](https://github.com/pmd/pmd/pull/5700): \[core] Don't accidentally catch unexpected runtime exceptions in CpdAnalysis - [Elliotte Rusty Harold](https://github.com/elharo) (@elharo) +* [#5712](https://github.com/pmd/pmd/pull/5712): Fix #5711: \[java] UseArrayAsList - only consider List.add - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5715](https://github.com/pmd/pmd/pull/5715): Fix #5476: \[visualforce] Resolve data types of standard object fields - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5716](https://github.com/pmd/pmd/pull/5716): Fix #5634: \[java] CommentDefaultAccessModifier: Comment between annotation and constructor not recognized - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#5726](https://github.com/pmd/pmd/pull/5726): Fix #5724: \[java] Implicit functional interface FP with sealed interface - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5727](https://github.com/pmd/pmd/pull/5727): Fix #5621: \[java] Fix FPs with UnusedPrivateMethod - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5728](https://github.com/pmd/pmd/pull/5728): \[ci] Improvements for "Publish Pull Requests" - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5730](https://github.com/pmd/pmd/pull/5730): \[ci] Refactor git-repo-sync - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5731](https://github.com/pmd/pmd/pull/5731): \[cli] Share more CLI options between CPD and PMD - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5736](https://github.com/pmd/pmd/pull/5736): Fix #5061: \[java] UnusedLocalVariable FP when using compound assignment - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#5741](https://github.com/pmd/pmd/pull/5741): \[cli] Make CLI default to multithreaded - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5742](https://github.com/pmd/pmd/pull/5742): \[ci] publish-snapshot/old build: migrate to central portal - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5743](https://github.com/pmd/pmd/pull/5743): \[ci] Make build a reuseable workflow - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5744](https://github.com/pmd/pmd/pull/5744): Fix #5705: \[cli] Always determine PMD_HOME based on script location - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5748](https://github.com/pmd/pmd/pull/5748): \[core] Reformat SarifLog to comply to coding standards - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5763](https://github.com/pmd/pmd/pull/5763): \[java] Support annotated constructor return type in symbol API - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5764](https://github.com/pmd/pmd/pull/5764): Fix #2462: \[java] LinguisticNaming should ignore setters for Builders - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) + +### ๐Ÿ“ฆ Dependency updates + +* [#5706](https://github.com/pmd/pmd/pull/5706): Bump PMD from 7.12.0 to 7.13.0 +* [#5709](https://github.com/pmd/pmd/pull/5709): Bump com.google.code.gson:gson from 2.13.0 to 2.13.1 +* [#5710](https://github.com/pmd/pmd/pull/5710): Bump com.puppycrawl.tools:checkstyle from 10.23.0 to 10.23.1 +* [#5717](https://github.com/pmd/pmd/pull/5717): Bump scalameta.version from 4.13.4 to 4.13.5 +* [#5718](https://github.com/pmd/pmd/pull/5718): Bump org.checkerframework:checker-qual from 3.49.2 to 3.49.3 +* [#5719](https://github.com/pmd/pmd/pull/5719): Bump org.jsoup:jsoup from 1.19.1 to 1.20.1 +* [#5751](https://github.com/pmd/pmd/pull/5751): Bump scalameta.version from 4.13.5 to 4.13.6 +* [#5754](https://github.com/pmd/pmd/pull/5754): Bump com.google.protobuf:protobuf-java from 4.30.2 to 4.31.0 +* [#5766](https://github.com/pmd/pmd/pull/5766): Bump io.github.git-commit-id:git-commit-id-maven-plugin from 9.0.1 to 9.0.2 +* [#5767](https://github.com/pmd/pmd/pull/5767): Bump org.mockito:mockito-core from 5.17.0 to 5.18.0 +* [#5768](https://github.com/pmd/pmd/pull/5768): Bump com.puppycrawl.tools:checkstyle from 10.23.1 to 10.24.0 + +### ๐Ÿ“ˆ Stats + +* 165 commits +* 33 closed tickets & PRs +* Days since last release: 35 + + + ## 25-April-2025 - 7.13.0 The PMD team is pleased to announce PMD 7.13.0. diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index 073d1f71515..bbd23e238b4 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.14.0 + 7.15.0-SNAPSHOT 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 0872fba9db7..3d35c407e80 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index 049d5a37fc1..191e71b9bde 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index 077744594c6..3a1c11d004b 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index 7fb3d5de3ab..81ed1e69f02 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index 621fbe874ac..8d1c59882a3 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index aac319d2b75..edfc5fa8321 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index 9bbdd76f918..fedc7994deb 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index 67db605adf8..90c00afca0b 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index 195006c07b3..497d8bb3ca4 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index f033d82b044..109f135291f 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index 45107ef97cd..19b65e796eb 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index 8f956def526..c66301b99b7 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index e74bbfcfb91..e99db49412d 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index ba1885e6c80..4bb58950191 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 6ca317a8a3a..62c662c5d98 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index 0b646398683..0416b66c8d9 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index 26241e5d15f..b235b370e09 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index a8197bf7ad9..ef26b4eb69d 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index a6c444d13a7..f78f03e53e2 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index 746ad1fc003..339b4802173 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index 32ca123f669..0ebdadd9adf 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index 7c7da3b1818..a3fd4d33024 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index 811e242fbb0..1f91d04a33a 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index d65b67a928c..8fc1b69156a 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index 638335990c8..25d35c988e3 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index a529fb049f1..391533c5a10 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index 96513b80458..4e1bc768c7a 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index 40409e508df..90d77043388 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index b0d9c91eae0..fae9ebfb13d 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index 202635fedf1..71b878cbea4 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index 97376d1de49..530a73df72a 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index 45852620c62..e883b0cff0a 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index 549d92eec8a..1140719f814 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.14.0 + 7.15.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index 60d92652964..f5f409836fb 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.14.0 + 7.15.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index 0d8f2693d3e..b58f26118d7 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index f643e5bce5a..5b0ca0ea7c4 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index 5e3faf2e4a4..2e83785af2d 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index f5a40c1b1b3..2491c5a22eb 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index b7d97d992df..e719ca61414 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index 92ff2dfc062..253205a7f95 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index ec68d13796f..a03917aa061 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index 985c8e63726..373b3156607 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.14.0 + 7.15.0-SNAPSHOT pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - pmd_releases/7.14.0 + HEAD PMD From 0d0c0a2e16130cdaa6e54aa4b951c44073416b30 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 May 2025 21:54:58 +0200 Subject: [PATCH 0982/1962] Bump PMD from 7.13.0 to 7.14.0 (#5775) Dogfood update... --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 373b3156607..5875b782f6e 100644 --- a/pom.xml +++ b/pom.xml @@ -579,22 +579,22 @@ net.sourceforge.pmd pmd-core - 7.13.0 + 7.14.0 net.sourceforge.pmd pmd-java - 7.13.0 + 7.14.0 net.sourceforge.pmd pmd-jsp - 7.13.0 + 7.14.0 net.sourceforge.pmd pmd-javascript - 7.13.0 + 7.14.0 From 332015b858a878393b6bdf6bfb54e94104bd67f4 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 3 Jun 2025 20:58:47 +0200 Subject: [PATCH 0983/1962] [doc] Add a simple check whether generate rule doc pages exist This is to prevent issues like #5790 --- docs/_plugins/check_rule_docs.rb | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 docs/_plugins/check_rule_docs.rb diff --git a/docs/_plugins/check_rule_docs.rb b/docs/_plugins/check_rule_docs.rb new file mode 100644 index 00000000000..4170a78664e --- /dev/null +++ b/docs/_plugins/check_rule_docs.rb @@ -0,0 +1,33 @@ + +Jekyll::Hooks.register :site, :after_init do |site| + ENV_VAR_NAME='PMD_DOC_IGNORE_MISSING_RULE_DOC' + + if ENV[ENV_VAR_NAME] then + Jekyll.logger.warn "Not verifying that generated rule doc pages exist. The generated documentation might be incomplete!" + else + + def check_file(filename) + unless File.exist?(filename) + Jekyll.logger.error "File #{filename} does not exist!" + Jekyll.logger.abort_with "Please execute `./mvnw package -Pgenerate-rule-docs -pl pmd-doc` before"\ + "generating pmd documentation or ignore by setting env variable #{ENV_VAR_NAME}" + end + end + + sourceDir = site.source + + Jekyll.logger.info "Verifying that generated rule doc pages exist in #{sourceDir}..." + + languages = ['apex', 'ecmascript', 'html', 'java', 'jsp', 'kotlin', 'modelica', 'plsql', 'pom', + 'swift', 'velocity', 'visualforce', 'xml', 'xsl'] + languages.each do |lang| + check_file "#{sourceDir}/pages/pmd/rules/#{lang}.md" + end + + # spot check of some categories + categories = ['apex/bestpractices.md', 'apex/codestyle.md', 'java/bestpractices.md', 'java/codestyle.md', 'java/design.md', 'modelica/bestpractices.md'] + categories.each do |cat| + check_file "#{sourceDir}/pages/pmd/rules/#{cat}" + end + end +end From 7611087b28c570bc34ea8a4bf08d617fbcd91128 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 5 Jun 2025 16:47:30 +0200 Subject: [PATCH 0984/1962] [doc] Improve check_rule_docs.rb - moved into subfolder to not be loaded automatically when generating release notes - check all existing languages and categories - check last modification time --- docs/_plugins/check_rule_docs.rb | 33 ------- docs/_plugins/hooks/check_rule_docs.rb | 131 +++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 33 deletions(-) delete mode 100644 docs/_plugins/check_rule_docs.rb create mode 100644 docs/_plugins/hooks/check_rule_docs.rb diff --git a/docs/_plugins/check_rule_docs.rb b/docs/_plugins/check_rule_docs.rb deleted file mode 100644 index 4170a78664e..00000000000 --- a/docs/_plugins/check_rule_docs.rb +++ /dev/null @@ -1,33 +0,0 @@ - -Jekyll::Hooks.register :site, :after_init do |site| - ENV_VAR_NAME='PMD_DOC_IGNORE_MISSING_RULE_DOC' - - if ENV[ENV_VAR_NAME] then - Jekyll.logger.warn "Not verifying that generated rule doc pages exist. The generated documentation might be incomplete!" - else - - def check_file(filename) - unless File.exist?(filename) - Jekyll.logger.error "File #{filename} does not exist!" - Jekyll.logger.abort_with "Please execute `./mvnw package -Pgenerate-rule-docs -pl pmd-doc` before"\ - "generating pmd documentation or ignore by setting env variable #{ENV_VAR_NAME}" - end - end - - sourceDir = site.source - - Jekyll.logger.info "Verifying that generated rule doc pages exist in #{sourceDir}..." - - languages = ['apex', 'ecmascript', 'html', 'java', 'jsp', 'kotlin', 'modelica', 'plsql', 'pom', - 'swift', 'velocity', 'visualforce', 'xml', 'xsl'] - languages.each do |lang| - check_file "#{sourceDir}/pages/pmd/rules/#{lang}.md" - end - - # spot check of some categories - categories = ['apex/bestpractices.md', 'apex/codestyle.md', 'java/bestpractices.md', 'java/codestyle.md', 'java/design.md', 'modelica/bestpractices.md'] - categories.each do |cat| - check_file "#{sourceDir}/pages/pmd/rules/#{cat}" - end - end -end diff --git a/docs/_plugins/hooks/check_rule_docs.rb b/docs/_plugins/hooks/check_rule_docs.rb new file mode 100644 index 00000000000..a1485d9bedb --- /dev/null +++ b/docs/_plugins/hooks/check_rule_docs.rb @@ -0,0 +1,131 @@ +# +# A jekyll hook, that verifies, that the generated rule documentation pages are existing. +# They would be generated by calling "./mvnw package -Pgenerate-rule-docs -pl pmd-doc", but are +# missing on a fresh clone/checkout. +# This is to avoid creating PMD documentation without rule documentation. +# +# Note: This does exclude various ruleset categories, as they don't contain rules and we don't +# generate documentation for these. +# + +Jekyll::Hooks.register :site, :after_init do |site| + ENV_VAR_NAME='PMD_DOC_IGNORE_MISSING_RULE_DOC' + + if ENV[ENV_VAR_NAME] then + Jekyll.logger.warn "Not verifying that generated rule doc pages exist. The generated documentation might be incomplete!" + else + + def check_file(filename, mtime = nil, messages) + if not File.exist?(filename) + messages << "File #{filename} does not exist!" + elsif mtime != nil and File.stat(filename).mtime < mtime + messages << "File #{filename} needs to be regenerated!" + end + end + + sourceDir = site.source + Jekyll.logger.info "Verifying that generated rule doc pages exist in #{sourceDir}..." + + languages = {} + categories = {} + Dir.glob('**/src/main/resources/category/*/*.xml', base: "#{sourceDir}/..").each {|file| + mtime = File.stat("#{sourceDir}/../#{file}").mtime + %r<.+src/main/resources/category/([^/]+)/([^.]+)\.xml> =~ file + languages[$1] = 1 + categories["#{$1}/#{$2}.md"] = mtime + } + + messages = [] + + languages_exceptions = [ + 'wsdl' + ] + languages.each { |lang, _| + check_file "#{sourceDir}/pages/pmd/rules/#{lang}.md", messages unless languages_exceptions.any?(lang) + } + + categories_exceptions = [ + 'apex/multithreading.md', + 'html/codestyle.md', + 'html/design.md', + 'html/documentation.md', + 'html/errorprone.md', + 'html/multithreading.md', + 'html/performance.md', + 'html/security.md', + 'ecmascript/design.md', + 'ecmascript/documentation.md', + 'ecmascript/multithreading.md', + 'ecmascript/security.md', + 'jsp/documentation.md', + 'jsp/multithreading.md', + 'jsp/performance.md', + 'plsql/documentation.md', + 'plsql/multithreading.md', + 'plsql/performance.md', + 'plsql/security.md', + 'scala/bestpractices.md', + 'scala/codestyle.md', + 'scala/design.md', + 'scala/documentation.md', + 'scala/errorprone.md', + 'scala/multithreading.md', + 'scala/performance.md', + 'scala/security.md', + 'swift/codestyle.md', + 'swift/design.md', + 'swift/documentation.md', + 'swift/multithreading.md', + 'swift/performance.md', + 'swift/security.md', + 'velocity/codestyle.md', + 'velocity/documentation.md', + 'velocity/multithreading.md', + 'velocity/performance.md', + 'velocity/security.md', + 'visualforce/bestpractices.md', + 'visualforce/codestyle.md', + 'visualforce/design.md', + 'visualforce/documentation.md', + 'visualforce/errorprone.md', + 'visualforce/multithreading.md', + 'visualforce/performance.md', + 'pom/bestpractices.md', + 'pom/codestyle.md', + 'pom/design.md', + 'pom/documentation.md', + 'pom/multithreading.md', + 'pom/performance.md', + 'pom/security.md', + 'wsdl/bestpractices.md', + 'wsdl/codestyle.md', + 'wsdl/design.md', + 'wsdl/documentation.md', + 'wsdl/errorprone.md', + 'wsdl/multithreading.md', + 'wsdl/performance.md', + 'wsdl/security.md', + 'xml/codestyle.md', + 'xml/design.md', + 'xml/documentation.md', + 'xml/multithreading.md', + 'xml/performance.md', + 'xml/security.md', + 'xsl/bestpractices.md', + 'xsl/design.md', + 'xsl/documentation.md', + 'xsl/errorprone.md', + 'xsl/multithreading.md', + 'xsl/security.md' + ] + categories.each { |cat, mtime| + check_file "#{sourceDir}/pages/pmd/rules/#{cat}", mtime, messages unless categories_exceptions.any?(cat) + } + + if not messages.empty? + messages.each {|m| Jekyll.logger.error m} + Jekyll.logger.abort_with "Please execute `./mvnw package -Pgenerate-rule-docs -pl pmd-doc` before"\ + "generating pmd documentation or ignore by setting env variable #{ENV_VAR_NAME}" + end + end +end From 44ecb35dbe688787e4e20986a8e641ca986cb0bd Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 5 Jun 2025 16:48:49 +0200 Subject: [PATCH 0985/1962] [doc] Update release notes (#5791) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 0c9c0dd3524..b2aac67e7ec 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,11 +25,14 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* doc + * [#5790](https://github.com/pmd/pmd/issues/5790): \[doc] Website rule reference pages are returning 404 ### ๐Ÿšจ API Changes ### โœจ Merged pull requests +* [#5791](https://github.com/pmd/pmd/pull/5791): \[doc] Add a simple check whether generate rule doc pages exist - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ Dependency updates From 0bf21b8c586609dd745c3057347005c5059edf53 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 5 Jun 2025 16:49:09 +0200 Subject: [PATCH 0986/1962] Update @ethauvin as a contributor --- .all-contributorsrc | 3 ++- docs/pages/pmd/projectdocs/credits.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index a0757f1e2ba..4963dcaa893 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7309,7 +7309,8 @@ "avatar_url": "https://avatars.githubusercontent.com/u/705618?v=4", "profile": "https://erik.thauvin.net/", "contributions": [ - "doc" + "doc", + "bug" ] }, { diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 4de08edd91f..1edee60c6b8 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -276,7 +276,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d - + From 15b6ea5d488a99594d598ca1b3a88bc436d53930 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 6 Jun 2025 09:36:29 +0200 Subject: [PATCH 0987/1962] Update SPONSORS.md --- SPONSORS.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/SPONSORS.md b/SPONSORS.md index 6376a0e9725..727b734bb9c 100644 --- a/SPONSORS.md +++ b/SPONSORS.md @@ -2,11 +2,13 @@ Many thanks to all our sponsors: -* [Matt Hargett](https://github.com/matthargett) (@matthargett) -* [Oliver Siegmar](https://github.com/osiegmar) (@osiegmar) -* [screamingfrog](https://github.com/screamingfrog) (@screamingfrog) -* John Kuhl via opencollective -* [flxbl-io](https://github.com/flxbl-io) (@flxbl-io) +* [Matt Hargett](https://github.com/matthargett) (@matthargett) (7/2022 till 3/2023) +* [Oliver Siegmar](https://github.com/osiegmar) (@osiegmar) (9/2022) +* [screamingfrog](https://github.com/screamingfrog) (@screamingfrog) (11/2022) +* John Kuhl via opencollective (11/2023) +* [flxbl-io](https://github.com/flxbl-io) (@flxbl-io) (12/2024 till 05/2025) +* [Jonathan Gillespie](https://github.com/jongpie) (@jongpie) (12/2024 till 04/2025) +* [Cybozu](https://github.com/cybozu) (@cybozu) (since 05/2025) If you also want to sponsor PMD, you have two options: From bb9e8917fcf0e9486fbfaa36f6aebc66963e0f46 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 6 Jun 2025 09:37:34 +0200 Subject: [PATCH 0988/1962] Add @jongpie as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 167 +++++++++++++------------- 2 files changed, 93 insertions(+), 83 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index a0757f1e2ba..9a1c9d00009 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8131,6 +8131,15 @@ "contributions": [ "bug" ] + }, + { + "login": "jongpie", + "name": "Jonathan Gillespie", + "avatar_url": "https://avatars.githubusercontent.com/u/1267157?v=4", + "profile": "https://linkedin.com/in/jongpie", + "contributions": [ + "financial" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 4de08edd91f..c1105502eb0 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -405,750 +405,751 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + From d76a569482befd2dc15b6081769fbd226faab226 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 6 Jun 2025 09:37:44 +0200 Subject: [PATCH 0989/1962] Add @cybozu as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 213 +++++++++++++------------- 2 files changed, 116 insertions(+), 106 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 9a1c9d00009..35cfcc7eba3 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8140,6 +8140,15 @@ "contributions": [ "financial" ] + }, + { + "login": "cybozu", + "name": "Cybozu", + "avatar_url": "https://avatars.githubusercontent.com/u/2433152?v=4", + "profile": "https://www.kintone.com/", + "contributions": [ + "financial" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index c1105502eb0..34b98ea0c98 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -201,954 +201,955 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + From da14e670a0e531d8ac3f245bfdbbfd590fdbc20a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 6 Jun 2025 10:36:50 +0200 Subject: [PATCH 0990/1962] Fix #5793: [java] NonExhaustiveSwitch should ignore "case null" --- docs/pages/release_notes.md | 2 ++ .../resources/category/java/bestpractices.xml | 4 ++- .../bestpractices/xml/NonExhaustiveSwitch.xml | 30 +++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 0c9c0dd3524..c8e96a32326 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,6 +25,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* java-bestpractices + * [#5793](https://github.com/pmd/pmd/issues/5793): \[java] NonExhaustiveSwitch fails on exhaustive switch with sealed class ### ๐Ÿšจ API Changes diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 3f40ad75535..5cff27a574f 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -1017,10 +1017,12 @@ public class SecureSystem { 1] [@DefaultCase = false()] [@ExhaustiveEnumSwitch = false()] (: exclude pattern tests - for these, the compiler will ensure exhaustiveness :) - [*/SwitchLabel[@PatternLabel = false()]] + [not(*/SwitchLabel[@PatternLabel = true()])] ]]> diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/NonExhaustiveSwitch.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/NonExhaustiveSwitch.xml index 4531e2695d5..b7c17810d84 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/NonExhaustiveSwitch.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/NonExhaustiveSwitch.xml @@ -440,6 +440,36 @@ class Tester { } } } +]]> + + + + [java] NonExhaustiveSwitch fails on exhaustive switch with sealed class #5793 + 0 + sealedClass1.method1(); + case SealedClass2 sealedClass2 -> sealedClass2.method2(); + case null -> throw new IllegalStateException("Unexpected value: " + sealedInterface); + } + } +} ]]> From 22df6f5743ca7dad39297b8584a046ad2023e5fb Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 6 Jun 2025 10:37:33 +0200 Subject: [PATCH 0991/1962] Add @pkernevez as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 159 +++++++++++++------------- 2 files changed, 89 insertions(+), 79 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index a0757f1e2ba..476f266ce6d 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8131,6 +8131,15 @@ "contributions": [ "bug" ] + }, + { + "login": "pkernevez", + "name": "Kernevez", + "avatar_url": "https://avatars.githubusercontent.com/u/338699?v=4", + "profile": "https://github.com/pkernevez", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 4de08edd91f..2b80701a6d3 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -443,712 +443,713 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + From 4f251d43def1a38a1cdf87e6d3bfe10b258dbe3a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Jun 2025 14:22:21 +0200 Subject: [PATCH 0992/1962] Bump the all-gems group across 2 directories with 3 updates (#5778) Bumps the all-gems group with 2 updates in the /.ci/files directory: [base64](https://github.com/ruby/base64) and [bigdecimal](https://github.com/ruby/bigdecimal). Bumps the all-gems group with 2 updates in the /docs directory: [csv](https://github.com/ruby/csv) and [bigdecimal](https://github.com/ruby/bigdecimal). Updates `base64` from 0.2.0 to 0.3.0 - [Release notes](https://github.com/ruby/base64/releases) - [Commits](https://github.com/ruby/base64/compare/v0.2.0...v0.3.0) Updates `bigdecimal` from 3.1.9 to 3.2.1 - [Release notes](https://github.com/ruby/bigdecimal/releases) - [Changelog](https://github.com/ruby/bigdecimal/blob/master/CHANGES.md) - [Commits](https://github.com/ruby/bigdecimal/compare/v3.1.9...v3.2.1) Updates `csv` from 3.3.4 to 3.3.5 - [Release notes](https://github.com/ruby/csv/releases) - [Changelog](https://github.com/ruby/csv/blob/main/NEWS.md) - [Commits](https://github.com/ruby/csv/compare/v3.3.4...v3.3.5) Updates `bigdecimal` from 3.1.9 to 3.2.1 - [Release notes](https://github.com/ruby/bigdecimal/releases) - [Changelog](https://github.com/ruby/bigdecimal/blob/master/CHANGES.md) - [Commits](https://github.com/ruby/bigdecimal/compare/v3.1.9...v3.2.1) --- updated-dependencies: - dependency-name: base64 dependency-version: 0.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: all-gems - dependency-name: bigdecimal dependency-version: 3.2.1 dependency-type: indirect update-type: version-update:semver-minor dependency-group: all-gems - dependency-name: csv dependency-version: 3.3.5 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all-gems - dependency-name: bigdecimal dependency-version: 3.2.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: all-gems ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .ci/files/Gemfile.lock | 4 ++-- docs/Gemfile.lock | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.ci/files/Gemfile.lock b/.ci/files/Gemfile.lock index 8d3b87d7eb2..01f30141368 100644 --- a/.ci/files/Gemfile.lock +++ b/.ci/files/Gemfile.lock @@ -1,8 +1,8 @@ GEM remote: https://rubygems.org/ specs: - base64 (0.2.0) - bigdecimal (3.1.9) + base64 (0.3.0) + bigdecimal (3.2.1) concurrent-ruby (1.3.5) differ (0.1.2) et-orbi (1.2.11) diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index c48e4cfd195..6c377760453 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -18,7 +18,7 @@ GEM public_suffix (>= 2.0.2, < 7.0) base64 (0.2.0) benchmark (0.4.0) - bigdecimal (3.1.9) + bigdecimal (3.2.1) coffee-script (2.4.1) coffee-script-source execjs @@ -27,7 +27,7 @@ GEM commonmarker (0.23.11) concurrent-ruby (1.3.5) connection_pool (2.5.2) - csv (3.3.4) + csv (3.3.5) dnsruby (1.72.4) base64 (~> 0.2.0) logger (~> 1.6.5) From ee43313b9cdf2f34c31a8fc39259a8f3c5eca686 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Jun 2025 14:22:42 +0200 Subject: [PATCH 0993/1962] Bump org.codehaus.mojo:exec-maven-plugin from 3.5.0 to 3.5.1 (#5779) Bumps [org.codehaus.mojo:exec-maven-plugin](https://github.com/mojohaus/exec-maven-plugin) from 3.5.0 to 3.5.1. - [Release notes](https://github.com/mojohaus/exec-maven-plugin/releases) - [Commits](https://github.com/mojohaus/exec-maven-plugin/compare/3.5.0...3.5.1) --- updated-dependencies: - dependency-name: org.codehaus.mojo:exec-maven-plugin dependency-version: 3.5.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5875b782f6e..7992b9044ce 100644 --- a/pom.xml +++ b/pom.xml @@ -380,7 +380,7 @@ org.codehaus.mojo exec-maven-plugin - 3.5.0 + 3.5.1 org.apache.maven.plugins From 43831c041a661738666acd43cf7723d6bc00d53c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Jun 2025 14:23:14 +0200 Subject: [PATCH 0994/1962] Bump org.apache.maven.plugins:maven-clean-plugin from 3.4.1 to 3.5.0 (#5780) Bumps [org.apache.maven.plugins:maven-clean-plugin](https://github.com/apache/maven-clean-plugin) from 3.4.1 to 3.5.0. - [Release notes](https://github.com/apache/maven-clean-plugin/releases) - [Commits](https://github.com/apache/maven-clean-plugin/compare/maven-clean-plugin-3.4.1...maven-clean-plugin-3.5.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-clean-plugin dependency-version: 3.5.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7992b9044ce..13b08598a0e 100644 --- a/pom.xml +++ b/pom.xml @@ -198,7 +198,7 @@ org.apache.maven.plugins maven-clean-plugin - 3.4.1 + 3.5.0 From 3f7ccd7f5b5b2d5f455e254895a8a04881cf294e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Jun 2025 14:23:39 +0200 Subject: [PATCH 0995/1962] Bump com.google.protobuf:protobuf-java from 4.31.0 to 4.31.1 (#5781) Bumps [com.google.protobuf:protobuf-java](https://github.com/protocolbuffers/protobuf) from 4.31.0 to 4.31.1. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl) - [Commits](https://github.com/protocolbuffers/protobuf/compare/v4.31.0...v4.31.1) --- updated-dependencies: - dependency-name: com.google.protobuf:protobuf-java dependency-version: 4.31.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 13b08598a0e..be667598a19 100644 --- a/pom.xml +++ b/pom.xml @@ -1105,7 +1105,7 @@ com.google.protobuf protobuf-java - 4.31.0 + 4.31.1 +* [#5738](https://github.com/pmd/pmd/pull/5738): chore: Remove unused private methods in test classes - [Pankraz76](https://github.com/Pankraz76) (@Pankraz76) ### ๐Ÿ“ฆ Dependency updates From 09203c20283e2021903f5e3d0f10302643a49fb2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 9 Jun 2025 11:13:18 +0200 Subject: [PATCH 1011/1962] Fix #5788: [apex] ApexCRUDViolation - consider deeper nested Soql --- docs/pages/release_notes.md | 2 ++ .../rule/security/ApexCRUDViolationRule.java | 8 ++++---- .../rule/security/xml/ApexCRUDViolation.xml | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 25ace786e57..15b20b1a2e1 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,6 +25,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* apex-security + * [#5788](https://github.com/pmd/pmd/issues/5788): \[apex] ApexCRUDViolation unable to detect insecure SOQL if it is a direct input argument ### ๐Ÿšจ API Changes diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexCRUDViolationRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexCRUDViolationRule.java index 21257734fea..8b39e0d7ca2 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexCRUDViolationRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexCRUDViolationRule.java @@ -327,7 +327,7 @@ public Object visit(ASTDmlMergeStatement node, Object data) { @Override public Object visit(final ASTAssignmentExpression node, Object data) { - final ASTSoqlExpression soql = node.firstChild(ASTSoqlExpression.class); + final ASTSoqlExpression soql = node.descendants(ASTSoqlExpression.class).first(); if (soql != null) { checkForAccessibility(soql, data); } @@ -340,7 +340,7 @@ public Object visit(final ASTVariableDeclaration node, Object data) { String type = node.getType(); addVariableToMapping(Helper.getFQVariableName(node), type); - final ASTSoqlExpression soql = node.firstChild(ASTSoqlExpression.class); + final ASTSoqlExpression soql = node.descendants(ASTSoqlExpression.class).first(); if (soql != null) { checkForAccessibility(soql, data); } @@ -363,7 +363,7 @@ public Object visit(final ASTFieldDeclaration node, Object data) { String namesString = field.getTypeName(); addVariableToMapping(Helper.getFQVariableName(node), namesString); } - final ASTSoqlExpression soql = node.firstChild(ASTSoqlExpression.class); + final ASTSoqlExpression soql = node.descendants(ASTSoqlExpression.class).first(); if (soql != null) { checkForAccessibility(soql, data); } @@ -373,7 +373,7 @@ public Object visit(final ASTFieldDeclaration node, Object data) { @Override public Object visit(final ASTReturnStatement node, Object data) { - final ASTSoqlExpression soql = node.firstChild(ASTSoqlExpression.class); + final ASTSoqlExpression soql = node.descendants(ASTSoqlExpression.class).first(); if (soql != null) { checkForAccessibility(soql, data); } diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/security/xml/ApexCRUDViolation.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/security/xml/ApexCRUDViolation.xml index ef3dbb3681f..7be5f9902e0 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/security/xml/ApexCRUDViolation.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/security/xml/ApexCRUDViolation.xml @@ -1878,6 +1878,24 @@ public class Foo { return accounts; } } +]]> + + + + [apex] ApexCRUDViolation unable to detect insecure SOQL if it is a direct input argument #5788 + 1 + 4 + mapOfAccounts; + mapOfAccounts = new Map([ // line 4 + SELECT Id, Name + FROM Account + WHERE Id IN :setOfAccountId + ]); + } +} ]]> From 2827c59344fa9600cd9296232a38861823b72bee Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 9 Jun 2025 11:49:36 +0200 Subject: [PATCH 1012/1962] Fix #5785: [java] UnusedPrivateField should ignore SuppressWarnings --- docs/pages/release_notes.md | 2 ++ .../bestpractices/UnusedPrivateFieldRule.java | 3 +- .../bestpractices/xml/UnusedPrivateField.xml | 28 +++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 25ace786e57..5e0629f66ef 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,6 +25,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* java-bestpractices + * [#5785](https://github.com/pmd/pmd/issues/5785): \[java] UnusedPrivateField doesn't play well with UnnecessaryWarningSuppression ### ๐Ÿšจ API Changes diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateFieldRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateFieldRule.java index 3bfa3226e98..21ddd90a574 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateFieldRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateFieldRule.java @@ -75,7 +75,8 @@ private boolean isOK(ASTFieldDeclaration field) { } private boolean hasAnyAnnotation(Annotatable node) { - NodeStream declaredAnnotations = node.getDeclaredAnnotations(); + NodeStream declaredAnnotations = node.getDeclaredAnnotations() + .filterNot(a -> TypeTestUtil.isA(SuppressWarnings.class, a)); for (String reportAnnotation : getProperty(REPORT_FOR_ANNOTATIONS_DESCRIPTOR)) { for (ASTAnnotation annotation: declaredAnnotations) { if (TypeTestUtil.isA(reportAnnotation, annotation)) { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml index 30ed1b84508..70a5c527016 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml @@ -875,6 +875,34 @@ public class Board { return Board.length; } } +]]> + + + + [java] UnusedPrivateField doesn't play well with UnnecessaryWarningSuppression #5785 - case 1 + 0 + + + + + + + + [java] UnusedPrivateField doesn't play well with UnnecessaryWarningSuppression #5785 - case 2 + 0 + + + + From 699c2f4e84873aeea57b8ffb091887775d067baa Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 9 Jun 2025 12:52:20 +0200 Subject: [PATCH 1013/1962] Refactor CpdAnalysis Only keep a reference to "tokens" as short as needed. Tokens is a huge data structure which contains all tokens from all analyzed files. Avoiding a reference when rendering the report makes is eligible for garbage collection thus freeing up memory when needed. --- .../net/sourceforge/pmd/cpd/CpdAnalysis.java | 95 +++++++++++-------- 1 file changed, 58 insertions(+), 37 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java index f7d0b377cf2..acd2b7a5e1f 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java @@ -9,6 +9,7 @@ import java.nio.charset.Charset; import java.nio.file.Path; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -75,6 +76,8 @@ public final class CpdAnalysis implements AutoCloseable { private final CPDConfiguration configuration; private final FileCollector files; private final PmdReporter reporter; + private final Map numberOfTokensPerFile = new HashMap<>(); + private final List processingErrors = new ArrayList<>(); private final @Nullable CPDReportRenderer renderer; private @NonNull CPDListener listener = new CPDNullListener(); @@ -152,53 +155,18 @@ public void performAnalysis() { performAnalysis(r -> { }); } - @SuppressWarnings("PMD.CloseResource") public void performAnalysis(Consumer consumer) { - try (SourceManager sourceManager = new SourceManager(files.getCollectedFiles())) { if (sourceManager.isEmpty()) { reporter.warn("No files to analyze. Check input paths and exclude parameters, use --debug to see file collection traces."); } - Map tokenizers = - sourceManager.getTextFiles().stream() - .map(it -> it.getLanguageVersion().getLanguage()) - .distinct() - .filter(it -> it instanceof CpdCapableLanguage) - .collect(Collectors.toMap(lang -> lang, lang -> ((CpdCapableLanguage) lang).createCpdLexer(configuration.getLanguageProperties(lang)))); - - Map numberOfTokensPerFile = new HashMap<>(); - - List processingErrors = new ArrayList<>(); - Tokens tokens = new Tokens(); - for (TextFile textFile : sourceManager.getTextFiles()) { - TextDocument textDocument = sourceManager.get(textFile); - Tokens.State savedState = tokens.savePoint(); - try { - int newTokens = doTokenize(textDocument, tokenizers.get(textFile.getLanguageVersion().getLanguage()), tokens); - numberOfTokensPerFile.put(textDocument.getFileId(), newTokens); - listener.addedFile(1); - } catch (IOException | FileAnalysisException e) { - if (e instanceof FileAnalysisException) { // NOPMD - ((FileAnalysisException) e).setFileId(textFile.getFileId()); - } - String message = configuration.isSkipLexicalErrors() ? "Skipping file" : "Error while tokenizing"; - reporter.errorEx(message, e); - processingErrors.add(new Report.ProcessingError(e, textFile.getFileId())); - savedState.restore(tokens); - } - } - if (!processingErrors.isEmpty() && !configuration.isSkipLexicalErrors()) { + List matches = findMatches(sourceManager); + if (shouldAbortEarlyBecauseOfProcessingErrors()) { reporter.error("Errors were detected while lexing source, exiting because --skip-lexical-errors is unset."); return; } - LOGGER.debug("Running match algorithm on {} files...", sourceManager.size()); - MatchAlgorithm matchAlgorithm = new MatchAlgorithm(tokens, configuration.getMinimumTileSize()); - List matches = matchAlgorithm.findMatches(listener, sourceManager); - tokens = null; // null it out before rendering, might help gc - LOGGER.debug("Finished: {} duplicates found", matches.size()); - CPDReport cpdReport = new CPDReport(sourceManager, matches, numberOfTokensPerFile, processingErrors); if (renderer != null) { @@ -216,6 +184,59 @@ public void performAnalysis(Consumer consumer) { // source manager is closed and closes all text files now. } + private boolean shouldAbortEarlyBecauseOfProcessingErrors() { + return !processingErrors.isEmpty() && !configuration.isSkipLexicalErrors(); + } + + private List findMatches(SourceManager sourceManager) { + // Note: tokens contains all tokens of all analyzed files which is a huge data structure. + // The tokens are only needed for finding the matches and can be garbage collected afterwards. + // The report only needs the matches. Especially, the tokens are only referenced here and in + // matchAlgorithm. When this method finishes, tokens should be eligible for garbage collection + // making it possible to free up memory for render the report if needed. + + Tokens tokens = tokenizeFiles(sourceManager); + if (shouldAbortEarlyBecauseOfProcessingErrors()) { + return Collections.emptyList(); + } + + LOGGER.debug("Running match algorithm on {} files...", sourceManager.size()); + MatchAlgorithm matchAlgorithm = new MatchAlgorithm(tokens, configuration.getMinimumTileSize()); + List matches = matchAlgorithm.findMatches(listener, sourceManager); + LOGGER.debug("Finished: {} duplicates found", matches.size()); + return matches; + } + + @SuppressWarnings("PMD.CloseResource") + // TextFiles and TextDocuments are managed by sourceManager, which closes all text files in the end. + private Tokens tokenizeFiles(SourceManager sourceManager) { + Map tokenizers = + sourceManager.getTextFiles().stream() + .map(it -> it.getLanguageVersion().getLanguage()) + .distinct() + .filter(it -> it instanceof CpdCapableLanguage) + .collect(Collectors.toMap(lang -> lang, lang -> ((CpdCapableLanguage) lang).createCpdLexer(configuration.getLanguageProperties(lang)))); + + Tokens tokens = new Tokens(); + for (TextFile textFile : sourceManager.getTextFiles()) { + TextDocument textDocument = sourceManager.get(textFile); + Tokens.State savedState = tokens.savePoint(); + try { + int newTokens = doTokenize(textDocument, tokenizers.get(textFile.getLanguageVersion().getLanguage()), tokens); + numberOfTokensPerFile.put(textDocument.getFileId(), newTokens); + listener.addedFile(1); + } catch (IOException | FileAnalysisException e) { + if (e instanceof FileAnalysisException) { // NOPMD + ((FileAnalysisException) e).setFileId(textFile.getFileId()); + } + String message = configuration.isSkipLexicalErrors() ? "Skipping file" : "Error while tokenizing"; + reporter.errorEx(message, e); + processingErrors.add(new Report.ProcessingError(e, textFile.getFileId())); + savedState.restore(tokens); + } + } + return tokens; + } @Override public void close() throws IOException { From 810b0fcbcf16787a86607329b4269ceec83f7373 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 15 May 2025 19:12:43 +0200 Subject: [PATCH 1014/1962] [ci] New "Publish Release" workflow --- .github/workflows/build-release.yml | 12 + .github/workflows/old-build.yml | 3 - .github/workflows/publish-release.yml | 525 ++++++++++++++++++ .../pmd/devdocs/github_actions_workflows.md | 14 +- 4 files changed, 549 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/build-release.yml create mode 100644 .github/workflows/publish-release.yml diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml new file mode 100644 index 00000000000..94f4dc9ed1c --- /dev/null +++ b/.github/workflows/build-release.yml @@ -0,0 +1,12 @@ +name: Build Release + +on: + push: + tags: + - '**' + workflow_dispatch: + +jobs: + build: + name: Build Release + uses: ./.github/workflows/build.yml diff --git a/.github/workflows/old-build.yml b/.github/workflows/old-build.yml index 23f5604fafb..c7329fc0e1b 100644 --- a/.github/workflows/old-build.yml +++ b/.github/workflows/old-build.yml @@ -1,9 +1,6 @@ name: old-build on: - push: - tags: - - '**' workflow_dispatch: inputs: build_cli_dist_only: diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml new file mode 100644 index 00000000000..836f8c1c545 --- /dev/null +++ b/.github/workflows/publish-release.yml @@ -0,0 +1,525 @@ +name: Publish Release + +on: + workflow_run: + workflows: [Build Release] + types: + - completed + branches: + - '**' + workflow_dispatch: + inputs: + build_cli_dist_only: + description: "Build only modules cli and dist" + required: true + type: boolean + default: false + +permissions: + contents: read # to fetch code (actions/checkout) + +env: + LANG: 'en_US.UTF-8' + +jobs: + check-version: + # only run in the official pmd/pmd repo, where we have access to the secrets and not on forks + # and only run for _successful_ push workflow runs on tags. + if: ${{ github.repository == 'pmd/pmd' + && contains(fromJSON('["push", "workflow_dispatch"]'), github.event.workflow_run.event) + && github.event.workflow_run.head_branch != main + && github.event.workflow_run.conclusion == 'success' }} + runs-on: ubuntu-latest + timeout-minutes: 10 + defaults: + run: + shell: bash + outputs: + PMD_VERSION: ${{ steps.version.outputs.PMD_VERSION }} + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.workflow_run.head_branch }} + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '11' + cache: 'maven' + - name: Determine Version + id: version + env: + REF: ${{ github.event.workflow_run.head_branch }} + run: | + if ! git show-ref --exists "refs/tags/$REF"; then + echo "::error ::Tag $REF does not exist, aborting." + exit 1 + fi + + PMD_VERSION=$(./mvnw --batch-mode --no-transfer-progress help:evaluate -Dexpression=project.version -q -DforceStdout) + echo "Determined PMD_VERSION=$PMD_VERSION" + if [[ "$PMD_VERSION" = *-SNAPSHOT ]]; then + echo "::error ::PMD_VERSION=$PMD_VERSION is a snapshot version, aborting." + exit 1 + fi + echo "PMD_VERSION=$PMD_VERSION" >> "$GITHUB_OUTPUT" + - name: Add Job Summary + env: + WORKFLOW_RUN_DISPLAY_TITLE: ${{ github.event.workflow_run.display_title }} + WORKFLOW_RUN_NAME: ${{ github.event.workflow_run.name }} + WORKFLOW_RUN_NUMBER: ${{ github.event.workflow_run.run_number }} + WORKFLOW_RUN_HTML_URL: ${{ github.event.workflow_run.html_url }} + VERSION: ${{ steps.version.outputs.PMD_VERSION }} + TAG: ${{ github.event.workflow_run.head_branch }} + run: | + echo "### Run Info" >> "${GITHUB_STEP_SUMMARY}" + echo "Building Version: ${VERSION}" >> "${GITHUB_STEP_SUMMARY}" + echo "" >> "${GITHUB_STEP_SUMMARY}" + echo "Tag: ${TAG}" >> "${GITHUB_STEP_SUMMARY}" + echo "" >> "${GITHUB_STEP_SUMMARY}" + echo "Called by [${WORKFLOW_RUN_DISPLAY_TITLE} (${WORKFLOW_RUN_NAME} #${WORKFLOW_RUN_NUMBER})](${WORKFLOW_RUN_HTML_URL})" >> "${GITHUB_STEP_SUMMARY}" + echo "" >> "${GITHUB_STEP_SUMMARY}" + + deploy-to-maven-central: + needs: [check-version] + # use environment maven-central, where secrets are configured for OSSRH_* + environment: + name: maven-central + url: https://oss.sonatype.org/content/repositories/snapshots/net/sourceforge/pmd/ + runs-on: ubuntu-latest + timeout-minutes: 20 + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + with: + ref: main + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '11' + server-id: ossrh + server-username: MAVEN_USERNAME + server-password: MAVEN_PASSWORD + gpg-passphrase: MAVEN_GPG_PASSPHRASE + gpg-private-key: ${{ secrets.PMD_CI_GPG_PRIVATE_KEY }} + - uses: actions/download-artifact@v4 + with: + name: compile-artifact + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + - name: Build and publish + env: + MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} + MAVEN_GPG_PASSPHRASE: ${{ secrets.PMD_CI_GPG_PASSPHRASE }} + BUILD_CLI_DIST_ONLY: ${{ inputs.build_cli_dist_only }} + # note: we can't use artifact staging-repository, as the jars are unsigned and javadoc+sources are missing. + run: | + # make sure, BUILD_CLI_DIST_ONLY is set to false by default + : "${BUILD_CLI_DIST_ONLY:=false}" + echo "BUILD_CLI_DIST_ONLY=${BUILD_CLI_DIST_ONLY}" + # There are two possible release builds: + if [ "${BUILD_CLI_DIST_ONLY}" = "false" ]; then + # a) everything without pmd-cli and pmd-dist + BUILD_CLI_DIST_MAVEN_OPTION="-Dskip-cli-dist" + else + # b) only pmd-cli and pmd-dist + BUILD_CLI_DIST_MAVEN_OPTION="-pl pmd-cli,pmd-dist" + fi + + ./mvnw --show-version --errors --batch-mode \ + deploy \ + -DskipTests \ + ${BUILD_CLI_DIST_MAVEN_OPTION} \ + -PfastSkip,sign,pmd-release -Dcyclonedx.skip=false + + deploy-to-sourceforge-files: + needs: [check-version, deploy-to-maven-central] + if: ${{ inputs.build_cli_dist_only == true }} + # use environment sourceforge, where secrets/vars are configured for PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY + # and PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS and PMD_SF_APIKEY + environment: + name: sourceforge + url: ${{ steps.upload.outputs.url_output }} + runs-on: ubuntu-latest + timeout-minutes: 10 + defaults: + run: + shell: bash + steps: + - uses: actions/download-artifact@v4 + with: + name: dist-artifact + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + path: dist + + - uses: actions/download-artifact@v4 + with: + name: docs-artifact + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + path: docs + + - name: Setup GPG + env: + PMD_CI_GPG_PRIVATE_KEY: ${{ secrets.PMD_CI_GPG_PRIVATE_KEY }} + run: | + mkdir -p "${HOME}/.gpg" + chmod 700 "${HOME}/.gpg" + printenv PMD_CI_GPG_PRIVATE_KEY | gpg --batch --import + + gpg --list-keys --fingerprint --keyid-format=long + gpg --list-secret-keys --fingerprint --keyid-format=long + + - name: Setup ssh key for sourceforge + env: + WEB_SF_DEPLOY_KEY: ${{ secrets.PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY }} + WEB_SF_KNOWN_HOSTS: ${{ vars.PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS }} + run: | + mkdir -p "${HOME}/.ssh" + chmod 700 "${HOME}/.ssh" + printenv WEB_SF_DEPLOY_KEY > "${HOME}/.ssh/web.sourceforge.net_deploy_key" + chmod 600 "${HOME}/.ssh/web.sourceforge.net_deploy_key" + echo " + Host web.sourceforge.net + IdentityFile=$HOME/.ssh/web.sourceforge.net_deploy_key + " > "$HOME/.ssh/config" + echo "${WEB_SF_KNOWN_HOSTS}" > "$HOME/.ssh/known_hosts" + + - name: Create docs zip + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + run: | + mv docs "pmd-doc-${PMD_VERSION}" + zip -qr "dist/pmd-dist-${PMD_VERSION}-doc.zip" "pmd-doc-${PMD_VERSION}/" + + - name: Sign files + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + MAVEN_GPG_PASSPHRASE: ${{ secrets.PMD_CI_GPG_PASSPHRASE }} + run: | + cd dist + printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ + --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-bin.zip" + printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ + --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-src.zip" + printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ + --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-doc.zip" + + - name: Upload to sourceforge + id: upload + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + PMD_SF_USER: adangel + run: | + # Deploy to sourceforge files https://sourceforge.net/projects/pmd/files/pmd/ + basePath="pmd/${PMD_VERSION}" + uploadUrl="${PMD_SF_USER}@web.sourceforge.net:/home/frs/project/pmd/${basePath}/" + + rsync -avh "dist/pmd-dist-${PMD_VERSION}-bin.zip" "${uploadUrl}" + rsync -avh "dist/pmd-dist-${PMD_VERSION}-bin.zip.asc" "${uploadUrl}" + rsync -avh "dist/pmd-dist-${PMD_VERSION}-src.zip" "${uploadUrl}" + rsync -avh "dist/pmd-dist-${PMD_VERSION}-src.zip.asc" "${uploadUrl}" + rsync -avh "dist/pmd-dist-${PMD_VERSION}-doc.zip" "${uploadUrl}" + rsync -avh "dist/pmd-dist-${PMD_VERSION}-doc.zip.asc" "${uploadUrl}" + rsync -avh "dist/pmd-${PMD_VERSION}-cyclonedx.xml" "${uploadUrl}" + rsync -avh "dist/pmd-${PMD_VERSION}-cyclonedx.json" "${uploadUrl}" + rsync -avh "pmd-doc-${PMD_VERSION}/pmd_release_notes.md" "${uploadUrl}/ReadMe.md" + + targetUrl="https://sourceforge.net/projects/pmd/files/${basePath}" + echo "TargetUrl: ${targetUrl}" + echo "url_output=${targetUrl}" >> "$GITHUB_OUTPUT" + + - name: Select latest release as default on sourceforge + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + PMD_SF_APIKEY: ${{ secrets.PMD_SF_APIKEY }} + run: | + # + # Select the given version as the new default download. + # + # https://sourceforge.net/p/forge/documentation/Using%20the%20Release%20API/ + # https://sourceforge.net/projects/pmd/best_release.json + # + curl -H "Accept: application/json" \ + -X PUT \ + -d "api_key=${PMD_SF_APIKEY}" \ + -d "default=windows&default=mac&default=linux&default=bsd&default=solaris&default=others" \ + "https://sourceforge.net/projects/pmd/files/pmd/${PMD_VERSION}/pmd-dist-${PMD_VERSION}-bin.zip" + + - name: Cleanup ssh and gpg + if: ${{ always() }} + run: | + rm -rf "${HOME}/.ssh" + rm -rf "${HOME}/.gpg" + + deploy-to-sourceforge-io: + needs: [check-version, deploy-to-maven-central] + if: ${{ inputs.build_cli_dist_only == true }} + # use environment sourceforge, where secrets/vars are configured for PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY + # and PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS + environment: + name: sourceforge + url: ${{ steps.upload.outputs.url_output }} + runs-on: ubuntu-latest + timeout-minutes: 10 + defaults: + run: + shell: bash + steps: + - uses: actions/download-artifact@v4 + with: + name: docs-artifact + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + path: docs + + - name: Setup ssh key for sourceforge + env: + WEB_SF_DEPLOY_KEY: ${{ secrets.PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY }} + WEB_SF_KNOWN_HOSTS: ${{ vars.PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS }} + run: | + mkdir -p "${HOME}/.ssh" + chmod 700 "${HOME}/.ssh" + printenv WEB_SF_DEPLOY_KEY > "${HOME}/.ssh/web.sourceforge.net_deploy_key" + chmod 600 "${HOME}/.ssh/web.sourceforge.net_deploy_key" + echo " + Host web.sourceforge.net + IdentityFile=$HOME/.ssh/web.sourceforge.net_deploy_key + " > "$HOME/.ssh/config" + echo "${WEB_SF_KNOWN_HOSTS}" > "$HOME/.ssh/known_hosts" + + - name: Upload to sourceforge + id: upload + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + PMD_SF_USER: adangel + run: | + rsync -ah --stats --delete "docs/" "${PMD_SF_USER}@web.sourceforge.net:/home/project-web/pmd/htdocs/pmd-${PMD_VERSION}/" + echo "url_output=https://pmd.sourceforge.io/pmd-${PMD_VERSION}/" >> "$GITHUB_OUTPUT" + + - name: Cleanup ssh + if: ${{ always() }} + run: | + rm -rf "${HOME}/.ssh" + + deploy-to-pmd-code-doc: + needs: [check-version, deploy-to-maven-central] + if: ${{ inputs.build_cli_dist_only == true }} + # use environment pmd-code, where secrets/vars are configured for PMD_CODE_ORG_DEPLOY_KEY + # and PMD_CODE_ORG_KNOWN_HOSTS + environment: + name: pmd-code + url: ${{ steps.upload.outputs.url_output }} + runs-on: ubuntu-latest + timeout-minutes: 10 + defaults: + run: + shell: bash + steps: + - uses: actions/download-artifact@v4 + with: + name: docs-artifact + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + path: docs + + - name: Setup ssh key for pmd-code + env: + PMD_CODE_ORG_DEPLOY_KEY: ${{ secrets.PMD_CODE_ORG_DEPLOY_KEY }} + PMD_CODE_ORG_KNOWN_HOSTS: ${{ vars.PMD_CODE_ORG_KNOWN_HOSTS }} + run: | + mkdir -p "${HOME}/.ssh" + chmod 700 "${HOME}/.ssh" + printenv PMD_CODE_ORG_DEPLOY_KEY > "${HOME}/.ssh/pmd-code.org_deploy_key" + chmod 600 "${HOME}/.ssh/pmd-code.org_deploy_key" + echo " + Host pmd-code.org + IdentityFile=$HOME/.ssh/pmd-code.org_deploy_key + " > "$HOME/.ssh/config" + echo "${PMD_CODE_ORG_KNOWN_HOSTS}" > "$HOME/.ssh/known_hosts" + + - name: Create docs zip + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + run: | + mv docs "pmd-doc-${PMD_VERSION}" + zip -qr "pmd-dist-${PMD_VERSION}-doc.zip" "pmd-doc-${PMD_VERSION}/" + + - name: Upload to pmd-code.org + id: upload + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + PMD_CODE_SSH_USER: pmd + PMD_CODE_DOCS_PATH: /docs.pmd-code.org/ + run: | + filename="pmd-dist-${PMD_VERSION}-doc.zip" + + scp "${filename}" ${PMD_CODE_SSH_USER}@pmd-code.org:${PMD_CODE_DOCS_PATH} + # shellcheck disable=SC2029 + ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \ + ( test -h pmd-doc-${PMD_VERSION} && rm pmd-doc-${PMD_VERSION} || true ) && \ + unzip -qo \"${filename}\" && \ + rm \"${filename}\"" + + # only for release builds: https://docs.pmd-code.org/latest -> pmd-doc-${PMD_VERSION} + # shellcheck disable=SC2029 + ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \ + rm -f \"latest\" && \ + ln -s \"pmd-doc-${PMD_VERSION}\" \"snapshot\"" + + targetUrl="https://docs.pmd-code.org/pmd-doc-${PMD_VERSION}/" + echo "TargetUrl: ${targetUrl}" + echo "url_output=${targetUrl}" >> "$GITHUB_OUTPUT" + + # remove old snapshot doc and point to the new version + # shellcheck disable=SC2029 + ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \ + rm -rf \"pmd-doc-${PMD_VERSION}-SNAPSHOT/\" && \ + ln -s \"pmd-doc-${PMD_VERSION}\" \"pmd-doc-${PMD_VERSION}-SNAPSHOT\"" + echo "Symlink created: https://docs.pmd-code.org/pmd-doc-${PMD_VERSION}-SNAPSHOT/ -> https://docs.pmd-code.org/pmd-doc-${PMD_VERSION}/" + + - name: Cleanup ssh + if: ${{ always() }} + run: | + rm -rf "${HOME}/.ssh" + + deploy-to-pmd-code-javadoc: + needs: [check-version, deploy-to-maven-central] + if: ${{ inputs.build_cli_dist_only == true }} + # use environment pmd-code, where secrets/vars are configured for PMD_CODE_ORG_DEPLOY_KEY + # and PMD_CODE_ORG_KNOWN_HOSTS + environment: + name: pmd-code + url: https://docs.pmd-code.org/apidocs/ + runs-on: ubuntu-latest + timeout-minutes: 10 + defaults: + run: + shell: bash + steps: + - uses: actions/download-artifact@v4 + with: + name: javadocs-artifact + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + + - name: Setup ssh key for pmd-code + env: + PMD_CODE_ORG_DEPLOY_KEY: ${{ secrets.PMD_CODE_ORG_DEPLOY_KEY }} + PMD_CODE_ORG_KNOWN_HOSTS: ${{ vars.PMD_CODE_ORG_KNOWN_HOSTS }} + run: | + mkdir -p "${HOME}/.ssh" + chmod 700 "${HOME}/.ssh" + printenv PMD_CODE_ORG_DEPLOY_KEY > "${HOME}/.ssh/pmd-code.org_deploy_key" + chmod 600 "${HOME}/.ssh/pmd-code.org_deploy_key" + echo " + Host pmd-code.org + IdentityFile=$HOME/.ssh/pmd-code.org_deploy_key + " > "$HOME/.ssh/config" + echo "${PMD_CODE_ORG_KNOWN_HOSTS}" > "$HOME/.ssh/known_hosts" + + - name: Upload javadocs to pmd-code.org + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + PMD_CODE_SSH_USER: pmd + PMD_CODE_DOCS_PATH: /docs.pmd-code.org/ + run: | + for moduleJavadocJar in */target/*-javadoc.jar */*/target/*-javadoc.jar; do + moduleJavadocJarBasename="$(basename "$moduleJavadocJar")" + module=${moduleJavadocJarBasename%%-${PMD_VERSION}-javadoc.jar} + + echo "Copying module ${moduleJavadocJar}..." + scp "$moduleJavadocJar" ${PMD_CODE_SSH_USER}@pmd-code.org:${PMD_CODE_DOCS_PATH} + echo "Extracting remotely ${module}..." + # shellcheck disable=SC2029 + ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \ + mkdir -p \"apidocs/${module}/${PMD_VERSION}\" && \ + unzip -qo -d \"apidocs/${module}/${PMD_VERSION}\" \"${moduleJavadocJarBasename}\" && \ + rm \"${moduleJavadocJarBasename}\"" + done + + # remove old snapshot javadoc + # shellcheck disable=SC2029 + ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \ + rm -rf apidocs/*/\"${PMD_VERSION}-SNAPSHOT\"" + + echo "(Re)creating .htaccess" + # make sure https://docs.pmd-code.org/apidocs/ shows directory index + # shellcheck disable=SC2029 + ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}/apidocs\" && \ + echo 'Options +Indexes' > .htaccess" + + - name: Cleanup ssh + if: ${{ always() }} + run: | + rm -rf "${HOME}/.ssh" + + github-release: + # github release only for releases + pmd_ci_gh_releases_updateRelease "$GH_RELEASE" "$release_name" "${rendered_release_notes}" + # Deploy to github releases + pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip" + pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-src.zip" + # Deploy SBOM + pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.xml" + pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.json" + # Deploy signatures + pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip.asc" + pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-src.zip.asc" + + pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "docs/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-doc.zip" + pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "docs/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-doc.zip.asc" + + create-sourceforge-blog-post: + local rendered_release_notes_with_links + rendered_release_notes_with_links=" + * Downloads: https://github.com/pmd/pmd/releases/tag/pmd_releases%2F${PMD_CI_MAVEN_PROJECT_VERSION} + * Documentation: https://docs.pmd-code.org/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}/ + + ${rendered_release_notes}" + pmd_ci_sourceforge_createDraftBlogPost "${release_name} released" "${rendered_release_notes_with_links}" "pmd,release" + SF_BLOG_URL="${RESULT}" + + create-regression-tester-baseline: + # create a baseline for snapshot builds (when pmd-dist is built) + # or for release builds for case b) when pmd-cli/pmd-dist is released + if pmd_ci_maven_isSnapshotBuild || [ "${BUILD_CLI_DIST_ONLY}" = "true" ]; then + pmd_ci_log_group_start "Creating new baseline for regression tester" + regression_tester_setup_ci + regression_tester_uploadBaseline + pmd_ci_log_group_end + fi + + create-docker: + # Trigger docker workflow to build new images for release builds + # but only for case b) pmd-cli/pmd-dist release + if pmd_ci_maven_isReleaseBuild && [ "${BUILD_CLI_DIST_ONLY}" = "true" ]; then + pmd_ci_log_group_start "Trigger docker workflow" + # split semantic version by dot + IFS="." read -ra VERSION_ARRAY <<< "${PMD_CI_MAVEN_PROJECT_VERSION}" + all_tags="" + new_tag="" + for i in "${VERSION_ARRAY[@]}"; do + if [ -z "$new_tag" ]; then + new_tag="${i}" + else + new_tag="${new_tag}.${i}" + fi + all_tags="${all_tags}${new_tag}," + done + all_tags="${all_tags}latest" + echo "version: ${PMD_CI_MAVEN_PROJECT_VERSION}" + echo "tags: ${all_tags}" + + GH_TOKEN="${PMD_ACTIONS_HELPER_TOKEN}" \ + gh api \ + --method POST \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + /repos/pmd/docker/actions/workflows/publish-docker-image.yaml/dispatches \ + -f "ref=main" -f "inputs[version]=${PMD_CI_MAVEN_PROJECT_VERSION}" -f "inputs[tags]=${all_tags}" + pmd_ci_log_group_end + fi diff --git a/docs/pages/pmd/devdocs/github_actions_workflows.md b/docs/pages/pmd/devdocs/github_actions_workflows.md index 3c141babd14..520714ed2c9 100644 --- a/docs/pages/pmd/devdocs/github_actions_workflows.md +++ b/docs/pages/pmd/devdocs/github_actions_workflows.md @@ -10,18 +10,20 @@ last_updated: May 2025 (7.14.0) {%include note.html content="This page is work in progress and does not yet describe all workflows."%} -## Build, Build Pull Request, Build Snapshot +## Build, Build Pull Request, Build Snapshot, Build Release "Build" itself is a [reuseable workflow](https://docs.github.com/en/actions/sharing-automations/reusing-workflows), -that is called by "Build Pull Request" and "Build Snapshot". +that is called by "Build Pull Request" and "Build Snapshot" and "Build Release". * Workflow files: * * * + * * Builds: * Build Pull Request: * Build Snapshot: + * Build Release: All these workflows execute exactly the same steps. But only the triggering event is different. It is designed to run on the main repository in PMD's GitHub organization as well as for forks, as it does @@ -32,6 +34,8 @@ not require any secrets. "Build Snapshot" is triggered, whenever new commits are pushed to a branch (including the default branch and including forks). +"Build Release" is triggered, whenever a tag is pushed. + In order to avoid unnecessary builds, we use concurrency control to make sure, we cancel any in-progress jobs for the current branch or pull request when a new commit has been pushed. This means, only the latest commit is built, which is enough, since only this will be released or merged in the end. Only the latest build matters. @@ -195,6 +199,12 @@ we are actually building a SNAPSHOT version. Then a couple of other jobs are bei * Environment: coveralls * Secrets: COVERALLS_REPO_TOKEN +## Publish Release + +* Builds: +* Workflow file: + + ## Secrets and Variables The "Build" workflow doesn't need any secrets or additional permissions, it just builds and creates artifacts. This is necessary, so that this workflow can also run on forks, so that contributors can develop in their From 68c8293e5de370fa0c840e3a99531b085e1ff1ab Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Mon, 9 Jun 2025 00:03:29 +0200 Subject: [PATCH 1015/1962] Fix #2304: [java] UnnecessaryImport FP in javadoc for on-demand imports --- .../rule/codestyle/UnnecessaryImportRule.java | 20 +++++++++++++ .../rule/codestyle/xml/UnnecessaryImport.xml | 28 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java index 515035cf624..ea35a5b924a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java @@ -44,6 +44,7 @@ import net.sourceforge.pmd.lang.java.types.OverloadSelectionResult; import net.sourceforge.pmd.lang.java.types.TypeSystem; import net.sourceforge.pmd.lang.java.types.TypeTestUtil; +import net.sourceforge.pmd.lang.java.types.TypesFromReflection; import net.sourceforge.pmd.util.CollectionUtil; /** @@ -208,6 +209,7 @@ private void visitComments(ASTCompilationUnit node) { if (fullname != null) { // may be null for "@see #" and "@link #" removeReferenceSingleImport(fullname); + removeReferenceOnDemandImport(fullname); } if (m.groupCount() > 1) { @@ -436,6 +438,24 @@ private void removeReferenceSingleImport(String referenceName) { allSingleNameImports.removeIf(it -> expectedImport.equals(it.node.getImportedSimpleName())); } + private void removeReferenceOnDemandImport(String referenceName) { + typeImportsOnDemand.removeIf(it -> { + final ASTImportDeclaration importNode = it.node; + return importNode.isImportOnDemand() + && TypesFromReflection.loadSymbol(importNode.getTypeSystem(), importNode.getPackageName() + "." + referenceName) != null; + }); + + staticImportsOnDemand.removeIf(it -> { + final ASTImportDeclaration importNode = it.node; + if (importNode.isImportOnDemand()) { + final JClassSymbol symbol = TypesFromReflection.loadSymbol(importNode.getTypeSystem(), importNode.getImportedName()); + return symbol != null && (symbol.getDeclaredField(referenceName) != null || symbol.getDeclaredClass(referenceName) != null); + } + + return false; + }); + } + /** Override the equal behaviour of ASTImportDeclaration to put it into a set. */ private static final class ImportWrapper { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml index 2029ee1ef65..5e47b32abd2 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml @@ -1357,4 +1357,32 @@ public class C { ]]> + + #2304: [java] static on-demand import in javadoc + 0 + + + + + #2304: [java] on-demand import in javadoc + 0 + + + From 601d2eb8b49e8f7857c35545c0699bf1c8d5c48d Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Mon, 9 Jun 2025 00:05:08 +0200 Subject: [PATCH 1016/1962] #2304: Fix basic method param case --- .../rule/codestyle/UnnecessaryImportRule.java | 1 + .../rule/codestyle/xml/UnnecessaryImport.xml | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java index ea35a5b924a..f770359299d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java @@ -217,6 +217,7 @@ private void visitComments(ASTCompilationUnit node) { if (fullname != null) { for (String param : fullname.split("\\s*,\\s*")) { removeReferenceSingleImport(param); + removeReferenceOnDemandImport(param); } } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml index 5e47b32abd2..583a8e64d5d 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml @@ -1381,6 +1381,22 @@ public class Foo { * {@link ArrayList arraylist} */ public void test() {} +} + ]]> + + + + #2304: [java] on-demand import in javadoc method param + 0 + From 99aafc04ee19444b77825dd2c62b47d851cc440b Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Mon, 9 Jun 2025 15:48:57 +0200 Subject: [PATCH 1017/1962] #2304: Improve handling of static on-demand imports --- .../rule/codestyle/UnnecessaryImportRule.java | 3 +- .../rule/codestyle/xml/UnnecessaryImport.xml | 34 +++++++++++++++++-- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java index f770359299d..35aaaec9d79 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java @@ -445,12 +445,11 @@ private void removeReferenceOnDemandImport(String referenceName) { return importNode.isImportOnDemand() && TypesFromReflection.loadSymbol(importNode.getTypeSystem(), importNode.getPackageName() + "." + referenceName) != null; }); - staticImportsOnDemand.removeIf(it -> { final ASTImportDeclaration importNode = it.node; if (importNode.isImportOnDemand()) { final JClassSymbol symbol = TypesFromReflection.loadSymbol(importNode.getTypeSystem(), importNode.getImportedName()); - return symbol != null && (symbol.getDeclaredField(referenceName) != null || symbol.getDeclaredClass(referenceName) != null); + return symbol != null && (symbol.getSimpleName().equals(referenceName) || symbol.getDeclaredField(referenceName) != null || symbol.getDeclaredClass(referenceName) != null); } return false; diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml index 583a8e64d5d..32a4fd84c76 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml @@ -1358,13 +1358,41 @@ public class C { - #2304: [java] static on-demand import in javadoc + #2304: [java] static on-demand field import in javadoc 0 + + + + #2304: [java] static on-demand method import in javadoc + 0 + + + + + #2304: [java] static on-demand class import in javadoc + 0 + Date: Mon, 9 Jun 2025 15:59:31 +0200 Subject: [PATCH 1018/1962] #2304: Add additional javadoc method param test --- .../rule/codestyle/xml/UnnecessaryImport.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml index 32a4fd84c76..139b4792b23 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml @@ -1425,6 +1425,22 @@ public class Foo { */ public void test() {} +} + ]]> + + + + #2304: [java] static on-demand import in javadoc method param + 0 + From 6184ed54f0e6774be8c250b9670606bf20c3b6ba Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 9 Jun 2025 16:51:05 +0200 Subject: [PATCH 1019/1962] [ci] publish-snapshot.yml: also create sources and javadocs --- .github/workflows/publish-snapshot.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index ee9a1025e31..f7b3e206693 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -110,7 +110,10 @@ jobs: -Dmaven.repo.local=.m2/repository \ deploy \ -DskipTests \ - -PfastSkip,sign,pmd-release -Dcyclonedx.skip=false + -PfastSkip,sign,pmd-release \ + -Dcyclonedx.skip=false \ + -Dmaven.javadoc.skip=false \ + -Dmaven.source.skip=false deploy-to-sourceforge-files: needs: check-version From e2929e92ceb1193bc9aa60a6f17e0ccac6269e33 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 9 Jun 2025 16:51:58 +0200 Subject: [PATCH 1020/1962] [ci] publish-release.yml: use maven central --- .github/workflows/publish-release.yml | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 836f8c1c545..a9830dee37e 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -81,24 +81,24 @@ jobs: deploy-to-maven-central: needs: [check-version] - # use environment maven-central, where secrets are configured for OSSRH_* + # use environment maven-central, where secrets are configured for MAVEN_CENTRAL_PORTAL_* environment: name: maven-central - url: https://oss.sonatype.org/content/repositories/snapshots/net/sourceforge/pmd/ + url: https://repo.maven.apache.org/maven2/net/sourceforge/pmd/ runs-on: ubuntu-latest - timeout-minutes: 20 + timeout-minutes: 40 defaults: run: shell: bash steps: - uses: actions/checkout@v4 with: - ref: main + ref: ${{ github.event.workflow_run.head_branch }} - uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: '11' - server-id: ossrh + server-id: central server-username: MAVEN_USERNAME server-password: MAVEN_PASSWORD gpg-passphrase: MAVEN_GPG_PASSPHRASE @@ -110,8 +110,8 @@ jobs: run-id: ${{ github.event.workflow_run.id }} - name: Build and publish env: - MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} - MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} + MAVEN_USERNAME: ${{ secrets.MAVEN_CENTRAL_PORTAL_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PORTAL_PASSWORD }} MAVEN_GPG_PASSPHRASE: ${{ secrets.PMD_CI_GPG_PASSPHRASE }} BUILD_CLI_DIST_ONLY: ${{ inputs.build_cli_dist_only }} # note: we can't use artifact staging-repository, as the jars are unsigned and javadoc+sources are missing. @@ -127,12 +127,16 @@ jobs: # b) only pmd-cli and pmd-dist BUILD_CLI_DIST_MAVEN_OPTION="-pl pmd-cli,pmd-dist" fi + echo "BUILD_CLI_DIST_MAVEN_OPTION=${BUILD_CLI_DIST_MAVEN_OPTION}" ./mvnw --show-version --errors --batch-mode \ deploy \ -DskipTests \ ${BUILD_CLI_DIST_MAVEN_OPTION} \ - -PfastSkip,sign,pmd-release -Dcyclonedx.skip=false + -PfastSkip,sign,pmd-release \ + -Dcyclonedx.skip=false \ + -Dmaven.javadoc.skip=false \ + -Dmaven.source.skip=false deploy-to-sourceforge-files: needs: [check-version, deploy-to-maven-central] From 19148766978589f65a91baa7407d77f241a4324d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 9 Jun 2025 16:52:22 +0200 Subject: [PATCH 1021/1962] [ci] publish-release.yml: improve apidocs - add SNAPSHOT links - add latest links --- .github/workflows/publish-release.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index a9830dee37e..7a1954acf71 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -449,6 +449,20 @@ jobs: # shellcheck disable=SC2029 ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \ rm -rf apidocs/*/\"${PMD_VERSION}-SNAPSHOT\"" + + # create a symlink from SNAPSHOT to released version + # shellcheck disable=SC2029 + ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \ + for i in apidocs/*/\"${PMD_VERSION}\"; do \ + ln -s \"${PMD_VERSION}\" \"\$i-SNAPSHOT\"; \ + done" + + # (re)create a symlink from latest to released version + # shellcheck disable=SC2029 + ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \ + for i in apidocs/*/\"${PMD_VERSION}\"; do \ + ln -snf \"${PMD_VERSION}\" \"\${i%%${PMD_VERSION}}latest\"; \ + done" echo "(Re)creating .htaccess" # make sure https://docs.pmd-code.org/apidocs/ shows directory index From e928baee108ec1cdb70cc5b2ab6f78c1d1dd10e7 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 9 Jun 2025 17:44:31 +0200 Subject: [PATCH 1022/1962] [ci] publish-release.yml: add remaining jobs - github-release - create-sourceforge-blog-post - create-regression-tester-baseline - create-docker --- .github/workflows/publish-release.yml | 321 +++++++++++++++++++++----- 1 file changed, 263 insertions(+), 58 deletions(-) diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 7a1954acf71..c3dc849ddda 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -476,68 +476,273 @@ jobs: rm -rf "${HOME}/.ssh" github-release: - # github release only for releases - pmd_ci_gh_releases_updateRelease "$GH_RELEASE" "$release_name" "${rendered_release_notes}" - # Deploy to github releases - pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip" - pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-src.zip" - # Deploy SBOM - pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.xml" - pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.json" - # Deploy signatures - pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip.asc" - pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-src.zip.asc" - - pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "docs/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-doc.zip" - pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "docs/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-doc.zip.asc" + needs: [check-version, deploy-to-maven-central] + if: ${{ inputs.build_cli_dist_only == true }} + environment: + name: github + url: ${{ steps.release.outputs.release_url }} + runs-on: ubuntu-latest + timeout-minutes: 10 + defaults: + run: + shell: bash + steps: + - uses: actions/download-artifact@v4 + with: + name: dist-artifact + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + path: dist + + - uses: actions/download-artifact@v4 + with: + name: docs-artifact + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + path: docs + + - name: Setup GPG + env: + PMD_CI_GPG_PRIVATE_KEY: ${{ secrets.PMD_CI_GPG_PRIVATE_KEY }} + run: | + mkdir -p "${HOME}/.gpg" + chmod 700 "${HOME}/.gpg" + printenv PMD_CI_GPG_PRIVATE_KEY | gpg --batch --import + + gpg --list-keys --fingerprint --keyid-format=long + gpg --list-secret-keys --fingerprint --keyid-format=long + - name: Create docs zip + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + run: | + mv docs "pmd-doc-${PMD_VERSION}" + zip -qr "dist/pmd-dist-${PMD_VERSION}-doc.zip" "pmd-doc-${PMD_VERSION}/" + + - name: Sign files + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + MAVEN_GPG_PASSPHRASE: ${{ secrets.PMD_CI_GPG_PASSPHRASE }} + run: | + cd dist + printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ + --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-bin.zip" + printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ + --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-src.zip" + printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ + --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-doc.zip" + - name: Create GitHub Release + id: release + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + release_name="PMD ${PMD_VERSION} ($(date -u +%d-%B-%Y))" + gh release --verify-tag \ + --title "$release_name" \ + --notes-file "pmd-doc-${PMD_VERSION}/pmd_release_notes.md" \ + create "pmd_releases/${PMD_VERSION}" \ + "dist/pmd-dist-${PMD_VERSION}-bin.zip" \ + "dist/pmd-dist-${PMD_VERSION}-bin.zip.asc" \ + "dist/pmd-dist-${PMD_VERSION}-src.zip" \ + "dist/pmd-dist-${PMD_VERSION}-src.zip.asc" \ + "dist/pmd-dist-${PMD_VERSION}-doc.zip" \ + "dist/pmd-dist-${PMD_VERSION}-doc.zip.asc" \ + "dist/pmd-${PMD_VERSION}-cyclonedx.xml" \ + "dist/pmd-${PMD_VERSION}-cyclonedx.json" + echo "release_url=https://github.com/pmd/pmd/releases/tag/pmd_releases%2F${PMD_VERSION}" >> "$GITHUB_OUTPUT" create-sourceforge-blog-post: - local rendered_release_notes_with_links - rendered_release_notes_with_links=" - * Downloads: https://github.com/pmd/pmd/releases/tag/pmd_releases%2F${PMD_CI_MAVEN_PROJECT_VERSION} - * Documentation: https://docs.pmd-code.org/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}/ + needs: [check-version, deploy-to-maven-central] + if: ${{ inputs.build_cli_dist_only == true }} + # use environment sourceforge, where secrets/vars are configured for PMD_SF_BEARER_TOKEN + environment: + name: sourceforge + url: ${{ steps.upload.outputs.url_output }} + runs-on: ubuntu-latest + timeout-minutes: 10 + defaults: + run: + shell: bash + steps: + - uses: actions/download-artifact@v4 + with: + name: docs-artifact + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + path: docs - ${rendered_release_notes}" - pmd_ci_sourceforge_createDraftBlogPost "${release_name} released" "${rendered_release_notes_with_links}" "pmd,release" - SF_BLOG_URL="${RESULT}" + - name: Create blog post + id: upload + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + PMD_SF_BEARER_TOKEN: ${{ secrets.PMD_SF_BEARER_TOKEN }} + run: | + rendered_release_notes="$(cat docs/pmd_release_notes.md)" + echo " + * Downloads: https://github.com/pmd/pmd/releases/tag/pmd_releases%2F${PMD_VERSION} + * Documentation: https://docs.pmd-code.org/pmd-doc-${PMD_VERSION}/ + + ${rendered_release_notes}" > docs/pmd_release_notes.md + release_name="PMD ${PMD_VERSION} ($(date -u +%d-%B-%Y)) released" + + # See https://sourceforge.net/p/forge/documentation/Allura%20API/ + curl --request POST \ + --header "Authorization: Bearer ${PMD_SF_BEARER_TOKEN}" \ + --form "labels=pmd,release" \ + --form "state=published" \ + --form "text=> "$GITHUB_OUTPUT" create-regression-tester-baseline: - # create a baseline for snapshot builds (when pmd-dist is built) - # or for release builds for case b) when pmd-cli/pmd-dist is released - if pmd_ci_maven_isSnapshotBuild || [ "${BUILD_CLI_DIST_ONLY}" = "true" ]; then - pmd_ci_log_group_start "Creating new baseline for regression tester" - regression_tester_setup_ci - regression_tester_uploadBaseline - pmd_ci_log_group_end - fi + needs: [check-version, deploy-to-maven-central] + if: ${{ inputs.build_cli_dist_only == true }} + # use environment pmd-code, where secrets/vars are configured for PMD_CODE_ORG_DEPLOY_KEY + # and PMD_CODE_ORG_KNOWN_HOSTS + environment: + name: pmd-code + url: https://pmd-code.org/pmd-regression-tester/ + runs-on: ubuntu-latest + timeout-minutes: 60 + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.workflow_run.head_branch }} + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '11' + - name: Set up Ruby 3.3 + uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.3 + - uses: actions/cache@v4 + with: + path: | + ~/.m2/repository + ~/.gradle/caches + ~/work/pmd/target/repositories + .ci/files/vendor/bundle + key: regressiontester-${{ hashFiles('.ci/files/project-list.xml', 'Gemfile.lock') }} + restore-keys: regressiontester- + - uses: actions/download-artifact@v4 + with: + name: dist-artifact + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + path: pmd-dist/target + - name: Setup bundler + run: | + bundle config set --local gemfile .ci/files/Gemfile + bundle config set --local path vendor/bundle + bundle install + - name: Prepare HOME/openjdk11 + run: | + ln -sfn "${JAVA_HOME_11_X64}" "${HOME}/openjdk11" + - name: Run pmdtester + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + run: | + cd .. + rm -f .bundle/config + bundle config set --local gemfile pmd/.ci/files/Gemfile + bundle config set --local path vendor/bundle + bundle exec pmdtester \ + --mode single \ + --local-git-repo ./pmd \ + --patch-branch "pmd_releases/${PMD_VERSION}" \ + --patch-config ./pmd/.ci/files/all-regression-rules.xml \ + --list-of-project ./pmd/.ci/files/project-list.xml --html-flag \ + --threads "$(nproc)" \ + --error-recovery + pushd target/reports || { echo "Directory 'target/reports' doesn't exist"; exit 1; } + - name: Setup ssh key for pmd-code + env: + PMD_CODE_ORG_DEPLOY_KEY: ${{ secrets.PMD_CODE_ORG_DEPLOY_KEY }} + PMD_CODE_ORG_KNOWN_HOSTS: ${{ vars.PMD_CODE_ORG_KNOWN_HOSTS }} + run: | + mkdir -p "${HOME}/.ssh" + chmod 700 "${HOME}/.ssh" + printenv PMD_CODE_ORG_DEPLOY_KEY > "${HOME}/.ssh/pmd-code.org_deploy_key" + chmod 600 "${HOME}/.ssh/pmd-code.org_deploy_key" + echo " + Host pmd-code.org + IdentityFile=$HOME/.ssh/pmd-code.org_deploy_key + " > "$HOME/.ssh/config" + echo "${PMD_CODE_ORG_KNOWN_HOSTS}" > "$HOME/.ssh/known_hosts" + - name: Upload report + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + run: | + cd ../target/reports + baseline_branch="pmd_releases/${PMD_VERSION}" + BRANCH_FILENAME="${baseline_branch/\//_}" + zip -q -r "${BRANCH_FILENAME}-baseline.zip" "${BRANCH_FILENAME}/" + scp "${BRANCH_FILENAME}-baseline.zip" pmd@pmd-code.org:/httpdocs/pmd-regression-tester/ + - name: Cleanup ssh + if: ${{ always() }} + run: | + rm -rf "${HOME}/.ssh" create-docker: - # Trigger docker workflow to build new images for release builds - # but only for case b) pmd-cli/pmd-dist release - if pmd_ci_maven_isReleaseBuild && [ "${BUILD_CLI_DIST_ONLY}" = "true" ]; then - pmd_ci_log_group_start "Trigger docker workflow" - # split semantic version by dot - IFS="." read -ra VERSION_ARRAY <<< "${PMD_CI_MAVEN_PROJECT_VERSION}" - all_tags="" - new_tag="" - for i in "${VERSION_ARRAY[@]}"; do - if [ -z "$new_tag" ]; then - new_tag="${i}" - else - new_tag="${new_tag}.${i}" - fi - all_tags="${all_tags}${new_tag}," - done - all_tags="${all_tags}latest" - echo "version: ${PMD_CI_MAVEN_PROJECT_VERSION}" - echo "tags: ${all_tags}" - - GH_TOKEN="${PMD_ACTIONS_HELPER_TOKEN}" \ - gh api \ - --method POST \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - /repos/pmd/docker/actions/workflows/publish-docker-image.yaml/dispatches \ - -f "ref=main" -f "inputs[version]=${PMD_CI_MAVEN_PROJECT_VERSION}" -f "inputs[tags]=${all_tags}" - pmd_ci_log_group_end - fi + needs: [check-version, deploy-to-maven-central] + if: ${{ inputs.build_cli_dist_only == true }} + environment: + name: github + url: https://github.com/pmd/docker/actions + runs-on: ubuntu-latest + timeout-minutes: 10 + defaults: + run: + shell: bash + steps: + - uses: actions/create-github-app-token@v2 + id: pmd-actions-helper-app-token + with: + app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} + private-key: ${{ secrets.PMD_ACTIONS_HELPER_PRIVATE_KEY }} + owner: pmd + repositories: docker + permission-actions: write + - name: Trigger docker build + env: + GH_TOKEN: ${{ steps.pmd-actions-helper-app-token.outputs.token }} + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + run: | + # split semantic version by dot + IFS="." read -ra VERSION_ARRAY <<< "${PMD_VERSION}" + all_tags="" + new_tag="" + for i in "${VERSION_ARRAY[@]}"; do + if [ -z "$new_tag" ]; then + new_tag="${i}" + else + new_tag="${new_tag}.${i}" + fi + all_tags="${all_tags}${new_tag}," + done + all_tags="${all_tags}latest" + echo "version: ${PMD_VERSION}" + echo "tags: ${all_tags}" + + gh api \ + --method POST \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + /repos/pmd/docker/actions/workflows/publish-docker-image.yaml/dispatches \ + -f "ref=main" -f "inputs[version]=${PMD_VERSION}" -f "inputs[tags]=${all_tags}" From 85eda52f486c619f3d0abefbffde0735f33b2cfb Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 9 Jun 2025 17:45:30 +0200 Subject: [PATCH 1023/1962] [ci] Don't skip ci for first commit after release That way, a new SNAPSHOT is available sooner and PR don't fail (because of missing regression tester baseline) --- do-release.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/do-release.sh b/do-release.sh index df730632918..d449c447abc 100755 --- a/do-release.sh +++ b/do-release.sh @@ -296,7 +296,7 @@ EOF echo "Committing current changes on branch ${CURRENT_BRANCH}" # note: using [skip ci] as only the first stage is done and the full build # requires pmd-designer to be present, which might not be the case yet... -git commit -a -m "[release] Prepare next development version [skip ci]" +git commit -a -m "[release] Prepare next development version" echo "Push branch ${CURRENT_BRANCH}" git push origin "${CURRENT_BRANCH}" From 4266d4e856bff6c9c1968ebaddbf0984024a86ab Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Mon, 9 Jun 2025 21:11:54 +0200 Subject: [PATCH 1024/1962] #2304: Regression test finding: Fix error when referenceName is empty --- .../pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java index 35aaaec9d79..0a939aa7e28 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java @@ -440,6 +440,10 @@ private void removeReferenceSingleImport(String referenceName) { } private void removeReferenceOnDemandImport(String referenceName) { + if (referenceName.isEmpty()) { + return; + } + typeImportsOnDemand.removeIf(it -> { final ASTImportDeclaration importNode = it.node; return importNode.isImportOnDemand() From e479b43744d9780d53c03e5ded1dc2fab42834f0 Mon Sep 17 00:00:00 2001 From: Mitch Spano Date: Mon, 9 Jun 2025 14:30:57 -0500 Subject: [PATCH 1025/1962] Add `AvoidBooleanMethodParameters` rule to detect boolean parameters in public/global methods This commit introduces a new rule that flags boolean parameters in public and global Apex methods, encouraging the use of more descriptive alternatives. It includes the rule implementation, corresponding XML configuration, and test cases to validate its functionality. --- .../AvoidBooleanMethodParametersRule.java | 81 +++++++++++++++++++ .../main/resources/category/apex/design.xml | 45 +++++++++++ .../AvoidBooleanMethodParametersTest.java | 11 +++ .../xml/AvoidBooleanMethodParameters.xml | 77 ++++++++++++++++++ 4 files changed, 214 insertions(+) create mode 100644 pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidBooleanMethodParametersRule.java create mode 100644 pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidBooleanMethodParametersTest.java create mode 100644 pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/AvoidBooleanMethodParameters.xml diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidBooleanMethodParametersRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidBooleanMethodParametersRule.java new file mode 100644 index 00000000000..14ff352680b --- /dev/null +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidBooleanMethodParametersRule.java @@ -0,0 +1,81 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.apex.rule.design; + +import org.checkerframework.checker.nullness.qual.NonNull; + +import net.sourceforge.pmd.lang.apex.ast.ASTMethod; +import net.sourceforge.pmd.lang.apex.ast.ASTModifierNode; +import net.sourceforge.pmd.lang.apex.ast.ASTParameter; +import net.sourceforge.pmd.lang.apex.rule.AbstractApexRule; +import net.sourceforge.pmd.lang.rule.RuleTargetSelector; + +/** + * Rule that detects boolean parameters in public and global Apex methods. + * + *

    + * Boolean parameters can make method calls difficult to understand and + * maintain. They often indicate that a method is doing more than one thing and + * could benefit from being split into separate methods with more descriptive + * names. + *

    + * + *

    + * This rule flags any boolean parameters found in public or global methods, + * encouraging developers to use more expressive alternatives such as enums, + * separate methods, or configuration objects. + *

    + * + * @see https://github.com/pmd/pmd/issues/5427 + */ +public class AvoidBooleanMethodParametersRule extends AbstractApexRule { + + private static final String BOOLEAN_TYPE = "boolean"; + + /** + * Visits an Apex method node and checks for boolean global/public + * parameters. + * + * @param theMethod + * the method node being visited + * @param data + * the rule context data + * @return the rule context data + */ + @Override + public Object visit(ASTMethod theMethod, Object data) { + if (!isPublicOrGlobal(theMethod)) { + return data; + } + theMethod.descendants(ASTParameter.class).filter(parameter -> isBoolean(parameter)) + .forEach(parameter -> asCtx(data).addViolation(parameter)); + return data; + } + + /** + * Builds the target selector for this rule. + * + *

    + * This rule targets Apex method nodes ({@link ASTMethod}) since it needs to + * analyze method parameters for boolean types. + *

    + * + * @return a rule target selector configured for ASTMethod nodes + */ + @Override + protected @NonNull RuleTargetSelector buildTargetSelector() { + return RuleTargetSelector.forTypes(ASTMethod.class); + } + + + private boolean isPublicOrGlobal(ASTMethod method) { + ASTModifierNode modifier = method.getModifiers(); + return modifier.isPublic() || modifier.isGlobal(); + } + + private boolean isBoolean(ASTParameter parameter) { + return BOOLEAN_TYPE.equalsIgnoreCase(parameter.getType()); + } +} diff --git a/pmd-apex/src/main/resources/category/apex/design.xml b/pmd-apex/src/main/resources/category/apex/design.xml index 0c7f7a6ad9b..aa02eb2b862 100644 --- a/pmd-apex/src/main/resources/category/apex/design.xml +++ b/pmd-apex/src/main/resources/category/apex/design.xml @@ -488,4 +488,49 @@ public class Person { + + + +Boolean parameters in a system's API can make method calls difficult to understand and +maintain. They often indicate that a method is doing more than one thing and +could benefit from being split into separate methods with more descriptive +names. + +This rule flags any boolean parameters found in public or global methods, +encouraging developers to use more expressive alternatives such as enums, +separate methods, or configuration objects. + + 2 + + + + + diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidBooleanMethodParametersTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidBooleanMethodParametersTest.java new file mode 100644 index 00000000000..5bece8fcc9b --- /dev/null +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidBooleanMethodParametersTest.java @@ -0,0 +1,11 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.apex.rule.design; + +import net.sourceforge.pmd.test.PmdRuleTst; + +class AvoidBooleanMethodParametersTest extends PmdRuleTst { + // no additional unit tests +} diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/AvoidBooleanMethodParameters.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/AvoidBooleanMethodParameters.xml new file mode 100644 index 00000000000..e79b34e912e --- /dev/null +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/AvoidBooleanMethodParameters.xml @@ -0,0 +1,77 @@ + + + + + Global Boolean parameter should cause violation + 1 + + + + + Public Boolean parameter should cause violation + 1 + + + + + Case insensitive type declaration of Boolean parameter should cause violation + 1 + + + + + Protected Boolean parameter should not cause violation + 0 + + + + + Private Boolean parameter should not cause violation + 0 + + + + From 88512fe24b4a82cb6350daa2411010334179464c Mon Sep 17 00:00:00 2001 From: Mitch Spano Date: Tue, 10 Jun 2025 10:51:31 -0500 Subject: [PATCH 1026/1962] Add AnnotationsShouldBePascalCaseRule to enforce PascalCase for Apex annotations This commit introduces a new rule that checks if Apex annotations are written in PascalCase, ensuring adherence to naming conventions for improved readability and maintainability. Additionally, relevant XML configuration and test cases have been added to support this rule. --- .../AnnotationsShouldBePascalCaseRule.java | 67 +++ .../main/resources/category/apex/design.xml | 37 ++ .../AnnotationsShouldBePascalCaseTest.java | 11 + .../xml/AnnotationsShouldBePascalCase.xml | 533 ++++++++++++++++++ 4 files changed, 648 insertions(+) create mode 100644 pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AnnotationsShouldBePascalCaseRule.java create mode 100644 pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/AnnotationsShouldBePascalCaseTest.java create mode 100644 pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/AnnotationsShouldBePascalCase.xml diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AnnotationsShouldBePascalCaseRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AnnotationsShouldBePascalCaseRule.java new file mode 100644 index 00000000000..58a41615425 --- /dev/null +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AnnotationsShouldBePascalCaseRule.java @@ -0,0 +1,67 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.apex.rule.design; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.checkerframework.checker.nullness.qual.NonNull; + +import net.sourceforge.pmd.lang.apex.ast.ASTAnnotation; +import net.sourceforge.pmd.lang.apex.ast.ASTField; +import net.sourceforge.pmd.lang.apex.ast.ASTMethod; +import net.sourceforge.pmd.lang.apex.ast.ASTModifierNode; +import net.sourceforge.pmd.lang.apex.ast.ASTUserClass; +import net.sourceforge.pmd.lang.apex.ast.ASTUserInterface; +import net.sourceforge.pmd.lang.apex.ast.ApexNode; +import net.sourceforge.pmd.lang.apex.rule.AbstractApexRule; +import net.sourceforge.pmd.lang.rule.RuleTargetSelector; + +/** + * Rule that checks if Apex annotations are written in PascalCase. This rule + * ensures that all annotations follow the standard naming convention where each + * word in the annotation name starts with a capital letter. + */ +public class AnnotationsShouldBePascalCaseRule extends AbstractApexRule { + + private static final Set>> VALID_PARENT_TYPES = Collections.unmodifiableSet( + new HashSet<>(Arrays.asList(ASTUserClass.class, ASTUserInterface.class, ASTMethod.class, ASTField.class))); + + @Override + public Object visit(ASTAnnotation annotation, Object data) { + if (annotation.isResolved() && isValidAnnotationContext(annotation) && !isPascalCase(annotation)) { + asCtx(data).addViolation(annotation); + } + return data; + } + + @Override + protected @NonNull RuleTargetSelector buildTargetSelector() { + return RuleTargetSelector.forTypes(ASTAnnotation.class); + } + + /** + * Checks if the annotation is in a valid context (direct child of a + * modifier node that is a direct child of a valid parent type). + */ + private boolean isValidAnnotationContext(ASTAnnotation annotation) { + if (!(annotation.getParent() instanceof ASTModifierNode)) { + return false; + } + ASTModifierNode modifierNode = (ASTModifierNode) annotation.getParent(); + return VALID_PARENT_TYPES.stream().anyMatch(type -> type.isInstance(modifierNode.getParent())); + } + + /** + * Checks if the annotation name matches its raw name (indicating + * PascalCase). + */ + private boolean isPascalCase(ASTAnnotation annotation) { + return annotation.getName().equals(annotation.getRawName()); + } + +} diff --git a/pmd-apex/src/main/resources/category/apex/design.xml b/pmd-apex/src/main/resources/category/apex/design.xml index 0c7f7a6ad9b..62f1ca6f312 100644 --- a/pmd-apex/src/main/resources/category/apex/design.xml +++ b/pmd-apex/src/main/resources/category/apex/design.xml @@ -484,6 +484,43 @@ public class Person { Date birthDate; BodyMeasurements measurements; } +]]> + + + + + +Apex, while case-insensitive, benefits from a consistent code style to improve readability and maintainability. +Enforcing PascalCase for annotations aligns with the established conventions and reduces ambiguity - promoting a unified coding standard. + + 3 + + diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/AnnotationsShouldBePascalCaseTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/AnnotationsShouldBePascalCaseTest.java new file mode 100644 index 00000000000..d47927bdcef --- /dev/null +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/AnnotationsShouldBePascalCaseTest.java @@ -0,0 +1,11 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.apex.rule.design; + +import net.sourceforge.pmd.test.PmdRuleTst; + +class AnnotationsShouldBePascalCaseTest extends PmdRuleTst { + // no additional unit tests +} diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/AnnotationsShouldBePascalCase.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/AnnotationsShouldBePascalCase.xml new file mode 100644 index 00000000000..501c168e2d3 --- /dev/null +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/AnnotationsShouldBePascalCase.xml @@ -0,0 +1,533 @@ + + + + + AuraEnabled PascalCase is correct + 0 + + + + + AuraEnabled lowercase is incorrect + 1 + + + + + Deprecated PascalCase is correct + 0 + + + + + Deprecated lowercase is incorrect + 1 + + + + + Future PascalCase is correct + 0 + + + + + Future lowercase is incorrect + 1 + + + + + InvocableMethod PascalCase is correct + 0 + + + + + InvocableMethod lowercase is incorrect + 1 + + + + + InvocableVariable PascalCase is correct + 0 + + + + + InvocableVariable lowercase is incorrect + 1 + + + + + IsTest PascalCase is correct + 0 + + + + + IsTest lowercase is incorrect + 1 + + + + + JsonAccess PascalCase is correct + 0 + + + + + JsonAccess lowercase is incorrect + 1 + + + + + NamespaceAccessible PascalCase is correct + 0 + + + + + NamespaceAccessible lowercase is incorrect + 1 + + + + + ReadOnly PascalCase is correct + 0 + + + + + ReadOnly lowercase is incorrect + 1 + + + + + RemoteAction PascalCase is correct + 0 + + + + + RemoteAction lowercase is incorrect + 1 + + + + + SuppressWarnings PascalCase is correct + 0 + + + + + SuppressWarnings lowercase is incorrect + 1 + + + + + TestSetup PascalCase is correct + 0 + + + + + TestSetup lowercase is incorrect + 1 + + + + + TestVisible PascalCase is correct + 0 + + + + + TestVisible lowercase is incorrect + 1 + + + + + RestResource PascalCase is correct + 0 + + + + + RestResource lowercase is incorrect + 1 + + + + + HttpDelete PascalCase is correct + 0 + + + + + HttpDelete lowercase is incorrect + 1 + + + + + HttpGet PascalCase is correct + 0 + + + + + HttpGet lowercase is incorrect + 1 + + + + + HttpPatch PascalCase is correct + 0 + + + + + HttpPatch lowercase is incorrect + 1 + + + + + HttpPost PascalCase is correct + 0 + + + + + HttpPost lowercase is incorrect + 1 + + + + + HttpPut PascalCase is correct + 0 + + + + + HttpPut lowercase is incorrect + 1 + + + + + Invalid annotation on class is ignored + 0 + + + + + Invalid annotation on method is ignored + 0 + + + + From 3557765abbb0d6ad7b795b760653f6f018492a40 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 10 Jun 2025 20:47:14 +0200 Subject: [PATCH 1027/1962] Fix deployment name for central-publishing-maven-plugin --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 660ad1fc236..d1cf13869df 100644 --- a/pom.xml +++ b/pom.xml @@ -787,7 +787,7 @@ central true published - ${project.artifactId} + PMD ${project.version}
    From 507c35573323d39411dc59880f5f0c3e1dabf3f5 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 10 Jun 2025 21:03:10 +0200 Subject: [PATCH 1028/1962] [ci] publish-release.yml: upload regression baseline to sourceforge --- .github/workflows/publish-release.yml | 53 +++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index c3dc849ddda..c5636268075 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -690,10 +690,55 @@ jobs: PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} run: | cd ../target/reports - baseline_branch="pmd_releases/${PMD_VERSION}" - BRANCH_FILENAME="${baseline_branch/\//_}" - zip -q -r "${BRANCH_FILENAME}-baseline.zip" "${BRANCH_FILENAME}/" - scp "${BRANCH_FILENAME}-baseline.zip" pmd@pmd-code.org:/httpdocs/pmd-regression-tester/ + baseline_name="pmd_releases_${PMD_VERSION}" + zip -q -r "${baseline_name}-baseline.zip" "${baseline_name}/" + scp "${baseline_name}-baseline.zip" pmd@pmd-code.org:/httpdocs/pmd-regression-tester/ + - uses: actions/upload-artifact@v4 + with: + name: regression-tester-baseline + path: ${{ format('pmd_releases_{0}-baseline.zip', needs.check-version.outputs.PMD_VERSION) }} + - name: Cleanup ssh + if: ${{ always() }} + run: | + rm -rf "${HOME}/.ssh" + + upload-regression-tester-baseline-sourceforge: + needs: [check-version, deploy-to-maven-central, create-regression-tester-baseline] + if: ${{ inputs.build_cli_dist_only == true }} + # use environment sourceforge, where secrets/vars are configured for PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY + # and PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS and PMD_SF_APIKEY + environment: + name: sourceforge + url: https://sourceforge.net/projects/pmd/files/pmd-regression-tester/ + runs-on: ubuntu-latest + timeout-minutes: 60 + defaults: + run: + shell: bash + steps: + - name: Setup ssh key for sourceforge + env: + WEB_SF_DEPLOY_KEY: ${{ secrets.PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY }} + WEB_SF_KNOWN_HOSTS: ${{ vars.PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS }} + run: | + mkdir -p "${HOME}/.ssh" + chmod 700 "${HOME}/.ssh" + printenv WEB_SF_DEPLOY_KEY > "${HOME}/.ssh/web.sourceforge.net_deploy_key" + chmod 600 "${HOME}/.ssh/web.sourceforge.net_deploy_key" + echo " + Host web.sourceforge.net + IdentityFile=$HOME/.ssh/web.sourceforge.net_deploy_key + " > "$HOME/.ssh/config" + echo "${WEB_SF_KNOWN_HOSTS}" > "$HOME/.ssh/known_hosts" + - uses: actions/download-artifact@v4 + with: + name: regression-tester-baseline + - name: Upload to sourceforge + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + run: | + uploadUrl="adangel@web.sourceforge.net:/home/frs/project/pmd/pmd-regression-tester/" + rsync -avh "pmd_releases_${PMD_VERSION}-baseline.zip" "${uploadUrl}" - name: Cleanup ssh if: ${{ always() }} run: | From 79db238386c4250494fb7752b4d433afc37821d6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 10 Jun 2025 21:41:31 +0200 Subject: [PATCH 1029/1962] [doc] Fix javadoc plugin configuration Since upgrade to version 3.10.0 the links to pmd-core from other modules didn't work anymore. Compare https://docs.pmd-code.org/apidocs/pmd-java/7.0.0/net/sourceforge/pmd/lang/java/JavaLanguageModule.html with https://docs.pmd-code.org/apidocs/pmd-java/7.14.0/net/sourceforge/pmd/lang/java/JavaLanguageModule.html Last working version: 7.8.0 Refs #5410 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 660ad1fc236..d46b79d67a9 100644 --- a/pom.xml +++ b/pom.xml @@ -400,11 +400,11 @@ false - ${project.basedir}/../pmd-core/target/apidocs + ${project.basedir}/../pmd-core/target/reports/apidocs ../../pmd-core/${project.version} - ${project.basedir}/../pmd-test/target/apidocs + ${project.basedir}/../pmd-test/target/reports/apidocs ../../pmd-test/${project.version} From 2042e5cd8fef129f63fa60e574054bbdff4ac940 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 10 Jun 2025 21:49:30 +0200 Subject: [PATCH 1030/1962] [doc] Fix dokka plugin configuration as well --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index d46b79d67a9..65a0ba58002 100644 --- a/pom.xml +++ b/pom.xml @@ -453,11 +453,11 @@ https://docs.pmd-code.org/apidocs/pmd-core/${project.version}/ - file://${project.basedir}/../pmd-core/target/apidocs/element-list + file://${project.basedir}/../pmd-core/target/reports/apidocs/element-list https://docs.pmd-code.org/apidocs/pmd-test/${project.version}/ - file://${project.basedir}/../pmd-test/target/apidocs/element-list + file://${project.basedir}/../pmd-test/target/reports/apidocs/element-list https://docs.pmd-code.org/apidocs/pmd-lang-test/${project.version}/ From cecb81304b45321896ae2e3f7b8960af0d97892d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 18 Jun 2025 11:01:58 +0200 Subject: [PATCH 1031/1962] Fix #1639 #5832: Use filtered comment text for UnnecessaryImport Filtered comment text has the prefixes "/**" and "*" removed, so that only the plain javadoc text is used. This allows for correct multiline detection of references in javadoc. --- docs/pages/release_notes.md | 3 ++ .../rule/codestyle/UnnecessaryImportRule.java | 8 ++++- .../rule/codestyle/xml/UnnecessaryImport.xml | 29 +++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 25ace786e57..d98eb1912d3 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,6 +25,9 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* java-codestyle + * [#1639](https://github.com/pmd/pmd/issues/1639): \[java] UnnecessaryImport false positive for multiline @link Javadoc + * [#5832](https://github.com/pmd/pmd/issues/5832): \[java] UnnecessaryImport false positive for multiline @see Javadoc ### ๐Ÿšจ API Changes diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java index 515035cf624..4ad606baae4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java @@ -10,6 +10,7 @@ import java.util.function.Predicate; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -45,6 +46,7 @@ import net.sourceforge.pmd.lang.java.types.TypeSystem; import net.sourceforge.pmd.lang.java.types.TypeTestUtil; import net.sourceforge.pmd.util.CollectionUtil; +import net.sourceforge.pmd.util.IteratorUtil; /** * Detects unnecessary imports. @@ -201,8 +203,12 @@ private void visitComments(ASTCompilationUnit node) { if (!(comment instanceof JavadocComment)) { continue; } + + String filteredCommentText = IteratorUtil.toStream(comment.getFilteredLines(true)) + .collect(Collectors.joining("\n")); + for (Pattern p : PATTERNS) { - Matcher m = p.matcher(comment.getText()); + Matcher m = p.matcher(filteredCommentText); while (m.find()) { String fullname = m.group(1); diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml index 2029ee1ef65..484652f8211 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml @@ -1357,4 +1357,33 @@ public class C { ]]> + + [java] UnnecessaryImport false positive for multiline @see Javadoc #5832 + 0 + + + + + [java] UnusedImports false positive for multiline @link Javadoc #1639 + 0 + + From e203793ae5d252ed11058fb2aa5c32992b6f56e6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Jun 2025 12:18:15 +0200 Subject: [PATCH 1032/1962] Bump scalameta.version from 4.13.6 to 4.13.7 (#5828) Bumps `scalameta.version` from 4.13.6 to 4.13.7. Updates `org.scalameta:parsers_2.13` from 4.13.6 to 4.13.7 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.6...v4.13.7) Updates `org.scalameta:trees_2.13` from 4.13.6 to 4.13.7 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.6...v4.13.7) Updates `org.scalameta:parsers_2.12` from 4.13.6 to 4.13.7 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.6...v4.13.7) Updates `org.scalameta:trees_2.12` from 4.13.6 to 4.13.7 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.6...v4.13.7) --- updated-dependencies: - dependency-name: org.scalameta:parsers_2.13 dependency-version: 4.13.7 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:trees_2.13 dependency-version: 4.13.7 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:parsers_2.12 dependency-version: 4.13.7 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:trees_2.12 dependency-version: 4.13.7 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index e883b0cff0a..c75b609a21e 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -13,7 +13,7 @@ - 4.13.6 + 4.13.7 From 4d6459594bca987945d3fb31c01887ef7be497ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Jun 2025 12:18:55 +0200 Subject: [PATCH 1033/1962] Bump liquid from 5.8.6 to 5.8.7 in /.ci/files in the all-gems group across 1 directory (#5829) Bump liquid in /.ci/files in the all-gems group across 1 directory Bumps the all-gems group with 1 update in the /.ci/files directory: [liquid](https://github.com/Shopify/liquid). Updates `liquid` from 5.8.6 to 5.8.7 - [Release notes](https://github.com/Shopify/liquid/releases) - [Changelog](https://github.com/Shopify/liquid/blob/main/History.md) - [Commits](https://github.com/Shopify/liquid/compare/v5.8.6...v5.8.7) --- updated-dependencies: - dependency-name: liquid dependency-version: 5.8.7 dependency-type: indirect update-type: version-update:semver-patch dependency-group: all-gems ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .ci/files/Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/files/Gemfile.lock b/.ci/files/Gemfile.lock index 7a46a06fcdc..d74aba21750 100644 --- a/.ci/files/Gemfile.lock +++ b/.ci/files/Gemfile.lock @@ -10,7 +10,7 @@ GEM fugit (1.11.1) et-orbi (~> 1, >= 1.2.11) raabro (~> 1.4) - liquid (5.8.6) + liquid (5.8.7) bigdecimal strscan (>= 3.1.1) logger (1.7.0) @@ -30,7 +30,7 @@ GEM rufus-scheduler (3.9.2) fugit (~> 1.1, >= 1.11.1) slop (4.10.1) - strscan (3.1.3) + strscan (3.1.5) tzinfo (2.0.6) concurrent-ruby (~> 1.0) From 6057f8d42b37f73f4818a1b8f92f91e3f8714ae1 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 19 Jun 2025 15:31:32 +0200 Subject: [PATCH 1034/1962] [ci] publish-release.yml: simplify for now, we ignore #4446 and release everything in one go. --- .github/workflows/publish-release.yml | 34 +++------------------------ 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index c5636268075..e1e90f8445d 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -8,12 +8,6 @@ on: branches: - '**' workflow_dispatch: - inputs: - build_cli_dist_only: - description: "Build only modules cli and dist" - required: true - type: boolean - default: false permissions: contents: read # to fetch code (actions/checkout) @@ -113,26 +107,11 @@ jobs: MAVEN_USERNAME: ${{ secrets.MAVEN_CENTRAL_PORTAL_USERNAME }} MAVEN_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PORTAL_PASSWORD }} MAVEN_GPG_PASSPHRASE: ${{ secrets.PMD_CI_GPG_PASSPHRASE }} - BUILD_CLI_DIST_ONLY: ${{ inputs.build_cli_dist_only }} # note: we can't use artifact staging-repository, as the jars are unsigned and javadoc+sources are missing. run: | - # make sure, BUILD_CLI_DIST_ONLY is set to false by default - : "${BUILD_CLI_DIST_ONLY:=false}" - echo "BUILD_CLI_DIST_ONLY=${BUILD_CLI_DIST_ONLY}" - # There are two possible release builds: - if [ "${BUILD_CLI_DIST_ONLY}" = "false" ]; then - # a) everything without pmd-cli and pmd-dist - BUILD_CLI_DIST_MAVEN_OPTION="-Dskip-cli-dist" - else - # b) only pmd-cli and pmd-dist - BUILD_CLI_DIST_MAVEN_OPTION="-pl pmd-cli,pmd-dist" - fi - echo "BUILD_CLI_DIST_MAVEN_OPTION=${BUILD_CLI_DIST_MAVEN_OPTION}" - ./mvnw --show-version --errors --batch-mode \ deploy \ -DskipTests \ - ${BUILD_CLI_DIST_MAVEN_OPTION} \ -PfastSkip,sign,pmd-release \ -Dcyclonedx.skip=false \ -Dmaven.javadoc.skip=false \ @@ -140,7 +119,6 @@ jobs: deploy-to-sourceforge-files: needs: [check-version, deploy-to-maven-central] - if: ${{ inputs.build_cli_dist_only == true }} # use environment sourceforge, where secrets/vars are configured for PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY # and PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS and PMD_SF_APIKEY environment: @@ -261,7 +239,6 @@ jobs: deploy-to-sourceforge-io: needs: [check-version, deploy-to-maven-central] - if: ${{ inputs.build_cli_dist_only == true }} # use environment sourceforge, where secrets/vars are configured for PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY # and PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS environment: @@ -311,7 +288,6 @@ jobs: deploy-to-pmd-code-doc: needs: [check-version, deploy-to-maven-central] - if: ${{ inputs.build_cli_dist_only == true }} # use environment pmd-code, where secrets/vars are configured for PMD_CODE_ORG_DEPLOY_KEY # and PMD_CODE_ORG_KNOWN_HOSTS environment: @@ -392,7 +368,6 @@ jobs: deploy-to-pmd-code-javadoc: needs: [check-version, deploy-to-maven-central] - if: ${{ inputs.build_cli_dist_only == true }} # use environment pmd-code, where secrets/vars are configured for PMD_CODE_ORG_DEPLOY_KEY # and PMD_CODE_ORG_KNOWN_HOSTS environment: @@ -477,11 +452,12 @@ jobs: github-release: needs: [check-version, deploy-to-maven-central] - if: ${{ inputs.build_cli_dist_only == true }} environment: name: github url: ${{ steps.release.outputs.release_url }} runs-on: ubuntu-latest + permissions: + contents: write # create a release timeout-minutes: 10 defaults: run: @@ -553,7 +529,6 @@ jobs: create-sourceforge-blog-post: needs: [check-version, deploy-to-maven-central] - if: ${{ inputs.build_cli_dist_only == true }} # use environment sourceforge, where secrets/vars are configured for PMD_SF_BEARER_TOKEN environment: name: sourceforge @@ -608,7 +583,6 @@ jobs: create-regression-tester-baseline: needs: [check-version, deploy-to-maven-central] - if: ${{ inputs.build_cli_dist_only == true }} # use environment pmd-code, where secrets/vars are configured for PMD_CODE_ORG_DEPLOY_KEY # and PMD_CODE_ORG_KNOWN_HOSTS environment: @@ -685,7 +659,7 @@ jobs: IdentityFile=$HOME/.ssh/pmd-code.org_deploy_key " > "$HOME/.ssh/config" echo "${PMD_CODE_ORG_KNOWN_HOSTS}" > "$HOME/.ssh/known_hosts" - - name: Upload report + - name: Upload baseline env: PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} run: | @@ -704,7 +678,6 @@ jobs: upload-regression-tester-baseline-sourceforge: needs: [check-version, deploy-to-maven-central, create-regression-tester-baseline] - if: ${{ inputs.build_cli_dist_only == true }} # use environment sourceforge, where secrets/vars are configured for PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY # and PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS and PMD_SF_APIKEY environment: @@ -746,7 +719,6 @@ jobs: create-docker: needs: [check-version, deploy-to-maven-central] - if: ${{ inputs.build_cli_dist_only == true }} environment: name: github url: https://github.com/pmd/docker/actions From 64e5e3512867f1127953cc3fb2a12f93c619fa4b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 19 Jun 2025 15:59:12 +0200 Subject: [PATCH 1035/1962] [ci] publish-release.yml: update documentation --- .../pmd/devdocs/github_actions_workflows.md | 68 ++++++++++++++++++- 1 file changed, 65 insertions(+), 3 deletions(-) diff --git a/docs/pages/pmd/devdocs/github_actions_workflows.md b/docs/pages/pmd/devdocs/github_actions_workflows.md index 520714ed2c9..e532d965b70 100644 --- a/docs/pages/pmd/devdocs/github_actions_workflows.md +++ b/docs/pages/pmd/devdocs/github_actions_workflows.md @@ -32,9 +32,13 @@ not require any secrets. "Build Pull Request" is triggered, whenever a pull request is created or synchronized. "Build Snapshot" is triggered, whenever new commits are pushed to a branch (including the default branch and -including forks). +including forks). This is also a scheduled workflow that runs every month to make sure, the project +can still be built. -"Build Release" is triggered, whenever a tag is pushed. +"Build Release" is triggered, whenever a tag is pushed. Note that the whole project is built at once, that +means if pmd-designer/pmd-core update is required, this can't be built. See also +[Circular dependencies between pmd-designer, pmd-core, pmd-cli #4446](https://github.com/pmd/pmd/issues/4446). +As this happens very seldom, this situation is ignored for now. In order to avoid unnecessary builds, we use concurrency control to make sure, we cancel any in-progress jobs for the current branch or pull request when a new commit has been pushed. This means, only the latest commit is built, @@ -147,7 +151,7 @@ crawling side. This runs after "Build Snapshot" of a push on the `main` branch is finished. It runs in the context of our own repository and has access to all secrets. In order -to have a nicer display in GitHub actions, we leverage "environments", which also +to have a nicer progress display in GitHub actions, we leverage "environments", which also contain secrets. There is a first job "check-version" that just determines the version of PMD we are building. This is to ensure, @@ -204,6 +208,64 @@ we are actually building a SNAPSHOT version. Then a couple of other jobs are bei * Builds: * Workflow file: +This runs after "Build Release" finishes from building from a tag. +It runs in the context of our own repository and has access to all secrets. In order to have +a nicer progress display in GitHub actions, we leverage "environments", which also +contain secrets. + +There is a first job "check-version" that just determines the version of PMD we are building. This is to ensure, +we are actually building a RELEASE version. Then a first job is executed: + +* deploy-to-maven-central: Rebuilds PMD from the tag and deploys the artifact to maven central at + . + Rebuilding is necessary in order to produce all necessary artifacts (sources, javadoc) and also gpg-sign the + artifacts. This is not available from the build artifacts of the "Build" workflow. + * Environment: maven-central + * Secrets: MAVEN_CENTRAL_PORTAL_USERNAME, MAVEN_CENTRAL_PORTAL_PASSWORD + +When this was successful, then a couple of other jobs are being executed in parallel: + +* deploy-to-sourceforge-files: Uploads the binary distribution files to sourceforge at + and select the new file as the latest + version. + * Environment: sourceforge + * Secrets: PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY, PMD_SF_APIKEY + * Vars: PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS +* deploy-to-sourceforge-io: Uploads the documentation to + . + * Environment: sourceforge + * Secrets: PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY + * Vars: PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS +* deploy-to-pmd-code-doc: Uploads the documentation to . + * Environment: pmd-code + * Secrets: PMD_CODE_ORG_DEPLOY_KEY + * Vars: PMD_CODE_ORG_KNOWN_HOSTS +* deploy-to-pmd-code-javadoc: Uploads the javadoc to + * Environment: pmd-code + * Secrets: PMD_CODE_ORG_DEPLOY_KEY + * Vars: PMD_CODE_ORG_KNOWN_HOSTS +* github-release: Creates a new github release at including + the attached artifacts. + * Environment: github +* create-sourceforge-blog-post: Creates a news entry at . + * Environment: sourceforge + * Secrets: PMD_SF_BEARER_TOKEN +* create-regression-tester-baseline: Creates a new baseline and uploads it to + . + * Environment: pmd-code + * Secrets: PMD_CODE_ORG_DEPLOY_KEY + * Vars: PMD_CODE_ORG_KNOWN_HOSTS +* upload-regression-tester-baseline-sourceforge: Uploads the baseline additionally to sourceforge + at . Needs the previous job. + * Environment: sourceforge + * Secrets: PMD_WEB_SOURCEFORGE_NET_DEPLOY_KEY + * Vars: PMD_WEB_SOURCEFORGE_NET_KNOWN_HOSTS +* create-docker: Triggers a new build at to create and + upload a new docker image to Docker Hub and GitHub Packages. + * Environment: github + * Uses PMD Actions Helper app to call a workflow in the other repository + * Secrets: PMD_ACTIONS_HELPER_ID, PMD_ACTIONS_HELPER_PRIVATE_KEY + ## Secrets and Variables The "Build" workflow doesn't need any secrets or additional permissions, it just builds and creates artifacts. From e39ceed13f7f456fe445ca96fc567122637987f0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 19 Jun 2025 16:34:10 +0200 Subject: [PATCH 1036/1962] [ci] publish-release.yml: update do-release.sh and documentation --- .ci/files/project-list.xml | 4 +- do-release.sh | 51 ++----- .../pmd/devdocs/github_actions_workflows.md | 6 +- .../pmd/projectdocs/committers/releasing.md | 125 +++++++----------- pom.xml | 2 +- 5 files changed, 65 insertions(+), 123 deletions(-) diff --git a/.ci/files/project-list.xml b/.ci/files/project-list.xml index 77c0ac8cd5f..98c2bf1c167 100644 --- a/.ci/files/project-list.xml +++ b/.ci/files/project-list.xml @@ -21,7 +21,7 @@ fi set -e -# Make sure to use java11. This is already installed by build.sh +# Make sure to use java11. This is already installed by build.yml/publish-snapshot.yml/publish-release.yml export JAVA_HOME=${HOME}/openjdk11 export PATH=$JAVA_HOME/bin:$PATH @@ -47,7 +47,7 @@ fi set -e -# Make sure to use java11. This is already installed by build.sh +# Make sure to use java11. This is already installed by build.yml/publish-snapshot.yml/publish-release.yml export JAVA_HOME=${HOME}/openjdk11 export PATH=$JAVA_HOME/bin:$PATH diff --git a/do-release.sh b/do-release.sh index d449c447abc..ab09ddd5f12 100755 --- a/do-release.sh +++ b/do-release.sh @@ -134,7 +134,8 @@ echo echo "* Update **../pmd.github.io/_config.yml** to mention the new release" echo echo "* Update property \`pmd-designer.version\` in **pom.xml** to reference the version, that will be released" -echo " later in this process." +echo " later in this process. โš  WARNING! This does not work. You need to select an already released version." +echo " See ." echo echo "Press enter to continue..." read -r @@ -192,9 +193,8 @@ echo "Change version in the POMs to ${RELEASE_VERSION} and update build timestam ./mvnw --quiet versions:set -DnewVersion="${RELEASE_VERSION}" -DgenerateBackupPoms=false -DupdateBuildOutputTimestampPolicy=always echo "Transform the SCM information in the POM" sed -i "s|HEAD|pmd_releases/${RELEASE_VERSION}|" pom.xml -echo "Run the project tests against the changed POMs to confirm everything is in running order (skipping cli and dist)" -# note: skipping pmd in order to avoid failures due to #4757 -./mvnw clean verify -Dskip-cli-dist -Dpmd.skip=true -Dcpd.skip=true -Pgenerate-rule-docs +echo "Run the project tests against the changed POMs to confirm everything is in running order" +./mvnw clean verify -Pgenerate-rule-docs echo "Commit and create tag" git commit -a -m "[release] prepare release pmd_releases/${RELEASE_VERSION}" git tag -m "[release] copy for tag pmd_releases/${RELEASE_VERSION}" "pmd_releases/${RELEASE_VERSION}" @@ -205,16 +205,17 @@ git push origin tag "pmd_releases/${RELEASE_VERSION}" echo echo "Tag has been pushed.... now check github actions: " echo -echo "Now wait, until first stage of the release is finished successfully..." -echo "You don't need to wait until artifacts are in maven central, just the GitHub Action must be successful." +echo "Now wait, until the workflows 'Build Release' and 'Publish Release' finished successfully..." +echo "You don't need to wait until artifacts are in maven central, just the GitHub Actions must be successful." echo -echo "If it is failing, you can fix the code/scripts and force push the tag via" +echo "If it is failing already at the first job (deploy-to-maven-central), you can fix the code/scripts and force push the tag via" echo echo " git tag -d \"pmd_releases/${RELEASE_VERSION}\"" echo " git tag -m \"[release] copy for tag pmd_releases/${RELEASE_VERSION}\" \"pmd_releases/${RELEASE_VERSION}\"" echo " git push origin tag \"pmd_releases/${RELEASE_VERSION}\" --force" echo echo "However: This is only possible, if the artefacts have not been pushed to maven central yet..." +echo " And doing this later will destroy reproducible builds." echo echo "Press enter to continue, once the GitHub Action finished successfully..." read -r @@ -294,40 +295,10 @@ This is a {{ site.pmd.release_type }} release. EOF echo "Committing current changes on branch ${CURRENT_BRANCH}" -# note: using [skip ci] as only the first stage is done and the full build -# requires pmd-designer to be present, which might not be the case yet... git commit -a -m "[release] Prepare next development version" echo "Push branch ${CURRENT_BRANCH}" git push origin "${CURRENT_BRANCH}" -echo -echo -echo -echo "* Wait until the new version is synced to maven central and appears as latest version in" -echo " ." -echo -echo -echo "Then proceed with releasing pmd-designer..." -echo "" -echo -echo "Press enter to continue when pmd-designer is available in maven-central..." -echo "." -echo -echo "Note: If there is no new pmd-designer release needed, you can directly proceed." -read -r - -echo -echo "Continuing with release of pmd-cli and pmd-dist..." -echo "Before proceeding however, wait another 10 minutes, so that the freshly released artefacts" -echo "are indeed available from maven central. The GitHub runners might not yet see them..." -echo "If that happens, the old-build job needs to be started again, maybe the runner cache needs to be cleared as well." -echo -echo "Go to and manually trigger a new old-build job" -echo "from tag 'pmd_releases/${RELEASE_VERSION}' and with option 'Build only modules cli and dist' checked." -echo -echo "This triggers the second stage release and eventually publishes the release on GitHub." -echo -echo "Now check github actions: " echo echo echo "Verification: (see also )" @@ -340,12 +311,10 @@ echo " * Default download should be new version" echo " * All assets are there (bin, src, doc, cyclondx.json, cyclondx.xml, ReadMe.md)" echo "* News entry on sourceforge: " echo "* Latest documentation points to new release: " -echo "* JavaDoc API Doc is available: " -echo "* All artefacts are on maven central, especially pmd-cli" -echo " * " +echo "* JavaDoc API Doc is available: " +echo "* All artefacts are on maven central" echo " * " echo " * " -echo " * " echo "* Regression Tester baseline has been created: " echo "* Docker images have been created: / " echo diff --git a/docs/pages/pmd/devdocs/github_actions_workflows.md b/docs/pages/pmd/devdocs/github_actions_workflows.md index e532d965b70..2a878fc018f 100644 --- a/docs/pages/pmd/devdocs/github_actions_workflows.md +++ b/docs/pages/pmd/devdocs/github_actions_workflows.md @@ -5,7 +5,7 @@ summary: | PMD uses GitHub Actions as the CI/CD infrastructure to build and release new versions. This page gives an overview of how these workflows work and how to use them. author: Andreas Dangel -last_updated: May 2025 (7.14.0) +last_updated: June 2025 (7.15.0) --- {%include note.html content="This page is work in progress and does not yet describe all workflows."%} @@ -219,7 +219,9 @@ we are actually building a RELEASE version. Then a first job is executed: * deploy-to-maven-central: Rebuilds PMD from the tag and deploys the artifact to maven central at . Rebuilding is necessary in order to produce all necessary artifacts (sources, javadoc) and also gpg-sign the - artifacts. This is not available from the build artifacts of the "Build" workflow. + artifacts. This is not available from the build artifacts of the "Build" workflow. + The maven plugin [central-publishing-maven-plugin](https://central.sonatype.org/publish/publish-portal-maven/) is used + to upload and publish the artifacts to maven central. * Environment: maven-central * Secrets: MAVEN_CENTRAL_PORTAL_USERNAME, MAVEN_CENTRAL_PORTAL_PASSWORD diff --git a/docs/pages/pmd/projectdocs/committers/releasing.md b/docs/pages/pmd/projectdocs/committers/releasing.md index 4ff39f433eb..21b190a86eb 100644 --- a/docs/pages/pmd/projectdocs/committers/releasing.md +++ b/docs/pages/pmd/projectdocs/committers/releasing.md @@ -2,7 +2,7 @@ title: Release process permalink: pmd_projectdocs_committers_releasing.html author: Romain Pelisse , Andreas Dangel -last_updated: April 2025 (7.13.0) +last_updated: June 2025 (7.15.0) --- This page describes the current status of the release process. @@ -13,6 +13,10 @@ Since 7.0.0-rc4, the release happens in two phases: First pmd-core with all the This allows to release then pmd-designer or any other project, that just depends on pmd-core and the languages. And in the second phase, pmd-cli and pmd-dist are released. These include e.g. pmd-designer. +Since 7.15.0, the release scripts changed again, see [GitHub Actions Workflows](pmd_devdocs_github_actions_workflows.html). +Only a full release is supported now, the two phases are gone. If a new pmd-designer is needed, it has to be released +before. + While the release is mostly automated, there are still a few steps, that need manual examination. ## Overview @@ -22,12 +26,6 @@ required in order to verify that the release was successful or in case the autom some reason. Then individual steps need to be executed manually. Because the build is reproducible, these steps can be repeated if the same tag is used. -There is one special case in this project: As outlined above, the release of PMD consists of two phases or parts: -1. All modules except pmd-cli and pmd-dist are released. That means, pmd-core and all the language modules - are released. This is, so that these libs can be used by pmd-designer to create a new release. -2. pmd-cli and pmd-dist are released after that. Both depend on pmd-designer, and this two-step release - process is used for now to break the cycling release dependency. - The three main steps are: * Preparations (which sets the versions and creates the tags) - use `do-release.sh` for that @@ -72,13 +70,13 @@ in order to release version "7.2.0", the configuration should look like this: ```yaml pmd: - version: 7.2.0 - previous_version: 7.1.0 - date: 2024-05-31 + version: 7.15.0 + previous_version: 7.14.0 + date: 2025-06-27 release_type: minor ``` -The release type could be one of "bugfix" (e.g. 7.2.x), "minor" (7.x.0), or "major" (x.0.0). +The release type could be one of "bugfix" (e.g. 7.15.x), "minor" (7.x.0), or "major" (x.0.0). The release notes usually mention any new rules that have been added since the last release. @@ -87,13 +85,10 @@ Add the new rules as comments to the quickstart rulesets: * `pmd-java/src/main/resources/rulesets/java/quickstart.xml` The designer lives at [pmd/pmd-designer](https://github.com/pmd/pmd-designer). -Update property `pmd-designer.version` in **pom.xml** to reference the new version, that will be released -shortly. Note: This new version does at the moment not exist. That means, that a full build of the sources -will currently fail. That's why the first phase of the release will build only pmd-core and languages but -not pmd-cli and pmd-dist. - -In case, there is no need for a new pmd-designer version, we could stick to the latest already available version. -Then we can skip the release of pmd-designer and immediately start the second phase of the release. +Update property `pmd-designer.version` in **pom.xml** to reference a possible new version. +Note: This version must exist already. If it doesn't, a release is not possible. +Usually the version should have been updated before the release already, so that it could be tested. +In case, there is no newer pmd-designer version, we simply stick to the latest already available version. Starting with PMD 7.5.0 we use Dependabot to update dependencies. Dependabot will create pull requests labeled with `dependencies`. When we merge such a pull request, we should assign it to the correct @@ -104,7 +99,7 @@ This is done by the script `.ci/tools/release-notes-generate.sh`. It needs to be LAST_VERSION and RELEASE_VERSION as parameters, e.g. ```shell -.ci/tool/release-notes-generate.sh 7.5.0 7.6.0 +.ci/tool/release-notes-generate.sh 7.14.0 7.15.0 ``` This script will directly modify the file `docs/pages/release_notes.md`. It can be called multiple times @@ -112,7 +107,7 @@ without issues. However, there is active [rate limiting](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2022-11-28) of the GitHub API, which might cause issues. If that happens, you need to set the env var `GITHUB_TOKEN` with your personal access token. The script will pick it up automatically. -A fine-grained token with onl "Public Repositories (read-only)" access is enough. +A fine-grained token with only "Public Repositories (read-only)" access is enough. Starting with PMD 6.23.0 we'll provide small statistics for every release. This needs to be added to the release notes as the last section (after "Dependency updates"). To count the closed issues and pull requests, the milestone @@ -138,14 +133,14 @@ The new version needs to be entered into `_config.yml`, e.g.: ```yaml pmd: - latestVersion: 7.2.0 - latestVersionDate: 31-May-2024 + latestVersion: 7.15.0 + latestVersionDate: 27-June-2025 ``` Also move the previous version down into the "downloads" section. We usually keep only the last 3 versions in this list, so remove the oldest version. -Then create a new page for the new release, e.g. `_posts/2024-05-31-PMD-7.2.0.md` and copy +Then create a new page for the new release, e.g. `_posts/2025-06-27-PMD-7.15.0.md` and copy the release notes into this page. This will appear under the news section. Note: The release notes typically contain some Jekyll macros for linking to the rule pages. These macros won't @@ -179,27 +174,25 @@ Check in all (version, blog post) changes to branch main: ## The actual release The actual release is done by changing the versions, creating a tag and pushing this tag. Previously this was done -by calling _maven-release-plugin_, but these steps are done without the plugin to have more control. And since we -might reference a not yet released pmd-designer version, the test-build would fail. +by calling _maven-release-plugin_, but these steps are done without the plugin to have more control. We first change the version of PMD and all modules by basically removing the "-SNAPSHOT" suffix, building the changed -project locally with tests (and with skipping pmd-cli and pmd-dist) in order to be sure, everything is in working +project locally with tests in order to be sure, everything is in working order. Then the version changes are committed and a new release tag is created. Then, the versions are changed to the next snapshot. As last step, everything is pushed. `RELEASE_VERSION` is the version of the release. It is reused for the tag. `DEVELOPMENT_VERSION` is the -next snapshot version after the release. Skipping the builds of pmd-cli and pmd-dist is done by setting -the property `skip-cli-dist`. +next snapshot version after the release. ```shell -RELEASE_VERSION=7.2.0 -DEVELOPMENT_VERSION=7.3.0-SNAPSHOT +RELEASE_VERSION=7.15.0 +DEVELOPMENT_VERSION=7.16.0-SNAPSHOT # Change version in the POMs to ${RELEASE_VERSION} and update build timestamp ./mvnw --quiet versions:set -DnewVersion="${RELEASE_VERSION}" -DgenerateBackupPoms=false -DupdateBuildOutputTimestampPolicy=always # Transform the SCM information in the POM sed -i "s|.\+|pmd_releases/${RELEASE_VERSION}|" pom.xml -# Run the project tests against the changed POMs to confirm everything is in running order (skipping cli and dist) -./mvnw clean verify -Dskip-cli-dist -Pgenerate-rule-docs +# Run the project tests against the changed POMs to confirm everything is in running order +./mvnw clean verify -Pgenerate-rule-docs # Commit and create tag git commit -a -m "[release] prepare release pmd_releases/${RELEASE_VERSION}" git tag -m "[release] copy for tag pmd_releases/${RELEASE_VERSION}" "pmd_releases/${RELEASE_VERSION}" @@ -213,12 +206,9 @@ git push origin tag "pmd_releases/${RELEASE_VERSION}" ``` Once we have pushed the tag, GitHub Actions take over and build a new version from this tag. Since -it is a tag build and a release version (version without SNAPSHOT), the build script will do a couple of additional stuff. -This is all automated in `.ci/build.sh`. - -Note: The property "skip-cli-dist" is activated, so this release command doesn't include pmd-cli and pmd-dist. -They will be released separately after pmd-designer is released. Since pmd-dist is not included in this first -step, no binaries are created yet. +it is a tag build and a release version (version without SNAPSHOT), eventually the workflow "Publish Release" +will be triggered which will upload the release at the various places. This is all automated in +[GitHub Actions Workflows](pmd_devdocs_github_actions_workflows.html). Here is, what happens: @@ -226,51 +216,32 @@ Here is, what happens: . This is done automatically, if the build doesn't fail for any reason. Note, that unit tests are not executed anymore, since they have been run already locally before pushing the tag. - The plugin [nexus-staging-maven-plugin](https://github.com/sonatype/nexus-maven-plugins/tree/master/staging/maven-plugin) - is used to upload and publish the artifacts to maven central. -* Create a draft release on GitHub and upload the release notes from `docs/pages/release_notes.md`. - Note: During the process, the release is a draft mode and not visible yet. - At the end of the process, the release will be published. * Render the documentation in `docs/` with `bundle exec jekyll build` and create a zip file from it. -* Upload the doc zip file to the current (draft) GitHub Release under and - to . -* Upload the documentation to , e.g. and +* Create a release on GitHub and upload the release notes from `docs/pages/pmd_release_notes.md`. + Note: The release is directly published and marked as the latest release. +* Upload all artifacts (binary dist) to . + And select the new binary as the new default for PMD. +* Upload the documentation to , e.g. and create a symlink, so that points to the new version. -* Remove the old snapshot documentation, e.g. so that is gone. - Also create a symlink from pmd-doc-7.2.0-SNAPSHOT to pmd-doc-7.2.0, so that old references still work, e.g. - points to the released version. +* Remove the old snapshot documentation, e.g. so that is gone. + Also create a symlink from pmd-doc-7.15.0-SNAPSHOT to pmd-doc-7.15.0, so that old references still work, e.g. + points to the released version. * Deploy javadoc to "https://docs.pmd-code.org/apidocs/*/RELEASE_VERSION/", e.g. - . This is done for all modules. -* Remove old javadoc for the SNAPSHOT version, e.g. delete . -* Create a draft news post on for the new release. This contains the + . Also create/update symlinks to that the latest javadoc + is available at and redirect old SNAPSHOT to the new version, + so that old references still work, e.g. . + This is done for all modules. +* Create a news post on for the new release. This contains the rendered release notes. * Copy the documentation to sourceforge's web space, so that it is available as - . All previously copied versions are listed + . All previously copied versions are automatically listed under . - -The release on GitHub Actions currently takes about 30-45 minutes. Once this is done, you -can proceed with releasing pmd designer, see . -Make sure to release the version, you have used earlier for the property `pmd-designer.version`. - -Once the pmd-designer release is done, you can proceed with part 2. This is simply triggering manually -a build on GitHub Actions: from the same tag again, but -with the parameter "build_cli_dist_only" set to "true". With this parameter, the script `.ci/build.sh` will -perform the following steps: - -* Build only modules pmd-cli and pmd-dist (via maven parameter `-pl pmd-cli,pmd-dist`). -* Upload the new binaries to the existing draft GitHub Release under . -* Upload the new binaries additionally to sourceforge, so that they can be downloaded from - . -* After all this is done, the release on GitHub () is published - and the news post on sourceforge is published as well. -* The new binary at is - selected as the new default for PMD. * As a last step, a new baseline for the [regression tester](https://github.com/pmd/pmd-regression-tester) is created and uploaded to . * After that, the workflow in is triggered to create and publish a new docker image for the new PMD version. -Once this second GitHub Action run is done, you can spread additional news: +Once the GitHub Action run is done, you can spread additional news: * Write an email to the mailing list @@ -285,9 +256,9 @@ Once this second GitHub Action run is done, you can spread additional news: * Tweet about the new release -Tweet on , eg.: +Tweet on , eg.: - PMD 6.34.0 released: https://github.com/pmd/pmd/releases/tag/pmd_releases/6.34.0 #PMD + PMD 7.15.0 released: https://github.com/pmd/pmd/releases/tag/pmd_releases/7.15.0 #PMD * Post the same twitter message into the gitter chat at @@ -323,9 +294,9 @@ There are a couple of manual steps needed to prepare the current main branch for ```yaml pmd: - version: 7.3.0-SNAPSHOT - previous_version: 7.2.0 - date: 2024-??-?? + version: 7.16.0-SNAPSHOT + previous_version: 7.15.0 + date: 2025-??-?? release_type: minor ``` diff --git a/pom.xml b/pom.xml index d1cf13869df..d17e5039a85 100644 --- a/pom.xml +++ b/pom.xml @@ -575,7 +575,7 @@ - + net.sourceforge.pmd pmd-core From 1a7119ad10012f382e6de3197fac80d8c7c5353b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 19 Jun 2025 16:37:55 +0200 Subject: [PATCH 1037/1962] [ci] Delete old build scripts --- .ci/README.md | 157 --------- .ci/build.sh | 453 -------------------------- .ci/inc/fetch_ci_scripts.bash | 19 -- .ci/inc/pmd-code-api.inc | 93 ------ .ci/inc/pmd-doc.inc | 71 ---- .ci/inc/regression-tester.inc | 93 ------ .github/workflows/old-build.yml | 91 ------ .github/workflows/troubleshooting.yml | 58 ---- 8 files changed, 1035 deletions(-) delete mode 100644 .ci/README.md delete mode 100755 .ci/build.sh delete mode 100644 .ci/inc/fetch_ci_scripts.bash delete mode 100644 .ci/inc/pmd-code-api.inc delete mode 100644 .ci/inc/pmd-doc.inc delete mode 100644 .ci/inc/regression-tester.inc delete mode 100644 .github/workflows/old-build.yml delete mode 100644 .github/workflows/troubleshooting.yml diff --git a/.ci/README.md b/.ci/README.md deleted file mode 100644 index b2ce6f60b89..00000000000 --- a/.ci/README.md +++ /dev/null @@ -1,157 +0,0 @@ -# PMD CI Scripts - -This folder contains scripts used for CI, that are PMD specific. -It uses the common scripts from [build-tools](https://github.com/pmd/build-tools). - -## .ci/files/public-env.gpg - -This files contains the following environment variables: - -* DANGER_GITHUB_API_TOKEN: Token for danger to add comments to PRs as . - The token needs the scope "public_repo". Note: The default GITHUB_TOKEN can't be used, because - danger runs in pull request builds from fork and the default GITHUB_TOKEN has read-only access there - and can't write comments. Therefore the personal access token of the bot account "pmd-test" is used. - pmd-test has no commit permissions, but can comment on any public repo, including pmd/pmd. -* PMD_CI_CHUNK_TOKEN: Token for uploading reports to chunk.io - -The file is encrypted, so that the tokens are not automatically disabled when github detects them -in clear text. - -**Decrypting**: - - gpg --batch --yes --decrypt --passphrase="GnxdjywUEPveyCD1RLiTd7t8CImnefYr" \ - --output .ci/files/public-env .ci/files/public-env.gpg - -**Encrypting**: - - gpg --batch --symmetric --cipher-algo AES256 \ - --armor --passphrase="GnxdjywUEPveyCD1RLiTd7t8CImnefYr" \ - --output .ci/files/public-env.gpg .ci/files/public-env - -## Local tests with docker - -Using the same docker container as described in [build-env @ build-tools](https://github.com/pmd/build-tools). - -### Testing a push build (snapshot) - -Start docker without binding to local directory, so that we can do a fresh checkout - - $ docker run \ - --interactive \ - --tty \ - --name pmd-build-env_pmd \ - pmd-build-env:latest - - -``` -export LANG=en_US.UTF-8 -export PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/main/scripts - -export PMD_CI_SECRET_PASSPHRASE="xyz" -export PMD_CI_DEBUG=true - -MAIN_BRANCH="main" -eval $(~/create-gh-actions-env.sh push pmd/pmd $MAIN_BRANCH) - -cd /workspaces/pmd -rmdir pmd && mkdir pmd -cd pmd -git init -git remote add origin https://github.com/pmd/pmd -git fetch --no-tags --prune --progress --no-recurse-submodules --depth=2 origin +refs/heads/${MAIN_BRANCH}:refs/remotes/origin/${MAIN_BRANCH} -git checkout --progress --force -B ${MAIN_BRANCH} refs/remotes/origin/${MAIN_BRANCH} - - -f=check-environment.sh; \ - mkdir -p .ci && \ - ( [ -e .ci/$f ] || curl -sSL "${PMD_CI_SCRIPTS_URL}/$f" > ".ci/$f" ) && \ - chmod 755 .ci/$f && \ - .ci/$f - -.ci/build.sh -``` - -### Testing a pull request - -Same as the above, but this line changes: - -``` -eval $(~/create-gh-actions-env.sh pull_request pmd/pmd $MAIN_BRANCH) -``` - -Maybe update `/workspaces/event.json` to fill in a real pull request number, so that -danger can comment the correct PR. - -And the checkout must be different. Example for PR 3220: - -``` -PMD_CI_PULL_REQUEST_NUMBER=3220 -cd /workspace/pmd -rmdir pmd && mkdir pmd -cd pmd -git init -git remote add origin https://github.com/pmd/pmd -git fetch --no-tags --prune --progress --no-recurse-submodules --depth=2 origin +refs/pull/${PMD_CI_PULL_REQUEST_NUMBER}/merge:refs/remotes/pull/${PMD_CI_PULL_REQUEST_NUMBER}/merge -git checkout --progress --force refs/remotes/pull/${PMD_CI_PULL_REQUEST_NUMBER}/merge -``` - -### Forked build - -A build executing on a forked repository. - -``` -$(~/create-gh-actions-env.sh push adangel/pmd $MAIN_BRANCH) -``` - - -### Performing a release (push) build - -``` -export LANG=en_US.UTF-8 -export PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/main/scripts - -export PMD_CI_SECRET_PASSPHRASE="xyz" -export PMD_CI_DEBUG=true - -TAG_NAME=pmd_releases/6.33.0 - -eval $(~/create-gh-actions-env.sh push pmd/pmd refs/tags/$TAG_NAME) - -cd /workspaces/pmd -rmdir pmd && mkdir pmd -cd pmd -git init -git remote add origin https://github.com/pmd/pmd -git fetch --no-tags --prune --progress --no-recurse-submodules --depth=2 origin +refs/tags/$TAG_NAME:refs/tags/$TAG_NAME -git checkout --progress --force refs/tags/$TAG_NAME - -f=check-environment.sh; \ - mkdir -p .ci && \ - ( [ -e .ci/$f ] || curl -sSL "${PMD_CI_SCRIPTS_URL}/$f" > ".ci/$f" ) && \ - chmod 755 .ci/$f && \ - .ci/$f - -# -# .ci/build.sh -# -``` - -Calling `.ci/build.sh` directly would re-release the tag $TAG_NAME - that's why it is commented out. -All the side-effects of a release would be carried out like creating and publishing a release on github, -uploading the release to sourceforge, uploading the docs to docs.pmd-code.org, uploading a -new baseline for the regression tester and so on. While the release should be reproducible and therefore should -produce exactly the same artifacts, re-uploading artifacts is not desired just for testing. - -Note that maven-central would not be changed, since this is skipped via MAVEN_OPTS: -`MAVEN_OPTS` contains `-DskipRemoteStaging=true`, so that no maven artifacts are deployed -to maven central (this is set by `create-gh-actions-env.sh`). - -So for now in order to test the build script, you need to manually edit the script and comment out the -critical lines... (like publish github releases, uploading files to sourceforge ...). Later a -"dry-run" mode could be added. - -Make sure to cleanup after the test, e.g. discard the draft github release. - -## Workflow git-repo-sync - -Synchronizes the github git repository pmd/pmd on every push to sourceforge. diff --git a/.ci/build.sh b/.ci/build.sh deleted file mode 100755 index 7c24a458807..00000000000 --- a/.ci/build.sh +++ /dev/null @@ -1,453 +0,0 @@ -#!/usr/bin/env bash - -# Exit this script immediately if a command/function exits with a non-zero status. -set -e - -SCRIPT_INCLUDES="log.bash utils.bash setup-secrets.bash openjdk.bash maven.bash github-releases-api.bash - sourceforge-api.bash pmd-doc.inc pmd-code-api.inc regression-tester.inc" -# shellcheck source=inc/fetch_ci_scripts.bash -source "$(dirname "$0")/inc/fetch_ci_scripts.bash" && fetch_ci_scripts - -function build() { - pmd_ci_log_group_start "Prepare Java 8+11+17+21, Bundler" - pmd_ci_openjdk_install_adoptium 11 - pmd_ci_openjdk_setdefault 11 - PMD_MAVEN_EXTRA_OPTS=() - if [ "$(pmd_ci_utils_get_os)" = "linux" ]; then - pmd_ci_log_info "Install openjdk8 for integration tests and pmd-regression-tests" - pmd_ci_openjdk_install_adoptium 8 - pmd_ci_log_info "Install openjdk17 for integration tests and pmd-regression-tests" - pmd_ci_openjdk_install_adoptium 17 - pmd_ci_log_info "Install openjdk21 for integration tests and pmd-regression-tests" - pmd_ci_openjdk_install_adoptium 21 - PMD_MAVEN_EXTRA_OPTS=( - -Djava8.home="${HOME}/openjdk8" - -Djava17.home="${HOME}/openjdk17" - -Djava21.home="${HOME}/openjdk21" - ) - fi - pmd_ci_build_setup_bundler - pmd_ci_log_group_end - - echo - pmd_ci_maven_display_info_banner - pmd_ci_utils_determine_build_env pmd/pmd - echo - - if pmd_ci_utils_is_fork_or_pull_request; then - pmd_ci_log_group_start "Build with mvnw" - ./mvnw clean install --show-version --errors --batch-mode -Pgenerate-rule-docs "${PMD_MAVEN_EXTRA_OPTS[@]}" - pmd_ci_log_group_end - - # Execute danger and dogfood only for pull requests in our own repository - if [[ "${PMD_CI_IS_FORK}" = "false" && -n "${PMD_CI_PULL_REQUEST_NUMBER}" ]]; then - # Danger is executed only on the linux runner - if [ "$(pmd_ci_utils_get_os)" = "linux" ]; then - pmd_ci_log_group_start "Executing danger" - regression_tester_setup_ci - regression_tester_executeDanger - pmd_ci_log_group_end - - # also run dogfood for PRs (only on linux) - pmd_ci_log_group_start "Executing PMD dogfood test with ${PMD_CI_MAVEN_PROJECT_VERSION}" - pmd_ci_dogfood - pmd_ci_log_group_end - fi - fi - - exit 0 - fi - - # stop early for invalid maven version and branch/tag combination - pmd_ci_maven_verify_version || exit 0 - - # skip tests when doing a release build - this makes the process faster - # it's a manual task now to verify that a release is only started, when the main branch - # was green before. This is usually checked via a local build, see ./do-release.sh - if pmd_ci_maven_isReleaseBuild; then - PMD_MAVEN_EXTRA_OPTS+=(-DskipTests=true) - fi - - # make sure, BUILD_CLI_DIST_ONLY is set to false by default - pmd_ci_log_info "BUILD_CLI_DIST_ONLY=${BUILD_CLI_DIST_ONLY}" - : "${BUILD_CLI_DIST_ONLY:=false}" - pmd_ci_log_info "BUILD_CLI_DIST_ONLY=${BUILD_CLI_DIST_ONLY}" - - if [ "$(pmd_ci_utils_get_os)" != "linux" ]; then - pmd_ci_log_group_start "Build with mvnw verify on $(pmd_ci_utils_get_os)" - if pmd_ci_maven_isReleaseBuild; then - pmd_ci_log_info "This is a release version build..." - # There are two possible (release) builds: - if [ "${BUILD_CLI_DIST_ONLY}" = "false" ]; then - # a) everything without pmd-cli and pmd-dist - ./mvnw clean verify -Dskip-cli-dist --show-version --errors --batch-mode "${PMD_MAVEN_EXTRA_OPTS[@]}" - else - # b) only pmd-cli and pmd-dist - # - # In the first stage build (without pmd-cli and pmd-dist), cyclonedx:makeAggregateBom tries to - # fetch the jars of the to-be-released modules, which don't exist yet. This is recorded in *.lastUpdated - # files in the local repo and might end up in the cache, that is used for this 2nd stage build. - # Trying to delete the files now, if they exist. - # Alternatively, we could run maven with flag "-U" to force update all dependencies... - pmd_ci_log_info "Cleanup local maven repo..." - find ~/.m2/repository -path "*/net/sourceforge/pmd/*/${PMD_CI_MAVEN_PROJECT_VERSION}/*.lastUpdated" -print0 | xargs -0 rm -v - pmd_ci_log_info "Cleanup local maven repo finished." - - ./mvnw clean verify -pl pmd-cli,pmd-dist --show-version --errors --batch-mode "${PMD_MAVEN_EXTRA_OPTS[@]}" - fi - else - # snapshot build - just verify on the different OS - ./mvnw clean verify --show-version --errors --batch-mode "${PMD_MAVEN_EXTRA_OPTS[@]}" - fi - pmd_ci_log_group_end - - pmd_ci_log_info "Stopping build here, because os is not linux" - exit 0 - fi - - # only builds on pmd/pmd on linux continue here - pmd_ci_log_group_start "Setup environment" - pmd_ci_setup_secrets_private_env - pmd_ci_setup_secrets_gpg_key - pmd_ci_setup_secrets_ssh - pmd_ci_build_setup_maven_settings - pmd_ci_log_group_end - - pmd_ci_log_group_start "Build and Deploy" - pmd_ci_build_run - pmd_ci_deploy_build_artifacts - pmd_ci_log_group_end - - pmd_ci_log_group_start "Build and Upload documentation" - pmd_ci_build_and_upload_doc - pmd_ci_log_group_end - - # release is published only for the case b) pmd-cli/pmd-dist release - if pmd_ci_maven_isReleaseBuild && [ "${BUILD_CLI_DIST_ONLY}" = "true" ]; then - pmd_ci_log_group_start "Publishing Release" - pmd_ci_gh_releases_publishRelease "$GH_RELEASE" - pmd_ci_sourceforge_selectDefault "${PMD_CI_MAVEN_PROJECT_VERSION}" - # reconstruct the SF_BLOG_URL - the news entry has been created as draft when running the - # first release stage - local news_title - news_title="PMD ${PMD_CI_MAVEN_PROJECT_VERSION} ($(date -u +%d-%B-%Y)) released" - news_title="${news_title// /-}" - news_title="${news_title//\./}" - news_title="${news_title//\(/}" - news_title="${news_title//\)/}" - news_title="${news_title,,}" # convert to lowercase - SF_BLOG_URL="https://sourceforge.net/rest/p/pmd/news/$(date -u +%Y)/$(date -u +%m)/${news_title// /_}" - pmd_ci_sourceforge_publishBlogPost "$SF_BLOG_URL" - pmd_ci_log_group_end - fi - - # create a baseline for snapshot builds (when pmd-dist is built) - # or for release builds for case b) when pmd-cli/pmd-dist is released - if pmd_ci_maven_isSnapshotBuild || [ "${BUILD_CLI_DIST_ONLY}" = "true" ]; then - pmd_ci_log_group_start "Creating new baseline for regression tester" - regression_tester_setup_ci - regression_tester_uploadBaseline - pmd_ci_log_group_end - fi - - # Trigger docker workflow to build new images for release builds - # but only for case b) pmd-cli/pmd-dist release - if pmd_ci_maven_isReleaseBuild && [ "${BUILD_CLI_DIST_ONLY}" = "true" ]; then - pmd_ci_log_group_start "Trigger docker workflow" - # split semantic version by dot - IFS="." read -ra VERSION_ARRAY <<< "${PMD_CI_MAVEN_PROJECT_VERSION}" - all_tags="" - new_tag="" - for i in "${VERSION_ARRAY[@]}"; do - if [ -z "$new_tag" ]; then - new_tag="${i}" - else - new_tag="${new_tag}.${i}" - fi - all_tags="${all_tags}${new_tag}," - done - all_tags="${all_tags}latest" - echo "version: ${PMD_CI_MAVEN_PROJECT_VERSION}" - echo "tags: ${all_tags}" - - GH_TOKEN="${PMD_ACTIONS_HELPER_TOKEN}" \ - gh api \ - --method POST \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - /repos/pmd/docker/actions/workflows/publish-docker-image.yaml/dispatches \ - -f "ref=main" -f "inputs[version]=${PMD_CI_MAVEN_PROJECT_VERSION}" -f "inputs[tags]=${all_tags}" - pmd_ci_log_group_end - fi - - # - # everything from here runs only on snapshots, not on release builds - # - if pmd_ci_maven_isSnapshotBuild; then - pmd_ci_log_group_start "Executing PMD dogfood test with ${PMD_CI_MAVEN_PROJECT_VERSION}" - pmd_ci_dogfood - pmd_ci_log_group_end - - pmd_ci_log_group_start "Executing build with sonar" - pmd_ci_openjdk_setdefault 17 - # Note: Sonar also needs GITHUB_TOKEN (!) - ./mvnw \ - --show-version --errors --batch-mode \ - clean package \ - sonar:sonar -Dsonar.token="${SONAR_TOKEN}" -Psonar,fastSkip - pmd_ci_log_success "New sonar results: https://sonarcloud.io/dashboard?id=net.sourceforge.pmd%3Apmd" - pmd_ci_log_group_end - - pmd_ci_log_group_start "Executing build with coveralls" - pmd_ci_openjdk_setdefault 17 - export CI_NAME="github actions" - export CI_BUILD_URL="${PMD_CI_JOB_URL}" - export CI_BRANCH="${PMD_CI_BRANCH}" - # first create jacoco report - ./mvnw \ - --show-version --errors --batch-mode \ - clean package \ - jacoco:report -Pcoveralls,fastSkip - - # workaround, maybe https://github.com/jacoco/jacoco/issues/654 - # we use $ as a regex separator, not a shell variable, so no expansion - # shellcheck disable=SC2016 - sed -i 's$Comparisons.kt$ApexTreeBuilder.kt$g' pmd-apex/target/site/jacoco/jacoco.xml - - # then create and send coveralls report - # note: generate-sources is needed, so that antlr4 generated directories are on the compileSourceRoots - ./mvnw \ - --show-version --errors --batch-mode \ - generate-sources \ - coveralls:report -DrepoToken="${COVERALLS_REPO_TOKEN}" -Pcoveralls,fastSkip - - pmd_ci_log_success "New coveralls result: https://coveralls.io/github/pmd/pmd" - pmd_ci_log_group_end - fi -} - - -# -# Bundler should be already installed - it should be included in the ruby distribution. -# Bundler is needed for doc generation and regression tester -# -function pmd_ci_build_setup_bundler() { - pmd_ci_log_info "Checking bundler version..." - bundle --version -} - -function pmd_ci_build_setup_maven_settings() { - pmd_ci_log_info "Setting up maven at ${HOME}/.m2/settings.xml..." - mkdir -p "${HOME}/.m2" - cat > "${HOME}/.m2/settings.xml" < - - - - - - org.sonarsource.scanner.maven - - - - central - \${env.MAVEN_CENTRAL_PORTAL_USERNAME} - \${env.MAVEN_CENTRAL_PORTAL_PASSWORD} - - - - - - - -EOF -} - -# -# Performs the actual build. -# Deploys the artifacts to maven central. -# Also generates rule documentation. -# -function pmd_ci_build_run() { - local mvn_profiles="sign,generate-rule-docs" - - if pmd_ci_maven_isReleaseBuild; then - pmd_ci_log_info "This is a release build" - mvn_profiles="${mvn_profiles},pmd-release" - - # There are two possible (release) builds: - if [ "${BUILD_CLI_DIST_ONLY}" = "false" ]; then - # a) everything without pmd-cli and pmd-dist - ./mvnw clean deploy -P"${mvn_profiles}" -Dskip-cli-dist --show-version --errors --batch-mode "${PMD_MAVEN_EXTRA_OPTS[@]}" - else - # b) only pmd-cli and pmd-dist - ./mvnw clean deploy -P"${mvn_profiles}" -pl pmd-cli,pmd-dist --show-version --errors --batch-mode "${PMD_MAVEN_EXTRA_OPTS[@]}" - fi - else - pmd_ci_log_info "This is a snapshot build" - ./mvnw clean deploy -P"${mvn_profiles}" --show-version --errors --batch-mode "${PMD_MAVEN_EXTRA_OPTS[@]}" - fi - -} - -# -# Deploys the binary distribution -# -function pmd_ci_deploy_build_artifacts() { - if pmd_ci_maven_isSnapshotBuild; then - # Deploy to sourceforge files https://sourceforge.net/projects/pmd/files/pmd/ - pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip" - pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-src.zip" - # Deploy SBOM - pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.xml" - pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.json" - # Sign and deploy the binary dist files - pmd_ci_gpg_sign_file "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip" - pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip.asc" - pmd_ci_gpg_sign_file "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-src.zip" - pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-src.zip.asc" - fi - - # release build case a): everything without pmd-cli and pmd-dist is released - if pmd_ci_maven_isReleaseBuild && [ "${BUILD_CLI_DIST_ONLY}" = "false" ]; then - # create a draft github release - pmd_ci_gh_releases_createDraftRelease "${PMD_CI_TAG}" "$(git rev-list -n 1 "${PMD_CI_TAG}")" - GH_RELEASE="$RESULT" - fi - - # release build case b): only pmd-cli and pmd-dist are released - if pmd_ci_maven_isReleaseBuild && [ "${BUILD_CLI_DIST_ONLY}" = "true" ]; then - # Deploy to sourceforge files https://sourceforge.net/projects/pmd/files/pmd/ - pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip" - pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-src.zip" - # Deploy SBOM - pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.xml" - pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.json" - # Sign and deploy the binary dist files - pmd_ci_gpg_sign_file "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip" - pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip.asc" - pmd_ci_gpg_sign_file "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-src.zip" - pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-src.zip.asc" - - # draft release has already been created - pmd_ci_gh_releases_getLatestDraftRelease - GH_RELEASE="$RESULT" - - # Deploy to github releases - pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip" - pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-src.zip" - # Deploy SBOM - pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.xml" - pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.json" - # Deploy signatures - pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip.asc" - pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-src.zip.asc" - fi -} - -# -# Builds and uploads the documentation site -# Renders release notes and uploads them as ReadMe.md to sourceforge -# -function pmd_ci_build_and_upload_doc() { - # generate the site only for snapshots from main and for release builds for case a) (everything without cli/dist) - # to avoid building it twice during a release... - if pmd_ci_maven_isSnapshotBuild && [ "${PMD_CI_BRANCH}" = "main" ] || [ "${BUILD_CLI_DIST_ONLY}" = "false" ]; then - pmd_doc_generate_jekyll_site - pmd_doc_create_archive - - pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "docs/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-doc.zip" - pmd_ci_gpg_sign_file "docs/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-doc.zip" - pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "docs/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-doc.zip.asc" - - if pmd_ci_maven_isReleaseBuild; then - pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "docs/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-doc.zip" - pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "docs/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-doc.zip.asc" - fi - - # Deploy doc to https://docs.pmd-code.org/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}/ - pmd_code_uploadDocumentation "${PMD_CI_MAVEN_PROJECT_VERSION}" "docs/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-doc.zip" - # Deploy javadoc to https://docs.pmd-code.org/apidocs/*/${PMD_CI_MAVEN_PROJECT_VERSION}/ - pmd_code_uploadJavadoc "${PMD_CI_MAVEN_PROJECT_VERSION}" "$(pwd)" - - # render release notes - # updating github release text - pushd docs || { echo "Directory 'docs' doesn't exist"; exit 1; } - bundle config set --local path vendor/bundle - bundle install - # renders, and skips the first 6 lines - the Jekyll front-matter - local rendered_release_notes - rendered_release_notes=$(bundle exec render_release_notes.rb pages/release_notes.md | tail -n +6) - popd || exit 1 - local release_name - release_name="PMD ${PMD_CI_MAVEN_PROJECT_VERSION} ($(date -u +%d-%B-%Y))" - # Upload to https://sourceforge.net/projects/pmd/files/pmd/${PMD_CI_MAVEN_PROJECT_VERSION}/ReadMe.md - pmd_ci_sourceforge_uploadReleaseNotes "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "${rendered_release_notes}" - fi - - if pmd_ci_maven_isSnapshotBuild && [ "${PMD_CI_BRANCH}" = "main" ]; then - # only for snapshot builds from branch main: https://docs.pmd-code.org/snapshot -> pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION} - pmd_code_createSymlink "${PMD_CI_MAVEN_PROJECT_VERSION}" "snapshot" - - # update github pages https://pmd.github.io/pmd/ - pmd_doc_publish_to_github_pages - # rsync site to https://pmd.sourceforge.io/snapshot - pmd_ci_sourceforge_rsyncSnapshotDocumentation "${PMD_CI_MAVEN_PROJECT_VERSION}" "snapshot" - fi - - if pmd_ci_maven_isReleaseBuild && [ "${BUILD_CLI_DIST_ONLY}" = "false" ]; then - # documentation is already uploaded to https://docs.pmd-code.org/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION} - # we only need to setup symlinks for the released version - pmd_code_createSymlink "${PMD_CI_MAVEN_PROJECT_VERSION}" "latest" - # remove old doc and point to the new version - pmd_code_removeDocumentation "${PMD_CI_MAVEN_PROJECT_VERSION}-SNAPSHOT" - pmd_code_createSymlink "${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}-SNAPSHOT" - # remove old javadoc - pmd_code_removeJavadoc "${PMD_CI_MAVEN_PROJECT_VERSION}-SNAPSHOT" - - # github release only for releases - pmd_ci_gh_releases_updateRelease "$GH_RELEASE" "$release_name" "${rendered_release_notes}" - - local rendered_release_notes_with_links - rendered_release_notes_with_links=" -* Downloads: https://github.com/pmd/pmd/releases/tag/pmd_releases%2F${PMD_CI_MAVEN_PROJECT_VERSION} -* Documentation: https://docs.pmd-code.org/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}/ - -${rendered_release_notes}" - pmd_ci_sourceforge_createDraftBlogPost "${release_name} released" "${rendered_release_notes_with_links}" "pmd,release" - SF_BLOG_URL="${RESULT}" - - # rsync site to https://pmd.sourceforge.io/pmd-${PMD_CI_MAVEN_PROJECT_VERSION} - pmd_ci_sourceforge_rsyncSnapshotDocumentation "${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-${PMD_CI_MAVEN_PROJECT_VERSION}" - fi -} - -# -# Runs the dogfood ruleset with the currently built pmd against itself -# -function pmd_ci_dogfood() { - local mpmdVersion=() - ./mvnw versions:set -DnewVersion="${PMD_CI_MAVEN_PROJECT_VERSION%-SNAPSHOT}-dogfood-SNAPSHOT" -DgenerateBackupPoms=false - sed -i 's/[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}.*<\/version>\( *\)/'"${PMD_CI_MAVEN_PROJECT_VERSION}"'<\/version>\1/' pom.xml - ./mvnw verify --show-version --errors --batch-mode "${PMD_MAVEN_EXTRA_OPTS[@]}" \ - "${mpmdVersion[@]}" \ - -DskipTests \ - -Dmaven.javadoc.skip=true \ - -Dmaven.source.skip=true \ - -Dcheckstyle.skip=true - ./mvnw versions:set -DnewVersion="${PMD_CI_MAVEN_PROJECT_VERSION}" -DgenerateBackupPoms=false - git checkout -- pom.xml -} - -function pmd_ci_gpg_sign_file() { - local fileToSign="$1" - pmd_ci_log_info "Signing file ${fileToSign}..." - printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty --status-fd 1 --armor --detach-sign --sign "$fileToSign" -} - -build - -exit 0 diff --git a/.ci/inc/fetch_ci_scripts.bash b/.ci/inc/fetch_ci_scripts.bash deleted file mode 100644 index 835fe6782ee..00000000000 --- a/.ci/inc/fetch_ci_scripts.bash +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash - -function fetch_ci_scripts() { - local inc_dir - local inc_url - inc_dir="$(dirname "$0")/inc" - inc_url="${PMD_CI_SCRIPTS_URL:-https://raw.githubusercontent.com/pmd/build-tools/main/scripts}/inc" - - mkdir -p "${inc_dir}" - - for f in ${SCRIPT_INCLUDES}; do - if [ ! -e "${inc_dir}/$f" ]; then - curl -sSL "${inc_url}/$f" > "${inc_dir}/$f" - fi - [ "$PMD_CI_DEBUG" = "true" ] && echo "loading ${inc_dir}/$f in ${MODULE:-$0}" - # shellcheck source=/dev/null - source "${inc_dir}/$f" || exit 1 - done -} diff --git a/.ci/inc/pmd-code-api.inc b/.ci/inc/pmd-code-api.inc deleted file mode 100644 index e28eaf5767c..00000000000 --- a/.ci/inc/pmd-code-api.inc +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/env bash - -MODULE="pmd-code-api" -SCRIPT_INCLUDES="log.bash" -# shellcheck source=inc/fetch_ci_scripts.bash -source "$(dirname "$0")/inc/fetch_ci_scripts.bash" && fetch_ci_scripts - -PMD_CODE_SSH_USER=pmd -PMD_CODE_DOCS_PATH=/docs.pmd-code.org/ - -function pmd_code_uploadDocumentation() { - local -r pmdVersion="$1" - local -r filename="$2" - local -r basefilename="$(basename "$filename")" - - pmd_ci_log_debug "${FUNCNAME[0]} pmdVersion=$pmdVersion filename=$filename" - - scp "${filename}" ${PMD_CODE_SSH_USER}@pmd-code.org:${PMD_CODE_DOCS_PATH} - # shellcheck disable=SC2029 - ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \ - ( test -h pmd-doc-${pmdVersion} && rm pmd-doc-${pmdVersion} || true ) && \ - unzip -qo \"${basefilename}\" && \ - rm \"${basefilename}\"" - pmd_ci_log_info "Docs updated: https://docs.pmd-code.org/pmd-doc-${pmdVersion}/" -} - -function pmd_code_removeDocumentation() { - local pmdVersion="$1" - - pmd_ci_log_debug "${FUNCNAME[0]} pmdVersion=$pmdVersion" - - # shellcheck disable=SC2029 - ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \ - rm -rf \"pmd-doc-${pmdVersion}/\"" - pmd_ci_log_info "Removed docs: https://docs.pmd-code.org/pmd-doc-${pmdVersion}/" -} - -function pmd_code_createSymlink() { - local -r pmdVersion="$1" - local -r name="$2" - - pmd_ci_log_debug "${FUNCNAME[0]} pmdVersion=$pmdVersion name=$name" - - # shellcheck disable=SC2029 - ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \ - rm -f \"$name\" && \ - ln -s \"pmd-doc-${pmdVersion}\" \"$name\"" - pmd_ci_log_info "Symlink created: https://docs.pmd-code.org/$name/ -> https://docs.pmd-code.org/pmd-doc-${pmdVersion}/" -} - -function pmd_code_uploadJavadoc() { - local -r pmdVersion="$1" - local -r basePath="$2" - - pmd_ci_log_debug "${FUNCNAME[0]} pmdVersion=$pmdVersion basePath=$basePath" - - for i in "${basePath}"/*/target/*-javadoc.jar */*/target/*-javadoc.jar; do - pmd_code_uploadJavadocModule "$pmdVersion" "$i" - done - - # make sure https://docs.pmd-code.org/apidocs/ shows directory index - # shellcheck disable=SC2029 - ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}/apidocs\" && \ - echo 'Options +Indexes' > .htaccess" - pmd_ci_log_info "Directory index enabled for https://docs.pmd-code.org/apidocs/" -} - -function pmd_code_uploadJavadocModule() { - local -r pmdVersion="$1" - local -r moduleJavadocJar="$2" - local -r moduleJavadocJarBasename="$(basename "$moduleJavadocJar")" - local -r module=${moduleJavadocJarBasename%%-${pmdVersion}-javadoc.jar} - - pmd_ci_log_debug "${FUNCNAME[0]} pmdVersion=$pmdVersion moduleJavadocJar=$moduleJavadocJar module=$module" - - scp "$moduleJavadocJar" ${PMD_CODE_SSH_USER}@pmd-code.org:${PMD_CODE_DOCS_PATH} - # shellcheck disable=SC2029 - ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \ - mkdir -p \"apidocs/${module}/${pmdVersion}\" && \ - unzip -qo -d \"apidocs/${module}/${pmdVersion}\" \"${moduleJavadocJarBasename}\" && \ - rm \"${moduleJavadocJarBasename}\"" - pmd_ci_log_info "JavaDoc for $module uploaded: https://docs.pmd-code.org/apidocs/${module}/${pmdVersion}/" -} - -function pmd_code_removeJavadoc() { - local -r pmdVersion="$1" - - pmd_ci_log_debug "${FUNCNAME[0]} pmdVersion=$pmdVersion" - # shellcheck disable=SC2029 - ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \ - rm -rf apidocs/*/\"${pmdVersion}\"" - pmd_ci_log_info "Removed Javadoc: https://docs.pmd-code.org/apidocs/*/${pmdVersion}/ is gone" -} diff --git a/.ci/inc/pmd-doc.inc b/.ci/inc/pmd-doc.inc deleted file mode 100644 index baba63d43f3..00000000000 --- a/.ci/inc/pmd-doc.inc +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env bash - -MODULE="pmd-doc" -SCRIPT_INCLUDES="log.bash" -# shellcheck source=inc/fetch_ci_scripts.bash -source "$(dirname "$0")/inc/fetch_ci_scripts.bash" && fetch_ci_scripts - -# Used env vars: -# PMD_CI_JOB_URL -# PMD_CI_PUSH_COMMIT_COMPARE - - -# -# Executes jekyll and generates the documentation -# The documentation will be generated in the directory "docs/_site". -# -function pmd_doc_generate_jekyll_site() { - pushd docs || { echo "Directory 'docs' doesn't exist"; exit 1; } - - echo -e "\n\n" - pmd_ci_log_info "Building documentation using jekyll..." - bundle config set --local path vendor/bundle - bundle install - bundle exec jekyll build - - popd || exit 1 -} - -# -# Creates the pmd-doc.zip archive. It will be placed in "docs/". -# -function pmd_doc_create_archive() { - pushd docs || { echo "Directory 'docs' doesn't exist"; exit 1; } - - echo -e "\n\n" - pmd_ci_log_info "Creating pmd-doc archive..." - mv _site "pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}" - zip -qr "pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-doc.zip" "pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}/" - pmd_ci_log_success "Successfully created pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-doc.zip" - - popd || exit 1 -} - -# -# Updates github pages branch "gh-pages" of the main repository, -# so that https://pmd.github.io/pmd/ has the latest (snapshot) content -# -function pmd_doc_publish_to_github_pages() { - echo -e "\n\n" - pmd_ci_log_info "Pushing the new site to github pages..." - git clone --branch gh-pages --depth 1 --origin origin https://github.com/pmd/pmd.git pmd-gh-pages - # clear the files first - rm -rf pmd-gh-pages/* - # copy the new site - cp -a "docs/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}"/* pmd-gh-pages/ - ( - cd pmd-gh-pages || { echo "Directory 'pmd-gh-pages' doesn't exist"; exit 1; } - git config user.name "PMD CI (pmd-bot)" - git config user.email "pmd-bot@users.noreply.github.com" - git config --local http.https://github.com/.extraheader "AUTHORIZATION: basic $(echo -n "x-access-token:${GITHUB_TOKEN}"|base64)" - git add -A - MSG="Update documentation - -${PMD_CI_JOB_URL} -${PMD_CI_PUSH_COMMIT_COMPARE}" - git commit -q -m "$MSG" - git push origin HEAD:gh-pages - git config --local --unset-all http.https://github.com/.extraheader - pmd_ci_log_success "Successfully pushed site to https://pmd.github.io/pmd/" - ) -} diff --git a/.ci/inc/regression-tester.inc b/.ci/inc/regression-tester.inc deleted file mode 100644 index ef60cba5a29..00000000000 --- a/.ci/inc/regression-tester.inc +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/env bash - -MODULE="pmd-doc" -SCRIPT_INCLUDES="log.bash openjdk.bash" -# shellcheck source=inc/fetch_ci_scripts.bash -source "$(dirname "$0")/inc/fetch_ci_scripts.bash" && fetch_ci_scripts - -# -# The functions here require the following environment variables: -# PMD_CI_BRANCH -# -# GITHUB_TOKEN -# PMD_CI_CHUNK_TOKEN - -function regression_tester_setup_ci() { - gpg --batch --yes --decrypt --passphrase="GnxdjywUEPveyCD1RLiTd7t8CImnefYr" \ - --output .ci/files/public-env .ci/files/public-env.gpg - # shellcheck disable=SC1091 - source .ci/files/public-env >/dev/null 2>&1 - rm .ci/files/public-env - - if hash "bundle" 2>/dev/null; then - pmd_ci_log_debug "Bundler is already installed" - bundle --version - else - pmd_ci_log_info "Installing bundler..." - gem install bundler - fi - - rm -f .bundle/config - bundle config set --local gemfile .ci/files/Gemfile - bundle config set --local path vendor/bundle - bundle config set --local with release_notes_preprocessing - bundle install -} - -# -# Generate a new baseline and upload it to pmd-code.org -# -function regression_tester_uploadBaseline() { - local pmdcodeUrl="https://pmd-code.org/pmd-regression-tester/" - local baseline_branch="${PMD_CI_BRANCH:-$PMD_CI_TAG}" - pmd_ci_log_debug "${FUNCNAME[0]} branch=${baseline_branch}" - - pmd_ci_log_info "Generating and uploading baseline for pmdtester (${baseline_branch})..." - pushd .. - rm -f .bundle/config - bundle config set --local gemfile pmd/.ci/files/Gemfile - bundle config set --local path vendor/bundle - bundle exec pmdtester \ - --mode single \ - --local-git-repo ./pmd \ - --patch-branch "${baseline_branch}" \ - --patch-config ./pmd/.ci/files/all-regression-rules.xml \ - --list-of-project ./pmd/.ci/files/project-list.xml --html-flag \ - --threads "$(nproc)" \ - --error-recovery - pushd target/reports || { echo "Directory 'target/reports' doesn't exist"; exit 1; } - BRANCH_FILENAME="${baseline_branch/\//_}" - zip -q -r "${BRANCH_FILENAME}-baseline.zip" "${BRANCH_FILENAME}/" - # ssh-key for pmd-code.org is setup already by pmd_ci_setup_secrets_ssh - scp "${BRANCH_FILENAME}-baseline.zip" pmd@pmd-code.org:/httpdocs/pmd-regression-tester/ - pmd_ci_log_success "Successfully uploaded ${BRANCH_FILENAME}-baseline.zip to ${pmdcodeUrl}" - popd || exit 1 - popd || exit 1 -} - -# -# Execute danger, which executes pmd-regression-tester (via Dangerfile). -# -function regression_tester_executeDanger() { - pmd_ci_log_debug "${FUNCNAME[0]}" - - # git clone initially only fetched with depth 2. Danger and regression tester - # need more history, so we'll fetch more here - # and create local branches as well (${PMD_CI_BRANCH} and pr-fetch) - - pmd_ci_log_info "Fetching 25 commits for ${PMD_CI_BRANCH} and pull/${PMD_CI_PULL_REQUEST_NUMBER}/head" - git fetch --no-tags --depth=25 origin "${PMD_CI_BRANCH}:${PMD_CI_BRANCH}" "pull/${PMD_CI_PULL_REQUEST_NUMBER}/head:pr-fetch" - - # if the PR is older, base might have advanced more than 25 commits... fetch more, up to 150 - for i in $(seq 1 3); do - if [ -z "$( git merge-base "${PMD_CI_BRANCH}" "pr-fetch" )" ]; then - pmd_ci_log_info "No merge-base yet - fetching more commits... (try $i)" - git fetch --no-tags --deepen=50 origin "${PMD_CI_BRANCH}:" "pull/${PMD_CI_PULL_REQUEST_NUMBER}/head:pr-fetch" - fi - done - pmd_ci_log_info "Merge base is: $( git merge-base "${PMD_CI_BRANCH}" "pr-fetch" )" - - pmd_ci_log_info "Running danger on branch ${PMD_CI_BRANCH}" - bundle exec danger --verbose - pmd_ci_log_success "Executed danger successfully" -} diff --git a/.github/workflows/old-build.yml b/.github/workflows/old-build.yml deleted file mode 100644 index c7329fc0e1b..00000000000 --- a/.github/workflows/old-build.yml +++ /dev/null @@ -1,91 +0,0 @@ -name: old-build - -on: - workflow_dispatch: - inputs: - build_cli_dist_only: - description: "Build only modules cli and dist" - required: true - type: boolean - default: false - -permissions: - contents: read # to fetch code (actions/checkout) - -jobs: - build: - runs-on: ${{ matrix.os }} - permissions: - # read to fetch code (actions/checkout) - # write to push code to gh-pages, create releases - # note: forked repositories will have maximum read access - contents: write - continue-on-error: false - strategy: - matrix: - os: [ ubuntu-latest, windows-latest, macos-latest ] - if: ${{ !contains(github.event.head_commit.message, '[skip ci]') }} - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 2 - - uses: actions/cache@v4 - with: - path: | - ~/.m2/repository - ~/.gradle/caches - ~/.cache - ~/work/pmd/target/repositories - vendor/bundle - key: v3-${{ runner.os }}-${{ hashFiles('**/pom.xml') }} - restore-keys: | - v3-${{ runner.os }}- - - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@v1 - with: - ruby-version: 3.3 - - name: Setup Environment - shell: bash - run: | - echo "LANG=en_US.UTF-8" >> $GITHUB_ENV - echo "MAVEN_OPTS=-Daether.connector.http.connectionMaxTtl=180 -DautoReleaseAfterClose=true -DstagingProgressTimeoutMinutes=30" >> $GITHUB_ENV - echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/30/scripts" >> $GITHUB_ENV - - name: Check Environment - shell: bash - run: | - f=check-environment.sh; \ - mkdir -p .ci && \ - ( [ -e .ci/$f ] || curl -sSL "${PMD_CI_SCRIPTS_URL}/$f" > ".ci/$f" ) && \ - chmod 755 .ci/$f && \ - .ci/$f - - uses: actions/create-github-app-token@v2 - id: pmd-actions-helper-app-token - # only run in the official pmd repo, where we have access to the secrets and not on forks - if: github.repository == 'pmd/pmd' - with: - app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} - private-key: ${{ secrets.PMD_ACTIONS_HELPER_PRIVATE_KEY }} - owner: ${{ github.repository_owner }} - repositories: docker - permission-actions: write - - name: Build - run: .ci/build.sh - shell: bash - env: - BUILD_CLI_DIST_ONLY: ${{ inputs.build_cli_dist_only }} - PMD_CI_SECRET_PASSPHRASE: ${{ secrets.PMD_CI_SECRET_PASSPHRASE }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PMD_CI_GPG_PRIVATE_KEY: ${{ secrets.PMD_CI_GPG_PRIVATE_KEY }} - MAVEN_GPG_PASSPHRASE: ${{ secrets.PMD_CI_GPG_PASSPHRASE }} - PMD_ACTIONS_HELPER_TOKEN: ${{ steps.pmd-actions-helper-app-token.outputs.token }} - MAVEN_CENTRAL_PORTAL_USERNAME: ${{ secrets.MAVEN_CENTRAL_PORTAL_USERNAME }} - MAVEN_CENTRAL_PORTAL_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PORTAL_PASSWORD }} - - name: Workaround actions/upload-artifact#176 - run: | - echo "artifacts_path=$(realpath ..)" >> $GITHUB_ENV - - name: Upload regression tester report - uses: actions/upload-artifact@v4 - with: - name: pmd-regression-tester - path: ${{ env.artifacts_path }}/target/pr-*-diff-report-*.tar.gz - if-no-files-found: ignore diff --git a/.github/workflows/troubleshooting.yml b/.github/workflows/troubleshooting.yml deleted file mode 100644 index a4562892230..00000000000 --- a/.github/workflows/troubleshooting.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: troubleshooting - -on: workflow_dispatch - -permissions: - contents: read - -jobs: - build: - runs-on: ${{ matrix.os }} - continue-on-error: false - strategy: - matrix: - #os: [ ubuntu-latest, windows-latest, macos-latest ] - os: [ ubuntu-latest ] - - steps: - - uses: actions/checkout@v4 - - uses: actions/cache@v4 - with: - path: | - ~/.m2/repository - ~/.gradle/caches - ~/.cache - ~/work/pmd/target/repositories - vendor/bundle - key: v3-${{ runner.os }}-${{ hashFiles('**/pom.xml') }} - restore-keys: | - v3-${{ runner.os }}- - - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@v1 - with: - ruby-version: 3.3 - - name: Setup Environment - shell: bash - run: | - echo "LANG=en_US.UTF-8" >> $GITHUB_ENV - echo "MAVEN_OPTS=-Daether.connector.http.connectionMaxTtl=180 -DstagingProgressTimeoutMinutes=30" >> $GITHUB_ENV - echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/30/scripts" >> $GITHUB_ENV - - name: Check Environment - shell: bash - run: | - f=check-environment.sh; \ - mkdir -p .ci && \ - ( [ -e .ci/$f ] || curl -sSL "${PMD_CI_SCRIPTS_URL}/$f" > ".ci/$f" ) && \ - chmod 755 .ci/$f && \ - .ci/$f - - name: Build - run: | - f=openjdk.bash; \ - mkdir -p .ci/inc && \ - ( [ -e .ci/inc/$f ] || curl -sSL "${PMD_CI_SCRIPTS_URL}/inc/$f" > ".ci/inc/$f" ) && \ - source .ci/inc/$f ; \ - pmd_ci_openjdk_install_adoptium 11 ; \ - pmd_ci_openjdk_setdefault 11 - shell: bash - - name: Setup tmate session - uses: mxschmitt/action-tmate@v3 From 687a7df05ff8e4edf5ed1fc2354328e2420325cc Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 19 Jun 2025 16:49:49 +0200 Subject: [PATCH 1038/1962] Bump maven from 3.9.8 to 3.9.10 (#5807) --- .mvn/wrapper/maven-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index f95f1ee8071..2f94e616987 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -16,4 +16,4 @@ # under the License. wrapperVersion=3.3.2 distributionType=only-script -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.8/apache-maven-3.9.8-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.10/apache-maven-3.9.10-bin.zip From f27495687bbdd06cd0ca10f29e9625e6a0b84cdf Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Fri, 20 Jun 2025 13:52:15 +0200 Subject: [PATCH 1039/1962] #2304: Review findings for static on-demand imports: Only support cases also supported by JavaDoc --- .../pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java | 2 +- .../pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java index 0a939aa7e28..31970158ad9 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryImportRule.java @@ -453,7 +453,7 @@ private void removeReferenceOnDemandImport(String referenceName) { final ASTImportDeclaration importNode = it.node; if (importNode.isImportOnDemand()) { final JClassSymbol symbol = TypesFromReflection.loadSymbol(importNode.getTypeSystem(), importNode.getImportedName()); - return symbol != null && (symbol.getSimpleName().equals(referenceName) || symbol.getDeclaredField(referenceName) != null || symbol.getDeclaredClass(referenceName) != null); + return symbol != null && symbol.getDeclaredClass(referenceName) != null; } return false; diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml index 139b4792b23..d031d3ae02c 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml @@ -1359,7 +1359,8 @@ public class C { #2304: [java] static on-demand field import in javadoc - 0 + 1 + 1 #2304: [java] static on-demand method import in javadoc - 0 + 1 + 1 Date: Fri, 20 Jun 2025 20:27:45 +0200 Subject: [PATCH 1040/1962] [doc] Update release notes --- docs/pages/release_notes.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 0c9c0dd3524..b4d7ae941c8 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -28,6 +28,12 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿšจ API Changes +### ๐Ÿ’ต Financial Contributions + +Many thanks to our sponsors: + +* [Cybozu](https://github.com/cybozu) (@cybozu) + ### โœจ Merged pull requests From 1be8392301bb85b31135be6a484a1eb367ce0cbd Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 20 Jun 2025 20:38:24 +0200 Subject: [PATCH 1041/1962] Update @Pankraz76 as a contributor --- .all-contributorsrc | 3 ++- docs/pages/pmd/projectdocs/credits.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index f2dd0096924..278cd73d2c4 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8138,7 +8138,8 @@ "avatar_url": "https://avatars.githubusercontent.com/u/8830888?v=4", "profile": "https://github.com/Pankraz76", "contributions": [ - "code" + "code", + "bug" ] } ], diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 584f4bec916..f6a3f3de65a 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -636,7 +636,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
    - + From dd1f995f8181949527d69b3f296e9ca64ae0217c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 22 Jun 2025 14:51:24 +0200 Subject: [PATCH 1042/1962] [doc] Update release notes (#5818, #2304) --- docs/pages/release_notes.md | 3 +++ .../pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 25ace786e57..172f8696ac4 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,12 +25,15 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* java-codestyle + * [#2304](https://github.com/pmd/pmd/issues/2304): \[java] UnnecessaryImport false positive for on-demand imports in JavaDoc ### ๐Ÿšจ API Changes ### โœจ Merged pull requests * [#5738](https://github.com/pmd/pmd/pull/5738): chore: Remove unused private methods in test classes - [Pankraz76](https://github.com/Pankraz76) (@Pankraz76) +* [#5818](https://github.com/pmd/pmd/pull/5818): Fix #2304: \[java] UnnecessaryImport FP for on-demand imports in JavaDoc - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) ### ๐Ÿ“ฆ Dependency updates diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml index d031d3ae02c..9b1b719371e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml @@ -1362,7 +1362,7 @@ public class C { 1 1 1 1 Date: Sun, 22 Jun 2025 21:59:15 +0200 Subject: [PATCH 1043/1962] Rule-Test schema now at version 1.1.0 --- docs/pages/pmd/userdocs/extending/testing.md | 8 +- .../rule/errorprone/xml/AvoidHardcodingId.xml | 2 +- .../xml/UnnecessaryWarningSuppression.xml | 2 +- .../bestpractices/xml/UnusedAssignment.xml | 2 +- .../xml/UnusedFormalParameter.xml | 2 +- .../bestpractices/xml/UnusedLocalVariable.xml | 2 +- .../bestpractices/xml/UnusedPrivateMethod.xml | 2 +- .../codestyle/xml/BooleanGetMethodName.xml | 2 +- .../rule/documentation/xml/CommentContent.xml | 2 +- .../rule/documentation/xml/CommentSize.xml | 2 +- .../rule/errorprone/xml/CloseResource.xml | 2 +- .../xml/ImplicitSwitchFallThrough.xml | 2 +- .../errorprone/xml/NonSerializableClass.xml | 2 +- .../pmd/test/schema/TestSchemaVersion.java | 2 +- .../pmd/test/schema/rule-tests_1_0_0.xsd | 20 +-- .../pmd/test/schema/rule-tests_1_1_0.xsd | 133 ++++++++++++++++++ .../pmd/test/schema/TestSchemaParserTest.java | 6 +- .../src/main/resources/rule-tests_1_0_0.xsd | 20 +-- .../src/main/resources/rule-tests_1_1_0.xsd | 133 ++++++++++++++++++ 19 files changed, 290 insertions(+), 56 deletions(-) create mode 100644 pmd-test-schema/src/main/resources/net/sourceforge/pmd/test/schema/rule-tests_1_1_0.xsd create mode 100644 pmd-test/src/main/resources/rule-tests_1_1_0.xsd diff --git a/docs/pages/pmd/userdocs/extending/testing.md b/docs/pages/pmd/userdocs/extending/testing.md index 13206f35dfd..4340f66a44b 100644 --- a/docs/pages/pmd/userdocs/extending/testing.md +++ b/docs/pages/pmd/userdocs/extending/testing.md @@ -101,7 +101,7 @@ This is a stripped down example which just contains two test cases. + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.github.io/schema/rule-tests_1_1_0.xsd"> concrete class @@ -132,7 +132,7 @@ The root element is ``. It can contain one or more `` and Each `` element defines a single test case. `` elements are used to share code snippets between different test cases. -{%include note.html content="The XML schema is available at [rule-tests.xsd](https://github.com/pmd/pmd/blob/main/pmd-test-schema/src/main/resources/net/sourceforge/pmd/test/schema/rule-tests_1_0_0.xsd)." %} +{%include note.html content="The XML schema is available at [rule-tests.xsd](https://github.com/pmd/pmd/blob/main/pmd-test-schema/src/main/resources/net/sourceforge/pmd/test/schema/rule-tests_1_1_0.xsd)." %} ### `` attributes @@ -173,7 +173,7 @@ The `` elements understands the following optional attributes: @SuppressWarnings ``` - This is available since PMD 7.15.0. + This is available since PMD 7.15.0 (rule-test schema version 1.1.0). * **``**: Either the `` element or the `` element is required. It provides the actual code snippet on which the rule is executed. The code itself is usually wrapped in a "CDATA" section, so that no @@ -200,7 +200,7 @@ in a "CDATA" section, so that no further XML escapes (entity references such as + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.sourceforge.io/rule-tests_1_1_0.xsd"> Just a description, will be used as the test name for JUnit in the reports diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/AvoidHardcodingId.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/AvoidHardcodingId.xml index 1c66afd6e26..50fb56ee985 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/AvoidHardcodingId.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/errorprone/xml/AvoidHardcodingId.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.github.io/schema/rule-tests_1_1_0.xsd"> Non compliant scenario: Hardcoded Id diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnnecessaryWarningSuppression.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnnecessaryWarningSuppression.xml index 5b556c5581f..d8aa5101f06 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnnecessaryWarningSuppression.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnnecessaryWarningSuppression.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.github.io/schema/rule-tests_1_1_0.xsd"> comment suppression (baseline) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedAssignment.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedAssignment.xml index ae39cf1b4de..7d253ad2b5e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedAssignment.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedAssignment.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.github.io/schema/rule-tests_1_1_0.xsd"> NPE on nested record decl #3224 diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedFormalParameter.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedFormalParameter.xml index 821c74cdfda..f069757a657 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedFormalParameter.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedFormalParameter.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.github.io/schema/rule-tests_1_1_0.xsd"> failure case diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml index 9a3a58f1ff3..517db4e2c45 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.github.io/schema/rule-tests_1_1_0.xsd"> unused local with assignment diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index 47da44fcae6..09611c5dad7 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.github.io/schema/rule-tests_1_1_0.xsd"> private method called by public method diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/BooleanGetMethodName.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/BooleanGetMethodName.xml index 44e72f7d20f..98116ca6bcb 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/BooleanGetMethodName.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/BooleanGetMethodName.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.github.io/schema/rule-tests_1_1_0.xsd"> Bad name diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentContent.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentContent.xml index 0dd4dc455c4..4440db34ce3 100755 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentContent.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentContent.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.github.io/schema/rule-tests_1_1_0.xsd"> Includes bad words diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentSize.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentSize.xml index 36c33dbb612..5b9e0a275b8 100755 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentSize.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentSize.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.github.io/schema/rule-tests_1_1_0.xsd"> Too many lines diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml index c1ce4e9364e..4b6cdb5d134 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.github.io/schema/rule-tests_1_1_0.xsd"> connection is closed, ok diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ImplicitSwitchFallThrough.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ImplicitSwitchFallThrough.xml index 08736473966..2f354e11e4a 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ImplicitSwitchFallThrough.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ImplicitSwitchFallThrough.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.github.io/schema/rule-tests_1_1_0.xsd"> one case, which is not empty diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/NonSerializableClass.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/NonSerializableClass.xml index cfbd3b8166d..f82316023a9 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/NonSerializableClass.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/NonSerializableClass.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.github.io/schema/rule-tests_1_1_0.xsd"> Example code diff --git a/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/TestSchemaVersion.java b/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/TestSchemaVersion.java index 0ea49e1f415..dc152539d83 100644 --- a/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/TestSchemaVersion.java +++ b/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/TestSchemaVersion.java @@ -18,7 +18,7 @@ * @author Clรฉment Fournier */ enum TestSchemaVersion { - V1("rule-tests_1_0_0.xsd", new BaseTestParserImpl.ParserV1()); + V1("rule-tests_1_1_0.xsd", new BaseTestParserImpl.ParserV1()); private final Schema schema; private String schemaLoc; diff --git a/pmd-test-schema/src/main/resources/net/sourceforge/pmd/test/schema/rule-tests_1_0_0.xsd b/pmd-test-schema/src/main/resources/net/sourceforge/pmd/test/schema/rule-tests_1_0_0.xsd index 0795747654f..eb6164a5910 100644 --- a/pmd-test-schema/src/main/resources/net/sourceforge/pmd/test/schema/rule-tests_1_0_0.xsd +++ b/pmd-test-schema/src/main/resources/net/sourceforge/pmd/test/schema/rule-tests_1_0_0.xsd @@ -1,4 +1,6 @@ + + - - - Declares the expected suppressed violations. Since 7.15.0. - - - - - - - - - - - - - - - diff --git a/pmd-test-schema/src/main/resources/net/sourceforge/pmd/test/schema/rule-tests_1_1_0.xsd b/pmd-test-schema/src/main/resources/net/sourceforge/pmd/test/schema/rule-tests_1_1_0.xsd new file mode 100644 index 00000000000..18b638ad5d0 --- /dev/null +++ b/pmd-test-schema/src/main/resources/net/sourceforge/pmd/test/schema/rule-tests_1_1_0.xsd @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + A code fragment that can be referred to by several tests. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Declares the expected suppressed violations. Since PMD 7.15.0 / rule-tests 1.1.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + Language version of the source, eg 'java 8'. + + + + + + + + This attribute is deprecated, it is assumed true and ignored. + + + + + + + This attribute is deprecated. Use "disabled" instead. + If this attribute is set to "false", then the test is ignored. + + + + + + + This attribute is deprecated, it is assumed true and ignored. + + + + + + + + A reason why the test is disabled/ignored should be provided as a comment for the test. + + + + + + + If true, only this test will be executed, and all others will be disabled. + If several tests in the same file are focused, then the last one wins, in + document order. + This attribute is provided as a way for developers to temporarily focus on a single test. + Test files with a focused test should not be checked in. For this reason, + using this attribute produces a warning. + + + + + + + + + + + + + diff --git a/pmd-test-schema/src/test/java/net/sourceforge/pmd/test/schema/TestSchemaParserTest.java b/pmd-test-schema/src/test/java/net/sourceforge/pmd/test/schema/TestSchemaParserTest.java index de312e450ab..bb689e9d0ef 100644 --- a/pmd-test-schema/src/test/java/net/sourceforge/pmd/test/schema/TestSchemaParserTest.java +++ b/pmd-test-schema/src/test/java/net/sourceforge/pmd/test/schema/TestSchemaParserTest.java @@ -147,7 +147,7 @@ void withExpectedSuppressions() throws IOException { + "\n" + " xmlns=\"http://pmd.sourceforge.net/rule-tests\"\n" + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" - + " xsi:schemaLocation=\"http://pmd.sourceforge.net/rule-tests net/sourceforge/pmd/test/schema/rule-tests_1_0_0.xsd\">\n" + + " xsi:schemaLocation=\"http://pmd.sourceforge.net/rule-tests net/sourceforge/pmd/test/schema/rule-tests_1_1_0.xsd\">\n" + " \n" + " Test case with suppression\n" + " 0\n" @@ -177,7 +177,7 @@ void withExpectedEmptySuppressions() throws IOException { + "\n" + " xmlns=\"http://pmd.sourceforge.net/rule-tests\"\n" + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" - + " xsi:schemaLocation=\"http://pmd.sourceforge.net/rule-tests net/sourceforge/pmd/test/schema/rule-tests_1_0_0.xsd\">\n" + + " xsi:schemaLocation=\"http://pmd.sourceforge.net/rule-tests net/sourceforge/pmd/test/schema/rule-tests_1_1_0.xsd\">\n" + " \n" + " Test case with suppression\n" + " 0\n" @@ -201,7 +201,7 @@ void withExpectedNoSuppressions() throws IOException { + "\n" + " xmlns=\"http://pmd.sourceforge.net/rule-tests\"\n" + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" - + " xsi:schemaLocation=\"http://pmd.sourceforge.net/rule-tests net/sourceforge/pmd/test/schema/rule-tests_1_0_0.xsd\">\n" + + " xsi:schemaLocation=\"http://pmd.sourceforge.net/rule-tests net/sourceforge/pmd/test/schema/rule-tests_1_1_0.xsd\">\n" + " \n" + " Test case with suppression\n" + " 0\n" diff --git a/pmd-test/src/main/resources/rule-tests_1_0_0.xsd b/pmd-test/src/main/resources/rule-tests_1_0_0.xsd index 0795747654f..eb6164a5910 100644 --- a/pmd-test/src/main/resources/rule-tests_1_0_0.xsd +++ b/pmd-test/src/main/resources/rule-tests_1_0_0.xsd @@ -1,4 +1,6 @@ + + - - - Declares the expected suppressed violations. Since 7.15.0. - - - - - - - - - - - - - - - diff --git a/pmd-test/src/main/resources/rule-tests_1_1_0.xsd b/pmd-test/src/main/resources/rule-tests_1_1_0.xsd new file mode 100644 index 00000000000..18b638ad5d0 --- /dev/null +++ b/pmd-test/src/main/resources/rule-tests_1_1_0.xsd @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + A code fragment that can be referred to by several tests. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Declares the expected suppressed violations. Since PMD 7.15.0 / rule-tests 1.1.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + Language version of the source, eg 'java 8'. + + + + + + + + This attribute is deprecated, it is assumed true and ignored. + + + + + + + This attribute is deprecated. Use "disabled" instead. + If this attribute is set to "false", then the test is ignored. + + + + + + + This attribute is deprecated, it is assumed true and ignored. + + + + + + + + A reason why the test is disabled/ignored should be provided as a comment for the test. + + + + + + + If true, only this test will be executed, and all others will be disabled. + If several tests in the same file are focused, then the last one wins, in + document order. + This attribute is provided as a way for developers to temporarily focus on a single test. + Test files with a focused test should not be checked in. For this reason, + using this attribute produces a warning. + + + + + + + + + + + + + From f213e8afce868924b4dcc997688162198bf6700e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 22 Jun 2025 22:10:22 +0200 Subject: [PATCH 1044/1962] Avoid duplication of rule-test schema --- pmd-test/pom.xml | 31 ++++ .../src/main/resources/rule-tests_1_0_0.xsd | 114 --------------- .../src/main/resources/rule-tests_1_1_0.xsd | 133 ------------------ 3 files changed, 31 insertions(+), 247 deletions(-) delete mode 100644 pmd-test/src/main/resources/rule-tests_1_0_0.xsd delete mode 100644 pmd-test/src/main/resources/rule-tests_1_1_0.xsd diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index 2e83785af2d..36efb02b8db 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -31,6 +31,37 @@ + + org.apache.maven.plugins + maven-dependency-plugin + 3.8.1 + + + copy-rule-test-schema + process-resources + + unpack + + + + + net.sourceforge.pmd + pmd-test-schema + ${project.version} + net/sourceforge/pmd/test/schema/rule-tests_*.xsd + + + ^\Qnet/sourceforge/pmd/test/schema/\E + ./ + + + + + ${project.build.outputDirectory} + + + + diff --git a/pmd-test/src/main/resources/rule-tests_1_0_0.xsd b/pmd-test/src/main/resources/rule-tests_1_0_0.xsd deleted file mode 100644 index eb6164a5910..00000000000 --- a/pmd-test/src/main/resources/rule-tests_1_0_0.xsd +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - - - - - - - - A code fragment that can be referred to by several tests. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Language version of the source, eg 'java 8'. - - - - - - - - This attribute is deprecated, it is assumed true and ignored. - - - - - - - This attribute is deprecated. Use "disabled" instead. - If this attribute is set to "false", then the test is ignored. - - - - - - - This attribute is deprecated, it is assumed true and ignored. - - - - - - - - A reason why the test is disabled/ignored should be provided as a comment for the test. - - - - - - - If true, only this test will be executed, and all others will be disabled. - If several tests in the same file are focused, then the last one wins, in - document order. - This attribute is provided as a way for developers to temporarily focus on a single test. - Test files with a focused test should not be checked in. For this reason, - using this attribute produces a warning. - - - - - - - - - - - - - diff --git a/pmd-test/src/main/resources/rule-tests_1_1_0.xsd b/pmd-test/src/main/resources/rule-tests_1_1_0.xsd deleted file mode 100644 index 18b638ad5d0..00000000000 --- a/pmd-test/src/main/resources/rule-tests_1_1_0.xsd +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - - - - - - - - - A code fragment that can be referred to by several tests. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Declares the expected suppressed violations. Since PMD 7.15.0 / rule-tests 1.1.0. - - - - - - - - - - - - - - - - - - - - - - - - - - - Language version of the source, eg 'java 8'. - - - - - - - - This attribute is deprecated, it is assumed true and ignored. - - - - - - - This attribute is deprecated. Use "disabled" instead. - If this attribute is set to "false", then the test is ignored. - - - - - - - This attribute is deprecated, it is assumed true and ignored. - - - - - - - - A reason why the test is disabled/ignored should be provided as a comment for the test. - - - - - - - If true, only this test will be executed, and all others will be disabled. - If several tests in the same file are focused, then the last one wins, in - document order. - This attribute is provided as a way for developers to temporarily focus on a single test. - Test files with a focused test should not be checked in. For this reason, - using this attribute produces a warning. - - - - - - - - - - - - - From e87d30af0e9da070d18743bc31f7f9ab25444da8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Tue, 24 Jun 2025 12:24:57 +0200 Subject: [PATCH 1045/1962] Fix name of test --- .../java/rule/bestpractices/xml/ReplaceHashtableWithMap.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/ReplaceHashtableWithMap.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/ReplaceHashtableWithMap.xml index 96ccaae33cf..a55c83c0a8f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/ReplaceHashtableWithMap.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/ReplaceHashtableWithMap.xml @@ -29,7 +29,7 @@ public class Foo { ]]> - ok, not java.util.Vector + ok, not java.util.Hashtable 0 Date: Thu, 26 Jun 2025 09:16:20 +0200 Subject: [PATCH 1046/1962] Remove rule-test schema from pmd-test It is now only available in pmd-test-schema under the paths net/sourceforge/pmd/test/schema/rule-tests_1_0_0.xsd and net/sourceforge/pmd/test/schema/rule-tests_1_1_0.xsd --- pmd-test/pom.xml | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index 36efb02b8db..2e83785af2d 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -31,37 +31,6 @@ - - org.apache.maven.plugins - maven-dependency-plugin - 3.8.1 - - - copy-rule-test-schema - process-resources - - unpack - - - - - net.sourceforge.pmd - pmd-test-schema - ${project.version} - net/sourceforge/pmd/test/schema/rule-tests_*.xsd - - - ^\Qnet/sourceforge/pmd/test/schema/\E - ./ - - - - - ${project.build.outputDirectory} - - - - From 2aaabd2be76735cbd6da175003288dce55f73380 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 Jun 2025 10:10:27 +0200 Subject: [PATCH 1047/1962] [test] Make suppressor id for expected suppressions optional --- docs/pages/pmd/userdocs/extending/testing.md | 3 +- .../pmd/test/schema/BaseTestParserImpl.java | 2 +- .../pmd/test/schema/RuleTestDescriptor.java | 11 +++- .../pmd/test/schema/TestSchemaParserTest.java | 8 ++- .../net/sourceforge/pmd/test/RuleTst.java | 6 +- .../net/sourceforge/pmd/test/RuleTstTest.java | 64 +++++++++++++++++++ 6 files changed, 87 insertions(+), 7 deletions(-) diff --git a/docs/pages/pmd/userdocs/extending/testing.md b/docs/pages/pmd/userdocs/extending/testing.md index 4340f66a44b..a43d9efa93c 100644 --- a/docs/pages/pmd/userdocs/extending/testing.md +++ b/docs/pages/pmd/userdocs/extending/testing.md @@ -167,10 +167,11 @@ The `` elements understands the following optional attributes: * **``**: Optional element, with `` elements as children. Each `` element has an attribute `line`, where the suppression violation occurred and - the suppressor's id as the text content. Example: + the suppressor's id as the text content. The suppression id is optional and can be omitted. Example: ```xml @SuppressWarnings + ``` This is available since PMD 7.15.0 (rule-test schema version 1.1.0). diff --git a/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/BaseTestParserImpl.java b/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/BaseTestParserImpl.java index b0a43a98f84..0d50d4e95eb 100644 --- a/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/BaseTestParserImpl.java +++ b/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/BaseTestParserImpl.java @@ -217,7 +217,7 @@ private void parseExpectedSuppressions(Element testCode, RuleTestDescriptor desc String suppressor = parseTextNode(itemEl); if (line != null) { - descriptor.recordExpectedSuppression(line.getValue(), suppressor); + descriptor.recordExpectedSuppression(Integer.parseInt(line.getValue()), suppressor); } } } diff --git a/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/RuleTestDescriptor.java b/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/RuleTestDescriptor.java index 975b6d89195..42ec6cd6cc6 100644 --- a/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/RuleTestDescriptor.java +++ b/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/RuleTestDescriptor.java @@ -164,8 +164,15 @@ void createEmptyExpectedSuppression() { expectedSuppressions = new ArrayList<>(); } - void recordExpectedSuppression(String line, String suppressor) { - this.expectedSuppressions.add(new SuppressionDescriptor(Integer.parseInt(line), suppressor)); + public void recordExpectedSuppression(int line) { + recordExpectedSuppression(line, null); + } + + public void recordExpectedSuppression(int line, String suppressor) { + if (expectedSuppressions == null) { + createEmptyExpectedSuppression(); + } + this.expectedSuppressions.add(new SuppressionDescriptor(line, suppressor)); } public List getExpectedSuppressions() { diff --git a/pmd-test-schema/src/test/java/net/sourceforge/pmd/test/schema/TestSchemaParserTest.java b/pmd-test-schema/src/test/java/net/sourceforge/pmd/test/schema/TestSchemaParserTest.java index bb689e9d0ef..dc42cf7324a 100644 --- a/pmd-test-schema/src/test/java/net/sourceforge/pmd/test/schema/TestSchemaParserTest.java +++ b/pmd-test-schema/src/test/java/net/sourceforge/pmd/test/schema/TestSchemaParserTest.java @@ -154,6 +154,8 @@ void withExpectedSuppressions() throws IOException { + " \n" + " @SuppressWarnings\n" + " NOPMD\n" + + " \n" + + " \n" + " \n" + " { + RuleContext context = invocation.getArgument(1, RuleContext.class); + DummyRootNode node = invocation.getArgument(0, DummyRootNode.class); + + node = node.withNoPmdComments(new SuppressionCommentImpl<>(node, "ohio")); + context.addViolation(node); + + return null; + }).when(rule).apply(any(Node.class), Mockito.any(RuleContext.class)); + } + + @Test + void suppressionAssertSuppressorIdIsOptional() { + setupRuleWithSuppression(); + + RuleTestDescriptor testDescriptor = new RuleTestDescriptor(0, rule); + testDescriptor.setLanguageVersion(dummyLanguage); + testDescriptor.setCode("(a)(b)\n(c)"); + testDescriptor.setDescription("sample test"); + testDescriptor.recordExpectedViolations(0, Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); + testDescriptor.recordExpectedSuppression(1); + + ruleTester.runTest(testDescriptor); + } + + @Test + void suppressionAssertSuppressorIdGood() { + setupRuleWithSuppression(); + + RuleTestDescriptor testDescriptor = new RuleTestDescriptor(0, rule); + testDescriptor.setLanguageVersion(dummyLanguage); + testDescriptor.setCode("(a)(b)\n(c)"); + testDescriptor.setDescription("sample test"); + testDescriptor.recordExpectedViolations(0, Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); + testDescriptor.recordExpectedSuppression(1, "//NOPMD"); + + ruleTester.runTest(testDescriptor); + } + + @Test + void suppressionAssertSuppressorIdWrong() { + setupRuleWithSuppression(); + + RuleTestDescriptor testDescriptor = new RuleTestDescriptor(0, rule); + testDescriptor.setLanguageVersion(dummyLanguage); + testDescriptor.setCode("(a)(b)\n(c)"); + testDescriptor.setDescription("sample test"); + testDescriptor.recordExpectedViolations(0, Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); + testDescriptor.recordExpectedSuppression(1, "wrong id"); + + AssertionFailedError assertionFailedError = assertThrows(AssertionFailedError.class, () -> ruleTester.runTest(testDescriptor)); + assertEquals("wrong suppressor id ==> expected: but was: ", assertionFailedError.getMessage()); + } } From fafa7ab78514cdf689d0a5b31a69e02164437e47 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 Jun 2025 10:12:51 +0200 Subject: [PATCH 1048/1962] [doc] Update release notes (#5806) --- 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 0c9c0dd3524..a99af6aaa7a 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -28,8 +28,16 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿšจ API Changes +#### Rule Test Schema +The rule test schema has been extended to support verifying suppressed violations. +See [Testing your rules]({{ baseurl }}pmd_userdocs_extending_testing.html) for more information. + +Also note, the schema [rule-tests.xsd](https://github.com/pmd/pmd/blob/main/pmd-test-schema/src/main/resources/net/sourceforge/pmd/test/schema/rule-tests_1_1_0.xsd) +is now only in the module "pmd-test-schema". It has been removed from the old location from module "pmd-test". + ### โœจ Merged pull requests +* [#5806](https://github.com/pmd/pmd/pull/5806): \[test] Verify suppressed violations in rule tests - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ Dependency updates From 92cec8e422423d04fe4bcd847baa34fb0ecd229c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 Jun 2025 10:37:39 +0200 Subject: [PATCH 1049/1962] [java] Reference new schema for rule tests --- .../pmd/lang/apex/rule/performance/xml/AvoidDebugStatements.xml | 2 +- .../pmd/lang/java/rule/codestyle/xml/PackageCase.xml | 2 +- .../lang/java/rule/design/xml/AvoidCatchingGenericException.xml | 2 +- .../pmd/lang/java/rule/design/xml/CyclomaticComplexity.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/performance/xml/AvoidDebugStatements.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/performance/xml/AvoidDebugStatements.xml index 0ab8e2e1720..078abb2c1cb 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/performance/xml/AvoidDebugStatements.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/performance/xml/AvoidDebugStatements.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.github.io/schema/rule-tests_1_1_0.xsd"> No debug statements diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/PackageCase.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/PackageCase.xml index b47c22349a6..5ecf0fdb8ec 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/PackageCase.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/PackageCase.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.github.io/schema/rule-tests_1_1_0.xsd"> bad diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidCatchingGenericException.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidCatchingGenericException.xml index 6572effcf9d..db5d1ed7a06 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidCatchingGenericException.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidCatchingGenericException.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.github.io/schema/rule-tests_1_1_0.xsd"> failure case diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/CyclomaticComplexity.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/CyclomaticComplexity.xml index 2e77be81cda..9f7e7d567d1 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/CyclomaticComplexity.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/CyclomaticComplexity.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.github.io/schema/rule-tests_1_1_0.xsd"> Date: Thu, 26 Jun 2025 10:43:23 +0200 Subject: [PATCH 1050/1962] [apex] Update rule doc AvoidBooleanMethodParameters --- .../AvoidBooleanMethodParametersRule.java | 3 +- .../main/resources/category/apex/design.xml | 198 +++++++++--------- 2 files changed, 104 insertions(+), 97 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidBooleanMethodParametersRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidBooleanMethodParametersRule.java index 14ff352680b..6512bc8675e 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidBooleanMethodParametersRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidBooleanMethodParametersRule.java @@ -28,7 +28,8 @@ * separate methods, or configuration objects. *

    * - * @see https://github.com/pmd/pmd/issues/5427 + * @see [apex] New Rule: Avoid Boolean Method Parameters #5427 + * @since 7.15.0 */ public class AvoidBooleanMethodParametersRule extends AbstractApexRule { diff --git a/pmd-apex/src/main/resources/category/apex/design.xml b/pmd-apex/src/main/resources/category/apex/design.xml index aa02eb2b862..839b0b06e30 100644 --- a/pmd-apex/src/main/resources/category/apex/design.xml +++ b/pmd-apex/src/main/resources/category/apex/design.xml @@ -36,76 +36,55 @@ public class Foo { - - + since="7.15.0" + message="Avoid Boolean method parameters" + class="net.sourceforge.pmd.lang.apex.rule.design.AvoidBooleanMethodParametersRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_design.html#avoidbooleanmethodparameters"> + + Boolean parameters in a system's API can make method calls difficult to understand and + maintain. They often indicate that a method is doing more than one thing and + could benefit from being split into separate methods with more descriptive + names. + + This rule flags any boolean parameters found in public or global methods, + encouraging developers to use more expressive alternatives such as enums, + separate methods, or configuration objects. - 3 + 2 + - - - -Boolean parameters in a system's API can make method calls difficult to understand and -maintain. They often indicate that a method is doing more than one thing and -could benefit from being split into separate methods with more descriptive -names. - -This rule flags any boolean parameters found in public or global methods, -encouraging developers to use more expressive alternatives such as enums, -separate methods, or configuration objects. - - 2 - - + + + 3 + + From a87178222e048eb097f83ba8cd288042fecc1ba9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 Jun 2025 10:49:35 +0200 Subject: [PATCH 1051/1962] [doc] Update release notes (#5427, #5821) --- docs/pages/release_notes.md | 9 +++++++++ pmd-apex/src/main/resources/rulesets/apex/quickstart.xml | 1 + 2 files changed, 10 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 25ace786e57..aaf3283c146 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -24,13 +24,22 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy +#### โœจ New Rules + +* The new Apex rule {% rule apex/design/AvoidBooleanMethodParameters %} finds methods that take a + boolean parameter. This can make method calls difficult to understand and maintain as the method is clearly + doing two things. + ### ๐Ÿ› Fixed Issues +* apex-design + * [#5427](https://github.com/pmd/pmd/issues/5427): \[apex] New Rule: Avoid Boolean Method Parameters ### ๐Ÿšจ API Changes ### โœจ Merged pull requests * [#5738](https://github.com/pmd/pmd/pull/5738): chore: Remove unused private methods in test classes - [Pankraz76](https://github.com/Pankraz76) (@Pankraz76) +* [#5821](https://github.com/pmd/pmd/pull/5821): \[apex] New Rule: Avoid boolean method parameters - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) ### ๐Ÿ“ฆ Dependency updates diff --git a/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml b/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml index dd7835b1714..f5bc151c69d 100644 --- a/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml +++ b/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml @@ -64,6 +64,7 @@ 3 + From 2b81f100114509ef76887a971f5d9997a765e3b1 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 Jun 2025 11:14:11 +0200 Subject: [PATCH 1052/1962] Add @UncleOwen as a contributor --- .all-contributorsrc | 9 ++++ docs/pages/pmd/projectdocs/credits.md | 75 ++++++++++++++------------- 2 files changed, 47 insertions(+), 37 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index f3159f49105..0ae15c07cad 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8169,6 +8169,15 @@ "contributions": [ "bug" ] + }, + { + "login": "UncleOwen", + "name": "UncleOwen", + "avatar_url": "https://avatars.githubusercontent.com/u/15789140?v=4", + "profile": "https://github.com/UncleOwen", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index b8162a80a67..24c0c8bb4e5 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -829,335 +829,336 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
    + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + From 6ea8fa9979441c3ccdc84d045f58b37828de9986 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 Jun 2025 11:15:06 +0200 Subject: [PATCH 1053/1962] [doc] Update release notes (#5851) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index e105ffcc17a..cfd31694dc4 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -49,6 +49,7 @@ Many thanks to our sponsors: * [#5738](https://github.com/pmd/pmd/pull/5738): chore: Remove unused private methods in test classes - [Pankraz76](https://github.com/Pankraz76) (@Pankraz76) * [#5791](https://github.com/pmd/pmd/pull/5791): \[doc] Add a simple check whether generate rule doc pages exist - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5818](https://github.com/pmd/pmd/pull/5818): Fix #2304: \[java] UnnecessaryImport FP for on-demand imports in JavaDoc - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#5851](https://github.com/pmd/pmd/pull/5851): chore: \[java] ReplaceHashtableWithMap: Fix name of test - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) ### ๐Ÿ“ฆ Dependency updates From 0905435de8806ed7634bd65394c1d95029c0e8f0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 Jun 2025 11:25:25 +0200 Subject: [PATCH 1054/1962] [java] UnusedPrivateField - update test to verify suppressions --- .../rule/bestpractices/xml/UnusedPrivateField.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml index 70a5c527016..29baacaf863 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.github.io/schema/rule-tests_1_1_0.xsd"> simple unused private field @@ -881,9 +881,9 @@ public class Board { [java] UnusedPrivateField doesn't play well with UnnecessaryWarningSuppression #5785 - case 1 0 - - - + + @SuppressWarnings + [java] UnusedPrivateField doesn't play well with UnnecessaryWarningSuppression #5785 - case 2 0 - - - + + @SuppressWarnings + Date: Thu, 26 Jun 2025 11:31:45 +0200 Subject: [PATCH 1055/1962] [java] UselessOverridingMethod - skip SuppressWarnings Fixes #5804 --- docs/pages/release_notes.md | 2 ++ .../design/UselessOverridingMethodRule.java | 5 +++- .../design/xml/UselessOverridingMethod.xml | 25 ++++++++++++++++++- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 69b233883a7..a6c89ea163d 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -43,6 +43,8 @@ This is a {{ site.pmd.release_type }} release. * [#1639](https://github.com/pmd/pmd/issues/1639): \[java] UnnecessaryImport false positive for multiline @link Javadoc * [#2304](https://github.com/pmd/pmd/issues/2304): \[java] UnnecessaryImport false positive for on-demand imports in JavaDoc * [#5832](https://github.com/pmd/pmd/issues/5832): \[java] UnnecessaryImport false positive for multiline @see Javadoc +* java-design + * [#5804](https://github.com/pmd/pmd/issues/5804): \[java] UselessOverridingMethod doesn't play well with UnnecessarySuppressWarning ### ๐Ÿšจ API Changes diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/UselessOverridingMethodRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/UselessOverridingMethodRule.java index 2add4ddd6ab..a4d792b802c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/UselessOverridingMethodRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/UselessOverridingMethodRule.java @@ -60,7 +60,10 @@ public Object visit(ASTMethodDeclaration node, Object data) { // skip annotated methods if (!getProperty(IGNORE_ANNOTATIONS_DESCRIPTOR) - && node.getDeclaredAnnotations().any(it -> !TypeTestUtil.isA(Override.class, it))) { + && node.getDeclaredAnnotations() + .filter(it -> !TypeTestUtil.isA(SuppressWarnings.class, it)) + .filter(it -> !TypeTestUtil.isA(Override.class, it)) + .nonEmpty()) { return null; } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/UselessOverridingMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/UselessOverridingMethod.xml index 9175c3f0808..a18fdcd551b 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/UselessOverridingMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/UselessOverridingMethod.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.github.io/schema/rule-tests_1_1_0.xsd"> call super @@ -688,4 +688,27 @@ public class OtherSubclass extends BaseClass { } ]]> + + + [java] UselessOverridingMethod doesn't play well with UnnecessarySuppressWarning #5804 + 0 + + @SuppressWarnings + + + From 5078542e644fc868071a859f81086e3f4ced0be0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 Jun 2025 11:57:24 +0200 Subject: [PATCH 1056/1962] [java] Verify unused private field for unrelated suppress warnings --- .../rule/bestpractices/xml/UnusedPrivateField.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml index 29baacaf863..ab2a6925276 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml @@ -903,6 +903,18 @@ public class Foo { @SuppressWarnings("unused") private String foo; } +]]> + + + + [java] UnusedPrivateField doesn't play well with UnnecessaryWarningSuppression #5785 - valid violation + 1 + 2 + From 6025d12f12c2d4bd345facccc2a455e60c1caae3 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 Jun 2025 12:14:01 +0200 Subject: [PATCH 1057/1962] Fix test --- .../pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml index ab2a6925276..e39dc714bd1 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateField.xml @@ -909,7 +909,7 @@ public class Foo { [java] UnusedPrivateField doesn't play well with UnnecessaryWarningSuppression #5785 - valid violation 1 - 2 + 3 Date: Thu, 26 Jun 2025 12:23:23 +0200 Subject: [PATCH 1058/1962] Bump marocchino/sticky-pull-request-comment from 2.9.2 to 2.9.3 in the all-actions group (#5838) Bump marocchino/sticky-pull-request-comment in the all-actions group Bumps the all-actions group with 1 update: [marocchino/sticky-pull-request-comment](https://github.com/marocchino/sticky-pull-request-comment). Updates `marocchino/sticky-pull-request-comment` from 2.9.2 to 2.9.3 - [Release notes](https://github.com/marocchino/sticky-pull-request-comment/releases) - [Commits](https://github.com/marocchino/sticky-pull-request-comment/compare/67d0dec7b07ed060a405f9b2a64b8ab319fdd7db...d2ad0de260ae8b0235ce059e63f2949ba9e05943) --- updated-dependencies: - dependency-name: marocchino/sticky-pull-request-comment dependency-version: 2.9.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all-actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/publish-pull-requests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-pull-requests.yml b/.github/workflows/publish-pull-requests.yml index 4fd43105b8a..4acf8093855 100644 --- a/.github/workflows/publish-pull-requests.yml +++ b/.github/workflows/publish-pull-requests.yml @@ -177,7 +177,7 @@ jobs: echo "### Result" >> "${GITHUB_STEP_SUMMARY}" echo "${comment}" >> "${GITHUB_STEP_SUMMARY}" - - uses: marocchino/sticky-pull-request-comment@67d0dec7b07ed060a405f9b2a64b8ab319fdd7db #v2.9.2 + - uses: marocchino/sticky-pull-request-comment@d2ad0de260ae8b0235ce059e63f2949ba9e05943 #v2.9.3 with: header: pmd-publish-pull-requests number: ${{ env.PR_NUMBER }} From dd61df894d1bc8f830604e347d814fdd00704471 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Jun 2025 12:23:45 +0200 Subject: [PATCH 1059/1962] Bump log4j.version from 2.24.3 to 2.25.0 (#5839) Bumps `log4j.version` from 2.24.3 to 2.25.0. Updates `org.apache.logging.log4j:log4j-api` from 2.24.3 to 2.25.0 Updates `org.apache.logging.log4j:log4j-core` from 2.24.3 to 2.25.0 --- updated-dependencies: - dependency-name: org.apache.logging.log4j:log4j-api dependency-version: 2.25.0 dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: org.apache.logging.log4j:log4j-core dependency-version: 2.25.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-java/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 62c662c5d98..a55e2a25983 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -12,7 +12,7 @@ - 2.24.3 + 2.25.0 From 720aaf70a0353d4744460cbc5147eb07b8d9daf6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Jun 2025 12:24:16 +0200 Subject: [PATCH 1060/1962] Bump com.puppycrawl.tools:checkstyle from 10.25.0 to 10.25.1 (#5840) Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.25.0 to 10.25.1. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.25.0...checkstyle-10.25.1) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-version: 10.25.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 65a0ba58002..495595a8d7b 100644 --- a/pom.xml +++ b/pom.xml @@ -90,7 +90,7 @@ 5.0 3.5.3 - 10.25.0 + 10.25.1 3.6.0 3.26.0 1.10.15 From 9dc239ea4a9f15140b9383db5fbccde77a783f10 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Jun 2025 12:24:38 +0200 Subject: [PATCH 1061/1962] Bump net.bytebuddy:byte-buddy-agent from 1.17.5 to 1.17.6 (#5841) Bumps [net.bytebuddy:byte-buddy-agent](https://github.com/raphw/byte-buddy) from 1.17.5 to 1.17.6. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.17.5...byte-buddy-1.17.6) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy-agent dependency-version: 1.17.6 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 495595a8d7b..eaa78c026bc 100644 --- a/pom.xml +++ b/pom.xml @@ -1015,7 +1015,7 @@ net.bytebuddy byte-buddy-agent - 1.17.5 + 1.17.6 test From e4fbcd82b72206c909684471733d9f4bf3d26db1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Jun 2025 12:25:33 +0200 Subject: [PATCH 1062/1962] Bump net.bytebuddy:byte-buddy from 1.17.5 to 1.17.6 (#5842) Bumps [net.bytebuddy:byte-buddy](https://github.com/raphw/byte-buddy) from 1.17.5 to 1.17.6. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.17.5...byte-buddy-1.17.6) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-version: 1.17.6 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index eaa78c026bc..2bed6f1e010 100644 --- a/pom.xml +++ b/pom.xml @@ -1009,7 +1009,7 @@ net.bytebuddy byte-buddy - 1.17.5 + 1.17.6 test From 9606a1a4e9d2177b6af8f5b6edf7ad9714fa9769 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Jun 2025 12:25:54 +0200 Subject: [PATCH 1063/1962] Bump org.sonatype.central:central-publishing-maven-plugin from 0.7.0 to 0.8.0 (#5843) Bump org.sonatype.central:central-publishing-maven-plugin Bumps [org.sonatype.central:central-publishing-maven-plugin](https://github.com/sonatype/central-publishing-maven-plugin) from 0.7.0 to 0.8.0. - [Commits](https://github.com/sonatype/central-publishing-maven-plugin/commits) --- updated-dependencies: - dependency-name: org.sonatype.central:central-publishing-maven-plugin dependency-version: 0.8.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2bed6f1e010..004973e8a0b 100644 --- a/pom.xml +++ b/pom.xml @@ -617,7 +617,7 @@ org.sonatype.central central-publishing-maven-plugin - 0.7.0 + 0.8.0 org.jacoco From d22f1d266ab87596792dde70b8f2704a795a43d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Jun 2025 12:26:30 +0200 Subject: [PATCH 1064/1962] Bump ostruct from 0.6.1 to 0.6.2 in /.ci/files in the all-gems group across 1 directory (#5844) Bump ostruct in /.ci/files in the all-gems group across 1 directory Bumps the all-gems group with 1 update in the /.ci/files directory: [ostruct](https://github.com/ruby/ostruct). Updates `ostruct` from 0.6.1 to 0.6.2 - [Release notes](https://github.com/ruby/ostruct/releases) - [Commits](https://github.com/ruby/ostruct/compare/v0.6.1...v0.6.2) --- updated-dependencies: - dependency-name: ostruct dependency-version: 0.6.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all-gems ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .ci/files/Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/files/Gemfile.lock b/.ci/files/Gemfile.lock index d74aba21750..56097198fa2 100644 --- a/.ci/files/Gemfile.lock +++ b/.ci/files/Gemfile.lock @@ -17,7 +17,7 @@ GEM logger-colors (1.0.0) nokogiri (1.18.8-x86_64-linux-gnu) racc (~> 1.4) - ostruct (0.6.1) + ostruct (0.6.2) pmdtester (1.5.5) differ (~> 0.1) liquid (~> 5.4) From 6462b0cf0993b72e9093e0bbd095bc0b9aebecef Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 Jun 2025 14:57:12 +0200 Subject: [PATCH 1065/1962] [ci] Small fixes - use correct cache key for regression tester - cleanup gpg key - create correct docs.pmd-code.org/latest symlink --- .github/workflows/build.yml | 2 +- .github/workflows/publish-release.yml | 37 +++++++++++++++----------- .github/workflows/publish-snapshot.yml | 2 +- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index afd000f68c0..20df1953a99 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -303,7 +303,7 @@ jobs: ~/.gradle/caches ~/work/pmd/target/repositories .ci/files/vendor/bundle - key: regressiontester-${{ hashFiles('.ci/files/project-list.xml', 'Gemfile.lock') }} + key: regressiontester-${{ hashFiles('.ci/files/project-list.xml', '.ci/files/Gemfile.lock') }} restore-keys: regressiontester- - uses: actions/download-artifact@v4 with: diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index e1e90f8445d..b86742a0ddf 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -194,20 +194,19 @@ jobs: id: upload env: PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} - PMD_SF_USER: adangel run: | # Deploy to sourceforge files https://sourceforge.net/projects/pmd/files/pmd/ basePath="pmd/${PMD_VERSION}" - uploadUrl="${PMD_SF_USER}@web.sourceforge.net:/home/frs/project/pmd/${basePath}/" - - rsync -avh "dist/pmd-dist-${PMD_VERSION}-bin.zip" "${uploadUrl}" - rsync -avh "dist/pmd-dist-${PMD_VERSION}-bin.zip.asc" "${uploadUrl}" - rsync -avh "dist/pmd-dist-${PMD_VERSION}-src.zip" "${uploadUrl}" - rsync -avh "dist/pmd-dist-${PMD_VERSION}-src.zip.asc" "${uploadUrl}" - rsync -avh "dist/pmd-dist-${PMD_VERSION}-doc.zip" "${uploadUrl}" - rsync -avh "dist/pmd-dist-${PMD_VERSION}-doc.zip.asc" "${uploadUrl}" - rsync -avh "dist/pmd-${PMD_VERSION}-cyclonedx.xml" "${uploadUrl}" - rsync -avh "dist/pmd-${PMD_VERSION}-cyclonedx.json" "${uploadUrl}" + uploadUrl="adangel@web.sourceforge.net:/home/frs/project/pmd/${basePath}" + + rsync -avh "dist/pmd-dist-${PMD_VERSION}-bin.zip" "${uploadUrl}/" + rsync -avh "dist/pmd-dist-${PMD_VERSION}-bin.zip.asc" "${uploadUrl}/" + rsync -avh "dist/pmd-dist-${PMD_VERSION}-src.zip" "${uploadUrl}/" + rsync -avh "dist/pmd-dist-${PMD_VERSION}-src.zip.asc" "${uploadUrl}/" + rsync -avh "dist/pmd-dist-${PMD_VERSION}-doc.zip" "${uploadUrl}/" + rsync -avh "dist/pmd-dist-${PMD_VERSION}-doc.zip.asc" "${uploadUrl}/" + rsync -avh "dist/pmd-${PMD_VERSION}-cyclonedx.xml" "${uploadUrl}/" + rsync -avh "dist/pmd-${PMD_VERSION}-cyclonedx.json" "${uploadUrl}/" rsync -avh "pmd-doc-${PMD_VERSION}/pmd_release_notes.md" "${uploadUrl}/ReadMe.md" targetUrl="https://sourceforge.net/projects/pmd/files/${basePath}" @@ -276,9 +275,8 @@ jobs: id: upload env: PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} - PMD_SF_USER: adangel run: | - rsync -ah --stats --delete "docs/" "${PMD_SF_USER}@web.sourceforge.net:/home/project-web/pmd/htdocs/pmd-${PMD_VERSION}/" + rsync -ah --stats --delete "docs/" "adangel@web.sourceforge.net:/home/project-web/pmd/htdocs/pmd-${PMD_VERSION}/" echo "url_output=https://pmd.sourceforge.io/pmd-${PMD_VERSION}/" >> "$GITHUB_OUTPUT" - name: Cleanup ssh @@ -340,7 +338,7 @@ jobs: scp "${filename}" ${PMD_CODE_SSH_USER}@pmd-code.org:${PMD_CODE_DOCS_PATH} # shellcheck disable=SC2029 ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \ - ( test -h pmd-doc-${PMD_VERSION} && rm pmd-doc-${PMD_VERSION} || true ) && \ + rm -rf \"pmd-doc-${PMD_VERSION}\" && \ unzip -qo \"${filename}\" && \ rm \"${filename}\"" @@ -348,7 +346,7 @@ jobs: # shellcheck disable=SC2029 ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \ rm -f \"latest\" && \ - ln -s \"pmd-doc-${PMD_VERSION}\" \"snapshot\"" + ln -s \"pmd-doc-${PMD_VERSION}\" \"latest\"" targetUrl="https://docs.pmd-code.org/pmd-doc-${PMD_VERSION}/" echo "TargetUrl: ${targetUrl}" @@ -415,6 +413,7 @@ jobs: echo "Extracting remotely ${module}..." # shellcheck disable=SC2029 ssh ${PMD_CODE_SSH_USER}@pmd-code.org "cd \"${PMD_CODE_DOCS_PATH}\" && \ + rm -rf \"apidocs/${module}/${PMD_VERSION}\" && \ mkdir -p \"apidocs/${module}/${PMD_VERSION}\" && \ unzip -qo -d \"apidocs/${module}/${PMD_VERSION}\" \"${moduleJavadocJarBasename}\" && \ rm \"${moduleJavadocJarBasename}\"" @@ -526,6 +525,10 @@ jobs: "dist/pmd-${PMD_VERSION}-cyclonedx.xml" \ "dist/pmd-${PMD_VERSION}-cyclonedx.json" echo "release_url=https://github.com/pmd/pmd/releases/tag/pmd_releases%2F${PMD_VERSION}" >> "$GITHUB_OUTPUT" + - name: Cleanup gpg + if: ${{ always() }} + run: | + rm -rf "${HOME}/.gpg" create-sourceforge-blog-post: needs: [check-version, deploy-to-maven-central] @@ -612,7 +615,7 @@ jobs: ~/.gradle/caches ~/work/pmd/target/repositories .ci/files/vendor/bundle - key: regressiontester-${{ hashFiles('.ci/files/project-list.xml', 'Gemfile.lock') }} + key: regressiontester-${{ hashFiles('.ci/files/project-list.xml', '.ci/files/Gemfile.lock') }} restore-keys: regressiontester- - uses: actions/download-artifact@v4 with: @@ -666,6 +669,8 @@ jobs: cd ../target/reports baseline_name="pmd_releases_${PMD_VERSION}" zip -q -r "${baseline_name}-baseline.zip" "${baseline_name}/" + cd ../../pmd + mv ../target/report/"${baseline_name}-baseline.zip" . scp "${baseline_name}-baseline.zip" pmd@pmd-code.org:/httpdocs/pmd-regression-tester/ - uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index f7b3e206693..a967f5daf1e 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -475,7 +475,7 @@ jobs: ~/.gradle/caches ~/work/pmd/target/repositories .ci/files/vendor/bundle - key: regressiontester-${{ hashFiles('.ci/files/project-list.xml', 'Gemfile.lock') }} + key: regressiontester-${{ hashFiles('.ci/files/project-list.xml', '.ci/files/Gemfile.lock') }} restore-keys: regressiontester- - uses: actions/download-artifact@v4 with: From 59e32be4d8a807c4ef378aa1a2869e89df1aa660 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 Jun 2025 16:09:48 +0200 Subject: [PATCH 1066/1962] Bump build-tools from 30 to 32 (#5853) * Update build-tools from 30 to 32 This enables the new rule UnnecessaryWarningSuppression Ref pmd/build-tools#74 Ref #5803 * Fix UnnecessaryWarningSuppression for missing override Refs #4291 #5299 For now, the rule is disabled for this single class --- pmd-core/pmd-core-exclude-pmd.properties | 2 ++ pmd-core/pom.xml | 13 +++++++++++++ .../net/sourceforge/pmd/lang/document/Chars.java | 5 ++++- pom.xml | 2 +- 4 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 pmd-core/pmd-core-exclude-pmd.properties diff --git a/pmd-core/pmd-core-exclude-pmd.properties b/pmd-core/pmd-core-exclude-pmd.properties new file mode 100644 index 00000000000..6e636acc2fe --- /dev/null +++ b/pmd-core/pmd-core-exclude-pmd.properties @@ -0,0 +1,2 @@ +# ignore missing override for isEmpty() method, see #4291 #5299 +net.sourceforge.pmd.lang.document.Chars=MissingOverride diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index 81ed1e69f02..339f383f1c4 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -96,6 +96,19 @@ + + + org.apache.maven.plugins + maven-pmd-plugin + + + pmd-main + + ${project.basedir}/pmd-core-exclude-pmd.properties + + + + diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/Chars.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/Chars.java index c834bcbdf9f..56c578d70f8 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/Chars.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/Chars.java @@ -75,7 +75,10 @@ private int idx(int off) { /** Whether this slice is the empty string. */ - @SuppressWarnings("PMD.MissingOverride") // with Java 15, isEmpty() has been added to java.lang.CharSequence (#4291) + // @SuppressWarnings("PMD.MissingOverride") // with Java 15, isEmpty() has been added to java.lang.CharSequence (#4291) + // We compile against Java 8 and execute maven on GitHub Actions with Java 11. So there is no missing override. + // However, when executing Maven with Java 15+, then we get MissingOverride (#5299). + // This is suppressed via maven-pmd-plugin's excludeFromFailureFile public boolean isEmpty() { return len == 0; } diff --git a/pom.xml b/pom.xml index 2ef7ec11c3e..944328af832 100644 --- a/pom.xml +++ b/pom.xml @@ -106,7 +106,7 @@ -Xmx512m -Dfile.encoding=${project.build.sourceEncoding} ${extraArgLine} - 30 + 32 7.10.0 From 888eb624616dcc660c096d5136a8c3768a32851d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Jun 2025 09:43:34 +0200 Subject: [PATCH 1067/1962] [ci] Fix dogfood check during release builds Refs #5745 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 944328af832..07b9dd85ab9 100644 --- a/pom.xml +++ b/pom.xml @@ -1299,7 +1299,7 @@ dogfood file://${dogfoodStagingRepo} - false + true true From 2b40c9eac39b4f4b450edde6a316d568e03de900 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Jun 2025 10:19:06 +0200 Subject: [PATCH 1068/1962] [ci] Fix regression tester script for release builds Refs #5745 --- .ci/files/pmdtester_start.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.ci/files/pmdtester_start.sh b/.ci/files/pmdtester_start.sh index 27cc5f6a42b..a94e13719c3 100755 --- a/.ci/files/pmdtester_start.sh +++ b/.ci/files/pmdtester_start.sh @@ -56,10 +56,16 @@ echo "::group::Fetching additional commits" # - ${PMD_REGRESSION_TESTER_BASE_BRANCH}_BASE_FETCH # - ${PMD_REGRESSION_TESTER_HEAD_BRANCH}_HEAD_FETCH +# For release builds, HEAD points to a tag, which is not a normal reference +head_references_tag="" +if git show-ref -q --verify "refs/tags/${PMD_REGRESSION_TESTER_HEAD_BRANCH}" 2>/dev/null; then + head_references_tag="refs/tags/" +fi + echo "Fetching 25 commits for ${PMD_REGRESSION_TESTER_BASE_BRANCH} and ${PMD_REGRESSION_TESTER_HEAD_BRANCH}" git fetch --no-tags --depth=25 origin \ "${PMD_REGRESSION_TESTER_BASE_BRANCH}:${PMD_REGRESSION_TESTER_BASE_BRANCH}_BASE_FETCH" \ - "${PMD_REGRESSION_TESTER_HEAD_BRANCH}:${PMD_REGRESSION_TESTER_HEAD_BRANCH}_HEAD_FETCH" + "${head_references_tag}${PMD_REGRESSION_TESTER_HEAD_BRANCH}:${head_references_tag}${PMD_REGRESSION_TESTER_HEAD_BRANCH}_HEAD_FETCH" # if the PR/branch is older, base might have advanced more than 25 commits... fetch more, up to 150 # until we find a merge base, so that we are sure, regression tester can find all the changed files on @@ -69,7 +75,7 @@ for i in $(seq 1 3); do echo "No merge-base yet - fetching more commits... (try $i)" git fetch --no-tags --deepen=50 origin \ "${PMD_REGRESSION_TESTER_BASE_BRANCH}:${PMD_REGRESSION_TESTER_BASE_BRANCH}_BASE_FETCH" \ - "${PMD_REGRESSION_TESTER_HEAD_BRANCH}:${PMD_REGRESSION_TESTER_HEAD_BRANCH}_HEAD_FETCH" + "${head_references_tag}${PMD_REGRESSION_TESTER_HEAD_BRANCH}:${head_references_tag}${PMD_REGRESSION_TESTER_HEAD_BRANCH}_HEAD_FETCH" fi done merge_base="$( git merge-base "${PMD_REGRESSION_TESTER_BASE_BRANCH}_BASE_FETCH" "${PMD_REGRESSION_TESTER_2ND_REF}" )" From 77276fb5453220a3951c29004645f44552ff111b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Jun 2025 10:19:29 +0200 Subject: [PATCH 1069/1962] [ci] Fix condition for publish-release Refs #5745 --- .github/workflows/publish-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index b86742a0ddf..85cdb9361e1 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -21,7 +21,7 @@ jobs: # and only run for _successful_ push workflow runs on tags. if: ${{ github.repository == 'pmd/pmd' && contains(fromJSON('["push", "workflow_dispatch"]'), github.event.workflow_run.event) - && github.event.workflow_run.head_branch != main + && github.event.workflow_run.head_branch != 'main' && github.event.workflow_run.conclusion == 'success' }} runs-on: ubuntu-latest timeout-minutes: 10 From 48e6c5fb906858bce774dcdf1aa54684705be54e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Jun 2025 11:33:36 +0200 Subject: [PATCH 1070/1962] [doc] Fix javadoc plugin offline link configuration Refs #5823 Follow-up on 79db238386c4250494fb7752b4d433afc37821d6 --- pmd-ant/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index bbd23e238b4..b7eb4cc5d4b 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -24,7 +24,7 @@ - ${project.basedir}/../pmd-core/target/apidocs + ${project.basedir}/../pmd-core/target/reports/apidocs ../../pmd-core/${project.version} diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index 5b0ca0ea7c4..b30c2714bbf 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -28,7 +28,7 @@ - ${project.basedir}/../pmd-core/target/apidocs + ${project.basedir}/../pmd-core/target/reports/apidocs ../../pmd-core/${project.version} diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index 2e83785af2d..d0c917bcaf4 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -25,7 +25,7 @@ - ${project.basedir}/../pmd-core/target/apidocs + ${project.basedir}/../pmd-core/target/reports/apidocs ../../pmd-core/${project.version} From 8e5654fa786955f969b6904241fd56b2d10bb6b3 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Jun 2025 11:34:18 +0200 Subject: [PATCH 1071/1962] [ci] publish-snapshot/release: also create javadocs for kotlin (dokka) Refs #5745 Follow-up on 6184ed54f0e6774be8c250b9670606bf20c3b6ba --- .github/workflows/publish-release.yml | 1 + .github/workflows/publish-snapshot.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 85cdb9361e1..facdc1c7fac 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -115,6 +115,7 @@ jobs: -PfastSkip,sign,pmd-release \ -Dcyclonedx.skip=false \ -Dmaven.javadoc.skip=false \ + -Ddokka.skip=false \ -Dmaven.source.skip=false deploy-to-sourceforge-files: diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index a967f5daf1e..c07327915cf 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -113,6 +113,7 @@ jobs: -PfastSkip,sign,pmd-release \ -Dcyclonedx.skip=false \ -Dmaven.javadoc.skip=false \ + -Ddokka.skip=false \ -Dmaven.source.skip=false deploy-to-sourceforge-files: From e84f47ade44726923f65d60a66fa39677ab41328 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Jun 2025 11:37:37 +0200 Subject: [PATCH 1072/1962] Prepare pmd release 7.15.0 --- docs/_config.yml | 2 +- docs/pages/release_notes.md | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 92a893edacc..4788fc95c55 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,7 +1,7 @@ repository: pmd/pmd pmd: - version: 7.15.0-SNAPSHOT + version: 7.15.0 previous_version: 7.14.0 date: 2025-06-27 # release types: major, minor, bugfix diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 43f1c27d294..55561c947b3 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -65,17 +65,52 @@ Many thanks to our sponsors: ### โœจ Merged pull requests * [#5738](https://github.com/pmd/pmd/pull/5738): chore: Remove unused private methods in test classes - [Pankraz76](https://github.com/Pankraz76) (@Pankraz76) +* [#5745](https://github.com/pmd/pmd/pull/5745): \[ci] New "Publish Release" workflow - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5791](https://github.com/pmd/pmd/pull/5791): \[doc] Add a simple check whether generate rule doc pages exist - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5797](https://github.com/pmd/pmd/pull/5797): \[doc] Update sponsors - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5800](https://github.com/pmd/pmd/pull/5800): Fix #5793: \[java] NonExhaustiveSwitch should ignore "case null" - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5803](https://github.com/pmd/pmd/pull/5803): chore: Remove unnecessary suppress warnings - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5805](https://github.com/pmd/pmd/pull/5805): Fix #5804: \[java] UselessOverridingMethod needs to ignore SuppressWarnings - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5806](https://github.com/pmd/pmd/pull/5806): \[test] Verify suppressed violations in rule tests - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5814](https://github.com/pmd/pmd/pull/5814): Fix #5788: \[apex] ApexCRUDViolation - consider deeper nested Soql - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5815](https://github.com/pmd/pmd/pull/5815): Fix #5785: \[java] UnusedPrivateField should ignore SuppressWarnings - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5818](https://github.com/pmd/pmd/pull/5818): Fix #2304: \[java] UnnecessaryImport FP for on-demand imports in JavaDoc - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#5821](https://github.com/pmd/pmd/pull/5821): \[apex] New Rule: Avoid boolean method parameters - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) +* [#5823](https://github.com/pmd/pmd/pull/5823): \[doc] Fix javadoc plugin configuration - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5833](https://github.com/pmd/pmd/pull/5833): Fix #1639 #5832: Use filtered comment text for UnnecessaryImport - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5851](https://github.com/pmd/pmd/pull/5851): chore: \[java] ReplaceHashtableWithMap: Fix name of test - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) ### ๐Ÿ“ฆ Dependency updates +* [#5775](https://github.com/pmd/pmd/pull/5775): Bump PMD from 7.13.0 to 7.14.0 +* [#5778](https://github.com/pmd/pmd/pull/5778): Bump the all-gems group across 2 directories with 3 updates +* [#5779](https://github.com/pmd/pmd/pull/5779): Bump org.codehaus.mojo:exec-maven-plugin from 3.5.0 to 3.5.1 +* [#5780](https://github.com/pmd/pmd/pull/5780): Bump org.apache.maven.plugins:maven-clean-plugin from 3.4.1 to 3.5.0 +* [#5781](https://github.com/pmd/pmd/pull/5781): Bump com.google.protobuf:protobuf-java from 4.31.0 to 4.31.1 +* [#5782](https://github.com/pmd/pmd/pull/5782): Bump org.apache.groovy:groovy from 4.0.26 to 4.0.27 +* [#5783](https://github.com/pmd/pmd/pull/5783): Bump com.puppycrawl.tools:checkstyle from 10.24.0 to 10.25.0 +* [#5784](https://github.com/pmd/pmd/pull/5784): Bump org.junit:junit-bom from 5.12.2 to 5.13.0 +* [#5807](https://github.com/pmd/pmd/pull/5807): Bump maven from 3.9.8 to 3.9.10 +* [#5809](https://github.com/pmd/pmd/pull/5809): Bump org.codehaus.mojo:build-helper-maven-plugin from 3.6.0 to 3.6.1 +* [#5810](https://github.com/pmd/pmd/pull/5810): Bump org.junit:junit-bom from 5.13.0 to 5.13.1 +* [#5811](https://github.com/pmd/pmd/pull/5811): Bump junit5.platform.version from 1.13.0 to 1.13.1 +* [#5812](https://github.com/pmd/pmd/pull/5812): Bump org.checkerframework:checker-qual from 3.49.3 to 3.49.4 +* [#5813](https://github.com/pmd/pmd/pull/5813): Bump the all-gems group across 2 directories with 1 update +* [#5828](https://github.com/pmd/pmd/pull/5828): Bump scalameta.version from 4.13.6 to 4.13.7 +* [#5829](https://github.com/pmd/pmd/pull/5829): Bump liquid from 5.8.6 to 5.8.7 in /.ci/files in the all-gems group across 1 directory +* [#5838](https://github.com/pmd/pmd/pull/5838): Bump marocchino/sticky-pull-request-comment from 2.9.2 to 2.9.3 in the all-actions group +* [#5839](https://github.com/pmd/pmd/pull/5839): Bump log4j.version from 2.24.3 to 2.25.0 +* [#5840](https://github.com/pmd/pmd/pull/5840): Bump com.puppycrawl.tools:checkstyle from 10.25.0 to 10.25.1 +* [#5841](https://github.com/pmd/pmd/pull/5841): Bump net.bytebuddy:byte-buddy-agent from 1.17.5 to 1.17.6 +* [#5842](https://github.com/pmd/pmd/pull/5842): Bump net.bytebuddy:byte-buddy from 1.17.5 to 1.17.6 +* [#5843](https://github.com/pmd/pmd/pull/5843): Bump org.sonatype.central:central-publishing-maven-plugin from 0.7.0 to 0.8.0 +* [#5844](https://github.com/pmd/pmd/pull/5844): Bump ostruct from 0.6.1 to 0.6.2 in /.ci/files in the all-gems group across 1 directory +* [#5853](https://github.com/pmd/pmd/pull/5853): Bump build-tools from 30 to 32 ### ๐Ÿ“ˆ Stats +* 91 commits +* 24 closed tickets & PRs +* Days since last release: 27 {% endtocmaker %} - From f06835e0afc59b11f440fffd999d13ebe48a43d2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Jun 2025 11:57:28 +0200 Subject: [PATCH 1073/1962] [release] prepare release pmd_releases/7.15.0 --- pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-rust/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 6 +++--- 43 files changed, 45 insertions(+), 45 deletions(-) diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index b7eb4cc5d4b..21edb29e785 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.15.0-SNAPSHOT + 7.15.0 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 3d35c407e80..80753166414 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index 191e71b9bde..23f976092ea 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index 3a1c11d004b..4d7b0c0d524 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index 339f383f1c4..c9cee82067e 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index 8d1c59882a3..842335678e1 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index edfc5fa8321..5dee3388e05 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index fedc7994deb..604ca311f61 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index 90c00afca0b..44b1444467b 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index 497d8bb3ca4..208298046df 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index 109f135291f..54b61382546 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index 19b65e796eb..801d1781d07 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index c66301b99b7..83dc13a4f1c 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index e99db49412d..dfb629a9211 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index 4bb58950191..1cf8914a4b5 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index a55e2a25983..6186b0974ec 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index 0416b66c8d9..6310cfee83f 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index b235b370e09..af3aaea2da9 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index ef26b4eb69d..dd806a7a19e 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index f78f03e53e2..b7ee90d7c07 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index 339b4802173..109f441b995 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index 0ebdadd9adf..fb8f56b01f8 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index a3fd4d33024..2bf110ed519 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index 1f91d04a33a..43b0f827b97 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index 8fc1b69156a..4d0a195a541 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index 25d35c988e3..d595ba05c0f 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index 391533c5a10..a9eb26c0e8e 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index 4e1bc768c7a..fdb2957ae80 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index 90d77043388..d14b8098608 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index fae9ebfb13d..b9c573ad041 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index 71b878cbea4..d3420edef8e 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index 530a73df72a..cda184f815f 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index c75b609a21e..cf3d58738dc 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index 1140719f814..d68cc9aeba1 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.15.0-SNAPSHOT + 7.15.0 ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index f5f409836fb..bf255a403c7 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.15.0-SNAPSHOT + 7.15.0 ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index b58f26118d7..e6cb3311ea6 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index b30c2714bbf..6ef29ba5917 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index d0c917bcaf4..1cd64841cb1 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index 2491c5a22eb..093352fd219 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index e719ca61414..b52723c31da 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index 253205a7f95..2fd78b07eef 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index a03917aa061..7dcac5c27e4 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 ../pom.xml diff --git a/pom.xml b/pom.xml index 07b9dd85ab9..839bf0f1eca 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.15.0-SNAPSHOT + 7.15.0 pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - HEAD + pmd_releases/7.15.0 PMD @@ -73,7 +73,7 @@ - 2025-05-30T16:37:58Z + 2025-06-27T09:37:42Z 8 From 82778e29c08c2120b7b93911ea2f7fddb541cfd0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Jun 2025 15:05:52 +0200 Subject: [PATCH 1074/1962] [release] Prepare next development version --- docs/_config.yml | 6 +- docs/pages/release_notes.md | 77 +------------- docs/pages/release_notes_old.md | 111 +++++++++++++++++++++ pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-rust/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 4 +- 46 files changed, 159 insertions(+), 123 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 4788fc95c55..81988a78a48 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,9 +1,9 @@ repository: pmd/pmd pmd: - version: 7.15.0 - previous_version: 7.14.0 - date: 2025-06-27 + version: 7.16.0-SNAPSHOT + previous_version: 7.15.0 + date: 2025-07-25 # release types: major, minor, bugfix release_type: minor diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 55561c947b3..0c9c0dd3524 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -24,93 +24,18 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy -#### โœจ New Rules - -* The new Apex rule {% rule apex/design/AvoidBooleanMethodParameters %} finds methods that take a - boolean parameter. This can make method calls difficult to understand and maintain as the method is clearly - doing two things. - ### ๐Ÿ› Fixed Issues -* apex-design - * [#5427](https://github.com/pmd/pmd/issues/5427): \[apex] New Rule: Avoid Boolean Method Parameters -* apex-security - * [#5788](https://github.com/pmd/pmd/issues/5788): \[apex] ApexCRUDViolation unable to detect insecure SOQL if it is a direct input argument -* doc - * [#5790](https://github.com/pmd/pmd/issues/5790): \[doc] Website rule reference pages are returning 404 -* java-bestpractices - * [#5785](https://github.com/pmd/pmd/issues/5785): \[java] UnusedPrivateField doesn't play well with UnnecessaryWarningSuppression - * [#5793](https://github.com/pmd/pmd/issues/5793): \[java] NonExhaustiveSwitch fails on exhaustive switch with sealed class -* java-codestyle - * [#1639](https://github.com/pmd/pmd/issues/1639): \[java] UnnecessaryImport false positive for multiline @link Javadoc - * [#2304](https://github.com/pmd/pmd/issues/2304): \[java] UnnecessaryImport false positive for on-demand imports in JavaDoc - * [#5832](https://github.com/pmd/pmd/issues/5832): \[java] UnnecessaryImport false positive for multiline @see Javadoc -* java-design - * [#5804](https://github.com/pmd/pmd/issues/5804): \[java] UselessOverridingMethod doesn't play well with UnnecessarySuppressWarning ### ๐Ÿšจ API Changes -#### Rule Test Schema -The rule test schema has been extended to support verifying suppressed violations. -See [Testing your rules]({{ baseurl }}pmd_userdocs_extending_testing.html) for more information. - -Also note, the schema [rule-tests.xsd](https://github.com/pmd/pmd/blob/main/pmd-test-schema/src/main/resources/net/sourceforge/pmd/test/schema/rule-tests_1_1_0.xsd) -is now only in the module "pmd-test-schema". It has been removed from the old location from module "pmd-test". - -### ๐Ÿ’ต Financial Contributions - -Many thanks to our sponsors: - -* [Cybozu](https://github.com/cybozu) (@cybozu) - ### โœจ Merged pull requests -* [#5738](https://github.com/pmd/pmd/pull/5738): chore: Remove unused private methods in test classes - [Pankraz76](https://github.com/Pankraz76) (@Pankraz76) -* [#5745](https://github.com/pmd/pmd/pull/5745): \[ci] New "Publish Release" workflow - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5791](https://github.com/pmd/pmd/pull/5791): \[doc] Add a simple check whether generate rule doc pages exist - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5797](https://github.com/pmd/pmd/pull/5797): \[doc] Update sponsors - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5800](https://github.com/pmd/pmd/pull/5800): Fix #5793: \[java] NonExhaustiveSwitch should ignore "case null" - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5803](https://github.com/pmd/pmd/pull/5803): chore: Remove unnecessary suppress warnings - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5805](https://github.com/pmd/pmd/pull/5805): Fix #5804: \[java] UselessOverridingMethod needs to ignore SuppressWarnings - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5806](https://github.com/pmd/pmd/pull/5806): \[test] Verify suppressed violations in rule tests - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5814](https://github.com/pmd/pmd/pull/5814): Fix #5788: \[apex] ApexCRUDViolation - consider deeper nested Soql - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5815](https://github.com/pmd/pmd/pull/5815): Fix #5785: \[java] UnusedPrivateField should ignore SuppressWarnings - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5818](https://github.com/pmd/pmd/pull/5818): Fix #2304: \[java] UnnecessaryImport FP for on-demand imports in JavaDoc - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) -* [#5821](https://github.com/pmd/pmd/pull/5821): \[apex] New Rule: Avoid boolean method parameters - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) -* [#5823](https://github.com/pmd/pmd/pull/5823): \[doc] Fix javadoc plugin configuration - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5833](https://github.com/pmd/pmd/pull/5833): Fix #1639 #5832: Use filtered comment text for UnnecessaryImport - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5851](https://github.com/pmd/pmd/pull/5851): chore: \[java] ReplaceHashtableWithMap: Fix name of test - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) ### ๐Ÿ“ฆ Dependency updates -* [#5775](https://github.com/pmd/pmd/pull/5775): Bump PMD from 7.13.0 to 7.14.0 -* [#5778](https://github.com/pmd/pmd/pull/5778): Bump the all-gems group across 2 directories with 3 updates -* [#5779](https://github.com/pmd/pmd/pull/5779): Bump org.codehaus.mojo:exec-maven-plugin from 3.5.0 to 3.5.1 -* [#5780](https://github.com/pmd/pmd/pull/5780): Bump org.apache.maven.plugins:maven-clean-plugin from 3.4.1 to 3.5.0 -* [#5781](https://github.com/pmd/pmd/pull/5781): Bump com.google.protobuf:protobuf-java from 4.31.0 to 4.31.1 -* [#5782](https://github.com/pmd/pmd/pull/5782): Bump org.apache.groovy:groovy from 4.0.26 to 4.0.27 -* [#5783](https://github.com/pmd/pmd/pull/5783): Bump com.puppycrawl.tools:checkstyle from 10.24.0 to 10.25.0 -* [#5784](https://github.com/pmd/pmd/pull/5784): Bump org.junit:junit-bom from 5.12.2 to 5.13.0 -* [#5807](https://github.com/pmd/pmd/pull/5807): Bump maven from 3.9.8 to 3.9.10 -* [#5809](https://github.com/pmd/pmd/pull/5809): Bump org.codehaus.mojo:build-helper-maven-plugin from 3.6.0 to 3.6.1 -* [#5810](https://github.com/pmd/pmd/pull/5810): Bump org.junit:junit-bom from 5.13.0 to 5.13.1 -* [#5811](https://github.com/pmd/pmd/pull/5811): Bump junit5.platform.version from 1.13.0 to 1.13.1 -* [#5812](https://github.com/pmd/pmd/pull/5812): Bump org.checkerframework:checker-qual from 3.49.3 to 3.49.4 -* [#5813](https://github.com/pmd/pmd/pull/5813): Bump the all-gems group across 2 directories with 1 update -* [#5828](https://github.com/pmd/pmd/pull/5828): Bump scalameta.version from 4.13.6 to 4.13.7 -* [#5829](https://github.com/pmd/pmd/pull/5829): Bump liquid from 5.8.6 to 5.8.7 in /.ci/files in the all-gems group across 1 directory -* [#5838](https://github.com/pmd/pmd/pull/5838): Bump marocchino/sticky-pull-request-comment from 2.9.2 to 2.9.3 in the all-actions group -* [#5839](https://github.com/pmd/pmd/pull/5839): Bump log4j.version from 2.24.3 to 2.25.0 -* [#5840](https://github.com/pmd/pmd/pull/5840): Bump com.puppycrawl.tools:checkstyle from 10.25.0 to 10.25.1 -* [#5841](https://github.com/pmd/pmd/pull/5841): Bump net.bytebuddy:byte-buddy-agent from 1.17.5 to 1.17.6 -* [#5842](https://github.com/pmd/pmd/pull/5842): Bump net.bytebuddy:byte-buddy from 1.17.5 to 1.17.6 -* [#5843](https://github.com/pmd/pmd/pull/5843): Bump org.sonatype.central:central-publishing-maven-plugin from 0.7.0 to 0.8.0 -* [#5844](https://github.com/pmd/pmd/pull/5844): Bump ostruct from 0.6.1 to 0.6.2 in /.ci/files in the all-gems group across 1 directory -* [#5853](https://github.com/pmd/pmd/pull/5853): Bump build-tools from 30 to 32 ### ๐Ÿ“ˆ Stats -* 91 commits -* 24 closed tickets & PRs -* Days since last release: 27 {% endtocmaker %} + diff --git a/docs/pages/release_notes_old.md b/docs/pages/release_notes_old.md index 45ef7c403c8..30b0af44dc0 100644 --- a/docs/pages/release_notes_old.md +++ b/docs/pages/release_notes_old.md @@ -7,6 +7,117 @@ Previous versions of PMD can be downloaded here: [Releases - pmd/pmd (GitHub)](h +## 27-June-2025 - 7.15.0 + +The PMD team is pleased to announce PMD 7.15.0. + +This is a minor release. + +### Table Of Contents + +* [๐Ÿš€ New and noteworthy](#new-and-noteworthy) + * [โœจ New Rules](#new-rules) +* [๐Ÿ› Fixed Issues](#fixed-issues) +* [๐Ÿšจ API Changes](#api-changes) + * [Rule Test Schema](#rule-test-schema) +* [๐Ÿ’ต Financial Contributions](#financial-contributions) +* [โœจ Merged pull requests](#merged-pull-requests) +* [๐Ÿ“ฆ Dependency updates](#dependency-updates) +* [๐Ÿ“ˆ Stats](#stats) + +### ๐Ÿš€ New and noteworthy + +#### โœจ New Rules + +* The new Apex rule [`AvoidBooleanMethodParameters`](https://docs.pmd-code.org/pmd-doc-7.15.0/pmd_rules_apex_design.html#avoidbooleanmethodparameters) finds methods that take a + boolean parameter. This can make method calls difficult to understand and maintain as the method is clearly + doing two things. + +### ๐Ÿ› Fixed Issues +* apex-design + * [#5427](https://github.com/pmd/pmd/issues/5427): \[apex] New Rule: Avoid Boolean Method Parameters +* apex-security + * [#5788](https://github.com/pmd/pmd/issues/5788): \[apex] ApexCRUDViolation unable to detect insecure SOQL if it is a direct input argument +* doc + * [#5790](https://github.com/pmd/pmd/issues/5790): \[doc] Website rule reference pages are returning 404 +* java-bestpractices + * [#5785](https://github.com/pmd/pmd/issues/5785): \[java] UnusedPrivateField doesn't play well with UnnecessaryWarningSuppression + * [#5793](https://github.com/pmd/pmd/issues/5793): \[java] NonExhaustiveSwitch fails on exhaustive switch with sealed class +* java-codestyle + * [#1639](https://github.com/pmd/pmd/issues/1639): \[java] UnnecessaryImport false positive for multiline @link Javadoc + * [#2304](https://github.com/pmd/pmd/issues/2304): \[java] UnnecessaryImport false positive for on-demand imports in JavaDoc + * [#5832](https://github.com/pmd/pmd/issues/5832): \[java] UnnecessaryImport false positive for multiline @see Javadoc +* java-design + * [#5804](https://github.com/pmd/pmd/issues/5804): \[java] UselessOverridingMethod doesn't play well with UnnecessarySuppressWarning + +### ๐Ÿšจ API Changes + +#### Rule Test Schema +The rule test schema has been extended to support verifying suppressed violations. +See [Testing your rules](https://docs.pmd-code.org/pmd-doc-7.15.0/pmd_userdocs_extending_testing.html) for more information. + +Also note, the schema [rule-tests.xsd](https://github.com/pmd/pmd/blob/main/pmd-test-schema/src/main/resources/net/sourceforge/pmd/test/schema/rule-tests_1_1_0.xsd) +is now only in the module "pmd-test-schema". It has been removed from the old location from module "pmd-test". + +### ๐Ÿ’ต Financial Contributions + +Many thanks to our sponsors: + +* [Cybozu](https://github.com/cybozu) (@cybozu) + +### โœจ Merged pull requests + +* [#5738](https://github.com/pmd/pmd/pull/5738): chore: Remove unused private methods in test classes - [Pankraz76](https://github.com/Pankraz76) (@Pankraz76) +* [#5745](https://github.com/pmd/pmd/pull/5745): \[ci] New "Publish Release" workflow - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5791](https://github.com/pmd/pmd/pull/5791): \[doc] Add a simple check whether generate rule doc pages exist - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5797](https://github.com/pmd/pmd/pull/5797): \[doc] Update sponsors - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5800](https://github.com/pmd/pmd/pull/5800): Fix #5793: \[java] NonExhaustiveSwitch should ignore "case null" - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5803](https://github.com/pmd/pmd/pull/5803): chore: Remove unnecessary suppress warnings - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5805](https://github.com/pmd/pmd/pull/5805): Fix #5804: \[java] UselessOverridingMethod needs to ignore SuppressWarnings - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5806](https://github.com/pmd/pmd/pull/5806): \[test] Verify suppressed violations in rule tests - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5814](https://github.com/pmd/pmd/pull/5814): Fix #5788: \[apex] ApexCRUDViolation - consider deeper nested Soql - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5815](https://github.com/pmd/pmd/pull/5815): Fix #5785: \[java] UnusedPrivateField should ignore SuppressWarnings - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5818](https://github.com/pmd/pmd/pull/5818): Fix #2304: \[java] UnnecessaryImport FP for on-demand imports in JavaDoc - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#5821](https://github.com/pmd/pmd/pull/5821): \[apex] New Rule: Avoid boolean method parameters - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) +* [#5823](https://github.com/pmd/pmd/pull/5823): \[doc] Fix javadoc plugin configuration - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5833](https://github.com/pmd/pmd/pull/5833): Fix #1639 #5832: Use filtered comment text for UnnecessaryImport - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5851](https://github.com/pmd/pmd/pull/5851): chore: \[java] ReplaceHashtableWithMap: Fix name of test - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) + +### ๐Ÿ“ฆ Dependency updates + +* [#5775](https://github.com/pmd/pmd/pull/5775): Bump PMD from 7.13.0 to 7.14.0 +* [#5778](https://github.com/pmd/pmd/pull/5778): Bump the all-gems group across 2 directories with 3 updates +* [#5779](https://github.com/pmd/pmd/pull/5779): Bump org.codehaus.mojo:exec-maven-plugin from 3.5.0 to 3.5.1 +* [#5780](https://github.com/pmd/pmd/pull/5780): Bump org.apache.maven.plugins:maven-clean-plugin from 3.4.1 to 3.5.0 +* [#5781](https://github.com/pmd/pmd/pull/5781): Bump com.google.protobuf:protobuf-java from 4.31.0 to 4.31.1 +* [#5782](https://github.com/pmd/pmd/pull/5782): Bump org.apache.groovy:groovy from 4.0.26 to 4.0.27 +* [#5783](https://github.com/pmd/pmd/pull/5783): Bump com.puppycrawl.tools:checkstyle from 10.24.0 to 10.25.0 +* [#5784](https://github.com/pmd/pmd/pull/5784): Bump org.junit:junit-bom from 5.12.2 to 5.13.0 +* [#5807](https://github.com/pmd/pmd/pull/5807): Bump maven from 3.9.8 to 3.9.10 +* [#5809](https://github.com/pmd/pmd/pull/5809): Bump org.codehaus.mojo:build-helper-maven-plugin from 3.6.0 to 3.6.1 +* [#5810](https://github.com/pmd/pmd/pull/5810): Bump org.junit:junit-bom from 5.13.0 to 5.13.1 +* [#5811](https://github.com/pmd/pmd/pull/5811): Bump junit5.platform.version from 1.13.0 to 1.13.1 +* [#5812](https://github.com/pmd/pmd/pull/5812): Bump org.checkerframework:checker-qual from 3.49.3 to 3.49.4 +* [#5813](https://github.com/pmd/pmd/pull/5813): Bump the all-gems group across 2 directories with 1 update +* [#5828](https://github.com/pmd/pmd/pull/5828): Bump scalameta.version from 4.13.6 to 4.13.7 +* [#5829](https://github.com/pmd/pmd/pull/5829): Bump liquid from 5.8.6 to 5.8.7 in /.ci/files in the all-gems group across 1 directory +* [#5838](https://github.com/pmd/pmd/pull/5838): Bump marocchino/sticky-pull-request-comment from 2.9.2 to 2.9.3 in the all-actions group +* [#5839](https://github.com/pmd/pmd/pull/5839): Bump log4j.version from 2.24.3 to 2.25.0 +* [#5840](https://github.com/pmd/pmd/pull/5840): Bump com.puppycrawl.tools:checkstyle from 10.25.0 to 10.25.1 +* [#5841](https://github.com/pmd/pmd/pull/5841): Bump net.bytebuddy:byte-buddy-agent from 1.17.5 to 1.17.6 +* [#5842](https://github.com/pmd/pmd/pull/5842): Bump net.bytebuddy:byte-buddy from 1.17.5 to 1.17.6 +* [#5843](https://github.com/pmd/pmd/pull/5843): Bump org.sonatype.central:central-publishing-maven-plugin from 0.7.0 to 0.8.0 +* [#5844](https://github.com/pmd/pmd/pull/5844): Bump ostruct from 0.6.1 to 0.6.2 in /.ci/files in the all-gems group across 1 directory +* [#5853](https://github.com/pmd/pmd/pull/5853): Bump build-tools from 30 to 32 + +### ๐Ÿ“ˆ Stats + +* 91 commits +* 24 closed tickets & PRs +* Days since last release: 27 + + + ## 30-May-2025 - 7.14.0 The PMD team is pleased to announce PMD 7.14.0. diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index 21edb29e785..7eb774ace5e 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.15.0 + 7.16.0-SNAPSHOT 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 80753166414..f9f29e187d2 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index 23f976092ea..8d3dba71f25 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index 4d7b0c0d524..687492b7fa4 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index c9cee82067e..c6010b9b3c1 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index 842335678e1..3662ed6e7c9 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index 5dee3388e05..3d081ecf94f 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index 604ca311f61..19151c6ce15 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index 44b1444467b..6c0ff57cd48 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index 208298046df..64261e34d4b 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index 54b61382546..b390c6bdfbf 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index 801d1781d07..f93b937d38d 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index 83dc13a4f1c..296d4b41c20 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index dfb629a9211..5b5200942ca 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index 1cf8914a4b5..cc502f1798b 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 6186b0974ec..1aaf1d96e73 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index 6310cfee83f..1ff4da6cccd 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index af3aaea2da9..696bba50f7a 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index dd806a7a19e..97c68523615 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index b7ee90d7c07..d64022a1d86 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index 109f441b995..deaccd20333 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index fb8f56b01f8..e07a28da4c0 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index 2bf110ed519..fbef69b5fd4 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index 43b0f827b97..1c83809190d 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index 4d0a195a541..99ded9d44e1 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index d595ba05c0f..8cb2a4a6c0d 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index a9eb26c0e8e..85ba2bb679c 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index fdb2957ae80..a874bc3ce48 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index d14b8098608..7540812aa0c 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index b9c573ad041..97abcec0ca9 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index d3420edef8e..ec3ef9fe3f9 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index cda184f815f..962bbe92a76 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index cf3d58738dc..b22f2a93637 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index d68cc9aeba1..196a5d01020 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.15.0 + 7.16.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index bf255a403c7..f0c5358429c 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.15.0 + 7.16.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index e6cb3311ea6..8043b3a6cae 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index 6ef29ba5917..dd9a4c608e4 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index 1cd64841cb1..3d6ba6ff1ac 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index 093352fd219..5648a746151 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index b52723c31da..d40ae521432 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index 2fd78b07eef..6e4965b9a65 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index 7dcac5c27e4..f8f080434e1 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index 839bf0f1eca..c7ac512a4ef 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.15.0 + 7.16.0-SNAPSHOT pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - pmd_releases/7.15.0 + HEAD PMD From 420a1ae9abee335eddccdc6aae64c24422cc3fa1 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Jun 2025 15:21:02 +0200 Subject: [PATCH 1075/1962] [ci] publish-release: fix github-release job - Fix gh cli arguments - Use pmd actions helper token --- .github/workflows/publish-release.yml | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index facdc1c7fac..429bca354c8 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -456,8 +456,6 @@ jobs: name: github url: ${{ steps.release.outputs.release_url }} runs-on: ubuntu-latest - permissions: - contents: write # create a release timeout-minutes: 10 defaults: run: @@ -506,17 +504,26 @@ jobs: --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-src.zip" printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-doc.zip" + - uses: actions/create-github-app-token@v2 + id: pmd-actions-helper-app-token + with: + app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} + private-key: ${{ secrets.PMD_ACTIONS_HELPER_PRIVATE_KEY }} + owner: pmd + repositories: pmd + permission-contents: write # create a release - name: Create GitHub Release id: release env: PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ steps.pmd-actions-helper-app-token.outputs.token }} run: | release_name="PMD ${PMD_VERSION} ($(date -u +%d-%B-%Y))" - gh release --verify-tag \ + gh release create "pmd_releases/${PMD_VERSION}" \ + --repo pmd/pmd \ + --verify-tag \ --title "$release_name" \ --notes-file "pmd-doc-${PMD_VERSION}/pmd_release_notes.md" \ - create "pmd_releases/${PMD_VERSION}" \ "dist/pmd-dist-${PMD_VERSION}-bin.zip" \ "dist/pmd-dist-${PMD_VERSION}-bin.zip.asc" \ "dist/pmd-dist-${PMD_VERSION}-src.zip" \ From df4c1560263253603ee5bfd02062f9ff7b0cbdf2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Jun 2025 15:35:50 +0200 Subject: [PATCH 1076/1962] [ci] publish-release: increase timeout for maven deploy Default is 1800 seconds (30 minutes) https://central.sonatype.org/publish/publish-portal-maven/#waitmaxtime --- .github/workflows/publish-release.yml | 2 +- pom.xml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 429bca354c8..d6946f2b037 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -80,7 +80,7 @@ jobs: name: maven-central url: https://repo.maven.apache.org/maven2/net/sourceforge/pmd/ runs-on: ubuntu-latest - timeout-minutes: 40 + timeout-minutes: 180 defaults: run: shell: bash diff --git a/pom.xml b/pom.xml index c7ac512a4ef..a71d668c126 100644 --- a/pom.xml +++ b/pom.xml @@ -119,6 +119,8 @@ ${project.basedir}/../antlr4-wrapper.xml false + + 10800 @@ -787,6 +789,7 @@ central true published + ${central-publishing.waitMaxTime} PMD ${project.version} From 261f8f3780fa7b5328f5a2f8fed1a8ba6e9b83f4 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 27 Jun 2025 15:36:25 +0200 Subject: [PATCH 1077/1962] [ci] publish-release: fix regression tester baseline --- .github/workflows/publish-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index d6946f2b037..0eb149f66cf 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -678,7 +678,7 @@ jobs: baseline_name="pmd_releases_${PMD_VERSION}" zip -q -r "${baseline_name}-baseline.zip" "${baseline_name}/" cd ../../pmd - mv ../target/report/"${baseline_name}-baseline.zip" . + mv ../target/reports/"${baseline_name}-baseline.zip" . scp "${baseline_name}-baseline.zip" pmd@pmd-code.org:/httpdocs/pmd-regression-tester/ - uses: actions/upload-artifact@v4 with: From bed27deecf2dde3a5c0dbb05b1e89ae62e2f64bc Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Mon, 30 Jun 2025 04:56:14 +0200 Subject: [PATCH 1078/1962] Fix false positive in FinalFieldCouldBeStatic for array initializers --- .../design/FinalFieldCouldBeStaticRule.java | 8 +++++++- .../rule/design/xml/FinalFieldCouldBeStatic.xml | 17 +++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/FinalFieldCouldBeStaticRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/FinalFieldCouldBeStaticRule.java index 96ead257d85..0dc2b001c0e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/FinalFieldCouldBeStaticRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/FinalFieldCouldBeStaticRule.java @@ -52,7 +52,9 @@ public Object visit(ASTFieldDeclaration node, Object data) { } private boolean isAllowedExpression(ASTExpression e) { - if (e instanceof ASTLiteral || e instanceof ASTClassLiteral || e instanceof ASTTypeExpression || e.isCompileTimeConstant()) { + if (e instanceof ASTLiteral || e instanceof ASTClassLiteral + || e instanceof ASTTypeExpression + || e.isCompileTimeConstant() && !isNonEmptyArray(e)) { return true; } else if (e instanceof ASTFieldAccess && "length".equals(((ASTFieldAccess) e).getName()) @@ -84,6 +86,10 @@ private boolean isAllowedExpression(ASTExpression e) { return false; } + private boolean isNonEmptyArray(ASTExpression e) { + return e instanceof ASTArrayInitializer && e.getNumChildren() > 0; + } + private boolean isUsedForSynchronization(ASTVariableId field) { return field.getLocalUsages().stream().anyMatch( it -> it.getParent() instanceof ASTSynchronizedStatement diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/FinalFieldCouldBeStatic.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/FinalFieldCouldBeStatic.xml index 8a76fdf9255..fbddc8efd3a 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/FinalFieldCouldBeStatic.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/FinalFieldCouldBeStatic.xml @@ -355,10 +355,23 @@ class Literals { ]]> + + array initializers + 1 + 4 + + + Static array property length - 2 - 3,5 + 1 + 3 Date: Thu, 3 Jul 2025 10:17:20 +0200 Subject: [PATCH 1079/1962] [java] Add new java language versions 25 and 25-preview --- docs/pages/pmd/languages/java.md | 6 +++-- docs/pages/pmd/userdocs/tools/ant.md | 4 ++-- .../pmd/dist/BinaryDistributionIT.java | 1 + .../pmd/lang/java/JavaLanguageModule.java | 6 +++-- .../pmd/lang/java/JavaLanguageModuleTest.java | 4 ++-- .../pmd/lang/java/LanguageVersionTest.java | 4 +++- .../lang/java/ast/AllJavaAstTreeDumpTest.java | 4 +++- .../pmd/lang/java/ast/Java24TreeDumpTest.java | 1 + .../java/ast/Java25PreviewTreeDumpTest.java | 22 +++++++++++++++++++ .../pmd/lang/java/ast/Java25TreeDumpTest.java | 21 ++++++++++++++++++ .../pmd/lang/java/ast/KotlinTestingDsl.kt | 3 ++- .../table/internal/HeaderScopesTest.kt | 2 +- 12 files changed, 66 insertions(+), 12 deletions(-) create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25PreviewTreeDumpTest.java create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java diff --git a/docs/pages/pmd/languages/java.md b/docs/pages/pmd/languages/java.md index bcc516dc834..dfa71279c2e 100644 --- a/docs/pages/pmd/languages/java.md +++ b/docs/pages/pmd/languages/java.md @@ -2,7 +2,7 @@ title: Java support permalink: pmd_languages_java.html author: Clรฉment Fournier -last_updated: January 2025 (7.10.0) +last_updated: July 2025 (7.16.0) tags: [languages, PmdCapableLanguage, CpdCapableLanguage] summary: "Java-specific features and guidance" --- @@ -15,8 +15,10 @@ Usually the latest non-preview Java Version is the default version. | Java Version | Alias | Supported by PMD since | |--------------|-------|------------------------| +| 25-preview | | 7.16.0 | +| 25 (default) | | 7.16.0 | | 24-preview | | 7.10.0 | -| 24 (default) | | 7.10.0 | +| 24 | | 7.10.0 | | 23-preview | | 7.5.0 | | 23 | | 7.5.0 | | 22 | | 7.0.0 | diff --git a/docs/pages/pmd/userdocs/tools/ant.md b/docs/pages/pmd/userdocs/tools/ant.md index 1201a60c5ab..007f23500f6 100644 --- a/docs/pages/pmd/userdocs/tools/ant.md +++ b/docs/pages/pmd/userdocs/tools/ant.md @@ -6,7 +6,7 @@ author: > David Dixon-Peugh , Tom Copeland , Xavier Le Vourch -last_updated: January 2025 (7.10.0) +last_updated: July 2025 (7.16.0) --- ## PMD @@ -213,7 +213,7 @@ accordingly and this rule won't be executed. The specific version of a language to be used is selected via the `sourceLanguage` nested element. Example: - + The available versions depend on the language. You can get a list of the currently supported language versions via the CLI option `--help`. diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java b/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java index a0f6f453f32..d1ba8482708 100644 --- a/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java +++ b/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java @@ -55,6 +55,7 @@ class BinaryDistributionIT extends AbstractBinaryDistributionTest { "java-22", "java-23", "java-23-preview", "java-24", "java-24-preview", + "java-25", "java-25-preview", "java-5", "java-6", "java-7", "java-8", "java-9", "jsp-2", "jsp-3", "kotlin-1.6", "kotlin-1.7", "kotlin-1.8", "modelica-3.4", "modelica-3.5", diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java index 461b09c5ae2..09e73c2a409 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java @@ -46,8 +46,10 @@ public JavaLanguageModule() { .addVersion("22") .addVersion("23") .addVersion("23-preview") - .addDefaultVersion("24") // 24 is the default - .addVersion("24-preview")); + .addVersion("24") + .addVersion("24-preview") + .addDefaultVersion("25") // 25 is the default + .addVersion("25-preview")); } public static JavaLanguageModule getInstance() { diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaLanguageModuleTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaLanguageModuleTest.java index 04d8b67bd8f..3afe74e3962 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaLanguageModuleTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaLanguageModuleTest.java @@ -24,8 +24,8 @@ void java9IsSmallerThanJava10() { @Test void previewVersionShouldBeGreaterThanNonPreview() { - LanguageVersion java = JavaLanguageModule.getInstance().getVersion("24"); - LanguageVersion javaPreview = JavaLanguageModule.getInstance().getVersion("24-preview"); + LanguageVersion java = JavaLanguageModule.getInstance().getVersion("25"); + LanguageVersion javaPreview = JavaLanguageModule.getInstance().getVersion("25-preview"); assertTrue(javaPreview.compareTo(java) > 0, "java-preview should be greater than java"); } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionTest.java index 6cf9c4dd693..8848e45fee2 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionTest.java @@ -43,8 +43,10 @@ static Collection data() { new TestDescriptor(java, "23-preview"), new TestDescriptor(java, "24"), new TestDescriptor(java, "24-preview"), + new TestDescriptor(java, "25"), + new TestDescriptor(java, "25-preview"), - defaultVersionIs(java, "24"), + defaultVersionIs(java, "25"), // this one won't be found: case-sensitive! versionDoesNotExist("JAVA", "JAVA", "1.7"), diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AllJavaAstTreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AllJavaAstTreeDumpTest.java index bdb10b6bcf8..853f4bc03ee 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AllJavaAstTreeDumpTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AllJavaAstTreeDumpTest.java @@ -21,7 +21,9 @@ Java23TreeDumpTest.class, Java23PreviewTreeDumpTest.class, Java24TreeDumpTest.class, - Java24PreviewTreeDumpTest.class + Java24PreviewTreeDumpTest.class, + Java25TreeDumpTest.class, + Java25PreviewTreeDumpTest.class }) class AllJavaAstTreeDumpTest { diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java24TreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java24TreeDumpTest.java index 4df560bc867..7b93d8ccfdc 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java24TreeDumpTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java24TreeDumpTest.java @@ -18,4 +18,5 @@ class Java24TreeDumpTest extends BaseJavaTreeDumpTest { return java24; } + // Java 24 didn't finalize any new features, thus there are no tests } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25PreviewTreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25PreviewTreeDumpTest.java new file mode 100644 index 00000000000..e6f98c35484 --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25PreviewTreeDumpTest.java @@ -0,0 +1,22 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.ast; + +import net.sourceforge.pmd.lang.java.BaseJavaTreeDumpTest; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; +import net.sourceforge.pmd.lang.test.ast.BaseParsingHelper; + +class Java25PreviewTreeDumpTest extends BaseJavaTreeDumpTest { + private final JavaParsingHelper java25p = + JavaParsingHelper.DEFAULT.withDefaultVersion("25-preview") + .withResourceContext(Java25PreviewTreeDumpTest.class, "jdkversiontests/java25p/"); + private final JavaParsingHelper java25 = java25p.withDefaultVersion("25"); + + @Override + public BaseParsingHelper getParser() { + return java25p; + } + +} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java new file mode 100644 index 00000000000..e9c5dbab42a --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java @@ -0,0 +1,21 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.ast; + +import net.sourceforge.pmd.lang.java.BaseJavaTreeDumpTest; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; +import net.sourceforge.pmd.lang.test.ast.BaseParsingHelper; + +class Java25TreeDumpTest extends BaseJavaTreeDumpTest { + private final JavaParsingHelper java25 = + JavaParsingHelper.DEFAULT.withDefaultVersion("25") + .withResourceContext(Java25TreeDumpTest.class, "jdkversiontests/java25/"); + + @Override + public BaseParsingHelper getParser() { + return java25; + } + +} diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt index f87eb54c0cd..843d1aecc40 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt @@ -41,7 +41,8 @@ enum class JavaVersion : Comparable { J21, J22, J23, J23__PREVIEW, - J24, J24__PREVIEW; + J24, J24__PREVIEW, + J25, J25__PREVIEW; /** Name suitable for use with e.g. [JavaParsingHelper.parse] */ val pmdName: String = name.removePrefix("J").replaceFirst("__", "-").replace('_', '.').lowercase() diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/HeaderScopesTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/HeaderScopesTest.kt index b5428ae72fb..0066eea208a 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/HeaderScopesTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/HeaderScopesTest.kt @@ -357,7 +357,7 @@ class HeaderScopesTest : ProcessorTestSpec({ block.symbolTable.types().resolve("Inner").shouldBeEmpty() } - parserTest("$moduleImport of java.base should resolve java.util.List") { + parserTest("$moduleImport of java.base should resolve java.util.List", javaVersion = JavaVersion.J24__PREVIEW) { assertNoSemanticErrorsOrWarnings() val acu = parser.parse( From cd2776f8a39720e3b0e2540d0d1c2075b1435908 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 3 Jul 2025 10:55:15 +0200 Subject: [PATCH 1080/1962] [java] Remove java language version 23-preview --- docs/pages/pmd/languages/java.md | 1 - .../pmd/dist/BinaryDistributionIT.java | 2 +- .../pmd/lang/java/JavaLanguageModule.java | 1 - .../pmd/lang/java/LanguageVersionTest.java | 1 - .../lang/java/ast/AllJavaAstTreeDumpTest.java | 1 - .../java/ast/Java23PreviewTreeDumpTest.java | 123 ----- .../java/ast/ASTInstanceOfExpressionTest.kt | 4 +- .../pmd/lang/java/ast/KotlinTestingDsl.kt | 2 +- ...iveTypesInPatternsInstanceofAndSwitch.java | 92 ---- ...tiveTypesInPatternsInstanceofAndSwitch.txt | 467 ------------------ .../Jep476_ModuleImportDeclarations.java | 20 - .../Jep476_ModuleImportDeclarations.txt | 53 -- ...eclaredClassesAndInstanceMainMethods1.java | 27 - ...DeclaredClassesAndInstanceMainMethods1.txt | 67 --- ...eclaredClassesAndInstanceMainMethods2.java | 24 - ...DeclaredClassesAndInstanceMainMethods2.txt | 61 --- .../Jep482_FlexibleConstructorBodies.java | 106 ---- .../Jep482_FlexibleConstructorBodies.txt | 344 ------------- ...StringTemplatesAreNotSupportedAnymore.java | 20 - .../rule/codestyle/xml/UnnecessaryImport.xml | 8 +- 20 files changed, 8 insertions(+), 1416 deletions(-) delete mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java23PreviewTreeDumpTest.java delete mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep455_PrimitiveTypesInPatternsInstanceofAndSwitch.java delete mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep455_PrimitiveTypesInPatternsInstanceofAndSwitch.txt delete mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep476_ModuleImportDeclarations.java delete mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep476_ModuleImportDeclarations.txt delete mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep477_ImplicitlyDeclaredClassesAndInstanceMainMethods1.java delete mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep477_ImplicitlyDeclaredClassesAndInstanceMainMethods1.txt delete mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep477_ImplicitlyDeclaredClassesAndInstanceMainMethods2.java delete mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep477_ImplicitlyDeclaredClassesAndInstanceMainMethods2.txt delete mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep482_FlexibleConstructorBodies.java delete mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep482_FlexibleConstructorBodies.txt delete mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/StringTemplatesAreNotSupportedAnymore.java diff --git a/docs/pages/pmd/languages/java.md b/docs/pages/pmd/languages/java.md index dfa71279c2e..f28c6ab184e 100644 --- a/docs/pages/pmd/languages/java.md +++ b/docs/pages/pmd/languages/java.md @@ -19,7 +19,6 @@ Usually the latest non-preview Java Version is the default version. | 25 (default) | | 7.16.0 | | 24-preview | | 7.10.0 | | 24 | | 7.10.0 | -| 23-preview | | 7.5.0 | | 23 | | 7.5.0 | | 22 | | 7.0.0 | | 21 | | 7.0.0 | diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java b/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java index d1ba8482708..f6b87c74dad 100644 --- a/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java +++ b/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java @@ -53,7 +53,7 @@ class BinaryDistributionIT extends AbstractBinaryDistributionTest { "java-20", "java-21", "java-22", - "java-23", "java-23-preview", + "java-23", "java-24", "java-24-preview", "java-25", "java-25-preview", "java-5", "java-6", "java-7", diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java index 09e73c2a409..0c8beb7e6c5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java @@ -45,7 +45,6 @@ public JavaLanguageModule() { .addVersion("21") .addVersion("22") .addVersion("23") - .addVersion("23-preview") .addVersion("24") .addVersion("24-preview") .addDefaultVersion("25") // 25 is the default diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionTest.java index 8848e45fee2..54dcce96a36 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionTest.java @@ -40,7 +40,6 @@ static Collection data() { new TestDescriptor(java, "21"), new TestDescriptor(java, "22"), new TestDescriptor(java, "23"), - new TestDescriptor(java, "23-preview"), new TestDescriptor(java, "24"), new TestDescriptor(java, "24-preview"), new TestDescriptor(java, "25"), diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AllJavaAstTreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AllJavaAstTreeDumpTest.java index 853f4bc03ee..dee52501779 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AllJavaAstTreeDumpTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AllJavaAstTreeDumpTest.java @@ -19,7 +19,6 @@ Java21TreeDumpTest.class, Java22TreeDumpTest.class, Java23TreeDumpTest.class, - Java23PreviewTreeDumpTest.class, Java24TreeDumpTest.class, Java24PreviewTreeDumpTest.class, Java25TreeDumpTest.class, diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java23PreviewTreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java23PreviewTreeDumpTest.java deleted file mode 100644 index 732e73e5ac6..00000000000 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java23PreviewTreeDumpTest.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.ast; - -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assumptions.assumeTrue; - -import java.util.List; - -import org.junit.jupiter.api.Test; - -import net.sourceforge.pmd.lang.ast.LexException; -import net.sourceforge.pmd.lang.ast.ParseException; -import net.sourceforge.pmd.lang.java.BaseJavaTreeDumpTest; -import net.sourceforge.pmd.lang.java.JavaParsingHelper; -import net.sourceforge.pmd.lang.java.types.OverloadSelectionResult; -import net.sourceforge.pmd.lang.java.types.TypeTestUtil; -import net.sourceforge.pmd.lang.test.ast.BaseParsingHelper; - -class Java23PreviewTreeDumpTest extends BaseJavaTreeDumpTest { - private final JavaParsingHelper java23p = - JavaParsingHelper.DEFAULT.withDefaultVersion("23-preview") - .withResourceContext(Java23PreviewTreeDumpTest.class, "jdkversiontests/java23p/"); - private final JavaParsingHelper java23 = java23p.withDefaultVersion("23"); - - @Override - public BaseParsingHelper getParser() { - return java23p; - } - - @Test - void jep477ImplicitlyDeclaredClassesAndInstanceMainMethods1() { - doTest("Jep477_ImplicitlyDeclaredClassesAndInstanceMainMethods1"); - ASTCompilationUnit compilationUnit = java23p.parseResource("Jep477_ImplicitlyDeclaredClassesAndInstanceMainMethods1.java"); - assertTrue(compilationUnit.isSimpleCompilationUnit()); - - List methodCalls = compilationUnit.descendants(ASTMethodCall.class).toList(); - OverloadSelectionResult systemOutPrintln = methodCalls.get(0).getOverloadSelectionInfo(); // System.out.println - assertFalse(systemOutPrintln.isFailed()); - TypeTestUtil.isA("java.io.PrintStream", systemOutPrintln.getMethodType().getDeclaringType()); - - ASTVariableDeclarator authorsVar = compilationUnit.descendants(ASTVariableDeclarator.class).filter(decl -> "authors".equals(decl.getName())).first(); - assertInstanceOf(ASTMethodCall.class, authorsVar.getInitializer()); - ASTMethodCall initializer = (ASTMethodCall) authorsVar.getInitializer(); - assertEquals("of", initializer.getMethodName()); - assertInstanceOf(ASTTypeExpression.class, initializer.getQualifier()); - ASTTypeExpression qualifier = (ASTTypeExpression) initializer.getQualifier(); - TypeTestUtil.isA("java.util.List", qualifier.getTypeNode().getTypeMirror()); - } - - @Test - void jep477ImplicitlyDeclaredClassesAndInstanceMainMethods1WithJava23Runtime() { - int javaVersion = Integer.parseInt(System.getProperty("java.version").split("\\.")[0].replaceAll("-ea", "")); - assumeTrue(javaVersion >= 23, "Java " + javaVersion + " doesn't support java.io.IO. At least Java 23 is needed for this test."); - - ASTCompilationUnit compilationUnit = java23p.parseResource("Jep477_ImplicitlyDeclaredClassesAndInstanceMainMethods1.java"); - - List methodCalls = compilationUnit.descendants(ASTMethodCall.class).toList(); - OverloadSelectionResult javaIoPrintln = methodCalls.get(1).getOverloadSelectionInfo(); // println from java.io.IO - assertFalse(javaIoPrintln.isFailed()); - TypeTestUtil.isA("java.io.IO", javaIoPrintln.getMethodType().getDeclaringType()); - } - - @Test - void jep477ImplicitlyDeclaredClassesAndInstanceMainMethods1BeforeJava23Preview() { - ParseException thrown = assertThrows(ParseException.class, () -> java23.parseResource("Jep477_ImplicitlyDeclaredClassesAndInstanceMainMethods1.java")); - assertThat(thrown.getMessage(), containsString("Simple source files and instance main methods is a preview feature of JDK 23, you should select your language version accordingly")); - } - - @Test - void jep477ImplicitlyDeclaredClassesAndInstanceMainMethods2() { - doTest("Jep477_ImplicitlyDeclaredClassesAndInstanceMainMethods2"); - } - - @Test - void jep482FlexibleConstructorBodies() { - doTest("Jep482_FlexibleConstructorBodies"); - } - - @Test - void jep482FlexibleConstructorBodiesBeforeJava23Preview() { - ParseException thrown = assertThrows(ParseException.class, () -> java23.parseResource("Jep482_FlexibleConstructorBodies.java")); - assertThat(thrown.getMessage(), containsString("Flexible constructor bodies is a preview feature of JDK 23, you should select your language version accordingly")); - } - - @Test - void jep476ModuleImportDeclarations() { - doTest("Jep476_ModuleImportDeclarations"); - } - - @Test - void jep476ModuleImportDeclarationsBeforeJava23Preview() { - ParseException thrown = assertThrows(ParseException.class, () -> java23.parseResource("Jep476_ModuleImportDeclarations.java")); - assertThat(thrown.getMessage(), containsString("Module import declarations is a preview feature of JDK 23, you should select your language version accordingly")); - } - - @Test - void jep455PrimitiveTypesInPatternsInstanceofAndSwitch() { - doTest("Jep455_PrimitiveTypesInPatternsInstanceofAndSwitch"); - } - - @Test - void jep455PrimitiveTypesInPatternsInstanceofAndSwitchBeforeJava23Preview() { - ParseException thrown = assertThrows(ParseException.class, () -> java23.parseResource("Jep455_PrimitiveTypesInPatternsInstanceofAndSwitch.java")); - assertThat(thrown.getMessage(), containsString("Primitive types in patterns instanceof and switch is a preview feature of JDK 23, you should select your language version accordingly")); - } - - @Test - void stringTemplatesAreNotSupportedAnymore() { - LexException thrown = assertThrows(LexException.class, () -> java23p.parseResource("StringTemplatesAreNotSupportedAnymore.java")); - assertThat(thrown.getMessage(), containsString("Lexical error in file")); - LexException thrown2 = assertThrows(LexException.class, () -> java23.parseResource("StringTemplatesAreNotSupportedAnymore.java")); - assertThat(thrown2.getMessage(), containsString("Lexical error in file")); - } -} diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTInstanceOfExpressionTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTInstanceOfExpressionTest.kt index 0d0be76d649..4e77aa31d08 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTInstanceOfExpressionTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTInstanceOfExpressionTest.kt @@ -48,7 +48,7 @@ class ASTInstanceOfExpressionTest : ParserTestSpec({ } } - parserTestContainer("InstanceofExpression cannot test primitive types", JavaVersion.except(JavaVersion.J23__PREVIEW, JavaVersion.J24__PREVIEW)) { + parserTestContainer("InstanceofExpression cannot test primitive types", JavaVersion.except(JavaVersion.J24__PREVIEW)) { inContext(ExpressionParsingCtx) { PrimitiveTypeKind.values().map { it.simpleName }.forEach { "f instanceof $it" shouldNot parse() @@ -59,7 +59,7 @@ class ASTInstanceOfExpressionTest : ParserTestSpec({ // since Java 23 Preview, primitive types in instanceof are possible (JEP 455) // Java 24 Preview: JEP 488 - parserTestContainer("InstanceofExpression can test primitive types", listOf(JavaVersion.J23__PREVIEW, JavaVersion.J24__PREVIEW)) { + parserTestContainer("InstanceofExpression can test primitive types", listOf(JavaVersion.J24__PREVIEW)) { inContext(ExpressionParsingCtx) { PrimitiveTypeKind.values().forEach { typeKind -> "f instanceof ${typeKind.simpleName}" should parseAs { diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt index 843d1aecc40..3a0de20f1d9 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt @@ -40,7 +40,7 @@ enum class JavaVersion : Comparable { J20, J21, J22, - J23, J23__PREVIEW, + J23, J24, J24__PREVIEW, J25, J25__PREVIEW; diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep455_PrimitiveTypesInPatternsInstanceofAndSwitch.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep455_PrimitiveTypesInPatternsInstanceofAndSwitch.java deleted file mode 100644 index 8c2a0805456..00000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep455_PrimitiveTypesInPatternsInstanceofAndSwitch.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -/** - * @see JEP 455: Primitive Types in Patterns, instanceof, and switch (Preview) (Java 23) - */ -public class Jep455_PrimitiveTypesInPatternsInstanceofAndSwitch { - public static void instanceofWithPrimitiveTypes() { - byte b = 42; - if (b instanceof int) { // true (unconditionally exact) - System.out.println("b = " + b + " is an int"); - } - int i = 42; - if (i instanceof byte) { // true (exact) - System.out.println("i = " + i + " can be converted to byte"); - } - int bigInt = 1000; - if (bigInt instanceof byte) { // false (not exact) - System.out.println("bigInt = " + bigInt); - } else { - System.out.println("bigInt = " + bigInt + " cannot be converted to byte"); - } - - int i2 = 16_777_217; // 2^24 + 1 - System.out.println("i2 as float: " + (i2 instanceof float)); // false (not exact) - System.out.println("i2 as double: " + (i2 instanceof double)); // true (unconditionally exact) - System.out.println("i2 as Integer: " + (i2 instanceof Integer)); // true (unconditionally exact) - System.out.println("i2 as Number: " + (i2 instanceof Number)); // true (unconditionally exact) - - float f = 1000.0f; - System.out.println("f as byte: " + (f instanceof byte)); // false - System.out.println("f as int: " + (f instanceof int)); // true (exact) - System.out.println("f as double: " + (f instanceof double)); // true (unconditionally exact) - - double d = 1000.0d; - System.out.println("d as byte: " + (d instanceof byte)); // false - System.out.println("d as int: " + (d instanceof int)); // true (exact) - System.out.println("d as float: " + (d instanceof float)); // true (exact) - - Integer ii = 1000; - System.out.println("ii as int: " + (ii instanceof int)); // true (exact) - System.out.println("ii as float: " + (ii instanceof float)); // true (exact) - System.out.println("ii as double: " + (ii instanceof double)); // true (exact) - - Integer ii2 = 16_777_217; - System.out.println("ii2 as float: " + (ii2 instanceof float)); // false (not exact) - System.out.println("ii2 as double: " + (ii2 instanceof double)); // true (exact) - } - - public static void primitiveTypePatternsInInstanceof() { - int i = 1000; - if (i instanceof byte b) { - System.out.println("b = " + b); - } else { - System.out.println("i cannot be coverted to byte without loss..."); - } - } - - public static void primitiveTypePatternsInSwitch() { - int i = 1000; - switch (i) { - case double d: - System.out.println("d = " + d); - break; - } - } - - public static void expandedPrimitiveSupportInSwitch() { - float v = 1.0f; - float f = switch (v) { - case 0f -> 5f; - case float x when x == 1f -> 6f + x; - case float x -> 7f + x; - }; - System.out.println("f = " + f); - - boolean b = true; - switch (b) { - case true -> System.out.println("b was true"); - case false -> System.out.println("b was false"); - // Alternatively: case true, false -> ... - } - } - - public static void main(String[] args) { - instanceofWithPrimitiveTypes(); - primitiveTypePatternsInInstanceof(); - primitiveTypePatternsInSwitch(); - expandedPrimitiveSupportInSwitch(); - } -} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep455_PrimitiveTypesInPatternsInstanceofAndSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep455_PrimitiveTypesInPatternsInstanceofAndSwitch.txt deleted file mode 100644 index 998f29bf63a..00000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep455_PrimitiveTypesInPatternsInstanceofAndSwitch.txt +++ /dev/null @@ -1,467 +0,0 @@ -+- CompilationUnit[@PackageName = ""] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep455_PrimitiveTypesInPatternsInstanceofAndSwitch", @CanonicalName = "Jep455_PrimitiveTypesInPatternsInstanceofAndSwitch", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Jep455_PrimitiveTypesInPatternsInstanceofAndSwitch", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] - +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - +- ClassBody[@Empty = false, @Size = 5] - +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @Name = "instanceofWithPrimitiveTypes", @Overridden = false, @Static = true, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @Void = true] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.STATIC), @ExplicitModifiers = (JModifier.PUBLIC, JModifier.STATIC)] - | +- VoidType[] - | +- FormalParameters[@Empty = true, @Size = 0] - | +- Block[@Empty = false, @Size = 26, @containsComment = true] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] - | | +- VariableDeclarator[@Initializer = true, @Name = "b"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "b", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "42", @IntLiteral = true, @Integral = true, @LiteralText = "42", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 42.0, @ValueAsFloat = 42.0, @ValueAsInt = 42, @ValueAsLong = 42] - | +- IfStatement[@Else = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "b = ", @Empty = false, @Image = "\"b = \"", @Length = 4, @LiteralText = "\"b = \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = " is an int", @Empty = false, @Image = "\" is an int\"", @Length = 10, @LiteralText = "\" is an int\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- VariableDeclarator[@Initializer = true, @Name = "i"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "42", @IntLiteral = true, @Integral = true, @LiteralText = "42", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 42.0, @ValueAsFloat = 42.0, @ValueAsInt = 42, @ValueAsLong = 42] - | +- IfStatement[@Else = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] - | | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "i = ", @Empty = false, @Image = "\"i = \"", @Length = 4, @LiteralText = "\"i = \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = " can be converted to byte", @Empty = false, @Image = "\" can be converted to byte\"", @Length = 25, @LiteralText = "\" can be converted to byte\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- VariableDeclarator[@Initializer = true, @Name = "bigInt"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "bigInt", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1000", @IntLiteral = true, @Integral = true, @LiteralText = "1000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1000.0, @ValueAsFloat = 1000.0, @ValueAsInt = 1000, @ValueAsLong = 1000] - | +- IfStatement[@Else = true] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "bigInt", @Name = "bigInt", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] - | | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | | | +- ExpressionStatement[] - | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | | +- ArgumentList[@Empty = false, @Size = 1] - | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "bigInt = ", @Empty = false, @Image = "\"bigInt = \"", @Length = 9, @LiteralText = "\"bigInt = \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "bigInt", @Name = "bigInt", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "bigInt = ", @Empty = false, @Image = "\"bigInt = \"", @Length = 9, @LiteralText = "\"bigInt = \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "bigInt", @Name = "bigInt", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = " cannot be converted to byte", @Empty = false, @Image = "\" cannot be converted to byte\"", @Length = 28, @LiteralText = "\" cannot be converted to byte\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- VariableDeclarator[@Initializer = true, @Name = "i2"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i2", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "16_777_217", @IntLiteral = true, @Integral = true, @LiteralText = "16_777_217", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.6777217E7, @ValueAsFloat = 1.6777216E7, @ValueAsInt = 16777217, @ValueAsLong = 16777217] - | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "i2 as float: ", @Empty = false, @Image = "\"i2 as float: \"", @Length = 13, @LiteralText = "\"i2 as float: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i2", @Name = "i2", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] - | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "i2 as double: ", @Empty = false, @Image = "\"i2 as double: \"", @Length = 14, @LiteralText = "\"i2 as double: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i2", @Name = "i2", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] - | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "i2 as Integer: ", @Empty = false, @Image = "\"i2 as Integer: \"", @Length = 15, @LiteralText = "\"i2 as Integer: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i2", @Name = "i2", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] - | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "i2 as Number: ", @Empty = false, @Image = "\"i2 as Number: \"", @Length = 14, @LiteralText = "\"i2 as Number: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i2", @Name = "i2", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Number"] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] - | | +- VariableDeclarator[@Initializer = true, @Name = "f"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "f", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "1000.0f", @IntLiteral = false, @Integral = false, @LiteralText = "1000.0f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1000.0, @ValueAsFloat = 1000.0, @ValueAsInt = 1000, @ValueAsLong = 1000] - | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "f as byte: ", @Empty = false, @Image = "\"f as byte: \"", @Length = 11, @LiteralText = "\"f as byte: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "f", @Name = "f", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] - | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "f as int: ", @Empty = false, @Image = "\"f as int: \"", @Length = 10, @LiteralText = "\"f as int: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "f", @Name = "f", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "f as double: ", @Empty = false, @Image = "\"f as double: \"", @Length = 13, @LiteralText = "\"f as double: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "f", @Name = "f", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] - | | +- VariableDeclarator[@Initializer = true, @Name = "d"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "d", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = true, @FloatLiteral = false, @Image = "1000.0d", @IntLiteral = false, @Integral = false, @LiteralText = "1000.0d", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1000.0, @ValueAsFloat = 1000.0, @ValueAsInt = 1000, @ValueAsLong = 1000] - | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "d as byte: ", @Empty = false, @Image = "\"d as byte: \"", @Length = 11, @LiteralText = "\"d as byte: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] - | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "d as int: ", @Empty = false, @Image = "\"d as int: \"", @Length = 10, @LiteralText = "\"d as int: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "d as float: ", @Empty = false, @Image = "\"d as float: \"", @Length = 12, @LiteralText = "\"d as float: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] - | | +- VariableDeclarator[@Initializer = true, @Name = "ii"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "ii", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1000", @IntLiteral = true, @Integral = true, @LiteralText = "1000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1000.0, @ValueAsFloat = 1000.0, @ValueAsInt = 1000, @ValueAsLong = 1000] - | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "ii as int: ", @Empty = false, @Image = "\"ii as int: \"", @Length = 11, @LiteralText = "\"ii as int: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "ii", @Name = "ii", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "ii as float: ", @Empty = false, @Image = "\"ii as float: \"", @Length = 13, @LiteralText = "\"ii as float: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "ii", @Name = "ii", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] - | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "ii as double: ", @Empty = false, @Image = "\"ii as double: \"", @Length = 14, @LiteralText = "\"ii as double: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "ii", @Name = "ii", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] - | | +- VariableDeclarator[@Initializer = true, @Name = "ii2"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "ii2", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "16_777_217", @IntLiteral = true, @Integral = true, @LiteralText = "16_777_217", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.6777217E7, @ValueAsFloat = 1.6777216E7, @ValueAsInt = 16777217, @ValueAsLong = 16777217] - | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "ii2 as float: ", @Empty = false, @Image = "\"ii2 as float: \"", @Length = 14, @LiteralText = "\"ii2 as float: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "ii2", @Name = "ii2", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] - | +- ExpressionStatement[] - | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "ii2 as double: ", @Empty = false, @Image = "\"ii2 as double: \"", @Length = 15, @LiteralText = "\"ii2 as double: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "ii2", @Name = "ii2", @ParenthesisDepth = 0, @Parenthesized = false] - | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] - +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @Name = "primitiveTypePatternsInInstanceof", @Overridden = false, @Static = true, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @Void = true] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.STATIC), @ExplicitModifiers = (JModifier.PUBLIC, JModifier.STATIC)] - | +- VoidType[] - | +- FormalParameters[@Empty = true, @Size = 0] - | +- Block[@Empty = false, @Size = 2, @containsComment = false] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- VariableDeclarator[@Initializer = true, @Name = "i"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1000", @IntLiteral = true, @Integral = true, @LiteralText = "1000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1000.0, @ValueAsFloat = 1000.0, @ValueAsInt = 1000, @ValueAsLong = 1000] - | +- IfStatement[@Else = true] - | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "b", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "b = ", @Empty = false, @Image = "\"b = \"", @Length = 4, @LiteralText = "\"b = \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] - | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- ExpressionStatement[] - | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "i cannot be coverted to byte without loss...", @Empty = false, @Image = "\"i cannot be coverted to byte without loss...\"", @Length = 44, @LiteralText = "\"i cannot be coverted to byte without loss...\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @Name = "primitiveTypePatternsInSwitch", @Overridden = false, @Static = true, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @Void = true] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.STATIC), @ExplicitModifiers = (JModifier.PUBLIC, JModifier.STATIC)] - | +- VoidType[] - | +- FormalParameters[@Empty = true, @Size = 0] - | +- Block[@Empty = false, @Size = 2, @containsComment = false] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- VariableDeclarator[@Initializer = true, @Name = "i"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1000", @IntLiteral = true, @Integral = true, @LiteralText = "1000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1000.0, @ValueAsFloat = 1000.0, @ValueAsInt = 1000, @ValueAsLong = 1000] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] - | +- SwitchFallthroughBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = true] - | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "d", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "d = ", @Empty = false, @Image = "\"d = \"", @Length = 4, @LiteralText = "\"d = \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] - | +- BreakStatement[@Label = null] - +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @Name = "expandedPrimitiveSupportInSwitch", @Overridden = false, @Static = true, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @Void = true] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.STATIC), @ExplicitModifiers = (JModifier.PUBLIC, JModifier.STATIC)] - | +- VoidType[] - | +- FormalParameters[@Empty = true, @Size = 0] - | +- Block[@Empty = false, @Size = 5, @containsComment = false] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] - | | +- VariableDeclarator[@Initializer = true, @Name = "v"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "v", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "1.0f", @IntLiteral = false, @Integral = false, @LiteralText = "1.0f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] - | | +- VariableDeclarator[@Initializer = true, @Name = "f"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "f", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "v", @Name = "v", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] - | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "0f", @IntLiteral = false, @Integral = false, @LiteralText = "0f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] - | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "5f", @IntLiteral = false, @Integral = false, @LiteralText = "5f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 5.0, @ValueAsFloat = 5.0, @ValueAsInt = 5, @ValueAsLong = 5] - | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = true] - | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] - | | | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | | | +- Guard[] - | | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.EQ, @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "1f", @IntLiteral = false, @Integral = false, @LiteralText = "1f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] - | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "6f", @IntLiteral = false, @Integral = false, @LiteralText = "6f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 6.0, @ValueAsFloat = 6.0, @ValueAsInt = 6, @ValueAsLong = 6] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] - | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] - | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "7f", @IntLiteral = false, @Integral = false, @LiteralText = "7f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 7.0, @ValueAsFloat = 7.0, @ValueAsInt = 7, @ValueAsLong = 7] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "f = ", @Empty = false, @Image = "\"f = \"", @Length = 4, @LiteralText = "\"f = \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "f", @Name = "f", @ParenthesisDepth = 0, @Parenthesized = false] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BOOLEAN] - | | +- VariableDeclarator[@Initializer = true, @Name = "b"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "b", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "true", @ParenthesisDepth = 0, @Parenthesized = false, @True = true] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] - | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] - | | | +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "true", @ParenthesisDepth = 0, @Parenthesized = false, @True = true] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "b was true", @Empty = false, @Image = "\"b was true\"", @Length = 10, @LiteralText = "\"b was true\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = false] - | | +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "false", @ParenthesisDepth = 0, @Parenthesized = false, @True = false] - | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "b was false", @Empty = false, @Image = "\"b was false\"", @Length = 11, @LiteralText = "\"b was false\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- MethodDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @MainMethod = true, @Name = "main", @Overridden = false, @Static = true, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @Void = true] - +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.STATIC), @ExplicitModifiers = (JModifier.PUBLIC, JModifier.STATIC)] - +- VoidType[] - +- FormalParameters[@Empty = false, @Size = 1] - | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- ArrayType[@ArrayDepth = 1] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] - | | +- ArrayDimensions[@Empty = false, @Size = 1] - | | +- ArrayTypeDim[@Varargs = false] - | +- VariableId[@ArrayType = true, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "args", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - +- Block[@Empty = false, @Size = 4, @containsComment = false] - +- ExpressionStatement[] - | +- MethodCall[@CompileTimeConstant = false, @Image = "instanceofWithPrimitiveTypes", @MethodName = "instanceofWithPrimitiveTypes", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ArgumentList[@Empty = true, @Size = 0] - +- ExpressionStatement[] - | +- MethodCall[@CompileTimeConstant = false, @Image = "primitiveTypePatternsInInstanceof", @MethodName = "primitiveTypePatternsInInstanceof", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ArgumentList[@Empty = true, @Size = 0] - +- ExpressionStatement[] - | +- MethodCall[@CompileTimeConstant = false, @Image = "primitiveTypePatternsInSwitch", @MethodName = "primitiveTypePatternsInSwitch", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ArgumentList[@Empty = true, @Size = 0] - +- ExpressionStatement[] - +- MethodCall[@CompileTimeConstant = false, @Image = "expandedPrimitiveSupportInSwitch", @MethodName = "expandedPrimitiveSupportInSwitch", @ParenthesisDepth = 0, @Parenthesized = false] - +- ArgumentList[@Empty = true, @Size = 0] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep476_ModuleImportDeclarations.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep476_ModuleImportDeclarations.java deleted file mode 100644 index ddfb68b8561..00000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep476_ModuleImportDeclarations.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -import module java.base; -import module java.desktop; - -import java.util.List; - -/** - * @see JEP 476: Module Import Declarations (Preview) (Java 23) - */ -public class Jep476_ModuleImportDeclarations { - public static void main(String[] args) { - File f = new File("."); - List myList = new ArrayList<>(); - myList.add(f); - System.out.println("myList = " + myList); - } -} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep476_ModuleImportDeclarations.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep476_ModuleImportDeclarations.txt deleted file mode 100644 index 8fd7fa761ce..00000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep476_ModuleImportDeclarations.txt +++ /dev/null @@ -1,53 +0,0 @@ -+- CompilationUnit[@PackageName = ""] - +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.base", @ImportedSimpleName = null, @ModuleImport = true, @PackageName = null, @Static = false] - +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.desktop", @ImportedSimpleName = null, @ModuleImport = true, @PackageName = null, @Static = false] - +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.List", @ImportedSimpleName = "List", @ModuleImport = false, @PackageName = "java.util", @Static = false] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep476_ModuleImportDeclarations", @CanonicalName = "Jep476_ModuleImportDeclarations", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Jep476_ModuleImportDeclarations", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] - +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - +- ClassBody[@Empty = false, @Size = 1] - +- MethodDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @MainMethod = true, @Name = "main", @Overridden = false, @Static = true, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @Void = true] - +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.STATIC), @ExplicitModifiers = (JModifier.PUBLIC, JModifier.STATIC)] - +- VoidType[] - +- FormalParameters[@Empty = false, @Size = 1] - | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- ArrayType[@ArrayDepth = 1] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] - | | +- ArrayDimensions[@Empty = false, @Size = 1] - | | +- ArrayTypeDim[@Varargs = false] - | +- VariableId[@ArrayType = true, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "args", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - +- Block[@Empty = false, @Size = 4, @containsComment = false] - +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "File"] - | +- VariableDeclarator[@Initializer = true, @Name = "f"] - | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "f", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "File"] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = ".", @Empty = false, @Image = "\".\"", @Length = 1, @LiteralText = "\".\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "List"] - | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "File"] - | +- VariableDeclarator[@Initializer = true, @Name = "myList"] - | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "myList", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = true, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "ArrayList"] - | | +- TypeArguments[@Diamond = true, @Empty = true, @Size = 0] - | +- ArgumentList[@Empty = true, @Size = 0] - +- ExpressionStatement[] - | +- MethodCall[@CompileTimeConstant = false, @Image = "add", @MethodName = "add", @ParenthesisDepth = 0, @Parenthesized = false] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "myList", @Name = "myList", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "f", @Name = "f", @ParenthesisDepth = 0, @Parenthesized = false] - +- ExpressionStatement[] - +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - +- ArgumentList[@Empty = false, @Size = 1] - +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "myList = ", @Empty = false, @Image = "\"myList = \"", @Length = 9, @LiteralText = "\"myList = \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "myList", @Name = "myList", @ParenthesisDepth = 0, @Parenthesized = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep477_ImplicitlyDeclaredClassesAndInstanceMainMethods1.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep477_ImplicitlyDeclaredClassesAndInstanceMainMethods1.java deleted file mode 100644 index a47ed80e4d0..00000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep477_ImplicitlyDeclaredClassesAndInstanceMainMethods1.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - - - -/** - * @see JEP 445: Unnamed Classes and Instance Main Methods (Preview) (Java 21) - * @see JEP 463: Implicitly Declared Classes and Instance Main Methods (Second Preview) (Java 22) - * @see JEP 477: Implicitly Declared Classes and Instance Main Methods (Third Preview) (Java 23) - */ - -void main() { - System.out.println("Hello World"); - println("Hello, World!"); // since JEP477, implicitly imports "import static java.io.IO.*" - - // this is java.io.IO.readln ... - String name = readln("Please enter your name: "); - print("Pleased to meet you, "); - println(name); - - // this is java.util.List - by implicitly "import module java.base" - var authors = List.of("James", "Bill", "Guy", "Alex", "Dan", "Gavin"); - for (var authorName : authors) { - println(authorName + ": " + authorName.length()); - } -} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep477_ImplicitlyDeclaredClassesAndInstanceMainMethods1.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep477_ImplicitlyDeclaredClassesAndInstanceMainMethods1.txt deleted file mode 100644 index 1ea00bd0fb5..00000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep477_ImplicitlyDeclaredClassesAndInstanceMainMethods1.txt +++ /dev/null @@ -1,67 +0,0 @@ -+- CompilationUnit[@PackageName = ""] - +- ImplicitClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "", @CanonicalName = null, @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = false, @SimpleName = "", @Static = false, @TopLevel = true, @UnnamedToplevelClass = true, @Visibility = Visibility.V_PACKAGE] - +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - +- ClassBody[@Empty = false, @Size = 1] - +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @MainMethod = true, @Name = "main", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] - +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - +- VoidType[] - +- FormalParameters[@Empty = true, @Size = 0] - +- Block[@Empty = false, @Size = 7, @containsComment = false] - +- ExpressionStatement[] - | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Hello World", @Empty = false, @Image = "\"Hello World\"", @Length = 11, @LiteralText = "\"Hello World\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- ExpressionStatement[] - | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Hello, World!", @Empty = false, @Image = "\"Hello, World!\"", @Length = 13, @LiteralText = "\"Hello, World!\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] - | +- VariableDeclarator[@Initializer = true, @Name = "name"] - | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "name", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- MethodCall[@CompileTimeConstant = false, @Image = "readln", @MethodName = "readln", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Please enter your name: ", @Empty = false, @Image = "\"Please enter your name: \"", @Length = 24, @LiteralText = "\"Please enter your name: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- ExpressionStatement[] - | +- MethodCall[@CompileTimeConstant = false, @Image = "print", @MethodName = "print", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Pleased to meet you, ", @Empty = false, @Image = "\"Pleased to meet you, \"", @Length = 21, @LiteralText = "\"Pleased to meet you, \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- ExpressionStatement[] - | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "name", @Name = "name", @ParenthesisDepth = 0, @Parenthesized = false] - +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = true, @Visibility = Visibility.V_LOCAL] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- VariableDeclarator[@Initializer = true, @Name = "authors"] - | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "authors", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- MethodCall[@CompileTimeConstant = false, @Image = "of", @MethodName = "of", @ParenthesisDepth = 0, @Parenthesized = false] - | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "List"] - | +- ArgumentList[@Empty = false, @Size = 6] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "James", @Empty = false, @Image = "\"James\"", @Length = 5, @LiteralText = "\"James\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Bill", @Empty = false, @Image = "\"Bill\"", @Length = 4, @LiteralText = "\"Bill\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Guy", @Empty = false, @Image = "\"Guy\"", @Length = 3, @LiteralText = "\"Guy\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Alex", @Empty = false, @Image = "\"Alex\"", @Length = 4, @LiteralText = "\"Alex\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Dan", @Empty = false, @Image = "\"Dan\"", @Length = 3, @LiteralText = "\"Dan\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Gavin", @Empty = false, @Image = "\"Gavin\"", @Length = 5, @LiteralText = "\"Gavin\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- ForeachStatement[] - +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = true, @Visibility = Visibility.V_LOCAL] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- VariableDeclarator[@Initializer = false, @Name = "authorName"] - | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = true, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "authorName", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "authors", @Name = "authors", @ParenthesisDepth = 0, @Parenthesized = false] - +- Block[@Empty = false, @Size = 1, @containsComment = false] - +- ExpressionStatement[] - +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - +- ArgumentList[@Empty = false, @Size = 1] - +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "authorName", @Name = "authorName", @ParenthesisDepth = 0, @Parenthesized = false] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = ": ", @Empty = false, @Image = "\": \"", @Length = 2, @LiteralText = "\": \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- MethodCall[@CompileTimeConstant = false, @Image = "length", @MethodName = "length", @ParenthesisDepth = 0, @Parenthesized = false] - +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "authorName", @Name = "authorName", @ParenthesisDepth = 0, @Parenthesized = false] - +- ArgumentList[@Empty = true, @Size = 0] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep477_ImplicitlyDeclaredClassesAndInstanceMainMethods2.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep477_ImplicitlyDeclaredClassesAndInstanceMainMethods2.java deleted file mode 100644 index 2974f3d59c8..00000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep477_ImplicitlyDeclaredClassesAndInstanceMainMethods2.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// explicit imports are possible as well (although not really needed in this example) -import java.util.Arrays; -import java.util.stream.Collectors; - -/** - * @see JEP 445: Unnamed Classes and Instance Main Methods (Preview) (Java 21) - * @see JEP 463: Implicitly Declared Classes and Instance Main Methods (Second Preview) (Java 22) - * @see JEP 477: Implicitly Declared Classes and Instance Main Methods (Third Preview) (Java 23) - */ - -// Top-level members are interpreted as members of the implicit class (methods and fields) -String greeting() { return "Hello, World! (method)"; } -String greetingText = "Hello, World! (text)"; -String greetingText2 = Arrays.asList("Hello", "World!", "(with imports)").stream().collect(Collectors.joining(", ")); - -void main() { - System.out.println(greeting()); - println(greetingText); - println(greetingText2); -} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep477_ImplicitlyDeclaredClassesAndInstanceMainMethods2.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep477_ImplicitlyDeclaredClassesAndInstanceMainMethods2.txt deleted file mode 100644 index 61df683d8ca..00000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep477_ImplicitlyDeclaredClassesAndInstanceMainMethods2.txt +++ /dev/null @@ -1,61 +0,0 @@ -+- CompilationUnit[@PackageName = ""] - +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.Arrays", @ImportedSimpleName = "Arrays", @ModuleImport = false, @PackageName = "java.util", @Static = false] - +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.stream.Collectors", @ImportedSimpleName = "Collectors", @ModuleImport = false, @PackageName = "java.util.stream", @Static = false] - +- ImplicitClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "", @CanonicalName = null, @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = false, @SimpleName = "", @Static = false, @TopLevel = true, @UnnamedToplevelClass = true, @Visibility = Visibility.V_PACKAGE] - +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - +- ClassBody[@Empty = false, @Size = 4] - +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "greeting", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = false] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] - | +- FormalParameters[@Empty = true, @Size = 0] - | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- ReturnStatement[] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Hello, World! (method)", @Empty = false, @Image = "\"Hello, World! (method)\"", @Length = 22, @LiteralText = "\"Hello, World! (method)\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- FieldDeclaration[@EffectiveVisibility = Visibility.V_PACKAGE, @Static = false, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] - | +- VariableDeclarator[@Initializer = true, @Name = "greetingText"] - | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PACKAGE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = true, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "greetingText", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PACKAGE] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Hello, World! (text)", @Empty = false, @Image = "\"Hello, World! (text)\"", @Length = 20, @LiteralText = "\"Hello, World! (text)\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- FieldDeclaration[@EffectiveVisibility = Visibility.V_PACKAGE, @Static = false, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] - | +- VariableDeclarator[@Initializer = true, @Name = "greetingText2"] - | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PACKAGE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = true, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "greetingText2", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PACKAGE] - | +- MethodCall[@CompileTimeConstant = false, @Image = "collect", @MethodName = "collect", @ParenthesisDepth = 0, @Parenthesized = false] - | +- MethodCall[@CompileTimeConstant = false, @Image = "stream", @MethodName = "stream", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "asList", @MethodName = "asList", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Arrays"] - | | | +- ArgumentList[@Empty = false, @Size = 3] - | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Hello", @Empty = false, @Image = "\"Hello\"", @Length = 5, @LiteralText = "\"Hello\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "World!", @Empty = false, @Image = "\"World!\"", @Length = 6, @LiteralText = "\"World!\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "(with imports)", @Empty = false, @Image = "\"(with imports)\"", @Length = 14, @LiteralText = "\"(with imports)\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- ArgumentList[@Empty = true, @Size = 0] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- MethodCall[@CompileTimeConstant = false, @Image = "joining", @MethodName = "joining", @ParenthesisDepth = 0, @Parenthesized = false] - | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Collectors"] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = ", ", @Empty = false, @Image = "\", \"", @Length = 2, @LiteralText = "\", \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @MainMethod = true, @Name = "main", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] - +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - +- VoidType[] - +- FormalParameters[@Empty = true, @Size = 0] - +- Block[@Empty = false, @Size = 3, @containsComment = false] - +- ExpressionStatement[] - | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- MethodCall[@CompileTimeConstant = false, @Image = "greeting", @MethodName = "greeting", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ArgumentList[@Empty = true, @Size = 0] - +- ExpressionStatement[] - | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "greetingText", @Name = "greetingText", @ParenthesisDepth = 0, @Parenthesized = false] - +- ExpressionStatement[] - +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - +- ArgumentList[@Empty = false, @Size = 1] - +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "greetingText2", @Name = "greetingText2", @ParenthesisDepth = 0, @Parenthesized = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep482_FlexibleConstructorBodies.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep482_FlexibleConstructorBodies.java deleted file mode 100644 index ea1461ab796..00000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep482_FlexibleConstructorBodies.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -import java.math.BigInteger; -import java.nio.charset.StandardCharsets; -import java.security.cert.Certificate; -import java.security.interfaces.DSAPublicKey; -import java.security.interfaces.RSAKey; - -/** - * @see JEP 447: Statements before super(...) (Preview) (Java 22) - * @see JEP 482: Flexible Constructor Bodies (Second Preview) (Java 23) - */ -class Jep482_FlexibleConstructorBodies { - // To test backwards compatibility - "normal" explicit constructor invocation - public static class Old { - public Old() { - super(); - } - } - - // Example: Validating superclass constructor arguments - public static class PositiveBigInteger extends BigInteger { - - public PositiveBigInteger(long value) { - if (value <= 0) - throw new IllegalArgumentException("non-positive value"); - final String valueAsString = String.valueOf(value); - super(valueAsString); - } - } - - // Example: Preparing superclass constructor arguments - public static class Super { - public Super(byte[] bytes) {} - } - - public class Sub extends Super { - public Sub(Certificate certificate) { - var publicKey = certificate.getPublicKey(); - if (publicKey == null) - throw new IllegalArgumentException("null certificate"); - final byte[] byteArray = switch (publicKey) { - case RSAKey rsaKey -> rsaKey.toString().getBytes(StandardCharsets.UTF_8); - case DSAPublicKey dsaKey -> dsaKey.toString().getBytes(StandardCharsets.UTF_8); - default -> new byte[0]; - }; - super(byteArray); - } - } - - // Example: Sharing superclass constructor arguments - public static class F {} - public static class Super2 { - public Super2(F f1, F f2) {} - } - public class Sub2 extends Super2 { - public Sub2(int i) { - var f = new F(); - super(f, f); - // ... i ... - } - } - - // Example with records - public record Range(int lo, int hi) { - public Range(int lo, int hi, int maxDistance) { - if (lo > hi) - throw new IllegalArgumentException(String.format("(%d,%d)", lo, hi)); - if (hi - lo > maxDistance) - throw new IllegalArgumentException(String.format("(%d,%d,%d", lo, hi, maxDistance)); - this(lo, hi); - } - } - - // Example with enum - public enum Color { - BLUE(1); - private Color() { - } - private Color(int a) { - if (a < 0) throw new IllegalArgumentException(); - this(); - }; - } - - // Example for Early assignment to fields (new with Java 23 preview) - public static class EarlyAssignmentToFieldsSuper { - EarlyAssignmentToFieldsSuper() { overriddenMethod(); } - - void overriddenMethod() { System.out.println("hello"); } - } - - public static class EarlyAssignmentToFieldsSub extends EarlyAssignmentToFieldsSuper { - final int x; - - EarlyAssignmentToFieldsSub(int x) { - this.x = x; // Initialize the field - super(); // Then invoke the Super constructor explicitly - } - - @Override - void overriddenMethod() { System.out.println(x); } - } -} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep482_FlexibleConstructorBodies.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep482_FlexibleConstructorBodies.txt deleted file mode 100644 index 0233d0ccdc9..00000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/Jep482_FlexibleConstructorBodies.txt +++ /dev/null @@ -1,344 +0,0 @@ -+- CompilationUnit[@PackageName = ""] - +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.math.BigInteger", @ImportedSimpleName = "BigInteger", @ModuleImport = false, @PackageName = "java.math", @Static = false] - +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.nio.charset.StandardCharsets", @ImportedSimpleName = "StandardCharsets", @ModuleImport = false, @PackageName = "java.nio.charset", @Static = false] - +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.security.cert.Certificate", @ImportedSimpleName = "Certificate", @ModuleImport = false, @PackageName = "java.security.cert", @Static = false] - +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.security.interfaces.DSAPublicKey", @ImportedSimpleName = "DSAPublicKey", @ModuleImport = false, @PackageName = "java.security.interfaces", @Static = false] - +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.security.interfaces.RSAKey", @ImportedSimpleName = "RSAKey", @ModuleImport = false, @PackageName = "java.security.interfaces", @Static = false] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep482_FlexibleConstructorBodies", @CanonicalName = "Jep482_FlexibleConstructorBodies", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Jep482_FlexibleConstructorBodies", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] - +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - +- ClassBody[@Empty = false, @Size = 11] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep482_FlexibleConstructorBodies$Old", @CanonicalName = "Jep482_FlexibleConstructorBodies.Old", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Old", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.STATIC), @ExplicitModifiers = (JModifier.PUBLIC, JModifier.STATIC)] - | +- ClassBody[@Empty = false, @Size = 1] - | +- ConstructorDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Image = "Old", @Name = "Old", @Static = false, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @containsComment = false] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - | +- FormalParameters[@Empty = true, @Size = 0] - | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- ExplicitConstructorInvocation[@ArgumentCount = 0, @MethodName = "new", @Qualified = false, @Super = true, @This = false] - | +- ArgumentList[@Empty = true, @Size = 0] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep482_FlexibleConstructorBodies$PositiveBigInteger", @CanonicalName = "Jep482_FlexibleConstructorBodies.PositiveBigInteger", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "PositiveBigInteger", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.STATIC), @ExplicitModifiers = (JModifier.PUBLIC, JModifier.STATIC)] - | +- ExtendsList[@Empty = false, @Size = 1] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "BigInteger"] - | +- ClassBody[@Empty = false, @Size = 1] - | +- ConstructorDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Image = "PositiveBigInteger", @Name = "PositiveBigInteger", @Static = false, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @containsComment = false] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - | +- FormalParameters[@Empty = false, @Size = 1] - | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.LONG] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "value", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- Block[@Empty = false, @Size = 3, @containsComment = false] - | +- IfStatement[@Else = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.LE, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "value", @Name = "value", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] - | | +- ThrowStatement[] - | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "IllegalArgumentException"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "non-positive value", @Empty = false, @Image = "\"non-positive value\"", @Length = 18, @LiteralText = "\"non-positive value\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = true, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (JModifier.FINAL), @ExplicitModifiers = (JModifier.FINAL)] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] - | | +- VariableDeclarator[@Initializer = true, @Name = "valueAsString"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "valueAsString", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "valueOf", @MethodName = "valueOf", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "value", @Name = "value", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ExplicitConstructorInvocation[@ArgumentCount = 1, @MethodName = "new", @Qualified = false, @Super = true, @This = false] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "valueAsString", @Name = "valueAsString", @ParenthesisDepth = 0, @Parenthesized = false] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep482_FlexibleConstructorBodies$Super", @CanonicalName = "Jep482_FlexibleConstructorBodies.Super", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Super", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.STATIC), @ExplicitModifiers = (JModifier.PUBLIC, JModifier.STATIC)] - | +- ClassBody[@Empty = false, @Size = 1] - | +- ConstructorDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Image = "Super", @Name = "Super", @Static = false, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @containsComment = false] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - | +- FormalParameters[@Empty = false, @Size = 1] - | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- ArrayType[@ArrayDepth = 1] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] - | | | +- ArrayDimensions[@Empty = false, @Size = 1] - | | | +- ArrayTypeDim[@Varargs = false] - | | +- VariableId[@ArrayType = true, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "bytes", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- Block[@Empty = true, @Size = 0, @containsComment = false] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep482_FlexibleConstructorBodies$Sub", @CanonicalName = "Jep482_FlexibleConstructorBodies.Sub", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Sub", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - | +- ExtendsList[@Empty = false, @Size = 1] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Super"] - | +- ClassBody[@Empty = false, @Size = 1] - | +- ConstructorDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Image = "Sub", @Name = "Sub", @Static = false, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @containsComment = false] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - | +- FormalParameters[@Empty = false, @Size = 1] - | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Certificate"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "certificate", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- Block[@Empty = false, @Size = 4, @containsComment = false] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = true, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- VariableDeclarator[@Initializer = true, @Name = "publicKey"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "publicKey", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "getPublicKey", @MethodName = "getPublicKey", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "certificate", @Name = "certificate", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ArgumentList[@Empty = true, @Size = 0] - | +- IfStatement[@Else = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.EQ, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "publicKey", @Name = "publicKey", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ThrowStatement[] - | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "IllegalArgumentException"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "null certificate", @Empty = false, @Image = "\"null certificate\"", @Length = 16, @LiteralText = "\"null certificate\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = true, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (JModifier.FINAL), @ExplicitModifiers = (JModifier.FINAL)] - | | +- ArrayType[@ArrayDepth = 1] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] - | | | +- ArrayDimensions[@Empty = false, @Size = 1] - | | | +- ArrayTypeDim[@Varargs = false] - | | +- VariableDeclarator[@Initializer = true, @Name = "byteArray"] - | | +- VariableId[@ArrayType = true, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "byteArray", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "publicKey", @Name = "publicKey", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = true] - | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "RSAKey"] - | | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "rsaKey", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | | +- MethodCall[@CompileTimeConstant = false, @Image = "getBytes", @MethodName = "getBytes", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- MethodCall[@CompileTimeConstant = false, @Image = "toString", @MethodName = "toString", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "rsaKey", @Name = "rsaKey", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- ArgumentList[@Empty = true, @Size = 0] - | | | +- ArgumentList[@Empty = false, @Size = 1] - | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "UTF_8", @Name = "UTF_8", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "StandardCharsets"] - | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = true] - | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "DSAPublicKey"] - | | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "dsaKey", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | | +- MethodCall[@CompileTimeConstant = false, @Image = "getBytes", @MethodName = "getBytes", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- MethodCall[@CompileTimeConstant = false, @Image = "toString", @MethodName = "toString", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "dsaKey", @Name = "dsaKey", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- ArgumentList[@Empty = true, @Size = 0] - | | | +- ArgumentList[@Empty = false, @Size = 1] - | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "UTF_8", @Name = "UTF_8", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "StandardCharsets"] - | | +- SwitchArrowBranch[@Default = true] - | | +- SwitchLabel[@Default = true, @PatternLabel = false] - | | +- ArrayAllocation[@ArrayDepth = 1, @CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ArrayType[@ArrayDepth = 1] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] - | | +- ArrayDimensions[@Empty = false, @Size = 1] - | | +- ArrayDimExpr[@Varargs = false] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] - | +- ExplicitConstructorInvocation[@ArgumentCount = 1, @MethodName = "new", @Qualified = false, @Super = true, @This = false] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "byteArray", @Name = "byteArray", @ParenthesisDepth = 0, @Parenthesized = false] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep482_FlexibleConstructorBodies$F", @CanonicalName = "Jep482_FlexibleConstructorBodies.F", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "F", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.STATIC), @ExplicitModifiers = (JModifier.PUBLIC, JModifier.STATIC)] - | +- ClassBody[@Empty = true, @Size = 0] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep482_FlexibleConstructorBodies$Super2", @CanonicalName = "Jep482_FlexibleConstructorBodies.Super2", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Super2", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.STATIC), @ExplicitModifiers = (JModifier.PUBLIC, JModifier.STATIC)] - | +- ClassBody[@Empty = false, @Size = 1] - | +- ConstructorDeclaration[@Abstract = false, @Arity = 2, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Image = "Super2", @Name = "Super2", @Static = false, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @containsComment = false] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - | +- FormalParameters[@Empty = false, @Size = 2] - | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "F"] - | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "f1", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "F"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "f2", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- Block[@Empty = true, @Size = 0, @containsComment = false] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep482_FlexibleConstructorBodies$Sub2", @CanonicalName = "Jep482_FlexibleConstructorBodies.Sub2", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Sub2", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - | +- ExtendsList[@Empty = false, @Size = 1] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Super2"] - | +- ClassBody[@Empty = false, @Size = 1] - | +- ConstructorDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Image = "Sub2", @Name = "Sub2", @Static = false, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @containsComment = true] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - | +- FormalParameters[@Empty = false, @Size = 1] - | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- Block[@Empty = false, @Size = 2, @containsComment = true] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = true, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- VariableDeclarator[@Initializer = true, @Name = "f"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "f", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "F"] - | | +- ArgumentList[@Empty = true, @Size = 0] - | +- ExplicitConstructorInvocation[@ArgumentCount = 2, @MethodName = "new", @Qualified = false, @Super = true, @This = false] - | +- ArgumentList[@Empty = false, @Size = 2] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "f", @Name = "f", @ParenthesisDepth = 0, @Parenthesized = false] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "f", @Name = "f", @ParenthesisDepth = 0, @Parenthesized = false] - +- RecordDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep482_FlexibleConstructorBodies$Range", @CanonicalName = "Jep482_FlexibleConstructorBodies.Range", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = true, @RegularClass = false, @RegularInterface = false, @SimpleName = "Range", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = (JModifier.PUBLIC)] - | +- RecordComponentList[@Empty = false, @Size = 2, @Varargs = false] - | | +- RecordComponent[@EffectiveVisibility = Visibility.V_PRIVATE, @Varargs = false, @Visibility = Visibility.V_PRIVATE] - | | | +- ModifierList[@EffectiveModifiers = (JModifier.PRIVATE, JModifier.FINAL), @ExplicitModifiers = ()] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PRIVATE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "lo", @PatternBinding = false, @RecordComponent = true, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PRIVATE] - | | +- RecordComponent[@EffectiveVisibility = Visibility.V_PRIVATE, @Varargs = false, @Visibility = Visibility.V_PRIVATE] - | | +- ModifierList[@EffectiveModifiers = (JModifier.PRIVATE, JModifier.FINAL), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PRIVATE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "hi", @PatternBinding = false, @RecordComponent = true, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PRIVATE] - | +- RecordBody[@Empty = false, @Size = 1] - | +- ConstructorDeclaration[@Abstract = false, @Arity = 3, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Image = "Range", @Name = "Range", @Static = false, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @containsComment = false] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - | +- FormalParameters[@Empty = false, @Size = 3] - | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "lo", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "hi", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "maxDistance", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- Block[@Empty = false, @Size = 3, @containsComment = false] - | +- IfStatement[@Else = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.GT, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "lo", @Name = "lo", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "hi", @Name = "hi", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ThrowStatement[] - | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "IllegalArgumentException"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "format", @MethodName = "format", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] - | | +- ArgumentList[@Empty = false, @Size = 3] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "(%d,%d)", @Empty = false, @Image = "\"(%d,%d)\"", @Length = 7, @LiteralText = "\"(%d,%d)\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "lo", @Name = "lo", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "hi", @Name = "hi", @ParenthesisDepth = 0, @Parenthesized = false] - | +- IfStatement[@Else = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.GT, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.SUB, @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "hi", @Name = "hi", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "lo", @Name = "lo", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "maxDistance", @Name = "maxDistance", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ThrowStatement[] - | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "IllegalArgumentException"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "format", @MethodName = "format", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] - | | +- ArgumentList[@Empty = false, @Size = 4] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "(%d,%d,%d", @Empty = false, @Image = "\"(%d,%d,%d\"", @Length = 9, @LiteralText = "\"(%d,%d,%d\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "lo", @Name = "lo", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "hi", @Name = "hi", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "maxDistance", @Name = "maxDistance", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ExplicitConstructorInvocation[@ArgumentCount = 2, @MethodName = "new", @Qualified = false, @Super = false, @This = true] - | +- ArgumentList[@Empty = false, @Size = 2] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "lo", @Name = "lo", @ParenthesisDepth = 0, @Parenthesized = false] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "hi", @Name = "hi", @ParenthesisDepth = 0, @Parenthesized = false] - +- EnumDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep482_FlexibleConstructorBodies$Color", @CanonicalName = "Jep482_FlexibleConstructorBodies.Color", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = true, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = false, @SimpleName = "Color", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = (JModifier.PUBLIC)] - | +- EnumBody[@Empty = false, @SeparatorSemi = true, @Size = 4, @TrailingComma = false] - | +- EnumConstant[@AnonymousClass = false, @EffectiveVisibility = Visibility.V_PACKAGE, @Image = "BLUE", @MethodName = "new", @Name = "BLUE", @Visibility = Visibility.V_PUBLIC] - | | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = ()] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PACKAGE, @EnumConstant = true, @ExceptionBlockParameter = false, @Field = false, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "BLUE", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = true, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_PUBLIC] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] - | +- ConstructorDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PRIVATE, @Final = false, @Image = "Color", @Name = "Color", @Static = false, @Varargs = false, @Visibility = Visibility.V_PRIVATE, @containsComment = false] - | | +- ModifierList[@EffectiveModifiers = (JModifier.PRIVATE), @ExplicitModifiers = (JModifier.PRIVATE)] - | | +- FormalParameters[@Empty = true, @Size = 0] - | | +- Block[@Empty = true, @Size = 0, @containsComment = false] - | +- ConstructorDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PRIVATE, @Final = false, @Image = "Color", @Name = "Color", @Static = false, @Varargs = false, @Visibility = Visibility.V_PRIVATE, @containsComment = false] - | | +- ModifierList[@EffectiveModifiers = (JModifier.PRIVATE), @ExplicitModifiers = (JModifier.PRIVATE)] - | | +- FormalParameters[@Empty = false, @Size = 1] - | | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "a", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- Block[@Empty = false, @Size = 2, @containsComment = false] - | | +- IfStatement[@Else = false] - | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.LT, @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "a", @Name = "a", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] - | | | +- ThrowStatement[] - | | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "IllegalArgumentException"] - | | | +- ArgumentList[@Empty = true, @Size = 0] - | | +- ExplicitConstructorInvocation[@ArgumentCount = 0, @MethodName = "new", @Qualified = false, @Super = false, @This = true] - | | +- ArgumentList[@Empty = true, @Size = 0] - | +- EmptyDeclaration[] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep482_FlexibleConstructorBodies$EarlyAssignmentToFieldsSuper", @CanonicalName = "Jep482_FlexibleConstructorBodies.EarlyAssignmentToFieldsSuper", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "EarlyAssignmentToFieldsSuper", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.STATIC), @ExplicitModifiers = (JModifier.PUBLIC, JModifier.STATIC)] - | +- ClassBody[@Empty = false, @Size = 2] - | +- ConstructorDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Image = "EarlyAssignmentToFieldsSuper", @Name = "EarlyAssignmentToFieldsSuper", @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @containsComment = false] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- FormalParameters[@Empty = true, @Size = 0] - | | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "overriddenMethod", @MethodName = "overriddenMethod", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ArgumentList[@Empty = true, @Size = 0] - | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "overriddenMethod", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- VoidType[] - | +- FormalParameters[@Empty = true, @Size = 0] - | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- ExpressionStatement[] - | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "hello", @Empty = false, @Image = "\"hello\"", @Length = 5, @LiteralText = "\"hello\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep482_FlexibleConstructorBodies$EarlyAssignmentToFieldsSub", @CanonicalName = "Jep482_FlexibleConstructorBodies.EarlyAssignmentToFieldsSub", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "EarlyAssignmentToFieldsSub", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] - +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.STATIC), @ExplicitModifiers = (JModifier.PUBLIC, JModifier.STATIC)] - +- ExtendsList[@Empty = false, @Size = 1] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "EarlyAssignmentToFieldsSuper"] - +- ClassBody[@Empty = false, @Size = 3] - +- FieldDeclaration[@EffectiveVisibility = Visibility.V_PACKAGE, @Static = false, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (JModifier.FINAL), @ExplicitModifiers = (JModifier.FINAL)] - | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | +- VariableDeclarator[@Initializer = false, @Name = "x"] - | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PACKAGE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = true, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PACKAGE] - +- ConstructorDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Image = "EarlyAssignmentToFieldsSub", @Name = "EarlyAssignmentToFieldsSub", @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @containsComment = true] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- FormalParameters[@Empty = false, @Size = 1] - | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- Block[@Empty = false, @Size = 2, @containsComment = true] - | +- ExpressionStatement[] - | | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ThisExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ExplicitConstructorInvocation[@ArgumentCount = 0, @MethodName = "new", @Qualified = false, @Super = true, @This = false] - | +- ArgumentList[@Empty = true, @Size = 0] - +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "overriddenMethod", @Overridden = true, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] - +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- Annotation[@SimpleName = "Override"] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Override"] - +- VoidType[] - +- FormalParameters[@Empty = true, @Size = 0] - +- Block[@Empty = false, @Size = 1, @containsComment = false] - +- ExpressionStatement[] - +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - +- ArgumentList[@Empty = false, @Size = 1] - +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/StringTemplatesAreNotSupportedAnymore.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/StringTemplatesAreNotSupportedAnymore.java deleted file mode 100644 index f2346fa84c5..00000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23p/StringTemplatesAreNotSupportedAnymore.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -/** - * It was decided, that String Templates will be removed. - * - * @see JDK-8329949 Remove the String Templates preview feature (Java 23) - */ -public class StringTemplatesAreNotSupportedAnymore { - static void STRTemplateProcessor() { - // Embedded expressions can be strings - String firstName = "Bill"; - String lastName = "Duck"; - String fullName = STR."\{firstName} \{lastName}"; - // | "Bill Duck" - String sortName = STR."\{lastName}, \{firstName}"; - // | "Duck, Bill" - } -} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml index b99003af102..b01453c39f5 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml @@ -1273,7 +1273,7 @@ public class Foo { private File file; // imported via module import from java.base } ]]> - java 23-preview + java 24-preview @@ -1288,7 +1288,7 @@ import module java.base; // unnecessary public class Foo { } ]]> - java 23-preview + java 24-preview @@ -1302,7 +1302,7 @@ public class Foo { private File file; } ]]> - java 23-preview + java 24-preview @@ -1319,7 +1319,7 @@ public class Foo { private File file; } ]]> - java 23-preview + java 24-preview From 5a11bf91018ca010cafc71ab4dc7c552277e17e2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 3 Jul 2025 11:40:06 +0200 Subject: [PATCH 1081/1962] [java] Update implementation for JEP 507 Primitive Types in Patterns, instanceof, and switch (Third Preview) --- .../ast/internal/LanguageLevelChecker.java | 3 +- .../java/ast/Java25PreviewTreeDumpTest.java | 18 + .../java/ast/ASTInstanceOfExpressionTest.kt | 5 +- ...iveTypesInPatternsInstanceofAndSwitch.java | 173 ++++ ...tiveTypesInPatternsInstanceofAndSwitch.txt | 742 ++++++++++++++++++ 5 files changed, 938 insertions(+), 3 deletions(-) create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25p/Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25p/Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.txt diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java index 872d1000401..af7884e758d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java @@ -156,8 +156,9 @@ private enum PreviewFeature implements LanguageFeature { * Primitive types in patterns, instanceof, and switch * @see JEP 455: Primitive Types in Patterns, instanceof, and switch (Preview) (Java 23) * @see JEP 488: Primitive Types in Patterns, instanceof, and switch (Second Preview) (Java 24) + * @see JEP 507: Primitive Types in Patterns, instanceof, and switch (Third Preview) (Java 25) */ - PRIMITIVE_TYPES_IN_PATTERNS_INSTANCEOF_AND_SWITCH(23, 24, false), + PRIMITIVE_TYPES_IN_PATTERNS_INSTANCEOF_AND_SWITCH(23, 25, false), ; // SUPPRESS CHECKSTYLE enum trailing semi is awesome diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25PreviewTreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25PreviewTreeDumpTest.java index e6f98c35484..79331d00628 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25PreviewTreeDumpTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25PreviewTreeDumpTest.java @@ -4,6 +4,13 @@ package net.sourceforge.pmd.lang.java.ast; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +import net.sourceforge.pmd.lang.ast.ParseException; import net.sourceforge.pmd.lang.java.BaseJavaTreeDumpTest; import net.sourceforge.pmd.lang.java.JavaParsingHelper; import net.sourceforge.pmd.lang.test.ast.BaseParsingHelper; @@ -19,4 +26,15 @@ class Java25PreviewTreeDumpTest extends BaseJavaTreeDumpTest { return java25p; } + @Test + void jep507PrimitiveTypesInPatternsInstanceofAndSwitch() { + doTest("Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch"); + } + + @Test + void jep507PrimitiveTypesInPatternsInstanceofAndSwitchBeforeJava25Preview() { + ParseException thrown = assertThrows(ParseException.class, () -> java25.parseResource("Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.java")); + assertThat(thrown.getMessage(), containsString("Primitive types in patterns instanceof and switch is a preview feature of JDK 25, you should select your language version accordingly")); + } + } diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTInstanceOfExpressionTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTInstanceOfExpressionTest.kt index 4e77aa31d08..8cb1f86868e 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTInstanceOfExpressionTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTInstanceOfExpressionTest.kt @@ -48,7 +48,7 @@ class ASTInstanceOfExpressionTest : ParserTestSpec({ } } - parserTestContainer("InstanceofExpression cannot test primitive types", JavaVersion.except(JavaVersion.J24__PREVIEW)) { + parserTestContainer("InstanceofExpression cannot test primitive types", JavaVersion.except(JavaVersion.J24__PREVIEW, JavaVersion.J25__PREVIEW)) { inContext(ExpressionParsingCtx) { PrimitiveTypeKind.values().map { it.simpleName }.forEach { "f instanceof $it" shouldNot parse() @@ -59,7 +59,8 @@ class ASTInstanceOfExpressionTest : ParserTestSpec({ // since Java 23 Preview, primitive types in instanceof are possible (JEP 455) // Java 24 Preview: JEP 488 - parserTestContainer("InstanceofExpression can test primitive types", listOf(JavaVersion.J24__PREVIEW)) { + // Java 25 Preview: JEP 507 + parserTestContainer("InstanceofExpression can test primitive types", listOf(JavaVersion.J24__PREVIEW, JavaVersion.J25__PREVIEW)) { inContext(ExpressionParsingCtx) { PrimitiveTypeKind.values().forEach { typeKind -> "f instanceof ${typeKind.simpleName}" should parseAs { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25p/Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25p/Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.java new file mode 100644 index 00000000000..bd8948aa39d --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25p/Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.java @@ -0,0 +1,173 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +import java.util.Map; + +/** + * @see JEP 507: Primitive Types in Patterns, instanceof, and switch (Third Preview) (Java 25) + */ +public class Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch { + + void switchWithPrimitiveTypePatterns() { + class X { + int getStatus() { return 0; } + int getYearlyFlights() { return 1; } + void noop() {} + void issueDiscount() {} + void issueGoldCard() {} + } + X x = new X(); + + String status = switch (x.getStatus()) { + case 0 -> "okay"; + case 1 -> "warning"; + case 2 -> "error"; + case int i -> "unknown status: " + i; + }; + System.out.println("status: " + status); + + switch (x.getYearlyFlights()) { + case 0 -> x.noop(); + case 1 -> x.noop(); + case 2 -> x.issueDiscount(); + case int i when i >= 100 -> x.issueGoldCard(); + case int i -> x.issueDiscount(); // ... appropriate action when i > 2 && i < 100 ... + } + } + + sealed interface JsonValue {} + record JsonString(String s) implements JsonValue { } + record JsonNumber(double d) implements JsonValue { } + record JsonObject(Map map) implements JsonValue { } + void recordPatternsWithPrimitiveTypes() { + var json = new JsonObject(Map.of("name", new JsonString("John"), + "age", new JsonNumber(30))); + + if (json instanceof JsonObject(var map) + && map.get("name") instanceof JsonString(String n) + && map.get("age") instanceof JsonNumber(int a)) { + int age = a; + System.out.printf("Name: %s Age: %d%n", n, age); + } + } + + void patternMatchingForInstanceofWithPrimitiveTypes() { + class X { + int getPopulation() { return 0; } + } + + X x = new X(); + if (x.getPopulation() instanceof float pop) { + System.out.println("pop: " + pop); + } + int i = x.getPopulation(); + if (i instanceof byte b) { + System.out.println("byte: " + b); + } + if (i instanceof byte) { // value of i fits in a byte + byte b = (byte)i; // traditional cast required + System.out.println("byte: ... " + b); + } + } + + void expandedPrimitiveSupportInSwitch() { + class User { + boolean isLoggedIn() { return false; } + int id() { return 42; } + } + User user = new User(); + int userId = switch(user.isLoggedIn()) { + case true -> user.id(); + case false -> { System.out.println("Unrecognized user"); yield - 1; } + }; + + long v = 12345L; + switch(v) { + case 1L -> System.out.println("1L"); + case 2L -> System.out.println("2L"); + case 10_000_000_000L -> System.out.println("10x"); + case 20_000_000_000L -> System.out.println("20x"); + case long x -> System.out.println("... " + x + " ..."); + } + + float fv = 1.2f; + fv = switch (fv) { + case 0f -> 5f; + case float x when x == 1f -> 6f + x; + case float x -> 7f + x; + }; + + double dd = 1.2; + dd = switch (dd) { + case 0d -> 5; + case double d when d == 2 -> 6 + d; + case double d -> 8 + d; + }; + } + + void instanceofPrecondition() { + { + byte b = 42; + assert b instanceof int; // true (unconditionally exact) + } + + { + int i = 42; + assert i instanceof byte; // true (exact) + } + + { + int i = 1000; + assert !(i instanceof byte); // false (not exact) + } + + { + int i = 16_777_217; // 2^24 + 1 + assert !(i instanceof float); // false (not exact) + assert i instanceof double; // true (unconditionally exact) + assert i instanceof Integer; // true (unconditionally exact) + assert i instanceof Number; // true (unconditionally exact) + } + + { + float f = 1000.0f; + assert !(f instanceof byte); // false + assert f instanceof int; // true (exact) + assert f instanceof double; // true (unconditionally exact) + } + + { + double d = 1000.0d; + assert !(d instanceof byte); // false + assert d instanceof int; // true (exact) + assert d instanceof float; // true (exact) + } + + { + Integer ii = 1000; + assert ii instanceof int; // true (exact) + assert ii instanceof float; // true (exact) + assert ii instanceof double; // true (exact) + } + + { + Integer ii = 16_777_217; + assert !(ii instanceof float); // false (not exact) + assert ii instanceof double; // true (exact) + } + } + + void primitivePatternInSwitch() { + // Applicability + int i = 1; + switch (i) { + case double d -> System.out.println("double: " + d); + } + + Byte b = 1; + switch (b) { // exhaustive switch + case int p -> System.out.println("p: " + p); + } + } +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25p/Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25p/Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.txt new file mode 100644 index 00000000000..dd31d413db7 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25p/Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.txt @@ -0,0 +1,742 @@ ++- CompilationUnit[@PackageName = ""] + +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.Map", @ImportedSimpleName = "Map", @ModuleImport = false, @PackageName = "java.util", @Static = false] + +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch", @CanonicalName = "Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] + +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] + +- ClassBody[@Empty = false, @Size = 10] + +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "switchWithPrimitiveTypePatterns", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- VoidType[] + | +- FormalParameters[@Empty = true, @Size = 0] + | +- Block[@Empty = false, @Size = 5, @containsComment = false] + | +- LocalClassStatement[] + | | +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch$1X", @CanonicalName = null, @EffectiveVisibility = Visibility.V_LOCAL, @Enum = false, @Final = false, @Interface = false, @Local = true, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "X", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- ClassBody[@Empty = false, @Size = 5] + | | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Name = "getStatus", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = false] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | | +- FormalParameters[@Empty = true, @Size = 0] + | | | +- Block[@Empty = false, @Size = 1, @containsComment = false] + | | | +- ReturnStatement[] + | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] + | | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Name = "getYearlyFlights", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = false] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | | +- FormalParameters[@Empty = true, @Size = 0] + | | | +- Block[@Empty = false, @Size = 1, @containsComment = false] + | | | +- ReturnStatement[] + | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] + | | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Name = "noop", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- VoidType[] + | | | +- FormalParameters[@Empty = true, @Size = 0] + | | | +- Block[@Empty = true, @Size = 0, @containsComment = false] + | | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Name = "issueDiscount", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- VoidType[] + | | | +- FormalParameters[@Empty = true, @Size = 0] + | | | +- Block[@Empty = true, @Size = 0, @containsComment = false] + | | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Name = "issueGoldCard", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- VoidType[] + | | +- FormalParameters[@Empty = true, @Size = 0] + | | +- Block[@Empty = true, @Size = 0, @containsComment = false] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "X"] + | | +- VariableDeclarator[@Initializer = true, @Name = "x"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "X"] + | | +- ArgumentList[@Empty = true, @Size = 0] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] + | | +- VariableDeclarator[@Initializer = true, @Name = "status"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "status", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "getStatus", @MethodName = "getStatus", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ArgumentList[@Empty = true, @Size = 0] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] + | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "okay", @Empty = false, @Image = "\"okay\"", @Length = 4, @LiteralText = "\"okay\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] + | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "warning", @Empty = false, @Image = "\"warning\"", @Length = 7, @LiteralText = "\"warning\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2", @IntLiteral = true, @Integral = true, @LiteralText = "2", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] + | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "error", @Empty = false, @Image = "\"error\"", @Length = 5, @LiteralText = "\"error\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- SwitchArrowBranch[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "i", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "unknown status: ", @Empty = false, @Image = "\"unknown status: \"", @Length = 16, @LiteralText = "\"unknown status: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | +- ExpressionStatement[] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | | +- ArgumentList[@Empty = false, @Size = 1] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "status: ", @Empty = false, @Image = "\"status: \"", @Length = 8, @LiteralText = "\"status: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "status", @Name = "status", @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- MethodCall[@CompileTimeConstant = false, @Image = "getYearlyFlights", @MethodName = "getYearlyFlights", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ArgumentList[@Empty = true, @Size = 0] + | +- SwitchArrowBranch[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "noop", @MethodName = "noop", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ArgumentList[@Empty = true, @Size = 0] + | +- SwitchArrowBranch[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "noop", @MethodName = "noop", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ArgumentList[@Empty = true, @Size = 0] + | +- SwitchArrowBranch[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2", @IntLiteral = true, @Integral = true, @LiteralText = "2", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "issueDiscount", @MethodName = "issueDiscount", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ArgumentList[@Empty = true, @Size = 0] + | +- SwitchArrowBranch[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "i", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | | +- Guard[] + | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.GE, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "100", @IntLiteral = true, @Integral = true, @LiteralText = "100", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 100.0, @ValueAsFloat = 100.0, @ValueAsInt = 100, @ValueAsLong = 100] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "issueGoldCard", @MethodName = "issueGoldCard", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ArgumentList[@Empty = true, @Size = 0] + | +- SwitchArrowBranch[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "i", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- MethodCall[@CompileTimeConstant = false, @Image = "issueDiscount", @MethodName = "issueDiscount", @ParenthesisDepth = 0, @Parenthesized = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | +- ArgumentList[@Empty = true, @Size = 0] + +- ClassDeclaration[@Abstract = true, @Annotation = false, @Anonymous = false, @BinaryName = "Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch$JsonValue", @CanonicalName = "Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.JsonValue", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = true, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = true, @SimpleName = "JsonValue", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + | +- ModifierList[@EffectiveModifiers = (JModifier.SEALED, JModifier.ABSTRACT, JModifier.STATIC), @ExplicitModifiers = (JModifier.SEALED)] + | +- ClassBody[@Empty = true, @Size = 0] + +- RecordDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch$JsonString", @CanonicalName = "Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.JsonString", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = true, @RegularClass = false, @RegularInterface = false, @SimpleName = "JsonString", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = ()] + | +- RecordComponentList[@Empty = false, @Size = 1, @Varargs = false] + | | +- RecordComponent[@EffectiveVisibility = Visibility.V_PRIVATE, @Varargs = false, @Visibility = Visibility.V_PRIVATE] + | | +- ModifierList[@EffectiveModifiers = (JModifier.PRIVATE, JModifier.FINAL), @ExplicitModifiers = ()] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PRIVATE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = false, @RecordComponent = true, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PRIVATE] + | +- ImplementsList[@Empty = false, @Size = 1] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonValue"] + | +- RecordBody[@Empty = true, @Size = 0] + +- RecordDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch$JsonNumber", @CanonicalName = "Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.JsonNumber", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = true, @RegularClass = false, @RegularInterface = false, @SimpleName = "JsonNumber", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = ()] + | +- RecordComponentList[@Empty = false, @Size = 1, @Varargs = false] + | | +- RecordComponent[@EffectiveVisibility = Visibility.V_PRIVATE, @Varargs = false, @Visibility = Visibility.V_PRIVATE] + | | +- ModifierList[@EffectiveModifiers = (JModifier.PRIVATE, JModifier.FINAL), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PRIVATE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "d", @PatternBinding = false, @RecordComponent = true, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PRIVATE] + | +- ImplementsList[@Empty = false, @Size = 1] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonValue"] + | +- RecordBody[@Empty = true, @Size = 0] + +- RecordDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch$JsonObject", @CanonicalName = "Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.JsonObject", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = true, @RegularClass = false, @RegularInterface = false, @SimpleName = "JsonObject", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = ()] + | +- RecordComponentList[@Empty = false, @Size = 1, @Varargs = false] + | | +- RecordComponent[@EffectiveVisibility = Visibility.V_PRIVATE, @Varargs = false, @Visibility = Visibility.V_PRIVATE] + | | +- ModifierList[@EffectiveModifiers = (JModifier.PRIVATE, JModifier.FINAL), @ExplicitModifiers = ()] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Map"] + | | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 2] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonValue"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PRIVATE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "map", @PatternBinding = false, @RecordComponent = true, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PRIVATE] + | +- ImplementsList[@Empty = false, @Size = 1] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonValue"] + | +- RecordBody[@Empty = true, @Size = 0] + +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "recordPatternsWithPrimitiveTypes", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- VoidType[] + | +- FormalParameters[@Empty = true, @Size = 0] + | +- Block[@Empty = false, @Size = 2, @containsComment = false] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = true, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- VariableDeclarator[@Initializer = true, @Name = "json"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "json", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonObject"] + | | +- ArgumentList[@Empty = false, @Size = 1] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "of", @MethodName = "of", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Map"] + | | +- ArgumentList[@Empty = false, @Size = 4] + | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "name", @Empty = false, @Image = "\"name\"", @Length = 4, @LiteralText = "\"name\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonString"] + | | | +- ArgumentList[@Empty = false, @Size = 1] + | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "John", @Empty = false, @Image = "\"John\"", @Length = 4, @LiteralText = "\"John\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "age", @Empty = false, @Image = "\"age\"", @Length = 3, @LiteralText = "\"age\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonNumber"] + | | +- ArgumentList[@Empty = false, @Size = 1] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "30", @IntLiteral = true, @Integral = true, @LiteralText = "30", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 30.0, @ValueAsFloat = 30.0, @ValueAsInt = 30, @ValueAsLong = 30] + | +- IfStatement[@Else = false] + | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.CONDITIONAL_AND, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.CONDITIONAL_AND, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "json", @Name = "json", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- RecordPattern[] + | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonObject"] + | | | | +- PatternList[@Empty = false, @Size = 1] + | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "map", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "get", @MethodName = "get", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "map", @Name = "map", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- ArgumentList[@Empty = false, @Size = 1] + | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "name", @Empty = false, @Image = "\"name\"", @Length = 4, @LiteralText = "\"name\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | | +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- RecordPattern[] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonString"] + | | | +- PatternList[@Empty = false, @Size = 1] + | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "n", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "get", @MethodName = "get", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "map", @Name = "map", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ArgumentList[@Empty = false, @Size = 1] + | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "age", @Empty = false, @Image = "\"age\"", @Length = 3, @LiteralText = "\"age\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- RecordPattern[] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonNumber"] + | | +- PatternList[@Empty = false, @Size = 1] + | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "a", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- Block[@Empty = false, @Size = 2, @containsComment = false] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- VariableDeclarator[@Initializer = true, @Name = "age"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "age", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "a", @Name = "a", @ParenthesisDepth = 0, @Parenthesized = false] + | +- ExpressionStatement[] + | +- MethodCall[@CompileTimeConstant = false, @Image = "printf", @MethodName = "printf", @ParenthesisDepth = 0, @Parenthesized = false] + | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | +- ArgumentList[@Empty = false, @Size = 3] + | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Name: %s Age: %d%n", @Empty = false, @Image = "\"Name: %s Age: %d%n\"", @Length = 18, @LiteralText = "\"Name: %s Age: %d%n\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "n", @Name = "n", @ParenthesisDepth = 0, @Parenthesized = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "age", @Name = "age", @ParenthesisDepth = 0, @Parenthesized = false] + +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "patternMatchingForInstanceofWithPrimitiveTypes", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- VoidType[] + | +- FormalParameters[@Empty = true, @Size = 0] + | +- Block[@Empty = false, @Size = 6, @containsComment = false] + | +- LocalClassStatement[] + | | +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch$2X", @CanonicalName = null, @EffectiveVisibility = Visibility.V_LOCAL, @Enum = false, @Final = false, @Interface = false, @Local = true, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "X", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- ClassBody[@Empty = false, @Size = 1] + | | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Name = "getPopulation", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = false] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- FormalParameters[@Empty = true, @Size = 0] + | | +- Block[@Empty = false, @Size = 1, @containsComment = false] + | | +- ReturnStatement[] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "X"] + | | +- VariableDeclarator[@Initializer = true, @Name = "x"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "X"] + | | +- ArgumentList[@Empty = true, @Size = 0] + | +- IfStatement[@Else = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "getPopulation", @MethodName = "getPopulation", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- ArgumentList[@Empty = true, @Size = 0] + | | | +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "pop", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- Block[@Empty = false, @Size = 1, @containsComment = false] + | | +- ExpressionStatement[] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | | +- ArgumentList[@Empty = false, @Size = 1] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "pop: ", @Empty = false, @Image = "\"pop: \"", @Length = 5, @LiteralText = "\"pop: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "pop", @Name = "pop", @ParenthesisDepth = 0, @Parenthesized = false] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- VariableDeclarator[@Initializer = true, @Name = "i"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "getPopulation", @MethodName = "getPopulation", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ArgumentList[@Empty = true, @Size = 0] + | +- IfStatement[@Else = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "b", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- Block[@Empty = false, @Size = 1, @containsComment = false] + | | +- ExpressionStatement[] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | | +- ArgumentList[@Empty = false, @Size = 1] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "byte: ", @Empty = false, @Image = "\"byte: \"", @Length = 6, @LiteralText = "\"byte: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] + | +- IfStatement[@Else = false] + | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] + | +- Block[@Empty = false, @Size = 2, @containsComment = false] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] + | | +- VariableDeclarator[@Initializer = true, @Name = "b"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "b", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- CastExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | +- ExpressionStatement[] + | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | +- ArgumentList[@Empty = false, @Size = 1] + | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] + | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "byte: ... ", @Empty = false, @Image = "\"byte: ... \"", @Length = 10, @LiteralText = "\"byte: ... \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] + +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "expandedPrimitiveSupportInSwitch", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- VoidType[] + | +- FormalParameters[@Empty = true, @Size = 0] + | +- Block[@Empty = false, @Size = 9, @containsComment = false] + | +- LocalClassStatement[] + | | +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch$1User", @CanonicalName = null, @EffectiveVisibility = Visibility.V_LOCAL, @Enum = false, @Final = false, @Interface = false, @Local = true, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "User", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- ClassBody[@Empty = false, @Size = 2] + | | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Name = "isLoggedIn", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = false] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BOOLEAN] + | | | +- FormalParameters[@Empty = true, @Size = 0] + | | | +- Block[@Empty = false, @Size = 1, @containsComment = false] + | | | +- ReturnStatement[] + | | | +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "false", @ParenthesisDepth = 0, @Parenthesized = false, @True = false] + | | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Name = "id", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = false] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- FormalParameters[@Empty = true, @Size = 0] + | | +- Block[@Empty = false, @Size = 1, @containsComment = false] + | | +- ReturnStatement[] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "42", @IntLiteral = true, @Integral = true, @LiteralText = "42", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 42.0, @ValueAsFloat = 42.0, @ValueAsInt = 42, @ValueAsLong = 42] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "User"] + | | +- VariableDeclarator[@Initializer = true, @Name = "user"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "user", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "User"] + | | +- ArgumentList[@Empty = true, @Size = 0] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- VariableDeclarator[@Initializer = true, @Name = "userId"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "userId", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "isLoggedIn", @MethodName = "isLoggedIn", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "user", @Name = "user", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ArgumentList[@Empty = true, @Size = 0] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | | +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "true", @ParenthesisDepth = 0, @Parenthesized = false, @True = true] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "id", @MethodName = "id", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "user", @Name = "user", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ArgumentList[@Empty = true, @Size = 0] + | | +- SwitchArrowBranch[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "false", @ParenthesisDepth = 0, @Parenthesized = false, @True = false] + | | +- Block[@Empty = false, @Size = 2, @containsComment = false] + | | +- ExpressionStatement[] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | | | +- ArgumentList[@Empty = false, @Size = 1] + | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Unrecognized user", @Empty = false, @Image = "\"Unrecognized user\"", @Length = 17, @LiteralText = "\"Unrecognized user\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- YieldStatement[] + | | +- UnaryExpression[@CompileTimeConstant = true, @Operator = UnaryOp.UNARY_MINUS, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.LONG] + | | +- VariableDeclarator[@Initializer = true, @Name = "v"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "v", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "12345L", @IntLiteral = false, @Integral = true, @LiteralText = "12345L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 12345.0, @ValueAsFloat = 12345.0, @ValueAsInt = 12345, @ValueAsLong = 12345] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "v", @Name = "v", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1L", @IntLiteral = false, @Integral = true, @LiteralText = "1L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | | | +- ArgumentList[@Empty = false, @Size = 1] + | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "1L", @Empty = false, @Image = "\"1L\"", @Length = 2, @LiteralText = "\"1L\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2L", @IntLiteral = false, @Integral = true, @LiteralText = "2L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | | | +- ArgumentList[@Empty = false, @Size = 1] + | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "2L", @Empty = false, @Image = "\"2L\"", @Length = 2, @LiteralText = "\"2L\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "10_000_000_000L", @IntLiteral = false, @Integral = true, @LiteralText = "10_000_000_000L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0E10, @ValueAsFloat = 1.0E10, @ValueAsInt = 1410065408, @ValueAsLong = 10000000000] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | | | +- ArgumentList[@Empty = false, @Size = 1] + | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "10x", @Empty = false, @Image = "\"10x\"", @Length = 3, @LiteralText = "\"10x\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "20_000_000_000L", @IntLiteral = false, @Integral = true, @LiteralText = "20_000_000_000L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0E10, @ValueAsFloat = 2.0E10, @ValueAsInt = -1474836480, @ValueAsLong = 20000000000] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | | | +- ArgumentList[@Empty = false, @Size = 1] + | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "20x", @Empty = false, @Image = "\"20x\"", @Length = 3, @LiteralText = "\"20x\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- SwitchArrowBranch[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.LONG] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | | +- ArgumentList[@Empty = false, @Size = 1] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "... ", @Empty = false, @Image = "\"... \"", @Length = 4, @LiteralText = "\"... \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = " ...", @Empty = false, @Image = "\" ...\"", @Length = 4, @LiteralText = "\" ...\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] + | | +- VariableDeclarator[@Initializer = true, @Name = "fv"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "fv", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "1.2f", @IntLiteral = false, @Integral = false, @LiteralText = "1.2f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.2, @ValueAsFloat = 1.2, @ValueAsInt = 1, @ValueAsLong = 1] + | +- ExpressionStatement[] + | | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "fv", @Name = "fv", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "fv", @Name = "fv", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "0f", @IntLiteral = false, @Integral = false, @LiteralText = "0f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] + | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "5f", @IntLiteral = false, @Integral = false, @LiteralText = "5f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 5.0, @ValueAsFloat = 5.0, @ValueAsInt = 5, @ValueAsLong = 5] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] + | | | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | | | +- Guard[] + | | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.EQ, @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "1f", @IntLiteral = false, @Integral = false, @LiteralText = "1f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] + | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "6f", @IntLiteral = false, @Integral = false, @LiteralText = "6f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 6.0, @ValueAsFloat = 6.0, @ValueAsInt = 6, @ValueAsLong = 6] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchArrowBranch[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "7f", @IntLiteral = false, @Integral = false, @LiteralText = "7f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 7.0, @ValueAsFloat = 7.0, @ValueAsInt = 7, @ValueAsLong = 7] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] + | | +- VariableDeclarator[@Initializer = true, @Name = "dd"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "dd", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = true, @FloatLiteral = false, @Image = "1.2", @IntLiteral = false, @Integral = false, @LiteralText = "1.2", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.2, @ValueAsFloat = 1.2, @ValueAsInt = 1, @ValueAsLong = 1] + | +- ExpressionStatement[] + | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] + | +- VariableAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "dd", @Name = "dd", @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "dd", @Name = "dd", @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchArrowBranch[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = true, @FloatLiteral = false, @Image = "0d", @IntLiteral = false, @Integral = false, @LiteralText = "0d", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "5", @IntLiteral = true, @Integral = true, @LiteralText = "5", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 5.0, @ValueAsFloat = 5.0, @ValueAsInt = 5, @ValueAsLong = 5] + | +- SwitchArrowBranch[@Default = false] + | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] + | | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "d", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | | +- Guard[] + | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.EQ, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2", @IntLiteral = true, @Integral = true, @LiteralText = "2", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "6", @IntLiteral = true, @Integral = true, @LiteralText = "6", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 6.0, @ValueAsFloat = 6.0, @ValueAsInt = 6, @ValueAsLong = 6] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchArrowBranch[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "d", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] + | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "8", @IntLiteral = true, @Integral = true, @LiteralText = "8", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 8.0, @ValueAsFloat = 8.0, @ValueAsInt = 8, @ValueAsLong = 8] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] + +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "instanceofPrecondition", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- VoidType[] + | +- FormalParameters[@Empty = true, @Size = 0] + | +- Block[@Empty = false, @Size = 8, @containsComment = false] + | +- Block[@Empty = false, @Size = 2, @containsComment = true] + | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] + | | | +- VariableDeclarator[@Initializer = true, @Name = "b"] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "b", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "42", @IntLiteral = true, @Integral = true, @LiteralText = "42", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 42.0, @ValueAsFloat = 42.0, @ValueAsInt = 42, @ValueAsLong = 42] + | | +- AssertStatement[@DetailMessage = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | +- Block[@Empty = false, @Size = 2, @containsComment = true] + | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | | +- VariableDeclarator[@Initializer = true, @Name = "i"] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "42", @IntLiteral = true, @Integral = true, @LiteralText = "42", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 42.0, @ValueAsFloat = 42.0, @ValueAsInt = 42, @ValueAsLong = 42] + | | +- AssertStatement[@DetailMessage = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] + | +- Block[@Empty = false, @Size = 2, @containsComment = true] + | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | | +- VariableDeclarator[@Initializer = true, @Name = "i"] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1000", @IntLiteral = true, @Integral = true, @LiteralText = "1000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1000.0, @ValueAsFloat = 1000.0, @ValueAsInt = 1000, @ValueAsLong = 1000] + | | +- AssertStatement[@DetailMessage = false] + | | +- UnaryExpression[@CompileTimeConstant = false, @Operator = UnaryOp.NEGATION, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] + | +- Block[@Empty = false, @Size = 5, @containsComment = true] + | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | | +- VariableDeclarator[@Initializer = true, @Name = "i"] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "16_777_217", @IntLiteral = true, @Integral = true, @LiteralText = "16_777_217", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.6777217E7, @ValueAsFloat = 1.6777216E7, @ValueAsInt = 16777217, @ValueAsLong = 16777217] + | | +- AssertStatement[@DetailMessage = false] + | | | +- UnaryExpression[@CompileTimeConstant = false, @Operator = UnaryOp.NEGATION, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] + | | +- AssertStatement[@DetailMessage = false] + | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] + | | +- AssertStatement[@DetailMessage = false] + | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] + | | +- AssertStatement[@DetailMessage = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Number"] + | +- Block[@Empty = false, @Size = 4, @containsComment = true] + | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] + | | | +- VariableDeclarator[@Initializer = true, @Name = "f"] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "f", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "1000.0f", @IntLiteral = false, @Integral = false, @LiteralText = "1000.0f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1000.0, @ValueAsFloat = 1000.0, @ValueAsInt = 1000, @ValueAsLong = 1000] + | | +- AssertStatement[@DetailMessage = false] + | | | +- UnaryExpression[@CompileTimeConstant = false, @Operator = UnaryOp.NEGATION, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "f", @Name = "f", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] + | | +- AssertStatement[@DetailMessage = false] + | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "f", @Name = "f", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- AssertStatement[@DetailMessage = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "f", @Name = "f", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] + | +- Block[@Empty = false, @Size = 4, @containsComment = true] + | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] + | | | +- VariableDeclarator[@Initializer = true, @Name = "d"] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "d", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = true, @FloatLiteral = false, @Image = "1000.0d", @IntLiteral = false, @Integral = false, @LiteralText = "1000.0d", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1000.0, @ValueAsFloat = 1000.0, @ValueAsInt = 1000, @ValueAsLong = 1000] + | | +- AssertStatement[@DetailMessage = false] + | | | +- UnaryExpression[@CompileTimeConstant = false, @Operator = UnaryOp.NEGATION, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] + | | +- AssertStatement[@DetailMessage = false] + | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- AssertStatement[@DetailMessage = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] + | +- Block[@Empty = false, @Size = 4, @containsComment = true] + | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] + | | | +- VariableDeclarator[@Initializer = true, @Name = "ii"] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "ii", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1000", @IntLiteral = true, @Integral = true, @LiteralText = "1000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1000.0, @ValueAsFloat = 1000.0, @ValueAsInt = 1000, @ValueAsLong = 1000] + | | +- AssertStatement[@DetailMessage = false] + | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "ii", @Name = "ii", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- AssertStatement[@DetailMessage = false] + | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "ii", @Name = "ii", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] + | | +- AssertStatement[@DetailMessage = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "ii", @Name = "ii", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] + | +- Block[@Empty = false, @Size = 3, @containsComment = true] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] + | | +- VariableDeclarator[@Initializer = true, @Name = "ii"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "ii", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "16_777_217", @IntLiteral = true, @Integral = true, @LiteralText = "16_777_217", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.6777217E7, @ValueAsFloat = 1.6777216E7, @ValueAsInt = 16777217, @ValueAsLong = 16777217] + | +- AssertStatement[@DetailMessage = false] + | | +- UnaryExpression[@CompileTimeConstant = false, @Operator = UnaryOp.NEGATION, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "ii", @Name = "ii", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] + | +- AssertStatement[@DetailMessage = false] + | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "ii", @Name = "ii", @ParenthesisDepth = 0, @Parenthesized = false] + | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] + +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "primitivePatternInSwitch", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + +- VoidType[] + +- FormalParameters[@Empty = true, @Size = 0] + +- Block[@Empty = false, @Size = 4, @containsComment = false] + +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | +- VariableDeclarator[@Initializer = true, @Name = "i"] + | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] + +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchArrowBranch[@Default = false] + | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "d", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | +- ArgumentList[@Empty = false, @Size = 1] + | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] + | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "double: ", @Empty = false, @Image = "\"double: \"", @Length = 8, @LiteralText = "\"double: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] + +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Byte"] + | +- VariableDeclarator[@Initializer = true, @Name = "b"] + | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "b", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] + +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] + +- SwitchArrowBranch[@Default = false] + +- SwitchLabel[@Default = false, @PatternLabel = true] + | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "p", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + +- ArgumentList[@Empty = false, @Size = 1] + +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] + +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "p: ", @Empty = false, @Image = "\"p: \"", @Length = 3, @LiteralText = "\"p: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "p", @Name = "p", @ParenthesisDepth = 0, @Parenthesized = false] From b10566d07be54aa916ab2302355b11126f0b0120 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 3 Jul 2025 11:51:45 +0200 Subject: [PATCH 1082/1962] [java] Update implementation for JEP 513 Flexible Constructor Bodies --- .../ast/internal/LanguageLevelChecker.java | 5 +- .../java/ast/Java24PreviewTreeDumpTest.java | 2 +- .../pmd/lang/java/ast/Java25TreeDumpTest.java | 19 ++ .../Jep513_FlexibleConstructorBodies.java | 98 ++++++ .../Jep513_FlexibleConstructorBodies.txt | 318 ++++++++++++++++++ 5 files changed, 439 insertions(+), 3 deletions(-) create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep513_FlexibleConstructorBodies.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep513_FlexibleConstructorBodies.txt diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java index af7884e758d..3ec27893ecb 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java @@ -138,12 +138,13 @@ private enum PreviewFeature implements LanguageFeature { SIMPLE_SOURCE_FILES_AND_INSTANCE_MAIN_METHODS(22, 24, false), /** - * Statements before super + * Flexible Constructor Bodies * @see JEP 447: Statements before super(...) (Preview) (Java 22) * @see JEP 482: Flexible Constructor Bodies (Second Preview) (Java 23) * @see JEP 492: Flexible Constructor Bodies (Third Preview) (Java 24) + * @see JEP 513: Flexible Constructor Bodies (Java 25) */ - FLEXIBLE_CONSTRUCTOR_BODIES(22, 24, false), + FLEXIBLE_CONSTRUCTOR_BODIES(22, 24, true), /** * Module import declarations diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java24PreviewTreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java24PreviewTreeDumpTest.java index 6f3f4cb406f..ae37e9b312b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java24PreviewTreeDumpTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java24PreviewTreeDumpTest.java @@ -54,7 +54,7 @@ void jep492FlexibleConstructorBodies() { @Test void jep492FlexibleConstructorBodiesBeforeJava24Preview() { ParseException thrown = assertThrows(ParseException.class, () -> java24.parseResource("Jep492_FlexibleConstructorBodies.java")); - assertThat(thrown.getMessage(), containsString("Flexible constructor bodies is a preview feature of JDK 24, you should select your language version accordingly")); + assertThat(thrown.getMessage(), containsString("Flexible constructor bodies was only standardized in Java 25, you should select your language version accordingly")); } @Test diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java index e9c5dbab42a..8091ecc49f2 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java @@ -4,6 +4,13 @@ package net.sourceforge.pmd.lang.java.ast; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +import net.sourceforge.pmd.lang.ast.ParseException; import net.sourceforge.pmd.lang.java.BaseJavaTreeDumpTest; import net.sourceforge.pmd.lang.java.JavaParsingHelper; import net.sourceforge.pmd.lang.test.ast.BaseParsingHelper; @@ -12,10 +19,22 @@ class Java25TreeDumpTest extends BaseJavaTreeDumpTest { private final JavaParsingHelper java25 = JavaParsingHelper.DEFAULT.withDefaultVersion("25") .withResourceContext(Java25TreeDumpTest.class, "jdkversiontests/java25/"); + private final JavaParsingHelper java24 = java25.withDefaultVersion("24"); @Override public BaseParsingHelper getParser() { return java25; } + @Test + void jep513FlexibleConstructorBodies() { + doTest("Jep513_FlexibleConstructorBodies"); + } + + @Test + void jep513FlexibleConstructorBodiesBeforeJava25() { + ParseException thrown = assertThrows(ParseException.class, () -> java24.parseResource("Jep513_FlexibleConstructorBodies.java")); + assertThat(thrown.getMessage(), containsString("Flexible constructor bodies was only standardized in Java 25, you should select your language version accordingly")); + } + } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep513_FlexibleConstructorBodies.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep513_FlexibleConstructorBodies.java new file mode 100644 index 00000000000..5291666c8b1 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep513_FlexibleConstructorBodies.java @@ -0,0 +1,98 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +import java.math.BigInteger; +import java.security.cert.Certificate; +import java.security.interfaces.DSAPublicKey; +import java.security.interfaces.RSAKey; + +/** + * @see JEP 513: Flexible Constructor Bodies (Java 25) + */ +public class Jep513_FlexibleConstructorBodies { + + // Example: Validating superclass constructor arguments + public class PositiveBigInteger extends BigInteger { + public PositiveBigInteger(long value) { + if (value <= 0) throw new IllegalArgumentException("value must be positive"); + super(String.valueOf(value)); + } + } + + // Example: Preparing superclass constructor arguments + public class Super { + public Super(byte[] bytes) {} + } + public class Sub extends Super { + public Sub(Certificate certificate) { + var publicKey = certificate.getPublicKey(); + if (publicKey == null) throw new NullPointerException(); + byte[] certBytes = switch (publicKey) { + case RSAKey rsaKey -> rsaKey.getModulus().toByteArray(); + case DSAPublicKey dsaKey -> dsaKey.getY().toByteArray(); + default -> new byte[0]; + }; + super(certBytes); + } + } + + // Example: Sharing superclass constructor arguments + public class C { + private final int i; + public C(int i) { + this.i = i; + } + } + public class Super2 { + private final C x; + private final C y; + public Super2(C x, C y) { + this.x = x; + this.y = y; + } + } + public class Sub2 extends Super2 { + public Sub2(int i) { + var x = new C(i); + super(x, x); + } + } + + // Using enclosing instances in early construction contexts + class Outer { + int i; + void hello() { System.out.println("Hello"); } + + class Inner { + int j; + + Inner() { + var x = i; // OK - implicitly refers to field of enclosing instance + var y = Outer.this.i; // OK - explicitly refers to field of enclosing instance + hello(); // OK - implicitly refers to method of enclosing instance + Outer.this.hello(); // OK - explicitly refers to method of enclosing instance + super(); + } + } + } + + // Early assignment to fields + class Super3 { + Super3() { overriddenMethod(); } + void overriddenMethod() { System.out.println("hello"); } + } + class Sub3 extends Super3 { + final int x; + + Sub3(int x) { + this.x = x; // Initialize the field + super(); // Then invoke the Super constructor explicitly + } + + @Override + void overriddenMethod() { System.out.println(x); } + } + + +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep513_FlexibleConstructorBodies.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep513_FlexibleConstructorBodies.txt new file mode 100644 index 00000000000..916ad3a1ae8 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep513_FlexibleConstructorBodies.txt @@ -0,0 +1,318 @@ ++- CompilationUnit[@PackageName = ""] + +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.math.BigInteger", @ImportedSimpleName = "BigInteger", @ModuleImport = false, @PackageName = "java.math", @Static = false] + +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.security.cert.Certificate", @ImportedSimpleName = "Certificate", @ModuleImport = false, @PackageName = "java.security.cert", @Static = false] + +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.security.interfaces.DSAPublicKey", @ImportedSimpleName = "DSAPublicKey", @ModuleImport = false, @PackageName = "java.security.interfaces", @Static = false] + +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.security.interfaces.RSAKey", @ImportedSimpleName = "RSAKey", @ModuleImport = false, @PackageName = "java.security.interfaces", @Static = false] + +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep513_FlexibleConstructorBodies", @CanonicalName = "Jep513_FlexibleConstructorBodies", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Jep513_FlexibleConstructorBodies", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] + +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] + +- ClassBody[@Empty = false, @Size = 9] + +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep513_FlexibleConstructorBodies$PositiveBigInteger", @CanonicalName = "Jep513_FlexibleConstructorBodies.PositiveBigInteger", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "PositiveBigInteger", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] + | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] + | +- ExtendsList[@Empty = false, @Size = 1] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "BigInteger"] + | +- ClassBody[@Empty = false, @Size = 1] + | +- ConstructorDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @Image = "PositiveBigInteger", @Name = "PositiveBigInteger", @Static = false, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @containsComment = false] + | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] + | +- FormalParameters[@Empty = false, @Size = 1] + | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.LONG] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "value", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- Block[@Empty = false, @Size = 2, @containsComment = false] + | +- IfStatement[@Else = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.LE, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "value", @Name = "value", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] + | | +- ThrowStatement[] + | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "IllegalArgumentException"] + | | +- ArgumentList[@Empty = false, @Size = 1] + | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "value must be positive", @Empty = false, @Image = "\"value must be positive\"", @Length = 22, @LiteralText = "\"value must be positive\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | +- ExplicitConstructorInvocation[@ArgumentCount = 1, @MethodName = "new", @Qualified = false, @Super = true, @This = false] + | +- ArgumentList[@Empty = false, @Size = 1] + | +- MethodCall[@CompileTimeConstant = false, @Image = "valueOf", @MethodName = "valueOf", @ParenthesisDepth = 0, @Parenthesized = false] + | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] + | +- ArgumentList[@Empty = false, @Size = 1] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "value", @Name = "value", @ParenthesisDepth = 0, @Parenthesized = false] + +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep513_FlexibleConstructorBodies$Super", @CanonicalName = "Jep513_FlexibleConstructorBodies.Super", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Super", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] + | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] + | +- ClassBody[@Empty = false, @Size = 1] + | +- ConstructorDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @Image = "Super", @Name = "Super", @Static = false, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @containsComment = false] + | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] + | +- FormalParameters[@Empty = false, @Size = 1] + | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- ArrayType[@ArrayDepth = 1] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] + | | | +- ArrayDimensions[@Empty = false, @Size = 1] + | | | +- ArrayTypeDim[@Varargs = false] + | | +- VariableId[@ArrayType = true, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "bytes", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- Block[@Empty = true, @Size = 0, @containsComment = false] + +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep513_FlexibleConstructorBodies$Sub", @CanonicalName = "Jep513_FlexibleConstructorBodies.Sub", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Sub", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] + | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] + | +- ExtendsList[@Empty = false, @Size = 1] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Super"] + | +- ClassBody[@Empty = false, @Size = 1] + | +- ConstructorDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @Image = "Sub", @Name = "Sub", @Static = false, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @containsComment = false] + | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] + | +- FormalParameters[@Empty = false, @Size = 1] + | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Certificate"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "certificate", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- Block[@Empty = false, @Size = 4, @containsComment = false] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = true, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- VariableDeclarator[@Initializer = true, @Name = "publicKey"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "publicKey", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "getPublicKey", @MethodName = "getPublicKey", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "certificate", @Name = "certificate", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ArgumentList[@Empty = true, @Size = 0] + | +- IfStatement[@Else = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.EQ, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "publicKey", @Name = "publicKey", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ThrowStatement[] + | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "NullPointerException"] + | | +- ArgumentList[@Empty = true, @Size = 0] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- ArrayType[@ArrayDepth = 1] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] + | | | +- ArrayDimensions[@Empty = false, @Size = 1] + | | | +- ArrayTypeDim[@Varargs = false] + | | +- VariableDeclarator[@Initializer = true, @Name = "certBytes"] + | | +- VariableId[@ArrayType = true, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "certBytes", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "publicKey", @Name = "publicKey", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "RSAKey"] + | | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "rsaKey", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "toByteArray", @MethodName = "toByteArray", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "getModulus", @MethodName = "getModulus", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "rsaKey", @Name = "rsaKey", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- ArgumentList[@Empty = true, @Size = 0] + | | | +- ArgumentList[@Empty = true, @Size = 0] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "DSAPublicKey"] + | | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "dsaKey", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "toByteArray", @MethodName = "toByteArray", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "getY", @MethodName = "getY", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "dsaKey", @Name = "dsaKey", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- ArgumentList[@Empty = true, @Size = 0] + | | | +- ArgumentList[@Empty = true, @Size = 0] + | | +- SwitchArrowBranch[@Default = true] + | | +- SwitchLabel[@Default = true, @PatternLabel = false] + | | +- ArrayAllocation[@ArrayDepth = 1, @CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ArrayType[@ArrayDepth = 1] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] + | | +- ArrayDimensions[@Empty = false, @Size = 1] + | | +- ArrayDimExpr[@Varargs = false] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] + | +- ExplicitConstructorInvocation[@ArgumentCount = 1, @MethodName = "new", @Qualified = false, @Super = true, @This = false] + | +- ArgumentList[@Empty = false, @Size = 1] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "certBytes", @Name = "certBytes", @ParenthesisDepth = 0, @Parenthesized = false] + +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep513_FlexibleConstructorBodies$C", @CanonicalName = "Jep513_FlexibleConstructorBodies.C", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "C", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] + | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] + | +- ClassBody[@Empty = false, @Size = 2] + | +- FieldDeclaration[@EffectiveVisibility = Visibility.V_PRIVATE, @Static = false, @Visibility = Visibility.V_PRIVATE] + | | +- ModifierList[@EffectiveModifiers = (JModifier.PRIVATE, JModifier.FINAL), @ExplicitModifiers = (JModifier.PRIVATE, JModifier.FINAL)] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- VariableDeclarator[@Initializer = false, @Name = "i"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PRIVATE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = true, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PRIVATE] + | +- ConstructorDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @Image = "C", @Name = "C", @Static = false, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @containsComment = false] + | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] + | +- FormalParameters[@Empty = false, @Size = 1] + | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- Block[@Empty = false, @Size = 1, @containsComment = false] + | +- ExpressionStatement[] + | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] + | +- FieldAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ThisExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep513_FlexibleConstructorBodies$Super2", @CanonicalName = "Jep513_FlexibleConstructorBodies.Super2", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Super2", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] + | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] + | +- ClassBody[@Empty = false, @Size = 3] + | +- FieldDeclaration[@EffectiveVisibility = Visibility.V_PRIVATE, @Static = false, @Visibility = Visibility.V_PRIVATE] + | | +- ModifierList[@EffectiveModifiers = (JModifier.PRIVATE, JModifier.FINAL), @ExplicitModifiers = (JModifier.PRIVATE, JModifier.FINAL)] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "C"] + | | +- VariableDeclarator[@Initializer = false, @Name = "x"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PRIVATE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = true, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PRIVATE] + | +- FieldDeclaration[@EffectiveVisibility = Visibility.V_PRIVATE, @Static = false, @Visibility = Visibility.V_PRIVATE] + | | +- ModifierList[@EffectiveModifiers = (JModifier.PRIVATE, JModifier.FINAL), @ExplicitModifiers = (JModifier.PRIVATE, JModifier.FINAL)] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "C"] + | | +- VariableDeclarator[@Initializer = false, @Name = "y"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PRIVATE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = true, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "y", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PRIVATE] + | +- ConstructorDeclaration[@Abstract = false, @Arity = 2, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @Image = "Super2", @Name = "Super2", @Static = false, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @containsComment = false] + | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] + | +- FormalParameters[@Empty = false, @Size = 2] + | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "C"] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "C"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "y", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- Block[@Empty = false, @Size = 2, @containsComment = false] + | +- ExpressionStatement[] + | | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- FieldAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ThisExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | +- ExpressionStatement[] + | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] + | +- FieldAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "y", @Name = "y", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ThisExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "y", @Name = "y", @ParenthesisDepth = 0, @Parenthesized = false] + +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep513_FlexibleConstructorBodies$Sub2", @CanonicalName = "Jep513_FlexibleConstructorBodies.Sub2", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Sub2", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] + | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] + | +- ExtendsList[@Empty = false, @Size = 1] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Super2"] + | +- ClassBody[@Empty = false, @Size = 1] + | +- ConstructorDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @Image = "Sub2", @Name = "Sub2", @Static = false, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @containsComment = false] + | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] + | +- FormalParameters[@Empty = false, @Size = 1] + | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- Block[@Empty = false, @Size = 2, @containsComment = false] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = true, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- VariableDeclarator[@Initializer = true, @Name = "x"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "C"] + | | +- ArgumentList[@Empty = false, @Size = 1] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | +- ExplicitConstructorInvocation[@ArgumentCount = 2, @MethodName = "new", @Qualified = false, @Super = true, @This = false] + | +- ArgumentList[@Empty = false, @Size = 2] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep513_FlexibleConstructorBodies$Outer", @CanonicalName = "Jep513_FlexibleConstructorBodies.Outer", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Outer", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- ClassBody[@Empty = false, @Size = 3] + | +- FieldDeclaration[@EffectiveVisibility = Visibility.V_PACKAGE, @Static = false, @Visibility = Visibility.V_PACKAGE] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- VariableDeclarator[@Initializer = false, @Name = "i"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PACKAGE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = true, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PACKAGE] + | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "hello", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- VoidType[] + | | +- FormalParameters[@Empty = true, @Size = 0] + | | +- Block[@Empty = false, @Size = 1, @containsComment = false] + | | +- ExpressionStatement[] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | | +- ArgumentList[@Empty = false, @Size = 1] + | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Hello", @Empty = false, @Image = "\"Hello\"", @Length = 5, @LiteralText = "\"Hello\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep513_FlexibleConstructorBodies$Outer$Inner", @CanonicalName = "Jep513_FlexibleConstructorBodies.Outer.Inner", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Inner", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- ClassBody[@Empty = false, @Size = 2] + | +- FieldDeclaration[@EffectiveVisibility = Visibility.V_PACKAGE, @Static = false, @Visibility = Visibility.V_PACKAGE] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- VariableDeclarator[@Initializer = false, @Name = "j"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PACKAGE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = true, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "j", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PACKAGE] + | +- ConstructorDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Image = "Inner", @Name = "Inner", @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @containsComment = false] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- FormalParameters[@Empty = true, @Size = 0] + | +- Block[@Empty = false, @Size = 5, @containsComment = false] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = true, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- VariableDeclarator[@Initializer = true, @Name = "x"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = true, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- VariableDeclarator[@Initializer = true, @Name = "y"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "y", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ThisExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Outer"] + | +- ExpressionStatement[] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "hello", @MethodName = "hello", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ArgumentList[@Empty = true, @Size = 0] + | +- ExpressionStatement[] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "hello", @MethodName = "hello", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ThisExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Outer"] + | | +- ArgumentList[@Empty = true, @Size = 0] + | +- ExplicitConstructorInvocation[@ArgumentCount = 0, @MethodName = "new", @Qualified = false, @Super = true, @This = false] + | +- ArgumentList[@Empty = true, @Size = 0] + +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep513_FlexibleConstructorBodies$Super3", @CanonicalName = "Jep513_FlexibleConstructorBodies.Super3", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Super3", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- ClassBody[@Empty = false, @Size = 2] + | +- ConstructorDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Image = "Super3", @Name = "Super3", @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @containsComment = false] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- FormalParameters[@Empty = true, @Size = 0] + | | +- Block[@Empty = false, @Size = 1, @containsComment = false] + | | +- ExpressionStatement[] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "overriddenMethod", @MethodName = "overriddenMethod", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ArgumentList[@Empty = true, @Size = 0] + | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "overriddenMethod", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- VoidType[] + | +- FormalParameters[@Empty = true, @Size = 0] + | +- Block[@Empty = false, @Size = 1, @containsComment = false] + | +- ExpressionStatement[] + | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | +- ArgumentList[@Empty = false, @Size = 1] + | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "hello", @Empty = false, @Image = "\"hello\"", @Length = 5, @LiteralText = "\"hello\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep513_FlexibleConstructorBodies$Sub3", @CanonicalName = "Jep513_FlexibleConstructorBodies.Sub3", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Sub3", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + +- ExtendsList[@Empty = false, @Size = 1] + | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Super3"] + +- ClassBody[@Empty = false, @Size = 3] + +- FieldDeclaration[@EffectiveVisibility = Visibility.V_PACKAGE, @Static = false, @Visibility = Visibility.V_PACKAGE] + | +- ModifierList[@EffectiveModifiers = (JModifier.FINAL), @ExplicitModifiers = (JModifier.FINAL)] + | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | +- VariableDeclarator[@Initializer = false, @Name = "x"] + | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PACKAGE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = true, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PACKAGE] + +- ConstructorDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Image = "Sub3", @Name = "Sub3", @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @containsComment = true] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- FormalParameters[@Empty = false, @Size = 1] + | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- Block[@Empty = false, @Size = 2, @containsComment = true] + | +- ExpressionStatement[] + | | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- FieldAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ThisExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | +- ExplicitConstructorInvocation[@ArgumentCount = 0, @MethodName = "new", @Qualified = false, @Super = true, @This = false] + | +- ArgumentList[@Empty = true, @Size = 0] + +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "overriddenMethod", @Overridden = true, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- Annotation[@SimpleName = "Override"] + | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Override"] + +- VoidType[] + +- FormalParameters[@Empty = true, @Size = 0] + +- Block[@Empty = false, @Size = 1, @containsComment = false] + +- ExpressionStatement[] + +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + +- ArgumentList[@Empty = false, @Size = 1] + +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] From 9110eb94df293bd4ff5b8b4249dc33c4b52ee841 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 3 Jul 2025 12:09:07 +0200 Subject: [PATCH 1083/1962] [java] Update implementation for JEP 511 Module Import Declarations --- .../lang/java/ast/ASTImportDeclaration.java | 6 +-- .../ast/internal/LanguageLevelChecker.java | 3 +- .../java/ast/Java24PreviewTreeDumpTest.java | 2 +- .../pmd/lang/java/ast/Java25TreeDumpTest.java | 11 ++++ .../table/internal/HeaderScopesTest.kt | 2 +- .../Jep511_ModuleImportDeclarations.java | 20 +++++++ .../Jep511_ModuleImportDeclarations.txt | 53 +++++++++++++++++++ .../rule/codestyle/xml/UnnecessaryImport.xml | 12 ++--- 8 files changed, 94 insertions(+), 15 deletions(-) create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep511_ModuleImportDeclarations.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep511_ModuleImportDeclarations.txt diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTImportDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTImportDeclaration.java index 8b3b3750065..11b9cce0849 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTImportDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTImportDeclaration.java @@ -6,8 +6,6 @@ import org.checkerframework.checker.nullness.qual.NonNull; -import net.sourceforge.pmd.annotation.Experimental; - /** * Represents an import declaration in a Java file. * @@ -137,11 +135,11 @@ void setModuleImport() { * of a module. * * @return {@code true} if this is a module declaration import - * @since 7.5.0 * @see JEP 476: Module Import Declarations (Preview) (Java 23) * @see JEP 494: Module Import Declarations (Second Preview) (Java 24) + * @see JEP 511: Module Import Declarations (Java 25) + * @since 7.16.0 */ - @Experimental public boolean isModuleImport() { return moduleImport; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java index 3ec27893ecb..82a77a44e06 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java @@ -150,8 +150,9 @@ private enum PreviewFeature implements LanguageFeature { * Module import declarations * @see JEP 476: Module Import Declarations (Preview) (Java 23) * @see JEP 494: Module Import Declarations (Second Preview) (Java 24) + * @see JEP 511: Module Import Declarations (Java 25) */ - MODULE_IMPORT_DECLARATIONS(23, 24, false), + MODULE_IMPORT_DECLARATIONS(23, 24, true), /** * Primitive types in patterns, instanceof, and switch diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java24PreviewTreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java24PreviewTreeDumpTest.java index ae37e9b312b..f11650b73b5 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java24PreviewTreeDumpTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java24PreviewTreeDumpTest.java @@ -65,7 +65,7 @@ void jep494ModuleImportDeclarations() { @Test void jep494ModuleImportDeclarationsBeforeJava24Preview() { ParseException thrown = assertThrows(ParseException.class, () -> java24.parseResource("Jep494_ModuleImportDeclarations.java")); - assertThat(thrown.getMessage(), containsString("Module import declarations is a preview feature of JDK 24, you should select your language version accordingly")); + assertThat(thrown.getMessage(), containsString("Module import declarations was only standardized in Java 25, you should select your language version accordingly")); } @Test diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java index 8091ecc49f2..115d5669db5 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java @@ -37,4 +37,15 @@ void jep513FlexibleConstructorBodiesBeforeJava25() { assertThat(thrown.getMessage(), containsString("Flexible constructor bodies was only standardized in Java 25, you should select your language version accordingly")); } + @Test + void jep511ModuleImportDeclarations() { + doTest("Jep511_ModuleImportDeclarations"); + } + + @Test + void jep511ModuleImportDeclarationsBeforeJava25() { + ParseException thrown = assertThrows(ParseException.class, () -> java24.parseResource("Jep511_ModuleImportDeclarations.java")); + assertThat(thrown.getMessage(), containsString("Module import declarations was only standardized in Java 25, you should select your language version accordingly")); + } + } diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/HeaderScopesTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/HeaderScopesTest.kt index 0066eea208a..b5428ae72fb 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/HeaderScopesTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/HeaderScopesTest.kt @@ -357,7 +357,7 @@ class HeaderScopesTest : ProcessorTestSpec({ block.symbolTable.types().resolve("Inner").shouldBeEmpty() } - parserTest("$moduleImport of java.base should resolve java.util.List", javaVersion = JavaVersion.J24__PREVIEW) { + parserTest("$moduleImport of java.base should resolve java.util.List") { assertNoSemanticErrorsOrWarnings() val acu = parser.parse( diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep511_ModuleImportDeclarations.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep511_ModuleImportDeclarations.java new file mode 100644 index 00000000000..68426e7aa6b --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep511_ModuleImportDeclarations.java @@ -0,0 +1,20 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +import module java.base; +import module java.desktop; + +import java.util.List; + +/** + * @see JEP 511: Module Import Declarations (Java 25) + */ +public class Jep511_ModuleImportDeclarations { + public static void main(String[] args) { + File f = new File("."); + List myList = new ArrayList<>(); + myList.add(f); + System.out.println("myList = " + myList); + } +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep511_ModuleImportDeclarations.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep511_ModuleImportDeclarations.txt new file mode 100644 index 00000000000..34661167fe8 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep511_ModuleImportDeclarations.txt @@ -0,0 +1,53 @@ ++- CompilationUnit[@PackageName = ""] + +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.base", @ImportedSimpleName = null, @ModuleImport = true, @PackageName = null, @Static = false] + +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.desktop", @ImportedSimpleName = null, @ModuleImport = true, @PackageName = null, @Static = false] + +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.List", @ImportedSimpleName = "List", @ModuleImport = false, @PackageName = "java.util", @Static = false] + +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep511_ModuleImportDeclarations", @CanonicalName = "Jep511_ModuleImportDeclarations", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Jep511_ModuleImportDeclarations", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] + +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] + +- ClassBody[@Empty = false, @Size = 1] + +- MethodDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @MainMethod = true, @Name = "main", @Overridden = false, @Static = true, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @Void = true] + +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.STATIC), @ExplicitModifiers = (JModifier.PUBLIC, JModifier.STATIC)] + +- VoidType[] + +- FormalParameters[@Empty = false, @Size = 1] + | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- ArrayType[@ArrayDepth = 1] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] + | | +- ArrayDimensions[@Empty = false, @Size = 1] + | | +- ArrayTypeDim[@Varargs = false] + | +- VariableId[@ArrayType = true, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "args", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + +- Block[@Empty = false, @Size = 4, @containsComment = false] + +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "File"] + | +- VariableDeclarator[@Initializer = true, @Name = "f"] + | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "f", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] + | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "File"] + | +- ArgumentList[@Empty = false, @Size = 1] + | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = ".", @Empty = false, @Image = "\".\"", @Length = 1, @LiteralText = "\".\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "List"] + | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "File"] + | +- VariableDeclarator[@Initializer = true, @Name = "myList"] + | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "myList", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = true, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] + | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "ArrayList"] + | | +- TypeArguments[@Diamond = true, @Empty = true, @Size = 0] + | +- ArgumentList[@Empty = true, @Size = 0] + +- ExpressionStatement[] + | +- MethodCall[@CompileTimeConstant = false, @Image = "add", @MethodName = "add", @ParenthesisDepth = 0, @Parenthesized = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "myList", @Name = "myList", @ParenthesisDepth = 0, @Parenthesized = false] + | +- ArgumentList[@Empty = false, @Size = 1] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "f", @Name = "f", @ParenthesisDepth = 0, @Parenthesized = false] + +- ExpressionStatement[] + +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + +- ArgumentList[@Empty = false, @Size = 1] + +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] + +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "myList = ", @Empty = false, @Image = "\"myList = \"", @Length = 9, @LiteralText = "\"myList = \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "myList", @Name = "myList", @ParenthesisDepth = 0, @Parenthesized = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml index b01453c39f5..f9a13041d13 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml @@ -1265,7 +1265,7 @@ public class Foo { - module import declarations (since java 23 preview, JEP 476) + module import declarations (since java 25, JEP 511) 0 - java 24-preview - module import declarations - unnecessary (since java 23 preview, JEP 476) + module import declarations - unnecessary (since java 25, JEP 511) 1 1 @@ -1288,11 +1287,10 @@ import module java.base; // unnecessary public class Foo { } ]]> - java 24-preview - module import declarations - duplicate 1 (since java 23 preview, JEP 476) + module import declarations - duplicate 1 (since java 25, JEP 511) 1 2 - java 24-preview - module import declarations - duplicate 2 (since java 23 preview, JEP 476) + module import declarations - duplicate 2 (since java 25, JEP 511) 1 1 @@ -1319,7 +1316,6 @@ public class Foo { private File file; } ]]> - java 24-preview From c26f988ea7de57f7e2402dd8dd21adc659064bc9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 3 Jul 2025 15:59:22 +0200 Subject: [PATCH 1084/1962] [java] Update implementation for JEP 512 Compact Source Files and Instance Main Methods --- .../pmd/lang/java/ast/ASTCompilationUnit.java | 15 ++- .../java/ast/ASTImplicitClassDeclaration.java | 6 +- .../lang/java/ast/ASTMethodDeclaration.java | 4 +- .../pmd/lang/java/ast/JavaVisitorBase.java | 2 - .../ast/internal/LanguageLevelChecker.java | 7 +- .../table/internal/SymbolTableResolver.java | 7 +- pmd-java/src/main/javacc/Java.jjt | 2 +- .../java/ast/Java24PreviewTreeDumpTest.java | 6 +- .../pmd/lang/java/ast/Java25TreeDumpTest.java | 54 ++++++++ ...mpleSourceFilesAndInstanceMainMethods.java | 1 + ...impleSourceFilesAndInstanceMainMethods.txt | 1 + ...ilesAndInstanceMainMethodsAfterJava23.java | 37 ++++++ ...FilesAndInstanceMainMethodsAfterJava23.txt | 115 ++++++++++++++++++ ...lesAndInstanceMainMethodsBeforeJava23.java | 37 ++++++ ...ilesAndInstanceMainMethodsBeforeJava23.txt | 112 +++++++++++++++++ 15 files changed, 383 insertions(+), 23 deletions(-) create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsAfterJava23.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsAfterJava23.txt create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsBeforeJava23.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsBeforeJava23.txt diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java index 7d3729f074e..aca023f9d4e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java @@ -10,7 +10,6 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; -import net.sourceforge.pmd.annotation.Experimental; import net.sourceforge.pmd.lang.ast.AstInfo; import net.sourceforge.pmd.lang.ast.NodeStream; import net.sourceforge.pmd.lang.ast.RootNode; @@ -26,7 +25,7 @@ *
      *
      * CompilationUnit ::= OrdinaryCompilationUnit
    - *                   | SimpleCompilationUnit
    + *                   | CompactCompilationUnit
      *                   | ModularCompilationUnit
      *
      * OrdinaryCompilationUnit ::=
    @@ -34,7 +33,7 @@
      *   {@linkplain ASTImportDeclaration ImportDeclaration}*
      *   {@linkplain ASTTypeDeclaration TypeDeclaration}*
      *
    - * SimpleCompilationUnit ::=
    + * CompactCompilationUnit ::=
      *   {@linkplain ASTImportDeclaration ImportDeclaration}*
      *   {@linkplain ASTImplicitClassDeclaration ImplicitClassDeclaration}
      *
    @@ -156,9 +155,15 @@ void setTypeResolver(LazyTypeResolver typeResolver) {
             return lazyTypeResolver;
         }
     
    -    @Experimental("Implicitly Declared Classes and Instance Main Methods is a Java 22 / Java 23 Preview feature")
    +    /**
    +     * If this compilation is a compact compilation unit and contains an
    +     * implicitly declared class.
    +     *
    +     * @see JEP 512: Compact Source Files and Instance Main Methods (Java 25)
    +     * @since 7.16.0
    +     */
         @NoAttribute
    -    public boolean isSimpleCompilationUnit() {
    +    public boolean isCompact() {
             return children(ASTImplicitClassDeclaration.class).nonEmpty();
         }
     }
    diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTImplicitClassDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTImplicitClassDeclaration.java
    index 5a34e180f45..797aaa3f6c0 100644
    --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTImplicitClassDeclaration.java
    +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTImplicitClassDeclaration.java
    @@ -6,9 +6,8 @@
     
     import org.checkerframework.checker.nullness.qual.NonNull;
     
    -import net.sourceforge.pmd.annotation.Experimental;
    -
     /**
    + * A class declaration added by the compiler implicitly in a compact compilation unit (see JEP 512, Java 25).
      *
      * 
      * ImplicitClassDeclaration ::= {@linkplain ASTClassBody ClassBody}
    @@ -20,8 +19,9 @@
      *
      * @see JEP 477: Implicitly Declared Classes and Instance Main Methods (Third Preview) (Java 23)
      * @see JEP 495: Simple Source Files and Instance Main Methods (Fourth Preview) (Java 24)
    + * @see JEP 512: Compact Source Files and Instance Main Methods (Java 25)
    + * @since 7.16.0
      */
    -@Experimental("Simple Source Files and Instance Main Methods is a Java 22 / Java 23 / Java 24 Preview feature")
     public final class ASTImplicitClassDeclaration extends AbstractTypeDeclaration {
         ASTImplicitClassDeclaration(int id) {
             super(id);
    diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java
    index 56ad3f0c58a..636bef97661 100644
    --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java
    +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java
    @@ -141,11 +141,11 @@ public boolean isMainMethod() {
         }
     
         /**
    -     * With JEP 445/463/477/495 (Java 23/24 Preview) the main method does not need to be static anymore and
    +     * With JEP 445/463/477/495/512 (Java 24 Preview/Java 25) the main method does not need to be static anymore and
          * does not need to be public or have a formal parameter.
          */
         private boolean isLaunchableMainMethod() {
    -        return this.getRoot().isSimpleCompilationUnit()
    +        return this.getRoot().isCompact()
                     && "main".equals(this.getName())
                     && !this.hasModifiers(JModifier.PRIVATE)
                     && this.isVoid()
    diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaVisitorBase.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaVisitorBase.java
    index 984523e9ee8..c21f94e496f 100644
    --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaVisitorBase.java
    +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaVisitorBase.java
    @@ -4,7 +4,6 @@
     
     package net.sourceforge.pmd.lang.java.ast;
     
    -import net.sourceforge.pmd.annotation.Experimental;
     import net.sourceforge.pmd.lang.ast.AstVisitorBase;
     import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr.ASTNamedReferenceExpr;
     
    @@ -78,7 +77,6 @@ public R visit(ASTAnnotationTypeDeclaration node, P data) {
         }
     
         @Override
    -    @Experimental
         public R visit(ASTImplicitClassDeclaration node, P data) {
             return visitTypeDecl(node, data);
         }
    diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java
    index 82a77a44e06..4a580034b60 100644
    --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java
    +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java
    @@ -129,13 +129,14 @@ private static String versionDisplayName(int jdk) {
          */
         private enum PreviewFeature implements LanguageFeature {
             /**
    -         * Unnamed Classes and Instance Main Methods
    +         * Compact Source Files and Instance Main Methods
              * @see JEP 445: Unnamed Classes and Instance Main Methods (Preview) (Java 21)
              * @see JEP 463: Implicitly Declared Classes and Instance Main Methods (Second Preview) (Java 22)
              * @see JEP 477: Implicitly Declared Classes and Instance Main Methods (Third Preview) (Java 23)
              * @see JEP 495: Simple Source Files and Instance Main Methods (Fourth Preview) (Java 24)
    +         * @see JEP 512: Compact Source Files and Instance Main Methods (Java 25)
              */
    -        SIMPLE_SOURCE_FILES_AND_INSTANCE_MAIN_METHODS(22, 24, false),
    +        COMPACT_SOURCE_FILES_AND_INSTANCE_MAIN_METHODS(22, 24, true),
     
             /**
              * Flexible Constructor Bodies
    @@ -440,7 +441,7 @@ public Void visitNode(Node node, T param) {
     
             @Override
             public Void visit(ASTImplicitClassDeclaration node, T data) {
    -            check(node, PreviewFeature.SIMPLE_SOURCE_FILES_AND_INSTANCE_MAIN_METHODS, data);
    +            check(node, PreviewFeature.COMPACT_SOURCE_FILES_AND_INSTANCE_MAIN_METHODS, data);
                 return null;
             }
     
    diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java
    index 7310d3259ae..40a4117719f 100644
    --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java
    +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java
    @@ -221,12 +221,11 @@ public Void visit(ASTCompilationUnit node, @NonNull ReferenceCtx ctx) {
     
                 int pushed = 0;
     
    -            // Java 23 Preview
    -            if (node.isSimpleCompilationUnit()) {
    +            // Since Java 23 Preview, finalized with Java 25 (JEP 512)
    +            if (node.isCompact()) {
                     pushed += pushOnStack(f.moduleImportJavaBase(top()));
    -                pushed += pushOnStack(f.importsOnDemandJavaIo(top()));
                 }
    -            pushed += pushOnStack(f.moduleImports(top(), moduleImports)); // Java 23 preview
    +            pushed += pushOnStack(f.moduleImports(top(), moduleImports)); // Since Java 23 preview, finalized with Java 25 (JEP 512)
                 pushed += pushOnStack(f.importsOnDemand(top(), importsOnDemand));
                 pushed += pushOnStack(f.javaLangSymTable(top()));
                 pushed += pushOnStack(f.samePackageSymTable(top()));
    diff --git a/pmd-java/src/main/javacc/Java.jjt b/pmd-java/src/main/javacc/Java.jjt
    index d07ed954911..b93225aa447 100644
    --- a/pmd-java/src/main/javacc/Java.jjt
    +++ b/pmd-java/src/main/javacc/Java.jjt
    @@ -1058,7 +1058,7 @@ ASTCompilationUnit CompilationUnit() :
       // OrdinaryCompilationUnit: -> TopLevelClassOrInterfaceDeclaration
       ( TypeDeclaration() ( EmptyDeclaration() )* )*
     
    -  // SimpleCompilationUnit:
    +  // CompactCompilationUnit:
       [
         (
           { pushEmptyModifierList(); }
    diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java24PreviewTreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java24PreviewTreeDumpTest.java
    index f11650b73b5..87d1a78675f 100644
    --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java24PreviewTreeDumpTest.java
    +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java24PreviewTreeDumpTest.java
    @@ -76,10 +76,10 @@ void jep495SimpleSourceFilesAndInstanceMainMethods() {
         @Test
         void jep495SimpleSourceFilesAndInstanceMainMethodsVerifyTypes() {
             int javaVersion = Integer.parseInt(System.getProperty("java.version").split("\\.")[0].replaceAll("-ea", ""));
    -        assumeTrue(javaVersion >= 23, "Java " + javaVersion + " doesn't support java.io.IO. At least Java 23 is needed for this test.");
    +        assumeTrue(javaVersion >= 23 && javaVersion < 25, "Java " + javaVersion + " doesn't support java.io.IO. Java 23 or Java 24 is needed for this test.");
     
             ASTCompilationUnit compilationUnit = java24p.parseResource("Jep495_SimpleSourceFilesAndInstanceMainMethods.java");
    -        assertTrue(compilationUnit.isSimpleCompilationUnit());
    +        assertTrue(compilationUnit.isCompact());
     
             List methodCalls = compilationUnit.descendants(ASTMethodCall.class).toList();
             OverloadSelectionResult systemOutPrintln = methodCalls.get(4).getOverloadSelectionInfo(); // System.out.println
    @@ -102,6 +102,6 @@ void jep495SimpleSourceFilesAndInstanceMainMethodsVerifyTypes() {
         @Test
         void jep495SimpleSourceFilesAndInstanceMainMethodsBeforeJava24Preview() {
             ParseException thrown = assertThrows(ParseException.class, () -> java24.parseResource("Jep495_SimpleSourceFilesAndInstanceMainMethods.java"));
    -        assertThat(thrown.getMessage(), containsString("Simple source files and instance main methods is a preview feature of JDK 24, you should select your language version accordingly"));
    +        assertThat(thrown.getMessage(), containsString("Compact source files and instance main methods was only standardized in Java 25, you should select your language version accordingly"));
         }
     }
    diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java
    index 115d5669db5..263637d5494 100644
    --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java
    +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java
    @@ -6,13 +6,22 @@
     
     import static org.hamcrest.CoreMatchers.containsString;
     import static org.hamcrest.MatcherAssert.assertThat;
    +import static org.junit.jupiter.api.Assertions.assertEquals;
    +import static org.junit.jupiter.api.Assertions.assertFalse;
    +import static org.junit.jupiter.api.Assertions.assertInstanceOf;
     import static org.junit.jupiter.api.Assertions.assertThrows;
    +import static org.junit.jupiter.api.Assertions.assertTrue;
    +import static org.junit.jupiter.api.Assumptions.assumeTrue;
    +
    +import java.util.List;
     
     import org.junit.jupiter.api.Test;
     
     import net.sourceforge.pmd.lang.ast.ParseException;
     import net.sourceforge.pmd.lang.java.BaseJavaTreeDumpTest;
     import net.sourceforge.pmd.lang.java.JavaParsingHelper;
    +import net.sourceforge.pmd.lang.java.types.OverloadSelectionResult;
    +import net.sourceforge.pmd.lang.java.types.TypeTestUtil;
     import net.sourceforge.pmd.lang.test.ast.BaseParsingHelper;
     
     class Java25TreeDumpTest extends BaseJavaTreeDumpTest {
    @@ -48,4 +57,49 @@ void jep511ModuleImportDeclarationsBeforeJava25() {
             assertThat(thrown.getMessage(), containsString("Module import declarations was only standardized in Java 25, you should select your language version accordingly"));
         }
     
    +    @Test
    +    void jep512CompactSourceFilesAndInstanceMainMethods() {
    +        int javaVersion = Integer.parseInt(System.getProperty("java.version").split("\\.")[0].replaceAll("-ea", ""));
    +        //assumeTrue(javaVersion < 23, "This test is for Java < 23, where java.lang.IO/java.io.IO is not existing yet - and thus AmbiguousNames are left in the AST");
    +        if (javaVersion < 23) {
    +            // java.lang.IO/java.io.IO is not existing yet - and thus AmbiguousNames are left in the AST
    +            doTest("Jep512_CompactSourceFilesAndInstanceMainMethodsBeforeJava23");
    +        } else {
    +            // java.lang.IO/java.io.IO are available - the AmbiguousNames are resolved as ClassTypes in the AST
    +            doTest("Jep512_CompactSourceFilesAndInstanceMainMethodsAfterJava23");
    +        }
    +    }
    +
    +    @Test
    +    void jep512CompactSourceFilesAndInstanceMainMethodsVerifyTypes() {
    +        int javaVersion = Integer.parseInt(System.getProperty("java.version").split("\\.")[0].replaceAll("-ea", ""));
    +        assumeTrue(javaVersion >= 25, "Java " + javaVersion + " doesn't support java.lang.IO. At least Java 25 is needed for this test.");
    +
    +        ASTCompilationUnit compilationUnit = java25.parseResource("Jep512_CompactSourceFilesAndInstanceMainMethods.java");
    +        assertTrue(compilationUnit.isCompact());
    +
    +        List methodCalls = compilationUnit.descendants(ASTMethodCall.class).toList();
    +        OverloadSelectionResult systemOutPrintln = methodCalls.get(4).getOverloadSelectionInfo(); // System.out.println
    +        assertFalse(systemOutPrintln.isFailed());
    +        TypeTestUtil.isA("java.io.PrintStream", systemOutPrintln.getMethodType().getDeclaringType());
    +
    +        ASTVariableDeclarator authorsVar = compilationUnit.descendants(ASTVariableDeclarator.class).filter(decl -> "authors".equals(decl.getName())).first();
    +        assertInstanceOf(ASTMethodCall.class, authorsVar.getInitializer());
    +        ASTMethodCall initializer = (ASTMethodCall) authorsVar.getInitializer();
    +        assertEquals("of", initializer.getMethodName());
    +        assertInstanceOf(ASTTypeExpression.class, initializer.getQualifier());
    +        ASTTypeExpression qualifier = (ASTTypeExpression) initializer.getQualifier();
    +        TypeTestUtil.isA("java.util.List", qualifier.getTypeNode().getTypeMirror());
    +
    +        OverloadSelectionResult javaIoPrintln = methodCalls.get(5).getOverloadSelectionInfo(); // println from java.lang.IO
    +        assertFalse(javaIoPrintln.isFailed());
    +        TypeTestUtil.isA("java.lang.IO", javaIoPrintln.getMethodType().getDeclaringType());
    +    }
    +
    +    @Test
    +    void jep512CompactSourceFilesAndInstanceMainMethodsBeforeJava24Preview() {
    +        ParseException thrown = assertThrows(ParseException.class, () -> java24.parseResource("Jep512_CompactSourceFilesAndInstanceMainMethodsAfterJava23.java"));
    +        assertThat(thrown.getMessage(), containsString("Compact source files and instance main methods was only standardized in Java 25, you should select your language version accordingly"));
    +    }
    +
     }
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep495_SimpleSourceFilesAndInstanceMainMethods.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep495_SimpleSourceFilesAndInstanceMainMethods.java
    index 0128d2b8812..e3e8fb05538 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep495_SimpleSourceFilesAndInstanceMainMethods.java
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep495_SimpleSourceFilesAndInstanceMainMethods.java
    @@ -5,6 +5,7 @@
     // explicit imports are possible as well (although not really needed in this example)
     import java.util.Arrays;
     import java.util.stream.Collectors;
    +import static java.io.IO.*; // support for the implicit import in PMD and Java 25 has been removed with JEP 512
     
     /**
      * @see JEP 495: Simple Source Files and Instance Main Methods (Fourth Preview) (Java 24)
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep495_SimpleSourceFilesAndInstanceMainMethods.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep495_SimpleSourceFilesAndInstanceMainMethods.txt
    index ff83bd0d79a..8db4b96d345 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep495_SimpleSourceFilesAndInstanceMainMethods.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep495_SimpleSourceFilesAndInstanceMainMethods.txt
    @@ -1,6 +1,7 @@
     +- CompilationUnit[@PackageName = ""]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.Arrays", @ImportedSimpleName = "Arrays", @ModuleImport = false, @PackageName = "java.util", @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.stream.Collectors", @ImportedSimpleName = "Collectors", @ModuleImport = false, @PackageName = "java.util.stream", @Static = false]
    +   +- ImportDeclaration[@ImportOnDemand = true, @ImportedName = "java.io.IO", @ImportedSimpleName = null, @ModuleImport = false, @PackageName = "java.io.IO", @Static = true]
        +- ImplicitClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "", @CanonicalName = null, @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = false, @SimpleName = "", @Static = false, @TopLevel = true, @UnnamedToplevelClass = true, @Visibility = Visibility.V_PACKAGE]
           +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
           +- ClassBody[@Empty = false, @Size = 4]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsAfterJava23.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsAfterJava23.java
    new file mode 100644
    index 00000000000..5259a892ce8
    --- /dev/null
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsAfterJava23.java
    @@ -0,0 +1,37 @@
    +/*
    + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
    + */
    +
    +// explicit imports are possible as well (although not really needed in this example)
    +import java.util.Arrays;
    +import java.util.stream.Collectors;
    +
    +import static java.lang.IO.println;
    +
    +/**
    + * @see JEP 512: Compact Source Files and Instance Main Methods (Java 25)
    + */
    +
    +// Top-level members are interpreted as members of the implicit class (methods and fields)
    +String greetingField = "Hello, World! (Field)";
    +String greeting() {
    +    return "Hello, World! (Method)";
    +}
    +String greetingText2 = Arrays.asList("Hello", "World!", "(with imports)").stream().collect(Collectors.joining(", "));
    +
    +void main() {
    +    System.out.println(greetingField);
    +    IO.println(greeting()); // java.lang.IO.println via qualifier
    +    println(greetingText2); // java.lang.IO.println via static import
    +
    +    // java.lang.IO.readln
    +    String name = IO.readln("Please enter your name: ");
    +    IO.print("Pleased to meet you, ");
    +    println(name);
    +
    +    // java.util.List is automatically available via implicit "import module java.base"
    +    var authors = List.of("James", "Bill", "Guy", "Alex", "Dan", "Gavin");
    +    for (var authorName : authors) {
    +        println(authorName + ": " + authorName.length());
    +    }
    +}
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsAfterJava23.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsAfterJava23.txt
    new file mode 100644
    index 00000000000..f5e1c4a7914
    --- /dev/null
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsAfterJava23.txt
    @@ -0,0 +1,115 @@
    ++- CompilationUnit[@PackageName = ""]
    +   +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.Arrays", @ImportedSimpleName = "Arrays", @ModuleImport = false, @PackageName = "java.util", @Static = false]
    +   +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.stream.Collectors", @ImportedSimpleName = "Collectors", @ModuleImport = false, @PackageName = "java.util.stream", @Static = false]
    +   +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.lang.IO.println", @ImportedSimpleName = "println", @ModuleImport = false, @PackageName = "java.lang.IO", @Static = true]
    +   +- ImplicitClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "", @CanonicalName = null, @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = false, @SimpleName = "", @Static = false, @TopLevel = true, @UnnamedToplevelClass = true, @Visibility = Visibility.V_PACKAGE]
    +      +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
    +      +- ClassBody[@Empty = false, @Size = 4]
    +         +- FieldDeclaration[@EffectiveVisibility = Visibility.V_PACKAGE, @Static = false, @Visibility = Visibility.V_PACKAGE]
    +         |  +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
    +         |  +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"]
    +         |  +- VariableDeclarator[@Initializer = true, @Name = "greetingField"]
    +         |     +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PACKAGE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = true, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "greetingField", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PACKAGE]
    +         |     +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Hello, World! (Field)", @Empty = false, @Image = "\"Hello, World! (Field)\"", @Length = 21, @LiteralText = "\"Hello, World! (Field)\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +         +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "greeting", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = false]
    +         |  +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
    +         |  +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"]
    +         |  +- FormalParameters[@Empty = true, @Size = 0]
    +         |  +- Block[@Empty = false, @Size = 1, @containsComment = false]
    +         |     +- ReturnStatement[]
    +         |        +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Hello, World! (Method)", @Empty = false, @Image = "\"Hello, World! (Method)\"", @Length = 22, @LiteralText = "\"Hello, World! (Method)\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +         +- FieldDeclaration[@EffectiveVisibility = Visibility.V_PACKAGE, @Static = false, @Visibility = Visibility.V_PACKAGE]
    +         |  +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
    +         |  +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"]
    +         |  +- VariableDeclarator[@Initializer = true, @Name = "greetingText2"]
    +         |     +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PACKAGE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = true, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "greetingText2", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PACKAGE]
    +         |     +- MethodCall[@CompileTimeConstant = false, @Image = "collect", @MethodName = "collect", @ParenthesisDepth = 0, @Parenthesized = false]
    +         |        +- MethodCall[@CompileTimeConstant = false, @Image = "stream", @MethodName = "stream", @ParenthesisDepth = 0, @Parenthesized = false]
    +         |        |  +- MethodCall[@CompileTimeConstant = false, @Image = "asList", @MethodName = "asList", @ParenthesisDepth = 0, @Parenthesized = false]
    +         |        |  |  +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false]
    +         |        |  |  |  +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Arrays"]
    +         |        |  |  +- ArgumentList[@Empty = false, @Size = 3]
    +         |        |  |     +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Hello", @Empty = false, @Image = "\"Hello\"", @Length = 5, @LiteralText = "\"Hello\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +         |        |  |     +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "World!", @Empty = false, @Image = "\"World!\"", @Length = 6, @LiteralText = "\"World!\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +         |        |  |     +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "(with imports)", @Empty = false, @Image = "\"(with imports)\"", @Length = 14, @LiteralText = "\"(with imports)\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +         |        |  +- ArgumentList[@Empty = true, @Size = 0]
    +         |        +- ArgumentList[@Empty = false, @Size = 1]
    +         |           +- MethodCall[@CompileTimeConstant = false, @Image = "joining", @MethodName = "joining", @ParenthesisDepth = 0, @Parenthesized = false]
    +         |              +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false]
    +         |              |  +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Collectors"]
    +         |              +- ArgumentList[@Empty = false, @Size = 1]
    +         |                 +- StringLiteral[@CompileTimeConstant = true, @ConstValue = ", ", @Empty = false, @Image = "\", \"", @Length = 2, @LiteralText = "\", \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +         +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @MainMethod = true, @Name = "main", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true]
    +            +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
    +            +- VoidType[]
    +            +- FormalParameters[@Empty = true, @Size = 0]
    +            +- Block[@Empty = false, @Size = 8, @containsComment = false]
    +               +- ExpressionStatement[]
    +               |  +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false]
    +               |     +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false]
    +               |     |  +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false]
    +               |     |     +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"]
    +               |     +- ArgumentList[@Empty = false, @Size = 1]
    +               |        +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "greetingField", @Name = "greetingField", @ParenthesisDepth = 0, @Parenthesized = false]
    +               +- ExpressionStatement[]
    +               |  +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false]
    +               |     +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false]
    +               |     |  +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "IO"]
    +               |     +- ArgumentList[@Empty = false, @Size = 1]
    +               |        +- MethodCall[@CompileTimeConstant = false, @Image = "greeting", @MethodName = "greeting", @ParenthesisDepth = 0, @Parenthesized = false]
    +               |           +- ArgumentList[@Empty = true, @Size = 0]
    +               +- ExpressionStatement[]
    +               |  +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false]
    +               |     +- ArgumentList[@Empty = false, @Size = 1]
    +               |        +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "greetingText2", @Name = "greetingText2", @ParenthesisDepth = 0, @Parenthesized = false]
    +               +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL]
    +               |  +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
    +               |  +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"]
    +               |  +- VariableDeclarator[@Initializer = true, @Name = "name"]
    +               |     +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "name", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL]
    +               |     +- MethodCall[@CompileTimeConstant = false, @Image = "readln", @MethodName = "readln", @ParenthesisDepth = 0, @Parenthesized = false]
    +               |        +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false]
    +               |        |  +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "IO"]
    +               |        +- ArgumentList[@Empty = false, @Size = 1]
    +               |           +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Please enter your name: ", @Empty = false, @Image = "\"Please enter your name: \"", @Length = 24, @LiteralText = "\"Please enter your name: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +               +- ExpressionStatement[]
    +               |  +- MethodCall[@CompileTimeConstant = false, @Image = "print", @MethodName = "print", @ParenthesisDepth = 0, @Parenthesized = false]
    +               |     +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false]
    +               |     |  +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "IO"]
    +               |     +- ArgumentList[@Empty = false, @Size = 1]
    +               |        +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Pleased to meet you, ", @Empty = false, @Image = "\"Pleased to meet you, \"", @Length = 21, @LiteralText = "\"Pleased to meet you, \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +               +- ExpressionStatement[]
    +               |  +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false]
    +               |     +- ArgumentList[@Empty = false, @Size = 1]
    +               |        +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "name", @Name = "name", @ParenthesisDepth = 0, @Parenthesized = false]
    +               +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = true, @Visibility = Visibility.V_LOCAL]
    +               |  +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
    +               |  +- VariableDeclarator[@Initializer = true, @Name = "authors"]
    +               |     +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "authors", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL]
    +               |     +- MethodCall[@CompileTimeConstant = false, @Image = "of", @MethodName = "of", @ParenthesisDepth = 0, @Parenthesized = false]
    +               |        +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false]
    +               |        |  +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "List"]
    +               |        +- ArgumentList[@Empty = false, @Size = 6]
    +               |           +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "James", @Empty = false, @Image = "\"James\"", @Length = 5, @LiteralText = "\"James\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +               |           +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Bill", @Empty = false, @Image = "\"Bill\"", @Length = 4, @LiteralText = "\"Bill\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +               |           +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Guy", @Empty = false, @Image = "\"Guy\"", @Length = 3, @LiteralText = "\"Guy\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +               |           +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Alex", @Empty = false, @Image = "\"Alex\"", @Length = 4, @LiteralText = "\"Alex\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +               |           +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Dan", @Empty = false, @Image = "\"Dan\"", @Length = 3, @LiteralText = "\"Dan\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +               |           +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Gavin", @Empty = false, @Image = "\"Gavin\"", @Length = 5, @LiteralText = "\"Gavin\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +               +- ForeachStatement[]
    +                  +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = true, @Visibility = Visibility.V_LOCAL]
    +                  |  +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
    +                  |  +- VariableDeclarator[@Initializer = false, @Name = "authorName"]
    +                  |     +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = true, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "authorName", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL]
    +                  +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "authors", @Name = "authors", @ParenthesisDepth = 0, @Parenthesized = false]
    +                  +- Block[@Empty = false, @Size = 1, @containsComment = false]
    +                     +- ExpressionStatement[]
    +                        +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false]
    +                           +- ArgumentList[@Empty = false, @Size = 1]
    +                              +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false]
    +                                 +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false]
    +                                 |  +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "authorName", @Name = "authorName", @ParenthesisDepth = 0, @Parenthesized = false]
    +                                 |  +- StringLiteral[@CompileTimeConstant = true, @ConstValue = ": ", @Empty = false, @Image = "\": \"", @Length = 2, @LiteralText = "\": \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +                                 +- MethodCall[@CompileTimeConstant = false, @Image = "length", @MethodName = "length", @ParenthesisDepth = 0, @Parenthesized = false]
    +                                    +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "authorName", @Name = "authorName", @ParenthesisDepth = 0, @Parenthesized = false]
    +                                    +- ArgumentList[@Empty = true, @Size = 0]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsBeforeJava23.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsBeforeJava23.java
    new file mode 100644
    index 00000000000..5259a892ce8
    --- /dev/null
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsBeforeJava23.java
    @@ -0,0 +1,37 @@
    +/*
    + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
    + */
    +
    +// explicit imports are possible as well (although not really needed in this example)
    +import java.util.Arrays;
    +import java.util.stream.Collectors;
    +
    +import static java.lang.IO.println;
    +
    +/**
    + * @see JEP 512: Compact Source Files and Instance Main Methods (Java 25)
    + */
    +
    +// Top-level members are interpreted as members of the implicit class (methods and fields)
    +String greetingField = "Hello, World! (Field)";
    +String greeting() {
    +    return "Hello, World! (Method)";
    +}
    +String greetingText2 = Arrays.asList("Hello", "World!", "(with imports)").stream().collect(Collectors.joining(", "));
    +
    +void main() {
    +    System.out.println(greetingField);
    +    IO.println(greeting()); // java.lang.IO.println via qualifier
    +    println(greetingText2); // java.lang.IO.println via static import
    +
    +    // java.lang.IO.readln
    +    String name = IO.readln("Please enter your name: ");
    +    IO.print("Pleased to meet you, ");
    +    println(name);
    +
    +    // java.util.List is automatically available via implicit "import module java.base"
    +    var authors = List.of("James", "Bill", "Guy", "Alex", "Dan", "Gavin");
    +    for (var authorName : authors) {
    +        println(authorName + ": " + authorName.length());
    +    }
    +}
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsBeforeJava23.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsBeforeJava23.txt
    new file mode 100644
    index 00000000000..cb8cda89fbc
    --- /dev/null
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsBeforeJava23.txt
    @@ -0,0 +1,112 @@
    ++- CompilationUnit[@PackageName = ""]
    +   +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.Arrays", @ImportedSimpleName = "Arrays", @ModuleImport = false, @PackageName = "java.util", @Static = false]
    +   +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.stream.Collectors", @ImportedSimpleName = "Collectors", @ModuleImport = false, @PackageName = "java.util.stream", @Static = false]
    +   +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.lang.IO.println", @ImportedSimpleName = "println", @ModuleImport = false, @PackageName = "java.lang.IO", @Static = true]
    +   +- ImplicitClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "", @CanonicalName = null, @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = false, @SimpleName = "", @Static = false, @TopLevel = true, @UnnamedToplevelClass = true, @Visibility = Visibility.V_PACKAGE]
    +      +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
    +      +- ClassBody[@Empty = false, @Size = 4]
    +         +- FieldDeclaration[@EffectiveVisibility = Visibility.V_PACKAGE, @Static = false, @Visibility = Visibility.V_PACKAGE]
    +         |  +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
    +         |  +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"]
    +         |  +- VariableDeclarator[@Initializer = true, @Name = "greetingField"]
    +         |     +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PACKAGE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = true, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "greetingField", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PACKAGE]
    +         |     +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Hello, World! (Field)", @Empty = false, @Image = "\"Hello, World! (Field)\"", @Length = 21, @LiteralText = "\"Hello, World! (Field)\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +         +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "greeting", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = false]
    +         |  +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
    +         |  +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"]
    +         |  +- FormalParameters[@Empty = true, @Size = 0]
    +         |  +- Block[@Empty = false, @Size = 1, @containsComment = false]
    +         |     +- ReturnStatement[]
    +         |        +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Hello, World! (Method)", @Empty = false, @Image = "\"Hello, World! (Method)\"", @Length = 22, @LiteralText = "\"Hello, World! (Method)\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +         +- FieldDeclaration[@EffectiveVisibility = Visibility.V_PACKAGE, @Static = false, @Visibility = Visibility.V_PACKAGE]
    +         |  +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
    +         |  +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"]
    +         |  +- VariableDeclarator[@Initializer = true, @Name = "greetingText2"]
    +         |     +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PACKAGE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = true, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "greetingText2", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PACKAGE]
    +         |     +- MethodCall[@CompileTimeConstant = false, @Image = "collect", @MethodName = "collect", @ParenthesisDepth = 0, @Parenthesized = false]
    +         |        +- MethodCall[@CompileTimeConstant = false, @Image = "stream", @MethodName = "stream", @ParenthesisDepth = 0, @Parenthesized = false]
    +         |        |  +- MethodCall[@CompileTimeConstant = false, @Image = "asList", @MethodName = "asList", @ParenthesisDepth = 0, @Parenthesized = false]
    +         |        |  |  +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false]
    +         |        |  |  |  +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Arrays"]
    +         |        |  |  +- ArgumentList[@Empty = false, @Size = 3]
    +         |        |  |     +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Hello", @Empty = false, @Image = "\"Hello\"", @Length = 5, @LiteralText = "\"Hello\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +         |        |  |     +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "World!", @Empty = false, @Image = "\"World!\"", @Length = 6, @LiteralText = "\"World!\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +         |        |  |     +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "(with imports)", @Empty = false, @Image = "\"(with imports)\"", @Length = 14, @LiteralText = "\"(with imports)\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +         |        |  +- ArgumentList[@Empty = true, @Size = 0]
    +         |        +- ArgumentList[@Empty = false, @Size = 1]
    +         |           +- MethodCall[@CompileTimeConstant = false, @Image = "joining", @MethodName = "joining", @ParenthesisDepth = 0, @Parenthesized = false]
    +         |              +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false]
    +         |              |  +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Collectors"]
    +         |              +- ArgumentList[@Empty = false, @Size = 1]
    +         |                 +- StringLiteral[@CompileTimeConstant = true, @ConstValue = ", ", @Empty = false, @Image = "\", \"", @Length = 2, @LiteralText = "\", \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +         +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @MainMethod = true, @Name = "main", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true]
    +            +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
    +            +- VoidType[]
    +            +- FormalParameters[@Empty = true, @Size = 0]
    +            +- Block[@Empty = false, @Size = 8, @containsComment = false]
    +               +- ExpressionStatement[]
    +               |  +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false]
    +               |     +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false]
    +               |     |  +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false]
    +               |     |     +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"]
    +               |     +- ArgumentList[@Empty = false, @Size = 1]
    +               |        +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "greetingField", @Name = "greetingField", @ParenthesisDepth = 0, @Parenthesized = false]
    +               +- ExpressionStatement[]
    +               |  +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false]
    +               |     +- AmbiguousName[@CompileTimeConstant = false, @Image = "IO", @Name = "IO", @ParenthesisDepth = 0, @Parenthesized = false]
    +               |     +- ArgumentList[@Empty = false, @Size = 1]
    +               |        +- MethodCall[@CompileTimeConstant = false, @Image = "greeting", @MethodName = "greeting", @ParenthesisDepth = 0, @Parenthesized = false]
    +               |           +- ArgumentList[@Empty = true, @Size = 0]
    +               +- ExpressionStatement[]
    +               |  +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false]
    +               |     +- ArgumentList[@Empty = false, @Size = 1]
    +               |        +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "greetingText2", @Name = "greetingText2", @ParenthesisDepth = 0, @Parenthesized = false]
    +               +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL]
    +               |  +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
    +               |  +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"]
    +               |  +- VariableDeclarator[@Initializer = true, @Name = "name"]
    +               |     +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "name", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL]
    +               |     +- MethodCall[@CompileTimeConstant = false, @Image = "readln", @MethodName = "readln", @ParenthesisDepth = 0, @Parenthesized = false]
    +               |        +- AmbiguousName[@CompileTimeConstant = false, @Image = "IO", @Name = "IO", @ParenthesisDepth = 0, @Parenthesized = false]
    +               |        +- ArgumentList[@Empty = false, @Size = 1]
    +               |           +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Please enter your name: ", @Empty = false, @Image = "\"Please enter your name: \"", @Length = 24, @LiteralText = "\"Please enter your name: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +               +- ExpressionStatement[]
    +               |  +- MethodCall[@CompileTimeConstant = false, @Image = "print", @MethodName = "print", @ParenthesisDepth = 0, @Parenthesized = false]
    +               |     +- AmbiguousName[@CompileTimeConstant = false, @Image = "IO", @Name = "IO", @ParenthesisDepth = 0, @Parenthesized = false]
    +               |     +- ArgumentList[@Empty = false, @Size = 1]
    +               |        +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Pleased to meet you, ", @Empty = false, @Image = "\"Pleased to meet you, \"", @Length = 21, @LiteralText = "\"Pleased to meet you, \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +               +- ExpressionStatement[]
    +               |  +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false]
    +               |     +- ArgumentList[@Empty = false, @Size = 1]
    +               |        +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "name", @Name = "name", @ParenthesisDepth = 0, @Parenthesized = false]
    +               +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = true, @Visibility = Visibility.V_LOCAL]
    +               |  +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
    +               |  +- VariableDeclarator[@Initializer = true, @Name = "authors"]
    +               |     +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "authors", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL]
    +               |     +- MethodCall[@CompileTimeConstant = false, @Image = "of", @MethodName = "of", @ParenthesisDepth = 0, @Parenthesized = false]
    +               |        +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false]
    +               |        |  +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "List"]
    +               |        +- ArgumentList[@Empty = false, @Size = 6]
    +               |           +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "James", @Empty = false, @Image = "\"James\"", @Length = 5, @LiteralText = "\"James\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +               |           +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Bill", @Empty = false, @Image = "\"Bill\"", @Length = 4, @LiteralText = "\"Bill\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +               |           +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Guy", @Empty = false, @Image = "\"Guy\"", @Length = 3, @LiteralText = "\"Guy\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +               |           +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Alex", @Empty = false, @Image = "\"Alex\"", @Length = 4, @LiteralText = "\"Alex\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +               |           +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Dan", @Empty = false, @Image = "\"Dan\"", @Length = 3, @LiteralText = "\"Dan\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +               |           +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Gavin", @Empty = false, @Image = "\"Gavin\"", @Length = 5, @LiteralText = "\"Gavin\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +               +- ForeachStatement[]
    +                  +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = true, @Visibility = Visibility.V_LOCAL]
    +                  |  +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
    +                  |  +- VariableDeclarator[@Initializer = false, @Name = "authorName"]
    +                  |     +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = true, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "authorName", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL]
    +                  +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "authors", @Name = "authors", @ParenthesisDepth = 0, @Parenthesized = false]
    +                  +- Block[@Empty = false, @Size = 1, @containsComment = false]
    +                     +- ExpressionStatement[]
    +                        +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false]
    +                           +- ArgumentList[@Empty = false, @Size = 1]
    +                              +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false]
    +                                 +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false]
    +                                 |  +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "authorName", @Name = "authorName", @ParenthesisDepth = 0, @Parenthesized = false]
    +                                 |  +- StringLiteral[@CompileTimeConstant = true, @ConstValue = ": ", @Empty = false, @Image = "\": \"", @Length = 2, @LiteralText = "\": \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
    +                                 +- MethodCall[@CompileTimeConstant = false, @Image = "length", @MethodName = "length", @ParenthesisDepth = 0, @Parenthesized = false]
    +                                    +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "authorName", @Name = "authorName", @ParenthesisDepth = 0, @Parenthesized = false]
    +                                    +- ArgumentList[@Empty = true, @Size = 0]
    
    From 9bb483ff6047aa7a51ee43d3d2887444ee2fad67 Mon Sep 17 00:00:00 2001
    From: Andreas Dangel 
    Date: Thu, 3 Jul 2025 17:08:35 +0200
    Subject: [PATCH 1085/1962] [java] ASTCompilationUnit - expose isCompact XPath
     attribute
    
    ---
     .../net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java   | 2 --
     .../resources/net/sourceforge/pmd/lang/java/ast/Bug1429.txt     | 2 +-
     .../resources/net/sourceforge/pmd/lang/java/ast/Bug1530.txt     | 2 +-
     .../resources/net/sourceforge/pmd/lang/java/ast/EmptyStmts1.txt | 2 +-
     .../resources/net/sourceforge/pmd/lang/java/ast/EmptyStmts2.txt | 2 +-
     .../resources/net/sourceforge/pmd/lang/java/ast/EmptyStmts3.txt | 2 +-
     .../sourceforge/pmd/lang/java/ast/GitHubBug1780OuterClass.txt   | 2 +-
     .../net/sourceforge/pmd/lang/java/ast/GitHubBug207.txt          | 2 +-
     .../net/sourceforge/pmd/lang/java/ast/GitHubBug208.txt          | 2 +-
     .../net/sourceforge/pmd/lang/java/ast/GitHubBug309.txt          | 2 +-
     .../net/sourceforge/pmd/lang/java/ast/GitHubBug3642.txt         | 2 +-
     .../net/sourceforge/pmd/lang/java/ast/LambdaBug1333.txt         | 2 +-
     .../net/sourceforge/pmd/lang/java/ast/LambdaBug1470.txt         | 2 +-
     .../net/sourceforge/pmd/lang/java/ast/LambdaBug206.txt          | 2 +-
     .../net/sourceforge/pmd/lang/java/ast/ParserCornerCases.txt     | 2 +-
     .../net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.txt   | 2 +-
     .../net/sourceforge/pmd/lang/java/ast/ParserCornerCases18.txt   | 2 +-
     .../net/sourceforge/pmd/lang/java/ast/SwitchStatements.txt      | 2 +-
     .../net/sourceforge/pmd/lang/java/ast/SwitchWithFallthrough.txt | 2 +-
     .../net/sourceforge/pmd/lang/java/ast/SynchronizedStmts.txt     | 2 +-
     .../lang/java/ast/jdkversiontests/java14/MultipleCaseLabels.txt | 2 +-
     .../java/ast/jdkversiontests/java14/SimpleSwitchExpressions.txt | 2 +-
     .../lang/java/ast/jdkversiontests/java14/SwitchExpressions.txt  | 2 +-
     .../pmd/lang/java/ast/jdkversiontests/java14/SwitchRules.txt    | 2 +-
     .../lang/java/ast/jdkversiontests/java14/YieldStatements.txt    | 2 +-
     .../java/ast/jdkversiontests/java15/NonSealedIdentifier.txt     | 2 +-
     .../pmd/lang/java/ast/jdkversiontests/java15/TextBlocks.txt     | 2 +-
     .../java16/LocalClassAndInterfaceDeclarations.txt               | 2 +-
     .../pmd/lang/java/ast/jdkversiontests/java16/LocalRecords.txt   | 2 +-
     .../java/ast/jdkversiontests/java16/NonSealedIdentifier.txt     | 2 +-
     .../ast/jdkversiontests/java16/PatternMatchingInstanceof.txt    | 2 +-
     .../pmd/lang/java/ast/jdkversiontests/java16/Point.txt          | 2 +-
     .../pmd/lang/java/ast/jdkversiontests/java16/Records.txt        | 2 +-
     .../pmd/lang/java/ast/jdkversiontests/java17/LocalVars.txt      | 2 +-
     .../lang/java/ast/jdkversiontests/java17/SealedInnerClasses.txt | 2 +-
     .../lang/java/ast/jdkversiontests/java17/expression/Expr.txt    | 2 +-
     .../pmd/lang/java/ast/jdkversiontests/java17/geometry/Shape.txt | 2 +-
     .../lang/java/ast/jdkversiontests/java17/geometry/Square.txt    | 2 +-
     .../ast/jdkversiontests/java21/AnnotationValueInitializers.txt  | 2 +-
     .../lang/java/ast/jdkversiontests/java21/DealingWithNull.txt    | 2 +-
     .../ast/jdkversiontests/java21/EnhancedTypeCheckingSwitch.txt   | 2 +-
     .../lang/java/ast/jdkversiontests/java21/ExhaustiveSwitch.txt   | 2 +-
     .../lang/java/ast/jdkversiontests/java21/GuardedPatterns.txt    | 2 +-
     .../java/ast/jdkversiontests/java21/Jep440_RecordPatterns.txt   | 2 +-
     .../jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt  | 2 +-
     .../java/ast/jdkversiontests/java21/PatternsInSwitchLabels.txt  | 2 +-
     .../pmd/lang/java/ast/jdkversiontests/java21/RecordPatterns.txt | 2 +-
     .../jdkversiontests/java21/RecordPatternsExhaustiveSwitch.txt   | 2 +-
     .../ast/jdkversiontests/java21/RefiningPatternsInSwitch.txt     | 2 +-
     .../java21/ScopeOfPatternVariableDeclarations.txt               | 2 +-
     .../java22/Jep456_UnnamedPatternsAndVariables.txt               | 2 +-
     .../java23/Jep467_MarkdownDocumentationComments.txt             | 2 +-
     .../Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt      | 2 +-
     .../java24p/Jep492_FlexibleConstructorBodies.txt                | 2 +-
     .../jdkversiontests/java24p/Jep494_ModuleImportDeclarations.txt | 2 +-
     .../java24p/Jep495_SimpleSourceFilesAndInstanceMainMethods.txt  | 2 +-
     .../jdkversiontests/java25/Jep511_ModuleImportDeclarations.txt  | 2 +-
     ...p512_CompactSourceFilesAndInstanceMainMethodsAfterJava23.txt | 2 +-
     ...512_CompactSourceFilesAndInstanceMainMethodsBeforeJava23.txt | 2 +-
     .../jdkversiontests/java25/Jep513_FlexibleConstructorBodies.txt | 2 +-
     .../Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.txt      | 2 +-
     .../pmd/lang/java/ast/jdkversiontests/java8/UnnamedVariable.txt | 2 +-
     .../lang/java/ast/jdkversiontests/java9/jdk9_module_info.txt    | 2 +-
     .../ast/jdkversiontests/java9/jdk9_module_info_with_annot.txt   | 2 +-
     64 files changed, 63 insertions(+), 65 deletions(-)
    
    diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java
    index aca023f9d4e..452040c25ba 100644
    --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java
    +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java
    @@ -16,7 +16,6 @@
     import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils;
     import net.sourceforge.pmd.lang.java.types.TypeSystem;
     import net.sourceforge.pmd.lang.java.types.ast.internal.LazyTypeResolver;
    -import net.sourceforge.pmd.lang.rule.xpath.NoAttribute;
     
     
     /**
    @@ -162,7 +161,6 @@ void setTypeResolver(LazyTypeResolver typeResolver) {
          * @see JEP 512: Compact Source Files and Instance Main Methods (Java 25)
          * @since 7.16.0
          */
    -    @NoAttribute
         public boolean isCompact() {
             return children(ASTImplicitClassDeclaration.class).nonEmpty();
         }
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/Bug1429.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/Bug1429.txt
    index bf1e7dd8b97..9133b04d838 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/Bug1429.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/Bug1429.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Bug1429", @CanonicalName = "Bug1429", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Bug1429", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 1]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/Bug1530.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/Bug1530.txt
    index e91f8874621..95fcf906c8a 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/Bug1530.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/Bug1530.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Bug1530", @CanonicalName = "Bug1530", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Bug1530", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 1]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/EmptyStmts1.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/EmptyStmts1.txt
    index 605b2cee70b..6adfea8ebe2 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/EmptyStmts1.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/EmptyStmts1.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "a", @ImportedSimpleName = "a", @ModuleImport = false, @PackageName = "", @Static = false]
        +- EmptyDeclaration[]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "b", @ImportedSimpleName = "b", @ModuleImport = false, @PackageName = "", @Static = false]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/EmptyStmts2.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/EmptyStmts2.txt
    index f926c474900..8c71fdfcd9e 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/EmptyStmts2.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/EmptyStmts2.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = "c"]
    ++- CompilationUnit[@Compact = false, @PackageName = "c"]
        +- PackageDeclaration[@Name = "c"]
        |  +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
        +- EmptyDeclaration[]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/EmptyStmts3.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/EmptyStmts3.txt
    index 867e176508b..1962228898c 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/EmptyStmts3.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/EmptyStmts3.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = "c"]
    ++- CompilationUnit[@Compact = false, @PackageName = "c"]
        +- PackageDeclaration[@Name = "c"]
        |  +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "a", @ImportedSimpleName = "a", @ModuleImport = false, @PackageName = "", @Static = false]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug1780OuterClass.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug1780OuterClass.txt
    index 6d9052027fd..c54e4a688c0 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug1780OuterClass.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug1780OuterClass.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = "com.pmd.test"]
    ++- CompilationUnit[@Compact = false, @PackageName = "com.pmd.test"]
        +- PackageDeclaration[@Name = "com.pmd.test"]
        |  +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "com.pmd.test.GitHubBug1780OuterClass", @CanonicalName = "com.pmd.test.GitHubBug1780OuterClass", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "com.pmd.test", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "GitHubBug1780OuterClass", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug207.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug207.txt
    index 4d8e35e65eb..c781b4d6ea5 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug207.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug207.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "GitHubBug207", @CanonicalName = "GitHubBug207", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "GitHubBug207", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 1]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug208.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug208.txt
    index 766afbbbb51..d718fdab763 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug208.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug208.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "GitHubBug208", @CanonicalName = "GitHubBug208", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "GitHubBug208", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 1]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug309.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug309.txt
    index 22b9ac7b820..19a84047096 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug309.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug309.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ImportDeclaration[@ImportOnDemand = true, @ImportedName = "java.util", @ImportedSimpleName = null, @ModuleImport = false, @PackageName = "java.util", @Static = false]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "GitHubBug309", @CanonicalName = "GitHubBug309", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "GitHubBug309", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug3642.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug3642.txt
    index 40572d29436..2bcc77f98ec 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug3642.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug3642.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "GitHubBug3642", @CanonicalName = "GitHubBug3642", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "GitHubBug3642", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 1]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/LambdaBug1333.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/LambdaBug1333.txt
    index 5f9c4b02c8e..29e190ee886 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/LambdaBug1333.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/LambdaBug1333.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Bug1333", @CanonicalName = "Bug1333", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Bug1333", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE]
           +- ModifierList[@EffectiveModifiers = (JModifier.FINAL), @ExplicitModifiers = (JModifier.FINAL)]
           +- ClassBody[@Empty = false, @Size = 4]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/LambdaBug1470.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/LambdaBug1470.txt
    index 140c3457189..5031bf4d17a 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/LambdaBug1470.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/LambdaBug1470.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = "com.sample.test"]
    ++- CompilationUnit[@Compact = false, @PackageName = "com.sample.test"]
        +- PackageDeclaration[@Name = "com.sample.test"]
        |  +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "rx.Observable", @ImportedSimpleName = "Observable", @ModuleImport = false, @PackageName = "rx", @Static = false]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/LambdaBug206.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/LambdaBug206.txt
    index acd9ba07c15..d0228541611 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/LambdaBug206.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/LambdaBug206.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- AnnotationTypeDeclaration[@Abstract = true, @Annotation = true, @Anonymous = false, @BinaryName = "Foo", @CanonicalName = "Foo", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = true, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = false, @SimpleName = "Foo", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.ABSTRACT), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- AnnotationTypeBody[@Empty = false, @Size = 1]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases.txt
    index 37eaa7e14bc..6df6012b863 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Superclass", @CanonicalName = "Superclass", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Superclass", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE]
        |  +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
        |  +- ClassBody[@Empty = false, @Size = 3]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.txt
    index 25d08df176a..9ec8a167ecd 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.io.BufferedReader", @ImportedSimpleName = "BufferedReader", @ModuleImport = false, @PackageName = "java.io", @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.io.File", @ImportedSimpleName = "File", @ModuleImport = false, @PackageName = "java.io", @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.io.FileReader", @ImportedSimpleName = "FileReader", @ModuleImport = false, @PackageName = "java.io", @Static = false]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases18.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases18.txt
    index 651ea25013a..b5115d3968a 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases18.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases18.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.awt.Button", @ImportedSimpleName = "Button", @ModuleImport = false, @PackageName = "java.awt", @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.io.File", @ImportedSimpleName = "File", @ModuleImport = false, @PackageName = "java.io", @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.io.FileFilter", @ImportedSimpleName = "FileFilter", @ModuleImport = false, @PackageName = "java.io", @Static = false]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchStatements.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchStatements.txt
    index f5356906563..e9dd434478d 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchStatements.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchStatements.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "SwitchStatements", @CanonicalName = "SwitchStatements", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "SwitchStatements", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 1]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchWithFallthrough.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchWithFallthrough.txt
    index b7ccd9f2bc2..d61e7005f1b 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchWithFallthrough.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchWithFallthrough.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "SwitchWithFallthrough", @CanonicalName = "SwitchWithFallthrough", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "SwitchWithFallthrough", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 1]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SynchronizedStmts.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SynchronizedStmts.txt
    index 173c1be4c0b..3cee4a15714 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SynchronizedStmts.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SynchronizedStmts.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Sync", @CanonicalName = "Sync", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Sync", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE]
           +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
           +- ClassBody[@Empty = false, @Size = 1]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/MultipleCaseLabels.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/MultipleCaseLabels.txt
    index 944e6311a9c..16a741f8340 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/MultipleCaseLabels.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/MultipleCaseLabels.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "MultipleCaseLabels", @CanonicalName = "MultipleCaseLabels", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "MultipleCaseLabels", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 8]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SimpleSwitchExpressions.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SimpleSwitchExpressions.txt
    index b56461320f3..261e68797dd 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SimpleSwitchExpressions.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SimpleSwitchExpressions.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "SimpleSwitchExpressions", @CanonicalName = "SimpleSwitchExpressions", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "SimpleSwitchExpressions", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 9]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchExpressions.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchExpressions.txt
    index 5e657237559..dcc9b803bdc 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchExpressions.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchExpressions.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "SwitchExpressions", @CanonicalName = "SwitchExpressions", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "SwitchExpressions", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 6]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchRules.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchRules.txt
    index 4aad77ffc44..1f064e65db5 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchRules.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchRules.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "SwitchRules", @CanonicalName = "SwitchRules", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "SwitchRules", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 8]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.txt
    index ef4b5b1b57c..49226fc4f71 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "YieldStatements", @CanonicalName = "YieldStatements", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "YieldStatements", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 1]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/NonSealedIdentifier.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/NonSealedIdentifier.txt
    index 68afdba1146..f6ae4239dfb 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/NonSealedIdentifier.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/NonSealedIdentifier.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "NonSealedIdentifier", @CanonicalName = "NonSealedIdentifier", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "NonSealedIdentifier", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 1]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/TextBlocks.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/TextBlocks.txt
    index 2d99ee8adc2..1c5c1002b7e 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/TextBlocks.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/TextBlocks.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "javax.script.ScriptEngine", @ImportedSimpleName = "ScriptEngine", @ModuleImport = false, @PackageName = "javax.script", @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "javax.script.ScriptEngineManager", @ImportedSimpleName = "ScriptEngineManager", @ModuleImport = false, @PackageName = "javax.script", @Static = false]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "TextBlocks", @CanonicalName = "TextBlocks", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "TextBlocks", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/LocalClassAndInterfaceDeclarations.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/LocalClassAndInterfaceDeclarations.txt
    index 341ea7034b0..3a48bc7068a 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/LocalClassAndInterfaceDeclarations.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/LocalClassAndInterfaceDeclarations.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "LocalClassAndInterfaceDeclarations", @CanonicalName = "LocalClassAndInterfaceDeclarations", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "LocalClassAndInterfaceDeclarations", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 1]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/LocalRecords.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/LocalRecords.txt
    index 43856e366fe..0529eeef7c9 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/LocalRecords.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/LocalRecords.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.stream.Collectors", @ImportedSimpleName = "Collectors", @ModuleImport = false, @PackageName = "java.util.stream", @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.List", @ImportedSimpleName = "List", @ModuleImport = false, @PackageName = "java.util", @Static = false]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "LocalRecords", @CanonicalName = "LocalRecords", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "LocalRecords", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/NonSealedIdentifier.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/NonSealedIdentifier.txt
    index 68afdba1146..f6ae4239dfb 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/NonSealedIdentifier.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/NonSealedIdentifier.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "NonSealedIdentifier", @CanonicalName = "NonSealedIdentifier", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "NonSealedIdentifier", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 1]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/PatternMatchingInstanceof.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/PatternMatchingInstanceof.txt
    index c1e0751303d..af9df718de3 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/PatternMatchingInstanceof.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/PatternMatchingInstanceof.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.lang.annotation.ElementType.CONSTRUCTOR", @ImportedSimpleName = "CONSTRUCTOR", @ModuleImport = false, @PackageName = "java.lang.annotation.ElementType", @Static = true]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.lang.annotation.ElementType.FIELD", @ImportedSimpleName = "FIELD", @ModuleImport = false, @PackageName = "java.lang.annotation.ElementType", @Static = true]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.lang.annotation.ElementType.LOCAL_VARIABLE", @ImportedSimpleName = "LOCAL_VARIABLE", @ModuleImport = false, @PackageName = "java.lang.annotation.ElementType", @Static = true]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/Point.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/Point.txt
    index 3ee1eed2483..4552969d8d1 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/Point.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/Point.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- RecordDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Point", @CanonicalName = "Point", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = true, @RegularClass = false, @RegularInterface = false, @SimpleName = "Point", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.FINAL), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- RecordComponentList[@Empty = false, @Size = 2, @Varargs = false]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/Records.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/Records.txt
    index d30d7ce1f63..2064e9aada0 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/Records.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/Records.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.io.IOException", @ImportedSimpleName = "IOException", @ModuleImport = false, @PackageName = "java.io", @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.lang.annotation.Target", @ImportedSimpleName = "Target", @ModuleImport = false, @PackageName = "java.lang.annotation", @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.lang.annotation.ElementType", @ImportedSimpleName = "ElementType", @ModuleImport = false, @PackageName = "java.lang.annotation", @Static = false]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/LocalVars.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/LocalVars.txt
    index 1a9bd382b44..a464e7a1d3c 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/LocalVars.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/LocalVars.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "LocalVars", @CanonicalName = "LocalVars", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "LocalVars", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 1]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/SealedInnerClasses.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/SealedInnerClasses.txt
    index 47d40067294..4cfd71f285f 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/SealedInnerClasses.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/SealedInnerClasses.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "SealedInnerClasses", @CanonicalName = "SealedInnerClasses", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "SealedInnerClasses", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 2]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/expression/Expr.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/expression/Expr.txt
    index c8b68c39601..002b3726468 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/expression/Expr.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/expression/Expr.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = "com.example.expression"]
    ++- CompilationUnit[@Compact = false, @PackageName = "com.example.expression"]
        +- PackageDeclaration[@Name = "com.example.expression"]
        |  +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
        +- ClassDeclaration[@Abstract = true, @Annotation = false, @Anonymous = false, @BinaryName = "com.example.expression.Expr", @CanonicalName = "com.example.expression.Expr", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = true, @Local = false, @Nested = false, @PackageName = "com.example.expression", @Record = false, @RegularClass = false, @RegularInterface = true, @SimpleName = "Expr", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/geometry/Shape.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/geometry/Shape.txt
    index 3e1359f3eae..d1aae6845ab 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/geometry/Shape.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/geometry/Shape.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = "com.example.geometry"]
    ++- CompilationUnit[@Compact = false, @PackageName = "com.example.geometry"]
        +- PackageDeclaration[@Name = "com.example.geometry"]
        |  +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "com.example.geometry.Shape", @CanonicalName = "com.example.geometry.Shape", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "com.example.geometry", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Shape", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/geometry/Square.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/geometry/Square.txt
    index 6939b80ab6f..9c5a966a773 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/geometry/Square.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/geometry/Square.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = "com.example.geometry"]
    ++- CompilationUnit[@Compact = false, @PackageName = "com.example.geometry"]
        +- PackageDeclaration[@Name = "com.example.geometry"]
        |  +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "com.example.geometry.Square", @CanonicalName = "com.example.geometry.Square", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "com.example.geometry", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Square", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/AnnotationValueInitializers.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/AnnotationValueInitializers.txt
    index 9f95fc329d2..6df5b04340b 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/AnnotationValueInitializers.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/AnnotationValueInitializers.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "AnnotationValueInitializers", @CanonicalName = "AnnotationValueInitializers", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "AnnotationValueInitializers", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE]
        |  +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
        |  |  +- Annotation[@SimpleName = "MyAnnotation"]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/DealingWithNull.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/DealingWithNull.txt
    index 0716f68aa71..feeaec8b249 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/DealingWithNull.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/DealingWithNull.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "DealingWithNull", @CanonicalName = "DealingWithNull", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "DealingWithNull", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 6]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/EnhancedTypeCheckingSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/EnhancedTypeCheckingSwitch.txt
    index ddc4cb15f6b..b820b67415e 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/EnhancedTypeCheckingSwitch.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/EnhancedTypeCheckingSwitch.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "EnhancedTypeCheckingSwitch", @CanonicalName = "EnhancedTypeCheckingSwitch", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "EnhancedTypeCheckingSwitch", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 4]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ExhaustiveSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ExhaustiveSwitch.txt
    index f3aafd2a07d..e47f062db0f 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ExhaustiveSwitch.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ExhaustiveSwitch.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "ExhaustiveSwitch", @CanonicalName = "ExhaustiveSwitch", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "ExhaustiveSwitch", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 13]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/GuardedPatterns.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/GuardedPatterns.txt
    index fc4111aa7bb..d80e6232574 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/GuardedPatterns.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/GuardedPatterns.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "GuardedPatterns", @CanonicalName = "GuardedPatterns", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "GuardedPatterns", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 8]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep440_RecordPatterns.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep440_RecordPatterns.txt
    index 187801751da..4bed5a255f4 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep440_RecordPatterns.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep440_RecordPatterns.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep440_RecordPatterns", @CanonicalName = "Jep440_RecordPatterns", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Jep440_RecordPatterns", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE]
           +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
           +- ClassBody[@Empty = false, @Size = 15]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt
    index 0fe43b24319..1ad645a2dc3 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep441_PatternMatchingForSwitch", @CanonicalName = "Jep441_PatternMatchingForSwitch", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Jep441_PatternMatchingForSwitch", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE]
           +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
           +- ClassBody[@Empty = false, @Size = 13]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/PatternsInSwitchLabels.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/PatternsInSwitchLabels.txt
    index 8805f7d44c3..d84807282c5 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/PatternsInSwitchLabels.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/PatternsInSwitchLabels.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "PatternsInSwitchLabels", @CanonicalName = "PatternsInSwitchLabels", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "PatternsInSwitchLabels", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 1]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatterns.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatterns.txt
    index 44dc24bba69..5aa874c6697 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatterns.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatterns.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "RecordPatterns", @CanonicalName = "RecordPatterns", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "RecordPatterns", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 21]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatternsExhaustiveSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatternsExhaustiveSwitch.txt
    index 4c2bf0e9e0c..1b4098d2f75 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatternsExhaustiveSwitch.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatternsExhaustiveSwitch.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "RecordPatternsExhaustiveSwitch", @CanonicalName = "RecordPatternsExhaustiveSwitch", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "RecordPatternsExhaustiveSwitch", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 7]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RefiningPatternsInSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RefiningPatternsInSwitch.txt
    index 1ade3b146fc..974ccbd24bf 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RefiningPatternsInSwitch.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RefiningPatternsInSwitch.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "RefiningPatternsInSwitch", @CanonicalName = "RefiningPatternsInSwitch", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "RefiningPatternsInSwitch", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 7]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ScopeOfPatternVariableDeclarations.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ScopeOfPatternVariableDeclarations.txt
    index 9d5dfc52cfb..6d448620011 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ScopeOfPatternVariableDeclarations.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ScopeOfPatternVariableDeclarations.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "ScopeOfPatternVariableDeclarations", @CanonicalName = "ScopeOfPatternVariableDeclarations", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "ScopeOfPatternVariableDeclarations", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
           +- ClassBody[@Empty = false, @Size = 4]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt
    index 698a2f5780e..6b7b7c19ca5 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.ArrayDeque", @ImportedSimpleName = "ArrayDeque", @ModuleImport = false, @PackageName = "java.util", @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.List", @ImportedSimpleName = "List", @ModuleImport = false, @PackageName = "java.util", @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.Queue", @ImportedSimpleName = "Queue", @ModuleImport = false, @PackageName = "java.util", @Static = false]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23/Jep467_MarkdownDocumentationComments.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23/Jep467_MarkdownDocumentationComments.txt
    index b814782ef3a..f12069bc9f4 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23/Jep467_MarkdownDocumentationComments.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java23/Jep467_MarkdownDocumentationComments.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.Locale", @ImportedSimpleName = "Locale", @ModuleImport = false, @PackageName = "java.util", @Static = false]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep467_MarkdownDocumentationComments", @CanonicalName = "Jep467_MarkdownDocumentationComments", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Jep467_MarkdownDocumentationComments", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt
    index 176fa4a1b63..0360136ed35 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.Map", @ImportedSimpleName = "Map", @ModuleImport = false, @PackageName = "java.util", @Static = false]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch", @CanonicalName = "Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep492_FlexibleConstructorBodies.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep492_FlexibleConstructorBodies.txt
    index c010e438de3..4000fafd72e 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep492_FlexibleConstructorBodies.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep492_FlexibleConstructorBodies.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.math.BigInteger", @ImportedSimpleName = "BigInteger", @ModuleImport = false, @PackageName = "java.math", @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.security.cert.Certificate", @ImportedSimpleName = "Certificate", @ModuleImport = false, @PackageName = "java.security.cert", @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.security.interfaces.DSAPublicKey", @ImportedSimpleName = "DSAPublicKey", @ModuleImport = false, @PackageName = "java.security.interfaces", @Static = false]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep494_ModuleImportDeclarations.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep494_ModuleImportDeclarations.txt
    index 135131c4cc1..795eafa6cd3 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep494_ModuleImportDeclarations.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep494_ModuleImportDeclarations.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.base", @ImportedSimpleName = null, @ModuleImport = true, @PackageName = null, @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.desktop", @ImportedSimpleName = null, @ModuleImport = true, @PackageName = null, @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.List", @ImportedSimpleName = "List", @ModuleImport = false, @PackageName = "java.util", @Static = false]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep495_SimpleSourceFilesAndInstanceMainMethods.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep495_SimpleSourceFilesAndInstanceMainMethods.txt
    index 8db4b96d345..6c1d79e6793 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep495_SimpleSourceFilesAndInstanceMainMethods.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep495_SimpleSourceFilesAndInstanceMainMethods.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = true, @PackageName = ""]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.Arrays", @ImportedSimpleName = "Arrays", @ModuleImport = false, @PackageName = "java.util", @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.stream.Collectors", @ImportedSimpleName = "Collectors", @ModuleImport = false, @PackageName = "java.util.stream", @Static = false]
        +- ImportDeclaration[@ImportOnDemand = true, @ImportedName = "java.io.IO", @ImportedSimpleName = null, @ModuleImport = false, @PackageName = "java.io.IO", @Static = true]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep511_ModuleImportDeclarations.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep511_ModuleImportDeclarations.txt
    index 34661167fe8..2ac1e5d525b 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep511_ModuleImportDeclarations.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep511_ModuleImportDeclarations.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.base", @ImportedSimpleName = null, @ModuleImport = true, @PackageName = null, @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.desktop", @ImportedSimpleName = null, @ModuleImport = true, @PackageName = null, @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.List", @ImportedSimpleName = "List", @ModuleImport = false, @PackageName = "java.util", @Static = false]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsAfterJava23.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsAfterJava23.txt
    index f5e1c4a7914..96670375745 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsAfterJava23.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsAfterJava23.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = true, @PackageName = ""]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.Arrays", @ImportedSimpleName = "Arrays", @ModuleImport = false, @PackageName = "java.util", @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.stream.Collectors", @ImportedSimpleName = "Collectors", @ModuleImport = false, @PackageName = "java.util.stream", @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.lang.IO.println", @ImportedSimpleName = "println", @ModuleImport = false, @PackageName = "java.lang.IO", @Static = true]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsBeforeJava23.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsBeforeJava23.txt
    index cb8cda89fbc..7943abdb83b 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsBeforeJava23.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep512_CompactSourceFilesAndInstanceMainMethodsBeforeJava23.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = true, @PackageName = ""]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.Arrays", @ImportedSimpleName = "Arrays", @ModuleImport = false, @PackageName = "java.util", @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.stream.Collectors", @ImportedSimpleName = "Collectors", @ModuleImport = false, @PackageName = "java.util.stream", @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.lang.IO.println", @ImportedSimpleName = "println", @ModuleImport = false, @PackageName = "java.lang.IO", @Static = true]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep513_FlexibleConstructorBodies.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep513_FlexibleConstructorBodies.txt
    index 916ad3a1ae8..945103e6e90 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep513_FlexibleConstructorBodies.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep513_FlexibleConstructorBodies.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.math.BigInteger", @ImportedSimpleName = "BigInteger", @ModuleImport = false, @PackageName = "java.math", @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.security.cert.Certificate", @ImportedSimpleName = "Certificate", @ModuleImport = false, @PackageName = "java.security.cert", @Static = false]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.security.interfaces.DSAPublicKey", @ImportedSimpleName = "DSAPublicKey", @ModuleImport = false, @PackageName = "java.security.interfaces", @Static = false]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25p/Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25p/Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.txt
    index dd31d413db7..b0ab8cd21fb 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25p/Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25p/Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.Map", @ImportedSimpleName = "Map", @ModuleImport = false, @PackageName = "java.util", @Static = false]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch", @CanonicalName = "Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
           +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java8/UnnamedVariable.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java8/UnnamedVariable.txt
    index ec85c473a2e..7cf9de77837 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java8/UnnamedVariable.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java8/UnnamedVariable.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "UnnamedVariable", @CanonicalName = "UnnamedVariable", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "UnnamedVariable", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE]
           +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
           +- ClassBody[@Empty = false, @Size = 2]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java9/jdk9_module_info.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java9/jdk9_module_info.txt
    index f66cf45b11c..ef1d04582c2 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java9/jdk9_module_info.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java9/jdk9_module_info.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ModuleDeclaration[@Name = "com.example.foo", @Open = true]
           +- ModuleName[@Name = "com.example.foo"]
           +- ModuleRequiresDirective[@Static = false, @Transitive = false]
    diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java9/jdk9_module_info_with_annot.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java9/jdk9_module_info_with_annot.txt
    index a911c31526b..b2faeb0adee 100644
    --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java9/jdk9_module_info_with_annot.txt
    +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java9/jdk9_module_info_with_annot.txt
    @@ -1,4 +1,4 @@
    -+- CompilationUnit[@PackageName = ""]
    ++- CompilationUnit[@Compact = false, @PackageName = ""]
        +- ModuleDeclaration[@Name = "jdk.pack", @Open = false]
           +- Annotation[@SimpleName = "Deprecated"]
           |  +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Deprecated"]
    
    From 99d0f6e485ffe80d71e1ab25a850b6ba114c792b Mon Sep 17 00:00:00 2001
    From: Andreas Dangel 
    Date: Thu, 3 Jul 2025 17:29:20 +0200
    Subject: [PATCH 1086/1962] [doc] Update release notes (#5478)
    
    ---
     docs/pages/release_notes.md | 32 ++++++++++++++++++++++++++++++++
     1 file changed, 32 insertions(+)
    
    diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md
    index 0c9c0dd3524..7f3949f1a49 100644
    --- a/docs/pages/release_notes.md
    +++ b/docs/pages/release_notes.md
    @@ -24,10 +24,42 @@ This is a {{ site.pmd.release_type }} release.
     
     ### ๐Ÿš€ New and noteworthy
     
    +#### ๐Ÿš€ New: Java 25 Support
    +This release of PMD brings support for Java 25.
    +
    +There are the following new standard language features:
    +* [JEP 511: Module Import Declarations](https://openjdk.org/jeps/511)
    +* [JEP 512: Compact Source Files and Instance Main Methods](https://openjdk.org/jeps/512)
    +* [JEP 513: Flexible Constructor Bodies](https://openjdk.org/jeps/513)
    +
    +And one preview language feature:
    +* [JEP 507: Primitive Types in Patterns, instanceof, and switch (Third Preview)](https://openjdk.org/jeps/507)
    +
    +In order to analyze a project with PMD that uses these preview language features,
    +you'll need to enable it via the environment variable `PMD_JAVA_OPTS` and select the new language
    +version `25-preview`:
    +
    +    export PMD_JAVA_OPTS=--enable-preview
    +    pmd check --use-version java-25-preview ...
    +
    +Note: Support for Java 23 preview language features have been removed. The version "23-preview"
    +is no longer available.
    +
     ### ๐Ÿ› Fixed Issues
    +* java
    +  * [#5478](https://github.com/pmd/pmd/issues/5478): \[java] Support Java 25
     
     ### ๐Ÿšจ API Changes
     
    +#### Experimental APIs that are now considered stable
    +* pmd-java
    +  * {% jdoc !!java::lang.java.ast.ASTImportDeclaration#isModuleImport() %} is now stable API.
    +  * {% jdoc !!java::lang.java.ast.ASTCompilationUnit#isCompact() %} is now stable API. Note, it was previously
    +    called `isSimpleCompilationUnit`.
    +  * {% jdoc java::lang.java.ast.ASTImplicitClassDeclaration %} is now stable API.
    +  * {% jdoc !ac!java::lang.java.ast.JavaVisitorBase#visit(java::lang.java.ast.ASTImplicitClassDeclaration,P) %} is now
    +    stable API.
    +
     ### โœจ Merged pull requests
     
     
    
    From eb7f4b78e6be6eb3619855e6d2377053eb59d766 Mon Sep 17 00:00:00 2001
    From: Andreas Dangel 
    Date: Fri, 4 Jul 2025 09:27:41 +0200
    Subject: [PATCH 1087/1962] chore: pmd-core: Update license header
    
    ---
     .../main/java/net/sourceforge/pmd/AbstractConfiguration.java  | 2 +-
     .../src/main/java/net/sourceforge/pmd/PMDConfiguration.java   | 2 +-
     pmd-core/src/main/java/net/sourceforge/pmd/PMDVersion.java    | 2 +-
     pmd-core/src/main/java/net/sourceforge/pmd/PmdAnalysis.java   | 2 +-
     .../main/java/net/sourceforge/pmd/annotation/InternalApi.java | 2 +-
     .../sourceforge/pmd/benchmark/TextTimingReportRenderer.java   | 2 +-
     .../main/java/net/sourceforge/pmd/benchmark/TimeTracker.java  | 2 +-
     .../java/net/sourceforge/pmd/benchmark/TimedOperation.java    | 2 +-
     .../net/sourceforge/pmd/benchmark/TimedOperationCategory.java | 2 +-
     .../main/java/net/sourceforge/pmd/benchmark/TimingReport.java | 2 +-
     .../net/sourceforge/pmd/benchmark/TimingReportRenderer.java   | 2 +-
     .../sourceforge/pmd/cache/internal/AbstractAnalysisCache.java | 2 +-
     .../net/sourceforge/pmd/cache/internal/AnalysisCache.java     | 2 +-
     .../sourceforge/pmd/cache/internal/AnalysisCacheListener.java | 2 +-
     .../net/sourceforge/pmd/cache/internal/AnalysisResult.java    | 2 +-
     .../net/sourceforge/pmd/cache/internal/CachedRuleMapper.java  | 2 +-
     .../sourceforge/pmd/cache/internal/CachedRuleViolation.java   | 2 +-
     .../net/sourceforge/pmd/cache/internal/ChecksumAware.java     | 2 +-
     .../pmd/cache/internal/ClasspathEntryFingerprinter.java       | 2 +-
     .../pmd/cache/internal/ClasspathFingerprinter.java            | 2 +-
     .../net/sourceforge/pmd/cache/internal/FileAnalysisCache.java | 2 +-
     .../net/sourceforge/pmd/cache/internal/NoopAnalysisCache.java | 2 +-
     .../net/sourceforge/pmd/cache/internal/NoopFingerprinter.java | 2 +-
     .../sourceforge/pmd/cache/internal/RawFileFingerprinter.java  | 2 +-
     .../sourceforge/pmd/cache/internal/ZipFileFingerprinter.java  | 2 +-
     .../src/main/java/net/sourceforge/pmd/cpd/AnyCpdLexer.java    | 2 +-
     .../main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java   | 2 +-
     .../src/main/java/net/sourceforge/pmd/cpd/CPDListener.java    | 2 +-
     .../main/java/net/sourceforge/pmd/cpd/CPDNullListener.java    | 2 +-
     pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDReport.java | 2 +-
     .../src/main/java/net/sourceforge/pmd/cpd/CSVRenderer.java    | 2 +-
     .../sourceforge/pmd/cpd/CSVWithLinecountPerFileRenderer.java  | 2 +-
     .../src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java    | 2 +-
     pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdLexer.java  | 2 +-
     pmd-core/src/main/java/net/sourceforge/pmd/cpd/GUI.java       | 2 +-
     pmd-core/src/main/java/net/sourceforge/pmd/cpd/Mark.java      | 2 +-
     pmd-core/src/main/java/net/sourceforge/pmd/cpd/Match.java     | 2 +-
     .../src/main/java/net/sourceforge/pmd/cpd/MatchAlgorithm.java | 2 +-
     .../src/main/java/net/sourceforge/pmd/cpd/MatchCollector.java | 2 +-
     .../src/main/java/net/sourceforge/pmd/cpd/SimpleRenderer.java | 2 +-
     .../src/main/java/net/sourceforge/pmd/cpd/SourceManager.java  | 2 +-
     .../src/main/java/net/sourceforge/pmd/cpd/TokenEntry.java     | 2 +-
     .../src/main/java/net/sourceforge/pmd/cpd/TokenFactory.java   | 2 +-
     pmd-core/src/main/java/net/sourceforge/pmd/cpd/Tokens.java    | 2 +-
     .../src/main/java/net/sourceforge/pmd/cpd/VSRenderer.java     | 2 +-
     .../src/main/java/net/sourceforge/pmd/cpd/XMLOldRenderer.java | 2 +-
     .../src/main/java/net/sourceforge/pmd/cpd/XMLRenderer.java    | 2 +-
     .../main/java/net/sourceforge/pmd/cpd/impl/CpdLexerBase.java  | 2 +-
     .../java/net/sourceforge/pmd/cpd/impl/JavaccCpdLexer.java     | 2 +-
     .../net/sourceforge/pmd/internal/util/ShortFilenameUtil.java  | 2 +-
     .../pmd/lang/AbstractPmdLanguageVersionHandler.java           | 2 +-
     pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java | 2 +-
     .../java/net/sourceforge/pmd/lang/LanguageFilenameFilter.java | 2 +-
     .../main/java/net/sourceforge/pmd/lang/LanguageVersion.java   | 2 +-
     .../net/sourceforge/pmd/lang/LanguageVersionDiscoverer.java   | 2 +-
     .../java/net/sourceforge/pmd/lang/LanguageVersionHandler.java | 2 +-
     .../src/main/java/net/sourceforge/pmd/lang/TokenManager.java  | 2 +-
     .../main/java/net/sourceforge/pmd/lang/ast/NodeStream.java    | 2 +-
     .../java/net/sourceforge/pmd/lang/ast/ParseException.java     | 2 +-
     .../src/main/java/net/sourceforge/pmd/lang/ast/RootNode.java  | 2 +-
     .../sourceforge/pmd/lang/ast/impl/SuppressionCommentImpl.java | 2 +-
     .../pmd/lang/ast/impl/javacc/JjtreeParserAdapter.java         | 2 +-
     .../pmd/lang/impl/BasePmdDialectLanguageVersionHandler.java   | 2 +-
     .../sourceforge/pmd/lang/metrics/LanguageMetricsProvider.java | 2 +-
     .../main/java/net/sourceforge/pmd/lang/metrics/Metric.java    | 2 +-
     .../java/net/sourceforge/pmd/lang/metrics/MetricOption.java   | 2 +-
     .../java/net/sourceforge/pmd/lang/metrics/MetricOptions.java  | 2 +-
     .../sourceforge/pmd/lang/metrics/ParameterizedMetricKey.java  | 2 +-
     .../main/java/net/sourceforge/pmd/lang/rule/AbstractRule.java | 2 +-
     .../src/main/java/net/sourceforge/pmd/lang/rule/Rule.java     | 2 +-
     .../main/java/net/sourceforge/pmd/lang/rule/RulePriority.java | 2 +-
     .../java/net/sourceforge/pmd/lang/rule/RuleReference.java     | 2 +-
     .../src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java  | 2 +-
     .../java/net/sourceforge/pmd/lang/rule/RuleSetWriter.java     | 2 +-
     .../pmd/lang/rule/impl/UnnecessaryPmdSuppressionRule.java     | 2 +-
     .../sourceforge/pmd/lang/rule/internal/RuleSetReference.java  | 2 +-
     .../pmd/lang/rule/internal/RuleSetReferenceId.java            | 2 +-
     .../java/net/sourceforge/pmd/lang/rule/internal/RuleSets.java | 2 +-
     .../java/net/sourceforge/pmd/lang/rule/xpath/XPathRule.java   | 2 +-
     .../pmd/lang/symboltable/AbstractNameDeclaration.java         | 2 +-
     .../net/sourceforge/pmd/lang/symboltable/AbstractScope.java   | 2 +-
     .../java/net/sourceforge/pmd/lang/symboltable/Applier.java    | 2 +-
     .../sourceforge/pmd/lang/symboltable/ImageFinderFunction.java | 2 +-
     .../net/sourceforge/pmd/lang/symboltable/NameDeclaration.java | 2 +-
     .../net/sourceforge/pmd/lang/symboltable/NameOccurrence.java  | 2 +-
     .../main/java/net/sourceforge/pmd/lang/symboltable/Scope.java | 2 +-
     .../java/net/sourceforge/pmd/lang/symboltable/ScopedNode.java | 2 +-
     .../sourceforge/pmd/properties/AbstractPropertySource.java    | 2 +-
     .../java/net/sourceforge/pmd/properties/PropertyBuilder.java  | 2 +-
     .../net/sourceforge/pmd/properties/PropertyDescriptor.java    | 2 +-
     .../java/net/sourceforge/pmd/properties/PropertyFactory.java  | 2 +-
     .../java/net/sourceforge/pmd/properties/PropertySource.java   | 2 +-
     .../sourceforge/pmd/properties/internal/PropertyTypeId.java   | 2 +-
     .../pmd/renderers/AbstractAccumulatingRenderer.java           | 2 +-
     .../pmd/renderers/AbstractIncrementingRenderer.java           | 2 +-
     .../java/net/sourceforge/pmd/renderers/AbstractRenderer.java  | 2 +-
     .../main/java/net/sourceforge/pmd/renderers/CSVRenderer.java  | 2 +-
     .../main/java/net/sourceforge/pmd/renderers/CSVWriter.java    | 2 +-
     .../java/net/sourceforge/pmd/renderers/CodeClimateIssue.java  | 2 +-
     .../net/sourceforge/pmd/renderers/CodeClimateRenderer.java    | 2 +-
     .../java/net/sourceforge/pmd/renderers/ColumnDescriptor.java  | 2 +-
     .../java/net/sourceforge/pmd/renderers/EmacsRenderer.java     | 2 +-
     .../java/net/sourceforge/pmd/renderers/EmptyRenderer.java     | 2 +-
     .../main/java/net/sourceforge/pmd/renderers/HTMLRenderer.java | 2 +-
     .../java/net/sourceforge/pmd/renderers/IDEAJRenderer.java     | 2 +-
     .../src/main/java/net/sourceforge/pmd/renderers/Renderer.java | 2 +-
     .../java/net/sourceforge/pmd/renderers/RendererFactory.java   | 2 +-
     .../net/sourceforge/pmd/renderers/SummaryHTMLRenderer.java    | 2 +-
     .../java/net/sourceforge/pmd/renderers/TextColorRenderer.java | 2 +-
     .../java/net/sourceforge/pmd/renderers/TextPadRenderer.java   | 2 +-
     .../main/java/net/sourceforge/pmd/renderers/TextRenderer.java | 2 +-
     .../java/net/sourceforge/pmd/renderers/VBHTMLRenderer.java    | 2 +-
     .../main/java/net/sourceforge/pmd/renderers/XMLRenderer.java  | 2 +-
     .../main/java/net/sourceforge/pmd/renderers/XSLTRenderer.java | 2 +-
     .../java/net/sourceforge/pmd/renderers/YAHTMLRenderer.java    | 2 +-
     .../sourceforge/pmd/reporting/ParametricRuleViolation.java    | 2 +-
     .../main/java/net/sourceforge/pmd/reporting/RuleContext.java  | 2 +-
     .../java/net/sourceforge/pmd/reporting/RuleViolation.java     | 2 +-
     .../main/java/net/sourceforge/pmd/util/CollectionUtil.java    | 2 +-
     .../src/main/java/net/sourceforge/pmd/util/StringUtil.java    | 2 +-
     .../java/net/sourceforge/pmd/util/database/DBMSMetadata.java  | 2 +-
     .../main/java/net/sourceforge/pmd/util/database/DBType.java   | 2 +-
     .../main/java/net/sourceforge/pmd/util/database/DBURI.java    | 2 +-
     .../net/sourceforge/pmd/util/database/ResourceLoader.java     | 2 +-
     .../net/sourceforge/pmd/util/database/ResourceResolver.java   | 2 +-
     .../java/net/sourceforge/pmd/util/database/SourceObject.java  | 2 +-
     .../net/sourceforge/pmd/util/internal/ResourceLoader.java     | 2 +-
     .../src/test/java/net/sourceforge/pmd/AbstractRuleTest.java   | 2 +-
     .../src/test/java/net/sourceforge/pmd/FileSelectorTest.java   | 2 +-
     pmd-core/src/test/java/net/sourceforge/pmd/FooRule.java       | 2 +-
     .../test/java/net/sourceforge/pmd/PmdConfigurationTest.java   | 2 +-
     .../src/test/java/net/sourceforge/pmd/RuleSetSchemaTest.java  | 2 +-
     .../src/test/java/net/sourceforge/pmd/RuleWithProperties.java | 2 +-
     .../internal/AbstractClasspathEntryFingerprinterTest.java     | 2 +-
     .../sourceforge/pmd/cache/internal/FileAnalysisCacheTest.java | 2 +-
     .../pmd/cache/internal/RawFileFingerprinterTest.java          | 2 +-
     .../pmd/cache/internal/ZipFileFingerprinterTest.java          | 2 +-
     .../test/java/net/sourceforge/pmd/cpd/AnyCpdLexerTest.java    | 2 +-
     .../java/net/sourceforge/pmd/cpd/CPDConfigurationTest.java    | 2 +-
     .../test/java/net/sourceforge/pmd/cpd/CPDFilelistTest.java    | 2 +-
     .../test/java/net/sourceforge/pmd/cpd/CSVRendererTest.java    | 2 +-
     .../test/java/net/sourceforge/pmd/cpd/CpdAnalysisTest.java    | 2 +-
     pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkTest.java  | 2 +-
     pmd-core/src/test/java/net/sourceforge/pmd/cpd/MatchTest.java | 2 +-
     .../src/test/java/net/sourceforge/pmd/cpd/TokenEntryTest.java | 2 +-
     .../test/java/net/sourceforge/pmd/cpd/XMLRendererTest.java    | 2 +-
     .../java/net/sourceforge/pmd/lang/CpdOnlyDummyLanguage.java   | 2 +-
     .../java/net/sourceforge/pmd/lang/Dummy2LanguageModule.java   | 2 +-
     .../net/sourceforge/pmd/lang/DummyLanguageDialectModule.java  | 2 +-
     .../java/net/sourceforge/pmd/lang/DummyLanguageModule.java    | 2 +-
     .../net/sourceforge/pmd/lang/DummyLanguageNoCapabilities.java | 2 +-
     .../java/net/sourceforge/pmd/lang/LanguageRegistryTest.java   | 2 +-
     .../sourceforge/pmd/lang/LanguageVersionDiscovererTest.java   | 2 +-
     .../net/sourceforge/pmd/lang/ast/BoundaryTraversalTest.java   | 2 +-
     .../src/test/java/net/sourceforge/pmd/lang/ast/DummyNode.java | 2 +-
     .../pmd/lang/ast/DummyNodeWithDeprecatedAttribute.java        | 2 +-
     .../sourceforge/pmd/lang/document/FileCollectorZipTest.java   | 2 +-
     .../sourceforge/pmd/lang/impl/MultiThreadProcessorTest.java   | 2 +-
     .../pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java    | 2 +-
     .../java/net/sourceforge/pmd/lang/rule/RuleReferenceTest.java | 2 +-
     .../test/java/net/sourceforge/pmd/lang/rule/RuleSetTest.java  | 2 +-
     .../java/net/sourceforge/pmd/lang/rule/RuleSetWriterTest.java | 2 +-
     .../pmd/lang/rule/internal/RuleSetReferenceIdTest.java        | 2 +-
     .../net/sourceforge/pmd/lang/symboltable/ApplierTest.java     | 2 +-
     .../sourceforge/pmd/properties/PropertyDescriptorTest.java    | 2 +-
     .../net/sourceforge/pmd/renderers/AbstractRendererTest.java   | 2 +-
     .../java/net/sourceforge/pmd/renderers/CSVRendererTest.java   | 2 +-
     .../sourceforge/pmd/renderers/CodeClimateRendererTest.java    | 2 +-
     .../java/net/sourceforge/pmd/renderers/EmacsRendererTest.java | 2 +-
     .../java/net/sourceforge/pmd/renderers/EmptyRendererTest.java | 2 +-
     .../java/net/sourceforge/pmd/renderers/HTMLRendererTest.java  | 2 +-
     .../java/net/sourceforge/pmd/renderers/IDEAJRendererTest.java | 2 +-
     .../java/net/sourceforge/pmd/renderers/RenderersTests.java    | 2 +-
     .../sourceforge/pmd/renderers/SummaryHTMLRendererTest.java    | 2 +-
     .../net/sourceforge/pmd/renderers/TextColorRendererTest.java  | 2 +-
     .../net/sourceforge/pmd/renderers/TextPadRendererTest.java    | 2 +-
     .../java/net/sourceforge/pmd/renderers/TextRendererTest.java  | 2 +-
     .../net/sourceforge/pmd/renderers/VBHTMLRendererTest.java     | 2 +-
     .../java/net/sourceforge/pmd/renderers/XMLRendererTest.java   | 2 +-
     .../java/net/sourceforge/pmd/renderers/XSLTRendererTest.java  | 2 +-
     .../net/sourceforge/pmd/renderers/YAHTMLRendererTest.java     | 2 +-
     .../java/net/sourceforge/pmd/reporting/RuleContextTest.java   | 2 +-
     .../pmd/reporting/RuleViolationComparatorTest.java            | 2 +-
     .../java/net/sourceforge/pmd/reporting/RuleViolationTest.java | 2 +-
     .../test/java/net/sourceforge/pmd/util/StringUtilTest.java    | 2 +-
     .../net/sourceforge/pmd/util/database/DBMSMetadataTest.java   | 2 +-
     .../java/net/sourceforge/pmd/util/database/DBTypeTest.java    | 2 +-
     .../java/net/sourceforge/pmd/util/database/DBURITest.java     | 2 +-
     .../net/sourceforge/pmd/util/database/ResourceLoaderTest.java | 2 +-
     .../sourceforge/pmd/util/database/ResourceResolverTest.java   | 2 +-
     .../src/test/resources/net/sourceforge/pmd/cpd/files/dup1.txt | 4 ++--
     .../src/test/resources/net/sourceforge/pmd/cpd/files/dup2.txt | 4 ++--
     192 files changed, 194 insertions(+), 194 deletions(-)
    
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/AbstractConfiguration.java b/pmd-core/src/main/java/net/sourceforge/pmd/AbstractConfiguration.java
    index 848203ca3b6..ee95be58332 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/AbstractConfiguration.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/AbstractConfiguration.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java
    index b2bf76402e6..bbd888aba82 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PMDVersion.java b/pmd-core/src/main/java/net/sourceforge/pmd/PMDVersion.java
    index 4b7a72e5118..f95c18b1e77 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/PMDVersion.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PMDVersion.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PmdAnalysis.java b/pmd-core/src/main/java/net/sourceforge/pmd/PmdAnalysis.java
    index 985c5e233dc..255eed05ce2 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/PmdAnalysis.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PmdAnalysis.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/annotation/InternalApi.java b/pmd-core/src/main/java/net/sourceforge/pmd/annotation/InternalApi.java
    index c74c3bd421f..cd56e76fafd 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/annotation/InternalApi.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/annotation/InternalApi.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TextTimingReportRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TextTimingReportRenderer.java
    index 088adf564aa..6e5f6da8187 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TextTimingReportRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TextTimingReportRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimeTracker.java b/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimeTracker.java
    index 4c407eb41ba..13c39b7b967 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimeTracker.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimeTracker.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimedOperation.java b/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimedOperation.java
    index 74ba7fa6f3f..8242c9c43b6 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimedOperation.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimedOperation.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimedOperationCategory.java b/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimedOperationCategory.java
    index fc8958fdcbb..b1ef5e06575 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimedOperationCategory.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimedOperationCategory.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimingReport.java b/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimingReport.java
    index 028e8906f61..c4cf50d6dcb 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimingReport.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimingReport.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimingReportRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimingReportRenderer.java
    index 8bd8818c266..6f89adef301 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimingReportRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimingReportRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/AbstractAnalysisCache.java b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/AbstractAnalysisCache.java
    index 76aa6141f9d..dfaa7f4d26b 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/AbstractAnalysisCache.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/AbstractAnalysisCache.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/AnalysisCache.java b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/AnalysisCache.java
    index 13e9f6ee6b1..804584bf16a 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/AnalysisCache.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/AnalysisCache.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/AnalysisCacheListener.java b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/AnalysisCacheListener.java
    index fdd719c6145..c703c102d2c 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/AnalysisCacheListener.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/AnalysisCacheListener.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/AnalysisResult.java b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/AnalysisResult.java
    index 3de09d07dfe..c4bc88696ba 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/AnalysisResult.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/AnalysisResult.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/CachedRuleMapper.java b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/CachedRuleMapper.java
    index 06541ed9f08..6cc1c60ce02 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/CachedRuleMapper.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/CachedRuleMapper.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/CachedRuleViolation.java b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/CachedRuleViolation.java
    index 732be7d241a..4abbd5b91e8 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/CachedRuleViolation.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/CachedRuleViolation.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/ChecksumAware.java b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/ChecksumAware.java
    index 48e92082431..2f4395a0b85 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/ChecksumAware.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/ChecksumAware.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/ClasspathEntryFingerprinter.java b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/ClasspathEntryFingerprinter.java
    index be77b1adfbe..2f9e53fb7f7 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/ClasspathEntryFingerprinter.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/ClasspathEntryFingerprinter.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/ClasspathFingerprinter.java b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/ClasspathFingerprinter.java
    index 691bf2bf9d9..402c20250f7 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/ClasspathFingerprinter.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/ClasspathFingerprinter.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/FileAnalysisCache.java b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/FileAnalysisCache.java
    index 2fcd061b52e..54969bd4bbd 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/FileAnalysisCache.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/FileAnalysisCache.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/NoopAnalysisCache.java b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/NoopAnalysisCache.java
    index da030a4317e..1d9ad3e8435 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/NoopAnalysisCache.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/NoopAnalysisCache.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/NoopFingerprinter.java b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/NoopFingerprinter.java
    index 7cdc1eecec7..02bd2851fca 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/NoopFingerprinter.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/NoopFingerprinter.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/RawFileFingerprinter.java b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/RawFileFingerprinter.java
    index 50ce1984889..2c06f7337f6 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/RawFileFingerprinter.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/RawFileFingerprinter.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/ZipFileFingerprinter.java b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/ZipFileFingerprinter.java
    index 826ce01fc6f..f8310cfc98f 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/ZipFileFingerprinter.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cache/internal/ZipFileFingerprinter.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AnyCpdLexer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AnyCpdLexer.java
    index db0988c0ffd..cbc68f82509 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AnyCpdLexer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AnyCpdLexer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java
    index 8c63ae32527..9d5f104b990 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDListener.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDListener.java
    index 6f361d1afb8..ee09981ba56 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDListener.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDListener.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDNullListener.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDNullListener.java
    index 3566a9a6cf3..4b1380b22be 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDNullListener.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDNullListener.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDReport.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDReport.java
    index 50bbf6ccaae..e8c00d779d8 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDReport.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDReport.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CSVRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CSVRenderer.java
    index f68e1c4c6e2..6e10e73fbf3 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CSVRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CSVRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CSVWithLinecountPerFileRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CSVWithLinecountPerFileRenderer.java
    index 6409fe86ae7..5617a90742e 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CSVWithLinecountPerFileRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CSVWithLinecountPerFileRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java
    index acd2b7a5e1f..817ca27de1d 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdLexer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdLexer.java
    index 5a88b259eb4..603fa650fff 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdLexer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdLexer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/GUI.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/GUI.java
    index 91e1bb8fe6d..5704b1a5a13 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/GUI.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/GUI.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Mark.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Mark.java
    index df163e59fc7..a4227def8ba 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Mark.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Mark.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Match.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Match.java
    index 0480922f902..3e7cc7953f1 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Match.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Match.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MatchAlgorithm.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MatchAlgorithm.java
    index ecd10d3fe26..7a87c39447c 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MatchAlgorithm.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MatchAlgorithm.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MatchCollector.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MatchCollector.java
    index d2d4264f2b6..6fc84bdd81e 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MatchCollector.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MatchCollector.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SimpleRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SimpleRenderer.java
    index d7d2e6e2290..eb906416ec9 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SimpleRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SimpleRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceManager.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceManager.java
    index c7c9d469faf..3d2de6b3882 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceManager.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceManager.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/TokenEntry.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/TokenEntry.java
    index c90701a0265..da44ab51106 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/TokenEntry.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/TokenEntry.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/TokenFactory.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/TokenFactory.java
    index cfc2eba6385..52480adc76d 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/TokenFactory.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/TokenFactory.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Tokens.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Tokens.java
    index 105efdcaa81..b2a4c384ce5 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Tokens.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Tokens.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/VSRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/VSRenderer.java
    index 58298785ff1..353f6fcd8fd 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/VSRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/VSRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLOldRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLOldRenderer.java
    index d5867e1399b..3df44d6e961 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLOldRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLOldRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLRenderer.java
    index 8e9b8fe5b6b..671c628ddbf 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/CpdLexerBase.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/CpdLexerBase.java
    index 22478fa3447..92696b3f98e 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/CpdLexerBase.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/CpdLexerBase.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/JavaccCpdLexer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/JavaccCpdLexer.java
    index 7f5641aedbb..aefe196a2f0 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/JavaccCpdLexer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/JavaccCpdLexer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ShortFilenameUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ShortFilenameUtil.java
    index fa10c36459b..48a5fbf01b7 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ShortFilenameUtil.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ShortFilenameUtil.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/AbstractPmdLanguageVersionHandler.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/AbstractPmdLanguageVersionHandler.java
    index 00ad1b5b84b..daa90580687 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/AbstractPmdLanguageVersionHandler.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/AbstractPmdLanguageVersionHandler.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java
    index c47312ddef9..e66a985e476 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageFilenameFilter.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageFilenameFilter.java
    index 6635ac66633..b8e61640334 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageFilenameFilter.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageFilenameFilter.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersion.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersion.java
    index 5e9d787fd06..830e9700c46 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersion.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersion.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionDiscoverer.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionDiscoverer.java
    index 4edb42c5057..1edfb9aeba0 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionDiscoverer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionDiscoverer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionHandler.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionHandler.java
    index 73cd406d9eb..5bde3ef5b1a 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionHandler.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageVersionHandler.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/TokenManager.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/TokenManager.java
    index 89623409ccf..5d5e2334809 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/TokenManager.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/TokenManager.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/NodeStream.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/NodeStream.java
    index 45f73d08823..e7041145e1f 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/NodeStream.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/NodeStream.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/ParseException.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/ParseException.java
    index 1cbf565158a..6367b4fc03a 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/ParseException.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/ParseException.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/RootNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/RootNode.java
    index 973d2d5748d..e8f5dd41ca0 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/RootNode.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/RootNode.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/SuppressionCommentImpl.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/SuppressionCommentImpl.java
    index b38d06597c4..580c13cc8c2 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/SuppressionCommentImpl.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/SuppressionCommentImpl.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeParserAdapter.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeParserAdapter.java
    index 3838c48655a..7b274480f11 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeParserAdapter.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeParserAdapter.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/BasePmdDialectLanguageVersionHandler.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/BasePmdDialectLanguageVersionHandler.java
    index 2fe55b0f615..6cea5f62078 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/BasePmdDialectLanguageVersionHandler.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/BasePmdDialectLanguageVersionHandler.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/LanguageMetricsProvider.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/LanguageMetricsProvider.java
    index e2062af0dee..510d63887d9 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/LanguageMetricsProvider.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/LanguageMetricsProvider.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/Metric.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/Metric.java
    index 735c3ef6c93..9b2fcd2760f 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/Metric.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/Metric.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOption.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOption.java
    index 79226400ba7..84e155ec611 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOption.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOption.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOptions.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOptions.java
    index 99e844851bc..d55a3c58523 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOptions.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOptions.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/ParameterizedMetricKey.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/ParameterizedMetricKey.java
    index 230c8a033bb..27b83fb2014 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/ParameterizedMetricKey.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/ParameterizedMetricKey.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractRule.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractRule.java
    index d00fca4b095..508bed36379 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractRule.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/Rule.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/Rule.java
    index 6123fc07bd9..a40e85e7f73 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/Rule.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/Rule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RulePriority.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RulePriority.java
    index 2007fcf0aa1..acbbf15f449 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RulePriority.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RulePriority.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleReference.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleReference.java
    index 54021e50208..df9c3792af7 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleReference.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleReference.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java
    index 9b580c206a7..e131a0f037f 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetWriter.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetWriter.java
    index 3a043326559..1a435cfea7b 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetWriter.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetWriter.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/impl/UnnecessaryPmdSuppressionRule.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/impl/UnnecessaryPmdSuppressionRule.java
    index 0ef159e7072..f48ac5ac6b8 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/impl/UnnecessaryPmdSuppressionRule.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/impl/UnnecessaryPmdSuppressionRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/RuleSetReference.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/RuleSetReference.java
    index 89590dd04a1..1591af8480b 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/RuleSetReference.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/RuleSetReference.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/RuleSetReferenceId.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/RuleSetReferenceId.java
    index b0ce233400f..e29fc6efba7 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/RuleSetReferenceId.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/RuleSetReferenceId.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/RuleSets.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/RuleSets.java
    index 1c8b2b956c4..7c54718123d 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/RuleSets.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/RuleSets.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/XPathRule.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/XPathRule.java
    index 1b89b1766f1..0301cb0eb88 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/XPathRule.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/XPathRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/AbstractNameDeclaration.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/AbstractNameDeclaration.java
    index be0b8c566ff..5e282fb3dba 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/AbstractNameDeclaration.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/AbstractNameDeclaration.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/AbstractScope.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/AbstractScope.java
    index d5433344897..8c4bebedf2c 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/AbstractScope.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/AbstractScope.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/Applier.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/Applier.java
    index e42b0cc8c0f..2e7c968265a 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/Applier.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/Applier.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/ImageFinderFunction.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/ImageFinderFunction.java
    index 5b8dcfd9449..2ac2b9cba74 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/ImageFinderFunction.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/ImageFinderFunction.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/NameDeclaration.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/NameDeclaration.java
    index ffe9e23ac77..cf352b6be0a 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/NameDeclaration.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/NameDeclaration.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/NameOccurrence.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/NameOccurrence.java
    index dc8376426a4..cc5b4de311a 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/NameOccurrence.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/NameOccurrence.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/Scope.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/Scope.java
    index 5c601395738..2945510d8d3 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/Scope.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/Scope.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/ScopedNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/ScopedNode.java
    index 80ea45ae3eb..612c9339d60 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/ScopedNode.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/ScopedNode.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/AbstractPropertySource.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/AbstractPropertySource.java
    index 5b4939b29f3..cb07209d728 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/AbstractPropertySource.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/AbstractPropertySource.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyBuilder.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyBuilder.java
    index b1b1b748e27..7ed1b243d9d 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyBuilder.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyBuilder.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyDescriptor.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyDescriptor.java
    index e640284f727..a5abed824a6 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyDescriptor.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyDescriptor.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java
    index d7466254f68..24dcc82fdba 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertySource.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertySource.java
    index 0e0bb08f797..c16d0e76d8f 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertySource.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertySource.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyTypeId.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyTypeId.java
    index 0b6f6f21849..08928569eb9 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyTypeId.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyTypeId.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/AbstractAccumulatingRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/AbstractAccumulatingRenderer.java
    index 9e66aa84773..9928da5e02a 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/AbstractAccumulatingRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/AbstractAccumulatingRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/AbstractIncrementingRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/AbstractIncrementingRenderer.java
    index f17c5cfd426..d964c0d9b5c 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/AbstractIncrementingRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/AbstractIncrementingRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/AbstractRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/AbstractRenderer.java
    index 29804ac1e37..c803ed68c63 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/AbstractRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/AbstractRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java
    index 85e869eced6..8092c5ac8ca 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVWriter.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVWriter.java
    index 572a82ca379..9048fbb079d 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVWriter.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVWriter.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateIssue.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateIssue.java
    index 519992e5a72..0ac57223d5e 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateIssue.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateIssue.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateRenderer.java
    index 2e892d9385e..f88741a3de4 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/ColumnDescriptor.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/ColumnDescriptor.java
    index 73af3f401ae..d9752c3537c 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/ColumnDescriptor.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/ColumnDescriptor.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/EmacsRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/EmacsRenderer.java
    index 2f1a144f0a7..23b7f2d36db 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/EmacsRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/EmacsRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/EmptyRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/EmptyRenderer.java
    index 6161d866048..c1ff02f9670 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/EmptyRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/EmptyRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/HTMLRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/HTMLRenderer.java
    index 016cc31f403..100df5babfc 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/HTMLRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/HTMLRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/IDEAJRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/IDEAJRenderer.java
    index fcfa274fde1..038d7bb3b7a 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/IDEAJRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/IDEAJRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/Renderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/Renderer.java
    index d88f4305093..9b21598f35b 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/Renderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/Renderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/RendererFactory.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/RendererFactory.java
    index cccd6b1d7be..8288be5cef9 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/RendererFactory.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/RendererFactory.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/SummaryHTMLRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/SummaryHTMLRenderer.java
    index b552af92d0e..c7d1076d483 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/SummaryHTMLRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/SummaryHTMLRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/TextColorRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/TextColorRenderer.java
    index 010a15170f2..fba63b165d5 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/TextColorRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/TextColorRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/TextPadRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/TextPadRenderer.java
    index 77ced0a1c4f..9805904d51a 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/TextPadRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/TextPadRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/TextRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/TextRenderer.java
    index 4e727c125cc..950c9448de0 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/TextRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/TextRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/VBHTMLRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/VBHTMLRenderer.java
    index 2d751aedb45..5864e9f010d 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/VBHTMLRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/VBHTMLRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/XMLRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/XMLRenderer.java
    index 3f600098386..6c78964c454 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/XMLRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/XMLRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/XSLTRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/XSLTRenderer.java
    index d505eb08eb3..6b72d360937 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/XSLTRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/XSLTRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/YAHTMLRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/YAHTMLRenderer.java
    index 03170d23ae4..b545d2a6c0b 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/YAHTMLRenderer.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/YAHTMLRenderer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ParametricRuleViolation.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ParametricRuleViolation.java
    index 5ca33eeadb0..c6a4328f6b3 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ParametricRuleViolation.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ParametricRuleViolation.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java
    index a86feb993e1..07647286ad4 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleViolation.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleViolation.java
    index 20da6f80f53..820fb4771c9 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleViolation.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleViolation.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java
    index de335c7a259..d9131a6a725 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/StringUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/StringUtil.java
    index 60ec003e578..e40a78e60e7 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/StringUtil.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/StringUtil.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/database/DBMSMetadata.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/database/DBMSMetadata.java
    index d2ab8ffa9df..7728ca00c82 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/database/DBMSMetadata.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/database/DBMSMetadata.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/database/DBType.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/database/DBType.java
    index c0bf035948c..916826b8daf 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/database/DBType.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/database/DBType.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/database/DBURI.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/database/DBURI.java
    index 1a5b2ac8564..1a06bf54820 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/database/DBURI.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/database/DBURI.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/database/ResourceLoader.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/database/ResourceLoader.java
    index 461c3f5f949..898eac6a0ea 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/database/ResourceLoader.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/database/ResourceLoader.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/database/ResourceResolver.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/database/ResourceResolver.java
    index 233157831bc..dda3e56f26d 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/database/ResourceResolver.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/database/ResourceResolver.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/database/SourceObject.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/database/SourceObject.java
    index 1e2112c3157..3c65e505f8a 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/database/SourceObject.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/database/SourceObject.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/internal/ResourceLoader.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/internal/ResourceLoader.java
    index 15dfa27989b..015b536b063 100644
    --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/internal/ResourceLoader.java
    +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/internal/ResourceLoader.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/AbstractRuleTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/AbstractRuleTest.java
    index 868f2e657a0..8c861065a86 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/AbstractRuleTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/AbstractRuleTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/FileSelectorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/FileSelectorTest.java
    index bb3b5ecf626..c5ded3d3114 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/FileSelectorTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/FileSelectorTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/FooRule.java b/pmd-core/src/test/java/net/sourceforge/pmd/FooRule.java
    index 3b3141baadb..c5a09a65705 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/FooRule.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/FooRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/PmdConfigurationTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/PmdConfigurationTest.java
    index 0424ee010b1..b65885869c6 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/PmdConfigurationTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/PmdConfigurationTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetSchemaTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetSchemaTest.java
    index 48e0ded0972..9c457cb8dc4 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetSchemaTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/RuleSetSchemaTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/RuleWithProperties.java b/pmd-core/src/test/java/net/sourceforge/pmd/RuleWithProperties.java
    index 37defeccc35..c0209716895 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/RuleWithProperties.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/RuleWithProperties.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cache/internal/AbstractClasspathEntryFingerprinterTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cache/internal/AbstractClasspathEntryFingerprinterTest.java
    index 4ba84186383..c387cb505ec 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/cache/internal/AbstractClasspathEntryFingerprinterTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cache/internal/AbstractClasspathEntryFingerprinterTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cache/internal/FileAnalysisCacheTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cache/internal/FileAnalysisCacheTest.java
    index 253abd19dd4..50a8f733327 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/cache/internal/FileAnalysisCacheTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cache/internal/FileAnalysisCacheTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cache/internal/RawFileFingerprinterTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cache/internal/RawFileFingerprinterTest.java
    index 31a5910e4c1..f249ff6ac15 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/cache/internal/RawFileFingerprinterTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cache/internal/RawFileFingerprinterTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cache/internal/ZipFileFingerprinterTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cache/internal/ZipFileFingerprinterTest.java
    index f9a829b17dc..b78abb7e02a 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/cache/internal/ZipFileFingerprinterTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cache/internal/ZipFileFingerprinterTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/AnyCpdLexerTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/AnyCpdLexerTest.java
    index d2ec5f54327..ae90a411d72 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/AnyCpdLexerTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/AnyCpdLexerTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDConfigurationTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDConfigurationTest.java
    index acb2dc8cfe4..3abd2b2562e 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDConfigurationTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDConfigurationTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDFilelistTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDFilelistTest.java
    index 355d169b89a..96cce4b7d72 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDFilelistTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDFilelistTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CSVRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CSVRendererTest.java
    index 8ee85e12e02..853fd45da50 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CSVRendererTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CSVRendererTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CpdAnalysisTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CpdAnalysisTest.java
    index f390e7c760a..18c455a41a3 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CpdAnalysisTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CpdAnalysisTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkTest.java
    index 09e84e1ad87..45359cd3af2 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MatchTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MatchTest.java
    index 1d6ba62c0fe..bcb5f6f1043 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MatchTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MatchTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/TokenEntryTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/TokenEntryTest.java
    index 247fe7eb9b3..a2977f278c6 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/TokenEntryTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/TokenEntryTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/XMLRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/XMLRendererTest.java
    index 05b511d0c0b..b1f69a0429e 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/XMLRendererTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/XMLRendererTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/CpdOnlyDummyLanguage.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/CpdOnlyDummyLanguage.java
    index 85f57d383fe..d02ef035c1c 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/CpdOnlyDummyLanguage.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/CpdOnlyDummyLanguage.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/Dummy2LanguageModule.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/Dummy2LanguageModule.java
    index 6b20bc93b2f..8a8056bfca4 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/Dummy2LanguageModule.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/Dummy2LanguageModule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageDialectModule.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageDialectModule.java
    index 380ec1356f9..870895491c9 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageDialectModule.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageDialectModule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java
    index 4138100bb8d..3e67afd1947 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageNoCapabilities.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageNoCapabilities.java
    index 2d2b347faad..e05a197c863 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageNoCapabilities.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageNoCapabilities.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/LanguageRegistryTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/LanguageRegistryTest.java
    index 4d4109ffa5e..e0d9fbb2004 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/LanguageRegistryTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/LanguageRegistryTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/LanguageVersionDiscovererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/LanguageVersionDiscovererTest.java
    index db639a1dbf5..f34d1a2ebba 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/LanguageVersionDiscovererTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/LanguageVersionDiscovererTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/BoundaryTraversalTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/BoundaryTraversalTest.java
    index e99324f2fdf..802ee580b1e 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/BoundaryTraversalTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/BoundaryTraversalTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyNode.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyNode.java
    index 627b9395a22..f921e0ab83c 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyNode.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyNode.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyNodeWithDeprecatedAttribute.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyNodeWithDeprecatedAttribute.java
    index 9a84d9997c9..b8713fb72ca 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyNodeWithDeprecatedAttribute.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/DummyNodeWithDeprecatedAttribute.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/FileCollectorZipTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/FileCollectorZipTest.java
    index 634e2859a11..136a152cdef 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/FileCollectorZipTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/FileCollectorZipTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/MultiThreadProcessorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/MultiThreadProcessorTest.java
    index 1fc72e45c99..598749eaeb0 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/MultiThreadProcessorTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/MultiThreadProcessorTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java
    index 4106fbe67e3..334147d5299 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBaseTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleReferenceTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleReferenceTest.java
    index 3114a6e4a32..7fa0b42718c 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleReferenceTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleReferenceTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleSetTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleSetTest.java
    index 03706c3d325..b566236ec53 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleSetTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleSetTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleSetWriterTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleSetWriterTest.java
    index 44a5dfa48bb..ac46efa4f8e 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleSetWriterTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleSetWriterTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/internal/RuleSetReferenceIdTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/internal/RuleSetReferenceIdTest.java
    index 3de2efd91db..cacd5be9e1e 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/internal/RuleSetReferenceIdTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/internal/RuleSetReferenceIdTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/symboltable/ApplierTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/symboltable/ApplierTest.java
    index 4f27b551706..6699ac73c50 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/symboltable/ApplierTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/symboltable/ApplierTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java
    index 89a8788ef29..35aa820e3f4 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/AbstractRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/AbstractRendererTest.java
    index 89110711601..698c726c591 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/AbstractRendererTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/AbstractRendererTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CSVRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CSVRendererTest.java
    index 644a3de23e4..d0e9aeac870 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CSVRendererTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CSVRendererTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CodeClimateRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CodeClimateRendererTest.java
    index 293daca9b38..ac632893045 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CodeClimateRendererTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CodeClimateRendererTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/EmacsRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/EmacsRendererTest.java
    index cb65d9fa17b..242b67051db 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/EmacsRendererTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/EmacsRendererTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/EmptyRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/EmptyRendererTest.java
    index 778c070b4ab..717a80c4c89 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/EmptyRendererTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/EmptyRendererTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/HTMLRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/HTMLRendererTest.java
    index 669faa13372..356ab4facb7 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/HTMLRendererTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/HTMLRendererTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/IDEAJRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/IDEAJRendererTest.java
    index 8a97b526950..d4ad6dec67d 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/IDEAJRendererTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/IDEAJRendererTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/RenderersTests.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/RenderersTests.java
    index 46443e82eb0..8b56f6436d6 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/RenderersTests.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/RenderersTests.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/SummaryHTMLRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/SummaryHTMLRendererTest.java
    index 28a91e9c834..529d10fa598 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/SummaryHTMLRendererTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/SummaryHTMLRendererTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/TextColorRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/TextColorRendererTest.java
    index 9514bbfc553..b3ff9679205 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/TextColorRendererTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/TextColorRendererTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/TextPadRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/TextPadRendererTest.java
    index d5b2dc0a261..60b1e8506fc 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/TextPadRendererTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/TextPadRendererTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/TextRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/TextRendererTest.java
    index 72c1d88c8d2..c248038981a 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/TextRendererTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/TextRendererTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/VBHTMLRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/VBHTMLRendererTest.java
    index e3f6f5155bd..302a4b60b35 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/VBHTMLRendererTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/VBHTMLRendererTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/XMLRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/XMLRendererTest.java
    index 287e2bbaa63..6580e8f5ae1 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/XMLRendererTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/XMLRendererTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/XSLTRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/XSLTRendererTest.java
    index 6bae1589c4b..02ee3b379e3 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/XSLTRendererTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/XSLTRendererTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/YAHTMLRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/YAHTMLRendererTest.java
    index 09c618807f4..329b0c3f8ed 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/YAHTMLRendererTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/YAHTMLRendererTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/reporting/RuleContextTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/reporting/RuleContextTest.java
    index 8cd42b37578..44dea32530a 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/reporting/RuleContextTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/reporting/RuleContextTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/reporting/RuleViolationComparatorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/reporting/RuleViolationComparatorTest.java
    index 8db1bdb9730..78fda80ddbd 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/reporting/RuleViolationComparatorTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/reporting/RuleViolationComparatorTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/reporting/RuleViolationTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/reporting/RuleViolationTest.java
    index bb8b7c88ca6..21fd321d6b7 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/reporting/RuleViolationTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/reporting/RuleViolationTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/util/StringUtilTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/util/StringUtilTest.java
    index 634607ba85f..d479eed8023 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/util/StringUtilTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/util/StringUtilTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/util/database/DBMSMetadataTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/util/database/DBMSMetadataTest.java
    index da516d08595..0b3fb07b706 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/util/database/DBMSMetadataTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/util/database/DBMSMetadataTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/util/database/DBTypeTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/util/database/DBTypeTest.java
    index efedd59518b..9d7d7a3a77d 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/util/database/DBTypeTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/util/database/DBTypeTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/util/database/DBURITest.java b/pmd-core/src/test/java/net/sourceforge/pmd/util/database/DBURITest.java
    index 6c0e37b0a2b..da4a1e4809b 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/util/database/DBURITest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/util/database/DBURITest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/util/database/ResourceLoaderTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/util/database/ResourceLoaderTest.java
    index 5e07493a20d..ab409fa7bf3 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/util/database/ResourceLoaderTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/util/database/ResourceLoaderTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/util/database/ResourceResolverTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/util/database/ResourceResolverTest.java
    index a46c32fe4b5..256e3a82bef 100644
    --- a/pmd-core/src/test/java/net/sourceforge/pmd/util/database/ResourceResolverTest.java
    +++ b/pmd-core/src/test/java/net/sourceforge/pmd/util/database/ResourceResolverTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/dup1.txt b/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/dup1.txt
    index 2fde07a30a4..6cbf664c733 100644
    --- a/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/dup1.txt
    +++ b/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/dup1.txt
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    @@ -15,4 +15,4 @@ public class dup1 {
             System.out.println("Test8");
             System.out.println("Test9");
         }
    -}
    \ No newline at end of file
    +}
    diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/dup2.txt b/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/dup2.txt
    index 91779c045b5..4117d624ab2 100644
    --- a/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/dup2.txt
    +++ b/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/dup2.txt
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    @@ -15,4 +15,4 @@ public class dup2 {
             System.out.println("Test8");
             System.out.println("Test9");
         }
    -}
    \ No newline at end of file
    +}
    
    From 4440e08dd39fb5e036f7cdaea1824aaa399b41f4 Mon Sep 17 00:00:00 2001
    From: Andreas Dangel 
    Date: Fri, 4 Jul 2025 09:31:25 +0200
    Subject: [PATCH 1088/1962] chore: pmd-ant: Update license header
    
    ---
     pmd-ant/src/main/java/net/sourceforge/pmd/ant/Formatter.java    | 2 +-
     .../src/main/java/net/sourceforge/pmd/ant/RuleSetWrapper.java   | 2 +-
     .../src/main/java/net/sourceforge/pmd/ant/SourceLanguage.java   | 2 +-
     .../main/java/net/sourceforge/pmd/ant/internal/PMDTaskImpl.java | 2 +-
     4 files changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/Formatter.java b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/Formatter.java
    index 159f19d7e1a..9022edb6a0b 100644
    --- a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/Formatter.java
    +++ b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/Formatter.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/RuleSetWrapper.java b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/RuleSetWrapper.java
    index 031ba15b21f..83d880ae212 100644
    --- a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/RuleSetWrapper.java
    +++ b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/RuleSetWrapper.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/SourceLanguage.java b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/SourceLanguage.java
    index c1c81aa12a8..2c339823de9 100644
    --- a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/SourceLanguage.java
    +++ b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/SourceLanguage.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/internal/PMDTaskImpl.java b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/internal/PMDTaskImpl.java
    index 5f5e1f9bd91..fc43d4976f7 100644
    --- a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/internal/PMDTaskImpl.java
    +++ b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/internal/PMDTaskImpl.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    
    From 3959c2cc8b377d10a62a0314726d285601501a26 Mon Sep 17 00:00:00 2001
    From: Andreas Dangel 
    Date: Fri, 4 Jul 2025 09:33:15 +0200
    Subject: [PATCH 1089/1962] chore: pmd-test: Update license header
    
    ---
     .../java/net/sourceforge/pmd/test/AbstractAntTestHelper.java    | 2 +-
     .../net/sourceforge/pmd/test/AbstractLanguageVersionTest.java   | 2 +-
     pmd-test/src/main/java/net/sourceforge/pmd/test/PmdRuleTst.java | 2 +-
     pmd-test/src/main/java/net/sourceforge/pmd/test/RuleTst.java    | 2 +-
     .../main/java/net/sourceforge/pmd/test/SimpleAggregatorTst.java | 2 +-
     .../pmd/test/lang/rule/AbstractRuleSetFactoryTest.java          | 2 +-
     .../src/test/java/net/sourceforge/pmd/test/RuleTstTest.java     | 2 +-
     7 files changed, 7 insertions(+), 7 deletions(-)
    
    diff --git a/pmd-test/src/main/java/net/sourceforge/pmd/test/AbstractAntTestHelper.java b/pmd-test/src/main/java/net/sourceforge/pmd/test/AbstractAntTestHelper.java
    index 3c822601e5c..901ad437b5c 100644
    --- a/pmd-test/src/main/java/net/sourceforge/pmd/test/AbstractAntTestHelper.java
    +++ b/pmd-test/src/main/java/net/sourceforge/pmd/test/AbstractAntTestHelper.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-test/src/main/java/net/sourceforge/pmd/test/AbstractLanguageVersionTest.java b/pmd-test/src/main/java/net/sourceforge/pmd/test/AbstractLanguageVersionTest.java
    index 54ec50a108d..55a3017ef58 100644
    --- a/pmd-test/src/main/java/net/sourceforge/pmd/test/AbstractLanguageVersionTest.java
    +++ b/pmd-test/src/main/java/net/sourceforge/pmd/test/AbstractLanguageVersionTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-test/src/main/java/net/sourceforge/pmd/test/PmdRuleTst.java b/pmd-test/src/main/java/net/sourceforge/pmd/test/PmdRuleTst.java
    index 0e7764693bd..bc36f6d232f 100644
    --- a/pmd-test/src/main/java/net/sourceforge/pmd/test/PmdRuleTst.java
    +++ b/pmd-test/src/main/java/net/sourceforge/pmd/test/PmdRuleTst.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-test/src/main/java/net/sourceforge/pmd/test/RuleTst.java b/pmd-test/src/main/java/net/sourceforge/pmd/test/RuleTst.java
    index 40f4f34225d..6b1e58fecc7 100644
    --- a/pmd-test/src/main/java/net/sourceforge/pmd/test/RuleTst.java
    +++ b/pmd-test/src/main/java/net/sourceforge/pmd/test/RuleTst.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-test/src/main/java/net/sourceforge/pmd/test/SimpleAggregatorTst.java b/pmd-test/src/main/java/net/sourceforge/pmd/test/SimpleAggregatorTst.java
    index db2e3f8daa7..2481ab62617 100644
    --- a/pmd-test/src/main/java/net/sourceforge/pmd/test/SimpleAggregatorTst.java
    +++ b/pmd-test/src/main/java/net/sourceforge/pmd/test/SimpleAggregatorTst.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java b/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java
    index d9118bb40d3..93fa3d24222 100644
    --- a/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java
    +++ b/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-test/src/test/java/net/sourceforge/pmd/test/RuleTstTest.java b/pmd-test/src/test/java/net/sourceforge/pmd/test/RuleTstTest.java
    index 831183ef7d5..0822f36f975 100644
    --- a/pmd-test/src/test/java/net/sourceforge/pmd/test/RuleTstTest.java
    +++ b/pmd-test/src/test/java/net/sourceforge/pmd/test/RuleTstTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    
    From 5cb022dc6978643bf69f2dddcda136b2556b29af Mon Sep 17 00:00:00 2001
    From: Andreas Dangel 
    Date: Fri, 4 Jul 2025 09:40:53 +0200
    Subject: [PATCH 1090/1962] chore: pmd-apex: Update license header
    
    ---
     .../java/net/sourceforge/pmd/lang/apex/ApexLanguageHandler.java | 2 +-
     .../java/net/sourceforge/pmd/lang/apex/ApexLanguageModule.java  | 2 +-
     .../net/sourceforge/pmd/lang/apex/ApexLanguageProcessor.java    | 2 +-
     .../java/net/sourceforge/pmd/lang/apex/ast/ASTApexFile.java     | 2 +-
     .../net/sourceforge/pmd/lang/apex/ast/AssignmentOperator.java   | 2 +-
     .../java/net/sourceforge/pmd/lang/apex/ast/BinaryOperator.java  | 2 +-
     .../java/net/sourceforge/pmd/lang/apex/ast/BooleanOperator.java | 2 +-
     .../java/net/sourceforge/pmd/lang/apex/ast/PostfixOperator.java | 2 +-
     .../java/net/sourceforge/pmd/lang/apex/ast/PrefixOperator.java  | 2 +-
     .../pmd/lang/apex/multifile/ApexMultifileAnalysis.java          | 2 +-
     .../bestpractices/ApexAssertionsShouldIncludeMessageRule.java   | 2 +-
     .../bestpractices/ApexUnitTestClassShouldHaveAssertsRule.java   | 2 +-
     .../bestpractices/ApexUnitTestClassShouldHaveRunAsRule.java     | 2 +-
     .../ApexUnitTestShouldNotUseSeeAllDataTrueRule.java             | 2 +-
     .../lang/apex/rule/bestpractices/AvoidGlobalModifierRule.java   | 2 +-
     .../lang/apex/rule/bestpractices/AvoidLogicInTriggerRule.java   | 2 +-
     .../lang/apex/rule/codestyle/AbstractNamingConventionsRule.java | 2 +-
     .../lang/apex/rule/codestyle/ClassNamingConventionsRule.java    | 2 +-
     .../rule/codestyle/FieldDeclarationsShouldBeAtStartRule.java    | 2 +-
     .../lang/apex/rule/codestyle/FieldNamingConventionsRule.java    | 2 +-
     .../rule/codestyle/FormalParameterNamingConventionsRule.java    | 2 +-
     .../apex/rule/codestyle/LocalVariableNamingConventionsRule.java | 2 +-
     .../lang/apex/rule/codestyle/MethodNamingConventionsRule.java   | 2 +-
     .../lang/apex/rule/codestyle/PropertyNamingConventionsRule.java | 2 +-
     .../lang/apex/rule/design/AvoidBooleanMethodParametersRule.java | 2 +-
     .../pmd/lang/apex/rule/design/AvoidDeeplyNestedIfStmtsRule.java | 2 +-
     .../pmd/lang/apex/rule/design/CognitiveComplexityRule.java      | 2 +-
     .../pmd/lang/apex/rule/design/CyclomaticComplexityRule.java     | 2 +-
     .../pmd/lang/apex/rule/design/ExcessiveClassLengthRule.java     | 2 +-
     .../pmd/lang/apex/rule/design/ExcessiveParameterListRule.java   | 2 +-
     .../pmd/lang/apex/rule/design/ExcessivePublicCountRule.java     | 2 +-
     .../pmd/lang/apex/rule/design/NcssConstructorCountRule.java     | 2 +-
     .../pmd/lang/apex/rule/design/NcssMethodCountRule.java          | 2 +-
     .../pmd/lang/apex/rule/design/NcssTypeCountRule.java            | 2 +-
     .../pmd/lang/apex/rule/design/StdCyclomaticComplexityRule.java  | 2 +-
     .../pmd/lang/apex/rule/design/TooManyFieldsRule.java            | 2 +-
     .../sourceforge/pmd/lang/apex/rule/design/UnusedMethodRule.java | 2 +-
     .../pmd/lang/apex/rule/documentation/ApexDocRule.java           | 2 +-
     .../sourceforge/pmd/lang/apex/rule/errorprone/ApexCSRFRule.java | 2 +-
     .../pmd/lang/apex/rule/errorprone/AvoidHardcodingIdRule.java    | 2 +-
     .../apex/rule/errorprone/AvoidNonExistentAnnotationsRule.java   | 2 +-
     .../apex/rule/errorprone/InaccessibleAuraEnabledGetterRule.java | 2 +-
     .../rule/errorprone/MethodWithSameNameAsEnclosingClassRule.java | 2 +-
     .../net/sourceforge/pmd/lang/apex/rule/internal/Helper.java     | 2 +-
     .../apex/rule/performance/AbstractAvoidNodeInLoopsRule.java     | 2 +-
     .../apex/rule/performance/OperationWithHighCostInLoopRule.java  | 2 +-
     .../apex/rule/performance/OperationWithLimitsInLoopRule.java    | 2 +-
     .../pmd/lang/apex/rule/security/ApexBadCryptoRule.java          | 2 +-
     .../pmd/lang/apex/rule/security/ApexCRUDViolationRule.java      | 2 +-
     .../pmd/lang/apex/rule/security/ApexDangerousMethodsRule.java   | 2 +-
     .../pmd/lang/apex/rule/security/ApexInsecureEndpointRule.java   | 2 +-
     .../pmd/lang/apex/rule/security/ApexOpenRedirectRule.java       | 2 +-
     .../pmd/lang/apex/rule/security/ApexSOQLInjectionRule.java      | 2 +-
     .../pmd/lang/apex/rule/security/ApexSharingViolationsRule.java  | 2 +-
     .../lang/apex/rule/security/ApexSuggestUsingNamedCredRule.java  | 2 +-
     .../pmd/lang/apex/rule/security/ApexXSSFromEscapeFalseRule.java | 2 +-
     .../pmd/lang/apex/rule/security/ApexXSSFromURLParamRule.java    | 2 +-
     .../src/test/java/net/sourceforge/pmd/lang/apex/FooRule.java    | 2 +-
     .../java/net/sourceforge/pmd/lang/apex/LanguageVersionTest.java | 2 +-
     .../net/sourceforge/pmd/lang/apex/QuickstartRulesetTest.java    | 2 +-
     .../java/net/sourceforge/pmd/lang/apex/RuleSetFactoryTest.java  | 2 +-
     .../net/sourceforge/pmd/lang/apex/SuppressWarningsTest.java     | 2 +-
     .../java/net/sourceforge/pmd/lang/apex/ast/ASTFieldTest.java    | 2 +-
     .../pmd/lang/apex/ast/ASTNewKeyValueObjectExpressionTest.java   | 2 +-
     .../net/sourceforge/pmd/lang/apex/ast/ASTUserClassTest.java     | 2 +-
     .../java/net/sourceforge/pmd/lang/apex/ast/ASTUserEnumTest.java | 2 +-
     .../net/sourceforge/pmd/lang/apex/ast/ASTUserInterfaceTest.java | 2 +-
     .../net/sourceforge/pmd/lang/apex/ast/ASTUserTriggerTest.java   | 2 +-
     .../java/net/sourceforge/pmd/lang/apex/ast/ApexCommentTest.java | 2 +-
     .../net/sourceforge/pmd/lang/apex/ast/ApexCompilerSoqlTest.java | 2 +-
     .../net/sourceforge/pmd/lang/apex/ast/ApexCompilerTest.java     | 2 +-
     .../java/net/sourceforge/pmd/lang/apex/ast/ApexLexerTest.java   | 2 +-
     .../java/net/sourceforge/pmd/lang/apex/ast/ApexParserTest.java  | 2 +-
     .../net/sourceforge/pmd/lang/apex/ast/ApexParsingHelper.java    | 2 +-
     .../sourceforge/pmd/lang/apex/ast/ApexQualifiedNameTest.java    | 2 +-
     .../pmd/lang/apex/metrics/internal/AllMetricsTest.java          | 2 +-
     .../lang/apex/metrics/internal/CognitiveComplexityTestRule.java | 2 +-
     .../pmd/lang/apex/metrics/internal/CycloTestRule.java           | 2 +-
     .../sourceforge/pmd/lang/apex/metrics/internal/WmcTestRule.java | 2 +-
     .../bestpractices/ApexAssertionsShouldIncludeMessageTest.java   | 2 +-
     .../bestpractices/ApexUnitTestClassShouldHaveAssertsTest.java   | 2 +-
     .../bestpractices/ApexUnitTestClassShouldHaveRunAsTest.java     | 2 +-
     .../ApexUnitTestMethodShouldHaveIsTestAnnotationTest.java       | 2 +-
     .../ApexUnitTestShouldNotUseSeeAllDataTrueTest.java             | 2 +-
     .../lang/apex/rule/bestpractices/AvoidGlobalModifierTest.java   | 2 +-
     .../lang/apex/rule/bestpractices/AvoidLogicInTriggerTest.java   | 2 +-
     .../lang/apex/rule/codestyle/ClassNamingConventionsTest.java    | 2 +-
     .../rule/codestyle/FieldDeclarationsShouldBeAtStartTest.java    | 2 +-
     .../lang/apex/rule/codestyle/FieldNamingConventionsTest.java    | 2 +-
     .../pmd/lang/apex/rule/codestyle/ForLoopsMustUseBracesTest.java | 2 +-
     .../rule/codestyle/FormalParameterNamingConventionsTest.java    | 2 +-
     .../lang/apex/rule/codestyle/IfElseStmtsMustUseBracesTest.java  | 2 +-
     .../pmd/lang/apex/rule/codestyle/IfStmtsMustUseBracesTest.java  | 2 +-
     .../apex/rule/codestyle/LocalVariableNamingConventionsTest.java | 2 +-
     .../lang/apex/rule/codestyle/MethodNamingConventionsTest.java   | 2 +-
     .../pmd/lang/apex/rule/codestyle/OneDeclarationPerLineTest.java | 2 +-
     .../lang/apex/rule/codestyle/PropertyNamingConventionsTest.java | 2 +-
     .../lang/apex/rule/codestyle/WhileLoopsMustUseBracesTest.java   | 2 +-
     .../lang/apex/rule/design/AvoidBooleanMethodParametersTest.java | 2 +-
     .../pmd/lang/apex/rule/design/AvoidDeeplyNestedIfStmtsTest.java | 2 +-
     .../pmd/lang/apex/rule/design/CyclomaticComplexityTest.java     | 2 +-
     .../pmd/lang/apex/rule/design/ExcessiveClassLengthTest.java     | 2 +-
     .../pmd/lang/apex/rule/design/ExcessiveParameterListTest.java   | 2 +-
     .../pmd/lang/apex/rule/design/ExcessivePublicCountTest.java     | 2 +-
     .../pmd/lang/apex/rule/design/NcssConstructorCountTest.java     | 2 +-
     .../pmd/lang/apex/rule/design/NcssMethodCountTest.java          | 2 +-
     .../pmd/lang/apex/rule/design/NcssTypeCountTest.java            | 2 +-
     .../pmd/lang/apex/rule/design/StdCyclomaticComplexityTest.java  | 2 +-
     .../pmd/lang/apex/rule/design/TooManyFieldsTest.java            | 2 +-
     .../pmd/lang/apex/rule/documentation/ApexDocTest.java           | 2 +-
     .../sourceforge/pmd/lang/apex/rule/errorprone/ApexCSRFTest.java | 2 +-
     .../apex/rule/errorprone/AvoidDirectAccessTriggerMapTest.java   | 2 +-
     .../pmd/lang/apex/rule/errorprone/AvoidHardcodingIdTest.java    | 2 +-
     .../apex/rule/errorprone/AvoidNonExistentAnnotationsTest.java   | 2 +-
     .../pmd/lang/apex/rule/errorprone/EmptyCatchBlockTest.java      | 2 +-
     .../pmd/lang/apex/rule/errorprone/EmptyIfStmtTest.java          | 2 +-
     .../pmd/lang/apex/rule/errorprone/EmptyStatementBlockTest.java  | 2 +-
     .../lang/apex/rule/errorprone/EmptyTryOrFinallyBlockTest.java   | 2 +-
     .../pmd/lang/apex/rule/errorprone/EmptyWhileStmtTest.java       | 2 +-
     .../apex/rule/errorprone/InaccessibleAuraEnabledGetterTest.java | 2 +-
     .../rule/errorprone/MethodWithSameNameAsEnclosingClassTest.java | 2 +-
     .../apex/rule/errorprone/OverrideBothEqualsAndHashcodeTest.java | 2 +-
     .../rule/errorprone/TestMethodsMustBeInTestClassesTest.java     | 2 +-
     .../apex/rule/errorprone/TypeShadowsBuiltInNamespaceTest.java   | 2 +-
     .../performance/EagerlyLoadedDescribeSObjectResultTest.java     | 2 +-
     .../apex/rule/performance/OperationWithHighCostInLoopTest.java  | 2 +-
     .../apex/rule/performance/OperationWithLimitsInLoopTest.java    | 2 +-
     .../pmd/lang/apex/rule/security/ApexBadCryptoTest.java          | 2 +-
     .../pmd/lang/apex/rule/security/ApexCRUDViolationTest.java      | 2 +-
     .../pmd/lang/apex/rule/security/ApexDangerousMethodsTest.java   | 2 +-
     .../pmd/lang/apex/rule/security/ApexInsecureEndpointTest.java   | 2 +-
     .../pmd/lang/apex/rule/security/ApexOpenRedirectTest.java       | 2 +-
     .../pmd/lang/apex/rule/security/ApexSOQLInjectionTest.java      | 2 +-
     .../rule/security/ApexSharingViolationsNestedClassTest.java     | 2 +-
     .../pmd/lang/apex/rule/security/ApexSharingViolationsTest.java  | 2 +-
     .../lang/apex/rule/security/ApexSuggestUsingNamedCredTest.java  | 2 +-
     .../pmd/lang/apex/rule/security/ApexXSSFromEscapeFalseTest.java | 2 +-
     .../pmd/lang/apex/rule/security/ApexXSSFromURLParamTest.java    | 2 +-
     138 files changed, 138 insertions(+), 138 deletions(-)
    
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexLanguageHandler.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexLanguageHandler.java
    index f2a3be5e5ae..cf4ef96cb7e 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexLanguageHandler.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexLanguageHandler.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexLanguageModule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexLanguageModule.java
    index 66bb88c9340..b90b7b430f8 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexLanguageModule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexLanguageModule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexLanguageProcessor.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexLanguageProcessor.java
    index ca626f0976f..9836cdae149 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexLanguageProcessor.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexLanguageProcessor.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTApexFile.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTApexFile.java
    index a95d4d9b7a9..217b49e250b 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTApexFile.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTApexFile.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/AssignmentOperator.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/AssignmentOperator.java
    index 1a7a5b71e04..51cfc9e9f8e 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/AssignmentOperator.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/AssignmentOperator.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/BinaryOperator.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/BinaryOperator.java
    index bc4b96cfa60..8b9a4b809c5 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/BinaryOperator.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/BinaryOperator.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/BooleanOperator.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/BooleanOperator.java
    index fa5378b3de7..827466c50dc 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/BooleanOperator.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/BooleanOperator.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/PostfixOperator.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/PostfixOperator.java
    index 7582b17fa5c..bae52aedd9b 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/PostfixOperator.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/PostfixOperator.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/PrefixOperator.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/PrefixOperator.java
    index dbb92491e0c..7f33ff5733e 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/PrefixOperator.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/PrefixOperator.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/ApexMultifileAnalysis.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/ApexMultifileAnalysis.java
    index 4a7acb921b8..2f2ebd5590d 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/ApexMultifileAnalysis.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/ApexMultifileAnalysis.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexAssertionsShouldIncludeMessageRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexAssertionsShouldIncludeMessageRule.java
    index bed4a82a8fb..dd2a9ab0e37 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexAssertionsShouldIncludeMessageRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexAssertionsShouldIncludeMessageRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestClassShouldHaveAssertsRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestClassShouldHaveAssertsRule.java
    index 7b95fc17e2a..c2446e1e9d1 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestClassShouldHaveAssertsRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestClassShouldHaveAssertsRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestClassShouldHaveRunAsRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestClassShouldHaveRunAsRule.java
    index 2f2bfd1a51c..c51816b26fc 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestClassShouldHaveRunAsRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestClassShouldHaveRunAsRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestShouldNotUseSeeAllDataTrueRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestShouldNotUseSeeAllDataTrueRule.java
    index c5a5912a134..c85f6d019d5 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestShouldNotUseSeeAllDataTrueRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestShouldNotUseSeeAllDataTrueRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/AvoidGlobalModifierRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/AvoidGlobalModifierRule.java
    index 59abdd90b34..658b5120068 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/AvoidGlobalModifierRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/AvoidGlobalModifierRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/AvoidLogicInTriggerRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/AvoidLogicInTriggerRule.java
    index 6974d9f59ae..0e1b85b2900 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/AvoidLogicInTriggerRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/AvoidLogicInTriggerRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/AbstractNamingConventionsRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/AbstractNamingConventionsRule.java
    index eb6120289e1..2dffb293dcb 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/AbstractNamingConventionsRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/AbstractNamingConventionsRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/ClassNamingConventionsRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/ClassNamingConventionsRule.java
    index 508650adbcc..ec55494a564 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/ClassNamingConventionsRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/ClassNamingConventionsRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldDeclarationsShouldBeAtStartRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldDeclarationsShouldBeAtStartRule.java
    index d9d9e429166..4f9863f62b0 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldDeclarationsShouldBeAtStartRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldDeclarationsShouldBeAtStartRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldNamingConventionsRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldNamingConventionsRule.java
    index 01b77d87b21..5d562ad5530 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldNamingConventionsRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldNamingConventionsRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FormalParameterNamingConventionsRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FormalParameterNamingConventionsRule.java
    index 10bc064bb4f..44faf99ada1 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FormalParameterNamingConventionsRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FormalParameterNamingConventionsRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/LocalVariableNamingConventionsRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/LocalVariableNamingConventionsRule.java
    index c3a85971d57..35b5c176b00 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/LocalVariableNamingConventionsRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/LocalVariableNamingConventionsRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/MethodNamingConventionsRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/MethodNamingConventionsRule.java
    index de3ae0a330e..f6bd6492776 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/MethodNamingConventionsRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/MethodNamingConventionsRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/PropertyNamingConventionsRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/PropertyNamingConventionsRule.java
    index b65850ae543..11af35f5dd6 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/PropertyNamingConventionsRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/PropertyNamingConventionsRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidBooleanMethodParametersRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidBooleanMethodParametersRule.java
    index 6512bc8675e..b3d9323b703 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidBooleanMethodParametersRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidBooleanMethodParametersRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidDeeplyNestedIfStmtsRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidDeeplyNestedIfStmtsRule.java
    index a462a6b387b..37394576fc6 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidDeeplyNestedIfStmtsRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidDeeplyNestedIfStmtsRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/CognitiveComplexityRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/CognitiveComplexityRule.java
    index 28a2110917d..df619c3a2e6 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/CognitiveComplexityRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/CognitiveComplexityRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/CyclomaticComplexityRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/CyclomaticComplexityRule.java
    index e1af8663df7..1da80e59ec5 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/CyclomaticComplexityRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/CyclomaticComplexityRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveClassLengthRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveClassLengthRule.java
    index 73d6e06c922..ea95460f9c3 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveClassLengthRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveClassLengthRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveParameterListRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveParameterListRule.java
    index fa5220151d4..2b1dd82bf44 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveParameterListRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveParameterListRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountRule.java
    index 5be01a62c67..af61e66df31 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssConstructorCountRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssConstructorCountRule.java
    index 44cbc9c3814..6d22f9bc2d8 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssConstructorCountRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssConstructorCountRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountRule.java
    index 2891dc92353..d4f54677bb9 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssTypeCountRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssTypeCountRule.java
    index f534a140fed..62a1d585e0d 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssTypeCountRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssTypeCountRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/StdCyclomaticComplexityRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/StdCyclomaticComplexityRule.java
    index 076ba77a0a1..fc9d1216397 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/StdCyclomaticComplexityRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/StdCyclomaticComplexityRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/TooManyFieldsRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/TooManyFieldsRule.java
    index 8500fa22e11..39d7528148c 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/TooManyFieldsRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/TooManyFieldsRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/UnusedMethodRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/UnusedMethodRule.java
    index e912f343f6e..ceddddd93c2 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/UnusedMethodRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/UnusedMethodRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/documentation/ApexDocRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/documentation/ApexDocRule.java
    index dc926065f8c..e1ffea4a748 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/documentation/ApexDocRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/documentation/ApexDocRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/ApexCSRFRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/ApexCSRFRule.java
    index cb8d095fc11..6e2b640f0ee 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/ApexCSRFRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/ApexCSRFRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidHardcodingIdRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidHardcodingIdRule.java
    index 38062083476..74e2643dc48 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidHardcodingIdRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidHardcodingIdRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidNonExistentAnnotationsRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidNonExistentAnnotationsRule.java
    index dbd3be2e707..efd14a580bf 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidNonExistentAnnotationsRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidNonExistentAnnotationsRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/InaccessibleAuraEnabledGetterRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/InaccessibleAuraEnabledGetterRule.java
    index d6978f66190..dcac7336b96 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/InaccessibleAuraEnabledGetterRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/InaccessibleAuraEnabledGetterRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/MethodWithSameNameAsEnclosingClassRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/MethodWithSameNameAsEnclosingClassRule.java
    index aa30b268bef..be3024deba4 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/MethodWithSameNameAsEnclosingClassRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/errorprone/MethodWithSameNameAsEnclosingClassRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/internal/Helper.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/internal/Helper.java
    index de284ef7502..992bddd8de2 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/internal/Helper.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/internal/Helper.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/performance/AbstractAvoidNodeInLoopsRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/performance/AbstractAvoidNodeInLoopsRule.java
    index 5606082e4a1..4f628b9f636 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/performance/AbstractAvoidNodeInLoopsRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/performance/AbstractAvoidNodeInLoopsRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/performance/OperationWithHighCostInLoopRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/performance/OperationWithHighCostInLoopRule.java
    index ee2a7ef06cc..5a4bb29b8b3 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/performance/OperationWithHighCostInLoopRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/performance/OperationWithHighCostInLoopRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/performance/OperationWithLimitsInLoopRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/performance/OperationWithLimitsInLoopRule.java
    index bd440e4013a..a1cb6f6be6c 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/performance/OperationWithLimitsInLoopRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/performance/OperationWithLimitsInLoopRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexBadCryptoRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexBadCryptoRule.java
    index a3ffbaa4808..6ead998e978 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexBadCryptoRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexBadCryptoRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexCRUDViolationRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexCRUDViolationRule.java
    index 8b39e0d7ca2..34ad5ddc00e 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexCRUDViolationRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexCRUDViolationRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexDangerousMethodsRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexDangerousMethodsRule.java
    index 5fdba1d5c81..180b87ed227 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexDangerousMethodsRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexDangerousMethodsRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexInsecureEndpointRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexInsecureEndpointRule.java
    index f107bce6fcc..0aa82401541 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexInsecureEndpointRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexInsecureEndpointRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexOpenRedirectRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexOpenRedirectRule.java
    index 25a1872bda8..abd64ae21c5 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexOpenRedirectRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexOpenRedirectRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSOQLInjectionRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSOQLInjectionRule.java
    index e7de58c97e9..13fd6b00d1f 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSOQLInjectionRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSOQLInjectionRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSharingViolationsRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSharingViolationsRule.java
    index a4bb420ef41..d33f72213ff 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSharingViolationsRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSharingViolationsRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSuggestUsingNamedCredRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSuggestUsingNamedCredRule.java
    index f2af171e819..43d07f98714 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSuggestUsingNamedCredRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSuggestUsingNamedCredRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexXSSFromEscapeFalseRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexXSSFromEscapeFalseRule.java
    index 1002bc08fdf..be15c77e551 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexXSSFromEscapeFalseRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexXSSFromEscapeFalseRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexXSSFromURLParamRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexXSSFromURLParamRule.java
    index 1fdb805a26f..494553e1c3d 100644
    --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexXSSFromURLParamRule.java
    +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexXSSFromURLParamRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/FooRule.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/FooRule.java
    index a5ac08be285..bf145615b4b 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/FooRule.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/FooRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/LanguageVersionTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/LanguageVersionTest.java
    index 622f358037f..21e678edbb4 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/LanguageVersionTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/LanguageVersionTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/QuickstartRulesetTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/QuickstartRulesetTest.java
    index dcde511529d..1c443e7785a 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/QuickstartRulesetTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/QuickstartRulesetTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/RuleSetFactoryTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/RuleSetFactoryTest.java
    index 2017f895c2d..a8b9b34e09e 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/RuleSetFactoryTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/RuleSetFactoryTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/SuppressWarningsTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/SuppressWarningsTest.java
    index 2fea34a088a..9366c75f538 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/SuppressWarningsTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/SuppressWarningsTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTFieldTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTFieldTest.java
    index 6c4797a7b68..63cffcafdb7 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTFieldTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTFieldTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTNewKeyValueObjectExpressionTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTNewKeyValueObjectExpressionTest.java
    index 83751e6648d..611f9430a88 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTNewKeyValueObjectExpressionTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTNewKeyValueObjectExpressionTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserClassTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserClassTest.java
    index 97120ce364b..afe6dec4d79 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserClassTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserClassTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserEnumTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserEnumTest.java
    index 406177cc707..0bb0f87f6ee 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserEnumTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserEnumTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserInterfaceTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserInterfaceTest.java
    index 1786022e8aa..38966d82f6e 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserInterfaceTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserInterfaceTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserTriggerTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserTriggerTest.java
    index f995c95e8bd..6747c9edb43 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserTriggerTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ASTUserTriggerTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexCommentTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexCommentTest.java
    index 6e847170bfe..c9e4db0b479 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexCommentTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexCommentTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexCompilerSoqlTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexCompilerSoqlTest.java
    index e585078d7fd..a6996c6396f 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexCompilerSoqlTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexCompilerSoqlTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexCompilerTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexCompilerTest.java
    index 107da7d444e..ad7915a75e1 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexCompilerTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexCompilerTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexLexerTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexLexerTest.java
    index 0d456d29559..1e6e9f9c195 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexLexerTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexLexerTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParserTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParserTest.java
    index ede06c79afe..01245574772 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParserTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParserTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParsingHelper.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParsingHelper.java
    index 5761140413c..ff031c6ea49 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParsingHelper.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexParsingHelper.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexQualifiedNameTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexQualifiedNameTest.java
    index bfe0af7510b..a7f57b32484 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexQualifiedNameTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexQualifiedNameTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/AllMetricsTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/AllMetricsTest.java
    index f3d9d791edd..0f8c4c2c8ca 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/AllMetricsTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/AllMetricsTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/CognitiveComplexityTestRule.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/CognitiveComplexityTestRule.java
    index dcfd7fb034b..391c1f554ee 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/CognitiveComplexityTestRule.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/CognitiveComplexityTestRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/CycloTestRule.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/CycloTestRule.java
    index 447ff4dfb3c..82a002c6fc1 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/CycloTestRule.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/CycloTestRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/WmcTestRule.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/WmcTestRule.java
    index ebda680adc5..fabe84cbb62 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/WmcTestRule.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/WmcTestRule.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexAssertionsShouldIncludeMessageTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexAssertionsShouldIncludeMessageTest.java
    index 4bf289fe695..bd3d55214b4 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexAssertionsShouldIncludeMessageTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexAssertionsShouldIncludeMessageTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestClassShouldHaveAssertsTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestClassShouldHaveAssertsTest.java
    index 5fbb7c8c264..f62e7dbaafb 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestClassShouldHaveAssertsTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestClassShouldHaveAssertsTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestClassShouldHaveRunAsTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestClassShouldHaveRunAsTest.java
    index cb4d8c5141c..53d92db18b0 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestClassShouldHaveRunAsTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestClassShouldHaveRunAsTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestMethodShouldHaveIsTestAnnotationTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestMethodShouldHaveIsTestAnnotationTest.java
    index 5917436c6c5..9292971239a 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestMethodShouldHaveIsTestAnnotationTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestMethodShouldHaveIsTestAnnotationTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestShouldNotUseSeeAllDataTrueTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestShouldNotUseSeeAllDataTrueTest.java
    index 5485453809c..cbbca2b7e61 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestShouldNotUseSeeAllDataTrueTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestShouldNotUseSeeAllDataTrueTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/AvoidGlobalModifierTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/AvoidGlobalModifierTest.java
    index 9b6143c8802..41fdb0a199a 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/AvoidGlobalModifierTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/AvoidGlobalModifierTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/AvoidLogicInTriggerTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/AvoidLogicInTriggerTest.java
    index e95f227e072..65371b79f64 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/AvoidLogicInTriggerTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/AvoidLogicInTriggerTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/ClassNamingConventionsTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/ClassNamingConventionsTest.java
    index 3da177d181c..368f048930e 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/ClassNamingConventionsTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/ClassNamingConventionsTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldDeclarationsShouldBeAtStartTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldDeclarationsShouldBeAtStartTest.java
    index 1ad6d892b6e..5d76b0cafcb 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldDeclarationsShouldBeAtStartTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldDeclarationsShouldBeAtStartTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldNamingConventionsTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldNamingConventionsTest.java
    index b2e251df952..ac419c8835d 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldNamingConventionsTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldNamingConventionsTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/ForLoopsMustUseBracesTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/ForLoopsMustUseBracesTest.java
    index b884764b704..7972d1906b4 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/ForLoopsMustUseBracesTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/ForLoopsMustUseBracesTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FormalParameterNamingConventionsTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FormalParameterNamingConventionsTest.java
    index 3642c8c0a08..16d356c8a4d 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FormalParameterNamingConventionsTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FormalParameterNamingConventionsTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/IfElseStmtsMustUseBracesTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/IfElseStmtsMustUseBracesTest.java
    index 7331b729a27..7d3c8866976 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/IfElseStmtsMustUseBracesTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/IfElseStmtsMustUseBracesTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/IfStmtsMustUseBracesTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/IfStmtsMustUseBracesTest.java
    index e405118d3b0..d0e9a5d106f 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/IfStmtsMustUseBracesTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/IfStmtsMustUseBracesTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/LocalVariableNamingConventionsTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/LocalVariableNamingConventionsTest.java
    index 0c428f5c6c7..fd1b08cc4a4 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/LocalVariableNamingConventionsTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/LocalVariableNamingConventionsTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/MethodNamingConventionsTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/MethodNamingConventionsTest.java
    index a62c323436f..b614d2b44ff 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/MethodNamingConventionsTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/MethodNamingConventionsTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/OneDeclarationPerLineTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/OneDeclarationPerLineTest.java
    index 7a6385bb8bb..4876e5419e1 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/OneDeclarationPerLineTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/OneDeclarationPerLineTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/PropertyNamingConventionsTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/PropertyNamingConventionsTest.java
    index 96c1d7fa948..f41ab828f8a 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/PropertyNamingConventionsTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/PropertyNamingConventionsTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/WhileLoopsMustUseBracesTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/WhileLoopsMustUseBracesTest.java
    index 2246058de99..184220d8898 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/WhileLoopsMustUseBracesTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/WhileLoopsMustUseBracesTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidBooleanMethodParametersTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidBooleanMethodParametersTest.java
    index 5bece8fcc9b..83893086357 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidBooleanMethodParametersTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidBooleanMethodParametersTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidDeeplyNestedIfStmtsTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidDeeplyNestedIfStmtsTest.java
    index bd2541ea5a8..985f527b495 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidDeeplyNestedIfStmtsTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/AvoidDeeplyNestedIfStmtsTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/CyclomaticComplexityTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/CyclomaticComplexityTest.java
    index b55778bce92..6969a25035c 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/CyclomaticComplexityTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/CyclomaticComplexityTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveClassLengthTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveClassLengthTest.java
    index beb8138b8ae..f988c628f46 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveClassLengthTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveClassLengthTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveParameterListTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveParameterListTest.java
    index 178f7e1255a..c33c9b956b1 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveParameterListTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveParameterListTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountTest.java
    index e2eae7a804e..5056077f78e 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssConstructorCountTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssConstructorCountTest.java
    index 70bb6b81b0d..a6168f0f90b 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssConstructorCountTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssConstructorCountTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountTest.java
    index a334a639e7e..c019fc10acb 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssTypeCountTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssTypeCountTest.java
    index a1147606c67..463d797e57f 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssTypeCountTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssTypeCountTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/StdCyclomaticComplexityTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/StdCyclomaticComplexityTest.java
    index 686a99fb1ab..f2babd571c3 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/StdCyclomaticComplexityTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/StdCyclomaticComplexityTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/TooManyFieldsTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/TooManyFieldsTest.java
    index 27dd2cc5529..20d26731ed2 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/TooManyFieldsTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/TooManyFieldsTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/documentation/ApexDocTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/documentation/ApexDocTest.java
    index c4f0fb2356d..dcd261620ac 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/documentation/ApexDocTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/documentation/ApexDocTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/ApexCSRFTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/ApexCSRFTest.java
    index 694907f980b..77cfe742661 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/ApexCSRFTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/ApexCSRFTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidDirectAccessTriggerMapTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidDirectAccessTriggerMapTest.java
    index 8f9ddd1e0fe..9cb3218ae66 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidDirectAccessTriggerMapTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidDirectAccessTriggerMapTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidHardcodingIdTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidHardcodingIdTest.java
    index 2896accdedf..3c8806ca3e0 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidHardcodingIdTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidHardcodingIdTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidNonExistentAnnotationsTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidNonExistentAnnotationsTest.java
    index f244db32e4a..728139c7d5e 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidNonExistentAnnotationsTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/AvoidNonExistentAnnotationsTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/EmptyCatchBlockTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/EmptyCatchBlockTest.java
    index 329de97e77a..f36495d51f5 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/EmptyCatchBlockTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/EmptyCatchBlockTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/EmptyIfStmtTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/EmptyIfStmtTest.java
    index e21bb438ba3..9a255c00462 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/EmptyIfStmtTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/EmptyIfStmtTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/EmptyStatementBlockTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/EmptyStatementBlockTest.java
    index 7df8c60d6b3..2ecf2e3b12a 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/EmptyStatementBlockTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/EmptyStatementBlockTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/EmptyTryOrFinallyBlockTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/EmptyTryOrFinallyBlockTest.java
    index 0adb332e799..fcce49501ef 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/EmptyTryOrFinallyBlockTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/EmptyTryOrFinallyBlockTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/EmptyWhileStmtTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/EmptyWhileStmtTest.java
    index 5f6fc34e818..593a76f7891 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/EmptyWhileStmtTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/EmptyWhileStmtTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/InaccessibleAuraEnabledGetterTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/InaccessibleAuraEnabledGetterTest.java
    index e423dc004b1..aba378c292c 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/InaccessibleAuraEnabledGetterTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/InaccessibleAuraEnabledGetterTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/MethodWithSameNameAsEnclosingClassTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/MethodWithSameNameAsEnclosingClassTest.java
    index 19def64a1e7..b5f4e60e367 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/MethodWithSameNameAsEnclosingClassTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/MethodWithSameNameAsEnclosingClassTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/OverrideBothEqualsAndHashcodeTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/OverrideBothEqualsAndHashcodeTest.java
    index 637e9f1cdfe..5a764b625e8 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/OverrideBothEqualsAndHashcodeTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/OverrideBothEqualsAndHashcodeTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/TestMethodsMustBeInTestClassesTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/TestMethodsMustBeInTestClassesTest.java
    index 4ea8975c09b..b87964bf902 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/TestMethodsMustBeInTestClassesTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/TestMethodsMustBeInTestClassesTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/TypeShadowsBuiltInNamespaceTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/TypeShadowsBuiltInNamespaceTest.java
    index 577a86b76ea..d39a24e4a60 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/TypeShadowsBuiltInNamespaceTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/errorprone/TypeShadowsBuiltInNamespaceTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/performance/EagerlyLoadedDescribeSObjectResultTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/performance/EagerlyLoadedDescribeSObjectResultTest.java
    index 4f73dcb894d..6d5bf7c4aab 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/performance/EagerlyLoadedDescribeSObjectResultTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/performance/EagerlyLoadedDescribeSObjectResultTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/performance/OperationWithHighCostInLoopTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/performance/OperationWithHighCostInLoopTest.java
    index e61681e5ec1..e4a6a53a571 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/performance/OperationWithHighCostInLoopTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/performance/OperationWithHighCostInLoopTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/performance/OperationWithLimitsInLoopTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/performance/OperationWithLimitsInLoopTest.java
    index 9c13461634f..f73944017be 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/performance/OperationWithLimitsInLoopTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/performance/OperationWithLimitsInLoopTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexBadCryptoTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexBadCryptoTest.java
    index 988e4c14010..776a3aa1c1c 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexBadCryptoTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexBadCryptoTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexCRUDViolationTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexCRUDViolationTest.java
    index b8367a79e01..09e8022f317 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexCRUDViolationTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexCRUDViolationTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexDangerousMethodsTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexDangerousMethodsTest.java
    index 60f2e9a0bfb..85d844cdfc2 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexDangerousMethodsTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexDangerousMethodsTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexInsecureEndpointTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexInsecureEndpointTest.java
    index 7189c176bd0..b5fdff960d7 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexInsecureEndpointTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexInsecureEndpointTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexOpenRedirectTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexOpenRedirectTest.java
    index f16dcb45724..2a0c350e24d 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexOpenRedirectTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexOpenRedirectTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSOQLInjectionTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSOQLInjectionTest.java
    index 4b9381632dd..f544abd164d 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSOQLInjectionTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSOQLInjectionTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSharingViolationsNestedClassTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSharingViolationsNestedClassTest.java
    index 05c95696c69..a6e8f71368c 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSharingViolationsNestedClassTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSharingViolationsNestedClassTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSharingViolationsTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSharingViolationsTest.java
    index b228dd48da7..6812fef94df 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSharingViolationsTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSharingViolationsTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSuggestUsingNamedCredTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSuggestUsingNamedCredTest.java
    index e13e2f48214..847a7e9076d 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSuggestUsingNamedCredTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSuggestUsingNamedCredTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexXSSFromEscapeFalseTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexXSSFromEscapeFalseTest.java
    index 4d0ad58f8a6..00555b634d6 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexXSSFromEscapeFalseTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexXSSFromEscapeFalseTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexXSSFromURLParamTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexXSSFromURLParamTest.java
    index 283f8de0517..187cb699ec0 100644
    --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexXSSFromURLParamTest.java
    +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/security/ApexXSSFromURLParamTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    
    From 1e3afe3ef484ba73652a4c424af066b7d46b90de Mon Sep 17 00:00:00 2001
    From: Andreas Dangel 
    Date: Fri, 4 Jul 2025 09:43:49 +0200
    Subject: [PATCH 1091/1962] Bump PMD from 7.14.0 to 7.15.0 (#5857)
    
    ---
     pom.xml | 8 ++++----
     1 file changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/pom.xml b/pom.xml
    index a71d668c126..c12c0ff2b49 100644
    --- a/pom.xml
    +++ b/pom.xml
    @@ -581,22 +581,22 @@
                             
                                 net.sourceforge.pmd
                                 pmd-core
    -                            7.14.0 
    +                            7.15.0 
                             
                             
                                 net.sourceforge.pmd
                                 pmd-java
    -                            7.14.0 
    +                            7.15.0 
                             
                             
                                 net.sourceforge.pmd
                                 pmd-jsp
    -                            7.14.0 
    +                            7.15.0 
                             
                             
                                 net.sourceforge.pmd
                                 pmd-javascript
    -                            7.14.0 
    +                            7.15.0 
                             
                             
                             
    
    From 00e7575aef34574d8cfd0cf33f4124524fb9d069 Mon Sep 17 00:00:00 2001
    From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
    Date: Fri, 4 Jul 2025 09:45:20 +0200
    Subject: [PATCH 1092/1962] Bump scalameta.version from 4.13.7 to 4.13.8
     (#5861)
    
    Bumps `scalameta.version` from 4.13.7 to 4.13.8.
    
    Updates `org.scalameta:parsers_2.13` from 4.13.7 to 4.13.8
    - [Release notes](https://github.com/scalameta/scalameta/releases)
    - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.7...v4.13.8)
    
    Updates `org.scalameta:trees_2.13` from 4.13.7 to 4.13.8
    - [Release notes](https://github.com/scalameta/scalameta/releases)
    - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.7...v4.13.8)
    
    Updates `org.scalameta:parsers_2.12` from 4.13.7 to 4.13.8
    - [Release notes](https://github.com/scalameta/scalameta/releases)
    - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.7...v4.13.8)
    
    Updates `org.scalameta:trees_2.12` from 4.13.7 to 4.13.8
    - [Release notes](https://github.com/scalameta/scalameta/releases)
    - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.7...v4.13.8)
    
    ---
    updated-dependencies:
    - dependency-name: org.scalameta:parsers_2.13
      dependency-version: 4.13.8
      dependency-type: direct:production
      update-type: version-update:semver-patch
    - dependency-name: org.scalameta:trees_2.13
      dependency-version: 4.13.8
      dependency-type: direct:production
      update-type: version-update:semver-patch
    - dependency-name: org.scalameta:parsers_2.12
      dependency-version: 4.13.8
      dependency-type: direct:production
      update-type: version-update:semver-patch
    - dependency-name: org.scalameta:trees_2.12
      dependency-version: 4.13.8
      dependency-type: direct:production
      update-type: version-update:semver-patch
    ...
    
    Signed-off-by: dependabot[bot] 
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    ---
     pmd-scala-modules/pmd-scala-common/pom.xml | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml
    index b22f2a93637..935eec31472 100644
    --- a/pmd-scala-modules/pmd-scala-common/pom.xml
    +++ b/pmd-scala-modules/pmd-scala-common/pom.xml
    @@ -13,7 +13,7 @@
         
     
         
    -        4.13.7
    +        4.13.8
         
     
         
    
    From 2b62c37d4123332b516f6ae2b90d7c2258100c9e Mon Sep 17 00:00:00 2001
    From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
    Date: Fri, 4 Jul 2025 09:45:56 +0200
    Subject: [PATCH 1093/1962] Bump com.puppycrawl.tools:checkstyle from 10.25.1
     to 10.26.1 (#5862)
    
    Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.25.1 to 10.26.1.
    - [Release notes](https://github.com/checkstyle/checkstyle/releases)
    - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.25.1...checkstyle-10.26.1)
    
    ---
    updated-dependencies:
    - dependency-name: com.puppycrawl.tools:checkstyle
      dependency-version: 10.26.1
      dependency-type: direct:production
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] 
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    ---
     pom.xml | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/pom.xml b/pom.xml
    index c12c0ff2b49..654d9cd4019 100644
    --- a/pom.xml
    +++ b/pom.xml
    @@ -90,7 +90,7 @@
     
             5.0
             3.5.3
    -        10.25.1
    +        10.26.1
             3.6.0
             3.26.0
             1.10.15
    
    From 0e88cece0ba030f3a2a99ee11ac5b77ebe9d5949 Mon Sep 17 00:00:00 2001
    From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
    Date: Fri, 4 Jul 2025 09:46:43 +0200
    Subject: [PATCH 1094/1962] Bump org.apache.maven.plugins:maven-pmd-plugin from
     3.26.0 to 3.27.0 (#5863)
    
    Bumps [org.apache.maven.plugins:maven-pmd-plugin](https://github.com/apache/maven-pmd-plugin) from 3.26.0 to 3.27.0.
    - [Release notes](https://github.com/apache/maven-pmd-plugin/releases)
    - [Commits](https://github.com/apache/maven-pmd-plugin/compare/maven-pmd-plugin-3.26.0...maven-pmd-plugin-3.27.0)
    
    ---
    updated-dependencies:
    - dependency-name: org.apache.maven.plugins:maven-pmd-plugin
      dependency-version: 3.27.0
      dependency-type: direct:production
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] 
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    ---
     pom.xml | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/pom.xml b/pom.xml
    index 654d9cd4019..7b5a8cd35c8 100644
    --- a/pom.xml
    +++ b/pom.xml
    @@ -92,7 +92,7 @@
             3.5.3
             10.26.1
             3.6.0
    -        3.26.0
    +        3.27.0
             1.10.15
             3.11.2
             4.9.3
    
    From af05132f7a739501a44fd1a9f79559a624d0536e Mon Sep 17 00:00:00 2001
    From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
    Date: Fri, 4 Jul 2025 09:47:40 +0200
    Subject: [PATCH 1095/1962] Bump org.jsoup:jsoup from 1.20.1 to 1.21.1 (#5866)
    
    Bumps [org.jsoup:jsoup](https://github.com/jhy/jsoup) from 1.20.1 to 1.21.1.
    - [Release notes](https://github.com/jhy/jsoup/releases)
    - [Changelog](https://github.com/jhy/jsoup/blob/master/CHANGES.md)
    - [Commits](https://github.com/jhy/jsoup/compare/jsoup-1.20.1...jsoup-1.21.1)
    
    ---
    updated-dependencies:
    - dependency-name: org.jsoup:jsoup
      dependency-version: 1.21.1
      dependency-type: direct:production
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] 
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    ---
     pmd-html/pom.xml | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml
    index cc502f1798b..8c01d373ef5 100644
    --- a/pmd-html/pom.xml
    +++ b/pmd-html/pom.xml
    @@ -31,7 +31,7 @@
             
                 org.jsoup
                 jsoup
    -            1.20.1
    +            1.21.1
             
     
             
    
    From 45767b3b6f9f137a817317662a59a6ecdea49931 Mon Sep 17 00:00:00 2001
    From: Andreas Dangel 
    Date: Fri, 4 Jul 2025 09:53:13 +0200
    Subject: [PATCH 1096/1962] chore: pmd-coco: Update license header
    
    ---
     .../java/net/sourceforge/pmd/lang/coco/cpd/CocoCpdLexer.java    | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/cpd/CocoCpdLexer.java b/pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/cpd/CocoCpdLexer.java
    index cda9ab4b7f6..23548d91be2 100644
    --- a/pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/cpd/CocoCpdLexer.java
    +++ b/pmd-coco/src/main/java/net/sourceforge/pmd/lang/coco/cpd/CocoCpdLexer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    
    From b37c10e5914cdf2c3481751967e6e27fc23b6425 Mon Sep 17 00:00:00 2001
    From: Andreas Dangel 
    Date: Fri, 4 Jul 2025 10:02:47 +0200
    Subject: [PATCH 1097/1962] chore: pmd-gherkin: Update license header
    
    ---
     .../net/sourceforge/pmd/lang/gherkin/cpd/GherkinCpdLexer.java   | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/cpd/GherkinCpdLexer.java b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/cpd/GherkinCpdLexer.java
    index 73120670e26..5281cccda48 100644
    --- a/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/cpd/GherkinCpdLexer.java
    +++ b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/cpd/GherkinCpdLexer.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    
    From 418967454caf1f88d2ff91e2f4121e1c10559392 Mon Sep 17 00:00:00 2001
    From: Andreas Dangel 
    Date: Fri, 4 Jul 2025 10:06:08 +0200
    Subject: [PATCH 1098/1962] chore: pmd-html: Update license header
    
    ---
     .../java/net/sourceforge/pmd/lang/html/ast/LineNumbers.java     | 2 +-
     .../java/net/sourceforge/pmd/lang/html/RuleSetFactoryTest.java  | 2 +-
     .../net/sourceforge/pmd/lang/html/ast/HtmlParsingHelper.java    | 2 +-
     .../pmd/lang/html/rule/bestpractices/AvoidInlineStylesTest.java | 2 +-
     4 files changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/pmd-html/src/main/java/net/sourceforge/pmd/lang/html/ast/LineNumbers.java b/pmd-html/src/main/java/net/sourceforge/pmd/lang/html/ast/LineNumbers.java
    index 5419b30e3a4..c5a37faf4b9 100644
    --- a/pmd-html/src/main/java/net/sourceforge/pmd/lang/html/ast/LineNumbers.java
    +++ b/pmd-html/src/main/java/net/sourceforge/pmd/lang/html/ast/LineNumbers.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/RuleSetFactoryTest.java b/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/RuleSetFactoryTest.java
    index a79d09a0af0..858e7ada106 100644
    --- a/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/RuleSetFactoryTest.java
    +++ b/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/RuleSetFactoryTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/ast/HtmlParsingHelper.java b/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/ast/HtmlParsingHelper.java
    index 531577d920b..41529c22c07 100644
    --- a/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/ast/HtmlParsingHelper.java
    +++ b/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/ast/HtmlParsingHelper.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    diff --git a/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/rule/bestpractices/AvoidInlineStylesTest.java b/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/rule/bestpractices/AvoidInlineStylesTest.java
    index e3dab363380..414fa3a456d 100644
    --- a/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/rule/bestpractices/AvoidInlineStylesTest.java
    +++ b/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/rule/bestpractices/AvoidInlineStylesTest.java
    @@ -1,4 +1,4 @@
    -/**
    +/*
      * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
      */
     
    
    From a09b0827e5b1b755d9ed8bff7fcef845ba6a80d1 Mon Sep 17 00:00:00 2001
    From: Thomas Prouvot 
    Date: Fri, 4 Jul 2025 10:10:07 +0200
    Subject: [PATCH 1099/1962] Implementing changes requested in PR comments
    
    ---
     docs/_plugins/jdoc_namespace_tag.rb           |  2 +-
     .../pmd/lang/css/cpd/CssCpdLexer.java         |  9 ------
     .../pmd/lang/css/cpd/testdata/literals.txt    | 32 +++++++++----------
     3 files changed, 17 insertions(+), 26 deletions(-)
    
    diff --git a/docs/_plugins/jdoc_namespace_tag.rb b/docs/_plugins/jdoc_namespace_tag.rb
    index f6a1a1500df..3becd9c7f21 100644
    --- a/docs/_plugins/jdoc_namespace_tag.rb
    +++ b/docs/_plugins/jdoc_namespace_tag.rb
    @@ -99,7 +99,7 @@ def self.parse_fqcn(fqcn, var_ctx, allow_sym = true)
       private
     
       JDOC_NAMESPACE_MAP = "jdoc_nspaces"
    -  RESERVED_NSPACES = ['ant', 'apex', 'cli', 'coco', 'core', 'cpp', 'cs', 'dart', 'dist', 'doc',
    +  RESERVED_NSPACES = ['ant', 'apex', 'cli', 'coco', 'core', 'cpp', 'cs', 'css', 'dart', 'dist', 'doc',
         'fortran', 'gherkin', 'go', 'groovy', 'html', 'java',
         'javascript', 'jsp', 'julia',
         'kotlin', 'lang-test', 'lua', 'matlab', 'objectivec', 'perl', 'php', 'plsql', 'python', 'ruby', 'rust', 'scala', 'swift',
    diff --git a/pmd-css/src/main/java/net/sourceforge/pmd/lang/css/cpd/CssCpdLexer.java b/pmd-css/src/main/java/net/sourceforge/pmd/lang/css/cpd/CssCpdLexer.java
    index 697f43db34f..2ce7e8486a3 100644
    --- a/pmd-css/src/main/java/net/sourceforge/pmd/lang/css/cpd/CssCpdLexer.java
    +++ b/pmd-css/src/main/java/net/sourceforge/pmd/lang/css/cpd/CssCpdLexer.java
    @@ -4,13 +4,10 @@
     
     package net.sourceforge.pmd.lang.css.cpd;
     
    -import java.util.Locale;
    -
     import org.antlr.v4.runtime.CharStream;
     import org.antlr.v4.runtime.Lexer;
     
     import net.sourceforge.pmd.cpd.impl.AntlrCpdLexer;
    -import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrToken;
     import net.sourceforge.pmd.lang.css.ast.CssLexer;
     
     public class CssCpdLexer extends AntlrCpdLexer {
    @@ -19,10 +16,4 @@ public class CssCpdLexer extends AntlrCpdLexer {
         protected Lexer getLexerForSource(CharStream charStream) {
             return new CssLexer(charStream);
         }
    -
    -    @Override
    -    protected String getImage(AntlrToken token) {
    -        // normalize case-insensitive tokens
    -        return token.getImage().toUpperCase(Locale.ROOT);
    -    }
     }
    diff --git a/pmd-css/src/test/resources/net/sourceforge/pmd/lang/css/cpd/testdata/literals.txt b/pmd-css/src/test/resources/net/sourceforge/pmd/lang/css/cpd/testdata/literals.txt
    index ea9abad9c53..9a3f085ec19 100644
    --- a/pmd-css/src/test/resources/net/sourceforge/pmd/lang/css/cpd/testdata/literals.txt
    +++ b/pmd-css/src/test/resources/net/sourceforge/pmd/lang/css/cpd/testdata/literals.txt
    @@ -1,63 +1,63 @@
         [Image] or [Truncated image[            Bcol      Ecol
     L1
    -    [/* ALL ELEMENTS WITH CLASS="SPACIO[    1         41
    +    [/* All elements with class="spacio[    1         41
         [\n]                                    41        42
     L2
         [.]                                     1         2
    -    [SPACIOUS]                              2         10
    +    [spacious]                              2         10
         [ ]                                     10        11
         [{]                                     11        12
         [\n  ]                                  12        3
     L3
    -    [MARGIN]                                3         9
    +    [margin]                                3         9
         [:]                                     9         10
         [ ]                                     10        11
    -    [2EM]                                   11        14
    +    [2em]                                   11        14
         [;]                                     14        15
         [\n]                                    15        16
     L4
         [}]                                     1         2
         [\n\n]                                  2         2
     L6
    -    [/* ALL 
  • ELEMENTS WITH CLASS="S[ 1 46 + [/* All
  • elements with class="s[ 1 46 [\n] 46 47 L7 - [LI] 1 3 + [li] 1 3 [.] 3 4 - [SPACIOUS] 4 12 + [spacious] 4 12 [ ] 12 13 [{] 13 14 [\n ] 14 3 L8 - [MARGIN] 3 9 + [margin] 3 9 [:] 9 10 [ ] 10 11 - [2EM] 11 14 + [2em] 11 14 [;] 14 15 [\n] 15 16 L9 [}] 1 2 [\n\n] 2 2 L11 - [/* ALL
  • ELEMENTS WITH A CLASS [ 1 86 + [/* All
  • elements with a class [ 1 86 [\n] 86 87 L12 - [/* FOR EXAMPLE, CLASS="ELEGANT RET[ 1 50 + [/* For example, class="elegant ret[ 1 50 [\n] 50 51 L13 - [LI] 1 3 + [li] 1 3 [.] 3 4 - [SPACIOUS] 4 12 + [spacious] 4 12 [.] 12 13 - [ELEGANT] 13 20 + [elegant] 13 20 [ ] 20 21 [{] 21 22 [\n ] 22 3 L14 - [MARGIN] 3 9 + [margin] 3 9 [:] 9 10 [ ] 10 11 - [2EM] 11 14 + [2em] 11 14 [;] 14 15 [\n] 15 16 L15 From ba7fb0924dfbd23aeeb305cd8e99052ffb409e9b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Jul 2025 10:12:15 +0200 Subject: [PATCH 1100/1962] Bump org.junit:junit-bom from 5.13.1 to 5.13.2 (#5865) * Bump org.junit:junit-bom from 5.13.1 to 5.13.2 Bumps [org.junit:junit-bom](https://github.com/junit-team/junit-framework) from 5.13.1 to 5.13.2. - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r5.13.1...r5.13.2) --- updated-dependencies: - dependency-name: org.junit:junit-bom dependency-version: 5.13.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump junit5.platform.version from 1.13.1 to 1.13.2 --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andreas Dangel --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 7b5a8cd35c8..2c30081d76e 100644 --- a/pom.xml +++ b/pom.xml @@ -84,8 +84,8 @@ ${maven.compiler.test.target} 1.9.24 5.9.1 - 5.13.1 - 1.13.1 + 5.13.2 + 1.13.2 2.0.0 5.0 From 54de287dc7fd5b0a876332d197e356cecdc38b46 Mon Sep 17 00:00:00 2001 From: Thomas Prouvot Date: Fri, 4 Jul 2025 10:22:24 +0200 Subject: [PATCH 1101/1962] Updating snapshot version --- pmd-css/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-css/pom.xml b/pmd-css/pom.xml index d3ea9bc0472..6b0f538b361 100644 --- a/pmd-css/pom.xml +++ b/pmd-css/pom.xml @@ -9,7 +9,7 @@ net.sourceforge.pmd pmd - 7.14.0-SNAPSHOT + 7.16.0-SNAPSHOT ../pom.xml From 8dd7d595c82c00b18be04334b6f5e7370ad6d31d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Jul 2025 10:26:03 +0200 Subject: [PATCH 1102/1962] chore: pmd-java: Update license header --- .../net/sourceforge/pmd/lang/java/JavaLanguageModule.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTAmbiguousName.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/ASTAnnotation.java | 2 +- .../pmd/lang/java/ast/ASTAnnotationMemberList.java | 2 +- .../sourceforge/pmd/lang/java/ast/ASTAnnotationTypeBody.java | 2 +- .../pmd/lang/java/ast/ASTAnnotationTypeDeclaration.java | 2 +- .../pmd/lang/java/ast/ASTAnonymousClassDeclaration.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTArgumentList.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTArrayAccess.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTArrayAllocation.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTArrayDimExpr.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTArrayDimensions.java | 2 +- .../sourceforge/pmd/lang/java/ast/ASTArrayInitializer.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/ASTArrayType.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTArrayTypeDim.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTAssertStatement.java | 2 +- .../pmd/lang/java/ast/ASTAssignmentExpression.java | 2 +- .../main/java/net/sourceforge/pmd/lang/java/ast/ASTBlock.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTBodyDeclaration.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTBooleanLiteral.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTBreakStatement.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTCastExpression.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTCatchClause.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTCatchParameter.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTCharLiteral.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/ASTClassBody.java | 2 +- .../sourceforge/pmd/lang/java/ast/ASTClassDeclaration.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTClassLiteral.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/ASTClassType.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java | 2 +- .../pmd/lang/java/ast/ASTConditionalExpression.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTConstructorCall.java | 2 +- .../pmd/lang/java/ast/ASTConstructorDeclaration.java | 2 +- .../sourceforge/pmd/lang/java/ast/ASTContinueStatement.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTDefaultValue.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTDoStatement.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTEmptyStatement.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/ASTEnumBody.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTEnumConstant.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTEnumDeclaration.java | 2 +- .../pmd/lang/java/ast/ASTExecutableDeclaration.java | 2 +- .../pmd/lang/java/ast/ASTExplicitConstructorInvocation.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/ASTExpression.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTExtendsList.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTFieldAccess.java | 2 +- .../sourceforge/pmd/lang/java/ast/ASTFieldDeclaration.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTFinallyClause.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/ASTForInit.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTForStatement.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/ASTForUpdate.java | 2 +- .../sourceforge/pmd/lang/java/ast/ASTForeachStatement.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTFormalParameter.java | 2 +- .../sourceforge/pmd/lang/java/ast/ASTFormalParameters.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTIfStatement.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTImplementsList.java | 2 +- .../sourceforge/pmd/lang/java/ast/ASTImportDeclaration.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTInitializer.java | 2 +- .../sourceforge/pmd/lang/java/ast/ASTLabeledStatement.java | 2 +- .../sourceforge/pmd/lang/java/ast/ASTLambdaExpression.java | 2 +- .../main/java/net/sourceforge/pmd/lang/java/ast/ASTList.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/ASTLiteral.java | 2 +- .../pmd/lang/java/ast/ASTLocalVariableDeclaration.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTMemberValue.java | 2 +- .../pmd/lang/java/ast/ASTMemberValueArrayInitializer.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTMemberValuePair.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/ASTMethodCall.java | 2 +- .../sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java | 2 +- .../sourceforge/pmd/lang/java/ast/ASTModuleDeclaration.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTModuleDirective.java | 2 +- .../pmd/lang/java/ast/ASTModuleExportsDirective.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/ASTModuleName.java | 2 +- .../pmd/lang/java/ast/ASTModuleOpensDirective.java | 2 +- .../pmd/lang/java/ast/ASTModuleProvidesDirective.java | 2 +- .../pmd/lang/java/ast/ASTModuleRequiresDirective.java | 2 +- .../sourceforge/pmd/lang/java/ast/ASTModuleUsesDirective.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTNullLiteral.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTNumericLiteral.java | 2 +- .../sourceforge/pmd/lang/java/ast/ASTPackageDeclaration.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTPermitsList.java | 2 +- .../sourceforge/pmd/lang/java/ast/ASTPrimaryExpression.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTPrimitiveType.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTReferenceType.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/ASTResource.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTResourceList.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTReturnStatement.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/ASTStatement.java | 2 +- .../pmd/lang/java/ast/ASTStatementExpressionList.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTStringLiteral.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTSuperExpression.java | 2 +- .../sourceforge/pmd/lang/java/ast/ASTSwitchArrowBranch.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTSwitchArrowRHS.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTSwitchBranch.java | 2 +- .../sourceforge/pmd/lang/java/ast/ASTSwitchExpression.java | 2 +- .../pmd/lang/java/ast/ASTSwitchFallthroughBranch.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTSwitchLabel.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLike.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTSwitchStatement.java | 2 +- .../pmd/lang/java/ast/ASTSynchronizedStatement.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTThisExpression.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTThrowStatement.java | 2 +- .../sourceforge/pmd/lang/java/ast/ASTTopLevelDeclaration.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTTryStatement.java | 2 +- .../main/java/net/sourceforge/pmd/lang/java/ast/ASTType.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTTypeArguments.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTTypeDeclaration.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTTypeParameter.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTTypeParameters.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTUnaryExpression.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTVariableAccess.java | 2 +- .../sourceforge/pmd/lang/java/ast/ASTVariableDeclarator.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/ASTVariableId.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/ASTVoidType.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTWhileStatement.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTWildcardType.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTYieldStatement.java | 2 +- .../pmd/lang/java/ast/AbstractExecutableDeclaration.java | 2 +- .../sourceforge/pmd/lang/java/ast/AbstractJavaPattern.java | 2 +- .../sourceforge/pmd/lang/java/ast/AbstractJavaTypeNode.java | 2 +- .../pmd/lang/java/ast/AbstractPackageNameModuleDirective.java | 2 +- .../pmd/lang/java/ast/AbstractTypeBodyDeclaration.java | 2 +- .../pmd/lang/java/ast/AbstractTypeDeclaration.java | 2 +- .../pmd/lang/java/ast/AbstractTypedSymbolDeclarator.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/Annotatable.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/AssignmentOp.java | 2 +- .../main/java/net/sourceforge/pmd/lang/java/ast/BinaryOp.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/JavaComment.java | 2 +- .../main/java/net/sourceforge/pmd/lang/java/ast/JavaNode.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/JavaVisitorBase.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/JavadocComment.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ReturnScopeNode.java | 2 +- .../main/java/net/sourceforge/pmd/lang/java/ast/TypeNode.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/package-info.java | 2 +- .../net/sourceforge/pmd/lang/java/javadoc/JavadocTag.java | 2 +- .../java/metrics/internal/CognitiveComplexityVisitor.java | 2 +- .../pmd/lang/java/metrics/internal/NPathMetricCalculator.java | 2 +- .../java/rule/bestpractices/AccessorClassGenerationRule.java | 2 +- .../java/rule/bestpractices/AccessorMethodGenerationRule.java | 2 +- .../java/rule/bestpractices/ArrayIsStoredDirectlyRule.java | 2 +- .../bestpractices/AvoidReassigningCatchVariablesRule.java | 2 +- .../rule/bestpractices/AvoidReassigningLoopVariablesRule.java | 2 +- .../rule/bestpractices/AvoidReassigningParametersRule.java | 2 +- .../pmd/lang/java/rule/bestpractices/CheckResultSetRule.java | 2 +- .../lang/java/rule/bestpractices/GuardLogStatementRule.java | 2 +- .../JUnitAssertionsShouldIncludeMessageRule.java | 2 +- .../bestpractices/JUnitTestContainsTooManyAssertsRule.java | 2 +- .../rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java | 2 +- .../lang/java/rule/bestpractices/JUnitUseExpectedRule.java | 2 +- .../pmd/lang/java/rule/bestpractices/LooseCouplingRule.java | 2 +- .../rule/bestpractices/MethodReturnsInternalArrayRule.java | 2 +- .../pmd/lang/java/rule/bestpractices/MissingOverrideRule.java | 2 +- .../lang/java/rule/bestpractices/PreserveStackTraceRule.java | 2 +- .../UnitTestAssertionsShouldIncludeMessageRule.java | 2 +- .../bestpractices/UnitTestContainsTooManyAssertsRule.java | 2 +- .../rule/bestpractices/UnitTestShouldIncludeAssertRule.java | 2 +- .../java/rule/bestpractices/UnusedFormalParameterRule.java | 2 +- .../lang/java/rule/bestpractices/UnusedLocalVariableRule.java | 2 +- .../lang/java/rule/bestpractices/UnusedPrivateFieldRule.java | 2 +- .../java/rule/bestpractices/UseCollectionIsEmptyRule.java | 2 +- .../lang/java/rule/bestpractices/UseEnumCollectionsRule.java | 2 +- .../java/rule/codestyle/AbstractNamingConventionRule.java | 2 +- .../lang/java/rule/codestyle/AtLeastOneConstructorRule.java | 2 +- .../lang/java/rule/codestyle/ClassNamingConventionsRule.java | 2 +- .../java/rule/codestyle/CommentDefaultAccessModifierRule.java | 2 +- .../pmd/lang/java/rule/codestyle/ConfusingTernaryRule.java | 2 +- .../lang/java/rule/codestyle/EmptyControlStatementRule.java | 2 +- .../FieldDeclarationsShouldBeAtStartOfClassRule.java | 2 +- .../lang/java/rule/codestyle/FieldNamingConventionsRule.java | 2 +- .../rule/codestyle/FormalParameterNamingConventionsRule.java | 2 +- .../lang/java/rule/codestyle/IdenticalCatchBranchesRule.java | 2 +- .../java/rule/codestyle/LambdaCanBeMethodReferenceRule.java | 2 +- .../java/rule/codestyle/LocalVariableCouldBeFinalRule.java | 2 +- .../rule/codestyle/LocalVariableNamingConventionsRule.java | 2 +- .../java/rule/codestyle/MethodArgumentCouldBeFinalRule.java | 2 +- .../lang/java/rule/codestyle/MethodNamingConventionsRule.java | 2 +- .../pmd/lang/java/rule/codestyle/OnlyOneReturnRule.java | 2 +- .../lang/java/rule/codestyle/PrematureDeclarationRule.java | 2 +- .../lang/java/rule/codestyle/UnnecessaryConstructorRule.java | 2 +- .../rule/codestyle/UnnecessaryFullyQualifiedNameRule.java | 2 +- .../java/rule/codestyle/UnnecessaryLocalBeforeReturnRule.java | 2 +- .../pmd/lang/java/rule/codestyle/UnnecessaryModifierRule.java | 2 +- .../pmd/lang/java/rule/codestyle/UselessParenthesesRule.java | 2 +- .../lang/java/rule/design/AvoidDeeplyNestedIfStmtsRule.java | 2 +- .../rule/design/AvoidThrowingNullPointerExceptionRule.java | 2 +- .../pmd/lang/java/rule/design/CouplingBetweenObjectsRule.java | 2 +- .../pmd/lang/java/rule/design/CyclomaticComplexityRule.java | 2 +- .../sourceforge/pmd/lang/java/rule/design/DataClassRule.java | 2 +- .../pmd/lang/java/rule/design/ExceptionAsFlowControlRule.java | 2 +- .../lang/java/rule/design/FinalFieldCouldBeStaticRule.java | 2 +- .../sourceforge/pmd/lang/java/rule/design/GodClassRule.java | 2 +- .../pmd/lang/java/rule/design/ImmutableFieldRule.java | 2 +- .../pmd/lang/java/rule/design/LawOfDemeterRule.java | 2 +- .../pmd/lang/java/rule/design/LoosePackageCouplingRule.java | 2 +- .../sourceforge/pmd/lang/java/rule/design/NcssCountRule.java | 2 +- .../java/rule/design/SignatureDeclareThrowsExceptionRule.java | 2 +- .../pmd/lang/java/rule/design/SimplifyBooleanReturnsRule.java | 2 +- .../pmd/lang/java/rule/design/SwitchDensityRule.java | 2 +- .../pmd/lang/java/rule/design/UseUtilityClassRule.java | 2 +- .../lang/java/rule/design/UselessOverridingMethodRule.java | 2 +- .../pmd/lang/java/rule/documentation/CommentContentRule.java | 2 +- .../pmd/lang/java/rule/documentation/CommentRequiredRule.java | 2 +- .../pmd/lang/java/rule/documentation/CommentSizeRule.java | 2 +- .../lang/java/rule/errorprone/AssignmentInOperandRule.java | 2 +- .../java/rule/errorprone/AssignmentToNonFinalStaticRule.java | 2 +- .../errorprone/AvoidBranchingStatementAsLastInLoopRule.java | 2 +- .../lang/java/rule/errorprone/AvoidDuplicateLiteralsRule.java | 2 +- .../lang/java/rule/errorprone/AvoidUsingOctalValuesRule.java | 2 +- .../pmd/lang/java/rule/errorprone/BrokenNullCheckRule.java | 2 +- .../pmd/lang/java/rule/errorprone/CheckSkipResultRule.java | 2 +- .../errorprone/CloneMethodMustImplementCloneableRule.java | 2 +- .../errorprone/ConstructorCallsOverridableMethodRule.java | 2 +- .../pmd/lang/java/rule/errorprone/DetachedTestCaseRule.java | 2 +- .../lang/java/rule/errorprone/IdempotentOperationsRule.java | 2 +- .../java/rule/errorprone/InvalidLogMessageFormatRule.java | 2 +- .../lang/java/rule/errorprone/NonSerializableClassRule.java | 2 +- .../pmd/lang/java/rule/errorprone/NullAssignmentRule.java | 2 +- .../rule/errorprone/OverrideBothEqualsAndHashcodeRule.java | 2 +- .../lang/java/rule/errorprone/SingleMethodSingletonRule.java | 2 +- .../errorprone/SingletonClassReturningNewInstanceRule.java | 2 +- .../lang/java/rule/errorprone/SuspiciousOctalEscapeRule.java | 2 +- .../java/rule/errorprone/TestClassWithoutTestCasesRule.java | 2 +- .../lang/java/rule/errorprone/UnnecessaryCaseChangeRule.java | 2 +- .../java/rule/errorprone/UselessOperationOnImmutableRule.java | 2 +- .../java/rule/multithreading/DoubleCheckedLockingRule.java | 2 +- .../java/rule/multithreading/NonThreadSafeSingletonRule.java | 2 +- .../multithreading/UnsynchronizedStaticFormatterRule.java | 2 +- .../java/net/sourceforge/pmd/lang/java/rule/package-info.java | 2 +- .../pmd/lang/java/rule/performance/AddEmptyStringRule.java | 2 +- .../java/rule/performance/AppendCharacterWithCharRule.java | 2 +- .../performance/AvoidInstantiatingObjectsInLoopsRule.java | 2 +- .../java/rule/performance/BigIntegerInstantiationRule.java | 2 +- .../rule/performance/ConsecutiveAppendsShouldReuseRule.java | 2 +- .../java/rule/performance/ConsecutiveLiteralAppendsRule.java | 2 +- .../rule/performance/InefficientEmptyStringCheckRule.java | 2 +- .../java/rule/performance/InefficientStringBufferingRule.java | 2 +- .../performance/InsufficientStringBufferDeclarationRule.java | 2 +- .../java/rule/performance/RedundantFieldInitializerRule.java | 2 +- .../lang/java/rule/performance/StringInstantiationRule.java | 2 +- .../pmd/lang/java/rule/performance/UseIndexOfCharRule.java | 2 +- .../lang/java/rule/performance/UselessStringValueOfRule.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ExcludeLinesTest.java | 2 +- .../src/test/java/net/sourceforge/pmd/lang/java/FooRule.java | 2 +- .../java/net/sourceforge/pmd/lang/java/JavaParsingHelper.java | 2 +- .../pmd/lang/java/LanguageVersionDiscovererTest.java | 2 +- .../net/sourceforge/pmd/lang/java/LanguageVersionTest.java | 2 +- .../java/net/sourceforge/pmd/lang/java/PMDCoverageTest.java | 2 +- .../test/java/net/sourceforge/pmd/lang/java/PMDTaskTest.java | 2 +- .../net/sourceforge/pmd/lang/java/QuickstartRulesetTest.java | 2 +- .../test/java/net/sourceforge/pmd/lang/java/ReportTest.java | 2 +- .../net/sourceforge/pmd/lang/java/RuleSetFactoryTest.java | 2 +- .../net/sourceforge/pmd/lang/java/SuppressWarningsTest.java | 2 +- .../sourceforge/pmd/lang/java/ast/ASTBooleanLiteralTest.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTClassTypeTest.java | 2 +- .../pmd/lang/java/ast/ASTImportDeclarationTest.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTInitializerTest.java | 2 +- .../pmd/lang/java/ast/ASTPackageDeclarationTest.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTSwitchLabelTest.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ASTVariableIdTest.java | 2 +- .../sourceforge/pmd/lang/java/ast/AllJavaAstTreeDumpTest.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/CommentTest.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/EncodingTest.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/JDKVersionTest.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/Java10Test.java | 2 +- .../java/net/sourceforge/pmd/lang/java/ast/Java8Test.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/Java8TreeDumpTest.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/Java9TreeDumpTest.java | 2 +- .../sourceforge/pmd/lang/java/ast/JavaQualifiedNameTest.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java | 2 +- .../sourceforge/pmd/lang/java/ast/TextBlockEscapeTest.java | 2 +- .../pmd/lang/java/ast/testdata/InterfaceWithNestedClass.java | 2 +- .../pmd/lang/java/internal/JavaViolationDecoratorTest.java | 2 +- .../pmd/lang/java/metrics/JavaMetricsProviderTest.java | 2 +- .../pmd/lang/java/metrics/MetricsMemoizationTest.java | 2 +- .../pmd/lang/java/metrics/impl/AllMetricsTest.java | 2 +- .../sourceforge/pmd/lang/java/metrics/impl/AtfdTestRule.java | 2 +- .../sourceforge/pmd/lang/java/metrics/impl/CfoTestRule.java | 2 +- .../lang/java/metrics/impl/CognitiveComplexityTestRule.java | 2 +- .../sourceforge/pmd/lang/java/metrics/impl/CycloTestRule.java | 2 +- .../sourceforge/pmd/lang/java/metrics/impl/LocTestRule.java | 2 +- .../sourceforge/pmd/lang/java/metrics/impl/NPathTestRule.java | 2 +- .../sourceforge/pmd/lang/java/metrics/impl/NcssTestRule.java | 2 +- .../sourceforge/pmd/lang/java/metrics/impl/NoamTestRule.java | 2 +- .../sourceforge/pmd/lang/java/metrics/impl/NopaTestRule.java | 2 +- .../sourceforge/pmd/lang/java/metrics/impl/TccTestRule.java | 2 +- .../sourceforge/pmd/lang/java/metrics/impl/WmcTestRule.java | 2 +- .../sourceforge/pmd/lang/java/metrics/impl/WocTestRule.java | 2 +- .../pmd/lang/java/metrics/testdata/GetterDetection.java | 2 +- .../lang/java/metrics/testdata/MetricsVisitorTestData.java | 2 +- .../pmd/lang/java/metrics/testdata/SetterDetection.java | 2 +- .../bestpractices/AbstractClassWithoutAbstractMethodTest.java | 2 +- .../java/rule/bestpractices/AccessorClassGenerationTest.java | 2 +- .../java/rule/bestpractices/AccessorMethodGenerationTest.java | 2 +- .../java/rule/bestpractices/ArrayIsStoredDirectlyTest.java | 2 +- .../java/rule/bestpractices/AvoidMessageDigestFieldTest.java | 2 +- .../java/rule/bestpractices/AvoidPrintStackTraceTest.java | 2 +- .../bestpractices/AvoidReassigningCatchVariablesTest.java | 2 +- .../rule/bestpractices/AvoidReassigningLoopVariablesTest.java | 2 +- .../rule/bestpractices/AvoidReassigningParametersTest.java | 2 +- .../java/rule/bestpractices/AvoidStringBufferFieldTest.java | 2 +- .../java/rule/bestpractices/AvoidUsingHardCodedIPTest.java | 2 +- .../pmd/lang/java/rule/bestpractices/CheckResultSetTest.java | 2 +- .../java/rule/bestpractices/ConstantsInInterfaceTest.java | 2 +- .../rule/bestpractices/DefaultLabelNotLastInSwitchTest.java | 2 +- .../lang/java/rule/bestpractices/ForLoopCanBeForeachTest.java | 2 +- .../java/rule/bestpractices/ForLoopVariableCountTest.java | 2 +- .../lang/java/rule/bestpractices/GuardLogStatementTest.java | 2 +- .../rule/bestpractices/ImplicitFunctionalInterfaceTest.java | 2 +- .../JUnit4SuitesShouldUseSuiteAnnotationTest.java | 2 +- .../bestpractices/JUnit5TestShouldBePackagePrivateTest.java | 2 +- .../lang/java/rule/bestpractices/JUnitUseExpectedTest.java | 2 +- .../rule/bestpractices/LiteralsFirstInComparisonsTest.java | 2 +- .../pmd/lang/java/rule/bestpractices/LooseCouplingTest.java | 2 +- .../rule/bestpractices/MethodReturnsInternalArrayTest.java | 2 +- .../pmd/lang/java/rule/bestpractices/MissingOverrideTest.java | 2 +- .../lang/java/rule/bestpractices/NonExhaustiveSwitchTest.java | 2 +- .../java/rule/bestpractices/OneDeclarationPerLineTest.java | 2 +- .../lang/java/rule/bestpractices/PreserveStackTraceTest.java | 2 +- .../rule/bestpractices/PrimitiveWrapperInstantiationTest.java | 2 +- .../bestpractices/ReplaceEnumerationWithIteratorTest.java | 2 +- .../java/rule/bestpractices/ReplaceHashtableWithMapTest.java | 2 +- .../java/rule/bestpractices/ReplaceVectorWithListTest.java | 2 +- .../rule/bestpractices/SimplifiableTestAssertionTest.java | 2 +- .../pmd/lang/java/rule/bestpractices/SystemPrintlnTest.java | 2 +- .../UnitTestAssertionsShouldIncludeMessageTest.java | 2 +- .../bestpractices/UnitTestContainsTooManyAssertsTest.java | 2 +- .../rule/bestpractices/UnitTestShouldIncludeAssertTest.java | 2 +- .../bestpractices/UnitTestShouldUseAfterAnnotationTest.java | 2 +- .../bestpractices/UnitTestShouldUseBeforeAnnotationTest.java | 2 +- .../bestpractices/UnitTestShouldUseTestAnnotationTest.java | 2 +- .../rule/bestpractices/UnnecessaryWarningSuppressionTest.java | 2 +- .../java/rule/bestpractices/UnusedFormalParameterTest.java | 2 +- .../lang/java/rule/bestpractices/UnusedLocalVariableTest.java | 2 +- .../lang/java/rule/bestpractices/UnusedPrivateFieldTest.java | 2 +- .../lang/java/rule/bestpractices/UnusedPrivateMethodTest.java | 2 +- .../java/rule/bestpractices/UseCollectionIsEmptyTest.java | 2 +- .../lang/java/rule/bestpractices/UseEnumCollectionsTest.java | 2 +- .../lang/java/rule/bestpractices/UseStandardCharsetsTest.java | 2 +- .../lang/java/rule/bestpractices/UseTryWithResourcesTest.java | 2 +- .../pmd/lang/java/rule/bestpractices/UseVarargsTest.java | 2 +- .../rule/bestpractices/WhileLoopWithLiteralBooleanTest.java | 2 +- .../bestpractices/missingoverride/AbsClassWithInterface.java | 2 +- .../rule/bestpractices/missingoverride/AbstractClass.java | 2 +- .../rule/bestpractices/missingoverride/AmbiguousOverload.java | 2 +- .../rule/bestpractices/missingoverride/AnonClassExample.java | 2 +- .../bestpractices/missingoverride/CloneableInterface.java | 2 +- .../missingoverride/CloneableInterfaceOverride.java | 2 +- .../rule/bestpractices/missingoverride/ConcreteClass.java | 2 +- .../missingoverride/ConcreteClassArrayParams.java | 2 +- .../missingoverride/ConcreteClassTransitive.java | 2 +- .../bestpractices/missingoverride/CovariantReturnType.java | 2 +- .../rule/bestpractices/missingoverride/EnumWithAnonClass.java | 2 +- .../bestpractices/missingoverride/EnumWithInterfaces.java | 2 +- .../missingoverride/GenericInterfaceWithOverloads.java | 2 +- .../missingoverride/GenericWithOverloadsImpl.java | 2 +- .../missingoverride/HierarchyWithSeveralBridges.java | 2 +- .../missingoverride/InterfaceWithNoSuperClass.java | 2 +- .../lang/java/rule/bestpractices/missingoverride/Option.java | 2 +- .../bestpractices/missingoverride/OptionTestCaseOneParam.java | 2 +- .../java/rule/bestpractices/missingoverride/RunnableImpl.java | 2 +- .../missingoverride/SubclassPrivateNoOverride.java | 2 +- .../missingoverride/SubclassWithGenericMethod.java | 2 +- .../bestpractices/missingoverride/SubclassWithStatic.java | 2 +- .../bestpractices/missingoverride/SuperclassWithPrivate.java | 2 +- .../bestpractices/missingoverride/SuperclassWithStatic.java | 2 +- .../switchstmtsshouldhavedefault/SimpleEnum.java | 2 +- .../unusedprivatemethod/ClassWithPublicEnum.java | 2 +- .../unusedprivatemethod/DashboardGraphInnateFilter.java | 2 +- .../unusedprivatemethod/DashboardInnateFilter.java | 2 +- .../lang/java/rule/codestyle/AtLeastOneConstructorTest.java | 2 +- .../pmd/lang/java/rule/codestyle/AvoidDollarSignsTest.java | 2 +- .../rule/codestyle/AvoidProtectedFieldInFinalClassTest.java | 2 +- .../AvoidProtectedMethodInFinalClassNotExtendingTest.java | 2 +- .../lang/java/rule/codestyle/AvoidUsingNativeCodeTest.java | 2 +- .../lang/java/rule/codestyle/BooleanGetMethodNameTest.java | 2 +- .../lang/java/rule/codestyle/CallSuperInConstructorTest.java | 2 +- .../lang/java/rule/codestyle/ClassNamingConventionsTest.java | 2 +- .../java/rule/codestyle/CommentDefaultAccessModifierTest.java | 2 +- .../pmd/lang/java/rule/codestyle/ConfusingTernaryTest.java | 2 +- .../lang/java/rule/codestyle/ControlStatementBracesTest.java | 2 +- .../lang/java/rule/codestyle/EmptyControlStatementTest.java | 2 +- .../EmptyMethodInAbstractClassShouldBeAbstractTest.java | 2 +- .../pmd/lang/java/rule/codestyle/ExtendsObjectTest.java | 2 +- .../FieldDeclarationsShouldBeAtStartOfClassTest.java | 2 +- .../lang/java/rule/codestyle/FieldNamingConventionsTest.java | 2 +- .../java/rule/codestyle/ForLoopShouldBeWhileLoopTest.java | 2 +- .../rule/codestyle/FormalParameterNamingConventionsTest.java | 2 +- .../pmd/lang/java/rule/codestyle/GenericsNamingTest.java | 2 +- .../lang/java/rule/codestyle/IdenticalCatchBranchesTest.java | 2 +- .../java/rule/codestyle/LambdaCanBeMethodReferenceTest.java | 2 +- .../pmd/lang/java/rule/codestyle/LinguisticNamingTest.java | 2 +- .../java/rule/codestyle/LocalHomeNamingConventionTest.java | 2 +- .../codestyle/LocalInterfaceSessionNamingConventionTest.java | 2 +- .../java/rule/codestyle/LocalVariableCouldBeFinalTest.java | 2 +- .../rule/codestyle/LocalVariableNamingConventionsTest.java | 2 +- .../pmd/lang/java/rule/codestyle/LongVariableTest.java | 2 +- .../rule/codestyle/MDBAndSessionBeanNamingConventionTest.java | 2 +- .../java/rule/codestyle/MethodArgumentCouldBeFinalTest.java | 2 +- .../lang/java/rule/codestyle/MethodNamingConventionsTest.java | 2 +- .../pmd/lang/java/rule/codestyle/NoPackageTest.java | 2 +- .../pmd/lang/java/rule/codestyle/OnlyOneReturnTest.java | 2 +- .../pmd/lang/java/rule/codestyle/PackageCaseTest.java | 2 +- .../lang/java/rule/codestyle/PrematureDeclarationTest.java | 2 +- .../rule/codestyle/RemoteInterfaceNamingConventionTest.java | 2 +- .../codestyle/RemoteSessionInterfaceNamingConventionTest.java | 2 +- .../pmd/lang/java/rule/codestyle/ShortClassNameTest.java | 2 +- .../pmd/lang/java/rule/codestyle/ShortMethodNameTest.java | 2 +- .../pmd/lang/java/rule/codestyle/ShortVariableTest.java | 2 +- .../lang/java/rule/codestyle/TooManyStaticImportsTest.java | 2 +- .../rule/codestyle/UnnecessaryAnnotationValueElementTest.java | 2 +- .../lang/java/rule/codestyle/UnnecessaryConstructorTest.java | 2 +- .../rule/codestyle/UnnecessaryFullyQualifiedNameTest.java | 2 +- .../java/rule/codestyle/UnnecessaryLocalBeforeReturnTest.java | 2 +- .../pmd/lang/java/rule/codestyle/UnnecessaryModifierTest.java | 2 +- .../pmd/lang/java/rule/codestyle/UnnecessaryReturnTest.java | 2 +- .../lang/java/rule/codestyle/UnnecessarySemicolonTest.java | 2 +- .../pmd/lang/java/rule/codestyle/UseDiamondOperatorTest.java | 2 +- .../java/rule/codestyle/UseShortArrayInitializerTest.java | 2 +- .../rule/codestyle/UseUnderscoresInNumericLiteralsTest.java | 2 +- .../pmd/lang/java/rule/codestyle/UselessParenthesesTest.java | 2 +- .../lang/java/rule/codestyle/UselessQualifiedThisTest.java | 2 +- .../commentdefaultaccessmodifier/OnlyForTesting.java | 2 +- .../java/rule/design/AbstractClassWithoutAnyMethodTest.java | 2 +- .../java/rule/design/AvoidCatchingGenericExceptionTest.java | 2 +- .../lang/java/rule/design/AvoidDeeplyNestedIfStmtsTest.java | 2 +- .../lang/java/rule/design/AvoidRethrowingExceptionTest.java | 2 +- .../design/AvoidThrowingNewInstanceOfSameExceptionTest.java | 2 +- .../rule/design/AvoidThrowingNullPointerExceptionTest.java | 2 +- .../java/rule/design/AvoidThrowingRawExceptionTypesTest.java | 2 +- .../rule/design/AvoidUncheckedExceptionsInSignaturesTest.java | 2 +- .../ClassWithOnlyPrivateConstructorsShouldBeFinalTest.java | 2 +- .../pmd/lang/java/rule/design/CognitiveComplexityTest.java | 2 +- .../lang/java/rule/design/CollapsibleIfStatementsTest.java | 2 +- .../pmd/lang/java/rule/design/CouplingBetweenObjectsTest.java | 2 +- .../pmd/lang/java/rule/design/CyclomaticComplexityTest.java | 2 +- .../sourceforge/pmd/lang/java/rule/design/DataClassTest.java | 2 +- .../lang/java/rule/design/DoNotExtendJavaLangErrorTest.java | 2 +- .../pmd/lang/java/rule/design/ExceptionAsFlowControlTest.java | 2 +- .../pmd/lang/java/rule/design/ExcessiveImportsTest.java | 2 +- .../pmd/lang/java/rule/design/ExcessiveParameterListTest.java | 2 +- .../pmd/lang/java/rule/design/ExcessivePublicCountTest.java | 2 +- .../lang/java/rule/design/FinalFieldCouldBeStaticTest.java | 2 +- .../sourceforge/pmd/lang/java/rule/design/GodClassTest.java | 2 +- .../pmd/lang/java/rule/design/ImmutableFieldTest.java | 2 +- .../pmd/lang/java/rule/design/LawOfDemeterTest.java | 2 +- .../pmd/lang/java/rule/design/LogicInversionTest.java | 2 +- .../pmd/lang/java/rule/design/LoosePackageCouplingTest.java | 2 +- .../pmd/lang/java/rule/design/MutableStaticStateTest.java | 2 +- .../pmd/lang/java/rule/design/NPathComplexityTest.java | 2 +- .../sourceforge/pmd/lang/java/rule/design/NcssCountTest.java | 2 +- .../java/rule/design/SignatureDeclareThrowsExceptionTest.java | 2 +- .../pmd/lang/java/rule/design/SimplifiedTernaryTest.java | 2 +- .../lang/java/rule/design/SimplifyBooleanExpressionsTest.java | 2 +- .../pmd/lang/java/rule/design/SimplifyBooleanReturnsTest.java | 2 +- .../pmd/lang/java/rule/design/SimplifyConditionalTest.java | 2 +- .../pmd/lang/java/rule/design/SingularFieldTest.java | 2 +- .../pmd/lang/java/rule/design/SwitchDensityTest.java | 2 +- .../pmd/lang/java/rule/design/TooManyFieldsTest.java | 2 +- .../pmd/lang/java/rule/design/TooManyMethodsTest.java | 2 +- .../pmd/lang/java/rule/design/UseObjectForClearerAPITest.java | 2 +- .../pmd/lang/java/rule/design/UseUtilityClassTest.java | 2 +- .../lang/java/rule/design/UselessOverridingMethodTest.java | 2 +- .../lang/java/rule/design/donotextendjavalangerror/Error.java | 2 +- .../design/signaturedeclarethrowsexception/MyTestCase.java | 2 +- .../pmd/lang/java/rule/documentation/CommentContentTest.java | 2 +- .../pmd/lang/java/rule/documentation/CommentRequiredTest.java | 2 +- .../pmd/lang/java/rule/documentation/CommentSizeTest.java | 2 +- .../rule/documentation/UncommentedEmptyConstructorTest.java | 2 +- .../rule/documentation/UncommentedEmptyMethodBodyTest.java | 2 +- .../lang/java/rule/errorprone/AssignmentInOperandTest.java | 2 +- .../java/rule/errorprone/AssignmentToNonFinalStaticTest.java | 2 +- .../java/rule/errorprone/AvoidAssertAsIdentifierTest.java | 2 +- .../errorprone/AvoidBranchingStatementAsLastInLoopTest.java | 2 +- .../lang/java/rule/errorprone/AvoidCallingFinalizeTest.java | 2 +- .../pmd/lang/java/rule/errorprone/AvoidCatchingNPETest.java | 2 +- .../lang/java/rule/errorprone/AvoidCatchingThrowableTest.java | 2 +- .../AvoidDecimalLiteralsInBigDecimalConstructorTest.java | 2 +- .../lang/java/rule/errorprone/AvoidDuplicateLiteralsTest.java | 2 +- .../lang/java/rule/errorprone/AvoidEnumAsIdentifierTest.java | 2 +- .../rule/errorprone/AvoidFieldNameMatchingMethodNameTest.java | 2 +- .../rule/errorprone/AvoidFieldNameMatchingTypeNameTest.java | 2 +- .../errorprone/AvoidInstanceofChecksInCatchClauseTest.java | 2 +- .../java/rule/errorprone/AvoidLiteralsInIfConditionTest.java | 2 +- .../rule/errorprone/AvoidLosingExceptionInformationTest.java | 2 +- .../java/rule/errorprone/AvoidMultipleUnaryOperatorsTest.java | 2 +- .../lang/java/rule/errorprone/AvoidUsingOctalValuesTest.java | 2 +- .../pmd/lang/java/rule/errorprone/BrokenNullCheckTest.java | 2 +- .../pmd/lang/java/rule/errorprone/CallSuperFirstTest.java | 2 +- .../pmd/lang/java/rule/errorprone/CallSuperLastTest.java | 2 +- .../pmd/lang/java/rule/errorprone/CheckSkipResultTest.java | 2 +- .../rule/errorprone/ClassCastExceptionWithToArrayTest.java | 2 +- .../java/rule/errorprone/CloneMethodMustBePublicTest.java | 2 +- .../errorprone/CloneMethodMustImplementCloneableTest.java | 2 +- .../CloneMethodReturnTypeMustMatchClassNameTest.java | 2 +- .../pmd/lang/java/rule/errorprone/CloseResourceTest.java | 2 +- .../java/rule/errorprone/CompareObjectsWithEqualsTest.java | 2 +- .../pmd/lang/java/rule/errorprone/ComparisonWithNaNTest.java | 2 +- .../rule/errorprone/ConfusingArgumentToVarargsMethodTest.java | 2 +- .../errorprone/ConstructorCallsOverridableMethodTest.java | 2 +- .../pmd/lang/java/rule/errorprone/DetachedTestCaseTest.java | 2 +- .../errorprone/DoNotCallGarbageCollectionExplicitlyTest.java | 2 +- .../rule/errorprone/DoNotExtendJavaLangThrowableTest.java | 2 +- .../lang/java/rule/errorprone/DoNotHardCodeSDCardTest.java | 2 +- .../rule/errorprone/DoNotThrowExceptionInFinallyTest.java | 2 +- .../pmd/lang/java/rule/errorprone/DontImportSunTest.java | 2 +- .../rule/errorprone/DontUseFloatTypeForLoopIndicesTest.java | 2 +- .../pmd/lang/java/rule/errorprone/EmptyCatchBlockTest.java | 2 +- .../pmd/lang/java/rule/errorprone/EmptyFinalizerTest.java | 2 +- .../pmd/lang/java/rule/errorprone/EqualsNullTest.java | 2 +- .../rule/errorprone/FinalizeDoesNotCallSuperFinalizeTest.java | 2 +- .../rule/errorprone/FinalizeOnlyCallsSuperFinalizeTest.java | 2 +- .../pmd/lang/java/rule/errorprone/FinalizeOverloadedTest.java | 2 +- .../java/rule/errorprone/FinalizeShouldBeProtectedTest.java | 2 +- .../lang/java/rule/errorprone/IdempotentOperationsTest.java | 2 +- .../java/rule/errorprone/ImplicitSwitchFallThroughTest.java | 2 +- .../java/rule/errorprone/InstantiationToGetClassTest.java | 2 +- .../java/rule/errorprone/InvalidLogMessageFormatTest.java | 2 +- .../pmd/lang/java/rule/errorprone/JUnitSpellingTest.java | 2 +- .../pmd/lang/java/rule/errorprone/JUnitStaticSuiteTest.java | 2 +- .../pmd/lang/java/rule/errorprone/JumbledIncrementerTest.java | 2 +- .../errorprone/MethodWithSameNameAsEnclosingClassTest.java | 2 +- .../pmd/lang/java/rule/errorprone/MisplacedNullCheckTest.java | 2 +- .../java/rule/errorprone/MissingSerialVersionUIDBase.java | 2 +- .../java/rule/errorprone/MissingSerialVersionUIDTest.java | 2 +- .../MissingStaticMethodInNonInstantiatableClassTest.java | 2 +- .../pmd/lang/java/rule/errorprone/MoreThanOneLoggerTest.java | 2 +- .../pmd/lang/java/rule/errorprone/MyInterface.java | 2 +- .../lang/java/rule/errorprone/NonCaseLabelInSwitchTest.java | 2 +- .../lang/java/rule/errorprone/NonSerializableClassTest.java | 2 +- .../lang/java/rule/errorprone/NonStaticInitializerTest.java | 2 +- .../pmd/lang/java/rule/errorprone/NullAssignmentTest.java | 2 +- .../rule/errorprone/OverrideBothEqualsAndHashcodeTest.java | 2 +- .../java/rule/errorprone/ProperCloneImplementationTest.java | 2 +- .../pmd/lang/java/rule/errorprone/ProperLoggerTest.java | 2 +- .../errorprone/ReturnEmptyCollectionRatherThanNullTest.java | 2 +- .../lang/java/rule/errorprone/ReturnFromFinallyBlockTest.java | 2 +- .../java/rule/errorprone/SimpleDateFormatNeedsLocaleTest.java | 2 +- .../lang/java/rule/errorprone/SingleMethodSingletonTest.java | 2 +- .../errorprone/SingletonClassReturningNewInstanceTest.java | 2 +- .../java/rule/errorprone/StaticEJBFieldShouldBeFinalTest.java | 2 +- .../errorprone/StringBufferInstantiationWithCharTest.java | 2 +- .../java/rule/errorprone/SuspiciousEqualsMethodNameTest.java | 2 +- .../rule/errorprone/SuspiciousHashcodeMethodNameTest.java | 2 +- .../lang/java/rule/errorprone/SuspiciousOctalEscapeTest.java | 2 +- .../java/rule/errorprone/TestClassWithoutTestCasesTest.java | 2 +- .../java/rule/errorprone/UnconditionalIfStatementTest.java | 2 +- .../java/rule/errorprone/UnnecessaryBooleanAssertionTest.java | 2 +- .../lang/java/rule/errorprone/UnnecessaryCaseChangeTest.java | 2 +- .../rule/errorprone/UnnecessaryConversionTemporaryTest.java | 2 +- .../java/rule/errorprone/UnusedNullCheckInEqualsTest.java | 2 +- .../java/rule/errorprone/UseCorrectExceptionLoggingTest.java | 2 +- .../java/rule/errorprone/UseEqualsToCompareStringsTest.java | 2 +- .../rule/errorprone/UseLocaleWithCaseConversionsTest.java | 2 +- .../lang/java/rule/errorprone/UseProperClassLoaderTest.java | 2 +- .../java/rule/errorprone/UselessOperationOnImmutableTest.java | 2 +- .../rule/errorprone/closeresource/CustomStringWriter.java | 2 +- .../multithreading/AvoidSynchronizedAtMethodLevelTest.java | 2 +- .../rule/multithreading/AvoidSynchronizedStatementTest.java | 2 +- .../lang/java/rule/multithreading/AvoidThreadGroupTest.java | 2 +- .../lang/java/rule/multithreading/AvoidUsingVolatileTest.java | 2 +- .../lang/java/rule/multithreading/DoNotUseThreadsTest.java | 2 +- .../lang/java/rule/multithreading/DontCallThreadRunTest.java | 2 +- .../java/rule/multithreading/DoubleCheckedLockingTest.java | 2 +- .../java/rule/multithreading/NonThreadSafeSingletonTest.java | 2 +- .../multithreading/UnsynchronizedStaticFormatterTest.java | 2 +- .../java/rule/multithreading/UseConcurrentHashMapTest.java | 2 +- .../rule/multithreading/UseNotifyAllInsteadOfNotifyTest.java | 2 +- .../pmd/lang/java/rule/performance/AddEmptyStringTest.java | 2 +- .../java/rule/performance/AppendCharacterWithCharTest.java | 2 +- .../pmd/lang/java/rule/performance/AvoidArrayLoopsTest.java | 2 +- .../java/rule/performance/AvoidCalendarDateCreationTest.java | 2 +- .../pmd/lang/java/rule/performance/AvoidFileStreamTest.java | 2 +- .../performance/AvoidInstantiatingObjectsInLoopsTest.java | 2 +- .../java/rule/performance/BigIntegerInstantiationTest.java | 2 +- .../rule/performance/ConsecutiveAppendsShouldReuseTest.java | 2 +- .../java/rule/performance/ConsecutiveLiteralAppendsTest.java | 2 +- .../rule/performance/InefficientEmptyStringCheckTest.java | 2 +- .../java/rule/performance/InefficientStringBufferingTest.java | 2 +- .../performance/InsufficientStringBufferDeclarationTest.java | 2 +- .../java/rule/performance/OptimizableToArrayCallTest.java | 2 +- .../java/rule/performance/RedundantFieldInitializerTest.java | 2 +- .../lang/java/rule/performance/StringInstantiationTest.java | 2 +- .../pmd/lang/java/rule/performance/StringToStringTest.java | 2 +- .../java/rule/performance/TooFewBranchesForSwitchTest.java | 2 +- .../rule/performance/UseArrayListInsteadOfVectorTest.java | 2 +- .../pmd/lang/java/rule/performance/UseArraysAsListTest.java | 2 +- .../pmd/lang/java/rule/performance/UseIndexOfCharTest.java | 2 +- .../lang/java/rule/performance/UseStringBufferLengthTest.java | 2 +- .../lang/java/rule/performance/UselessStringValueOfTest.java | 2 +- .../net/sourceforge/pmd/ast/FullTypeAnnotations.java | 2 +- .../resources/net/sourceforge/pmd/cli/EmptyIfStatement.java | 4 ++-- .../net/sourceforge/pmd/lang/java/ast/ParserCornerCases.java | 2 +- .../sourceforge/pmd/lang/java/ast/ParserCornerCases17.java | 2 +- .../sourceforge/pmd/lang/java/ast/ParserCornerCases18.java | 2 +- .../private_method_in_inner_class_interface1.java | 2 +- .../private_method_in_inner_class_interface2.java | 2 +- .../pmd/lang/java/cpd/testdata/StringTemplateReduction2.java | 2 +- 595 files changed, 596 insertions(+), 596 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java index 461b09c5ae2..69571972e2e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAmbiguousName.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAmbiguousName.java index 9bab43d8977..8f1593c21ae 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAmbiguousName.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAmbiguousName.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnnotation.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnnotation.java index d69c0e3ac51..69d1e6da73f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnnotation.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnnotation.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnnotationMemberList.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnnotationMemberList.java index d36eab477a2..dfe8513d137 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnnotationMemberList.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnnotationMemberList.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnnotationTypeBody.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnnotationTypeBody.java index e350c9f85ba..70ccdab9cee 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnnotationTypeBody.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnnotationTypeBody.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnnotationTypeDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnnotationTypeDeclaration.java index f2551b3d1ec..3b186e59e0b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnnotationTypeDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnnotationTypeDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnonymousClassDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnonymousClassDeclaration.java index f9d035a1583..33fa2bbff38 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnonymousClassDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAnonymousClassDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArgumentList.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArgumentList.java index 828396b006c..551dbd02da8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArgumentList.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArgumentList.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayAccess.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayAccess.java index b05513c467e..3e123cc3f75 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayAccess.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayAccess.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayAllocation.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayAllocation.java index e76d88dafd8..8f7c3707f3c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayAllocation.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayAllocation.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayDimExpr.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayDimExpr.java index a281c9e4b46..f0b704328ec 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayDimExpr.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayDimExpr.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayDimensions.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayDimensions.java index f9041231d85..9eedf00e8fd 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayDimensions.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayDimensions.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayInitializer.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayInitializer.java index eea8f50e9ad..e178f89ec10 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayInitializer.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayInitializer.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayType.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayType.java index 100dea3952d..e06e5b53ee0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayType.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayType.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayTypeDim.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayTypeDim.java index 3e97796c5eb..8762732a738 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayTypeDim.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayTypeDim.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAssertStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAssertStatement.java index 65865b54e73..907c214faed 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAssertStatement.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAssertStatement.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAssignmentExpression.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAssignmentExpression.java index 8364a91776c..0e5d4e57eb5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAssignmentExpression.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAssignmentExpression.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTBlock.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTBlock.java index 605b264c7c1..88bea83dd12 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTBlock.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTBlock.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTBodyDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTBodyDeclaration.java index 69106d9faf3..e7670f1ff6f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTBodyDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTBodyDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTBooleanLiteral.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTBooleanLiteral.java index ac5f1a43aa7..80318d87587 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTBooleanLiteral.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTBooleanLiteral.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTBreakStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTBreakStatement.java index f6931a6ac59..b953bbff86e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTBreakStatement.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTBreakStatement.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCastExpression.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCastExpression.java index 7ce73d58571..1abcb018880 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCastExpression.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCastExpression.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCatchClause.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCatchClause.java index e9f6b2f9c56..2868c8a6fcb 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCatchClause.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCatchClause.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCatchParameter.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCatchParameter.java index a3e0aefb67a..37d3c7a29f9 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCatchParameter.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCatchParameter.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCharLiteral.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCharLiteral.java index 2d1bef042bd..b7e0e6abdce 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCharLiteral.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCharLiteral.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassBody.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassBody.java index 85ba96d0734..ad8c04989e0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassBody.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassBody.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassDeclaration.java index 9d0e280cbea..429c4a5c7a9 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassLiteral.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassLiteral.java index 2dfba4cb91a..42850799c4e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassLiteral.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassLiteral.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassType.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassType.java index 0fd3c90229a..e1bc4fe1800 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassType.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassType.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java index 7d3729f074e..8a6b30b5a21 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompilationUnit.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConditionalExpression.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConditionalExpression.java index eaa8450c446..42fed7128a8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConditionalExpression.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConditionalExpression.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorCall.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorCall.java index c70ac0f2929..51c55bd7154 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorCall.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorCall.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclaration.java index 4d52a92d860..4ee43ee4668 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTContinueStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTContinueStatement.java index c00fbb9697a..04edf21ac69 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTContinueStatement.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTContinueStatement.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTDefaultValue.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTDefaultValue.java index 122106cbeed..bd6bfed66f7 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTDefaultValue.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTDefaultValue.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTDoStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTDoStatement.java index 0b89f8b6606..15b4e2fd9ee 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTDoStatement.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTDoStatement.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTEmptyStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTEmptyStatement.java index a8a178633a0..42cfa605727 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTEmptyStatement.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTEmptyStatement.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTEnumBody.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTEnumBody.java index 0a81de67316..ee3a6ba3e43 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTEnumBody.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTEnumBody.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTEnumConstant.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTEnumConstant.java index 4832a5d7991..e399113ba2b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTEnumConstant.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTEnumConstant.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTEnumDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTEnumDeclaration.java index bf0ad882bc0..73695d48830 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTEnumDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTEnumDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExecutableDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExecutableDeclaration.java index 850cc71d2e0..ea7a624cf98 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExecutableDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExecutableDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExplicitConstructorInvocation.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExplicitConstructorInvocation.java index ea3a24c77d4..095e8c49196 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExplicitConstructorInvocation.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExplicitConstructorInvocation.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExpression.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExpression.java index 571d05b5bc6..ccaef468bc8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExpression.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExpression.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExtendsList.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExtendsList.java index 607cf81d6fe..a38c00ee597 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExtendsList.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExtendsList.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldAccess.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldAccess.java index 55415818ed1..e9803b5cad3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldAccess.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldAccess.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclaration.java index e3ba01bc4a4..f6267635cc5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFinallyClause.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFinallyClause.java index 0497238c45e..b02380adc77 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFinallyClause.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFinallyClause.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTForInit.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTForInit.java index eeeb462029c..6a7f3a113d0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTForInit.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTForInit.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTForStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTForStatement.java index e2c744efef3..ecb5857c8c8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTForStatement.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTForStatement.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTForUpdate.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTForUpdate.java index 376a58731fa..9cd3a23c5ae 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTForUpdate.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTForUpdate.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTForeachStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTForeachStatement.java index 65734e85f61..2b373b2f900 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTForeachStatement.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTForeachStatement.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameter.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameter.java index 1151c126628..e0ce7809cbd 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameter.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameter.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameters.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameters.java index d449bbb7865..2f167c1b29a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameters.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameters.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTIfStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTIfStatement.java index f0bac784ccd..f377c44c67d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTIfStatement.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTIfStatement.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTImplementsList.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTImplementsList.java index 61b7dc22ac0..44882c4fb4a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTImplementsList.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTImplementsList.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTImportDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTImportDeclaration.java index 8b3b3750065..dbdf373f15b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTImportDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTImportDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTInitializer.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTInitializer.java index 25412a74481..21febaab347 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTInitializer.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTInitializer.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLabeledStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLabeledStatement.java index 7e1edc84d9b..fa51efa8d25 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLabeledStatement.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLabeledStatement.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLambdaExpression.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLambdaExpression.java index 3c22c5a1132..7688c8bd96e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLambdaExpression.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLambdaExpression.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTList.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTList.java index 07bd5fdbe2e..b546ff69d25 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTList.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTList.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLiteral.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLiteral.java index b57de1eada9..a4b366e3418 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLiteral.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLiteral.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLocalVariableDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLocalVariableDeclaration.java index ce7ccf27d28..ba25ab8acf2 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLocalVariableDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLocalVariableDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMemberValue.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMemberValue.java index 4fecc7e4df6..d1d1e4e21d7 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMemberValue.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMemberValue.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMemberValueArrayInitializer.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMemberValueArrayInitializer.java index 60cc7deee49..dd332c1d1fd 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMemberValueArrayInitializer.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMemberValueArrayInitializer.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMemberValuePair.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMemberValuePair.java index 02d0fcb2feb..eb8b33ef993 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMemberValuePair.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMemberValuePair.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodCall.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodCall.java index 3ddb812b9f3..2730a7853c4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodCall.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodCall.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java index 56ad3f0c58a..30c2d7b2b19 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleDeclaration.java index 9c2a0237534..a61c9aea7c2 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleDirective.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleDirective.java index a9bf8c5d910..e6b8346fa20 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleDirective.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleDirective.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleExportsDirective.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleExportsDirective.java index e20dbf22690..a0c17fb58af 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleExportsDirective.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleExportsDirective.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleName.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleName.java index af72a7f3c4b..fa5b87cae3d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleName.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleName.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleOpensDirective.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleOpensDirective.java index d412faa88c5..06546407324 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleOpensDirective.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleOpensDirective.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleProvidesDirective.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleProvidesDirective.java index 9c897e82469..e27fcb441de 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleProvidesDirective.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleProvidesDirective.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleRequiresDirective.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleRequiresDirective.java index c696aba3b37..1893057ab81 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleRequiresDirective.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleRequiresDirective.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleUsesDirective.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleUsesDirective.java index 6c75bca494f..e851782e25c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleUsesDirective.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleUsesDirective.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTNullLiteral.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTNullLiteral.java index bbc678c23ca..4e134781237 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTNullLiteral.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTNullLiteral.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTNumericLiteral.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTNumericLiteral.java index c348c8b9f6c..c07841c4c22 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTNumericLiteral.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTNumericLiteral.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTPackageDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTPackageDeclaration.java index 40cf4b0f3bb..e5bb4f7cafe 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTPackageDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTPackageDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTPermitsList.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTPermitsList.java index 87f99756324..2722afae487 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTPermitsList.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTPermitsList.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTPrimaryExpression.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTPrimaryExpression.java index a872b89d563..14a651529f3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTPrimaryExpression.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTPrimaryExpression.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTPrimitiveType.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTPrimitiveType.java index 2ed2a08b740..c6998ba14f3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTPrimitiveType.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTPrimitiveType.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTReferenceType.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTReferenceType.java index bfdd8cb1e34..0031e5a1662 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTReferenceType.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTReferenceType.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTResource.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTResource.java index 577c28d17d1..6e6c56e4911 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTResource.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTResource.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTResourceList.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTResourceList.java index 9c977acb782..bd44e5ad04f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTResourceList.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTResourceList.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTReturnStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTReturnStatement.java index bd95e6a0d1d..7e3978ad0c8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTReturnStatement.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTReturnStatement.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTStatement.java index f88ec6a3138..fa8e1ec2e68 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTStatement.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTStatement.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTStatementExpressionList.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTStatementExpressionList.java index fbf845d773a..fdf659e4bee 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTStatementExpressionList.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTStatementExpressionList.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTStringLiteral.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTStringLiteral.java index 640cc6c589f..1b0af7a68a2 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTStringLiteral.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTStringLiteral.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSuperExpression.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSuperExpression.java index b565424356e..fd05f47654f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSuperExpression.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSuperExpression.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchArrowBranch.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchArrowBranch.java index f7dc8b77ba3..78f8e0345bc 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchArrowBranch.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchArrowBranch.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchArrowRHS.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchArrowRHS.java index 191984c2c31..0627d7da4a2 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchArrowRHS.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchArrowRHS.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchBranch.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchBranch.java index bb039e81dbe..7582c86aaaa 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchBranch.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchBranch.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchExpression.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchExpression.java index c25ded10732..9e703723be2 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchExpression.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchExpression.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchFallthroughBranch.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchFallthroughBranch.java index a1e8ecff8a2..e95041abc7c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchFallthroughBranch.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchFallthroughBranch.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabel.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabel.java index 2b489d4fde4..93491bf09bc 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabel.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabel.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLike.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLike.java index 4eaa9af0d59..b7cd1c98751 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLike.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLike.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchStatement.java index 115ab5c866a..58aa8856b83 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchStatement.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchStatement.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSynchronizedStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSynchronizedStatement.java index b8e92e39ce5..ac4b05bb9bd 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSynchronizedStatement.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSynchronizedStatement.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTThisExpression.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTThisExpression.java index 145dd50dc98..7d903c967e2 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTThisExpression.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTThisExpression.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTThrowStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTThrowStatement.java index 150a8e8840f..0253ac01618 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTThrowStatement.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTThrowStatement.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTopLevelDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTopLevelDeclaration.java index 027621ca925..73d1177a249 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTopLevelDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTopLevelDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTryStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTryStatement.java index b2c40a9910d..216faedd5e1 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTryStatement.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTryStatement.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTType.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTType.java index b5d5a0b4526..2080dd5483c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTType.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTType.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeArguments.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeArguments.java index 3ed33dc5d12..08b776a55d2 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeArguments.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeArguments.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeDeclaration.java index dca287f136e..fdd382e517f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeParameter.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeParameter.java index 6c67feedde1..5e9b6599008 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeParameter.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeParameter.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeParameters.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeParameters.java index b6efbe872ce..37e90c2218c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeParameters.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeParameters.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTUnaryExpression.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTUnaryExpression.java index 3e6235c7d1a..311338e5d5c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTUnaryExpression.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTUnaryExpression.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableAccess.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableAccess.java index 7263898d72f..a7441e0cd96 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableAccess.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableAccess.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclarator.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclarator.java index d27ba7a7d0a..1c12cd009b4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclarator.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclarator.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableId.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableId.java index d917a5db810..9fb49073851 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableId.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableId.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVoidType.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVoidType.java index 06dc15cf5f6..3aabd86b56e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVoidType.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVoidType.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTWhileStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTWhileStatement.java index ebc39d8d0af..8b5b23eac20 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTWhileStatement.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTWhileStatement.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTWildcardType.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTWildcardType.java index 09fa07f8cc2..8f74b573209 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTWildcardType.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTWildcardType.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTYieldStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTYieldStatement.java index 16fdd17582b..e076f68a1d9 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTYieldStatement.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTYieldStatement.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractExecutableDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractExecutableDeclaration.java index c6c37e7f159..df469338919 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractExecutableDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractExecutableDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaPattern.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaPattern.java index caacac7312e..1c93cbf96b7 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaPattern.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaPattern.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaTypeNode.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaTypeNode.java index a24edf09d41..4b7126988ea 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaTypeNode.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaTypeNode.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractPackageNameModuleDirective.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractPackageNameModuleDirective.java index 9dd98db9158..ece7666e8e1 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractPackageNameModuleDirective.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractPackageNameModuleDirective.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractTypeBodyDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractTypeBodyDeclaration.java index c916eb2780e..55515dc0c67 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractTypeBodyDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractTypeBodyDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractTypeDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractTypeDeclaration.java index 141272c607d..c1f8ebf2989 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractTypeDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractTypeDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractTypedSymbolDeclarator.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractTypedSymbolDeclarator.java index e9c9022eb83..a3a3b11d73b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractTypedSymbolDeclarator.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractTypedSymbolDeclarator.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/Annotatable.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/Annotatable.java index 3e02925d2c8..e4258437e9f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/Annotatable.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/Annotatable.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AssignmentOp.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AssignmentOp.java index 584b640b2a1..cfc411feb08 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AssignmentOp.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AssignmentOp.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/BinaryOp.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/BinaryOp.java index e660e51ed8f..e9957e5b325 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/BinaryOp.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/BinaryOp.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaComment.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaComment.java index b501ba5c3db..714d29da0b9 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaComment.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaComment.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaNode.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaNode.java index 230b72ec570..294f2fdadc3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaNode.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaNode.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaVisitorBase.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaVisitorBase.java index 984523e9ee8..767f06b9734 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaVisitorBase.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavaVisitorBase.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavadocComment.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavadocComment.java index 8aea22e0c24..6cf3ac566d5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavadocComment.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JavadocComment.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ReturnScopeNode.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ReturnScopeNode.java index acdb6108e11..48ef8f14975 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ReturnScopeNode.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ReturnScopeNode.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/TypeNode.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/TypeNode.java index aea94a9e027..7d977e644e5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/TypeNode.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/TypeNode.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/package-info.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/package-info.java index 406b6fdfe04..9332936a74b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/package-info.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/package-info.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/javadoc/JavadocTag.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/javadoc/JavadocTag.java index 79f599dec37..c012d2b784c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/javadoc/JavadocTag.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/javadoc/JavadocTag.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/CognitiveComplexityVisitor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/CognitiveComplexityVisitor.java index 9bcf86b6aa5..2f704d670e9 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/CognitiveComplexityVisitor.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/CognitiveComplexityVisitor.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/NPathMetricCalculator.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/NPathMetricCalculator.java index d1ac42a47a0..2244f19ce35 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/NPathMetricCalculator.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/NPathMetricCalculator.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AccessorClassGenerationRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AccessorClassGenerationRule.java index 076a1521613..a3859456bf1 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AccessorClassGenerationRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AccessorClassGenerationRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AccessorMethodGenerationRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AccessorMethodGenerationRule.java index fe906511a89..4aef7a34031 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AccessorMethodGenerationRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AccessorMethodGenerationRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ArrayIsStoredDirectlyRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ArrayIsStoredDirectlyRule.java index 91d02008d03..afa7e1092e5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ArrayIsStoredDirectlyRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ArrayIsStoredDirectlyRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningCatchVariablesRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningCatchVariablesRule.java index 5403f02c547..f75f9811cd8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningCatchVariablesRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningCatchVariablesRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java index 4c0658a9f2c..2f9218c8f94 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningParametersRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningParametersRule.java index ed49d1836aa..0f3711c2e0e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningParametersRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningParametersRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java index 10cf14200e5..c66633ee1fc 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/GuardLogStatementRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/GuardLogStatementRule.java index e51a08b0781..22975c940a4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/GuardLogStatementRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/GuardLogStatementRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitAssertionsShouldIncludeMessageRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitAssertionsShouldIncludeMessageRule.java index 4da48f44b07..3917356c4e0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitAssertionsShouldIncludeMessageRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitAssertionsShouldIncludeMessageRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestContainsTooManyAssertsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestContainsTooManyAssertsRule.java index 13b9d247e13..164db22c17e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestContainsTooManyAssertsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestContainsTooManyAssertsRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java index 452e67d033d..6f4ff918627 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitUseExpectedRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitUseExpectedRule.java index 5deb9dadfe2..1a7f7a9be27 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitUseExpectedRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitUseExpectedRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/LooseCouplingRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/LooseCouplingRule.java index fee7f3bb799..c5a8e2960a7 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/LooseCouplingRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/LooseCouplingRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/MethodReturnsInternalArrayRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/MethodReturnsInternalArrayRule.java index db2480b3a42..a3742416112 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/MethodReturnsInternalArrayRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/MethodReturnsInternalArrayRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/MissingOverrideRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/MissingOverrideRule.java index da2fba47eaf..be1304d07aa 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/MissingOverrideRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/MissingOverrideRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/PreserveStackTraceRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/PreserveStackTraceRule.java index 229e8a5da03..639d5ed5f9e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/PreserveStackTraceRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/PreserveStackTraceRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestAssertionsShouldIncludeMessageRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestAssertionsShouldIncludeMessageRule.java index 78be7c765e2..52c597d4029 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestAssertionsShouldIncludeMessageRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestAssertionsShouldIncludeMessageRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestContainsTooManyAssertsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestContainsTooManyAssertsRule.java index 42168a10b57..a574a555673 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestContainsTooManyAssertsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestContainsTooManyAssertsRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertRule.java index 3f071aa7130..21608823e9e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedFormalParameterRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedFormalParameterRule.java index 76dd7645f71..50a8d733f82 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedFormalParameterRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedFormalParameterRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLocalVariableRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLocalVariableRule.java index c67f80ebe4d..d9d5267372e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLocalVariableRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLocalVariableRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateFieldRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateFieldRule.java index 21ddd90a574..26a6c869a06 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateFieldRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateFieldRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseCollectionIsEmptyRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseCollectionIsEmptyRule.java index 36f72991234..83f685fd441 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseCollectionIsEmptyRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseCollectionIsEmptyRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseEnumCollectionsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseEnumCollectionsRule.java index a90b9715446..be7c774c076 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseEnumCollectionsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseEnumCollectionsRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/AbstractNamingConventionRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/AbstractNamingConventionRule.java index 4c1503392dc..506b9610410 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/AbstractNamingConventionRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/AbstractNamingConventionRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/AtLeastOneConstructorRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/AtLeastOneConstructorRule.java index 2f0aea0edb6..5ee5d0597db 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/AtLeastOneConstructorRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/AtLeastOneConstructorRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ClassNamingConventionsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ClassNamingConventionsRule.java index 3849bd4866c..095a450ac9d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ClassNamingConventionsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ClassNamingConventionsRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/CommentDefaultAccessModifierRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/CommentDefaultAccessModifierRule.java index dee9921d2d8..c027adfe6cd 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/CommentDefaultAccessModifierRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/CommentDefaultAccessModifierRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryRule.java index bed90127c0c..dcf79844cf4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/EmptyControlStatementRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/EmptyControlStatementRule.java index 6c10f58259a..b4ada01dc8f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/EmptyControlStatementRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/EmptyControlStatementRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/FieldDeclarationsShouldBeAtStartOfClassRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/FieldDeclarationsShouldBeAtStartOfClassRule.java index 7e0efbbdc79..e381fa6f981 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/FieldDeclarationsShouldBeAtStartOfClassRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/FieldDeclarationsShouldBeAtStartOfClassRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/FieldNamingConventionsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/FieldNamingConventionsRule.java index 7b0f65506af..e92b44035f9 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/FieldNamingConventionsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/FieldNamingConventionsRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/FormalParameterNamingConventionsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/FormalParameterNamingConventionsRule.java index 57cd8ee6c80..7d63e37ffae 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/FormalParameterNamingConventionsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/FormalParameterNamingConventionsRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesRule.java index c9f3de30067..36895906b83 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LambdaCanBeMethodReferenceRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LambdaCanBeMethodReferenceRule.java index ddfe188625d..51f8beb1ef9 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LambdaCanBeMethodReferenceRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LambdaCanBeMethodReferenceRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableCouldBeFinalRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableCouldBeFinalRule.java index 2fae99dd5bb..a0a5e4a1773 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableCouldBeFinalRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableCouldBeFinalRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableNamingConventionsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableNamingConventionsRule.java index 928ed24a475..05873c4aa5c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableNamingConventionsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableNamingConventionsRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/MethodArgumentCouldBeFinalRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/MethodArgumentCouldBeFinalRule.java index 23b180e761d..89c25d18fc8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/MethodArgumentCouldBeFinalRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/MethodArgumentCouldBeFinalRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/MethodNamingConventionsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/MethodNamingConventionsRule.java index 25d82c9cf46..648d4f8c210 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/MethodNamingConventionsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/MethodNamingConventionsRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/OnlyOneReturnRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/OnlyOneReturnRule.java index 34813ecfc45..7414be76b4f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/OnlyOneReturnRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/OnlyOneReturnRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/PrematureDeclarationRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/PrematureDeclarationRule.java index 8571d76a97b..aaa44fa310e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/PrematureDeclarationRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/PrematureDeclarationRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java index ee20fbd19c7..cee6ab5c463 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameRule.java index 7914866909f..0db2edde6dc 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryLocalBeforeReturnRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryLocalBeforeReturnRule.java index d0c879d67e9..b5582878a98 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryLocalBeforeReturnRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryLocalBeforeReturnRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryModifierRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryModifierRule.java index 97c9a263b84..2509b124320 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryModifierRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryModifierRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java index 39a3f56fbd7..f70f2163cf0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/AvoidDeeplyNestedIfStmtsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/AvoidDeeplyNestedIfStmtsRule.java index 7da5deafa5b..136907f51a2 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/AvoidDeeplyNestedIfStmtsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/AvoidDeeplyNestedIfStmtsRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/AvoidThrowingNullPointerExceptionRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/AvoidThrowingNullPointerExceptionRule.java index ec29215ddfd..aff1824640d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/AvoidThrowingNullPointerExceptionRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/AvoidThrowingNullPointerExceptionRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CouplingBetweenObjectsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CouplingBetweenObjectsRule.java index 230e0861c77..48e030d7a4a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CouplingBetweenObjectsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CouplingBetweenObjectsRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CyclomaticComplexityRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CyclomaticComplexityRule.java index 52359d84395..fe221d3239f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CyclomaticComplexityRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CyclomaticComplexityRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/DataClassRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/DataClassRule.java index 941cb2c28ed..caf4e0412ac 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/DataClassRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/DataClassRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExceptionAsFlowControlRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExceptionAsFlowControlRule.java index 17e26ac4ec2..53b7bc47df2 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExceptionAsFlowControlRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExceptionAsFlowControlRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/FinalFieldCouldBeStaticRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/FinalFieldCouldBeStaticRule.java index 96ead257d85..94dc615623b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/FinalFieldCouldBeStaticRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/FinalFieldCouldBeStaticRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/GodClassRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/GodClassRule.java index e59b688a98d..92d7c517bc9 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/GodClassRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/GodClassRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java index a2d4b7a2525..59eeb2132f5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/LawOfDemeterRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/LawOfDemeterRule.java index e1243919582..6a1a2f69a49 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/LawOfDemeterRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/LawOfDemeterRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/LoosePackageCouplingRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/LoosePackageCouplingRule.java index 1e71a21117e..fd19a4b8e64 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/LoosePackageCouplingRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/LoosePackageCouplingRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/NcssCountRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/NcssCountRule.java index 94e134460ba..7244df718e4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/NcssCountRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/NcssCountRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SignatureDeclareThrowsExceptionRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SignatureDeclareThrowsExceptionRule.java index 1f30c90793a..896216a1217 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SignatureDeclareThrowsExceptionRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SignatureDeclareThrowsExceptionRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SimplifyBooleanReturnsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SimplifyBooleanReturnsRule.java index dfd0521aba7..6e2ee2d3c19 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SimplifyBooleanReturnsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SimplifyBooleanReturnsRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SwitchDensityRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SwitchDensityRule.java index a8a6fe6fbe4..43dd57686c8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SwitchDensityRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SwitchDensityRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/UseUtilityClassRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/UseUtilityClassRule.java index ef019499388..459bcde7b30 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/UseUtilityClassRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/UseUtilityClassRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/UselessOverridingMethodRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/UselessOverridingMethodRule.java index a4d792b802c..a0ec1978347 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/UselessOverridingMethodRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/UselessOverridingMethodRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentContentRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentContentRule.java index 1a3318d03e7..0a9afc88d05 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentContentRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentContentRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredRule.java index 8992970ec61..7928fc21ee0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentSizeRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentSizeRule.java index 21c1f3bb41a..1bfc37327d7 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentSizeRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentSizeRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java index a638fafc317..23065e209cf 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentToNonFinalStaticRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentToNonFinalStaticRule.java index b965f1bbe13..3fc86530d1b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentToNonFinalStaticRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentToNonFinalStaticRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java index 62b9f62d348..85ddc490dc6 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidDuplicateLiteralsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidDuplicateLiteralsRule.java index 6551ac5763a..3d6a24be597 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidDuplicateLiteralsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidDuplicateLiteralsRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidUsingOctalValuesRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidUsingOctalValuesRule.java index c17cf5d2ac8..3d2d1d24b6e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidUsingOctalValuesRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidUsingOctalValuesRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/BrokenNullCheckRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/BrokenNullCheckRule.java index b344a9d6746..78ffcd88f62 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/BrokenNullCheckRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/BrokenNullCheckRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CheckSkipResultRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CheckSkipResultRule.java index 0f3ecfd6283..bcfd7486f4d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CheckSkipResultRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CheckSkipResultRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloneMethodMustImplementCloneableRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloneMethodMustImplementCloneableRule.java index 3f8891150d5..297d1aba566 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloneMethodMustImplementCloneableRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloneMethodMustImplementCloneableRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConstructorCallsOverridableMethodRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConstructorCallsOverridableMethodRule.java index 8f5c41369da..ced24b66160 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConstructorCallsOverridableMethodRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConstructorCallsOverridableMethodRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/DetachedTestCaseRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/DetachedTestCaseRule.java index 3d8ab0d6b78..15a71bc392f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/DetachedTestCaseRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/DetachedTestCaseRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/IdempotentOperationsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/IdempotentOperationsRule.java index 6ed31e967c2..7f76306bfd5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/IdempotentOperationsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/IdempotentOperationsRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidLogMessageFormatRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidLogMessageFormatRule.java index e3935178b1f..0bbb4d3d768 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidLogMessageFormatRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidLogMessageFormatRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/NonSerializableClassRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/NonSerializableClassRule.java index 31e5c53f2f8..066378fc8a0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/NonSerializableClassRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/NonSerializableClassRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/NullAssignmentRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/NullAssignmentRule.java index 4af8fe30960..bf6166a5702 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/NullAssignmentRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/NullAssignmentRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashcodeRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashcodeRule.java index 3d3d2b1ef1c..8350ede471d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashcodeRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashcodeRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/SingleMethodSingletonRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/SingleMethodSingletonRule.java index 54d34c61022..d5405fb57ee 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/SingleMethodSingletonRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/SingleMethodSingletonRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/SingletonClassReturningNewInstanceRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/SingletonClassReturningNewInstanceRule.java index 9589b49d119..f62deeb9d8b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/SingletonClassReturningNewInstanceRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/SingletonClassReturningNewInstanceRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/SuspiciousOctalEscapeRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/SuspiciousOctalEscapeRule.java index c85e7576315..81b85de34b6 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/SuspiciousOctalEscapeRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/SuspiciousOctalEscapeRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/TestClassWithoutTestCasesRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/TestClassWithoutTestCasesRule.java index fbfb6e637b6..c62acdd3a3a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/TestClassWithoutTestCasesRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/TestClassWithoutTestCasesRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnnecessaryCaseChangeRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnnecessaryCaseChangeRule.java index 08e2ffe4314..fde044aa7ae 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnnecessaryCaseChangeRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnnecessaryCaseChangeRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessOperationOnImmutableRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessOperationOnImmutableRule.java index 89434b830d4..29d8dbe461d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessOperationOnImmutableRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessOperationOnImmutableRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoubleCheckedLockingRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoubleCheckedLockingRule.java index 81331adcd9d..e2463a566e3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoubleCheckedLockingRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoubleCheckedLockingRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/NonThreadSafeSingletonRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/NonThreadSafeSingletonRule.java index 6ba0fd13a40..dca7b19e2a6 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/NonThreadSafeSingletonRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/NonThreadSafeSingletonRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/UnsynchronizedStaticFormatterRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/UnsynchronizedStaticFormatterRule.java index f6487b15f6d..6ef258bf8ec 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/UnsynchronizedStaticFormatterRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/UnsynchronizedStaticFormatterRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/package-info.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/package-info.java index 6652b542d41..ff08f9b313a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/package-info.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/package-info.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/AddEmptyStringRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/AddEmptyStringRule.java index 679c13823df..9a549e2be1c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/AddEmptyStringRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/AddEmptyStringRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/AppendCharacterWithCharRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/AppendCharacterWithCharRule.java index a08f5ae3782..ae164071b63 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/AppendCharacterWithCharRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/AppendCharacterWithCharRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/AvoidInstantiatingObjectsInLoopsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/AvoidInstantiatingObjectsInLoopsRule.java index 3f066ebe20b..5b3289430b3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/AvoidInstantiatingObjectsInLoopsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/AvoidInstantiatingObjectsInLoopsRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/BigIntegerInstantiationRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/BigIntegerInstantiationRule.java index c49cacc44a9..97e3593aa42 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/BigIntegerInstantiationRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/BigIntegerInstantiationRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveAppendsShouldReuseRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveAppendsShouldReuseRule.java index 2dd4d8ffb2d..a0324def94c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveAppendsShouldReuseRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveAppendsShouldReuseRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveLiteralAppendsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveLiteralAppendsRule.java index 367c2e7be03..7248897a7be 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveLiteralAppendsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveLiteralAppendsRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientEmptyStringCheckRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientEmptyStringCheckRule.java index a6b68688d54..d24e2641e83 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientEmptyStringCheckRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientEmptyStringCheckRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientStringBufferingRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientStringBufferingRule.java index b717c7962e4..d622f51116b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientStringBufferingRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientStringBufferingRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java index 5acd063c154..bd994279717 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/RedundantFieldInitializerRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/RedundantFieldInitializerRule.java index d1932d24633..7632ff47d09 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/RedundantFieldInitializerRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/RedundantFieldInitializerRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/StringInstantiationRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/StringInstantiationRule.java index 1d14ca0e073..5ca7194b5a2 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/StringInstantiationRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/StringInstantiationRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/UseIndexOfCharRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/UseIndexOfCharRule.java index 86820a3760f..6b4bfa3932e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/UseIndexOfCharRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/UseIndexOfCharRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/UselessStringValueOfRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/UselessStringValueOfRule.java index fb2bb052581..8e5f6314814 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/UselessStringValueOfRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/UselessStringValueOfRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ExcludeLinesTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ExcludeLinesTest.java index f8be02dc22c..ba636dfd71b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ExcludeLinesTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ExcludeLinesTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/FooRule.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/FooRule.java index 7875410bddd..7aed17c8510 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/FooRule.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/FooRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaParsingHelper.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaParsingHelper.java index d8e82c8c73f..94724fed2f4 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaParsingHelper.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaParsingHelper.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionDiscovererTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionDiscovererTest.java index 77ff85c6c70..6a80afa78ca 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionDiscovererTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionDiscovererTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionTest.java index 6cf9c4dd693..6e0af18b921 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/PMDCoverageTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/PMDCoverageTest.java index 5202134e263..1a818a197c2 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/PMDCoverageTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/PMDCoverageTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/PMDTaskTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/PMDTaskTest.java index 268b850b111..2ffeb046631 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/PMDTaskTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/PMDTaskTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/QuickstartRulesetTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/QuickstartRulesetTest.java index 15e89221e7d..2882ec7bf3a 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/QuickstartRulesetTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/QuickstartRulesetTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ReportTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ReportTest.java index 2e6befc7488..0e87260fce7 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ReportTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ReportTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/RuleSetFactoryTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/RuleSetFactoryTest.java index 7276d213b0d..210ad6f3e42 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/RuleSetFactoryTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/RuleSetFactoryTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/SuppressWarningsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/SuppressWarningsTest.java index 40a023f9659..fae286c2fe6 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/SuppressWarningsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/SuppressWarningsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTBooleanLiteralTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTBooleanLiteralTest.java index a52aad46459..957872adf41 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTBooleanLiteralTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTBooleanLiteralTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTClassTypeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTClassTypeTest.java index ec218b5e784..c715cfbe68f 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTClassTypeTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTClassTypeTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTImportDeclarationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTImportDeclarationTest.java index af228746557..94de863155d 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTImportDeclarationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTImportDeclarationTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTInitializerTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTInitializerTest.java index 711312156f8..d36ad3d4218 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTInitializerTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTInitializerTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTPackageDeclarationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTPackageDeclarationTest.java index 7d581c63082..51ae11f2dcf 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTPackageDeclarationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTPackageDeclarationTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabelTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabelTest.java index 77cd4d70e8d..acc67d902f3 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabelTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabelTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTVariableIdTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTVariableIdTest.java index 41269475efc..06d03e20c79 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTVariableIdTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTVariableIdTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AllJavaAstTreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AllJavaAstTreeDumpTest.java index bdb10b6bcf8..a4686908901 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AllJavaAstTreeDumpTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AllJavaAstTreeDumpTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/CommentTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/CommentTest.java index 29530d227df..23672dc6cb3 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/CommentTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/CommentTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/EncodingTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/EncodingTest.java index 918ad502301..c3430debd9b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/EncodingTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/EncodingTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JDKVersionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JDKVersionTest.java index 1d8b8459b6d..e37a4e4916e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JDKVersionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JDKVersionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java10Test.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java10Test.java index 04bc2fa5741..c283d6966fd 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java10Test.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java10Test.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java8Test.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java8Test.java index 73ba7154836..1ffd7fbc1ba 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java8Test.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java8Test.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java8TreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java8TreeDumpTest.java index a28b11172c2..0d741bb98e5 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java8TreeDumpTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java8TreeDumpTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java9TreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java9TreeDumpTest.java index a015033f1ff..d633c708a6c 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java9TreeDumpTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java9TreeDumpTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JavaQualifiedNameTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JavaQualifiedNameTest.java index 8131dc68e2f..a75039a352e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JavaQualifiedNameTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JavaQualifiedNameTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java index fec719a586c..c56643588f9 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/TextBlockEscapeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/TextBlockEscapeTest.java index 9068386b7fe..3a12a1f3156 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/TextBlockEscapeTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/TextBlockEscapeTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/testdata/InterfaceWithNestedClass.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/testdata/InterfaceWithNestedClass.java index bc141422240..f43c91130ed 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/testdata/InterfaceWithNestedClass.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/testdata/InterfaceWithNestedClass.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecoratorTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecoratorTest.java index 4273b38e7de..a08b86f42f4 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecoratorTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecoratorTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsProviderTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsProviderTest.java index 0757f50f527..2a282a4ebff 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsProviderTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/JavaMetricsProviderTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/MetricsMemoizationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/MetricsMemoizationTest.java index 6d48226c222..8ec4401899e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/MetricsMemoizationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/MetricsMemoizationTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/AllMetricsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/AllMetricsTest.java index 7ba095df80d..ab37b2c4d51 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/AllMetricsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/AllMetricsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/AtfdTestRule.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/AtfdTestRule.java index 1839a8afad8..535219d6d65 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/AtfdTestRule.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/AtfdTestRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/CfoTestRule.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/CfoTestRule.java index ec1300277d9..8e5a7253f9a 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/CfoTestRule.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/CfoTestRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/CognitiveComplexityTestRule.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/CognitiveComplexityTestRule.java index 82c81bd66de..5b6703a4e17 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/CognitiveComplexityTestRule.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/CognitiveComplexityTestRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/CycloTestRule.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/CycloTestRule.java index 29a27de2efd..852560aac1b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/CycloTestRule.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/CycloTestRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/LocTestRule.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/LocTestRule.java index d7caaa24b70..ca8646c35a9 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/LocTestRule.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/LocTestRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NPathTestRule.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NPathTestRule.java index 19539ca83d1..7b6ea966d4c 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NPathTestRule.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NPathTestRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NcssTestRule.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NcssTestRule.java index 1b6825677dc..27f5e7cd09f 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NcssTestRule.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NcssTestRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NoamTestRule.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NoamTestRule.java index 1277803630a..964b44ee2e2 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NoamTestRule.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NoamTestRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NopaTestRule.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NopaTestRule.java index bffb6b6231c..089bafa1d86 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NopaTestRule.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NopaTestRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/TccTestRule.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/TccTestRule.java index 081740505bb..247fe14a3ae 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/TccTestRule.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/TccTestRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/WmcTestRule.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/WmcTestRule.java index 980adce0441..6cadae86790 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/WmcTestRule.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/WmcTestRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/WocTestRule.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/WocTestRule.java index 93d5a291f78..decd5478184 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/WocTestRule.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/WocTestRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/testdata/GetterDetection.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/testdata/GetterDetection.java index 7988940aaea..f0f353baf72 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/testdata/GetterDetection.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/testdata/GetterDetection.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/testdata/MetricsVisitorTestData.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/testdata/MetricsVisitorTestData.java index 20f7a9f29c5..28be68f09ec 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/testdata/MetricsVisitorTestData.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/testdata/MetricsVisitorTestData.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/testdata/SetterDetection.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/testdata/SetterDetection.java index f690d17aa35..bab857da5e1 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/testdata/SetterDetection.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/testdata/SetterDetection.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AbstractClassWithoutAbstractMethodTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AbstractClassWithoutAbstractMethodTest.java index f1d3e1eb283..eaacb5984b2 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AbstractClassWithoutAbstractMethodTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AbstractClassWithoutAbstractMethodTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AccessorClassGenerationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AccessorClassGenerationTest.java index b4818807f88..55edd360393 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AccessorClassGenerationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AccessorClassGenerationTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AccessorMethodGenerationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AccessorMethodGenerationTest.java index a4bff3af894..7e3198d8c15 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AccessorMethodGenerationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AccessorMethodGenerationTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ArrayIsStoredDirectlyTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ArrayIsStoredDirectlyTest.java index 9df0a316440..ceb5078ac04 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ArrayIsStoredDirectlyTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ArrayIsStoredDirectlyTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidMessageDigestFieldTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidMessageDigestFieldTest.java index 1403fe41f31..0011c7e6c22 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidMessageDigestFieldTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidMessageDigestFieldTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidPrintStackTraceTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidPrintStackTraceTest.java index c3c2d9a56e6..62027ba5b83 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidPrintStackTraceTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidPrintStackTraceTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningCatchVariablesTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningCatchVariablesTest.java index 67fd392bdef..1539107d43e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningCatchVariablesTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningCatchVariablesTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesTest.java index b7deb6616c2..40756a86e21 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningParametersTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningParametersTest.java index aa1eecf167e..ceceb497cda 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningParametersTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningParametersTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidStringBufferFieldTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidStringBufferFieldTest.java index 7f1b4a2e16a..5d526ff3976 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidStringBufferFieldTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidStringBufferFieldTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidUsingHardCodedIPTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidUsingHardCodedIPTest.java index fe7b0ce420e..e521dc0b19e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidUsingHardCodedIPTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidUsingHardCodedIPTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetTest.java index 8699d4134d2..9e83d5a392a 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ConstantsInInterfaceTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ConstantsInInterfaceTest.java index c81183b7b6a..6ecb51bec04 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ConstantsInInterfaceTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ConstantsInInterfaceTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/DefaultLabelNotLastInSwitchTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/DefaultLabelNotLastInSwitchTest.java index a012153e0e7..9956280be3e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/DefaultLabelNotLastInSwitchTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/DefaultLabelNotLastInSwitchTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ForLoopCanBeForeachTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ForLoopCanBeForeachTest.java index 771debeb162..cbae33427ee 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ForLoopCanBeForeachTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ForLoopCanBeForeachTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ForLoopVariableCountTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ForLoopVariableCountTest.java index 059c71f39de..86c706d1b10 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ForLoopVariableCountTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ForLoopVariableCountTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/GuardLogStatementTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/GuardLogStatementTest.java index a4f14322026..21ad6e9376e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/GuardLogStatementTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/GuardLogStatementTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ImplicitFunctionalInterfaceTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ImplicitFunctionalInterfaceTest.java index 4e6af987769..5555aa5c4a1 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ImplicitFunctionalInterfaceTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ImplicitFunctionalInterfaceTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnit4SuitesShouldUseSuiteAnnotationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnit4SuitesShouldUseSuiteAnnotationTest.java index 2765a69ce27..092f62e03ff 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnit4SuitesShouldUseSuiteAnnotationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnit4SuitesShouldUseSuiteAnnotationTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnit5TestShouldBePackagePrivateTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnit5TestShouldBePackagePrivateTest.java index d39a19249bd..18ec60bba0b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnit5TestShouldBePackagePrivateTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnit5TestShouldBePackagePrivateTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitUseExpectedTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitUseExpectedTest.java index 3ad1c367843..39880295714 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitUseExpectedTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitUseExpectedTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/LiteralsFirstInComparisonsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/LiteralsFirstInComparisonsTest.java index a5720ad7f7f..2c70a02d402 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/LiteralsFirstInComparisonsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/LiteralsFirstInComparisonsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/LooseCouplingTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/LooseCouplingTest.java index 5578b24fd51..bea6988ed7c 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/LooseCouplingTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/LooseCouplingTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/MethodReturnsInternalArrayTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/MethodReturnsInternalArrayTest.java index f3646e5d543..36624122c6a 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/MethodReturnsInternalArrayTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/MethodReturnsInternalArrayTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/MissingOverrideTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/MissingOverrideTest.java index fd9b847b625..6f221803a22 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/MissingOverrideTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/MissingOverrideTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/NonExhaustiveSwitchTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/NonExhaustiveSwitchTest.java index 2d7b18f754e..1fe281b5376 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/NonExhaustiveSwitchTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/NonExhaustiveSwitchTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/OneDeclarationPerLineTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/OneDeclarationPerLineTest.java index 8c21b1715c1..b6b3c2e39f0 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/OneDeclarationPerLineTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/OneDeclarationPerLineTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/PreserveStackTraceTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/PreserveStackTraceTest.java index 56e4f6de8bc..f115216dd80 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/PreserveStackTraceTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/PreserveStackTraceTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/PrimitiveWrapperInstantiationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/PrimitiveWrapperInstantiationTest.java index 6e656beb8e3..daac959b3d4 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/PrimitiveWrapperInstantiationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/PrimitiveWrapperInstantiationTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ReplaceEnumerationWithIteratorTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ReplaceEnumerationWithIteratorTest.java index 125b827b3a5..34cd6a870fa 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ReplaceEnumerationWithIteratorTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ReplaceEnumerationWithIteratorTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ReplaceHashtableWithMapTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ReplaceHashtableWithMapTest.java index 32a5a7d6827..2b42d84f34c 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ReplaceHashtableWithMapTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ReplaceHashtableWithMapTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ReplaceVectorWithListTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ReplaceVectorWithListTest.java index ef8f827443d..b6d2387edc2 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ReplaceVectorWithListTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/ReplaceVectorWithListTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/SimplifiableTestAssertionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/SimplifiableTestAssertionTest.java index 3d40f44bd23..f2e21fc66ce 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/SimplifiableTestAssertionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/SimplifiableTestAssertionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/SystemPrintlnTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/SystemPrintlnTest.java index eb401c15bc5..4eb2ef0c330 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/SystemPrintlnTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/SystemPrintlnTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestAssertionsShouldIncludeMessageTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestAssertionsShouldIncludeMessageTest.java index c24f4bcbe0d..cbd2a063b0c 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestAssertionsShouldIncludeMessageTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestAssertionsShouldIncludeMessageTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestContainsTooManyAssertsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestContainsTooManyAssertsTest.java index e0d7780c956..e1ba4559cba 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestContainsTooManyAssertsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestContainsTooManyAssertsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertTest.java index bab5134261c..922ac2f246b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldIncludeAssertTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldUseAfterAnnotationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldUseAfterAnnotationTest.java index 87c0b30c819..b7c1a02321a 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldUseAfterAnnotationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldUseAfterAnnotationTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldUseBeforeAnnotationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldUseBeforeAnnotationTest.java index 794e4f86b4b..aa4de531328 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldUseBeforeAnnotationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldUseBeforeAnnotationTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldUseTestAnnotationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldUseTestAnnotationTest.java index 3f50bf341c1..3b03fc02dac 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldUseTestAnnotationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnitTestShouldUseTestAnnotationTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnnecessaryWarningSuppressionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnnecessaryWarningSuppressionTest.java index b0b95e62667..22a6d382b59 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnnecessaryWarningSuppressionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnnecessaryWarningSuppressionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedFormalParameterTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedFormalParameterTest.java index d50db5eed9a..27abc5cea78 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedFormalParameterTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedFormalParameterTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLocalVariableTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLocalVariableTest.java index e036436f048..275544c430a 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLocalVariableTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLocalVariableTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateFieldTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateFieldTest.java index 393832d4520..2bed46858e9 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateFieldTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateFieldTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodTest.java index a865a707065..72343f6f699 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedPrivateMethodTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseCollectionIsEmptyTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseCollectionIsEmptyTest.java index 59f03df249d..48c1a761eb1 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseCollectionIsEmptyTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseCollectionIsEmptyTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseEnumCollectionsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseEnumCollectionsTest.java index 5dcb333fc46..cffc0e88de7 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseEnumCollectionsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseEnumCollectionsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseStandardCharsetsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseStandardCharsetsTest.java index aca984101e7..d5636f076f0 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseStandardCharsetsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseStandardCharsetsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseTryWithResourcesTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseTryWithResourcesTest.java index 07334453bdc..0ef32bcde55 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseTryWithResourcesTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseTryWithResourcesTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseVarargsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseVarargsTest.java index d3c6b354118..472483e7e48 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseVarargsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UseVarargsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/WhileLoopWithLiteralBooleanTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/WhileLoopWithLiteralBooleanTest.java index 4fe2c32ef5c..aaa61b0f9fb 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/WhileLoopWithLiteralBooleanTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/WhileLoopWithLiteralBooleanTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/AbsClassWithInterface.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/AbsClassWithInterface.java index 09d691a4a42..4910eb30ff0 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/AbsClassWithInterface.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/AbsClassWithInterface.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/AbstractClass.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/AbstractClass.java index cf18ad4a39a..3f4b80c98f2 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/AbstractClass.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/AbstractClass.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/AmbiguousOverload.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/AmbiguousOverload.java index e944f6c3a01..d5e259e49c4 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/AmbiguousOverload.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/AmbiguousOverload.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/AnonClassExample.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/AnonClassExample.java index 9435ec213dd..51880b3da41 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/AnonClassExample.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/AnonClassExample.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/CloneableInterface.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/CloneableInterface.java index e9b7b24a4a8..24fe4ce86de 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/CloneableInterface.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/CloneableInterface.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/CloneableInterfaceOverride.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/CloneableInterfaceOverride.java index d6b66f2774d..a5f72a7eda9 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/CloneableInterfaceOverride.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/CloneableInterfaceOverride.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/ConcreteClass.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/ConcreteClass.java index 8e4605e7652..708072191b9 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/ConcreteClass.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/ConcreteClass.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/ConcreteClassArrayParams.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/ConcreteClassArrayParams.java index 19d3ff1a49a..cb34c6f63dc 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/ConcreteClassArrayParams.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/ConcreteClassArrayParams.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/ConcreteClassTransitive.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/ConcreteClassTransitive.java index 64293b5c599..b4552e8b16e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/ConcreteClassTransitive.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/ConcreteClassTransitive.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/CovariantReturnType.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/CovariantReturnType.java index 6e977c65c6e..f115fdeedc4 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/CovariantReturnType.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/CovariantReturnType.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/EnumWithAnonClass.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/EnumWithAnonClass.java index 04b00abecde..2c18df354b8 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/EnumWithAnonClass.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/EnumWithAnonClass.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/EnumWithInterfaces.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/EnumWithInterfaces.java index e03ecaa15d0..5c67881867c 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/EnumWithInterfaces.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/EnumWithInterfaces.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/GenericInterfaceWithOverloads.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/GenericInterfaceWithOverloads.java index 4ed3999d418..d5fbd4f9b00 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/GenericInterfaceWithOverloads.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/GenericInterfaceWithOverloads.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/GenericWithOverloadsImpl.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/GenericWithOverloadsImpl.java index 8ee0974ad4f..9e50ae6f72b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/GenericWithOverloadsImpl.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/GenericWithOverloadsImpl.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/HierarchyWithSeveralBridges.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/HierarchyWithSeveralBridges.java index 08e1f1fd932..7147636e668 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/HierarchyWithSeveralBridges.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/HierarchyWithSeveralBridges.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/InterfaceWithNoSuperClass.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/InterfaceWithNoSuperClass.java index 0972217af3e..3fecb8a7656 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/InterfaceWithNoSuperClass.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/InterfaceWithNoSuperClass.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/Option.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/Option.java index bd4c1980328..0a358db323b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/Option.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/Option.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/OptionTestCaseOneParam.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/OptionTestCaseOneParam.java index 968f0003577..bfc38a576f0 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/OptionTestCaseOneParam.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/OptionTestCaseOneParam.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/RunnableImpl.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/RunnableImpl.java index d631863ffd5..63b12fd93ac 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/RunnableImpl.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/RunnableImpl.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/SubclassPrivateNoOverride.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/SubclassPrivateNoOverride.java index 5cc4bc00add..b551e93c06f 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/SubclassPrivateNoOverride.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/SubclassPrivateNoOverride.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/SubclassWithGenericMethod.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/SubclassWithGenericMethod.java index 191b7decc7a..c6257a720ce 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/SubclassWithGenericMethod.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/SubclassWithGenericMethod.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/SubclassWithStatic.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/SubclassWithStatic.java index 4e8a68d9e77..47914c7986a 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/SubclassWithStatic.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/SubclassWithStatic.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/SuperclassWithPrivate.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/SuperclassWithPrivate.java index d2cea858737..8e156728a9d 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/SuperclassWithPrivate.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/SuperclassWithPrivate.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/SuperclassWithStatic.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/SuperclassWithStatic.java index d8d2a8d0172..3d3e2e85564 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/SuperclassWithStatic.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/missingoverride/SuperclassWithStatic.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/switchstmtsshouldhavedefault/SimpleEnum.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/switchstmtsshouldhavedefault/SimpleEnum.java index 1fa9ce966c0..03478aac59b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/switchstmtsshouldhavedefault/SimpleEnum.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/switchstmtsshouldhavedefault/SimpleEnum.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/ClassWithPublicEnum.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/ClassWithPublicEnum.java index 4d338960784..95eec2664a0 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/ClassWithPublicEnum.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/ClassWithPublicEnum.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/DashboardGraphInnateFilter.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/DashboardGraphInnateFilter.java index c2e2f9a7cb9..93d9efe082b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/DashboardGraphInnateFilter.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/DashboardGraphInnateFilter.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/DashboardInnateFilter.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/DashboardInnateFilter.java index 0b54ce8e03b..cc99baa96c3 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/DashboardInnateFilter.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/unusedprivatemethod/DashboardInnateFilter.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/AtLeastOneConstructorTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/AtLeastOneConstructorTest.java index 0016e9ddbcb..ac28de01786 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/AtLeastOneConstructorTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/AtLeastOneConstructorTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/AvoidDollarSignsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/AvoidDollarSignsTest.java index 34a6e215bbb..31783242fef 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/AvoidDollarSignsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/AvoidDollarSignsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/AvoidProtectedFieldInFinalClassTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/AvoidProtectedFieldInFinalClassTest.java index f7776cd2255..043ed7d66a6 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/AvoidProtectedFieldInFinalClassTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/AvoidProtectedFieldInFinalClassTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/AvoidProtectedMethodInFinalClassNotExtendingTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/AvoidProtectedMethodInFinalClassNotExtendingTest.java index 7d7e2cfa3b3..f27ae889f58 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/AvoidProtectedMethodInFinalClassNotExtendingTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/AvoidProtectedMethodInFinalClassNotExtendingTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/AvoidUsingNativeCodeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/AvoidUsingNativeCodeTest.java index fae466967b8..f2dfc8acf58 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/AvoidUsingNativeCodeTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/AvoidUsingNativeCodeTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/BooleanGetMethodNameTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/BooleanGetMethodNameTest.java index 1b239e2ab1b..7f6880bbbac 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/BooleanGetMethodNameTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/BooleanGetMethodNameTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/CallSuperInConstructorTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/CallSuperInConstructorTest.java index 34310381dee..bb6377efc24 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/CallSuperInConstructorTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/CallSuperInConstructorTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ClassNamingConventionsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ClassNamingConventionsTest.java index ca721c867a9..9f4068b63cb 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ClassNamingConventionsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ClassNamingConventionsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/CommentDefaultAccessModifierTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/CommentDefaultAccessModifierTest.java index c6e02b62f5c..5173dbc82a9 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/CommentDefaultAccessModifierTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/CommentDefaultAccessModifierTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryTest.java index ed559d2e323..a3af233519e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ControlStatementBracesTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ControlStatementBracesTest.java index c94aed935cc..7bc559cd3cc 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ControlStatementBracesTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ControlStatementBracesTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/EmptyControlStatementTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/EmptyControlStatementTest.java index 4cb1a84298d..388444ead14 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/EmptyControlStatementTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/EmptyControlStatementTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/EmptyMethodInAbstractClassShouldBeAbstractTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/EmptyMethodInAbstractClassShouldBeAbstractTest.java index 27bb5620d12..dbe2935e5ef 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/EmptyMethodInAbstractClassShouldBeAbstractTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/EmptyMethodInAbstractClassShouldBeAbstractTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ExtendsObjectTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ExtendsObjectTest.java index 6e66ca54e47..77d238947c4 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ExtendsObjectTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ExtendsObjectTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/FieldDeclarationsShouldBeAtStartOfClassTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/FieldDeclarationsShouldBeAtStartOfClassTest.java index f1c9cfcb916..4f3f5708edf 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/FieldDeclarationsShouldBeAtStartOfClassTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/FieldDeclarationsShouldBeAtStartOfClassTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/FieldNamingConventionsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/FieldNamingConventionsTest.java index e4a1157bf28..c0c38ceaa54 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/FieldNamingConventionsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/FieldNamingConventionsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ForLoopShouldBeWhileLoopTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ForLoopShouldBeWhileLoopTest.java index 427e066be8f..e036246709a 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ForLoopShouldBeWhileLoopTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ForLoopShouldBeWhileLoopTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/FormalParameterNamingConventionsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/FormalParameterNamingConventionsTest.java index 2327c1cd2fe..18b115ec350 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/FormalParameterNamingConventionsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/FormalParameterNamingConventionsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/GenericsNamingTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/GenericsNamingTest.java index 4ed583d9fe4..903510212b5 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/GenericsNamingTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/GenericsNamingTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesTest.java index 87875e0f14e..de207318839 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LambdaCanBeMethodReferenceTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LambdaCanBeMethodReferenceTest.java index 8fd614d560f..a310f0f1a27 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LambdaCanBeMethodReferenceTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LambdaCanBeMethodReferenceTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LinguisticNamingTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LinguisticNamingTest.java index fd1466df701..792a7d48043 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LinguisticNamingTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LinguisticNamingTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalHomeNamingConventionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalHomeNamingConventionTest.java index 04fdee75ab5..f1638dcab2c 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalHomeNamingConventionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalHomeNamingConventionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalInterfaceSessionNamingConventionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalInterfaceSessionNamingConventionTest.java index ff119c1a285..e26d0782365 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalInterfaceSessionNamingConventionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalInterfaceSessionNamingConventionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableCouldBeFinalTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableCouldBeFinalTest.java index d87bf490ac2..9fc915aba98 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableCouldBeFinalTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableCouldBeFinalTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableNamingConventionsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableNamingConventionsTest.java index 18753981b97..85bf2beba14 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableNamingConventionsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LocalVariableNamingConventionsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LongVariableTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LongVariableTest.java index 86ad669aac0..74e6c1bb403 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LongVariableTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/LongVariableTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/MDBAndSessionBeanNamingConventionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/MDBAndSessionBeanNamingConventionTest.java index 5104b29ffc2..887ed5d7408 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/MDBAndSessionBeanNamingConventionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/MDBAndSessionBeanNamingConventionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/MethodArgumentCouldBeFinalTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/MethodArgumentCouldBeFinalTest.java index 55d43256659..f2e08ec8781 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/MethodArgumentCouldBeFinalTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/MethodArgumentCouldBeFinalTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/MethodNamingConventionsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/MethodNamingConventionsTest.java index 67a7557ec06..9f03e97ca29 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/MethodNamingConventionsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/MethodNamingConventionsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/NoPackageTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/NoPackageTest.java index 80badeb38ca..16ba4649bf9 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/NoPackageTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/NoPackageTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/OnlyOneReturnTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/OnlyOneReturnTest.java index bf2e0d75eb0..295cf45fa2a 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/OnlyOneReturnTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/OnlyOneReturnTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/PackageCaseTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/PackageCaseTest.java index f82f7071ceb..335ce735c1b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/PackageCaseTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/PackageCaseTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/PrematureDeclarationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/PrematureDeclarationTest.java index 7449842bd84..e56021e8854 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/PrematureDeclarationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/PrematureDeclarationTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/RemoteInterfaceNamingConventionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/RemoteInterfaceNamingConventionTest.java index 99b7caad866..69cc300b3b7 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/RemoteInterfaceNamingConventionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/RemoteInterfaceNamingConventionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/RemoteSessionInterfaceNamingConventionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/RemoteSessionInterfaceNamingConventionTest.java index 8c9a2dba9cc..440e5547aa2 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/RemoteSessionInterfaceNamingConventionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/RemoteSessionInterfaceNamingConventionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ShortClassNameTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ShortClassNameTest.java index cc08d111d94..33e4dfba506 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ShortClassNameTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ShortClassNameTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ShortMethodNameTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ShortMethodNameTest.java index 77f1793eca9..261077e83b1 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ShortMethodNameTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ShortMethodNameTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ShortVariableTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ShortVariableTest.java index e505d0ef49b..238b21e2b43 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ShortVariableTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ShortVariableTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/TooManyStaticImportsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/TooManyStaticImportsTest.java index 6346aa9a48a..f9ad32dbd23 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/TooManyStaticImportsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/TooManyStaticImportsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryAnnotationValueElementTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryAnnotationValueElementTest.java index 051a52d5084..644f37c90fe 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryAnnotationValueElementTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryAnnotationValueElementTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorTest.java index b5111c5bb47..5e5472dd4ce 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameTest.java index 9f0c2eec0ff..6147491f27d 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryLocalBeforeReturnTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryLocalBeforeReturnTest.java index 10bf3efae5c..15b4c13a3c1 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryLocalBeforeReturnTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryLocalBeforeReturnTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryModifierTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryModifierTest.java index 5c77459d42c..d528b2b59db 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryModifierTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryModifierTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryReturnTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryReturnTest.java index 9213d7d9f27..f237feabf08 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryReturnTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryReturnTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessarySemicolonTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessarySemicolonTest.java index 9e488c285cb..bb84cef6904 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessarySemicolonTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessarySemicolonTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseDiamondOperatorTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseDiamondOperatorTest.java index 3148d3a6909..fda2e85daac 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseDiamondOperatorTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseDiamondOperatorTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseShortArrayInitializerTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseShortArrayInitializerTest.java index a4cec59f395..a78d8efa783 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseShortArrayInitializerTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseShortArrayInitializerTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseUnderscoresInNumericLiteralsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseUnderscoresInNumericLiteralsTest.java index 71098101c01..c3ddbb8c0c9 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseUnderscoresInNumericLiteralsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseUnderscoresInNumericLiteralsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesTest.java index 8e4050c9aaa..c5728c490a9 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessQualifiedThisTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessQualifiedThisTest.java index c7eed79ceee..f5f425fa966 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessQualifiedThisTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessQualifiedThisTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/commentdefaultaccessmodifier/OnlyForTesting.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/commentdefaultaccessmodifier/OnlyForTesting.java index 6f4a6608ed1..ae63bcffc34 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/commentdefaultaccessmodifier/OnlyForTesting.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/commentdefaultaccessmodifier/OnlyForTesting.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AbstractClassWithoutAnyMethodTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AbstractClassWithoutAnyMethodTest.java index a5d9253ee22..7170dd63bb8 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AbstractClassWithoutAnyMethodTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AbstractClassWithoutAnyMethodTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidCatchingGenericExceptionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidCatchingGenericExceptionTest.java index 32fecf59f87..8bca7c27216 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidCatchingGenericExceptionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidCatchingGenericExceptionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidDeeplyNestedIfStmtsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidDeeplyNestedIfStmtsTest.java index 28eab0fdf14..c89342b6fa9 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidDeeplyNestedIfStmtsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidDeeplyNestedIfStmtsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidRethrowingExceptionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidRethrowingExceptionTest.java index aa3bbd57baf..e6728d2ff68 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidRethrowingExceptionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidRethrowingExceptionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidThrowingNewInstanceOfSameExceptionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidThrowingNewInstanceOfSameExceptionTest.java index 14e7a6b7dfa..accc7224c28 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidThrowingNewInstanceOfSameExceptionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidThrowingNewInstanceOfSameExceptionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidThrowingNullPointerExceptionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidThrowingNullPointerExceptionTest.java index e729824a6d4..d998548338c 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidThrowingNullPointerExceptionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidThrowingNullPointerExceptionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidThrowingRawExceptionTypesTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidThrowingRawExceptionTypesTest.java index 8cffad6aebf..89a9dd682c6 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidThrowingRawExceptionTypesTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidThrowingRawExceptionTypesTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidUncheckedExceptionsInSignaturesTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidUncheckedExceptionsInSignaturesTest.java index 146b4990f3d..2b7bf594fc5 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidUncheckedExceptionsInSignaturesTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/AvoidUncheckedExceptionsInSignaturesTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ClassWithOnlyPrivateConstructorsShouldBeFinalTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ClassWithOnlyPrivateConstructorsShouldBeFinalTest.java index 7328a0999f5..07579581cab 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ClassWithOnlyPrivateConstructorsShouldBeFinalTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ClassWithOnlyPrivateConstructorsShouldBeFinalTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/CognitiveComplexityTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/CognitiveComplexityTest.java index b20c1035a89..fc2433b669c 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/CognitiveComplexityTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/CognitiveComplexityTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/CollapsibleIfStatementsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/CollapsibleIfStatementsTest.java index 44d831ea9e7..6cea8fbb843 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/CollapsibleIfStatementsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/CollapsibleIfStatementsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/CouplingBetweenObjectsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/CouplingBetweenObjectsTest.java index 79ab664ae7c..0a84a3574cc 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/CouplingBetweenObjectsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/CouplingBetweenObjectsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/CyclomaticComplexityTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/CyclomaticComplexityTest.java index 7833abbb86c..4595a0cb606 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/CyclomaticComplexityTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/CyclomaticComplexityTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/DataClassTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/DataClassTest.java index 6a7cccfdd99..d2e377857ae 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/DataClassTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/DataClassTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/DoNotExtendJavaLangErrorTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/DoNotExtendJavaLangErrorTest.java index 57280be3f80..f30e42e5d19 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/DoNotExtendJavaLangErrorTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/DoNotExtendJavaLangErrorTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ExceptionAsFlowControlTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ExceptionAsFlowControlTest.java index 2dbd142d271..7344b56f9ba 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ExceptionAsFlowControlTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ExceptionAsFlowControlTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsTest.java index 7547ce785ad..a08c2ead045 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListTest.java index 30fa157b94d..699fc1f2a2b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountTest.java index 7417e82f49e..f49daeea22b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/FinalFieldCouldBeStaticTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/FinalFieldCouldBeStaticTest.java index 71b86c40144..c5d946ae4ad 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/FinalFieldCouldBeStaticTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/FinalFieldCouldBeStaticTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/GodClassTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/GodClassTest.java index eac3f103221..4cbc2a89ac9 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/GodClassTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/GodClassTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldTest.java index 7c614b7dcdf..92a8e4a8f93 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/LawOfDemeterTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/LawOfDemeterTest.java index 88e54418ac3..2e50228b970 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/LawOfDemeterTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/LawOfDemeterTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/LogicInversionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/LogicInversionTest.java index b59044573af..da9636a1078 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/LogicInversionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/LogicInversionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/LoosePackageCouplingTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/LoosePackageCouplingTest.java index b838934226d..6dcd32c98d5 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/LoosePackageCouplingTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/LoosePackageCouplingTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/MutableStaticStateTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/MutableStaticStateTest.java index df946baa867..6a1f3303a54 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/MutableStaticStateTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/MutableStaticStateTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/NPathComplexityTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/NPathComplexityTest.java index f23536ba556..e0d04a7d568 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/NPathComplexityTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/NPathComplexityTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/NcssCountTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/NcssCountTest.java index 537485d26c9..f9d0d1780ab 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/NcssCountTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/NcssCountTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SignatureDeclareThrowsExceptionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SignatureDeclareThrowsExceptionTest.java index d5e0bc20af2..e1732973daa 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SignatureDeclareThrowsExceptionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SignatureDeclareThrowsExceptionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SimplifiedTernaryTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SimplifiedTernaryTest.java index dc68ac28bd2..377ab8ea3ba 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SimplifiedTernaryTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SimplifiedTernaryTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SimplifyBooleanExpressionsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SimplifyBooleanExpressionsTest.java index f17434579f5..d3a8c03666f 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SimplifyBooleanExpressionsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SimplifyBooleanExpressionsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SimplifyBooleanReturnsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SimplifyBooleanReturnsTest.java index e385db5af12..faf72057333 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SimplifyBooleanReturnsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SimplifyBooleanReturnsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SimplifyConditionalTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SimplifyConditionalTest.java index 9ad90e779d0..65d9438b4bb 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SimplifyConditionalTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SimplifyConditionalTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SingularFieldTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SingularFieldTest.java index b550b06f85e..d52d2b3624b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SingularFieldTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SingularFieldTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SwitchDensityTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SwitchDensityTest.java index 20788f1419d..01d0231e045 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SwitchDensityTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SwitchDensityTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/TooManyFieldsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/TooManyFieldsTest.java index 9c3c33d7eea..c31ea84f815 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/TooManyFieldsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/TooManyFieldsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/TooManyMethodsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/TooManyMethodsTest.java index fa9d3db7638..e1c737b64e0 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/TooManyMethodsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/TooManyMethodsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/UseObjectForClearerAPITest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/UseObjectForClearerAPITest.java index fc4a699a0df..880d130f57f 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/UseObjectForClearerAPITest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/UseObjectForClearerAPITest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/UseUtilityClassTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/UseUtilityClassTest.java index 7d023149da6..1ffc52e0583 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/UseUtilityClassTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/UseUtilityClassTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/UselessOverridingMethodTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/UselessOverridingMethodTest.java index ead57712d12..3cebad92576 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/UselessOverridingMethodTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/UselessOverridingMethodTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/donotextendjavalangerror/Error.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/donotextendjavalangerror/Error.java index 3631156f731..0b393d4b291 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/donotextendjavalangerror/Error.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/donotextendjavalangerror/Error.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/signaturedeclarethrowsexception/MyTestCase.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/signaturedeclarethrowsexception/MyTestCase.java index 939c88bd8a6..5ac8d8358cf 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/signaturedeclarethrowsexception/MyTestCase.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/signaturedeclarethrowsexception/MyTestCase.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentContentTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentContentTest.java index 9ecdfb0ba90..922557a8841 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentContentTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentContentTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredTest.java index b3f976c2a91..8f0bb0e2043 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentSizeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentSizeTest.java index 5c7b46c6042..7037b788e48 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentSizeTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentSizeTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/UncommentedEmptyConstructorTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/UncommentedEmptyConstructorTest.java index 07db696d069..c3ba825c4e0 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/UncommentedEmptyConstructorTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/UncommentedEmptyConstructorTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/UncommentedEmptyMethodBodyTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/UncommentedEmptyMethodBodyTest.java index cf02536ff65..88cd3c3b619 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/UncommentedEmptyMethodBodyTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/UncommentedEmptyMethodBodyTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandTest.java index bcc9a1a047b..50c37db5182 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentToNonFinalStaticTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentToNonFinalStaticTest.java index a0ec733db16..621e281f38d 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentToNonFinalStaticTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentToNonFinalStaticTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidAssertAsIdentifierTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidAssertAsIdentifierTest.java index 2181e84e4b3..1b2723f5131 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidAssertAsIdentifierTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidAssertAsIdentifierTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopTest.java index e220e19d133..d98d44e44bc 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidCallingFinalizeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidCallingFinalizeTest.java index d677bbb03e1..0ca8771d922 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidCallingFinalizeTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidCallingFinalizeTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidCatchingNPETest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidCatchingNPETest.java index b232a83d679..cf376eeb6f9 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidCatchingNPETest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidCatchingNPETest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidCatchingThrowableTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidCatchingThrowableTest.java index c8a5c0c84d9..63139012a3e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidCatchingThrowableTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidCatchingThrowableTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidDecimalLiteralsInBigDecimalConstructorTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidDecimalLiteralsInBigDecimalConstructorTest.java index 89ea4cb63c7..e439eb0164d 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidDecimalLiteralsInBigDecimalConstructorTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidDecimalLiteralsInBigDecimalConstructorTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidDuplicateLiteralsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidDuplicateLiteralsTest.java index c08bad740bd..b386447c12e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidDuplicateLiteralsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidDuplicateLiteralsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidEnumAsIdentifierTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidEnumAsIdentifierTest.java index 8b6da142634..8b41890a6a5 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidEnumAsIdentifierTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidEnumAsIdentifierTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidFieldNameMatchingMethodNameTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidFieldNameMatchingMethodNameTest.java index 9cea99c5772..127938c7bbf 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidFieldNameMatchingMethodNameTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidFieldNameMatchingMethodNameTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidFieldNameMatchingTypeNameTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidFieldNameMatchingTypeNameTest.java index 3583b1a5573..c932fd8e9e7 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidFieldNameMatchingTypeNameTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidFieldNameMatchingTypeNameTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidInstanceofChecksInCatchClauseTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidInstanceofChecksInCatchClauseTest.java index a839a4c68af..ac958cff4cf 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidInstanceofChecksInCatchClauseTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidInstanceofChecksInCatchClauseTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidLiteralsInIfConditionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidLiteralsInIfConditionTest.java index d2a8f2c42b9..4afd819cf7a 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidLiteralsInIfConditionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidLiteralsInIfConditionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidLosingExceptionInformationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidLosingExceptionInformationTest.java index e1cdd898957..8093c6c7458 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidLosingExceptionInformationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidLosingExceptionInformationTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidMultipleUnaryOperatorsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidMultipleUnaryOperatorsTest.java index 3d2893f02cb..a09c0947415 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidMultipleUnaryOperatorsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidMultipleUnaryOperatorsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidUsingOctalValuesTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidUsingOctalValuesTest.java index 9b396d15198..491a54f2cf1 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidUsingOctalValuesTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidUsingOctalValuesTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/BrokenNullCheckTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/BrokenNullCheckTest.java index bf48e3784a8..66efdeff4c1 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/BrokenNullCheckTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/BrokenNullCheckTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CallSuperFirstTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CallSuperFirstTest.java index 930906b275c..1a8a6fb045f 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CallSuperFirstTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CallSuperFirstTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CallSuperLastTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CallSuperLastTest.java index c9102640caa..878982a3abe 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CallSuperLastTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CallSuperLastTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CheckSkipResultTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CheckSkipResultTest.java index 26fc541489c..989c079955b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CheckSkipResultTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CheckSkipResultTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ClassCastExceptionWithToArrayTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ClassCastExceptionWithToArrayTest.java index 502cf5ea4f6..b106f11599a 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ClassCastExceptionWithToArrayTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ClassCastExceptionWithToArrayTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloneMethodMustBePublicTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloneMethodMustBePublicTest.java index 371d240c069..b816bf81d24 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloneMethodMustBePublicTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloneMethodMustBePublicTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloneMethodMustImplementCloneableTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloneMethodMustImplementCloneableTest.java index 3f37f37eafc..a453472c30c 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloneMethodMustImplementCloneableTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloneMethodMustImplementCloneableTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloneMethodReturnTypeMustMatchClassNameTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloneMethodReturnTypeMustMatchClassNameTest.java index 63df372d7a0..c20266f7218 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloneMethodReturnTypeMustMatchClassNameTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloneMethodReturnTypeMustMatchClassNameTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceTest.java index 20856ab956d..bfa317287c5 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CompareObjectsWithEqualsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CompareObjectsWithEqualsTest.java index 25e111a8fa7..26f4dbab552 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CompareObjectsWithEqualsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/CompareObjectsWithEqualsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ComparisonWithNaNTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ComparisonWithNaNTest.java index 1015af42ed3..05f16dbf137 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ComparisonWithNaNTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ComparisonWithNaNTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConfusingArgumentToVarargsMethodTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConfusingArgumentToVarargsMethodTest.java index 876c5646001..ce19b8c25d5 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConfusingArgumentToVarargsMethodTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConfusingArgumentToVarargsMethodTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConstructorCallsOverridableMethodTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConstructorCallsOverridableMethodTest.java index 8420a865ab9..43d078b6511 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConstructorCallsOverridableMethodTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConstructorCallsOverridableMethodTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DetachedTestCaseTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DetachedTestCaseTest.java index f2def6539a0..94fc406fcc5 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DetachedTestCaseTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DetachedTestCaseTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DoNotCallGarbageCollectionExplicitlyTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DoNotCallGarbageCollectionExplicitlyTest.java index 46202e927a5..f471e72a5e9 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DoNotCallGarbageCollectionExplicitlyTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DoNotCallGarbageCollectionExplicitlyTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DoNotExtendJavaLangThrowableTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DoNotExtendJavaLangThrowableTest.java index 6a849194f6f..d42bf928b23 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DoNotExtendJavaLangThrowableTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DoNotExtendJavaLangThrowableTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DoNotHardCodeSDCardTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DoNotHardCodeSDCardTest.java index bdfd5d58cbf..667eb5650bd 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DoNotHardCodeSDCardTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DoNotHardCodeSDCardTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DoNotThrowExceptionInFinallyTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DoNotThrowExceptionInFinallyTest.java index 7eefe57ee0b..1e0136be63a 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DoNotThrowExceptionInFinallyTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DoNotThrowExceptionInFinallyTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DontImportSunTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DontImportSunTest.java index f4c0ae4184f..358bb02e850 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DontImportSunTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DontImportSunTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DontUseFloatTypeForLoopIndicesTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DontUseFloatTypeForLoopIndicesTest.java index 1572170e72e..00866cf7ac5 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DontUseFloatTypeForLoopIndicesTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DontUseFloatTypeForLoopIndicesTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/EmptyCatchBlockTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/EmptyCatchBlockTest.java index 9a5537230bd..728c0a308e9 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/EmptyCatchBlockTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/EmptyCatchBlockTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/EmptyFinalizerTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/EmptyFinalizerTest.java index cd31622ab28..8ec68a34ca8 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/EmptyFinalizerTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/EmptyFinalizerTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/EqualsNullTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/EqualsNullTest.java index f0cfd64e5c8..58dd3417c03 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/EqualsNullTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/EqualsNullTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/FinalizeDoesNotCallSuperFinalizeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/FinalizeDoesNotCallSuperFinalizeTest.java index d1747d48857..330b35d1a85 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/FinalizeDoesNotCallSuperFinalizeTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/FinalizeDoesNotCallSuperFinalizeTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/FinalizeOnlyCallsSuperFinalizeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/FinalizeOnlyCallsSuperFinalizeTest.java index 7da75fa5c1f..d6f81b306d9 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/FinalizeOnlyCallsSuperFinalizeTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/FinalizeOnlyCallsSuperFinalizeTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/FinalizeOverloadedTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/FinalizeOverloadedTest.java index c529f24a4a1..263ef5a3583 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/FinalizeOverloadedTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/FinalizeOverloadedTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/FinalizeShouldBeProtectedTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/FinalizeShouldBeProtectedTest.java index e2cab4ed1a6..933d87e5457 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/FinalizeShouldBeProtectedTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/FinalizeShouldBeProtectedTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/IdempotentOperationsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/IdempotentOperationsTest.java index 424df377680..9efbc3e0c30 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/IdempotentOperationsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/IdempotentOperationsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ImplicitSwitchFallThroughTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ImplicitSwitchFallThroughTest.java index 71f0e034950..0d808efca93 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ImplicitSwitchFallThroughTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ImplicitSwitchFallThroughTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/InstantiationToGetClassTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/InstantiationToGetClassTest.java index f575d90629e..aaa88aa0961 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/InstantiationToGetClassTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/InstantiationToGetClassTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidLogMessageFormatTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidLogMessageFormatTest.java index 091595c70ef..b256e23f997 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidLogMessageFormatTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidLogMessageFormatTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/JUnitSpellingTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/JUnitSpellingTest.java index faaffea06c3..44318e2b13b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/JUnitSpellingTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/JUnitSpellingTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/JUnitStaticSuiteTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/JUnitStaticSuiteTest.java index 858cc27ba48..89d784d0fb9 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/JUnitStaticSuiteTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/JUnitStaticSuiteTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/JumbledIncrementerTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/JumbledIncrementerTest.java index ac16e6555e4..67f1397f6cf 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/JumbledIncrementerTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/JumbledIncrementerTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MethodWithSameNameAsEnclosingClassTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MethodWithSameNameAsEnclosingClassTest.java index fe78042cbf5..600b0a96787 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MethodWithSameNameAsEnclosingClassTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MethodWithSameNameAsEnclosingClassTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MisplacedNullCheckTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MisplacedNullCheckTest.java index 3f5c5a01069..a0aa41285ca 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MisplacedNullCheckTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MisplacedNullCheckTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingSerialVersionUIDBase.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingSerialVersionUIDBase.java index f402d9a7931..9e8cf553df3 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingSerialVersionUIDBase.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingSerialVersionUIDBase.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingSerialVersionUIDTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingSerialVersionUIDTest.java index bb338c59698..9a36f76c936 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingSerialVersionUIDTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingSerialVersionUIDTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingStaticMethodInNonInstantiatableClassTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingStaticMethodInNonInstantiatableClassTest.java index cadf17f5f91..67c12590150 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingStaticMethodInNonInstantiatableClassTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingStaticMethodInNonInstantiatableClassTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MoreThanOneLoggerTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MoreThanOneLoggerTest.java index fedc2ed3269..f99b2302c47 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MoreThanOneLoggerTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MoreThanOneLoggerTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MyInterface.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MyInterface.java index b8ae7fb7eb5..a9627bec1cc 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MyInterface.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MyInterface.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/NonCaseLabelInSwitchTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/NonCaseLabelInSwitchTest.java index 8644b8d91c8..5ba633cf480 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/NonCaseLabelInSwitchTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/NonCaseLabelInSwitchTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/NonSerializableClassTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/NonSerializableClassTest.java index 5cc867bdb8a..5013db34a64 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/NonSerializableClassTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/NonSerializableClassTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/NonStaticInitializerTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/NonStaticInitializerTest.java index a971ea77c36..f3c35ef5ff7 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/NonStaticInitializerTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/NonStaticInitializerTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/NullAssignmentTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/NullAssignmentTest.java index 140df2e813d..59ba6700a7f 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/NullAssignmentTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/NullAssignmentTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashcodeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashcodeTest.java index 7611bfaa34d..a11bb64c115 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashcodeTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashcodeTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ProperCloneImplementationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ProperCloneImplementationTest.java index a6f9bbe99a7..f483b84882c 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ProperCloneImplementationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ProperCloneImplementationTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ProperLoggerTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ProperLoggerTest.java index 602ad8bdd52..ff84aca1b82 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ProperLoggerTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ProperLoggerTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReturnEmptyCollectionRatherThanNullTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReturnEmptyCollectionRatherThanNullTest.java index 499e6d67282..2340e46a3ef 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReturnEmptyCollectionRatherThanNullTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReturnEmptyCollectionRatherThanNullTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReturnFromFinallyBlockTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReturnFromFinallyBlockTest.java index b3e87a6011c..756b46f0a83 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReturnFromFinallyBlockTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReturnFromFinallyBlockTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SimpleDateFormatNeedsLocaleTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SimpleDateFormatNeedsLocaleTest.java index 51199fb4996..46cb8c729f8 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SimpleDateFormatNeedsLocaleTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SimpleDateFormatNeedsLocaleTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SingleMethodSingletonTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SingleMethodSingletonTest.java index e77ffe6cb01..22a7289b95e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SingleMethodSingletonTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SingleMethodSingletonTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SingletonClassReturningNewInstanceTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SingletonClassReturningNewInstanceTest.java index 2b178c9b729..27007ee30d3 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SingletonClassReturningNewInstanceTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SingletonClassReturningNewInstanceTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/StaticEJBFieldShouldBeFinalTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/StaticEJBFieldShouldBeFinalTest.java index 0b3916d1310..bb3058c2d71 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/StaticEJBFieldShouldBeFinalTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/StaticEJBFieldShouldBeFinalTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/StringBufferInstantiationWithCharTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/StringBufferInstantiationWithCharTest.java index f33dfcfd38c..35dde4bfd99 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/StringBufferInstantiationWithCharTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/StringBufferInstantiationWithCharTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SuspiciousEqualsMethodNameTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SuspiciousEqualsMethodNameTest.java index 0193d8d266e..96c12191231 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SuspiciousEqualsMethodNameTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SuspiciousEqualsMethodNameTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SuspiciousHashcodeMethodNameTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SuspiciousHashcodeMethodNameTest.java index 6e341e0ebdf..4416f951290 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SuspiciousHashcodeMethodNameTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SuspiciousHashcodeMethodNameTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SuspiciousOctalEscapeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SuspiciousOctalEscapeTest.java index 5c17a207558..d1d1ca12e88 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SuspiciousOctalEscapeTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/SuspiciousOctalEscapeTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/TestClassWithoutTestCasesTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/TestClassWithoutTestCasesTest.java index b0a4edebcea..9d52e77b16a 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/TestClassWithoutTestCasesTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/TestClassWithoutTestCasesTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnconditionalIfStatementTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnconditionalIfStatementTest.java index 6485314b6c4..e0fa92d7a0b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnconditionalIfStatementTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnconditionalIfStatementTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnnecessaryBooleanAssertionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnnecessaryBooleanAssertionTest.java index 87621208a97..59383c9782a 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnnecessaryBooleanAssertionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnnecessaryBooleanAssertionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnnecessaryCaseChangeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnnecessaryCaseChangeTest.java index 1a39ba29be2..d2df58747c4 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnnecessaryCaseChangeTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnnecessaryCaseChangeTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnnecessaryConversionTemporaryTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnnecessaryConversionTemporaryTest.java index 54dfa6fc6c7..4e928540db4 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnnecessaryConversionTemporaryTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnnecessaryConversionTemporaryTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnusedNullCheckInEqualsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnusedNullCheckInEqualsTest.java index 03383eca022..faaa25055bb 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnusedNullCheckInEqualsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnusedNullCheckInEqualsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UseCorrectExceptionLoggingTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UseCorrectExceptionLoggingTest.java index deda76b27e8..c2b4f6117ef 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UseCorrectExceptionLoggingTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UseCorrectExceptionLoggingTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UseEqualsToCompareStringsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UseEqualsToCompareStringsTest.java index 482ed8de750..d53d2782a5f 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UseEqualsToCompareStringsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UseEqualsToCompareStringsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UseLocaleWithCaseConversionsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UseLocaleWithCaseConversionsTest.java index d592198d36f..91fb7791ccf 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UseLocaleWithCaseConversionsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UseLocaleWithCaseConversionsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UseProperClassLoaderTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UseProperClassLoaderTest.java index c310e272489..817f527bf26 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UseProperClassLoaderTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UseProperClassLoaderTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessOperationOnImmutableTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessOperationOnImmutableTest.java index eb8596e34e7..be1a7310045 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessOperationOnImmutableTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessOperationOnImmutableTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/closeresource/CustomStringWriter.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/closeresource/CustomStringWriter.java index fc56da5596d..44e101492f5 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/closeresource/CustomStringWriter.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/closeresource/CustomStringWriter.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/AvoidSynchronizedAtMethodLevelTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/AvoidSynchronizedAtMethodLevelTest.java index dd623cd3410..6ee306d4ce6 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/AvoidSynchronizedAtMethodLevelTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/AvoidSynchronizedAtMethodLevelTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/AvoidSynchronizedStatementTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/AvoidSynchronizedStatementTest.java index bb021942122..b6fe3ba8c05 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/AvoidSynchronizedStatementTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/AvoidSynchronizedStatementTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/AvoidThreadGroupTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/AvoidThreadGroupTest.java index 0c06cbd520e..cea8ac55b4a 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/AvoidThreadGroupTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/AvoidThreadGroupTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/AvoidUsingVolatileTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/AvoidUsingVolatileTest.java index 5b34e87a17c..5aad06bad92 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/AvoidUsingVolatileTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/AvoidUsingVolatileTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoNotUseThreadsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoNotUseThreadsTest.java index dc8b383e6bd..fdf3119488b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoNotUseThreadsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoNotUseThreadsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/DontCallThreadRunTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/DontCallThreadRunTest.java index 53120d95285..414a099a202 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/DontCallThreadRunTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/DontCallThreadRunTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoubleCheckedLockingTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoubleCheckedLockingTest.java index 903ad31b5f0..f0371c998c9 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoubleCheckedLockingTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoubleCheckedLockingTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/NonThreadSafeSingletonTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/NonThreadSafeSingletonTest.java index b3ff3d7dba6..e0c4eecc6be 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/NonThreadSafeSingletonTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/NonThreadSafeSingletonTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/UnsynchronizedStaticFormatterTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/UnsynchronizedStaticFormatterTest.java index 0d3f1cbd57c..f8338326299 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/UnsynchronizedStaticFormatterTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/UnsynchronizedStaticFormatterTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/UseConcurrentHashMapTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/UseConcurrentHashMapTest.java index 2959aeaee61..c581ded473a 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/UseConcurrentHashMapTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/UseConcurrentHashMapTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/UseNotifyAllInsteadOfNotifyTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/UseNotifyAllInsteadOfNotifyTest.java index 5a93c3355bd..5213579eaab 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/UseNotifyAllInsteadOfNotifyTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/multithreading/UseNotifyAllInsteadOfNotifyTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AddEmptyStringTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AddEmptyStringTest.java index 37fddac850a..0c6a8f37c44 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AddEmptyStringTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AddEmptyStringTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AppendCharacterWithCharTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AppendCharacterWithCharTest.java index 46ece8b8515..42cc2598e9d 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AppendCharacterWithCharTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AppendCharacterWithCharTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AvoidArrayLoopsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AvoidArrayLoopsTest.java index a0bca3e5f51..1d4b3208b3e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AvoidArrayLoopsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AvoidArrayLoopsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AvoidCalendarDateCreationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AvoidCalendarDateCreationTest.java index dfbab655278..a56ce342d5a 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AvoidCalendarDateCreationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AvoidCalendarDateCreationTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AvoidFileStreamTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AvoidFileStreamTest.java index 5df006ff243..e489c3f1f45 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AvoidFileStreamTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AvoidFileStreamTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AvoidInstantiatingObjectsInLoopsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AvoidInstantiatingObjectsInLoopsTest.java index 852c358a135..93f83be2414 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AvoidInstantiatingObjectsInLoopsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/AvoidInstantiatingObjectsInLoopsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/BigIntegerInstantiationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/BigIntegerInstantiationTest.java index 61670a78284..8c54897b7f5 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/BigIntegerInstantiationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/BigIntegerInstantiationTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveAppendsShouldReuseTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveAppendsShouldReuseTest.java index d0579e70f77..6d39cbdf7a1 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveAppendsShouldReuseTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveAppendsShouldReuseTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveLiteralAppendsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveLiteralAppendsTest.java index 7c8a1881522..a9f8d5af726 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveLiteralAppendsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveLiteralAppendsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientEmptyStringCheckTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientEmptyStringCheckTest.java index 480a3076983..37251cb72c2 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientEmptyStringCheckTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientEmptyStringCheckTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientStringBufferingTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientStringBufferingTest.java index 54ffe496af1..94aa156d806 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientStringBufferingTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientStringBufferingTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationTest.java index e98a01ad114..5730bbc27f6 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/OptimizableToArrayCallTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/OptimizableToArrayCallTest.java index e5f1e928345..60899fa73cd 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/OptimizableToArrayCallTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/OptimizableToArrayCallTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/RedundantFieldInitializerTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/RedundantFieldInitializerTest.java index 515a3ea422a..7f4644bc0f9 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/RedundantFieldInitializerTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/RedundantFieldInitializerTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/StringInstantiationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/StringInstantiationTest.java index 893a5a43326..ba8610ffc30 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/StringInstantiationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/StringInstantiationTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/StringToStringTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/StringToStringTest.java index 54ceb4ad7d7..f74278d6bc2 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/StringToStringTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/StringToStringTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/TooFewBranchesForSwitchTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/TooFewBranchesForSwitchTest.java index 1787e14681e..ead4bcd30d2 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/TooFewBranchesForSwitchTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/TooFewBranchesForSwitchTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UseArrayListInsteadOfVectorTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UseArrayListInsteadOfVectorTest.java index 57a489e8156..b90a458726d 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UseArrayListInsteadOfVectorTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UseArrayListInsteadOfVectorTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UseArraysAsListTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UseArraysAsListTest.java index db1b6dc67be..9873a262355 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UseArraysAsListTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UseArraysAsListTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UseIndexOfCharTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UseIndexOfCharTest.java index fdb10da98c5..005622e2e4b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UseIndexOfCharTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UseIndexOfCharTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UseStringBufferLengthTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UseStringBufferLengthTest.java index a79cf05c1af..29b5f9d7169 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UseStringBufferLengthTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UseStringBufferLengthTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UselessStringValueOfTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UselessStringValueOfTest.java index 4ddf1ee0253..37455fa5cec 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UselessStringValueOfTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/performance/UselessStringValueOfTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/ast/FullTypeAnnotations.java b/pmd-java/src/test/resources/net/sourceforge/pmd/ast/FullTypeAnnotations.java index e4f7a995ad1..2e6a515c6e6 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/ast/FullTypeAnnotations.java +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/ast/FullTypeAnnotations.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/cli/EmptyIfStatement.java b/pmd-java/src/test/resources/net/sourceforge/pmd/cli/EmptyIfStatement.java index 5406a9fe84c..e99a78f111f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/cli/EmptyIfStatement.java +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/cli/EmptyIfStatement.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ @@ -10,4 +10,4 @@ public class EmptyIfStatement { public void foo() { if (1 == 2) { } } -} \ No newline at end of file +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases.java index e5ad4b99dae..457dc0e0c74 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases.java +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.java index 42e409469d9..ca8849fdfdc 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.java +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases18.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases18.java index 8651c40fe58..82d83097df4 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases18.java +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases18.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/private_method_in_inner_class_interface1.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/private_method_in_inner_class_interface1.java index df2809d14f8..8b1c79deff7 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/private_method_in_inner_class_interface1.java +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/private_method_in_inner_class_interface1.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/private_method_in_inner_class_interface2.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/private_method_in_inner_class_interface2.java index 06ec5637ab3..f9bc410f282 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/private_method_in_inner_class_interface2.java +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/private_method_in_inner_class_interface2.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/StringTemplateReduction2.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/StringTemplateReduction2.java index 803c213ca76..45ad1a16865 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/StringTemplateReduction2.java +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/cpd/testdata/StringTemplateReduction2.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ From 514594fbc5d91daa4cd15351827cf89ca8e0e8ea Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Jul 2025 10:43:41 +0200 Subject: [PATCH 1103/1962] chore: pmd-javascript: Update license header --- .../pmd/lang/ecmascript/EcmascriptLanguageModule.java | 2 +- .../ecmascript/rule/bestpractices/ConsistentReturnRule.java | 2 +- .../sourceforge/pmd/lang/typescript/cpd/TypeScriptCpdLexer.java | 2 +- .../sourceforge/pmd/lang/ecmascript/LanguageVersionTest.java | 2 +- .../java/net/sourceforge/pmd/lang/ecmascript/PMDTaskTest.java | 2 +- .../java/net/sourceforge/pmd/lang/ecmascript/ReportTest.java | 2 +- .../net/sourceforge/pmd/lang/ecmascript/RuleSetFactoryTest.java | 2 +- .../pmd/lang/ecmascript/ast/ASTFunctionNodeTest.java | 2 +- .../pmd/lang/ecmascript/ast/ASTTryStatementTest.java | 2 +- .../pmd/lang/ecmascript/ast/EcmascriptParserTest.java | 2 +- .../pmd/lang/ecmascript/ast/EcmascriptParserTestBase.java | 2 +- .../sourceforge/pmd/lang/ecmascript/ast/JsParsingHelper.java | 2 +- .../sourceforge/pmd/lang/ecmascript/ast/TrailingCommaTest.java | 2 +- .../ecmascript/rule/bestpractices/AvoidWithStatementTest.java | 2 +- .../ecmascript/rule/bestpractices/ConsistentReturnTest.java | 2 +- .../lang/ecmascript/rule/bestpractices/GlobalVariableTest.java | 2 +- .../ecmascript/rule/bestpractices/ScopeForInVariableTest.java | 2 +- .../ecmascript/rule/bestpractices/UseBaseWithParseIntTest.java | 2 +- .../lang/ecmascript/rule/codestyle/AssignmentInOperandTest.java | 2 +- .../ecmascript/rule/codestyle/ForLoopsMustUseBracesTest.java | 2 +- .../ecmascript/rule/codestyle/IfElseStmtsMustUseBracesTest.java | 2 +- .../ecmascript/rule/codestyle/IfStmtsMustUseBracesTest.java | 2 +- .../pmd/lang/ecmascript/rule/codestyle/NoElseReturnTest.java | 2 +- .../lang/ecmascript/rule/codestyle/UnnecessaryBlockTest.java | 2 +- .../ecmascript/rule/codestyle/UnnecessaryParenthesesTest.java | 2 +- .../pmd/lang/ecmascript/rule/codestyle/UnreachableCodeTest.java | 2 +- .../ecmascript/rule/codestyle/WhileLoopsMustUseBracesTest.java | 2 +- .../lang/ecmascript/rule/errorprone/AvoidTrailingCommaTest.java | 2 +- .../lang/ecmascript/rule/errorprone/EqualComparisonTest.java | 2 +- .../rule/errorprone/InaccurateNumericLiteralTest.java | 2 +- .../pmd/lang/typescript/cpd/TypeScriptCpdLexerTest.java | 2 +- 31 files changed, 31 insertions(+), 31 deletions(-) diff --git a/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/EcmascriptLanguageModule.java b/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/EcmascriptLanguageModule.java index 31bc4af4aa9..233accc240b 100644 --- a/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/EcmascriptLanguageModule.java +++ b/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/EcmascriptLanguageModule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/ConsistentReturnRule.java b/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/ConsistentReturnRule.java index e159f2f14c1..44a9a867547 100644 --- a/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/ConsistentReturnRule.java +++ b/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/ConsistentReturnRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/typescript/cpd/TypeScriptCpdLexer.java b/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/typescript/cpd/TypeScriptCpdLexer.java index aa18c60d5b9..89405a3128f 100644 --- a/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/typescript/cpd/TypeScriptCpdLexer.java +++ b/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/typescript/cpd/TypeScriptCpdLexer.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/LanguageVersionTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/LanguageVersionTest.java index c835b51951d..da9135c118e 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/LanguageVersionTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/LanguageVersionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/PMDTaskTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/PMDTaskTest.java index c77cdb9cce3..534e7de8a85 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/PMDTaskTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/PMDTaskTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ReportTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ReportTest.java index be7fc68b18f..521a922d25a 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ReportTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ReportTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/RuleSetFactoryTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/RuleSetFactoryTest.java index 61cfb5bfc09..61c8b84d111 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/RuleSetFactoryTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/RuleSetFactoryTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTFunctionNodeTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTFunctionNodeTest.java index 011d836b049..83320806e11 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTFunctionNodeTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTFunctionNodeTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTTryStatementTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTTryStatementTest.java index 75f1fa6f72c..8c0059f9bc0 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTTryStatementTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTTryStatementTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParserTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParserTest.java index ee5354a7eed..e8f4e35cc1c 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParserTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParserTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParserTestBase.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParserTestBase.java index ff9c6c46e39..7b8e4f6fe44 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParserTestBase.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParserTestBase.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/JsParsingHelper.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/JsParsingHelper.java index 74ca07591f3..8031d15b615 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/JsParsingHelper.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/JsParsingHelper.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/TrailingCommaTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/TrailingCommaTest.java index 48dc3225539..ca84f12d89b 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/TrailingCommaTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/TrailingCommaTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/AvoidWithStatementTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/AvoidWithStatementTest.java index be636f6ca7e..8873662b876 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/AvoidWithStatementTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/AvoidWithStatementTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/ConsistentReturnTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/ConsistentReturnTest.java index 0d2066ec8b6..73a13b00ed6 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/ConsistentReturnTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/ConsistentReturnTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/GlobalVariableTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/GlobalVariableTest.java index e949d1e498f..45175baa440 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/GlobalVariableTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/GlobalVariableTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/ScopeForInVariableTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/ScopeForInVariableTest.java index 390b61c5f03..11eaab41633 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/ScopeForInVariableTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/ScopeForInVariableTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/UseBaseWithParseIntTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/UseBaseWithParseIntTest.java index b6aab8d246c..35d4a2bb0a6 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/UseBaseWithParseIntTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/bestpractices/UseBaseWithParseIntTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/AssignmentInOperandTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/AssignmentInOperandTest.java index 8d83dfa58c3..5d5cfeced4f 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/AssignmentInOperandTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/AssignmentInOperandTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/ForLoopsMustUseBracesTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/ForLoopsMustUseBracesTest.java index c992b704b99..ae8919bf297 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/ForLoopsMustUseBracesTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/ForLoopsMustUseBracesTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/IfElseStmtsMustUseBracesTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/IfElseStmtsMustUseBracesTest.java index d2afcf84f16..f106a069011 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/IfElseStmtsMustUseBracesTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/IfElseStmtsMustUseBracesTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/IfStmtsMustUseBracesTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/IfStmtsMustUseBracesTest.java index e5d996f6547..b5b6e9e1837 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/IfStmtsMustUseBracesTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/IfStmtsMustUseBracesTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/NoElseReturnTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/NoElseReturnTest.java index abbe38ecbb9..6d33e39c925 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/NoElseReturnTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/NoElseReturnTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/UnnecessaryBlockTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/UnnecessaryBlockTest.java index 97390b04c57..3529fb750b0 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/UnnecessaryBlockTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/UnnecessaryBlockTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/UnnecessaryParenthesesTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/UnnecessaryParenthesesTest.java index b50f4927af7..5cfe0cc68e1 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/UnnecessaryParenthesesTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/UnnecessaryParenthesesTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/UnreachableCodeTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/UnreachableCodeTest.java index 438e03aa2f1..a89d64de899 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/UnreachableCodeTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/UnreachableCodeTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/WhileLoopsMustUseBracesTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/WhileLoopsMustUseBracesTest.java index 4878c6aac67..97d6e0f2266 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/WhileLoopsMustUseBracesTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/WhileLoopsMustUseBracesTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/errorprone/AvoidTrailingCommaTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/errorprone/AvoidTrailingCommaTest.java index 2406d43308b..6dbc212f154 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/errorprone/AvoidTrailingCommaTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/errorprone/AvoidTrailingCommaTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/errorprone/EqualComparisonTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/errorprone/EqualComparisonTest.java index b7947031574..78709447d7c 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/errorprone/EqualComparisonTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/errorprone/EqualComparisonTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/errorprone/InaccurateNumericLiteralTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/errorprone/InaccurateNumericLiteralTest.java index 976e888e176..cf1be2cc058 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/errorprone/InaccurateNumericLiteralTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/rule/errorprone/InaccurateNumericLiteralTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/typescript/cpd/TypeScriptCpdLexerTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/typescript/cpd/TypeScriptCpdLexerTest.java index f37676926e4..0441841c9f4 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/typescript/cpd/TypeScriptCpdLexerTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/typescript/cpd/TypeScriptCpdLexerTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ From da25c243e092baf51b710c905f10b78d29862329 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Jul 2025 10:53:57 +0200 Subject: [PATCH 1104/1962] chore: pmd-jsp: Update license header --- .../pmd/lang/jsp/rule/design/NoInlineStyleInformationRule.java | 2 +- .../lang/jsp/rule/security/NoUnsanitizedJSPExpressionRule.java | 2 +- .../test/java/net/sourceforge/pmd/lang/jsp/JspParserTest.java | 2 +- .../java/net/sourceforge/pmd/lang/jsp/LanguageVersionTest.java | 2 +- .../java/net/sourceforge/pmd/lang/jsp/RuleSetFactoryTest.java | 2 +- .../net/sourceforge/pmd/lang/jsp/ast/AbstractJspNodesTst.java | 2 +- .../java/net/sourceforge/pmd/lang/jsp/ast/JspDocStyleTest.java | 2 +- .../java/net/sourceforge/pmd/lang/jsp/ast/JspPageStyleTest.java | 2 +- .../java/net/sourceforge/pmd/lang/jsp/ast/JspParsingHelper.java | 2 +- .../net/sourceforge/pmd/lang/jsp/ast/OpenTagRegisterTest.java | 2 +- .../java/net/sourceforge/pmd/lang/jsp/ast/XPathJspRuleTest.java | 2 +- .../jsp/rule/bestpractices/DontNestJsfInJstlIterationTest.java | 2 +- .../pmd/lang/jsp/rule/bestpractices/NoClassAttributeTest.java | 2 +- .../pmd/lang/jsp/rule/bestpractices/NoHtmlCommentsTest.java | 2 +- .../pmd/lang/jsp/rule/bestpractices/NoJspForwardTest.java | 2 +- .../pmd/lang/jsp/rule/codestyle/DuplicateJspImportsTest.java | 2 +- .../pmd/lang/jsp/rule/design/NoInlineScriptTest.java | 2 +- .../pmd/lang/jsp/rule/design/NoInlineStyleInformationTest.java | 2 +- .../sourceforge/pmd/lang/jsp/rule/design/NoLongScriptsTest.java | 2 +- .../sourceforge/pmd/lang/jsp/rule/design/NoScriptletsTest.java | 2 +- .../pmd/lang/jsp/rule/errorprone/JspEncodingTest.java | 2 +- .../lang/jsp/rule/security/IframeMissingSrcAttributeTest.java | 2 +- .../lang/jsp/rule/security/NoUnsanitizedJSPExpressionTest.java | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/rule/design/NoInlineStyleInformationRule.java b/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/rule/design/NoInlineStyleInformationRule.java index 685c8a97f43..1d835d8b2a3 100644 --- a/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/rule/design/NoInlineStyleInformationRule.java +++ b/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/rule/design/NoInlineStyleInformationRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/rule/security/NoUnsanitizedJSPExpressionRule.java b/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/rule/security/NoUnsanitizedJSPExpressionRule.java index 3561e397b2b..f3726c31682 100644 --- a/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/rule/security/NoUnsanitizedJSPExpressionRule.java +++ b/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/rule/security/NoUnsanitizedJSPExpressionRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/JspParserTest.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/JspParserTest.java index fb0367c940c..5ef5bc6a951 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/JspParserTest.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/JspParserTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/LanguageVersionTest.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/LanguageVersionTest.java index 303be4dbd69..fb8693dbb6b 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/LanguageVersionTest.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/LanguageVersionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/RuleSetFactoryTest.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/RuleSetFactoryTest.java index e9e19c024cb..25b027ebd4a 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/RuleSetFactoryTest.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/RuleSetFactoryTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/AbstractJspNodesTst.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/AbstractJspNodesTst.java index fd8c4082fb9..8da16da266a 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/AbstractJspNodesTst.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/AbstractJspNodesTst.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/JspDocStyleTest.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/JspDocStyleTest.java index 5cb956609e7..c5f890ea229 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/JspDocStyleTest.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/JspDocStyleTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/JspPageStyleTest.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/JspPageStyleTest.java index 6206bc10345..e6ca4775916 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/JspPageStyleTest.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/JspPageStyleTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/JspParsingHelper.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/JspParsingHelper.java index a41f150d32a..414bf762009 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/JspParsingHelper.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/JspParsingHelper.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/OpenTagRegisterTest.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/OpenTagRegisterTest.java index 04c13d7846f..9c02f0c4429 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/OpenTagRegisterTest.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/OpenTagRegisterTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/XPathJspRuleTest.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/XPathJspRuleTest.java index 0e93b4b7a70..83e5df32325 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/XPathJspRuleTest.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/XPathJspRuleTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/bestpractices/DontNestJsfInJstlIterationTest.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/bestpractices/DontNestJsfInJstlIterationTest.java index 9947b4b7532..a8dc25949ea 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/bestpractices/DontNestJsfInJstlIterationTest.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/bestpractices/DontNestJsfInJstlIterationTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/bestpractices/NoClassAttributeTest.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/bestpractices/NoClassAttributeTest.java index 672db299c78..869b74214f8 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/bestpractices/NoClassAttributeTest.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/bestpractices/NoClassAttributeTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/bestpractices/NoHtmlCommentsTest.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/bestpractices/NoHtmlCommentsTest.java index 3832823a05b..7ef5213fdf8 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/bestpractices/NoHtmlCommentsTest.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/bestpractices/NoHtmlCommentsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/bestpractices/NoJspForwardTest.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/bestpractices/NoJspForwardTest.java index a76a1aea750..65cdb4b5172 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/bestpractices/NoJspForwardTest.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/bestpractices/NoJspForwardTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/codestyle/DuplicateJspImportsTest.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/codestyle/DuplicateJspImportsTest.java index 3beab29c655..ee469514a8e 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/codestyle/DuplicateJspImportsTest.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/codestyle/DuplicateJspImportsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/design/NoInlineScriptTest.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/design/NoInlineScriptTest.java index f0bf436d1b5..38955035ca4 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/design/NoInlineScriptTest.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/design/NoInlineScriptTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/design/NoInlineStyleInformationTest.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/design/NoInlineStyleInformationTest.java index e7333d6da47..dd1c04345ab 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/design/NoInlineStyleInformationTest.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/design/NoInlineStyleInformationTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/design/NoLongScriptsTest.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/design/NoLongScriptsTest.java index fef126e2c51..25f73b13ed3 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/design/NoLongScriptsTest.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/design/NoLongScriptsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/design/NoScriptletsTest.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/design/NoScriptletsTest.java index 6723f8fabe0..2ef6c62d2df 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/design/NoScriptletsTest.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/design/NoScriptletsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/errorprone/JspEncodingTest.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/errorprone/JspEncodingTest.java index fc2bfc86f29..70384c83583 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/errorprone/JspEncodingTest.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/errorprone/JspEncodingTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/security/IframeMissingSrcAttributeTest.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/security/IframeMissingSrcAttributeTest.java index 6eb20112d87..0ae8316eb13 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/security/IframeMissingSrcAttributeTest.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/security/IframeMissingSrcAttributeTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/security/NoUnsanitizedJSPExpressionTest.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/security/NoUnsanitizedJSPExpressionTest.java index 21f79ed3d6d..1c95e97cd9e 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/security/NoUnsanitizedJSPExpressionTest.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/rule/security/NoUnsanitizedJSPExpressionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ From 7424798e9b8abc56f0a70552c4a732d96b87ef49 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Jul 2025 10:58:58 +0200 Subject: [PATCH 1105/1962] chore: pmd-julia: Update license header --- .../java/net/sourceforge/pmd/lang/julia/cpd/JuliaCpdLexer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-julia/src/main/java/net/sourceforge/pmd/lang/julia/cpd/JuliaCpdLexer.java b/pmd-julia/src/main/java/net/sourceforge/pmd/lang/julia/cpd/JuliaCpdLexer.java index b9c3684bfe8..a481f4d6e09 100644 --- a/pmd-julia/src/main/java/net/sourceforge/pmd/lang/julia/cpd/JuliaCpdLexer.java +++ b/pmd-julia/src/main/java/net/sourceforge/pmd/lang/julia/cpd/JuliaCpdLexer.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ From 0e1f23ee1e2950a9701ab076fbfd9681a3e82733 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Jul 2025 11:04:37 +0200 Subject: [PATCH 1106/1962] chore: pmd-kotlin: Update license header --- .../net/sourceforge/pmd/lang/kotlin/AbstractKotlinRule.java | 2 +- .../java/net/sourceforge/pmd/lang/kotlin/KotlinHandler.java | 2 +- .../net/sourceforge/pmd/lang/kotlin/KotlinLanguageModule.java | 2 +- .../net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java | 2 +- .../kotlin/rule/bestpractices/FunctionNameTooShortTest.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/AbstractKotlinRule.java b/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/AbstractKotlinRule.java index e824bee510e..dc00612c9a9 100644 --- a/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/AbstractKotlinRule.java +++ b/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/AbstractKotlinRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/KotlinHandler.java b/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/KotlinHandler.java index 4302bf39d4d..6d687c39815 100644 --- a/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/KotlinHandler.java +++ b/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/KotlinHandler.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/KotlinLanguageModule.java b/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/KotlinLanguageModule.java index d4a8bbd0a7b..732d512853e 100644 --- a/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/KotlinLanguageModule.java +++ b/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/KotlinLanguageModule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java b/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java index ed8c4339828..1916b796ed8 100644 --- a/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java +++ b/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/UnicodeClasses.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-kotlin/src/test/java/net/sourceforge/pmd/lang/kotlin/rule/bestpractices/FunctionNameTooShortTest.java b/pmd-kotlin/src/test/java/net/sourceforge/pmd/lang/kotlin/rule/bestpractices/FunctionNameTooShortTest.java index 24d80ce15e3..950acf45395 100644 --- a/pmd-kotlin/src/test/java/net/sourceforge/pmd/lang/kotlin/rule/bestpractices/FunctionNameTooShortTest.java +++ b/pmd-kotlin/src/test/java/net/sourceforge/pmd/lang/kotlin/rule/bestpractices/FunctionNameTooShortTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ From 4aa9286d960b1c74a72a7c5a1078eb37a895d40c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Jul 2025 11:09:55 +0200 Subject: [PATCH 1107/1962] chore: pmd-modelica: Update license header --- .../java/net/sourceforge/pmd/lang/modelica/ModelicaHandler.java | 2 +- .../sourceforge/pmd/lang/modelica/ModelicaLanguageModule.java | 2 +- .../sourceforge/pmd/lang/modelica/ast/ASTClassDefinition.java | 2 +- .../pmd/lang/modelica/ast/ASTComponentReference.java | 2 +- .../sourceforge/pmd/lang/modelica/ast/ASTDerClassSpecifier.java | 2 +- .../net/sourceforge/pmd/lang/modelica/ast/ASTElementList.java | 2 +- .../lang/modelica/ast/ASTEnumerationShortClassSpecifier.java | 2 +- .../pmd/lang/modelica/ast/ASTExtendingLongClassSpecifier.java | 2 +- .../lang/modelica/ast/ASTMultipleDefinitionImportClause.java | 2 +- .../java/net/sourceforge/pmd/lang/modelica/ast/ASTName.java | 2 +- .../pmd/lang/modelica/ast/ASTRenamingImportClause.java | 2 +- .../pmd/lang/modelica/ast/ASTSimpleLongClassSpecifier.java | 2 +- .../pmd/lang/modelica/ast/ASTSimpleShortClassSpecifier.java | 2 +- .../pmd/lang/modelica/ast/ASTSingleDefinitionImportClause.java | 2 +- .../sourceforge/pmd/lang/modelica/ast/ASTStoredDefinition.java | 2 +- .../pmd/lang/modelica/ast/ASTUnqualifiedImportClause.java | 2 +- .../net/sourceforge/pmd/lang/modelica/ast/ASTWithinClause.java | 2 +- .../lang/modelica/ast/AbstractModelicaClassSpecifierNode.java | 2 +- .../pmd/lang/modelica/ast/AbstractModelicaImportClause.java | 2 +- .../sourceforge/pmd/lang/modelica/ast/AbstractModelicaNode.java | 2 +- .../main/java/net/sourceforge/pmd/lang/modelica/ast/Helper.java | 2 +- .../sourceforge/pmd/lang/modelica/ast/InternalApiBridge.java | 2 +- .../pmd/lang/modelica/ast/ModelicaClassSpecifierNode.java | 2 +- .../sourceforge/pmd/lang/modelica/ast/ModelicaImportClause.java | 2 +- .../net/sourceforge/pmd/lang/modelica/ast/ModelicaNode.java | 2 +- .../pmd/lang/modelica/ast/ResolvableModelicaNode.java | 2 +- .../java/net/sourceforge/pmd/lang/modelica/ast/Visibility.java | 2 +- .../pmd/lang/modelica/resolver/AbstractModelicaDeclaration.java | 2 +- .../pmd/lang/modelica/resolver/AbstractModelicaScope.java | 2 +- .../sourceforge/pmd/lang/modelica/resolver/CompositeName.java | 2 +- .../pmd/lang/modelica/resolver/InternalApiBridge.java | 2 +- .../pmd/lang/modelica/resolver/ModelicaBuiltinType.java | 2 +- .../pmd/lang/modelica/resolver/ModelicaClassDeclaration.java | 2 +- .../pmd/lang/modelica/resolver/ModelicaClassScope.java | 2 +- .../pmd/lang/modelica/resolver/ModelicaClassSpecialization.java | 2 +- .../pmd/lang/modelica/resolver/ModelicaClassType.java | 2 +- .../lang/modelica/resolver/ModelicaComponentDeclaration.java | 2 +- .../pmd/lang/modelica/resolver/ModelicaDeclaration.java | 2 +- .../sourceforge/pmd/lang/modelica/resolver/ModelicaScope.java | 2 +- .../pmd/lang/modelica/resolver/ModelicaSourceFileScope.java | 2 +- .../sourceforge/pmd/lang/modelica/resolver/ModelicaType.java | 2 +- .../pmd/lang/modelica/resolver/ResolutionResult.java | 2 +- .../pmd/lang/modelica/resolver/ResolvableEntity.java | 2 +- .../net/sourceforge/pmd/lang/modelica/resolver/RootScope.java | 2 +- .../pmd/lang/modelica/resolver/ScopeAndDeclarationFinder.java | 2 +- .../pmd/lang/modelica/resolver/SubcomponentResolver.java | 2 +- .../pmd/lang/modelica/resolver/internal/ResolutionContext.java | 2 +- .../pmd/lang/modelica/resolver/internal/ResolutionState.java | 2 +- .../pmd/lang/modelica/resolver/internal/Watchdog.java | 2 +- .../modelica/rule/bestpractices/AmbiguousResolutionRule.java | 2 +- .../rule/bestpractices/ConnectUsingNonConnectorRule.java | 2 +- .../net/sourceforge/pmd/lang/modelica/LanguageVersionTest.java | 2 +- .../net/sourceforge/pmd/lang/modelica/ModelicaParserTest.java | 2 +- .../sourceforge/pmd/lang/modelica/ModelicaParsingHelper.java | 2 +- .../net/sourceforge/pmd/lang/modelica/RuleSetFactoryTest.java | 2 +- .../pmd/lang/modelica/resolver/ModelicaResolverTest.java | 2 +- .../modelica/rule/bestpractices/AmbiguousResolutionTest.java | 2 +- .../rule/bestpractices/ClassStartNameEqualsEndNameTest.java | 2 +- .../rule/bestpractices/ConnectUsingNonConnectorTest.java | 2 +- 59 files changed, 59 insertions(+), 59 deletions(-) diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ModelicaHandler.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ModelicaHandler.java index 2deb0547f9e..9b0edef61bb 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ModelicaHandler.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ModelicaHandler.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ModelicaLanguageModule.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ModelicaLanguageModule.java index 6baba2eae2c..65c19cc4ec8 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ModelicaLanguageModule.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ModelicaLanguageModule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTClassDefinition.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTClassDefinition.java index 3c56c0862f1..c2dc6c86d69 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTClassDefinition.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTClassDefinition.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTComponentReference.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTComponentReference.java index b838dc56564..dc3a5771abc 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTComponentReference.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTComponentReference.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTDerClassSpecifier.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTDerClassSpecifier.java index fb490eec047..fde73401a24 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTDerClassSpecifier.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTDerClassSpecifier.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTElementList.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTElementList.java index 451bbe90d7f..831d1357a32 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTElementList.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTElementList.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTEnumerationShortClassSpecifier.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTEnumerationShortClassSpecifier.java index 9a88f5a990b..47257b4d361 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTEnumerationShortClassSpecifier.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTEnumerationShortClassSpecifier.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTExtendingLongClassSpecifier.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTExtendingLongClassSpecifier.java index ac325dfd915..6a7157312dd 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTExtendingLongClassSpecifier.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTExtendingLongClassSpecifier.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTMultipleDefinitionImportClause.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTMultipleDefinitionImportClause.java index 7e6eef87665..f2bcb368385 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTMultipleDefinitionImportClause.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTMultipleDefinitionImportClause.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTName.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTName.java index f4ffa130eab..cf940ed8d09 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTName.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTName.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTRenamingImportClause.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTRenamingImportClause.java index 2038b8b5090..79c7dbb6ca3 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTRenamingImportClause.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTRenamingImportClause.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTSimpleLongClassSpecifier.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTSimpleLongClassSpecifier.java index 1ade6b14c10..080ebe1e567 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTSimpleLongClassSpecifier.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTSimpleLongClassSpecifier.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTSimpleShortClassSpecifier.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTSimpleShortClassSpecifier.java index 8ad0381623c..0d20d58c6d4 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTSimpleShortClassSpecifier.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTSimpleShortClassSpecifier.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTSingleDefinitionImportClause.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTSingleDefinitionImportClause.java index 4b72743aa96..c00f5aadef4 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTSingleDefinitionImportClause.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTSingleDefinitionImportClause.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTStoredDefinition.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTStoredDefinition.java index 2feef6b0946..ba6bfc28c8d 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTStoredDefinition.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTStoredDefinition.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTUnqualifiedImportClause.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTUnqualifiedImportClause.java index ad4b685b8ca..3e0ce095a66 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTUnqualifiedImportClause.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTUnqualifiedImportClause.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTWithinClause.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTWithinClause.java index c3a972a53f2..35947e2d643 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTWithinClause.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ASTWithinClause.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/AbstractModelicaClassSpecifierNode.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/AbstractModelicaClassSpecifierNode.java index b0d52ee2e41..fda61456737 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/AbstractModelicaClassSpecifierNode.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/AbstractModelicaClassSpecifierNode.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/AbstractModelicaImportClause.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/AbstractModelicaImportClause.java index 98608a1ad0d..d325e5c8652 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/AbstractModelicaImportClause.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/AbstractModelicaImportClause.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/AbstractModelicaNode.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/AbstractModelicaNode.java index ee0d7c9223e..5049aca4765 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/AbstractModelicaNode.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/AbstractModelicaNode.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/Helper.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/Helper.java index 871700b60aa..4142b4903a0 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/Helper.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/Helper.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/InternalApiBridge.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/InternalApiBridge.java index 475f5d046ca..320be32319f 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/InternalApiBridge.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/InternalApiBridge.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ModelicaClassSpecifierNode.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ModelicaClassSpecifierNode.java index 7a39f9902ed..dde973519d9 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ModelicaClassSpecifierNode.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ModelicaClassSpecifierNode.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ModelicaImportClause.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ModelicaImportClause.java index 09774336d27..ef4b77b9e1d 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ModelicaImportClause.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ModelicaImportClause.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ModelicaNode.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ModelicaNode.java index 0acfd1636e7..048f3298d5b 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ModelicaNode.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ModelicaNode.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ResolvableModelicaNode.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ResolvableModelicaNode.java index f3b4c3e50ed..441a9b62d90 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ResolvableModelicaNode.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/ResolvableModelicaNode.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/Visibility.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/Visibility.java index 3e876b39b59..5a3fa3504f9 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/Visibility.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/Visibility.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/AbstractModelicaDeclaration.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/AbstractModelicaDeclaration.java index bc03e13ed17..2ada271a719 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/AbstractModelicaDeclaration.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/AbstractModelicaDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/AbstractModelicaScope.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/AbstractModelicaScope.java index 04556dc870c..fdfe94f93f4 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/AbstractModelicaScope.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/AbstractModelicaScope.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/CompositeName.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/CompositeName.java index e37b053ca69..3bb0dbba610 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/CompositeName.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/CompositeName.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/InternalApiBridge.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/InternalApiBridge.java index 0ae25284904..7ef7190fc55 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/InternalApiBridge.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/InternalApiBridge.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaBuiltinType.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaBuiltinType.java index acff1703962..81683f8e051 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaBuiltinType.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaBuiltinType.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaClassDeclaration.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaClassDeclaration.java index 900b2f487f3..8d88218fcc1 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaClassDeclaration.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaClassDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaClassScope.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaClassScope.java index 4231baa91b5..ace8439461c 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaClassScope.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaClassScope.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaClassSpecialization.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaClassSpecialization.java index 71c177b27aa..5a4b8378811 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaClassSpecialization.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaClassSpecialization.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaClassType.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaClassType.java index e47c69f7f6c..7cf1d281ac4 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaClassType.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaClassType.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaComponentDeclaration.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaComponentDeclaration.java index 2f4a0c11046..c032f2517d0 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaComponentDeclaration.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaComponentDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaDeclaration.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaDeclaration.java index 9808542d3c2..8fc2a5cfffd 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaDeclaration.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaScope.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaScope.java index 0b12d1597b4..31e22a40ff5 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaScope.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaScope.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaSourceFileScope.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaSourceFileScope.java index 1a9e216b99b..b52138ab866 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaSourceFileScope.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaSourceFileScope.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaType.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaType.java index 0078e718a24..e0e8799ee75 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaType.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaType.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ResolutionResult.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ResolutionResult.java index be357b4b34d..c55488b73b1 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ResolutionResult.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ResolutionResult.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ResolvableEntity.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ResolvableEntity.java index 440bd33dbf0..17a30747e27 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ResolvableEntity.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ResolvableEntity.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/RootScope.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/RootScope.java index 2652db5c127..5ed9a68c3c8 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/RootScope.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/RootScope.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ScopeAndDeclarationFinder.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ScopeAndDeclarationFinder.java index e552296e1f3..d12b2cfdb5d 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ScopeAndDeclarationFinder.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ScopeAndDeclarationFinder.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/SubcomponentResolver.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/SubcomponentResolver.java index 7584c83431a..0ec1e77b19f 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/SubcomponentResolver.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/SubcomponentResolver.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/internal/ResolutionContext.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/internal/ResolutionContext.java index 40c60274fd2..50961f0a733 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/internal/ResolutionContext.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/internal/ResolutionContext.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/internal/ResolutionState.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/internal/ResolutionState.java index 3c78958906f..9d471d5df45 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/internal/ResolutionState.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/internal/ResolutionState.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/internal/Watchdog.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/internal/Watchdog.java index d0ab889ebd6..a083dadd253 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/internal/Watchdog.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/internal/Watchdog.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/rule/bestpractices/AmbiguousResolutionRule.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/rule/bestpractices/AmbiguousResolutionRule.java index f42ddfdfb57..43dd91aee4a 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/rule/bestpractices/AmbiguousResolutionRule.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/rule/bestpractices/AmbiguousResolutionRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/rule/bestpractices/ConnectUsingNonConnectorRule.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/rule/bestpractices/ConnectUsingNonConnectorRule.java index d91e5ae4084..17a5f987e8c 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/rule/bestpractices/ConnectUsingNonConnectorRule.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/rule/bestpractices/ConnectUsingNonConnectorRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/LanguageVersionTest.java b/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/LanguageVersionTest.java index f09c75c2bab..674dd9c8c39 100644 --- a/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/LanguageVersionTest.java +++ b/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/LanguageVersionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/ModelicaParserTest.java b/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/ModelicaParserTest.java index 33349b59f28..daf1caf10c4 100644 --- a/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/ModelicaParserTest.java +++ b/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/ModelicaParserTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/ModelicaParsingHelper.java b/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/ModelicaParsingHelper.java index f3e53369026..6be11017b6e 100644 --- a/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/ModelicaParsingHelper.java +++ b/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/ModelicaParsingHelper.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/RuleSetFactoryTest.java b/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/RuleSetFactoryTest.java index fe3902f6de1..b1873357ff1 100644 --- a/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/RuleSetFactoryTest.java +++ b/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/RuleSetFactoryTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaResolverTest.java b/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaResolverTest.java index 2808e058445..7718391101f 100644 --- a/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaResolverTest.java +++ b/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaResolverTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/rule/bestpractices/AmbiguousResolutionTest.java b/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/rule/bestpractices/AmbiguousResolutionTest.java index 201788ca197..a0004d9fd33 100644 --- a/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/rule/bestpractices/AmbiguousResolutionTest.java +++ b/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/rule/bestpractices/AmbiguousResolutionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/rule/bestpractices/ClassStartNameEqualsEndNameTest.java b/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/rule/bestpractices/ClassStartNameEqualsEndNameTest.java index edebad3f189..5065b014867 100644 --- a/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/rule/bestpractices/ClassStartNameEqualsEndNameTest.java +++ b/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/rule/bestpractices/ClassStartNameEqualsEndNameTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/rule/bestpractices/ConnectUsingNonConnectorTest.java b/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/rule/bestpractices/ConnectUsingNonConnectorTest.java index 67b2348d79e..1568344afb7 100644 --- a/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/rule/bestpractices/ConnectUsingNonConnectorTest.java +++ b/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/rule/bestpractices/ConnectUsingNonConnectorTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ From f6c874dac8f60512d3e194751635bf7eb7b0fba6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Jul 2025 11:17:24 +0200 Subject: [PATCH 1108/1962] chore: pmd-plsql: Update license header --- .../main/java/net/sourceforge/pmd/lang/plsql/PLSQLHandler.java | 2 +- .../net/sourceforge/pmd/lang/plsql/PLSQLLanguageModule.java | 2 +- .../pmd/lang/plsql/rule/codestyle/AvoidTabCharacterRule.java | 2 +- .../pmd/lang/plsql/rule/codestyle/CodeFormatRule.java | 2 +- .../pmd/lang/plsql/rule/codestyle/LineLengthRule.java | 2 +- .../pmd/lang/plsql/rule/design/CyclomaticComplexityRule.java | 2 +- .../pmd/lang/plsql/rule/design/ExcessiveMethodLengthRule.java | 2 +- .../pmd/lang/plsql/rule/design/ExcessiveObjectLengthRule.java | 2 +- .../lang/plsql/rule/design/ExcessivePackageBodyLengthRule.java | 2 +- .../rule/design/ExcessivePackageSpecificationLengthRule.java | 2 +- .../pmd/lang/plsql/rule/design/ExcessiveParameterListRule.java | 2 +- .../pmd/lang/plsql/rule/design/ExcessiveTypeLengthRule.java | 2 +- .../pmd/lang/plsql/rule/design/NPathComplexityRule.java | 2 +- .../pmd/lang/plsql/rule/design/NcssObjectCountRule.java | 2 +- .../pmd/lang/plsql/rule/design/TooManyFieldsRule.java | 2 +- .../pmd/lang/plsql/symboltable/ClassNameDeclaration.java | 2 +- .../pmd/lang/plsql/symboltable/MethodNameDeclaration.java | 2 +- .../net/sourceforge/pmd/lang/plsql/symboltable/NameFinder.java | 2 +- .../pmd/lang/plsql/symboltable/OccurrenceFinder.java | 2 +- .../pmd/lang/plsql/symboltable/PLSQLNameOccurrence.java | 2 +- .../java/net/sourceforge/pmd/lang/plsql/symboltable/Search.java | 2 +- .../sourceforge/pmd/lang/plsql/symboltable/SourceFileScope.java | 2 +- .../sourceforge/pmd/lang/plsql/symboltable/SymbolFacade.java | 2 +- .../net/sourceforge/pmd/lang/plsql/symboltable/TypeSet.java | 2 +- .../pmd/lang/plsql/symboltable/VariableNameDeclaration.java | 2 +- .../net/sourceforge/pmd/lang/plsql/AbstractPLSQLParserTst.java | 2 +- .../pmd/lang/plsql/LanguageVersionDiscovererTest.java | 2 +- .../net/sourceforge/pmd/lang/plsql/LanguageVersionTest.java | 2 +- .../java/net/sourceforge/pmd/lang/plsql/PLSQLXPathRuleTest.java | 2 +- .../java/net/sourceforge/pmd/lang/plsql/PlsqlParsingHelper.java | 2 +- .../java/net/sourceforge/pmd/lang/plsql/RuleSetFactoryTest.java | 2 +- .../pmd/lang/plsql/ast/ASTComparisonConditionTest.java | 2 +- .../pmd/lang/plsql/ast/ASTCompoundConditionTest.java | 2 +- .../sourceforge/pmd/lang/plsql/ast/AllPlsqlAstTreeDumpTest.java | 2 +- .../net/sourceforge/pmd/lang/plsql/ast/AnonymousBlockTest.java | 2 +- .../net/sourceforge/pmd/lang/plsql/ast/CreateTableTest.java | 2 +- .../sourceforge/pmd/lang/plsql/ast/CursorAttributesTest.java | 2 +- .../net/sourceforge/pmd/lang/plsql/ast/CursorForLoopTest.java | 2 +- .../net/sourceforge/pmd/lang/plsql/ast/CursorWithWithTest.java | 2 +- .../net/sourceforge/pmd/lang/plsql/ast/DeleteStatementTest.java | 2 +- .../pmd/lang/plsql/ast/ExecuteImmediateBulkCollectTest.java | 2 +- .../sourceforge/pmd/lang/plsql/ast/ExecuteImmediateTest.java | 2 +- .../java/net/sourceforge/pmd/lang/plsql/ast/FunctionsTest.java | 2 +- .../net/sourceforge/pmd/lang/plsql/ast/IfStatementTest.java | 2 +- .../net/sourceforge/pmd/lang/plsql/ast/InOutNoCopyTest.java | 2 +- .../sourceforge/pmd/lang/plsql/ast/InsertIntoClauseTest.java | 2 +- .../java/net/sourceforge/pmd/lang/plsql/ast/JoinClauseTest.java | 2 +- .../sourceforge/pmd/lang/plsql/ast/LexicalParametersTest.java | 2 +- .../sourceforge/pmd/lang/plsql/ast/OrderByExpressionsTest.java | 2 +- .../sourceforge/pmd/lang/plsql/ast/ParenthesisGroupTest.java | 2 +- .../java/net/sourceforge/pmd/lang/plsql/ast/RecordTypeTest.java | 2 +- .../sourceforge/pmd/lang/plsql/ast/SelectExpressionsTest.java | 2 +- .../net/sourceforge/pmd/lang/plsql/ast/SelectForUpdateTest.java | 2 +- .../sourceforge/pmd/lang/plsql/ast/SelectHierarchicalTest.java | 2 +- .../sourceforge/pmd/lang/plsql/ast/SelectIntoStatementTest.java | 2 +- .../pmd/lang/plsql/ast/SelectIntoWithGroupByTest.java | 2 +- .../net/sourceforge/pmd/lang/plsql/ast/SelectUnionTest.java | 2 +- .../net/sourceforge/pmd/lang/plsql/ast/SlashAsDivisionTest.java | 2 +- .../net/sourceforge/pmd/lang/plsql/ast/StringLiteralsTest.java | 2 +- .../pmd/lang/plsql/ast/TableCollectionExpressionTest.java | 2 +- .../net/sourceforge/pmd/lang/plsql/ast/UpdateStatementTest.java | 2 +- .../test/java/net/sourceforge/pmd/lang/plsql/ast/ViewTest.java | 2 +- .../net/sourceforge/pmd/lang/plsql/ast/WhereClauseTest.java | 2 +- .../java/net/sourceforge/pmd/lang/plsql/ast/WithClauseTest.java | 2 +- .../pmd/lang/plsql/rule/bestpractices/TomKytesDespairTest.java | 2 +- .../pmd/lang/plsql/rule/codestyle/AvoidTabCharacterTest.java | 2 +- .../pmd/lang/plsql/rule/codestyle/CodeFormatTest.java | 2 +- .../pmd/lang/plsql/rule/codestyle/ForLoopNamingTest.java | 2 +- .../pmd/lang/plsql/rule/codestyle/LineLengthTest.java | 2 +- .../pmd/lang/plsql/rule/codestyle/MisplacedPragmaTest.java | 2 +- .../pmd/lang/plsql/rule/design/CyclomaticComplexityTest.java | 2 +- .../pmd/lang/plsql/rule/design/ExcessiveMethodLengthTest.java | 2 +- .../pmd/lang/plsql/rule/design/ExcessiveObjectLengthTest.java | 2 +- .../lang/plsql/rule/design/ExcessivePackageBodyLengthTest.java | 2 +- .../rule/design/ExcessivePackageSpecificationLengthTest.java | 2 +- .../pmd/lang/plsql/rule/design/ExcessiveParameterListTest.java | 2 +- .../pmd/lang/plsql/rule/design/ExcessiveTypeLengthTest.java | 2 +- .../pmd/lang/plsql/rule/design/NPathComplexityTest.java | 2 +- .../pmd/lang/plsql/rule/design/NcssMethodCountTest.java | 2 +- .../pmd/lang/plsql/rule/design/NcssObjectCountTest.java | 2 +- .../pmd/lang/plsql/rule/design/TooManyFieldsTest.java | 2 +- .../pmd/lang/plsql/rule/design/TooManyMethodsTest.java | 2 +- .../pmd/lang/plsql/rule/errorprone/ToDateToCharTest.java | 2 +- .../lang/plsql/rule/errorprone/ToDateWithoutDateFormatTest.java | 2 +- .../plsql/rule/errorprone/ToTimestampWithoutDateFormatTest.java | 2 +- 85 files changed, 85 insertions(+), 85 deletions(-) diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/PLSQLHandler.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/PLSQLHandler.java index 5c6b7295e39..93a8f162235 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/PLSQLHandler.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/PLSQLHandler.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/PLSQLLanguageModule.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/PLSQLLanguageModule.java index f5c51bc3d84..9b73c241f57 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/PLSQLLanguageModule.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/PLSQLLanguageModule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/AvoidTabCharacterRule.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/AvoidTabCharacterRule.java index 2c8d9210c05..bead0e2c022 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/AvoidTabCharacterRule.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/AvoidTabCharacterRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/CodeFormatRule.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/CodeFormatRule.java index f0692c9f42a..65b38a52cbf 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/CodeFormatRule.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/CodeFormatRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/LineLengthRule.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/LineLengthRule.java index 07f9a875c3d..958e060fba3 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/LineLengthRule.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/LineLengthRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/CyclomaticComplexityRule.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/CyclomaticComplexityRule.java index c35c9b17526..4d1c38f8630 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/CyclomaticComplexityRule.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/CyclomaticComplexityRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveMethodLengthRule.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveMethodLengthRule.java index dcfb1ec42f2..d916c3f2a4d 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveMethodLengthRule.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveMethodLengthRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveObjectLengthRule.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveObjectLengthRule.java index 273042a97a2..380f5344024 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveObjectLengthRule.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveObjectLengthRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessivePackageBodyLengthRule.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessivePackageBodyLengthRule.java index f103abf0b86..fb178059e3f 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessivePackageBodyLengthRule.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessivePackageBodyLengthRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessivePackageSpecificationLengthRule.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessivePackageSpecificationLengthRule.java index 5cb3150b264..4af0312a215 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessivePackageSpecificationLengthRule.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessivePackageSpecificationLengthRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveParameterListRule.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveParameterListRule.java index 004f9a772ae..92609fe095e 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveParameterListRule.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveParameterListRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveTypeLengthRule.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveTypeLengthRule.java index 3ff292e00f5..821a5349e2d 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveTypeLengthRule.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveTypeLengthRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/NPathComplexityRule.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/NPathComplexityRule.java index 6cd22fa117d..484da52ec6e 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/NPathComplexityRule.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/NPathComplexityRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/NcssObjectCountRule.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/NcssObjectCountRule.java index c8d13ce7756..28f072447ec 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/NcssObjectCountRule.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/NcssObjectCountRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/TooManyFieldsRule.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/TooManyFieldsRule.java index 21552c3ee6d..c48899a8669 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/TooManyFieldsRule.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/TooManyFieldsRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/ClassNameDeclaration.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/ClassNameDeclaration.java index b3181f3e922..347d44f1748 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/ClassNameDeclaration.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/ClassNameDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/MethodNameDeclaration.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/MethodNameDeclaration.java index 442f9c279cc..e6daa79f35f 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/MethodNameDeclaration.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/MethodNameDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/NameFinder.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/NameFinder.java index 8a3084aa124..b4cb28df7ac 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/NameFinder.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/NameFinder.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/OccurrenceFinder.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/OccurrenceFinder.java index 77c7ecf01aa..f7ca0ee01d6 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/OccurrenceFinder.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/OccurrenceFinder.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/PLSQLNameOccurrence.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/PLSQLNameOccurrence.java index 70a12dbc597..865c2fdfe2d 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/PLSQLNameOccurrence.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/PLSQLNameOccurrence.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/Search.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/Search.java index d2ed164cb27..12af7002ed7 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/Search.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/Search.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/SourceFileScope.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/SourceFileScope.java index d57c7af6579..42a7b860ca4 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/SourceFileScope.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/SourceFileScope.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/SymbolFacade.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/SymbolFacade.java index 3cda6ef3321..ca1da7207d6 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/SymbolFacade.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/SymbolFacade.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/TypeSet.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/TypeSet.java index f36786edbfb..d3f8dd807f7 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/TypeSet.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/TypeSet.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/VariableNameDeclaration.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/VariableNameDeclaration.java index 2aa56df8d95..bde0e2d1fba 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/VariableNameDeclaration.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/VariableNameDeclaration.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/AbstractPLSQLParserTst.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/AbstractPLSQLParserTst.java index 52aa2c8fbc2..177deb1681f 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/AbstractPLSQLParserTst.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/AbstractPLSQLParserTst.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/LanguageVersionDiscovererTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/LanguageVersionDiscovererTest.java index 65ec52e0559..014404ab593 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/LanguageVersionDiscovererTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/LanguageVersionDiscovererTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/LanguageVersionTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/LanguageVersionTest.java index 85ad70e843d..d9cbf4dd07d 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/LanguageVersionTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/LanguageVersionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/PLSQLXPathRuleTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/PLSQLXPathRuleTest.java index 16d9cafd2f8..306039c1baa 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/PLSQLXPathRuleTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/PLSQLXPathRuleTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/PlsqlParsingHelper.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/PlsqlParsingHelper.java index ad5a12313a9..3eaf5412908 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/PlsqlParsingHelper.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/PlsqlParsingHelper.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/RuleSetFactoryTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/RuleSetFactoryTest.java index 9e1b17520bd..acafd46fa9c 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/RuleSetFactoryTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/RuleSetFactoryTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ASTComparisonConditionTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ASTComparisonConditionTest.java index 3617b8e5136..f6da8bc3595 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ASTComparisonConditionTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ASTComparisonConditionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ASTCompoundConditionTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ASTCompoundConditionTest.java index e8bda66e3be..0d339a89763 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ASTCompoundConditionTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ASTCompoundConditionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/AllPlsqlAstTreeDumpTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/AllPlsqlAstTreeDumpTest.java index 4cca4d3eba4..8fe91c42b7b 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/AllPlsqlAstTreeDumpTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/AllPlsqlAstTreeDumpTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/AnonymousBlockTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/AnonymousBlockTest.java index 7d2781cb088..6f765b2219a 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/AnonymousBlockTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/AnonymousBlockTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CreateTableTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CreateTableTest.java index 0074c3cd97e..6e796a2f099 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CreateTableTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CreateTableTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorAttributesTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorAttributesTest.java index 0f5aecee1ea..e1e70597820 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorAttributesTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorAttributesTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorForLoopTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorForLoopTest.java index 696674f8e04..dceadad9748 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorForLoopTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorForLoopTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorWithWithTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorWithWithTest.java index e3d87b64553..70f51aef04b 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorWithWithTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/CursorWithWithTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/DeleteStatementTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/DeleteStatementTest.java index cf62d0d6f19..bcecb04a2ae 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/DeleteStatementTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/DeleteStatementTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ExecuteImmediateBulkCollectTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ExecuteImmediateBulkCollectTest.java index 09e47c86884..6036609df07 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ExecuteImmediateBulkCollectTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ExecuteImmediateBulkCollectTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ExecuteImmediateTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ExecuteImmediateTest.java index 9ca9633f6ec..f4e1d217578 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ExecuteImmediateTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ExecuteImmediateTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/FunctionsTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/FunctionsTest.java index 8caf9e2ed27..9fde8afdc9e 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/FunctionsTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/FunctionsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/IfStatementTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/IfStatementTest.java index fe7a7cfa6f0..ca4c8a85048 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/IfStatementTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/IfStatementTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/InOutNoCopyTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/InOutNoCopyTest.java index 1d437b30486..1994261bde8 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/InOutNoCopyTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/InOutNoCopyTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/InsertIntoClauseTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/InsertIntoClauseTest.java index cd5bde53fd7..627d7c9cded 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/InsertIntoClauseTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/InsertIntoClauseTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/JoinClauseTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/JoinClauseTest.java index b3571bbd4e5..047a4aec47c 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/JoinClauseTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/JoinClauseTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/LexicalParametersTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/LexicalParametersTest.java index 0dd90e0d007..1147382719a 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/LexicalParametersTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/LexicalParametersTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/OrderByExpressionsTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/OrderByExpressionsTest.java index 41a3e0109c6..45fb7daf10d 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/OrderByExpressionsTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/OrderByExpressionsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ParenthesisGroupTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ParenthesisGroupTest.java index 5547589c0d2..c5b3471480c 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ParenthesisGroupTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ParenthesisGroupTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/RecordTypeTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/RecordTypeTest.java index 413c2c34f3e..98c792b2df8 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/RecordTypeTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/RecordTypeTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectExpressionsTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectExpressionsTest.java index 3dad91dc8a6..224d59c730a 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectExpressionsTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectExpressionsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectForUpdateTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectForUpdateTest.java index 4f98fd3f0d3..4be80d80ebd 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectForUpdateTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectForUpdateTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectHierarchicalTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectHierarchicalTest.java index 07d74fbf164..4f4fd05c4ef 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectHierarchicalTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectHierarchicalTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementTest.java index cfdface850b..347f39d85e9 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoStatementTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupByTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupByTest.java index 9c793e4dc64..272a5ff4196 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupByTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectIntoWithGroupByTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectUnionTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectUnionTest.java index 26a2f873e33..3d20fb7a8fe 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectUnionTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SelectUnionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SlashAsDivisionTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SlashAsDivisionTest.java index c9d7d9e45cd..e8d50bca60d 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SlashAsDivisionTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/SlashAsDivisionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/StringLiteralsTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/StringLiteralsTest.java index c753ef2a07f..15ef13281dc 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/StringLiteralsTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/StringLiteralsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TableCollectionExpressionTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TableCollectionExpressionTest.java index 622af81ee75..452c2d85584 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TableCollectionExpressionTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/TableCollectionExpressionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/UpdateStatementTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/UpdateStatementTest.java index bab9be252a7..07981f29e5b 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/UpdateStatementTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/UpdateStatementTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ViewTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ViewTest.java index 952d28778c5..87bf7e76333 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ViewTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/ViewTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/WhereClauseTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/WhereClauseTest.java index a71c0395a66..75faab8ed3a 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/WhereClauseTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/WhereClauseTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/WithClauseTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/WithClauseTest.java index 8700acd656c..4e2e27ad617 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/WithClauseTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/WithClauseTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/bestpractices/TomKytesDespairTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/bestpractices/TomKytesDespairTest.java index 37d924c6158..7cb1fb20b68 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/bestpractices/TomKytesDespairTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/bestpractices/TomKytesDespairTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/AvoidTabCharacterTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/AvoidTabCharacterTest.java index a5956b6ff1f..af6d0496667 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/AvoidTabCharacterTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/AvoidTabCharacterTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/CodeFormatTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/CodeFormatTest.java index 1f159c060ed..ce522182354 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/CodeFormatTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/CodeFormatTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/ForLoopNamingTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/ForLoopNamingTest.java index a558d99427a..094c1987f5d 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/ForLoopNamingTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/ForLoopNamingTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/LineLengthTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/LineLengthTest.java index 3e60f684a29..7a3aec0f049 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/LineLengthTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/LineLengthTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/MisplacedPragmaTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/MisplacedPragmaTest.java index 93868afc246..a3402ca100c 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/MisplacedPragmaTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/codestyle/MisplacedPragmaTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/CyclomaticComplexityTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/CyclomaticComplexityTest.java index 55681426ef4..123cde96db3 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/CyclomaticComplexityTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/CyclomaticComplexityTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveMethodLengthTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveMethodLengthTest.java index 05c012e36ed..8c611eddd71 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveMethodLengthTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveMethodLengthTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveObjectLengthTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveObjectLengthTest.java index c7087894ebe..021a31f72ab 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveObjectLengthTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveObjectLengthTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessivePackageBodyLengthTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessivePackageBodyLengthTest.java index 380e6230b60..8e69d32d741 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessivePackageBodyLengthTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessivePackageBodyLengthTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessivePackageSpecificationLengthTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessivePackageSpecificationLengthTest.java index 15147ca728c..a63ce4d46e8 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessivePackageSpecificationLengthTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessivePackageSpecificationLengthTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveParameterListTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveParameterListTest.java index 2b55d6800fe..8190741640a 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveParameterListTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveParameterListTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveTypeLengthTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveTypeLengthTest.java index 136ef873e42..31ad4a2191f 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveTypeLengthTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/ExcessiveTypeLengthTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/NPathComplexityTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/NPathComplexityTest.java index 7ea85366ade..f6d3fdd1192 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/NPathComplexityTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/NPathComplexityTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/NcssMethodCountTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/NcssMethodCountTest.java index d1354c3f010..20399ca83f8 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/NcssMethodCountTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/NcssMethodCountTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/NcssObjectCountTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/NcssObjectCountTest.java index 3d5034ef2ec..7aea67eff87 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/NcssObjectCountTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/NcssObjectCountTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/TooManyFieldsTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/TooManyFieldsTest.java index 09fc17ad949..b5650c61c34 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/TooManyFieldsTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/TooManyFieldsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/TooManyMethodsTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/TooManyMethodsTest.java index 5d7b9e24e8e..bd03dd74874 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/TooManyMethodsTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/design/TooManyMethodsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/errorprone/ToDateToCharTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/errorprone/ToDateToCharTest.java index 986da1dd6d8..ff040e9e2a2 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/errorprone/ToDateToCharTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/errorprone/ToDateToCharTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/errorprone/ToDateWithoutDateFormatTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/errorprone/ToDateWithoutDateFormatTest.java index 7c75ad1d5b3..1dee009f11f 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/errorprone/ToDateWithoutDateFormatTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/errorprone/ToDateWithoutDateFormatTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/errorprone/ToTimestampWithoutDateFormatTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/errorprone/ToTimestampWithoutDateFormatTest.java index 45a227884c2..0c7c19b51c1 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/errorprone/ToTimestampWithoutDateFormatTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/rule/errorprone/ToTimestampWithoutDateFormatTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ From 051635af35003356aa8486a7eb86ace084f070e2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Jul 2025 11:27:24 +0200 Subject: [PATCH 1109/1962] chore: pmd-scala: Update license header --- .../java/net/sourceforge/pmd/lang/scala/cpd/ScalaCpdLexer.java | 2 +- .../net/sourceforge/pmd/lang/scala/cpd/ScalaTokenAdapter.java | 2 +- .../java/net/sourceforge/pmd/lang/scala/rule/ScalaRule.java | 2 +- .../net/sourceforge/pmd/lang/scala/LanguageVersionTest.java | 2 +- .../java/net/sourceforge/pmd/lang/scala/RulesetFactoryTest.java | 2 +- .../net/sourceforge/pmd/lang/scala/cpd/ScalaCpdLexerTest.java | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/cpd/ScalaCpdLexer.java b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/cpd/ScalaCpdLexer.java index 74020fd07da..de0a6aee464 100644 --- a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/cpd/ScalaCpdLexer.java +++ b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/cpd/ScalaCpdLexer.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/cpd/ScalaTokenAdapter.java b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/cpd/ScalaTokenAdapter.java index 828b8bd4d12..9e448460e7d 100644 --- a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/cpd/ScalaTokenAdapter.java +++ b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/cpd/ScalaTokenAdapter.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/rule/ScalaRule.java b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/rule/ScalaRule.java index 84c1459f63a..2758c4577ae 100644 --- a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/rule/ScalaRule.java +++ b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/rule/ScalaRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/LanguageVersionTest.java b/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/LanguageVersionTest.java index c68489cad7c..f0725c3c500 100644 --- a/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/LanguageVersionTest.java +++ b/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/LanguageVersionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/RulesetFactoryTest.java b/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/RulesetFactoryTest.java index ba6dac0f712..b964e995789 100644 --- a/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/RulesetFactoryTest.java +++ b/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/RulesetFactoryTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/cpd/ScalaCpdLexerTest.java b/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/cpd/ScalaCpdLexerTest.java index 0237f14a9ac..1c241ca845c 100644 --- a/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/cpd/ScalaCpdLexerTest.java +++ b/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/cpd/ScalaCpdLexerTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ From 128e3d9bf25d88943d0bd12d47df374959880f73 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Jul 2025 11:31:25 +0200 Subject: [PATCH 1110/1962] chore: pmd-swift: Update license header --- .../main/java/net/sourceforge/pmd/lang/swift/SwiftHandler.java | 2 +- .../net/sourceforge/pmd/lang/swift/SwiftLanguageModule.java | 2 +- .../lang/swift/rule/bestpractices/UnavailableFunctionRule.java | 2 +- .../java/net/sourceforge/pmd/lang/swift/RuleSetFactoryTest.java | 2 +- .../rule/bestpractices/ProhibitedInterfaceBuilderTest.java | 2 +- .../lang/swift/rule/bestpractices/UnavailableFunctionTest.java | 2 +- .../pmd/lang/swift/rule/errorprone/ForceCastTest.java | 2 +- .../pmd/lang/swift/rule/errorprone/ForceTryTest.java | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftHandler.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftHandler.java index 5f096968095..6129faa3e02 100644 --- a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftHandler.java +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftHandler.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftLanguageModule.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftLanguageModule.java index b62613ba66e..5688c4065f2 100644 --- a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftLanguageModule.java +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftLanguageModule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionRule.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionRule.java index 8de8308a14d..0b1d14ce50e 100644 --- a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionRule.java +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/RuleSetFactoryTest.java b/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/RuleSetFactoryTest.java index 27add5aaefd..83e0bb2e329 100644 --- a/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/RuleSetFactoryTest.java +++ b/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/RuleSetFactoryTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/ProhibitedInterfaceBuilderTest.java b/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/ProhibitedInterfaceBuilderTest.java index 76a14465bfd..dc72876e593 100644 --- a/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/ProhibitedInterfaceBuilderTest.java +++ b/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/ProhibitedInterfaceBuilderTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionTest.java b/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionTest.java index f8b0f5bc2c6..ce46a54b95c 100644 --- a/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionTest.java +++ b/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/rule/errorprone/ForceCastTest.java b/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/rule/errorprone/ForceCastTest.java index 7255f6bbc5b..5de4399170c 100644 --- a/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/rule/errorprone/ForceCastTest.java +++ b/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/rule/errorprone/ForceCastTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/rule/errorprone/ForceTryTest.java b/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/rule/errorprone/ForceTryTest.java index ddca99ad3dd..14df87d108e 100644 --- a/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/rule/errorprone/ForceTryTest.java +++ b/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/rule/errorprone/ForceTryTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ From 371740370cc1beeaf11480455e30106cfdb39f21 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Jul 2025 11:39:55 +0200 Subject: [PATCH 1111/1962] chore: pmd-tsql: Update license header --- .../java/net/sourceforge/pmd/lang/tsql/cpd/TSqlCpdLexer.java | 2 +- .../net/sourceforge/pmd/lang/tsql/cpd/TSqlCpdLexerTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-tsql/src/main/java/net/sourceforge/pmd/lang/tsql/cpd/TSqlCpdLexer.java b/pmd-tsql/src/main/java/net/sourceforge/pmd/lang/tsql/cpd/TSqlCpdLexer.java index 3e82239cda6..4e41653384e 100644 --- a/pmd-tsql/src/main/java/net/sourceforge/pmd/lang/tsql/cpd/TSqlCpdLexer.java +++ b/pmd-tsql/src/main/java/net/sourceforge/pmd/lang/tsql/cpd/TSqlCpdLexer.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-tsql/src/test/java/net/sourceforge/pmd/lang/tsql/cpd/TSqlCpdLexerTest.java b/pmd-tsql/src/test/java/net/sourceforge/pmd/lang/tsql/cpd/TSqlCpdLexerTest.java index 87568ca3d66..00854459d4c 100644 --- a/pmd-tsql/src/test/java/net/sourceforge/pmd/lang/tsql/cpd/TSqlCpdLexerTest.java +++ b/pmd-tsql/src/test/java/net/sourceforge/pmd/lang/tsql/cpd/TSqlCpdLexerTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ From f3a1dfd41f97d2f4ae25206a4917fdba37449a6b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Jul 2025 11:47:13 +0200 Subject: [PATCH 1112/1962] chore: pmd-visualforce: Update license header --- .../java/net/sourceforge/pmd/lang/visualforce/DataType.java | 2 +- .../sourceforge/pmd/lang/visualforce/ast/InternalApiBridge.java | 2 +- .../pmd/lang/visualforce/rule/security/VfCsrfRule.java | 2 +- .../pmd/lang/visualforce/rule/security/VfUnescapeElRule.java | 2 +- .../java/net/sourceforge/pmd/lang/visualforce/DataTypeTest.java | 2 +- .../pmd/lang/visualforce/LanguageVersionDiscovererTest.java | 2 +- .../sourceforge/pmd/lang/visualforce/LanguageVersionTest.java | 2 +- .../sourceforge/pmd/lang/visualforce/RuleSetFactoryTest.java | 2 +- .../java/net/sourceforge/pmd/lang/visualforce/VFTestUtils.java | 2 +- .../sourceforge/pmd/lang/visualforce/ast/ASTExpressionTest.java | 2 +- .../sourceforge/pmd/lang/visualforce/ast/AbstractVfTest.java | 2 +- .../pmd/lang/visualforce/ast/OpenTagRegisterTest.java | 2 +- .../sourceforge/pmd/lang/visualforce/ast/VfDocStyleTest.java | 2 +- .../sourceforge/pmd/lang/visualforce/ast/VfPageStyleTest.java | 2 +- .../sourceforge/pmd/lang/visualforce/ast/VfParsingHelper.java | 2 +- .../pmd/lang/visualforce/rule/security/VfCsrfTest.java | 2 +- .../lang/visualforce/rule/security/VfHtmlStyleTagXssTest.java | 2 +- .../rule/security/VfHtmlXssStyleTagUrlPatternMatchingTest.java | 2 +- .../pmd/lang/visualforce/rule/security/VfUnescapeElTest.java | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/DataType.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/DataType.java index 6b16786b463..bab5aa35b48 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/DataType.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/DataType.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/InternalApiBridge.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/InternalApiBridge.java index a696f4c55cc..2124753744b 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/InternalApiBridge.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/InternalApiBridge.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfCsrfRule.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfCsrfRule.java index ca47f05ab42..2c268a6bb68 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfCsrfRule.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfCsrfRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfUnescapeElRule.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfUnescapeElRule.java index c528b3eb924..fde795c3dec 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfUnescapeElRule.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfUnescapeElRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/DataTypeTest.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/DataTypeTest.java index b323fa226c3..b0ee7bc6983 100644 --- a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/DataTypeTest.java +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/DataTypeTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/LanguageVersionDiscovererTest.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/LanguageVersionDiscovererTest.java index 1fe24ad8b94..a475c0e5c95 100644 --- a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/LanguageVersionDiscovererTest.java +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/LanguageVersionDiscovererTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/LanguageVersionTest.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/LanguageVersionTest.java index 9c98b4d64e3..a079acbac3b 100644 --- a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/LanguageVersionTest.java +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/LanguageVersionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/RuleSetFactoryTest.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/RuleSetFactoryTest.java index 1fd91dbf852..c9b6a721cac 100644 --- a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/RuleSetFactoryTest.java +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/RuleSetFactoryTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/VFTestUtils.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/VFTestUtils.java index 783498f77d3..9965121767a 100644 --- a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/VFTestUtils.java +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/VFTestUtils.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/ASTExpressionTest.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/ASTExpressionTest.java index 6454f010fb5..7694b78a9b0 100644 --- a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/ASTExpressionTest.java +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/ASTExpressionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/AbstractVfTest.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/AbstractVfTest.java index 1a3c4cc03f7..76aa4380314 100644 --- a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/AbstractVfTest.java +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/AbstractVfTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/OpenTagRegisterTest.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/OpenTagRegisterTest.java index 327ec073be4..2be1166094a 100644 --- a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/OpenTagRegisterTest.java +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/OpenTagRegisterTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/VfDocStyleTest.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/VfDocStyleTest.java index 18f76c452a9..4848f62643f 100644 --- a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/VfDocStyleTest.java +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/VfDocStyleTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/VfPageStyleTest.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/VfPageStyleTest.java index fe0e9468e42..c9a3fff84d9 100644 --- a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/VfPageStyleTest.java +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/VfPageStyleTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/VfParsingHelper.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/VfParsingHelper.java index b306ae8768d..72639c0e599 100644 --- a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/VfParsingHelper.java +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/VfParsingHelper.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfCsrfTest.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfCsrfTest.java index f0bcf75fe06..9d4e0b019a7 100644 --- a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfCsrfTest.java +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfCsrfTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfHtmlStyleTagXssTest.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfHtmlStyleTagXssTest.java index f47d3b5a9e2..6d24edfbf80 100644 --- a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfHtmlStyleTagXssTest.java +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfHtmlStyleTagXssTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfHtmlXssStyleTagUrlPatternMatchingTest.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfHtmlXssStyleTagUrlPatternMatchingTest.java index 00afa413fba..bbcbd02a458 100644 --- a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfHtmlXssStyleTagUrlPatternMatchingTest.java +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfHtmlXssStyleTagUrlPatternMatchingTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfUnescapeElTest.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfUnescapeElTest.java index bc8e1ab1c5d..fe78c5dcf3c 100644 --- a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfUnescapeElTest.java +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/rule/security/VfUnescapeElTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ From 0e85ee0aa1f980cc49fcca3df07e70b8bfe4cd28 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Jul 2025 11:51:17 +0200 Subject: [PATCH 1113/1962] chore: pmd-xml: Update license header --- .../src/main/java/net/sourceforge/pmd/lang/xml/XmlHandler.java | 2 +- .../java/net/sourceforge/pmd/lang/xml/XmlLanguageModule.java | 2 +- .../src/main/java/net/sourceforge/pmd/lang/xml/XmlParser.java | 2 +- .../main/java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java | 2 +- .../src/main/java/net/sourceforge/pmd/lang/xml/ast/XmlNode.java | 2 +- .../java/net/sourceforge/pmd/lang/xml/pom/PomDialectModule.java | 2 +- .../net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java | 2 +- .../java/net/sourceforge/pmd/lang/xml/rule/AbstractXmlRule.java | 2 +- .../java/net/sourceforge/pmd/lang/xml/rule/DomXPathRule.java | 2 +- .../net/sourceforge/pmd/lang/xml/rule/SaxonDomXPathQuery.java | 2 +- .../net/sourceforge/pmd/lang/xml/wsdl/WsdlDialectModule.java | 2 +- .../net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java | 2 +- .../java/net/sourceforge/pmd/lang/xml/xsl/XslDialectModule.java | 2 +- .../net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java | 2 +- .../java/net/sourceforge/pmd/lang/xml/LanguageVersionTest.java | 2 +- .../src/test/java/net/sourceforge/pmd/lang/xml/PMDTaskTest.java | 2 +- .../java/net/sourceforge/pmd/lang/xml/RuleSetFactoryTest.java | 2 +- .../xml/pom/rule/errorprone/InvalidDependencyTypesTest.java | 2 +- .../rule/errorprone/ProjectVersionAsDependencyVersionTest.java | 2 +- .../net/sourceforge/pmd/lang/xml/rule/XmlXPathRuleTest.java | 2 +- .../pmd/lang/xml/rule/bestpractices/MissingEncodingTest.java | 2 +- .../pmd/lang/xml/rule/errorprone/MistypedCDATASectionTest.java | 2 +- .../pmd/lang/xml/xsl/rule/codestyle/UseConcatOnceTest.java | 2 +- .../lang/xml/xsl/rule/performance/AvoidAxisNavigationTest.java | 2 +- 24 files changed, 24 insertions(+), 24 deletions(-) diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/XmlHandler.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/XmlHandler.java index 3e0a138800c..88e945c21fc 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/XmlHandler.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/XmlHandler.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/XmlLanguageModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/XmlLanguageModule.java index 4b3e30929ce..9120a2517d0 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/XmlLanguageModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/XmlLanguageModule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/XmlParser.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/XmlParser.java index 71114027278..9be8e24d64d 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/XmlParser.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/XmlParser.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java index ca52185930e..2c3b6debc81 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/antlr4/XMLLexer.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/ast/XmlNode.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/ast/XmlNode.java index ade3d69ba8e..aa526e4fb3f 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/ast/XmlNode.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/ast/XmlNode.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomDialectModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomDialectModule.java index 59aa1ae790d..89b88d977f8 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomDialectModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomDialectModule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java index aca61a68b96..ef7acc6ee0b 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/pom/PomLanguageModule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/rule/AbstractXmlRule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/rule/AbstractXmlRule.java index 6b2d9be2436..57710fd0187 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/rule/AbstractXmlRule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/rule/AbstractXmlRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/rule/DomXPathRule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/rule/DomXPathRule.java index 3ecd8ed1096..abf52c5c98b 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/rule/DomXPathRule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/rule/DomXPathRule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/rule/SaxonDomXPathQuery.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/rule/SaxonDomXPathQuery.java index 348f99bc575..5d7104db231 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/rule/SaxonDomXPathQuery.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/rule/SaxonDomXPathQuery.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlDialectModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlDialectModule.java index a1745811dc0..e212e2733e5 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlDialectModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlDialectModule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java index b849bd79d9d..6ba91858fcc 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/wsdl/WsdlLanguageModule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslDialectModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslDialectModule.java index 94d9f7afa95..b55db60f82c 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslDialectModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslDialectModule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java index 1dd2e7efbd6..5264489df05 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/xsl/XslLanguageModule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/LanguageVersionTest.java b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/LanguageVersionTest.java index 8dc8ff2d055..d96a3209e12 100644 --- a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/LanguageVersionTest.java +++ b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/LanguageVersionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/PMDTaskTest.java b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/PMDTaskTest.java index bb270df6b82..f4d129a921b 100644 --- a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/PMDTaskTest.java +++ b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/PMDTaskTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/RuleSetFactoryTest.java b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/RuleSetFactoryTest.java index c98dba1c9d8..83a7ec2ef3a 100644 --- a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/RuleSetFactoryTest.java +++ b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/RuleSetFactoryTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/pom/rule/errorprone/InvalidDependencyTypesTest.java b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/pom/rule/errorprone/InvalidDependencyTypesTest.java index 10c6674a362..f39a6532d20 100644 --- a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/pom/rule/errorprone/InvalidDependencyTypesTest.java +++ b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/pom/rule/errorprone/InvalidDependencyTypesTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/pom/rule/errorprone/ProjectVersionAsDependencyVersionTest.java b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/pom/rule/errorprone/ProjectVersionAsDependencyVersionTest.java index 8011eb18a03..a2268f1e668 100644 --- a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/pom/rule/errorprone/ProjectVersionAsDependencyVersionTest.java +++ b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/pom/rule/errorprone/ProjectVersionAsDependencyVersionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/rule/XmlXPathRuleTest.java b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/rule/XmlXPathRuleTest.java index 64a31dba0af..07db5c8b962 100644 --- a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/rule/XmlXPathRuleTest.java +++ b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/rule/XmlXPathRuleTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/rule/bestpractices/MissingEncodingTest.java b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/rule/bestpractices/MissingEncodingTest.java index 499d979dfbe..8b8017cbf8e 100644 --- a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/rule/bestpractices/MissingEncodingTest.java +++ b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/rule/bestpractices/MissingEncodingTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/rule/errorprone/MistypedCDATASectionTest.java b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/rule/errorprone/MistypedCDATASectionTest.java index bc78d8d8d8a..ffeb2fece3d 100644 --- a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/rule/errorprone/MistypedCDATASectionTest.java +++ b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/rule/errorprone/MistypedCDATASectionTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/xsl/rule/codestyle/UseConcatOnceTest.java b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/xsl/rule/codestyle/UseConcatOnceTest.java index b9b36aed242..9bd71ae58a2 100644 --- a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/xsl/rule/codestyle/UseConcatOnceTest.java +++ b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/xsl/rule/codestyle/UseConcatOnceTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/xsl/rule/performance/AvoidAxisNavigationTest.java b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/xsl/rule/performance/AvoidAxisNavigationTest.java index ee4fbc514e5..24d61a37fb2 100644 --- a/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/xsl/rule/performance/AvoidAxisNavigationTest.java +++ b/pmd-xml/src/test/java/net/sourceforge/pmd/lang/xml/xsl/rule/performance/AvoidAxisNavigationTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ From 99b7fc37efa06dec2daef562b53c13947548e34a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Jul 2025 11:53:50 +0200 Subject: [PATCH 1114/1962] chore: pmd-doc: Update license header --- .../java/net/sourceforge/pmd/doc/internal/DeadLinksChecker.java | 2 +- .../net/sourceforge/pmd/doc/internal/DefaultFileWriter.java | 2 +- .../main/java/net/sourceforge/pmd/doc/internal/EscapeUtils.java | 2 +- .../main/java/net/sourceforge/pmd/doc/internal/FileWriter.java | 2 +- .../net/sourceforge/pmd/doc/internal/GenerateRuleDocsCmd.java | 2 +- .../java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java | 2 +- .../java/net/sourceforge/pmd/doc/internal/RuleSetUtils.java | 2 +- .../java/net/sourceforge/pmd/doc/internal/SidebarGenerator.java | 2 +- .../java/net/sourceforge/pmd/doc/internal/EscapeUtilsTest.java | 2 +- .../java/net/sourceforge/pmd/doc/internal/MockedFileWriter.java | 2 +- .../net/sourceforge/pmd/doc/internal/RuleDocGeneratorTest.java | 2 +- .../net/sourceforge/pmd/doc/internal/RuleSetResolverTest.java | 2 +- .../net/sourceforge/pmd/doc/internal/SidebarGeneratorTest.java | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/DeadLinksChecker.java b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/DeadLinksChecker.java index eea45f8719a..628fb7a6ca1 100644 --- a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/DeadLinksChecker.java +++ b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/DeadLinksChecker.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/DefaultFileWriter.java b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/DefaultFileWriter.java index 3a105f05d25..8094356261b 100644 --- a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/DefaultFileWriter.java +++ b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/DefaultFileWriter.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/EscapeUtils.java b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/EscapeUtils.java index 1dda3b81829..6c47a20566e 100644 --- a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/EscapeUtils.java +++ b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/EscapeUtils.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/FileWriter.java b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/FileWriter.java index e00b335f022..5ab18631672 100644 --- a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/FileWriter.java +++ b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/FileWriter.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/GenerateRuleDocsCmd.java b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/GenerateRuleDocsCmd.java index c1958e9c39e..4e32d8ded05 100644 --- a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/GenerateRuleDocsCmd.java +++ b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/GenerateRuleDocsCmd.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java index aff45936e7b..33de5b42f55 100644 --- a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java +++ b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleSetUtils.java b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleSetUtils.java index 2399f96ebdd..8ad5026b0ea 100644 --- a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleSetUtils.java +++ b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleSetUtils.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/SidebarGenerator.java b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/SidebarGenerator.java index d9f248eb0c3..e60de3a3f71 100644 --- a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/SidebarGenerator.java +++ b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/SidebarGenerator.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/EscapeUtilsTest.java b/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/EscapeUtilsTest.java index fe83327d77e..ce0eb372af4 100644 --- a/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/EscapeUtilsTest.java +++ b/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/EscapeUtilsTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/MockedFileWriter.java b/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/MockedFileWriter.java index 7173fcc9270..3cc5c9d7798 100644 --- a/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/MockedFileWriter.java +++ b/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/MockedFileWriter.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/RuleDocGeneratorTest.java b/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/RuleDocGeneratorTest.java index cffe8af1259..c51d3d2dc79 100644 --- a/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/RuleDocGeneratorTest.java +++ b/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/RuleDocGeneratorTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/RuleSetResolverTest.java b/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/RuleSetResolverTest.java index 9abb6b4618b..5b2ede906c6 100644 --- a/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/RuleSetResolverTest.java +++ b/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/RuleSetResolverTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/SidebarGeneratorTest.java b/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/SidebarGeneratorTest.java index 81f3392583b..2dbffb5d754 100644 --- a/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/SidebarGeneratorTest.java +++ b/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/SidebarGeneratorTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ From ca2e0aa675886c9e3165f86d8b2cc94aa4f2bc74 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Jul 2025 11:57:53 +0200 Subject: [PATCH 1115/1962] chore: pmd-cli: Update license header --- .../java/me/tongfei/progressbar/PmdProgressBarFriend.java | 2 +- pmd-cli/src/main/java/net/sourceforge/pmd/cli/PmdCli.java | 2 +- .../cli/commands/internal/AbstractAnalysisPmdSubcommand.java | 2 +- .../pmd/cli/commands/internal/AbstractPmdSubcommand.java | 2 +- .../net/sourceforge/pmd/cli/commands/internal/CpdCommand.java | 2 +- .../sourceforge/pmd/cli/commands/internal/CpdGuiCommand.java | 2 +- .../pmd/cli/commands/internal/DesignerCommand.java | 2 +- .../net/sourceforge/pmd/cli/commands/internal/PmdCommand.java | 2 +- .../sourceforge/pmd/cli/commands/internal/PmdRootCommand.java | 2 +- .../pmd/cli/commands/internal/TreeExportCommand.java | 2 +- .../pmd/cli/commands/mixins/internal/EncodingMixin.java | 2 +- .../commands/typesupport/internal/CpdLanguageTypeSupport.java | 2 +- .../commands/typesupport/internal/LanguageTypeSupport.java | 2 +- .../commands/typesupport/internal/NumThreadsConverter.java | 2 +- .../commands/typesupport/internal/PmdLanguageTypeSupport.java | 2 +- .../typesupport/internal/PmdLanguageVersionTypeSupport.java | 2 +- .../java/net/sourceforge/pmd/cli/internal/CliExitCode.java | 2 +- .../src/test/java/net/sourceforge/pmd/cli/BaseCliTest.java | 2 +- pmd-cli/src/test/java/net/sourceforge/pmd/cli/CpdCliTest.java | 2 +- .../pmd/cli/commands/internal/BaseCommandTest.java | 2 +- .../sourceforge/pmd/cli/commands/internal/CpdCommandTest.java | 2 +- .../sourceforge/pmd/cli/commands/internal/PmdCommandTest.java | 2 +- .../resources/net/sourceforge/pmd/cli/cpd/files/dup1.java | 4 ++-- .../resources/net/sourceforge/pmd/cli/cpd/files/dup2.java | 4 ++-- 24 files changed, 26 insertions(+), 26 deletions(-) diff --git a/pmd-cli/src/main/java/me/tongfei/progressbar/PmdProgressBarFriend.java b/pmd-cli/src/main/java/me/tongfei/progressbar/PmdProgressBarFriend.java index ac670a560e5..2123f49b3e5 100644 --- a/pmd-cli/src/main/java/me/tongfei/progressbar/PmdProgressBarFriend.java +++ b/pmd-cli/src/main/java/me/tongfei/progressbar/PmdProgressBarFriend.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/PmdCli.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/PmdCli.java index a31326f4fc1..622aaa83af3 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/PmdCli.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/PmdCli.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java index 801f7e5bc3f..cd7f17f183f 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractPmdSubcommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractPmdSubcommand.java index bd55b1cc140..c8113a15dee 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractPmdSubcommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractPmdSubcommand.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java index 7f22bb57174..b12b70eed5e 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdGuiCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdGuiCommand.java index 6310b58e910..358afbda474 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdGuiCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdGuiCommand.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/DesignerCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/DesignerCommand.java index 8c53634b696..edc23e2de94 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/DesignerCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/DesignerCommand.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java index 6f55c1fc928..152e73e7762 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdRootCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdRootCommand.java index 1ef0bcc74a9..c2ce3860460 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdRootCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdRootCommand.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/TreeExportCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/TreeExportCommand.java index 0655739e5d5..9cbf5e7ec55 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/TreeExportCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/TreeExportCommand.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/mixins/internal/EncodingMixin.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/mixins/internal/EncodingMixin.java index e6086bb46f7..aa693d28bec 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/mixins/internal/EncodingMixin.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/mixins/internal/EncodingMixin.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/CpdLanguageTypeSupport.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/CpdLanguageTypeSupport.java index 74bdcd594d0..5c9e1250f5b 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/CpdLanguageTypeSupport.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/CpdLanguageTypeSupport.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/LanguageTypeSupport.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/LanguageTypeSupport.java index 0630b125f64..618e87c9de2 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/LanguageTypeSupport.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/LanguageTypeSupport.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/NumThreadsConverter.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/NumThreadsConverter.java index e0f4e90a46d..13e659f9c1f 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/NumThreadsConverter.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/NumThreadsConverter.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/PmdLanguageTypeSupport.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/PmdLanguageTypeSupport.java index 41023a59b09..13e75a0c91f 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/PmdLanguageTypeSupport.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/PmdLanguageTypeSupport.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/PmdLanguageVersionTypeSupport.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/PmdLanguageVersionTypeSupport.java index fdc5f51efac..205868fead4 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/PmdLanguageVersionTypeSupport.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/PmdLanguageVersionTypeSupport.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/internal/CliExitCode.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/internal/CliExitCode.java index 909f942c6c3..f7ad05994e1 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/internal/CliExitCode.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/internal/CliExitCode.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/BaseCliTest.java b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/BaseCliTest.java index c8deed0a7a3..ed193c80514 100644 --- a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/BaseCliTest.java +++ b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/BaseCliTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/CpdCliTest.java b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/CpdCliTest.java index d9b0975fab9..bd62ba75287 100644 --- a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/CpdCliTest.java +++ b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/CpdCliTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/commands/internal/BaseCommandTest.java b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/commands/internal/BaseCommandTest.java index 6057a549b99..37315ebbdf0 100644 --- a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/commands/internal/BaseCommandTest.java +++ b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/commands/internal/BaseCommandTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/commands/internal/CpdCommandTest.java b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/commands/internal/CpdCommandTest.java index e089203283a..503f4790322 100644 --- a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/commands/internal/CpdCommandTest.java +++ b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/commands/internal/CpdCommandTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/commands/internal/PmdCommandTest.java b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/commands/internal/PmdCommandTest.java index 9e2fca1d504..dae10156383 100644 --- a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/commands/internal/PmdCommandTest.java +++ b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/commands/internal/PmdCommandTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/cpd/files/dup1.java b/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/cpd/files/dup1.java index 2fde07a30a4..6cbf664c733 100644 --- a/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/cpd/files/dup1.java +++ b/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/cpd/files/dup1.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ @@ -15,4 +15,4 @@ public static void main(String[] args) { System.out.println("Test8"); System.out.println("Test9"); } -} \ No newline at end of file +} diff --git a/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/cpd/files/dup2.java b/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/cpd/files/dup2.java index 91779c045b5..4117d624ab2 100644 --- a/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/cpd/files/dup2.java +++ b/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/cpd/files/dup2.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ @@ -15,4 +15,4 @@ public static void main(String[] args) { System.out.println("Test8"); System.out.println("Test9"); } -} \ No newline at end of file +} From 82c38b9b757047340af86f7d7bb31c9bf67e4ba5 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Jul 2025 12:02:30 +0200 Subject: [PATCH 1116/1962] chore: pmd-dist: Update license header --- .../src/test/java/net/sourceforge/pmd/dist/CpdExecutor.java | 2 +- .../src/test/java/net/sourceforge/pmd/dist/ExecutionResult.java | 2 +- .../src/test/java/net/sourceforge/pmd/dist/PMDExecutor.java | 2 +- .../java/net/sourceforge/pmd/dist/SourceDistributionIT.java | 2 +- .../test/java/net/sourceforge/pmd/dist/ZipFileExtractor.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/dist/CpdExecutor.java b/pmd-dist/src/test/java/net/sourceforge/pmd/dist/CpdExecutor.java index 742426f1fd9..ab14e810bde 100644 --- a/pmd-dist/src/test/java/net/sourceforge/pmd/dist/CpdExecutor.java +++ b/pmd-dist/src/test/java/net/sourceforge/pmd/dist/CpdExecutor.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/dist/ExecutionResult.java b/pmd-dist/src/test/java/net/sourceforge/pmd/dist/ExecutionResult.java index 3b54753bf1d..1bf2fce9565 100644 --- a/pmd-dist/src/test/java/net/sourceforge/pmd/dist/ExecutionResult.java +++ b/pmd-dist/src/test/java/net/sourceforge/pmd/dist/ExecutionResult.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/dist/PMDExecutor.java b/pmd-dist/src/test/java/net/sourceforge/pmd/dist/PMDExecutor.java index 84cd11a4025..0cf2ede2867 100644 --- a/pmd-dist/src/test/java/net/sourceforge/pmd/dist/PMDExecutor.java +++ b/pmd-dist/src/test/java/net/sourceforge/pmd/dist/PMDExecutor.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/dist/SourceDistributionIT.java b/pmd-dist/src/test/java/net/sourceforge/pmd/dist/SourceDistributionIT.java index 707dd70cc8e..5ffa63242fb 100644 --- a/pmd-dist/src/test/java/net/sourceforge/pmd/dist/SourceDistributionIT.java +++ b/pmd-dist/src/test/java/net/sourceforge/pmd/dist/SourceDistributionIT.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/dist/ZipFileExtractor.java b/pmd-dist/src/test/java/net/sourceforge/pmd/dist/ZipFileExtractor.java index 07b22f094ee..fcd522be509 100644 --- a/pmd-dist/src/test/java/net/sourceforge/pmd/dist/ZipFileExtractor.java +++ b/pmd-dist/src/test/java/net/sourceforge/pmd/dist/ZipFileExtractor.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ From 0a644297b0195e753a8e68afd833a4cdbd45dc52 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Jul 2025 15:46:34 +0200 Subject: [PATCH 1117/1962] Add @zbynek as a contributor --- .all-contributorsrc | 10 +++++ docs/pages/pmd/projectdocs/credits.md | 63 ++++++++++++++------------- 2 files changed, 42 insertions(+), 31 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 0ae15c07cad..aa2c07306b6 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8178,6 +8178,16 @@ "contributions": [ "code" ] + }, + { + "login": "zbynek", + "name": "Zbynek Konecny", + "avatar_url": "https://avatars.githubusercontent.com/u/1105305?v=4", + "profile": "http://www.geogebra.org/u/zbynek", + "contributions": [ + "bug", + "code" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 24c0c8bb4e5..c6ec56c96d5 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -884,280 +884,281 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
  • + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + From 5745fb29bd7799ba4f377f64ac14323a2fabef04 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 4 Jul 2025 15:46:55 +0200 Subject: [PATCH 1118/1962] [doc] Update release notes (#5858, #5859) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 0c9c0dd3524..20ceca853d4 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,11 +25,14 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* java-design + * [#5858](https://github.com/pmd/pmd/issues/5858): \[java] FinalFieldCouldBeStatic false positive for array initializers ### ๐Ÿšจ API Changes ### โœจ Merged pull requests +* [#5859](https://github.com/pmd/pmd/pull/5859): Fix #5858: \[java] Fix false positive in FinalFieldCouldBeStatic for array initializers - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) ### ๐Ÿ“ฆ Dependency updates From 762a449292dc487fb91cfa7c247e45ee9c317fb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Fri, 27 Jun 2025 20:48:36 +0200 Subject: [PATCH 1119/1962] New rules: * java/errorprone/ReplaceJavaUtilCalendar * java/errorprone/ReplaceJavaUtilDate --- .../resources/category/java/errorprone.xml | 61 +++++++++++++++++++ .../ReplaceJavaUtilCalendarTest.java | 11 ++++ .../errorprone/ReplaceJavaUtilDateTest.java | 11 ++++ .../xml/ReplaceJavaUtilCalendar.xml | 60 ++++++++++++++++++ .../errorprone/xml/ReplaceJavaUtilDate.xml | 59 ++++++++++++++++++ 5 files changed, 202 insertions(+) create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReplaceJavaUtilCalendarTest.java create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReplaceJavaUtilDateTest.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ReplaceJavaUtilCalendar.xml create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ReplaceJavaUtilDate.xml diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 1dd3096af4d..ac83fbb9a62 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -2436,6 +2436,67 @@ public class Foo { + + + Using java.util.Calendar leads to bugs. Use java.time instead. + + 3 + + + + + + + + + + + + + Using java.util.Date leads to bugs. Use java.time instead. + + 3 + + + + + + + + + + + + + + bad, local variable of type java.util.Calendar + 1 + + + + + bad, param of type java.util.Calendar + 1 + + + + + bad, creating object of type java.util.GregorianCalendar + 1 + + + + + ok, not java.util.Calendar + 0 + + + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ReplaceJavaUtilDate.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ReplaceJavaUtilDate.xml new file mode 100644 index 00000000000..4efb11b32a1 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ReplaceJavaUtilDate.xml @@ -0,0 +1,59 @@ + + + + + bad, local variable of type java.util.Date + 2 + + + + + bad, param of type java.util.Date + 1 + + + + + bad, param of type java.sql.Date + 1 + + + + + ok, not java.util.Date + 0 + + + From 5f0d7920a0b04694ec8372ee54a626506ec1138d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Sat, 5 Jul 2025 19:30:26 +0200 Subject: [PATCH 1120/1962] Improve description and examples --- .../resources/category/java/errorprone.xml | 61 +++++++++++++++++-- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index ac83fbb9a62..2b15cd27d1d 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -2443,7 +2443,11 @@ public class Foo { class="net.sourceforge.pmd.lang.rule.xpath.XPathRule" externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#replacejavautilcalendar"> - Using java.util.Calendar leads to bugs. Use java.time instead. +The legacy java.util.Calendar API is error-prone, mutable, and not thread-safe. It has confusing month indexing +(January = 0), inconsistent field semantics, and verbose usage patterns. The modern java.time API (introduced in Java 8) +provides immutable, thread-safe alternatives with clear, intuitive methods. + +Use LocalDate (for date-only operations), LocalDateTime (for date and time), or ZonedDateTime (when timezone is important) from java.time package instead. 3 @@ -2457,10 +2461,27 @@ public class Foo { @@ -2474,7 +2495,13 @@ public class Foo { class="net.sourceforge.pmd.lang.rule.xpath.XPathRule" externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#replacejavautildate"> - Using java.util.Date leads to bugs. Use java.time instead. +The legacy java.util.Date class is mutable, not thread-safe, and has a confusing API. Many of its methods +are deprecated, it doesn't handle timezones properly, and it represents both date and time even when only +one is needed. The constructor parameters are particularly error-prone: year is "years since 1900" and +month is 0-based (January = 0). The modern java.time API provides better type safety, immutability, and clearer semantics. + +Use LocalDate (date only), LocalTime (time only), LocalDateTime (date and time), Instant (timestamp), +or ZonedDateTime (date-time with timezone) from java.time package instead. 3 @@ -2487,10 +2514,32 @@ public class Foo { From 1df38edc27d210aa472d991fe8ad2be1ae4d915d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Sun, 6 Jul 2025 21:09:35 +0200 Subject: [PATCH 1121/1962] License headers aren't javadocs Just saw https://github.com/pmd/pmd/pull/5876 --- .../lang/java/rule/errorprone/ReplaceJavaUtilCalendarTest.java | 2 +- .../pmd/lang/java/rule/errorprone/ReplaceJavaUtilDateTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReplaceJavaUtilCalendarTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReplaceJavaUtilCalendarTest.java index 4b1732c5151..91140eaa3eb 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReplaceJavaUtilCalendarTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReplaceJavaUtilCalendarTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReplaceJavaUtilDateTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReplaceJavaUtilDateTest.java index d3c0e5099ff..305f55e03e1 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReplaceJavaUtilDateTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReplaceJavaUtilDateTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ From c6d5e85ee9def449f5afb1a0861f098637e469a5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Jul 2025 19:28:25 +0200 Subject: [PATCH 1122/1962] Bump org.junit:junit-bom from 5.13.2 to 5.13.3 (#5884) * Bump org.junit:junit-bom from 5.13.2 to 5.13.3 Bumps [org.junit:junit-bom](https://github.com/junit-team/junit-framework) from 5.13.2 to 5.13.3. - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r5.13.2...r5.13.3) --- updated-dependencies: - dependency-name: org.junit:junit-bom dependency-version: 5.13.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump junit5.platform.version from 1.13.2 to 1.13.3 --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andreas Dangel --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 2c30081d76e..be0e4268e13 100644 --- a/pom.xml +++ b/pom.xml @@ -84,8 +84,8 @@ ${maven.compiler.test.target} 1.9.24 5.9.1 - 5.13.2 - 1.13.2 + 5.13.3 + 1.13.3 2.0.0 5.0 From aed9b57cf34712a88957d320e6425a0d12bac81f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Jul 2025 19:47:53 +0200 Subject: [PATCH 1123/1962] Bump org.apache.maven.plugins:maven-enforcer-plugin from 3.5.0 to 3.6.0 (#5889) Bumps [org.apache.maven.plugins:maven-enforcer-plugin](https://github.com/apache/maven-enforcer) from 3.5.0 to 3.6.0. - [Release notes](https://github.com/apache/maven-enforcer/releases) - [Commits](https://github.com/apache/maven-enforcer/compare/enforcer-3.5.0...enforcer-3.6.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-enforcer-plugin dependency-version: 3.6.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index be0e4268e13..1401bde17d9 100644 --- a/pom.xml +++ b/pom.xml @@ -513,7 +513,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 3.5.0 + 3.6.0 org.apache.maven.plugins From 9a1e2c208eb3ccf40b24316d95209e2d3ae1bbef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Jul 2025 19:48:29 +0200 Subject: [PATCH 1124/1962] Bump org.checkerframework:checker-qual from 3.49.4 to 3.49.5 (#5886) Bumps [org.checkerframework:checker-qual](https://github.com/typetools/checker-framework) from 3.49.4 to 3.49.5. - [Release notes](https://github.com/typetools/checker-framework/releases) - [Changelog](https://github.com/typetools/checker-framework/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/typetools/checker-framework/compare/checker-framework-3.49.4...checker-framework-3.49.5) --- updated-dependencies: - dependency-name: org.checkerframework:checker-qual dependency-version: 3.49.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1401bde17d9..5c17275e802 100644 --- a/pom.xml +++ b/pom.xml @@ -877,7 +877,7 @@ org.checkerframework checker-qual - 3.49.4 + 3.49.5 net.sf.saxon From 01aaa106b8e365bc175ae12d67830ae31f8ff744 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Jul 2025 19:49:05 +0200 Subject: [PATCH 1125/1962] Bump org.apache.maven.plugins:maven-gpg-plugin from 3.2.7 to 3.2.8 (#5885) Bumps [org.apache.maven.plugins:maven-gpg-plugin](https://github.com/apache/maven-gpg-plugin) from 3.2.7 to 3.2.8. - [Release notes](https://github.com/apache/maven-gpg-plugin/releases) - [Commits](https://github.com/apache/maven-gpg-plugin/compare/maven-gpg-plugin-3.2.7...maven-gpg-plugin-3.2.8) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-gpg-plugin dependency-version: 3.2.8 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5c17275e802..86133e3b053 100644 --- a/pom.xml +++ b/pom.xml @@ -1151,7 +1151,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.2.7 + 3.2.8 true From a9492592092dfc8cd524bb01c142c993212fb1a4 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 10 Jul 2025 10:11:36 +0200 Subject: [PATCH 1126/1962] chore: Fix Mockito javaagent warning for Java 21+ --- pom.xml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/pom.xml b/pom.xml index 86133e3b053..eb1d48159f7 100644 --- a/pom.xml +++ b/pom.xml @@ -1124,6 +1124,40 @@ + + Java 21+ + + [21,) + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + dependency-properties + + properties + + + + + + + + + org.mockito + mockito-core + test + + + + + -javaagent:${org.mockito:mockito-core:jar} + + + with-slf4j-impl From ec932f3f0c0d934f4e602edb4d8e9a92a262db67 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 10 Jul 2025 12:22:48 +0200 Subject: [PATCH 1127/1962] chore: Fix JUnit warning about invalid test factory --- .../sourceforge/pmd/lang/test/ast/IntelliMarker.kt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/test/ast/IntelliMarker.kt b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/test/ast/IntelliMarker.kt index 5754bc4143a..c7c419f1ee3 100644 --- a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/test/ast/IntelliMarker.kt +++ b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/test/ast/IntelliMarker.kt @@ -5,8 +5,8 @@ package net.sourceforge.pmd.lang.test.ast -import org.junit.jupiter.api.TestFactory -import org.junit.jupiter.api.condition.EnabledIfSystemProperty +import net.sourceforge.pmd.annotation.InternalApi +import org.junit.jupiter.api.Test /** * This is to trick Intellij into making subclasses executable (because of @TestFactory). @@ -14,8 +14,12 @@ import org.junit.jupiter.api.condition.EnabledIfSystemProperty * Kotest, but was removed in 4.2.0 without explanation. */ interface IntelliMarker { - @EnabledIfSystemProperty(named = "wibble", matches = "wobble") - @TestFactory + @Deprecated("This is not an API") fun primer() { } + + @Test + @InternalApi + fun dummyTestForIntelliJIntegration() { + } } From 4192af066ac90fc761718bbadf19a05d0229236b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 10 Jul 2025 15:59:46 +0200 Subject: [PATCH 1128/1962] Fix #5597: Move dogfood profile to separate settings.xml The settings.xml is generated on demand when the staging repo should be used. --- .github/workflows/build.yml | 26 ++++++++++++++++++++++++-- pom.xml | 28 ---------------------------- 2 files changed, 24 insertions(+), 30 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 20df1953a99..e27c19e3f8c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -39,7 +39,7 @@ jobs: ./mvnw --show-version --errors --batch-mode \ -Dmaven.repo.local=.m2/repository \ verify -PfastSkip -DskipTests -Dcyclonedx.skip=false \ - deploy:deploy -DdogfoodStagingRepo="$(pwd)/target/staging" + deploy:deploy -DaltDeploymentRepository="dogfood::file://$(pwd)/target/staging" - name: Cleanup local repository run: | # Cleanup local repository to not poison the shared cache with our SNAPSHOTS of the current build. @@ -207,12 +207,34 @@ jobs: sed -i 's/[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}.*<\/version>\( *\)/'"${current_pmd_version}"'<\/version>\1/' pom.xml echo "::endgroup::" + echo "::group::Generate settings.xml to use dogfoodStagingRepo" + maven_settings_file="$(pwd)/target/staging/settings.xml" + cat > "${maven_settings_file}" < + + + dogfood + + + dogfood + file://$(pwd)/target/staging + true + true + + + + + + EOF + echo "::endgroup::" + echo "::group::Run ./mvnw verify" ./mvnw --show-version --errors --batch-mode \ + --settings "${maven_settings_file}" \ -Dmaven.repo.local=.m2/repository \ verify \ -PfastSkip \ - -DdogfoodStagingRepo="$(pwd)/target/staging" \ -DskipTests \ -Dpmd.skip=false \ -Dcpd.skip=false diff --git a/pom.xml b/pom.xml index 86133e3b053..8012c97c36f 100644 --- a/pom.xml +++ b/pom.xml @@ -1280,34 +1280,6 @@ - - dogfood - - - dogfoodStagingRepo - - - - - - org.apache.maven.plugins - maven-deploy-plugin - - dogfood::file://${dogfoodStagingRepo} - - - - - - - dogfood - file://${dogfoodStagingRepo} - true - true - - - - central-portal-snapshots From 82fec8fb51f498d86d05f3ba600a445bd4a6df6f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 10 Jul 2025 16:25:39 +0200 Subject: [PATCH 1129/1962] [doc] Update version --- docs/pages/pmd/languages/css.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/pages/pmd/languages/css.md b/docs/pages/pmd/languages/css.md index cf484020e6f..d24f79a24fe 100644 --- a/docs/pages/pmd/languages/css.md +++ b/docs/pages/pmd/languages/css.md @@ -1,11 +1,11 @@ --- title: CSS support permalink: pmd_languages_css.html -last_updated: May 2025 (7.14.0) +last_updated: July 2025 (7.16.0) tags: [languages, CpdCapableLanguage] summary: "CSS-specific features and guidance" --- > [CSS](https://www.w3.org/TR/css/) is a language for describing the rendering of structured documents (such as HTML and XML) on screen, on paper, etc. -{% include language_info.html name='Css' id='css' implementation='css::lang.css.CssLanguageModule' supports_cpd=true since='7.14.0' %} +{% include language_info.html name='Css' id='css' implementation='css::lang.css.CssLanguageModule' supports_cpd=true since='7.16.0' %} From bdfbdaf8e24391183e07f58df06cea0d65b3a1ec Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 10 Jul 2025 16:30:57 +0200 Subject: [PATCH 1130/1962] [doc] Update release notes (#5733) --- docs/pages/release_notes.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 0c9c0dd3524..d34507cef7c 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -24,12 +24,18 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy +#### New: CPD support for CSS +CPD now supports CSS (Cascading Style Sheets), a language for describing the rendering of structured +documents (such as HTML) on screen, on paper etc. +It is shipped with the new module `pmd-css`. + ### ๐Ÿ› Fixed Issues ### ๐Ÿšจ API Changes ### โœจ Merged pull requests +* [#5733](https://github.com/pmd/pmd/pull/5733): \[css] Add new CPD language - [Thomas Prouvot](https://github.com/tprouvot) (@tprouvot) ### ๐Ÿ“ฆ Dependency updates From 5c9c4d0af12865c22a1a0ce99665058ebc18066c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 10 Jul 2025 16:58:33 +0200 Subject: [PATCH 1131/1962] Add debug output --- .github/workflows/build.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e27c19e3f8c..4622d7d2a0a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -208,6 +208,9 @@ jobs: echo "::endgroup::" echo "::group::Generate settings.xml to use dogfoodStagingRepo" + echo "original file ~/.m2/settings.xml:" + cat ~/.m2/settings.xml + echo "-------------------" maven_settings_file="$(pwd)/target/staging/settings.xml" cat > "${maven_settings_file}" < EOF + echo "new file ${maven_settings_file}:" + cat "${maven_settings_file}" echo "::endgroup::" echo "::group::Run ./mvnw verify" From c1ad1b50fd8b3f3a505aaf22cb94870f63ffdf11 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 10 Jul 2025 17:08:34 +0200 Subject: [PATCH 1132/1962] Enable dogfood profile --- .github/workflows/build.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4622d7d2a0a..d52d2a10352 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -208,9 +208,6 @@ jobs: echo "::endgroup::" echo "::group::Generate settings.xml to use dogfoodStagingRepo" - echo "original file ~/.m2/settings.xml:" - cat ~/.m2/settings.xml - echo "-------------------" maven_settings_file="$(pwd)/target/staging/settings.xml" cat > "${maven_settings_file}" < Date: Thu, 10 Jul 2025 17:35:18 +0200 Subject: [PATCH 1133/1962] Update pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/test/ast/IntelliMarker.kt --- .../kotlin/net/sourceforge/pmd/lang/test/ast/IntelliMarker.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/test/ast/IntelliMarker.kt b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/test/ast/IntelliMarker.kt index c7c419f1ee3..16c713aa2b3 100644 --- a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/test/ast/IntelliMarker.kt +++ b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/test/ast/IntelliMarker.kt @@ -9,7 +9,7 @@ import net.sourceforge.pmd.annotation.InternalApi import org.junit.jupiter.api.Test /** - * This is to trick Intellij into making subclasses executable (because of @TestFactory). + * This is to trick Intellij into making subclasses executable (because of @Test). * But Junit does not use it because of the unsatisfiable condition. This comes from * Kotest, but was removed in 4.2.0 without explanation. */ From c5112287935e54fb6e065e3b09fdeecfe55669e5 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 10 Jul 2025 18:04:34 +0200 Subject: [PATCH 1134/1962] [ci] publish-snapshot: increase timeout for maven deploy See also df4c1560263253603ee5bfd02062f9ff7b0cbdf2 --- .github/workflows/publish-snapshot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index c07327915cf..5d0f1903304 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -71,7 +71,7 @@ jobs: name: maven-central url: https://central.sonatype.com/service/rest/repository/browse/maven-snapshots/net/sourceforge/pmd/ runs-on: ubuntu-latest - timeout-minutes: 40 + timeout-minutes: 180 defaults: run: shell: bash From 9696112537ea504aea92d3c5e12d6cca3fb39a8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Thu, 10 Jul 2025 18:21:50 +0200 Subject: [PATCH 1135/1962] Feedback from review --- pmd-java/src/main/resources/category/java/errorprone.xml | 8 +++++--- .../java/rule/errorprone/ReplaceJavaUtilCalendarTest.java | 2 +- .../java/rule/errorprone/ReplaceJavaUtilDateTest.java | 2 +- .../java/rule/errorprone/xml/ReplaceJavaUtilCalendar.xml | 3 +++ .../lang/java/rule/errorprone/xml/ReplaceJavaUtilDate.xml | 3 +++ 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 2b15cd27d1d..54d8070eec8 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -2438,8 +2438,9 @@ public class Foo { @@ -2490,15 +2491,16 @@ public class Foo { The legacy java.util.Date class is mutable, not thread-safe, and has a confusing API. Many of its methods are deprecated, it doesn't handle timezones properly, and it represents both date and time even when only one is needed. The constructor parameters are particularly error-prone: year is "years since 1900" and -month is 0-based (January = 0). The modern java.time API provides better type safety, immutability, and clearer semantics. +month is 0-based (January = 0). The modern java.time API (introduced in Java 8) provides better type safety, immutability, and clearer semantics. Use LocalDate (date only), LocalTime (time only), LocalDateTime (date and time), Instant (timestamp), or ZonedDateTime (date-time with timezone) from java.time package instead. diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReplaceJavaUtilCalendarTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReplaceJavaUtilCalendarTest.java index 91140eaa3eb..c70e87bfbbb 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReplaceJavaUtilCalendarTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReplaceJavaUtilCalendarTest.java @@ -6,6 +6,6 @@ import net.sourceforge.pmd.test.PmdRuleTst; -public class ReplaceJavaUtilCalendarTest extends PmdRuleTst { +class ReplaceJavaUtilCalendarTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReplaceJavaUtilDateTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReplaceJavaUtilDateTest.java index 305f55e03e1..cb6036b251e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReplaceJavaUtilDateTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ReplaceJavaUtilDateTest.java @@ -6,6 +6,6 @@ import net.sourceforge.pmd.test.PmdRuleTst; -public class ReplaceJavaUtilDateTest extends PmdRuleTst { +class ReplaceJavaUtilDateTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ReplaceJavaUtilCalendar.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ReplaceJavaUtilCalendar.xml index a54221b5b44..d49895bf75d 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ReplaceJavaUtilCalendar.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ReplaceJavaUtilCalendar.xml @@ -7,6 +7,7 @@ bad, local variable of type java.util.Calendar 1 + 5 bad, param of type java.util.Calendar 1 + 4 bad, creating object of type java.util.GregorianCalendar 1 + 5 bad, local variable of type java.util.Date 2 + 5,5 bad, param of type java.util.Date 1 + 4 bad, param of type java.sql.Date 1 + 4 Date: Fri, 11 Jul 2025 17:39:52 +0200 Subject: [PATCH 1136/1962] Fix #5344: [java] Just log invalid annotation target type No error is logged anymore. --- .../java/symbols/internal/asm/GenericSigBase.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java index 86b25d847e6..4d0dfe00a68 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java @@ -17,6 +17,8 @@ import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.TypePath; import org.objectweb.asm.TypeReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; import net.sourceforge.pmd.lang.java.symbols.JTypeParameterOwnerSymbol; @@ -34,6 +36,8 @@ import net.sourceforge.pmd.util.CollectionUtil; abstract class GenericSigBase { + private static final Logger LOGGER = LoggerFactory.getLogger(GenericSigBase.class); + /* Signatures must be parsed lazily, because at the point we see them in the file, the enclosing class might not yet have been encountered @@ -408,9 +412,18 @@ boolean acceptAnnotationAfterParse(TypeReference tyRef, @Nullable TypePath path, receiverAnnotations.add(path, annot); return false; } + case TypeReference.CLASS_EXTENDS: { + // avoid exception for Java 11 bug + // see https://github.com/pmd/pmd/issues/5344 and https://bugs.openjdk.org/browse/JDK-8198945 + LOGGER.debug("Invalid target type CLASS_EXTENDS of type annotation {} for method or ctor detected. " + + "The annotation is ignored. Method: {}#{}. See https://github.com/pmd/pmd/issues/5344.", + annot, ctx.getEnclosingClass().getCanonicalName(), ctx.getSimpleName()); + return false; + } default: throw new IllegalArgumentException( - "Invalid type reference for method or ctor type annotation: " + tyRef.getSort()); + "Invalid target type of type annotation " + annot + " for method or ctor type annotation: " + + tyRef.getSort()); } } From 591af28844c39115b68eed9d64c71c9bfe892f8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Sat, 12 Jul 2025 22:00:52 +0200 Subject: [PATCH 1137/1962] don't trigger too many violations when one change fixes all --- .../resources/category/java/errorprone.xml | 10 ++++++++-- .../xml/ReplaceJavaUtilCalendar.xml | 20 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 54d8070eec8..d0ecc602c87 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -2454,7 +2454,10 @@ Use LocalDate (for date-only operations), LocalDateTime (for date and time), or @@ -2509,7 +2512,10 @@ or ZonedDateTime (date-time with timezone) from java.time package instead. diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ReplaceJavaUtilCalendar.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ReplaceJavaUtilCalendar.xml index d49895bf75d..94a33bb4f51 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ReplaceJavaUtilCalendar.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ReplaceJavaUtilCalendar.xml @@ -57,6 +57,26 @@ import foo.Calendar; public class Foo { void bar(Calendar d) { } +} + ]]> + + + + don't trigger too many violations when one change fixes all + 1 + 5 + From 45d73e9fc87f0da60f1fe117f1dcf1dfcf778c1a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 17 Jul 2025 12:26:04 +0200 Subject: [PATCH 1138/1962] [ci] Create a pre-release for snapshot builds Refs #4328 --- .github/workflows/publish-release.yml | 17 +++ .github/workflows/publish-snapshot.yml | 108 ++++++++++++++++++ .../pmd/devdocs/github_actions_workflows.md | 10 +- 3 files changed, 132 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 0eb149f66cf..76946516d23 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -512,6 +512,23 @@ jobs: owner: pmd repositories: pmd permission-contents: write # create a release + - name: Delete old GitHub Pre-Release + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + GH_TOKEN: ${{ steps.pmd-actions-helper-app-token.outputs.token }} + run: | + tagName="pmd_releases/${PMD_VERSION}-SNAPSHOT" + existingTagName="$(gh --repo pmd/pmd release list --json tagName,isPrerelease --jq ".[] | select(.tagName == \"${tagName}\" and .isPrerelease == true) | .tagName")" + + if [ "${existingTagName}" = "${tagName}" ]; then + echo "Pre-release for tag ${tagName} exists - deleting it..." + gh release delete "${tagName}" \ + --repo pmd/pmd \ + --cleanup-tag \ + --yes + else + echo "No pre-release ${tagName} exists, nothing to delete" + fi - name: Create GitHub Release id: release env: diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 5d0f1903304..921bebc67b3 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -445,6 +445,114 @@ jobs: git commit -q -m "$MSG" git push + github-prerelease: + needs: check-version + environment: + name: github + url: ${{ steps.release.outputs.release_url }} + runs-on: ubuntu-latest + timeout-minutes: 10 + defaults: + run: + shell: bash + steps: + - uses: actions/download-artifact@v4 + with: + name: dist-artifact + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + path: dist + + - uses: actions/download-artifact@v4 + with: + name: docs-artifact + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + path: docs + + - name: Setup GPG + env: + PMD_CI_GPG_PRIVATE_KEY: ${{ secrets.PMD_CI_GPG_PRIVATE_KEY }} + run: | + mkdir -p "${HOME}/.gpg" + chmod 700 "${HOME}/.gpg" + printenv PMD_CI_GPG_PRIVATE_KEY | gpg --batch --import + + gpg --list-keys --fingerprint --keyid-format=long + gpg --list-secret-keys --fingerprint --keyid-format=long + - name: Create docs zip + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + run: | + mv docs "pmd-doc-${PMD_VERSION}" + zip -qr "dist/pmd-dist-${PMD_VERSION}-doc.zip" "pmd-doc-${PMD_VERSION}/" + + - name: Sign files + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + MAVEN_GPG_PASSPHRASE: ${{ secrets.PMD_CI_GPG_PASSPHRASE }} + run: | + cd dist + printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ + --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-bin.zip" + printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ + --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-src.zip" + printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ + --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-doc.zip" + - uses: actions/create-github-app-token@v2 + id: pmd-actions-helper-app-token + with: + app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} + private-key: ${{ secrets.PMD_ACTIONS_HELPER_PRIVATE_KEY }} + owner: pmd + repositories: pmd + permission-contents: write # create a release + - name: Delete old GitHub Pre-Release + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + GH_TOKEN: ${{ steps.pmd-actions-helper-app-token.outputs.token }} + run: | + tagName="pmd_releases/${PMD_VERSION}" + existingTagName="$(gh --repo pmd/pmd release list --json tagName,isPrerelease --jq ".[] | select(.tagName == \"${tagName}\" and .isPrerelease == true) | .tagName")" + + if [ "${existingTagName}" = "${tagName}" ]; then + echo "Pre-release for tag ${tagName} already exists - deleting it..." + gh release delete "${tagName}" \ + --repo pmd/pmd \ + --cleanup-tag \ + --yes + else + echo "No pre-release ${tagName} exists, nothing to delete" + fi + - name: Create GitHub Pre-Release + id: release + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + GH_TOKEN: ${{ steps.pmd-actions-helper-app-token.outputs.token }} + run: | + tagName="pmd_releases/${PMD_VERSION}" + # now, create a new pre-release for the same tag (new tag will be created) + release_name="PMD ${PMD_VERSION} ($(date -u +%d-%B-%Y))" + gh release create "${tagName}" \ + --repo pmd/pmd \ + --prerelease \ + --target main \ + --title "$release_name" \ + --notes-file "pmd-doc-${PMD_VERSION}/pmd_release_notes.md" \ + "dist/pmd-dist-${PMD_VERSION}-bin.zip" \ + "dist/pmd-dist-${PMD_VERSION}-bin.zip.asc" \ + "dist/pmd-dist-${PMD_VERSION}-src.zip" \ + "dist/pmd-dist-${PMD_VERSION}-src.zip.asc" \ + "dist/pmd-dist-${PMD_VERSION}-doc.zip" \ + "dist/pmd-dist-${PMD_VERSION}-doc.zip.asc" \ + "dist/pmd-${PMD_VERSION}-cyclonedx.xml" \ + "dist/pmd-${PMD_VERSION}-cyclonedx.json" + echo "release_url=https://github.com/pmd/pmd/releases/tag/pmd_releases%2F${PMD_VERSION}" >> "$GITHUB_OUTPUT" + - name: Cleanup gpg + if: ${{ always() }} + run: | + rm -rf "${HOME}/.gpg" + create-regression-tester-baseline: needs: check-version runs-on: ubuntu-latest diff --git a/docs/pages/pmd/devdocs/github_actions_workflows.md b/docs/pages/pmd/devdocs/github_actions_workflows.md index 2a878fc018f..ec09e9eae27 100644 --- a/docs/pages/pmd/devdocs/github_actions_workflows.md +++ b/docs/pages/pmd/devdocs/github_actions_workflows.md @@ -5,7 +5,7 @@ summary: | PMD uses GitHub Actions as the CI/CD infrastructure to build and release new versions. This page gives an overview of how these workflows work and how to use them. author: Andreas Dangel -last_updated: June 2025 (7.15.0) +last_updated: July 2025 (7.16.0) --- {%include note.html content="This page is work in progress and does not yet describe all workflows."%} @@ -189,6 +189,10 @@ we are actually building a SNAPSHOT version. Then a couple of other jobs are bei . * Environment: github-pages * Secrets: no additional secrets +* github-prerelease: Creates a new GitHub pre-release at including + the attached artifacts. It first removes an old pre-release, then + creates the new one with the same tag name. This means, the tag is moved forward for every pre-release. + * Environment: github * create-regression-tester-baseline: Creates a new baseline to be used by the pull request builds for regression testing. The baseline is uploaded to . * Environment: pmd-code @@ -246,8 +250,8 @@ When this was successful, then a couple of other jobs are being executed in para * Environment: pmd-code * Secrets: PMD_CODE_ORG_DEPLOY_KEY * Vars: PMD_CODE_ORG_KNOWN_HOSTS -* github-release: Creates a new github release at including - the attached artifacts. +* github-release: Creates a new GitHub release at including + the attached artifacts. Deletes a pre-release for the same version, if it exists. * Environment: github * create-sourceforge-blog-post: Creates a news entry at . * Environment: sourceforge From e2307bef5e528e37477f89c9eac05ebc2935e8b7 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 17 Jul 2025 15:18:30 +0200 Subject: [PATCH 1139/1962] README.md: Fix build badge [skip ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aa1e7368367..4d71288b511 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ![PMD Logo](https://raw.githubusercontent.com/pmd/pmd/main/docs/images/logo/pmd-logo-300px.png) [![Join the chat](https://img.shields.io/gitter/room/pmd/pmd)](https://app.gitter.im/#/room/#pmd_pmd:gitter.im?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![Build Status](https://github.com/pmd/pmd/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/pmd/pmd/actions) +[![Build Snapshot](https://github.com/pmd/pmd/actions/workflows/build-snapshot.yml/badge.svg?branch=main)](https://github.com/pmd/pmd/actions/workflows/build-snapshot.yml) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/net.sourceforge.pmd/pmd/badge.svg)](https://maven-badges.herokuapp.com/maven-central/net.sourceforge.pmd/pmd) [![Reproducible Builds](https://img.shields.io/badge/Reproducible_Builds-ok-green?labelColor=blue)](https://github.com/jvm-repo-rebuild/reproducible-central/tree/master/content/net/sourceforge/pmd#readme) [![Coverage Status](https://coveralls.io/repos/github/pmd/pmd/badge.svg?branch=main&v=1)](https://coveralls.io/github/pmd/pmd?branch=main) From 8828de8401dcae10c718ad035d7f8e0b383f29b7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Jul 2025 15:20:50 +0200 Subject: [PATCH 1140/1962] Bump org.apache.commons:commons-lang3 from 3.17.0 to 3.18.0 (#5900) Bumps org.apache.commons:commons-lang3 from 3.17.0 to 3.18.0. --- updated-dependencies: - dependency-name: org.apache.commons:commons-lang3 dependency-version: 3.18.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0de048dc04c..12ee95208b6 100644 --- a/pom.xml +++ b/pom.xml @@ -887,7 +887,7 @@ org.apache.commons commons-lang3 - 3.17.0 + 3.18.0 org.apache.commons From 3b4ff97285196d39fe5a2ecda64b2538a5fb4284 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Jul 2025 15:21:22 +0200 Subject: [PATCH 1141/1962] Bump io.github.apex-dev-tools:apex-parser from 4.4.0 to 4.4.1 (#5901) Bumps [io.github.apex-dev-tools:apex-parser](https://github.com/apex-dev-tools/apex-parser) from 4.4.0 to 4.4.1. - [Release notes](https://github.com/apex-dev-tools/apex-parser/releases) - [Changelog](https://github.com/apex-dev-tools/apex-parser/blob/v4.4.1/CHANGELOG.md) - [Commits](https://github.com/apex-dev-tools/apex-parser/compare/v4.4.0...v4.4.1) --- updated-dependencies: - dependency-name: io.github.apex-dev-tools:apex-parser dependency-version: 4.4.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-apex/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index f9f29e187d2..43e761c649c 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -96,7 +96,7 @@ io.github.apex-dev-tools apex-parser - 4.4.0 + 4.4.1 com.google.summit From 989919914b2713289fc85f79dd51b610c69a6fb7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Jul 2025 15:21:50 +0200 Subject: [PATCH 1142/1962] Bump log4j.version from 2.25.0 to 2.25.1 (#5902) Bumps `log4j.version` from 2.25.0 to 2.25.1. Updates `org.apache.logging.log4j:log4j-api` from 2.25.0 to 2.25.1 Updates `org.apache.logging.log4j:log4j-core` from 2.25.0 to 2.25.1 --- updated-dependencies: - dependency-name: org.apache.logging.log4j:log4j-api dependency-version: 2.25.1 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: org.apache.logging.log4j:log4j-core dependency-version: 2.25.1 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-java/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 1aaf1d96e73..0b6b5937736 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -12,7 +12,7 @@ - 2.25.0 + 2.25.1 From 17c06f7dcc8b5e6041421bc71c8b46d97dd461c5 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 17 Jul 2025 16:15:36 +0200 Subject: [PATCH 1143/1962] [doc] Point to CPD Capable Languages in CPD CLI docu instead of maintaining another list of languages Refs https://github.com/pmd/pmd/pull/5733#issuecomment-3083310697 --- docs/pages/pmd/userdocs/cpd/cpd.md | 38 ++---------------------------- 1 file changed, 2 insertions(+), 36 deletions(-) diff --git a/docs/pages/pmd/userdocs/cpd/cpd.md b/docs/pages/pmd/userdocs/cpd/cpd.md index 67fe51ff9ee..5b2a6da6dc8 100644 --- a/docs/pages/pmd/userdocs/cpd/cpd.md +++ b/docs/pages/pmd/userdocs/cpd/cpd.md @@ -4,7 +4,7 @@ tags: [cpd, userdocs] summary: "Learn how to use CPD, the copy-paste detector shipped with PMD." permalink: pmd_userdocs_cpd.html author: Tom Copeland -last_updated: May 2025 (7.14.0) +last_updated: July 2025 (7.16.0) --- ## Overview @@ -270,41 +270,7 @@ to be "debug". ## Supported Languages -* C# -* C/C++ -* [Coco](pmd_languages_coco.html) -* Dart -* EcmaScript (JavaScript) -* Fortran -* [Gherkin](pmd_languages_gherkin.html) (Cucumber) -* Go -* Groovy -* [Html](pmd_languages_html.html) -* [Java](pmd_languages_java.html) -* [Jsp](pmd_languages_jsp.html) -* [Julia](pmd_languages_julia.html) -* [Kotlin](pmd_languages_kotlin.html) -* Lua -* Matlab -* Modelica -* Objective-C -* Perl -* PHP -* [PL/SQL](pmd_languages_plsql.html) -* Python -* Ruby -* [Rust](pmd_languages_rust.html) -* [Salesforce.com Apex](pmd_languages_apex.html) -* Scala -* Swift -* T-SQL -* [TypeScript](pmd_languages_js_ts.html) -* [Visualforce](pmd_languages_visualforce.html) -* vm (Apache Velocity) -* [XML](pmd_languages_xml.html) - * POM (Apache Maven) - * XSL - * WSDL +See [CPD Capable Languages](tag_CpdCapableLanguage.html) for the full list of supported languages. ## Available report formats From 4432b503d82e9928fda36b0e050dbb39d4263df7 Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Thu, 17 Jul 2025 21:48:20 +0200 Subject: [PATCH 1144/1962] Fix #5892: [java] ShortVariable FP for java 22 unnamed variable --- .../resources/category/java/codestyle.xml | 2 ++ .../java/rule/codestyle/xml/ShortVariable.xml | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml index 1ffd8bbbd64..d1165814ba3 100644 --- a/pmd-java/src/main/resources/category/java/codestyle.xml +++ b/pmd-java/src/main/resources/category/java/codestyle.xml @@ -1461,6 +1461,8 @@ Fields, local variables, enum constant names or parameter names that are very sh [not(parent::CatchParameter)] (: Lambda expression parameter :) [not(parent::LambdaParameter)] + (: Exclude Unnamed Variables (JEP 456) :) + [not(@Name='_')] ]]> diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ShortVariable.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ShortVariable.xml index 513b2c1d426..d3b33e6b158 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ShortVariable.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ShortVariable.xml @@ -142,6 +142,32 @@ public class ShortVariable { String foo = (a, b) -> foo(); String bar = (String a, Boolean b) -> foo(); } +} + ]]> + + + + #5892: Unnamed Variables are not flagged + 0 + list = new ArrayList<>(); + var _ = list.add(1); + boolean _ = list.add(1); + } +} + ]]> + + + + #5892: Unnamed Variable in Exception is OK + 0 + From aba727f9c65a2a02eaf578d1dae4942ff9b29521 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Thu, 17 Jul 2025 23:01:54 +0200 Subject: [PATCH 1145/1962] [java] new rule: UselessPureMethodCall --- .../errorprone/UselessPureMethodCallRule.java | 34 +++++++++ .../lang/java/rule/internal/JavaRuleUtil.java | 39 ++++++++-- .../lang/java/types/InvocationMatcher.java | 34 ++++++--- .../resources/category/java/errorprone.xml | 23 ++++++ .../errorprone/UselessPureMethodCallTest.java | 14 ++++ .../errorprone/xml/UselessPureMethodCall.xml | 71 +++++++++++++++++++ 6 files changed, 200 insertions(+), 15 deletions(-) create mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessPureMethodCallRule.java create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessPureMethodCallTest.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessPureMethodCall.xml diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessPureMethodCallRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessPureMethodCallRule.java new file mode 100644 index 00000000000..8db802aa3dd --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessPureMethodCallRule.java @@ -0,0 +1,34 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.errorprone; + +import net.sourceforge.pmd.lang.java.ast.ASTExpressionStatement; +import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; +import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; +import net.sourceforge.pmd.lang.java.rule.internal.JavaRuleUtil; + +/** + * Reports usages of pure methods where the result is ignored. + */ +public class UselessPureMethodCallRule extends AbstractJavaRulechainRule { + + /** + * Specify the node types to visit as parameters. + */ + public UselessPureMethodCallRule() { + super(ASTExpressionStatement.class); + } + + @Override + public Object visit(ASTExpressionStatement node, Object data) { + if (node.getExpr() instanceof ASTMethodCall) { + ASTMethodCall methodCall = (ASTMethodCall) node.getExpr(); + if (JavaRuleUtil.isKnownPure(methodCall)) { + asCtx(data).addViolation(node, methodCall.getMethodName()); + } + } + return null; + } +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/JavaRuleUtil.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/JavaRuleUtil.java index 55604f7f2e0..1128419228f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/JavaRuleUtil.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/JavaRuleUtil.java @@ -40,9 +40,11 @@ import net.sourceforge.pmd.lang.java.ast.ModifierOwner.Visibility; import net.sourceforge.pmd.lang.java.ast.TypeNode; import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; +import net.sourceforge.pmd.lang.java.symbols.JTypeDeclSymbol; import net.sourceforge.pmd.lang.java.symbols.JVariableSymbol; import net.sourceforge.pmd.lang.java.types.InvocationMatcher; import net.sourceforge.pmd.lang.java.types.InvocationMatcher.CompoundInvocationMatcher; +import net.sourceforge.pmd.lang.java.types.JTypeMirror; import net.sourceforge.pmd.lang.java.types.TypeTestUtil; /** @@ -59,11 +61,17 @@ public final class JavaRuleUtil { // actually not all of them, probs only stream of some type // arg which doesn't implement Closeable... "java.util.stream.Stream#_(_*)", + "java.util.Collection#contains(_)", "java.util.Collection#size()", "java.util.List#get(int)", "java.util.Map#get(_)", "java.lang.Iterable#iterator()", - "java.lang.Comparable#compareTo(_)" + "java.lang.Comparable#compareTo(_)", + "java.math.BigDecimal#_(_*)", + "java.math.BigInteger#_(_*)", + "java.time.Temporal#_(_*)", + "java.time.Duration#_(_*)", + "java.time.Period#_(_*)" ); public static final Set LOMBOK_ANNOTATIONS = immutableSetOf( @@ -262,12 +270,12 @@ private static boolean isSetterCall(ASTMethodCall call) { } public static boolean isGetterCall(ASTMethodCall call) { - return call.getArguments().size() == 0 + return call.getArguments().isEmpty() && (startsWithCamelCaseWord(call.getMethodName(), "get") - || startsWithCamelCaseWord(call.getMethodName(), "is")); + || startsWithCamelCaseWord(call.getMethodName(), "is")) + && !call.getMethodType().getReturnType().isVoid(); } - public static boolean isGetterOrSetter(ASTMethodDeclaration node) { return isGetter(node) || isSetter(node); } @@ -384,11 +392,34 @@ private static boolean isNonLocalLhs(ASTExpression lhs) { /** * Whether the invocation has no side-effects. Very conservative. + * @param call method call */ private static boolean isPure(ASTMethodCall call) { return isGetterCall(call) || KNOWN_PURE_METHODS.anyMatch(call); } + /** + * Whether the invocation has no side effects. Even more conservative than {@code isPure}. + * Only checks methods in java.* packages because frameworks may define getter-like methods + * with side effects (such as isEqualTo matcher in AssertJ). + * @param call method call + */ + public static boolean isKnownPure(ASTMethodCall call) { + return isGetterCall(call) + && InvocationMatcher.matchQualifier(call, (type, exact) -> hasPureGetters(type)) + || KNOWN_PURE_METHODS.anyMatch(call) && !call.getMethodType().getReturnType().isVoid(); + } + + private static boolean hasPureGetters(JTypeMirror type) { + JTypeDeclSymbol symbol = type.getSymbol(); + if (symbol == null) { + return false; + } + String pkg = symbol.getPackageName(); + return pkg.startsWith("java.") + && !pkg.startsWith("java.nio") && !pkg.startsWith("java.net"); + } + public static @Nullable ASTVariableId getReferencedNode(ASTNamedReferenceExpr expr) { JVariableSymbol referencedSym = expr.getReferencedSym(); return referencedSym == null ? null : referencedSym.tryGetNode(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/InvocationMatcher.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/InvocationMatcher.java index 2c2604f99a1..2f5d1488856 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/InvocationMatcher.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/InvocationMatcher.java @@ -11,6 +11,7 @@ import java.util.List; import org.apache.commons.lang3.StringUtils; +import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import net.sourceforge.pmd.lang.java.ast.ASTConstructorCall; @@ -98,11 +99,17 @@ public boolean matchesCall(@Nullable InvocationNode node) { return false; } OverloadSelectionResult info = node.getOverloadSelectionInfo(); - return !info.isFailed() && matchQualifier(node) + return !info.isFailed() && matchQualifier(node, qualifierMatcher) && argsMatchOverload(info.getMethodType()); } - private boolean matchQualifier(InvocationNode node) { + /** + * Check if method was invoked on a type that satisfies given condition. + * @param node invocation + * @param qualifierMatcher type matcher + * @return whether declaring type matches + */ + public static boolean matchQualifier(InvocationNode node, TypeMatcher qualifierMatcher) { if (qualifierMatcher == TypeMatcher.ANY) { return true; } @@ -269,24 +276,29 @@ private static int parseType(String source, int i) { } private static TypeMatcher newMatcher(String name) { - return "_".equals(name) ? TypeMatcher.ANY : new TypeMatcher(name); + return "_".equals(name) ? TypeMatcher.ANY : new ClassTypeMatcher(name); } - private static final class TypeMatcher { + public interface TypeMatcher { /** Matches any type. */ - public static final TypeMatcher ANY = new TypeMatcher(null); + TypeMatcher ANY = (type, exact) -> true; + + boolean matches(JTypeMirror type, boolean exact); + } + + private static final class ClassTypeMatcher implements TypeMatcher { - final @Nullable String name; + final @NonNull String name; - private TypeMatcher(@Nullable String name) { + private ClassTypeMatcher(@NonNull String name) { this.name = name; } - boolean matches(JTypeMirror type, boolean exact) { - return name == null - || (exact ? TypeTestUtil.isExactlyAOrAnon(name, type) == OptionalBool.YES - : TypeTestUtil.isA(name, type)); + @Override + public boolean matches(JTypeMirror type, boolean exact) { + return exact ? TypeTestUtil.isExactlyAOrAnon(name, type) == OptionalBool.YES + : TypeTestUtil.isA(name, type); } } diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 1dd3096af4d..65fe66af783 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -3158,6 +3158,29 @@ class Test { + + + Useless Pure Method Call detects when a pure method is called and the result is unused. + + 3 + + System.out.format("%s", item)); // result unused + Stream.of("bar").forEach(item -> System.out.format("%s", item)); // better + } +} +]]> + + + + + + + Collection methods + 4 + 8,9,10,11 + + + + Throwable methods + 4 + 6,7,8,9 + + + + + String methods + 3 + 5,8,9 + + + From b7a76e95d92dd2ba4ddeb411533778c380571798 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Jul 2025 11:59:08 +0200 Subject: [PATCH 1146/1962] [cli] Improve symbolic link tests for Windows Creating symbolic links under Windows requires special permission "SeCreateSymbolicLinkPrivilege". GitHub Actions runners under Windows run with Administrator privileges, which allow to create symlinks. Non-admin users would need to have this privilege added or enable Developer Mode. However, we only need a symlink to a directory, and Windows supports "Directory Junctions" for this - these can be created by ordinary users without special privileges. See also https://gitforwindows.org/symbolic-links.html --- .../net/sourceforge/pmd/cli/PmdCliTest.java | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java index e98aa24ba9a..a396332325c 100644 --- a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java +++ b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java @@ -18,6 +18,7 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.startsWith; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -37,6 +38,7 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; +import org.apache.commons.lang3.SystemUtils; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -456,11 +458,39 @@ void testRelativizeWith() throws Exception { }); } + private static Path createSymlink(Path linkName, Path target) throws IOException { + assertTrue(Files.isDirectory(target), "Symbolic link target " + target + " is not a directory!"); + try { + return Files.createSymbolicLink(linkName, target); + } catch (IOException e) { + if (SystemUtils.IS_OS_WINDOWS) { + // Creating symbolic links under Windows requires special permission "SeCreateSymbolicLinkPrivilege". + // GitHub Actions runners under Windows run with Administrator privileges, which allow to create + // symlinks. Non-admin users would need to have this privilege added or enable Developer Mode. + // However, we only need a symlink to a directory, and Windows supports "Directory Junctions" + // for this - these can be created by ordinary users without special privileges. + Process process = Runtime.getRuntime().exec(new String[]{"cmd", "/c", "mklink", "/J", linkName.toString(), target.toString()}); + int exitCode; + try { + exitCode = process.waitFor(); + } catch (InterruptedException interrupt) { + Thread.currentThread().interrupt(); + throw new RuntimeException(interrupt); + } + assertEquals(0, exitCode, "Error creating symlink on windows: exit code = " + exitCode); + assertTrue(Files.exists(linkName), "Symlink (junction) " + linkName + " doesn't exist!"); + return linkName; + } else { + throw e; + } + } + } + @Test void testRelativizeWithSymLink() throws Exception { // srcDir = /tmp/junit123/src // symlinkedSrcDir = /tmp/junit123/sources -> /tmp/junit123/src - Path symlinkedSrcDir = Files.createSymbolicLink(tempRoot().resolve("sources"), srcDir); + Path symlinkedSrcDir = createSymlink(tempRoot().resolve("sources"), srcDir); runCli(VIOLATIONS_FOUND, "--dir", symlinkedSrcDir.toString(), "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "-z", symlinkedSrcDir.toString()) .verify(result -> { @@ -476,7 +506,7 @@ void testRelativizeWithSymLinkParent() throws Exception { // symlinkedSrcDir = /tmp/junit-relativize-with-123 -> /tmp/junit123/src Path tempPath = Files.createTempDirectory("junit-relativize-with-"); Files.delete(tempPath); - Path symlinkedSrcDir = Files.createSymbolicLink(tempPath, srcDir); + Path symlinkedSrcDir = createSymlink(tempPath, srcDir); // relativizing against parent of symlinkedSrcDir: /tmp runCli(VIOLATIONS_FOUND, "--dir", symlinkedSrcDir.toString(), "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "-z", symlinkedSrcDir.getParent().toString()) From 94e7c350fa8e90a92bb34303a9403864d1b3daaa Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Jul 2025 14:23:51 +0200 Subject: [PATCH 1147/1962] [doc] Update release notes (#5883, #2862) --- docs/pages/release_notes.md | 10 ++++++++++ .../src/main/resources/rulesets/java/quickstart.xml | 2 ++ 2 files changed, 12 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 20ceca853d4..b0050d337a4 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -24,15 +24,25 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy +#### โœจ New Rules + +* Two new rules have been added to Java's Error Prone category: {%rule java/errorprone/ReplaceJavaUtilCalendar %} + and {%rule java/errorprone/ReplaceJavaUtilDate %}. These rules help to migrate away from old Java APIs around + `java.util.Calendar` and `java.util.Date`. It is recommended to use the modern `java.time` API instead, which + is available since Java 8. + ### ๐Ÿ› Fixed Issues * java-design * [#5858](https://github.com/pmd/pmd/issues/5858): \[java] FinalFieldCouldBeStatic false positive for array initializers +* java-errorprone + * [#2862](https://github.com/pmd/pmd/issues/2862): \[java] New Rules: Avoid java.util.Date and Calendar classes ### ๐Ÿšจ API Changes ### โœจ Merged pull requests * [#5859](https://github.com/pmd/pmd/pull/5859): Fix #5858: \[java] Fix false positive in FinalFieldCouldBeStatic for array initializers - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#5883](https://github.com/pmd/pmd/pull/5883): Fix #2862: \[java] Add rules discouraging the use of java.util.Calendar and java.util.Date - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) ### ๐Ÿ“ฆ Dependency updates diff --git a/pmd-java/src/main/resources/rulesets/java/quickstart.xml b/pmd-java/src/main/resources/rulesets/java/quickstart.xml index 5f32089a1d9..3ed29a0f41d 100644 --- a/pmd-java/src/main/resources/rulesets/java/quickstart.xml +++ b/pmd-java/src/main/resources/rulesets/java/quickstart.xml @@ -252,6 +252,8 @@ + + From c8930f4c6d4693aab3f1ef4a1db0b2a941126513 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Jul 2025 14:53:59 +0200 Subject: [PATCH 1148/1962] [scala] Fix javadoc config Follow-up on #5823 --- pmd-scala-modules/pmd-scala-common/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index 935eec31472..b5c75688419 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -112,12 +112,12 @@ ../../pmd-lang-test/${project.version} - ${project.basedir}/../../pmd-test/target/apidocs + ${project.basedir}/../../pmd-test/target/reports/apidocs ../../pmd-test/${project.version} - ${project.basedir}/../../pmd-core/target/apidocs + ${project.basedir}/../../pmd-core/target/reports/apidocs ../../pmd-core/${project.version} From 49782a67ce1c1dc251285a2311d0277f424530ec Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Jul 2025 16:13:19 +0200 Subject: [PATCH 1149/1962] [java] ShortVariable - add test for unnamed pattern --- .../lang/java/rule/codestyle/xml/ShortVariable.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ShortVariable.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ShortVariable.xml index d3b33e6b158..9bcf6b088ea 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ShortVariable.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ShortVariable.xml @@ -168,6 +168,19 @@ public class Foo { private void bar() { try {} catch (Exception _) {} } +} + ]]> + + + + #5892: Unnamed Variable in record pattern matching is OK + 0 + From ca5e70dabbea25a148659378ef2df4659615300c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Jul 2025 16:15:15 +0200 Subject: [PATCH 1150/1962] [doc] Update release notes (#5914, #5892) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 1f57f39fec0..b26f3d53c48 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -30,6 +30,8 @@ documents (such as HTML) on screen, on paper etc. It is shipped with the new module `pmd-css`. ### ๐Ÿ› Fixed Issues +* java-codestyle + * [#5892](https://github.com/pmd/pmd/issues/5892): \[java] ShortVariable false positive for java 22 unnamed variable `_` * java-design * [#5858](https://github.com/pmd/pmd/issues/5858): \[java] FinalFieldCouldBeStatic false positive for array initializers @@ -39,6 +41,7 @@ It is shipped with the new module `pmd-css`. * [#5733](https://github.com/pmd/pmd/pull/5733): \[css] Add new CPD language - [Thomas Prouvot](https://github.com/tprouvot) (@tprouvot) * [#5859](https://github.com/pmd/pmd/pull/5859): Fix #5858: \[java] Fix false positive in FinalFieldCouldBeStatic for array initializers - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#5914](https://github.com/pmd/pmd/pull/5914): Fix #5892: \[java] ShortVariable FP for java 22 Unnamed Variable - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) ### ๐Ÿ“ฆ Dependency updates From c1f2190718031c048b28575ca79843f214e85827 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Jul 2025 16:39:24 +0200 Subject: [PATCH 1151/1962] [doc] Update release notes (#5876) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 0c9c0dd3524..47b01148f05 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -30,6 +30,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ Merged pull requests +* [#5876](https://github.com/pmd/pmd/pull/5876): chore: license header cleanup - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ Dependency updates From c007522004f7e8f0369bf7983e817cbede539975 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Jul 2025 19:48:13 +0200 Subject: [PATCH 1152/1962] [doc] Update release notes (#5597, #5895) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 20ceca853d4..bb33293b6c5 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,6 +25,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* core + * [#5597](https://github.com/pmd/pmd/issues/5597): \[core] POM Incompatibility with Maven 4 * java-design * [#5858](https://github.com/pmd/pmd/issues/5858): \[java] FinalFieldCouldBeStatic false positive for array initializers @@ -33,6 +35,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ Merged pull requests * [#5859](https://github.com/pmd/pmd/pull/5859): Fix #5858: \[java] Fix false positive in FinalFieldCouldBeStatic for array initializers - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#5895](https://github.com/pmd/pmd/pull/5895): Fix #5597: Move dogfood profile to separate settings.xml - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ Dependency updates From 26b4ffddfec19456150548c94d6c0ccdfc38eab7 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 18 Jul 2025 20:14:52 +0200 Subject: [PATCH 1153/1962] Bump build-tools from 32 to 33 (#5921) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fc8fba01c6f..26ffd37a527 100644 --- a/pom.xml +++ b/pom.xml @@ -106,7 +106,7 @@ -Xmx512m -Dfile.encoding=${project.build.sourceEncoding} ${extraArgLine} - 32 + 33 7.10.0 From 9d61ef490ef6d1986d22f0dbf1e90873b4ca0a97 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Fri, 18 Jul 2025 23:57:40 +0200 Subject: [PATCH 1154/1962] [java] new rule: Dangling Javadoc --- .../documentation/DanglingJavadocRule.java | 33 ++++++++ .../resources/category/java/documentation.xml | 27 +++++++ .../documentation/DanglingJavadocTest.java | 11 +++ .../documentation/xml/DanglingJavadoc.xml | 81 +++++++++++++++++++ 4 files changed, 152 insertions(+) create mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/DanglingJavadocRule.java create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/DanglingJavadocTest.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/DanglingJavadoc.xml diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/DanglingJavadocRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/DanglingJavadocRule.java new file mode 100644 index 00000000000..80734730769 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/DanglingJavadocRule.java @@ -0,0 +1,33 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.documentation; + +import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; +import net.sourceforge.pmd.lang.java.ast.JavaComment; +import net.sourceforge.pmd.lang.java.ast.JavadocComment; +import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; +import net.sourceforge.pmd.reporting.RuleContext; + +/** + * Looks for Javadoc that doesn't belong to any particular class, method or field. + */ +public class DanglingJavadocRule extends AbstractJavaRulechainRule { + + public DanglingJavadocRule() { + super(ASTCompilationUnit.class); + } + + @Override + public Object visit(ASTCompilationUnit unit, Object data) { + for (JavaComment comment: unit.getComments()) { + if (comment instanceof JavadocComment && ((JavadocComment) comment).getOwner() == null) { + ((RuleContext) data).addViolationWithPosition(comment.getToken(), + unit.getAstInfo(), + comment.getReportLocation(), getMessage()); + } + } + return null; + } +} diff --git a/pmd-java/src/main/resources/category/java/documentation.xml b/pmd-java/src/main/resources/category/java/documentation.xml index 8b513885054..82a5f9ce3b8 100644 --- a/pmd-java/src/main/resources/category/java/documentation.xml +++ b/pmd-java/src/main/resources/category/java/documentation.xml @@ -148,5 +148,32 @@ public void doSomething() { ]]> + + + Javadoc should belong to a class or method. + + 3 + + + + diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/DanglingJavadocTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/DanglingJavadocTest.java new file mode 100644 index 00000000000..001d47ea913 --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/DanglingJavadocTest.java @@ -0,0 +1,11 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.documentation; + +import net.sourceforge.pmd.test.PmdRuleTst; + +class DanglingJavadocTest extends PmdRuleTst { + // no additional unit tests +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/DanglingJavadoc.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/DanglingJavadoc.xml new file mode 100644 index 00000000000..55e8c347489 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/DanglingJavadoc.xml @@ -0,0 +1,81 @@ + + + + + Dangling javadoc + 5 + 1,9,13,25,29 + + + + + Inline comments + 2 + 1,3 + + + + + Markdown + 2 + 6,15 + + + \ No newline at end of file From 1cd99159b355a2567193fa171d84fe78fbcc9c01 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 19 Jul 2025 19:11:20 +0200 Subject: [PATCH 1155/1962] [doc] Update release notes (#5893) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 20ceca853d4..c56a95bfcb1 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -33,6 +33,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ Merged pull requests * [#5859](https://github.com/pmd/pmd/pull/5859): Fix #5858: \[java] Fix false positive in FinalFieldCouldBeStatic for array initializers - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#5893](https://github.com/pmd/pmd/pull/5893): chore: Fix Mockito javaagent warning for Java 21+ - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ Dependency updates From 1ea8c62d89b0b329a837acb7e1d7db10fc16139f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 19 Jul 2025 19:14:22 +0200 Subject: [PATCH 1156/1962] [doc] Update release notes (#5894) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 3ad1c56dbc1..66c18289b52 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -54,6 +54,7 @@ It is shipped with the new module `pmd-css`. * [#5859](https://github.com/pmd/pmd/pull/5859): Fix #5858: \[java] Fix false positive in FinalFieldCouldBeStatic for array initializers - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#5876](https://github.com/pmd/pmd/pull/5876): chore: license header cleanup - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5883](https://github.com/pmd/pmd/pull/5883): Fix #2862: \[java] Add rules discouraging the use of java.util.Calendar and java.util.Date - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5894](https://github.com/pmd/pmd/pull/5894): chore: Fix JUnit warning about invalid test factory - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5895](https://github.com/pmd/pmd/pull/5895): Fix #5597: Move dogfood profile to separate settings.xml - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5914](https://github.com/pmd/pmd/pull/5914): Fix #5892: \[java] ShortVariable FP for java 22 Unnamed Variable - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) From 2dff3a75b148bd0cb013d6bb962779e441f2a436 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 19 Jul 2025 19:17:10 +0200 Subject: [PATCH 1157/1962] [doc] Update release notes (#5344, #5899) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 3ad1c56dbc1..757db30a384 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -39,6 +39,8 @@ It is shipped with the new module `pmd-css`. ### ๐Ÿ› Fixed Issues * core * [#5597](https://github.com/pmd/pmd/issues/5597): \[core] POM Incompatibility with Maven 4 +* java + * [#5344](https://github.com/pmd/pmd/issues/5344): \[java] IllegalArgumentException: Invalid type reference for method or ctor type annotation: 16 * java-codestyle * [#5892](https://github.com/pmd/pmd/issues/5892): \[java] ShortVariable false positive for java 22 unnamed variable `_` * java-design @@ -55,6 +57,7 @@ It is shipped with the new module `pmd-css`. * [#5876](https://github.com/pmd/pmd/pull/5876): chore: license header cleanup - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5883](https://github.com/pmd/pmd/pull/5883): Fix #2862: \[java] Add rules discouraging the use of java.util.Calendar and java.util.Date - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5895](https://github.com/pmd/pmd/pull/5895): Fix #5597: Move dogfood profile to separate settings.xml - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5899](https://github.com/pmd/pmd/pull/5899): Fix #5344: \[java] Just log invalid annotation target type - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5914](https://github.com/pmd/pmd/pull/5914): Fix #5892: \[java] ShortVariable FP for java 22 Unnamed Variable - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) ### ๐Ÿ“ฆ Dependency updates From fb7ffb312d92b2b84aa967399b86582aa251f92c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 19 Jul 2025 19:20:23 +0200 Subject: [PATCH 1158/1962] [doc] Update release notes (#4328, #5909) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 3ad1c56dbc1..0442bc6f7c4 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -38,6 +38,7 @@ It is shipped with the new module `pmd-css`. ### ๐Ÿ› Fixed Issues * core + * [#4328](https://github.com/pmd/pmd/issues/4328): \[ci] Improve Github Actions Workflows * [#5597](https://github.com/pmd/pmd/issues/5597): \[core] POM Incompatibility with Maven 4 * java-codestyle * [#5892](https://github.com/pmd/pmd/issues/5892): \[java] ShortVariable false positive for java 22 unnamed variable `_` @@ -55,6 +56,7 @@ It is shipped with the new module `pmd-css`. * [#5876](https://github.com/pmd/pmd/pull/5876): chore: license header cleanup - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5883](https://github.com/pmd/pmd/pull/5883): Fix #2862: \[java] Add rules discouraging the use of java.util.Calendar and java.util.Date - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5895](https://github.com/pmd/pmd/pull/5895): Fix #5597: Move dogfood profile to separate settings.xml - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5909](https://github.com/pmd/pmd/pull/5909): \[ci] Create a pre-release for snapshot builds - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5914](https://github.com/pmd/pmd/pull/5914): Fix #5892: \[java] ShortVariable FP for java 22 Unnamed Variable - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) ### ๐Ÿ“ฆ Dependency updates From 43c58323ffa6fc53ab1279edc477558ff62f6fb9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 19 Jul 2025 19:23:12 +0200 Subject: [PATCH 1159/1962] [doc] Update release notes (#5911) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 3ad1c56dbc1..a7bd1d02e6e 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -55,6 +55,7 @@ It is shipped with the new module `pmd-css`. * [#5876](https://github.com/pmd/pmd/pull/5876): chore: license header cleanup - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5883](https://github.com/pmd/pmd/pull/5883): Fix #2862: \[java] Add rules discouraging the use of java.util.Calendar and java.util.Date - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5895](https://github.com/pmd/pmd/pull/5895): Fix #5597: Move dogfood profile to separate settings.xml - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5911](https://github.com/pmd/pmd/pull/5911): \[doc] Reference CPD Capable Languages in CPD CLI docu - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5914](https://github.com/pmd/pmd/pull/5914): Fix #5892: \[java] ShortVariable FP for java 22 Unnamed Variable - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) ### ๐Ÿ“ฆ Dependency updates From 0372970ed533eff7a8b9b7b7c95a45fa9a4f3c1c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 19 Jul 2025 19:25:16 +0200 Subject: [PATCH 1160/1962] [doc] Update release notes (#5918) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 3ad1c56dbc1..66ed647090e 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -56,6 +56,7 @@ It is shipped with the new module `pmd-css`. * [#5883](https://github.com/pmd/pmd/pull/5883): Fix #2862: \[java] Add rules discouraging the use of java.util.Calendar and java.util.Date - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5895](https://github.com/pmd/pmd/pull/5895): Fix #5597: Move dogfood profile to separate settings.xml - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5914](https://github.com/pmd/pmd/pull/5914): Fix #5892: \[java] ShortVariable FP for java 22 Unnamed Variable - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#5918](https://github.com/pmd/pmd/pull/5918): chore: \[cli] Improve symbolic link tests for Windows - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ Dependency updates From 426ea3e0d2a79de92b83c2be9789465a140e5f3c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 19 Jul 2025 19:26:43 +0200 Subject: [PATCH 1161/1962] [doc] Update release notes (#5920) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 3ad1c56dbc1..4b0ae1787db 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -56,6 +56,7 @@ It is shipped with the new module `pmd-css`. * [#5883](https://github.com/pmd/pmd/pull/5883): Fix #2862: \[java] Add rules discouraging the use of java.util.Calendar and java.util.Date - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5895](https://github.com/pmd/pmd/pull/5895): Fix #5597: Move dogfood profile to separate settings.xml - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5914](https://github.com/pmd/pmd/pull/5914): Fix #5892: \[java] ShortVariable FP for java 22 Unnamed Variable - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#5920](https://github.com/pmd/pmd/pull/5920): chore: \[scala] Fix javadoc config - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ Dependency updates From abdad72e342e55e1ce06501b074cf2184e033e96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Sat, 19 Jul 2025 21:27:46 +0200 Subject: [PATCH 1162/1962] Add a new rule TypeParameterNamingConventions Deprecate GenericsNaming The old rule wasn't configurable, the new one is. The name of the new rule is in line with the existing rules ClassNamingConventions, FormalParameterNamingConventions, LocalVariableNamingConventions, and MethodNamingConventions. --- .../TypeParameterNamingConventionsRule.java | 45 ++++++ .../resources/category/java/codestyle.xml | 42 +++++ .../TypeParameterNamingConventionsTest.java | 11 ++ .../xml/TypeParameterNamingConventions.xml | 150 ++++++++++++++++++ 4 files changed, 248 insertions(+) create mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/TypeParameterNamingConventionsRule.java create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/TypeParameterNamingConventionsTest.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/TypeParameterNamingConventions.xml diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/TypeParameterNamingConventionsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/TypeParameterNamingConventionsRule.java new file mode 100644 index 00000000000..a6dbe697d9c --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/TypeParameterNamingConventionsRule.java @@ -0,0 +1,45 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.codestyle; + +import java.util.regex.Pattern; + +import net.sourceforge.pmd.lang.java.ast.ASTTypeParameter; +import net.sourceforge.pmd.properties.PropertyDescriptor; + + +/** + * Configurable naming conventions for type parameters. + */ +public class TypeParameterNamingConventionsRule extends AbstractNamingConventionRule { + + private final PropertyDescriptor typeParameterRegex = defaultProp("typeParameterName", "type parameter").build(); + + public TypeParameterNamingConventionsRule() { + super(ASTTypeParameter.class); + definePropertyDescriptor(typeParameterRegex); + } + + @Override + public Object visit(ASTTypeParameter node, Object data) { + checkMatches(node, typeParameterRegex, data); + return data; + } + + @Override + String defaultConvention() { + return "[A-Z]"; + } + + @Override + String nameExtractor(ASTTypeParameter node) { + return node.getName(); + } + + @Override + String kindDisplayName(ASTTypeParameter node, PropertyDescriptor descriptor) { + return "type parameter"; + } +} diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml index d1165814ba3..892784203a6 100644 --- a/pmd-java/src/main/resources/category/java/codestyle.xml +++ b/pmd-java/src/main/resources/category/java/codestyle.xml @@ -701,11 +701,14 @@ public class Foo { Names for references to generic values should be limited to a single uppercase letter. + +**Deprecated:** This rule has been replaced by TypeParameterNamingConventions, which provides more comprehensive and configurable naming conventions for type parameters. 4 @@ -1204,6 +1207,45 @@ public class Foo { + + + Configurable naming conventions for type parameters in generic types and methods. + This rule reports type parameter declarations which do not match the configured regex. + Type parameters can appear on classes, interfaces, enums, records, and methods. + + By default, this rule uses the standard Java naming convention (single uppercase letter). + + 4 + + { } +public class Cache { } + +// Generic types - invalid +public interface Repository { } // lowercase +public class Cache { } // multiple letters + +// Generic methods - valid +public class Util { + public static T identity(T value) { return value; } + public R transform(T input, Function mapper) { } +} + +// Generic methods - invalid +public class Util { + public static element get(element value) { } // lowercase + public OUTPUT convert(INPUT in) { } // multiple letters +} +]]> + + + + + + + 1 upper case/single letter + 0 + +{ +} + ]]> + + + + 2 upper case/single letter + 0 + > +{ +} + ]]> + + + + 1 lower case/single letter + 1 + 1 + + The type parameter name 'b' doesn't match '[A-Z]' + + +{ +} + ]]> + + + + 1 upper case/multiple letter + 1 + 1 + + The type parameter name 'CBA' doesn't match '[A-Z]' + + > +{ +} + ]]> + + + + 1 upper case/multiple letter - custom pattern + [A-Z]+ + 0 + > +{ +} + ]]> + + + + Generic method - single uppercase letter (valid) + 0 + T getValue(T input) { + return input; + } +} + ]]> + + + + Generic method - multiple type parameters (valid) + 0 + T transform(T input, U other) { + return input; + } +} + ]]> + + + + Generic method - lowercase letter (invalid) + 1 + 2 + + The type parameter name 't' doesn't match '[A-Z]' + + t getValue(t input) { + return input; + } +} + ]]> + + + + Generic method - multiple letters (invalid) + 1 + 2 + + The type parameter name 'TYPE' doesn't match '[A-Z]' + + TYPE getValue(TYPE input) { + return input; + } +} + ]]> + + + + Generic method - mixed valid and invalid + 1 + 2 + + The type parameter name 'invalid' doesn't match '[A-Z]' + + T transform(T input, invalid other) { + return input; + } +} + ]]> + + + + Generic static method - valid + 0 + > T max(T a, T b) { + return a.compareTo(b) > 0 ? a : b; + } +} + ]]> + + + From b4b24969ddb27c7cc59640dec53e9f14850ebdaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Sat, 19 Jul 2025 21:48:22 +0200 Subject: [PATCH 1163/1962] add TypeParameterNamingConventions to quickstart.xml, comment out GenericsNaming --- pmd-java/src/main/resources/rulesets/java/quickstart.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/resources/rulesets/java/quickstart.xml b/pmd-java/src/main/resources/rulesets/java/quickstart.xml index 3ed29a0f41d..4147dbd27a8 100644 --- a/pmd-java/src/main/resources/rulesets/java/quickstart.xml +++ b/pmd-java/src/main/resources/rulesets/java/quickstart.xml @@ -66,7 +66,7 @@ - + @@ -76,6 +76,7 @@ + From 8e8acc0e89d2be2b9601a4ce58d5cb62f2c34694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Sun, 20 Jul 2025 18:01:46 +0200 Subject: [PATCH 1164/1962] Fix AssignmentInOperandRule to also work an do-while loops and switch statements. --- .../errorprone/AssignmentInOperandRule.java | 19 ++++- .../errorprone/xml/AssignmentInOperand.xml | 78 +++++++++++++++++++ 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java index 23065e209cf..e33a89566d5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java @@ -7,10 +7,12 @@ import static net.sourceforge.pmd.properties.PropertyFactory.booleanProperty; import net.sourceforge.pmd.lang.java.ast.ASTAssignmentExpression; +import net.sourceforge.pmd.lang.java.ast.ASTDoStatement; import net.sourceforge.pmd.lang.java.ast.ASTExpression; import net.sourceforge.pmd.lang.java.ast.ASTExpressionStatement; import net.sourceforge.pmd.lang.java.ast.ASTForStatement; import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; +import net.sourceforge.pmd.lang.java.ast.ASTSwitchStatement; import net.sourceforge.pmd.lang.java.ast.ASTUnaryExpression; import net.sourceforge.pmd.lang.java.ast.ASTWhileStatement; import net.sourceforge.pmd.lang.java.ast.JavaNode; @@ -30,6 +32,11 @@ public class AssignmentInOperandRule extends AbstractJavaRulechainRule { .desc("Allow assignment within the conditional expression of an if statement") .defaultValue(false).build(); + private static final PropertyDescriptor ALLOW_SWITCH_DESCRIPTOR = + booleanProperty("allowSwitch") + .desc("Allow assignment within the conditional expression of a switch statement") + .defaultValue(false).build(); + private static final PropertyDescriptor ALLOW_FOR_DESCRIPTOR = booleanProperty("allowFor") .desc("Allow assignment within the conditional expression of a for statement") @@ -40,6 +47,11 @@ public class AssignmentInOperandRule extends AbstractJavaRulechainRule { .desc("Allow assignment within the conditional expression of a while statement") .defaultValue(false).build(); + private static final PropertyDescriptor ALLOW_DO_WHILE_DESCRIPTOR = + booleanProperty("allowDoWhile") + .desc("Allow assignment within the conditional expression of a do-while statement") + .defaultValue(false).build(); + private static final PropertyDescriptor ALLOW_INCREMENT_DECREMENT_DESCRIPTOR = booleanProperty("allowIncrementDecrement") .desc("Allow increment or decrement operators within the conditional expression of an if, for, or while statement") @@ -52,6 +64,8 @@ public AssignmentInOperandRule() { definePropertyDescriptor(ALLOW_FOR_DESCRIPTOR); definePropertyDescriptor(ALLOW_WHILE_DESCRIPTOR); definePropertyDescriptor(ALLOW_INCREMENT_DECREMENT_DESCRIPTOR); + definePropertyDescriptor(ALLOW_DO_WHILE_DESCRIPTOR); + definePropertyDescriptor(ALLOW_SWITCH_DESCRIPTOR); } @Override @@ -77,6 +91,8 @@ private void checkAssignment(ASTExpression impureExpr, RuleContext ctx) { } if (parent instanceof ASTIfStatement && !getProperty(ALLOW_IF_DESCRIPTOR) || parent instanceof ASTWhileStatement && !getProperty(ALLOW_WHILE_DESCRIPTOR) + || parent instanceof ASTDoStatement && !getProperty(ALLOW_DO_WHILE_DESCRIPTOR) + || parent instanceof ASTSwitchStatement && !getProperty(ALLOW_SWITCH_DESCRIPTOR) || parent instanceof ASTForStatement && ((ASTForStatement) parent).getCondition() == toplevel && !getProperty(ALLOW_FOR_DESCRIPTOR)) { ctx.addViolation(impureExpr); @@ -85,7 +101,8 @@ private void checkAssignment(ASTExpression impureExpr, RuleContext ctx) { public boolean allowsAllAssignments() { return getProperty(ALLOW_IF_DESCRIPTOR) && getProperty(ALLOW_FOR_DESCRIPTOR) - && getProperty(ALLOW_WHILE_DESCRIPTOR) && getProperty(ALLOW_INCREMENT_DECREMENT_DESCRIPTOR); + && getProperty(ALLOW_WHILE_DESCRIPTOR) && getProperty(ALLOW_INCREMENT_DECREMENT_DESCRIPTOR) + && getProperty(ALLOW_DO_WHILE_DESCRIPTOR) && getProperty(ALLOW_SWITCH_DESCRIPTOR); } /** diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml index 5e1eca9d6c4..c9935b8f2ba 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml @@ -105,6 +105,46 @@ public class Foo { ]]> + + assignment in do-while conditional expression + 1 + 6 + Avoid assignments in operands + 0); + } + private int getX() {return 1;} +} + ]]> + + + + assignment in switch expression + 1 + 4 + Avoid assignments in operands + + + assignment in while conditional expression, allowed true @@ -154,6 +194,44 @@ public class Foo { ]]> + + assignment in do-while conditional expression, allowed + true + 0 + 0); + } + private int getX() {return 1;} +} + ]]> + + + + assignment in switch expression, allowed + true + 0 + + + increment in if conditional expression, allowed true From 9b280a1cdc7b6520dadcedf637d0d87b840b6d3f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Jul 2025 19:18:38 +0200 Subject: [PATCH 1165/1962] Bump kotlin.version from 1.9.24 to 2.2.0 (#5864) * Bump kotlin.version from 1.9.24 to 2.2.0 Bumps `kotlin.version` from 1.9.24 to 2.2.0. Updates `org.jetbrains.kotlin:kotlin-stdlib` from 1.9.24 to 2.2.0 - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v1.9.24...v2.2.0) Updates `org.jetbrains.kotlin:kotlin-stdlib-jdk8` from 1.9.24 to 2.2.0 - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v1.9.24...v2.2.0) Updates `org.jetbrains.kotlin:kotlin-reflect` from 1.9.24 to 2.2.0 - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v1.9.24...v2.2.0) Updates `org.jetbrains.kotlin:kotlin-test-junit` from 1.9.24 to 2.2.0 - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v1.9.24...v2.2.0) Updates `org.jetbrains.kotlin:kotlin-maven-plugin` from 1.9.24 to 2.2.0 --- updated-dependencies: - dependency-name: org.jetbrains.kotlin:kotlin-stdlib dependency-version: 2.2.0 dependency-type: direct:production update-type: version-update:semver-major - dependency-name: org.jetbrains.kotlin:kotlin-stdlib-jdk8 dependency-version: 2.2.0 dependency-type: direct:production update-type: version-update:semver-major - dependency-name: org.jetbrains.kotlin:kotlin-reflect dependency-version: 2.2.0 dependency-type: direct:development update-type: version-update:semver-major - dependency-name: org.jetbrains.kotlin:kotlin-test-junit dependency-version: 2.2.0 dependency-type: direct:production update-type: version-update:semver-major - dependency-name: org.jetbrains.kotlin:kotlin-maven-plugin dependency-version: 2.2.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Use kotlin 1.9 for compatibility * Fix dokka-maven-plugin for Java 25 * Fix Java Tests for Java 25 * Revert "Fix Java Tests for Java 25" This reverts commit 8aa3c4824e4ba5550f9b98ba2110b62b211e30c8. This is actually part of #5872 --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andreas Dangel --- pom.xml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 26ffd37a527..d4b6998553b 100644 --- a/pom.xml +++ b/pom.xml @@ -81,8 +81,10 @@ 1.8 + 1.9 + 1.9 ${maven.compiler.test.target} - 1.9.24 + 2.2.0 5.9.1 5.13.3 1.13.3 @@ -475,6 +477,19 @@ + + + + org.jetbrains.kotlin + kotlin-compiler + ${kotlin.version} + + org.apache.maven.plugins From 2c7aab872ea8f1a34446e090dd4a548b8735d5b2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 22 Jul 2025 19:19:13 +0200 Subject: [PATCH 1166/1962] Bump maven from 3.9.10 to 3.9.11 (#5910) --- .mvn/wrapper/maven-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 2f94e616987..12fbe1e9078 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -16,4 +16,4 @@ # under the License. wrapperVersion=3.3.2 distributionType=only-script -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.10/apache-maven-3.9.10-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip From 25950f3088c81560beb42c28c53a6b38216e58f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Jul 2025 19:26:04 +0200 Subject: [PATCH 1167/1962] chore(deps): bump org.apache.maven.plugins:maven-enforcer-plugin from 3.6.0 to 3.6.1 (#5926) chore(deps): bump org.apache.maven.plugins:maven-enforcer-plugin Bumps [org.apache.maven.plugins:maven-enforcer-plugin](https://github.com/apache/maven-enforcer) from 3.6.0 to 3.6.1. - [Release notes](https://github.com/apache/maven-enforcer/releases) - [Commits](https://github.com/apache/maven-enforcer/compare/enforcer-3.6.0...enforcer-3.6.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-enforcer-plugin dependency-version: 3.6.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9f5a870ca96..325f6fd821f 100644 --- a/pom.xml +++ b/pom.xml @@ -528,7 +528,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 3.6.0 + 3.6.1 org.apache.maven.plugins From 5cf96ff0c9f58e93dada97a3f403e49c28d3b4e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Jul 2025 19:26:31 +0200 Subject: [PATCH 1168/1962] chore(deps): bump ostruct from 0.6.2 to 0.6.3 in /.ci/files in the all-gems group across 1 directory (#5927) chore(deps): bump ostruct --- updated-dependencies: - dependency-name: ostruct dependency-version: 0.6.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all-gems ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .ci/files/Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/files/Gemfile.lock b/.ci/files/Gemfile.lock index 56097198fa2..5f8f0360cf7 100644 --- a/.ci/files/Gemfile.lock +++ b/.ci/files/Gemfile.lock @@ -17,7 +17,7 @@ GEM logger-colors (1.0.0) nokogiri (1.18.8-x86_64-linux-gnu) racc (~> 1.4) - ostruct (0.6.2) + ostruct (0.6.3) pmdtester (1.5.5) differ (~> 0.1) liquid (~> 5.4) From a5b3fe4ea202ed604458859382ac20c35a604f4c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Jul 2025 19:27:04 +0200 Subject: [PATCH 1169/1962] chore(deps): bump marocchino/sticky-pull-request-comment from 2.9.3 to 2.9.4 in the all-actions group (#5928) chore(deps): bump marocchino/sticky-pull-request-comment Bumps the all-actions group with 1 update: [marocchino/sticky-pull-request-comment](https://github.com/marocchino/sticky-pull-request-comment). Updates `marocchino/sticky-pull-request-comment` from 2.9.3 to 2.9.4 - [Release notes](https://github.com/marocchino/sticky-pull-request-comment/releases) - [Commits](https://github.com/marocchino/sticky-pull-request-comment/compare/d2ad0de260ae8b0235ce059e63f2949ba9e05943...773744901bac0e8cbb5a0dc842800d45e9b2b405) --- updated-dependencies: - dependency-name: marocchino/sticky-pull-request-comment dependency-version: 2.9.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all-actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/publish-pull-requests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-pull-requests.yml b/.github/workflows/publish-pull-requests.yml index 4acf8093855..bbb6f833f14 100644 --- a/.github/workflows/publish-pull-requests.yml +++ b/.github/workflows/publish-pull-requests.yml @@ -177,7 +177,7 @@ jobs: echo "### Result" >> "${GITHUB_STEP_SUMMARY}" echo "${comment}" >> "${GITHUB_STEP_SUMMARY}" - - uses: marocchino/sticky-pull-request-comment@d2ad0de260ae8b0235ce059e63f2949ba9e05943 #v2.9.3 + - uses: marocchino/sticky-pull-request-comment@773744901bac0e8cbb5a0dc842800d45e9b2b405 #v2.9.4 with: header: pmd-publish-pull-requests number: ${{ env.PR_NUMBER }} From 7d391f6e5af1cbcf540fed7e9061c05ea418a380 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 22 Jul 2025 20:23:02 +0200 Subject: [PATCH 1170/1962] chore(deps): Update gems (#5929) - benchmark from 0.4.0 to 0.4.1 - drb from 2.2.1 to 2.2.3 - connection_pool from 2.5.2 to 2.5.3 - json from 2.11.0 to 2.13.0 - nokogiri from 1.18.8 to 1.18.9 This fixes https://github.com/pmd/pmd/security/dependabot/83 and https://github.com/pmd/pmd/security/dependabot/84 https://github.com/advisories/GHSA-353f-x4gh-cqq8 - faraday-net_http from 3.4.0 to 3.4.1 - faraday from 2.13.0 to 2.13.3 --- .ci/files/Gemfile.lock | 2 +- docs/Gemfile.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.ci/files/Gemfile.lock b/.ci/files/Gemfile.lock index 5f8f0360cf7..64b4474638d 100644 --- a/.ci/files/Gemfile.lock +++ b/.ci/files/Gemfile.lock @@ -15,7 +15,7 @@ GEM strscan (>= 3.1.1) logger (1.7.0) logger-colors (1.0.0) - nokogiri (1.18.8-x86_64-linux-gnu) + nokogiri (1.18.9-x86_64-linux-gnu) racc (~> 1.4) ostruct (0.6.3) pmdtester (1.5.5) diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index 05f7e7704bc..5a804d7ea68 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -17,7 +17,7 @@ GEM addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) base64 (0.2.0) - benchmark (0.4.0) + benchmark (0.4.1) bigdecimal (3.2.2) coffee-script (2.4.1) coffee-script-source @@ -26,13 +26,13 @@ GEM colorator (1.1.0) commonmarker (0.23.11) concurrent-ruby (1.3.5) - connection_pool (2.5.2) + connection_pool (2.5.3) csv (3.3.5) dnsruby (1.72.4) base64 (~> 0.2.0) logger (~> 1.6.5) simpleidn (~> 0.2.1) - drb (2.2.1) + drb (2.2.3) em-websocket (0.5.3) eventmachine (>= 0.12.9) http_parser.rb (~> 0) @@ -40,11 +40,11 @@ GEM ffi (>= 1.15.0) eventmachine (1.2.7) execjs (2.10.0) - faraday (2.13.0) + faraday (2.13.3) faraday-net_http (>= 2.0, < 3.5) json logger - faraday-net_http (3.4.0) + faraday-net_http (3.4.1) net-http (>= 0.5.0) ffi (1.17.2-x86_64-linux-gnu) forwardable-extended (2.6.0) @@ -217,7 +217,7 @@ GEM gemoji (>= 3, < 5) html-pipeline (~> 2.2) jekyll (>= 3.0, < 5.0) - json (2.11.0) + json (2.13.0) kramdown (2.4.0) rexml kramdown-parser-gfm (1.1.0) @@ -235,7 +235,7 @@ GEM minitest (5.25.5) net-http (0.6.0) uri - nokogiri (1.18.8-x86_64-linux-gnu) + nokogiri (1.18.9-x86_64-linux-gnu) racc (~> 1.4) octokit (4.25.1) faraday (>= 1, < 3) From 15c0591e001f0308e72a8b6bc3f794d82f6db111 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Wed, 23 Jul 2025 15:39:53 +0200 Subject: [PATCH 1171/1962] Fix AvoidReassigningLoopVariablesRule to allow only the following kinds of assingments in the forReassign=skip case: i++ ++i i+=1 i=i+1 i=1+i (and the negative versions of those) --- .../AvoidReassigningLoopVariablesRule.java | 77 ++++++++++++++++++- .../xml/AvoidReassigningLoopVariables.xml | 29 +++---- 2 files changed, 91 insertions(+), 15 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java index 2f9218c8f94..1061e1e55e3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java @@ -12,6 +12,7 @@ import net.sourceforge.pmd.lang.ast.NodeStream; import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr.ASTNamedReferenceExpr; import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr.AccessType; +import net.sourceforge.pmd.lang.java.ast.ASTAssignmentExpression; import net.sourceforge.pmd.lang.java.ast.ASTBlock; import net.sourceforge.pmd.lang.java.ast.ASTBreakStatement; import net.sourceforge.pmd.lang.java.ast.ASTContinueStatement; @@ -20,6 +21,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTForUpdate; import net.sourceforge.pmd.lang.java.ast.ASTForeachStatement; import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; +import net.sourceforge.pmd.lang.java.ast.ASTInfixExpression; import net.sourceforge.pmd.lang.java.ast.ASTLocalClassStatement; import net.sourceforge.pmd.lang.java.ast.ASTLoopStatement; import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement; @@ -27,6 +29,8 @@ import net.sourceforge.pmd.lang.java.ast.ASTSwitchStatement; import net.sourceforge.pmd.lang.java.ast.ASTThrowStatement; import net.sourceforge.pmd.lang.java.ast.ASTVariableId; +import net.sourceforge.pmd.lang.java.ast.AssignmentOp; +import net.sourceforge.pmd.lang.java.ast.BinaryOp; import net.sourceforge.pmd.lang.java.ast.JavaNode; import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; @@ -202,10 +206,81 @@ private void checkVorViolations(JavaNode node) { final boolean onlyConsiderWrite = guarded || mayExit; node.descendants(ASTNamedReferenceExpr.class) .filter(it -> loopVarNames.contains(it.getName())) - .filter(it -> onlyConsiderWrite ? JavaAstUtils.isVarAccessStrictlyWrite(it) + .filter(it -> onlyConsiderWrite ? it.getAccessType() == AccessType.WRITE && !isSimpleSkipOperation(it) : JavaAstUtils.isVarAccessReadAndWrite(it)) .forEach(it -> asCtx(ruleCtx).addViolation(it, it.getName())); } + + private boolean isSimpleSkipOperation(ASTNamedReferenceExpr expr) { + if (expr.getAccessType() != AccessType.WRITE) { + return false; + } + + if (expr.getParent() instanceof ASTAssignmentExpression) { + // Check for simple assignment operations: i += 1, i -= 1, i = i + 1, i = i - 1 + ASTAssignmentExpression assignment = (ASTAssignmentExpression) expr.getParent(); + if (expr.getIndexInParent() == 0) { // expr is the left side of assignment + return isSimpleSkipAssignment(assignment, expr.getName()); + } + } else { + // Check for unary increment/decrement: i++, ++i, i--, --i + return JavaAstUtils.isVarAccessReadAndWrite(expr); + } + + return false; + } + + private boolean isSimpleSkipAssignment(ASTAssignmentExpression assignment, String varName) { + if (assignment.getOperator().isCompound()) { + // Only += 1 and -= 1 are allowed as compound assignments + AssignmentOp op = assignment.getOperator(); + ASTExpression rhs = assignment.getRightOperand(); + return (op == AssignmentOp.ADD_ASSIGN || op == AssignmentOp.SUB_ASSIGN) && isLiteralOne(rhs); + } + + if (assignment.getOperator() == AssignmentOp.ASSIGN) { + // Check for i = i + 1 or i = i - 1 + ASTExpression rhs = assignment.getRightOperand(); + return isSimpleIncrementExpression(rhs, varName); + } + + return false; + } + + private boolean isLiteralOne(ASTExpression expr) { + // Check if expression is the literal "1" + return expr.isCompileTimeConstant() + && expr.getConstValue() instanceof Number + && ((Number) expr.getConstValue()).intValue() == 1; + } + + private boolean isSimpleIncrementExpression(ASTExpression expr, String varName) { + // Check for patterns: i + 1, i - 1, 1 + i + if (expr instanceof ASTInfixExpression) { + ASTInfixExpression infixExpr = (ASTInfixExpression) expr; + BinaryOp operator = infixExpr.getOperator(); + + if (operator == BinaryOp.ADD || operator == BinaryOp.SUB) { + ASTExpression left = infixExpr.getLeftOperand(); + ASTExpression right = infixExpr.getRightOperand(); + + // Check i + 1 or i - 1 + if (isVariableReference(left, varName) && isLiteralOne(right)) { + return true; + } + + // Check 1 + i (only for addition) + if (operator == BinaryOp.ADD && isLiteralOne(left) && isVariableReference(right, varName)) { + return true; + } + } + } + return false; + } + + private boolean isVariableReference(ASTExpression expr, String varName) { + return expr instanceof ASTNamedReferenceExpr && ((ASTNamedReferenceExpr) expr).getName().equals(varName); + } } private enum ForeachReassignOption { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidReassigningLoopVariables.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidReassigningLoopVariables.xml index db040456476..d4ddb5cc984 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidReassigningLoopVariables.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidReassigningLoopVariables.xml @@ -673,12 +673,11 @@ public class Foo { ]]> - - + #4500 violation: various conditional reassignments of 'for' loop variable, skip allowed skip - 10 - 13,14,15,16,17,18,19,20,21,22 + 9 + 16,17,18,19,20,21,22,23,24 Date: Wed, 23 Jul 2025 22:38:26 +0200 Subject: [PATCH 1172/1962] Fix UseUtilityClassRule to use the message provided in design.xml --- .../pmd/lang/java/rule/design/UseUtilityClassRule.java | 4 +--- pmd-java/src/main/resources/category/java/design.xml | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/UseUtilityClassRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/UseUtilityClassRule.java index 459bcde7b30..48cbf8650e3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/UseUtilityClassRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/UseUtilityClassRule.java @@ -76,10 +76,8 @@ public Object visit(ASTClassDeclaration klass, Object data) { && !hasLombokPrivateCtor(klass); - String message; if (hasAnyMethods && hasNonPrivateCtor) { - message = "This utility class has a non-private constructor"; - asCtx(data).addViolationWithMessage(klass, message); + asCtx(data).addViolation(klass); } return null; } diff --git a/pmd-java/src/main/resources/category/java/design.xml b/pmd-java/src/main/resources/category/java/design.xml index 5f5a4ef9c15..2065e163bfe 100644 --- a/pmd-java/src/main/resources/category/java/design.xml +++ b/pmd-java/src/main/resources/category/java/design.xml @@ -1452,7 +1452,7 @@ public class MyClass { From cc9de39ab69ae087ae6c99ecb67b827b67199835 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Jul 2025 11:10:47 +0200 Subject: [PATCH 1173/1962] [ci] Reuse GitHub Pre-Releases By reusing an already existing pre-release, no notifications should be sent when updating the release. Previously, we deleted the old pre-release and created a new pre-release, which resulted in a notification about a new release for every build from branch main. Reusing the pre-release is not straight forward: releases are coupled to tags. Deleting a tag for an already existing release changes that release to "draft" which then needs to be published again. But we don't want to publish the release again to avoid unnecessary notifications about a pre-release. That's why a new temporary tag is created, the existing pre-release is moved onto this temporary tag and then the old tag is removed and recreated to point to the tip of the main branch. This effectively moves the release tag for the pre-release forward. After that the release is updated with the new information. The build-release.yml and git-repo-sync.yml workflows are updated to ignore these "SNAPSHOT" release tags. --- .github/workflows/build-release.yml | 3 +- .github/workflows/git-repo-sync.yml | 3 +- .github/workflows/publish-snapshot.yml | 150 +++++++++++++----- .../pmd/devdocs/github_actions_workflows.md | 11 +- 4 files changed, 122 insertions(+), 45 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 94f4dc9ed1c..a63a429378a 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -3,7 +3,8 @@ name: Build Release on: push: tags: - - '**' + - 'pmd_releases/*' + - '!pmd_releases/*-SNAPSHOT' workflow_dispatch: jobs: diff --git a/.github/workflows/git-repo-sync.yml b/.github/workflows/git-repo-sync.yml index 32d01fb48a5..f68e4ea2fdf 100644 --- a/.github/workflows/git-repo-sync.yml +++ b/.github/workflows/git-repo-sync.yml @@ -5,7 +5,8 @@ on: branches: - main tags: - - '**' + - 'pmd_releases/*' + - '!pmd_releases/*-SNAPSHOT' workflow_dispatch: permissions: diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 921bebc67b3..aae6c27faf8 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -468,8 +468,13 @@ jobs: name: docs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id }} - path: docs - + path: pmd-doc-${{ needs.check-version.outputs.PMD_VERSION }} + - name: Create docs zip + env: + PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} + run: | + zip -qr "dist/pmd-dist-${PMD_VERSION}-doc.zip" "pmd-doc-${PMD_VERSION}/" + rm -rf "pmd-doc-${PMD_VERSION}/" - name: Setup GPG env: PMD_CI_GPG_PRIVATE_KEY: ${{ secrets.PMD_CI_GPG_PRIVATE_KEY }} @@ -480,13 +485,6 @@ jobs: gpg --list-keys --fingerprint --keyid-format=long gpg --list-secret-keys --fingerprint --keyid-format=long - - name: Create docs zip - env: - PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} - run: | - mv docs "pmd-doc-${PMD_VERSION}" - zip -qr "dist/pmd-dist-${PMD_VERSION}-doc.zip" "pmd-doc-${PMD_VERSION}/" - - name: Sign files env: PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} @@ -506,47 +504,123 @@ jobs: private-key: ${{ secrets.PMD_ACTIONS_HELPER_PRIVATE_KEY }} owner: pmd repositories: pmd - permission-contents: write # create a release - - name: Delete old GitHub Pre-Release + permission-contents: write # create a release, remove/create a tag + - name: Prepare tag for GitHub Pre-Release + id: tags env: PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} GH_TOKEN: ${{ steps.pmd-actions-helper-app-token.outputs.token }} run: | - tagName="pmd_releases/${PMD_VERSION}" - existingTagName="$(gh --repo pmd/pmd release list --json tagName,isPrerelease --jq ".[] | select(.tagName == \"${tagName}\" and .isPrerelease == true) | .tagName")" - - if [ "${existingTagName}" = "${tagName}" ]; then - echo "Pre-release for tag ${tagName} already exists - deleting it..." - gh release delete "${tagName}" \ + existingTagName="$(gh --repo pmd/pmd release list --json tagName,isPrerelease --jq ".[] | select(.isPrerelease == true) | .tagName")" + previousTagName="" + + if [ -n "${existingTagName}" ]; then + # we can't simply delete the old tag, as the existing pre-release would then become a draft and + # we would need to republish it again, which we want to avoid to avoid notifications for every pre-release. + # strategy: + # 1. create a new tag with suffix "-previous-SNAPSHOT" + previousSha="$(gh api \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + "/repos/pmd/pmd/git/ref/tags/${existingTagName}" --jq ".object.sha")" + previousTagName="${existingTagName}-previous-SNAPSHOT" + echo "Creating tag ${previousTagName} -> ${previousSha}" + gh api \ + --method POST \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + /repos/pmd/pmd/git/refs \ + -f "ref=refs/tags/${previousTagName}" -f "sha=${previousSha}" + # 2. update pre-release to point to this new tag + echo "Update existing pre-release to use tag ${previousTagName}" + gh release edit "${existingTagName}" \ --repo pmd/pmd \ - --cleanup-tag \ - --yes - else - echo "No pre-release ${tagName} exists, nothing to delete" + --tag "${previousTagName}" \ + --verify-tag + # 3. remove the old, existing tag + echo "Deleting tag ${existingTagName}" + gh api \ + --method DELETE \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + "/repos/pmd/pmd/git/refs/tags/${existingTagName}" fi - - name: Create GitHub Pre-Release + + # create a new tag + mainSha="$(gh api \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + /repos/pmd/pmd/git/ref/heads/main --jq ".object.sha")" + tagName="pmd_releases/${PMD_VERSION}" + echo "Creating tag ${tagName} -> ${mainSha}" + gh api \ + --method POST \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + /repos/pmd/pmd/git/refs \ + -f "ref=refs/tags/${tagName}" -f "sha=${mainSha}" + + echo "tagName=${tagName}" >> "${GITHUB_OUTPUT}" + echo "previousTagName=${previousTagName}" >> "${GITHUB_OUTPUT}" + - name: Create or Update GitHub Pre-Release id: release env: PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} GH_TOKEN: ${{ steps.pmd-actions-helper-app-token.outputs.token }} + TAG_NAME: ${{ steps.tags.outputs.tagName }} + PREVIOUS_TAG_NAME: ${{ steps.tags.outputs.previousTagName }} run: | - tagName="pmd_releases/${PMD_VERSION}" - # now, create a new pre-release for the same tag (new tag will be created) release_name="PMD ${PMD_VERSION} ($(date -u +%d-%B-%Y))" - gh release create "${tagName}" \ - --repo pmd/pmd \ - --prerelease \ - --target main \ - --title "$release_name" \ - --notes-file "pmd-doc-${PMD_VERSION}/pmd_release_notes.md" \ - "dist/pmd-dist-${PMD_VERSION}-bin.zip" \ - "dist/pmd-dist-${PMD_VERSION}-bin.zip.asc" \ - "dist/pmd-dist-${PMD_VERSION}-src.zip" \ - "dist/pmd-dist-${PMD_VERSION}-src.zip.asc" \ - "dist/pmd-dist-${PMD_VERSION}-doc.zip" \ - "dist/pmd-dist-${PMD_VERSION}-doc.zip.asc" \ - "dist/pmd-${PMD_VERSION}-cyclonedx.xml" \ - "dist/pmd-${PMD_VERSION}-cyclonedx.json" + if [ -z "${PREVIOUS_TAG_NAME}" ]; then + echo "Create new release ${TAG_NAME}" + gh release create "${TAG_NAME}" \ + --repo pmd/pmd \ + --verify-tag \ + --prerelease \ + --title "$release_name" \ + --notes-file "pmd-doc-${PMD_VERSION}/pmd_release_notes.md" \ + "dist/pmd-dist-${PMD_VERSION}-bin.zip" \ + "dist/pmd-dist-${PMD_VERSION}-bin.zip.asc" \ + "dist/pmd-dist-${PMD_VERSION}-src.zip" \ + "dist/pmd-dist-${PMD_VERSION}-src.zip.asc" \ + "dist/pmd-dist-${PMD_VERSION}-doc.zip" \ + "dist/pmd-dist-${PMD_VERSION}-doc.zip.asc" \ + "dist/pmd-${PMD_VERSION}-cyclonedx.xml" \ + "dist/pmd-${PMD_VERSION}-cyclonedx.json" + else + echo "Update release ${PREVIOUS_TAG_NAME} -> ${TAG_NAME}" + gh release edit "${PREVIOUS_TAG_NAME}" \ + --repo pmd/pmd \ + --tag "${TAG_NAME}" \ + --verify-tag \ + --prerelease \ + --title "$release_name" \ + --notes-file "pmd-doc-${PMD_VERSION}/pmd_release_notes.md" + echo "Deleting old release assets" + for name in $(gh release view "${TAG_NAME}" --repo pmd/pmd --json assets --jq ".assets[].name"); do + gh release delete-asset "${TAG_NAME}" "$name" \ + --repo pmd/pmd \ + --yes + done + echo "Uploading new release assets" + gh release upload "${TAG_NAME}" \ + --repo pmd/pmd \ + "dist/pmd-dist-${PMD_VERSION}-bin.zip" \ + "dist/pmd-dist-${PMD_VERSION}-bin.zip.asc" \ + "dist/pmd-dist-${PMD_VERSION}-src.zip" \ + "dist/pmd-dist-${PMD_VERSION}-src.zip.asc" \ + "dist/pmd-dist-${PMD_VERSION}-doc.zip" \ + "dist/pmd-dist-${PMD_VERSION}-doc.zip.asc" \ + "dist/pmd-${PMD_VERSION}-cyclonedx.xml" \ + "dist/pmd-${PMD_VERSION}-cyclonedx.json" + + echo "Deleting tag ${PREVIOUS_TAG_NAME}" + gh api \ + --method DELETE \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + "/repos/pmd/pmd/git/refs/tags/${PREVIOUS_TAG_NAME}" + fi echo "release_url=https://github.com/pmd/pmd/releases/tag/pmd_releases%2F${PMD_VERSION}" >> "$GITHUB_OUTPUT" - name: Cleanup gpg if: ${{ always() }} diff --git a/docs/pages/pmd/devdocs/github_actions_workflows.md b/docs/pages/pmd/devdocs/github_actions_workflows.md index ec09e9eae27..dd1eeeacbf2 100644 --- a/docs/pages/pmd/devdocs/github_actions_workflows.md +++ b/docs/pages/pmd/devdocs/github_actions_workflows.md @@ -5,7 +5,7 @@ summary: | PMD uses GitHub Actions as the CI/CD infrastructure to build and release new versions. This page gives an overview of how these workflows work and how to use them. author: Andreas Dangel -last_updated: July 2025 (7.16.0) +last_updated: July 2025 (7.17.0) --- {%include note.html content="This page is work in progress and does not yet describe all workflows."%} @@ -35,7 +35,8 @@ not require any secrets. including forks). This is also a scheduled workflow that runs every month to make sure, the project can still be built. -"Build Release" is triggered, whenever a tag is pushed. Note that the whole project is built at once, that +"Build Release" is triggered, whenever a tag is pushed (excluding SNAPSHOT pre-release tags). +Note that the whole project is built at once, that means if pmd-designer/pmd-core update is required, this can't be built. See also [Circular dependencies between pmd-designer, pmd-core, pmd-cli #4446](https://github.com/pmd/pmd/issues/4446). As this happens very seldom, this situation is ignored for now. @@ -189,9 +190,9 @@ we are actually building a SNAPSHOT version. Then a couple of other jobs are bei . * Environment: github-pages * Secrets: no additional secrets -* github-prerelease: Creates a new GitHub pre-release at including - the attached artifacts. It first removes an old pre-release, then - creates the new one with the same tag name. This means, the tag is moved forward for every pre-release. +* github-prerelease: Creates a new GitHub pre-release or updates and existing one at . + This looks like a real release and includes the usual attached (signed) artifacts. + The release is reused and the tag is moved forward for every pre-release. * Environment: github * create-regression-tester-baseline: Creates a new baseline to be used by the pull request builds for regression testing. The baseline is uploaded to . From d426747e932b3754995f4658280f0d316fc0e81d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Thu, 24 Jul 2025 13:56:06 +0200 Subject: [PATCH 1174/1962] New Rule: RelianceOnDefaultCharset Flags constructor calls / method invocations that rely on the default charset. Recommend specifying the charset explicitely. --- .../RelianceOnDefaultCharsetRule.java | 109 +++++ .../resources/category/java/bestpractices.xml | 47 ++ .../RelianceOnDefaultCharsetTest.java | 11 + .../xml/RelianceOnDefaultCharset.xml | 454 ++++++++++++++++++ 4 files changed, 621 insertions(+) create mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/RelianceOnDefaultCharsetRule.java create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/RelianceOnDefaultCharsetTest.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/RelianceOnDefaultCharset.xml diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/RelianceOnDefaultCharsetRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/RelianceOnDefaultCharsetRule.java new file mode 100644 index 00000000000..8b16ebfbd90 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/RelianceOnDefaultCharsetRule.java @@ -0,0 +1,109 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.bestpractices; + +import java.util.HashMap; +import java.util.Map; + +import net.sourceforge.pmd.lang.java.ast.ASTConstructorCall; +import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; +import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; +import net.sourceforge.pmd.lang.java.types.InvocationMatcher; + +/** + * Detects constructors and methods that use the JVM's default character set + * instead of explicitly specifying a charset. This rule helps ensure + * platform-independent text encoding behavior. + * + *

    The rule only flags violations when the appropriate replacement method + * with explicit charset parameter is available in the target Java version. + * + * @since 7.17.0 + */ +public class RelianceOnDefaultCharsetRule extends AbstractJavaRulechainRule { + + /** + * Maps each violating method/constructor to the minimum Java version + * where its charset-aware replacement is available. + */ + private static final Map METHOD_TO_MIN_VERSION = new HashMap<>(); + + static { + METHOD_TO_MIN_VERSION.put("java.io.InputStreamReader#new(java.io.InputStream)", "1.3"); + METHOD_TO_MIN_VERSION.put("java.io.OutputStreamWriter#new(java.io.OutputStream)", "1.3"); + + METHOD_TO_MIN_VERSION.put("java.net.URLEncoder#encode(java.lang.String)", "1.4"); + METHOD_TO_MIN_VERSION.put("java.net.URLDecoder#decode(java.lang.String)", "1.4"); + + METHOD_TO_MIN_VERSION.put("java.io.PrintStream#new(java.io.OutputStream)", "1.4"); + METHOD_TO_MIN_VERSION.put("java.io.PrintStream#new(java.io.OutputStream,boolean)", "1.4"); + METHOD_TO_MIN_VERSION.put("java.io.PrintStream#new(java.lang.String)", "1.5"); + METHOD_TO_MIN_VERSION.put("java.io.PrintStream#new(java.io.File)", "1.5"); + + METHOD_TO_MIN_VERSION.put("java.io.PrintWriter#new(java.lang.String)", "1.5"); + METHOD_TO_MIN_VERSION.put("java.io.PrintWriter#new(java.io.File)", "1.5"); + METHOD_TO_MIN_VERSION.put("java.io.PrintWriter#new(java.io.OutputStream)", "10"); + METHOD_TO_MIN_VERSION.put("java.io.PrintWriter#new(java.io.OutputStream,boolean)", "10"); + + METHOD_TO_MIN_VERSION.put("java.util.Scanner#new(java.io.InputStream)", "1.5"); + METHOD_TO_MIN_VERSION.put("java.util.Scanner#new(java.io.File)", "1.5"); + METHOD_TO_MIN_VERSION.put("java.util.Scanner#new(java.nio.file.Path)", "1.7"); + METHOD_TO_MIN_VERSION.put("java.util.Scanner#new(java.nio.channels.ReadableByteChannel)", "1.10"); + + METHOD_TO_MIN_VERSION.put("java.util.Formatter#new()", "1.5"); + METHOD_TO_MIN_VERSION.put("java.util.Formatter#new(java.io.OutputStream)", "1.5"); + METHOD_TO_MIN_VERSION.put("java.util.Formatter#new(java.io.PrintStream)", "1.5"); + METHOD_TO_MIN_VERSION.put("java.util.Formatter#new(java.lang.String)", "1.5"); + METHOD_TO_MIN_VERSION.put("java.util.Formatter#new(java.io.File)", "1.5"); + + METHOD_TO_MIN_VERSION.put("java.lang.String#new(byte[])", "1.6"); + METHOD_TO_MIN_VERSION.put("java.lang.String#new(byte[],int,int)", "1.6"); + METHOD_TO_MIN_VERSION.put("java.lang.String#getBytes()", "1.6"); + + METHOD_TO_MIN_VERSION.put("java.io.ByteArrayOutputStream#toString()", "10"); + + METHOD_TO_MIN_VERSION.put("java.io.FileReader#new(java.lang.String)", "11"); + METHOD_TO_MIN_VERSION.put("java.io.FileReader#new(java.io.File)", "11"); + METHOD_TO_MIN_VERSION.put("java.io.FileReader#new(java.io.FileDescriptor)", "11"); + + METHOD_TO_MIN_VERSION.put("java.io.FileWriter#new(java.lang.String)", "11"); + METHOD_TO_MIN_VERSION.put("java.io.FileWriter#new(java.lang.String,boolean)", "11"); + METHOD_TO_MIN_VERSION.put("java.io.FileWriter#new(java.io.File)", "11"); + METHOD_TO_MIN_VERSION.put("java.io.FileWriter#new(java.io.File,boolean)", "11"); + METHOD_TO_MIN_VERSION.put("java.io.FileWriter#new(java.io.FileDescriptor)", "11"); + } + + public RelianceOnDefaultCharsetRule() { + super(ASTConstructorCall.class, ASTMethodCall.class); + } + + @Override + public Object visit(ASTConstructorCall node, Object data) { + checkInvocation(node, data); + return data; + } + + @Override + public Object visit(ASTMethodCall node, Object data) { + checkInvocation(node, data); + return data; + } + + private void checkInvocation(net.sourceforge.pmd.lang.java.ast.JavaNode node, Object data) { + for (Map.Entry entry : METHOD_TO_MIN_VERSION.entrySet()) { + String methodSignature = entry.getKey(); + String minVersion = entry.getValue(); + + InvocationMatcher matcher = InvocationMatcher.parse(methodSignature); + if (matcher.matchesCall(node)) { + // Only flag violation if replacement method is available in current Java version + if (node.getLanguageVersion().compareToVersion(minVersion) >= 0) { + asCtx(data).addViolation(node); + } + return; + } + } + } +} diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 5cff27a574f..4e6e068a21e 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -1163,6 +1163,53 @@ public class Foo { + + +Be sure to specify a character set for APIs that use the JVM's default character set to ensure +stable encoding behavior between different JVMs, programs, and servers. Using the platform's +default charset makes the code less portable and might lead to unexpected behavior when running +on different systems. + + 3 + + + + + + + + + InputStreamReader + 1 + 6 + + + + + + OutputStreamWriter + 1 + 6 + + java 1.4 + + + + + URLEncoder/URLDecoder - violations and replacements in Java 1.4+ + 2 + 6,7 + + java 1.4 + + + + URLEncoder/URLDecoder - no violations in Java 1.3 (replacements not available) + 0 + + java 1.3 + + + + + PrintStream - violations and replacements in Java 1.5+ + 4 + 7,8,9,10 + + java 1.5 + + + + PrintStream - partial violations in Java 1.4 (some replacements available) + 2 + 6,7 + + java 1.4 + + + + PrintStream - no violations in Java 1.3 (no replacements available) + 0 + + java 1.3 + + + + + PrintWriter - violations and replacements in Java 10+ + 4 + 7,8,9,10 + + java 10 + + + + PrintWriter - partial violations in Java 1.5 (some replacements available) + 2 + 8,9 + + java 1.5 + + + + PrintWriter - no violations in Java 1.5 (no replacements available) + 0 + + java 1.4 + + + + + Scanner - violations and replacements in Java 10+ + 4 + 9,10,11,12 + + java 10 + + + + + Formatter - violations and replacements in Java 1.5+ + 5 + 7,8,9,10,11 + + java 1.5 + + + + + String - violations and replacements in Java 1.6+ + 3 + 4,5,6 + + java 1.6 + + + + String - no violations in Java 1.5 (replacements not available) + 0 + + java 1.5 + + + + + ByteArrayOutputStream - violations and replacements in Java 10+ + 1 + 5 + + java 10 + + + + ByteArrayOutputStream - no violations in Java 9 (replacement not available) + 0 + + java 9 + + + + + FileReader - violations and replacements in Java 11+ + 3 + 8,9,10 + + java 11 + + + + FileReader - no violations in Java 10 (replacements not available) + 0 + + java 10 + + + + + FileWriter - violations and replacements in Java 11+ + 5 + 8,9,10,11,12 + + java 11 + + + + FileWriter - no violations in Java 10 (replacements not available) + 0 + + java 10 + + + From 443f466ffd6878cb318107371367f2cd7a3df13e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Thu, 24 Jul 2025 16:23:42 +0200 Subject: [PATCH 1175/1962] Feedback from review --- pmd-java/src/main/resources/category/java/codestyle.xml | 4 ++-- pmd-java/src/main/resources/rulesets/java/quickstart.xml | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml index 892784203a6..2c05de955d0 100644 --- a/pmd-java/src/main/resources/category/java/codestyle.xml +++ b/pmd-java/src/main/resources/category/java/codestyle.xml @@ -708,7 +708,7 @@ public class Foo { Names for references to generic values should be limited to a single uppercase letter. -**Deprecated:** This rule has been replaced by TypeParameterNamingConventions, which provides more comprehensive and configurable naming conventions for type parameters. +**Deprecated:** This rule has been replaced by {% rule TypeParameterNamingConventions %}, which provides more comprehensive and configurable naming conventions for type parameters. 4 @@ -1209,7 +1209,7 @@ public class Foo { diff --git a/pmd-java/src/main/resources/rulesets/java/quickstart.xml b/pmd-java/src/main/resources/rulesets/java/quickstart.xml index 4147dbd27a8..436645c8c8f 100644 --- a/pmd-java/src/main/resources/rulesets/java/quickstart.xml +++ b/pmd-java/src/main/resources/rulesets/java/quickstart.xml @@ -66,7 +66,6 @@ - From 0b80d904080f9321472dd649ca45c87e6dc2d6f3 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 25 Jul 2025 08:06:05 +0200 Subject: [PATCH 1176/1962] Prepare pmd release 7.16.0 --- docs/_config.yml | 2 +- docs/pages/release_notes.md | 25 ++++++++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 81988a78a48..e9ba013e856 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,7 +1,7 @@ repository: pmd/pmd pmd: - version: 7.16.0-SNAPSHOT + version: 7.16.0 previous_version: 7.15.0 date: 2025-07-25 # release types: major, minor, bugfix diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 969f9ef31d8..3a8228a18b4 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -85,6 +85,7 @@ It is shipped with the new module `pmd-css`. * [#5733](https://github.com/pmd/pmd/pull/5733): \[css] Add new CPD language - [Thomas Prouvot](https://github.com/tprouvot) (@tprouvot) * [#5859](https://github.com/pmd/pmd/pull/5859): Fix #5858: \[java] Fix false positive in FinalFieldCouldBeStatic for array initializers - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#5872](https://github.com/pmd/pmd/pull/5872): \[java] Add Support for Java 25 - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5876](https://github.com/pmd/pmd/pull/5876): chore: license header cleanup - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5883](https://github.com/pmd/pmd/pull/5883): Fix #2862: \[java] Add rules discouraging the use of java.util.Calendar and java.util.Date - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5893](https://github.com/pmd/pmd/pull/5893): chore: Fix Mockito javaagent warning for Java 21+ - [Andreas Dangel](https://github.com/adangel) (@adangel) @@ -99,9 +100,31 @@ It is shipped with the new module `pmd-css`. ### ๐Ÿ“ฆ Dependency updates +* [#5857](https://github.com/pmd/pmd/pull/5857): Bump PMD from 7.14.0 to 7.15.0 +* [#5861](https://github.com/pmd/pmd/pull/5861): Bump scalameta.version from 4.13.7 to 4.13.8 +* [#5862](https://github.com/pmd/pmd/pull/5862): Bump com.puppycrawl.tools:checkstyle from 10.25.1 to 10.26.1 +* [#5863](https://github.com/pmd/pmd/pull/5863): Bump org.apache.maven.plugins:maven-pmd-plugin from 3.26.0 to 3.27.0 +* [#5864](https://github.com/pmd/pmd/pull/5864): Bump kotlin.version from 1.9.24 to 2.2.0 +* [#5865](https://github.com/pmd/pmd/pull/5865): Bump org.junit:junit-bom from 5.13.1 to 5.13.2 +* [#5866](https://github.com/pmd/pmd/pull/5866): Bump org.jsoup:jsoup from 1.20.1 to 1.21.1 +* [#5884](https://github.com/pmd/pmd/pull/5884): Bump org.junit:junit-bom from 5.13.2 to 5.13.3 +* [#5885](https://github.com/pmd/pmd/pull/5885): Bump org.apache.maven.plugins:maven-gpg-plugin from 3.2.7 to 3.2.8 +* [#5886](https://github.com/pmd/pmd/pull/5886): Bump org.checkerframework:checker-qual from 3.49.4 to 3.49.5 +* [#5889](https://github.com/pmd/pmd/pull/5889): Bump org.apache.maven.plugins:maven-enforcer-plugin from 3.5.0 to 3.6.0 +* [#5900](https://github.com/pmd/pmd/pull/5900): Bump org.apache.commons:commons-lang3 from 3.17.0 to 3.18.0 +* [#5901](https://github.com/pmd/pmd/pull/5901): Bump io.github.apex-dev-tools:apex-parser from 4.4.0 to 4.4.1 +* [#5902](https://github.com/pmd/pmd/pull/5902): Bump log4j.version from 2.25.0 to 2.25.1 +* [#5910](https://github.com/pmd/pmd/pull/5910): Bump maven from 3.9.10 to 3.9.11 +* [#5921](https://github.com/pmd/pmd/pull/5921): Bump build-tools from 32 to 33 +* [#5926](https://github.com/pmd/pmd/pull/5926): chore(deps): bump org.apache.maven.plugins:maven-enforcer-plugin from 3.6.0 to 3.6.1 +* [#5927](https://github.com/pmd/pmd/pull/5927): chore(deps): bump ostruct from 0.6.2 to 0.6.3 in /.ci/files in the all-gems group across 1 directory +* [#5928](https://github.com/pmd/pmd/pull/5928): chore(deps): bump marocchino/sticky-pull-request-comment from 2.9.3 to 2.9.4 in the all-actions group +* [#5929](https://github.com/pmd/pmd/pull/5929): chore(deps): Update gems ### ๐Ÿ“ˆ Stats +* 100 commits +* 21 closed tickets & PRs +* Days since last release: 27 {% endtocmaker %} - From d60e2685371e1970ad836bfea824cc98dd689a10 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 25 Jul 2025 08:30:02 +0200 Subject: [PATCH 1177/1962] [release] prepare release pmd_releases/7.16.0 --- pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-css/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-rust/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 6 +++--- 44 files changed, 46 insertions(+), 46 deletions(-) diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index 7eb774ace5e..e7e050a961a 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.16.0-SNAPSHOT + 7.16.0 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 43e761c649c..502b5529d5e 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index 8d3dba71f25..53ce32e10ae 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index 687492b7fa4..74244a4af21 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index c6010b9b3c1..843c40ed38d 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index 3662ed6e7c9..a170041cd1c 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index 3d081ecf94f..40d72be2f0a 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-css/pom.xml b/pmd-css/pom.xml index 6b0f538b361..0311abac40b 100644 --- a/pmd-css/pom.xml +++ b/pmd-css/pom.xml @@ -9,7 +9,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index 19151c6ce15..b3bfdc4c056 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index 6c0ff57cd48..d67a00a056b 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index 64261e34d4b..87dc7625fa0 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index b390c6bdfbf..693c4698532 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index f93b937d38d..f9ab450b022 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index 296d4b41c20..017698d7091 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index 5b5200942ca..01c107a189c 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index 8c01d373ef5..b47510ba4d8 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 0b6b5937736..a5a326cdf3a 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index 1ff4da6cccd..6c29c246f6c 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index 696bba50f7a..2eca0bb74c6 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index 97c68523615..112198e777f 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index d64022a1d86..9f263459e0d 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index deaccd20333..082c805f68e 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index f31d1abfb44..400609afe1c 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index fbef69b5fd4..abcc09b0e6a 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index 1c83809190d..a7483f22a66 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index 99ded9d44e1..73149f218f8 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index 8cb2a4a6c0d..f939a34f901 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index 85ba2bb679c..b433fdfa1d3 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index a874bc3ce48..4ef2665e8a8 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index 7540812aa0c..df824b99ab6 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index 97abcec0ca9..00196ce68cc 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index ec3ef9fe3f9..e37b8e21dec 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index 962bbe92a76..fda9a9b5413 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index b5c75688419..86bd3cb4d70 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index 196a5d01020..e03f635ab8e 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.16.0-SNAPSHOT + 7.16.0 ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index f0c5358429c..c5c16de1e85 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.16.0-SNAPSHOT + 7.16.0 ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index 8043b3a6cae..1440a2449e4 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index dd9a4c608e4..024c4586faa 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index 3d6ba6ff1ac..4bc602a2528 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index 5648a746151..38e3da4afb2 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index d40ae521432..f99230c5e13 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index 6e4965b9a65..13943e3c66f 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index f8f080434e1..936003fdd6f 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 ../pom.xml diff --git a/pom.xml b/pom.xml index 325f6fd821f..3eb21ba3a37 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.16.0-SNAPSHOT + 7.16.0 pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - HEAD + pmd_releases/7.16.0 PMD @@ -73,7 +73,7 @@ - 2025-06-27T09:37:42Z + 2025-07-25T06:06:19Z 8 From 25a5d0891e954005ff1c8f1ef6f3d63eb462db4d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 25 Jul 2025 09:07:15 +0200 Subject: [PATCH 1178/1962] [release] Prepare next development version --- docs/_config.yml | 6 +- docs/pages/release_notes.md | 91 +-------------- docs/pages/release_notes_old.md | 126 +++++++++++++++++++++ pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-css/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-rust/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 4 +- 47 files changed, 175 insertions(+), 138 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index e9ba013e856..d7e2157eac9 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,9 +1,9 @@ repository: pmd/pmd pmd: - version: 7.16.0 - previous_version: 7.15.0 - date: 2025-07-25 + version: 7.17.0-SNAPSHOT + previous_version: 7.16.0 + date: 2025-09-12 # release types: major, minor, bugfix release_type: minor diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 3a8228a18b4..0c9c0dd3524 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -24,107 +24,18 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy -#### ๐Ÿš€ New: Java 25 Support -This release of PMD brings support for Java 25. - -There are the following new standard language features: -* [JEP 511: Module Import Declarations](https://openjdk.org/jeps/511) -* [JEP 512: Compact Source Files and Instance Main Methods](https://openjdk.org/jeps/512) -* [JEP 513: Flexible Constructor Bodies](https://openjdk.org/jeps/513) - -And one preview language feature: -* [JEP 507: Primitive Types in Patterns, instanceof, and switch (Third Preview)](https://openjdk.org/jeps/507) - -In order to analyze a project with PMD that uses these preview language features, -you'll need to enable it via the environment variable `PMD_JAVA_OPTS` and select the new language -version `25-preview`: - - export PMD_JAVA_OPTS=--enable-preview - pmd check --use-version java-25-preview ... - -Note: Support for Java 23 preview language features have been removed. The version "23-preview" -is no longer available. - -#### New: CPD support for CSS -CPD now supports CSS (Cascading Style Sheets), a language for describing the rendering of structured -documents (such as HTML) on screen, on paper etc. -It is shipped with the new module `pmd-css`. - -#### โœจ New Rules -* Two new rules have been added to Java's Error Prone category: {%rule java/errorprone/ReplaceJavaUtilCalendar %} - and {%rule java/errorprone/ReplaceJavaUtilDate %}. These rules help to migrate away from old Java APIs around - `java.util.Calendar` and `java.util.Date`. It is recommended to use the modern `java.time` API instead, which - is available since Java 8. - ### ๐Ÿ› Fixed Issues -* core - * [#4328](https://github.com/pmd/pmd/issues/4328): \[ci] Improve Github Actions Workflows - * [#5597](https://github.com/pmd/pmd/issues/5597): \[core] POM Incompatibility with Maven 4 -* java - * [#5344](https://github.com/pmd/pmd/issues/5344): \[java] IllegalArgumentException: Invalid type reference for method or ctor type annotation: 16 - * [#5478](https://github.com/pmd/pmd/issues/5478): \[java] Support Java 25 -* java-codestyle - * [#5892](https://github.com/pmd/pmd/issues/5892): \[java] ShortVariable false positive for java 22 unnamed variable `_` -* java-design - * [#5858](https://github.com/pmd/pmd/issues/5858): \[java] FinalFieldCouldBeStatic false positive for array initializers -* java-errorprone - * [#2862](https://github.com/pmd/pmd/issues/2862): \[java] New Rules: Avoid java.util.Date and Calendar classes ### ๐Ÿšจ API Changes -#### Experimental APIs that are now considered stable -* pmd-java - * {% jdoc !!java::lang.java.ast.ASTImportDeclaration#isModuleImport() %} is now stable API. - * {% jdoc !!java::lang.java.ast.ASTCompilationUnit#isCompact() %} is now stable API. Note, it was previously - called `isSimpleCompilationUnit`. - * {% jdoc java::lang.java.ast.ASTImplicitClassDeclaration %} is now stable API. - * {% jdoc !ac!java::lang.java.ast.JavaVisitorBase#visit(java::lang.java.ast.ASTImplicitClassDeclaration,P) %} is now - stable API. - ### โœจ Merged pull requests -* [#5733](https://github.com/pmd/pmd/pull/5733): \[css] Add new CPD language - [Thomas Prouvot](https://github.com/tprouvot) (@tprouvot) -* [#5859](https://github.com/pmd/pmd/pull/5859): Fix #5858: \[java] Fix false positive in FinalFieldCouldBeStatic for array initializers - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#5872](https://github.com/pmd/pmd/pull/5872): \[java] Add Support for Java 25 - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5876](https://github.com/pmd/pmd/pull/5876): chore: license header cleanup - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5883](https://github.com/pmd/pmd/pull/5883): Fix #2862: \[java] Add rules discouraging the use of java.util.Calendar and java.util.Date - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#5893](https://github.com/pmd/pmd/pull/5893): chore: Fix Mockito javaagent warning for Java 21+ - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5894](https://github.com/pmd/pmd/pull/5894): chore: Fix JUnit warning about invalid test factory - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5895](https://github.com/pmd/pmd/pull/5895): Fix #5597: Move dogfood profile to separate settings.xml - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5899](https://github.com/pmd/pmd/pull/5899): Fix #5344: \[java] Just log invalid annotation target type - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5909](https://github.com/pmd/pmd/pull/5909): \[ci] Create a pre-release for snapshot builds - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5911](https://github.com/pmd/pmd/pull/5911): \[doc] Reference CPD Capable Languages in CPD CLI docu - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5914](https://github.com/pmd/pmd/pull/5914): Fix #5892: \[java] ShortVariable FP for java 22 Unnamed Variable - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) -* [#5918](https://github.com/pmd/pmd/pull/5918): chore: \[cli] Improve symbolic link tests for Windows - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5920](https://github.com/pmd/pmd/pull/5920): chore: \[scala] Fix javadoc config - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ Dependency updates -* [#5857](https://github.com/pmd/pmd/pull/5857): Bump PMD from 7.14.0 to 7.15.0 -* [#5861](https://github.com/pmd/pmd/pull/5861): Bump scalameta.version from 4.13.7 to 4.13.8 -* [#5862](https://github.com/pmd/pmd/pull/5862): Bump com.puppycrawl.tools:checkstyle from 10.25.1 to 10.26.1 -* [#5863](https://github.com/pmd/pmd/pull/5863): Bump org.apache.maven.plugins:maven-pmd-plugin from 3.26.0 to 3.27.0 -* [#5864](https://github.com/pmd/pmd/pull/5864): Bump kotlin.version from 1.9.24 to 2.2.0 -* [#5865](https://github.com/pmd/pmd/pull/5865): Bump org.junit:junit-bom from 5.13.1 to 5.13.2 -* [#5866](https://github.com/pmd/pmd/pull/5866): Bump org.jsoup:jsoup from 1.20.1 to 1.21.1 -* [#5884](https://github.com/pmd/pmd/pull/5884): Bump org.junit:junit-bom from 5.13.2 to 5.13.3 -* [#5885](https://github.com/pmd/pmd/pull/5885): Bump org.apache.maven.plugins:maven-gpg-plugin from 3.2.7 to 3.2.8 -* [#5886](https://github.com/pmd/pmd/pull/5886): Bump org.checkerframework:checker-qual from 3.49.4 to 3.49.5 -* [#5889](https://github.com/pmd/pmd/pull/5889): Bump org.apache.maven.plugins:maven-enforcer-plugin from 3.5.0 to 3.6.0 -* [#5900](https://github.com/pmd/pmd/pull/5900): Bump org.apache.commons:commons-lang3 from 3.17.0 to 3.18.0 -* [#5901](https://github.com/pmd/pmd/pull/5901): Bump io.github.apex-dev-tools:apex-parser from 4.4.0 to 4.4.1 -* [#5902](https://github.com/pmd/pmd/pull/5902): Bump log4j.version from 2.25.0 to 2.25.1 -* [#5910](https://github.com/pmd/pmd/pull/5910): Bump maven from 3.9.10 to 3.9.11 -* [#5921](https://github.com/pmd/pmd/pull/5921): Bump build-tools from 32 to 33 -* [#5926](https://github.com/pmd/pmd/pull/5926): chore(deps): bump org.apache.maven.plugins:maven-enforcer-plugin from 3.6.0 to 3.6.1 -* [#5927](https://github.com/pmd/pmd/pull/5927): chore(deps): bump ostruct from 0.6.2 to 0.6.3 in /.ci/files in the all-gems group across 1 directory -* [#5928](https://github.com/pmd/pmd/pull/5928): chore(deps): bump marocchino/sticky-pull-request-comment from 2.9.3 to 2.9.4 in the all-actions group -* [#5929](https://github.com/pmd/pmd/pull/5929): chore(deps): Update gems ### ๐Ÿ“ˆ Stats -* 100 commits -* 21 closed tickets & PRs -* Days since last release: 27 {% endtocmaker %} + diff --git a/docs/pages/release_notes_old.md b/docs/pages/release_notes_old.md index 30b0af44dc0..462cb5c1c51 100644 --- a/docs/pages/release_notes_old.md +++ b/docs/pages/release_notes_old.md @@ -7,6 +7,132 @@ Previous versions of PMD can be downloaded here: [Releases - pmd/pmd (GitHub)](h +## 25-July-2025 - 7.16.0 + +The PMD team is pleased to announce PMD 7.16.0. + +This is a minor release. + +### Table Of Contents + +* [๐Ÿš€ New and noteworthy](#new-and-noteworthy) + * [๐Ÿš€ New: Java 25 Support](#new-java-25-support) + * [New: CPD support for CSS](#new-cpd-support-for-css) + * [โœจ New Rules](#new-rules) +* [๐Ÿ› Fixed Issues](#fixed-issues) +* [๐Ÿšจ API Changes](#api-changes) + * [Experimental APIs that are now considered stable](#experimental-apis-that-are-now-considered-stable) +* [โœจ Merged pull requests](#merged-pull-requests) +* [๐Ÿ“ฆ Dependency updates](#dependency-updates) +* [๐Ÿ“ˆ Stats](#stats) + +### ๐Ÿš€ New and noteworthy + +#### ๐Ÿš€ New: Java 25 Support +This release of PMD brings support for Java 25. + +There are the following new standard language features: +* [JEP 511: Module Import Declarations](https://openjdk.org/jeps/511) +* [JEP 512: Compact Source Files and Instance Main Methods](https://openjdk.org/jeps/512) +* [JEP 513: Flexible Constructor Bodies](https://openjdk.org/jeps/513) + +And one preview language feature: +* [JEP 507: Primitive Types in Patterns, instanceof, and switch (Third Preview)](https://openjdk.org/jeps/507) + +In order to analyze a project with PMD that uses these preview language features, +you'll need to enable it via the environment variable `PMD_JAVA_OPTS` and select the new language +version `25-preview`: + + export PMD_JAVA_OPTS=--enable-preview + pmd check --use-version java-25-preview ... + +Note: Support for Java 23 preview language features have been removed. The version "23-preview" +is no longer available. + +#### New: CPD support for CSS +CPD now supports CSS (Cascading Style Sheets), a language for describing the rendering of structured +documents (such as HTML) on screen, on paper etc. +It is shipped with the new module `pmd-css`. + +#### โœจ New Rules +* Two new rules have been added to Java's Error Prone category: [`ReplaceJavaUtilCalendar`](https://docs.pmd-code.org/pmd-doc-7.16.0/pmd_rules_java_errorprone.html#replacejavautilcalendar) + and [`ReplaceJavaUtilDate`](https://docs.pmd-code.org/pmd-doc-7.16.0/pmd_rules_java_errorprone.html#replacejavautildate). These rules help to migrate away from old Java APIs around + `java.util.Calendar` and `java.util.Date`. It is recommended to use the modern `java.time` API instead, which + is available since Java 8. + +### ๐Ÿ› Fixed Issues +* core + * [#4328](https://github.com/pmd/pmd/issues/4328): \[ci] Improve Github Actions Workflows + * [#5597](https://github.com/pmd/pmd/issues/5597): \[core] POM Incompatibility with Maven 4 +* java + * [#5344](https://github.com/pmd/pmd/issues/5344): \[java] IllegalArgumentException: Invalid type reference for method or ctor type annotation: 16 + * [#5478](https://github.com/pmd/pmd/issues/5478): \[java] Support Java 25 +* java-codestyle + * [#5892](https://github.com/pmd/pmd/issues/5892): \[java] ShortVariable false positive for java 22 unnamed variable `_` +* java-design + * [#5858](https://github.com/pmd/pmd/issues/5858): \[java] FinalFieldCouldBeStatic false positive for array initializers +* java-errorprone + * [#2862](https://github.com/pmd/pmd/issues/2862): \[java] New Rules: Avoid java.util.Date and Calendar classes + +### ๐Ÿšจ API Changes + +#### Experimental APIs that are now considered stable +* pmd-java + * ASTImportDeclaration#isModuleImport is now stable API. + * ASTCompilationUnit#isCompact is now stable API. Note, it was previously + called `isSimpleCompilationUnit`. + * ASTImplicitClassDeclaration is now stable API. + * JavaVisitorBase#visit(ASTImplicitClassDeclaration, P) is now + stable API. + +### โœจ Merged pull requests + +* [#5733](https://github.com/pmd/pmd/pull/5733): \[css] Add new CPD language - [Thomas Prouvot](https://github.com/tprouvot) (@tprouvot) +* [#5859](https://github.com/pmd/pmd/pull/5859): Fix #5858: \[java] Fix false positive in FinalFieldCouldBeStatic for array initializers - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#5872](https://github.com/pmd/pmd/pull/5872): \[java] Add Support for Java 25 - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5876](https://github.com/pmd/pmd/pull/5876): chore: license header cleanup - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5883](https://github.com/pmd/pmd/pull/5883): Fix #2862: \[java] Add rules discouraging the use of java.util.Calendar and java.util.Date - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5893](https://github.com/pmd/pmd/pull/5893): chore: Fix Mockito javaagent warning for Java 21+ - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5894](https://github.com/pmd/pmd/pull/5894): chore: Fix JUnit warning about invalid test factory - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5895](https://github.com/pmd/pmd/pull/5895): Fix #5597: Move dogfood profile to separate settings.xml - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5899](https://github.com/pmd/pmd/pull/5899): Fix #5344: \[java] Just log invalid annotation target type - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5909](https://github.com/pmd/pmd/pull/5909): \[ci] Create a pre-release for snapshot builds - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5911](https://github.com/pmd/pmd/pull/5911): \[doc] Reference CPD Capable Languages in CPD CLI docu - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5914](https://github.com/pmd/pmd/pull/5914): Fix #5892: \[java] ShortVariable FP for java 22 Unnamed Variable - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#5918](https://github.com/pmd/pmd/pull/5918): chore: \[cli] Improve symbolic link tests for Windows - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5920](https://github.com/pmd/pmd/pull/5920): chore: \[scala] Fix javadoc config - [Andreas Dangel](https://github.com/adangel) (@adangel) + +### ๐Ÿ“ฆ Dependency updates + +* [#5857](https://github.com/pmd/pmd/pull/5857): Bump PMD from 7.14.0 to 7.15.0 +* [#5861](https://github.com/pmd/pmd/pull/5861): Bump scalameta.version from 4.13.7 to 4.13.8 +* [#5862](https://github.com/pmd/pmd/pull/5862): Bump com.puppycrawl.tools:checkstyle from 10.25.1 to 10.26.1 +* [#5863](https://github.com/pmd/pmd/pull/5863): Bump org.apache.maven.plugins:maven-pmd-plugin from 3.26.0 to 3.27.0 +* [#5864](https://github.com/pmd/pmd/pull/5864): Bump kotlin.version from 1.9.24 to 2.2.0 +* [#5865](https://github.com/pmd/pmd/pull/5865): Bump org.junit:junit-bom from 5.13.1 to 5.13.2 +* [#5866](https://github.com/pmd/pmd/pull/5866): Bump org.jsoup:jsoup from 1.20.1 to 1.21.1 +* [#5884](https://github.com/pmd/pmd/pull/5884): Bump org.junit:junit-bom from 5.13.2 to 5.13.3 +* [#5885](https://github.com/pmd/pmd/pull/5885): Bump org.apache.maven.plugins:maven-gpg-plugin from 3.2.7 to 3.2.8 +* [#5886](https://github.com/pmd/pmd/pull/5886): Bump org.checkerframework:checker-qual from 3.49.4 to 3.49.5 +* [#5889](https://github.com/pmd/pmd/pull/5889): Bump org.apache.maven.plugins:maven-enforcer-plugin from 3.5.0 to 3.6.0 +* [#5900](https://github.com/pmd/pmd/pull/5900): Bump org.apache.commons:commons-lang3 from 3.17.0 to 3.18.0 +* [#5901](https://github.com/pmd/pmd/pull/5901): Bump io.github.apex-dev-tools:apex-parser from 4.4.0 to 4.4.1 +* [#5902](https://github.com/pmd/pmd/pull/5902): Bump log4j.version from 2.25.0 to 2.25.1 +* [#5910](https://github.com/pmd/pmd/pull/5910): Bump maven from 3.9.10 to 3.9.11 +* [#5921](https://github.com/pmd/pmd/pull/5921): Bump build-tools from 32 to 33 +* [#5926](https://github.com/pmd/pmd/pull/5926): chore(deps): bump org.apache.maven.plugins:maven-enforcer-plugin from 3.6.0 to 3.6.1 +* [#5927](https://github.com/pmd/pmd/pull/5927): chore(deps): bump ostruct from 0.6.2 to 0.6.3 in /.ci/files in the all-gems group across 1 directory +* [#5928](https://github.com/pmd/pmd/pull/5928): chore(deps): bump marocchino/sticky-pull-request-comment from 2.9.3 to 2.9.4 in the all-actions group +* [#5929](https://github.com/pmd/pmd/pull/5929): chore(deps): Update gems + +### ๐Ÿ“ˆ Stats + +* 100 commits +* 21 closed tickets & PRs +* Days since last release: 27 + + + ## 27-June-2025 - 7.15.0 The PMD team is pleased to announce PMD 7.15.0. diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index e7e050a961a..f0cc4b70221 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.16.0 + 7.17.0-SNAPSHOT 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 502b5529d5e..096e64225e2 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index 53ce32e10ae..4a4fd8e0412 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index 74244a4af21..2a0c6a6c03c 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index 843c40ed38d..3f37627e79c 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index a170041cd1c..1720cf00cf8 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index 40d72be2f0a..2227a63bf15 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-css/pom.xml b/pmd-css/pom.xml index 0311abac40b..222cb3c91fe 100644 --- a/pmd-css/pom.xml +++ b/pmd-css/pom.xml @@ -9,7 +9,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index b3bfdc4c056..4e66fef3d68 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index d67a00a056b..c57d86cb9f2 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index 87dc7625fa0..ba8bddddc32 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index 693c4698532..739a49aeb15 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index f9ab450b022..141a3d96c99 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index 017698d7091..94021c721f0 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index 01c107a189c..ca0478806cd 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index b47510ba4d8..842b689093c 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index a5a326cdf3a..8888d826f6c 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index 6c29c246f6c..e5d58ce6c0f 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index 2eca0bb74c6..3fc79d1543c 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index 112198e777f..c51620f863a 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index 9f263459e0d..233531fca5e 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index 082c805f68e..dd1890a177a 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index 400609afe1c..b7dc600d7d6 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index abcc09b0e6a..55d01fa6ebc 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index a7483f22a66..86126c8a68c 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index 73149f218f8..32e1524fb37 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index f939a34f901..7d1381c9633 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index b433fdfa1d3..09660f11983 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index 4ef2665e8a8..052b8250dfe 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index df824b99ab6..884ab0872be 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index 00196ce68cc..1b6c5193225 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index e37b8e21dec..7f9355b6e35 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index fda9a9b5413..902f5bbf849 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index 86bd3cb4d70..4f4ea16e798 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index e03f635ab8e..7ae9b846cab 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.16.0 + 7.17.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index c5c16de1e85..fdcee740f4e 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.16.0 + 7.17.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index 1440a2449e4..9e92ecbd6a6 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index 024c4586faa..a6cf52a5a2c 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index 4bc602a2528..9f44f04163c 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index 38e3da4afb2..f2aad36c477 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index f99230c5e13..d596407f894 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index 13943e3c66f..d91e98a2874 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index 936003fdd6f..7df66cd92d4 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index 3eb21ba3a37..e256ef5d3dd 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.16.0 + 7.17.0-SNAPSHOT pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - pmd_releases/7.16.0 + HEAD PMD From aea3815eed9250381e7857e88c22d387d12b1637 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Fri, 25 Jul 2025 17:14:35 +0200 Subject: [PATCH 1179/1962] [docs] Update suppression docs to reflect PMD 7 changes --- docs/pages/pmd/userdocs/suppressing_warnings.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/pages/pmd/userdocs/suppressing_warnings.md b/docs/pages/pmd/userdocs/suppressing_warnings.md index d281e7d864b..ec38e582ca0 100644 --- a/docs/pages/pmd/userdocs/suppressing_warnings.md +++ b/docs/pages/pmd/userdocs/suppressing_warnings.md @@ -169,7 +169,7 @@ For example, to suppress reporting specifically named parameters which are unused: ```xml - + @@ -198,9 +198,9 @@ The XPath version used by those queries is XPath 3.1 since PMD 7. Before then XP For example, to suppress reporting specifically "String" parameters which are unused: ```xml - + - + ``` From c619ae3cde29baa26a56ffba3b7c99ecbd467ad3 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Fri, 25 Jul 2025 17:17:39 +0200 Subject: [PATCH 1180/1962] Update ruleset name --- docs/pages/pmd/userdocs/suppressing_warnings.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/pages/pmd/userdocs/suppressing_warnings.md b/docs/pages/pmd/userdocs/suppressing_warnings.md index ec38e582ca0..9da06db19a5 100644 --- a/docs/pages/pmd/userdocs/suppressing_warnings.md +++ b/docs/pages/pmd/userdocs/suppressing_warnings.md @@ -117,7 +117,7 @@ public class Foo { } } -$ pmd check -d Foo.java -f text -R java-unusedcode --suppress-marker TURN_OFF_WARNINGS +$ pmd check -d Foo.java -f text -R java-bestpractices --suppress-marker TURN_OFF_WARNINGS No problems found! UnusedLocalVariable rule violation suppressed by //NOPMD in /home/tom/pmd/pmd/bin/Foo.java ``` @@ -169,7 +169,7 @@ For example, to suppress reporting specifically named parameters which are unused: ```xml - + @@ -198,7 +198,7 @@ The XPath version used by those queries is XPath 3.1 since PMD 7. Before then XP For example, to suppress reporting specifically "String" parameters which are unused: ```xml - + From 169d3367ba1e0df5b7bbb15b29fc7c5cae60181b Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Fri, 25 Jul 2025 19:25:04 +0200 Subject: [PATCH 1181/1962] Fix #5198: [java] CheckResultSet FP when local variable is checked --- .../bestpractices/CheckResultSetRule.java | 20 +++++++--- .../rule/bestpractices/xml/CheckResultSet.xml | 40 +++++++++++++++++++ 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java index c66633ee1fc..9672f8d283a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java @@ -7,12 +7,11 @@ import static net.sourceforge.pmd.util.CollectionUtil.setOf; import java.sql.ResultSet; +import java.util.List; import java.util.Set; -import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; -import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; -import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement; -import net.sourceforge.pmd.lang.java.ast.ASTWhileStatement; +import net.sourceforge.pmd.lang.java.ast.*; +import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule; import net.sourceforge.pmd.lang.java.types.TypeTestUtil; @@ -41,7 +40,7 @@ public Object visit(ASTIfStatement node, Object data) { @Override public Object visit(ASTMethodCall node, Object data) { - if (isResultSetMethod(node)) { + if (isResultSetMethod(node) && !isCheckedIndirectly(node)) { asCtx(data).addViolation(node); } return super.visit(node, data); @@ -51,4 +50,15 @@ private boolean isResultSetMethod(ASTMethodCall node) { return METHODS.contains(node.getMethodName()) && TypeTestUtil.isDeclaredInClass(ResultSet.class, node.getMethodType()); } + + private boolean isCheckedIndirectly(ASTMethodCall node) { + if (!(node.getParent() instanceof ASTVariableDeclarator)) { + return false; + } + + final ASTVariableDeclarator declarator = (ASTVariableDeclarator) node.getParent(); + final List usages = declarator.getVarId().getLocalUsages(); + //check that the result is used and its first usage is not overwriting the result + return !usages.isEmpty() && usages.get(0).getAccessType() == ASTAssignableExpr.AccessType.READ; + } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml index c5d1f946408..95174d658e7 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml @@ -323,4 +323,44 @@ public class Foo { } ]]> + + + #5198: Result is saved in variable before being checked + 0 + + + + + + Result is overwritten before being checked + 1 + 6 + + + From 60323da3e9ae248158618cf80efc4f15014ad2ac Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Fri, 25 Jul 2025 19:50:12 +0200 Subject: [PATCH 1182/1962] #5198: CheckResultSetRule: Fix imports --- .../lang/java/rule/bestpractices/CheckResultSetRule.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java index 9672f8d283a..6cd09c518f3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java @@ -10,8 +10,12 @@ import java.util.List; import java.util.Set; -import net.sourceforge.pmd.lang.java.ast.*; -import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; +import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr; +import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; +import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; +import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement; +import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator; +import net.sourceforge.pmd.lang.java.ast.ASTWhileStatement; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule; import net.sourceforge.pmd.lang.java.types.TypeTestUtil; From 21e3c82e34e478245f3597863f61f0d343b1bff4 Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Fri, 25 Jul 2025 19:54:26 +0200 Subject: [PATCH 1183/1962] #5198: CheckResultSetRule: Add testcase with while loop --- .../rule/bestpractices/xml/CheckResultSet.xml | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml index 95174d658e7..47bc9795469 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml @@ -325,7 +325,7 @@ public class Foo { - #5198: Result is saved in variable before being checked + #5198: Result is saved in variable before being checked in if statement 0 + + #5198: Result is saved in variable before being checked in while loop + 0 + + Result is overwritten before being checked From 94c948005ef7522f1d8aadfe79ca6ec6ac927399 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Mon, 28 Jul 2025 00:32:17 +0200 Subject: [PATCH 1184/1962] Revert changes to InvocationMatcher --- .../errorprone/UselessPureMethodCallRule.java | 3 - .../lang/java/rule/internal/JavaRuleUtil.java | 6 +- .../lang/java/types/InvocationMatcher.java | 34 +- .../errorprone/xml/UselessPureMethodCall.xml | 330 +++++++++++++++++- 4 files changed, 342 insertions(+), 31 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessPureMethodCallRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessPureMethodCallRule.java index 8db802aa3dd..ef5148e8799 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessPureMethodCallRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessPureMethodCallRule.java @@ -14,9 +14,6 @@ */ public class UselessPureMethodCallRule extends AbstractJavaRulechainRule { - /** - * Specify the node types to visit as parameters. - */ public UselessPureMethodCallRule() { super(ASTExpressionStatement.class); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/JavaRuleUtil.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/JavaRuleUtil.java index 1128419228f..8886585a745 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/JavaRuleUtil.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/JavaRuleUtil.java @@ -69,7 +69,7 @@ public final class JavaRuleUtil { "java.lang.Comparable#compareTo(_)", "java.math.BigDecimal#_(_*)", "java.math.BigInteger#_(_*)", - "java.time.Temporal#_(_*)", + "java.time.temporal.Temporal#_(_*)", "java.time.Duration#_(_*)", "java.time.Period#_(_*)" ); @@ -392,7 +392,6 @@ private static boolean isNonLocalLhs(ASTExpression lhs) { /** * Whether the invocation has no side-effects. Very conservative. - * @param call method call */ private static boolean isPure(ASTMethodCall call) { return isGetterCall(call) || KNOWN_PURE_METHODS.anyMatch(call); @@ -402,11 +401,10 @@ private static boolean isPure(ASTMethodCall call) { * Whether the invocation has no side effects. Even more conservative than {@code isPure}. * Only checks methods in java.* packages because frameworks may define getter-like methods * with side effects (such as isEqualTo matcher in AssertJ). - * @param call method call */ public static boolean isKnownPure(ASTMethodCall call) { return isGetterCall(call) - && InvocationMatcher.matchQualifier(call, (type, exact) -> hasPureGetters(type)) + && hasPureGetters(call.getMethodType().getDeclaringType()) || KNOWN_PURE_METHODS.anyMatch(call) && !call.getMethodType().getReturnType().isVoid(); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/InvocationMatcher.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/InvocationMatcher.java index 2f5d1488856..2c2604f99a1 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/InvocationMatcher.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/InvocationMatcher.java @@ -11,7 +11,6 @@ import java.util.List; import org.apache.commons.lang3.StringUtils; -import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import net.sourceforge.pmd.lang.java.ast.ASTConstructorCall; @@ -99,17 +98,11 @@ public boolean matchesCall(@Nullable InvocationNode node) { return false; } OverloadSelectionResult info = node.getOverloadSelectionInfo(); - return !info.isFailed() && matchQualifier(node, qualifierMatcher) + return !info.isFailed() && matchQualifier(node) && argsMatchOverload(info.getMethodType()); } - /** - * Check if method was invoked on a type that satisfies given condition. - * @param node invocation - * @param qualifierMatcher type matcher - * @return whether declaring type matches - */ - public static boolean matchQualifier(InvocationNode node, TypeMatcher qualifierMatcher) { + private boolean matchQualifier(InvocationNode node) { if (qualifierMatcher == TypeMatcher.ANY) { return true; } @@ -276,29 +269,24 @@ private static int parseType(String source, int i) { } private static TypeMatcher newMatcher(String name) { - return "_".equals(name) ? TypeMatcher.ANY : new ClassTypeMatcher(name); + return "_".equals(name) ? TypeMatcher.ANY : new TypeMatcher(name); } - public interface TypeMatcher { + private static final class TypeMatcher { /** Matches any type. */ - TypeMatcher ANY = (type, exact) -> true; - - boolean matches(JTypeMirror type, boolean exact); - } - - private static final class ClassTypeMatcher implements TypeMatcher { + public static final TypeMatcher ANY = new TypeMatcher(null); - final @NonNull String name; + final @Nullable String name; - private ClassTypeMatcher(@NonNull String name) { + private TypeMatcher(@Nullable String name) { this.name = name; } - @Override - public boolean matches(JTypeMirror type, boolean exact) { - return exact ? TypeTestUtil.isExactlyAOrAnon(name, type) == OptionalBool.YES - : TypeTestUtil.isA(name, type); + boolean matches(JTypeMirror type, boolean exact) { + return name == null + || (exact ? TypeTestUtil.isExactlyAOrAnon(name, type) == OptionalBool.YES + : TypeTestUtil.isA(name, type)); } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessPureMethodCall.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessPureMethodCall.xml index 9ae1c3704de..dfd353c69d0 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessPureMethodCall.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessPureMethodCall.xml @@ -38,7 +38,7 @@ public class Foo { ex.getMessage(); ex.getLocalizedMessage(); ex.getCause(); - ex.getStacktrace(); + ex.getStackTrace(); if ("" != null) { throw ex.getCause(); } @@ -68,4 +68,332 @@ public class Foo { } ]]> + + useless operation on BigDecimal + 1 + + + + + useless operation on BigInteger + 1 + + + + + using the result, so OK + 0 + + + + + using the result in a method call, so OK + 0 + + + + + BigInteger obtained from compound method call + 0 + + + + + Using generics on List, OK + 0 + getSolution() { + List result = new ArrayList(); + for (int i = 0; i < size(); i++) { + result.add(entry(size(),i).negate()); + result.add(this.equations[i].check(solution)); + } + } +} + ]]> + + + + BigInteger in conditional statement + 0 + + + + + 1702782, Immutable used in comparison + 0 + + + + + String calls in expressions + 0 + 0) { + } + } +} + ]]> + + + + String::getChars is allowed + 0 + + + + + BigInteger calls in expression + 0 + + + + + 2645268, ClassCastException using Annotation on Local Field + 1 + + + + + [java] UselessOperationOnImmutable various false negatives with String #4513 + 3 + 3,6,9 + + + + + [java] UselessOperationOnImmutable should detect java.time types #5244 + 44 + 7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,61,66,71,76 + + + + + [java] UselessOperationOnImmutable should detect java.time types #5244 - Duration, Period + 2 + 5,10 + + + + + False positive for package private method calls in openjdk + 0 + + From 06e5cdaa0f9b46c35e5a4afc0b0ae61efadd056e Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Mon, 28 Jul 2025 00:41:08 +0200 Subject: [PATCH 1185/1962] Mark rules as deprecated --- pmd-java/src/main/resources/category/java/errorprone.xml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 65fe66af783..7f5a239550a 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -577,8 +577,10 @@ public void checkRequests() { language="java" message="Avoid statements in a catch block that invoke accessors on the exception without using the information" class="net.sourceforge.pmd.lang.rule.xpath.XPathRule" - externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidlosingexceptioninformation"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidlosingexceptioninformation" + deprecated="true"> +This rule is *deprecated* in favor of {% rule java/errorprone/UselessPureMethodCall %}. Statements in a catch block that invoke accessors on the exception without using the information only add to code size. Either remove the invocation, or use the return result. @@ -3132,8 +3134,11 @@ public boolean test(String s) { since="3.5" message="The result of an operation on an immutable object is ignored" class="net.sourceforge.pmd.lang.java.rule.errorprone.UselessOperationOnImmutableRule" - externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#uselessoperationonimmutable"> + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#uselessoperationonimmutable" + deprecated="true"> +This rule is *deprecated* in favor of {% rule java/errorprone/UselessPureMethodCall %}. + An operation on an immutable object will not change the object itself since the result of the operation is a new object. Therefore, ignoring the result of such an operation is likely a mistake. The operation can probably be removed. From d20af3ea39f45351c8b5b94a2b9930fd039cb6b5 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 31 Jul 2025 09:39:37 +0200 Subject: [PATCH 1186/1962] Bump PMD from 7.15.0 to 7.16.0 (#5936) --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index e256ef5d3dd..c678ec9315f 100644 --- a/pom.xml +++ b/pom.xml @@ -596,22 +596,22 @@ net.sourceforge.pmd pmd-core - 7.15.0 + 7.16.0 net.sourceforge.pmd pmd-java - 7.15.0 + 7.16.0 net.sourceforge.pmd pmd-jsp - 7.15.0 + 7.16.0 net.sourceforge.pmd pmd-javascript - 7.15.0 + 7.16.0 From e06909cfa27b94f75e24bb98bb4cac65f8f5d4f4 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 31 Jul 2025 09:40:52 +0200 Subject: [PATCH 1187/1962] Bump pmdtester from 1.5.5 to 1.6.0 (#5937) --- .ci/files/Gemfile.lock | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.ci/files/Gemfile.lock b/.ci/files/Gemfile.lock index 64b4474638d..bc84f0a26f9 100644 --- a/.ci/files/Gemfile.lock +++ b/.ci/files/Gemfile.lock @@ -18,13 +18,16 @@ GEM nokogiri (1.18.9-x86_64-linux-gnu) racc (~> 1.4) ostruct (0.6.3) - pmdtester (1.5.5) + pmdtester (1.6.0) + base64 (~> 0.3) + bigdecimal (~> 3.2) differ (~> 0.1) - liquid (~> 5.4) + liquid (~> 5.8) + logger (~> 1.7) logger-colors (~> 1.0) - nokogiri (~> 1.13) - rufus-scheduler (~> 3.8) - slop (~> 4.9) + nokogiri (~> 1.18) + rufus-scheduler (~> 3.9) + slop (~> 4.10) raabro (1.4.0) racc (1.8.1) rufus-scheduler (3.9.2) @@ -44,4 +47,4 @@ DEPENDENCIES pmdtester BUNDLED WITH - 2.6.6 + 2.6.9 From daf773bb1a98ceaf3c23a9b347c05157efd1229a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 31 Jul 2025 09:42:10 +0200 Subject: [PATCH 1188/1962] chore(deps): bump org.apache.commons:commons-text from 1.13.1 to 1.14.0 (#5941) Bumps [org.apache.commons:commons-text](https://github.com/apache/commons-text) from 1.13.1 to 1.14.0. - [Changelog](https://github.com/apache/commons-text/blob/master/RELEASE-NOTES.txt) - [Commits](https://github.com/apache/commons-text/compare/rel/commons-text-1.13.1...rel/commons-text-1.14.0) --- updated-dependencies: - dependency-name: org.apache.commons:commons-text dependency-version: 1.14.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c678ec9315f..f9db2cf6e2c 100644 --- a/pom.xml +++ b/pom.xml @@ -907,7 +907,7 @@ org.apache.commons commons-text - 1.13.1 + 1.14.0 org.slf4j From 437825d68d3a11caaf328e18d848f7fdc2fdb2f8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 31 Jul 2025 09:45:44 +0200 Subject: [PATCH 1189/1962] chore(deps): bump io.github.apex-dev-tools:apex-ls_2.13 from 5.9.0 to 5.10.0 (#5944) chore(deps): bump io.github.apex-dev-tools:apex-ls_2.13 Bumps [io.github.apex-dev-tools:apex-ls_2.13](https://github.com/apex-dev-tools/apex-ls) from 5.9.0 to 5.10.0. - [Release notes](https://github.com/apex-dev-tools/apex-ls/releases) - [Commits](https://github.com/apex-dev-tools/apex-ls/compare/v5.9.0...v5.10.0) --- updated-dependencies: - dependency-name: io.github.apex-dev-tools:apex-ls_2.13 dependency-version: 5.10.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-apex/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 096e64225e2..8a9639e59ab 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -106,7 +106,7 @@ io.github.apex-dev-tools apex-ls_2.13 - 5.9.0 + 5.10.0 From 71ed85adc2bee841181015bd0a17a2117ae54f44 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 31 Jul 2025 09:47:23 +0200 Subject: [PATCH 1190/1962] chore(deps): bump org.apache.groovy:groovy from 4.0.27 to 4.0.28 (#5946) Bumps [org.apache.groovy:groovy](https://github.com/apache/groovy) from 4.0.27 to 4.0.28. - [Commits](https://github.com/apache/groovy/commits) --- updated-dependencies: - dependency-name: org.apache.groovy:groovy dependency-version: 4.0.28 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f9db2cf6e2c..5057bd7db34 100644 --- a/pom.xml +++ b/pom.xml @@ -927,7 +927,7 @@ org.apache.groovy groovy - 4.0.27 + 4.0.28 com.google.code.gson From 3abda85425a4d8bdde1c86a46119d042d7b513f7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 31 Jul 2025 09:47:59 +0200 Subject: [PATCH 1191/1962] chore(deps): bump org.junit:junit-bom from 5.13.3 to 5.13.4 (#5945) * chore(deps): bump org.junit:junit-bom from 5.13.3 to 5.13.4 Bumps [org.junit:junit-bom](https://github.com/junit-team/junit-framework) from 5.13.3 to 5.13.4. - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r5.13.3...r5.13.4) --- updated-dependencies: - dependency-name: org.junit:junit-bom dependency-version: 5.13.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Update pom.xml --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andreas Dangel --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 5057bd7db34..a5c3ae583c5 100644 --- a/pom.xml +++ b/pom.xml @@ -86,8 +86,8 @@ ${maven.compiler.test.target} 2.2.0 5.9.1 - 5.13.3 - 1.13.3 + 5.13.4 + 1.13.4 2.0.0 5.0 From eb17dcfd1f5501dc7226e333446cd7b8a4f10900 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 31 Jul 2025 10:15:37 +0200 Subject: [PATCH 1192/1962] Do not delete pmd-doc-${PMD_VERSION} --- .github/workflows/publish-snapshot.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index aae6c27faf8..d5f04adf388 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -472,9 +472,7 @@ jobs: - name: Create docs zip env: PMD_VERSION: ${{ needs.check-version.outputs.PMD_VERSION }} - run: | - zip -qr "dist/pmd-dist-${PMD_VERSION}-doc.zip" "pmd-doc-${PMD_VERSION}/" - rm -rf "pmd-doc-${PMD_VERSION}/" + run: zip -qr "dist/pmd-dist-${PMD_VERSION}-doc.zip" "pmd-doc-${PMD_VERSION}/" - name: Setup GPG env: PMD_CI_GPG_PRIVATE_KEY: ${{ secrets.PMD_CI_GPG_PRIVATE_KEY }} From 59cc11494aa5155aa01c203b0b5ea373e5800fb4 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 31 Jul 2025 10:15:53 +0200 Subject: [PATCH 1193/1962] Update release notes (#5932) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 0c9c0dd3524..b74b27cf27f 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -30,6 +30,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ Merged pull requests +* [#5932](https://github.com/pmd/pmd/pull/5932): \[ci] Reuse GitHub Pre-Releases - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ Dependency updates From cd0c55f4af71a77e61b9475dffb3872bee9a3110 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 31 Jul 2025 10:42:21 +0200 Subject: [PATCH 1194/1962] Update pmd-java/src/main/resources/category/java/codestyle.xml --- pmd-java/src/main/resources/category/java/codestyle.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml index 2c05de955d0..d83a616c288 100644 --- a/pmd-java/src/main/resources/category/java/codestyle.xml +++ b/pmd-java/src/main/resources/category/java/codestyle.xml @@ -708,7 +708,7 @@ public class Foo { Names for references to generic values should be limited to a single uppercase letter. -**Deprecated:** This rule has been replaced by {% rule TypeParameterNamingConventions %}, which provides more comprehensive and configurable naming conventions for type parameters. +**Deprecated:** This rule is deprecated since PMD 7.17.0 and will be removed with PMD 8.0.0. This rule has been replaced by {% rule TypeParameterNamingConventions %}, which provides more comprehensive and configurable naming conventions for type parameters. 4 From e9b769250fbc614a176c9023030033b097c9fcb9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 31 Jul 2025 11:22:56 +0200 Subject: [PATCH 1195/1962] [doc] Update release notes (#972, #5922) --- docs/pages/release_notes.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index b74b27cf27f..d5e6a6999c7 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -24,12 +24,26 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy +#### โœจ New Rules +* The new java rule {% rule java/codestyle/TypeParameterNamingConventions %} replaces the now deprecated rule + GenericsNaming. The new rule is configurable and checks for naming conventions of type parameters in + generic types and methods. It can be configured via a regular expression. + By default, this rule uses the standard Java naming convention (single uppercase letter). + The rule is referenced in the quickstart.xml ruleset for Java. + +#### Deprecated Rules +* The java rule {% rule java/codestyle/GenericsNaming %} has been deprecated for removal in favor + of the new rule {% rule java/codestyle/TypeParameterNamingConventions %}. + ### ๐Ÿ› Fixed Issues +* java-codestyle + * [#972](https://github.com/pmd/pmd/issues/972): \[java] Improve naming conventions rules ### ๐Ÿšจ API Changes ### โœจ Merged pull requests +* [#5922](https://github.com/pmd/pmd/pull/5922): Fix #972: \[java] Add a new rule TypeParameterNamingConventions - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5932](https://github.com/pmd/pmd/pull/5932): \[ci] Reuse GitHub Pre-Releases - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ Dependency updates From d0087b6d0d37fe13003930e225384d05a176e75a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 31 Jul 2025 11:43:35 +0200 Subject: [PATCH 1196/1962] [ci] Add workflows permission for publish-snapshot When creating a tag and the referenced commits change a workflow file, then additionally the workflows permission is required. Otherwise GH API responds with "Resource not accessible by integration (HTTP 403)". Refs #5932 --- .github/workflows/publish-snapshot.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index d5f04adf388..48e04f6d177 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -503,6 +503,7 @@ jobs: owner: pmd repositories: pmd permission-contents: write # create a release, remove/create a tag + permission-workflows: write # needed for creating a tag, in case some workflow files have been modified - name: Prepare tag for GitHub Pre-Release id: tags env: From 7e116b148be2cf9d1481c94552fc0c37b514b61e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Thu, 31 Jul 2025 17:11:08 +0200 Subject: [PATCH 1197/1962] Update UseUtilityClass message --- pmd-java/src/main/resources/category/java/design.xml | 2 +- .../pmd/lang/java/rule/design/xml/UseUtilityClass.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/design.xml b/pmd-java/src/main/resources/category/java/design.xml index 2065e163bfe..a86f59d5e6b 100644 --- a/pmd-java/src/main/resources/category/java/design.xml +++ b/pmd-java/src/main/resources/category/java/design.xml @@ -1452,7 +1452,7 @@ public class MyClass { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/UseUtilityClass.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/UseUtilityClass.xml index 32af58ff8f7..2f13b9c84c7 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/UseUtilityClass.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/UseUtilityClass.xml @@ -8,7 +8,7 @@ should be utility class since all static, public constructor 1 - This utility class has a non-private constructor + All methods are static. Consider adding a private no-args constructor to prevent instantiation. Date: Thu, 31 Jul 2025 17:43:32 +0200 Subject: [PATCH 1198/1962] [apex] Move new rule AnnotationsNamingConventions to codestyle - Renamed from AnnotationsShouldBePascalCase - Simplified annotation context (Field vs. FieldDeclaration) - Improve violation message - Add to quickstart ruleset --- .../AnnotationsNamingConventionsRule.java | 53 +++++++++++++++ .../AnnotationsShouldBePascalCaseRule.java | 67 ------------------- .../resources/category/apex/codestyle.xml | 37 ++++++++++ .../main/resources/category/apex/design.xml | 37 ---------- .../resources/rulesets/apex/quickstart.xml | 3 + .../AnnotationsNamingConventionsTest.java} | 6 +- .../xml/AnnotationsNamingConventions.xml} | 15 +++++ 7 files changed, 111 insertions(+), 107 deletions(-) create mode 100644 pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/AnnotationsNamingConventionsRule.java delete mode 100644 pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AnnotationsShouldBePascalCaseRule.java rename pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/{design/AnnotationsShouldBePascalCaseTest.java => codestyle/AnnotationsNamingConventionsTest.java} (58%) rename pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/{design/xml/AnnotationsShouldBePascalCase.xml => codestyle/xml/AnnotationsNamingConventions.xml} (96%) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/AnnotationsNamingConventionsRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/AnnotationsNamingConventionsRule.java new file mode 100644 index 00000000000..f83d8c4fdd1 --- /dev/null +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/AnnotationsNamingConventionsRule.java @@ -0,0 +1,53 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.apex.rule.codestyle; + +import org.checkerframework.checker.nullness.qual.NonNull; + +import net.sourceforge.pmd.lang.apex.ast.ASTAnnotation; +import net.sourceforge.pmd.lang.apex.ast.ASTField; +import net.sourceforge.pmd.lang.apex.ast.ASTFieldDeclarationStatements; +import net.sourceforge.pmd.lang.apex.rule.AbstractApexRule; +import net.sourceforge.pmd.lang.rule.RuleTargetSelector; + +/** + * Rule that checks if Apex annotations are written in PascalCase. This rule + * ensures that all annotations follow the standard naming convention where each + * word in the annotation name starts with a capital letter. + */ +public class AnnotationsNamingConventionsRule extends AbstractApexRule { + + @Override + public Object visit(ASTAnnotation annotation, Object data) { + if (annotation.isResolved() && isNotField(annotation) && !isPascalCase(annotation)) { + asCtx(data).addViolation(annotation, annotation.getRawName(), annotation.getName()); + } + return data; + } + + @Override + protected @NonNull RuleTargetSelector buildTargetSelector() { + return RuleTargetSelector.forTypes(ASTAnnotation.class); + } + + /** + * Fields appear twice in the AST: once inside {@link ASTFieldDeclarationStatements} nodes + * which might contain one or more {@link ASTFieldDeclarationStatements}. This structure resembles the + * original source code. Additionally, all fields are also available as {@link ASTField} nodes, + * but then the annotations are duplicated there. So, we only use the + * original {@link ASTFieldDeclarationStatements} to avoid reporting the same annotation multiple times. + */ + private boolean isNotField(ASTAnnotation annotation) { + return !(annotation.getParent().getParent() instanceof ASTField); + } + + /** + * Checks if the annotation name matches its raw name (indicating + * PascalCase). + */ + private boolean isPascalCase(ASTAnnotation annotation) { + return annotation.getName().equals(annotation.getRawName()); + } +} diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AnnotationsShouldBePascalCaseRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AnnotationsShouldBePascalCaseRule.java deleted file mode 100644 index 58a41615425..00000000000 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AnnotationsShouldBePascalCaseRule.java +++ /dev/null @@ -1,67 +0,0 @@ -/** - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.apex.rule.design; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -import org.checkerframework.checker.nullness.qual.NonNull; - -import net.sourceforge.pmd.lang.apex.ast.ASTAnnotation; -import net.sourceforge.pmd.lang.apex.ast.ASTField; -import net.sourceforge.pmd.lang.apex.ast.ASTMethod; -import net.sourceforge.pmd.lang.apex.ast.ASTModifierNode; -import net.sourceforge.pmd.lang.apex.ast.ASTUserClass; -import net.sourceforge.pmd.lang.apex.ast.ASTUserInterface; -import net.sourceforge.pmd.lang.apex.ast.ApexNode; -import net.sourceforge.pmd.lang.apex.rule.AbstractApexRule; -import net.sourceforge.pmd.lang.rule.RuleTargetSelector; - -/** - * Rule that checks if Apex annotations are written in PascalCase. This rule - * ensures that all annotations follow the standard naming convention where each - * word in the annotation name starts with a capital letter. - */ -public class AnnotationsShouldBePascalCaseRule extends AbstractApexRule { - - private static final Set>> VALID_PARENT_TYPES = Collections.unmodifiableSet( - new HashSet<>(Arrays.asList(ASTUserClass.class, ASTUserInterface.class, ASTMethod.class, ASTField.class))); - - @Override - public Object visit(ASTAnnotation annotation, Object data) { - if (annotation.isResolved() && isValidAnnotationContext(annotation) && !isPascalCase(annotation)) { - asCtx(data).addViolation(annotation); - } - return data; - } - - @Override - protected @NonNull RuleTargetSelector buildTargetSelector() { - return RuleTargetSelector.forTypes(ASTAnnotation.class); - } - - /** - * Checks if the annotation is in a valid context (direct child of a - * modifier node that is a direct child of a valid parent type). - */ - private boolean isValidAnnotationContext(ASTAnnotation annotation) { - if (!(annotation.getParent() instanceof ASTModifierNode)) { - return false; - } - ASTModifierNode modifierNode = (ASTModifierNode) annotation.getParent(); - return VALID_PARENT_TYPES.stream().anyMatch(type -> type.isInstance(modifierNode.getParent())); - } - - /** - * Checks if the annotation name matches its raw name (indicating - * PascalCase). - */ - private boolean isPascalCase(ASTAnnotation annotation) { - return annotation.getName().equals(annotation.getRawName()); - } - -} diff --git a/pmd-apex/src/main/resources/category/apex/codestyle.xml b/pmd-apex/src/main/resources/category/apex/codestyle.xml index 448d8e9a00f..97b2ab0f56a 100644 --- a/pmd-apex/src/main/resources/category/apex/codestyle.xml +++ b/pmd-apex/src/main/resources/category/apex/codestyle.xml @@ -9,6 +9,43 @@ Rules which enforce a specific coding style. + + + Apex, while case-insensitive, benefits from a consistent code style to improve readability and maintainability. + Enforcing PascalCase for annotations aligns with the established conventions and reduces ambiguity - promoting a unified coding standard. + + 3 + + + + + - - -Apex, while case-insensitive, benefits from a consistent code style to improve readability and maintainability. -Enforcing PascalCase for annotations aligns with the established conventions and reduces ambiguity - promoting a unified coding standard. - - 3 - - - - - 3 + + 3 + diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/AnnotationsShouldBePascalCaseTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/AnnotationsNamingConventionsTest.java similarity index 58% rename from pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/AnnotationsShouldBePascalCaseTest.java rename to pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/AnnotationsNamingConventionsTest.java index d47927bdcef..b9c7c3c6840 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/AnnotationsShouldBePascalCaseTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/codestyle/AnnotationsNamingConventionsTest.java @@ -1,11 +1,11 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ -package net.sourceforge.pmd.lang.apex.rule.design; +package net.sourceforge.pmd.lang.apex.rule.codestyle; import net.sourceforge.pmd.test.PmdRuleTst; -class AnnotationsShouldBePascalCaseTest extends PmdRuleTst { +class AnnotationsNamingConventionsTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/AnnotationsShouldBePascalCase.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/codestyle/xml/AnnotationsNamingConventions.xml similarity index 96% rename from pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/AnnotationsShouldBePascalCase.xml rename to pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/codestyle/xml/AnnotationsNamingConventions.xml index 501c168e2d3..37a6fbffd61 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/AnnotationsShouldBePascalCase.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/codestyle/xml/AnnotationsNamingConventions.xml @@ -20,6 +20,10 @@ public class Foo { AuraEnabled lowercase is incorrect 1 + 2 + + The annotation @auraenabled should be in PascalCase: @AuraEnabled + + + InvocableVariable lowercase is incorrect for multiple fields + 1 + + + IsTest PascalCase is correct 0 From 646315f57ae2ba3d5c7398d7c6e362b18a941618 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 31 Jul 2025 17:53:46 +0200 Subject: [PATCH 1199/1962] [doc] Update release notes (#5650, #5822) --- docs/pages/release_notes.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index d5e6a6999c7..85402c20d18 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -30,12 +30,17 @@ This is a {{ site.pmd.release_type }} release. generic types and methods. It can be configured via a regular expression. By default, this rule uses the standard Java naming convention (single uppercase letter). The rule is referenced in the quickstart.xml ruleset for Java. +* The new apex rule {% rule apex/codestyle/AnnotationsNamingConventions %} enforces that annotations + are used consistently in PascalCase. + The rule is referenced in the quickstart.xml ruleset for Apex. #### Deprecated Rules * The java rule {% rule java/codestyle/GenericsNaming %} has been deprecated for removal in favor of the new rule {% rule java/codestyle/TypeParameterNamingConventions %}. ### ๐Ÿ› Fixed Issues +* apex-codestyle + * [#5650](https://github.com/pmd/pmd/issues/5650): \[apex] New Rule: AnnotationsNamingConventions * java-codestyle * [#972](https://github.com/pmd/pmd/issues/972): \[java] Improve naming conventions rules @@ -43,6 +48,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ Merged pull requests +* [#5822](https://github.com/pmd/pmd/pull/5822): Fix #5650: \[apex] New Rule: AnnotationsNamingConventions - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) * [#5922](https://github.com/pmd/pmd/pull/5922): Fix #972: \[java] Add a new rule TypeParameterNamingConventions - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5932](https://github.com/pmd/pmd/pull/5932): \[ci] Reuse GitHub Pre-Releases - [Andreas Dangel](https://github.com/adangel) (@adangel) From 94ded12569eaff01cfa6729a9ca1b27e92382e64 Mon Sep 17 00:00:00 2001 From: Vincent Potucek Date: Sun, 20 Jul 2025 18:44:49 +0200 Subject: [PATCH 1200/1962] Fix #5837: [java] New Rule: OverrideEqualsOnComparable --- .../MissingEqualsOnComparableRule.java | 76 ++++ .../resources/category/java/errorprone.xml | 56 +++ .../resources/rulesets/java/quickstart.xml | 1 + .../MissingEqualsOnComparableTest.java | 11 + .../xml/MissingEqualsOnComparable.xml | 430 ++++++++++++++++++ .../xml/OverrideBothEqualsAndHashcode.xml | 17 + 6 files changed, 591 insertions(+) create mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingEqualsOnComparableRule.java create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingEqualsOnComparableTest.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/MissingEqualsOnComparable.xml diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingEqualsOnComparableRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingEqualsOnComparableRule.java new file mode 100644 index 00000000000..848a041fb92 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingEqualsOnComparableRule.java @@ -0,0 +1,76 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.errorprone; + +import net.sourceforge.pmd.lang.java.ast.ASTAnonymousClassDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTClassDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTRecordDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration; +import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; +import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; +import net.sourceforge.pmd.lang.java.types.TypeTestUtil; + +/** + * Rule that checks {@link Comparable} classes for proper equals/hashCode implementations. + *

    + * ComparableImplementedButEqualsNotOverridden + * + * @author Vincent Rudolf Potuฤek + * @since 7.16.0 + */ +public class MissingEqualsOnComparableRule extends AbstractJavaRulechainRule { + + private static final String MISSING_HASH_CODE = "Missing hashCode"; + private static final String MISSING_EQUALS = "Missing equals"; + private static final String MISSING_EQUALS_AND_HASH_CODE = "Missing equals and hashCode"; + + public MissingEqualsOnComparableRule() { + super(ASTClassDeclaration.class, + ASTRecordDeclaration.class, + ASTAnonymousClassDeclaration.class); + } + + @Override + public Object visit(ASTAnonymousClassDeclaration node, Object data) { + visitTypeDecl(node, data); + return null; + } + + @Override + public Object visit(ASTClassDeclaration node, Object data) { + visitTypeDecl(node, data); + return null; + } + + @Override + public Object visit(ASTRecordDeclaration node, Object data) { + visitTypeDecl(node, data); + return null; + } + + private void visitTypeDecl(ASTTypeDeclaration node, Object data) { + if (TypeTestUtil.isA(Comparable.class, node) && !node.isInterface() && !node.isAbstract()) { + ASTMethodDeclaration equalsMethod = null; + ASTMethodDeclaration hashCodeMethod = null; + + for (ASTMethodDeclaration m : node.getDeclarations(ASTMethodDeclaration.class)) { + if (JavaAstUtils.isEqualsMethod(m)) { + equalsMethod = m; + } else if (JavaAstUtils.isHashCodeMethod(m)) { + hashCodeMethod = m; + } + } + + if (equalsMethod == null && hashCodeMethod == null) { + asCtx(data).addViolationWithMessage(node, MISSING_EQUALS_AND_HASH_CODE); + } else if (equalsMethod == null) { + asCtx(data).addViolationWithMessage(node, MISSING_EQUALS); + } else if (hashCodeMethod == null) { + asCtx(data).addViolationWithMessage(equalsMethod, MISSING_HASH_CODE); + } + } + } +} diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index d0ecc602c87..dbce679437d 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -2355,6 +2355,62 @@ public class Foo { // perfect, both methods provided // return some hash value } } +]]> + + + + + + Classes that implement `Comparable` should override both `equals()` and + `hashCode()` if instances of these classes are used in collections. This is + to ensure that the class's natural ordering is consistent with `equals()`. + Failing to do so can lead to unexpected behavior in sets which then do not + conform to the `Set` interface. While the `Set` interface relies on + `equals()` to determine object equality, sorted sets like `TreeSet` use + `compareTo()` instead. The same issue can arise when such objects are used + as keys in sorted maps. + + Note 1: This rule is related to {% rule OverrideBothEqualsAndHashcode %}. It + will report also missing `hashCode()` methods, if the class implements + `Comparable`. + Note 2: This rule also reports records that implement `Comparable`. While + for records, `equals()` and `hashCode()` are generated, you still must make + sure that `compareTo()` is consistent with `equals()`. + + 3 + + { // poor - missing equals() and hashCode() + public int compareTo(Bar other) { + // some comparison + } +} + +public class Baz implements Comparable { // poor - missing hashCode() + public int compareTo(Baz other) { + // some comparison + } + public boolean equals(Object o) { + // some comparison + } +} + +public class Foo implements Comparable { // correct + public int compareTo(Foo other) { + // some comparison + } + public boolean equals(Object o) { + // some comparison + } + public int hashCode() { + // return hash code + } +} ]]> diff --git a/pmd-java/src/main/resources/rulesets/java/quickstart.xml b/pmd-java/src/main/resources/rulesets/java/quickstart.xml index 436645c8c8f..0ce6225344c 100644 --- a/pmd-java/src/main/resources/rulesets/java/quickstart.xml +++ b/pmd-java/src/main/resources/rulesets/java/quickstart.xml @@ -250,6 +250,7 @@ + diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingEqualsOnComparableTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingEqualsOnComparableTest.java new file mode 100644 index 00000000000..c0d63e581c0 --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingEqualsOnComparableTest.java @@ -0,0 +1,11 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.errorprone; + +import net.sourceforge.pmd.test.PmdRuleTst; + +class MissingEqualsOnComparableTest extends PmdRuleTst { + // no additional unit tests +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/MissingEqualsOnComparable.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/MissingEqualsOnComparable.xml new file mode 100644 index 00000000000..2d07d7d1f6d --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/MissingEqualsOnComparable.xml @@ -0,0 +1,430 @@ + + + + Comparable without equals + 1 + 1 + + Missing equals and hashCode + + { + @Override + public int compareTo(Foo o) { + return 0; + } + } + ]]> + + + No feature envy on OverrideBothEqualsAndHashcodeRule: Only check Comparable + 0 + + + + Comparable with equals but no hashCode + 1 + 8 + { + @Override + public int compareTo(Foo o) { + return 0; + } + + @Override + public boolean equals(Object o) { + return o instanceof Foo && compareTo((Foo) o) == 0; + } + } + ]]> + + + Comparable with both methods + 0 + { + @Override + public int compareTo(Foo o) { + return 0; + } + + @Override + public boolean equals(Object o) { + return o instanceof Foo && compareTo((Foo) o) == 0; + } + + @Override + public int hashCode() { + return 0; + } + } + ]]> + + + Non-Comparable class + 0 + + + + Comparable interface + 0 + { + } + ]]> + + + Comparable with wrong equals signature + 1 + 1 + + Missing equals and hashCode + + { + @Override + public int compareTo(Foo o) { + return 0; + } + + public boolean equals(Foo o) { + return compareTo(o) == 0; + } + } + ]]> + + + Comparable with wrong equals signature + 1 + + 1 + + Missing equals + + { + @Override + public int compareTo(Foo o) { + return 0; + } + + @Override + public int hashCode() { + return 0; + } + } + ]]> + + + Comparable with wrong equals signature + 1 + 8 + + Missing hashCode + + { + @Override + public int compareTo(Foo o) { + return 0; + } + + @Override + public boolean equals(Object o) { + return false; + } + } + ]]> + + + Raw Comparable + 1 + 1 + + + + Anonymous Comparable + 1 + 2 + anonymous = new Comparable() { + @Override + public int compareTo(Object o) { + return 0; + } + }; + } + ]]> + + + FileId interface with proper methods + 0 + { + @Override + boolean equals(Object o); + + @Override + int hashCode(); + + @Override + default int compareTo(FileId o) { + return 0; + } + } + ]]> + + + Abstract class + 0 + + + + Abstract class with equals + 0 + + + + Concrete class missing hashCode + 0 + + + + enum declaration with no methods + 0 + + + + enum declaration with equals only + 0 + + + + enum declaration with hashCode only + 0 + + + + enum declaration with both equals and hashCode + 0 + + + + enum implementing Comparable with equals + 0 + { + VALUE1, VALUE2; + + @Override + public boolean equals(Object o) { + return false; + } + } + ]]> + + + enum implementing Comparable with hashCode + 0 + { + VALUE1, VALUE2; + + @Override + public int hashCode() { + return 42; + } + } + ]]> + + + Non-Comparable class with equals but no hashCode + 0 + + + + Record with Comparable and no explicit equals/hashCode + 1 + 1 + { + @Override + public int compareTo(Foo o) { + return Integer.compare(this.x, o.x); + } + } + ]]> + + + Record with Comparable and explicit equals + 1 + 8 + + Missing hashCode + + { + @Override + public int compareTo(Foo o) { + return Integer.compare(this.x, o.x); + } + + @Override + public boolean equals(Object o) { + return o instanceof Foo f && compareTo(f) == 0; + } + } + ]]> + + + Record with Comparable and explicit hashCode + 1 + 1 + + Missing equals + + { + @Override + public int compareTo(Foo o) { + return Integer.compare(this.x, o.x); + } + + @Override + public int hashCode() { + return x; + } + } + ]]> + + + Record with Comparable and both explicit equals and hashCode + 0 + { + @Override + public int compareTo(Foo o) { + return Integer.compare(this.x, o.x); + } + + @Override + public boolean equals(Object o) { + return o instanceof Foo f && compareTo(f) == 0; + } + + @Override + public int hashCode() { + return x; + } + } + ]]> + + + Record without Comparable + 0 + + + + Record with wrong equals signature + 1 + 1 + + Missing equals and hashCode + + { + @Override + public int compareTo(Foo o) { + return Integer.compare(this.x, o.x); + } + + public boolean equals(Foo o) { + return compareTo(o) == 0; + } + } + ]]> + + \ No newline at end of file diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashcode.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashcode.xml index 74e2f872dac..70a558b8d60 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashcode.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashcode.xml @@ -210,4 +210,21 @@ public class Foo { } ]]> + + No feature envy on MissingEqualsOnComparableRule: Comparable with equals, but missing hashCode. + 0 + { + @Override + public int compareTo(Foo o) { + return 0; + } + + @Override + public boolean equals(Object o) { + return o instanceof Foo && compareTo((Foo) o) == 0; + } + } + ]]> + From 7d9e9df15c3452fd962f16c4c554a2f6f6a0159d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Aug 2025 10:02:24 +0200 Subject: [PATCH 1201/1962] Fix checkstyle --- .../java/rule/errorprone/MissingEqualsOnComparableTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingEqualsOnComparableTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingEqualsOnComparableTest.java index c0d63e581c0..58dc7e90e48 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingEqualsOnComparableTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingEqualsOnComparableTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ From 6cc8a2b9ba07825dbd738516876486e3a09dba63 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Aug 2025 10:51:14 +0200 Subject: [PATCH 1202/1962] [java] OverrideBothEqualsAndHashcode - update tests regarding comparable --- .../xml/OverrideBothEqualsAndHashcode.xml | 66 ++++++++++++++----- 1 file changed, 48 insertions(+), 18 deletions(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashcode.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashcode.xml index 70a558b8d60..d1472086447 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashcode.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashcode.xml @@ -87,7 +87,7 @@ public class Foo { - skip Comparable implementations + skip Comparable implementations (raw, missing hashCode) 0 + + skip Comparable implementations (raw, missing equals) + 0 + + + + + skip Comparable implementation (generic, missing hashCode) + 0 + { + @Override + public int compareTo(Foo o) { + return 0; + } + + @Override + public boolean equals(Object o) { + return o instanceof Foo && compareTo((Foo) o) == 0; + } +} + ]]> + + + + skip Comparable implementation (generic, missing equals) + 0 + { + @Override + public int compareTo(Foo o) { + return 0; + } + + @Override + public int hashCode() { + return 0; + } +} + ]]> + + implements equals but with 2 args 0 @@ -210,21 +257,4 @@ public class Foo { } ]]> - - No feature envy on MissingEqualsOnComparableRule: Comparable with equals, but missing hashCode. - 0 - { - @Override - public int compareTo(Foo o) { - return 0; - } - - @Override - public boolean equals(Object o) { - return o instanceof Foo && compareTo((Foo) o) == 0; - } - } - ]]> - From 9399a88d27e7c5d5c3abde30c6b8853aec9fe2ba Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Aug 2025 11:07:40 +0200 Subject: [PATCH 1203/1962] [java] MissingEqualsOnComparable - cleanup tests - remove wrong enum tests - improve message - reorder tests to group similar cases - remove duplicated test cases --- .../MissingEqualsOnComparableRule.java | 9 +- .../xml/MissingEqualsOnComparable.xml | 202 +++++------------- 2 files changed, 58 insertions(+), 153 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingEqualsOnComparableRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingEqualsOnComparableRule.java index 848a041fb92..a3c50c27692 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingEqualsOnComparableRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingEqualsOnComparableRule.java @@ -23,9 +23,10 @@ */ public class MissingEqualsOnComparableRule extends AbstractJavaRulechainRule { - private static final String MISSING_HASH_CODE = "Missing hashCode"; - private static final String MISSING_EQUALS = "Missing equals"; - private static final String MISSING_EQUALS_AND_HASH_CODE = "Missing equals and hashCode"; + private static final String MESSAGE_PREFIX = "When implementing Comparable "; + private static final String MISSING_HASH_CODE = MESSAGE_PREFIX + "hashCode() should be overridden"; + private static final String MISSING_EQUALS = MESSAGE_PREFIX + "equals() should be overridden"; + private static final String MISSING_EQUALS_AND_HASH_CODE = MESSAGE_PREFIX + "both equals() and hashCode() should be overridden"; public MissingEqualsOnComparableRule() { super(ASTClassDeclaration.class, @@ -67,7 +68,7 @@ private void visitTypeDecl(ASTTypeDeclaration node, Object data) { if (equalsMethod == null && hashCodeMethod == null) { asCtx(data).addViolationWithMessage(node, MISSING_EQUALS_AND_HASH_CODE); } else if (equalsMethod == null) { - asCtx(data).addViolationWithMessage(node, MISSING_EQUALS); + asCtx(data).addViolationWithMessage(hashCodeMethod, MISSING_EQUALS); } else if (hashCodeMethod == null) { asCtx(data).addViolationWithMessage(equalsMethod, MISSING_HASH_CODE); } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/MissingEqualsOnComparable.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/MissingEqualsOnComparable.xml index 2d07d7d1f6d..150477bf966 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/MissingEqualsOnComparable.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/MissingEqualsOnComparable.xml @@ -4,11 +4,11 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests http://pmd.sourceforge.net/rule-tests_1_0_0.xsd"> - Comparable without equals + Comparable without equals and hashCode 1 1 - Missing equals and hashCode + When implementing Comparable both equals() and hashCode() should be overridden { @@ -20,20 +20,33 @@ ]]> - No feature envy on OverrideBothEqualsAndHashcodeRule: Only check Comparable - 0 + Comparable with equals but no hashCode + 1 + 8 + + When implementing Comparable hashCode() should be overridden + { + @Override public int compareTo(Foo o) { return 0; } + + @Override + public boolean equals(Object o) { + return o instanceof Foo && compareTo((Foo) o) == 0; + } } ]]> - Comparable with equals but no hashCode + Comparable with hashCode but no equals 1 8 + + When implementing Comparable equals() should be overridden + { @Override @@ -42,8 +55,8 @@ } @Override - public boolean equals(Object o) { - return o instanceof Foo && compareTo((Foo) o) == 0; + public int hashCode() { + return 0; } } ]]> @@ -70,6 +83,17 @@ } ]]> + + Ignore classes that don't implement Comparable + 0 + + Non-Comparable class 0 @@ -91,7 +115,7 @@ 1 1 - Missing equals and hashCode + When implementing Comparable both equals() and hashCode() should be overridden { @@ -107,52 +131,12 @@ ]]> - Comparable with wrong equals signature + Raw Comparable 1 - 1 - Missing equals + When implementing Comparable both equals() and hashCode() should be overridden - { - @Override - public int compareTo(Foo o) { - return 0; - } - - @Override - public int hashCode() { - return 0; - } - } - ]]> - - - Comparable with wrong equals signature - 1 - 8 - - Missing hashCode - - { - @Override - public int compareTo(Foo o) { - return 0; - } - - @Override - public boolean equals(Object o) { - return false; - } - } - ]]> - - - Raw Comparable - 1 - 1 Anonymous Comparable 1 2 + + When implementing Comparable both equals() and hashCode() should be overridden + anonymous = new Comparable() { @@ -216,14 +203,15 @@ ]]> - Concrete class missing hashCode + Non-Comparable class with equals but no hashCode 0 @@ -235,97 +223,13 @@ } ]]> - - enum declaration with equals only - 0 - - - - enum declaration with hashCode only - 0 - - - - enum declaration with both equals and hashCode - 0 - - - - enum implementing Comparable with equals - 0 - { - VALUE1, VALUE2; - - @Override - public boolean equals(Object o) { - return false; - } - } - ]]> - - - enum implementing Comparable with hashCode - 0 - { - VALUE1, VALUE2; - - @Override - public int hashCode() { - return 42; - } - } - ]]> - - - Non-Comparable class with equals but no hashCode - 0 - - Record with Comparable and no explicit equals/hashCode 1 1 + + When implementing Comparable both equals() and hashCode() should be overridden + { @Override @@ -340,7 +244,7 @@ 1 8 - Missing hashCode + When implementing Comparable hashCode() should be overridden { @@ -359,9 +263,9 @@ Record with Comparable and explicit hashCode 1 - 1 + 8 - Missing equals + When implementing Comparable equals() should be overridden { @@ -408,11 +312,11 @@ ]]> - Record with wrong equals signature + Comparable Record with wrong equals signature 1 1 - Missing equals and hashCode + When implementing Comparable both equals() and hashCode() should be overridden { @@ -427,4 +331,4 @@ } ]]> - \ No newline at end of file + From 8126001c7dd42aef042927b0b72a256fc5728c13 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Aug 2025 11:16:17 +0200 Subject: [PATCH 1204/1962] [java] Rename new rule OverrideBothEqualsAndHashCodeOnComparable Renamed from MissingEqualsOnComparable --- ...othEqualsAndHashCodeOnComparableRule.java} | 6 +-- .../resources/category/java/errorprone.xml | 38 +++++++++---------- .../resources/rulesets/java/quickstart.xml | 2 +- ...othEqualsAndHashCodeOnComparableTest.java} | 2 +- ...rideBothEqualsAndHashCodeOnComparable.xml} | 0 5 files changed, 24 insertions(+), 24 deletions(-) rename pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/{MissingEqualsOnComparableRule.java => OverrideBothEqualsAndHashCodeOnComparableRule.java} (94%) rename pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/{MissingEqualsOnComparableTest.java => OverrideBothEqualsAndHashCodeOnComparableTest.java} (75%) rename pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/{MissingEqualsOnComparable.xml => OverrideBothEqualsAndHashCodeOnComparable.xml} (100%) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingEqualsOnComparableRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java similarity index 94% rename from pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingEqualsOnComparableRule.java rename to pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java index a3c50c27692..fa80f37f7a4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingEqualsOnComparableRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java @@ -19,16 +19,16 @@ * ComparableImplementedButEqualsNotOverridden * * @author Vincent Rudolf Potuฤek - * @since 7.16.0 + * @since 7.17.0 */ -public class MissingEqualsOnComparableRule extends AbstractJavaRulechainRule { +public class OverrideBothEqualsAndHashCodeOnComparableRule extends AbstractJavaRulechainRule { private static final String MESSAGE_PREFIX = "When implementing Comparable "; private static final String MISSING_HASH_CODE = MESSAGE_PREFIX + "hashCode() should be overridden"; private static final String MISSING_EQUALS = MESSAGE_PREFIX + "equals() should be overridden"; private static final String MISSING_EQUALS_AND_HASH_CODE = MESSAGE_PREFIX + "both equals() and hashCode() should be overridden"; - public MissingEqualsOnComparableRule() { + public OverrideBothEqualsAndHashCodeOnComparableRule() { super(ASTClassDeclaration.class, ASTRecordDeclaration.class, ASTAnonymousClassDeclaration.class); diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index dbce679437d..af159545105 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -2358,28 +2358,28 @@ public class Foo { // perfect, both methods provided ]]> - - - - Classes that implement `Comparable` should override both `equals()` and - `hashCode()` if instances of these classes are used in collections. This is - to ensure that the class's natural ordering is consistent with `equals()`. - Failing to do so can lead to unexpected behavior in sets which then do not - conform to the `Set` interface. While the `Set` interface relies on - `equals()` to determine object equality, sorted sets like `TreeSet` use - `compareTo()` instead. The same issue can arise when such objects are used + since="7.17.0" + message="When implementing Comparable both equals() and hashCode() should be overridden" + class="net.sourceforge.pmd.lang.java.rule.errorprone.OverrideBothEqualsAndHashCodeOnComparableRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#overridebothequalsandhashcodeoncomparable"> + + Classes that implement `Comparable` should override both `equals()` and + `hashCode()` if instances of these classes are used in collections. This is + to ensure that the class's natural ordering is consistent with `equals()`. + Failing to do so can lead to unexpected behavior in sets which then do not + conform to the `Set` interface. While the `Set` interface relies on + `equals()` to determine object equality, sorted sets like `TreeSet` use + `compareTo()` instead. The same issue can arise when such objects are used as keys in sorted maps. - Note 1: This rule is related to {% rule OverrideBothEqualsAndHashcode %}. It - will report also missing `hashCode()` methods, if the class implements - `Comparable`. - Note 2: This rule also reports records that implement `Comparable`. While - for records, `equals()` and `hashCode()` are generated, you still must make + Note 1: This rule is related to {% rule OverrideBothEqualsAndHashcode %}. It + will report missing `equals()` and/or `hashCode()` methods for classes only + that implement `Comparable`. + Note 2: This rule also reports records that implement `Comparable`. While + for records, `equals()` and `hashCode()` are generated, you still must make sure that `compareTo()` is consistent with `equals()`. 3 diff --git a/pmd-java/src/main/resources/rulesets/java/quickstart.xml b/pmd-java/src/main/resources/rulesets/java/quickstart.xml index 0ce6225344c..2d6ea12ec4a 100644 --- a/pmd-java/src/main/resources/rulesets/java/quickstart.xml +++ b/pmd-java/src/main/resources/rulesets/java/quickstart.xml @@ -250,7 +250,7 @@ - + diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingEqualsOnComparableTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableTest.java similarity index 75% rename from pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingEqualsOnComparableTest.java rename to pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableTest.java index 58dc7e90e48..a0bc53b22a1 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/MissingEqualsOnComparableTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableTest.java @@ -6,6 +6,6 @@ import net.sourceforge.pmd.test.PmdRuleTst; -class MissingEqualsOnComparableTest extends PmdRuleTst { +class OverrideBothEqualsAndHashCodeOnComparableTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/MissingEqualsOnComparable.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml similarity index 100% rename from pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/MissingEqualsOnComparable.xml rename to pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml From 4ff0702e50881a305bb98d37908f83adef49353a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Aug 2025 11:41:57 +0200 Subject: [PATCH 1205/1962] [java] OverrideBothEqualsAndHashcode - share implementations --- ...BothEqualsAndHashCodeOnComparableRule.java | 64 +++++-------------- .../OverrideBothEqualsAndHashcodeRule.java | 15 ++++- 2 files changed, 27 insertions(+), 52 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java index fa80f37f7a4..100ce912e4d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java @@ -4,74 +4,40 @@ package net.sourceforge.pmd.lang.java.rule.errorprone; -import net.sourceforge.pmd.lang.java.ast.ASTAnonymousClassDeclaration; -import net.sourceforge.pmd.lang.java.ast.ASTClassDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; -import net.sourceforge.pmd.lang.java.ast.ASTRecordDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration; -import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; -import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; import net.sourceforge.pmd.lang.java.types.TypeTestUtil; +import net.sourceforge.pmd.reporting.RuleContext; /** * Rule that checks {@link Comparable} classes for proper equals/hashCode implementations. - *

    - * ComparableImplementedButEqualsNotOverridden + * + *

    This is essentially the same as the rule {@link OverrideBothEqualsAndHashcodeRule} but only for + * {@link Comparable} types. * * @author Vincent Rudolf Potuฤek + * @see ComparableImplementedButEqualsNotOverridden * @since 7.17.0 */ -public class OverrideBothEqualsAndHashCodeOnComparableRule extends AbstractJavaRulechainRule { - +public class OverrideBothEqualsAndHashCodeOnComparableRule extends OverrideBothEqualsAndHashcodeRule { private static final String MESSAGE_PREFIX = "When implementing Comparable "; private static final String MISSING_HASH_CODE = MESSAGE_PREFIX + "hashCode() should be overridden"; private static final String MISSING_EQUALS = MESSAGE_PREFIX + "equals() should be overridden"; private static final String MISSING_EQUALS_AND_HASH_CODE = MESSAGE_PREFIX + "both equals() and hashCode() should be overridden"; - public OverrideBothEqualsAndHashCodeOnComparableRule() { - super(ASTClassDeclaration.class, - ASTRecordDeclaration.class, - ASTAnonymousClassDeclaration.class); - } - @Override - public Object visit(ASTAnonymousClassDeclaration node, Object data) { - visitTypeDecl(node, data); - return null; + protected boolean skipType(ASTTypeDeclaration node) { + return !TypeTestUtil.isA(Comparable.class, node); } @Override - public Object visit(ASTClassDeclaration node, Object data) { - visitTypeDecl(node, data); - return null; - } - - @Override - public Object visit(ASTRecordDeclaration node, Object data) { - visitTypeDecl(node, data); - return null; - } - - private void visitTypeDecl(ASTTypeDeclaration node, Object data) { - if (TypeTestUtil.isA(Comparable.class, node) && !node.isInterface() && !node.isAbstract()) { - ASTMethodDeclaration equalsMethod = null; - ASTMethodDeclaration hashCodeMethod = null; - - for (ASTMethodDeclaration m : node.getDeclarations(ASTMethodDeclaration.class)) { - if (JavaAstUtils.isEqualsMethod(m)) { - equalsMethod = m; - } else if (JavaAstUtils.isHashCodeMethod(m)) { - hashCodeMethod = m; - } - } - - if (equalsMethod == null && hashCodeMethod == null) { - asCtx(data).addViolationWithMessage(node, MISSING_EQUALS_AND_HASH_CODE); - } else if (equalsMethod == null) { - asCtx(data).addViolationWithMessage(hashCodeMethod, MISSING_EQUALS); - } else if (hashCodeMethod == null) { - asCtx(data).addViolationWithMessage(equalsMethod, MISSING_HASH_CODE); - } + protected void maybeReport(RuleContext ctx, ASTTypeDeclaration node, ASTMethodDeclaration hashCodeMethod, ASTMethodDeclaration equalsMethod) { + if (equalsMethod == null && hashCodeMethod == null) { + ctx.addViolationWithMessage(node, MISSING_EQUALS_AND_HASH_CODE); + } else if (equalsMethod == null) { + ctx.addViolationWithMessage(hashCodeMethod, MISSING_EQUALS); + } else if (hashCodeMethod == null) { + ctx.addViolationWithMessage(equalsMethod, MISSING_HASH_CODE); } } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashcodeRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashcodeRule.java index 8350ede471d..e94e8dbd256 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashcodeRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashcodeRule.java @@ -12,6 +12,7 @@ import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; import net.sourceforge.pmd.lang.java.types.TypeTestUtil; +import net.sourceforge.pmd.reporting.RuleContext; public class OverrideBothEqualsAndHashcodeRule extends AbstractJavaRulechainRule { @@ -21,8 +22,12 @@ public OverrideBothEqualsAndHashcodeRule() { ASTAnonymousClassDeclaration.class); } + protected boolean skipType(ASTTypeDeclaration node) { + return TypeTestUtil.isA(Comparable.class, node); + } + private void visitTypeDecl(ASTTypeDeclaration node, Object data) { - if (TypeTestUtil.isA(Comparable.class, node)) { + if (skipType(node)) { return; } ASTMethodDeclaration equalsMethod = null; @@ -41,10 +46,14 @@ private void visitTypeDecl(ASTTypeDeclaration node, Object data) { } } + maybeReport(asCtx(data), node, hashCodeMethod, equalsMethod); + } + + protected void maybeReport(RuleContext ctx, ASTTypeDeclaration node, ASTMethodDeclaration hashCodeMethod, ASTMethodDeclaration equalsMethod) { if (hashCodeMethod != null ^ equalsMethod != null) { ASTMethodDeclaration nonNullNode = - equalsMethod == null ? hashCodeMethod : equalsMethod; - asCtx(data).addViolation(nonNullNode); + equalsMethod == null ? hashCodeMethod : equalsMethod; + ctx.addViolation(nonNullNode); } } From e315994aeadb5bc3f9eda8bfb3adbb38d28c3067 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Aug 2025 11:50:57 +0200 Subject: [PATCH 1206/1962] [java] OverrideBothEqualsAndHashcode - improve rule documentation --- .../src/main/resources/category/java/errorprone.xml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index af159545105..ed9bd9cd0c1 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -2330,7 +2330,16 @@ public void bar() { class="net.sourceforge.pmd.lang.java.rule.errorprone.OverrideBothEqualsAndHashcodeRule" externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#overridebothequalsandhashcode"> -Override both public boolean Object.equals(Object other), and public int Object.hashCode(), or override neither. Even if you are inheriting a hashCode() from a parent class, consider implementing hashCode and explicitly delegating to your superclass. +Override both `public boolean Object.equals(Object other)` and `public int Object.hashCode()` or override neither. +Even if you are inheriting a `hashCode()` from a parent class, consider implementing `hashCode()` and explicitly +delegating to your superclass. + +Not overriding both methods could violate the contract between `equals()` and `hashCode()`. Most importantly, +if two instances are equal, then they must have the same hash code. Using such invalid instances in hash-based +collections like `HashSet` or `HashMap` could lead to duplicated or missing entries. + +This rule does not consider types that implement `Comparable`. There is a separate rule +{% rule OverrideBothEqualsAndHashCodeOnComparable %} for this. 3 From 121f1bfa4408ac19c609a7a7d602ecd5df9c6d04 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Aug 2025 12:02:49 +0200 Subject: [PATCH 1207/1962] [doc] Update release notes (#5837, #5856) --- docs/pages/release_notes.md | 14 ++++++++++++++ .../main/resources/category/java/errorprone.xml | 1 + 2 files changed, 15 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index d5e6a6999c7..bd2f57158c2 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -30,6 +30,17 @@ This is a {{ site.pmd.release_type }} release. generic types and methods. It can be configured via a regular expression. By default, this rule uses the standard Java naming convention (single uppercase letter). The rule is referenced in the quickstart.xml ruleset for Java. +* The new java rule {% rule java/errorprone/OverrideBothEqualsAndHashCodeOnComparable %} finds missing + `hashCode()` and/or `equals()` methods on types that implement `Comparable`. This is important if + instances of these classes are used in collections. Failing to do so can lead to unexpected behavior in sets + which then do not conform to the `Set` interface. While the `Set` interface relies on + `equals()` to determine object equality, sorted sets like `TreeSet` use + `compareTo()` instead. The same issue can arise when such objects are used + as keys in sorted maps. + This rule is very similar to {% rule java/errorprone/OverrideBothEqualsAndHashcode %} which has always been + skipping `Comparable` and only reports if one of the two methods is missing. The new rule will also report, + if both methods (hashCode and equals) are missing. + The rule is referenced in the quickstart.xml ruleset for Java. #### Deprecated Rules * The java rule {% rule java/codestyle/GenericsNaming %} has been deprecated for removal in favor @@ -38,11 +49,14 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿ› Fixed Issues * java-codestyle * [#972](https://github.com/pmd/pmd/issues/972): \[java] Improve naming conventions rules +* java-errorprone + * [#5837](https://github.com/pmd/pmd/issues/5837): \[java] New Rule OverrideBothEqualsAndHashCodeOnComparable ### ๐Ÿšจ API Changes ### โœจ Merged pull requests +* [#5856](https://github.com/pmd/pmd/pull/5856): Fix #5837: \[java] New Rule OverrideBothEqualsAndHashCodeOnComparable - [Vincent Potucek](https://github.com/Pankraz76) (@Pankraz76) * [#5922](https://github.com/pmd/pmd/pull/5922): Fix #972: \[java] Add a new rule TypeParameterNamingConventions - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5932](https://github.com/pmd/pmd/pull/5932): \[ci] Reuse GitHub Pre-Releases - [Andreas Dangel](https://github.com/adangel) (@adangel) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index ed9bd9cd0c1..0ae46ec6bef 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -2387,6 +2387,7 @@ public class Foo { // perfect, both methods provided Note 1: This rule is related to {% rule OverrideBothEqualsAndHashcode %}. It will report missing `equals()` and/or `hashCode()` methods for classes only that implement `Comparable`. + Note 2: This rule also reports records that implement `Comparable`. While for records, `equals()` and `hashCode()` are generated, you still must make sure that `compareTo()` is consistent with `equals()`. From c1cd2cd91316dc7b002167bcbc34c676228b0df5 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Aug 2025 12:38:52 +0200 Subject: [PATCH 1208/1962] [doc] Update release notes (#5874) [skip ci] --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index d5e6a6999c7..97e90ae9123 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -36,6 +36,8 @@ This is a {{ site.pmd.release_type }} release. of the new rule {% rule java/codestyle/TypeParameterNamingConventions %}. ### ๐Ÿ› Fixed Issues +* java + * [#5874](https://github.com/pmd/pmd/issues/5874): \[java] Update java regression tests with Java 25 language features * java-codestyle * [#972](https://github.com/pmd/pmd/issues/972): \[java] Improve naming conventions rules From a274e3fe7ca5d8110128c3aac1dbe0d63b6d3420 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Aug 2025 12:43:30 +0200 Subject: [PATCH 1209/1962] [java] OverrideBothEqualsAndHashCodeOnComparable - skip enums --- .../OverrideBothEqualsAndHashCodeOnComparableRule.java | 2 +- .../xml/OverrideBothEqualsAndHashCodeOnComparable.xml | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java index 100ce912e4d..f1c0c80b4d4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java @@ -27,7 +27,7 @@ public class OverrideBothEqualsAndHashCodeOnComparableRule extends OverrideBothE @Override protected boolean skipType(ASTTypeDeclaration node) { - return !TypeTestUtil.isA(Comparable.class, node); + return !TypeTestUtil.isA(Comparable.class, node) || TypeTestUtil.isA(Enum.class, node); } @Override diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml index 150477bf966..a01c378e006 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml @@ -223,6 +223,15 @@ } ]]> + + enum declaration with implementation but no methods (anonymous classes) + 0 + + Record with Comparable and no explicit equals/hashCode 1 From d5a959f8f488a77cc086007a486df17fe41c262a Mon Sep 17 00:00:00 2001 From: Vincent Potucek <8830888+Pankraz76@users.noreply.github.com> Date: Fri, 1 Aug 2025 13:59:46 +0200 Subject: [PATCH 1210/1962] [doc] Update @author Tag --- .../OverrideBothEqualsAndHashCodeOnComparableRule.java | 1 - 1 file changed, 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java index f1c0c80b4d4..3169b0803cc 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java @@ -15,7 +15,6 @@ *

    This is essentially the same as the rule {@link OverrideBothEqualsAndHashcodeRule} but only for * {@link Comparable} types. * - * @author Vincent Rudolf Potuฤek * @see ComparableImplementedButEqualsNotOverridden * @since 7.17.0 */ From b99908f12d2f3f6ba1ea6882f9bc8bf4b34f1c0e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Aug 2025 14:40:51 +0200 Subject: [PATCH 1211/1962] [java] OverrideBothEqualsAndHashCodeOnComparable - skip inherited Do not report, if compareTo is not overridden locally, but only inherited. --- ...BothEqualsAndHashCodeOnComparableRule.java | 13 ++++++++++- ...rrideBothEqualsAndHashCodeOnComparable.xml | 23 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java index 3169b0803cc..2fcd2c4de59 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java @@ -6,6 +6,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration; +import net.sourceforge.pmd.lang.java.types.JPrimitiveType; import net.sourceforge.pmd.lang.java.types.TypeTestUtil; import net.sourceforge.pmd.reporting.RuleContext; @@ -26,7 +27,17 @@ public class OverrideBothEqualsAndHashCodeOnComparableRule extends OverrideBothE @Override protected boolean skipType(ASTTypeDeclaration node) { - return !TypeTestUtil.isA(Comparable.class, node) || TypeTestUtil.isA(Enum.class, node); + return !TypeTestUtil.isA(Comparable.class, node) + || TypeTestUtil.isA(Enum.class, node) + || hasNoCompareToMethod(node); + } + + private boolean hasNoCompareToMethod(ASTTypeDeclaration node) { + return node.getDeclarations(ASTMethodDeclaration.class) + .none(m -> "compareTo".equals(m.getName()) + && m.getArity() == 1 + && m.getResultTypeNode().getTypeMirror().isPrimitive(JPrimitiveType.PrimitiveTypeKind.INT) + && !m.isStatic()); } @Override diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml index a01c378e006..ddb4aaf79e5 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml @@ -340,4 +340,27 @@ } ]]> + + Do report in inherited Comparables with compareTo + 1 + 2 + + + + Do not report in inherited Comparables without compareTo + 0 + + From 0bdaaee9ee09f09c5978b4b38bcb828408d405b7 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Aug 2025 16:28:17 +0200 Subject: [PATCH 1212/1962] [java] OverrideBothEqualsAndHashCodeOnComparable - fix line number Now that we only report on types, that have a compareTo() method, we should report on this method rather than on the entire class when equals and hashCode are missing. --- ...BothEqualsAndHashCodeOnComparableRule.java | 24 +++++++++++-------- ...rrideBothEqualsAndHashCodeOnComparable.xml | 14 +++++------ 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java index 2fcd2c4de59..fa84becf465 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java @@ -27,23 +27,27 @@ public class OverrideBothEqualsAndHashCodeOnComparableRule extends OverrideBothE @Override protected boolean skipType(ASTTypeDeclaration node) { - return !TypeTestUtil.isA(Comparable.class, node) - || TypeTestUtil.isA(Enum.class, node) - || hasNoCompareToMethod(node); + return !TypeTestUtil.isA(Comparable.class, node) || TypeTestUtil.isA(Enum.class, node); } - private boolean hasNoCompareToMethod(ASTTypeDeclaration node) { - return node.getDeclarations(ASTMethodDeclaration.class) - .none(m -> "compareTo".equals(m.getName()) - && m.getArity() == 1 - && m.getResultTypeNode().getTypeMirror().isPrimitive(JPrimitiveType.PrimitiveTypeKind.INT) - && !m.isStatic()); + private static boolean isCompareToMethod(ASTMethodDeclaration method) { + return "compareTo".equals(method.getName()) + && method.getArity() == 1 + && method.getResultTypeNode().getTypeMirror().isPrimitive(JPrimitiveType.PrimitiveTypeKind.INT) + && !method.isStatic(); } @Override protected void maybeReport(RuleContext ctx, ASTTypeDeclaration node, ASTMethodDeclaration hashCodeMethod, ASTMethodDeclaration equalsMethod) { + ASTMethodDeclaration compareToMethod = node + .getDeclarations(ASTMethodDeclaration.class) + .first(OverrideBothEqualsAndHashCodeOnComparableRule::isCompareToMethod); + if (compareToMethod == null) { + return; + } + if (equalsMethod == null && hashCodeMethod == null) { - ctx.addViolationWithMessage(node, MISSING_EQUALS_AND_HASH_CODE); + ctx.addViolationWithMessage(compareToMethod, MISSING_EQUALS_AND_HASH_CODE); } else if (equalsMethod == null) { ctx.addViolationWithMessage(hashCodeMethod, MISSING_EQUALS); } else if (hashCodeMethod == null) { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml index ddb4aaf79e5..6e512d5bd78 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml @@ -6,7 +6,7 @@ Comparable without equals and hashCode 1 - 1 + 3 When implementing Comparable both equals() and hashCode() should be overridden @@ -113,7 +113,7 @@ Comparable with wrong equals signature 1 - 1 + 3 When implementing Comparable both equals() and hashCode() should be overridden @@ -133,7 +133,7 @@ Raw Comparable 1 - 1 + 3 When implementing Comparable both equals() and hashCode() should be overridden @@ -149,7 +149,7 @@ Anonymous Comparable 1 - 2 + 4 When implementing Comparable both equals() and hashCode() should be overridden @@ -235,7 +235,7 @@ Record with Comparable and no explicit equals/hashCode 1 - 1 + 3 When implementing Comparable both equals() and hashCode() should be overridden @@ -323,7 +323,7 @@ Comparable Record with wrong equals signature 1 - 1 + 3 When implementing Comparable both equals() and hashCode() should be overridden @@ -343,7 +343,7 @@ Do report in inherited Comparables with compareTo 1 - 2 + 4 Date: Fri, 1 Aug 2025 16:29:55 +0200 Subject: [PATCH 1213/1962] [java] OverrideBothEqualsAndHashCodeOnComparable - improve example Update code example for correct equals() implementation that uses compareTo() and is therefore automatically consistent. --- .../src/main/resources/category/java/errorprone.xml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 0ae46ec6bef..0033f31400b 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -2406,7 +2406,10 @@ public class Baz implements Comparable { // poor - missing hashCode() // some comparison } public boolean equals(Object o) { - // some comparison + if (o == null || getClass() != o.getClass() { + return false; + } + return compareTo((Baz) o) == 0; } } @@ -2415,7 +2418,10 @@ public class Foo implements Comparable { // correct // some comparison } public boolean equals(Object o) { - // some comparison + if (o == null || getClass() != o.getClass() { + return false; + } + return compareTo((Foo) o) == 0; } public int hashCode() { // return hash code From d298f93b0e95d621edb8e4938c9f3dbaf083b19a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Aug 2025 17:18:39 +0200 Subject: [PATCH 1214/1962] Fix example code --- pmd-java/src/main/resources/category/java/errorprone.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 0033f31400b..299fc9b6943 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -2406,7 +2406,7 @@ public class Baz implements Comparable { // poor - missing hashCode() // some comparison } public boolean equals(Object o) { - if (o == null || getClass() != o.getClass() { + if (o == null || getClass() != o.getClass()) { return false; } return compareTo((Baz) o) == 0; @@ -2418,7 +2418,7 @@ public class Foo implements Comparable { // correct // some comparison } public boolean equals(Object o) { - if (o == null || getClass() != o.getClass() { + if (o == null || getClass() != o.getClass()) { return false; } return compareTo((Foo) o) == 0; From c87d673e992faeb33a7bebb980c62682836e3f6e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Aug 2025 16:54:54 +0200 Subject: [PATCH 1215/1962] Fix #4721: [core] Enable XML rule MissingEncoding in dogfood ruleset --- pom.xml | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index a5c3ae583c5..8f02197ef91 100644 --- a/pom.xml +++ b/pom.xml @@ -555,10 +555,10 @@ /net/sourceforge/pmd/pmd-dogfood-config.xml - - target/generated-sources/javacc - target/generated-sources/antlr4 - + + ${project.basedir}/src/main/java + ${project.basedir}/src/main/resources + @@ -575,10 +575,17 @@ /net/sourceforge/pmd/pmd-test-dogfood-config.xml + + ${project.basedir}/src/test/java + + + **/*.java + **/*.xml + false 1.${java.version} false @@ -613,6 +620,11 @@ pmd-javascript 7.16.0 + + net.sourceforge.pmd + pmd-xml + 7.16.0 + net.sourceforge.pmd From 5f61a0e10887679b559a24a655dd5adcc8b0ceb0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Aug 2025 16:57:31 +0200 Subject: [PATCH 1216/1962] Remove now obsolete tests to verify xml encoding --- .../pmd/lang/apex/QuickstartRulesetTest.java | 6 ----- .../pmd/lang/java/QuickstartRulesetTest.java | 6 ----- .../lang/rule/AbstractRuleSetFactoryTest.java | 22 +++++-------------- 3 files changed, 5 insertions(+), 29 deletions(-) diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/QuickstartRulesetTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/QuickstartRulesetTest.java index 1c443e7785a..5a85979e79b 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/QuickstartRulesetTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/QuickstartRulesetTest.java @@ -11,7 +11,6 @@ import net.sourceforge.pmd.lang.rule.RuleSet; import net.sourceforge.pmd.lang.rule.RuleSetLoader; -import net.sourceforge.pmd.test.lang.rule.AbstractRuleSetFactoryTest; import com.github.stefanbirkner.systemlambda.SystemLambda; @@ -27,11 +26,6 @@ void loadQuickstartRuleset() throws Exception { assertTrue(log.isEmpty(), "No Logging expected"); } - @Test - void correctEncoding() throws Exception { - assertTrue(AbstractRuleSetFactoryTest.hasCorrectEncoding(QUICKSTART_RULESET)); - } - private RuleSetLoader rulesetLoader() { return new RuleSetLoader(); } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/QuickstartRulesetTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/QuickstartRulesetTest.java index 2882ec7bf3a..5689bccc240 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/QuickstartRulesetTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/QuickstartRulesetTest.java @@ -11,7 +11,6 @@ import net.sourceforge.pmd.lang.rule.RuleSet; import net.sourceforge.pmd.lang.rule.RuleSetLoader; -import net.sourceforge.pmd.test.lang.rule.AbstractRuleSetFactoryTest; import com.github.stefanbirkner.systemlambda.SystemLambda; @@ -27,9 +26,4 @@ void noDeprecations() throws Exception { }); assertTrue(errorOutput.isEmpty()); } - - @Test - void correctEncoding() throws Exception { - assertTrue(AbstractRuleSetFactoryTest.hasCorrectEncoding(QUICKSTART_RULESET)); - } } diff --git a/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java b/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java index 93fa3d24222..404eeb5ce84 100644 --- a/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java +++ b/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java @@ -248,23 +248,11 @@ void testXmlSchema() throws Exception { assertTrue(allValid, "All XML must parse without producing validation messages."); } - @Test - void verifyCorrectXmlEncoding() throws Exception { - boolean allValid = true; - List ruleSetFileNames = getRuleSetFileNames(); - StringBuilder messages = new StringBuilder(); - for (String fileName : ruleSetFileNames) { - boolean valid = hasCorrectEncoding(fileName); - allValid = allValid && valid; - if (!valid) { - messages.append("RuleSet ") - .append(fileName) - .append(" is missing XML encoding or not using UTF8\n"); - } - } - assertTrue(allValid, "All XML must use correct XML encoding\n" + messages); - } - + /** + * @deprecated This method will be removed. PMD has the rule "MissingEncoding" for XML files that + * is used instead. + */ + @Deprecated public static boolean hasCorrectEncoding(String fileName) throws IOException { try (InputStream inputStream = loadResourceAsStream(fileName)) { // first bytes must be: From fbfe757155ba78667b887dec6f4aab543e07e117 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Aug 2025 17:37:53 +0200 Subject: [PATCH 1217/1962] Add missing encodings to XML files --- pmd-dist/src/main/resources/assemblies/pmd-bin.xml | 1 + pmd-dist/src/main/resources/assemblies/pmd-src.xml | 1 + .../main/resources/rulesets/java/internal/diagnostics.xml | 2 +- pmd-test/src/main/resources/rulesets/dummy/basic.xml | 6 +++--- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pmd-dist/src/main/resources/assemblies/pmd-bin.xml b/pmd-dist/src/main/resources/assemblies/pmd-bin.xml index 79921a85e81..0b8baafeb61 100644 --- a/pmd-dist/src/main/resources/assemblies/pmd-bin.xml +++ b/pmd-dist/src/main/resources/assemblies/pmd-bin.xml @@ -1,3 +1,4 @@ + diff --git a/pmd-dist/src/main/resources/assemblies/pmd-src.xml b/pmd-dist/src/main/resources/assemblies/pmd-src.xml index f7650fe3e37..db8319cb18f 100644 --- a/pmd-dist/src/main/resources/assemblies/pmd-src.xml +++ b/pmd-dist/src/main/resources/assemblies/pmd-src.xml @@ -1,3 +1,4 @@ + diff --git a/pmd-java/src/main/resources/rulesets/java/internal/diagnostics.xml b/pmd-java/src/main/resources/rulesets/java/internal/diagnostics.xml index 52a523fe021..a7b1de553f0 100644 --- a/pmd-java/src/main/resources/rulesets/java/internal/diagnostics.xml +++ b/pmd-java/src/main/resources/rulesets/java/internal/diagnostics.xml @@ -1,4 +1,4 @@ - + + @@ -24,7 +24,6 @@ Just for test externalInfoUrl="${pmd.website.baseurl}/rules/dummy/basic.xml#SampleXPathRule"> Test 3 - - " + + From a44ad763d03a2c442f0da7d82489061d66fbe63e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Aug 2025 18:18:48 +0200 Subject: [PATCH 1218/1962] chore: Fix LiteralsFirstInComparison violations in test code --- .../test/java/net/sourceforge/pmd/lang/apex/FooRule.java | 8 ++++---- .../sourceforge/pmd/lang/apex/SuppressWarningsTest.java | 2 +- .../test/java/net/sourceforge/pmd/AbstractRuleTest.java | 4 +++- .../net/sourceforge/pmd/lang/DummyLanguageModule.java | 2 +- .../pmd/lang/ast/internal/NodeStreamBlanketTest.java | 2 +- .../java/net/sourceforge/pmd/lang/rule/RuleSetTest.java | 4 +++- .../pmd/lang/rule/internal/LatticeRelationTest.java | 2 +- .../java/net/sourceforge/pmd/util/IteratorUtilTest.java | 2 +- .../pmd/util/treeexport/XmlTreeRendererTest.java | 2 +- .../test/java/net/sourceforge/pmd/lang/java/FooRule.java | 4 ++-- .../pmd/lang/java/symbols/internal/TypeAnnotTestUtil.java | 8 ++++---- pom.xml | 8 ++++---- 12 files changed, 26 insertions(+), 22 deletions(-) diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/FooRule.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/FooRule.java index bf145615b4b..399beb357a1 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/FooRule.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/FooRule.java @@ -21,7 +21,7 @@ public FooRule() { @Override public Object visit(ASTUserClass c, Object ctx) { - if (c.getSimpleName().equalsIgnoreCase("Foo")) { + if ("Foo".equalsIgnoreCase(c.getSimpleName())) { asCtx(ctx).addViolation(c); } return super.visit(c, ctx); @@ -29,7 +29,7 @@ public Object visit(ASTUserClass c, Object ctx) { @Override public Object visit(ASTVariableDeclaration c, Object ctx) { - if (c.getImage().equalsIgnoreCase("Foo")) { + if ("Foo".equalsIgnoreCase(c.getImage())) { asCtx(ctx).addViolation(c); } return super.visit(c, ctx); @@ -37,7 +37,7 @@ public Object visit(ASTVariableDeclaration c, Object ctx) { @Override public Object visit(ASTField c, Object ctx) { - if (c.getImage().equalsIgnoreCase("Foo")) { + if ("Foo".equalsIgnoreCase(c.getImage())) { asCtx(ctx).addViolation(c); } return super.visit(c, ctx); @@ -45,7 +45,7 @@ public Object visit(ASTField c, Object ctx) { @Override public Object visit(ASTParameter c, Object ctx) { - if (c.getImage().equalsIgnoreCase("Foo")) { + if ("Foo".equalsIgnoreCase(c.getImage())) { asCtx(ctx).addViolation(c); } return super.visit(c, ctx); diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/SuppressWarningsTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/SuppressWarningsTest.java index 9366c75f538..c2131f234c1 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/SuppressWarningsTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/SuppressWarningsTest.java @@ -31,7 +31,7 @@ public String getMessage() { @Override public Object visit(ASTUserClass clazz, Object ctx) { - if (clazz.getSimpleName().equalsIgnoreCase("bar")) { + if ("bar".equalsIgnoreCase(clazz.getSimpleName())) { asCtx(ctx).addViolation(clazz); } return super.visit(clazz, ctx); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/AbstractRuleTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/AbstractRuleTest.java index 8c861065a86..be5151893d3 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/AbstractRuleTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/AbstractRuleTest.java @@ -160,7 +160,9 @@ void testEquals3() { @Test void testEquals4() { MyRule myRule = new MyRule(); - assertFalse(myRule.equals("MyRule"), "A rule cannot be equal to an object of another class"); + @SuppressWarnings("PMD.LiteralsFirstInComparisons") // we really want to call equals on MyRule + boolean result = myRule.equals("MyRule"); + assertFalse(result, "A rule cannot be equal to an object of another class"); } @Test diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java index 3e67afd1947..d0b6fb60f5e 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/DummyLanguageModule.java @@ -104,7 +104,7 @@ public static class Handler extends AbstractPmdLanguageVersionHandler { @Override public Parser getParser() { return task -> { - if (task.getLanguageVersion().getVersion().equals(PARSER_THROWS)) { + if (PARSER_THROWS.equals(task.getLanguageVersion().getVersion())) { throw new ParseException("ohio"); } return readLispNode(task); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/internal/NodeStreamBlanketTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/internal/NodeStreamBlanketTest.java index 755f948c7c2..83be8001b3c 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/internal/NodeStreamBlanketTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/ast/internal/NodeStreamBlanketTest.java @@ -236,7 +236,7 @@ static Collection> allNodeStreamVariants() { stream.precedingSiblings(), stream.descendantsOrSelf(), stream.children(), - stream.children().filter(c -> c.getImage().equals("0")), + stream.children().filter(c -> "0".equals(c.getImage())), stream.children(DummyNode.class) ) ).flatMap( diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleSetTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleSetTest.java index b566236ec53..af91181fc99 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleSetTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleSetTest.java @@ -215,7 +215,9 @@ void testEquals3() { .withName("basic rules") .withDescription("desc") .build(); - assertFalse(s.equals("basic rules"), "A ruleset cannot be equals to another kind of object"); + @SuppressWarnings("PMD.LiteralsFirstInComparisons") // we really want to call equals on RuleSet + boolean result = s.equals("basic rules"); + assertFalse(result, "A ruleset cannot be equals to another kind of object"); } @Test diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/internal/LatticeRelationTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/internal/LatticeRelationTest.java index 1670e9307c7..df237b9d6d7 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/internal/LatticeRelationTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/internal/LatticeRelationTest.java @@ -207,7 +207,7 @@ void testFilterOnChain() { void testTransitiveSucc() { LatticeRelation> lattice = - stringLattice(s -> s.equals("c") || s.equals("bc")); + stringLattice(s -> "c".equals(s) || "bc".equals(s)); lattice.put("abc", "val"); lattice.put("bc", "v2"); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/util/IteratorUtilTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/util/IteratorUtilTest.java index c58f39afc06..4be176e648d 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/util/IteratorUtilTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/util/IteratorUtilTest.java @@ -149,7 +149,7 @@ void testFlatmapEmpty2() { void testFlatmapIsLazy() { Iterator iter = iterOf("a", "b"); Function> fun = s -> { - if (s.equals("a")) { + if ("a".equals(s)) { return iterOf("a"); } else { throw new AssertionError("This statement shouldn't be reached"); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/util/treeexport/XmlTreeRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/util/treeexport/XmlTreeRendererTest.java index 49986694c60..10380a0c6cf 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/util/treeexport/XmlTreeRendererTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/util/treeexport/XmlTreeRendererTest.java @@ -130,7 +130,7 @@ void testRenderFilterAttributes() throws IOException { XmlRenderingConfig strategy = new XmlRenderingConfig() { @Override public boolean takeAttribute(Node node, Attribute attribute) { - return attribute.getName().equals("ohio"); + return "ohio".equals(attribute.getName()); } }.lineSeparator("\n"); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/FooRule.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/FooRule.java index 7aed17c8510..a67ed0386af 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/FooRule.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/FooRule.java @@ -20,7 +20,7 @@ public FooRule(String message) { @Override public Object visit(ASTClassDeclaration c, Object ctx) { - if (c.getSimpleName().equalsIgnoreCase("Foo")) { + if ("Foo".equalsIgnoreCase(c.getSimpleName())) { asCtx(ctx).addViolation(c); } return super.visit(c, ctx); @@ -28,7 +28,7 @@ public Object visit(ASTClassDeclaration c, Object ctx) { @Override public Object visit(ASTVariableId c, Object ctx) { - if (c.getName().equalsIgnoreCase("Foo")) { + if ("Foo".equalsIgnoreCase(c.getName())) { asCtx(ctx).addViolation(c); } return super.visit(c, ctx); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/TypeAnnotTestUtil.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/TypeAnnotTestUtil.java index 05ad17dba8d..37f0364fb7d 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/TypeAnnotTestUtil.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/internal/TypeAnnotTestUtil.java @@ -84,13 +84,13 @@ public static A createAnnotationInstance(Class annotat @SuppressWarnings("unchecked") public static A createAnnotationInstance(Class annotationClass, Map attributes) { return (A) Proxy.newProxyInstance(annotationClass.getClassLoader(), new Class[] { annotationClass }, (proxy, method, args) -> { - if (method.getName().equals("annotationType") && args == null) { + if ("annotationType".equals(method.getName()) && args == null) { return annotationClass; - } else if (method.getName().equals("toString") && args == null) { + } else if ("toString".equals(method.getName()) && args == null) { return AnnotationUtils.toString((Annotation) proxy); - } else if (method.getName().equals("hashCode") && args == null) { + } else if ("hashCode".equals(method.getName()) && args == null) { return AnnotationUtils.hashCode((Annotation) proxy); - } else if (method.getName().equals("equals") && args.length == 1) { + } else if ("equals".equals(method.getName()) && args.length == 1) { if (args[0] instanceof Annotation) { return AnnotationUtils.equals((Annotation) proxy, (Annotation) args[0]); } diff --git a/pom.xml b/pom.xml index a5c3ae583c5..4f8e75cd3be 100644 --- a/pom.xml +++ b/pom.xml @@ -555,10 +555,6 @@ /net/sourceforge/pmd/pmd-dogfood-config.xml - - target/generated-sources/javacc - target/generated-sources/antlr4 - @@ -585,6 +581,10 @@ 2 true true + + target/generated-sources/javacc + target/generated-sources/antlr4 + From 4a2191da8150a33b92f71df9255003e2e61744b2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Aug 2025 18:24:01 +0200 Subject: [PATCH 1219/1962] Update pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java Co-authored-by: Zbynek Konecny --- .../OverrideBothEqualsAndHashCodeOnComparableRule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java index fa84becf465..d6085df7320 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java @@ -20,7 +20,7 @@ * @since 7.17.0 */ public class OverrideBothEqualsAndHashCodeOnComparableRule extends OverrideBothEqualsAndHashcodeRule { - private static final String MESSAGE_PREFIX = "When implementing Comparable "; + private static final String MESSAGE_PREFIX = "When implementing Comparable, "; private static final String MISSING_HASH_CODE = MESSAGE_PREFIX + "hashCode() should be overridden"; private static final String MISSING_EQUALS = MESSAGE_PREFIX + "equals() should be overridden"; private static final String MISSING_EQUALS_AND_HASH_CODE = MESSAGE_PREFIX + "both equals() and hashCode() should be overridden"; From 980137a5ae6aace7c943b631e747efa749218151 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 1 Aug 2025 18:40:49 +0200 Subject: [PATCH 1220/1962] Fix tests --- ...rrideBothEqualsAndHashCodeOnComparable.xml | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml index 6e512d5bd78..652d837a21c 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml @@ -8,7 +8,7 @@ 1 3 - When implementing Comparable both equals() and hashCode() should be overridden + When implementing Comparable, both equals() and hashCode() should be overridden { @@ -24,7 +24,7 @@ 1 8 - When implementing Comparable hashCode() should be overridden + When implementing Comparable, hashCode() should be overridden { @@ -45,7 +45,7 @@ 1 8 - When implementing Comparable equals() should be overridden + When implementing Comparable, equals() should be overridden { @@ -115,7 +115,7 @@ 1 3 - When implementing Comparable both equals() and hashCode() should be overridden + When implementing Comparable, both equals() and hashCode() should be overridden { @@ -135,7 +135,7 @@ 1 3 - When implementing Comparable both equals() and hashCode() should be overridden + When implementing Comparable, both equals() and hashCode() should be overridden 1 4 - When implementing Comparable both equals() and hashCode() should be overridden + When implementing Comparable, both equals() and hashCode() should be overridden 1 3 - When implementing Comparable both equals() and hashCode() should be overridden + When implementing Comparable, both equals() and hashCode() should be overridden { @@ -253,7 +253,7 @@ 1 8 - When implementing Comparable hashCode() should be overridden + When implementing Comparable, hashCode() should be overridden { @@ -274,7 +274,7 @@ 1 8 - When implementing Comparable equals() should be overridden + When implementing Comparable, equals() should be overridden { @@ -325,7 +325,7 @@ 1 3 - When implementing Comparable both equals() and hashCode() should be overridden + When implementing Comparable, both equals() and hashCode() should be overridden { From 0dd2cef1ade7cae1a4790cd00f52f1fb8cca905f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Sat, 2 Aug 2025 15:51:34 +0200 Subject: [PATCH 1221/1962] Improve message/description/examples for AvoidUsingOctalValues --- .../resources/category/java/errorprone.xml | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index d0ecc602c87..7b538aa7fef 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -656,19 +656,30 @@ int j = -~7; -Integer literals should not start with zero since this denotes that the rest of literal will be -interpreted as an octal value. +Integer literals that start with zero are interpreted as octal (base-8) values in Java, which can lead to +unexpected behavior and bugs. Most developers expect decimal (base-10) interpretation, making octal literals +a common source of confusion and errors. For example, 012 equals 10 in decimal, not 12 as might be expected. +This rule helps prevent such mistakes by flagging integer literals that could be misinterpreted as decimal values. +Use decimal literals without leading zeros, or use explicit prefixes like 0x for hexadecimal or 0b for binary values to make the intended base clear. 3 From 6d25599b3a7a297ce56461e66565253eca4a7e60 Mon Sep 17 00:00:00 2001 From: Jude Pereira Date: Sat, 2 Aug 2025 16:59:57 +0200 Subject: [PATCH 1222/1962] Add begin and end for line and columns (default off). --- .../pmd/renderers/CSVRenderer.java | 41 ++++++++++++++----- .../pmd/renderers/ColumnDescriptor.java | 8 +++- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java index 8092c5ac8ca..4e502308a85 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java @@ -4,21 +4,16 @@ package net.sourceforge.pmd.renderers; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.apache.commons.lang3.StringUtils; -import org.checkerframework.checker.nullness.qual.NonNull; - import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.properties.PropertyFactory; import net.sourceforge.pmd.properties.PropertySource; import net.sourceforge.pmd.renderers.ColumnDescriptor.Accessor; import net.sourceforge.pmd.reporting.RuleViolation; +import org.apache.commons.lang3.StringUtils; +import org.checkerframework.checker.nullness.qual.NonNull; + +import java.io.IOException; +import java.util.*; /** @@ -39,6 +34,22 @@ public class CSVRenderer extends AbstractIncrementingRenderer { public static final String NAME = "csv"; + private static final String PROP_BEGIN_LINE = "beginLine"; + private static final String PROP_END_LINE = "endLine"; + private static final String PROP_BEGIN_COL = "beginCol"; + private static final String PROP_END_COL = "endCol"; + + private static final Set DEFAULT_OFF; + + static { + HashSet set = new HashSet<>(); + set.add(PROP_BEGIN_LINE); + set.add(PROP_END_LINE); + set.add(PROP_BEGIN_COL); + set.add(PROP_END_COL); + DEFAULT_OFF = Collections.unmodifiableSet(set); + } + @SuppressWarnings("unchecked") private final ColumnDescriptor[] allColumns = new ColumnDescriptor[] { newColDescriptor("problem", "Problem", (idx, rv, cr) -> Integer.toString(idx)), @@ -49,12 +60,20 @@ public class CSVRenderer extends AbstractIncrementingRenderer { newColDescriptor("desc", "Description", (idx, rv, cr) -> StringUtils.replaceChars(rv.getDescription(), '\"', '\'')), newColDescriptor("ruleSet", "Rule set", (idx, rv, cr) -> rv.getRule().getRuleSetName()), newColDescriptor("rule", "Rule", (idx, rv, cr) -> rv.getRule().getName()), + newColDescriptor(PROP_BEGIN_LINE, "Begin Line", (idx, rv, cr) -> Integer.toString(rv.getBeginLine()), false), + newColDescriptor(PROP_END_LINE, "End Line", (idx, rv, cr) -> Integer.toString(rv.getEndLine()), false), + newColDescriptor(PROP_BEGIN_COL, "Begin Column", (idx, rv, cr) -> Integer.toString(rv.getBeginColumn()), false), + newColDescriptor(PROP_END_COL, "End Column", (idx, rv, cr) -> Integer.toString(rv.getEndColumn()), false), }; private static @NonNull ColumnDescriptor newColDescriptor(String id, String title, Accessor accessor) { return new ColumnDescriptor<>(id, title, accessor); } + private static @NonNull ColumnDescriptor newColDescriptor(String id, String title, Accessor accessor, boolean enabled) { + return new ColumnDescriptor<>(id, title, accessor, enabled); + } + public CSVRenderer(ColumnDescriptor[] columns, String theSeparator, String theCR) { super(NAME, "Comma-separated values tabular format."); @@ -84,7 +103,7 @@ private static PropertyDescriptor booleanPropertyFor(String id, String return prop; } - prop = PropertyFactory.booleanProperty(id).defaultValue(true).desc("Include " + label + " column").build(); + prop = PropertyFactory.booleanProperty(id).defaultValue(!DEFAULT_OFF.contains(id)).desc("Include " + label + " column").build(); PROPERTY_DESCRIPTORS_BY_ID.put(id, prop); return prop; } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/ColumnDescriptor.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/ColumnDescriptor.java index d9752c3537c..6716fffc01d 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/ColumnDescriptor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/ColumnDescriptor.java @@ -12,15 +12,21 @@ final class ColumnDescriptor { public final String id; public final String title; public final Accessor accessor; + public final boolean enabled; public interface Accessor { String get(int idx, T violation, String lineSeparator); } - ColumnDescriptor(String theId, String theTitle, Accessor theAccessor) { + ColumnDescriptor(String theId, String theTitle, Accessor theAccessor, boolean theEnabled) { id = theId; title = theTitle; accessor = theAccessor; + enabled = theEnabled; + } + + ColumnDescriptor(String theId, String theTitle, Accessor theAccessor) { + this(theId, theTitle, theAccessor, true); } } From 4f425c4b35eb24afe24a2d8184c4b90c85c69544 Mon Sep 17 00:00:00 2001 From: Jude Pereira Date: Sat, 2 Aug 2025 17:06:23 +0200 Subject: [PATCH 1223/1962] Remove wildcard import. --- .../java/net/sourceforge/pmd/renderers/CSVRenderer.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java index 4e502308a85..5e7b5603589 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java @@ -13,7 +13,14 @@ import org.checkerframework.checker.nullness.qual.NonNull; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; /** From d86214966130b56e130b1157638ced1fca51c95a Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Sat, 2 Aug 2025 18:03:13 +0200 Subject: [PATCH 1224/1962] Improve message location for AddEmptyString rule --- .../java/rule/performance/AddEmptyStringRule.java | 9 +++++---- .../java/rule/performance/xml/AddEmptyString.xml | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/AddEmptyStringRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/AddEmptyStringRule.java index 9a549e2be1c..b7ebcf6190f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/AddEmptyStringRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/AddEmptyStringRule.java @@ -28,22 +28,23 @@ public Object visit(ASTStringLiteral node, Object data) { return null; } JavaNode parent = node.getParent(); - checkExpr(data, parent); + checkExpr(data, parent, node); if (parent instanceof ASTVariableDeclarator) { ASTVariableId varId = ((ASTVariableDeclarator) parent).getVarId(); if (varId.hasModifiers(JModifier.FINAL)) { for (ASTNamedReferenceExpr usage : varId.getLocalUsages()) { - checkExpr(data, usage.getParent()); + checkExpr(data, usage.getParent(), usage); } } } return null; } - private void checkExpr(Object data, JavaNode parent) { + private void checkExpr(Object data, JavaNode parent, JavaNode emptyStringNode) { if (JavaAstUtils.isInfixExprWithOperator(parent, BinaryOp.ADD) && parent.ancestors(ASTAnnotation.class).isEmpty()) { - asCtx(data).addViolation(parent); + asCtx(data).addViolationWithPosition(parent, parent.getAstInfo(), + emptyStringNode.getReportLocation(), getMessage()); } } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/AddEmptyString.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/AddEmptyString.xml index 052a50f8efe..bc9fb9eefbb 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/AddEmptyString.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/AddEmptyString.xml @@ -116,6 +116,20 @@ class Main { void otherMethod() { final String otherString = ""; } +} + ]]> + + + + Message location for multiline expression + 5 + 2,3,3,4,5 + From 3231a0289860e45d54e16a849ef42d1cdf10027a Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Sun, 3 Aug 2025 11:15:11 +0200 Subject: [PATCH 1225/1962] [java] Add details to some violation messages to avoid duplicates --- .../design/FinalFieldCouldBeStaticRule.java | 2 +- .../errorprone/AssignmentInOperandRule.java | 9 +++++++-- .../main/resources/category/java/design.xml | 6 +++--- .../resources/category/java/errorprone.xml | 4 ++-- .../xml/AvoidThrowingRawExceptionTypes.xml | 17 +++++++++++++++++ .../AvoidUncheckedExceptionsInSignatures.xml | 15 +++++++++++++++ .../design/xml/FinalFieldCouldBeStatic.xml | 13 +++++++++++++ .../errorprone/xml/AssignmentInOperand.xml | 19 +++++++++++++++++++ .../xml/AvoidLiteralsInIfCondition.xml | 18 ++++++++++++++++++ 9 files changed, 95 insertions(+), 8 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/FinalFieldCouldBeStaticRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/FinalFieldCouldBeStaticRule.java index a2e251251ec..62e0333191a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/FinalFieldCouldBeStaticRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/FinalFieldCouldBeStaticRule.java @@ -43,7 +43,7 @@ public Object visit(ASTFieldDeclaration node, Object data) { for (ASTVariableId field : node) { ASTExpression init = field.getInitializer(); if (init != null && isAllowedExpression(init) && !isUsedForSynchronization(field)) { - asCtx(data).addViolation(field); + asCtx(data).addViolation(field, field.getName()); } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java index 23065e209cf..5764be8bd9e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java @@ -12,6 +12,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTForStatement; import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; import net.sourceforge.pmd.lang.java.ast.ASTUnaryExpression; +import net.sourceforge.pmd.lang.java.ast.ASTVariableAccess; import net.sourceforge.pmd.lang.java.ast.ASTWhileStatement; import net.sourceforge.pmd.lang.java.ast.JavaNode; import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; @@ -78,8 +79,12 @@ private void checkAssignment(ASTExpression impureExpr, RuleContext ctx) { if (parent instanceof ASTIfStatement && !getProperty(ALLOW_IF_DESCRIPTOR) || parent instanceof ASTWhileStatement && !getProperty(ALLOW_WHILE_DESCRIPTOR) || parent instanceof ASTForStatement && ((ASTForStatement) parent).getCondition() == toplevel && !getProperty(ALLOW_FOR_DESCRIPTOR)) { - - ctx.addViolation(impureExpr); + JavaNode firstChild = impureExpr.getChild(0); + if (firstChild instanceof ASTVariableAccess) { + ctx.addViolation(impureExpr, ((ASTVariableAccess) firstChild).getName()); + } else { + ctx.addViolationWithMessage(impureExpr, "Avoid assignments in operands"); + } } } diff --git a/pmd-java/src/main/resources/category/java/design.xml b/pmd-java/src/main/resources/category/java/design.xml index 5f5a4ef9c15..9cc887f4489 100644 --- a/pmd-java/src/main/resources/category/java/design.xml +++ b/pmd-java/src/main/resources/category/java/design.xml @@ -242,7 +242,7 @@ public class Foo { @@ -282,7 +282,7 @@ public class Foo { @@ -716,7 +716,7 @@ public class Foo { diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index d0ecc602c87..1ffba009292 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -12,7 +12,7 @@ Rules to detect constructs that are either broken, extremely confusing or prone @@ -494,7 +494,7 @@ try { // Prefer this: diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidThrowingRawExceptionTypes.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidThrowingRawExceptionTypes.xml index d61ae828a60..e4d9ae0992b 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidThrowingRawExceptionTypes.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidThrowingRawExceptionTypes.xml @@ -82,6 +82,23 @@ public class Foo { public void bar() { throw new IOException(); } +} + ]]> + + + Distinct error messages for the same line + 2 + 4,4 + + Avoid throwing raw exception type Error. + Avoid throwing raw exception type RuntimeException. + + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidUncheckedExceptionsInSignatures.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidUncheckedExceptionsInSignatures.xml index cf7fde8f5a6..aca0665ff1f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidUncheckedExceptionsInSignatures.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidUncheckedExceptionsInSignatures.xml @@ -130,6 +130,21 @@ public interface Foo { + + + + Distinct error messages for the same line + 2 + 2,2 + + A method or constructor should not explicitly declare unchecked exception IllegalArgumentException in its 'throws' clause + A method or constructor should not explicitly declare unchecked exception NullPointerException in its 'throws' clause + + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/FinalFieldCouldBeStatic.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/FinalFieldCouldBeStatic.xml index fbddc8efd3a..275bab3af3c 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/FinalFieldCouldBeStatic.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/FinalFieldCouldBeStatic.xml @@ -406,6 +406,19 @@ class MyConstants { private final int BYTEPOWER = 3; private final int BYTEMASK = (1 << BYTEPOWER) - 1; //this one cannot } +]]> + + + Distinct error messages for the same line + 2 + + The final field FOO could be made static + The final field BAR could be made static + + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml index 5e1eca9d6c4..3cfb209dee2 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml @@ -169,4 +169,23 @@ public class Foo { } ]]> + + Distinct error messages for the same line + 2 + + Avoid assignment to x in operand + Avoid assignment to y in operand + + (y = 5)) { + x = 2; + } + } +} +]]> + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AvoidLiteralsInIfCondition.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AvoidLiteralsInIfCondition.xml index 418dccf581c..044e221f839 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AvoidLiteralsInIfCondition.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AvoidLiteralsInIfCondition.xml @@ -176,4 +176,22 @@ public class AvoidLiteralsInIfCondition { 4,5,8,9,9 + + + Distinct error messages for the same line + false + 2 + 3,3 + + Avoid using literals such as 7 in if statements + Avoid using literals such as "baz" in if statements + + "baz".length()) {} + } +} + ]]> + From 665aebb4ba26e3dace92b51067079b2bb87167fc Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Mon, 4 Aug 2025 01:22:52 +0200 Subject: [PATCH 1226/1962] Reduce test class visibility --- .../lang/java/rule/errorprone/UselessPureMethodCallTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessPureMethodCallTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessPureMethodCallTest.java index 021f37c018d..b5e0b318bef 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessPureMethodCallTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessPureMethodCallTest.java @@ -9,6 +9,6 @@ /** * Test for {@link UselessPureMethodCallRule}. */ -public class UselessPureMethodCallTest extends PmdRuleTst { +class UselessPureMethodCallTest extends PmdRuleTst { // no additional unit tests } From 664286134d181044e8aff543426cf1173dbfc915 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 5 Aug 2025 20:07:23 +0200 Subject: [PATCH 1227/1962] Fix #5881: AvoidLosingException - Consider nested method calls --- docs/pages/release_notes.md | 2 ++ .../resources/category/java/errorprone.xml | 2 +- .../xml/AvoidLosingExceptionInformation.xml | 21 +++++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 97e90ae9123..31535aa5209 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -40,6 +40,8 @@ This is a {{ site.pmd.release_type }} release. * [#5874](https://github.com/pmd/pmd/issues/5874): \[java] Update java regression tests with Java 25 language features * java-codestyle * [#972](https://github.com/pmd/pmd/issues/972): \[java] Improve naming conventions rules +* java-errorprone + * [#5881](https://github.com/pmd/pmd/issues/5881): \[java] AvoidLosingExceptionInformation does not trigger when inside if-else ### ๐Ÿšจ API Changes diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index d0ecc602c87..49761541638 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -587,7 +587,7 @@ only add to code size. Either remove the invocation, or use the return result. + + + + #5881 [java] AvoidLosingExceptionInformation does not trigger when inside if-else + 2 + 7,9 + From 20fecebce97d17c53bd913d227e5f6719418cbee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Aug 2025 20:14:40 +0200 Subject: [PATCH 1228/1962] chore(deps): bump scalameta.version from 4.13.8 to 4.13.9 (#5962) Bumps `scalameta.version` from 4.13.8 to 4.13.9. Updates `org.scalameta:parsers_2.13` from 4.13.8 to 4.13.9 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.8...v4.13.9) Updates `org.scalameta:trees_2.13` from 4.13.8 to 4.13.9 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.8...v4.13.9) Updates `org.scalameta:parsers_2.12` from 4.13.8 to 4.13.9 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.8...v4.13.9) Updates `org.scalameta:trees_2.12` from 4.13.8 to 4.13.9 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.8...v4.13.9) --- updated-dependencies: - dependency-name: org.scalameta:parsers_2.13 dependency-version: 4.13.9 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:trees_2.13 dependency-version: 4.13.9 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:parsers_2.12 dependency-version: 4.13.9 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:trees_2.12 dependency-version: 4.13.9 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index 4f4ea16e798..05139a5d96e 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -13,7 +13,7 @@ - 4.13.8 + 4.13.9 From 0cbaba5b9c0e5c050f77be4a4b82f447998745e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Aug 2025 20:15:08 +0200 Subject: [PATCH 1229/1962] chore(deps-dev): bump org.apache.commons:commons-compress from 1.27.1 to 1.28.0 (#5963) chore(deps-dev): bump org.apache.commons:commons-compress Bumps [org.apache.commons:commons-compress](https://github.com/apache/commons-compress) from 1.27.1 to 1.28.0. - [Changelog](https://github.com/apache/commons-compress/blob/master/RELEASE-NOTES.txt) - [Commits](https://github.com/apache/commons-compress/compare/rel/commons-compress-1.27.1...rel/commons-compress-1.28.0) --- updated-dependencies: - dependency-name: org.apache.commons:commons-compress dependency-version: 1.28.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-dist/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index c57d86cb9f2..63170d36759 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -178,7 +178,7 @@ org.apache.commons commons-compress - 1.27.1 + 1.28.0 test From b652b171b586c3a53e8370451bfaaa5237352b7a Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Tue, 5 Aug 2025 22:13:17 +0200 Subject: [PATCH 1230/1962] Better test description Co-authored-by: Andreas Dangel --- .../pmd/lang/java/rule/errorprone/xml/UselessPureMethodCall.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessPureMethodCall.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessPureMethodCall.xml index dfd353c69d0..1787f7d9b1f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessPureMethodCall.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessPureMethodCall.xml @@ -26,7 +26,7 @@ public class Foo { ]]> - Throwable methods + Throwable methods (formerly rule AvoidLosingExceptionInformation) 4 6,7,8,9 Date: Thu, 7 Aug 2025 08:57:16 +0200 Subject: [PATCH 1231/1962] Add @mrclmh as a contributor --- .all-contributorsrc | 9 +++++++++ docs/pages/pmd/projectdocs/credits.md | 29 ++++++++++++++------------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index aa2c07306b6..5374bba5377 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8188,6 +8188,15 @@ "bug", "code" ] + }, + { + "login": "mrclmh", + "name": "mrclmh", + "avatar_url": "https://avatars.githubusercontent.com/u/2975481?v=4", + "profile": "https://github.com/mrclmh", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index c6ec56c96d5..c152481d0e3 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -1038,126 +1038,127 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d

    - + + - + - + - + - + - + - + - + - + - + - + - + - + - + From 2ee3bf13356b0d6986e066fa8adaae16bbd6551f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 7 Aug 2025 09:03:02 +0200 Subject: [PATCH 1232/1962] [java] ReplaceJavaUtilDate - improve doc to mention java.sql.Date Refs #5966 --- .../resources/category/java/errorprone.xml | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index d0ecc602c87..6250c1a29eb 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -2444,11 +2444,15 @@ public class Foo { class="net.sourceforge.pmd.lang.rule.xpath.XPathRule" externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#replacejavautilcalendar"> -The legacy java.util.Calendar API is error-prone, mutable, and not thread-safe. It has confusing month indexing -(January = 0), inconsistent field semantics, and verbose usage patterns. The modern java.time API (introduced in Java 8) -provides immutable, thread-safe alternatives with clear, intuitive methods. +The legacy `java.util.Calendar` API is error-prone, mutable, and not thread-safe. It has confusing month indexing +(January = 0), inconsistent field semantics, and verbose usage patterns. The modern `java.time API` +(introduced in Java 8) provides immutable, thread-safe alternatives with clear, intuitive methods. -Use LocalDate (for date-only operations), LocalDateTime (for date and time), or ZonedDateTime (when timezone is important) from java.time package instead. +Use `LocalDate` (for date-only operations), `LocalDateTime` (for date and time), or `ZonedDateTime` +(when timezone is important) from `java.time` package instead. + +Note: Since JPA 3.2 (Jakarta Persistence) usage of `java.util.Date` and `java.util.Calendar` and others is +deprecated there as well in favour of `java.time` API. 3 @@ -2500,13 +2504,18 @@ public class Foo { class="net.sourceforge.pmd.lang.rule.xpath.XPathRule" externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#replacejavautildate"> -The legacy java.util.Date class is mutable, not thread-safe, and has a confusing API. Many of its methods -are deprecated, it doesn't handle timezones properly, and it represents both date and time even when only -one is needed. The constructor parameters are particularly error-prone: year is "years since 1900" and -month is 0-based (January = 0). The modern java.time API (introduced in Java 8) provides better type safety, immutability, and clearer semantics. +The legacy `java.util.Date` class is mutable, not thread-safe, and has a confusing API. Many of its methods +are deprecated, it doesn't handle timezones properly, and it represents both date and time even when only +one is needed. The constructor parameters are particularly error-prone: year is "years since 1900" and +month is 0-based (January = 0). The modern java.time API (introduced in Java 8) provides better type safety, +immutability, and clearer semantics. + +Use `LocalDate` (date only), `LocalTime` (time only), `LocalDateTime` (date and time), `Instant` (timestamp), +or `ZonedDateTime` (date-time with timezone) from `java.time` package instead. -Use LocalDate (date only), LocalTime (time only), LocalDateTime (date and time), Instant (timestamp), -or ZonedDateTime (date-time with timezone) from java.time package instead. +Note: This includes subtypes such as `java.sql.Date`, `java.sql.Time` and `java.sql.Timestamp`. +Since JPA 3.2 (Jakarta Persistence) usage of `java.util.Date` and `java.util.Calendar` and others is +deprecated there as well in favour of `java.time` API. 3 From 55eccae4f36f0365d347d0699c28033e27fdd04c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Thu, 7 Aug 2025 09:26:36 +0200 Subject: [PATCH 1233/1962] Feedback from review --- .../pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml index c9935b8f2ba..5464f524490 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml @@ -106,7 +106,7 @@ public class Foo { - assignment in do-while conditional expression + #5915 assignment in do-while conditional expression 1 6 Avoid assignments in operands From 0c769110245652f9db4e3781713565e84af467b8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 7 Aug 2025 10:05:35 +0200 Subject: [PATCH 1234/1962] [doc] Add logging page to sidebar under dev docs This has been apparently forgotten with #896. --- docs/_data/sidebars/pmd_sidebar.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/_data/sidebars/pmd_sidebar.yml b/docs/_data/sidebars/pmd_sidebar.yml index 5596665211f..9d7dadda5ba 100644 --- a/docs/_data/sidebars/pmd_sidebar.yml +++ b/docs/_data/sidebars/pmd_sidebar.yml @@ -583,6 +583,9 @@ entries: - title: How PMD works url: /pmd_devdocs_how_pmd_works.html output: web, pdf + - title: Logging + url: /pmd_devdocs_logging.html + output: web, pdf - title: Pmdtester url: /pmd_devdocs_pmdtester.html output: web, pdf From 6eb63af1a3788122bf8d011fa711b94edcc3f03c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Thu, 7 Aug 2025 10:33:11 +0200 Subject: [PATCH 1235/1962] Feedback from review --- pmd-java/src/main/resources/category/java/bestpractices.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 4e6e068a21e..95e0d19e1cf 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -1174,6 +1174,11 @@ Be sure to specify a character set for APIs that use the JVM's default character stable encoding behavior between different JVMs, programs, and servers. Using the platform's default charset makes the code less portable and might lead to unexpected behavior when running on different systems. + +Additional, since Java 18, the default charset for these APIs is consistently UTF-8 +(see [JEP 400](https://openjdk.org/jeps/400)). While this reduces unexpected behavior +on different systems, it is still advised to explicitly specify a character set, +especially if UTF-8 is not the desired charset. 3 From 6343ad9bb81a016a3887026d59aec04af7a80d2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Thu, 7 Aug 2025 11:03:11 +0200 Subject: [PATCH 1236/1962] Feedback from review --- .../rule/bestpractices/xml/AvoidReassigningLoopVariables.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidReassigningLoopVariables.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidReassigningLoopVariables.xml index d4ddb5cc984..870db0d8c81 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidReassigningLoopVariables.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidReassigningLoopVariables.xml @@ -693,8 +693,8 @@ public class Foo { doSomethingWith(i++); i = i + 1; i = i - 1; - i = 1 + i; - i = 1 - i; // not OK + i = 1 + i; // OK: same as i++ + i = 1 - i; // not OK: this is not the same as i-- i -= 2; // not OK i += 2; // not OK i &= 1; // not OK From 7b951120331cd14152524fac10c1eb293bf699bf Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 7 Aug 2025 15:14:50 +0200 Subject: [PATCH 1237/1962] [java] UselessPureMethodCall - update docs and tests --- .../errorprone/UselessPureMethodCallRule.java | 2 ++ .../resources/category/java/errorprone.xml | 16 +++++++++----- .../errorprone/xml/UselessPureMethodCall.xml | 21 +++++++++++++++++++ 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessPureMethodCallRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessPureMethodCallRule.java index ef5148e8799..c8dbef3e599 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessPureMethodCallRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessPureMethodCallRule.java @@ -11,6 +11,8 @@ /** * Reports usages of pure methods where the result is ignored. + * + * @since 7.17.0 */ public class UselessPureMethodCallRule extends AbstractJavaRulechainRule { diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index af94649c401..4df7b9fe4a7 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -580,9 +580,11 @@ public void checkRequests() { externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidlosingexceptioninformation" deprecated="true"> -This rule is *deprecated* in favor of {% rule java/errorprone/UselessPureMethodCall %}. Statements in a catch block that invoke accessors on the exception without using the information only add to code size. Either remove the invocation, or use the return result. + +**Deprecated:** This rule is deprecated since PMD 7.17.0 and will be removed with PMD 8.0.0. +This rule has been replaced by {% rule UselessPureMethodCall %}. 2 @@ -3255,12 +3257,13 @@ public boolean test(String s) { externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#uselessoperationonimmutable" deprecated="true"> -This rule is *deprecated* in favor of {% rule java/errorprone/UselessPureMethodCall %}. - An operation on an immutable object will not change the object itself since the result of the operation is a new object. Therefore, ignoring the result of such an operation is likely a mistake. The operation can probably be removed. This rule recognizes the types `String`, `BigDecimal`, `BigInteger` or any type from `java.time.*` as immutable. + +**Deprecated:** This rule is deprecated since PMD 7.17.0 and will be removed with PMD 8.0.0. +This rule has been replaced by {% rule UselessPureMethodCall %}. 3 @@ -3283,12 +3286,15 @@ class Test { - Useless Pure Method Call detects when a pure method is called and the result is unused. +This rule detects method calls of pure methods whose result is unused. A pure method is a method without +side effects. Therefore, ignoring the result of such a method call is likely a mistake. + +Either the method call can be removed or the result should be used. 3 diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessPureMethodCall.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessPureMethodCall.xml index 1787f7d9b1f..c4b76988df3 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessPureMethodCall.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessPureMethodCall.xml @@ -48,6 +48,27 @@ public class Foo { ]]> + + #5881 [java] AvoidLosingExceptionInformation does not trigger when inside if-else + 2 + 7,9 + + + String methods 3 From f7dc909e1bd05ea54cd6b8751fb458ff7fef4769 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 7 Aug 2025 15:20:57 +0200 Subject: [PATCH 1238/1962] [doc] Update release notes (#5907) --- docs/pages/release_notes.md | 9 +++++++++ pmd-java/src/main/resources/rulesets/java/quickstart.xml | 3 +-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 97e90ae9123..80edce1fd9e 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -30,10 +30,18 @@ This is a {{ site.pmd.release_type }} release. generic types and methods. It can be configured via a regular expression. By default, this rule uses the standard Java naming convention (single uppercase letter). The rule is referenced in the quickstart.xml ruleset for Java. +* The new java rule {% rule java/errorprone/UselessPureMethodCall %} finds method calls of pure methods + whose result is not used. Ignoring the result of such method calls is likely as mistake as pure + methods are side effect free. + The rule is referenced in the quickstart.xml ruleset for Java. #### Deprecated Rules * The java rule {% rule java/codestyle/GenericsNaming %} has been deprecated for removal in favor of the new rule {% rule java/codestyle/TypeParameterNamingConventions %}. +* The java rule {% rule java/errorprone/AvoidLosingExceptionInformation %} has been deprecated for removal + in favor of the new rule {% rule java/errorprone/UselessPureMethodCall %}. +* The java rule {% rule java/errorprone/UselessOperationOnImmutable %} has been deprecated for removal + in favor of the new rule {% rule java/errorprone/UselessPureMethodCall %}. ### ๐Ÿ› Fixed Issues * java @@ -45,6 +53,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ Merged pull requests +* [#5907](https://github.com/pmd/pmd/pull/5907): \[java] New rule: UselessPureMethodCall - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#5922](https://github.com/pmd/pmd/pull/5922): Fix #972: \[java] Add a new rule TypeParameterNamingConventions - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5932](https://github.com/pmd/pmd/pull/5932): \[ci] Reuse GitHub Pre-Releases - [Andreas Dangel](https://github.com/adangel) (@adangel) diff --git a/pmd-java/src/main/resources/rulesets/java/quickstart.xml b/pmd-java/src/main/resources/rulesets/java/quickstart.xml index 436645c8c8f..c7be6980059 100644 --- a/pmd-java/src/main/resources/rulesets/java/quickstart.xml +++ b/pmd-java/src/main/resources/rulesets/java/quickstart.xml @@ -201,7 +201,6 @@ - @@ -272,7 +271,7 @@ - + From 2ab1128807e8ecbfb1ce056e138b028c74e9389d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 7 Aug 2025 15:40:33 +0200 Subject: [PATCH 1239/1962] Update suppressing_warnings.md --- docs/pages/pmd/userdocs/suppressing_warnings.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/pages/pmd/userdocs/suppressing_warnings.md b/docs/pages/pmd/userdocs/suppressing_warnings.md index 9da06db19a5..60d2565dc05 100644 --- a/docs/pages/pmd/userdocs/suppressing_warnings.md +++ b/docs/pages/pmd/userdocs/suppressing_warnings.md @@ -5,7 +5,7 @@ tags: [userdocs] summary: "Learn how to suppress some rule violations, from the source code using annotations or comments, or globally from the ruleset" permalink: pmd_userdocs_suppressing_warnings.html author: Tom Copeland -last_updated: May 2025 (7.14.0) +last_updated: July 2025 (7.17.0) --- PMD provides several methods by which Rule violations can be suppressed. @@ -117,7 +117,7 @@ public class Foo { } } -$ pmd check -d Foo.java -f text -R java-bestpractices --suppress-marker TURN_OFF_WARNINGS +$ pmd check -d Foo.java -f text -R category/java/bestpractices.xml --suppress-marker TURN_OFF_WARNINGS No problems found! UnusedLocalVariable rule violation suppressed by //NOPMD in /home/tom/pmd/pmd/bin/Foo.java ``` @@ -134,7 +134,7 @@ public class Foo { } } } -$ java net.sourceforge.pmd.PMD -d ~/tmp/Foo.java -f text -R java-basic +$ java net.sourceforge.pmd.PMD -d ~/tmp/Foo.java -f text -R category/java/bestpractices.xml No problems found! ``` From 6cd7b9b1f124a386a951796e409ab3c32a951a11 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 7 Aug 2025 16:15:22 +0200 Subject: [PATCH 1240/1962] [doc] Add CSS in PMD's description Follow-up on #5733 --- README.md | 6 +++--- docs/index.md | 6 +++--- pom.xml | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 4d71288b511..466a4c67777 100644 --- a/README.md +++ b/README.md @@ -20,12 +20,12 @@ extended with custom rules. It uses JavaCC and Antlr to parse source files into (AST) and runs rules against them to find violations. Rules can be written in Java or using a XPath query. Currently, PMD supports Java, JavaScript, Salesforce.com Apex and Visualforce, -Kotlin, Swift, Modelica, PLSQL, Apache Velocity, JSP, WSDL, Maven POM, HTML, XML and XSL. +Kotlin, Swift, Modelica, PL/SQL, Apache Velocity, JSP, WSDL, Maven POM, HTML, XML and XSL. Scala is supported, but there are currently no Scala rules available. Additionally, it includes **CPD**, the copy-paste-detector. CPD finds duplicated code in -Coco, C/C++, C#, Dart, Fortran, Gherkin, Go, Groovy, HTML, Java, JavaScript, JSP, Julia, Kotlin, -Lua, Matlab, Modelica, Objective-C, Perl, PHP, PLSQL, Python, Ruby, Salesforce.com Apex and +Coco, C/C++, C#, CSS, Dart, Fortran, Gherkin, Go, Groovy, HTML, Java, JavaScript, JSP, Julia, Kotlin, +Lua, Matlab, Modelica, Objective-C, Perl, PHP, PL/SQL, Python, Ruby, Salesforce.com Apex and Visualforce, Scala, Swift, T-SQL, Typescript, Apache Velocity, WSDL, XML and XSL. ## ๐Ÿš€ Installation and Usage diff --git a/docs/index.md b/docs/index.md index 0a9e0be8758..1018fda2a87 100644 --- a/docs/index.md +++ b/docs/index.md @@ -31,12 +31,12 @@ extended with custom rules. It uses JavaCC and Antlr to parse source files into (AST) and runs rules against them to find violations. Rules can be written in Java or using a XPath query. Currently, PMD supports Java, JavaScript, Salesforce.com Apex and Visualforce, -Kotlin, Swift, Modelica, PLSQL, Apache Velocity, JSP, WSDL, Maven POM, HTML, XML and XSL. +Kotlin, Swift, Modelica, PL/SQL, Apache Velocity, JSP, WSDL, Maven POM, HTML, XML and XSL. Scala is supported, but there are currently no Scala rules available. Additionally, it includes **CPD**, the copy-paste-detector. CPD finds duplicated code in -Coco, C/C++, C#, Dart, Fortran, Gherkin, Go, Groovy, HTML, Java, JavaScript, JSP, Julia, Kotlin, -Lua, Matlab, Modelica, Objective-C, Perl, PHP, PLSQL, Python, Ruby, Rust, Salesforce.com Apex and +Coco, C/C++, C#, CSS, Dart, Fortran, Gherkin, Go, Groovy, HTML, Java, JavaScript, JSP, Julia, Kotlin, +Lua, Matlab, Modelica, Objective-C, Perl, PHP, PL/SQL, Python, Ruby, Rust, Salesforce.com Apex and Visualforce, Scala, Swift, T-SQL, Typescript, Apache Velocity, WSDL, XML and XSL. PMD features many **built-in checks** (in PMD lingo, *rules*), which are documented diff --git a/pom.xml b/pom.xml index a5c3ae583c5..aa5f0b06797 100644 --- a/pom.xml +++ b/pom.xml @@ -15,12 +15,12 @@ (AST) and runs rules against them to find violations. Rules can be written in Java or using a XPath query. Currently, PMD supports Java, JavaScript, Salesforce.com Apex and Visualforce, - Kotlin, Swift, Modelica, PLSQL, Apache Velocity, JSP, WSDL, Maven POM, HTML, XML and XSL. + Kotlin, Swift, Modelica, PL/SQL, Apache Velocity, JSP, WSDL, Maven POM, HTML, XML and XSL. Scala is supported, but there are currently no Scala rules available. Additionally, it includes CPD, the copy-paste-detector. CPD finds duplicated code in - Coco, C/C++, C#, Dart, Fortran, Gherkin, Go, Groovy, HTML, Java, JavaScript, JSP, Julia, Kotlin, - Lua, Matlab, Modelica, Objective-C, Perl, PHP, PLSQL, Python, Ruby, Rust, Salesforce.com Apex and + Coco, C/C++, C#, CSS, Dart, Fortran, Gherkin, Go, Groovy, HTML, Java, JavaScript, JSP, Julia, Kotlin, + Lua, Matlab, Modelica, Objective-C, Perl, PHP, PL/SQL, Python, Ruby, Rust, Salesforce.com Apex and Visualforce, Scala, Swift, T-SQL, Typescript, Apache Velocity, WSDL, XML and XSL. From b6371bea43c599e2ce6ebc7c0118ccd7fa933478 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 7 Aug 2025 17:13:36 +0200 Subject: [PATCH 1241/1962] [ci] publish-release: create-docker needs github-release The docker workflow doesn't need maven central. Instead, it loads the new release from github releases. So, this job should run after "github-release". --- .github/workflows/publish-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 76946516d23..78931465c52 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -748,7 +748,7 @@ jobs: rm -rf "${HOME}/.ssh" create-docker: - needs: [check-version, deploy-to-maven-central] + needs: [check-version, github-release] environment: name: github url: https://github.com/pmd/docker/actions From d42b9b358005a6b0a46fdf5da1a756b86490eae5 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 7 Aug 2025 17:38:32 +0200 Subject: [PATCH 1242/1962] [ci] publish-pull-requests: use pmd-actions-helper-app --- .github/workflows/publish-pull-requests.yml | 31 +++++++++++++-------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/.github/workflows/publish-pull-requests.yml b/.github/workflows/publish-pull-requests.yml index bbb6f833f14..1807bcddd05 100644 --- a/.github/workflows/publish-pull-requests.yml +++ b/.github/workflows/publish-pull-requests.yml @@ -6,10 +6,7 @@ on: types: - completed -permissions: - checks: write - statuses: write - pull-requests: write # in order to add a comment +permissions: {} jobs: publish: @@ -24,10 +21,21 @@ jobs: run: shell: bash steps: + - uses: actions/create-github-app-token@v2 + id: pmd-actions-helper-app-token + with: + app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} + private-key: ${{ secrets.PMD_ACTIONS_HELPER_PRIVATE_KEY }} + owner: pmd + repositories: pmd + permission-actions: read # download workflow run artifacts + permission-checks: write + permission-statuses: write + permission-pull-requests: write # in order to add/update a comment - name: 'Get PR context' env: # Token required for GH CLI: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ steps.pmd-actions-helper-app-token.outputs.token }} # If the PR is from a fork, prefix it with `:`, otherwise only the PR branch name is relevant: PR_BRANCH: |- ${{ @@ -57,7 +65,7 @@ jobs: - name: Download docs-artifact env: # Token required for GH CLI: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ steps.pmd-actions-helper-app-token.outputs.token }} RUN_ID: ${{ github.event.workflow_run.id }} run: | mkdir docs-artifact @@ -74,7 +82,7 @@ jobs: - name: Add commit status (Documentation) env: # Token required for GH CLI: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ steps.pmd-actions-helper-app-token.outputs.token }} run: | gh api \ --method POST \ @@ -86,7 +94,7 @@ jobs: - name: Add Check Status (Documentation) env: # Token required for GH CLI: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ steps.pmd-actions-helper-app-token.outputs.token }} run: | timestamp="$(date -uIs)" gh api \ @@ -101,7 +109,7 @@ jobs: - name: Download pmd-regression-tester env: # Token required for GH CLI: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ steps.pmd-actions-helper-app-token.outputs.token }} RUN_ID: ${{ github.event.workflow_run.id }} run: | mkdir pmd-regression-tester @@ -125,7 +133,7 @@ jobs: if: ${{ env.REGRESSION_REPORT_UPLOADED == 1 }} env: # Token required for GH CLI: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ steps.pmd-actions-helper-app-token.outputs.token }} run: | gh api \ --method POST \ @@ -148,7 +156,7 @@ jobs: - name: Add Check Status (Regression Tester) env: # Token required for GH CLI: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ steps.pmd-actions-helper-app-token.outputs.token }} run: | timestamp="$(date -uIs)" summary="$(cat pmd-regression-tester/summary.txt)" @@ -179,6 +187,7 @@ jobs: echo "${comment}" >> "${GITHUB_STEP_SUMMARY}" - uses: marocchino/sticky-pull-request-comment@773744901bac0e8cbb5a0dc842800d45e9b2b405 #v2.9.4 with: + GITHUB_TOKEN: ${{ steps.pmd-actions-helper-app-token.outputs.token }} header: pmd-publish-pull-requests number: ${{ env.PR_NUMBER }} path: comment.txt From 1cedbc3fdae5daf0a6289e9478a6443e541ccf54 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 7 Aug 2025 18:09:02 +0200 Subject: [PATCH 1243/1962] [ci] Pin used github actions to sha values --- .github/workflows/build.yml | 66 ++++++++++----------- .github/workflows/git-repo-sync.yml | 2 +- .github/workflows/publish-pull-requests.yml | 2 +- .github/workflows/publish-release.yml | 44 +++++++------- .github/workflows/publish-snapshot.yml | 54 ++++++++--------- 5 files changed, 84 insertions(+), 84 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d52d2a10352..77b0694255c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,12 +23,12 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v4 - - uses: actions/setup-java@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 + - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 with: distribution: 'temurin' java-version: '11' - - uses: actions/cache@v4 + - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- @@ -47,7 +47,7 @@ jobs: # version exactly is available in the staging repo. But if we rerun the build using the # older cache, it points to the old staging versions, which are not available anymore. find .m2/repository/net/sourceforge/pmd -type d -name "*-SNAPSHOT" -and -not -path "*/pmd-designer/*" -print0 | xargs -0 rm -vrf - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 with: name: compile-artifact if-no-files-found: error @@ -58,12 +58,12 @@ jobs: !pmd-dist/target/pmd-dist-*-src.zip !pmd-dist/target/pmd-*-cyclonedx.xml !pmd-dist/target/pmd-*-cyclonedx.json - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 with: name: staging-repository if-no-files-found: error path: target/staging - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 with: name: dist-artifact if-no-files-found: error @@ -81,18 +81,18 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v4 - - uses: actions/setup-java@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 + - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 with: distribution: 'temurin' java-version: '11' - - uses: actions/cache@v4 + - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- path: .m2/repository enableCrossOsArchive: true - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: compile-artifact - name: Full Build with Maven @@ -100,7 +100,7 @@ jobs: ./mvnw --show-version --errors --batch-mode \ -Dmaven.repo.local=.m2/repository \ verify -DskipTests - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 with: name: javadocs-artifact if-no-files-found: error @@ -121,8 +121,8 @@ jobs: matrix: os: [ ubuntu-latest, windows-latest, macos-latest ] steps: - - uses: actions/checkout@v4 - - uses: actions/setup-java@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 + - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 # under linux we execute more extensive integration tests with various java versions if: ${{ runner.os == 'Linux' }} with: @@ -131,7 +131,7 @@ jobs: 8 17 21 - - uses: actions/setup-java@v4 + - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 # default java version for all os is 11 with: distribution: 'temurin' @@ -140,13 +140,13 @@ jobs: # Note: this works under Windows only if pom.xml files use LF, so that hashFiles('**/pom.xml') # gives the same result (line endings...). # see .gitattributes for pom.xml - it should always be using lf. - - uses: actions/cache/restore@v4 + - uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- path: .m2/repository enableCrossOsArchive: true - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 # we can only reuse compile-artifacts under linux due to file timestamp issues and # platform specific line endings in test resource files. if: ${{ runner.os == 'Linux' }} @@ -170,21 +170,21 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v4 - - uses: actions/setup-java@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 + - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 with: distribution: 'temurin' java-version: '11' - - uses: actions/cache@v4 + - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- path: .m2/repository enableCrossOsArchive: true - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: compile-artifact - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: staging-repository path: target/staging @@ -256,18 +256,18 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v4 - - uses: actions/setup-java@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 + - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 with: distribution: 'temurin' java-version: '11' - - uses: actions/cache@v4 + - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- path: .m2/repository enableCrossOsArchive: true - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: compile-artifact - name: Generate rule docs @@ -278,7 +278,7 @@ jobs: -Pgenerate-rule-docs,fastSkip \ -DskipTests -Dassembly.skipAssembly=true - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@v1 + uses: ruby/setup-ruby@2a7b30092b0caf9c046252510f9273b4875f3db9 #v1.254.0 with: ruby-version: 3.3 - name: Setup bundler @@ -294,7 +294,7 @@ jobs: run: | cd docs bundle exec render_release_notes.rb pages/release_notes.md | tail -n +6 > _site/pmd_release_notes.md - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 with: name: docs-artifact if-no-files-found: error @@ -309,18 +309,18 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 with: fetch-depth: 2 - - uses: actions/setup-java@v4 + - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 with: distribution: 'temurin' java-version: '11' - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@v1 + uses: ruby/setup-ruby@2a7b30092b0caf9c046252510f9273b4875f3db9 #v1.254.0 with: ruby-version: 3.3 - - uses: actions/cache@v4 + - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: path: | ~/.m2/repository @@ -329,7 +329,7 @@ jobs: .ci/files/vendor/bundle key: regressiontester-${{ hashFiles('.ci/files/project-list.xml', '.ci/files/Gemfile.lock') }} restore-keys: regressiontester- - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: dist-artifact path: pmd-dist/target @@ -350,7 +350,7 @@ jobs: run: | echo "artifacts_path=$(realpath ..)" >> "${GITHUB_ENV}" - name: Upload regression tester report - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 with: name: pmd-regression-tester if-no-files-found: error diff --git a/.github/workflows/git-repo-sync.yml b/.github/workflows/git-repo-sync.yml index f68e4ea2fdf..11901d29107 100644 --- a/.github/workflows/git-repo-sync.yml +++ b/.github/workflows/git-repo-sync.yml @@ -28,7 +28,7 @@ jobs: shell: bash continue-on-error: false steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 with: fetch-depth: 100 - name: Setup ssh key for sourceforge diff --git a/.github/workflows/publish-pull-requests.yml b/.github/workflows/publish-pull-requests.yml index 1807bcddd05..bc09f94bde2 100644 --- a/.github/workflows/publish-pull-requests.yml +++ b/.github/workflows/publish-pull-requests.yml @@ -21,7 +21,7 @@ jobs: run: shell: bash steps: - - uses: actions/create-github-app-token@v2 + - uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e #v2.0.6 id: pmd-actions-helper-app-token with: app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 78931465c52..9d01e87f71f 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -31,10 +31,10 @@ jobs: outputs: PMD_VERSION: ${{ steps.version.outputs.PMD_VERSION }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 with: ref: ${{ github.event.workflow_run.head_branch }} - - uses: actions/setup-java@v4 + - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 with: distribution: 'temurin' java-version: '11' @@ -85,10 +85,10 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 with: ref: ${{ github.event.workflow_run.head_branch }} - - uses: actions/setup-java@v4 + - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 with: distribution: 'temurin' java-version: '11' @@ -97,7 +97,7 @@ jobs: server-password: MAVEN_PASSWORD gpg-passphrase: MAVEN_GPG_PASSPHRASE gpg-private-key: ${{ secrets.PMD_CI_GPG_PRIVATE_KEY }} - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: compile-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -131,14 +131,14 @@ jobs: run: shell: bash steps: - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: dist-artifact github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id }} path: dist - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: docs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -250,7 +250,7 @@ jobs: run: shell: bash steps: - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: docs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -298,7 +298,7 @@ jobs: run: shell: bash steps: - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: docs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -378,7 +378,7 @@ jobs: run: shell: bash steps: - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: javadocs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -461,14 +461,14 @@ jobs: run: shell: bash steps: - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: dist-artifact github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id }} path: dist - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: docs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -504,7 +504,7 @@ jobs: --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-src.zip" printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-doc.zip" - - uses: actions/create-github-app-token@v2 + - uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e #v2.0.6 id: pmd-actions-helper-app-token with: app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} @@ -567,7 +567,7 @@ jobs: run: shell: bash steps: - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: docs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -622,18 +622,18 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 with: ref: ${{ github.event.workflow_run.head_branch }} - - uses: actions/setup-java@v4 + - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 with: distribution: 'temurin' java-version: '11' - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@v1 + uses: ruby/setup-ruby@2a7b30092b0caf9c046252510f9273b4875f3db9 #v1.254.0 with: ruby-version: 3.3 - - uses: actions/cache@v4 + - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: path: | ~/.m2/repository @@ -642,7 +642,7 @@ jobs: .ci/files/vendor/bundle key: regressiontester-${{ hashFiles('.ci/files/project-list.xml', '.ci/files/Gemfile.lock') }} restore-keys: regressiontester- - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: dist-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -697,7 +697,7 @@ jobs: cd ../../pmd mv ../target/reports/"${baseline_name}-baseline.zip" . scp "${baseline_name}-baseline.zip" pmd@pmd-code.org:/httpdocs/pmd-regression-tester/ - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 with: name: regression-tester-baseline path: ${{ format('pmd_releases_{0}-baseline.zip', needs.check-version.outputs.PMD_VERSION) }} @@ -733,7 +733,7 @@ jobs: IdentityFile=$HOME/.ssh/web.sourceforge.net_deploy_key " > "$HOME/.ssh/config" echo "${WEB_SF_KNOWN_HOSTS}" > "$HOME/.ssh/known_hosts" - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: regression-tester-baseline - name: Upload to sourceforge @@ -758,7 +758,7 @@ jobs: run: shell: bash steps: - - uses: actions/create-github-app-token@v2 + - uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e #v2.0.6 id: pmd-actions-helper-app-token with: app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 48e04f6d177..4050121a2fd 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -30,10 +30,10 @@ jobs: outputs: PMD_VERSION: ${{ steps.version.outputs.PMD_VERSION }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 with: ref: main - - uses: actions/setup-java@v4 + - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 with: distribution: 'temurin' java-version: '11' @@ -76,10 +76,10 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 with: ref: main - - uses: actions/setup-java@v4 + - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 with: distribution: 'temurin' java-version: '11' @@ -88,13 +88,13 @@ jobs: server-password: MAVEN_PASSWORD gpg-passphrase: MAVEN_GPG_PASSPHRASE gpg-private-key: ${{ secrets.PMD_CI_GPG_PRIVATE_KEY }} - - uses: actions/cache@v4 + - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- path: .m2/repository enableCrossOsArchive: true - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: compile-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -129,14 +129,14 @@ jobs: run: shell: bash steps: - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: dist-artifact github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id }} path: dist - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: docs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -232,7 +232,7 @@ jobs: run: shell: bash steps: - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: docs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -278,7 +278,7 @@ jobs: run: shell: bash steps: - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: docs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -351,7 +351,7 @@ jobs: run: shell: bash steps: - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: javadocs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -416,12 +416,12 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 with: ref: gh-pages - name: Clear old files run: rm -rf * - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: docs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -456,14 +456,14 @@ jobs: run: shell: bash steps: - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: dist-artifact github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id }} path: dist - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: docs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -495,7 +495,7 @@ jobs: --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-src.zip" printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-doc.zip" - - uses: actions/create-github-app-token@v2 + - uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e #v2.0.6 id: pmd-actions-helper-app-token with: app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} @@ -639,18 +639,18 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 with: ref: main - - uses: actions/setup-java@v4 + - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 with: distribution: 'temurin' java-version: '11' - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@v1 + uses: ruby/setup-ruby@2a7b30092b0caf9c046252510f9273b4875f3db9 #v1.254.0 with: ruby-version: 3.3 - - uses: actions/cache@v4 + - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: path: | ~/.m2/repository @@ -659,7 +659,7 @@ jobs: .ci/files/vendor/bundle key: regressiontester-${{ hashFiles('.ci/files/project-list.xml', '.ci/files/Gemfile.lock') }} restore-keys: regressiontester- - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 with: name: dist-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -724,14 +724,14 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 with: ref: main - - uses: actions/setup-java@v4 + - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 with: distribution: 'temurin' java-version: '17' # sonar requires java 17 - - uses: actions/cache@v4 + - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- @@ -761,14 +761,14 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 with: ref: main - - uses: actions/setup-java@v4 + - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 with: distribution: 'temurin' java-version: '17' # coveralls requires java 17 - - uses: actions/cache@v4 + - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- From 34181c20437c8f0fe36e986f6d84117a449fb4ac Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 7 Aug 2025 18:09:27 +0200 Subject: [PATCH 1244/1962] chore: dependabot - add npm, don't group anymore --- .github/dependabot.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 38ac90aab48..e09c0b4e470 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,6 +5,7 @@ updates: directory: "/" schedule: interval: "weekly" + day: "wednesday" # Allow up to 10 open pull requests for maven dependencies open-pull-requests-limit: 10 - package-ecosystem: "bundler" @@ -13,13 +14,14 @@ updates: - "/docs" schedule: interval: "weekly" - groups: - all-gems: - patterns: [ "*" ] + day: "wednesday" - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" - groups: - all-actions: - patterns: [ "*" ] + day: "wednesday" + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "weekly" + day: "wednesday" From 9d446ca80362a738ccabd8998ca451e756781f7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Thu, 7 Aug 2025 18:08:47 +0200 Subject: [PATCH 1245/1962] UnnecessaryBoxingRule: Check if unboxing is required for overload resolution. --- .../rule/codestyle/UnnecessaryBoxingRule.java | 81 +++++++++++++++++ .../rule/codestyle/xml/UnnecessaryBoxing.xml | 90 +++++++++++++++++++ 2 files changed, 171 insertions(+) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryBoxingRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryBoxingRule.java index fc0af424e24..68b148f49b8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryBoxingRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryBoxingRule.java @@ -17,10 +17,12 @@ import net.sourceforge.pmd.lang.java.ast.ASTList; import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement; +import net.sourceforge.pmd.lang.java.ast.InvocationNode; import net.sourceforge.pmd.lang.java.ast.JavaNode; import net.sourceforge.pmd.lang.java.ast.QualifiableExpression; import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; +import net.sourceforge.pmd.lang.java.types.JClassType; import net.sourceforge.pmd.lang.java.types.JMethodSig; import net.sourceforge.pmd.lang.java.types.JTypeMirror; import net.sourceforge.pmd.lang.java.types.OverloadSelectionResult; @@ -28,6 +30,7 @@ import net.sourceforge.pmd.lang.java.types.TypeTestUtil; import net.sourceforge.pmd.lang.java.types.ast.ExprContext; import net.sourceforge.pmd.lang.java.types.ast.ExprContext.ExprContextKind; +import net.sourceforge.pmd.lang.java.types.internal.infer.OverloadSet; import net.sourceforge.pmd.reporting.RuleContext; /** @@ -155,6 +158,12 @@ && isObjectConversionNecessary(conversionExpr)) { reason = "boxing of boxed value"; } else if (isImplicitlyTypedLambdaReturnExpr(conversionExpr) || ctxType != null && conversionIsImplicitlyRealisable(sourceType, ctxType, ctx, conversionOutput)) { + + // Check if this unboxing is required for correct overload selection + if (sourceType.isBoxedPrimitive() && conversionOutput.isPrimitive() + && isUnboxingRequiredForOverloadSelection(conversionExpr, convertedExpr)) { + return; + } if (sourceType.unbox().equals(conversionOutput)) { reason = "explicit unboxing"; } else if (sourceType.box().equals(conversionOutput)) { @@ -181,6 +190,78 @@ private static boolean conversionIsImplicitlyRealisable(JTypeMirror sourceType, && conversionDoesNotChangesValue(sourceType, conversionOutput); } + /** + * Check if the unboxing conversion is required for correct method overload selection. + * Returns true if removing the unboxing would cause a different method overload to be selected. + */ + private boolean isUnboxingRequiredForOverloadSelection(ASTExpression conversionExpr, ASTExpression convertedExpr) { + // Find the invocation and argument index + JavaNode parent = conversionExpr.getParent(); + InvocationNode invocation; + int argIndex; + + if (parent instanceof ASTList && parent.getParent() instanceof InvocationNode) { + invocation = (InvocationNode) parent.getParent(); + argIndex = conversionExpr.getIndexInParent(); + } else if (parent instanceof InvocationNode) { + invocation = (InvocationNode) parent; + argIndex = 0; + } else { + return false; + } + + // Get the method and validate we have a boxed->primitive conversion + JMethodSig currentMethod; + try { + currentMethod = invocation.getMethodType(); + } catch (Exception e) { + return false; + } + + if (!convertedExpr.getTypeMirror().isBoxedPrimitive() || !conversionExpr.getTypeMirror().isPrimitive()) { + return false; + } + + // Check if there are overloads that would accept the boxed type differently + return hasObjectOverloadAtPosition(currentMethod, argIndex, invocation instanceof ASTConstructorCall); + } + + /** + * Check if there are other overloads that would accept the boxed type differently, + * making the unboxing necessary for correct overload selection. + */ + private boolean hasObjectOverloadAtPosition(JMethodSig currentMethod, int argIndex, boolean isConstructor) { + JTypeMirror declaringType = currentMethod.getDeclaringType(); + if (!(declaringType instanceof JClassType) || argIndex >= currentMethod.getFormalParameters().size()) { + return false; + } + + JClassType classType = (JClassType) declaringType; + JTypeMirror currentParamType = currentMethod.getFormalParameters().get(argIndex); + if (!currentParamType.isPrimitive()) { + return false; + } + + JTypeMirror boxedType = currentParamType.box(); + + // Get all overloads and check if any would accept the boxed type differently + java.util.List overloads = isConstructor + ? classType.getConstructors() + : classType.streamMethods(method -> method.nameEquals(currentMethod.getName())) + .collect(OverloadSet.collectMostSpecific(classType)); + + return overloads.stream() + .filter(overload -> !overload.equals(currentMethod)) + .filter(overload -> argIndex < overload.getFormalParameters().size()) + .map(overload -> overload.getFormalParameters().get(argIndex)) + .anyMatch(overloadParamType -> + // Boxed type is assignable to overload parameter (Object, generic, etc.) + boxedType.isSubtypeOf(overloadParamType) + // Or overload takes reference type while current takes primitive (different conversion paths) + || overloadParamType.isTypeVariable() || !overloadParamType.isPrimitive() && currentParamType.isPrimitive() + ); + } + private boolean isImplicitlyTypedLambdaReturnExpr(ASTExpression e) { JavaNode parent = e.getParent(); diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryBoxing.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryBoxing.xml index d36a46be5d5..89cd16a9125 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryBoxing.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryBoxing.xml @@ -660,4 +660,94 @@ public class Foo { } ]]> + + + #5948 Method overload - should not be flagged + 0 + l = new ArrayList<>(); + Integer i = 3; + + l.remove(i.intValue()); + } + } + ]]> + + + + Method overload - should not be flagged + 0 + + + + + Constructor overloads - should not be flagged + 0 + + + + + Generic method overloads - unboxing should not be flagged + 0 + void method(T value) { } + public void method(int value) { } + + void test() { + Integer boxed = 42; + // The unboxing should be necessary to select the int overload + method(boxed.intValue()); + } + } + ]]> + + + + Primitive widening vs boxing - unboxing should not be flagged + 0 + + From 2fb24deefad116f00a7cb5568a15bec7085cd48e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 8 Aug 2025 09:44:30 +0200 Subject: [PATCH 1246/1962] [test] Enable rule test xml validation Fixes #5973 --- .../pmd/test/schema/BaseTestParserImpl.java | 5 +- .../pmd/test/schema/TestSchemaParser.java | 30 +++- .../pmd/test/schema/TestSchemaVersion.java | 2 +- .../pmd/test/schema/rule-tests_1_1_1.xsd | 133 ++++++++++++++++++ .../pmd/test/schema/TestSchemaParserTest.java | 69 ++++++++- 5 files changed, 226 insertions(+), 13 deletions(-) create mode 100644 pmd-test-schema/src/main/resources/net/sourceforge/pmd/test/schema/rule-tests_1_1_1.xsd diff --git a/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/BaseTestParserImpl.java b/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/BaseTestParserImpl.java index 0d50d4e95eb..8c0a872c77b 100644 --- a/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/BaseTestParserImpl.java +++ b/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/BaseTestParserImpl.java @@ -317,7 +317,10 @@ private Attr getRequiredAttribute(String name, Element ruleProperty, PmdXmlRepor private boolean parseBoolAttribute(Element testCode, String attrName, boolean defaultValue, PmdXmlReporter err, String deprecationMessage) { Attr attrNode = testCode.getAttributeNode(attrName); if (attrNode != null) { - if (deprecationMessage != null) { + // only consider attributes that are "specified". XML Validation will add the default values of + // the defined attributes implicitly. This would lead to deprecation messages for attributes, that + // are not actually used. + if (deprecationMessage != null && attrNode.getSpecified()) { err.at(attrNode).warn(deprecationMessage); } return Boolean.parseBoolean(attrNode.getNodeValue()); diff --git a/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/TestSchemaParser.java b/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/TestSchemaParser.java index 4da511632fd..bb95d47ecf2 100644 --- a/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/TestSchemaParser.java +++ b/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/TestSchemaParser.java @@ -56,14 +56,33 @@ public TestSchemaParser() { * @throws XmlException If parsing throws this */ public RuleTestCollection parse(Rule rule, InputSource inputSource) throws IOException, XmlException { - // note: need to explicitly specify the writer here, so that in unit tests - // System.err can be swapped out and in - OoxmlFacade ooxml = new OoxmlFacade().withPrinter(new PrintStreamMessageHandler(System.err)); + class ErrorHandler extends PrintStreamMessageHandler { + private boolean hasError = false; + + ErrorHandler() { + // note: need to explicitly specify the writer here, so that in unit tests + // System.err can be swapped out and in with SystemLambda.tapSystemErr + super(System.err); + } + + @Override + public void accept(XmlException entry) { + super.accept(entry); + hasError |= entry.getSeverity() == XmlSeverity.ERROR; + } + + public boolean hasError() { + return hasError; + } + } + + ErrorHandler validationHandler = new ErrorHandler(); + OoxmlFacade ooxml = new OoxmlFacade().withPrinter(validationHandler); PositionedXmlDoc doc = ooxml.parse(newDocumentBuilder(), inputSource); try (PmdXmlReporterImpl err = new PmdXmlReporterImpl(ooxml, doc.getPositioner())) { RuleTestCollection collection = version.getParserImpl().parseDocument(rule, doc, err); - if (err.hasError()) { + if (validationHandler.hasError() || err.hasError()) { // todo maybe add a way not to throw here throw new IllegalStateException("Errors were encountered while parsing XML tests"); } @@ -121,8 +140,7 @@ public boolean hasError() { private DocumentBuilder newDocumentBuilder() { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); try { - // don't use the schema as it adds deprecated attributes implicitly... - // dbf.setSchema(version.getSchema()); + dbf.setSchema(version.getSchema()); dbf.setNamespaceAware(true); return dbf.newDocumentBuilder(); } catch (ParserConfigurationException e) { diff --git a/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/TestSchemaVersion.java b/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/TestSchemaVersion.java index dc152539d83..ce9b721c561 100644 --- a/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/TestSchemaVersion.java +++ b/pmd-test-schema/src/main/java/net/sourceforge/pmd/test/schema/TestSchemaVersion.java @@ -18,7 +18,7 @@ * @author Clรฉment Fournier */ enum TestSchemaVersion { - V1("rule-tests_1_1_0.xsd", new BaseTestParserImpl.ParserV1()); + V1("rule-tests_1_1_1.xsd", new BaseTestParserImpl.ParserV1()); private final Schema schema; private String schemaLoc; diff --git a/pmd-test-schema/src/main/resources/net/sourceforge/pmd/test/schema/rule-tests_1_1_1.xsd b/pmd-test-schema/src/main/resources/net/sourceforge/pmd/test/schema/rule-tests_1_1_1.xsd new file mode 100644 index 00000000000..a5e1510edc4 --- /dev/null +++ b/pmd-test-schema/src/main/resources/net/sourceforge/pmd/test/schema/rule-tests_1_1_1.xsd @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + A code fragment that can be referred to by several tests. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Declares the expected suppressed violations. Since PMD 7.15.0 / rule-tests 1.1.0. + + + + + + + + + + + + + + + + + + + + + + + + + + + Language version of the source, eg 'java 8'. + + + + + + + + This attribute is deprecated, it is assumed true and ignored. + + + + + + + This attribute is deprecated. Use "disabled" instead. + If this attribute is set to "false", then the test is ignored. + + + + + + + This attribute is deprecated, it is assumed true and ignored. + + + + + + + + A reason why the test is disabled/ignored should be provided as a comment for the test. + + + + + + + If true, only this test will be executed, and all others will be disabled. + If several tests in the same file are focused, then the last one wins, in + document order. + This attribute is provided as a way for developers to temporarily focus on a single test. + Test files with a focused test should not be checked in. For this reason, + using this attribute produces a warning. + + + + + + + + + + + + + diff --git a/pmd-test-schema/src/test/java/net/sourceforge/pmd/test/schema/TestSchemaParserTest.java b/pmd-test-schema/src/test/java/net/sourceforge/pmd/test/schema/TestSchemaParserTest.java index dc42cf7324a..b382f35e246 100644 --- a/pmd-test-schema/src/test/java/net/sourceforge/pmd/test/schema/TestSchemaParserTest.java +++ b/pmd-test-schema/src/test/java/net/sourceforge/pmd/test/schema/TestSchemaParserTest.java @@ -7,6 +7,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.not; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -14,6 +15,7 @@ import java.io.IOException; import java.io.StringReader; +import java.util.Locale; import org.junit.jupiter.api.Test; import org.xml.sax.InputSource; @@ -144,7 +146,7 @@ void testUnknownProperty() throws Exception { @Test void withExpectedSuppressions() throws IOException { String file = "\n" - + "\n" + + "\n" @@ -180,10 +182,10 @@ void withExpectedSuppressions() throws IOException { @Test void withExpectedEmptySuppressions() throws IOException { String file = "\n" - + "\n" + + "\n" + + " xsi:schemaLocation=\"http://pmd.sourceforge.net/rule-tests net/sourceforge/pmd/test/schema/rule-tests_1_1_1.xsd\">\n" + " \n" + " Test case with suppression\n" + " 0\n" @@ -204,7 +206,7 @@ void withExpectedEmptySuppressions() throws IOException { @Test void withExpectedNoSuppressions() throws IOException { String file = "\n" - + "\n" + + "\n" @@ -222,6 +224,55 @@ void withExpectedNoSuppressions() throws IOException { assertFalse(test.hasExpectedSuppressions()); } + @Test + void noWarningsForUnusedDeprecatedAttributes() throws Exception { + String file = "\n" + + "\n" + + " \n" + + " Test case with suppression\n" + + " 1\n" + + " 1\n" + + " \n" + + " \n" + + "\n"; + + String log = SystemLambda.tapSystemErr(() -> { + parseFile(file); + }); + + assertThat(log, not(containsString("is deprecated"))); + } + + @Test + void failOnValidationErrors() throws Exception { + String file = "\n" + + "\n" + + " \n" + + " Test case with suppression\n" + + " 1\n" + + " 1 \n" + + " \n" + + " \n" + + "\n"; + + + String log = SystemLambda.tapSystemErr(() -> { + assertThrows(IllegalStateException.class, () -> parseFile(file)); + }); + + assertThat(log, containsString("cvc-complex-type.2.4.a: Invalid content was found starting with element '{\"http://pmd.sourceforge.net/rule-tests\":expected-linenumber}'")); + } + private RuleTestCollection parseFile(String file) throws IOException { MockRule mockRule = new MockRule(); mockRule.setLanguage(PlainTextLanguage.getInstance()); @@ -230,7 +281,15 @@ private RuleTestCollection parseFile(String file) throws IOException { is.setSystemId("a/file.xml"); is.setCharacterStream(new StringReader(file)); - return new TestSchemaParser().parse(mockRule, is); + final Locale defaultLocale = Locale.getDefault(); + try { + // make sure to use English for XML validation errors, like invalid element + Locale.setDefault(Locale.ENGLISH); + + return new TestSchemaParser().parse(mockRule, is); + } finally { + Locale.setDefault(defaultLocale); + } } public static final class MockRule extends AbstractRule { From 318c384499d50bd0c289090bf2da8b1fda404b00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Thu, 7 Aug 2025 19:31:14 +0200 Subject: [PATCH 1247/1962] Fix XML errors in AssignmentInOperand.xml --- .../lang/java/rule/errorprone/xml/AssignmentInOperand.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml index 5464f524490..555eae05cf3 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml @@ -108,8 +108,8 @@ public class Foo { #5915 assignment in do-while conditional expression 1 - 6 - Avoid assignments in operands + 6 + Avoid assignments in operands assignment in switch expression 1 - 4 - Avoid assignments in operands + 4 + Avoid assignments in operands Date: Fri, 8 Aug 2025 10:17:58 +0200 Subject: [PATCH 1248/1962] [doc] Update release notes (#5973) --- docs/pages/pmd/userdocs/extending/testing.md | 12 +++++++----- docs/pages/release_notes.md | 11 +++++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/docs/pages/pmd/userdocs/extending/testing.md b/docs/pages/pmd/userdocs/extending/testing.md index a43d9efa93c..0518244dc4b 100644 --- a/docs/pages/pmd/userdocs/extending/testing.md +++ b/docs/pages/pmd/userdocs/extending/testing.md @@ -3,7 +3,7 @@ title: Testing your rules tags: [extending, userdocs] summary: "Learn how to use PMD's simple test framework for unit testing rules." permalink: pmd_userdocs_extending_testing.html -last_updated: June 2025 (7.15.0) +last_updated: July 2025 (7.17.0) author: Andreas Dangel --- @@ -101,7 +101,7 @@ This is a stripped down example which just contains two test cases. + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.github.io/schema/rule-tests_1_1_1.xsd"> concrete class @@ -132,7 +132,7 @@ The root element is ``. It can contain one or more `` and Each `` element defines a single test case. `` elements are used to share code snippets between different test cases. -{%include note.html content="The XML schema is available at [rule-tests.xsd](https://github.com/pmd/pmd/blob/main/pmd-test-schema/src/main/resources/net/sourceforge/pmd/test/schema/rule-tests_1_1_0.xsd)." %} +{%include note.html content="The XML schema is available at [rule-tests.xsd](https://github.com/pmd/pmd/blob/main/pmd-test-schema/src/main/resources/net/sourceforge/pmd/test/schema/rule-tests_1_1_1.xsd)." %} ### `` attributes @@ -174,7 +174,9 @@ The `` elements understands the following optional attributes: ``` - This is available since PMD 7.15.0 (rule-test schema version 1.1.0). + This is available since PMD 7.15.0 (rule-test schema version 1.1.0). + Since PMD 7.17.0 (rule-test schema version 1.1.1), an empty `` element without + `` children is allowed to test for no suppressed violations. * **``**: Either the `` element or the `` element is required. It provides the actual code snippet on which the rule is executed. The code itself is usually wrapped in a "CDATA" section, so that no @@ -201,7 +203,7 @@ in a "CDATA" section, so that no further XML escapes (entity references such as + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.sourceforge.io/rule-tests_1_1_1.xsd"> Just a description, will be used as the test name for JUnit in the reports diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 6beddd030b8..505ef7d0d2f 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -76,9 +76,20 @@ This is a {{ site.pmd.release_type }} release. * [#5837](https://github.com/pmd/pmd/issues/5837): \[java] New Rule OverrideBothEqualsAndHashCodeOnComparable * [#5881](https://github.com/pmd/pmd/issues/5881): \[java] AvoidLosingExceptionInformation does not trigger when inside if-else * [#5915](https://github.com/pmd/pmd/issues/5915): \[java] AssignmentInOperand not raised when inside do-while loop +* test + * [#5973](https://github.com/pmd/pmd/issues/5973): \[test] Enable XML validation for rule tests ### ๐Ÿšจ API Changes +#### Rule Test Schema +When executing rule tests, the rule test XML file will be validated against the schema and the tests will fail +if the XML file is invalid. + +There was a small bug in the schema around verifying suppressed violations: If a test wanted to verify, that there +are _no_ suppressed violations, then this was not possible. Now the `` element may be +empty. This is available in version 1.1.1 of the schema. +See [Testing your rules]({{ baseurl }}pmd_userdocs_extending_testing.html) for more information. + ### โœจ Merged pull requests * [#5822](https://github.com/pmd/pmd/pull/5822): Fix #5650: \[apex] New Rule: AnnotationsNamingConventions - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) From b0a33fed7a0034d559454e3ae61bf545af2d5ee0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 8 Aug 2025 10:21:12 +0200 Subject: [PATCH 1249/1962] Update @UncleOwen as a contributor --- .all-contributorsrc | 3 ++- docs/pages/pmd/projectdocs/credits.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 5374bba5377..4506d2c4166 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8176,7 +8176,8 @@ "avatar_url": "https://avatars.githubusercontent.com/u/15789140?v=4", "profile": "https://github.com/UncleOwen", "contributions": [ - "code" + "code", + "bug" ] }, { diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index c152481d0e3..52f9e825488 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -829,7 +829,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d - + From b4017c8797d52518821c674ef772dc4d2fcfae10 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 8 Aug 2025 12:09:39 +0200 Subject: [PATCH 1250/1962] Update @UncleOwen as a contributor --- .all-contributorsrc | 3 ++- docs/pages/pmd/projectdocs/credits.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 5374bba5377..f199e4ef65c 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8176,7 +8176,8 @@ "avatar_url": "https://avatars.githubusercontent.com/u/15789140?v=4", "profile": "https://github.com/UncleOwen", "contributions": [ - "code" + "code", + "doc" ] }, { diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index c152481d0e3..8971a11c83f 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -829,7 +829,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d - + From 9b3bd7c27079060c388816c3ea7b3d3ea5dd3b52 Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Fri, 8 Aug 2025 16:40:59 +0200 Subject: [PATCH 1251/1962] Fix #5974: [java] NPE in CloseResourceRule --- .../rule/errorprone/CloseResourceRule.java | 6 ++++++ .../rule/errorprone/xml/CloseResource.xml | 20 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceRule.java index f7caef91b68..5f84092d72e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceRule.java @@ -53,6 +53,7 @@ import net.sourceforge.pmd.lang.java.symbols.JTypeDeclSymbol; import net.sourceforge.pmd.lang.java.symbols.JVariableSymbol; import net.sourceforge.pmd.lang.java.types.InvocationMatcher; +import net.sourceforge.pmd.lang.java.types.JTypeMirror; import net.sourceforge.pmd.lang.java.types.TypeTestUtil; import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.reporting.RuleContext; @@ -678,6 +679,11 @@ private void addCloseResourceViolation(ASTVariableId id, TypeNode type, Object d } private String getResourceTypeName(ASTVariableId varId, TypeNode type) { + if (type == null) { + final JTypeMirror typeMirror = varId.getTypeMirror(); + return typeMirror.getSymbol() != null ? typeMirror.getSymbol().getSimpleName() : typeMirror.toString(); + } + if (type instanceof ASTType) { return PrettyPrintingUtil.prettyPrintType((ASTType) type); } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml index 4b6cdb5d134..c30bd7be4f3 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml @@ -2082,6 +2082,26 @@ public class DefaultFileSystemUsage { public void useDefaultFS() { FileSystem defaultFS = FileSystems.getDefault(); } +} + ]]> + + + #5974: NPE with var in for-each loop + 1 + 6 + + Ensure that resources like this Closeable object are closed after use + + connections) { + for (final var c: connections) { + c.close(); + } + } } ]]> From 10f053fe9895bd53ab07ac1e4352bbff2516debc Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Fri, 8 Aug 2025 21:08:38 +0200 Subject: [PATCH 1252/1962] #5974: Review finding: Improve testcase --- .../lang/java/rule/errorprone/xml/CloseResource.xml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml index c30bd7be4f3..2bd4047d915 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml @@ -2090,16 +2090,18 @@ public class DefaultFileSystemUsage { 1 6 - Ensure that resources like this Closeable object are closed after use + Ensure that resources like this FileInputStream object are closed after use connections) { - for (final var c: connections) { - c.close(); + public void bar(List streams) { + for (final var stream: streams) { + try { + int c = stream.in(); + } catch (IOException ignored) {} } } } From 24fdef9eb4d29b5df23594a418294419b557adcf Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Sat, 9 Aug 2025 07:30:56 +0200 Subject: [PATCH 1253/1962] Fix typos --- .../sourceforge/pmd/internal/util/IOUtil.java | 2 +- .../net/sourceforge/pmd/lang/ast/AstInfo.java | 2 +- .../pmd/lang/ast/ParseException.java | 2 +- .../pmd/lang/ast/internal/GreedyNStream.java | 6 +- .../pmd/lang/symboltable/Scope.java | 2 +- .../pmd/renderers/XSLTRenderer.java | 2 +- .../pmd/reporting/FileAnalysisListener.java | 2 +- .../pmd/util/database/DBMSMetadata.java | 2 +- .../sourceforge/pmd/util/database/DBURI.java | 2 +- .../net/sourceforge/pmd/cpd/CpdXsltTest.java | 2 +- .../pmd/lang/document/CharsTest.java | 4 +- .../pmd/lang/impl/PmdRunnableTest.java | 2 +- .../pmd/lang/rule/RuleSetFactoryTest.java | 2 +- .../rule/internal/RuleSetReferenceIdTest.java | 4 +- ...eterministicOutputListenerWrapperTest.java | 2 +- .../net/sourceforge/pmd/xml/j2ee.xml | 2 +- .../pmd/lang/java/ast/ASTAmbiguousName.java | 2 +- .../pmd/lang/java/metrics/JavaMetrics.java | 2 +- .../codestyle/UseDiamondOperatorRule.java | 2 +- .../rule/design/ExcessivePublicCountRule.java | 2 +- .../documentation/CommentContentRule.java | 6 +- .../symbols/table/internal/JavaResolvers.java | 2 +- .../table/internal/SymbolTableResolver.java | 2 +- .../pmd/lang/java/types/TypeOps.java | 2 +- .../types/internal/infer/ExprCheckHelper.java | 2 +- .../internal/infer/TypeInferenceLogger.java | 2 +- .../resources/category/java/bestpractices.xml | 4 +- .../resources/category/java/codestyle.xml | 6 +- .../main/resources/category/java/design.xml | 2 +- .../category/java/multithreading.xml | 4 +- .../pmd/lang/java/SuppressWarningsTest.java | 4 +- .../pmd/lang/java/ast/ParserCornersTest.java | 2 +- .../symbols/AnnotationReflectionTest.java | 2 +- .../lang/java/symbols/testdata/SomeClass.java | 2 +- .../pmd/lang/java/ast/ParserTestSpec.kt | 2 +- .../symbols/table/internal/VarScopingTest.kt | 2 +- .../lang/java/types/TestUtilitiesForTypes.kt | 4 +- .../internal/infer/CaptureInferenceTest.kt | 4 +- ...usandLinesOfCodeWithDuplicateLiterals.java | 2 +- .../pmd/lang/java/ast/ParserCornerCases.java | 2 +- .../lang/java/ast/ParserCornerCases17.java | 2 +- .../Jep456_UnnamedPatternsAndVariables.java | 2 +- .../Jep456_UnnamedPatternsAndVariables.txt | 22 +- ...iveTypesInPatternsInstanceofAndSwitch.java | 2 +- ...tiveTypesInPatternsInstanceofAndSwitch.txt | 2 +- .../java8/type_annotations.java | 2 +- .../xml/AccessorClassGeneration.xml | 2 +- .../rule/bestpractices/xml/CheckResultSet.xml | 2 +- .../xml/LiteralsFirstInComparisons.xml | 4 +- .../xml/OneDeclarationPerLine.xml | 2 +- .../bestpractices/xml/PreserveStackTrace.xml | 4 +- .../bestpractices/xml/UnusedPrivateMethod.xml | 4 +- .../xml/CommentDefaultAccessModifier.xml | 2 +- .../codestyle/xml/MethodNamingConventions.xml | 2 +- .../rule/codestyle/xml/UnnecessaryCast.xml | 4 +- .../xml/UnnecessaryFullyQualifiedName.xml | 2 +- .../rule/codestyle/xml/UnnecessaryImport.xml | 8 +- .../AvoidUncheckedExceptionsInSignatures.xml | 2 +- .../rule/design/xml/CognitiveComplexity.xml | 12 +- .../java/rule/design/xml/LawOfDemeter.xml | 2 +- .../design/xml/UseObjectForClearerAPI.xml | 10 +- .../documentation/xml/CommentRequired.xml | 22 +- .../xml/CloneMethodMustImplementCloneable.xml | 4 +- .../rule/errorprone/xml/CloseResource.xml | 4 +- .../DoNotCallGarbageCollectionExplicitly.xml | 2 +- .../rule/errorprone/xml/DoNotTerminateVM.xml | 2 +- .../xml/ImplicitSwitchFallThrough.xml | 14 +- .../rule/errorprone/xml/JUnitSpelling.xml | 2 +- .../java/rule/errorprone/xml/ProperLogger.xml | 4 +- .../xml/UseEqualsToCompareStrings.xml | 2 +- .../xml/UseLocaleWithCaseConversions.xml | 2 +- .../multithreading/xml/DoNotUseThreads.xml | 2 +- .../xml/UseConcurrentHashMap.xml | 2 +- .../xml/UseNotifyAllInsteadOfNotify.xml | 2 +- .../xml/InefficientStringBuffering.xml | 2 +- .../xml/RedundantFieldInitializer.xml | 2 +- .../performance/xml/StringInstantiation.xml | 2 +- .../xml/TooFewBranchesForSwitch.xml | 2 +- .../xml/UseStringBufferForStringAppends.xml | 4 +- .../java/types/dumptests/UnnamedPatterns.java | 2 +- .../java/types/dumptests/UnnamedPatterns.txt | 314 +++++++++--------- 81 files changed, 296 insertions(+), 296 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/IOUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/IOUtil.java index 853ae6ef928..89eec8882ea 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/IOUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/IOUtil.java @@ -176,7 +176,7 @@ public static Exception closeAll(Collection closeables) /** * Ensure that the closeables are closed. In the end, throws the - * pending exception if not null, or the exception retuned by {@link #closeAll(Collection)} + * pending exception if not null, or the exception returned by {@link #closeAll(Collection)} * if not null. If both are non-null, adds one of them to the suppress * list of the other, and throws that one. */ diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AstInfo.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AstInfo.java index 718aa16b3b7..0b9699f28c7 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AstInfo.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AstInfo.java @@ -95,7 +95,7 @@ public Map getSuppressionComments() { /** - * Return the suppresson comment at the given line, or null if there is none. + * Return the suppression comment at the given line, or null if there is none. * * @since 7.14.0 */ diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/ParseException.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/ParseException.java index 6367b4fc03a..fee7c8a5fe5 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/ParseException.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/ParseException.java @@ -22,7 +22,7 @@ public class ParseException extends FileAnalysisException { /** * This is the last token that has been consumed successfully. If * this object has been created due to a parse error, the token - * followng this token will (therefore) be the first error token. + * following this token will (therefore) be the first error token. */ private @Nullable FileLocation location; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/GreedyNStream.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/GreedyNStream.java index 98f7eee9361..21254c810dc 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/GreedyNStream.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/GreedyNStream.java @@ -73,9 +73,9 @@ public NodeStream take(int maxSize) { @Override public Spliterator spliterator() { - Spliterator spliter = toList().spliterator(); - return Spliterators.spliterator(iterator(), spliter.estimateSize(), - spliter.characteristics() | Spliterator.NONNULL); + Spliterator spliterator = toList().spliterator(); + return Spliterators.spliterator(iterator(), spliterator.estimateSize(), + spliterator.characteristics() | Spliterator.NONNULL); } @Override diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/Scope.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/Scope.java index 2945510d8d3..c7a60b246eb 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/Scope.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/Scope.java @@ -49,7 +49,7 @@ public interface Scope { /** * Helper method to get only a specific type of name declarations. The - * return map elemens have already been casted to the correct type. This + * return map elements have already been casted to the correct type. This * method usually returns a subset of {@link #getDeclarations()}. * * @param clazz diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/XSLTRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/XSLTRenderer.java index 6b72d360937..7a910e213d7 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/XSLTRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/XSLTRenderer.java @@ -74,7 +74,7 @@ public void start() throws IOException { } } - // We keep the inital writer to put the final html output + // We keep the initial writer to put the final html output this.outputWriter = getWriter(); // We use a new one to store the XML... this.stringWriter = new StringWriter(); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/FileAnalysisListener.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/FileAnalysisListener.java index 78a6368526e..50a046aa301 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/FileAnalysisListener.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/FileAnalysisListener.java @@ -14,7 +14,7 @@ import net.sourceforge.pmd.util.AssertionUtil; /** - * A handler for events occuring during analysis of a single file. Instances + * A handler for events occurring during analysis of a single file. Instances * are only used on a single thread for their entire lifetime, so don't * need to be synchronized to access state they own. File listeners are * spawned by a {@link GlobalAnalysisListener}. diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/database/DBMSMetadata.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/database/DBMSMetadata.java index 7728ca00c82..21bd7888e3b 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/database/DBMSMetadata.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/database/DBMSMetadata.java @@ -396,7 +396,7 @@ public List getSourceObjectList(List languages, List lines = bc.lineStream().map(Chars::toString).collect(Collectors.toList()); - assertEquals(listOf("aa", "b", "ded", "lff"), lines); + assertEquals(listOf("aa", "b", "did", "lff"), lines); } @Test diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/PmdRunnableTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/PmdRunnableTest.java index 7ca1db22f55..4c04aa8c4fa 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/PmdRunnableTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/impl/PmdRunnableTest.java @@ -164,7 +164,7 @@ private static class ThrowingLanguageModule extends SimpleLanguageModuleBase { .addVersion(THROWS_ASSERTION_ERROR) .addVersion(THROWS_SEMANTIC_ERROR) .addVersion(PARSER_REPORTS_SEMANTIC_ERROR) - .addDefaultVersion("defalt"), + .addDefaultVersion("default"), ThrowingLanguageModule::makeParser); } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleSetFactoryTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleSetFactoryTest.java index 7fe83afa0ab..1dba8fb4388 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleSetFactoryTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleSetFactoryTest.java @@ -339,7 +339,7 @@ void testRuleSetReferencesRulesetWithADeprecatedRenamedRule() throws Exception { * The user should not get a deprecation warning for the whole ruleset, * since not all rules are deprecated in the referenced ruleset. Since the deprecated rule is excluded, * there should be no deprecation warning at all, although the deprecated ruleset would have been - * excluded by default (without explictly excluding it). + * excluded by default (without explicitly excluding it). * *

    * In the end, we should get all non-deprecated rules of the referenced ruleset. diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/internal/RuleSetReferenceIdTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/internal/RuleSetReferenceIdTest.java index cacd5be9e1e..119b7922878 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/internal/RuleSetReferenceIdTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/internal/RuleSetReferenceIdTest.java @@ -167,9 +167,9 @@ void testMultipleFullRuleSet() { @Test void testUnknownRuleSet() { - List references = RuleSetReferenceId.parse("nonexistant.xml"); + List references = RuleSetReferenceId.parse("nonexistent.xml"); assertEquals(1, references.size()); - assertRuleSetReferenceId(true, "nonexistant.xml", true, null, "nonexistant.xml", references.get(0)); + assertRuleSetReferenceId(true, "nonexistent.xml", true, null, "nonexistent.xml", references.get(0)); } @Test diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/reporting/DeterministicOutputListenerWrapperTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/reporting/DeterministicOutputListenerWrapperTest.java index 440de59cce3..748c02f9f76 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/reporting/DeterministicOutputListenerWrapperTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/reporting/DeterministicOutputListenerWrapperTest.java @@ -27,7 +27,7 @@ class DeterministicOutputListenerWrapperTest { - // repeat the test several times to make sure it isn't suceeding by chance + // repeat the test several times to make sure it isn't succeeding by chance @RepeatedTest(10) void testDeterministicOutputListener() { PMDConfiguration config = new PMDConfiguration(); diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/xml/j2ee.xml b/pmd-core/src/test/resources/net/sourceforge/pmd/xml/j2ee.xml index 40af25174a6..72a82f66673 100644 --- a/pmd-core/src/test/resources/net/sourceforge/pmd/xml/j2ee.xml +++ b/pmd-core/src/test/resources/net/sourceforge/pmd/xml/j2ee.xml @@ -372,7 +372,7 @@ public class SomeEJB extends EJBObject implements EJBLocalHome { // Neither this, public class OtherThread implements Runnable { // Nor this ... - public void methode() { + public void method() { Runnable thread = new Thread(); thread.run(); } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAmbiguousName.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAmbiguousName.java index 8f1593c21ae..87504bd08ef 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAmbiguousName.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAmbiguousName.java @@ -61,7 +61,7 @@ * would allow us to remove all the remaining ambiguous names. */ public final class ASTAmbiguousName extends AbstractJavaExpr implements ASTReferenceType, ASTPrimaryExpression { - // if true, then this was explitly left in the tree by the disambig + // if true, then this was explicitly left in the tree by the disambig // pass, with a warning private boolean wasProcessed = false; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java index 2fa30bf8a40..736ca5dd180 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java @@ -357,7 +357,7 @@ public final class JavaMetrics { * because the {@code if} branch returns early. There are two paths * from {@code join} to {@code exit} (and notice, that's true even if * there is no else branch, because the path where the if condition is - * falso must be taken into account anyway). So in total there are {@code 1*2 + 1 = 3} + * false must be taken into account anyway). So in total there are {@code 1*2 + 1 = 3} * paths from {@code entry} to the end of the block or function (the * return statement still counts). * diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseDiamondOperatorRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseDiamondOperatorRule.java index 9e0df8176da..e4894ba1460 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseDiamondOperatorRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UseDiamondOperatorRule.java @@ -35,7 +35,7 @@ import net.sourceforge.pmd.lang.java.types.internal.infer.ast.JavaExprMirrors; /** - * Checks usages of explicity type arguments in a constructor call that + * Checks usages of explicit type arguments in a constructor call that * may be replaced by a diamond ({@code <>}). In order to determine this, * we mock a type resolution call site, which is equivalent to the expression * as if it had a diamond instead of explicit type arguments. We then perform diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java index 451b96935ad..4f820a6b8a0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java @@ -22,7 +22,7 @@ * subclasses.

    * *

    A large proportion of public members and operations means the class - * has high potential to be affected by external classes. Futhermore, + * has high potential to be affected by external classes. Furthermore, * increased effort will be required to thoroughly test the class. *

    * diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentContentRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentContentRule.java index 0a9afc88d05..be2eb61f9aa 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentContentRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentContentRule.java @@ -24,21 +24,21 @@ */ public class CommentContentRule extends AbstractJavaRulechainRule { - private static final PropertyDescriptor DISSALLOWED_TERMS_DESCRIPTOR = + private static final PropertyDescriptor DISALLOWED_TERMS_DESCRIPTOR = regexProperty("forbiddenRegex") .desc("Illegal terms or phrases") .defaultValue("idiot|jerk").build(); public CommentContentRule() { super(ASTCompilationUnit.class); - definePropertyDescriptor(DISSALLOWED_TERMS_DESCRIPTOR); + definePropertyDescriptor(DISALLOWED_TERMS_DESCRIPTOR); } @Override public Object visit(ASTCompilationUnit node, Object data) { - Pattern pattern = getProperty(DISSALLOWED_TERMS_DESCRIPTOR); + Pattern pattern = getProperty(DISALLOWED_TERMS_DESCRIPTOR); for (JavaComment comment : node.getComments()) { reportIllegalTerms(asCtx(data), comment, pattern, node); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/JavaResolvers.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/JavaResolvers.java index 796a4af1780..24202b1a065 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/JavaResolvers.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/JavaResolvers.java @@ -298,7 +298,7 @@ static BinaryOperator> methodMerger(boolean inStaticType) { private static List methodMerger(boolean inStaticType, List myResult, List otherResult) { if (otherResult.isEmpty()) { return myResult; - } // don't check myResult for emptyness, we might need to remove static methods + } // don't check myResult for emptiness, we might need to remove static methods // For both the input lists, their elements are pairwise non-equivalent. // If any element of myResult is override-equivalent to diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java index 40a4117719f..64258f2c711 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java @@ -512,7 +512,7 @@ public Void visit(ASTCatchClause node, @NonNull ReferenceCtx ctx) { @Override public Void visit(ASTInfixExpression node, @NonNull ReferenceCtx ctx) { // need to account for pattern bindings. - // visit left operand first. Maybe it introduces bindings in the rigt operand. + // visit left operand first. Maybe it introduces bindings in the right operand. node.getLeftOperand().acceptVisitor(this, ctx); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java index 01cb116b452..6c6945fe9c5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java @@ -1385,7 +1385,7 @@ public static boolean isSubSignature(JMethodSig m1, JMethodSig m2) { boolean m2Gen = m2.isGeneric(); if (m1Gen ^ m2Gen) { if (m1Gen) { - return false; // this test is assymetric + return false; // this test is asymmetric } else { m2 = m2.getErasure(); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java index 0b7dd29f3fc..94d25ed1183 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java @@ -253,7 +253,7 @@ private void handleFunctionalExprWithoutTargetType(FunctionalExprMirror expr, JT // we need to set the parameter types lambda.updateTypingContext(paramTypes); // And add a constraint on the free variables in the target type. - // These free variables may be inferrable when the classpath is complete + // These free variables may be inferable when the classpath is complete // through the lambda adding constraints on those variables. Since // we do not know the signature of the function, we should allow for // the variables mentioned in this type to resolve to (*unknown*) and not diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java index 57d3dd9eaa3..83ea662d57d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java @@ -114,7 +114,7 @@ default void ivarDependencyRegistered(InferenceContext ctx, InferenceVar var, Se * Such an event is perfectly normal and may happen repeatedly * when performing overload resolution. * - *

    Exceptions occuring in an {@link MethodResolutionPhase#isInvocation() invocation phase} + *

    Exceptions occurring in an {@link MethodResolutionPhase#isInvocation() invocation phase} * are compile-time errors though. * * @param exception Failure record diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 95e0d19e1cf..6bc0049ffa0 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -369,7 +369,7 @@ public class Foo { externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#avoidusinghardcodedip"> Application with hard-coded IP addresses can become impossible to deploy in some cases. -Externalizing IP adresses is preferable. +Externalizing IP addresses is preferable. 3 @@ -1732,7 +1732,7 @@ class C { 2. The assigned value is always overwritten by other assignments before the next read of the variable. - The rule tracks assignements to fields of `this`, and static fields of the current class. + The rule tracks assignments to fields of `this`, and static fields of the current class. This may cause some false positives in timing-sensitive concurrent code, which the rule cannot detect. The rule may be suppressed with the standard `@SuppressWarnings("unused")` tag. diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml index d83a616c288..eb1d33d7b59 100644 --- a/pmd-java/src/main/resources/category/java/codestyle.xml +++ b/pmd-java/src/main/resources/category/java/codestyle.xml @@ -424,7 +424,7 @@ while (true) { // preferred approach message="An empty method in an abstract class should be abstract instead" externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#emptymethodinabstractclassshouldbeabstract"> -Empty or auto-generated methods in an abstract class should be tagged as abstract. This helps to remove their inapproprate +Empty or auto-generated methods in an abstract class should be tagged as abstract. This helps to remove their inappropriate usage by developers who should be implementing their own versions in the concrete subclasses. 1 @@ -1857,7 +1857,7 @@ public interface Foo { } public class Bar { public static interface Baz {} // static ignored - public static enum FoorBar { // static ignored + public static enum FooBar { // static ignored FOO; } } @@ -2105,7 +2105,7 @@ public class Foo { } private class Foo2 { - final Foo2 myFoo2 = Foo2.this; // Use "this" direclty + final Foo2 myFoo2 = Foo2.this; // Use "this" directly } } ]]> diff --git a/pmd-java/src/main/resources/category/java/design.xml b/pmd-java/src/main/resources/category/java/design.xml index db6aaf820dc..0ac74721268 100644 --- a/pmd-java/src/main/resources/category/java/design.xml +++ b/pmd-java/src/main/resources/category/java/design.xml @@ -1436,7 +1436,7 @@ public class MyClass { public void connect(String username, String pssd, String databaseName, - String databaseAdress) + String databaseAddress) // Instead of those parameters object // would ensure a cleaner API and permit // to add extra data transparently (no code change): diff --git a/pmd-java/src/main/resources/category/java/multithreading.xml b/pmd-java/src/main/resources/category/java/multithreading.xml index d792d86728d..21bb0a95d48 100644 --- a/pmd-java/src/main/resources/category/java/multithreading.xml +++ b/pmd-java/src/main/resources/category/java/multithreading.xml @@ -180,7 +180,7 @@ the volatile keyword should not be used for maintenance purpose and portability. actualClass = SomeClass.class; JClassSymbol sym = impl.getSymbol(actualClass); - JMethodSymbol method = getMethodSym(sym, "anotatedMethod"); + JMethodSymbol method = getMethodSym(sym, "annotatedMethod"); assertHasAnnotations(emptySet(), method.getFormalParameters().get(0)); assertHasAnnotations(setOf(createAnnotationInstance(MethodAnnotation.class)), method); } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/testdata/SomeClass.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/testdata/SomeClass.java index 607ee1c4dc8..d989459d7b5 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/testdata/SomeClass.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/symbols/testdata/SomeClass.java @@ -27,7 +27,7 @@ void withAnnotatedLocal() { } @MethodAnnotation - void anotatedMethod(final int x) { + void annotatedMethod(final int x) { } diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ParserTestSpec.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ParserTestSpec.kt index 5910d76116e..1fcb34e84d5 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ParserTestSpec.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ParserTestSpec.kt @@ -120,7 +120,7 @@ abstract class ParserTestSpec(body: ParserTestSpec.() -> Unit) : DslDrivenSpec() * and grouped by the given [name]. * * @param name Name of the container test - * @param javaVersions Language versions fo which to generate tests + * @param javaVersions Language versions for which to generate tests * @param spec Assertions. */ fun parserTest(name: String, diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/VarScopingTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/VarScopingTest.kt index d1fc0ad6526..e5e89d3523a 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/VarScopingTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/VarScopingTest.kt @@ -237,7 +237,7 @@ class VarScopingTest : ProcessorTestSpec({ } doTest("Inside fallthrough: var is in scope") { - // this is suprising but legal, the var is just not definitely + // this is surprising but legal, the var is just not definitely // assigned at the point of use iAccess2 shouldResolveToLocal ivar } diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TestUtilitiesForTypes.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TestUtilitiesForTypes.kt index 9899f112266..9099589a748 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TestUtilitiesForTypes.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TestUtilitiesForTypes.kt @@ -213,12 +213,12 @@ fun JTypeMirror.shouldBePrimitive(kind: JPrimitiveType.PrimitiveTypeKind) { fun canIntersect(t: JTypeMirror, s: JTypeMirror, vararg others: JTypeMirror): Boolean { val comps = listOf(t, s, *others) - return comps.filter { it.isExlusiveIntersectionBound }.size <= 1 + return comps.filter { it.isExclusiveIntersectionBound }.size <= 1 && comps.none { it.isPrimitive || it.isGenericTypeDeclaration } } /** If so, there can only be one in a well formed intersection. */ -val JTypeMirror.isExlusiveIntersectionBound +val JTypeMirror.isExclusiveIntersectionBound get() = this is JArrayType || this is JClassType && this.symbol.isClass || this is JTypeVar diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/CaptureInferenceTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/CaptureInferenceTest.kt index f73631c84c0..d31e2f9cb43 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/CaptureInferenceTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/CaptureInferenceTest.kt @@ -550,7 +550,7 @@ public class SubClass { acu.varId("k") shouldHaveType acu.typeSystem.OBJECT } - parserTest("Problem with capture of type parametr that has wildcard parameterized bound") { + parserTest("Problem with capture of type parameter that has wildcard parameterized bound") { val (acu, spy) = parser.parseWithTypeInferenceSpy( """ class AJjtN {} @@ -577,7 +577,7 @@ public class SubClass { call.overloadSelectionInfo::isFailed shouldBe false } } - parserTest("Problem with capture of type parametr that has wildcard parameterized bound (field access)") { + parserTest("Problem with capture of type parameter that has wildcard parameterized bound (field access)") { val (acu, spy) = parser.parseWithTypeInferenceSpy( """ class AJjtN { diff --git a/pmd-java/src/test/resources/ant/java/MoreThanThousandLinesOfCodeWithDuplicateLiterals.java b/pmd-java/src/test/resources/ant/java/MoreThanThousandLinesOfCodeWithDuplicateLiterals.java index 7c102a99a4e..d658eb8e10c 100644 --- a/pmd-java/src/test/resources/ant/java/MoreThanThousandLinesOfCodeWithDuplicateLiterals.java +++ b/pmd-java/src/test/resources/ant/java/MoreThanThousandLinesOfCodeWithDuplicateLiterals.java @@ -1,7 +1,7 @@ package org.example.pmd; /** * This class with - * duplicated litterals + * duplicated literals * after more than one thousand lines should generate a warning, ending with a line number greater than 1000. * * This number is formatted with the thousand separator, and given the platform's locale, it may or not be in the ASCII diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases.java index 457dc0e0c74..0564ae2238a 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases.java +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases.java @@ -3,7 +3,7 @@ */ /* - * This file is to test the JavaCC java grammer, whether we can parse specific java constructs without + * This file is to test the JavaCC java grammar, whether we can parse specific java constructs without * throwing a syntax error. */ diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.java index ca8849fdfdc..398824e3fd1 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.java +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.java @@ -15,7 +15,7 @@ import java.util.zip.ZipEntry; /* - * This file is to test the JavaCC java grammer, whether we can parse specific java constructs without + * This file is to test the JavaCC java grammar, whether we can parse specific java constructs without * throwing a syntax error. * * Java 7, see: http://docs.oracle.com/javase/7/docs/technotes/guides/language/enhancements.html#javase7 diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.java index a9d8cb8004d..9763e93d5a0 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.java +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.java @@ -12,7 +12,7 @@ * @see JEP 443: Unnamed Patterns and Variables (Preview) (Java 21) * @see JEP 456: Unnamed Variables & Patterns (Java 22) */ -class Jep456_UnamedPatternsAndVariables { +class Jep456_UnnamedPatternsAndVariables { record Point(int x, int y) { } enum Color { RED, GREEN, BLUE } record ColoredPoint(Point p, Color c) { } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt index 6b7b7c19ca5..49ef85109b1 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt @@ -3,10 +3,10 @@ +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.List", @ImportedSimpleName = "List", @ModuleImport = false, @PackageName = "java.util", @Static = false] +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.Queue", @ImportedSimpleName = "Queue", @ModuleImport = false, @PackageName = "java.util", @Static = false] +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.stream.Collectors", @ImportedSimpleName = "Collectors", @ModuleImport = false, @PackageName = "java.util.stream", @Static = false] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep456_UnamedPatternsAndVariables", @CanonicalName = "Jep456_UnamedPatternsAndVariables", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Jep456_UnamedPatternsAndVariables", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep456_UnnamedPatternsAndVariables", @CanonicalName = "Jep456_UnnamedPatternsAndVariables", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Jep456_UnnamedPatternsAndVariables", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] +- ClassBody[@Empty = false, @Size = 19] - +- RecordDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep456_UnamedPatternsAndVariables$Point", @CanonicalName = "Jep456_UnamedPatternsAndVariables.Point", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = true, @RegularClass = false, @RegularInterface = false, @SimpleName = "Point", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + +- RecordDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep456_UnnamedPatternsAndVariables$Point", @CanonicalName = "Jep456_UnnamedPatternsAndVariables.Point", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = true, @RegularClass = false, @RegularInterface = false, @SimpleName = "Point", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = ()] | +- RecordComponentList[@Empty = false, @Size = 2, @Varargs = false] | | +- RecordComponent[@EffectiveVisibility = Visibility.V_PRIVATE, @Varargs = false, @Visibility = Visibility.V_PRIVATE] @@ -18,7 +18,7 @@ | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PRIVATE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "y", @PatternBinding = false, @RecordComponent = true, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PRIVATE] | +- RecordBody[@Empty = true, @Size = 0] - +- EnumDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep456_UnamedPatternsAndVariables$Color", @CanonicalName = "Jep456_UnamedPatternsAndVariables.Color", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = true, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = false, @SimpleName = "Color", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + +- EnumDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep456_UnnamedPatternsAndVariables$Color", @CanonicalName = "Jep456_UnnamedPatternsAndVariables.Color", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = true, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = false, @SimpleName = "Color", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = ()] | +- EnumBody[@Empty = false, @SeparatorSemi = false, @Size = 3, @TrailingComma = false] | +- EnumConstant[@AnonymousClass = false, @EffectiveVisibility = Visibility.V_PACKAGE, @Image = "RED", @MethodName = "new", @Name = "RED", @Visibility = Visibility.V_PUBLIC] @@ -30,7 +30,7 @@ | +- EnumConstant[@AnonymousClass = false, @EffectiveVisibility = Visibility.V_PACKAGE, @Image = "BLUE", @MethodName = "new", @Name = "BLUE", @Visibility = Visibility.V_PUBLIC] | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = ()] | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PACKAGE, @EnumConstant = true, @ExceptionBlockParameter = false, @Field = false, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "BLUE", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = true, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_PUBLIC] - +- RecordDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep456_UnamedPatternsAndVariables$ColoredPoint", @CanonicalName = "Jep456_UnamedPatternsAndVariables.ColoredPoint", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = true, @RegularClass = false, @RegularInterface = false, @SimpleName = "ColoredPoint", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + +- RecordDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep456_UnnamedPatternsAndVariables$ColoredPoint", @CanonicalName = "Jep456_UnnamedPatternsAndVariables.ColoredPoint", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = true, @RegularClass = false, @RegularInterface = false, @SimpleName = "ColoredPoint", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = ()] | +- RecordComponentList[@Empty = false, @Size = 2, @Varargs = false] | | +- RecordComponent[@EffectiveVisibility = Visibility.V_PRIVATE, @Varargs = false, @Visibility = Visibility.V_PRIVATE] @@ -125,29 +125,29 @@ | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = " ", @Empty = false, @Image = "\" \"", @Length = 1, @LiteralText = "\" \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "y", @Name = "y", @ParenthesisDepth = 0, @Parenthesized = false] - +- ClassDeclaration[@Abstract = true, @Annotation = false, @Anonymous = false, @BinaryName = "Jep456_UnamedPatternsAndVariables$Ball", @CanonicalName = "Jep456_UnamedPatternsAndVariables.Ball", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Ball", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + +- ClassDeclaration[@Abstract = true, @Annotation = false, @Anonymous = false, @BinaryName = "Jep456_UnnamedPatternsAndVariables$Ball", @CanonicalName = "Jep456_UnnamedPatternsAndVariables.Ball", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Ball", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] | +- ModifierList[@EffectiveModifiers = (JModifier.SEALED, JModifier.ABSTRACT), @ExplicitModifiers = (JModifier.SEALED, JModifier.ABSTRACT)] | +- PermitsList[@Empty = false, @Size = 3] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "RedBall"] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "BlueBall"] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "GreenBall"] | +- ClassBody[@Empty = true, @Size = 0] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep456_UnamedPatternsAndVariables$RedBall", @CanonicalName = "Jep456_UnamedPatternsAndVariables.RedBall", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "RedBall", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep456_UnnamedPatternsAndVariables$RedBall", @CanonicalName = "Jep456_UnnamedPatternsAndVariables.RedBall", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "RedBall", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] | +- ModifierList[@EffectiveModifiers = (JModifier.FINAL), @ExplicitModifiers = (JModifier.FINAL)] | +- ExtendsList[@Empty = false, @Size = 1] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Ball"] | +- ClassBody[@Empty = true, @Size = 0] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep456_UnamedPatternsAndVariables$BlueBall", @CanonicalName = "Jep456_UnamedPatternsAndVariables.BlueBall", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "BlueBall", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep456_UnnamedPatternsAndVariables$BlueBall", @CanonicalName = "Jep456_UnnamedPatternsAndVariables.BlueBall", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "BlueBall", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] | +- ModifierList[@EffectiveModifiers = (JModifier.FINAL), @ExplicitModifiers = (JModifier.FINAL)] | +- ExtendsList[@Empty = false, @Size = 1] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Ball"] | +- ClassBody[@Empty = true, @Size = 0] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep456_UnamedPatternsAndVariables$GreenBall", @CanonicalName = "Jep456_UnamedPatternsAndVariables.GreenBall", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "GreenBall", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep456_UnnamedPatternsAndVariables$GreenBall", @CanonicalName = "Jep456_UnnamedPatternsAndVariables.GreenBall", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "GreenBall", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] | +- ModifierList[@EffectiveModifiers = (JModifier.FINAL), @ExplicitModifiers = (JModifier.FINAL)] | +- ExtendsList[@Empty = false, @Size = 1] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Ball"] | +- ClassBody[@Empty = true, @Size = 0] - +- RecordDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep456_UnamedPatternsAndVariables$Box", @CanonicalName = "Jep456_UnamedPatternsAndVariables.Box", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = true, @RegularClass = false, @RegularInterface = false, @SimpleName = "Box", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + +- RecordDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep456_UnnamedPatternsAndVariables$Box", @CanonicalName = "Jep456_UnnamedPatternsAndVariables.Box", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = true, @RegularClass = false, @RegularInterface = false, @SimpleName = "Box", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = ()] | +- TypeParameters[@Empty = false, @Size = 1] | | +- TypeParameter[@Image = "T", @Name = "T", @TypeBound = true] @@ -316,7 +316,7 @@ | +- VoidType[] | +- FormalParameters[@Empty = true, @Size = 0] | +- Block[@Empty = true, @Size = 0, @containsComment = false] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep456_UnamedPatternsAndVariables$Order", @CanonicalName = "Jep456_UnamedPatternsAndVariables.Order", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Order", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep456_UnnamedPatternsAndVariables$Order", @CanonicalName = "Jep456_UnnamedPatternsAndVariables.Order", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Order", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | +- ClassBody[@Empty = true, @Size = 0] +- FieldDeclaration[@EffectiveVisibility = Visibility.V_PRIVATE, @Static = true, @Visibility = Visibility.V_PRIVATE] @@ -491,7 +491,7 @@ | +- ArgumentList[@Empty = false, @Size = 2] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep456_UnamedPatternsAndVariables$ScopedContext", @CanonicalName = "Jep456_UnamedPatternsAndVariables.ScopedContext", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "ScopedContext", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep456_UnnamedPatternsAndVariables$ScopedContext", @CanonicalName = "Jep456_UnnamedPatternsAndVariables.ScopedContext", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "ScopedContext", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC), @ExplicitModifiers = (JModifier.STATIC)] | +- ImplementsList[@Empty = false, @Size = 1] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "AutoCloseable"] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.java index 0628b7dcf6d..c85850e3057 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.java +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.java @@ -71,7 +71,7 @@ class X { } } - void expanedPrimitiveSupportInSwitch() { + void expandedPrimitiveSupportInSwitch() { class User { boolean isLoggedIn() { return false; } int id() { return 42; } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt index 0360136ed35..c228a586ba1 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt @@ -341,7 +341,7 @@ | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "byte: ... ", @Empty = false, @Image = "\"byte: ... \"", @Length = 10, @LiteralText = "\"byte: ... \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] - +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "expanedPrimitiveSupportInSwitch", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "expandedPrimitiveSupportInSwitch", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | +- VoidType[] | +- FormalParameters[@Empty = true, @Size = 0] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java8/type_annotations.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java8/type_annotations.java index 96df8a5624a..65133e6292d 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java8/type_annotations.java +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java8/type_annotations.java @@ -9,7 +9,7 @@ @Target(ElementType.TYPE_USE) @interface NonNull {} -class AnnotedArrayType { +class AnnotatedArrayType { @NonNull int @NonNull[] @NonNull[] field1; @NonNull int @NonNull [] @NonNull [] field2; private @NonNull int array2 @NonNull [] @NonNull []; diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AccessorClassGeneration.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AccessorClassGeneration.xml index f5a610e8f0d..0236be6ac2e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AccessorClassGeneration.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AccessorClassGeneration.xml @@ -109,7 +109,7 @@ public class Foo1 { #1452 ArrayIndexOutOfBoundsException with Annotations for AccessorClassGenerationRule 0 java 10 diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml index 47bc9795469..3da8abbf309 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml @@ -239,7 +239,7 @@ public class Foo { if (results.first()) { //do a little logic do { - //this is handeling paging + //this is handling paging if (results.getInt("RowNum") >= firstEntry && results.getInt("RowNum") <= lastEntry) { answer = results.getString("answer"); stringList.add(answer); diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/LiteralsFirstInComparisons.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/LiteralsFirstInComparisons.xml index b3781c9bf61..68ceadc1597 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/LiteralsFirstInComparisons.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/LiteralsFirstInComparisons.xml @@ -442,7 +442,7 @@ public class LiteralsFirstInComparisonCase { public static boolean compare() { return S1.equals(S2); } - public static boolean isUnkown() { + public static boolean isUnknown() { return Foo.VERSION.equals(S2); } } @@ -467,7 +467,7 @@ public class LiteralsFirstInComparisonCase { public static boolean compare() { return S1.equals(S2); } - public static boolean isUnkown() { + public static boolean isUnknown() { return Foo.VERSION.equals(S2); } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/OneDeclarationPerLine.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/OneDeclarationPerLine.xml index 9900d3c039c..2e8c76f027e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/OneDeclarationPerLine.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/OneDeclarationPerLine.xml @@ -12,7 +12,7 @@ public class Foo { public void bar() { - String name, lastname, adress; + String name, lastname, address; } } ]]> diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/PreserveStackTrace.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/PreserveStackTrace.xml index 637b6dffa6e..5b63d629686 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/PreserveStackTrace.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/PreserveStackTrace.xml @@ -149,7 +149,7 @@ public class Foo { - 9, Excetion is cast, OK + 9, Exception is cast, OK 0 - Problem with capture of type parametr that has wildcard parameterized bound + Problem with capture of type parameter that has wildcard parameterized bound 0 {} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/CommentDefaultAccessModifier.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/CommentDefaultAccessModifier.xml index c856252c0ba..8836da248a4 100755 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/CommentDefaultAccessModifier.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/CommentDefaultAccessModifier.xml @@ -484,7 +484,7 @@ class SomeTest { void repeatedTest() {} @RegisterExtension - void registerExtenstionTest(){} + void registerExtensionTest(){} } ]]> diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/MethodNamingConventions.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/MethodNamingConventions.xml index ecdd106b5da..ed9e28f3323 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/MethodNamingConventions.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/MethodNamingConventions.xml @@ -199,7 +199,7 @@ public class TournamentTest { public void getBestTeam() { } - @ParameterizedTest // this is a paramterized junit 5 test + @ParameterizedTest // this is a parameterized junit 5 test public void getWorstTeam(String param) { } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml index 3a3bad0258b..c2b53aa496e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml @@ -712,7 +712,7 @@ class Scratch { 9 void bar2(L2> l) {} void bar4(L2> l) {} void bar3(L2 l) {} - void foor(List someList) { + void foo(List someList) { bar(x -> (Comparable) "something"); // redundant bar2(x -> (Comparable) "something"); // redundant: lambda not context dependent bar4(x -> (Comparable) "something"); // redundant: lambda not context dependent diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml index 02eefa107fb..bfffc4b719d 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml @@ -352,7 +352,7 @@ import static net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryFullyQuali import static net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryFullyQualifiedNameTest.Container.PhonyMockito.mock; public class Foo { - private Foo bar = PhonyMockito.mock(Foo.class); // doing simply mock(Foo.class) would use a differen method than intended + private Foo bar = PhonyMockito.mock(Foo.class); // doing simply mock(Foo.class) would use a different method than intended } ]]> diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml index f9a13041d13..e19a72375a6 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryImport.xml @@ -345,7 +345,7 @@ public class FooTest { - #1465 False Positve UnusedImports with javadoc @link + #1465 False Positive UnusedImports with javadoc @link 0 - #1547 False Positve UnusedImports with javadoc for identifiers with underscores + #1547 False Positive UnusedImports with javadoc for identifiers with underscores 0 #2025 False Positive in UnusedImports for params when using @see with FQCN 0 #2025 False Positive in UnusedImports for params when using @link with FQCN 0 - method decalres a subclass of RuntimeException + method declares a subclass of RuntimeException 1 2 entry.hashCode()) { // +3 (nesting = 2) + if (first != null) { // +2 (nesting = 1) + if (first.hashCode() > entry.hashCode()) { // +3 (nesting = 2) throw new Exception(); } if (txn.isActive()) { // +3 (nesting = 2) for // +4 (nesting = 3) - (Entry e = frst; e != null; e = e.getPrevious()) { + (Entry e = first; e != null; e = e.getPrevious()) { final long version = e.getVersion(); final long depends = ti.wwDependency(version, txn.getTransactionStatus(), 0); @@ -98,8 +98,8 @@ public class Foo { } } } - entry.setPrevious(frst); - frst = entry; + entry.setPrevious(first); + first = entry; break; } } catch (final Exception re) { // +2 (nesting = 1) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/LawOfDemeter.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/LawOfDemeter.xml index b17e617bc7e..d58209f008e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/LawOfDemeter.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/LawOfDemeter.xml @@ -780,7 +780,7 @@ public final class ControlEvent { class Q { void foo(Token t) { Manager m = t.getLastToken().manager; - m.doSomethn(); + m.doSomething(); } } ]]> diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/UseObjectForClearerAPI.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/UseObjectForClearerAPI.xml index 9fbbe825349..7fb0ab1cfe1 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/UseObjectForClearerAPI.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/UseObjectForClearerAPI.xml @@ -41,7 +41,7 @@ public class MyClass { public void connect(String username, String pssd, String databaseName, - String databaseAdress) + String databaseAddress) // Instead of those parameters object // would ensure a cleaner API and permit // to add extra data transparently (no code change): @@ -60,19 +60,19 @@ public class MyClass { protected void connectProtected(String username, String pssd, String databaseName, - String databaseAdress) + String databaseAddress) { } void connectPackagePrivate(String username, String pssd, String databaseName, - String databaseAdress) + String databaseAddress) { } private void connectPrivate(String username, String pssd, String databaseName, - String databaseAdress) + String databaseAddress) { } } @@ -87,7 +87,7 @@ public class MyClass { public void connectProtected(String username, String[] pssd, String databaseName, - String databaseAdress) + String databaseAddress) { } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentRequired.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentRequired.xml index 4d5db44069a..6fe42408a28 100755 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentRequired.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentRequired.xml @@ -264,45 +264,45 @@ public class CommentRequired implements java.io.Serializable { package de.konsens.biene.ka.client; /** - * Kommentar zu PmdMissingHeaderCommentTest + * Comment for PmdMissingHeaderCommentTest */ public class PmdMissingHeaderCommentTest { /** - * Kommentar zu methode1() + * Comment for method1() */ - public void methode1() { + public void method1() { /** - * Kommentar zu Local + * Comment for Local */ class Local { /** - * Kommentar zu methode1() + * Comment for method1() */ - void methode1() { + void method1() { } } Local local = new Local(); - local.methode1(); + local.method1(); /** - * Kommentar zu Local2 + * Comment for Local2 */ class Local2 { /** - * Kommentar zu methode1() + * Comment for method1() */ - void methode1() { + void method1() { } } Local2 local2 = new Local2(); - local2.methode1(); + local2.method1(); } } ]]> diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloneMethodMustImplementCloneable.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloneMethodMustImplementCloneable.xml index a62c9c613c9..afc63d0e469 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloneMethodMustImplementCloneable.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloneMethodMustImplementCloneable.xml @@ -124,12 +124,12 @@ public final class Foo { - Bug 681, extending a class which implements Clonable. + Bug 681, extending a class which implements Cloneable. 0 - Alernate Basic test case + Alternate Basic test case 2 4,9 one break, but two cases + one default case. But there is an intentional fall through - -because there are no statemenets between case 1 and case 2. +because there are no statements between case 1 and case 2. diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryLocalBeforeReturnTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryLocalBeforeReturnTest.java index 15b4c13a3c1..7a01f3b8386 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryLocalBeforeReturnTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryLocalBeforeReturnTest.java @@ -6,6 +6,7 @@ import net.sourceforge.pmd.test.PmdRuleTst; +@Deprecated class UnnecessaryLocalBeforeReturnTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/VariableCanBeInlinedTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/VariableCanBeInlinedTest.java new file mode 100644 index 00000000000..9aebcb97257 --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/VariableCanBeInlinedTest.java @@ -0,0 +1,11 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.codestyle; + +import net.sourceforge.pmd.test.PmdRuleTst; + +class VariableCanBeInlinedTest extends PmdRuleTst { + // no additional unit tests +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/VariableCanBeInlined.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/VariableCanBeInlined.xml new file mode 100644 index 00000000000..788b8210b51 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/VariableCanBeInlined.xml @@ -0,0 +1,1042 @@ + + + + + + + skip void/native/abstract methods + 0 + + + + + skip literal returns + 0 + + + + + simple failure case + 1 + + + + + skip complicated returns + 0 + + + + + skip method calls + 0 + + + + + #1495 [java] UnnecessaryLocalBeforeReturn with assert + 0 + =0; + return res; + } +} + ]]> + + + + #219 ClassCastException in switch case with local variable returned + 1 + + + + + Detect violation even if not on consecutive lines + false + 1 + + + + + No violations on multiple uses of the variable + 0 + + + + + No violations on multiple uses of the variable - statement order does not matter + false + 0 + + + + + #933 UnnecessaryLocalBeforeReturn false positive for SuppressWarnings annotation + 0 + { + T getSomeT() { return null; } + private static T findEventTypeValueByName(TestCase unchecked) { + @SuppressWarnings("unchecked") + T result = (T) unchecked.getSomeT(); + return result; + } +} + ]]> + + + + #282 UnnecessaryLocalBeforeReturn false positive when cloning Maps + 0 + customerErrors = new ConcurrentHashMap<>(); + + public void error(String customerNr, String errorMsg) { + customerErrors.put(customerNr, errorMsg); + } + + public Map getAndReset() { + final Map copy = new HashMap<>(customerErrors); + customerErrors.clear(); + return copy; // PMD complains that variable could be avoided + } +} + ]]> + + + + #310 UnnecessaryLocalBeforeReturn enhancement is overly restrictive -- method order matters + 0 + + + + + #310 UnnecessaryLocalBeforeReturn statement order does not matter + false + 2 + 3,10 + + + + + #1775 [java] False negative in UnnecessaryLocalBeforeReturn when splitting statements across multiple lines + 1 + + + + + #1804 [java] NPE with fields + 1 + + + + + FP with captured method reference + 0 + create() { + final Object o = new Object(); // captured by the method ref + return o::toString; + } +} + ]]> + + + + FN with lambdas #3275 + 1 + 5 + c = () -> { String s = "1"; return s; }; + } +} + ]]> + + + + FN with anonymous classes #3275 + 1 + 7 + c = new Callable<>() { + public String call() { + String s = "1"; + return s; + } + }; + } +} + ]]> + + + + [java] UnnecessaryLocalBeforeReturn - false positive with catch clause + 0 + {}); + if (result != null) { + throw new RuntimeException(result); + } + } + + private Exception attempt(Runnable task) { + try { + task.run(); + return null; + } catch (Exception e) { + // src/Example.java:15: UnnecessaryLocalBeforeReturn: Consider simply returning the value vs storing it in local variable 'e' + return e; + } + } +} +]]> + + + + [java] UnnecessaryLocalBeforeReturn false positive when negating variable #2206 + 0 + + + + + + + #5770 Simple unnecessary local before throw + 1 + 3 + + + + Variable used elsewhere - no violation + 0 + + + + Annotated variable - no violation + 0 + + + + Statements not consecutive - no violation when order matters + 0 + + + + Statements not consecutive - violation when order does not matter + false + 1 + + + + Throw not using variable - no violation + 0 + + + + Variable used in try-catch - no violation + 0 + + + + Multiple variables but only one used in throw + 0 + + + + Multiple variables but only one used in throw + 1 + 4 + + + + Throwing field - no violation + 0 + + + + Throwing parameter - no violation + 0 + + + + Throw in switch statement + 1 + 5 + + + + Throw in if statement + 1 + 4 + + + + Throw in try-with-resources + 1 + 4 + + + + Throw inside for loop block + 1 + 4 + + + + Throw using lambda expression - no violation + 0 + s = () -> new RuntimeException(); + throw s.get(); + } +} + ]]> + + + Throw in ternary - no violation + 0 + + + + Nested block with unnecessary throw variable + 1 + 4 + + + + Inner class with throw - no violation + 1 + 4 + + + + Exception assigned and rethrown inside catch - no violation + 1 + 6 + + + + Multiple throw variables but one is unnecessary + 1 + 4 + + + + Return with method chain - no violation + 1 + + + + Throw with method chain - no violation + 1 + + + + + Return with array access - no violation + 1 + + + + + Return with field access - no violation + 1 + + + + + Throw with ternary initialization - violation + 1 + + + + + Return in try-with-resources - violation + 1 + 4 + + + + + Return in synchronized block - violation + 1 + 4 + + + + + Throw with multiple catch blocks - no violation + 0 + + + + Super coupling: Throw with multiple catch blocks + + 0 + + + + Would we detect it, if the declaration and initialization wouldn't be separated? + 1 + + + + Coupling: Throw with multiple catch blocks + + 0 + + + + + Return with instanceof check + 1 + + + + + Throw with initialization in if block - no violation + 0 + + + + + + + Simple yield with unnecessary local variable + 1 + 5 + { + int result = 10; // unnecessary + yield result; + } + default -> 0; + }; + } +} + ]]> + + + + Yield with variable used elsewhere - no violation + 0 + { + int result = 10; + System.out.println(result); + yield result; + } + default -> 0; + }; + } +} + ]]> + + + + Yield with multiple variables - one unnecessary + 1 + 7 + { + int x = 5; + int y = 10; + int result = x + y; // unnecessary + yield result; + } + default -> 0; + }; + } +} + ]]> + + + + Yield with complex expression - violation + 1 + { + int result = calculate(value) * 2; + yield result; + } + default -> 0; + }; + } + private int calculate(int x) { return x * 10; } +} + ]]> + + + + Yield with annotated variable - no violation + 0 + { + @SuppressWarnings("deprecation") + int result = deprecatedMethod(); + yield result; + } + default -> 0; + }; + } + @Deprecated + private int deprecatedMethod() { return 42; } +} + ]]> + + + + Yield with try-catch block - no violation + 0 + { + int result; + try { + result = riskyOperation(); + } catch (Exception e) { + result = -1; + } + yield result; + } + default -> 0; + }; + } + private int riskyOperation() throws Exception { return 42; } +} + ]]> + + + + Yield with multiple statements before - violation + 1 + 7 + { + log("processing case 1"); + validate(value); + int result = 42; // unnecessary + yield result; + } + default -> 0; + }; + } + private void log(String msg) {} + private void validate(int x) {} +} + ]]> + + + + Yield in nested switch expression + 1 + 6 + switch (subValue) { + case 1 -> { + int result = 100; // unnecessary + yield result; + } + default -> 0; + }; + default -> 0; + }; + } +} + ]]> + + From b2f6f4c292daca0007b3c3b8ca5d8d966aa0a34c Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Tue, 12 Aug 2025 23:40:15 +0200 Subject: [PATCH 1259/1962] Include code snippet in the message --- .../codestyle/UselessParenthesesRule.java | 43 ++++++------------- .../rule/codestyle/xml/UselessParentheses.xml | 18 ++++---- 2 files changed, 24 insertions(+), 37 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java index 94fecc16eb3..56bd797afd5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java @@ -11,17 +11,17 @@ import static net.sourceforge.pmd.lang.java.rule.codestyle.UselessParenthesesRule.Necessity.definitely; import static net.sourceforge.pmd.lang.java.rule.codestyle.UselessParenthesesRule.Necessity.necessaryIf; +import net.sourceforge.pmd.lang.document.Chars; +import net.sourceforge.pmd.lang.document.TextRegion; import net.sourceforge.pmd.lang.java.ast.ASTAssignmentExpression; import net.sourceforge.pmd.lang.java.ast.ASTCastExpression; import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression; import net.sourceforge.pmd.lang.java.ast.ASTExpression; import net.sourceforge.pmd.lang.java.ast.ASTInfixExpression; import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression; -import net.sourceforge.pmd.lang.java.ast.ASTLiteral; import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression; import net.sourceforge.pmd.lang.java.ast.ASTSwitchExpression; import net.sourceforge.pmd.lang.java.ast.ASTUnaryExpression; -import net.sourceforge.pmd.lang.java.ast.ASTVariableAccess; import net.sourceforge.pmd.lang.java.ast.BinaryOp; import net.sourceforge.pmd.lang.java.ast.JavaNode; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; @@ -48,6 +48,7 @@ public final class UselessParenthesesRule extends AbstractJavaRulechainRule { + "For example, in `(a == null) == (b == null)`, only the second pair " + "of parentheses is necessary, but the expression is clearer that way.") .build(); + private static final int MAX_SNIPPET_LENGTH = 50; public UselessParenthesesRule() { super(ASTExpression.class); @@ -87,40 +88,24 @@ private void checkExpr(ASTExpression e, Object data) { if (e.getParenthesisDepth() > 1) { asCtx(data).addViolationWithMessage(e, "Duplicate parentheses."); } else { - String description = getNodeDescription(e); - if (description != null) { - asCtx(data).addViolationWithMessage(e, "Useless parentheses around {0}.", - description); + TextRegion textRegion = e.getTextRegion().growLeft(-1).growRight(-1); + Chars nodeContent = e.getTextDocument().sliceOriginalText(textRegion).trim(); + String snippet; + String dots = "..."; + if (nodeContent.length() > MAX_SNIPPET_LENGTH) { + snippet = nodeContent.slice(0, MAX_SNIPPET_LENGTH - dots.length()) + .toString() + dots; } else { - asCtx(data).addViolation(e); + snippet = nodeContent.toString(); } + asCtx(data).addViolationWithMessage(e, "Useless parentheses around `{0}`.", + snippet); + } } } - private String getNodeDescription(ASTExpression e) { - final String desc; - if (e instanceof ASTInfixExpression) { - desc = ((ASTInfixExpression) e).getOperator().getToken(); - } else if (e instanceof ASTUnaryExpression) { - desc = ((ASTUnaryExpression) e).getOperator().getToken(); - } else if (e instanceof ASTLiteral) { - desc = ((ASTLiteral) e).getLiteralText().toString(); - } else if (e instanceof ASTVariableAccess) { - desc = ((ASTVariableAccess) e).getName(); - } else if (e instanceof ASTPrimaryExpression) { - desc = "primary expression"; - } else if (e instanceof ASTAssignmentExpression) { - desc = "assignment expression"; - } else if (e instanceof ASTConditionalExpression) { - desc = "conditional expression"; - } else { - desc = null; - } - return desc; - } - public static Necessity needsParentheses(ASTExpression inner, JavaNode outer) { // Note: as of jdk 15, PatternExpression cannot be parenthesized // TypeExpression may never be parenthesized either diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml index 2adf6ab2715..e2e5ff2d171 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml @@ -665,16 +665,17 @@ public class Test { Detailed message - 8 + 9 - Useless parentheses around *. - Useless parentheses around 4. - Useless parentheses around conditional expression. - Useless parentheses around k3. - Useless parentheses around primary expression. - Useless parentheses around ++. - Useless parentheses around assignment expression. + Useless parentheses around `3 * 3`. + Useless parentheses around `4`. + Useless parentheses around `true ? 4 : 2`. + Useless parentheses around `k3`. + Useless parentheses around `id(k3)`. + Useless parentheses around `k5++`. + Useless parentheses around `k2 = 2`. Duplicate parentheses. + Useless parentheses around `"very" + "long " + "concat split...`. From cea62a432170efe6768dfe9cddc8c3cc81978187 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Wed, 13 Aug 2025 20:08:47 +0200 Subject: [PATCH 1260/1962] Use pretty printing --- .../java/ast/internal/PrettyPrintingUtil.java | 45 ++++++++++++++++++- .../codestyle/UselessParenthesesRule.java | 16 +++---- .../ast/internal/PrettyPrintingUtilTest.java | 12 +++++ .../rule/codestyle/xml/UselessParentheses.xml | 11 ++++- 4 files changed, 70 insertions(+), 14 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/PrettyPrintingUtil.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/PrettyPrintingUtil.java index d78b500215e..6ffbe9b2141 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/PrettyPrintingUtil.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/PrettyPrintingUtil.java @@ -15,7 +15,9 @@ import net.sourceforge.pmd.lang.java.ast.ASTAnnotationTypeDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTArgumentList; import net.sourceforge.pmd.lang.java.ast.ASTArrayAccess; +import net.sourceforge.pmd.lang.java.ast.ASTArrayAllocation; import net.sourceforge.pmd.lang.java.ast.ASTArrayType; +import net.sourceforge.pmd.lang.java.ast.ASTAssignmentExpression; import net.sourceforge.pmd.lang.java.ast.ASTCastExpression; import net.sourceforge.pmd.lang.java.ast.ASTClassDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTClassLiteral; @@ -46,6 +48,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTReferenceType; import net.sourceforge.pmd.lang.java.ast.ASTResource; import net.sourceforge.pmd.lang.java.ast.ASTSuperExpression; +import net.sourceforge.pmd.lang.java.ast.ASTSwitchExpression; import net.sourceforge.pmd.lang.java.ast.ASTThisExpression; import net.sourceforge.pmd.lang.java.ast.ASTType; import net.sourceforge.pmd.lang.java.ast.ASTTypeArguments; @@ -363,8 +366,14 @@ public Void visit(ASTInfixExpression node, StringBuilder sb) { @Override public Void visit(ASTUnaryExpression node, StringBuilder sb) { - sb.append(node.getOperator()); + boolean prefix = node.getOperator().isPrefix(); + if (prefix) { + sb.append(node.getOperator()); + } printWithParensIfNecessary(node.getOperand(), sb, node); + if (!prefix) { + sb.append(node.getOperator()); + } return null; } @@ -469,6 +478,40 @@ public Void visit(ASTMethodReference node, StringBuilder sb) { return null; } + @Override + public Void visit(ASTAssignmentExpression node, StringBuilder sb) { + node.getLeftOperand().acceptVisitor(this, sb); + sb.append(" = "); + node.getRightOperand().acceptVisitor(this, sb); + return null; + } + + @Override + public Void visit(ASTSwitchExpression node, StringBuilder sb) { + sb.append("switch ("); + node.getFirstChild().acceptVisitor(this, sb); + sb.append(") { ... }"); + return null; + } + + @Override + public Void visit(ASTArrayAllocation node, StringBuilder sb) { + sb.append("new "); + node.getTypeNode().getElementType().acceptVisitor(this, sb); + node.getTypeNode().getDimensions().children().forEach(child -> { + sb.append('['); + JavaNode firstChild = child.getFirstChild(); + if (firstChild != null) { + firstChild.acceptVisitor(this, sb); + } + sb.append(']'); + }); + if (node.getArrayInitializer() != null) { + sb.append(node.getArrayInitializer().length() == 0 ? "{}" : "{ ... }"); + } + return null; + } + private void addQualifier(QualifiableExpression node, StringBuilder data) { ASTExpression qualifier = node.getQualifier(); if (qualifier != null) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java index 56bd797afd5..52406960e68 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java @@ -11,8 +11,6 @@ import static net.sourceforge.pmd.lang.java.rule.codestyle.UselessParenthesesRule.Necessity.definitely; import static net.sourceforge.pmd.lang.java.rule.codestyle.UselessParenthesesRule.Necessity.necessaryIf; -import net.sourceforge.pmd.lang.document.Chars; -import net.sourceforge.pmd.lang.document.TextRegion; import net.sourceforge.pmd.lang.java.ast.ASTAssignmentExpression; import net.sourceforge.pmd.lang.java.ast.ASTCastExpression; import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression; @@ -24,6 +22,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTUnaryExpression; import net.sourceforge.pmd.lang.java.ast.BinaryOp; import net.sourceforge.pmd.lang.java.ast.JavaNode; +import net.sourceforge.pmd.lang.java.ast.internal.PrettyPrintingUtil; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.properties.PropertyFactory; @@ -88,18 +87,13 @@ private void checkExpr(ASTExpression e, Object data) { if (e.getParenthesisDepth() > 1) { asCtx(data).addViolationWithMessage(e, "Duplicate parentheses."); } else { - TextRegion textRegion = e.getTextRegion().growLeft(-1).growRight(-1); - Chars nodeContent = e.getTextDocument().sliceOriginalText(textRegion).trim(); - String snippet; + CharSequence snippet = PrettyPrintingUtil.prettyPrint(e); String dots = "..."; - if (nodeContent.length() > MAX_SNIPPET_LENGTH) { - snippet = nodeContent.slice(0, MAX_SNIPPET_LENGTH - dots.length()) - .toString() + dots; - } else { - snippet = nodeContent.toString(); + if (snippet.length() > MAX_SNIPPET_LENGTH) { + snippet = snippet.subSequence(0, MAX_SNIPPET_LENGTH - dots.length()) + dots; } asCtx(data).addViolationWithMessage(e, "Useless parentheses around `{0}`.", - snippet); + snippet); } } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/internal/PrettyPrintingUtilTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/internal/PrettyPrintingUtilTest.java index de324875590..c8ce3f6b3eb 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/internal/PrettyPrintingUtilTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/internal/PrettyPrintingUtilTest.java @@ -11,6 +11,7 @@ import java.util.List; +import net.sourceforge.pmd.lang.java.ast.ASTArrayAllocation; import org.checkerframework.checker.nullness.qual.NonNull; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; @@ -80,6 +81,8 @@ void ppCtorCall() { @Test void ppUnary() { testPrettyPrintIdentity("-+4", ASTUnaryExpression.class); + testPrettyPrintIdentity("j++", ASTUnaryExpression.class); + testPrettyPrintIdentity("++j", ASTUnaryExpression.class); } @@ -111,6 +114,15 @@ void ppLambdaBlock() { "(a, b) -> { ... }"); } + @Test + void ppArrayAllocation() { + testPrettyPrintIdentity("new int[1]", ASTArrayAllocation.class); + testPrettyPrintIdentity("new int[1][2]", ASTArrayAllocation.class); + testPrettyPrint("new List[]{}", ASTArrayAllocation.class, "new List[]{}"); + testPrettyPrint("new int[]{1}", ASTArrayAllocation.class, "new int[]{ ... }"); + testPrettyPrint("new int[][]{{4}}", ASTArrayAllocation.class, "new int[][]{ ... }"); + } + private void testPrettyPrint(String expr, Class nodeTy, String expected) { ASTCompilationUnit root = java.parse("class A { { Object x = " + expr + "; } }"); @NonNull T node = root.descendants(nodeTy).firstOrThrow(); diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml index e2e5ff2d171..dd7e693bf3d 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml @@ -665,10 +665,10 @@ public class Test { Detailed message - 9 + 12 Useless parentheses around `3 * 3`. - Useless parentheses around `4`. + Useless parentheses around `(4)`. Useless parentheses around `true ? 4 : 2`. Useless parentheses around `k3`. Useless parentheses around `id(k3)`. @@ -676,6 +676,8 @@ public class Test { Useless parentheses around `k2 = 2`. Duplicate parentheses. Useless parentheses around `"very" + "long " + "concat split...`. + Useless parentheses around `new int[5][7]`. + Useless parentheses around `switch (k2 + k3) { ... }`. 7; + default -> 2; + }); } } ]]> From afe557578b0736aa05f2ad3ed02fd15d7dd4c653 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Wed, 13 Aug 2025 21:00:14 +0200 Subject: [PATCH 1261/1962] Fix import order --- .../pmd/lang/java/ast/internal/PrettyPrintingUtilTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/internal/PrettyPrintingUtilTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/internal/PrettyPrintingUtilTest.java index c8ce3f6b3eb..ceaa365c7ef 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/internal/PrettyPrintingUtilTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/internal/PrettyPrintingUtilTest.java @@ -11,7 +11,6 @@ import java.util.List; -import net.sourceforge.pmd.lang.java.ast.ASTArrayAllocation; import org.checkerframework.checker.nullness.qual.NonNull; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; @@ -19,6 +18,7 @@ import org.junit.jupiter.api.Test; import net.sourceforge.pmd.lang.java.BaseParserTest; +import net.sourceforge.pmd.lang.java.ast.ASTArrayAllocation; import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression; import net.sourceforge.pmd.lang.java.ast.ASTConstructorCall; From 7f24c1e7730182051fa0c991497efece0ba61b27 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Aug 2025 15:49:04 +0200 Subject: [PATCH 1262/1962] chore(deps): bump actions/checkout from 4.2.2 to 5.0.0 (#5984) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.2.2 to 5.0.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/11bd71901bbe5b1630ceea73d27597364c9af683...08c6903cd8c0fde910a37f88322edcfb5dd907a8) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 5.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 12 ++++++------ .github/workflows/git-repo-sync.yml | 2 +- .github/workflows/publish-release.yml | 6 +++--- .github/workflows/publish-snapshot.yml | 12 ++++++------ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 77b0694255c..7198b51a6f3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,7 +23,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 with: distribution: 'temurin' @@ -81,7 +81,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 with: distribution: 'temurin' @@ -121,7 +121,7 @@ jobs: matrix: os: [ ubuntu-latest, windows-latest, macos-latest ] steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 # under linux we execute more extensive integration tests with various java versions if: ${{ runner.os == 'Linux' }} @@ -170,7 +170,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 with: distribution: 'temurin' @@ -256,7 +256,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 with: distribution: 'temurin' @@ -309,7 +309,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: fetch-depth: 2 - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 diff --git a/.github/workflows/git-repo-sync.yml b/.github/workflows/git-repo-sync.yml index 11901d29107..30f71aed38c 100644 --- a/.github/workflows/git-repo-sync.yml +++ b/.github/workflows/git-repo-sync.yml @@ -28,7 +28,7 @@ jobs: shell: bash continue-on-error: false steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: fetch-depth: 100 - name: Setup ssh key for sourceforge diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 9d01e87f71f..3545d7ede63 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -31,7 +31,7 @@ jobs: outputs: PMD_VERSION: ${{ steps.version.outputs.PMD_VERSION }} steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: ref: ${{ github.event.workflow_run.head_branch }} - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 @@ -85,7 +85,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: ref: ${{ github.event.workflow_run.head_branch }} - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 @@ -622,7 +622,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: ref: ${{ github.event.workflow_run.head_branch }} - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 4050121a2fd..b18373745ee 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -30,7 +30,7 @@ jobs: outputs: PMD_VERSION: ${{ steps.version.outputs.PMD_VERSION }} steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: ref: main - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 @@ -76,7 +76,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: ref: main - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 @@ -416,7 +416,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: ref: gh-pages - name: Clear old files @@ -639,7 +639,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: ref: main - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 @@ -724,7 +724,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: ref: main - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 @@ -761,7 +761,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 with: ref: main - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #v4.7.1 From 3ff3275a31b2100067bcc657fc3307249dc7dcc0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Aug 2025 15:50:12 +0200 Subject: [PATCH 1263/1962] chore(deps): bump ruby/setup-ruby from 1.254.0 to 1.255.0 (#5985) Bumps [ruby/setup-ruby](https://github.com/ruby/setup-ruby) from 1.254.0 to 1.255.0. - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/2a7b30092b0caf9c046252510f9273b4875f3db9...829114fc20da43a41d27359103ec7a63020954d4) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-version: 1.255.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 4 ++-- .github/workflows/publish-release.yml | 2 +- .github/workflows/publish-snapshot.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7198b51a6f3..e23fa9a3e20 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -278,7 +278,7 @@ jobs: -Pgenerate-rule-docs,fastSkip \ -DskipTests -Dassembly.skipAssembly=true - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@2a7b30092b0caf9c046252510f9273b4875f3db9 #v1.254.0 + uses: ruby/setup-ruby@829114fc20da43a41d27359103ec7a63020954d4 #v1.255.0 with: ruby-version: 3.3 - name: Setup bundler @@ -317,7 +317,7 @@ jobs: distribution: 'temurin' java-version: '11' - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@2a7b30092b0caf9c046252510f9273b4875f3db9 #v1.254.0 + uses: ruby/setup-ruby@829114fc20da43a41d27359103ec7a63020954d4 #v1.255.0 with: ruby-version: 3.3 - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 3545d7ede63..e89039a4cc1 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -630,7 +630,7 @@ jobs: distribution: 'temurin' java-version: '11' - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@2a7b30092b0caf9c046252510f9273b4875f3db9 #v1.254.0 + uses: ruby/setup-ruby@829114fc20da43a41d27359103ec7a63020954d4 #v1.255.0 with: ruby-version: 3.3 - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index b18373745ee..57aa1e0091b 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -647,7 +647,7 @@ jobs: distribution: 'temurin' java-version: '11' - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@2a7b30092b0caf9c046252510f9273b4875f3db9 #v1.254.0 + uses: ruby/setup-ruby@829114fc20da43a41d27359103ec7a63020954d4 #v1.255.0 with: ruby-version: 3.3 - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 From e0ff201312e26ecb376459bf619fb918a6bb5654 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Aug 2025 15:57:43 +0200 Subject: [PATCH 1264/1962] chore(deps): bump actions/create-github-app-token from 2.0.6 to 2.1.1 (#5986) Bumps [actions/create-github-app-token](https://github.com/actions/create-github-app-token) from 2.0.6 to 2.1.1. - [Release notes](https://github.com/actions/create-github-app-token/releases) - [Commits](https://github.com/actions/create-github-app-token/compare/df432ceedc7162793a195dd1713ff69aefc7379e...a8d616148505b5069dccd32f177bb87d7f39123b) --- updated-dependencies: - dependency-name: actions/create-github-app-token dependency-version: 2.1.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/publish-pull-requests.yml | 2 +- .github/workflows/publish-release.yml | 4 ++-- .github/workflows/publish-snapshot.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish-pull-requests.yml b/.github/workflows/publish-pull-requests.yml index bc09f94bde2..3f5d3cb1a60 100644 --- a/.github/workflows/publish-pull-requests.yml +++ b/.github/workflows/publish-pull-requests.yml @@ -21,7 +21,7 @@ jobs: run: shell: bash steps: - - uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e #v2.0.6 + - uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b #v2.1.1 id: pmd-actions-helper-app-token with: app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index e89039a4cc1..f2c03a7b3ec 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -504,7 +504,7 @@ jobs: --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-src.zip" printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-doc.zip" - - uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e #v2.0.6 + - uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b #v2.1.1 id: pmd-actions-helper-app-token with: app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} @@ -758,7 +758,7 @@ jobs: run: shell: bash steps: - - uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e #v2.0.6 + - uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b #v2.1.1 id: pmd-actions-helper-app-token with: app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 57aa1e0091b..46f8473de82 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -495,7 +495,7 @@ jobs: --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-src.zip" printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-doc.zip" - - uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e #v2.0.6 + - uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b #v2.1.1 id: pmd-actions-helper-app-token with: app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} From a272d03ff72c5e62abe494ca73e9a5d50af18a10 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 14 Aug 2025 17:47:49 +0200 Subject: [PATCH 1265/1962] chore(deps): Bump build-tools from 33 to 34 (#5988) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8f02197ef91..0edc6390c1f 100644 --- a/pom.xml +++ b/pom.xml @@ -108,7 +108,7 @@ -Xmx512m -Dfile.encoding=${project.build.sourceEncoding} ${extraArgLine} - 33 + 34 7.10.0 From 2f3c175a1f715331ff4e7696d421af3ebf50a11e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Thu, 14 Aug 2025 19:21:23 +0200 Subject: [PATCH 1266/1962] Fix #3434 AssignmentInOperand FNs --- .../pmd/lang/rule/AbstractRule.java | 10 +++++ .../errorprone/AssignmentInOperandRule.java | 43 ++++++++++--------- .../errorprone/xml/AssignmentInOperand.xml | 31 +++++++++++++ 3 files changed, 64 insertions(+), 20 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractRule.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractRule.java index 508bed36379..7a0e99deeb3 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractRule.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractRule.java @@ -333,4 +333,14 @@ public Rule deepCopy() { } return rule; } + + @Override + @SuppressWarnings("PMD.UselessOverridingMethod") + public String dysfunctionReason() { + // This method is overridden to let subclasses remove their implementation + // of dysfunctionReason in a binary compatible way. For this to + // work one implementation has to be in a superclass, however this + // method only has a default implementation in the interface. + return super.dysfunctionReason(); + } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java index 13da91f1a36..87170d23c80 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java @@ -12,6 +12,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTExpressionStatement; import net.sourceforge.pmd.lang.java.ast.ASTForStatement; import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; +import net.sourceforge.pmd.lang.java.ast.ASTStatementExpressionList; import net.sourceforge.pmd.lang.java.ast.ASTSwitchStatement; import net.sourceforge.pmd.lang.java.ast.ASTUnaryExpression; import net.sourceforge.pmd.lang.java.ast.ASTVariableAccess; @@ -20,7 +21,6 @@ import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; import net.sourceforge.pmd.properties.PropertyDescriptor; -import net.sourceforge.pmd.properties.PropertySource; import net.sourceforge.pmd.reporting.RuleContext; /** @@ -86,35 +86,38 @@ public Object visit(ASTUnaryExpression node, Object data) { private void checkAssignment(ASTExpression impureExpr, RuleContext ctx) { ASTExpression toplevel = JavaAstUtils.getTopLevelExpr(impureExpr); JavaNode parent = toplevel.getParent(); - if (parent instanceof ASTExpressionStatement) { + + if (toplevel == impureExpr + && (parent instanceof ASTExpressionStatement + || parent instanceof ASTStatementExpressionList) + ) { // that's ok return; } - if (parent instanceof ASTIfStatement && !getProperty(ALLOW_IF_DESCRIPTOR) - || parent instanceof ASTWhileStatement && !getProperty(ALLOW_WHILE_DESCRIPTOR) - || parent instanceof ASTDoStatement && !getProperty(ALLOW_DO_WHILE_DESCRIPTOR) - || parent instanceof ASTSwitchStatement && !getProperty(ALLOW_SWITCH_DESCRIPTOR) - || parent instanceof ASTForStatement && ((ASTForStatement) parent).getCondition() == toplevel && !getProperty(ALLOW_FOR_DESCRIPTOR)) { - JavaNode firstChild = impureExpr.getChild(0); - if (firstChild instanceof ASTVariableAccess) { - ctx.addViolation(impureExpr, ((ASTVariableAccess) firstChild).getName()); - } else { - ctx.addViolationWithMessage(impureExpr, "Avoid assignments in operands"); - } + if (parent instanceof ASTIfStatement && getProperty(ALLOW_IF_DESCRIPTOR) + || parent instanceof ASTWhileStatement && getProperty(ALLOW_WHILE_DESCRIPTOR) + || parent instanceof ASTDoStatement && getProperty(ALLOW_DO_WHILE_DESCRIPTOR) + || parent instanceof ASTSwitchStatement && getProperty(ALLOW_SWITCH_DESCRIPTOR) + || parent instanceof ASTForStatement && ((ASTForStatement) parent).getCondition() == toplevel && getProperty(ALLOW_FOR_DESCRIPTOR) + ) { + return; + } + JavaNode firstChild = impureExpr.getChild(0); + if (firstChild instanceof ASTVariableAccess) { + ctx.addViolation(impureExpr, ((ASTVariableAccess) firstChild).getName()); + } else { + ctx.addViolationWithMessage(impureExpr, "Avoid assignments in operands"); } } + /** + * @deprecated Since 7.17.0. This method is an implementation detail and will be internalized. + */ + @Deprecated public boolean allowsAllAssignments() { return getProperty(ALLOW_IF_DESCRIPTOR) && getProperty(ALLOW_FOR_DESCRIPTOR) && getProperty(ALLOW_WHILE_DESCRIPTOR) && getProperty(ALLOW_INCREMENT_DECREMENT_DESCRIPTOR) && getProperty(ALLOW_DO_WHILE_DESCRIPTOR) && getProperty(ALLOW_SWITCH_DESCRIPTOR); } - /** - * @see PropertySource#dysfunctionReason() - */ - @Override - public String dysfunctionReason() { - return allowsAllAssignments() ? "All assignment types allowed, no checks performed" : null; - } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml index d797f9dc497..9aa3529407e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml @@ -247,6 +247,7 @@ public class Foo { } ]]> + Distinct error messages for the same line 2 @@ -266,4 +267,34 @@ public class Foo { } ]]> + + + #3434 Assignments in other contexts + 8 + 4,5,9,12,13,16,17,20 + + From 724707354772f5f071ea917d2d80066686082ae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Thu, 14 Aug 2025 19:28:59 +0200 Subject: [PATCH 1267/1962] Fix dogfood in pmd-core --- .../net/sourceforge/pmd/util/AssertionUtil.java | 14 ++++++++++---- .../net/sourceforge/pmd/util/CollectionUtil.java | 4 +++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/AssertionUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/AssertionUtil.java index 7ab20afbd63..df713e464ec 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/AssertionUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/AssertionUtil.java @@ -21,11 +21,17 @@ public final class AssertionUtil { private static final boolean ASSERT_ENABLED; + private static boolean areAssertsEnabled() { + try { + assert false; + return false; + } catch (AssertionError e) { + return true; + } + } + static { - boolean assertEnabled = false; - //noinspection AssertWithSideEffects - assert assertEnabled = true; // SUPPRESS CHECKSTYLE now - ASSERT_ENABLED = assertEnabled; + ASSERT_ENABLED = areAssertsEnabled(); } private AssertionUtil() { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java index d9131a6a725..4aa5c7b8f98 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java @@ -554,7 +554,9 @@ class Holder { return Collector.of( Holder::new, - (h, t) -> h.set = h.set.plus(t), + (h, t) -> { + h.set = h.set.plus(t); + }, (left, right) -> { left.set = left.set.plusAll(right.set); return left; From d55e0d59a14c02cacfeb30828d0b9c311d16be5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Thu, 14 Aug 2025 20:22:33 +0200 Subject: [PATCH 1268/1962] Add equals/hashCode to InvocationMatcher --- .../lang/java/types/InvocationMatcher.java | 31 ++++++++++++++ .../java/types/InvocationMatcherTest.java | 40 +++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/InvocationMatcher.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/InvocationMatcher.java index 2c2604f99a1..9fd1b285b41 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/InvocationMatcher.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/InvocationMatcher.java @@ -9,6 +9,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Objects; import org.apache.commons.lang3.StringUtils; import org.checkerframework.checker.nullness.qual.Nullable; @@ -272,6 +273,22 @@ private static TypeMatcher newMatcher(String name) { return "_".equals(name) ? TypeMatcher.ANY : new TypeMatcher(name); } + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + InvocationMatcher that = (InvocationMatcher) o; + return Objects.equals(expectedName, that.expectedName) + && Objects.equals(argMatchers, that.argMatchers) + && Objects.equals(qualifierMatcher, that.qualifierMatcher); + } + + @Override + public int hashCode() { + return Objects.hash(expectedName, argMatchers, qualifierMatcher); + } + private static final class TypeMatcher { /** Matches any type. */ @@ -288,6 +305,20 @@ boolean matches(JTypeMirror type, boolean exact) { || (exact ? TypeTestUtil.isExactlyAOrAnon(name, type) == OptionalBool.YES : TypeTestUtil.isA(name, type)); } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + TypeMatcher that = (TypeMatcher) o; + return Objects.equals(name, that.name); + } + + @Override + public int hashCode() { + return Objects.hashCode(name); + } } /** diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/InvocationMatcherTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/InvocationMatcherTest.java index e6cf124ab9b..f351da0a522 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/InvocationMatcherTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/InvocationMatcherTest.java @@ -94,4 +94,44 @@ private void assertNoMatch(InvocationNode call, String s) { assertFalse(parse(s).matchesCall(call), s + " should not match " + call); } + @Test + void testEquals() { + InvocationMatcher matcher1 = parse("java.lang.String#toString()"); + InvocationMatcher matcher2 = parse("java.lang.String#toString()"); + InvocationMatcher matcher3 = parse("java.lang.Object#toString()"); + InvocationMatcher matcher4 = parse("java.lang.String#valueOf(int)"); + InvocationMatcher matcher5 = parse("_#toString()"); + + assertTrue(matcher1.equals(matcher2)); + assertTrue(matcher2.equals(matcher1)); + assertTrue(matcher1.equals(matcher1)); + + assertFalse(matcher1.equals(null)); + assertFalse(matcher1.equals("not a matcher")); // NOPMD + assertFalse(matcher1.equals(matcher3)); + assertFalse(matcher1.equals(matcher4)); + assertFalse(matcher1.equals(matcher5)); + + InvocationMatcher anyArgsMatch1 = parse("java.lang.String#toString(_*)"); + InvocationMatcher anyArgsMatch2 = parse("java.lang.String#toString(_*)"); + InvocationMatcher emptyArgsMatch = parse("java.lang.String#toString()"); + + assertTrue(anyArgsMatch1.equals(anyArgsMatch2)); + assertFalse(anyArgsMatch1.equals(emptyArgsMatch)); + + InvocationMatcher wildcardMethod1 = parse("java.lang.String#_(int)"); + InvocationMatcher wildcardMethod2 = parse("java.lang.String#_(int)"); + InvocationMatcher namedMethod = parse("java.lang.String#valueOf(int)"); + + assertTrue(wildcardMethod1.equals(wildcardMethod2)); + assertFalse(wildcardMethod1.equals(namedMethod)); + } + + @Test + void testHashCode() { + InvocationMatcher matcher1 = parse("java.lang.String#toString()"); + InvocationMatcher matcher2 = parse("java.lang.String#toString()"); + + assertThat(matcher1.hashCode(), equalTo(matcher2.hashCode())); + } } From 4b55ff3b76330e2b822518c8fa3484ca005f3fa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Thu, 14 Aug 2025 20:30:50 +0200 Subject: [PATCH 1269/1962] Way less calls to InvocationMatcher.parse --- .../RelianceOnDefaultCharsetRule.java | 73 +++++++++---------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/RelianceOnDefaultCharsetRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/RelianceOnDefaultCharsetRule.java index 8b16ebfbd90..db36956a2d7 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/RelianceOnDefaultCharsetRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/RelianceOnDefaultCharsetRule.java @@ -28,51 +28,51 @@ public class RelianceOnDefaultCharsetRule extends AbstractJavaRulechainRule { * Maps each violating method/constructor to the minimum Java version * where its charset-aware replacement is available. */ - private static final Map METHOD_TO_MIN_VERSION = new HashMap<>(); + private static final Map METHOD_TO_MIN_VERSION = new HashMap<>(); static { - METHOD_TO_MIN_VERSION.put("java.io.InputStreamReader#new(java.io.InputStream)", "1.3"); - METHOD_TO_MIN_VERSION.put("java.io.OutputStreamWriter#new(java.io.OutputStream)", "1.3"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.io.InputStreamReader#new(java.io.InputStream)"), "1.3"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.io.OutputStreamWriter#new(java.io.OutputStream)"), "1.3"); - METHOD_TO_MIN_VERSION.put("java.net.URLEncoder#encode(java.lang.String)", "1.4"); - METHOD_TO_MIN_VERSION.put("java.net.URLDecoder#decode(java.lang.String)", "1.4"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.net.URLEncoder#encode(java.lang.String)"), "1.4"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.net.URLDecoder#decode(java.lang.String)"), "1.4"); - METHOD_TO_MIN_VERSION.put("java.io.PrintStream#new(java.io.OutputStream)", "1.4"); - METHOD_TO_MIN_VERSION.put("java.io.PrintStream#new(java.io.OutputStream,boolean)", "1.4"); - METHOD_TO_MIN_VERSION.put("java.io.PrintStream#new(java.lang.String)", "1.5"); - METHOD_TO_MIN_VERSION.put("java.io.PrintStream#new(java.io.File)", "1.5"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.io.PrintStream#new(java.io.OutputStream)"), "1.4"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.io.PrintStream#new(java.io.OutputStream,boolean)"), "1.4"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.io.PrintStream#new(java.lang.String)"), "1.5"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.io.PrintStream#new(java.io.File)"), "1.5"); - METHOD_TO_MIN_VERSION.put("java.io.PrintWriter#new(java.lang.String)", "1.5"); - METHOD_TO_MIN_VERSION.put("java.io.PrintWriter#new(java.io.File)", "1.5"); - METHOD_TO_MIN_VERSION.put("java.io.PrintWriter#new(java.io.OutputStream)", "10"); - METHOD_TO_MIN_VERSION.put("java.io.PrintWriter#new(java.io.OutputStream,boolean)", "10"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.io.PrintWriter#new(java.lang.String)"), "1.5"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.io.PrintWriter#new(java.io.File)"), "1.5"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.io.PrintWriter#new(java.io.OutputStream)"), "10"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.io.PrintWriter#new(java.io.OutputStream,boolean)"), "10"); - METHOD_TO_MIN_VERSION.put("java.util.Scanner#new(java.io.InputStream)", "1.5"); - METHOD_TO_MIN_VERSION.put("java.util.Scanner#new(java.io.File)", "1.5"); - METHOD_TO_MIN_VERSION.put("java.util.Scanner#new(java.nio.file.Path)", "1.7"); - METHOD_TO_MIN_VERSION.put("java.util.Scanner#new(java.nio.channels.ReadableByteChannel)", "1.10"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.util.Scanner#new(java.io.InputStream)"), "1.5"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.util.Scanner#new(java.io.File)"), "1.5"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.util.Scanner#new(java.nio.file.Path)"), "1.7"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.util.Scanner#new(java.nio.channels.ReadableByteChannel)"), "1.10"); - METHOD_TO_MIN_VERSION.put("java.util.Formatter#new()", "1.5"); - METHOD_TO_MIN_VERSION.put("java.util.Formatter#new(java.io.OutputStream)", "1.5"); - METHOD_TO_MIN_VERSION.put("java.util.Formatter#new(java.io.PrintStream)", "1.5"); - METHOD_TO_MIN_VERSION.put("java.util.Formatter#new(java.lang.String)", "1.5"); - METHOD_TO_MIN_VERSION.put("java.util.Formatter#new(java.io.File)", "1.5"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.util.Formatter#new()"), "1.5"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.util.Formatter#new(java.io.OutputStream)"), "1.5"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.util.Formatter#new(java.io.PrintStream)"), "1.5"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.util.Formatter#new(java.lang.String)"), "1.5"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.util.Formatter#new(java.io.File)"), "1.5"); - METHOD_TO_MIN_VERSION.put("java.lang.String#new(byte[])", "1.6"); - METHOD_TO_MIN_VERSION.put("java.lang.String#new(byte[],int,int)", "1.6"); - METHOD_TO_MIN_VERSION.put("java.lang.String#getBytes()", "1.6"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.lang.String#new(byte[])"), "1.6"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.lang.String#new(byte[],int,int)"), "1.6"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.lang.String#getBytes()"), "1.6"); - METHOD_TO_MIN_VERSION.put("java.io.ByteArrayOutputStream#toString()", "10"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.io.ByteArrayOutputStream#toString()"), "10"); - METHOD_TO_MIN_VERSION.put("java.io.FileReader#new(java.lang.String)", "11"); - METHOD_TO_MIN_VERSION.put("java.io.FileReader#new(java.io.File)", "11"); - METHOD_TO_MIN_VERSION.put("java.io.FileReader#new(java.io.FileDescriptor)", "11"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.io.FileReader#new(java.lang.String)"), "11"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.io.FileReader#new(java.io.File)"), "11"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.io.FileReader#new(java.io.FileDescriptor)"), "11"); - METHOD_TO_MIN_VERSION.put("java.io.FileWriter#new(java.lang.String)", "11"); - METHOD_TO_MIN_VERSION.put("java.io.FileWriter#new(java.lang.String,boolean)", "11"); - METHOD_TO_MIN_VERSION.put("java.io.FileWriter#new(java.io.File)", "11"); - METHOD_TO_MIN_VERSION.put("java.io.FileWriter#new(java.io.File,boolean)", "11"); - METHOD_TO_MIN_VERSION.put("java.io.FileWriter#new(java.io.FileDescriptor)", "11"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.io.FileWriter#new(java.lang.String)"), "11"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.io.FileWriter#new(java.lang.String,boolean)"), "11"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.io.FileWriter#new(java.io.File)"), "11"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.io.FileWriter#new(java.io.File,boolean)"), "11"); + METHOD_TO_MIN_VERSION.put(InvocationMatcher.parse("java.io.FileWriter#new(java.io.FileDescriptor)"), "11"); } public RelianceOnDefaultCharsetRule() { @@ -92,11 +92,10 @@ public Object visit(ASTMethodCall node, Object data) { } private void checkInvocation(net.sourceforge.pmd.lang.java.ast.JavaNode node, Object data) { - for (Map.Entry entry : METHOD_TO_MIN_VERSION.entrySet()) { - String methodSignature = entry.getKey(); + for (Map.Entry entry : METHOD_TO_MIN_VERSION.entrySet()) { + InvocationMatcher matcher = entry.getKey(); String minVersion = entry.getValue(); - InvocationMatcher matcher = InvocationMatcher.parse(methodSignature); if (matcher.matchesCall(node)) { // Only flag violation if replacement method is available in current Java version if (node.getLanguageVersion().compareToVersion(minVersion) >= 0) { From 32bd7f4340c4a74fbc173b58a521ef58507305b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Thu, 14 Aug 2025 20:33:46 +0200 Subject: [PATCH 1270/1962] Check cheap condition first, expensive condition second. --- .../rule/bestpractices/RelianceOnDefaultCharsetRule.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/RelianceOnDefaultCharsetRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/RelianceOnDefaultCharsetRule.java index db36956a2d7..77cd6d7a1a9 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/RelianceOnDefaultCharsetRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/RelianceOnDefaultCharsetRule.java @@ -96,12 +96,9 @@ private void checkInvocation(net.sourceforge.pmd.lang.java.ast.JavaNode node, Ob InvocationMatcher matcher = entry.getKey(); String minVersion = entry.getValue(); - if (matcher.matchesCall(node)) { - // Only flag violation if replacement method is available in current Java version - if (node.getLanguageVersion().compareToVersion(minVersion) >= 0) { - asCtx(data).addViolation(node); - } - return; + // Only flag violation if replacement method is available in current Java version + if (node.getLanguageVersion().compareToVersion(minVersion) >= 0 && matcher.matchesCall(node)) { + asCtx(data).addViolation(node); } } } From 52f38cc0191561c47b2c62dca6c11a1a9a179107 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 15 Aug 2025 11:09:35 +0200 Subject: [PATCH 1271/1962] Fixups from review --- .../UnnecessaryLocalBeforeReturnRule.java | 2 +- .../codestyle/VariableCanBeInlinedRule.java | 3 ++ .../resources/category/java/codestyle.xml | 7 ++- .../resources/rulesets/java/quickstart.xml | 2 +- .../UnnecessaryLocalBeforeReturnTest.java | 3 ++ .../codestyle/xml/VariableCanBeInlined.xml | 45 ++++++++----------- 6 files changed, 31 insertions(+), 31 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryLocalBeforeReturnRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryLocalBeforeReturnRule.java index 7f27c816f9a..f3c88f54791 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryLocalBeforeReturnRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryLocalBeforeReturnRule.java @@ -15,7 +15,7 @@ import net.sourceforge.pmd.properties.PropertyDescriptor; /** - * @deprecated Since 7.17.0. This rule is replaced by VariableCanBeInlined. + * @deprecated Since 7.17.0. This rule is replaced by {@link VariableCanBeInlinedRule}. */ @Deprecated public class UnnecessaryLocalBeforeReturnRule extends AbstractJavaRulechainRule { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/VariableCanBeInlinedRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/VariableCanBeInlinedRule.java index b6bd1db9f69..a24aae74e85 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/VariableCanBeInlinedRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/VariableCanBeInlinedRule.java @@ -18,6 +18,9 @@ import net.sourceforge.pmd.lang.java.symbols.JVariableSymbol; import net.sourceforge.pmd.properties.PropertyDescriptor; +/** + * @since 7.17.0 + */ public class VariableCanBeInlinedRule extends AbstractJavaRulechainRule { private static final PropertyDescriptor STATEMENT_ORDER_MATTERS = booleanProperty("statementOrderMatters") diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml index df47193e922..387337a8e54 100644 --- a/pmd-java/src/main/resources/category/java/codestyle.xml +++ b/pmd-java/src/main/resources/category/java/codestyle.xml @@ -1813,7 +1813,10 @@ public class Foo { class="net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryLocalBeforeReturnRule" externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#unnecessarylocalbeforereturn"> -Avoid the creation of unnecessary local variables +Avoid the creation of unnecessary local variables. + +This rule has been deprecated since 7.17.0. Use the new rule +{%rule VariableCanBeInlined %} instead, which additionally covers throw statements. 3 @@ -2148,7 +2151,7 @@ Foo[] x = { ... }; //Equivalent to above line diff --git a/pmd-java/src/main/resources/rulesets/java/quickstart.xml b/pmd-java/src/main/resources/rulesets/java/quickstart.xml index 1c84cf07604..f516566be21 100644 --- a/pmd-java/src/main/resources/rulesets/java/quickstart.xml +++ b/pmd-java/src/main/resources/rulesets/java/quickstart.xml @@ -115,12 +115,12 @@ - + diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryLocalBeforeReturnTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryLocalBeforeReturnTest.java index 7a01f3b8386..14e39cd0c55 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryLocalBeforeReturnTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryLocalBeforeReturnTest.java @@ -6,6 +6,9 @@ import net.sourceforge.pmd.test.PmdRuleTst; +/** + * @deprecated Since 7.17.0. See {@link UnnecessaryLocalBeforeReturnRule}. + */ @Deprecated class UnnecessaryLocalBeforeReturnTest extends PmdRuleTst { // no additional unit tests diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/VariableCanBeInlined.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/VariableCanBeInlined.xml index 788b8210b51..164a968a45a 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/VariableCanBeInlined.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/VariableCanBeInlined.xml @@ -31,6 +31,10 @@ public class Foo { simple failure case 1 + 3 + + Consider simply using the value vs. storing it in local variable 'x'. + - Multiple throw variables but one is unnecessary - 1 - 4 - - - - Return with method chain - no violation + Return a concatenated string - violation 1 - Throw with method chain - no violation + Throw an exception with a message build from a concatenated string - violation 1 - Return with array access - no violation + Return with array access - violation 1 - Return with field access - no violation + Return with field access - violation 1 - - Super coupling: Throw with multiple catch blocks - - 0 + + Super coupling: Throw with separated local var initializer in catch block + 1 + 6 - Would we detect it, if the declaration and initialization wouldn't be separated? + Throw in catch block with local var directly initialized 1 + 6 - - Coupling: Throw with multiple catch blocks - - 0 + + Coupling: Throw after catch block + 1 + 3 Date: Fri, 15 Aug 2025 11:10:05 +0200 Subject: [PATCH 1272/1962] [doc] Update release notes (#5770, #5847) --- docs/pages/release_notes.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 4089792464d..aa7db11fa58 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -51,7 +51,11 @@ This is a {{ site.pmd.release_type }} release. * The new java rule {% rule java/bestpractices/RelianceOnDefaultCharset %} finds method calls that depend on the JVM's default charset. Using these method without specifying the charset explicitly can lead to unexpected behavior on different platforms. -* [#5770](https://github.com/pmd/pmd/issues/5770): \[java] `VariableCanBeInlined` +* Thew new java rule {% rule java/codestyle/VariableCanBeInlined %} finds local variables that are + immediately returned or thrown. This rule replaces the old rule {% rule java/codestyle/UnnecessaryLocalBeforeReturn %} + which only considered return statements. The new rule also finds unnecessary local variables + before throw statements. + The rule is referenced in the quickstart.xml ruleset for Java. #### Deprecated Rules * The java rule {% rule java/codestyle/GenericsNaming %} has been deprecated for removal in favor @@ -60,6 +64,8 @@ This is a {{ site.pmd.release_type }} release. in favor of the new rule {% rule java/errorprone/UselessPureMethodCall %}. * The java rule {% rule java/errorprone/UselessOperationOnImmutable %} has been deprecated for removal in favor of the new rule {% rule java/errorprone/UselessPureMethodCall %}. +* The java rule {% rule java/codestyle/UnnecessaryLocalBeforeReturn %} has been deprecated for removal + in favor of the new rule {% rule java/codestyle/VariableCanBeInlined %}. ### ๐Ÿ› Fixed Issues * apex-codestyle @@ -71,6 +77,7 @@ This is a {{ site.pmd.release_type }} release. * [#4500](https://github.com/pmd/pmd/issues/4500): \[java] AvoidReassigningLoopVariables - false negatives within for-loops and skip allowed * java-codestyle * [#972](https://github.com/pmd/pmd/issues/972): \[java] Improve naming conventions rules + * [#5770](https://github.com/pmd/pmd/issues/5770): \[java] New Rule: VariableCanBeInlined: Local variables should not be declared and then immediately returned or thrown * java-design * [#5023](https://github.com/pmd/pmd/issues/5023): \[java] UseUtilityClass implementation hardcodes a message instead of using the one defined in the XML * java-errorprone @@ -83,6 +90,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ Merged pull requests * [#5822](https://github.com/pmd/pmd/pull/5822): Fix #5650: \[apex] New Rule: AnnotationsNamingConventions - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) +* [#5847](https://github.com/pmd/pmd/pull/5847): Fix #5770: \[java] New Rule: VariableCanBeInlined - [Vincent Potucek](https://github.com/Pankraz76) (@Pankraz76) * [#5856](https://github.com/pmd/pmd/pull/5856): Fix #5837: \[java] New Rule OverrideBothEqualsAndHashCodeOnComparable - [Vincent Potucek](https://github.com/Pankraz76) (@Pankraz76) * [#5907](https://github.com/pmd/pmd/pull/5907): \[java] New rule: UselessPureMethodCall - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#5922](https://github.com/pmd/pmd/pull/5922): Fix #972: \[java] Add a new rule TypeParameterNamingConventions - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) From b0ac603501601f1833074652fcd6cdb0a65ec792 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 15 Aug 2025 11:42:20 +0200 Subject: [PATCH 1273/1962] [java] ShortVariable - improve detection of unnamed variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs #5914 Co-authored-by: Juan Martรญn Sotuyo Dodero --- pmd-java/src/main/resources/category/java/codestyle.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml index 387337a8e54..343adb1db07 100644 --- a/pmd-java/src/main/resources/category/java/codestyle.xml +++ b/pmd-java/src/main/resources/category/java/codestyle.xml @@ -1504,7 +1504,7 @@ Fields, local variables, enum constant names or parameter names that are very sh (: Lambda expression parameter :) [not(parent::LambdaParameter)] (: Exclude Unnamed Variables (JEP 456) :) - [not(@Name='_')] + [@Unnamed = false()] ]]> From 8bb85a070c5076f4a1153134ea8270e7c15e3dc5 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 16 Aug 2025 20:01:47 +0200 Subject: [PATCH 1274/1962] Update pmd-java/src/main/resources/category/java/multithreading.xml --- pmd-java/src/main/resources/category/java/multithreading.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/main/resources/category/java/multithreading.xml b/pmd-java/src/main/resources/category/java/multithreading.xml index 21bb0a95d48..3319d4acf24 100644 --- a/pmd-java/src/main/resources/category/java/multithreading.xml +++ b/pmd-java/src/main/resources/category/java/multithreading.xml @@ -180,7 +180,7 @@ the volatile keyword should not be used for maintenance purpose and portability. Date: Sun, 17 Aug 2025 17:24:07 +0200 Subject: [PATCH 1275/1962] [doc] Update release notes (#4911, #5981) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 9ae5c9cc253..5fa442e62fb 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -74,6 +74,7 @@ This is a {{ site.pmd.release_type }} release. * [#972](https://github.com/pmd/pmd/issues/972): \[java] Improve naming conventions rules * [#5948](https://github.com/pmd/pmd/issues/5948): \[java] UnnecessaryBoxing false positive when calling `List.remove(int)` * java-design + * [#4911](https://github.com/pmd/pmd/issues/4911): \[java] AvoidRethrowingException should allow rethrowing exception subclasses * [#5023](https://github.com/pmd/pmd/issues/5023): \[java] UseUtilityClass implementation hardcodes a message instead of using the one defined in the XML * java-errorprone * [#3401](https://github.com/pmd/pmd/issues/3401): \[java] Improve AvoidUsingOctalValues documentation @@ -103,6 +104,7 @@ This is a {{ site.pmd.release_type }} release. * [#5967](https://github.com/pmd/pmd/pull/5967): \[doc]\[java] ReplaceJavaUtilDate - improve doc to mention java.sql.Date - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5970](https://github.com/pmd/pmd/pull/5970): chore: CI improvements - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5971](https://github.com/pmd/pmd/pull/5971): Fix #5948: \[java] UnnecessaryBoxingRule: Check if unboxing is required for overload resolution - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5981](https://github.com/pmd/pmd/pull/5981): Fix #4911: \[java] AvoidRethrowingException consider supertypes in following catches - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) ### ๐Ÿ“ฆ Dependency updates From eb22299c8a94d2172080927eed121ff6a7dfaa2c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 17 Aug 2025 18:38:30 +0200 Subject: [PATCH 1276/1962] chore(deps): Update @babel/runtime from 7.16.7 to 7.28.7 (#5990) chore: Update @babel/runtime from 7.16.7 to 7.28.7 Fixes https://github.com/advisories/GHSA-968p-4wvh-cqc8 --- package-lock.json | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/package-lock.json b/package-lock.json index f5a2f2dcfc2..566abe63334 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,13 +9,11 @@ } }, "node_modules/@babel/runtime": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.7.tgz", - "integrity": "sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.3.tgz", + "integrity": "sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==", "dev": true, - "dependencies": { - "regenerator-runtime": "^0.13.4" - }, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -484,12 +482,6 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", - "dev": true - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -717,13 +709,10 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.7.tgz", - "integrity": "sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.4" - } + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.3.tgz", + "integrity": "sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==", + "dev": true }, "all-contributors-cli": { "version": "6.26.1", @@ -1050,12 +1039,6 @@ "dev": true, "optional": true }, - "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", - "dev": true - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", From 7e3fed1cb87a1ef2a5d09decf7fa1e45ae43dde1 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 17 Aug 2025 18:39:53 +0200 Subject: [PATCH 1277/1962] chore(deps): Update tmp from 0.0.33 to 0.2.5 (#5991) chore: Update tmp from 0.0.33 to 0.2.5 Fixes https://github.com/advisories/GHSA-52f5-9888-hmc6 Fixes https://github.com/pmd/pmd/security/dependabot/85 --- package-lock.json | 40 ++++++++++------------------------------ package.json | 3 +++ 2 files changed, 13 insertions(+), 30 deletions(-) diff --git a/package-lock.json b/package-lock.json index 566abe63334..b9515c683b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -388,15 +388,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -594,15 +585,13 @@ "dev": true }, "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, + "license": "MIT", "engines": { - "node": ">=0.6.0" + "node": ">=14.14" } }, "node_modules/tr46": { @@ -858,7 +847,7 @@ "requires": { "chardet": "^0.7.0", "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" + "tmp": "^0.2.4" } }, "figures": { @@ -984,12 +973,6 @@ "mimic-fn": "^2.1.0" } }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -1130,13 +1113,10 @@ "dev": true }, "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", + "dev": true }, "tr46": { "version": "0.0.3", diff --git a/package.json b/package.json index 8d26c186dd4..7c81079d2e9 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,8 @@ { "devDependencies": { "all-contributors-cli": "^6.26.1" + }, + "overrides": { + "tmp": "^0.2.4" } } From 16ba8570d6d7cccd9b5533f11ffa4ef80e8fae84 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Mon, 18 Aug 2025 11:31:36 +0200 Subject: [PATCH 1278/1962] Review feedback --- .../java/ast/internal/PrettyPrintingUtil.java | 9 ++++---- .../codestyle/UselessParenthesesRule.java | 21 ++++++++----------- .../ast/internal/PrettyPrintingUtilTest.java | 20 ++++++++++++++++-- .../rule/codestyle/xml/UselessParentheses.xml | 6 +++--- 4 files changed, 35 insertions(+), 21 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/PrettyPrintingUtil.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/PrettyPrintingUtil.java index 6ffbe9b2141..686125df74f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/PrettyPrintingUtil.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/PrettyPrintingUtil.java @@ -266,6 +266,7 @@ public static CharSequence prettyPrint(JavaNode node) { static class ExprPrinter extends JavaVisitorBase { private static final int MAX_ARG_LENGTH = 20; + public static final String BLOCK_PLACEHOLDER = "{ ... }"; @Override public Void visitJavaNode(JavaNode node, StringBuilder data) { @@ -295,7 +296,7 @@ public Void visit(ASTClassLiteral node, StringBuilder data) { @Override public Void visitLiteral(ASTLiteral node, StringBuilder data) { - data.append(node.getText()); + data.append(node.getLiteralText()); return null; } @@ -403,7 +404,7 @@ public Void visit(ASTLambdaExpression node, StringBuilder sb) { if (exprBody != null) { exprBody.acceptVisitor(this, sb); } else { - sb.append("{ ... }"); + sb.append(BLOCK_PLACEHOLDER); } return null; } @@ -490,7 +491,7 @@ public Void visit(ASTAssignmentExpression node, StringBuilder sb) { public Void visit(ASTSwitchExpression node, StringBuilder sb) { sb.append("switch ("); node.getFirstChild().acceptVisitor(this, sb); - sb.append(") { ... }"); + sb.append(") ").append(BLOCK_PLACEHOLDER); return null; } @@ -507,7 +508,7 @@ public Void visit(ASTArrayAllocation node, StringBuilder sb) { sb.append(']'); }); if (node.getArrayInitializer() != null) { - sb.append(node.getArrayInitializer().length() == 0 ? "{}" : "{ ... }"); + sb.append(node.getArrayInitializer().length() == 0 ? "{}" : BLOCK_PLACEHOLDER); } return null; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java index 52406960e68..8aa0e2900ac 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java @@ -84,20 +84,17 @@ private void checkExpr(ASTExpression e, Object data) { if (necessity == NEVER || reportClarifying() && necessity == CLARIFYING || reportBalancing() && necessity == BALANCING) { - if (e.getParenthesisDepth() > 1) { - asCtx(data).addViolationWithMessage(e, "Duplicate parentheses."); - } else { - CharSequence snippet = PrettyPrintingUtil.prettyPrint(e); - String dots = "..."; - if (snippet.length() > MAX_SNIPPET_LENGTH) { - snippet = snippet.subSequence(0, MAX_SNIPPET_LENGTH - dots.length()) + dots; - } - asCtx(data).addViolationWithMessage(e, "Useless parentheses around `{0}`.", - snippet); - + String template = e.getParenthesisDepth() > 1 ? "Duplicate parentheses around `{0}`." + : "Useless parentheses around `{0}`."; + CharSequence snippet = PrettyPrintingUtil.prettyPrint(e); + String dots = "..."; + if (snippet.length() > MAX_SNIPPET_LENGTH) { + snippet = snippet.subSequence(0, MAX_SNIPPET_LENGTH - dots.length()) + dots; } - } + asCtx(data).addViolationWithMessage(e, template, + snippet); + } } public static Necessity needsParentheses(ASTExpression inner, JavaNode outer) { diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/internal/PrettyPrintingUtilTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/internal/PrettyPrintingUtilTest.java index ceaa365c7ef..b3d06b93bbd 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/internal/PrettyPrintingUtilTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/internal/PrettyPrintingUtilTest.java @@ -25,9 +25,11 @@ import net.sourceforge.pmd.lang.java.ast.ASTExpression; import net.sourceforge.pmd.lang.java.ast.ASTInfixExpression; import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression; +import net.sourceforge.pmd.lang.java.ast.ASTLiteral; import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTMethodReference; +import net.sourceforge.pmd.lang.java.ast.ASTSwitchExpression; import net.sourceforge.pmd.lang.java.ast.ASTUnaryExpression; import net.sourceforge.pmd.util.StringUtil; @@ -41,6 +43,16 @@ void displaySignatureTestWithExtraDimensions() { assertEquals("foo(String[][])", displaySignature(m)); } + @Test + void ppLiteral() { + testPrettyPrintIdentity("4", ASTLiteral.class); + testPrettyPrintIdentity("\"x\"", ASTLiteral.class); + testPrettyPrint("(4)", ASTLiteral.class, "4"); + testPrettyPrint("(\"x\")", ASTLiteral.class, "\"x\""); + testPrettyPrint("(true)", ASTLiteral.class, "true"); + testPrettyPrint("(null)", ASTLiteral.class, "null"); + } + @Test void ppMethodCall() { ASTCompilationUnit root = java.parse("class A { { foo(1); this.foo(1); A.this.foo(); } }"); @@ -98,7 +110,11 @@ void ppInfix() { testPrettyPrint("(1+2)*2", ASTInfixExpression.class, "(1 + 2) * 2"); } - + @Test + void ppSwitchExpression() { + testPrettyPrint("switch (x.toLowerCase()) { case \"a\" -> \"a\"; default -> \"o\"; }", + ASTSwitchExpression.class, "switch (x.toLowerCase()) { ... }"); + } @Test void ppLambdaExpr() { @@ -118,7 +134,7 @@ void ppLambdaBlock() { void ppArrayAllocation() { testPrettyPrintIdentity("new int[1]", ASTArrayAllocation.class); testPrettyPrintIdentity("new int[1][2]", ASTArrayAllocation.class); - testPrettyPrint("new List[]{}", ASTArrayAllocation.class, "new List[]{}"); + testPrettyPrintIdentity("new List[]{}", ASTArrayAllocation.class); testPrettyPrint("new int[]{1}", ASTArrayAllocation.class, "new int[]{ ... }"); testPrettyPrint("new int[][]{{4}}", ASTArrayAllocation.class, "new int[][]{ ... }"); } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml index dd7e693bf3d..53a20be4e32 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml @@ -665,16 +665,16 @@ public class Test { Detailed message - 12 + 11 Useless parentheses around `3 * 3`. - Useless parentheses around `(4)`. + Useless parentheses around `4`. Useless parentheses around `true ? 4 : 2`. Useless parentheses around `k3`. Useless parentheses around `id(k3)`. Useless parentheses around `k5++`. Useless parentheses around `k2 = 2`. - Duplicate parentheses. + Duplicate parentheses around `1 + 2`. Useless parentheses around `"very" + "long " + "concat split...`. Useless parentheses around `new int[5][7]`. Useless parentheses around `switch (k2 + k3) { ... }`. From 22abd0ecb8e58b700d4475de17cf7aef4a860f9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Mon, 18 Aug 2025 11:43:14 +0200 Subject: [PATCH 1279/1962] UnusedFormalParameter now ignores public/protected/defaultvisibility constructors, unless checkall property is set --- .../UnusedFormalParameterRule.java | 3 +++ .../xml/UnusedFormalParameter.xml | 21 +++++++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedFormalParameterRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedFormalParameterRule.java index 50a8d733f82..32917753ac0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedFormalParameterRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedFormalParameterRule.java @@ -30,6 +30,9 @@ public UnusedFormalParameterRule() { @Override public Object visit(ASTConstructorDeclaration node, Object data) { + if (node.getVisibility() != Visibility.V_PRIVATE && !getProperty(CHECKALL_DESCRIPTOR)) { + return data; + } check(node, data); return data; } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedFormalParameter.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedFormalParameter.xml index f069757a657..dcb3eabe227 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedFormalParameter.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedFormalParameter.xml @@ -105,14 +105,23 @@ class Foo { ]]> - - unused constructor param - 1 - + ]]> + + + #4700 don't flag unused constructor param by default + 0 + + + + + #4700 flag unused constructor param if checkall property is set + true + 1 + @@ -145,7 +154,7 @@ class Foo { Date: Mon, 18 Aug 2025 11:47:45 +0200 Subject: [PATCH 1280/1962] Update description of UnusedFormalParameterRule --- pmd-java/src/main/resources/category/java/bestpractices.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 6bc0049ffa0..a1b250ad7f2 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -1856,8 +1856,7 @@ Parameters whose name starts with `ignored` or `unused` are filtered out. Removing unused formal parameters from public methods could cause a ripple effect through the code base. Hence, by default, this rule only considers private methods. To include non-private methods, set the -`checkAll` property to `true`. - +`checkAll` property to `true`. The same applies to public constructors. 3 From a254dd26def2b2edded59cc59a65aaf24423d784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Mon, 18 Aug 2025 11:56:49 +0200 Subject: [PATCH 1281/1962] Remove now-unnecessary suppression --- .../sourceforge/pmd/lang/java/metrics/internal/NcssVisitor.java | 1 - 1 file changed, 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/NcssVisitor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/NcssVisitor.java index aa6ee1f5862..e3c713770d5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/NcssVisitor.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/NcssVisitor.java @@ -55,7 +55,6 @@ public class NcssVisitor extends JavaVisitorBase { protected final boolean countImports; - @SuppressWarnings("PMD.UnusedFormalParameter") public NcssVisitor(MetricOptions options, JavaNode topNode) { countImports = options.contains(NcssOption.COUNT_IMPORTS); // topNode is unused, but we'll need it if we want to discount lambdas From ad73e08da52836df8b86246769a42095624d37df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Tue, 19 Aug 2025 12:49:20 +0200 Subject: [PATCH 1282/1962] Rename constructor parameter to shut up PMD --- .../pmd/lang/java/metrics/internal/NcssVisitor.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/NcssVisitor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/NcssVisitor.java index e3c713770d5..76a4f323b3a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/NcssVisitor.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/internal/NcssVisitor.java @@ -55,9 +55,9 @@ public class NcssVisitor extends JavaVisitorBase { protected final boolean countImports; - public NcssVisitor(MetricOptions options, JavaNode topNode) { + public NcssVisitor(MetricOptions options, JavaNode unusedTopNode) { countImports = options.contains(NcssOption.COUNT_IMPORTS); - // topNode is unused, but we'll need it if we want to discount lambdas + // unusedTopNode is unused, but we'll need it if we want to discount lambdas // if we add it later, we break binary compatibility } From cfde9d992ffc4047ead6c1467a6033fe8fffc1cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Tue, 19 Aug 2025 18:30:11 +0200 Subject: [PATCH 1283/1962] Add test case that tests the end of a reported violation --- .../bestpractices/xml/UseAltAttributeForImages.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pmd-html/src/test/resources/net/sourceforge/pmd/lang/html/rule/bestpractices/xml/UseAltAttributeForImages.xml b/pmd-html/src/test/resources/net/sourceforge/pmd/lang/html/rule/bestpractices/xml/UseAltAttributeForImages.xml index 2090405e202..5db1909eff0 100644 --- a/pmd-html/src/test/resources/net/sourceforge/pmd/lang/html/rule/bestpractices/xml/UseAltAttributeForImages.xml +++ b/pmd-html/src/test/resources/net/sourceforge/pmd/lang/html/rule/bestpractices/xml/UseAltAttributeForImages.xml @@ -17,6 +17,17 @@ A house from the 18th century + + ]]> + + + + violation should only cover <img> tag + 1 + 2-2 + + ]]> From 8dfc03b69068669057f191ffa7ad79c3eee1490b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Tue, 19 Aug 2025 20:47:22 +0200 Subject: [PATCH 1284/1962] UseExplicitTypes: Add allowCasts property --- .../resources/category/java/codestyle.xml | 2 ++ .../rule/codestyle/xml/UseExplicitTypes.xml | 24 +++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml index 2903664fb36..df2e37711e3 100644 --- a/pmd-java/src/main/resources/category/java/codestyle.xml +++ b/pmd-java/src/main/resources/category/java/codestyle.xml @@ -2008,12 +2008,14 @@ See also [Local Variable Type Inference Style Guidelines](https://openjdk.org/pr + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UseExplicitTypes.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UseExplicitTypes.xml index 122283e4d5b..3b48f7bb5af 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UseExplicitTypes.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UseExplicitTypes.xml @@ -14,7 +14,9 @@ public class Foo { String s2 = "a"; // no violation - explicit type var f = getFoo(); // line 8 - violation var f = new Foo(); // line 9 - violation - ctor call - Function quadrat = (var x) -> x*x; + Function square = (var x) -> x*x; + + var f = (Integer)getFoo(); // line 12 - violation - cast } private String getFoo() { @@ -25,24 +27,32 @@ public class Foo { No vars anywhere - 4 - 5,6,8,9 + 5 + 5,6,8,9,12 Allow literals true - 2 - 8,9 + 3 + 8,9,12 Allow constructor calls true - 3 - 5,6,8 + 4 + 5,6,8,12 + + + + + Allow casts + true + 4 + 5,6,8,9 From 3424daca14deff96b57e1b0c6af264f031e109ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Tue, 19 Aug 2025 21:17:25 +0200 Subject: [PATCH 1285/1962] UseExplicitTypes: Add allowLoopVariable property --- .../resources/category/java/codestyle.xml | 2 + .../rule/codestyle/xml/UseExplicitTypes.xml | 41 +++++++++++++------ 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml index df2e37711e3..066427390a0 100644 --- a/pmd-java/src/main/resources/category/java/codestyle.xml +++ b/pmd-java/src/main/resources/category/java/codestyle.xml @@ -2009,6 +2009,7 @@ See also [Local Variable Type Inference Style Guidelines](https://openjdk.org/pr + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UseExplicitTypes.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UseExplicitTypes.xml index 3b48f7bb5af..c5ccdce6bcb 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UseExplicitTypes.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UseExplicitTypes.xml @@ -6,17 +6,24 @@ square = (var x) -> x*x; - var f = (Integer)getFoo(); // line 12 - violation - cast + var f = (Integer)getFoo(); // line 14 - violation - cast + + List strings = Arrays.asList("a", "b", "c"); + for (var str : strings) { // line 17 - violation - enhanced for loop + System.out.println(str); + } } private String getFoo() { @@ -27,32 +34,40 @@ public class Foo { No vars anywhere - 5 - 5,6,8,9,12 + 6 + 7,8,10,11,14,17 Allow literals true - 3 - 8,9,12 + 4 + 10,11,14,17 Allow constructor calls true - 4 - 5,6,8,12 + 5 + 7,8,10,14,17 Allow casts true - 4 - 5,6,8,9 + 5 + 7,8,10,11,17 + + + + + Allow loop variables + true + 5 + 7,8,10,11,14 From 48fac35dbc6a97e66b2224e64c7fe8c1bae213f0 Mon Sep 17 00:00:00 2001 From: Jude Pereira Date: Wed, 20 Aug 2025 09:49:44 +0200 Subject: [PATCH 1286/1962] Refactor CSVRenderer to use an enum for optional columns and add tests. --- .../pmd/renderers/CSVRenderer.java | 51 +++++++++++-------- .../pmd/renderers/CSVRendererTest.java | 19 +++++++ 2 files changed, 49 insertions(+), 21 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java index 5e7b5603589..a2dd2d4881a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java @@ -41,36 +41,45 @@ public class CSVRenderer extends AbstractIncrementingRenderer { public static final String NAME = "csv"; - private static final String PROP_BEGIN_LINE = "beginLine"; - private static final String PROP_END_LINE = "endLine"; - private static final String PROP_BEGIN_COL = "beginCol"; - private static final String PROP_END_COL = "endCol"; + enum CSVColumn { + END_LINE("endLine", "End Line", false), + BEGIN_COLUMN("beginColumn", "Begin Column", false), + END_COLUMN("endColumn", "End Column", false); + + final String id; + final String title; + final boolean enabled; + + CSVColumn(String id, String title, boolean enabled) { + this.id = id; + this.title = title; + this.enabled = enabled; + } + } private static final Set DEFAULT_OFF; static { HashSet set = new HashSet<>(); - set.add(PROP_BEGIN_LINE); - set.add(PROP_END_LINE); - set.add(PROP_BEGIN_COL); - set.add(PROP_END_COL); + set.add(CSVColumn.END_LINE.id); + set.add(CSVColumn.BEGIN_COLUMN.id); + set.add(CSVColumn.END_COLUMN.id); DEFAULT_OFF = Collections.unmodifiableSet(set); } @SuppressWarnings("unchecked") - private final ColumnDescriptor[] allColumns = new ColumnDescriptor[] { - newColDescriptor("problem", "Problem", (idx, rv, cr) -> Integer.toString(idx)), - newColDescriptor("package", "Package", (idx, rv, cr) -> rv.getAdditionalInfo().getOrDefault(RuleViolation.PACKAGE_NAME, "")), - newColDescriptor("file", "File", (idx, rv, cr) -> determineFileName(rv.getFileId())), - newColDescriptor("priority", "Priority", (idx, rv, cr) -> Integer.toString(rv.getRule().getPriority().getPriority())), - newColDescriptor("line", "Line", (idx, rv, cr) -> Integer.toString(rv.getBeginLine())), - newColDescriptor("desc", "Description", (idx, rv, cr) -> StringUtils.replaceChars(rv.getDescription(), '\"', '\'')), - newColDescriptor("ruleSet", "Rule set", (idx, rv, cr) -> rv.getRule().getRuleSetName()), - newColDescriptor("rule", "Rule", (idx, rv, cr) -> rv.getRule().getName()), - newColDescriptor(PROP_BEGIN_LINE, "Begin Line", (idx, rv, cr) -> Integer.toString(rv.getBeginLine()), false), - newColDescriptor(PROP_END_LINE, "End Line", (idx, rv, cr) -> Integer.toString(rv.getEndLine()), false), - newColDescriptor(PROP_BEGIN_COL, "Begin Column", (idx, rv, cr) -> Integer.toString(rv.getBeginColumn()), false), - newColDescriptor(PROP_END_COL, "End Column", (idx, rv, cr) -> Integer.toString(rv.getEndColumn()), false), + private final ColumnDescriptor[] allColumns = new ColumnDescriptor[]{ + newColDescriptor("problem", "Problem", (idx, rv, cr) -> Integer.toString(idx)), + newColDescriptor("package", "Package", (idx, rv, cr) -> rv.getAdditionalInfo().getOrDefault(RuleViolation.PACKAGE_NAME, "")), + newColDescriptor("file", "File", (idx, rv, cr) -> determineFileName(rv.getFileId())), + newColDescriptor("priority", "Priority", (idx, rv, cr) -> Integer.toString(rv.getRule().getPriority().getPriority())), + newColDescriptor("line", "Line", (idx, rv, cr) -> Integer.toString(rv.getBeginLine())), + newColDescriptor(CSVColumn.END_LINE.id, CSVColumn.END_LINE.title, (idx, rv, cr) -> Integer.toString(rv.getEndLine()), CSVColumn.END_LINE.enabled), + newColDescriptor(CSVColumn.BEGIN_COLUMN.id, CSVColumn.BEGIN_COLUMN.title, (idx, rv, cr) -> Integer.toString(rv.getBeginColumn()), CSVColumn.BEGIN_COLUMN.enabled), + newColDescriptor(CSVColumn.END_COLUMN.id, CSVColumn.END_COLUMN.title, (idx, rv, cr) -> Integer.toString(rv.getEndColumn()), CSVColumn.END_COLUMN.enabled), + newColDescriptor("desc", "Description", (idx, rv, cr) -> StringUtils.replaceChars(rv.getDescription(), '\"', '\'')), + newColDescriptor("ruleSet", "Rule set", (idx, rv, cr) -> rv.getRule().getRuleSetName()), + newColDescriptor("rule", "Rule", (idx, rv, cr) -> rv.getRule().getName()), }; private static @NonNull ColumnDescriptor newColDescriptor(String id, String title, Accessor accessor) { diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CSVRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CSVRendererTest.java index d0e9aeac870..6ccb5bc0e62 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CSVRendererTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CSVRendererTest.java @@ -4,8 +4,15 @@ package net.sourceforge.pmd.renderers; +import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.reporting.Report.ConfigurationError; import net.sourceforge.pmd.reporting.Report.ProcessingError; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; + +import java.nio.charset.Charset; + +import static org.junit.jupiter.api.Assertions.assertEquals; class CSVRendererTest extends AbstractRendererTest { @@ -20,6 +27,18 @@ String getExpected() { + "\"1\",\"\",\"" + getSourceCodeFilename() + "\",\"5\",\"1\",\"blah\",\"RuleSet\",\"Foo\"" + EOL; } + @ParameterizedTest + @EnumSource(CSVRenderer.CSVColumn.class) + void withOptionalColumns(final CSVRenderer.CSVColumn col) throws Exception { + CSVRenderer renderer = new CSVRenderer(); + renderer.setProperty((PropertyDescriptor) renderer.getPropertyDescriptor(col.id), true); + String actual = renderReport(renderer, reportOneViolation(), Charset.defaultCharset()); + + String expected = "\"Problem\",\"Package\",\"File\",\"Priority\",\"Line\",\"" + col.title + "\",\"Description\",\"Rule set\",\"Rule\"" + EOL + + "\"1\",\"\",\"" + getSourceCodeFilename() + "\",\"5\",\"1\",\"1\",\"blah\",\"RuleSet\",\"Foo\"" + EOL; + assertEquals(filter(expected), filter(actual)); + } + @Override String getExpectedEmpty() { return getHeader(); From c81a25cf52cc1dfc9842c8d239c57787febbb17a Mon Sep 17 00:00:00 2001 From: Jude Pereira Date: Wed, 20 Aug 2025 09:53:11 +0200 Subject: [PATCH 1287/1962] Document new optional columns for CSV. --- docs/pages/pmd/userdocs/pmd_report_formats.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/pmd/userdocs/pmd_report_formats.md b/docs/pages/pmd/userdocs/pmd_report_formats.md index 39873fc11c4..6d333a497a3 100644 --- a/docs/pages/pmd/userdocs/pmd_report_formats.md +++ b/docs/pages/pmd/userdocs/pmd_report_formats.md @@ -78,6 +78,9 @@ columns, use these CLI parameters additionally: `-property problem=false -proper * file: Include file column. Default: true. * priority: Include priority column. Default: true. * line: Include line column. Default: true. +* endLine: Include end line column. Default: false. +* beginColumn: Include begin column. Default: false. +* endColumn: Include end column. Default: false. * desc: Include description column. Default: true. * ruleSet: Include Rule set column. Default: true. * rule: Include Rule column. Default: true. From 13e1fe2719d37728da83b0f05fd3d6216f2d4c81 Mon Sep 17 00:00:00 2001 From: Jude Pereira Date: Wed, 20 Aug 2025 09:55:35 +0200 Subject: [PATCH 1288/1962] Fix formatting. --- .../pmd/renderers/CSVRenderer.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java index a2dd2d4881a..cce5c6c63cd 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java @@ -69,17 +69,17 @@ enum CSVColumn { @SuppressWarnings("unchecked") private final ColumnDescriptor[] allColumns = new ColumnDescriptor[]{ - newColDescriptor("problem", "Problem", (idx, rv, cr) -> Integer.toString(idx)), - newColDescriptor("package", "Package", (idx, rv, cr) -> rv.getAdditionalInfo().getOrDefault(RuleViolation.PACKAGE_NAME, "")), - newColDescriptor("file", "File", (idx, rv, cr) -> determineFileName(rv.getFileId())), - newColDescriptor("priority", "Priority", (idx, rv, cr) -> Integer.toString(rv.getRule().getPriority().getPriority())), - newColDescriptor("line", "Line", (idx, rv, cr) -> Integer.toString(rv.getBeginLine())), - newColDescriptor(CSVColumn.END_LINE.id, CSVColumn.END_LINE.title, (idx, rv, cr) -> Integer.toString(rv.getEndLine()), CSVColumn.END_LINE.enabled), - newColDescriptor(CSVColumn.BEGIN_COLUMN.id, CSVColumn.BEGIN_COLUMN.title, (idx, rv, cr) -> Integer.toString(rv.getBeginColumn()), CSVColumn.BEGIN_COLUMN.enabled), - newColDescriptor(CSVColumn.END_COLUMN.id, CSVColumn.END_COLUMN.title, (idx, rv, cr) -> Integer.toString(rv.getEndColumn()), CSVColumn.END_COLUMN.enabled), - newColDescriptor("desc", "Description", (idx, rv, cr) -> StringUtils.replaceChars(rv.getDescription(), '\"', '\'')), - newColDescriptor("ruleSet", "Rule set", (idx, rv, cr) -> rv.getRule().getRuleSetName()), - newColDescriptor("rule", "Rule", (idx, rv, cr) -> rv.getRule().getName()), + newColDescriptor("problem", "Problem", (idx, rv, cr) -> Integer.toString(idx)), + newColDescriptor("package", "Package", (idx, rv, cr) -> rv.getAdditionalInfo().getOrDefault(RuleViolation.PACKAGE_NAME, "")), + newColDescriptor("file", "File", (idx, rv, cr) -> determineFileName(rv.getFileId())), + newColDescriptor("priority", "Priority", (idx, rv, cr) -> Integer.toString(rv.getRule().getPriority().getPriority())), + newColDescriptor("line", "Line", (idx, rv, cr) -> Integer.toString(rv.getBeginLine())), + newColDescriptor(CSVColumn.END_LINE.id, CSVColumn.END_LINE.title, (idx, rv, cr) -> Integer.toString(rv.getEndLine()), CSVColumn.END_LINE.enabled), + newColDescriptor(CSVColumn.BEGIN_COLUMN.id, CSVColumn.BEGIN_COLUMN.title, (idx, rv, cr) -> Integer.toString(rv.getBeginColumn()), CSVColumn.BEGIN_COLUMN.enabled), + newColDescriptor(CSVColumn.END_COLUMN.id, CSVColumn.END_COLUMN.title, (idx, rv, cr) -> Integer.toString(rv.getEndColumn()), CSVColumn.END_COLUMN.enabled), + newColDescriptor("desc", "Description", (idx, rv, cr) -> StringUtils.replaceChars(rv.getDescription(), '\"', '\'')), + newColDescriptor("ruleSet", "Rule set", (idx, rv, cr) -> rv.getRule().getRuleSetName()), + newColDescriptor("rule", "Rule", (idx, rv, cr) -> rv.getRule().getName()), }; private static @NonNull ColumnDescriptor newColDescriptor(String id, String title, Accessor accessor) { From 7afe3ed3c72f7c81a5b72c6d4f7afccf1d9fdcce Mon Sep 17 00:00:00 2001 From: Jude Pereira Date: Wed, 20 Aug 2025 10:06:43 +0200 Subject: [PATCH 1289/1962] Reuse existing enum. --- .../pmd/renderers/CSVRenderer.java | 38 +++++-------------- .../pmd/renderers/CSVRendererTest.java | 10 +++-- 2 files changed, 16 insertions(+), 32 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java index cce5c6c63cd..fec121fd845 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVRenderer.java @@ -16,11 +16,9 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Set; /** @@ -41,30 +39,14 @@ public class CSVRenderer extends AbstractIncrementingRenderer { public static final String NAME = "csv"; - enum CSVColumn { - END_LINE("endLine", "End Line", false), - BEGIN_COLUMN("beginColumn", "Begin Column", false), - END_COLUMN("endColumn", "End Column", false); - - final String id; - final String title; - final boolean enabled; - - CSVColumn(String id, String title, boolean enabled) { - this.id = id; - this.title = title; - this.enabled = enabled; - } - } - - private static final Set DEFAULT_OFF; + static final Map> DEFAULT_OFF; static { - HashSet set = new HashSet<>(); - set.add(CSVColumn.END_LINE.id); - set.add(CSVColumn.BEGIN_COLUMN.id); - set.add(CSVColumn.END_COLUMN.id); - DEFAULT_OFF = Collections.unmodifiableSet(set); + HashMap> m = new HashMap<>(); + m.put("endLine", newColDescriptor("endLine", "End Line", (idx, rv, cr) -> Integer.toString(rv.getEndLine()), false)); + m.put("beginColumn", newColDescriptor("beginColumn", "Begin Column", (idx, rv, cr) -> Integer.toString(rv.getBeginColumn()), false)); + m.put("endColumn", newColDescriptor("endColumn", "End Column", (idx, rv, cr) -> Integer.toString(rv.getEndColumn()), false)); + DEFAULT_OFF = Collections.unmodifiableMap(m); } @SuppressWarnings("unchecked") @@ -74,9 +56,9 @@ enum CSVColumn { newColDescriptor("file", "File", (idx, rv, cr) -> determineFileName(rv.getFileId())), newColDescriptor("priority", "Priority", (idx, rv, cr) -> Integer.toString(rv.getRule().getPriority().getPriority())), newColDescriptor("line", "Line", (idx, rv, cr) -> Integer.toString(rv.getBeginLine())), - newColDescriptor(CSVColumn.END_LINE.id, CSVColumn.END_LINE.title, (idx, rv, cr) -> Integer.toString(rv.getEndLine()), CSVColumn.END_LINE.enabled), - newColDescriptor(CSVColumn.BEGIN_COLUMN.id, CSVColumn.BEGIN_COLUMN.title, (idx, rv, cr) -> Integer.toString(rv.getBeginColumn()), CSVColumn.BEGIN_COLUMN.enabled), - newColDescriptor(CSVColumn.END_COLUMN.id, CSVColumn.END_COLUMN.title, (idx, rv, cr) -> Integer.toString(rv.getEndColumn()), CSVColumn.END_COLUMN.enabled), + DEFAULT_OFF.get("endLine"), + DEFAULT_OFF.get("beginColumn"), + DEFAULT_OFF.get("endColumn"), newColDescriptor("desc", "Description", (idx, rv, cr) -> StringUtils.replaceChars(rv.getDescription(), '\"', '\'')), newColDescriptor("ruleSet", "Rule set", (idx, rv, cr) -> rv.getRule().getRuleSetName()), newColDescriptor("rule", "Rule", (idx, rv, cr) -> rv.getRule().getName()), @@ -119,7 +101,7 @@ private static PropertyDescriptor booleanPropertyFor(String id, String return prop; } - prop = PropertyFactory.booleanProperty(id).defaultValue(!DEFAULT_OFF.contains(id)).desc("Include " + label + " column").build(); + prop = PropertyFactory.booleanProperty(id).defaultValue(!DEFAULT_OFF.containsKey(id)).desc("Include " + label + " column").build(); PROPERTY_DESCRIPTORS_BY_ID.put(id, prop); return prop; } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CSVRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CSVRendererTest.java index 6ccb5bc0e62..b80e48a8a24 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CSVRendererTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CSVRendererTest.java @@ -7,8 +7,9 @@ import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.reporting.Report.ConfigurationError; import net.sourceforge.pmd.reporting.Report.ProcessingError; +import net.sourceforge.pmd.reporting.RuleViolation; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.ValueSource; import java.nio.charset.Charset; @@ -28,12 +29,13 @@ String getExpected() { } @ParameterizedTest - @EnumSource(CSVRenderer.CSVColumn.class) - void withOptionalColumns(final CSVRenderer.CSVColumn col) throws Exception { + @ValueSource(strings = {"endLine", "beginColumn", "endColumn"}) + void withOptionalColumns(final String id) throws Exception { CSVRenderer renderer = new CSVRenderer(); - renderer.setProperty((PropertyDescriptor) renderer.getPropertyDescriptor(col.id), true); + renderer.setProperty((PropertyDescriptor) renderer.getPropertyDescriptor(id), true); String actual = renderReport(renderer, reportOneViolation(), Charset.defaultCharset()); + ColumnDescriptor col = CSVRenderer.DEFAULT_OFF.get(id); String expected = "\"Problem\",\"Package\",\"File\",\"Priority\",\"Line\",\"" + col.title + "\",\"Description\",\"Rule set\",\"Rule\"" + EOL + "\"1\",\"\",\"" + getSourceCodeFilename() + "\",\"5\",\"1\",\"1\",\"blah\",\"RuleSet\",\"Foo\"" + EOL; assertEquals(filter(expected), filter(actual)); From ab34fefeb9dddaf5f511b71f0b8bd9a728d165b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Sat, 23 Aug 2025 17:04:13 +0200 Subject: [PATCH 1290/1962] New rule: ThatCantBeInHere --- .../rule/errorprone/ThatCantBeInHereRule.java | 297 ++++++ .../resources/category/java/errorprone.xml | 32 + .../rule/errorprone/ThatCantBeInHereTest.java | 11 + .../rule/errorprone/xml/ThatCantBeInHere.xml | 844 ++++++++++++++++++ 4 files changed, 1184 insertions(+) create mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ThatCantBeInHereRule.java create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/ThatCantBeInHereTest.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ThatCantBeInHere.xml diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ThatCantBeInHereRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ThatCantBeInHereRule.java new file mode 100644 index 00000000000..9b73a43f32c --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ThatCantBeInHereRule.java @@ -0,0 +1,297 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.errorprone; + +import net.sourceforge.pmd.lang.java.ast.ASTExpression; +import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; +import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; +import net.sourceforge.pmd.lang.java.types.InvocationMatcher; +import net.sourceforge.pmd.lang.java.types.JClassType; +import net.sourceforge.pmd.lang.java.types.JTypeMirror; +import net.sourceforge.pmd.lang.java.types.JTypeVar; +import net.sourceforge.pmd.lang.java.types.JWildcardType; +import net.sourceforge.pmd.lang.java.types.TypeOps; +import net.sourceforge.pmd.lang.java.types.TypeSystem; +import net.sourceforge.pmd.lang.java.types.TypeTestUtil; +import net.sourceforge.pmd.reporting.RuleContext; + +/** + * Detects method calls on collections where the passed object cannot possibly be in the collection + * due to type mismatch. This helps catch potential programming errors where incompatible types + * are used with collection methods like contains(), remove(), indexOf(), etc. + * + * Examples of violations: + * - List<Integer> list; list.remove("string"); // String cannot be in Integer list + * - Map<String, Integer> map; map.get(42); // Integer key cannot be in String-keyed map + */ +public class ThatCantBeInHereRule extends AbstractJavaRulechainRule { + + // Collection methods that take a single Object parameter + private static final InvocationMatcher COLLECTION_CONTAINS = InvocationMatcher.parse("java.util.Collection#contains(java.lang.Object)"); + private static final InvocationMatcher COLLECTION_REMOVE = InvocationMatcher.parse("java.util.Collection#remove(java.lang.Object)"); + private static final InvocationMatcher LIST_INDEX_OF = InvocationMatcher.parse("java.util.List#indexOf(java.lang.Object)"); + private static final InvocationMatcher LIST_LAST_INDEX_OF = InvocationMatcher.parse("java.util.List#lastIndexOf(java.lang.Object)"); + private static final InvocationMatcher DEQUE_REMOVE_FIRST_OCCURRENCE = InvocationMatcher.parse("java.util.Deque#removeFirstOccurrence(java.lang.Object)"); + private static final InvocationMatcher DEQUE_REMOVE_LAST_OCCURRENCE = InvocationMatcher.parse("java.util.Deque#removeLastOccurrence(java.lang.Object)"); + + // Collection methods that take a Collection parameter + private static final InvocationMatcher COLLECTION_REMOVE_ALL = InvocationMatcher.parse("java.util.Collection#removeAll(java.util.Collection)"); + private static final InvocationMatcher COLLECTION_RETAIN_ALL = InvocationMatcher.parse("java.util.Collection#retainAll(java.util.Collection)"); + private static final InvocationMatcher COLLECTION_CONTAINS_ALL = InvocationMatcher.parse("java.util.Collection#containsAll(java.util.Collection)"); + + // Map methods that take key parameters + private static final InvocationMatcher MAP_CONTAINS_KEY = InvocationMatcher.parse("java.util.Map#containsKey(java.lang.Object)"); + private static final InvocationMatcher MAP_GET = InvocationMatcher.parse("java.util.Map#get(java.lang.Object)"); + private static final InvocationMatcher MAP_GET_OR_DEFAULT = InvocationMatcher.parse("java.util.Map#getOrDefault(java.lang.Object,_)"); + private static final InvocationMatcher MAP_REMOVE_ONE_PARAM = InvocationMatcher.parse("java.util.Map#remove(java.lang.Object)"); + + // Map methods that take value parameters + private static final InvocationMatcher MAP_CONTAINS_VALUE = InvocationMatcher.parse("java.util.Map#containsValue(java.lang.Object)"); + + // Map methods that take key-value parameters + private static final InvocationMatcher MAP_REMOVE_TWO_PARAM = InvocationMatcher.parse("java.util.Map#remove(java.lang.Object,java.lang.Object)"); + + public ThatCantBeInHereRule() { + super(ASTMethodCall.class); + } + + @Override + public Object visit(ASTMethodCall node, Object data) { + RuleContext ctx = (RuleContext) data; + + if (COLLECTION_CONTAINS.matchesCall(node) + || COLLECTION_REMOVE.matchesCall(node) + || LIST_INDEX_OF.matchesCall(node) + || LIST_LAST_INDEX_OF.matchesCall(node) + || DEQUE_REMOVE_FIRST_OCCURRENCE.matchesCall(node) + || DEQUE_REMOVE_LAST_OCCURRENCE.matchesCall(node) + ) { + checkCollectionElementCompatibility(node, ctx); + } else if (COLLECTION_REMOVE_ALL.matchesCall(node) + || COLLECTION_RETAIN_ALL.matchesCall(node) + || COLLECTION_CONTAINS_ALL.matchesCall(node) + ) { + checkCollectionToCollectionCompatibility(node, ctx); + } else if (MAP_CONTAINS_KEY.matchesCall(node) + || MAP_GET.matchesCall(node) + || MAP_GET_OR_DEFAULT.matchesCall(node) + || MAP_REMOVE_ONE_PARAM.matchesCall(node) + ) { + checkMapKeyCompatibility(node, ctx); + } else if (MAP_CONTAINS_VALUE.matchesCall(node)) { + checkMapValueCompatibility(node, ctx); + } else if (MAP_REMOVE_TWO_PARAM.matchesCall(node)) { + checkMapKeyValueCompatibility(node, ctx); + } + + return null; + } + + private void checkCollectionElementCompatibility(ASTMethodCall node, RuleContext ctx) { + JTypeMirror qualifierType = getQualifierType(node); + if (!(qualifierType instanceof JClassType)) { + return; + } + + JTypeMirror elementType = getCollectionElementType((JClassType) qualifierType); + if (elementType == null) { + return; + } + + ASTExpression firstArg = getFirstArgument(node); + JTypeMirror argType = firstArg.getTypeMirror(); + if (!isCompatibleType(argType, elementType)) { + ctx.addViolation(node, argType.toString(), elementType.toString()); + } + } + + private void checkCollectionToCollectionCompatibility(ASTMethodCall node, RuleContext ctx) { + JTypeMirror qualifierType = getQualifierType(node); + if (!(qualifierType instanceof JClassType)) { + return; + } + + JTypeMirror elementType = getCollectionElementType((JClassType) qualifierType); + if (elementType == null) { + return; + } + + ASTExpression firstArg = getFirstArgument(node); + JTypeMirror argType = firstArg.getTypeMirror(); + if (argType instanceof JClassType && isCollectionType((JClassType) argType)) { + JTypeMirror argElementType = getCollectionElementType((JClassType) argType); + if (argElementType != null && !isCompatibleType(argElementType, elementType)) { + ctx.addViolation(node, argElementType.toString(), elementType.toString()); + } + } + } + + private void checkMapKeyCompatibility(ASTMethodCall node, RuleContext ctx) { + JTypeMirror qualifierType = getQualifierType(node); + if (!(qualifierType instanceof JClassType)) { + return; + } + + JTypeMirror keyType = getMapKeyType((JClassType) qualifierType); + if (keyType == null) { + return; + } + + ASTExpression firstArg = getFirstArgument(node); + JTypeMirror argType = firstArg.getTypeMirror(); + if (!isCompatibleType(argType, keyType)) { + ctx.addViolation(node, argType.toString(), keyType.toString()); + } + } + + private void checkMapValueCompatibility(ASTMethodCall node, RuleContext ctx) { + JTypeMirror qualifierType = getQualifierType(node); + if (!(qualifierType instanceof JClassType)) { + return; + } + + JTypeMirror valueType = getMapValueType((JClassType) qualifierType); + if (valueType == null) { + return; + } + + ASTExpression firstArg = getFirstArgument(node); + JTypeMirror argType = firstArg.getTypeMirror(); + if (!isCompatibleType(argType, valueType)) { + ctx.addViolation(node, argType.toString(), valueType.toString()); + } + } + + private void checkMapKeyValueCompatibility(ASTMethodCall node, RuleContext ctx) { + JTypeMirror qualifierType = getQualifierType(node); + if (!(qualifierType instanceof JClassType)) { + return; + } + + JTypeMirror keyType = getMapKeyType((JClassType) qualifierType); + JTypeMirror valueType = getMapValueType((JClassType) qualifierType); + if (keyType == null || valueType == null) { + return; + } + + ASTExpression keyArg = getFirstArgument(node); + ASTExpression valueArg = getSecondArgument(node); + + JTypeMirror keyArgType = keyArg.getTypeMirror(); + JTypeMirror valueArgType = valueArg.getTypeMirror(); + + if (!isCompatibleType(keyArgType, keyType)) { + ctx.addViolation(node, keyArgType.toString(), keyType.toString()); + } else if (!isCompatibleType(valueArgType, valueType)) { + ctx.addViolation(node, valueArgType.toString(), valueType.toString()); + } + } + + private boolean isCollectionType(JClassType type) { + return TypeTestUtil.isA(java.util.Collection.class, type); + } + + private JTypeMirror getCollectionElementType(JClassType collectionType) { + JClassType asSuperCollection = collectionType.getAsSuper(collectionType.getTypeSystem().getClassSymbol(java.util.Collection.class)); + if (asSuperCollection.getTypeArgs().isEmpty()) { + // Raw collection type without generics + return null; + } + JTypeMirror elementType = asSuperCollection.getTypeArgs().get(0); + return resolveWildcardBound(elementType); + } + + private JTypeMirror getMapKeyType(JClassType mapType) { + JClassType asSuperMap = mapType.getAsSuper(mapType.getTypeSystem().getClassSymbol(java.util.Map.class)); + if (asSuperMap.getTypeArgs().isEmpty()) { + // Raw map type without generics + return null; + } + JTypeMirror keyType = asSuperMap.getTypeArgs().get(0); + return resolveWildcardBound(keyType); + } + + private JTypeMirror getMapValueType(JClassType mapType) { + JClassType asSuperMap = mapType.getAsSuper(mapType.getTypeSystem().getClassSymbol(java.util.Map.class)); + if (asSuperMap.getTypeArgs().isEmpty()) { + // Raw map type without generics + return null; + } + JTypeMirror valueType = asSuperMap.getTypeArgs().get(1); + return resolveWildcardBound(valueType); + } + + private JTypeMirror resolveWildcardBound(JTypeMirror type) { + // Handle captured type variables from wildcards + if (type instanceof JTypeVar && ((JTypeVar) type).isCaptured()) { + JWildcardType wildcard = ((JTypeVar) type).getCapturedOrigin(); + if (wildcard != null) { + return resolveWildcard(wildcard, type.getTypeSystem()); + } + } + + // Handle direct wildcard types + if (type instanceof JWildcardType) { + return resolveWildcard((JWildcardType) type, type.getTypeSystem()); + } + + return type; + } + + private JTypeMirror resolveWildcard(JWildcardType wildcard, TypeSystem typeSystem) { + return wildcard.isUpperBound() + ? wildcard.asUpperBound() + : typeSystem.OBJECT; + } + + private boolean isCompatibleType(JTypeMirror argType, JTypeMirror expectedType) { + // If argType is unresolved, be conservative and assume compatibility + // This prevents false positives when external dependencies can't be resolved + if (TypeOps.isUnresolved(argType)) { + return true; + } + + // Check basic convertibility using raw types (ignore generics) + // This will cause some false-negaties, but doing this right would lead to much more complicated code + JTypeMirror rawArgType = getRawType(argType); + JTypeMirror rawExpectedType = getRawType(expectedType); + + if (TypeOps.isConvertible(rawArgType, rawExpectedType).somehow() + || TypeOps.isConvertible(rawExpectedType, rawArgType).somehow() + ) { + return true; + } + + // Check primitive/wrapper compatibility (autoboxing/unboxing) + if (argType.isPrimitive()) { + // Check if autoboxed primitive is compatible with expected type + JTypeMirror boxedArgType = argType.box(); + return TypeOps.isConvertible(boxedArgType, expectedType).somehow(); + } + + return false; + } + + private JTypeMirror getRawType(JTypeMirror type) { + if (type instanceof JClassType) { + JClassType classType = (JClassType) type; + return classType.getErasure(); + } + return type; + } + + + private JTypeMirror getQualifierType(ASTMethodCall node) { + return node.getQualifier() != null ? node.getQualifier().getTypeMirror() : null; + } + + private ASTExpression getFirstArgument(ASTMethodCall node) { + return node.getArguments().get(0); + } + + private ASTExpression getSecondArgument(ASTMethodCall node) { + return node.getArguments().get(1); + } +} diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 84044d626ab..76437a95906 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -3061,6 +3061,38 @@ public class CarTest { + + +Detects method calls on collections where the passed object cannot possibly be in the collection +due to type mismatch. This helps catch potential programming errors where incompatible types +are used with collection methods like contains(), remove(), indexOf(), etc. + +Methods checked include: +- Collection: contains(), remove() +- List: indexOf(), lastIndexOf() +- Map: containsKey(), containsValue(), get(), remove() +- Deque: removeFirstOccurrence(), removeLastOccurrence() + + 3 + + numbers = Arrays.asList(1, 2, 3); +numbers.remove("string"); // violation: String cannot be in Integer list + +Map map = new HashMap<>(); +map.get(42); // violation: Integer key cannot be in String-keyed map + +Set names = new HashSet<>(); +names.contains(123); // violation: Integer cannot be in String set +]]> + + + + + + + Collection.contains with incompatible type + 1 + 5 + collection, String stringParam) { + collection.contains(stringParam); // violation + } +} + ]]> + + + + Collection.remove with incompatible type + 1 + 5 + collection, String stringParam) { + collection.remove(stringParam); // violation + } +} + ]]> + + + + Collection.removeAll with incompatible type + 1 + 5 + collection, Collection stringCollection) { + collection.removeAll(stringCollection); // violation + } +} + ]]> + + + + Collection.retainAll with incompatible type + 1 + 5 + collection, Collection stringCollection) { + collection.retainAll(stringCollection); // violation + } +} + ]]> + + + + Collection.containsAll with incompatible type + 1 + 5 + collection, Collection stringCollection) { + collection.containsAll(stringCollection); // violation + } +} + ]]> + + + + List.indexOf with incompatible type + 1 + 5 + list, String stringParam) { + list.indexOf(stringParam); // violation + } +} + ]]> + + + + List.lastIndexOf with incompatible type + 1 + 5 + list, String stringParam) { + list.lastIndexOf(stringParam); // violation + } +} + ]]> + + + + Deque.removeFirstOccurrence with incompatible type + 1 + 5 + deque, String stringParam) { + deque.removeFirstOccurrence(stringParam); // violation + } +} + ]]> + + + + Deque.removeLastOccurrence with incompatible type + 1 + 5 + deque, String stringParam) { + deque.removeLastOccurrence(stringParam); // violation + } +} + ]]> + + + + Map.containsKey with incompatible type + 1 + 5 + map, String stringParam) { + map.containsKey(stringParam); // violation + } +} + ]]> + + + + Map.containsValue with incompatible type + 1 + 5 + map, String stringParam) { + map.containsValue(stringParam); // violation + } +} + ]]> + + + + Map.get with incompatible key type + 1 + 5 + map, String stringParam) { + map.get(stringParam); // violation + } +} + ]]> + + + + Map.getOrDefault with incompatible key type + 1 + 5 + map, String stringParam, String defaultValue) { + map.getOrDefault(stringParam, defaultValue); // violation + } +} + ]]> + + + + Map.remove with incompatible key type + 1 + 5 + map, String stringParam) { + map.remove(stringParam); // violation + } +} + ]]> + + + + Map.remove with incompatible key type (2-parameter) + 1 + 5 + map, String keyParam, String valueParam) { + map.remove(keyParam, valueParam); // violation + } +} + ]]> + + + + Map.remove with incompatible value type (2-parameter) + 1 + 5 + map, Integer keyParam, Integer valueParam) { + map.remove(keyParam, valueParam); // violation + } +} + ]]> + + + + Valid case - compatible types should not trigger violation + 0 + list, Set set, Map map, + Integer intParam, String stringParam, Collection intCollection + ) { + list.contains(intParam); + list.remove(intParam); + list.indexOf(intParam); + set.contains(stringParam); + set.remove(stringParam); + list.removeAll(intCollection); + map.containsKey(intParam); + map.containsValue(stringParam); + map.get(intParam); + } +} + ]]> + + + + Collection.add and Map.put should never trigger violations + 0 + intCollection, List stringList, + Map map, Set doubleSet + ) { + intCollection.add(42); + stringList.add("hello"); + doubleSet.add(3.14); + + map.put(123, "value"); + map.put(456, "another"); + } +} + ]]> + + + + Subtype compatibility - should not trigger violations + 0 + animals, List numbers, Set sequences, + Deque objects, Dog dog, Integer intValue, String stringValue, + Collection dogs, Collection integers, Collection strings, + Map animalToNumber, Map seqToObj + ) { + animals.contains(dog); + animals.remove(dog); + numbers.indexOf(intValue); + numbers.lastIndexOf(intValue); + sequences.contains(stringValue); + objects.removeFirstOccurrence(stringValue); + objects.removeLastOccurrence(intValue); + + animals.removeAll(dogs); + animals.retainAll(dogs); + animals.containsAll(dogs); + numbers.removeAll(integers); + sequences.containsAll(strings); + + animalToNumber.containsKey(dog); + animalToNumber.containsValue(intValue); + animalToNumber.get(dog); + animalToNumber.getOrDefault(dog, 0); + animalToNumber.remove(dog); + animalToNumber.remove(dog, intValue); + + seqToObj.containsKey(stringValue); + seqToObj.containsValue(stringValue); + seqToObj.get(stringValue); + seqToObj.remove(stringValue, intValue); + } +} + ]]> + + + + Supertype compatibility - should not trigger violations + 0 + dogs, List integers, Set strings, + Deque dogDeque, Animal animal, Number number, CharSequence charSeq, Object obj, + Collection animals, Collection numbers, Collection sequences, + Map dogToInt, Map stringToDog + ) { + // Static type is supertype of element type - dynamic type might be compatible + dogs.contains(animal); + dogs.remove(animal); + integers.indexOf(number); + integers.lastIndexOf(number); + strings.contains(charSeq); + dogDeque.removeFirstOccurrence(animal); + dogDeque.removeLastOccurrence(obj); + + dogs.removeAll(animals); + dogs.retainAll(animals); + dogs.containsAll(animals); + integers.removeAll(numbers); + strings.containsAll(sequences); + + dogToInt.containsKey(animal); + dogToInt.containsValue(number); + dogToInt.get(animal); + dogToInt.getOrDefault(animal, 0); + dogToInt.remove(animal); + dogToInt.remove(animal, number); + + stringToDog.containsKey(charSeq); + stringToDog.containsValue(animal); + stringToDog.get(charSeq); + stringToDog.remove(charSeq, animal); + } +} + ]]> + + + + MyList extends ArrayList - should detect incompatible type + 1 + 7 + {} + + void testMyListIncompatible(MyList myList, Integer intParam) { + myList.contains(intParam); + } +} + ]]> + + + + MyMap extends HashMap - should detect incompatible key type + 1 + 7 + {} + + void testMyMapIncompatibleKey(MyMap myMap, String stringParam) { + myMap.get(stringParam); + } +} + ]]> + + + + MyMap extends HashMap - should detect incompatible value type + 1 + 7 + {} + + void testMyMapIncompatibleValue(MyMap myMap, Integer intParam) { + myMap.containsValue(intParam); + } +} + ]]> + + + + MyList and MyMap with compatible types - should not trigger violations + 0 + {} + static class MyMap extends HashMap {} + + void testMyCollectionsCompatible(MyList myList, MyMap myMap, String stringParam, Integer intParam) { + myList.contains(stringParam); + myList.remove(stringParam); + myList.indexOf(stringParam); + + myMap.get(intParam); + myMap.containsKey(intParam); + myMap.containsValue(stringParam); + myMap.remove(intParam); + myMap.remove(intParam, stringParam); + } +} + ]]> + + + + Bounded generics with multiple violations + 5 + 12,13,14,17,18 + animals, Set dogSupers, + Map numberToStringSuper, String stringParam, Integer intParam + ) { + animals.contains(stringParam); // violation - String not compatible with ? extends Animal + animals.remove(intParam); // violation - Integer not compatible with ? extends Animal + animals.indexOf(stringParam); // violation - String not compatible with ? extends Animal + dogSupers.contains(stringParam); // no violation - String is compatible with Object (? super Dog โ†’ Object) + dogSupers.remove(intParam); // no violation - Integer is compatible with Object (? super Dog โ†’ Object) + numberToStringSuper.containsKey(stringParam); // violation - String not compatible with ? extends Number + numberToStringSuper.get(stringParam); // violation - String not compatible with ? extends Number + numberToStringSuper.containsValue(intParam); // no violation - Integer is compatible with Object (? super String โ†’ Object) + } +} + ]]> + + + + Bounded generics with no violations + 0 + animals, Set dogSupers, + Map numberToStringSuper, + Dog dog, Cat cat, Animal animal, Object obj, Integer intParam, Double doubleParam, + String stringParam, CharSequence charSeq, Collection animalCollection + ) { + // Compatible with ? extends Animal + animals.contains(dog); + animals.contains(cat); + animals.contains(animal); + animals.remove(dog); + animals.indexOf(cat); + animals.lastIndexOf(animal); + + // Compatible with ? super Dog + dogSupers.contains(dog); + dogSupers.contains(animal); + dogSupers.contains(obj); + dogSupers.remove(dog); + + // Compatible collections + animals.removeAll(animalCollection); + animals.containsAll(animalCollection); + + // Compatible with ? extends Number keys and ? super String values + numberToStringSuper.containsKey(intParam); + numberToStringSuper.containsKey(doubleParam); + numberToStringSuper.get(intParam); + numberToStringSuper.containsValue(stringParam); + numberToStringSuper.containsValue(charSeq); + numberToStringSuper.containsValue(obj); + numberToStringSuper.remove(doubleParam); + numberToStringSuper.remove(intParam, stringParam); + } +} + ]]> + + + + raw list + 0 + + + + + Primitive to wrapper compatibility - should not trigger violations + 0 + intCollection, List boolList, Set charSet, + Deque doubleDeque, Map longToFloatMap, + int primitiveInt, boolean primitiveBool, char primitiveChar, + double primitiveDouble, long primitiveLong, float primitiveFloat + ) { + // Collection methods with primitive arguments - should auto-box to wrapper + intCollection.contains(primitiveInt); + intCollection.remove(primitiveInt); + boolList.indexOf(primitiveBool); + boolList.lastIndexOf(primitiveBool); + charSet.contains(primitiveChar); + doubleDeque.removeFirstOccurrence(primitiveDouble); + doubleDeque.removeLastOccurrence(primitiveDouble); + + // Map methods with primitive arguments - should auto-box to wrapper + longToFloatMap.containsKey(primitiveLong); + longToFloatMap.containsValue(primitiveFloat); + longToFloatMap.get(primitiveLong); + longToFloatMap.getOrDefault(primitiveLong, primitiveFloat); + longToFloatMap.remove(primitiveLong); + longToFloatMap.remove(primitiveLong, primitiveFloat); + } +} + ]]> + + + + Mismatched primitive to wrapper types - should trigger violations + 13 + 11,12,13,14,15,16,17,20,21,22,23,24,25 + intCollection, List boolList, Set charSet, + Deque doubleDeque, Map longToFloatMap, + long wrongLong, int wrongInt, double wrongDouble, float wrongFloat, + char wrongChar, boolean wrongBool, short wrongShort + ) { + // Collection methods with mismatched primitive arguments - should trigger violations + intCollection.contains(wrongLong); // long cannot be in Integer collection + intCollection.remove(wrongDouble); // double cannot be in Integer collection + boolList.indexOf(wrongInt); // int cannot be in Boolean list + boolList.lastIndexOf(wrongChar); // char cannot be in Boolean list + charSet.contains(wrongBool); // boolean cannot be in Character set + doubleDeque.removeFirstOccurrence(wrongShort); // short cannot be in Double deque + doubleDeque.removeLastOccurrence(wrongLong); // long cannot be in Double deque + + // Map methods with mismatched primitive arguments - should trigger violations + longToFloatMap.containsKey(wrongInt); // int cannot be key in Long-keyed map + longToFloatMap.containsValue(wrongDouble); // double cannot be value in Float-valued map + longToFloatMap.get(wrongShort); // short cannot be key in Long-keyed map + longToFloatMap.getOrDefault(wrongChar, wrongFloat); // char cannot be key in Long-keyed map + longToFloatMap.remove(wrongBool); // boolean cannot be key in Long-keyed map + longToFloatMap.remove(wrongDouble, wrongInt); // double cannot be key in Long-keyed map + } +} + ]]> + + + + Primitives with non-wrapper collection types - should trigger violations + 13 + 11,12,13,14,15,16,17,20,21,22,23,24,25 + stringCollection, List stringList, Set numberSet, + Deque charSeqDeque, Map stringToStringMap, + int primitiveInt, long primitiveLong, double primitiveDouble, float primitiveFloat, + boolean primitiveBool, char primitiveChar, short primitiveShort, byte primitiveByte + ) { + // Collection methods with primitive arguments on non-wrapper collections - should trigger violations + stringCollection.contains(primitiveInt); // int cannot be in String collection + stringCollection.remove(primitiveLong); // long cannot be in String collection + stringList.indexOf(primitiveDouble); // double cannot be in String list + stringList.lastIndexOf(primitiveFloat); // float cannot be in String list + numberSet.contains(primitiveBool); // boolean cannot be in Number set + charSeqDeque.removeFirstOccurrence(primitiveChar); // char cannot be in CharSequence deque + charSeqDeque.removeLastOccurrence(primitiveShort); // short cannot be in CharSequence deque + + // Map methods with primitive arguments on non-wrapper maps - should trigger violations + stringToStringMap.containsKey(primitiveInt); // int cannot be key in String-keyed map + stringToStringMap.containsValue(primitiveLong); // long cannot be value in String-valued map + stringToStringMap.get(primitiveDouble); // double cannot be key in String-keyed map + stringToStringMap.getOrDefault(primitiveFloat, "default"); // float cannot be key in String-keyed map + stringToStringMap.remove(primitiveBool); // boolean cannot be key in String-keyed map + stringToStringMap.remove("key", primitiveByte); // byte cannot be value in String-valued map + } +} + ]]> + + + + Primitives with compatible supertype collections - should not trigger violations + 0 + objectCollection, List objectList, Set numberSet, + Deque objectDeque, Map objectToObjectMap, Map numberToObjectMap, + int primitiveInt, long primitiveLong, double primitiveDouble, float primitiveFloat, + boolean primitiveBool, char primitiveChar, short primitiveShort, byte primitiveByte + ) { + // Collection methods with primitive arguments on Object collections - should be compatible via autoboxing + objectCollection.contains(primitiveInt); // int autoboxes to Integer, which extends Object + objectCollection.remove(primitiveLong); // long autoboxes to Long, which extends Object + objectList.indexOf(primitiveDouble); // double autoboxes to Double, which extends Object + objectList.lastIndexOf(primitiveFloat); // float autoboxes to Float, which extends Object + objectList.contains(primitiveBool); // boolean autoboxes to Boolean, which extends Object + objectDeque.removeFirstOccurrence(primitiveChar); // char autoboxes to Character, which extends Object + objectDeque.removeLastOccurrence(primitiveShort); // short autoboxes to Short, which extends Object + + // Collection methods with numeric primitives on Number collections - should be compatible + numberSet.contains(primitiveInt); // int autoboxes to Integer, which extends Number + numberSet.remove(primitiveLong); // long autoboxes to Long, which extends Number + numberSet.contains(primitiveDouble); // double autoboxes to Double, which extends Number + numberSet.contains(primitiveFloat); // float autoboxes to Float, which extends Number + numberSet.contains(primitiveShort); // short autoboxes to Short, which extends Number + numberSet.contains(primitiveByte); // byte autoboxes to Byte, which extends Number + + // Map methods with primitive arguments on Object maps - should be compatible via autoboxing + objectToObjectMap.containsKey(primitiveInt); // int autoboxes to Integer, which extends Object + objectToObjectMap.containsValue(primitiveLong); // long autoboxes to Long, which extends Object + objectToObjectMap.get(primitiveDouble); // double autoboxes to Double, which extends Object + objectToObjectMap.getOrDefault(primitiveFloat, new Object()); // float autoboxes to Float, which extends Object + objectToObjectMap.remove(primitiveBool); // boolean autoboxes to Boolean, which extends Object + objectToObjectMap.remove(primitiveChar, primitiveShort); // both autobox to Objects + + // Map methods with numeric primitives on Number-keyed maps - should be compatible + numberToObjectMap.containsKey(primitiveInt); // int autoboxes to Integer, which extends Number + numberToObjectMap.get(primitiveLong); // long autoboxes to Long, which extends Number + numberToObjectMap.remove(primitiveDouble); // double autoboxes to Double, which extends Number + numberToObjectMap.remove(primitiveFloat, new Object()); // float autoboxes to Float, which extends Number + } +} + ]]> + + + + Generic wildcards with unbounded ? - should not trigger violations + 0 + unboundedCollection, List unboundedList, Set unboundedSet, + Deque unboundedDeque, Map wildcardKeyMap, Map wildcardValueMap, + Map fullWildcardMap, String stringParam, Integer intParam, Object objParam, + Collection stringCollection, Collection intCollection + ) { + // Collection methods with unbounded wildcards - should not trigger violations + // since ? can represent any type, including the argument type + unboundedCollection.contains(stringParam); + unboundedCollection.contains(intParam); + unboundedCollection.contains(objParam); + unboundedCollection.remove(stringParam); + unboundedCollection.remove(intParam); + + unboundedList.indexOf(stringParam); + unboundedList.indexOf(intParam); + unboundedList.lastIndexOf(objParam); + + unboundedSet.contains(stringParam); + unboundedSet.remove(intParam); + + unboundedDeque.removeFirstOccurrence(stringParam); + unboundedDeque.removeLastOccurrence(intParam); + + // Collection-to-collection operations with unbounded wildcards + unboundedCollection.removeAll(stringCollection); + unboundedCollection.retainAll(intCollection); + unboundedCollection.containsAll(stringCollection); + + // Map methods with wildcard keys - should not trigger violations + wildcardKeyMap.containsKey(stringParam); + wildcardKeyMap.containsKey(intParam); + wildcardKeyMap.get(objParam); + wildcardKeyMap.getOrDefault(stringParam, "default"); + wildcardKeyMap.remove(intParam); + wildcardKeyMap.remove(stringParam, "value"); + + // Map methods with wildcard values - should not trigger violations + wildcardValueMap.containsValue(stringParam); + wildcardValueMap.containsValue(intParam); + wildcardValueMap.remove("key", stringParam); + wildcardValueMap.remove("key", intParam); + + // Map methods with full wildcards - should not trigger violations + fullWildcardMap.containsKey(stringParam); + fullWildcardMap.containsKey(intParam); + fullWildcardMap.containsValue(stringParam); + fullWildcardMap.containsValue(intParam); + fullWildcardMap.get(objParam); + fullWildcardMap.remove(stringParam); + fullWildcardMap.remove(intParam, objParam); + } +} + ]]> + + + + Map wildcard get with String key should not trigger violation + 0 + ) c).get("path"); + Object value = ((Map) c).get("value"); + } + } +} + ]]> + + + + Constructor call with unresolved external type + 0 + , String> map) { + map.containsKey(new Pair<>("x", null)); + } +} + ]]> + + + + SimpleEntry with unresolved method return types + 0 + , String> map) { + // Generic inference with unresolved external types + map.get(new AbstractMap.SimpleEntry<>(SomeClass.getValue(), SomeClass.getValue())); + } +} + ]]> + + + + Class wildcard type incompatibility + 0 + , String> map, Class clazz) { + map.get(clazz); + } +} + ]]> + + + \ No newline at end of file From d7111799835c119f2596136b3c83f07822ad8d7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Sat, 23 Aug 2025 20:22:08 +0200 Subject: [PATCH 1291/1962] Fix false negative in ConcurrentSkipListMap --- .../java/rule/errorprone/ThatCantBeInHereRule.java | 8 ++++++++ .../java/rule/errorprone/xml/ThatCantBeInHere.xml | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ThatCantBeInHereRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ThatCantBeInHereRule.java index 9b73a43f32c..bb1c147c56f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ThatCantBeInHereRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ThatCantBeInHereRule.java @@ -253,6 +253,14 @@ private boolean isCompatibleType(JTypeMirror argType, JTypeMirror expectedType) return true; } + // Handle wildcards and captured type variables - they should be compatible with any type + // since they represent unknown types that could potentially be the expected type + if (argType instanceof JWildcardType + || (argType instanceof JTypeVar && ((JTypeVar) argType).isCaptured()) + ) { + return true; + } + // Check basic convertibility using raw types (ignore generics) // This will cause some false-negaties, but doing this right would lead to much more complicated code JTypeMirror rawArgType = getRawType(argType); diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ThatCantBeInHere.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ThatCantBeInHere.xml index a3be68b298f..77436226b43 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ThatCantBeInHere.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ThatCantBeInHere.xml @@ -841,4 +841,18 @@ public class Test { ]]> + + Map.Entry<?,?> + 0 + map, Map.Entry entry) { + map.get(entry.getKey()); + } +} + ]]> + + \ No newline at end of file From 828d4043532a4bdf1be123366947a3486585fa28 Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Sun, 24 Aug 2025 19:19:31 +0200 Subject: [PATCH 1292/1962] Fix #5849: [core] Support Markdown Output for CPD Reports --- .../sourceforge/pmd/cpd/CPDConfiguration.java | 1 + .../sourceforge/pmd/cpd/MarkdownRenderer.java | 49 ++++++++++++++ .../pmd/cpd/CPDConfigurationTest.java | 1 + .../pmd/cpd/MarkdownRendererTest.java | 67 +++++++++++++++++++ 4 files changed, 118 insertions(+) create mode 100644 pmd-core/src/main/java/net/sourceforge/pmd/cpd/MarkdownRenderer.java create mode 100644 pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownRendererTest.java diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java index 9d5f104b990..fc2a110ab38 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java @@ -43,6 +43,7 @@ public class CPDConfiguration extends AbstractConfiguration { RENDERERS.put("csv", CSVRenderer.class); RENDERERS.put("csv_with_linecount_per_file", CSVWithLinecountPerFileRenderer.class); RENDERERS.put("vs", VSRenderer.class); + RENDERERS.put("markdown", MarkdownRenderer.class); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MarkdownRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MarkdownRenderer.java new file mode 100644 index 00000000000..1387fd2fa42 --- /dev/null +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MarkdownRenderer.java @@ -0,0 +1,49 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.cpd; + +import java.io.IOException; +import java.io.Writer; +import java.util.Iterator; + +import net.sourceforge.pmd.lang.document.Chars; +import net.sourceforge.pmd.lang.document.FileLocation; + +public class MarkdownRenderer implements CPDReportRenderer { + + //separator must be surrounded by empty lines to be rendered properly + private static final String SEPARATOR = "\n---\n\n"; + private static final String FOUND_DUPLICATION_TEMPLATE = "Found a %d line (%d tokens) duplication in the following files:\n"; + private static final String STARTING_AT_LINE_TEMPLATE = "Starting at line %d of %s\n"; + private static final String CODE_BLOCK_TEMPLATE = "```\n%s```\n"; + + @Override + public void render(CPDReport report, Writer writer) throws IOException { + Iterator matches = report.getMatches().iterator(); + if (matches.hasNext()) { + renderDuplication(report, writer, matches.next()); + } + + while (matches.hasNext()) { + Match match = matches.next(); + writer.write(SEPARATOR); + renderDuplication(report, writer, match); + } + + writer.flush(); + } + + private void renderDuplication(CPDReport report, Writer writer, Match match) throws IOException { + writer.append(String.format(FOUND_DUPLICATION_TEMPLATE, match.getLineCount(), match.getTokenCount())); + + for (Mark mark : match) { + FileLocation loc = mark.getLocation(); + writer.append(String.format(STARTING_AT_LINE_TEMPLATE, loc.getStartLine(), report.getDisplayName(loc.getFileId()))); + } + + Chars source = report.getSourceCodeSlice(match.getFirstMark()); + writer.append(String.format(CODE_BLOCK_TEMPLATE, source)); + } +} diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDConfigurationTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDConfigurationTest.java index 3abd2b2562e..52ad36f5f0b 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDConfigurationTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDConfigurationTest.java @@ -30,6 +30,7 @@ void testRenderers() { renderersToTest.put("csv_with_linecount_per_file", CSVWithLinecountPerFileRenderer.class); renderersToTest.put("vs", VSRenderer.class); renderersToTest.put("text", SimpleRenderer.class); + renderersToTest.put("markdown", MarkdownRenderer.class); for (Map.Entry> entry : renderersToTest.entrySet()) { CPDReportRenderer r = CPDConfiguration.createRendererByName(entry.getKey(), StandardCharsets.UTF_8); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownRendererTest.java new file mode 100644 index 00000000000..c67cd2832dd --- /dev/null +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownRendererTest.java @@ -0,0 +1,67 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.cpd; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.IOException; +import java.io.StringWriter; + +import org.junit.jupiter.api.Test; + +import net.sourceforge.pmd.lang.document.FileId; + +class MarkdownRendererTest { + + @Test + void testMultipleDuplicates() throws IOException { + CPDReportRenderer renderer = new MarkdownRenderer(); + CpdTestUtils.CpdReportBuilder builder = new CpdTestUtils.CpdReportBuilder(); + + FileId foo = CpdTestUtils.FOO_FILE_ID; + FileId bar = CpdTestUtils.BAR_FILE_ID; + + int lineCount1 = 6; + Mark mark1 = builder.createMark("public", foo, 48, lineCount1); + Mark mark2 = builder.createMark("void", foo, 73, lineCount1); + builder.addMatch(new Match(75, mark1, mark2)); + + int lineCount2 = 5; + Mark mark3 = builder.createMark("void", bar, 49, lineCount2); + Mark mark4 = builder.createMark("stuff", bar, 74, lineCount2); + builder.addMatch(new Match(50, mark3, mark4)); + + StringWriter sw = new StringWriter(); + renderer.render(builder.build(), sw); + String report = sw.toString(); + String expectedReport = "Found a 6 line (75 tokens) duplication in the following files:\n" + + "Starting at line 48 of /var/Foo.java\n" + + "Starting at line 73 of /var/Foo.java\n" + + "```\n" + + "47_47_47_47_47_47_47_47_47_47_\n" + + "48_48_48_48_48_48_48_48_48_48_\n" + + "49_49_49_49_49_49_49_49_49_49_\n" + + "50_50_50_50_50_50_50_50_50_50_\n" + + "51_51_51_51_51_51_51_51_51_51_\n" + + "52_52_52_52_52_52_52_52_52_52_\n" + + "```\n" + + "\n" + + "---\n" + + "\n" + + "Found a 5 line (50 tokens) duplication in the following files:\n" + + "Starting at line 49 of /var/Bar.java\n" + + "Starting at line 74 of /var/Bar.java\n" + + "```\n" + + "48_48_48_48_48_48_48_48_48_48_\n" + + "49_49_49_49_49_49_49_49_49_49_\n" + + "50_50_50_50_50_50_50_50_50_50_\n" + + "51_51_51_51_51_51_51_51_51_51_\n" + + "52_52_52_52_52_52_52_52_52_52_\n" + + "```\n"; + + assertEquals(expectedReport, report); + } + +} From 407bbeccde6c9fda014ddde52d0b76ff3476ff1d Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Sun, 24 Aug 2025 21:59:58 +0200 Subject: [PATCH 1293/1962] Fix typos/grammar in userdocs/cpd --- docs/pages/pmd/userdocs/cpd/cpd.md | 2 +- docs/pages/pmd/userdocs/cpd/cpd_report_formats.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/pages/pmd/userdocs/cpd/cpd.md b/docs/pages/pmd/userdocs/cpd/cpd.md index 5b2a6da6dc8..d773811e94f 100644 --- a/docs/pages/pmd/userdocs/cpd/cpd.md +++ b/docs/pages/pmd/userdocs/cpd/cpd.md @@ -42,7 +42,7 @@ refactored out. We thus advise developers to use CPD to **help remove duplicates ### Refactoring duplicates -Once you have located some duplicates, several refactoring strategies may apply depending of the scope and extent of +Once you have located some duplicates, several refactoring strategies may apply depending on the scope and extent of the duplication. Here's a quick summary: * If the duplication is local to a method or single class: diff --git a/docs/pages/pmd/userdocs/cpd/cpd_report_formats.md b/docs/pages/pmd/userdocs/cpd/cpd_report_formats.md index cc366a59a17..c13f80c6c14 100644 --- a/docs/pages/pmd/userdocs/cpd/cpd_report_formats.md +++ b/docs/pages/pmd/userdocs/cpd/cpd_report_formats.md @@ -209,7 +209,7 @@ Example: ## csv This outputs the duplication as comma separated values. It only reports the duplication size (number -of lines and tokens) and the number of occurrences. After that, the begin lines and filenames are reported on +of lines and tokens) and the number of occurrences. After that, the starting lines and filenames are reported on after another. Example: @@ -228,7 +228,7 @@ for each occurrence separately. While the tokens are the same, due to formatting different. Whitespace and comments are usually ignored when finding duplicated code. In each line, the duplication size in tokens is reported, then the number of occurrences. And after that, for each -file, the begin line, the number of duplicated lines and the filename. +file, the starting line, the number of duplicated lines and the filename. Example: @@ -242,7 +242,7 @@ eTest.java ## vs -This outputs the duplication in a format, that Visual Studio. CPD can be added as a external tool and the output +This outputs the duplication in a format, that Visual Studio understands. CPD can be added as an external tool and the output is shown in the console. You can then click on the filenames to jump to the source where the duplication is located. Each occurrence of a duplication is reported in a separate line, that's why in this example, we have 5 lines. @@ -275,7 +275,7 @@ xalan -in cpd-report-sample.xml -xsl cpdhtml.xslt -out cpd-report-sample-cpdhtml [Example](report-examples/cpdhtml.html) -This stylesheet by default only consideres duplications longer than 30 lines. You can change the default value with +This stylesheet by default only considers duplications longer than 30 lines. You can change the default value with the param `lines`: ```shell From f22c15a23c3e509b794445d0186b262e36430fc6 Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Mon, 25 Aug 2025 21:17:08 +0200 Subject: [PATCH 1294/1962] #5849: [doc] Add documentation for MarkdownRenderer --- docs/pages/pmd/userdocs/cpd/cpd.md | 3 +- .../pmd/userdocs/cpd/cpd_report_formats.md | 75 ++++++++++++++++++- .../pmd/cpd/CPDReportRenderer.java | 1 + 3 files changed, 77 insertions(+), 2 deletions(-) diff --git a/docs/pages/pmd/userdocs/cpd/cpd.md b/docs/pages/pmd/userdocs/cpd/cpd.md index d773811e94f..71b82709236 100644 --- a/docs/pages/pmd/userdocs/cpd/cpd.md +++ b/docs/pages/pmd/userdocs/cpd/cpd.md @@ -4,7 +4,7 @@ tags: [cpd, userdocs] summary: "Learn how to use CPD, the copy-paste detector shipped with PMD." permalink: pmd_userdocs_cpd.html author: Tom Copeland -last_updated: July 2025 (7.16.0) +last_updated: August 2025 (7.17.0) --- ## Overview @@ -279,6 +279,7 @@ See [CPD Capable Languages](tag_CpdCapableLanguage.html) for the full list of su * csv * csv_with_linecount_per_file * vs +* markdown For details, see [CPD Report Formats](pmd_userdocs_cpd_report_formats.html). diff --git a/docs/pages/pmd/userdocs/cpd/cpd_report_formats.md b/docs/pages/pmd/userdocs/cpd/cpd_report_formats.md index c13f80c6c14..1bfe2c034d0 100644 --- a/docs/pages/pmd/userdocs/cpd/cpd_report_formats.md +++ b/docs/pages/pmd/userdocs/cpd/cpd_report_formats.md @@ -5,7 +5,7 @@ keywords: [formats, renderers] summary: "Overview of the built-in report formats for CPD" permalink: pmd_userdocs_cpd_report_formats.html author: Andreas Dangel -last_updated: June 2024 (7.3.0) +last_updated: August 2025 (7.17.0) --- ## Overview @@ -294,3 +294,76 @@ xalan -in pmd-core-cpd-report.xml -xsl etc/xslt/cpdhtml-v2.xslt -out pmd-core-cp It requires javascript enabled and uses [Bootstrap](https://getbootstrap.com/), [jQuery](https://jquery.com/), and [DataTables](https://datatables.net/). + +## markdown + +This report format outputs all duplications one after another in Markdown. Each duplication contains the complete code snippet as a code block. +Duplications are separated by a horizontal line (`---` in Markdown). + +Example: + +````markdown +Found a 33 line (239 tokens) duplication in the following files: +Starting at line 32 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java +Starting at line 68 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java +``` +public void testOverride() { + final StringProperty PROPERTY1_DESCRIPTOR = new StringProperty("property1", "Test property", null, 0f); + MockRule rule = new MockRule(); + rule.definePropertyDescriptor(PROPERTY1_DESCRIPTOR); + rule.setLanguage(LanguageRegistry.getLanguage(Dummy2LanguageModule.NAME)); + rule.setName("name1"); + rule.setProperty(PROPERTY1_DESCRIPTOR, "value1"); + rule.setMessage("message1"); + rule.setDescription("description1"); + rule.addExample("example1"); + rule.setExternalInfoUrl("externalInfoUrl1"); + rule.setPriority(RulePriority.HIGH); + + final StringProperty PROPERTY2_DESCRIPTOR = new StringProperty("property2", "Test property", null, 0f); + RuleReference ruleReference = new RuleReference(); + ruleReference.setRule(rule); + ruleReference.definePropertyDescriptor(PROPERTY2_DESCRIPTOR); + ruleReference.setLanguage(LanguageRegistry.getLanguage(DummyLanguageModule.NAME)); + ruleReference + .setMinimumLanguageVersion(LanguageRegistry.getLanguage(DummyLanguageModule.NAME).getVersion("1.3")); + ruleReference + .setMaximumLanguageVersion(LanguageRegistry.getLanguage(DummyLanguageModule.NAME).getVersion("1.7")); + ruleReference.setDeprecated(true); + ruleReference.setName("name2"); + ruleReference.setProperty(PROPERTY1_DESCRIPTOR, "value2"); + ruleReference.setProperty(PROPERTY2_DESCRIPTOR, "value3"); + ruleReference.setMessage("message2"); + ruleReference.setDescription("description2"); + ruleReference.addExample("example2"); + ruleReference.setExternalInfoUrl("externalInfoUrl2"); + ruleReference.setPriority(RulePriority.MEDIUM_HIGH); + + validateOverriddenValues(PROPERTY1_DESCRIPTOR, PROPERTY2_DESCRIPTOR, ruleReference); +``` + +--- + +Found a 16 line (110 tokens) duplication in the following files: +Starting at line 66 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java +Starting at line 88 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java +Starting at line 110 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java +``` +JaxenXPathRuleQuery query = createQuery(xpath); +List ruleChainVisits = query.getRuleChainVisits(); +Assert.assertEquals(2, ruleChainVisits.size()); +Assert.assertTrue(ruleChainVisits.contains("dummyNode")); +// Note: Having AST_ROOT in the rule chain visits is probably a mistake. But it doesn't hurt, it shouldn't +// match a real node name. +Assert.assertTrue(ruleChainVisits.contains(JaxenXPathRuleQuery.AST_ROOT)); + +DummyNodeWithListAndEnum dummy = new DummyNodeWithListAndEnum(1); +RuleContext data = new RuleContext(); +data.setLanguageVersion(LanguageRegistry.findLanguageByTerseName("dummy").getDefaultVersion()); + +query.evaluate(dummy, data); +// note: the actual xpath queries are only available after evaluating +Assert.assertEquals(2, query.nodeNameToXPaths.size()); +Assert.assertEquals("self::node()[(attribute::Test1 = \"false\")][(attribute::Test2 = \"true\")]", query.nodeNameToXPaths.get("dummyNode").get(0).toString()); +``` +```` diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDReportRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDReportRenderer.java index c6a10bea543..c690915a771 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDReportRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDReportRenderer.java @@ -15,6 +15,7 @@ * @see XMLRenderer * @see SimpleRenderer * @see VSRenderer + * @see MarkdownRenderer */ public interface CPDReportRenderer { From 19c2465785b23600ddc3657613172dbfd07df96d Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Mon, 25 Aug 2025 21:21:20 +0200 Subject: [PATCH 1295/1962] #5849: Add newline before starting code block --- docs/pages/pmd/userdocs/cpd/cpd_report_formats.md | 2 ++ .../src/main/java/net/sourceforge/pmd/cpd/MarkdownRenderer.java | 2 +- .../test/java/net/sourceforge/pmd/cpd/MarkdownRendererTest.java | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/pages/pmd/userdocs/cpd/cpd_report_formats.md b/docs/pages/pmd/userdocs/cpd/cpd_report_formats.md index 1bfe2c034d0..b5a52050a8b 100644 --- a/docs/pages/pmd/userdocs/cpd/cpd_report_formats.md +++ b/docs/pages/pmd/userdocs/cpd/cpd_report_formats.md @@ -306,6 +306,7 @@ Example: Found a 33 line (239 tokens) duplication in the following files: Starting at line 32 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java Starting at line 68 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java + ``` public void testOverride() { final StringProperty PROPERTY1_DESCRIPTOR = new StringProperty("property1", "Test property", null, 0f); @@ -348,6 +349,7 @@ Found a 16 line (110 tokens) duplication in the following files: Starting at line 66 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java Starting at line 88 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java Starting at line 110 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java + ``` JaxenXPathRuleQuery query = createQuery(xpath); List ruleChainVisits = query.getRuleChainVisits(); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MarkdownRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MarkdownRenderer.java index 1387fd2fa42..f3b1fac7163 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MarkdownRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MarkdownRenderer.java @@ -17,7 +17,7 @@ public class MarkdownRenderer implements CPDReportRenderer { private static final String SEPARATOR = "\n---\n\n"; private static final String FOUND_DUPLICATION_TEMPLATE = "Found a %d line (%d tokens) duplication in the following files:\n"; private static final String STARTING_AT_LINE_TEMPLATE = "Starting at line %d of %s\n"; - private static final String CODE_BLOCK_TEMPLATE = "```\n%s```\n"; + private static final String CODE_BLOCK_TEMPLATE = "\n```\n%s```\n"; @Override public void render(CPDReport report, Writer writer) throws IOException { diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownRendererTest.java index c67cd2832dd..71824739915 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownRendererTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownRendererTest.java @@ -39,6 +39,7 @@ void testMultipleDuplicates() throws IOException { String expectedReport = "Found a 6 line (75 tokens) duplication in the following files:\n" + "Starting at line 48 of /var/Foo.java\n" + "Starting at line 73 of /var/Foo.java\n" + + "\n" + "```\n" + "47_47_47_47_47_47_47_47_47_47_\n" + "48_48_48_48_48_48_48_48_48_48_\n" @@ -53,6 +54,7 @@ void testMultipleDuplicates() throws IOException { + "Found a 5 line (50 tokens) duplication in the following files:\n" + "Starting at line 49 of /var/Bar.java\n" + "Starting at line 74 of /var/Bar.java\n" + + "\n" + "```\n" + "48_48_48_48_48_48_48_48_48_48_\n" + "49_49_49_49_49_49_49_49_49_49_\n" From da6581eca3954d8cc4f9c5d4d40562a974264fe0 Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Mon, 25 Aug 2025 22:02:39 +0200 Subject: [PATCH 1296/1962] #5849: Make MarkdownRendererTest OS-independent --- .../net/sourceforge/pmd/cpd/MarkdownRendererTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownRendererTest.java index 71824739915..7fee8a0d565 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownRendererTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownRendererTest.java @@ -37,8 +37,8 @@ void testMultipleDuplicates() throws IOException { renderer.render(builder.build(), sw); String report = sw.toString(); String expectedReport = "Found a 6 line (75 tokens) duplication in the following files:\n" - + "Starting at line 48 of /var/Foo.java\n" - + "Starting at line 73 of /var/Foo.java\n" + + "Starting at line 48 of " + foo.getAbsolutePath() + "\n" + + "Starting at line 73 of " + foo.getAbsolutePath() + "\n" + "\n" + "```\n" + "47_47_47_47_47_47_47_47_47_47_\n" @@ -52,8 +52,8 @@ void testMultipleDuplicates() throws IOException { + "---\n" + "\n" + "Found a 5 line (50 tokens) duplication in the following files:\n" - + "Starting at line 49 of /var/Bar.java\n" - + "Starting at line 74 of /var/Bar.java\n" + + "Starting at line 49 of " + bar.getAbsolutePath() + "\n" + + "Starting at line 74 of " + bar.getAbsolutePath() + "\n" + "\n" + "```\n" + "48_48_48_48_48_48_48_48_48_48_\n" From a94f2d2b9709ceee6af65c7af5bddcd90f1e3912 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Tue, 26 Aug 2025 07:06:21 +0200 Subject: [PATCH 1297/1962] [java] More detailed message for AvoidInstanceofChecksInCatchClause --- .../resources/category/java/errorprone.xml | 3 ++- .../AvoidInstanceofChecksInCatchClause.xml | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 84044d626ab..9f53418befd 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -454,7 +454,7 @@ public interface Operation { @@ -468,6 +468,7 @@ Each caught exception type should be handled in its own catch clause. //CatchParameter /following-sibling::Block//InfixExpression[@Operator = 'instanceof'] /VariableAccess[@Name = ./ancestor::Block/preceding-sibling::CatchParameter/@Name] + /following-sibling::TypeExpression/* ]]> diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AvoidInstanceofChecksInCatchClause.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AvoidInstanceofChecksInCatchClause.xml index b3ee85db096..cc801e546e8 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AvoidInstanceofChecksInCatchClause.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AvoidInstanceofChecksInCatchClause.xml @@ -32,6 +32,25 @@ public class Foo { } catch (Exception e) { } } +} + ]]> + + + Distinct error messages for the same line + 2 + + An instanceof check is being performed on the caught exception. Create a separate catch clause for NullPointerException. + An instanceof check is being performed on the caught exception. Create a separate catch clause for IndexOutOfBoundsException. + + From 2bea133e07e8bb1bd440695910b3baa68907acc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Tue, 26 Aug 2025 14:56:54 +0200 Subject: [PATCH 1298/1962] Add tests from Findbugs Add support for Hashtable.contains() and ConcurrentHashMap.contains() --- .../rule/errorprone/ThatCantBeInHereRule.java | 8 +- .../rule/errorprone/xml/ThatCantBeInHere.xml | 235 ++++++++++++++++++ 2 files changed, 241 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ThatCantBeInHereRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ThatCantBeInHereRule.java index bb1c147c56f..113cc4001e4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ThatCantBeInHereRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ThatCantBeInHereRule.java @@ -49,7 +49,9 @@ public class ThatCantBeInHereRule extends AbstractJavaRulechainRule { // Map methods that take value parameters private static final InvocationMatcher MAP_CONTAINS_VALUE = InvocationMatcher.parse("java.util.Map#containsValue(java.lang.Object)"); - + private static final InvocationMatcher HASHTABLE_CONTAINS = InvocationMatcher.parse("java.util.Hashtable#contains(java.lang.Object)"); + private static final InvocationMatcher CONCURRENT_HASHMAP_CONTAINS = InvocationMatcher.parse("java.util.concurrent.ConcurrentHashMap#contains(java.lang.Object)"); + // Map methods that take key-value parameters private static final InvocationMatcher MAP_REMOVE_TWO_PARAM = InvocationMatcher.parse("java.util.Map#remove(java.lang.Object,java.lang.Object)"); @@ -80,7 +82,9 @@ public Object visit(ASTMethodCall node, Object data) { || MAP_REMOVE_ONE_PARAM.matchesCall(node) ) { checkMapKeyCompatibility(node, ctx); - } else if (MAP_CONTAINS_VALUE.matchesCall(node)) { + } else if (MAP_CONTAINS_VALUE.matchesCall(node) + || HASHTABLE_CONTAINS.matchesCall(node) + || CONCURRENT_HASHMAP_CONTAINS.matchesCall(node)) { checkMapValueCompatibility(node, ctx); } else if (MAP_REMOVE_TWO_PARAM.matchesCall(node)) { checkMapKeyValueCompatibility(node, ctx); diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ThatCantBeInHere.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ThatCantBeInHere.xml index 77436226b43..2818d752576 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ThatCantBeInHere.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ThatCantBeInHere.xml @@ -851,6 +851,241 @@ public class Test { void test(Map map, Map.Entry entry) { map.get(entry.getKey()); } +} + ]]> + + + + Findbugs test Ideas_2011_07_03 + 1 + 21 + s1, TreeSet s2) { +// return s1.equals(s2); +// } + +// public boolean test(HashSet s1, ArrayList s2) { +// return s1.equals(s2); +// } + +// public boolean test(HashSet s1, HashSet s2) { +// return s1.equals(s2); +// } + + public boolean test2(HashSet s1, HashSet s2) { + return s1.removeAll(s2); + } +} + ]]> + + + + Findbugs test Ideas_2011_07_24 + 2 + 21,21 + s, LinkedList lst) { +// return s.equals(lst); +// } + + static boolean test2(HashSet s, LinkedList lst) { + return s.containsAll(lst) && lst.containsAll(s); + } + +// static boolean test3(HashSet s, LinkedList lst) { +// return s.equals(lst); +// } + + static boolean test4(HashSet s, LinkedList lst) { + return s.containsAll(lst) && lst.containsAll(s); + } +} + ]]> + + + + Findbugs test Ideas_2011_10_21 + 7 + 17,25,33,41,45,49,57 + hashtable = new Hashtable(); + + ConcurrentHashMap concurrentHashMap = new ConcurrentHashMap(); + + public boolean testContainsHashtable(Integer i) { + return hashtable.contains(i); + } + + public boolean testContainsHashtable(String s) { + return hashtable.contains(s); + } + + public boolean testContainsConcurrentHashMap(Integer i) { + return concurrentHashMap.contains(i); + } + + public boolean testContainsConcurrentHashMap(String s) { + return concurrentHashMap.contains(s); + } + + public boolean testContainsValueHashtable(Integer i) { + return hashtable.containsValue(i); + } + + public boolean testContainsValueHashtable(String s) { + return hashtable.containsValue(s); + } + + public boolean testContainsValueConcurrentHashMap(Integer i) { + return concurrentHashMap.containsValue(i); + } + + public boolean testContainsValueConcurrentHashMap(String s) { + return concurrentHashMap.containsValue(s); + } + + public boolean testRemove(String s) { + return concurrentHashMap.remove(s, s); + } + + public boolean testRemove(Integer i) { + return concurrentHashMap.remove(i, i); + } + + public boolean testRemove(String s, Integer i) { + return concurrentHashMap.remove(s, i); + } + + public boolean testRemove(Integer i, String s) { + return concurrentHashMap.remove(i, s); + } +} + ]]> + + + + Findbugs test Ideas_2012_11_19 + 2 + 27,31 + extends ArrayList { + private static final long serialVersionUID = 1L; + } + + static class B extends ArrayList { + private static final long serialVersionUID = 1L; + } + + static A foo = new A(); + + static B bar = new B(); + + public static void OK(String args[]) { + foo.add(13L); + System.out.println(foo.contains(13L)); + bar.add(13L); + System.out.println(bar.contains(13L)); + } + + public static void bad1(String args[]) { + System.out.println(foo.contains("13")); + } + + public static void bad2(String args[]) { + System.out.println(bar.contains("13")); + } +} + ]]> + + + + Findbugs test Bug3470297 + 0 + void foo(A a, Foo foo) { + + Set empty = Collections.emptySet(); + foo.remove(a, empty); // This generated a false positive because it + // thinks that the second parameter should be of + // type B, not Set + } + + static class Foo extends Bar> { + + } + + static class Bar extends ConcurrentHashMap { + @Override + public boolean remove(Object key, Object value) { + return false; + } + } +} + ]]> + + + + Findbugs test Bug3470297a + 0 + foo = new Foo(); + foo.remove("", Collections.emptySet()); + } + + static class Foo extends Bar> { + } + + static class Bar extends ConcurrentHashMap { + @Override + public boolean remove(final Object key, final Object value) { + // ... + return super.remove(key, value); + } + } + } ]]> From f6fddb317be311656480d867200aa8042cb03c35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Tue, 26 Aug 2025 15:09:13 +0200 Subject: [PATCH 1299/1962] Rename new rule, update description --- ...e.java => CollectionTypeMismatchRule.java} | 4 +- .../resources/category/java/errorprone.xml | 65 ++++++++++--------- ...t.java => CollectionTypeMismatchTest.java} | 2 +- ...eInHere.xml => CollectionTypeMismatch.xml} | 0 4 files changed, 37 insertions(+), 34 deletions(-) rename pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/{ThatCantBeInHereRule.java => CollectionTypeMismatchRule.java} (99%) rename pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/{ThatCantBeInHereTest.java => CollectionTypeMismatchTest.java} (80%) rename pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/{ThatCantBeInHere.xml => CollectionTypeMismatch.xml} (100%) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ThatCantBeInHereRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CollectionTypeMismatchRule.java similarity index 99% rename from pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ThatCantBeInHereRule.java rename to pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CollectionTypeMismatchRule.java index 113cc4001e4..6771eede241 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ThatCantBeInHereRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CollectionTypeMismatchRule.java @@ -26,7 +26,7 @@ * - List<Integer> list; list.remove("string"); // String cannot be in Integer list * - Map<String, Integer> map; map.get(42); // Integer key cannot be in String-keyed map */ -public class ThatCantBeInHereRule extends AbstractJavaRulechainRule { +public class CollectionTypeMismatchRule extends AbstractJavaRulechainRule { // Collection methods that take a single Object parameter private static final InvocationMatcher COLLECTION_CONTAINS = InvocationMatcher.parse("java.util.Collection#contains(java.lang.Object)"); @@ -55,7 +55,7 @@ public class ThatCantBeInHereRule extends AbstractJavaRulechainRule { // Map methods that take key-value parameters private static final InvocationMatcher MAP_REMOVE_TWO_PARAM = InvocationMatcher.parse("java.util.Map#remove(java.lang.Object,java.lang.Object)"); - public ThatCantBeInHereRule() { + public CollectionTypeMismatchRule() { super(ASTMethodCall.class); } diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 76437a95906..86174eef101 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -1029,6 +1029,40 @@ public class Bar { + + +Detects method calls on collections where the passed object cannot possibly be in the collection +due to type mismatch. This helps catch potential programming errors where incompatible types +are used with collection methods like contains(), remove(), indexOf(), etc. + +Methods checked include: +- Collection: contains(), remove(), removeAll(), retainAll(), containsAll() +- List: indexOf(), lastIndexOf() +- Map: containsKey(), containsValue(), get(), getOrDefault(), remove() +- Deque: removeFirstOccurrence(), removeLastOccurrence() +- Hashtable: contains() (legacy method that checks values) +- ConcurrentHashMap: contains() (legacy method that checks values) + + 3 + + numbers = Arrays.asList(1, 2, 3); +numbers.remove("string"); // violation: String cannot be in Integer list + +Map map = new HashMap<>(); +map.get(42); // violation: Integer key cannot be in String-keyed map + +Set names = new HashSet<>(); +names.contains(123); // violation: Integer cannot be in String set +]]> + + + - - -Detects method calls on collections where the passed object cannot possibly be in the collection -due to type mismatch. This helps catch potential programming errors where incompatible types -are used with collection methods like contains(), remove(), indexOf(), etc. - -Methods checked include: -- Collection: contains(), remove() -- List: indexOf(), lastIndexOf() -- Map: containsKey(), containsValue(), get(), remove() -- Deque: removeFirstOccurrence(), removeLastOccurrence() - - 3 - - numbers = Arrays.asList(1, 2, 3); -numbers.remove("string"); // violation: String cannot be in Integer list - -Map map = new HashMap<>(); -map.get(42); // violation: Integer key cannot be in String-keyed map - -Set names = new HashSet<>(); -names.contains(123); // violation: Integer cannot be in String set -]]> - - Date: Wed, 27 Aug 2025 16:14:09 +0200 Subject: [PATCH 1300/1962] check if there are enough characters in the Chars object before accessing them. --- .../sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java | 4 +++- .../net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java index 0d4da1420ce..9b0808a15bf 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java @@ -26,6 +26,7 @@ import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.ast.NodeStream; import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken; +import net.sourceforge.pmd.lang.document.Chars; import net.sourceforge.pmd.lang.java.ast.ASTArgumentList; import net.sourceforge.pmd.lang.java.ast.ASTArrayAllocation; import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr.ASTNamedReferenceExpr; @@ -798,7 +799,8 @@ public static boolean isComment(JavaccToken t) { } public static boolean isMarkdownComment(JavaccToken token) { - return token.kind == JavaTokenKinds.SINGLE_LINE_COMMENT && token.getText().charAt(2) == '/'; + Chars text = token.getText(); + return token.kind == JavaTokenKinds.SINGLE_LINE_COMMENT && text.length() > 2 && text.charAt(2) == '/'; } /** diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java index 2b77b3d52f6..04c50c0051c 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java @@ -367,4 +367,9 @@ void testGitHubBug1780() { void testGithubBug4947() { java15.parseResource("testdata/Issue4947TextBlock.java"); } + + @Test + void testGithubBug6014() { + java.parse("//"); + } } From 9ed83f1c5295a188f6dc813a5a63c1ff04ab615c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Wed, 27 Aug 2025 17:33:38 +0200 Subject: [PATCH 1301/1962] [doc] Update release notes (#6014, #6016) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 843697c2faa..d3485cfcc5b 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -75,6 +75,7 @@ This is a {{ site.pmd.release_type }} release. * java * [#5874](https://github.com/pmd/pmd/issues/5874): \[java] Update java regression tests with Java 25 language features * [#5960](https://github.com/pmd/pmd/issues/5960): \[java] Avoid/reduce duplicate error messages for some rules + * [#6014](https://github.com/pmd/pmd/issues/6014): \[java] Crash when encountering a java comment at the end of a file * java-bestpractices * [#2186](https://github.com/pmd/pmd/issues/2186): \[java] New rule: Reliance on default charset * [#4500](https://github.com/pmd/pmd/issues/4500): \[java] AvoidReassigningLoopVariables - false negatives within for-loops and skip allowed @@ -129,6 +130,7 @@ This is a {{ site.pmd.release_type }} release. * [#5980](https://github.com/pmd/pmd/pull/5980): chore: Fix typos - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#5981](https://github.com/pmd/pmd/pull/5981): Fix #4911: \[java] AvoidRethrowingException consider supertypes in following catches - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5989](https://github.com/pmd/pmd/pull/5989): \[java] Improve performance of RelianceOnDefaultCharset - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6016](https://github.com/pmd/pmd/pull/6016): Fix #6014: \[java] Crash when encountering a java comment at the end of a file - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) ### ๐Ÿ“ฆ Dependency updates From 25cdec5386ebdb771a4377ffa6f467dd6935d493 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Tue, 26 Aug 2025 20:38:20 +0200 Subject: [PATCH 1302/1962] [pmd-java]Refactor subclasses of AbstractJavaCounterCheckRule to include count in the message. --- .../rule/design/ExcessiveImportsRule.java | 10 ++++++++- .../design/ExcessiveParameterListRule.java | 15 ++++++++++++- .../rule/design/ExcessivePublicCountRule.java | 22 ++++++++++++------- .../AbstractJavaCounterCheckRule.java | 14 ++++++++++-- .../main/resources/category/java/design.xml | 6 ++--- .../java/rule/design/xml/ExcessiveImports.xml | 16 ++++++++++++++ .../design/xml/ExcessiveParameterList.xml | 14 ++++++++++++ .../rule/design/xml/ExcessivePublicCount.xml | 10 +++++++++ 8 files changed, 92 insertions(+), 15 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsRule.java index cf54cbf7d8a..a7e74747e63 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsRule.java @@ -28,8 +28,16 @@ protected int defaultReportLevel() { return 30; } + /** + * @deprecated since 7.17.0 + */ @Override protected boolean isViolation(ASTCompilationUnit node, int reportLevel) { - return node.children(ASTImportDeclaration.class).count() >= reportLevel; + return false; + } + + @Override + protected int getMetric(ASTCompilationUnit node) { + return node.children(ASTImportDeclaration.class).count(); } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java index 5cc44f8890d..6db232d18fe 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java @@ -37,8 +37,21 @@ private boolean areParametersOfPrivateConstructor(ASTFormalParameters params) { && ((ASTConstructorDeclaration) parent).getVisibility() == Visibility.V_PRIVATE; } + /** + * @deprecated since 7.17.0 + */ @Override protected boolean isViolation(ASTFormalParameters node, int reportLevel) { - return node.size() > reportLevel; + return false; + } + + @Override + protected int getMetric(ASTFormalParameters node) { + return node.size(); + } + + @Override + protected boolean checkViolation(int metric, int threshold) { + return metric > threshold; } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java index 4f820a6b8a0..961e7c69e0e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java @@ -39,15 +39,21 @@ protected int defaultReportLevel() { return 45; } + /** + * @deprecated since 7.17.0 + */ @Override protected boolean isViolation(ASTTypeDeclaration node, int reportLevel) { - long publicCount = node.getDeclarations() - .filterIs(ModifierOwner.class) - .filter(it -> it.hasModifiers(PUBLIC)) - // filter out constants - .filter(it -> !(it instanceof ASTFieldDeclaration && it.hasModifiers(STATIC, FINAL))) - .count(); - - return publicCount >= reportLevel; + return false; + } + + @Override + protected int getMetric(ASTTypeDeclaration node) { + return node.getDeclarations() + .filterIs(ModifierOwner.class) + .filter(it -> it.hasModifiers(PUBLIC)) + // filter out constants + .filter(it -> !(it instanceof ASTFieldDeclaration && it.hasModifiers(STATIC, FINAL))) + .count(); } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java index f7491b00894..881ec5b145f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java @@ -42,8 +42,17 @@ protected boolean isIgnored(T node) { return false; } + + /** + * @deprecated since 7.17.0 + */ protected abstract boolean isViolation(T node, int reportLevel); + protected abstract int getMetric(T node); + + protected boolean checkViolation(int metric, int threshold) { + return metric >= threshold; + } @Override public Object visitJavaNode(JavaNode node, Object data) { @@ -52,8 +61,9 @@ public Object visitJavaNode(JavaNode node, Object data) { // since we only visit this node, it's ok if (!isIgnored(t)) { - if (isViolation(t, getProperty(reportLevel))) { - asCtx(data).addViolation(node); + int metric = getMetric(t); + if (checkViolation(metric, getProperty(reportLevel))) { + asCtx(data).addViolation(node, metric); } } diff --git a/pmd-java/src/main/resources/category/java/design.xml b/pmd-java/src/main/resources/category/java/design.xml index b7d74332da8..5480335b563 100644 --- a/pmd-java/src/main/resources/category/java/design.xml +++ b/pmd-java/src/main/resources/category/java/design.xml @@ -623,7 +623,7 @@ public void bar() { @@ -647,7 +647,7 @@ public class Foo { @@ -675,7 +675,7 @@ public void addPerson( // preferred approach diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ExcessiveImports.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ExcessiveImports.xml index 2c523b75cb7..543a36c176a 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ExcessiveImports.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ExcessiveImports.xml @@ -23,6 +23,22 @@ public class Foo{} 0 + + + + Verify message includes import count + 3 + 1 + + A high number of imports (4) can indicate a high degree of coupling within an object. + + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ExcessiveParameterList.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ExcessiveParameterList.xml index 5b081f50a63..fb5a7366d05 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ExcessiveParameterList.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ExcessiveParameterList.xml @@ -50,6 +50,20 @@ public class Foo { String[] arr, int data, long in, float fl, String res) {} // 11 params }; } +} + ]]> + + + + Verify message includes parameter count + 9 + 1 + + Avoid long parameter lists (10 parameters). + + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ExcessivePublicCount.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ExcessivePublicCount.xml index d1cd400527a..f83a2da2aa3 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ExcessivePublicCount.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ExcessivePublicCount.xml @@ -91,4 +91,14 @@ public class Foo { } ]]> + + + Verify message includes actual count + 2 + 1 + + This class has 3 public methods and attributes + + + From 57587983d6cf234ecaaf248b74505244b7bcf8ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Wed, 27 Aug 2025 13:34:00 +0200 Subject: [PATCH 1303/1962] [pmd-apex]Add counts to the message of ExcessiveClassLengthRule and ExcessiveParameterListRule Also add test that verifies the message for NcssConstructorCount and NcssTypeCount --- .../src/main/resources/category/apex/design.xml | 4 ++-- .../apex/rule/design/xml/ExcessiveClassLength.xml | 10 ++++++++++ .../rule/design/xml/ExcessiveParameterList.xml | 15 +++++++++++++++ .../apex/rule/design/xml/NcssConstructorCount.xml | 10 ++++++++++ .../lang/apex/rule/design/xml/NcssTypeCount.xml | 10 ++++++++++ 5 files changed, 47 insertions(+), 2 deletions(-) diff --git a/pmd-apex/src/main/resources/category/apex/design.xml b/pmd-apex/src/main/resources/category/apex/design.xml index 839b0b06e30..2ebfa4d5f55 100644 --- a/pmd-apex/src/main/resources/category/apex/design.xml +++ b/pmd-apex/src/main/resources/category/apex/design.xml @@ -206,7 +206,7 @@ public class Foo { @@ -238,7 +238,7 @@ public class Foo { diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessiveClassLength.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessiveClassLength.xml index bd49bb9340a..b3c463c08d4 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessiveClassLength.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessiveClassLength.xml @@ -41,6 +41,16 @@ public class Foo { + + Verify message includes line count + 10 + 1 + + Avoid really long classes (13 lines). + + + + long class - changed minimum 2000 diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessiveParameterList.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessiveParameterList.xml index cdf89e01448..ef3aacbc6a0 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessiveParameterList.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessiveParameterList.xml @@ -28,6 +28,21 @@ public class Foo { ]]> + + Verify message includes parameter count + 9 + 1 + + Avoid long parameter lists (10 parameters). + + + + #1396 Public method with javadoc 0 diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssConstructorCount.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssConstructorCount.xml index 99871f72e8e..964221d60b5 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssConstructorCount.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssConstructorCount.xml @@ -73,6 +73,16 @@ public class Foo { + + Verify message includes NCSS count + 13 + 1 + + The constructor has an NCSS line count of 13 + + + + long method - changed minimum diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssTypeCount.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssTypeCount.xml index ae8ada19ca3..04eb93c0dd4 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssTypeCount.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssTypeCount.xml @@ -73,6 +73,16 @@ public class Foo { + + Verify message includes NCSS count + 13 + 1 + + The type has an NCSS line count of 14 + + + + long method - changed minimum From 27c4d23eb998a6b0a7e5d4c77b6ccfaef4e04e1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Fri, 29 Aug 2025 14:44:07 +0200 Subject: [PATCH 1304/1962] Readd implementation of isViolation. Even if it's deprecated, it should work as it did before --- .../pmd/lang/java/rule/design/ExcessiveImportsRule.java | 2 +- .../lang/java/rule/design/ExcessiveParameterListRule.java | 2 +- .../pmd/lang/java/rule/design/ExcessivePublicCountRule.java | 2 +- .../java/rule/internal/AbstractJavaCounterCheckRule.java | 5 ++++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsRule.java index a7e74747e63..ecd0c9df478 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsRule.java @@ -33,7 +33,7 @@ protected int defaultReportLevel() { */ @Override protected boolean isViolation(ASTCompilationUnit node, int reportLevel) { - return false; + return super.isViolation(node, reportLevel); } @Override diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java index 6db232d18fe..e0cbae7774d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java @@ -42,7 +42,7 @@ private boolean areParametersOfPrivateConstructor(ASTFormalParameters params) { */ @Override protected boolean isViolation(ASTFormalParameters node, int reportLevel) { - return false; + return super.isViolation(node, reportLevel); } @Override diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java index 961e7c69e0e..0a1b1bd5f0f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java @@ -44,7 +44,7 @@ protected int defaultReportLevel() { */ @Override protected boolean isViolation(ASTTypeDeclaration node, int reportLevel) { - return false; + return super.isViolation(node, reportLevel); } @Override diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java index 881ec5b145f..52d8f83876b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java @@ -46,7 +46,10 @@ protected boolean isIgnored(T node) { /** * @deprecated since 7.17.0 */ - protected abstract boolean isViolation(T node, int reportLevel); + protected boolean isViolation(T node, int reportLevel) { + int metric = getMetric(node); + return checkViolation(metric, reportLevel); + } protected abstract int getMetric(T node); From b6dea20e05c60f73e70110f2b71cb380426e1334 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Fri, 29 Aug 2025 16:21:14 +0200 Subject: [PATCH 1305/1962] Change ExcessiveParameterListRule to trigger on metric >= reportLevel (used to be metric > reportLevel) This change makes ExcessiveParameterListRule consistent with the other subclasses of AbstractJavaCounterCheckRule, so we don't need the checkViolation method. --- .../java/rule/design/ExcessiveParameterListRule.java | 5 ----- .../java/rule/internal/AbstractJavaCounterCheckRule.java | 9 +++------ 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java index e0cbae7774d..5c382bf072f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java @@ -49,9 +49,4 @@ protected boolean isViolation(ASTFormalParameters node, int reportLevel) { protected int getMetric(ASTFormalParameters node) { return node.size(); } - - @Override - protected boolean checkViolation(int metric, int threshold) { - return metric > threshold; - } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java index 52d8f83876b..da1485fc93f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java @@ -48,15 +48,11 @@ protected boolean isIgnored(T node) { */ protected boolean isViolation(T node, int reportLevel) { int metric = getMetric(node); - return checkViolation(metric, reportLevel); + return metric >= reportLevel; } protected abstract int getMetric(T node); - protected boolean checkViolation(int metric, int threshold) { - return metric >= threshold; - } - @Override public Object visitJavaNode(JavaNode node, Object data) { @SuppressWarnings("unchecked") @@ -65,7 +61,8 @@ public Object visitJavaNode(JavaNode node, Object data) { if (!isIgnored(t)) { int metric = getMetric(t); - if (checkViolation(metric, getProperty(reportLevel))) { + int threshold = getProperty(reportLevel); + if (metric >= threshold) { asCtx(data).addViolation(node, metric); } } From f80cc21b34624864eb80e653cf0d641ba5d0880c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Fri, 29 Aug 2025 21:47:56 +0200 Subject: [PATCH 1306/1962] DontUseFloatTypeForLoopIndices now checks the UpdateStatement as well --- .../resources/category/java/errorprone.xml | 5 ++++- .../xml/DontUseFloatTypeForLoopIndices.xml | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 84044d626ab..e403eeecbe4 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -1481,7 +1481,10 @@ performance need (space or time). diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/DontUseFloatTypeForLoopIndices.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/DontUseFloatTypeForLoopIndices.xml index 83efad48642..f05dac97687 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/DontUseFloatTypeForLoopIndices.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/DontUseFloatTypeForLoopIndices.xml @@ -34,6 +34,25 @@ public class Count { for (double indice = START; indice < START + 50; indice++) count++; } +} + ]]> + + + + float variable declared before loop - issue #5878 + 1 + 4 + 5.0f) + break; + } + System.out.println("Loop completed at level: " + i); + } } ]]> From 8ae856d03a6c0b0598fd11e0bcc926e50b95b742 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Sun, 31 Aug 2025 18:32:09 +0200 Subject: [PATCH 1307/1962] Check unnecessary casts in method calls --- .../rule/codestyle/UnnecessaryCastRule.java | 8 ++++++++ .../rule/codestyle/xml/UnnecessaryCast.xml | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java index bfa4e5e2e2b..7eb4dd6153a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java @@ -31,6 +31,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTExpression; import net.sourceforge.pmd.lang.java.ast.ASTInfixExpression; import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression; +import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; import net.sourceforge.pmd.lang.java.ast.ASTMethodReference; import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement; import net.sourceforge.pmd.lang.java.ast.BinaryOp; @@ -107,6 +108,13 @@ public Object visit(ASTCastExpression castExpr, Object data) { // the object will not implement SubItf anymore. } else if (isCastUnnecessary(castExpr, context, coercionType, operandType)) { reportCast(castExpr, data); + } else if (castExpr.getParent() instanceof ASTMethodCall + && !coercionType.isGeneric()) { + ASTMethodCall call = (ASTMethodCall) castExpr.getParent(); + if (!call.getMethodType().isGeneric() + && TypeTestUtil.isA(call.getMethodType().getDeclaringType(), operandType)) { + reportCast(castExpr, data); + } } return null; } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml index c2b53aa496e..3b94f182caf 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml @@ -184,6 +184,25 @@ public class MapCasts { } ]]> + + Self cast + 1 + + Context is array index 2 From 9224406d29a7e13f2295a11e30bdddea6f41d944 Mon Sep 17 00:00:00 2001 From: Vincent Potucek Date: Sun, 31 Aug 2025 11:32:19 +0200 Subject: [PATCH 1308/1962] ModifierOrder: Add tests, update release notes --- docs/pages/release_notes.md | 3 + .../rule/codestyle/ModifierOrderTest.java | 2 +- .../symbols/internal/JClassSymbolTest.java | 13 +- .../java/rule/codestyle/xml/ModifierOrder.xml | 158 ++++++++++++++++++ 4 files changed, 169 insertions(+), 7 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 843697c2faa..67692390b2e 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,6 +25,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy #### โœจ New Rules +* The new Java rule {% rule java/codestyle/ModifierOrder %} (`codestyle`) finds incorrectly ordered modifiers + (e.g., `static public` instead of `public static`). It ensures modifiers appear in the correct order as recommended by the Java Language Specification. * The new apex rule {% rule apex/codestyle/AnnotationsNamingConventions %} enforces that annotations are used consistently in PascalCase. The rule is referenced in the quickstart.xml ruleset for Apex. @@ -103,6 +105,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ Merged pull requests +* [#5856](https://github.com/pmd/pmd/pull/6019): Fix #6019: \[java] New Rule ModifierOrder - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5822](https://github.com/pmd/pmd/pull/5822): Fix #5650: \[apex] New Rule: AnnotationsNamingConventions - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) * [#5847](https://github.com/pmd/pmd/pull/5847): Fix #5770: \[java] New Rule: VariableCanBeInlined - [Vincent Potucek](https://github.com/Pankraz76) (@Pankraz76) * [#5856](https://github.com/pmd/pmd/pull/5856): Fix #5837: \[java] New Rule OverrideBothEqualsAndHashCodeOnComparable - [Vincent Potucek](https://github.com/Pankraz76) (@Pankraz76) diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ModifierOrderTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ModifierOrderTest.java index de82fcfdf83..6f67395036e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ModifierOrderTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/ModifierOrderTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/JClassSymbolTest.java b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/JClassSymbolTest.java index c7a71ab7cfd..e5dc9cf30a6 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/JClassSymbolTest.java +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/JClassSymbolTest.java @@ -4,6 +4,7 @@ package net.sourceforge.pmd.lang.java.symbols.internal; +import static java.lang.annotation.ElementType.TYPE_PARAMETER; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.empty; @@ -14,6 +15,7 @@ import java.lang.annotation.ElementType; import java.lang.annotation.RetentionPolicy; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; @@ -46,16 +48,15 @@ void testAnnotWithNoRetention(SymImplementation impl) { assertEquals(RetentionPolicy.CLASS, sym.getAnnotationRetention()); } - @EnumSource @ParameterizedTest + @Disabled("tmp") void testAnnotWithNoTarget(SymImplementation impl) { - JClassSymbol sym = impl.getSymbol(AnnotationWithNoRetention.class); - for (ElementType type : ElementType.values()) { - assertEquals(type != ElementType.TYPE_PARAMETER - && type != ElementType.TYPE_USE, sym.annotationAppliesTo(type), - "annot supports " + type); + assertEquals( + TYPE_PARAMETER != type, + impl.getSymbol(AnnotationWithNoRetention.class).annotationAppliesTo(type), + "annot supports " + type); } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ModifierOrder.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ModifierOrder.xml index a81a44f50ea..089e6ee551b 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ModifierOrder.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ModifierOrder.xml @@ -110,5 +110,163 @@ abstract public class Foo { // warn l1 + + Interface with missorted modifiers + 2 + 3,4 + + Missorted modifiers `abstract public`. + Missorted modifiers `abstract public`. + + + + + + Method with multiple missorted modifiers + 1 + 2 + + Missorted modifiers `synchronized static`. + + + + + + Field declarations with various modifiers + 3 + 2,4,7 + + Missorted modifiers `transient static`. + Missorted modifiers `volatile public`. + Missorted modifiers `static public`. + + + + + + Constructor with missorted modifiers + 2 + 3,5 + + Missorted modifiers `strictfp public`. + Missorted modifiers `final protected`. + + + + + + Local variable with type annotations (property=anywhere) + anywhere + 2 + 3,5 + + Missorted modifiers `final @TypeA`. Type annotations should be placed before the type they + qualify. + + Missorted modifiers `@TypeA final`. Type annotations should be placed before the type they + qualify. + + + + + + + No violations on correctly sorted modifiers + 1 + 5 + + Missorted modifiers `synchronized static`. + + + + + + Record with missorted modifiers + 1 + 1 + + Missorted modifiers `final public`. + + + + + + Enum with missorted modifiers + 2 + 3,4 + + Missorted modifiers `final static`. + Missorted modifiers `abstract private`. + + + + From b3bbdfbdf56f8555b764f611eeb11e6a6f1eeb6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 1 Sep 2025 02:49:13 +0200 Subject: [PATCH 1309/1962] Fix JClassSymbolTest --- .../symbols/internal/JClassSymbolTest.java | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/JClassSymbolTest.java b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/JClassSymbolTest.java index e5dc9cf30a6..bed9d1395be 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/JClassSymbolTest.java +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/internal/JClassSymbolTest.java @@ -4,7 +4,6 @@ package net.sourceforge.pmd.lang.java.symbols.internal; -import static java.lang.annotation.ElementType.TYPE_PARAMETER; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.empty; @@ -15,14 +14,16 @@ import java.lang.annotation.ElementType; import java.lang.annotation.RetentionPolicy; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; +import net.sourceforge.pmd.lang.LanguageRegistry; +import net.sourceforge.pmd.lang.LanguageVersion; import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; import net.sourceforge.pmd.lang.java.symbols.internal.SymImplementation.Fixture; import net.sourceforge.pmd.lang.java.symbols.testdata.AnnotationWithNoRetention; import net.sourceforge.pmd.lang.java.symbols.testdata.TypeAnnotation; +import net.sourceforge.pmd.util.OptionalBool; /** * Tests that test both AST and ASM symbols. @@ -48,15 +49,25 @@ void testAnnotWithNoRetention(SymImplementation impl) { assertEquals(RetentionPolicy.CLASS, sym.getAnnotationRetention()); } + @EnumSource @ParameterizedTest - @Disabled("tmp") void testAnnotWithNoTarget(SymImplementation impl) { + // Default retention changed several times + // between versions, here we only test with Java 8... + // See annotationAppliesToContext. + LanguageVersion javaVer = + LanguageRegistry.PMD.getLanguageById("java").getVersion("8"); + + JClassSymbol sym = impl.getSymbol(AnnotationWithNoRetention.class); + for (ElementType type : ElementType.values()) { + boolean supportedOnJava8 = + type != ElementType.TYPE_PARAMETER && type != ElementType.TYPE_USE; assertEquals( - TYPE_PARAMETER != type, - impl.getSymbol(AnnotationWithNoRetention.class).annotationAppliesTo(type), - "annot supports " + type); + OptionalBool.definitely(supportedOnJava8), + sym.annotationAppliesToContext(type, javaVer), + "annot supports " + type); } } From bd788451015d9fbab33d05fb583b119143209698 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 1 Sep 2025 15:06:13 +0200 Subject: [PATCH 1310/1962] Update docs/pages/release_notes.md --- docs/pages/release_notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index d3485cfcc5b..640f4e6e510 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -130,7 +130,7 @@ This is a {{ site.pmd.release_type }} release. * [#5980](https://github.com/pmd/pmd/pull/5980): chore: Fix typos - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#5981](https://github.com/pmd/pmd/pull/5981): Fix #4911: \[java] AvoidRethrowingException consider supertypes in following catches - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5989](https://github.com/pmd/pmd/pull/5989): \[java] Improve performance of RelianceOnDefaultCharset - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#6016](https://github.com/pmd/pmd/pull/6016): Fix #6014: \[java] Crash when encountering a java comment at the end of a file - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6016](https://github.com/pmd/pmd/pull/6016): \[java] Fix #6014: Crash when encountering a java comment at the end of a file - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) ### ๐Ÿ“ฆ Dependency updates From d34e9eb0a113e23adf0495c26edfbeab392ee09f Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Mon, 1 Sep 2025 21:27:36 +0200 Subject: [PATCH 1311/1962] #5849: Review finding: Properly escape markdown codeblocks --- .../sourceforge/pmd/cpd/MarkdownRenderer.java | 45 ++++++++++++++++++- .../pmd/cpd/MarkdownCodeBlockTest.java | 28 ++++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownCodeBlockTest.java diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MarkdownRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MarkdownRenderer.java index f3b1fac7163..96a89e69f10 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MarkdownRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MarkdownRenderer.java @@ -7,6 +7,10 @@ import java.io.IOException; import java.io.Writer; import java.util.Iterator; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.lang3.StringUtils; import net.sourceforge.pmd.lang.document.Chars; import net.sourceforge.pmd.lang.document.FileLocation; @@ -17,7 +21,6 @@ public class MarkdownRenderer implements CPDReportRenderer { private static final String SEPARATOR = "\n---\n\n"; private static final String FOUND_DUPLICATION_TEMPLATE = "Found a %d line (%d tokens) duplication in the following files:\n"; private static final String STARTING_AT_LINE_TEMPLATE = "Starting at line %d of %s\n"; - private static final String CODE_BLOCK_TEMPLATE = "\n```\n%s```\n"; @Override public void render(CPDReport report, Writer writer) throws IOException { @@ -44,6 +47,44 @@ private void renderDuplication(CPDReport report, Writer writer, Match match) thr } Chars source = report.getSourceCodeSlice(match.getFirstMark()); - writer.append(String.format(CODE_BLOCK_TEMPLATE, source)); + final MarkdownCodeBlock markdownCodeBlock = new MarkdownCodeBlock(source); + writer.append(markdownCodeBlock.toString()); + } + + static class MarkdownCodeBlock { + private static final int MIN_CODE_FENCE_LENGTH = 3; + private static final Pattern CODE_FENCE_PATTERN = Pattern.compile(String.format("`{%d,}", MIN_CODE_FENCE_LENGTH)); + + private final CharSequence source; + + MarkdownCodeBlock(CharSequence source) { + this.source = source; + } + + private int calculateFenceLength() { + // ` and `` are already escaped by the standard code fence + final String defaultCodeFence = StringUtils.repeat("`", MIN_CODE_FENCE_LENGTH); + if (!source.toString().contains(defaultCodeFence)) { + return MIN_CODE_FENCE_LENGTH; + } + + int maximumCodeFenceLength = defaultCodeFence.length(); + final Matcher matcher = CODE_FENCE_PATTERN.matcher(source); + while (matcher.find()) { + final String codeFenceMatch = matcher.group(); + maximumCodeFenceLength = Math.max(maximumCodeFenceLength, codeFenceMatch.length()); + } + + return maximumCodeFenceLength + 1; + } + + @Override + public String toString() { + final int codeFenceLength = calculateFenceLength(); + final String codeFence = StringUtils.repeat("`", codeFenceLength); + + final String codeBlock = StringUtils.wrap(String.format("\n%s", source), codeFence); + return StringUtils.wrap(codeBlock, "\n"); + } } } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownCodeBlockTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownCodeBlockTest.java new file mode 100644 index 00000000000..ca6383c30d1 --- /dev/null +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownCodeBlockTest.java @@ -0,0 +1,28 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.cpd; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.startsWith; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class MarkdownCodeBlockTest { + + @ParameterizedTest(name = "{0} is escaped by {1}") + @CsvSource({ + "`, ```", + "``, ```", + "```, ````", + "````, `````", + "`````, ``````", + "``````, ```````" + }) + void testCodeFences(String input, String expectedCodeFence) { + final MarkdownRenderer.MarkdownCodeBlock markdownCodeBlock = new MarkdownRenderer.MarkdownCodeBlock(input); + assertThat(markdownCodeBlock.toString().trim(), startsWith(expectedCodeFence)); + } +} From 392b4fd8090aa3c182f3890737c7f30fbcf7eb14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 1 Sep 2025 22:22:44 +0200 Subject: [PATCH 1312/1962] Update PULL_REQUEST_TEMPLATE.md --- .github/PULL_REQUEST_TEMPLATE.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index d7f130be116..254b530afa5 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,3 +1,7 @@ + + + + ## Describe the PR From 989b270c31c83ca3af0c27d11f1afa4101e45aea Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Mon, 1 Sep 2025 22:28:36 +0200 Subject: [PATCH 1313/1962] #5849: Review finding: Improve MarkdownCodeBlockTest --- .../java/net/sourceforge/pmd/cpd/MarkdownCodeBlockTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownCodeBlockTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownCodeBlockTest.java index ca6383c30d1..76b54e4d97f 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownCodeBlockTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownCodeBlockTest.java @@ -23,6 +23,6 @@ class MarkdownCodeBlockTest { }) void testCodeFences(String input, String expectedCodeFence) { final MarkdownRenderer.MarkdownCodeBlock markdownCodeBlock = new MarkdownRenderer.MarkdownCodeBlock(input); - assertThat(markdownCodeBlock.toString().trim(), startsWith(expectedCodeFence)); + assertThat(markdownCodeBlock.toString().trim(), startsWith(expectedCodeFence + "\n")); } } From efe69e48371b51e71b1894727e873f6e35838127 Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Tue, 2 Sep 2025 14:59:05 +0200 Subject: [PATCH 1314/1962] [java] Fix #5880: DoubleCheckedLocking FN with more than one assignment --- .../DoubleCheckedLockingRule.java | 10 +++---- .../xml/DoubleCheckedLocking.xml | 30 ++++++++++++++++++- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoubleCheckedLockingRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoubleCheckedLockingRule.java index e2463a566e3..116579888b2 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoubleCheckedLockingRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoubleCheckedLockingRule.java @@ -98,12 +98,10 @@ public Object visit(ASTMethodDeclaration node, Object data) { if (ssl.size() == 1 && ssl.get(0).ancestors().any(it -> it == outerIf)) { ASTIfStatement is2 = isl.get(1); if (JavaRuleUtil.isNullCheck(is2.getCondition(), returnVariable)) { - List assignments = is2.descendants(ASTAssignmentExpression.class).toList(); - if (assignments.size() == 1 - && JavaAstUtils.isReferenceToVar(assignments.get(0).getLeftOperand(), returnVariable)) { - asCtx(data).addViolation(node); - - } + is2.descendants(ASTAssignmentExpression.class) + .filter(assignment -> JavaAstUtils.isReferenceToVar(assignment.getLeftOperand(), returnVariable)) + .firstOpt() + .ifPresent(ignored -> asCtx(data).addViolation(node)); } } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/multithreading/xml/DoubleCheckedLocking.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/multithreading/xml/DoubleCheckedLocking.xml index 2a1eb3fc079..8355e5dfc9f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/multithreading/xml/DoubleCheckedLocking.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/multithreading/xml/DoubleCheckedLocking.xml @@ -128,12 +128,40 @@ public class Foo { synchronized (Foo.class) { result = instance; if (result == null) { - result = instance = new Foo(); + instance = new Foo(); + result = instance; } } } return result; } +} + ]]> + + + + #5880: FN for DoubleCheckedLocking with more than one assignment + 1 + From a32b68d1d23d549baf8453ca06fc183938334b4e Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Tue, 2 Sep 2025 15:13:53 +0200 Subject: [PATCH 1315/1962] [java] Fix #5880: DoubleCheckedLocking FN with more than two if statements --- .../DoubleCheckedLockingRule.java | 21 +++++++++------- .../xml/DoubleCheckedLocking.xml | 24 +++++++++++++++++++ 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoubleCheckedLockingRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoubleCheckedLockingRule.java index 116579888b2..c1533adc993 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoubleCheckedLockingRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoubleCheckedLockingRule.java @@ -89,19 +89,22 @@ public Object visit(ASTMethodDeclaration node, Object data) { return data; } - List isl = node.descendants(ASTIfStatement.class).toList(); - if (isl.size() == 2) { - ASTIfStatement outerIf = isl.get(0); + List nestedIfs = node.descendants(ASTIfStatement.class) + .filterNot(astIfStatement -> astIfStatement.descendants(ASTIfStatement.class).isEmpty()) + .toList(); + + for (ASTIfStatement outerIf : nestedIfs) { if (JavaRuleUtil.isNullCheck(outerIf.getCondition(), returnVariable)) { // find synchronized List ssl = outerIf.descendants(ASTSynchronizedStatement.class).toList(); if (ssl.size() == 1 && ssl.get(0).ancestors().any(it -> it == outerIf)) { - ASTIfStatement is2 = isl.get(1); - if (JavaRuleUtil.isNullCheck(is2.getCondition(), returnVariable)) { - is2.descendants(ASTAssignmentExpression.class) - .filter(assignment -> JavaAstUtils.isReferenceToVar(assignment.getLeftOperand(), returnVariable)) - .firstOpt() - .ifPresent(ignored -> asCtx(data).addViolation(node)); + for (ASTIfStatement innerIf : outerIf.descendants(ASTIfStatement.class)) { + if (JavaRuleUtil.isNullCheck(innerIf.getCondition(), returnVariable)) { + innerIf.descendants(ASTAssignmentExpression.class) + .filter(assignment -> JavaAstUtils.isReferenceToVar(assignment.getLeftOperand(), returnVariable)) + .firstOpt() + .ifPresent(ignored -> asCtx(data).addViolation(node)); + } } } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/multithreading/xml/DoubleCheckedLocking.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/multithreading/xml/DoubleCheckedLocking.xml index 8355e5dfc9f..f152a707f09 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/multithreading/xml/DoubleCheckedLocking.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/multithreading/xml/DoubleCheckedLocking.xml @@ -162,6 +162,30 @@ class Foo { // do special stuff return obj; } +} + ]]> + + + #5880: FN for DoubleCheckedLocking with more than two if statements + 1 + From a5836e5151e804377428e451edb58aa28167ca9c Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Tue, 2 Sep 2025 20:05:21 +0200 Subject: [PATCH 1316/1962] #5880: Findings from regression tester --- .../DoubleCheckedLockingRule.java | 14 +++++----- .../xml/DoubleCheckedLocking.xml | 27 +++++++++++++++++-- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoubleCheckedLockingRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoubleCheckedLockingRule.java index c1533adc993..e29df65ca04 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoubleCheckedLockingRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/multithreading/DoubleCheckedLockingRule.java @@ -10,6 +10,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import net.sourceforge.pmd.lang.ast.NodeStream; import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr.ASTNamedReferenceExpr; import net.sourceforge.pmd.lang.java.ast.ASTAssignmentExpression; import net.sourceforge.pmd.lang.java.ast.ASTExpression; @@ -91,6 +92,7 @@ public Object visit(ASTMethodDeclaration node, Object data) { List nestedIfs = node.descendants(ASTIfStatement.class) .filterNot(astIfStatement -> astIfStatement.descendants(ASTIfStatement.class).isEmpty()) + .filter(astIfStatement -> astIfStatement.ancestors(ASTIfStatement.class).isEmpty()) .toList(); for (ASTIfStatement outerIf : nestedIfs) { @@ -98,13 +100,11 @@ public Object visit(ASTMethodDeclaration node, Object data) { // find synchronized List ssl = outerIf.descendants(ASTSynchronizedStatement.class).toList(); if (ssl.size() == 1 && ssl.get(0).ancestors().any(it -> it == outerIf)) { - for (ASTIfStatement innerIf : outerIf.descendants(ASTIfStatement.class)) { - if (JavaRuleUtil.isNullCheck(innerIf.getCondition(), returnVariable)) { - innerIf.descendants(ASTAssignmentExpression.class) - .filter(assignment -> JavaAstUtils.isReferenceToVar(assignment.getLeftOperand(), returnVariable)) - .firstOpt() - .ifPresent(ignored -> asCtx(data).addViolation(node)); - } + NodeStream assignments = outerIf.descendants(ASTIfStatement.class) + .filter(innerIf -> JavaRuleUtil.isNullCheck(innerIf.getCondition(), returnVariable)) + .flatMap(innerIf -> innerIf.descendants(ASTAssignmentExpression.class)); + if (assignments.all(assignment -> JavaAstUtils.isReferenceToVar(assignment.getLeftOperand(), returnVariable))) { + assignments.firstOpt().ifPresent(ignored -> asCtx(data).addViolation(node)); } } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/multithreading/xml/DoubleCheckedLocking.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/multithreading/xml/DoubleCheckedLocking.xml index f152a707f09..9732a75a028 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/multithreading/xml/DoubleCheckedLocking.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/multithreading/xml/DoubleCheckedLocking.xml @@ -128,8 +128,7 @@ public class Foo { synchronized (Foo.class) { result = instance; if (result == null) { - instance = new Foo(); - result = instance; + result = instance = new Foo(); } } } @@ -186,6 +185,30 @@ class Foo { } return baz; } +} + ]]> + + + volatile field is referenced indirectly + 0 + From 8ac18ea161ee134f6b18c46ddef3475d6f6a439c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Jul 2025 14:43:36 +0200 Subject: [PATCH 1317/1962] [test] Fix QuickstartRulesetTests to detect deprecated rules again --- .../pmd/lang/apex/QuickstartRulesetTest.java | 18 +----- .../pmd/lang/java/QuickstartRulesetTest.java | 17 +----- .../pmd/test/RuleSetAssertions.java | 55 +++++++++++++++++++ .../pmd/test/RuleSetAssertionsTest.java | 26 +++++++++ .../test/ruleset-with-deprecated-rule-ref.xml | 14 +++++ .../pmd/test/ruleset-with-deprecated-rule.xml | 31 +++++++++++ .../pmd/test/ruleset-without-warnings.xml | 30 ++++++++++ 7 files changed, 161 insertions(+), 30 deletions(-) create mode 100644 pmd-test/src/main/java/net/sourceforge/pmd/test/RuleSetAssertions.java create mode 100644 pmd-test/src/test/java/net/sourceforge/pmd/test/RuleSetAssertionsTest.java create mode 100644 pmd-test/src/test/resources/net/sourceforge/pmd/test/ruleset-with-deprecated-rule-ref.xml create mode 100644 pmd-test/src/test/resources/net/sourceforge/pmd/test/ruleset-with-deprecated-rule.xml create mode 100644 pmd-test/src/test/resources/net/sourceforge/pmd/test/ruleset-without-warnings.xml diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/QuickstartRulesetTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/QuickstartRulesetTest.java index 5a85979e79b..d4bee04f3bb 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/QuickstartRulesetTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/QuickstartRulesetTest.java @@ -4,29 +4,15 @@ package net.sourceforge.pmd.lang.apex; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - import org.junit.jupiter.api.Test; -import net.sourceforge.pmd.lang.rule.RuleSet; -import net.sourceforge.pmd.lang.rule.RuleSetLoader; - -import com.github.stefanbirkner.systemlambda.SystemLambda; +import net.sourceforge.pmd.test.RuleSetAssertions; class QuickstartRulesetTest { private static final String QUICKSTART_RULESET = "rulesets/apex/quickstart.xml"; @Test void loadQuickstartRuleset() throws Exception { - String log = SystemLambda.tapSystemErr(() -> { - RuleSet ruleset = rulesetLoader().loadFromResource(QUICKSTART_RULESET); - assertNotNull(ruleset); - }); - assertTrue(log.isEmpty(), "No Logging expected"); - } - - private RuleSetLoader rulesetLoader() { - return new RuleSetLoader(); + RuleSetAssertions.assertNoWarnings(QUICKSTART_RULESET); } } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/QuickstartRulesetTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/QuickstartRulesetTest.java index 5689bccc240..dc37b7b2895 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/QuickstartRulesetTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/QuickstartRulesetTest.java @@ -4,26 +4,15 @@ package net.sourceforge.pmd.lang.java; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - import org.junit.jupiter.api.Test; -import net.sourceforge.pmd.lang.rule.RuleSet; -import net.sourceforge.pmd.lang.rule.RuleSetLoader; - -import com.github.stefanbirkner.systemlambda.SystemLambda; +import net.sourceforge.pmd.test.RuleSetAssertions; class QuickstartRulesetTest { private static final String QUICKSTART_RULESET = "rulesets/java/quickstart.xml"; @Test - void noDeprecations() throws Exception { - RuleSetLoader ruleSetLoader = new RuleSetLoader(); - String errorOutput = SystemLambda.tapSystemErr(() -> { - RuleSet quickstart = ruleSetLoader.loadFromResource(QUICKSTART_RULESET); - assertFalse(quickstart.getRules().isEmpty()); - }); - assertTrue(errorOutput.isEmpty()); + void noDeprecations() { + RuleSetAssertions.assertNoWarnings(QUICKSTART_RULESET); } } diff --git a/pmd-test/src/main/java/net/sourceforge/pmd/test/RuleSetAssertions.java b/pmd-test/src/main/java/net/sourceforge/pmd/test/RuleSetAssertions.java new file mode 100644 index 00000000000..910bcb83a74 --- /dev/null +++ b/pmd-test/src/main/java/net/sourceforge/pmd/test/RuleSetAssertions.java @@ -0,0 +1,55 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.test; + +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.slf4j.event.Level; + +import net.sourceforge.pmd.PMDConfiguration; +import net.sourceforge.pmd.lang.rule.RuleSet; +import net.sourceforge.pmd.lang.rule.RuleSetLoader; +import net.sourceforge.pmd.util.log.internal.MessageReporterBase; + +public final class RuleSetAssertions { + private RuleSetAssertions() { + } + + public static void assertNoWarnings(String rulesetFilename) { + class Reporter extends MessageReporterBase { + private int warnings = 0; + + Reporter() { + setLevel(Level.WARN); + } + + @Override + protected void logImpl(Level level, String message) { + if (level == Level.WARN) { + warnings++; + } + System.out.println(message); + } + + public int numWarnings() { + return warnings; + } + } + + Reporter reporter = new Reporter(); + PMDConfiguration pmdConfig = new PMDConfiguration(); + pmdConfig.setReporter(reporter); + RuleSetLoader ruleSetLoader = RuleSetLoader.fromPmdConfig(pmdConfig).warnDeprecated(true); + + RuleSet ruleSet = ruleSetLoader.loadFromResource(rulesetFilename); + assertAll( + () -> assertEquals(0, reporter.numErrors(), "errors while loading ruleset " + rulesetFilename), + () -> assertEquals(0, reporter.numWarnings(), "warnings while loading ruleset " + rulesetFilename), + () -> assertFalse(ruleSet.getRules().isEmpty(), "ruleset " + rulesetFilename + " was empty") + ); + } +} diff --git a/pmd-test/src/test/java/net/sourceforge/pmd/test/RuleSetAssertionsTest.java b/pmd-test/src/test/java/net/sourceforge/pmd/test/RuleSetAssertionsTest.java new file mode 100644 index 00000000000..29eeb0d6afa --- /dev/null +++ b/pmd-test/src/test/java/net/sourceforge/pmd/test/RuleSetAssertionsTest.java @@ -0,0 +1,26 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.opentest4j.MultipleFailuresError; + +class RuleSetAssertionsTest { + @Test + void canDetectDeprecatedRuleReferences() { + MultipleFailuresError error = assertThrows(MultipleFailuresError.class, () -> RuleSetAssertions.assertNoWarnings("net/sourceforge/pmd/test/ruleset-with-deprecated-rule-ref.xml")); + assertEquals(1, error.getFailures().size()); + assertTrue(error.getFailures().get(0).getMessage().startsWith("warnings while loading")); + } + + @Test + void rulesetWithoutWarning() { + RuleSetAssertions.assertNoWarnings("net/sourceforge/pmd/test/ruleset-without-warnings.xml"); + } +} diff --git a/pmd-test/src/test/resources/net/sourceforge/pmd/test/ruleset-with-deprecated-rule-ref.xml b/pmd-test/src/test/resources/net/sourceforge/pmd/test/ruleset-with-deprecated-rule-ref.xml new file mode 100644 index 00000000000..4585f013b0b --- /dev/null +++ b/pmd-test/src/test/resources/net/sourceforge/pmd/test/ruleset-with-deprecated-rule-ref.xml @@ -0,0 +1,14 @@ + + + + + + My custom rules + + + + + diff --git a/pmd-test/src/test/resources/net/sourceforge/pmd/test/ruleset-with-deprecated-rule.xml b/pmd-test/src/test/resources/net/sourceforge/pmd/test/ruleset-with-deprecated-rule.xml new file mode 100644 index 00000000000..80963392461 --- /dev/null +++ b/pmd-test/src/test/resources/net/sourceforge/pmd/test/ruleset-with-deprecated-rule.xml @@ -0,0 +1,31 @@ + + + + + + My custom rules + + + + Test + 3 + + + + + + + + + diff --git a/pmd-test/src/test/resources/net/sourceforge/pmd/test/ruleset-without-warnings.xml b/pmd-test/src/test/resources/net/sourceforge/pmd/test/ruleset-without-warnings.xml new file mode 100644 index 00000000000..8a371a49c04 --- /dev/null +++ b/pmd-test/src/test/resources/net/sourceforge/pmd/test/ruleset-without-warnings.xml @@ -0,0 +1,30 @@ + + + + + + My custom rules + + + + Test + 3 + + + + + + + + + From 8714c78f85a07b030229a7882f487ff24ce9c51b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 5 Sep 2025 10:28:41 +0200 Subject: [PATCH 1318/1962] [doc] Update release notes (#5933) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 640f4e6e510..b2dccd43843 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -130,6 +130,7 @@ This is a {{ site.pmd.release_type }} release. * [#5980](https://github.com/pmd/pmd/pull/5980): chore: Fix typos - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#5981](https://github.com/pmd/pmd/pull/5981): Fix #4911: \[java] AvoidRethrowingException consider supertypes in following catches - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5989](https://github.com/pmd/pmd/pull/5989): \[java] Improve performance of RelianceOnDefaultCharset - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5933](https://github.com/pmd/pmd/pull/5933): \[test] Fix QuickstartRulesetTests to detect deprecated rules again - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6016](https://github.com/pmd/pmd/pull/6016): \[java] Fix #6014: Crash when encountering a java comment at the end of a file - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) ### ๐Ÿ“ฆ Dependency updates From cb09f2d5440de14ebb736a637625df0c520d39b7 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Sat, 6 Sep 2025 13:21:30 +0200 Subject: [PATCH 1319/1962] Make sure check only applies to receiver --- .../rule/codestyle/UnnecessaryCastRule.java | 13 ++++++++--- .../rule/codestyle/xml/UnnecessaryCast.xml | 22 +++++++++++++------ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java index 7eb4dd6153a..2d8999400ac 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java @@ -44,7 +44,9 @@ import net.sourceforge.pmd.lang.java.types.JClassType; import net.sourceforge.pmd.lang.java.types.JMethodSig; import net.sourceforge.pmd.lang.java.types.JTypeMirror; +import net.sourceforge.pmd.lang.java.types.JTypeVar; import net.sourceforge.pmd.lang.java.types.OverloadSelectionResult; +import net.sourceforge.pmd.lang.java.types.Substitution; import net.sourceforge.pmd.lang.java.types.TypeConversion; import net.sourceforge.pmd.lang.java.types.TypeOps; import net.sourceforge.pmd.lang.java.types.TypeOps.Convertibility; @@ -109,16 +111,21 @@ public Object visit(ASTCastExpression castExpr, Object data) { } else if (isCastUnnecessary(castExpr, context, coercionType, operandType)) { reportCast(castExpr, data); } else if (castExpr.getParent() instanceof ASTMethodCall - && !coercionType.isGeneric()) { + && castExpr.getIndexInParent() == 0) { ASTMethodCall call = (ASTMethodCall) castExpr.getParent(); - if (!call.getMethodType().isGeneric() - && TypeTestUtil.isA(call.getMethodType().getDeclaringType(), operandType)) { + boolean generic = call.getMethodType().getSymbol().getFormalParameters().stream() + .anyMatch(fp -> isTypeExpression(fp.getTypeMirror(Substitution.EMPTY))); + if (!generic && TypeTestUtil.isA(call.getMethodType().getDeclaringType(), operandType)) { reportCast(castExpr, data); } } return null; } + private boolean isTypeExpression(JTypeMirror type) { + return type.isGeneric() || type instanceof JTypeVar; + } + private boolean isCastUnnecessary(ASTCastExpression castExpr, @NonNull ExprContext context, JTypeMirror coercionType, JTypeMirror operandType) { if (isCastDeterminingReturnOfLambda(castExpr) != NO) { return false; diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml index 3b94f182caf..e0683e8bac4 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml @@ -1101,7 +1101,7 @@ class Tester { - + [java] UnnecessaryCast false-positive for raw types #4822 0 Cast is not found as unnecessary (for now) - 0 + 2 + 11,13 { } + public class Foo { public int compare(List o1) { - // note that here the cast is useless, because - // List::size is also available on the generic - // List type. However we don't report this - // as we don't analyse the usages of values for - // now. + String s = ((List) o1).get(0); + String s1 = ((StringList) o1).get(0); + Object t = ((List) o1).get(0); + ((List) o1).addAll(Collections.singletonList(t)); return ((List) o1).size(); } + + public int generic(List o1) { + String s = ((List) o1).get(0); + String s1 = ((StringList) o1).get(0); + return ((List) o1).size(); + } } ]]> From 97c460057643f75b54ed8bdae7d621c3d4278d04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sat, 6 Sep 2025 14:20:57 +0200 Subject: [PATCH 1320/1962] Revert schema change --- .../pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml index 53a20be4e32..afb580c6cdf 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests http://pmd.sourceforge.net/rule-tests_1_0_0.xsd"> failure case, return statement From 2d704057bcc5cdde59a8bc953338af5752c4b83e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sat, 6 Sep 2025 14:25:26 +0200 Subject: [PATCH 1321/1962] Update release notes, ref #5982 --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index de1e6cea496..5e859441dd7 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -84,6 +84,7 @@ This is a {{ site.pmd.release_type }} release. * [#972](https://github.com/pmd/pmd/issues/972): \[java] Improve naming conventions rules * [#5770](https://github.com/pmd/pmd/issues/5770): \[java] New Rule: VariableCanBeInlined: Local variables should not be declared and then immediately returned or thrown * [#5948](https://github.com/pmd/pmd/issues/5948): \[java] UnnecessaryBoxing false positive when calling `List.remove(int)` + * [#5982](https://github.com/pmd/pmd/issues/5982): \[java] More detailed message for the UselessParentheses rule * java-design * [#4911](https://github.com/pmd/pmd/issues/4911): \[java] AvoidRethrowingException should allow rethrowing exception subclasses * [#5023](https://github.com/pmd/pmd/issues/5023): \[java] UseUtilityClass implementation hardcodes a message instead of using the one defined in the XML From 9e4b23889e51a639f76557ae434eb3fcc48e1a8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sat, 6 Sep 2025 14:33:16 +0200 Subject: [PATCH 1322/1962] Update release notes, ref #5994 --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 5e859441dd7..a3e8a796ea1 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -79,6 +79,7 @@ This is a {{ site.pmd.release_type }} release. * java-bestpractices * [#2186](https://github.com/pmd/pmd/issues/2186): \[java] New rule: Reliance on default charset * [#4500](https://github.com/pmd/pmd/issues/4500): \[java] AvoidReassigningLoopVariables - false negatives within for-loops and skip allowed + * [#4770](https://github.com/pmd/pmd/issues/4770): \[java] UnusedFormalParameter should ignore public constructor as same as method * [#5198](https://github.com/pmd/pmd/issues/5198): \[java] CheckResultSet false-positive with local variable checked in a while loop * java-codestyle * [#972](https://github.com/pmd/pmd/issues/972): \[java] Improve naming conventions rules From 12bea40775176b5952e7a4d028bf4dbc6b219c65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sat, 6 Sep 2025 15:28:49 +0200 Subject: [PATCH 1323/1962] Update release notes, ref #6006 --- docs/pages/release_notes.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index a3e8a796ea1..da250f21f81 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,6 +25,10 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy #### โœจ New Rules + +This release brings several new rules for both Java and Apex. Please try them out +and submit feedback on [our issue tracker](https://github.com/pmd/pmd/issues)! + * The new apex rule {% rule apex/codestyle/AnnotationsNamingConventions %} enforces that annotations are used consistently in PascalCase. The rule is referenced in the quickstart.xml ruleset for Apex. @@ -56,6 +60,10 @@ This is a {{ site.pmd.release_type }} release. which only considered return statements. The new rule also finds unnecessary local variables before throw statements. The rule is referenced in the quickstart.xml ruleset for Java. +* The new java rule {% rule java/errorprone/CollectionTypeMismatch %} detects calls to + collection methods where we suspect the types are incompatible. This happens for instance + when you try to remove a `String` from a `Collection`: although it is allowed + to write this because `remove` takes an `Object` parameter, it is most likely a mistake. #### Deprecated Rules * The java rule {% rule java/codestyle/GenericsNaming %} has been deprecated for removal in favor @@ -95,6 +103,7 @@ This is a {{ site.pmd.release_type }} release. * [#5837](https://github.com/pmd/pmd/issues/5837): \[java] New Rule OverrideBothEqualsAndHashCodeOnComparable * [#5881](https://github.com/pmd/pmd/issues/5881): \[java] AvoidLosingExceptionInformation does not trigger when inside if-else * [#5915](https://github.com/pmd/pmd/issues/5915): \[java] AssignmentInOperand not raised when inside do-while loop + * [#5949](https://github.com/pmd/pmd/issues/5949): \[java] new rule for Collections methods that take Object as a parameter * [#5974](https://github.com/pmd/pmd/issues/5974): \[java] CloseResourceRule: NullPointerException while analyzing * test * [#5973](https://github.com/pmd/pmd/issues/5973): \[test] Enable XML validation for rule tests From e3142083475ef7d9c8fc36dd4d584766f23696e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Mon, 8 Sep 2025 17:05:10 +0200 Subject: [PATCH 1324/1962] Change "Threshold above" to "Threshold at or above" in property descriptions "above" implies, that we only trigger on value > limit. But all of these already trigger on value >= limit. --- docs/pages/pmd/userdocs/configuring_rules.md | 2 +- .../pmd/lang/apex/rule/internal/AbstractCounterCheckRule.java | 2 +- .../pmd/lang/java/rule/design/SwitchDensityRule.java | 2 +- .../lang/java/rule/internal/AbstractJavaCounterCheckRule.java | 2 +- .../pmd/lang/plsql/rule/design/AbstractCounterCheckRule.java | 2 +- .../lang/velocity/rule/design/ExcessiveTemplateLengthRule.java | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/pages/pmd/userdocs/configuring_rules.md b/docs/pages/pmd/userdocs/configuring_rules.md index d0425f1921b..8c28a80ad34 100644 --- a/docs/pages/pmd/userdocs/configuring_rules.md +++ b/docs/pages/pmd/userdocs/configuring_rules.md @@ -45,7 +45,7 @@ will cause the rule to be ignored. Properties make it easy to customise the behaviour of a rule directly from the xml. They come in several types, which correspond to the type of their values. For example, NPathComplexity declares a property "reportLevel", -with an integer value type, and which corresponds to the threshold above which a method will be reported. +with an integer value type, and which corresponds to the threshold at or above which a method will be reported. If you believe that its default value of 200 is too high, you could lower it to e.g. 150 in the following way: ```xml diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/internal/AbstractCounterCheckRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/internal/AbstractCounterCheckRule.java index 753527d029f..db8f38b1f64 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/internal/AbstractCounterCheckRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/internal/AbstractCounterCheckRule.java @@ -30,7 +30,7 @@ public abstract class AbstractCounterCheckRule> extends Ab private final PropertyDescriptor reportLevel = CommonPropertyDescriptors.reportLevelProperty() - .desc("Threshold above which a node is reported") + .desc("Threshold at or above which a node is reported") .require(positive()) .defaultValue(defaultReportLevel()).build(); private final Class nodeType; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SwitchDensityRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SwitchDensityRule.java index 43dd57686c8..9723b31001c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SwitchDensityRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SwitchDensityRule.java @@ -30,7 +30,7 @@ public class SwitchDensityRule extends AbstractJavaRulechainRule { private static final PropertyDescriptor REPORT_LEVEL = CommonPropertyDescriptors.reportLevelProperty() - .desc("Threshold above which a switch statement or expression is reported") + .desc("Threshold at or above which a switch statement or expression is reported") .require(positive()) .defaultValue(10) .build(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java index f7491b00894..21d9a66f563 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java @@ -23,7 +23,7 @@ public abstract class AbstractJavaCounterCheckRule extends A private final PropertyDescriptor reportLevel = CommonPropertyDescriptors.reportLevelProperty() - .desc("Threshold above which a node is reported") + .desc("Threshold at or above which a node is reported") .require(positive()) .defaultValue(defaultReportLevel()).build(); diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/AbstractCounterCheckRule.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/AbstractCounterCheckRule.java index 78e4029d1c2..b65b0247522 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/AbstractCounterCheckRule.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/AbstractCounterCheckRule.java @@ -43,7 +43,7 @@ abstract class AbstractCounterCheckRule extends AbstractPLS private final PropertyDescriptor reportLevel = CommonPropertyDescriptors.reportLevelProperty() - .desc("Threshold above which a node is reported") + .desc("Threshold at or above which a node is reported") .require(positive()) .defaultValue(defaultReportLevel()).build(); diff --git a/pmd-velocity/src/main/java/net/sourceforge/pmd/lang/velocity/rule/design/ExcessiveTemplateLengthRule.java b/pmd-velocity/src/main/java/net/sourceforge/pmd/lang/velocity/rule/design/ExcessiveTemplateLengthRule.java index f25220f700f..bcb4e1ba72d 100644 --- a/pmd-velocity/src/main/java/net/sourceforge/pmd/lang/velocity/rule/design/ExcessiveTemplateLengthRule.java +++ b/pmd-velocity/src/main/java/net/sourceforge/pmd/lang/velocity/rule/design/ExcessiveTemplateLengthRule.java @@ -18,7 +18,7 @@ public class ExcessiveTemplateLengthRule extends AbstractVtlRule { private static final PropertyDescriptor REPORT_LEVEL = CommonPropertyDescriptors.reportLevelProperty() - .desc("Threshold above which a node is reported") + .desc("Threshold at or above which a node is reported") .require(positive()) .defaultValue(1000) .build(); From b56f27151cdc66d67b8b1224ca6e4ad02995ac21 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 8 Sep 2025 19:40:01 +0200 Subject: [PATCH 1325/1962] [doc] Update release notes --- docs/pages/release_notes.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index da250f21f81..8c51ac8c60f 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -103,7 +103,7 @@ and submit feedback on [our issue tracker](https://github.com/pmd/pmd/issues)! * [#5837](https://github.com/pmd/pmd/issues/5837): \[java] New Rule OverrideBothEqualsAndHashCodeOnComparable * [#5881](https://github.com/pmd/pmd/issues/5881): \[java] AvoidLosingExceptionInformation does not trigger when inside if-else * [#5915](https://github.com/pmd/pmd/issues/5915): \[java] AssignmentInOperand not raised when inside do-while loop - * [#5949](https://github.com/pmd/pmd/issues/5949): \[java] new rule for Collections methods that take Object as a parameter + * [#5949](https://github.com/pmd/pmd/issues/5949): \[java] New rule for Collections methods that take Object as a parameter * [#5974](https://github.com/pmd/pmd/issues/5974): \[java] CloseResourceRule: NullPointerException while analyzing * test * [#5973](https://github.com/pmd/pmd/issues/5973): \[test] Enable XML validation for rule tests @@ -148,11 +148,15 @@ See [Testing your rules]({{ baseurl }}pmd_userdocs_extending_testing.html) for m * [#5970](https://github.com/pmd/pmd/pull/5970): chore: CI improvements - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5971](https://github.com/pmd/pmd/pull/5971): Fix #5948: \[java] UnnecessaryBoxingRule: Check if unboxing is required for overload resolution - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5972](https://github.com/pmd/pmd/pull/5972): Fix #3434: \[java] False negatives in AssignmentInOperand rule - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5975](https://github.com/pmd/pmd/pull/5975): Fix #5973: \[test] Enable XML Validation for rule tests - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5979](https://github.com/pmd/pmd/pull/5979): Fix #5974: \[java] NPE in CloseResourceRule - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#5980](https://github.com/pmd/pmd/pull/5980): chore: Fix typos - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#5981](https://github.com/pmd/pmd/pull/5981): Fix #4911: \[java] AvoidRethrowingException consider supertypes in following catches - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5982](https://github.com/pmd/pmd/pull/5982): \[java] More detailed message for the UselessParentheses rule - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#5989](https://github.com/pmd/pmd/pull/5989): \[java] Improve performance of RelianceOnDefaultCharset - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#6016](https://github.com/pmd/pmd/pull/6016): \[java] Fix #6014: Crash when encountering a java comment at the end of a file - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5994](https://github.com/pmd/pmd/pull/5994): Fix #4770: \[java] UnusedFormalParameter should ignore public constructor as same as method - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6006](https://github.com/pmd/pmd/pull/6006): Fix #5949: \[java] CollectionTypeMismatch - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6016](https://github.com/pmd/pmd/pull/6016): Fix #6014: \[java] Crash when encountering a java comment at the end of a file - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) ### ๐Ÿ“ฆ Dependency updates From d57fed34ca07e9cf0584d3bd5daee4750aad7e6a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 8 Sep 2025 20:19:01 +0200 Subject: [PATCH 1326/1962] [doc] Update release notes Consistently format pull request titles --- docs/pages/release_notes.md | 46 ++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 1d7fdacb2e1..5500a1d97ae 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -90,7 +90,7 @@ and submit feedback on [our issue tracker](https://github.com/pmd/pmd/issues)! * [#4770](https://github.com/pmd/pmd/issues/4770): \[java] UnusedFormalParameter should ignore public constructor as same as method * [#5198](https://github.com/pmd/pmd/issues/5198): \[java] CheckResultSet false-positive with local variable checked in a while loop * java-codestyle - * [#972](https://github.com/pmd/pmd/issues/972): \[java] Improve naming conventions rules + * [#972](https://github.com/pmd/pmd/issues/972): \[java] Improve naming conventions rules * [#5770](https://github.com/pmd/pmd/issues/5770): \[java] New Rule: VariableCanBeInlined: Local variables should not be declared and then immediately returned or thrown * [#5948](https://github.com/pmd/pmd/issues/5948): \[java] UnnecessaryBoxing false positive when calling `List.remove(int)` * [#5982](https://github.com/pmd/pmd/issues/5982): \[java] More detailed message for the UselessParentheses rule @@ -126,40 +126,40 @@ See [Testing your rules]({{ baseurl }}pmd_userdocs_extending_testing.html) for m ### โœจ Merged pull requests -* [#5822](https://github.com/pmd/pmd/pull/5822): Fix #5650: \[apex] New Rule: AnnotationsNamingConventions - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) -* [#5847](https://github.com/pmd/pmd/pull/5847): Fix #5770: \[java] New Rule: VariableCanBeInlined - [Vincent Potucek](https://github.com/Pankraz76) (@Pankraz76) -* [#5856](https://github.com/pmd/pmd/pull/5856): Fix #5837: \[java] New Rule OverrideBothEqualsAndHashCodeOnComparable - [Vincent Potucek](https://github.com/Pankraz76) (@Pankraz76) +* [#5822](https://github.com/pmd/pmd/pull/5822): \[apex] Fix #5650: New Rule: AnnotationsNamingConventions - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) +* [#5847](https://github.com/pmd/pmd/pull/5847): \[java] Fix #5770: New Rule: VariableCanBeInlined - [Vincent Potucek](https://github.com/Pankraz76) (@Pankraz76) +* [#5856](https://github.com/pmd/pmd/pull/5856): \[java] Fix #5837: New Rule OverrideBothEqualsAndHashCodeOnComparable - [Vincent Potucek](https://github.com/Pankraz76) (@Pankraz76) * [#5907](https://github.com/pmd/pmd/pull/5907): \[java] New rule: UselessPureMethodCall - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#5922](https://github.com/pmd/pmd/pull/5922): Fix #972: \[java] Add a new rule TypeParameterNamingConventions - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#5924](https://github.com/pmd/pmd/pull/5924): Fix #5915: \[java] Fix AssignmentInOperandRule to also work an do-while loops and switch statements - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#5930](https://github.com/pmd/pmd/pull/5930): Fix #4500: \[java] Fix AvoidReassigningLoopVariablesRule to allow only simple assignments in the forReassign=skip case - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#5931](https://github.com/pmd/pmd/pull/5931): Fix #5023: \[java] Fix UseUtilityClassRule to use the message provided in design.xml - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5922](https://github.com/pmd/pmd/pull/5922): \[java] Fix #972: Add a new rule TypeParameterNamingConventions - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5924](https://github.com/pmd/pmd/pull/5924): \[java] Fix #5915: Fix AssignmentInOperandRule to also work an do-while loops and switch statements - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5930](https://github.com/pmd/pmd/pull/5930): \[java] Fix #4500: Fix AvoidReassigningLoopVariablesRule to allow only simple assignments in the forReassign=skip case - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5931](https://github.com/pmd/pmd/pull/5931): \[java] Fix #5023: Fix UseUtilityClassRule to use the message provided in design.xml - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5932](https://github.com/pmd/pmd/pull/5932): \[ci] Reuse GitHub Pre-Releases - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5933](https://github.com/pmd/pmd/pull/5933): \[test] Fix QuickstartRulesetTests to detect deprecated rules again - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5934](https://github.com/pmd/pmd/pull/5934): Fix #2186: \[java] New Rule: RelianceOnDefaultCharset - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5934](https://github.com/pmd/pmd/pull/5934): \[java] Fix #2186: New Rule: RelianceOnDefaultCharset - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5938](https://github.com/pmd/pmd/pull/5938): \[doc] Update suppression docs to reflect PMD 7 changes - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#5939](https://github.com/pmd/pmd/pull/5939): Fix #5198: \[java] CheckResultSet FP when local variable is checked - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) -* [#5954](https://github.com/pmd/pmd/pull/5954): Fix #4721: \[core] Enable XML rule MissingEncoding in dogfood ruleset - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5939](https://github.com/pmd/pmd/pull/5939): \[java] Fix #5198: CheckResultSet FP when local variable is checked - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#5954](https://github.com/pmd/pmd/pull/5954): \[core] Fix #4721: Enable XML rule MissingEncoding in dogfood ruleset - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5955](https://github.com/pmd/pmd/pull/5955): chore: Fix LiteralsFirstInComparison violations in test code - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5957](https://github.com/pmd/pmd/pull/5957): Fix #3401: \[java] Improve message/description/examples for AvoidUsingOctalValues - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#5959](https://github.com/pmd/pmd/pull/5959): Fix #5960: \[java] AddEmptyString: Improve report location - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#5961](https://github.com/pmd/pmd/pull/5961): Fix #5960: \[java] Add details to the error message for some rules - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#5965](https://github.com/pmd/pmd/pull/5965): Fix #5881: AvoidLosingException - Consider nested method calls - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5957](https://github.com/pmd/pmd/pull/5957): \[java] Fix #3401: Improve message/description/examples for AvoidUsingOctalValues - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5959](https://github.com/pmd/pmd/pull/5959): \[java] Fix #5960: AddEmptyString: Improve report location - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#5961](https://github.com/pmd/pmd/pull/5961): \[java] Fix #5960: Add details to the error message for some rules - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#5965](https://github.com/pmd/pmd/pull/5965): \[java] Fix #5881: AvoidLosingException - Consider nested method calls - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5967](https://github.com/pmd/pmd/pull/5967): \[doc]\[java] ReplaceJavaUtilDate - improve doc to mention java.sql.Date - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5968](https://github.com/pmd/pmd/pull/5968): \[doc] Add logging page to sidebar under dev docs - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5969](https://github.com/pmd/pmd/pull/5969): \[doc] Add CSS in PMD's description - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5970](https://github.com/pmd/pmd/pull/5970): chore: CI improvements - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5971](https://github.com/pmd/pmd/pull/5971): Fix #5948: \[java] UnnecessaryBoxingRule: Check if unboxing is required for overload resolution - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#5972](https://github.com/pmd/pmd/pull/5972): Fix #3434: \[java] False negatives in AssignmentInOperand rule - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#5975](https://github.com/pmd/pmd/pull/5975): Fix #5973: \[test] Enable XML Validation for rule tests - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5979](https://github.com/pmd/pmd/pull/5979): Fix #5974: \[java] NPE in CloseResourceRule - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#5971](https://github.com/pmd/pmd/pull/5971): \[java] Fix #5948: UnnecessaryBoxingRule: Check if unboxing is required for overload resolution - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5972](https://github.com/pmd/pmd/pull/5972): \[java] Fix #3434: False negatives in AssignmentInOperand rule - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5975](https://github.com/pmd/pmd/pull/5975): \[test] Fix #5973: Enable XML Validation for rule tests - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5979](https://github.com/pmd/pmd/pull/5979): \[java] Fix #5974: NPE in CloseResourceRule - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#5980](https://github.com/pmd/pmd/pull/5980): chore: Fix typos - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#5981](https://github.com/pmd/pmd/pull/5981): Fix #4911: \[java] AvoidRethrowingException consider supertypes in following catches - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5981](https://github.com/pmd/pmd/pull/5981): \[java] Fix #4911: AvoidRethrowingException consider supertypes in following catches - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5982](https://github.com/pmd/pmd/pull/5982): \[java] More detailed message for the UselessParentheses rule - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#5989](https://github.com/pmd/pmd/pull/5989): \[java] Improve performance of RelianceOnDefaultCharset - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#5994](https://github.com/pmd/pmd/pull/5994): Fix #4770: \[java] UnusedFormalParameter should ignore public constructor as same as method - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#6006](https://github.com/pmd/pmd/pull/6006): Fix #5949: \[java] CollectionTypeMismatch - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#6016](https://github.com/pmd/pmd/pull/6016): Fix #6014: \[java] Crash when encountering a java comment at the end of a file - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5994](https://github.com/pmd/pmd/pull/5994): \[java] Fix #4770: UnusedFormalParameter should ignore public constructor as same as method - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6006](https://github.com/pmd/pmd/pull/6006): \[java] Fix #5949: CollectionTypeMismatch - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6016](https://github.com/pmd/pmd/pull/6016): \[java] Fix #6014: Crash when encountering a java comment at the end of a file - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) ### ๐Ÿ“ฆ Dependency updates From 8a96c025c5b3bb0f0ebea8e496a396d5605442cf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 20:36:31 +0200 Subject: [PATCH 1327/1962] chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.17.6 to 1.17.7 (#5997) Bumps [net.bytebuddy:byte-buddy](https://github.com/raphw/byte-buddy) from 1.17.6 to 1.17.7. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.17.6...byte-buddy-1.17.7) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-version: 1.17.7 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index eb59231a263..590c1a314f8 100644 --- a/pom.xml +++ b/pom.xml @@ -1039,7 +1039,7 @@ net.bytebuddy byte-buddy - 1.17.6 + 1.17.7 test From bdcab969602ab2bda80a0cdffd8def6f247aaaae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 20:36:40 +0200 Subject: [PATCH 1328/1962] chore(deps): bump kotlin.version from 2.2.0 to 2.2.10 (#5998) Bumps `kotlin.version` from 2.2.0 to 2.2.10. Updates `org.jetbrains.kotlin:kotlin-compiler` from 2.2.0 to 2.2.10 - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v2.2.0...v2.2.10) Updates `org.jetbrains.kotlin:kotlin-stdlib` from 2.2.0 to 2.2.10 - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v2.2.0...v2.2.10) Updates `org.jetbrains.kotlin:kotlin-stdlib-jdk8` from 2.2.0 to 2.2.10 - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v2.2.0...v2.2.10) Updates `org.jetbrains.kotlin:kotlin-reflect` from 2.2.0 to 2.2.10 - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v2.2.0...v2.2.10) Updates `org.jetbrains.kotlin:kotlin-test-junit` from 2.2.0 to 2.2.10 - [Release notes](https://github.com/JetBrains/kotlin/releases) - [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md) - [Commits](https://github.com/JetBrains/kotlin/compare/v2.2.0...v2.2.10) Updates `org.jetbrains.kotlin:kotlin-maven-plugin` from 2.2.0 to 2.2.10 --- updated-dependencies: - dependency-name: org.jetbrains.kotlin:kotlin-compiler dependency-version: 2.2.10 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.jetbrains.kotlin:kotlin-stdlib dependency-version: 2.2.10 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.jetbrains.kotlin:kotlin-stdlib-jdk8 dependency-version: 2.2.10 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.jetbrains.kotlin:kotlin-reflect dependency-version: 2.2.10 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: org.jetbrains.kotlin:kotlin-test-junit dependency-version: 2.2.10 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.jetbrains.kotlin:kotlin-maven-plugin dependency-version: 2.2.10 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 590c1a314f8..f2a526aec3b 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ 1.9 1.9 ${maven.compiler.test.target} - 2.2.0 + 2.2.10 5.9.1 5.13.4 1.13.4 From 6e51c7ee68858c89959f91cd868a294a3f6e8a50 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 20:37:05 +0200 Subject: [PATCH 1329/1962] chore(deps): bump org.mockito:mockito-core from 5.18.0 to 5.19.0 (#5999) Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.18.0 to 5.19.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.18.0...v5.19.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-version: 5.19.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f2a526aec3b..cecea875f45 100644 --- a/pom.xml +++ b/pom.xml @@ -1028,7 +1028,7 @@ org.mockito mockito-core - 5.18.0 + 5.19.0 test From 40f275189382cc46397cbc1837335e07fefd7e43 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 20:37:20 +0200 Subject: [PATCH 1330/1962] chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.17.6 to 1.17.7 (#6000) chore(deps-dev): bump net.bytebuddy:byte-buddy-agent Bumps [net.bytebuddy:byte-buddy-agent](https://github.com/raphw/byte-buddy) from 1.17.6 to 1.17.7. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.17.6...byte-buddy-1.17.7) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy-agent dependency-version: 1.17.7 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cecea875f45..bbfee1b4f69 100644 --- a/pom.xml +++ b/pom.xml @@ -1045,7 +1045,7 @@ net.bytebuddy byte-buddy-agent - 1.17.6 + 1.17.7 test From 7d0358cbee1870be2f60eb79f6ae82760f0ec3d0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 20:37:34 +0200 Subject: [PATCH 1331/1962] chore(deps): bump com.google.protobuf:protobuf-java from 4.31.1 to 4.32.0 (#6001) chore(deps): bump com.google.protobuf:protobuf-java Bumps [com.google.protobuf:protobuf-java](https://github.com/protocolbuffers/protobuf) from 4.31.1 to 4.32.0. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl) - [Commits](https://github.com/protocolbuffers/protobuf/commits) --- updated-dependencies: - dependency-name: com.google.protobuf:protobuf-java dependency-version: 4.32.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bbfee1b4f69..7cdd663d093 100644 --- a/pom.xml +++ b/pom.xml @@ -1135,7 +1135,7 @@ com.google.protobuf protobuf-java - 4.31.1 + 4.32.0 + From c829fe9f47d20637ca6387fcd24161b2434a3353 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 11 Sep 2025 10:11:16 +0200 Subject: [PATCH 1348/1962] Add @csrma as a contributor --- .all-contributorsrc | 9 +++++ docs/pages/pmd/projectdocs/credits.md | 53 ++++++++++++++------------- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index d5aa6e36695..ac6bc3aab43 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8208,6 +8208,15 @@ "contributions": [ "code" ] + }, + { + "login": "csrma", + "name": "csrma", + "avatar_url": "https://avatars.githubusercontent.com/u/213656372?v=4", + "profile": "https://github.com/csrma", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 6a1c2ff0460..4ebbee08e31 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -928,236 +928,237 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d

    + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + From d3cc63125a6b4ca37f58e76e793547d7b4f17aac Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 11 Sep 2025 10:12:01 +0200 Subject: [PATCH 1349/1962] Add @stevenschlansker as a contributor --- .all-contributorsrc | 9 +++ docs/pages/pmd/projectdocs/credits.md | 87 ++++++++++++++------------- 2 files changed, 53 insertions(+), 43 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index ac6bc3aab43..cef034a5998 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8217,6 +8217,15 @@ "contributions": [ "bug" ] + }, + { + "login": "stevenschlansker", + "name": "Steven Schlansker", + "avatar_url": "https://avatars.githubusercontent.com/u/129097?v=4", + "profile": "https://github.com/stevenschlansker", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 4ebbee08e31..efa6fa76856 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -776,388 +776,389 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + From 04372863207f3bef1e8a7144adec4448d174cb97 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 11 Sep 2025 10:55:54 +0200 Subject: [PATCH 1350/1962] [doc] Update release notes (#5601) Also add javadoc since, experimental, deprecated. --- docs/pages/release_notes.md | 15 ++++++++++++--- .../sourceforge/pmd/reporting/RuleContext.java | 4 ++-- .../pmd/lang/java/ast/ASTLambdaParameter.java | 1 + .../java/rule/codestyle/ModifierOrderRule.java | 3 +++ .../pmd/lang/java/symbols/JClassSymbol.java | 4 +++- .../main/resources/category/java/codestyle.xml | 2 +- .../main/resources/rulesets/java/quickstart.xml | 1 + 7 files changed, 23 insertions(+), 7 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 67692390b2e..8681655aa94 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,8 +25,6 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy #### โœจ New Rules -* The new Java rule {% rule java/codestyle/ModifierOrder %} (`codestyle`) finds incorrectly ordered modifiers - (e.g., `static public` instead of `public static`). It ensures modifiers appear in the correct order as recommended by the Java Language Specification. * The new apex rule {% rule apex/codestyle/AnnotationsNamingConventions %} enforces that annotations are used consistently in PascalCase. The rule is referenced in the quickstart.xml ruleset for Apex. @@ -58,6 +56,9 @@ This is a {{ site.pmd.release_type }} release. which only considered return statements. The new rule also finds unnecessary local variables before throw statements. The rule is referenced in the quickstart.xml ruleset for Java. +* The new java rule {% rule java/codestyle/ModifierOrder %} (`codestyle`) finds incorrectly ordered modifiers + (e.g., `static public` instead of `public static`). It ensures modifiers appear in the correct order as + recommended by the Java Language Specification. #### Deprecated Rules * The java rule {% rule java/codestyle/GenericsNaming %} has been deprecated for removal in favor @@ -85,6 +86,7 @@ This is a {{ site.pmd.release_type }} release. * [#972](https://github.com/pmd/pmd/issues/972): \[java] Improve naming conventions rules * [#5770](https://github.com/pmd/pmd/issues/5770): \[java] New Rule: VariableCanBeInlined: Local variables should not be declared and then immediately returned or thrown * [#5948](https://github.com/pmd/pmd/issues/5948): \[java] UnnecessaryBoxing false positive when calling `List.remove(int)` + * [#5601](https://github.com/pmd/pmd/issues/5601): \[java] New rule: ModifierOrder * java-design * [#4911](https://github.com/pmd/pmd/issues/4911): \[java] AvoidRethrowingException should allow rethrowing exception subclasses * [#5023](https://github.com/pmd/pmd/issues/5023): \[java] UseUtilityClass implementation hardcodes a message instead of using the one defined in the XML @@ -97,6 +99,13 @@ This is a {{ site.pmd.release_type }} release. * [#5974](https://github.com/pmd/pmd/issues/5974): \[java] CloseResourceRule: NullPointerException while analyzing ### ๐Ÿšจ API Changes +#### Deprecations +* pmd-java: + * {%jdoc !!java::lang.java.symbols.JClassSymbol#annotationAppliesTo(java.lang.annotation.ElementType) %}: Use + {%jdoc !!java::lang.java.symbols.JClassSymbol#annotationAppliesToContext(java.lang.annotation.ElementType,core::lang.LanguageVersion) %} + instead. +#### Experimental API +* pmd-core: {%jdoc !!core::reporting.RuleContext#addViolationWithPosition(core::lang.ast.Node,core::lang.ast.impl.javacc.JavaccToken,java.lang.String,java.lang.Object...) %} #### Deprecations * test @@ -105,7 +114,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ Merged pull requests -* [#5856](https://github.com/pmd/pmd/pull/6019): Fix #6019: \[java] New Rule ModifierOrder - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5601](https://github.com/pmd/pmd/pull/5601): \[java] New rule: ModifierOrder - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5822](https://github.com/pmd/pmd/pull/5822): Fix #5650: \[apex] New Rule: AnnotationsNamingConventions - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) * [#5847](https://github.com/pmd/pmd/pull/5847): Fix #5770: \[java] New Rule: VariableCanBeInlined - [Vincent Potucek](https://github.com/Pankraz76) (@Pankraz76) * [#5856](https://github.com/pmd/pmd/pull/5856): Fix #5837: \[java] New Rule OverrideBothEqualsAndHashCodeOnComparable - [Vincent Potucek](https://github.com/Pankraz76) (@Pankraz76) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java index ea9952f274f..0d1042f4878 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java @@ -156,7 +156,7 @@ public void addViolationWithPosition(Node node, int beginLine, int endLine, Stri * @param token Report location of the violation * @param message Violation message * @param formatArgs Format arguments for the message - * @experimental This will probably never be stabilized, will instead be + * @experimental Since 7.17.0. This will probably never be stabilized, will instead be * replaced by a fluent API or something to report violations. Do not use * this outside of the PMD codebase. See [core] Add fluent API to report violations #5039. */ @@ -177,7 +177,7 @@ public void addViolationWithPosition(Node node, JavaccToken token, String messag * @param location Report location of the violation * @param message Violation message * @param formatArgs Format arguments for the message - * @experimental This will probably never be stabilized, will instead be + * @experimental Since 7.9.0. This will probably never be stabilized, will instead be * replaced by a fluent API or something to report violations. Do not use * this outside of the PMD codebase. See [core] Add fluent API to report violations #5039. */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLambdaParameter.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLambdaParameter.java index 3abd2c88431..9a876e50c56 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLambdaParameter.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLambdaParameter.java @@ -35,6 +35,7 @@ void setUsesVarKw(boolean usesVarKw) { /** * If true, the type node is null and the type was written with the "var" * keyword in the source. + * @since 7.17.0 */ public boolean hasVarKeyword() { return usesVarKw; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ModifierOrderRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ModifierOrderRule.java index b7c0a2f6163..f2742200fc8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ModifierOrderRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ModifierOrderRule.java @@ -29,6 +29,9 @@ import net.sourceforge.pmd.util.AssertionUtil; import net.sourceforge.pmd.util.OptionalBool; +/** + * @since 7.17.0 + */ public class ModifierOrderRule extends AbstractJavaRulechainRule { private static final String MSG_KEYWORD_ORDER = diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JClassSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JClassSymbol.java index fd3108764f6..9bc0c239d63 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JClassSymbol.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JClassSymbol.java @@ -336,7 +336,7 @@ default PSet getAnnotationAttributeNames() { * Return whether annotations of this annotation type apply to the * given construct, as per the {@link Target} annotation. Return * false if this is not an annotation. - * @deprecated Use {@link #annotationAppliesToContext(ElementType, LanguageVersion)} + * @deprecated Since 7.17.0. Use {@link #annotationAppliesToContext(ElementType, LanguageVersion)} */ @Deprecated default boolean annotationAppliesTo(ElementType elementType) { @@ -349,6 +349,7 @@ default boolean annotationAppliesTo(ElementType elementType) { * given construct, as per the {@link Target} annotation. Return * false if this is not an annotation. May return unknown if we are * not sure. + * @since 7.17.0 */ default OptionalBool annotationAppliesToContext(ElementType elementType, LanguageVersion javaVersion) { if (isUnresolved()) { @@ -385,6 +386,7 @@ default OptionalBool annotationAppliesToContext(ElementType elementType, Languag * Whether a specific annotation of this type is a type annotation also depends * on the context where it appears, as this annotation type may be applicable * to other contexts than {@link ElementType#TYPE_USE}. + * @since 7.17.0 */ default OptionalBool mayBeTypeAnnotation(LanguageVersion lv) { return annotationAppliesToContext(ElementType.TYPE_USE, lv); diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml index 5abe7722a92..8f206eaa46c 100644 --- a/pmd-java/src/main/resources/category/java/codestyle.xml +++ b/pmd-java/src/main/resources/category/java/codestyle.xml @@ -1133,7 +1133,7 @@ public class Foo { diff --git a/pmd-java/src/main/resources/rulesets/java/quickstart.xml b/pmd-java/src/main/resources/rulesets/java/quickstart.xml index f516566be21..a115347e3b3 100644 --- a/pmd-java/src/main/resources/rulesets/java/quickstart.xml +++ b/pmd-java/src/main/resources/rulesets/java/quickstart.xml @@ -72,6 +72,7 @@ + From cf0ca0418eeb6bc18ddbc171baf981bb7e67a87c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 11 Sep 2025 11:48:28 +0200 Subject: [PATCH 1351/1962] [doc] Update release notes (#5995) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 843697c2faa..76cc4e5010e 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -129,6 +129,7 @@ This is a {{ site.pmd.release_type }} release. * [#5980](https://github.com/pmd/pmd/pull/5980): chore: Fix typos - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#5981](https://github.com/pmd/pmd/pull/5981): Fix #4911: \[java] AvoidRethrowingException consider supertypes in following catches - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5989](https://github.com/pmd/pmd/pull/5989): \[java] Improve performance of RelianceOnDefaultCharset - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5995](https://github.com/pmd/pmd/pull/5995): \[html] Add test case that tests the end of a reported violation (test for #3951) - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) ### ๐Ÿ“ฆ Dependency updates From b6ab6eae616bbeb930ec73acb975495961d9cd33 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 11 Sep 2025 14:02:46 +0200 Subject: [PATCH 1352/1962] Add @StevanWhite as a contributor --- .all-contributorsrc | 9 +++ docs/pages/pmd/projectdocs/credits.md | 87 ++++++++++++++------------- 2 files changed, 53 insertions(+), 43 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index f199e4ef65c..13e35b97358 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8198,6 +8198,15 @@ "contributions": [ "bug" ] + }, + { + "login": "StevanWhite", + "name": "Steve White", + "avatar_url": "https://avatars.githubusercontent.com/u/1576377?v=4", + "profile": "https://github.com/StevanWhite", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 8971a11c83f..63a3fbf95fb 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -775,389 +775,390 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + From deb5ee4f572ea5751b78afcdfd2778df1f25700e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 11 Sep 2025 14:03:01 +0200 Subject: [PATCH 1353/1962] [doc] Update release notes (#5996) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 843697c2faa..891de607f11 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -81,6 +81,7 @@ This is a {{ site.pmd.release_type }} release. * [#5198](https://github.com/pmd/pmd/issues/5198): \[java] CheckResultSet false-positive with local variable checked in a while loop * java-codestyle * [#972](https://github.com/pmd/pmd/issues/972): \[java] Improve naming conventions rules + * [#4916](https://github.com/pmd/pmd/issues/4916): \[java] UseExplicitTypes: cases where 'var' should be unobjectionable * [#5770](https://github.com/pmd/pmd/issues/5770): \[java] New Rule: VariableCanBeInlined: Local variables should not be declared and then immediately returned or thrown * [#5948](https://github.com/pmd/pmd/issues/5948): \[java] UnnecessaryBoxing false positive when calling `List.remove(int)` * java-design @@ -129,6 +130,7 @@ This is a {{ site.pmd.release_type }} release. * [#5980](https://github.com/pmd/pmd/pull/5980): chore: Fix typos - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#5981](https://github.com/pmd/pmd/pull/5981): Fix #4911: \[java] AvoidRethrowingException consider supertypes in following catches - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5989](https://github.com/pmd/pmd/pull/5989): \[java] Improve performance of RelianceOnDefaultCharset - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5996](https://github.com/pmd/pmd/pull/5996): \[java] Fix #4916: UseExplicitTypes cases where 'var' should be unobjectionable - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) ### ๐Ÿ“ฆ Dependency updates From 155fa3ced63550b2227b12dadb17a388b1b2362b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 11 Sep 2025 14:57:57 +0200 Subject: [PATCH 1354/1962] [core] MarkdownRenderer - syntax highlight for java Also render locations as a list --- .../pmd/userdocs/cpd/cpd_report_formats.md | 98 +++++++++++++++++-- .../sourceforge/pmd/cpd/MarkdownRenderer.java | 26 +++-- .../pmd/cpd/MarkdownCodeBlockTest.java | 2 +- .../pmd/cpd/MarkdownRendererTest.java | 12 +-- 4 files changed, 116 insertions(+), 22 deletions(-) diff --git a/docs/pages/pmd/userdocs/cpd/cpd_report_formats.md b/docs/pages/pmd/userdocs/cpd/cpd_report_formats.md index b5a52050a8b..d18cf985157 100644 --- a/docs/pages/pmd/userdocs/cpd/cpd_report_formats.md +++ b/docs/pages/pmd/userdocs/cpd/cpd_report_formats.md @@ -300,14 +300,17 @@ It requires javascript enabled and uses [Bootstrap](https://getbootstrap.com/), This report format outputs all duplications one after another in Markdown. Each duplication contains the complete code snippet as a code block. Duplications are separated by a horizontal line (`---` in Markdown). -Example: +This format is available since PMD 7.17.0. -````markdown -Found a 33 line (239 tokens) duplication in the following files: -Starting at line 32 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java -Starting at line 68 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java +
    + Example (rendered) +
    -``` +Found a 33 line (239 tokens) duplication in the following files: +* Starting at line 32 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java +* Starting at line 68 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java + +```java public void testOverride() { final StringProperty PROPERTY1_DESCRIPTOR = new StringProperty("property1", "Test property", null, 0f); MockRule rule = new MockRule(); @@ -346,11 +349,85 @@ public void testOverride() { --- Found a 16 line (110 tokens) duplication in the following files: -Starting at line 66 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java -Starting at line 88 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java -Starting at line 110 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java +* Starting at line 66 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java +* Starting at line 88 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java +* Starting at line 110 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java + +```java +JaxenXPathRuleQuery query = createQuery(xpath); +List ruleChainVisits = query.getRuleChainVisits(); +Assert.assertEquals(2, ruleChainVisits.size()); +Assert.assertTrue(ruleChainVisits.contains("dummyNode")); +// Note: Having AST_ROOT in the rule chain visits is probably a mistake. But it doesn't hurt, it shouldn't +// match a real node name. +Assert.assertTrue(ruleChainVisits.contains(JaxenXPathRuleQuery.AST_ROOT)); + +DummyNodeWithListAndEnum dummy = new DummyNodeWithListAndEnum(1); +RuleContext data = new RuleContext(); +data.setLanguageVersion(LanguageRegistry.findLanguageByTerseName("dummy").getDefaultVersion()); + +query.evaluate(dummy, data); +// note: the actual xpath queries are only available after evaluating +Assert.assertEquals(2, query.nodeNameToXPaths.size()); +Assert.assertEquals("self::node()[(attribute::Test1 = \"false\")][(attribute::Test2 = \"true\")]", query.nodeNameToXPaths.get("dummyNode").get(0).toString()); +``` +
    +
    + +

    + +
    + Markdown source +
    +````markdown +Found a 33 line (239 tokens) duplication in the following files: +* Starting at line 32 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java +* Starting at line 68 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java + +```java +public void testOverride() { + final StringProperty PROPERTY1_DESCRIPTOR = new StringProperty("property1", "Test property", null, 0f); + MockRule rule = new MockRule(); + rule.definePropertyDescriptor(PROPERTY1_DESCRIPTOR); + rule.setLanguage(LanguageRegistry.getLanguage(Dummy2LanguageModule.NAME)); + rule.setName("name1"); + rule.setProperty(PROPERTY1_DESCRIPTOR, "value1"); + rule.setMessage("message1"); + rule.setDescription("description1"); + rule.addExample("example1"); + rule.setExternalInfoUrl("externalInfoUrl1"); + rule.setPriority(RulePriority.HIGH); + final StringProperty PROPERTY2_DESCRIPTOR = new StringProperty("property2", "Test property", null, 0f); + RuleReference ruleReference = new RuleReference(); + ruleReference.setRule(rule); + ruleReference.definePropertyDescriptor(PROPERTY2_DESCRIPTOR); + ruleReference.setLanguage(LanguageRegistry.getLanguage(DummyLanguageModule.NAME)); + ruleReference + .setMinimumLanguageVersion(LanguageRegistry.getLanguage(DummyLanguageModule.NAME).getVersion("1.3")); + ruleReference + .setMaximumLanguageVersion(LanguageRegistry.getLanguage(DummyLanguageModule.NAME).getVersion("1.7")); + ruleReference.setDeprecated(true); + ruleReference.setName("name2"); + ruleReference.setProperty(PROPERTY1_DESCRIPTOR, "value2"); + ruleReference.setProperty(PROPERTY2_DESCRIPTOR, "value3"); + ruleReference.setMessage("message2"); + ruleReference.setDescription("description2"); + ruleReference.addExample("example2"); + ruleReference.setExternalInfoUrl("externalInfoUrl2"); + ruleReference.setPriority(RulePriority.MEDIUM_HIGH); + + validateOverriddenValues(PROPERTY1_DESCRIPTOR, PROPERTY2_DESCRIPTOR, ruleReference); ``` + +--- + +Found a 16 line (110 tokens) duplication in the following files: +* Starting at line 66 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java +* Starting at line 88 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java +* Starting at line 110 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java + +```java JaxenXPathRuleQuery query = createQuery(xpath); List ruleChainVisits = query.getRuleChainVisits(); Assert.assertEquals(2, ruleChainVisits.size()); @@ -369,3 +446,6 @@ Assert.assertEquals(2, query.nodeNameToXPaths.size()); Assert.assertEquals("self::node()[(attribute::Test1 = \"false\")][(attribute::Test2 = \"true\")]", query.nodeNameToXPaths.get("dummyNode").get(0).toString()); ``` ```` + +
    +
    diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MarkdownRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MarkdownRenderer.java index 96a89e69f10..c95224e56b5 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MarkdownRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MarkdownRenderer.java @@ -7,6 +7,7 @@ import java.io.IOException; import java.io.Writer; import java.util.Iterator; +import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -20,7 +21,7 @@ public class MarkdownRenderer implements CPDReportRenderer { //separator must be surrounded by empty lines to be rendered properly private static final String SEPARATOR = "\n---\n\n"; private static final String FOUND_DUPLICATION_TEMPLATE = "Found a %d line (%d tokens) duplication in the following files:\n"; - private static final String STARTING_AT_LINE_TEMPLATE = "Starting at line %d of %s\n"; + private static final String STARTING_AT_LINE_TEMPLATE = "* Starting at line %d of %s\n"; @Override public void render(CPDReport report, Writer writer) throws IOException { @@ -46,8 +47,15 @@ private void renderDuplication(CPDReport report, Writer writer, Match match) thr writer.append(String.format(STARTING_AT_LINE_TEMPLATE, loc.getStartLine(), report.getDisplayName(loc.getFileId()))); } - Chars source = report.getSourceCodeSlice(match.getFirstMark()); - final MarkdownCodeBlock markdownCodeBlock = new MarkdownCodeBlock(source); + Mark firstMark = match.getFirstMark(); + String filename = firstMark.getFileId().getFileName().toLowerCase(Locale.ROOT); + String highlightLanguage = null; + if (filename.endsWith(".java") || filename.endsWith(".jav")) { + highlightLanguage = "java"; + } + + Chars source = report.getSourceCodeSlice(firstMark); + final MarkdownCodeBlock markdownCodeBlock = new MarkdownCodeBlock(source, highlightLanguage); writer.append(markdownCodeBlock.toString()); } @@ -56,9 +64,11 @@ static class MarkdownCodeBlock { private static final Pattern CODE_FENCE_PATTERN = Pattern.compile(String.format("`{%d,}", MIN_CODE_FENCE_LENGTH)); private final CharSequence source; + private final String highlightLanguage; - MarkdownCodeBlock(CharSequence source) { + MarkdownCodeBlock(CharSequence source, String highlightLanguage) { this.source = source; + this.highlightLanguage = highlightLanguage != null ? highlightLanguage : ""; } private int calculateFenceLength() { @@ -81,9 +91,13 @@ private int calculateFenceLength() { @Override public String toString() { final int codeFenceLength = calculateFenceLength(); - final String codeFence = StringUtils.repeat("`", codeFenceLength); + String codeFence = StringUtils.repeat("`", codeFenceLength); - final String codeBlock = StringUtils.wrap(String.format("\n%s", source), codeFence); + final String codeBlock = + codeFence.concat(highlightLanguage) + .concat("\n") + .concat(source.toString()) + .concat(codeFence); return StringUtils.wrap(codeBlock, "\n"); } } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownCodeBlockTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownCodeBlockTest.java index 76b54e4d97f..35c192b8b3f 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownCodeBlockTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownCodeBlockTest.java @@ -22,7 +22,7 @@ class MarkdownCodeBlockTest { "``````, ```````" }) void testCodeFences(String input, String expectedCodeFence) { - final MarkdownRenderer.MarkdownCodeBlock markdownCodeBlock = new MarkdownRenderer.MarkdownCodeBlock(input); + final MarkdownRenderer.MarkdownCodeBlock markdownCodeBlock = new MarkdownRenderer.MarkdownCodeBlock(input, null); assertThat(markdownCodeBlock.toString().trim(), startsWith(expectedCodeFence + "\n")); } } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownRendererTest.java index 7fee8a0d565..e61fe24dfef 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownRendererTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/MarkdownRendererTest.java @@ -37,10 +37,10 @@ void testMultipleDuplicates() throws IOException { renderer.render(builder.build(), sw); String report = sw.toString(); String expectedReport = "Found a 6 line (75 tokens) duplication in the following files:\n" - + "Starting at line 48 of " + foo.getAbsolutePath() + "\n" - + "Starting at line 73 of " + foo.getAbsolutePath() + "\n" + + "* Starting at line 48 of " + foo.getAbsolutePath() + "\n" + + "* Starting at line 73 of " + foo.getAbsolutePath() + "\n" + "\n" - + "```\n" + + "```java\n" + "47_47_47_47_47_47_47_47_47_47_\n" + "48_48_48_48_48_48_48_48_48_48_\n" + "49_49_49_49_49_49_49_49_49_49_\n" @@ -52,10 +52,10 @@ void testMultipleDuplicates() throws IOException { + "---\n" + "\n" + "Found a 5 line (50 tokens) duplication in the following files:\n" - + "Starting at line 49 of " + bar.getAbsolutePath() + "\n" - + "Starting at line 74 of " + bar.getAbsolutePath() + "\n" + + "* Starting at line 49 of " + bar.getAbsolutePath() + "\n" + + "* Starting at line 74 of " + bar.getAbsolutePath() + "\n" + "\n" - + "```\n" + + "```java\n" + "48_48_48_48_48_48_48_48_48_48_\n" + "49_49_49_49_49_49_49_49_49_49_\n" + "50_50_50_50_50_50_50_50_50_50_\n" From c898e5f36c75f548a4cb2a4439374a9c9ff8128b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 11 Sep 2025 16:52:02 +0200 Subject: [PATCH 1355/1962] Add @malik-n as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 147 +++++++++++++------------- 2 files changed, 83 insertions(+), 73 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index f199e4ef65c..c109c26ce4b 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8198,6 +8198,15 @@ "contributions": [ "bug" ] + }, + { + "login": "malik-n", + "name": "Malik", + "avatar_url": "https://avatars.githubusercontent.com/u/160581225?v=4", + "profile": "https://github.com/malik-n", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 8971a11c83f..f6f09bef84b 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -504,660 +504,661 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
    + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + From d34dbfcbeeb4004f5bb2ae14bda48045d8f9e0da Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 11 Sep 2025 16:52:54 +0200 Subject: [PATCH 1356/1962] [doc] Update release notes (#6008, #5849) --- docs/pages/release_notes.md | 7 +++++++ .../java/net/sourceforge/pmd/cpd/MarkdownRenderer.java | 3 +++ 2 files changed, 10 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 843697c2faa..d16710f030c 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -67,11 +67,17 @@ This is a {{ site.pmd.release_type }} release. * The java rule {% rule java/codestyle/UnnecessaryLocalBeforeReturn %} has been deprecated for removal in favor of the new rule {% rule java/codestyle/VariableCanBeInlined %}. +#### CPD: New Markdown Report Format +This PMD version ships with a simple Markdown based output format for CPD. It outputs all duplications +one after another including the code snippets as code blocks. +See [Report formats for CPD]({{ baseurl }}pmd_userdocs_cpd_report_formats.html#markdown). + ### ๐Ÿ› Fixed Issues * apex-codestyle * [#5650](https://github.com/pmd/pmd/issues/5650): \[apex] New Rule: AnnotationsNamingConventions * core * [#4721](https://github.com/pmd/pmd/issues/4721): chore: \[core] Enable XML rule MissingEncoding in dogfood ruleset + * [#5849](https://github.com/pmd/pmd/issues/5849): \[core] Support Markdown Output for CPD Reports * java * [#5874](https://github.com/pmd/pmd/issues/5874): \[java] Update java regression tests with Java 25 language features * [#5960](https://github.com/pmd/pmd/issues/5960): \[java] Avoid/reduce duplicate error messages for some rules @@ -129,6 +135,7 @@ This is a {{ site.pmd.release_type }} release. * [#5980](https://github.com/pmd/pmd/pull/5980): chore: Fix typos - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#5981](https://github.com/pmd/pmd/pull/5981): Fix #4911: \[java] AvoidRethrowingException consider supertypes in following catches - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5989](https://github.com/pmd/pmd/pull/5989): \[java] Improve performance of RelianceOnDefaultCharset - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6008](https://github.com/pmd/pmd/pull/6008): \[core] Fix #5849: Support Markdown Output for CPD Reports - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) ### ๐Ÿ“ฆ Dependency updates diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MarkdownRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MarkdownRenderer.java index c95224e56b5..11e14b9a43b 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MarkdownRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MarkdownRenderer.java @@ -16,6 +16,9 @@ import net.sourceforge.pmd.lang.document.Chars; import net.sourceforge.pmd.lang.document.FileLocation; +/** + * @since 7.17.0 + */ public class MarkdownRenderer implements CPDReportRenderer { //separator must be surrounded by empty lines to be rendered properly From d55bea2ea019e52c60089f0be946ccfcfe03d7ce Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 11 Sep 2025 16:59:48 +0200 Subject: [PATCH 1357/1962] [doc] Update release notes (#6009) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index b39eb7ea427..65d972bae35 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -127,6 +127,7 @@ This is a {{ site.pmd.release_type }} release. * [#5979](https://github.com/pmd/pmd/pull/5979): Fix #5974: \[java] NPE in CloseResourceRule - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#5980](https://github.com/pmd/pmd/pull/5980): chore: Fix typos - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#5989](https://github.com/pmd/pmd/pull/5989): \[java] Improve performance of RelianceOnDefaultCharset - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6009](https://github.com/pmd/pmd/pull/6009): \[java] More detailed message for AvoidInstanceofChecksInCatchClause - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) ### ๐Ÿ“ฆ Dependency updates From 58dfb170213b1d1e4dc2b2e4e020ff4f28ea60b7 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 12 Sep 2025 08:37:43 +0200 Subject: [PATCH 1358/1962] [doc] Update release notes - add missing new rule fix issues --- .all-contributorsrc | 1 + docs/pages/pmd/projectdocs/credits.md | 695 +++++--------------------- docs/pages/release_notes.md | 22 +- 3 files changed, 129 insertions(+), 589 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index a982f85ceab..14dee6d8ef7 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8200,6 +8200,7 @@ "bug" ] }, + { "login": "judepereira", "name": "Jude Pereira", "avatar_url": "https://avatars.githubusercontent.com/u/747087?v=4", diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 7af7d81572f..4386e8247af 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -508,1130 +508,665 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + -<<<<<<< HEAD - - -<<<<<<< HEAD -======= -======= - - ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - -<<<<<<< HEAD -======= -======= + + ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - -<<<<<<< HEAD -======= -======= + + ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - -<<<<<<< HEAD -======= -======= + + ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - -<<<<<<< HEAD -======= -======= + + ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - -<<<<<<< HEAD -======= -======= + + ->>>>>>> main ->>>>>>> main - -<<<<<<< HEAD - - -<<<<<<< HEAD -======= -======= + - - ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - -<<<<<<< HEAD -======= -======= + + ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - -<<<<<<< HEAD -======= -======= + + ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - -<<<<<<< HEAD -======= -======= + + ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - -<<<<<<< HEAD -======= -======= + + ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - -<<<<<<< HEAD -======= -======= + + ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - -<<<<<<< HEAD -======= -======= + + ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - -<<<<<<< HEAD -======= -======= + + ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - -<<<<<<< HEAD -======= -======= + + ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - -<<<<<<< HEAD -======= -======= + + ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - -<<<<<<< HEAD -======= -======= + + ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main - - -<<<<<<< HEAD - - - - -======= + + -<<<<<<< HEAD - - -======= ->>>>>>> main ->>>>>>> main + + diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index e2d77356f53..91742fdf487 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -99,27 +99,31 @@ See [Report formats for CPD]({{ baseurl }}pmd_userdocs_cpd_report_formats.html#m * [#5960](https://github.com/pmd/pmd/issues/5960): \[java] Avoid/reduce duplicate error messages for some rules * [#6014](https://github.com/pmd/pmd/issues/6014): \[java] Crash when encountering a java comment at the end of a file * java-bestpractices - * [#2186](https://github.com/pmd/pmd/issues/2186): \[java] New rule: Reliance on default charset + * [#2186](https://github.com/pmd/pmd/issues/2186): \[java] New Rule: RelianceOnDefaultCharset * [#4500](https://github.com/pmd/pmd/issues/4500): \[java] AvoidReassigningLoopVariables - false negatives within for-loops and skip allowed * [#4770](https://github.com/pmd/pmd/issues/4770): \[java] UnusedFormalParameter should ignore public constructor as same as method * [#5198](https://github.com/pmd/pmd/issues/5198): \[java] CheckResultSet false-positive with local variable checked in a while loop * java-codestyle * [#972](https://github.com/pmd/pmd/issues/972): \[java] Improve naming conventions rules * [#4916](https://github.com/pmd/pmd/issues/4916): \[java] UseExplicitTypes: cases where 'var' should be unobjectionable - * [#5601](https://github.com/pmd/pmd/issues/5601): \[java] New rule: ModifierOrder + * [#5601](https://github.com/pmd/pmd/issues/5601): \[java] New Rule: ModifierOrder * [#5770](https://github.com/pmd/pmd/issues/5770): \[java] New Rule: VariableCanBeInlined: Local variables should not be declared and then immediately returned or thrown + * [#5922](https://github.com/pmd/pmd/issues/5922): \[java] New Rule: TypeParameterNamingConventions * [#5948](https://github.com/pmd/pmd/issues/5948): \[java] UnnecessaryBoxing false positive when calling `List.remove(int)` * [#5982](https://github.com/pmd/pmd/issues/5982): \[java] More detailed message for the UselessParentheses rule * java-design * [#4911](https://github.com/pmd/pmd/issues/4911): \[java] AvoidRethrowingException should allow rethrowing exception subclasses * [#5023](https://github.com/pmd/pmd/issues/5023): \[java] UseUtilityClass implementation hardcodes a message instead of using the one defined in the XML +* java-documentation + * [#5916](https://github.com/pmd/pmd/issues/5916): \[java] New Rule: DanglingJavadoc * java-errorprone * [#3401](https://github.com/pmd/pmd/issues/3401): \[java] Improve AvoidUsingOctalValues documentation * [#3434](https://github.com/pmd/pmd/issues/3434): \[java] False negatives in AssignmentInOperand Rule - * [#5837](https://github.com/pmd/pmd/issues/5837): \[java] New Rule OverrideBothEqualsAndHashCodeOnComparable + * [#5837](https://github.com/pmd/pmd/issues/5837): \[java] New Rule: OverrideBothEqualsAndHashCodeOnComparable * [#5881](https://github.com/pmd/pmd/issues/5881): \[java] AvoidLosingExceptionInformation does not trigger when inside if-else + * [#5907](https://github.com/pmd/pmd/issues/5907): \[java] New Rule: UselessPureMethodCall * [#5915](https://github.com/pmd/pmd/issues/5915): \[java] AssignmentInOperand not raised when inside do-while loop - * [#5949](https://github.com/pmd/pmd/issues/5949): \[java] New rule for Collections methods that take Object as a parameter + * [#5949](https://github.com/pmd/pmd/issues/5949): \[java] New Rule: CollectionTypeMismatch: for Collections methods that take Object as a parameter * [#5974](https://github.com/pmd/pmd/issues/5974): \[java] CloseResourceRule: NullPointerException while analyzing * test * [#5973](https://github.com/pmd/pmd/issues/5973): \[test] Enable XML validation for rule tests @@ -159,12 +163,12 @@ See [Testing your rules]({{ baseurl }}pmd_userdocs_extending_testing.html) for m ### โœจ Merged pull requests -* [#5601](https://github.com/pmd/pmd/pull/5601): \[java] New rule: ModifierOrder - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5601](https://github.com/pmd/pmd/pull/5601): \[java] New Rule: ModifierOrder - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5822](https://github.com/pmd/pmd/pull/5822): \[apex] Fix #5650: New Rule: AnnotationsNamingConventions - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) * [#5847](https://github.com/pmd/pmd/pull/5847): \[java] Fix #5770: New Rule: VariableCanBeInlined - [Vincent Potucek](https://github.com/Pankraz76) (@Pankraz76) -* [#5856](https://github.com/pmd/pmd/pull/5856): \[java] Fix #5837: New Rule OverrideBothEqualsAndHashCodeOnComparable - [Vincent Potucek](https://github.com/Pankraz76) (@Pankraz76) -* [#5907](https://github.com/pmd/pmd/pull/5907): \[java] New rule: UselessPureMethodCall - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#5916](https://github.com/pmd/pmd/pull/5916): \[java] New rule: Dangling Javadoc - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#5856](https://github.com/pmd/pmd/pull/5856): \[java] Fix #5837: New Rule: OverrideBothEqualsAndHashCodeOnComparable - [Vincent Potucek](https://github.com/Pankraz76) (@Pankraz76) +* [#5907](https://github.com/pmd/pmd/pull/5907): \[java] New Rule: UselessPureMethodCall - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#5916](https://github.com/pmd/pmd/pull/5916): \[java] New Rule: DanglingJavadoc - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#5922](https://github.com/pmd/pmd/pull/5922): \[java] Fix #972: Add a new rule TypeParameterNamingConventions - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5924](https://github.com/pmd/pmd/pull/5924): \[java] Fix #5915: Fix AssignmentInOperandRule to also work an do-while loops and switch statements - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5930](https://github.com/pmd/pmd/pull/5930): \[java] Fix #4500: Fix AvoidReassigningLoopVariablesRule to allow only simple assignments in the forReassign=skip case - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) @@ -196,7 +200,7 @@ See [Testing your rules]({{ baseurl }}pmd_userdocs_extending_testing.html) for m * [#5994](https://github.com/pmd/pmd/pull/5994): \[java] Fix #4770: UnusedFormalParameter should ignore public constructor as same as method - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5995](https://github.com/pmd/pmd/pull/5995): \[html] Add test case that tests the end of a reported violation (test for #3951) - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#5996](https://github.com/pmd/pmd/pull/5996): \[java] Fix #4916: UseExplicitTypes cases where 'var' should be unobjectionable - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#6006](https://github.com/pmd/pmd/pull/6006): \[java] Fix #5949: CollectionTypeMismatch - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6006](https://github.com/pmd/pmd/pull/6006): \[java] Fix #5949: New Rule: CollectionTypeMismatch - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6008](https://github.com/pmd/pmd/pull/6008): \[core] Fix #5849: Support Markdown Output for CPD Reports - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6009](https://github.com/pmd/pmd/pull/6009): \[java] More detailed message for AvoidInstanceofChecksInCatchClause - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6016](https://github.com/pmd/pmd/pull/6016): \[java] Fix #6014: Crash when encountering a java comment at the end of a file - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) From 76cc98aac0f9aadc62cb6b3795069b3a552d5a51 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 12 Sep 2025 09:17:13 +0200 Subject: [PATCH 1359/1962] Prepare pmd release 7.17.0 --- docs/_config.yml | 2 +- docs/pages/release_notes.md | 40 +++++++++++++++++-- .../resources/rulesets/java/quickstart.xml | 1 + 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index d7e2157eac9..0bfe9485184 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,7 +1,7 @@ repository: pmd/pmd pmd: - version: 7.17.0-SNAPSHOT + version: 7.17.0 previous_version: 7.16.0 date: 2025-09-12 # release types: major, minor, bugfix diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 91742fdf487..357852f56a0 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -63,7 +63,8 @@ and submit feedback on [our issue tracker](https://github.com/pmd/pmd/issues)! * The new java rule {% rule java/errorprone/CollectionTypeMismatch %} detects calls to collection methods where we suspect the types are incompatible. This happens for instance when you try to remove a `String` from a `Collection`: although it is allowed - to write this because `remove` takes an `Object` parameter, it is most likely a mistake. + to write this because `remove` takes an `Object` parameter, it is most likely a mistake. + This rule is referenced in the quickstart.xml ruleset for Java. * The new java rule {% rule java/documentation/DanglingJavadoc %} finds Javadoc comments that do not belong to a class, method or field. These comments are ignored by the Javadoc tool and should either be corrected or removed. @@ -91,7 +92,7 @@ See [Report formats for CPD]({{ baseurl }}pmd_userdocs_cpd_report_formats.html#m * apex-codestyle * [#5650](https://github.com/pmd/pmd/issues/5650): \[apex] New Rule: AnnotationsNamingConventions * core - * [#4721](https://github.com/pmd/pmd/issues/4721): chore: \[core] Enable XML rule MissingEncoding in dogfood ruleset + * [#4721](https://github.com/pmd/pmd/issues/4721): \[core] chore: Enable XML rule MissingEncoding in dogfood ruleset * [#5849](https://github.com/pmd/pmd/issues/5849): \[core] Support Markdown Output for CPD Reports * [#5958](https://github.com/pmd/pmd/issues/5958): \[core] CSVRenderer: Add begin and end for line and columns (default off) * java @@ -207,9 +208,42 @@ See [Testing your rules]({{ baseurl }}pmd_userdocs_extending_testing.html) for m ### ๐Ÿ“ฆ Dependency updates +* [#5936](https://github.com/pmd/pmd/pull/5936): Bump PMD from 7.15.0 to 7.16.0 +* [#5937](https://github.com/pmd/pmd/pull/5937): Bump pmdtester from 1.5.5 to 1.6.0 +* [#5941](https://github.com/pmd/pmd/pull/5941): chore(deps): bump org.apache.commons:commons-text from 1.13.1 to 1.14.0 +* [#5944](https://github.com/pmd/pmd/pull/5944): chore(deps): bump io.github.apex-dev-tools:apex-ls_2.13 from 5.9.0 to 5.10.0 +* [#5945](https://github.com/pmd/pmd/pull/5945): chore(deps): bump org.junit:junit-bom from 5.13.3 to 5.13.4 +* [#5946](https://github.com/pmd/pmd/pull/5946): chore(deps): bump org.apache.groovy:groovy from 4.0.27 to 4.0.28 +* [#5962](https://github.com/pmd/pmd/pull/5962): chore(deps): bump scalameta.version from 4.13.8 to 4.13.9 +* [#5963](https://github.com/pmd/pmd/pull/5963): chore(deps-dev): bump org.apache.commons:commons-compress from 1.27.1 to 1.28.0 +* [#5976](https://github.com/pmd/pmd/pull/5976): chore(deps-dev): bump all-contributors-cli from 6.20.0 to 6.26.1 +* [#5978](https://github.com/pmd/pmd/pull/5978): chore(deps-dev): bump org.assertj:assertj-core from 3.27.3 to 3.27.4 +* [#5984](https://github.com/pmd/pmd/pull/5984): chore(deps): bump actions/checkout from 4.2.2 to 5.0.0 +* [#5985](https://github.com/pmd/pmd/pull/5985): chore(deps): bump ruby/setup-ruby from 1.254.0 to 1.255.0 +* [#5986](https://github.com/pmd/pmd/pull/5986): chore(deps): bump actions/create-github-app-token from 2.0.6 to 2.1.1 +* [#5988](https://github.com/pmd/pmd/pull/5988): chore(deps): Bump build-tools from 33 to 34 +* [#5990](https://github.com/pmd/pmd/pull/5990): chore(deps): Update @babel/runtime from 7.16.7 to 7.28.7 +* [#5991](https://github.com/pmd/pmd/pull/5991): chore(deps): Update tmp from 0.0.33 to 0.2.5 +* [#5997](https://github.com/pmd/pmd/pull/5997): chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.17.6 to 1.17.7 +* [#5998](https://github.com/pmd/pmd/pull/5998): chore(deps): bump kotlin.version from 2.2.0 to 2.2.10 +* [#5999](https://github.com/pmd/pmd/pull/5999): chore(deps): bump org.mockito:mockito-core from 5.18.0 to 5.19.0 +* [#6000](https://github.com/pmd/pmd/pull/6000): chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.17.6 to 1.17.7 +* [#6001](https://github.com/pmd/pmd/pull/6001): chore(deps): bump com.google.protobuf:protobuf-java from 4.31.1 to 4.32.0 +* [#6002](https://github.com/pmd/pmd/pull/6002): chore(deps): bump org.apache.maven.plugins:maven-javadoc-plugin from 3.11.2 to 3.11.3 +* [#6013](https://github.com/pmd/pmd/pull/6013): chore(deps): bump actions/setup-java from 4.7.1 to 5.0.0 +* [#6033](https://github.com/pmd/pmd/pull/6033): chore(deps): bump ruby/setup-ruby from 1.255.0 to 1.257.0 +* [#6044](https://github.com/pmd/pmd/pull/6044): chore(deps): bump org.sonarsource.scanner.maven:sonar-maven-plugin from 5.1.0.4751 to 5.2.0.4988 +* [#6045](https://github.com/pmd/pmd/pull/6045): chore(deps): bump org.jetbrains:annotations from 26.0.2 to 26.0.2-1 +* [#6046](https://github.com/pmd/pmd/pull/6046): chore(deps): bump org.apache.groovy:groovy from 4.0.28 to 5.0.0 +* [#6047](https://github.com/pmd/pmd/pull/6047): chore(deps): bump org.yaml:snakeyaml from 2.4 to 2.5 +* [#6048](https://github.com/pmd/pmd/pull/6048): chore(deps): bump org.codehaus.mojo:versions-maven-plugin from 2.18.0 to 2.19.0 +* [#6049](https://github.com/pmd/pmd/pull/6049): chore(deps): bump org.jsoup:jsoup from 1.21.1 to 1.21.2 +* [#6050](https://github.com/pmd/pmd/pull/6050): chore(deps): bump bigdecimal from 3.2.2 to 3.2.3 in /docs ### ๐Ÿ“ˆ Stats +* 188 commits +* 65 closed tickets & PRs +* Days since last release: 49 {% endtocmaker %} - diff --git a/pmd-java/src/main/resources/rulesets/java/quickstart.xml b/pmd-java/src/main/resources/rulesets/java/quickstart.xml index faac9e0432a..18d886fbea9 100644 --- a/pmd-java/src/main/resources/rulesets/java/quickstart.xml +++ b/pmd-java/src/main/resources/rulesets/java/quickstart.xml @@ -217,6 +217,7 @@ + From d2942d5ded8e3f967ba8872f3dc58a7bdffa73bf Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 12 Sep 2025 09:36:48 +0200 Subject: [PATCH 1360/1962] [release] prepare release pmd_releases/7.17.0 --- pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-css/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-rust/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 6 +++--- 44 files changed, 46 insertions(+), 46 deletions(-) diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index f0cc4b70221..a0d19036c56 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.17.0-SNAPSHOT + 7.17.0 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 8a9639e59ab..7551a2b1a85 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index 4a4fd8e0412..a6e319f6395 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index 2a0c6a6c03c..6cdbf6c697e 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index 3f37627e79c..d2ad0dce5ff 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index 1720cf00cf8..6e31899349b 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index 2227a63bf15..0f82448ca3e 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-css/pom.xml b/pmd-css/pom.xml index 222cb3c91fe..2ddf3ad4026 100644 --- a/pmd-css/pom.xml +++ b/pmd-css/pom.xml @@ -9,7 +9,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index 4e66fef3d68..b9533702c61 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index 63170d36759..82c015859e4 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index ba8bddddc32..8f7cb32296d 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index 739a49aeb15..5dc8e44a75c 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index 141a3d96c99..5a872ee19c4 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index 94021c721f0..1a126c78517 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index ca0478806cd..0b5fd3ad190 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index fdd0b180321..8a06dfbd8f8 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 9ed75b3cb9f..dccfbb578ed 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index e5d58ce6c0f..83b176def3a 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index 3fc79d1543c..badd90ab80c 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index c51620f863a..cfbb0478a25 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index 233531fca5e..3e69e2f6804 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index dd1890a177a..2cafd6d49d1 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index b7dc600d7d6..926d3942452 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index 55d01fa6ebc..e5c0c6652fd 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index 86126c8a68c..2f5cc166116 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index 32e1524fb37..481eb59d670 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index 7d1381c9633..a85f004ec0c 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index 09660f11983..cf439647aeb 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index 052b8250dfe..41701ee8e4f 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index 884ab0872be..c93d229f624 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index 1b6c5193225..63f0884fd19 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index 7f9355b6e35..29524493fff 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index 902f5bbf849..d13f7bcbdf1 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index 05139a5d96e..c10666933e9 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index 7ae9b846cab..240f0cf647c 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.17.0-SNAPSHOT + 7.17.0 ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index fdcee740f4e..aa731525d5b 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.17.0-SNAPSHOT + 7.17.0 ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index 9e92ecbd6a6..447efb402df 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index a6cf52a5a2c..a7459e23590 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index 9f44f04163c..2c23a9f428a 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index f2aad36c477..101c07feacc 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index d596407f894..4cf7d6fb6a2 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index d91e98a2874..65fbea469b8 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index 7df66cd92d4..a0ab38be5ac 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 ../pom.xml diff --git a/pom.xml b/pom.xml index e7d43f8060a..80cb8cff38e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.17.0-SNAPSHOT + 7.17.0 pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - HEAD + pmd_releases/7.17.0 PMD @@ -73,7 +73,7 @@ - 2025-07-25T06:06:19Z + 2025-09-12T07:17:26Z 8 From 7b142249a406d3f34256afb73f789055f7188671 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 12 Sep 2025 10:26:29 +0200 Subject: [PATCH 1361/1962] [release] Prepare next development version --- docs/_config.yml | 6 +- docs/pages/release_notes.md | 210 +---------------- docs/pages/release_notes_old.md | 249 +++++++++++++++++++++ pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-css/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-rust/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 4 +- 47 files changed, 298 insertions(+), 257 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 0bfe9485184..4c140d5813a 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,9 +1,9 @@ repository: pmd/pmd pmd: - version: 7.17.0 - previous_version: 7.16.0 - date: 2025-09-12 + version: 7.18.0-SNAPSHOT + previous_version: 7.17.0 + date: 2025-10-31 # release types: major, minor, bugfix release_type: minor diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 357852f56a0..0c9c0dd3524 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -24,226 +24,18 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy -#### โœจ New Rules - -This release brings several new rules for both Java and Apex. Please try them out -and submit feedback on [our issue tracker](https://github.com/pmd/pmd/issues)! - -* The new apex rule {% rule apex/codestyle/AnnotationsNamingConventions %} enforces that annotations - are used consistently in PascalCase. - The rule is referenced in the quickstart.xml ruleset for Apex. -* The new java rule {% rule java/codestyle/TypeParameterNamingConventions %} replaces the now deprecated rule - GenericsNaming. The new rule is configurable and checks for naming conventions of type parameters in - generic types and methods. It can be configured via a regular expression. - By default, this rule uses the standard Java naming convention (single uppercase letter). - The rule is referenced in the quickstart.xml ruleset for Java. -* The new java rule {% rule java/errorprone/OverrideBothEqualsAndHashCodeOnComparable %} finds missing - `hashCode()` and/or `equals()` methods on types that implement `Comparable`. This is important if - instances of these classes are used in collections. Failing to do so can lead to unexpected behavior in sets - which then do not conform to the `Set` interface. While the `Set` interface relies on - `equals()` to determine object equality, sorted sets like `TreeSet` use - `compareTo()` instead. The same issue can arise when such objects are used - as keys in sorted maps. - This rule is very similar to {% rule java/errorprone/OverrideBothEqualsAndHashcode %} which has always been - skipping `Comparable` and only reports if one of the two methods is missing. The new rule will also report, - if both methods (hashCode and equals) are missing. - The rule is referenced in the quickstart.xml ruleset for Java. -* The new java rule {% rule java/errorprone/UselessPureMethodCall %} finds method calls of pure methods - whose result is not used. Ignoring the result of such method calls is likely as mistake as pure - methods are side effect free. - The rule is referenced in the quickstart.xml ruleset for Java. -* The new java rule {% rule java/bestpractices/RelianceOnDefaultCharset %} finds method calls that - depend on the JVM's default charset. Using these method without specifying the charset explicitly - can lead to unexpected behavior on different platforms. -* Thew new java rule {% rule java/codestyle/VariableCanBeInlined %} finds local variables that are - immediately returned or thrown. This rule replaces the old rule {% rule java/codestyle/UnnecessaryLocalBeforeReturn %} - which only considered return statements. The new rule also finds unnecessary local variables - before throw statements. - The rule is referenced in the quickstart.xml ruleset for Java. -* The new java rule {% rule java/errorprone/CollectionTypeMismatch %} detects calls to - collection methods where we suspect the types are incompatible. This happens for instance - when you try to remove a `String` from a `Collection`: although it is allowed - to write this because `remove` takes an `Object` parameter, it is most likely a mistake. - This rule is referenced in the quickstart.xml ruleset for Java. -* The new java rule {% rule java/documentation/DanglingJavadoc %} finds Javadoc comments that - do not belong to a class, method or field. These comments are ignored by the Javadoc tool - and should either be corrected or removed. - The rule is referenced in the quickstart.xml ruleset for Java. -* The new java rule {% rule java/codestyle/ModifierOrder %} (`codestyle`) finds incorrectly ordered modifiers - (e.g., `static public` instead of `public static`). It ensures modifiers appear in the correct order as - recommended by the Java Language Specification. - -#### Deprecated Rules -* The java rule {% rule java/codestyle/GenericsNaming %} has been deprecated for removal in favor - of the new rule {% rule java/codestyle/TypeParameterNamingConventions %}. -* The java rule {% rule java/errorprone/AvoidLosingExceptionInformation %} has been deprecated for removal - in favor of the new rule {% rule java/errorprone/UselessPureMethodCall %}. -* The java rule {% rule java/errorprone/UselessOperationOnImmutable %} has been deprecated for removal - in favor of the new rule {% rule java/errorprone/UselessPureMethodCall %}. -* The java rule {% rule java/codestyle/UnnecessaryLocalBeforeReturn %} has been deprecated for removal - in favor of the new rule {% rule java/codestyle/VariableCanBeInlined %}. - -#### CPD: New Markdown Report Format -This PMD version ships with a simple Markdown based output format for CPD. It outputs all duplications -one after another including the code snippets as code blocks. -See [Report formats for CPD]({{ baseurl }}pmd_userdocs_cpd_report_formats.html#markdown). - ### ๐Ÿ› Fixed Issues -* apex-codestyle - * [#5650](https://github.com/pmd/pmd/issues/5650): \[apex] New Rule: AnnotationsNamingConventions -* core - * [#4721](https://github.com/pmd/pmd/issues/4721): \[core] chore: Enable XML rule MissingEncoding in dogfood ruleset - * [#5849](https://github.com/pmd/pmd/issues/5849): \[core] Support Markdown Output for CPD Reports - * [#5958](https://github.com/pmd/pmd/issues/5958): \[core] CSVRenderer: Add begin and end for line and columns (default off) -* java - * [#5874](https://github.com/pmd/pmd/issues/5874): \[java] Update java regression tests with Java 25 language features - * [#5960](https://github.com/pmd/pmd/issues/5960): \[java] Avoid/reduce duplicate error messages for some rules - * [#6014](https://github.com/pmd/pmd/issues/6014): \[java] Crash when encountering a java comment at the end of a file -* java-bestpractices - * [#2186](https://github.com/pmd/pmd/issues/2186): \[java] New Rule: RelianceOnDefaultCharset - * [#4500](https://github.com/pmd/pmd/issues/4500): \[java] AvoidReassigningLoopVariables - false negatives within for-loops and skip allowed - * [#4770](https://github.com/pmd/pmd/issues/4770): \[java] UnusedFormalParameter should ignore public constructor as same as method - * [#5198](https://github.com/pmd/pmd/issues/5198): \[java] CheckResultSet false-positive with local variable checked in a while loop -* java-codestyle - * [#972](https://github.com/pmd/pmd/issues/972): \[java] Improve naming conventions rules - * [#4916](https://github.com/pmd/pmd/issues/4916): \[java] UseExplicitTypes: cases where 'var' should be unobjectionable - * [#5601](https://github.com/pmd/pmd/issues/5601): \[java] New Rule: ModifierOrder - * [#5770](https://github.com/pmd/pmd/issues/5770): \[java] New Rule: VariableCanBeInlined: Local variables should not be declared and then immediately returned or thrown - * [#5922](https://github.com/pmd/pmd/issues/5922): \[java] New Rule: TypeParameterNamingConventions - * [#5948](https://github.com/pmd/pmd/issues/5948): \[java] UnnecessaryBoxing false positive when calling `List.remove(int)` - * [#5982](https://github.com/pmd/pmd/issues/5982): \[java] More detailed message for the UselessParentheses rule -* java-design - * [#4911](https://github.com/pmd/pmd/issues/4911): \[java] AvoidRethrowingException should allow rethrowing exception subclasses - * [#5023](https://github.com/pmd/pmd/issues/5023): \[java] UseUtilityClass implementation hardcodes a message instead of using the one defined in the XML -* java-documentation - * [#5916](https://github.com/pmd/pmd/issues/5916): \[java] New Rule: DanglingJavadoc -* java-errorprone - * [#3401](https://github.com/pmd/pmd/issues/3401): \[java] Improve AvoidUsingOctalValues documentation - * [#3434](https://github.com/pmd/pmd/issues/3434): \[java] False negatives in AssignmentInOperand Rule - * [#5837](https://github.com/pmd/pmd/issues/5837): \[java] New Rule: OverrideBothEqualsAndHashCodeOnComparable - * [#5881](https://github.com/pmd/pmd/issues/5881): \[java] AvoidLosingExceptionInformation does not trigger when inside if-else - * [#5907](https://github.com/pmd/pmd/issues/5907): \[java] New Rule: UselessPureMethodCall - * [#5915](https://github.com/pmd/pmd/issues/5915): \[java] AssignmentInOperand not raised when inside do-while loop - * [#5949](https://github.com/pmd/pmd/issues/5949): \[java] New Rule: CollectionTypeMismatch: for Collections methods that take Object as a parameter - * [#5974](https://github.com/pmd/pmd/issues/5974): \[java] CloseResourceRule: NullPointerException while analyzing -* test - * [#5973](https://github.com/pmd/pmd/issues/5973): \[test] Enable XML validation for rule tests ### ๐Ÿšจ API Changes -#### Deprecations -* pmd-java: - * {%jdoc !!java::lang.java.symbols.JClassSymbol#annotationAppliesTo(java.lang.annotation.ElementType) %}: Use - {%jdoc !!java::lang.java.symbols.JClassSymbol#annotationAppliesToContext(java.lang.annotation.ElementType,core::lang.LanguageVersion) %} - instead. -#### Experimental API -* pmd-core: {%jdoc !!core::reporting.RuleContext#addViolationWithPosition(core::lang.ast.Node,core::lang.ast.impl.javacc.JavaccToken,java.lang.String,java.lang.Object...) %} - -#### PMD Report Format CSV -The CSV report format for PMD as three new columns: - -* End Line -* Begin Column -* End Column - -These columns are not enabled by default, but can be activated via their respective renderer properties. -See [Report formats for PMD]({{ baseurl }}pmd_userdocs_report_formats.html#csv). - -#### Rule Test Schema -When executing rule tests, the rule test XML file will be validated against the schema and the tests will fail -if the XML file is invalid. - -There was a small bug in the schema around verifying suppressed violations: If a test wanted to verify, that there -are _no_ suppressed violations, then this was not possible. Now the `` element may be -empty. This is available in version 1.1.1 of the schema. -See [Testing your rules]({{ baseurl }}pmd_userdocs_extending_testing.html) for more information. - -#### Deprecations -* test - * The method {%jdoc !!test::test.lang.rule.AbstractRuleSetFactoryTest#hasCorrectEncoding(java.lang.String) %} will be removed. - PMD has the rule {% rule xml/bestpractices/MissingEncoding %} for XML files that should be used instead. ### โœจ Merged pull requests -* [#5601](https://github.com/pmd/pmd/pull/5601): \[java] New Rule: ModifierOrder - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#5822](https://github.com/pmd/pmd/pull/5822): \[apex] Fix #5650: New Rule: AnnotationsNamingConventions - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) -* [#5847](https://github.com/pmd/pmd/pull/5847): \[java] Fix #5770: New Rule: VariableCanBeInlined - [Vincent Potucek](https://github.com/Pankraz76) (@Pankraz76) -* [#5856](https://github.com/pmd/pmd/pull/5856): \[java] Fix #5837: New Rule: OverrideBothEqualsAndHashCodeOnComparable - [Vincent Potucek](https://github.com/Pankraz76) (@Pankraz76) -* [#5907](https://github.com/pmd/pmd/pull/5907): \[java] New Rule: UselessPureMethodCall - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#5916](https://github.com/pmd/pmd/pull/5916): \[java] New Rule: DanglingJavadoc - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#5922](https://github.com/pmd/pmd/pull/5922): \[java] Fix #972: Add a new rule TypeParameterNamingConventions - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#5924](https://github.com/pmd/pmd/pull/5924): \[java] Fix #5915: Fix AssignmentInOperandRule to also work an do-while loops and switch statements - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#5930](https://github.com/pmd/pmd/pull/5930): \[java] Fix #4500: Fix AvoidReassigningLoopVariablesRule to allow only simple assignments in the forReassign=skip case - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#5931](https://github.com/pmd/pmd/pull/5931): \[java] Fix #5023: Fix UseUtilityClassRule to use the message provided in design.xml - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#5932](https://github.com/pmd/pmd/pull/5932): \[ci] Reuse GitHub Pre-Releases - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5933](https://github.com/pmd/pmd/pull/5933): \[test] Fix QuickstartRulesetTests to detect deprecated rules again - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5934](https://github.com/pmd/pmd/pull/5934): \[java] Fix #2186: New Rule: RelianceOnDefaultCharset - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#5938](https://github.com/pmd/pmd/pull/5938): \[doc] Update suppression docs to reflect PMD 7 changes - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#5939](https://github.com/pmd/pmd/pull/5939): \[java] Fix #5198: CheckResultSet FP when local variable is checked - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) -* [#5954](https://github.com/pmd/pmd/pull/5954): \[core] Fix #4721: Enable XML rule MissingEncoding in dogfood ruleset - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5955](https://github.com/pmd/pmd/pull/5955): chore: Fix LiteralsFirstInComparison violations in test code - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5957](https://github.com/pmd/pmd/pull/5957): \[java] Fix #3401: Improve message/description/examples for AvoidUsingOctalValues - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#5958](https://github.com/pmd/pmd/pull/5958): \[core] CSVRenderer: Add begin and end for line and columns (default off) - [Jude Pereira](https://github.com/judepereira) (@judepereira) -* [#5959](https://github.com/pmd/pmd/pull/5959): \[java] Fix #5960: AddEmptyString: Improve report location - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#5961](https://github.com/pmd/pmd/pull/5961): \[java] Fix #5960: Add details to the error message for some rules - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#5965](https://github.com/pmd/pmd/pull/5965): \[java] Fix #5881: AvoidLosingException - Consider nested method calls - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5967](https://github.com/pmd/pmd/pull/5967): \[doc]\[java] ReplaceJavaUtilDate - improve doc to mention java.sql.Date - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5968](https://github.com/pmd/pmd/pull/5968): \[doc] Add logging page to sidebar under dev docs - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5969](https://github.com/pmd/pmd/pull/5969): \[doc] Add CSS in PMD's description - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5970](https://github.com/pmd/pmd/pull/5970): chore: CI improvements - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5971](https://github.com/pmd/pmd/pull/5971): \[java] Fix #5948: UnnecessaryBoxingRule: Check if unboxing is required for overload resolution - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#5972](https://github.com/pmd/pmd/pull/5972): \[java] Fix #3434: False negatives in AssignmentInOperand rule - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#5975](https://github.com/pmd/pmd/pull/5975): \[test] Fix #5973: Enable XML Validation for rule tests - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5979](https://github.com/pmd/pmd/pull/5979): \[java] Fix #5974: NPE in CloseResourceRule - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) -* [#5980](https://github.com/pmd/pmd/pull/5980): chore: Fix typos - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#5981](https://github.com/pmd/pmd/pull/5981): \[java] Fix #4911: AvoidRethrowingException consider supertypes in following catches - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#5982](https://github.com/pmd/pmd/pull/5982): \[java] More detailed message for the UselessParentheses rule - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#5989](https://github.com/pmd/pmd/pull/5989): \[java] Improve performance of RelianceOnDefaultCharset - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#5994](https://github.com/pmd/pmd/pull/5994): \[java] Fix #4770: UnusedFormalParameter should ignore public constructor as same as method - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#5995](https://github.com/pmd/pmd/pull/5995): \[html] Add test case that tests the end of a reported violation (test for #3951) - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#5996](https://github.com/pmd/pmd/pull/5996): \[java] Fix #4916: UseExplicitTypes cases where 'var' should be unobjectionable - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#6006](https://github.com/pmd/pmd/pull/6006): \[java] Fix #5949: New Rule: CollectionTypeMismatch - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#6008](https://github.com/pmd/pmd/pull/6008): \[core] Fix #5849: Support Markdown Output for CPD Reports - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) -* [#6009](https://github.com/pmd/pmd/pull/6009): \[java] More detailed message for AvoidInstanceofChecksInCatchClause - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#6016](https://github.com/pmd/pmd/pull/6016): \[java] Fix #6014: Crash when encountering a java comment at the end of a file - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) ### ๐Ÿ“ฆ Dependency updates -* [#5936](https://github.com/pmd/pmd/pull/5936): Bump PMD from 7.15.0 to 7.16.0 -* [#5937](https://github.com/pmd/pmd/pull/5937): Bump pmdtester from 1.5.5 to 1.6.0 -* [#5941](https://github.com/pmd/pmd/pull/5941): chore(deps): bump org.apache.commons:commons-text from 1.13.1 to 1.14.0 -* [#5944](https://github.com/pmd/pmd/pull/5944): chore(deps): bump io.github.apex-dev-tools:apex-ls_2.13 from 5.9.0 to 5.10.0 -* [#5945](https://github.com/pmd/pmd/pull/5945): chore(deps): bump org.junit:junit-bom from 5.13.3 to 5.13.4 -* [#5946](https://github.com/pmd/pmd/pull/5946): chore(deps): bump org.apache.groovy:groovy from 4.0.27 to 4.0.28 -* [#5962](https://github.com/pmd/pmd/pull/5962): chore(deps): bump scalameta.version from 4.13.8 to 4.13.9 -* [#5963](https://github.com/pmd/pmd/pull/5963): chore(deps-dev): bump org.apache.commons:commons-compress from 1.27.1 to 1.28.0 -* [#5976](https://github.com/pmd/pmd/pull/5976): chore(deps-dev): bump all-contributors-cli from 6.20.0 to 6.26.1 -* [#5978](https://github.com/pmd/pmd/pull/5978): chore(deps-dev): bump org.assertj:assertj-core from 3.27.3 to 3.27.4 -* [#5984](https://github.com/pmd/pmd/pull/5984): chore(deps): bump actions/checkout from 4.2.2 to 5.0.0 -* [#5985](https://github.com/pmd/pmd/pull/5985): chore(deps): bump ruby/setup-ruby from 1.254.0 to 1.255.0 -* [#5986](https://github.com/pmd/pmd/pull/5986): chore(deps): bump actions/create-github-app-token from 2.0.6 to 2.1.1 -* [#5988](https://github.com/pmd/pmd/pull/5988): chore(deps): Bump build-tools from 33 to 34 -* [#5990](https://github.com/pmd/pmd/pull/5990): chore(deps): Update @babel/runtime from 7.16.7 to 7.28.7 -* [#5991](https://github.com/pmd/pmd/pull/5991): chore(deps): Update tmp from 0.0.33 to 0.2.5 -* [#5997](https://github.com/pmd/pmd/pull/5997): chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.17.6 to 1.17.7 -* [#5998](https://github.com/pmd/pmd/pull/5998): chore(deps): bump kotlin.version from 2.2.0 to 2.2.10 -* [#5999](https://github.com/pmd/pmd/pull/5999): chore(deps): bump org.mockito:mockito-core from 5.18.0 to 5.19.0 -* [#6000](https://github.com/pmd/pmd/pull/6000): chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.17.6 to 1.17.7 -* [#6001](https://github.com/pmd/pmd/pull/6001): chore(deps): bump com.google.protobuf:protobuf-java from 4.31.1 to 4.32.0 -* [#6002](https://github.com/pmd/pmd/pull/6002): chore(deps): bump org.apache.maven.plugins:maven-javadoc-plugin from 3.11.2 to 3.11.3 -* [#6013](https://github.com/pmd/pmd/pull/6013): chore(deps): bump actions/setup-java from 4.7.1 to 5.0.0 -* [#6033](https://github.com/pmd/pmd/pull/6033): chore(deps): bump ruby/setup-ruby from 1.255.0 to 1.257.0 -* [#6044](https://github.com/pmd/pmd/pull/6044): chore(deps): bump org.sonarsource.scanner.maven:sonar-maven-plugin from 5.1.0.4751 to 5.2.0.4988 -* [#6045](https://github.com/pmd/pmd/pull/6045): chore(deps): bump org.jetbrains:annotations from 26.0.2 to 26.0.2-1 -* [#6046](https://github.com/pmd/pmd/pull/6046): chore(deps): bump org.apache.groovy:groovy from 4.0.28 to 5.0.0 -* [#6047](https://github.com/pmd/pmd/pull/6047): chore(deps): bump org.yaml:snakeyaml from 2.4 to 2.5 -* [#6048](https://github.com/pmd/pmd/pull/6048): chore(deps): bump org.codehaus.mojo:versions-maven-plugin from 2.18.0 to 2.19.0 -* [#6049](https://github.com/pmd/pmd/pull/6049): chore(deps): bump org.jsoup:jsoup from 1.21.1 to 1.21.2 -* [#6050](https://github.com/pmd/pmd/pull/6050): chore(deps): bump bigdecimal from 3.2.2 to 3.2.3 in /docs ### ๐Ÿ“ˆ Stats -* 188 commits -* 65 closed tickets & PRs -* Days since last release: 49 {% endtocmaker %} + diff --git a/docs/pages/release_notes_old.md b/docs/pages/release_notes_old.md index 462cb5c1c51..fa93d9607f2 100644 --- a/docs/pages/release_notes_old.md +++ b/docs/pages/release_notes_old.md @@ -7,6 +7,255 @@ Previous versions of PMD can be downloaded here: [Releases - pmd/pmd (GitHub)](h +## 12-September-2025 - 7.17.0 + +The PMD team is pleased to announce PMD 7.17.0. + +This is a minor release. + +### Table Of Contents + +* [๐Ÿš€ New and noteworthy](#new-and-noteworthy) + * [โœจ New Rules](#new-rules) + * [Deprecated Rules](#deprecated-rules) + * [CPD: New Markdown Report Format](#cpd-new-markdown-report-format) +* [๐Ÿ› Fixed Issues](#fixed-issues) +* [๐Ÿšจ API Changes](#api-changes) + * [Deprecations](#deprecations) + * [Experimental API](#experimental-api) + * [PMD Report Format CSV](#pmd-report-format-csv) + * [Rule Test Schema](#rule-test-schema) + * [Deprecations](#deprecations) +* [โœจ Merged pull requests](#merged-pull-requests) +* [๐Ÿ“ฆ Dependency updates](#dependency-updates) +* [๐Ÿ“ˆ Stats](#stats) + +### ๐Ÿš€ New and noteworthy + +#### โœจ New Rules + +This release brings several new rules for both Java and Apex. Please try them out +and submit feedback on [our issue tracker](https://github.com/pmd/pmd/issues)! + +* The new apex rule [`AnnotationsNamingConventions`](https://docs.pmd-code.org/pmd-doc-7.17.0/pmd_rules_apex_codestyle.html#annotationsnamingconventions) enforces that annotations + are used consistently in PascalCase. + The rule is referenced in the quickstart.xml ruleset for Apex. +* The new java rule [`TypeParameterNamingConventions`](https://docs.pmd-code.org/pmd-doc-7.17.0/pmd_rules_java_codestyle.html#typeparameternamingconventions) replaces the now deprecated rule + GenericsNaming. The new rule is configurable and checks for naming conventions of type parameters in + generic types and methods. It can be configured via a regular expression. + By default, this rule uses the standard Java naming convention (single uppercase letter). + The rule is referenced in the quickstart.xml ruleset for Java. +* The new java rule [`OverrideBothEqualsAndHashCodeOnComparable`](https://docs.pmd-code.org/pmd-doc-7.17.0/pmd_rules_java_errorprone.html#overridebothequalsandhashcodeoncomparable) finds missing + `hashCode()` and/or `equals()` methods on types that implement `Comparable`. This is important if + instances of these classes are used in collections. Failing to do so can lead to unexpected behavior in sets + which then do not conform to the `Set` interface. While the `Set` interface relies on + `equals()` to determine object equality, sorted sets like `TreeSet` use + `compareTo()` instead. The same issue can arise when such objects are used + as keys in sorted maps. + This rule is very similar to [`OverrideBothEqualsAndHashcode`](https://docs.pmd-code.org/pmd-doc-7.17.0/pmd_rules_java_errorprone.html#overridebothequalsandhashcode) which has always been + skipping `Comparable` and only reports if one of the two methods is missing. The new rule will also report, + if both methods (hashCode and equals) are missing. + The rule is referenced in the quickstart.xml ruleset for Java. +* The new java rule [`UselessPureMethodCall`](https://docs.pmd-code.org/pmd-doc-7.17.0/pmd_rules_java_errorprone.html#uselesspuremethodcall) finds method calls of pure methods + whose result is not used. Ignoring the result of such method calls is likely as mistake as pure + methods are side effect free. + The rule is referenced in the quickstart.xml ruleset for Java. +* The new java rule [`RelianceOnDefaultCharset`](https://docs.pmd-code.org/pmd-doc-7.17.0/pmd_rules_java_bestpractices.html#relianceondefaultcharset) finds method calls that + depend on the JVM's default charset. Using these method without specifying the charset explicitly + can lead to unexpected behavior on different platforms. +* Thew new java rule [`VariableCanBeInlined`](https://docs.pmd-code.org/pmd-doc-7.17.0/pmd_rules_java_codestyle.html#variablecanbeinlined) finds local variables that are + immediately returned or thrown. This rule replaces the old rule [`UnnecessaryLocalBeforeReturn`](https://docs.pmd-code.org/pmd-doc-7.17.0/pmd_rules_java_codestyle.html#unnecessarylocalbeforereturn) + which only considered return statements. The new rule also finds unnecessary local variables + before throw statements. + The rule is referenced in the quickstart.xml ruleset for Java. +* The new java rule [`CollectionTypeMismatch`](https://docs.pmd-code.org/pmd-doc-7.17.0/pmd_rules_java_errorprone.html#collectiontypemismatch) detects calls to + collection methods where we suspect the types are incompatible. This happens for instance + when you try to remove a `String` from a `Collection`: although it is allowed + to write this because `remove` takes an `Object` parameter, it is most likely a mistake. + This rule is referenced in the quickstart.xml ruleset for Java. +* The new java rule [`DanglingJavadoc`](https://docs.pmd-code.org/pmd-doc-7.17.0/pmd_rules_java_documentation.html#danglingjavadoc) finds Javadoc comments that + do not belong to a class, method or field. These comments are ignored by the Javadoc tool + and should either be corrected or removed. + The rule is referenced in the quickstart.xml ruleset for Java. +* The new java rule [`ModifierOrder`](https://docs.pmd-code.org/pmd-doc-7.17.0/pmd_rules_java_codestyle.html#modifierorder) (`codestyle`) finds incorrectly ordered modifiers + (e.g., `static public` instead of `public static`). It ensures modifiers appear in the correct order as + recommended by the Java Language Specification. + +#### Deprecated Rules +* The java rule [`GenericsNaming`](https://docs.pmd-code.org/pmd-doc-7.17.0/pmd_rules_java_codestyle.html#genericsnaming) has been deprecated for removal in favor + of the new rule [`TypeParameterNamingConventions`](https://docs.pmd-code.org/pmd-doc-7.17.0/pmd_rules_java_codestyle.html#typeparameternamingconventions). +* The java rule [`AvoidLosingExceptionInformation`](https://docs.pmd-code.org/pmd-doc-7.17.0/pmd_rules_java_errorprone.html#avoidlosingexceptioninformation) has been deprecated for removal + in favor of the new rule [`UselessPureMethodCall`](https://docs.pmd-code.org/pmd-doc-7.17.0/pmd_rules_java_errorprone.html#uselesspuremethodcall). +* The java rule [`UselessOperationOnImmutable`](https://docs.pmd-code.org/pmd-doc-7.17.0/pmd_rules_java_errorprone.html#uselessoperationonimmutable) has been deprecated for removal + in favor of the new rule [`UselessPureMethodCall`](https://docs.pmd-code.org/pmd-doc-7.17.0/pmd_rules_java_errorprone.html#uselesspuremethodcall). +* The java rule [`UnnecessaryLocalBeforeReturn`](https://docs.pmd-code.org/pmd-doc-7.17.0/pmd_rules_java_codestyle.html#unnecessarylocalbeforereturn) has been deprecated for removal + in favor of the new rule [`VariableCanBeInlined`](https://docs.pmd-code.org/pmd-doc-7.17.0/pmd_rules_java_codestyle.html#variablecanbeinlined). + +#### CPD: New Markdown Report Format +This PMD version ships with a simple Markdown based output format for CPD. It outputs all duplications +one after another including the code snippets as code blocks. +See [Report formats for CPD](https://docs.pmd-code.org/pmd-doc-7.17.0/pmd_userdocs_cpd_report_formats.html#markdown). + +### ๐Ÿ› Fixed Issues +* apex-codestyle + * [#5650](https://github.com/pmd/pmd/issues/5650): \[apex] New Rule: AnnotationsNamingConventions +* core + * [#4721](https://github.com/pmd/pmd/issues/4721): \[core] chore: Enable XML rule MissingEncoding in dogfood ruleset + * [#5849](https://github.com/pmd/pmd/issues/5849): \[core] Support Markdown Output for CPD Reports + * [#5958](https://github.com/pmd/pmd/issues/5958): \[core] CSVRenderer: Add begin and end for line and columns (default off) +* java + * [#5874](https://github.com/pmd/pmd/issues/5874): \[java] Update java regression tests with Java 25 language features + * [#5960](https://github.com/pmd/pmd/issues/5960): \[java] Avoid/reduce duplicate error messages for some rules + * [#6014](https://github.com/pmd/pmd/issues/6014): \[java] Crash when encountering a java comment at the end of a file +* java-bestpractices + * [#2186](https://github.com/pmd/pmd/issues/2186): \[java] New Rule: RelianceOnDefaultCharset + * [#4500](https://github.com/pmd/pmd/issues/4500): \[java] AvoidReassigningLoopVariables - false negatives within for-loops and skip allowed + * [#4770](https://github.com/pmd/pmd/issues/4770): \[java] UnusedFormalParameter should ignore public constructor as same as method + * [#5198](https://github.com/pmd/pmd/issues/5198): \[java] CheckResultSet false-positive with local variable checked in a while loop +* java-codestyle + * [#972](https://github.com/pmd/pmd/issues/972): \[java] Improve naming conventions rules + * [#4916](https://github.com/pmd/pmd/issues/4916): \[java] UseExplicitTypes: cases where 'var' should be unobjectionable + * [#5601](https://github.com/pmd/pmd/issues/5601): \[java] New Rule: ModifierOrder + * [#5770](https://github.com/pmd/pmd/issues/5770): \[java] New Rule: VariableCanBeInlined: Local variables should not be declared and then immediately returned or thrown + * [#5922](https://github.com/pmd/pmd/issues/5922): \[java] New Rule: TypeParameterNamingConventions + * [#5948](https://github.com/pmd/pmd/issues/5948): \[java] UnnecessaryBoxing false positive when calling `List.remove(int)` + * [#5982](https://github.com/pmd/pmd/issues/5982): \[java] More detailed message for the UselessParentheses rule +* java-design + * [#4911](https://github.com/pmd/pmd/issues/4911): \[java] AvoidRethrowingException should allow rethrowing exception subclasses + * [#5023](https://github.com/pmd/pmd/issues/5023): \[java] UseUtilityClass implementation hardcodes a message instead of using the one defined in the XML +* java-documentation + * [#5916](https://github.com/pmd/pmd/issues/5916): \[java] New Rule: DanglingJavadoc +* java-errorprone + * [#3401](https://github.com/pmd/pmd/issues/3401): \[java] Improve AvoidUsingOctalValues documentation + * [#3434](https://github.com/pmd/pmd/issues/3434): \[java] False negatives in AssignmentInOperand Rule + * [#5837](https://github.com/pmd/pmd/issues/5837): \[java] New Rule: OverrideBothEqualsAndHashCodeOnComparable + * [#5881](https://github.com/pmd/pmd/issues/5881): \[java] AvoidLosingExceptionInformation does not trigger when inside if-else + * [#5907](https://github.com/pmd/pmd/issues/5907): \[java] New Rule: UselessPureMethodCall + * [#5915](https://github.com/pmd/pmd/issues/5915): \[java] AssignmentInOperand not raised when inside do-while loop + * [#5949](https://github.com/pmd/pmd/issues/5949): \[java] New Rule: CollectionTypeMismatch: for Collections methods that take Object as a parameter + * [#5974](https://github.com/pmd/pmd/issues/5974): \[java] CloseResourceRule: NullPointerException while analyzing +* test + * [#5973](https://github.com/pmd/pmd/issues/5973): \[test] Enable XML validation for rule tests + +### ๐Ÿšจ API Changes +#### Deprecations +* pmd-java: + * JClassSymbol#annotationAppliesTo: Use + JClassSymbol#annotationAppliesToContext + instead. +#### Experimental API +* pmd-core: RuleContext#addViolationWithPosition + +#### PMD Report Format CSV +The CSV report format for PMD as three new columns: + +* End Line +* Begin Column +* End Column + +These columns are not enabled by default, but can be activated via their respective renderer properties. +See [Report formats for PMD](https://docs.pmd-code.org/pmd-doc-7.17.0/pmd_userdocs_report_formats.html#csv). + +#### Rule Test Schema +When executing rule tests, the rule test XML file will be validated against the schema and the tests will fail +if the XML file is invalid. + +There was a small bug in the schema around verifying suppressed violations: If a test wanted to verify, that there +are _no_ suppressed violations, then this was not possible. Now the `` element may be +empty. This is available in version 1.1.1 of the schema. +See [Testing your rules](https://docs.pmd-code.org/pmd-doc-7.17.0/pmd_userdocs_extending_testing.html) for more information. + +#### Deprecations +* test + * The method AbstractRuleSetFactoryTest#hasCorrectEncoding will be removed. + PMD has the rule [`MissingEncoding`](https://docs.pmd-code.org/pmd-doc-7.17.0/pmd_rules_xml_bestpractices.html#missingencoding) for XML files that should be used instead. + +### โœจ Merged pull requests + +* [#5601](https://github.com/pmd/pmd/pull/5601): \[java] New Rule: ModifierOrder - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#5822](https://github.com/pmd/pmd/pull/5822): \[apex] Fix #5650: New Rule: AnnotationsNamingConventions - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) +* [#5847](https://github.com/pmd/pmd/pull/5847): \[java] Fix #5770: New Rule: VariableCanBeInlined - [Vincent Potucek](https://github.com/Pankraz76) (@Pankraz76) +* [#5856](https://github.com/pmd/pmd/pull/5856): \[java] Fix #5837: New Rule: OverrideBothEqualsAndHashCodeOnComparable - [Vincent Potucek](https://github.com/Pankraz76) (@Pankraz76) +* [#5907](https://github.com/pmd/pmd/pull/5907): \[java] New Rule: UselessPureMethodCall - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#5916](https://github.com/pmd/pmd/pull/5916): \[java] New Rule: DanglingJavadoc - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#5922](https://github.com/pmd/pmd/pull/5922): \[java] Fix #972: Add a new rule TypeParameterNamingConventions - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5924](https://github.com/pmd/pmd/pull/5924): \[java] Fix #5915: Fix AssignmentInOperandRule to also work an do-while loops and switch statements - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5930](https://github.com/pmd/pmd/pull/5930): \[java] Fix #4500: Fix AvoidReassigningLoopVariablesRule to allow only simple assignments in the forReassign=skip case - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5931](https://github.com/pmd/pmd/pull/5931): \[java] Fix #5023: Fix UseUtilityClassRule to use the message provided in design.xml - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5932](https://github.com/pmd/pmd/pull/5932): \[ci] Reuse GitHub Pre-Releases - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5933](https://github.com/pmd/pmd/pull/5933): \[test] Fix QuickstartRulesetTests to detect deprecated rules again - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5934](https://github.com/pmd/pmd/pull/5934): \[java] Fix #2186: New Rule: RelianceOnDefaultCharset - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5938](https://github.com/pmd/pmd/pull/5938): \[doc] Update suppression docs to reflect PMD 7 changes - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#5939](https://github.com/pmd/pmd/pull/5939): \[java] Fix #5198: CheckResultSet FP when local variable is checked - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#5954](https://github.com/pmd/pmd/pull/5954): \[core] Fix #4721: Enable XML rule MissingEncoding in dogfood ruleset - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5955](https://github.com/pmd/pmd/pull/5955): chore: Fix LiteralsFirstInComparison violations in test code - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5957](https://github.com/pmd/pmd/pull/5957): \[java] Fix #3401: Improve message/description/examples for AvoidUsingOctalValues - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5958](https://github.com/pmd/pmd/pull/5958): \[core] CSVRenderer: Add begin and end for line and columns (default off) - [Jude Pereira](https://github.com/judepereira) (@judepereira) +* [#5959](https://github.com/pmd/pmd/pull/5959): \[java] Fix #5960: AddEmptyString: Improve report location - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#5961](https://github.com/pmd/pmd/pull/5961): \[java] Fix #5960: Add details to the error message for some rules - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#5965](https://github.com/pmd/pmd/pull/5965): \[java] Fix #5881: AvoidLosingException - Consider nested method calls - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5967](https://github.com/pmd/pmd/pull/5967): \[doc]\[java] ReplaceJavaUtilDate - improve doc to mention java.sql.Date - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5968](https://github.com/pmd/pmd/pull/5968): \[doc] Add logging page to sidebar under dev docs - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5969](https://github.com/pmd/pmd/pull/5969): \[doc] Add CSS in PMD's description - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5970](https://github.com/pmd/pmd/pull/5970): chore: CI improvements - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5971](https://github.com/pmd/pmd/pull/5971): \[java] Fix #5948: UnnecessaryBoxingRule: Check if unboxing is required for overload resolution - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5972](https://github.com/pmd/pmd/pull/5972): \[java] Fix #3434: False negatives in AssignmentInOperand rule - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5975](https://github.com/pmd/pmd/pull/5975): \[test] Fix #5973: Enable XML Validation for rule tests - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5979](https://github.com/pmd/pmd/pull/5979): \[java] Fix #5974: NPE in CloseResourceRule - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#5980](https://github.com/pmd/pmd/pull/5980): chore: Fix typos - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#5981](https://github.com/pmd/pmd/pull/5981): \[java] Fix #4911: AvoidRethrowingException consider supertypes in following catches - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5982](https://github.com/pmd/pmd/pull/5982): \[java] More detailed message for the UselessParentheses rule - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#5989](https://github.com/pmd/pmd/pull/5989): \[java] Improve performance of RelianceOnDefaultCharset - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5994](https://github.com/pmd/pmd/pull/5994): \[java] Fix #4770: UnusedFormalParameter should ignore public constructor as same as method - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5995](https://github.com/pmd/pmd/pull/5995): \[html] Add test case that tests the end of a reported violation (test for #3951) - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#5996](https://github.com/pmd/pmd/pull/5996): \[java] Fix #4916: UseExplicitTypes cases where 'var' should be unobjectionable - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6006](https://github.com/pmd/pmd/pull/6006): \[java] Fix #5949: New Rule: CollectionTypeMismatch - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6008](https://github.com/pmd/pmd/pull/6008): \[core] Fix #5849: Support Markdown Output for CPD Reports - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#6009](https://github.com/pmd/pmd/pull/6009): \[java] More detailed message for AvoidInstanceofChecksInCatchClause - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6016](https://github.com/pmd/pmd/pull/6016): \[java] Fix #6014: Crash when encountering a java comment at the end of a file - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) + +### ๐Ÿ“ฆ Dependency updates + +* [#5936](https://github.com/pmd/pmd/pull/5936): Bump PMD from 7.15.0 to 7.16.0 +* [#5937](https://github.com/pmd/pmd/pull/5937): Bump pmdtester from 1.5.5 to 1.6.0 +* [#5941](https://github.com/pmd/pmd/pull/5941): chore(deps): bump org.apache.commons:commons-text from 1.13.1 to 1.14.0 +* [#5944](https://github.com/pmd/pmd/pull/5944): chore(deps): bump io.github.apex-dev-tools:apex-ls_2.13 from 5.9.0 to 5.10.0 +* [#5945](https://github.com/pmd/pmd/pull/5945): chore(deps): bump org.junit:junit-bom from 5.13.3 to 5.13.4 +* [#5946](https://github.com/pmd/pmd/pull/5946): chore(deps): bump org.apache.groovy:groovy from 4.0.27 to 4.0.28 +* [#5962](https://github.com/pmd/pmd/pull/5962): chore(deps): bump scalameta.version from 4.13.8 to 4.13.9 +* [#5963](https://github.com/pmd/pmd/pull/5963): chore(deps-dev): bump org.apache.commons:commons-compress from 1.27.1 to 1.28.0 +* [#5976](https://github.com/pmd/pmd/pull/5976): chore(deps-dev): bump all-contributors-cli from 6.20.0 to 6.26.1 +* [#5978](https://github.com/pmd/pmd/pull/5978): chore(deps-dev): bump org.assertj:assertj-core from 3.27.3 to 3.27.4 +* [#5984](https://github.com/pmd/pmd/pull/5984): chore(deps): bump actions/checkout from 4.2.2 to 5.0.0 +* [#5985](https://github.com/pmd/pmd/pull/5985): chore(deps): bump ruby/setup-ruby from 1.254.0 to 1.255.0 +* [#5986](https://github.com/pmd/pmd/pull/5986): chore(deps): bump actions/create-github-app-token from 2.0.6 to 2.1.1 +* [#5988](https://github.com/pmd/pmd/pull/5988): chore(deps): Bump build-tools from 33 to 34 +* [#5990](https://github.com/pmd/pmd/pull/5990): chore(deps): Update @babel/runtime from 7.16.7 to 7.28.7 +* [#5991](https://github.com/pmd/pmd/pull/5991): chore(deps): Update tmp from 0.0.33 to 0.2.5 +* [#5997](https://github.com/pmd/pmd/pull/5997): chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.17.6 to 1.17.7 +* [#5998](https://github.com/pmd/pmd/pull/5998): chore(deps): bump kotlin.version from 2.2.0 to 2.2.10 +* [#5999](https://github.com/pmd/pmd/pull/5999): chore(deps): bump org.mockito:mockito-core from 5.18.0 to 5.19.0 +* [#6000](https://github.com/pmd/pmd/pull/6000): chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.17.6 to 1.17.7 +* [#6001](https://github.com/pmd/pmd/pull/6001): chore(deps): bump com.google.protobuf:protobuf-java from 4.31.1 to 4.32.0 +* [#6002](https://github.com/pmd/pmd/pull/6002): chore(deps): bump org.apache.maven.plugins:maven-javadoc-plugin from 3.11.2 to 3.11.3 +* [#6013](https://github.com/pmd/pmd/pull/6013): chore(deps): bump actions/setup-java from 4.7.1 to 5.0.0 +* [#6033](https://github.com/pmd/pmd/pull/6033): chore(deps): bump ruby/setup-ruby from 1.255.0 to 1.257.0 +* [#6044](https://github.com/pmd/pmd/pull/6044): chore(deps): bump org.sonarsource.scanner.maven:sonar-maven-plugin from 5.1.0.4751 to 5.2.0.4988 +* [#6045](https://github.com/pmd/pmd/pull/6045): chore(deps): bump org.jetbrains:annotations from 26.0.2 to 26.0.2-1 +* [#6046](https://github.com/pmd/pmd/pull/6046): chore(deps): bump org.apache.groovy:groovy from 4.0.28 to 5.0.0 +* [#6047](https://github.com/pmd/pmd/pull/6047): chore(deps): bump org.yaml:snakeyaml from 2.4 to 2.5 +* [#6048](https://github.com/pmd/pmd/pull/6048): chore(deps): bump org.codehaus.mojo:versions-maven-plugin from 2.18.0 to 2.19.0 +* [#6049](https://github.com/pmd/pmd/pull/6049): chore(deps): bump org.jsoup:jsoup from 1.21.1 to 1.21.2 +* [#6050](https://github.com/pmd/pmd/pull/6050): chore(deps): bump bigdecimal from 3.2.2 to 3.2.3 in /docs + +### ๐Ÿ“ˆ Stats + +* 188 commits +* 65 closed tickets & PRs +* Days since last release: 49 + + + ## 25-July-2025 - 7.16.0 The PMD team is pleased to announce PMD 7.16.0. diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index a0d19036c56..441d81c8218 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.17.0 + 7.18.0-SNAPSHOT 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 7551a2b1a85..21a347b37bc 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index a6e319f6395..037c3a2b6d4 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index 6cdbf6c697e..eed309d5bc7 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index d2ad0dce5ff..346033b6609 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index 6e31899349b..57d24fbeb1f 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index 0f82448ca3e..e685def3471 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-css/pom.xml b/pmd-css/pom.xml index 2ddf3ad4026..77e32daec39 100644 --- a/pmd-css/pom.xml +++ b/pmd-css/pom.xml @@ -9,7 +9,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index b9533702c61..bb602e339b4 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index 82c015859e4..cc8b1a3e27a 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index 8f7cb32296d..04a216feb29 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index 5dc8e44a75c..11850173a09 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index 5a872ee19c4..3626234cd90 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index 1a126c78517..3b3e0d31a3e 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index 0b5fd3ad190..68fd2736548 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index 8a06dfbd8f8..7056f919cae 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index dccfbb578ed..1024a030aa5 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index 83b176def3a..f930eb79366 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index badd90ab80c..64ebf7df5ff 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index cfbb0478a25..eebf33e5d79 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index 3e69e2f6804..b5a32bf8d76 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index 2cafd6d49d1..7491a6cba4d 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index 926d3942452..03ec69f1317 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index e5c0c6652fd..528e987ee15 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index 2f5cc166116..6df181160c9 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index 481eb59d670..c4e20044c71 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index a85f004ec0c..1aea3d70ffd 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index cf439647aeb..5f9b21d2841 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index 41701ee8e4f..c9346f08d8d 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index c93d229f624..47ebf5db7df 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index 63f0884fd19..0cd7295f344 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index 29524493fff..c0d85656197 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index d13f7bcbdf1..dce6f86609f 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index c10666933e9..ea78faf70a9 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index 240f0cf647c..fde399ff44d 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.17.0 + 7.18.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index aa731525d5b..99e4bd6381d 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.17.0 + 7.18.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index 447efb402df..442e0af959d 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index a7459e23590..97e7eb18d07 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index 2c23a9f428a..6b92ff7f318 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index 101c07feacc..b9ca7062cde 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index 4cf7d6fb6a2..15573942257 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index 65fbea469b8..f814fa0bc7f 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index a0ab38be5ac..5ffef1ff41e 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index 80cb8cff38e..abf0022026b 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.17.0 + 7.18.0-SNAPSHOT pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - pmd_releases/7.17.0 + HEAD PMD From 97d38cce1c2d2747aa8558050f674df6cc4dd33c Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Fri, 29 Aug 2025 22:35:51 +0200 Subject: [PATCH 1362/1962] Alphabetically sort all default rules --- .../resources/category/apex/bestpractices.xml | 50 ++-- .../resources/category/apex/codestyle.xml | 140 ++++----- .../main/resources/category/apex/design.xml | 134 ++++----- .../resources/category/java/codestyle.xml | 271 +++++++++--------- .../main/resources/category/java/design.xml | 195 ++++++------- .../category/modelica/bestpractices.xml | 71 ++--- .../resources/category/plsql/codestyle.xml | 92 +++--- .../pmd/lang/scala/RulesetFactoryTest.java | 20 +- .../lang/rule/AbstractRuleSetFactoryTest.java | 171 ++++++----- 9 files changed, 586 insertions(+), 558 deletions(-) diff --git a/pmd-apex/src/main/resources/category/apex/bestpractices.xml b/pmd-apex/src/main/resources/category/apex/bestpractices.xml index 836894f3b5a..b617a6eff7d 100644 --- a/pmd-apex/src/main/resources/category/apex/bestpractices.xml +++ b/pmd-apex/src/main/resources/category/apex/bestpractices.xml @@ -264,27 +264,6 @@ public class Foo { - - -Detects when a local variable is declared and/or assigned but not used. - - - - - - -Detects when the Queueable interface is used but a Finalizer is not attached. -It is best practice to call the `System.attachFinalizer(Finalizer f)` method within the `execute` method of a class which implements the `Queueable` interface. -Without attaching a Finalizer, there is no way of designing error recovery actions should the Queueable action fail. + Detects when the Queueable interface is used but a Finalizer is not attached. + It is best practice to call the `System.attachFinalizer(Finalizer f)` method within the `execute` method of a class which implements the `Queueable` interface. + Without attaching a Finalizer, there is no way of designing error recovery actions should the Queueable action fail. 5 - usersToUpdate; @@ -337,4 +316,25 @@ public class UserUpdater implements Queueable, Finalizer { + + +Detects when a local variable is declared and/or assigned but not used. + + + + + + diff --git a/pmd-apex/src/main/resources/category/apex/codestyle.xml b/pmd-apex/src/main/resources/category/apex/codestyle.xml index 97b2ab0f56a..6cfaaac10d9 100644 --- a/pmd-apex/src/main/resources/category/apex/codestyle.xml +++ b/pmd-apex/src/main/resources/category/apex/codestyle.xml @@ -70,76 +70,6 @@ public class fooClass { } // This will be reported unless you change the regex - - -Avoid using if..else statements without using surrounding braces. If the code formatting -or indentation is lost then it becomes difficult to separate the code being controlled -from the rest. - - 3 - - - - 0] -| -//IfElseBlockStatement/BlockStatement[@CurlyBrace= false()][count(child::*) > 0] -]]> - - - - - - - - - - -Avoid using if statements without using braces to surround the code block. If the code -formatting or indentation is lost then it becomes difficult to separate the code being -controlled from the rest. - - 3 - - - - - - - - - - - - + + + Avoid using if..else statements without using surrounding braces. If the code formatting + or indentation is lost then it becomes difficult to separate the code being controlled + from the rest. + + 3 + + + + 0] +| +//IfElseBlockStatement/BlockStatement[@CurlyBrace= false()][count(child::*) > 0] +]]> + + + + + + + + + + + Avoid using if statements without using braces to surround the code block. If the code + formatting or indentation is lost then it becomes difficult to separate the code being + controlled from the rest. + + 3 + + + + + + + + + + + + - - -Avoid creating deeply nested if-then statements since they are harder to read and error-prone to maintain. - - 3 - -y) { - if (y>z) { - if (z==x) { - // !! too deep - } - } - } - } -} -]]> - - - - + since="5.5.0" + message="Deeply nested if..then statements are hard to read" + class="net.sourceforge.pmd.lang.apex.rule.design.AvoidDeeplyNestedIfStmtsRule" + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_design.html#avoiddeeplynestedifstmts"> -The complexity of methods directly affects maintenance costs and readability. Concentrating too much decisional logic -in a single method makes its behaviour hard to read and change. - -Cyclomatic complexity assesses the complexity of a method by counting the number of decision points in a method, -plus one for the method entry. Decision points are places where the control flow jumps to another place in the -program. As such, they include all control flow statements, such as 'if', 'while', 'for', and 'case'. - -Generally, numbers ranging from 1-4 denote low complexity, 5-7 denote moderate complexity, 8-10 denote -high complexity, and 11+ is very high complexity. By default, this rule reports methods with a complexity >= 10. -Additionally, classes with many methods of moderate complexity get reported as well once the total of their -methods' complexities reaches 40, even if none of the methods was directly reported. - -Reported methods should be broken down into several smaller methods. Reported classes should probably be broken down -into subcomponents. +Avoid creating deeply nested if-then statements since they are harder to read and error-prone to maintain. 3 y) { + if (y>z) { + if (z==x) { + // !! too deep + } + } + } } - } } ]]> @@ -203,6 +151,58 @@ public class Foo { + + +The complexity of methods directly affects maintenance costs and readability. Concentrating too much decisional logic +in a single method makes its behaviour hard to read and change. + +Cyclomatic complexity assesses the complexity of a method by counting the number of decision points in a method, +plus one for the method entry. Decision points are places where the control flow jumps to another place in the +program. As such, they include all control flow statements, such as 'if', 'while', 'for', and 'case'. + +Generally, numbers ranging from 1-4 denote low complexity, 5-7 denote moderate complexity, 8-10 denote +high complexity, and 11+ is very high complexity. By default, this rule reports methods with a complexity >= 10. +Additionally, classes with many methods of moderate complexity get reported as well once the total of their +methods' complexities reaches 40, even if none of the methods was directly reported. + +Reported methods should be broken down into several smaller methods. Reported classes should probably be broken down +into subcomponents. + + 3 + + + + + - - -Empty or auto-generated methods in an abstract class should be tagged as abstract. This helps to remove their inappropriate -usage by developers who should be implementing their own versions in the concrete subclasses. - - 1 - - - - - - - - - - - - 3 - + + +Empty or auto-generated methods in an abstract class should be tagged as abstract. This helps to remove their inappropriate +usage by developers who should be implementing their own versions in the concrete subclasses. + + 1 + + + + + + + + + + + + - - - Since Java 1.7, numeric literals can use underscores to separate digits. This rule enforces that - numeric literals above a certain length use these underscores to increase readability. - - The rule only supports decimal (base 10) literals for now. The acceptable length under which literals - are not required to have underscores is configurable via a property. Even under that length, underscores - that are misplaced (not making groups of 3 digits) are reported. - - 3 - - - - - - - - - - - - - - - - Configurable naming conventions for type parameters in generic types and methods. - This rule reports type parameter declarations which do not match the configured regex. - Type parameters can appear on classes, interfaces, enums, records, and methods. - - By default, this rule uses the standard Java naming convention (single uppercase letter). - - 4 - - { } -public class Cache { } - -// Generic types - invalid -public interface Repository { } // lowercase -public class Cache { } // multiple letters - -// Generic methods - valid -public class Util { - public static T identity(T value) { return value; } - public R transform(T input, Function mapper) { } -} - -// Generic methods - invalid -public class Util { - public static element get(element value) { } // lowercase - public OUTPUT convert(INPUT in) { } // multiple letters -} -]]> - - - + + + Configurable naming conventions for type parameters in generic types and methods. + This rule reports type parameter declarations which do not match the configured regex. + Type parameters can appear on classes, interfaces, enums, records, and methods. + + By default, this rule uses the standard Java naming convention (single uppercase letter). + + 4 + + { } +public class Cache { } + +// Generic types - invalid +public interface Repository { } // lowercase +public class Cache { } // multiple letters + +// Generic methods - valid +public class Util { + public static T identity(T value) { return value; } + public R transform(T input, Function mapper) { } +} + +// Generic methods - invalid +public class Util { + public static element get(element value) { } // lowercase + public OUTPUT convert(INPUT in) { } // multiple letters +} +]]> + + + + + Since Java 1.7, numeric literals can use underscores to separate digits. This rule enforces that + numeric literals above a certain length use these underscores to increase readability. + + The rule only supports decimal (base 10) literals for now. The acceptable length under which literals + are not required to have underscores is configurable via a property. Even under that length, underscores + that are misplaced (not making groups of 3 digits) are reported. + + 3 + + + + + + + + + + + + + + + + + By default, this rule reports methods with a complexity of 15 or more. Reported methods should be broken down into less + complex components. + ]]> + 3 + + contacts) { + List contactsToUpdate = new ArrayList(); + + for (Contact contact : contacts) { // +1 + if (contact.department.equals("Finance")) { // +2 (nesting = 1) + contact.title = "Finance Specialist"; + contactsToUpdate.add(contact); + } else if (contact.department.equals("Sales")) { // +1 + contact.title = "Sales Specialist"; + contactsToUpdate.add(contact); + } + } + // save contacts + } +} +]]> + + + - - - - By default, this rule reports methods with a complexity of 15 or more. Reported methods should be broken down into less - complex components. - ]]> - 3 - - contacts) { - List contactsToUpdate = new ArrayList(); - - for (Contact contact : contacts) { // +1 - if (contact.department.equals("Finance")) { // +2 (nesting = 1) - contact.title = "Finance Specialist"; - contactsToUpdate.add(contact); - } else if (contact.department.equals("Sales")) { // +1 - contact.title = "Sales Specialist"; - contactsToUpdate.add(contact); - } - } - // save contacts - } -} -]]> - - + + + Non-private static fields should be made constants (or immutable references) by + declaring them final. + + Non-private non-final static fields break encapsulation and can lead to hard to find + bugs, since these fields can be modified from anywhere within the program. + Callers can trivially access and modify non-private non-final static fields. Neither + accesses nor modifications can be guarded against, and newly set values cannot + be validated. + + If you are using this rule, then you don't need this + rule {% rule java/errorprone/AssignmentToNonFinalStatic %}. + + 3 + + + + + + + + + + + + - - - - - -Non-private static fields should be made constants (or immutable references) by -declaring them final. - -Non-private non-final static fields break encapsulation and can lead to hard to find -bugs, since these fields can be modified from anywhere within the program. -Callers can trivially access and modify non-private non-final static fields. Neither -accesses nor modifications can be guarded against, and newly set values cannot -be validated. - -If you are using this rule, then you don't need this -rule {% rule java/errorprone/AssignmentToNonFinalStatic %}. - - 3 - - - - - - - - - diff --git a/pmd-modelica/src/main/resources/category/modelica/bestpractices.xml b/pmd-modelica/src/main/resources/category/modelica/bestpractices.xml index c7caaa1bf09..f9a1e046a4b 100644 --- a/pmd-modelica/src/main/resources/category/modelica/bestpractices.xml +++ b/pmd-modelica/src/main/resources/category/modelica/bestpractices.xml @@ -8,6 +8,42 @@ Rules which enforce generally accepted best practices. + + + There is multiple candidates for this type resolution. While generally this is not an error, + this may indicate a bug. + + 3 + + + + + - - - There is multiple candidates for this type resolution. While generally this is not an error, - this may indicate a bug. - - 3 - - - - diff --git a/pmd-plsql/src/main/resources/category/plsql/codestyle.xml b/pmd-plsql/src/main/resources/category/plsql/codestyle.xml index 386f4cdf4f4..e701e8b5401 100644 --- a/pmd-plsql/src/main/resources/category/plsql/codestyle.xml +++ b/pmd-plsql/src/main/resources/category/plsql/codestyle.xml @@ -92,49 +92,6 @@ END; ]]> - - -Oracle states that the PRAQMA AUTONOMOUS_TRANSACTION must be in the declaration block, -but the code does not complain, when being compiled on the 11g DB. -https://docs.oracle.com/cd/B28359_01/appdev.111/b28370/static.htm#BABIIHBJ - - 3 - - - - - - - - - violation */ - /* do something */ - COMMIT; - end do_transaction; - -end inline_pragma_error; -/ -]]> - - - -In case you have loops please name the loop variables more meaningful. + In case you have loops please name the loop variables more meaningful. 3 - -3 + + + Oracle states that the PRAQMA AUTONOMOUS_TRANSACTION must be in the declaration block, + but the code does not complain, when being compiled on the 11g DB. + https://docs.oracle.com/cd/B28359_01/appdev.111/b28370/static.htm#BABIIHBJ + + 3 + + + + + + + + + violation */ + /* do something */ + COMMIT; + end do_transaction; + +end inline_pragma_error; +/ +]]> + + + diff --git a/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/RulesetFactoryTest.java b/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/RulesetFactoryTest.java index b964e995789..1867242500a 100644 --- a/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/RulesetFactoryTest.java +++ b/pmd-scala-modules/pmd-scala-common/src/test/java/net/sourceforge/pmd/lang/scala/RulesetFactoryTest.java @@ -4,11 +4,25 @@ package net.sourceforge.pmd.lang.scala; -import net.sourceforge.pmd.test.lang.rule.AbstractRuleSetFactoryTest; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.IOException; +import java.util.Properties; + +import org.junit.jupiter.api.Test; /** - * Test scala rulesets + * Test scala rulesets. */ -class RulesetFactoryTest extends AbstractRuleSetFactoryTest { +class RulesetFactoryTest { + // no rulesets yet + @Test + void nothingToTest() throws IOException { + Properties props = new Properties(); + props.load(RulesetFactoryTest.class.getClassLoader() + .getResourceAsStream("category/scala/categories.properties")); + assertEquals("", props.get("rulesets.filenames"), + "Once rulesets are added, this should extend AbstractRuleSetFactoryTest"); + } } diff --git a/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java b/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java index c4b92205b39..3ab0f9f7d76 100644 --- a/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java +++ b/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java @@ -10,6 +10,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS; import java.io.BufferedReader; import java.io.ByteArrayInputStream; @@ -36,6 +37,9 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; import org.slf4j.event.Level; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -60,6 +64,7 @@ * Base test class to verify the language's rulesets. This class should be * subclassed for each language. */ +@TestInstance(PER_CLASS) public abstract class AbstractRuleSetFactoryTest { private static ValidateDefaultHandler validateDefaultHandler; @@ -122,112 +127,120 @@ static void init() throws Exception { * @throws Exception * any error */ - @Test - void testAllPMDBuiltInRulesMeetConventions() throws Exception { + @ParameterizedTest + @MethodSource("getRuleSetFileNames") + void testAllPMDBuiltInRulesMeetConventions(String fileName) throws Exception { int invalidSinceAttributes = 0; int invalidExternalInfoURL = 0; int invalidClassName = 0; int invalidRegexSuppress = 0; int invalidXPathSuppress = 0; + int invalidOrder = 0; StringBuilder messages = new StringBuilder(); - List ruleSetFileNames = getRuleSetFileNames(); - for (String fileName : ruleSetFileNames) { - RuleSet ruleSet = loadRuleSetByFileName(fileName); - for (Rule rule : ruleSet.getRules()) { + String lastName = null; + RuleSet ruleSet = loadRuleSetByFileName(fileName); + for (Rule rule : ruleSet.getRules()) { - // Skip references - if (rule instanceof RuleReference) { - continue; - } + // Skip references + if (rule instanceof RuleReference) { + continue; + } + if (lastName != null + && String.CASE_INSENSITIVE_ORDER.compare(rule.getName(), lastName) < 0) { + invalidOrder++; + messages.append(rule.getName()).append(" should be before ") + .append(lastName).append("\n"); + } + lastName = rule.getName(); - Language language = rule.getLanguage(); - String group = fileName.substring(fileName.lastIndexOf('/') + 1); - group = group.substring(0, group.indexOf(".xml")); - if (group.indexOf('-') >= 0) { - group = group.substring(0, group.indexOf('-')); - } + Language language = rule.getLanguage(); + String group = fileName.substring(fileName.lastIndexOf('/') + 1); + group = group.substring(0, group.indexOf(".xml")); + if (group.indexOf('-') >= 0) { + group = group.substring(0, group.indexOf('-')); + } - // Is since missing ? - if (rule.getSince() == null) { - invalidSinceAttributes++; - messages.append("Rule ") - .append(fileName) - .append("/") - .append(rule.getName()) - .append(" is missing 'since' attribute\n"); - } - // Is URL valid ? - if (rule.getExternalInfoUrl() == null || "".equalsIgnoreCase(rule.getExternalInfoUrl())) { + // Is since missing ? + if (rule.getSince() == null) { + invalidSinceAttributes++; + messages.append("Rule ") + .append(fileName) + .append("/") + .append(rule.getName()) + .append(" is missing 'since' attribute\n"); + } + // Is URL valid ? + if (rule.getExternalInfoUrl() == null || "".equalsIgnoreCase(rule.getExternalInfoUrl())) { + invalidExternalInfoURL++; + messages.append("Rule ") + .append(fileName) + .append("/") + .append(rule.getName()) + .append(" is missing 'externalInfoURL' attribute\n"); + } else { + String expectedExternalInfoURL = "https://docs.pmd-code.org/.+/pmd_rules_" + + language.getId() + "_" + + IOUtil.getFilenameBase(fileName) + + ".html#" + + rule.getName().toLowerCase(Locale.ROOT); + if (rule.getExternalInfoUrl() == null + || !rule.getExternalInfoUrl().matches(expectedExternalInfoURL)) { invalidExternalInfoURL++; messages.append("Rule ") .append(fileName) .append("/") .append(rule.getName()) - .append(" is missing 'externalInfoURL' attribute\n"); - } else { - String expectedExternalInfoURL = "https://docs.pmd-code.org/.+/pmd_rules_" - + language.getId() + "_" - + IOUtil.getFilenameBase(fileName) - + ".html#" - + rule.getName().toLowerCase(Locale.ROOT); - if (rule.getExternalInfoUrl() == null - || !rule.getExternalInfoUrl().matches(expectedExternalInfoURL)) { - invalidExternalInfoURL++; - messages.append("Rule ") - .append(fileName) - .append("/") - .append(rule.getName()) - .append(" seems to have an invalid 'externalInfoURL' value (") - .append(rule.getExternalInfoUrl()) - .append("), it should be:") - .append(expectedExternalInfoURL) - .append('\n'); - } - } - // Proper class name/packaging? - String expectedClassName = "net.sourceforge.pmd.lang." + language.getId() + ".rule." + group - + "." + rule.getName() + "Rule"; - if (!rule.getRuleClass().equals(expectedClassName) - && !validXPathClassNames.contains(rule.getRuleClass())) { - invalidClassName++; - messages.append("Rule ") - .append(fileName) - .append("/") - .append(rule.getName()) - .append(" seems to have an invalid 'class' value (") - .append(rule.getRuleClass()) + .append(" seems to have an invalid 'externalInfoURL' value (") + .append(rule.getExternalInfoUrl()) .append("), it should be:") - .append(expectedClassName) + .append(expectedExternalInfoURL) .append('\n'); } - // Should not have violation suppress regex property - if (rule.getProperty(Rule.VIOLATION_SUPPRESS_REGEX_DESCRIPTOR).isPresent()) { - invalidRegexSuppress++; - messages.append("Rule ") - .append(fileName) - .append("/") - .append(rule.getName()) - .append(" should not have '") - .append(Rule.VIOLATION_SUPPRESS_REGEX_DESCRIPTOR.name()) - .append("', this is intended for end user customization only.\n"); - } - // Should not have violation suppress xpath property - if (rule.getProperty(Rule.VIOLATION_SUPPRESS_XPATH_DESCRIPTOR).isPresent()) { - invalidXPathSuppress++; - messages.append("Rule ").append(fileName).append("/").append(rule.getName()).append(" should not have '").append(Rule.VIOLATION_SUPPRESS_XPATH_DESCRIPTOR.name()).append("', this is intended for end user customization only.").append(System.lineSeparator()); - } + } + // Proper class name/packaging? + String expectedClassName = "net.sourceforge.pmd.lang." + language.getId() + ".rule." + group + + "." + rule.getName() + "Rule"; + if (!rule.getRuleClass().equals(expectedClassName) + && !validXPathClassNames.contains(rule.getRuleClass())) { + invalidClassName++; + messages.append("Rule ") + .append(fileName) + .append("/") + .append(rule.getName()) + .append(" seems to have an invalid 'class' value (") + .append(rule.getRuleClass()) + .append("), it should be:") + .append(expectedClassName) + .append('\n'); + } + // Should not have violation suppress regex property + if (rule.getProperty(Rule.VIOLATION_SUPPRESS_REGEX_DESCRIPTOR).isPresent()) { + invalidRegexSuppress++; + messages.append("Rule ") + .append(fileName) + .append("/") + .append(rule.getName()) + .append(" should not have '") + .append(Rule.VIOLATION_SUPPRESS_REGEX_DESCRIPTOR.name()) + .append("', this is intended for end user customization only.\n"); + } + // Should not have violation suppress xpath property + if (rule.getProperty(Rule.VIOLATION_SUPPRESS_XPATH_DESCRIPTOR).isPresent()) { + invalidXPathSuppress++; + messages.append("Rule ").append(fileName).append("/").append(rule.getName()).append(" should not have '").append(Rule.VIOLATION_SUPPRESS_XPATH_DESCRIPTOR.name()).append("', this is intended for end user customization only.").append(System.lineSeparator()); } } // We do this at the end to ensure we test ALL the rules before failing // the test if (invalidSinceAttributes > 0 || invalidExternalInfoURL > 0 || invalidClassName > 0 || invalidRegexSuppress > 0 - || invalidXPathSuppress > 0) { + || invalidXPathSuppress > 0 || invalidOrder > 0) { fail("All built-in PMD rules need 'since' attribute (" + invalidSinceAttributes + " are missing), a proper ExternalURLInfo (" + invalidExternalInfoURL + " are invalid), a class name meeting conventions (" + invalidClassName + " are invalid), no '" + Rule.VIOLATION_SUPPRESS_REGEX_DESCRIPTOR.name() + "' property (" + invalidRegexSuppress + " are invalid), and no '" + Rule.VIOLATION_SUPPRESS_XPATH_DESCRIPTOR.name() + "' property (" - + invalidXPathSuppress + " are invalid)\n" + messages); + + invalidXPathSuppress + " are invalid) and be alphabetically sorted (" + + invalidOrder + " misplaced)\n" + messages); } } From 42bcb0813b7b009dbc38682edf60741d0a97b3bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Tue, 16 Sep 2025 19:55:36 +0200 Subject: [PATCH 1363/1962] Update deprecation version --- .../pmd/lang/java/rule/design/ExcessiveImportsRule.java | 2 +- .../pmd/lang/java/rule/design/ExcessiveParameterListRule.java | 2 +- .../pmd/lang/java/rule/design/ExcessivePublicCountRule.java | 2 +- .../lang/java/rule/internal/AbstractJavaCounterCheckRule.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsRule.java index ecd0c9df478..44251a0bc57 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsRule.java @@ -29,7 +29,7 @@ protected int defaultReportLevel() { } /** - * @deprecated since 7.17.0 + * @deprecated since 7.18.0 */ @Override protected boolean isViolation(ASTCompilationUnit node, int reportLevel) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java index 5c382bf072f..87d2285193d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java @@ -38,7 +38,7 @@ private boolean areParametersOfPrivateConstructor(ASTFormalParameters params) { } /** - * @deprecated since 7.17.0 + * @deprecated since 7.18.0 */ @Override protected boolean isViolation(ASTFormalParameters node, int reportLevel) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java index 0a1b1bd5f0f..4933b1eeacf 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java @@ -40,7 +40,7 @@ protected int defaultReportLevel() { } /** - * @deprecated since 7.17.0 + * @deprecated since 7.18.0 */ @Override protected boolean isViolation(ASTTypeDeclaration node, int reportLevel) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java index da1485fc93f..98457b9fbf6 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java @@ -44,7 +44,7 @@ protected boolean isIgnored(T node) { /** - * @deprecated since 7.17.0 + * @deprecated since 7.18.0 */ protected boolean isViolation(T node, int reportLevel) { int metric = getMetric(node); From 5f5c4fcceec9796252ee856604e757e77b5f8b9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Tue, 16 Sep 2025 20:14:46 +0200 Subject: [PATCH 1364/1962] Add threshold to message --- .../java/rule/internal/AbstractJavaCounterCheckRule.java | 2 +- pmd-java/src/main/resources/category/java/design.xml | 6 +++--- .../pmd/lang/java/rule/design/xml/ExcessiveImports.xml | 2 +- .../lang/java/rule/design/xml/ExcessiveParameterList.xml | 2 +- .../pmd/lang/java/rule/design/xml/ExcessivePublicCount.xml | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java index 98457b9fbf6..2bb668d3fdb 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java @@ -63,7 +63,7 @@ public Object visitJavaNode(JavaNode node, Object data) { int metric = getMetric(t); int threshold = getProperty(reportLevel); if (metric >= threshold) { - asCtx(data).addViolation(node, metric); + asCtx(data).addViolation(node, metric, threshold); } } diff --git a/pmd-java/src/main/resources/category/java/design.xml b/pmd-java/src/main/resources/category/java/design.xml index 5480335b563..cc1ac004d18 100644 --- a/pmd-java/src/main/resources/category/java/design.xml +++ b/pmd-java/src/main/resources/category/java/design.xml @@ -623,7 +623,7 @@ public void bar() { @@ -647,7 +647,7 @@ public class Foo { @@ -675,7 +675,7 @@ public void addPerson( // preferred approach diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ExcessiveImports.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ExcessiveImports.xml index 543a36c176a..5363f5d2087 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ExcessiveImports.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ExcessiveImports.xml @@ -32,7 +32,7 @@ public class Foo{} 3 1 - A high number of imports (4) can indicate a high degree of coupling within an object. + A high number of imports (4) can indicate a high degree of coupling within an object; current threshold is 3. 9 1 - Avoid long parameter lists (10 parameters). + Avoid long parameter lists (10 parameters - threshold is 9). 2 1 - This class has 3 public methods and attributes + This class has 3 public methods and attributes; current threshold is 2. From adfd82c0680e1301896fa887dbdcec71ee49ce49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Tue, 16 Sep 2025 21:27:03 +0200 Subject: [PATCH 1365/1962] Add threshold to message --- pmd-apex/src/main/resources/category/apex/design.xml | 8 ++++---- .../lang/apex/rule/design/xml/ExcessiveClassLength.xml | 2 +- .../lang/apex/rule/design/xml/ExcessiveParameterList.xml | 2 +- .../lang/apex/rule/design/xml/NcssConstructorCount.xml | 2 +- .../pmd/lang/apex/rule/design/xml/NcssTypeCount.xml | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pmd-apex/src/main/resources/category/apex/design.xml b/pmd-apex/src/main/resources/category/apex/design.xml index 2ebfa4d5f55..ed601725fc1 100644 --- a/pmd-apex/src/main/resources/category/apex/design.xml +++ b/pmd-apex/src/main/resources/category/apex/design.xml @@ -206,7 +206,7 @@ public class Foo { @@ -238,7 +238,7 @@ public class Foo { @@ -296,7 +296,7 @@ public class Foo { @@ -353,7 +353,7 @@ public class Foo extends Bar { diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessiveClassLength.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessiveClassLength.xml index b3c463c08d4..045076da793 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessiveClassLength.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessiveClassLength.xml @@ -46,7 +46,7 @@ public class Foo { 10 1 - Avoid really long classes (13 lines). + Avoid really long classes (13 lines - threshold is 10). diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessiveParameterList.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessiveParameterList.xml index ef3aacbc6a0..df98c20deac 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessiveParameterList.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessiveParameterList.xml @@ -33,7 +33,7 @@ public class Foo { 9 1 - Avoid long parameter lists (10 parameters). + Avoid long parameter lists (10 parameters - threshold is 9). 13 1 - The constructor has an NCSS line count of 13 + The constructor has an NCSS line count of 13; current threshold is 13. diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssTypeCount.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssTypeCount.xml index 04eb93c0dd4..41553b019c6 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssTypeCount.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssTypeCount.xml @@ -78,7 +78,7 @@ public class Foo { 13 1 - The type has an NCSS line count of 14 + The type has an NCSS line count of 14; current threshold is 13. From b7456fed585f57aaf5e4a8cab683cd1aa4c9e570 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Thu, 18 Sep 2025 00:00:27 +0200 Subject: [PATCH 1366/1962] Add testcases, fix for ((List) list).size() --- .../rule/codestyle/UnnecessaryCastRule.java | 23 +++++++--- .../rule/codestyle/xml/UnnecessaryCast.xml | 42 ++++++++++++++----- 2 files changed, 49 insertions(+), 16 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java index 2d8999400ac..a3733264b61 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java @@ -112,14 +112,27 @@ public Object visit(ASTCastExpression castExpr, Object data) { reportCast(castExpr, data); } else if (castExpr.getParent() instanceof ASTMethodCall && castExpr.getIndexInParent() == 0) { - ASTMethodCall call = (ASTMethodCall) castExpr.getParent(); - boolean generic = call.getMethodType().getSymbol().getFormalParameters().stream() - .anyMatch(fp -> isTypeExpression(fp.getTypeMirror(Substitution.EMPTY))); - if (!generic && TypeTestUtil.isA(call.getMethodType().getDeclaringType(), operandType)) { + JMethodSig methodType = ((ASTMethodCall) castExpr.getParent()).getMethodType(); + handleMethodCall(castExpr, methodType, operandType, data); + } + return null; + } + + private void handleMethodCall(ASTCastExpression castExpr, JMethodSig methodType, + JTypeMirror operandType, Object data) { + boolean generic = methodType.getSymbol().getFormalParameters().stream() + .anyMatch(fp -> isTypeExpression(fp.getTypeMirror(Substitution.EMPTY))); + if (!generic) { + JTypeMirror declaringType = methodType.getDeclaringType(); + if (!isTypeExpression(methodType.getSymbol().getReturnType(Substitution.EMPTY))) { + // declaring type of List::size is List, but since the return type + // is not generic, it's enough to check that operand is a List + declaringType = declaringType.getErasure(); + } + if (TypeTestUtil.isA(declaringType, operandType)) { reportCast(castExpr, data); } } - return null; } private boolean isTypeExpression(JTypeMirror type) { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml index e0683e8bac4..9474939c7f7 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml @@ -1101,7 +1101,7 @@ class Tester { - + [java] UnnecessaryCast false-positive for raw types #4822 0 - Cast is not found as unnecessary (for now) - 2 - 11,13 + Cast in method call unnecessary + 3 + 7,8,12 { } public class Foo { - public int compare(List o1) { - String s = ((List) o1).get(0); - String s1 = ((StringList) o1).get(0); + public int parameterized(List o1) { Object t = ((List) o1).get(0); - ((List) o1).addAll(Collections.singletonList(t)); return ((List) o1).size(); } public int generic(List o1) { + return ((List) o1).size(); + } + } + ]]> + + + + Cast in method call needed + 0 + { } + + public class Foo { + public void parameterized(List o1) { String s = ((List) o1).get(0); String s1 = ((StringList) o1).get(0); - return ((List) o1).size(); + ((List) o1).addAll(Collections.singletonList(t)); + } + + public void generic(List o1) { + String s = ((List) o1).get(0); + String s1 = ((StringList) o1).get(0); + // the next 2 casts are not strictly needed, + // ignored to reduce complexity of the rule + ((StringList) o1).add("x"); + ((List) o1).add("x"); } } ]]> From c7f1dfe96a154a1459778f4ffdf4f27d23ad5ded Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Sep 2025 09:03:34 +0200 Subject: [PATCH 1367/1962] chore(deps): bump surefire.version from 3.5.3 to 3.5.4 (#6062) Bumps `surefire.version` from 3.5.3 to 3.5.4. Updates `org.apache.maven.plugins:maven-surefire-plugin` from 3.5.3 to 3.5.4 - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.5.3...surefire-3.5.4) Updates `org.apache.maven.plugins:maven-failsafe-plugin` from 3.5.3 to 3.5.4 - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.5.3...surefire-3.5.4) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-surefire-plugin dependency-version: 3.5.4 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.apache.maven.plugins:maven-failsafe-plugin dependency-version: 3.5.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index abf0022026b..a9e169187cc 100644 --- a/pom.xml +++ b/pom.xml @@ -91,7 +91,7 @@ 2.0.0 5.0 - 3.5.3 + 3.5.4 10.26.1 3.6.0 3.27.0 From 7e6d9acbd7b3b1da0d9ff86a98aade5fcbd1ed26 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Sep 2025 09:04:01 +0200 Subject: [PATCH 1368/1962] chore(deps): bump ruby/setup-ruby from 1.257.0 to 1.258.0 (#6063) Bumps [ruby/setup-ruby](https://github.com/ruby/setup-ruby) from 1.257.0 to 1.258.0. - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/44511735964dcb71245e7e55f72539531f7bc0eb...3fee6763234110473bd57dd4595c5199fce2c510) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-version: 1.258.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 4 ++-- .github/workflows/publish-release.yml | 2 +- .github/workflows/publish-snapshot.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a9e67524006..70818847a4b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -278,7 +278,7 @@ jobs: -Pgenerate-rule-docs,fastSkip \ -DskipTests -Dassembly.skipAssembly=true - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@44511735964dcb71245e7e55f72539531f7bc0eb #v1.257.0 + uses: ruby/setup-ruby@3fee6763234110473bd57dd4595c5199fce2c510 #v1.258.0 with: ruby-version: 3.3 - name: Setup bundler @@ -317,7 +317,7 @@ jobs: distribution: 'temurin' java-version: '11' - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@44511735964dcb71245e7e55f72539531f7bc0eb #v1.257.0 + uses: ruby/setup-ruby@3fee6763234110473bd57dd4595c5199fce2c510 #v1.258.0 with: ruby-version: 3.3 - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 63c3f6b7689..233b26e41a8 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -630,7 +630,7 @@ jobs: distribution: 'temurin' java-version: '11' - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@44511735964dcb71245e7e55f72539531f7bc0eb #v1.257.0 + uses: ruby/setup-ruby@3fee6763234110473bd57dd4595c5199fce2c510 #v1.258.0 with: ruby-version: 3.3 - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 7013b722b96..44a3489ca74 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -647,7 +647,7 @@ jobs: distribution: 'temurin' java-version: '11' - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@44511735964dcb71245e7e55f72539531f7bc0eb #v1.257.0 + uses: ruby/setup-ruby@3fee6763234110473bd57dd4595c5199fce2c510 #v1.258.0 with: ruby-version: 3.3 - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 From 9a6210ee1dbed8ffbd89a2a7c94909c753a19154 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Sep 2025 09:04:43 +0200 Subject: [PATCH 1369/1962] chore(deps): bump com.google.code.gson:gson from 2.13.1 to 2.13.2 (#6064) Bumps [com.google.code.gson:gson](https://github.com/google/gson) from 2.13.1 to 2.13.2. - [Release notes](https://github.com/google/gson/releases) - [Changelog](https://github.com/google/gson/blob/main/CHANGELOG.md) - [Commits](https://github.com/google/gson/compare/gson-parent-2.13.1...gson-parent-2.13.2) --- updated-dependencies: - dependency-name: com.google.code.gson:gson dependency-version: 2.13.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a9e169187cc..82d5cf62c72 100644 --- a/pom.xml +++ b/pom.xml @@ -944,7 +944,7 @@ com.google.code.gson gson - 2.13.1 + 2.13.2 org.yaml From 83c63de4d8fbd5445510d11a30cf2ad2853e734a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Sep 2025 09:05:06 +0200 Subject: [PATCH 1370/1962] chore(deps): bump actions/create-github-app-token from 2.1.1 to 2.1.4 (#6065) Bumps [actions/create-github-app-token](https://github.com/actions/create-github-app-token) from 2.1.1 to 2.1.4. - [Release notes](https://github.com/actions/create-github-app-token/releases) - [Commits](https://github.com/actions/create-github-app-token/compare/a8d616148505b5069dccd32f177bb87d7f39123b...67018539274d69449ef7c02e8e71183d1719ab42) --- updated-dependencies: - dependency-name: actions/create-github-app-token dependency-version: 2.1.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/publish-pull-requests.yml | 2 +- .github/workflows/publish-release.yml | 4 ++-- .github/workflows/publish-snapshot.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish-pull-requests.yml b/.github/workflows/publish-pull-requests.yml index 3f5d3cb1a60..b822aa8aec8 100644 --- a/.github/workflows/publish-pull-requests.yml +++ b/.github/workflows/publish-pull-requests.yml @@ -21,7 +21,7 @@ jobs: run: shell: bash steps: - - uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b #v2.1.1 + - uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 #v2.1.4 id: pmd-actions-helper-app-token with: app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 233b26e41a8..612e93984e9 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -504,7 +504,7 @@ jobs: --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-src.zip" printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-doc.zip" - - uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b #v2.1.1 + - uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 #v2.1.4 id: pmd-actions-helper-app-token with: app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} @@ -758,7 +758,7 @@ jobs: run: shell: bash steps: - - uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b #v2.1.1 + - uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 #v2.1.4 id: pmd-actions-helper-app-token with: app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 44a3489ca74..367e3488f0f 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -495,7 +495,7 @@ jobs: --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-src.zip" printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-doc.zip" - - uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b #v2.1.1 + - uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 #v2.1.4 id: pmd-actions-helper-app-token with: app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} From 2181cc3286c617721f3d3cf66e24226f3acacdda Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Sep 2025 09:05:33 +0200 Subject: [PATCH 1371/1962] chore(deps): bump org.apache.groovy:groovy from 5.0.0 to 5.0.1 (#6066) Bumps [org.apache.groovy:groovy](https://github.com/apache/groovy) from 5.0.0 to 5.0.1. - [Commits](https://github.com/apache/groovy/commits) --- updated-dependencies: - dependency-name: org.apache.groovy:groovy dependency-version: 5.0.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 82d5cf62c72..18bb819056a 100644 --- a/pom.xml +++ b/pom.xml @@ -939,7 +939,7 @@ org.apache.groovy groovy - 5.0.0 + 5.0.1 com.google.code.gson From f421052e25d7c4c0212d2efeb1f303a9e2eb74ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Sep 2025 09:05:55 +0200 Subject: [PATCH 1372/1962] chore(deps): bump org.apache.maven.plugins:maven-shade-plugin from 3.6.0 to 3.6.1 (#6067) chore(deps): bump org.apache.maven.plugins:maven-shade-plugin Bumps [org.apache.maven.plugins:maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.6.0 to 3.6.1. - [Release notes](https://github.com/apache/maven-shade-plugin/releases) - [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.6.0...v3.6.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-shade-plugin dependency-version: 3.6.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 18bb819056a..95c5d61116f 100644 --- a/pom.xml +++ b/pom.xml @@ -333,7 +333,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.6.0 + 3.6.1 org.apache.maven.plugins From 6329c33225537207ce88affb44ad9de3bdd24af7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Sep 2025 09:06:28 +0200 Subject: [PATCH 1373/1962] chore(deps): bump scalameta.version from 4.13.9 to 4.13.10 (#6068) Bumps `scalameta.version` from 4.13.9 to 4.13.10. Updates `org.scalameta:parsers_2.13` from 4.13.9 to 4.13.10 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.9...v4.13.10) Updates `org.scalameta:trees_2.13` from 4.13.9 to 4.13.10 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.9...v4.13.10) Updates `org.scalameta:parsers_2.12` from 4.13.9 to 4.13.10 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.9...v4.13.10) Updates `org.scalameta:trees_2.12` from 4.13.9 to 4.13.10 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.9...v4.13.10) --- updated-dependencies: - dependency-name: org.scalameta:parsers_2.13 dependency-version: 4.13.10 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:trees_2.13 dependency-version: 4.13.10 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:parsers_2.12 dependency-version: 4.13.10 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:trees_2.12 dependency-version: 4.13.10 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index ea78faf70a9..325cbac4724 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -13,7 +13,7 @@ - 4.13.9 + 4.13.10 From f64618ddffde747cee3172570771b181b9aa2a0c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 19 Sep 2025 10:47:18 +0200 Subject: [PATCH 1374/1962] [doc] Update release notes (#6012, #6023) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 0c9c0dd3524..12331906ed0 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,11 +25,14 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* misc + * [#6012](https://github.com/pmd/pmd/issues/6012): \[pmd-rulesets] Rulesets should be in alphabetical order ### ๐Ÿšจ API Changes ### โœจ Merged pull requests +* [#6023](https://github.com/pmd/pmd/pull/6023): \[test] Fix #6012: Alphabetically sort all default rules - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) ### ๐Ÿ“ฆ Dependency updates From a1af99e758b8abfcb5bec5787a0d8526c6c0cfec Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 19 Sep 2025 11:20:12 +0200 Subject: [PATCH 1375/1962] Fix build with Java 25 --- .../net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java index 263637d5494..348751441f8 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java @@ -75,7 +75,7 @@ void jep512CompactSourceFilesAndInstanceMainMethodsVerifyTypes() { int javaVersion = Integer.parseInt(System.getProperty("java.version").split("\\.")[0].replaceAll("-ea", "")); assumeTrue(javaVersion >= 25, "Java " + javaVersion + " doesn't support java.lang.IO. At least Java 25 is needed for this test."); - ASTCompilationUnit compilationUnit = java25.parseResource("Jep512_CompactSourceFilesAndInstanceMainMethods.java"); + ASTCompilationUnit compilationUnit = java25.parseResource("Jep512_CompactSourceFilesAndInstanceMainMethodsAfterJava23.java"); assertTrue(compilationUnit.isCompact()); List methodCalls = compilationUnit.descendants(ASTMethodCall.class).toList(); From c228f964d6a0b8c8d9f39ec6a79468cb45edd884 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 19 Sep 2025 15:09:16 +0200 Subject: [PATCH 1376/1962] Bump pmdtester from 1.6.0 to 1.6.1 (#6076) --- .ci/files/Gemfile.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.ci/files/Gemfile.lock b/.ci/files/Gemfile.lock index bc84f0a26f9..3811d713dab 100644 --- a/.ci/files/Gemfile.lock +++ b/.ci/files/Gemfile.lock @@ -2,12 +2,12 @@ GEM remote: https://rubygems.org/ specs: base64 (0.3.0) - bigdecimal (3.2.2) + bigdecimal (3.2.3) concurrent-ruby (1.3.5) differ (0.1.2) - et-orbi (1.2.11) + et-orbi (1.3.0) tzinfo - fugit (1.11.1) + fugit (1.11.2) et-orbi (~> 1, >= 1.2.11) raabro (~> 1.4) liquid (5.8.7) @@ -15,10 +15,10 @@ GEM strscan (>= 3.1.1) logger (1.7.0) logger-colors (1.0.0) - nokogiri (1.18.9-x86_64-linux-gnu) + nokogiri (1.18.10-x86_64-linux-gnu) racc (~> 1.4) ostruct (0.6.3) - pmdtester (1.6.0) + pmdtester (1.6.1) base64 (~> 0.3) bigdecimal (~> 3.2) differ (~> 0.1) From 6999bed0b0db025207950ec6575a8ae04ff72567 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 19 Sep 2025 15:20:48 +0200 Subject: [PATCH 1377/1962] [java] Document deprecated methods --- docs/pages/release_notes.md | 8 ++++++++ .../pmd/lang/java/rule/design/ExcessiveImportsRule.java | 6 +++--- .../java/rule/design/ExcessiveParameterListRule.java | 6 +++--- .../lang/java/rule/design/ExcessivePublicCountRule.java | 6 +++--- .../java/rule/internal/AbstractJavaCounterCheckRule.java | 9 --------- 5 files changed, 17 insertions(+), 18 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 0c9c0dd3524..69b57fb86b3 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -28,6 +28,14 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿšจ API Changes +#### Deprecations +* java + * The following methods have been deprecated. Due to refactoring of the internal base class, these methods are not + used anymore and are not required to be implemented anymore: + * {%jdoc !!java::lang.java.rule.design.ExcessiveImportsRule#isViolation(java::lang.java.ast.ASTCompilationUnit,int) %} + * {%jdoc !!java::lang.java.rule.design.ExcessiveParameterListRule#isViolation(java::lang.java.ast.ASTFormalParameters,int) %} + * {%jdoc !!java::lang.java.rule.design.ExcessivePublicCountRule#isViolation(java::lang.java.ast.ASTTypeDeclaration,int) %} + ### โœจ Merged pull requests diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsRule.java index 44251a0bc57..7f357fd17ba 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsRule.java @@ -29,11 +29,11 @@ protected int defaultReportLevel() { } /** - * @deprecated since 7.18.0 + * @deprecated since 7.18.0. This method is not used anymore and shouldn't be implemented. */ - @Override + @Deprecated protected boolean isViolation(ASTCompilationUnit node, int reportLevel) { - return super.isViolation(node, reportLevel); + throw new UnsupportedOperationException("method is deprecated and not supported anymore."); } @Override diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java index 87d2285193d..a586488334a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java @@ -38,11 +38,11 @@ private boolean areParametersOfPrivateConstructor(ASTFormalParameters params) { } /** - * @deprecated since 7.18.0 + * @deprecated since 7.18.0. This method is not used anymore and shouldn't be implemented. */ - @Override + @Deprecated protected boolean isViolation(ASTFormalParameters node, int reportLevel) { - return super.isViolation(node, reportLevel); + throw new UnsupportedOperationException("method is deprecated and not supported anymore."); } @Override diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java index 4933b1eeacf..bfed3d98b81 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java @@ -40,11 +40,11 @@ protected int defaultReportLevel() { } /** - * @deprecated since 7.18.0 + * @deprecated since 7.18.0. This method is not used anymore and shouldn't be implemented. */ - @Override + @Deprecated protected boolean isViolation(ASTTypeDeclaration node, int reportLevel) { - return super.isViolation(node, reportLevel); + throw new UnsupportedOperationException("method is deprecated and not supported anymore."); } @Override diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java index 2bb668d3fdb..833f144b512 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractJavaCounterCheckRule.java @@ -42,15 +42,6 @@ protected boolean isIgnored(T node) { return false; } - - /** - * @deprecated since 7.18.0 - */ - protected boolean isViolation(T node, int reportLevel) { - int metric = getMetric(node); - return metric >= reportLevel; - } - protected abstract int getMetric(T node); @Override From d813af55b85fbc8d6f644611494441bf72a4ef08 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 19 Sep 2025 15:28:45 +0200 Subject: [PATCH 1378/1962] [doc] Update release notes (#5569, #6021) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 69b57fb86b3..6ea539f640b 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,6 +25,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* java-design + * [#5569](https://github.com/pmd/pmd/issues/5569): \[java] ExcessivePublicCount should report number of public "things" ### ๐Ÿšจ API Changes @@ -38,6 +40,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ Merged pull requests +* [#6021](https://github.com/pmd/pmd/pull/6021): \[java] Fix #5569: ExcessiveImports/ExcessiveParameterList/ExcessivePublicCount include the metric in the message - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) ### ๐Ÿ“ฆ Dependency updates From 7afd0bc0c86623bc55b9d838d3e3bffb1128f7d5 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 19 Sep 2025 15:54:15 +0200 Subject: [PATCH 1379/1962] [doc] Update release notes (#6022) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 0c9c0dd3524..5e0bd4b2568 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,11 +25,14 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* apex-design + * [#6022](https://github.com/pmd/pmd/issues/6022): \[apex] ExcessiveClassLength/ExcessiveParameterList include the metric in the message ### ๐Ÿšจ API Changes ### โœจ Merged pull requests +* [#6022](https://github.com/pmd/pmd/pull/6022): \[apex] ExcessiveClassLength/ExcessiveParameterList include the metric in the message - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) ### ๐Ÿ“ฆ Dependency updates From 6c7b2e2a559d7d25a3efd512406f4d35b4ff10cf Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 19 Sep 2025 15:56:45 +0200 Subject: [PATCH 1380/1962] [doc] Update release notes (#6040) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 95be8730b6e..ea779311ed6 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -47,6 +47,7 @@ This is a {{ site.pmd.release_type }} release. * [#6021](https://github.com/pmd/pmd/pull/6021): \[java] Fix #5569: ExcessiveImports/ExcessiveParameterList/ExcessivePublicCount include the metric in the message - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6022](https://github.com/pmd/pmd/pull/6022): \[apex] ExcessiveClassLength/ExcessiveParameterList include the metric in the message - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6023](https://github.com/pmd/pmd/pull/6023): \[test] Fix #6012: Alphabetically sort all default rules - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6040](https://github.com/pmd/pmd/pull/6040): \[java,apex,plsql,velocity] Change description of "minimum" parameter - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) ### ๐Ÿ“ฆ Dependency updates From 44dd143d58f9a03d5036e8d8a6c158daa6840357 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 19 Sep 2025 16:00:13 +0200 Subject: [PATCH 1381/1962] [doc] Update release notes (#5880, #6031) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index ea779311ed6..89f99e81101 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -29,6 +29,8 @@ This is a {{ site.pmd.release_type }} release. * [#6022](https://github.com/pmd/pmd/issues/6022): \[apex] ExcessiveClassLength/ExcessiveParameterList include the metric in the message * java-design * [#5569](https://github.com/pmd/pmd/issues/5569): \[java] ExcessivePublicCount should report number of public "things" +* java-multithreading + * [#5880](https://github.com/pmd/pmd/issues/5880): \[java] DoubleCheckedLocking is not detected if more than 1 assignment or more than 2 if statements * misc * [#6012](https://github.com/pmd/pmd/issues/6012): \[pmd-rulesets] Rulesets should be in alphabetical order @@ -47,6 +49,7 @@ This is a {{ site.pmd.release_type }} release. * [#6021](https://github.com/pmd/pmd/pull/6021): \[java] Fix #5569: ExcessiveImports/ExcessiveParameterList/ExcessivePublicCount include the metric in the message - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6022](https://github.com/pmd/pmd/pull/6022): \[apex] ExcessiveClassLength/ExcessiveParameterList include the metric in the message - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6023](https://github.com/pmd/pmd/pull/6023): \[test] Fix #6012: Alphabetically sort all default rules - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6031](https://github.com/pmd/pmd/pull/6031): \[java] Fix #5880: False Negatives in DoubleCheckedLocking - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6040](https://github.com/pmd/pmd/pull/6040): \[java,apex,plsql,velocity] Change description of "minimum" parameter - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) ### ๐Ÿ“ฆ Dependency updates From 4209f718ef023dba1ce5a29a2ae65251fb9e660a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 19 Sep 2025 16:06:12 +0200 Subject: [PATCH 1382/1962] [doc] Update release notes (#6029) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 89f99e81101..3847b9d5160 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -27,6 +27,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿ› Fixed Issues * apex-design * [#6022](https://github.com/pmd/pmd/issues/6022): \[apex] ExcessiveClassLength/ExcessiveParameterList include the metric in the message +* java-codestyle + * [#6029](https://github.com/pmd/pmd/issues/6029): \[java] Fix UnnecessaryCast false-negative in method calls * java-design * [#5569](https://github.com/pmd/pmd/issues/5569): \[java] ExcessivePublicCount should report number of public "things" * java-multithreading @@ -49,6 +51,7 @@ This is a {{ site.pmd.release_type }} release. * [#6021](https://github.com/pmd/pmd/pull/6021): \[java] Fix #5569: ExcessiveImports/ExcessiveParameterList/ExcessivePublicCount include the metric in the message - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6022](https://github.com/pmd/pmd/pull/6022): \[apex] ExcessiveClassLength/ExcessiveParameterList include the metric in the message - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6023](https://github.com/pmd/pmd/pull/6023): \[test] Fix #6012: Alphabetically sort all default rules - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6029](https://github.com/pmd/pmd/pull/6029): \[java] Fix UnnecessaryCast false-negative in method calls - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6031](https://github.com/pmd/pmd/pull/6031): \[java] Fix #5880: False Negatives in DoubleCheckedLocking - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6040](https://github.com/pmd/pmd/pull/6040): \[java,apex,plsql,velocity] Change description of "minimum" parameter - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) From c3bd7c06938ad5e9256f8ea3002a849de3f44bc8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 19 Sep 2025 16:08:02 +0200 Subject: [PATCH 1383/1962] [doc] Update release notes (#5878, #6024) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 3847b9d5160..5ee534fe541 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -31,6 +31,8 @@ This is a {{ site.pmd.release_type }} release. * [#6029](https://github.com/pmd/pmd/issues/6029): \[java] Fix UnnecessaryCast false-negative in method calls * java-design * [#5569](https://github.com/pmd/pmd/issues/5569): \[java] ExcessivePublicCount should report number of public "things" +* java-errorprone + * [#5878](https://github.com/pmd/pmd/issues/5878): \[java] DontUseFloatTypeForLoopIndices false-negative if variable is declared before loop * java-multithreading * [#5880](https://github.com/pmd/pmd/issues/5880): \[java] DoubleCheckedLocking is not detected if more than 1 assignment or more than 2 if statements * misc @@ -51,6 +53,7 @@ This is a {{ site.pmd.release_type }} release. * [#6021](https://github.com/pmd/pmd/pull/6021): \[java] Fix #5569: ExcessiveImports/ExcessiveParameterList/ExcessivePublicCount include the metric in the message - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6022](https://github.com/pmd/pmd/pull/6022): \[apex] ExcessiveClassLength/ExcessiveParameterList include the metric in the message - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6023](https://github.com/pmd/pmd/pull/6023): \[test] Fix #6012: Alphabetically sort all default rules - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6024](https://github.com/pmd/pmd/pull/6024): \[java] Fix #5878: DontUseFloatTypeForLoopIndices now checks the UpdateStatement as well - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6029](https://github.com/pmd/pmd/pull/6029): \[java] Fix UnnecessaryCast false-negative in method calls - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6031](https://github.com/pmd/pmd/pull/6031): \[java] Fix #5880: False Negatives in DoubleCheckedLocking - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6040](https://github.com/pmd/pmd/pull/6040): \[java,apex,plsql,velocity] Change description of "minimum" parameter - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) From 0cfcdf1845a257fccc75e709e9976a3dd9e8ce8e Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Sat, 20 Sep 2025 01:42:33 +0200 Subject: [PATCH 1384/1962] [java] Fix false negative in IdenticalCatchBranches for overriddes --- .../codestyle/IdenticalCatchBranchesRule.java | 42 ++++++++++---- .../codestyle/xml/IdenticalCatchBranches.xml | 58 +++++++++++++++++++ 2 files changed, 89 insertions(+), 11 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesRule.java index 36895906b83..057dbe7f2ef 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesRule.java @@ -18,6 +18,9 @@ import net.sourceforge.pmd.lang.java.ast.internal.PrettyPrintingUtil; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; import net.sourceforge.pmd.lang.java.symbols.JExecutableSymbol; +import net.sourceforge.pmd.lang.java.types.JMethodSig; +import net.sourceforge.pmd.lang.java.types.JTypeMirror; +import net.sourceforge.pmd.lang.java.types.TypeTestUtil; import net.sourceforge.pmd.util.OptionalBool; @@ -42,17 +45,34 @@ private boolean areEquivalent(ASTCatchClause st1, ASTCatchClause st2) { String e2Name = st2.getParameter().getName(); return JavaAstUtils.tokenEquals(st1.getBody(), st2.getBody(), name -> name.equals(e1Name) ? e2Name : name) - && areStructurallyEquivalent(st1.getBody(), st2.getBody(), - (n1, n2) -> { - if (n1 instanceof InvocationNode) { - JExecutableSymbol sym1 = ((InvocationNode) n1).getMethodType().getSymbol(); - JExecutableSymbol sym2 = ((InvocationNode) n2).getMethodType().getSymbol(); - if (!Objects.equals(sym1, sym2)) { - return OptionalBool.NO; - } - } - return OptionalBool.UNKNOWN; - }); + && areStructurallyEquivalent(st1.getBody(), st2.getBody(), this::isSameMethod); + } + + private OptionalBool isSameMethod(JavaNode n1, JavaNode n2) { + if (n1 instanceof InvocationNode) { + JMethodSig methodType1 = ((InvocationNode) n1).getMethodType(); + JExecutableSymbol sym1 = methodType1.getSymbol(); + JMethodSig methodType2 = ((InvocationNode) n2).getMethodType(); + JExecutableSymbol sym2 = methodType2.getSymbol(); + if (Objects.equals(sym1, sym2)) { + return OptionalBool.UNKNOWN; + } + if (!sym1.getFormalParameters().equals(sym2.getFormalParameters())) { + return OptionalBool.NO; + } + JTypeMirror declaringType1 = methodType1.getDeclaringType(); + JTypeMirror declaringType2 = methodType2.getDeclaringType(); + boolean isOverride = declaringType2.getSuperTypeSet().stream().anyMatch(st -> + TypeTestUtil.isA(st, declaringType1) && st.streamDeclaredMethods( + method -> method.nameEquals(methodType1.getName()) + && method.getFormalParameters().equals(sym1.getFormalParameters()) + ).findAny().isPresent() + ); + if (!isOverride) { + return OptionalBool.NO; + } + } + return OptionalBool.UNKNOWN; } /** diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/IdenticalCatchBranches.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/IdenticalCatchBranches.xml index 21709c6e5ee..b88c7c7413e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/IdenticalCatchBranches.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/IdenticalCatchBranches.xml @@ -209,4 +209,62 @@ class Foo { } ]]> + + Overridden method call: common supertype + 2 + 7,9 + + + + + + + Overridden method call: unrelated types + 0 + + + + From 097592c10fc64ce1ebeeb5d18a8e670d3c631510 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Sat, 20 Sep 2025 21:11:56 +0200 Subject: [PATCH 1385/1962] A record without equals/hashCode shouldn't be reported. --- ...rideBothEqualsAndHashCodeOnComparableRule.java | 15 ++++++++++++++- .../main/resources/category/java/errorprone.xml | 4 ---- .../OverrideBothEqualsAndHashCodeOnComparable.xml | 6 +----- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java index d6085df7320..cc1857183fe 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java @@ -6,6 +6,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration; +import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; import net.sourceforge.pmd.lang.java.types.JPrimitiveType; import net.sourceforge.pmd.lang.java.types.TypeTestUtil; import net.sourceforge.pmd.reporting.RuleContext; @@ -37,6 +38,16 @@ private static boolean isCompareToMethod(ASTMethodDeclaration method) { && !method.isStatic(); } + private static boolean hasBrokenEqualsMethod(ASTTypeDeclaration node) { + for (ASTMethodDeclaration m : node.getDeclarations(ASTMethodDeclaration.class)) { + if ("equals".equals(m.getName()) && !JavaAstUtils.isEqualsMethod(m)) { + return true; + } + } + + return false; + } + @Override protected void maybeReport(RuleContext ctx, ASTTypeDeclaration node, ASTMethodDeclaration hashCodeMethod, ASTMethodDeclaration equalsMethod) { ASTMethodDeclaration compareToMethod = node @@ -47,7 +58,9 @@ protected void maybeReport(RuleContext ctx, ASTTypeDeclaration node, ASTMethodDe } if (equalsMethod == null && hashCodeMethod == null) { - ctx.addViolationWithMessage(compareToMethod, MISSING_EQUALS_AND_HASH_CODE); + if (!node.isRecord() || hasBrokenEqualsMethod(node)) { + ctx.addViolationWithMessage(compareToMethod, MISSING_EQUALS_AND_HASH_CODE); + } } else if (equalsMethod == null) { ctx.addViolationWithMessage(hashCodeMethod, MISSING_EQUALS); } else if (hashCodeMethod == null) { diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index f8eeefbec7d..86ae23dab19 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -2440,10 +2440,6 @@ public class Foo { // perfect, both methods provided Note 1: This rule is related to {% rule OverrideBothEqualsAndHashcode %}. It will report missing `equals()` and/or `hashCode()` methods for classes only that implement `Comparable`. - - Note 2: This rule also reports records that implement `Comparable`. While - for records, `equals()` and `hashCode()` are generated, you still must make - sure that `compareTo()` is consistent with `equals()`. 3 diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml index 652d837a21c..82a4f6c3140 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml @@ -234,11 +234,7 @@ Record with Comparable and no explicit equals/hashCode - 1 - 3 - - When implementing Comparable, both equals() and hashCode() should be overridden - + 0 { @Override From 3704f5e02f384c183ccbe794f89c298bbfda8199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Sat, 20 Sep 2025 21:31:28 +0200 Subject: [PATCH 1386/1962] Move isCompareToMethod to JavaAstUtils --- .../pmd/lang/java/ast/internal/JavaAstUtils.java | 8 ++++++++ .../OverrideBothEqualsAndHashCodeOnComparableRule.java | 10 +--------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java index 9b0808a15bf..31b2f4a542b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java @@ -93,6 +93,7 @@ import net.sourceforge.pmd.lang.java.symbols.JVariableSymbol; import net.sourceforge.pmd.lang.java.symbols.internal.ast.AstLocalVarSym; import net.sourceforge.pmd.lang.java.types.JMethodSig; +import net.sourceforge.pmd.lang.java.types.JPrimitiveType; import net.sourceforge.pmd.lang.java.types.JPrimitiveType.PrimitiveTypeKind; import net.sourceforge.pmd.lang.java.types.JTypeMirror; import net.sourceforge.pmd.lang.java.types.TypeTestUtil; @@ -732,6 +733,13 @@ public static boolean isHashCodeMethod(ASTMethodDeclaration node) { && !node.isStatic(); } + public static boolean isCompareToMethod(ASTMethodDeclaration method) { + return "compareTo".equals(method.getName()) + && method.getArity() == 1 + && method.getResultTypeNode().getTypeMirror().isPrimitive(JPrimitiveType.PrimitiveTypeKind.INT) + && !method.isStatic(); + } + public static boolean isArrayLengthFieldAccess(ASTExpression node) { if (node instanceof ASTFieldAccess) { ASTFieldAccess field = (ASTFieldAccess) node; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java index cc1857183fe..83e5960b6e8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java @@ -7,7 +7,6 @@ import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration; import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; -import net.sourceforge.pmd.lang.java.types.JPrimitiveType; import net.sourceforge.pmd.lang.java.types.TypeTestUtil; import net.sourceforge.pmd.reporting.RuleContext; @@ -31,13 +30,6 @@ protected boolean skipType(ASTTypeDeclaration node) { return !TypeTestUtil.isA(Comparable.class, node) || TypeTestUtil.isA(Enum.class, node); } - private static boolean isCompareToMethod(ASTMethodDeclaration method) { - return "compareTo".equals(method.getName()) - && method.getArity() == 1 - && method.getResultTypeNode().getTypeMirror().isPrimitive(JPrimitiveType.PrimitiveTypeKind.INT) - && !method.isStatic(); - } - private static boolean hasBrokenEqualsMethod(ASTTypeDeclaration node) { for (ASTMethodDeclaration m : node.getDeclarations(ASTMethodDeclaration.class)) { if ("equals".equals(m.getName()) && !JavaAstUtils.isEqualsMethod(m)) { @@ -52,7 +44,7 @@ private static boolean hasBrokenEqualsMethod(ASTTypeDeclaration node) { protected void maybeReport(RuleContext ctx, ASTTypeDeclaration node, ASTMethodDeclaration hashCodeMethod, ASTMethodDeclaration equalsMethod) { ASTMethodDeclaration compareToMethod = node .getDeclarations(ASTMethodDeclaration.class) - .first(OverrideBothEqualsAndHashCodeOnComparableRule::isCompareToMethod); + .first(JavaAstUtils::isCompareToMethod); if (compareToMethod == null) { return; } From 1a067387381bb02e2ccc00768082c34c531c5e15 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Wed, 24 Sep 2025 01:53:25 +0200 Subject: [PATCH 1387/1962] [java] Fix false positive for ModifierOrder --- .../pmd/lang/java/ast/JModifier.java | 20 +++++++++---------- .../java17/SealedInnerClasses.txt | 4 ++-- .../java17/expression/Expr.txt | 2 +- .../java21/ExhaustiveSwitch.txt | 4 ++-- .../Jep441_PatternMatchingForSwitch.txt | 4 ++-- .../java21/RecordPatternsExhaustiveSwitch.txt | 2 +- .../Jep456_UnnamedPatternsAndVariables.txt | 2 +- ...tiveTypesInPatternsInstanceofAndSwitch.txt | 2 +- ...tiveTypesInPatternsInstanceofAndSwitch.txt | 2 +- .../java/rule/codestyle/xml/ModifierOrder.xml | 10 ++++++++++ 10 files changed, 30 insertions(+), 22 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JModifier.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JModifier.java index 66e71946f4d..e215b56e7d3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JModifier.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JModifier.java @@ -26,27 +26,25 @@ public enum JModifier { PROTECTED(Modifier.PROTECTED), PRIVATE(Modifier.PRIVATE), + ABSTRACT(Modifier.ABSTRACT), + DEFAULT(0), + STATIC(Modifier.STATIC), + FINAL(Modifier.FINAL), + /** Modifier {@code "sealed"} (since Java 17). */ SEALED(0), /** Modifier {@code "non-sealed"} (since Java 17). */ NON_SEALED("non-sealed", 0), - ABSTRACT(Modifier.ABSTRACT), - STATIC(Modifier.STATIC), - FINAL(Modifier.FINAL), - + // for fields + TRANSIENT(Modifier.TRANSIENT), + VOLATILE(Modifier.VOLATILE), // for methods SYNCHRONIZED(Modifier.SYNCHRONIZED), NATIVE(Modifier.NATIVE), - DEFAULT(0), // not for fields - STRICTFP(Modifier.STRICT), - - // for fields - TRANSIENT(Modifier.TRANSIENT), - VOLATILE(Modifier.VOLATILE); - + STRICTFP(Modifier.STRICT); private final String token; private final int reflect; diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/SealedInnerClasses.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/SealedInnerClasses.txt index 4cfd71f285f..620b960bb9b 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/SealedInnerClasses.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/SealedInnerClasses.txt @@ -13,12 +13,12 @@ | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Square"] | | +- ClassBody[@Empty = true, @Size = 0] | +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "SealedInnerClasses$Square$StaticClass", @CanonicalName = "SealedInnerClasses.Square.StaticClass", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "StaticClass", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (JModifier.NON_SEALED, JModifier.STATIC), @ExplicitModifiers = (JModifier.NON_SEALED, JModifier.STATIC)] + | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC, JModifier.NON_SEALED), @ExplicitModifiers = (JModifier.STATIC, JModifier.NON_SEALED)] | +- ImplementsList[@Empty = false, @Size = 1] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Squircle"] | +- ClassBody[@Empty = true, @Size = 0] +- ClassDeclaration[@Abstract = true, @Annotation = false, @Anonymous = false, @BinaryName = "SealedInnerClasses$Squircle", @CanonicalName = "SealedInnerClasses.Squircle", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = true, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = true, @SimpleName = "Squircle", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] - +- ModifierList[@EffectiveModifiers = (JModifier.SEALED, JModifier.ABSTRACT, JModifier.STATIC), @ExplicitModifiers = (JModifier.SEALED)] + +- ModifierList[@EffectiveModifiers = (JModifier.ABSTRACT, JModifier.STATIC, JModifier.SEALED), @ExplicitModifiers = (JModifier.SEALED)] +- PermitsList[@Empty = false, @Size = 2] | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Square"] | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "StaticClass"] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/expression/Expr.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/expression/Expr.txt index 002b3726468..7eef9af075f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/expression/Expr.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java17/expression/Expr.txt @@ -2,7 +2,7 @@ +- PackageDeclaration[@Name = "com.example.expression"] | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] +- ClassDeclaration[@Abstract = true, @Annotation = false, @Anonymous = false, @BinaryName = "com.example.expression.Expr", @CanonicalName = "com.example.expression.Expr", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = true, @Local = false, @Nested = false, @PackageName = "com.example.expression", @Record = false, @RegularClass = false, @RegularInterface = true, @SimpleName = "Expr", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] - +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.SEALED, JModifier.ABSTRACT), @ExplicitModifiers = (JModifier.PUBLIC, JModifier.SEALED)] + +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.ABSTRACT, JModifier.SEALED), @ExplicitModifiers = (JModifier.PUBLIC, JModifier.SEALED)] +- PermitsList[@Empty = false, @Size = 4] | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "ConstantExpr"] | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "PlusExpr"] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ExhaustiveSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ExhaustiveSwitch.txt index e47f062db0f..02e353c5f0a 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ExhaustiveSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ExhaustiveSwitch.txt @@ -76,7 +76,7 @@ | +- SwitchLabel[@Default = true, @PatternLabel = false] | +- BreakStatement[@Label = null] +- ClassDeclaration[@Abstract = true, @Annotation = false, @Anonymous = false, @BinaryName = "ExhaustiveSwitch$S", @CanonicalName = "ExhaustiveSwitch.S", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = true, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = true, @SimpleName = "S", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (JModifier.SEALED, JModifier.ABSTRACT, JModifier.STATIC), @ExplicitModifiers = (JModifier.SEALED)] + | +- ModifierList[@EffectiveModifiers = (JModifier.ABSTRACT, JModifier.STATIC, JModifier.SEALED), @ExplicitModifiers = (JModifier.SEALED)] | +- PermitsList[@Empty = false, @Size = 3] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "A"] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "B"] @@ -186,7 +186,7 @@ | | +- BreakStatement[@Label = null] | +- EmptyStatement[] +- ClassDeclaration[@Abstract = true, @Annotation = false, @Anonymous = false, @BinaryName = "ExhaustiveSwitch$I", @CanonicalName = "ExhaustiveSwitch.I", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = true, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = true, @SimpleName = "I", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (JModifier.SEALED, JModifier.ABSTRACT, JModifier.STATIC), @ExplicitModifiers = (JModifier.SEALED)] + | +- ModifierList[@EffectiveModifiers = (JModifier.ABSTRACT, JModifier.STATIC, JModifier.SEALED), @ExplicitModifiers = (JModifier.SEALED)] | +- TypeParameters[@Empty = false, @Size = 1] | | +- TypeParameter[@Image = "T", @Name = "T", @TypeBound = false] | +- PermitsList[@Empty = false, @Size = 2] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt index 1ad645a2dc3..bb6eac4a489 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt @@ -264,7 +264,7 @@ | +- ArgumentList[@Empty = false, @Size = 1] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Sorry?", @Empty = false, @Image = "\"Sorry?\"", @Length = 6, @LiteralText = "\"Sorry?\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] +- ClassDeclaration[@Abstract = true, @Annotation = false, @Anonymous = false, @BinaryName = "Jep441_PatternMatchingForSwitch$CardClassification", @CanonicalName = "Jep441_PatternMatchingForSwitch.CardClassification", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = true, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = true, @SimpleName = "CardClassification", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (JModifier.SEALED, JModifier.ABSTRACT, JModifier.STATIC), @ExplicitModifiers = (JModifier.SEALED)] + | +- ModifierList[@EffectiveModifiers = (JModifier.ABSTRACT, JModifier.STATIC, JModifier.SEALED), @ExplicitModifiers = (JModifier.SEALED)] | +- PermitsList[@Empty = false, @Size = 2] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Suit"] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Tarot"] @@ -468,7 +468,7 @@ | +- ArgumentList[@Empty = false, @Size = 1] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "It\'s a tarot", @Empty = false, @Image = "\"It\'s a tarot\"", @Length = 12, @LiteralText = "\"It\'s a tarot\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] +- ClassDeclaration[@Abstract = true, @Annotation = false, @Anonymous = false, @BinaryName = "Jep441_PatternMatchingForSwitch$Currency", @CanonicalName = "Jep441_PatternMatchingForSwitch.Currency", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = true, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = true, @SimpleName = "Currency", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (JModifier.SEALED, JModifier.ABSTRACT, JModifier.STATIC), @ExplicitModifiers = (JModifier.SEALED)] + | +- ModifierList[@EffectiveModifiers = (JModifier.ABSTRACT, JModifier.STATIC, JModifier.SEALED), @ExplicitModifiers = (JModifier.SEALED)] | +- PermitsList[@Empty = false, @Size = 1] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Coin"] | +- ClassBody[@Empty = true, @Size = 0] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatternsExhaustiveSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatternsExhaustiveSwitch.txt index 1b4098d2f75..d61d70dccee 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatternsExhaustiveSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatternsExhaustiveSwitch.txt @@ -11,7 +11,7 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "A"] | +- ClassBody[@Empty = true, @Size = 0] +- ClassDeclaration[@Abstract = true, @Annotation = false, @Anonymous = false, @BinaryName = "RecordPatternsExhaustiveSwitch$I", @CanonicalName = "RecordPatternsExhaustiveSwitch.I", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = true, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = true, @SimpleName = "I", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (JModifier.SEALED, JModifier.ABSTRACT, JModifier.STATIC), @ExplicitModifiers = (JModifier.SEALED)] + | +- ModifierList[@EffectiveModifiers = (JModifier.ABSTRACT, JModifier.STATIC, JModifier.SEALED), @ExplicitModifiers = (JModifier.SEALED)] | +- PermitsList[@Empty = false, @Size = 2] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "C"] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "D"] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt index ff129f62484..d83a5066bfa 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt @@ -126,7 +126,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = " ", @Empty = false, @Image = "\" \"", @Length = 1, @LiteralText = "\" \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "y", @Name = "y", @ParenthesisDepth = 0, @Parenthesized = false] +- ClassDeclaration[@Abstract = true, @Annotation = false, @Anonymous = false, @BinaryName = "Jep456_UnnamedPatternsAndVariables$Ball", @CanonicalName = "Jep456_UnnamedPatternsAndVariables.Ball", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Ball", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (JModifier.SEALED, JModifier.ABSTRACT), @ExplicitModifiers = (JModifier.SEALED, JModifier.ABSTRACT)] + | +- ModifierList[@EffectiveModifiers = (JModifier.ABSTRACT, JModifier.SEALED), @ExplicitModifiers = (JModifier.ABSTRACT, JModifier.SEALED)] | +- PermitsList[@Empty = false, @Size = 3] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "RedBall"] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "BlueBall"] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt index c228a586ba1..001fb04dd0f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt @@ -133,7 +133,7 @@ | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] | +- ArgumentList[@Empty = true, @Size = 0] +- ClassDeclaration[@Abstract = true, @Annotation = false, @Anonymous = false, @BinaryName = "Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch$JsonValue", @CanonicalName = "Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.JsonValue", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = true, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = true, @SimpleName = "JsonValue", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (JModifier.SEALED, JModifier.ABSTRACT, JModifier.STATIC), @ExplicitModifiers = (JModifier.SEALED)] + | +- ModifierList[@EffectiveModifiers = (JModifier.ABSTRACT, JModifier.STATIC, JModifier.SEALED), @ExplicitModifiers = (JModifier.SEALED)] | +- ClassBody[@Empty = true, @Size = 0] +- RecordDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch$JsonString", @CanonicalName = "Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.JsonString", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = true, @RegularClass = false, @RegularInterface = false, @SimpleName = "JsonString", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = ()] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25p/Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25p/Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.txt index b0ab8cd21fb..1da9ed524af 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25p/Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25p/Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.txt @@ -133,7 +133,7 @@ | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] | +- ArgumentList[@Empty = true, @Size = 0] +- ClassDeclaration[@Abstract = true, @Annotation = false, @Anonymous = false, @BinaryName = "Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch$JsonValue", @CanonicalName = "Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.JsonValue", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = true, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = true, @SimpleName = "JsonValue", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (JModifier.SEALED, JModifier.ABSTRACT, JModifier.STATIC), @ExplicitModifiers = (JModifier.SEALED)] + | +- ModifierList[@EffectiveModifiers = (JModifier.ABSTRACT, JModifier.STATIC, JModifier.SEALED), @ExplicitModifiers = (JModifier.SEALED)] | +- ClassBody[@Empty = true, @Size = 0] +- RecordDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch$JsonString", @CanonicalName = "Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.JsonString", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = true, @RegularClass = false, @RegularInterface = false, @SimpleName = "JsonString", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = ()] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ModifierOrder.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ModifierOrder.xml index 089e6ee551b..78b36691b50 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ModifierOrder.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ModifierOrder.xml @@ -268,5 +268,15 @@ abstract public class Foo { // warn l1 ]]> + + Sealed class + 0 + + + From 228d313685c2f571058bc9e71e4a68ec832c6bb2 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Wed, 24 Sep 2025 23:58:20 +0200 Subject: [PATCH 1388/1962] Move logic to TypeOps, formatting --- .../codestyle/IdenticalCatchBranchesRule.java | 26 +++---------------- .../pmd/lang/java/types/TypeOps.java | 20 ++++++++++++++ .../codestyle/IdenticalCatchBranchesTest.java | 3 +++ .../codestyle/xml/IdenticalCatchBranches.xml | 9 +++---- 4 files changed, 30 insertions(+), 28 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesRule.java index 057dbe7f2ef..540385c1d23 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesRule.java @@ -7,7 +7,6 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; -import java.util.Objects; import java.util.Set; import net.sourceforge.pmd.lang.java.ast.ASTCatchClause; @@ -17,10 +16,8 @@ import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; import net.sourceforge.pmd.lang.java.ast.internal.PrettyPrintingUtil; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; -import net.sourceforge.pmd.lang.java.symbols.JExecutableSymbol; import net.sourceforge.pmd.lang.java.types.JMethodSig; -import net.sourceforge.pmd.lang.java.types.JTypeMirror; -import net.sourceforge.pmd.lang.java.types.TypeTestUtil; +import net.sourceforge.pmd.lang.java.types.TypeOps; import net.sourceforge.pmd.util.OptionalBool; @@ -51,26 +48,9 @@ private boolean areEquivalent(ASTCatchClause st1, ASTCatchClause st2) { private OptionalBool isSameMethod(JavaNode n1, JavaNode n2) { if (n1 instanceof InvocationNode) { JMethodSig methodType1 = ((InvocationNode) n1).getMethodType(); - JExecutableSymbol sym1 = methodType1.getSymbol(); JMethodSig methodType2 = ((InvocationNode) n2).getMethodType(); - JExecutableSymbol sym2 = methodType2.getSymbol(); - if (Objects.equals(sym1, sym2)) { - return OptionalBool.UNKNOWN; - } - if (!sym1.getFormalParameters().equals(sym2.getFormalParameters())) { - return OptionalBool.NO; - } - JTypeMirror declaringType1 = methodType1.getDeclaringType(); - JTypeMirror declaringType2 = methodType2.getDeclaringType(); - boolean isOverride = declaringType2.getSuperTypeSet().stream().anyMatch(st -> - TypeTestUtil.isA(st, declaringType1) && st.streamDeclaredMethods( - method -> method.nameEquals(methodType1.getName()) - && method.getFormalParameters().equals(sym1.getFormalParameters()) - ).findAny().isPresent() - ); - if (!isOverride) { - return OptionalBool.NO; - } + return TypeOps.overrideSameMethod(methodType1, methodType2) + ? OptionalBool.UNKNOWN : OptionalBool.NO; } return OptionalBool.UNKNOWN; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java index 6c6945fe9c5..d43f3887193 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java @@ -1460,6 +1460,26 @@ public static boolean overrides(JMethodSig m1, JMethodSig m2, JTypeMirror origin return false; } + /** + * Returns true if both methods override the same method of a common supertype. + */ + public static boolean overrideSameMethod(JMethodSig m1, JMethodSig m2) { + if (Objects.equals(m1.getSymbol(), m2.getSymbol())) { + return true; + } + if (!haveSameSignature(m1, m2)) { + return false; + } + JTypeMirror declaringType1 = m1.getDeclaringType(); + JTypeMirror declaringType2 = m2.getDeclaringType(); + return declaringType2.getSuperTypeSet().stream().anyMatch(st -> + TypeTestUtil.isA(st, declaringType1) && st.streamDeclaredMethods( + method -> method.nameEquals(m1.getName()) + && method.getFormalParameters().equals(m1.getSymbol().getFormalParameters()) + ).findAny().isPresent() + ); + } + private static boolean isOverridableIn(JMethodSig m, JTypeDeclSymbol origin) { return isOverridableIn(m.getSymbol(), origin); } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesTest.java index de207318839..b68f660b199 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/codestyle/IdenticalCatchBranchesTest.java @@ -6,6 +6,9 @@ import net.sourceforge.pmd.test.PmdRuleTst; +/** + * Test for {@link IdenticalCatchBranchesRule}. + */ class IdenticalCatchBranchesTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/IdenticalCatchBranches.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/IdenticalCatchBranches.xml index b88c7c7413e..ee7494c4fca 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/IdenticalCatchBranches.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/IdenticalCatchBranches.xml @@ -207,14 +207,14 @@ class Foo { } - ]]> + ]]> + Overridden method call: common supertype 2 7,9 - - - + ]]> From 6c6260bd2c1f35dcaa58fd9a29527ed4da180f78 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 09:42:19 +0200 Subject: [PATCH 1389/1962] chore(deps): bump ruby/setup-ruby from 1.258.0 to 1.263.0 (#6086) Bumps [ruby/setup-ruby](https://github.com/ruby/setup-ruby) from 1.258.0 to 1.263.0. - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/3fee6763234110473bd57dd4595c5199fce2c510...0481980f17b760ef6bca5e8c55809102a0af1e5a) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-version: 1.263.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 4 ++-- .github/workflows/publish-release.yml | 2 +- .github/workflows/publish-snapshot.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 70818847a4b..af136844c70 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -278,7 +278,7 @@ jobs: -Pgenerate-rule-docs,fastSkip \ -DskipTests -Dassembly.skipAssembly=true - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@3fee6763234110473bd57dd4595c5199fce2c510 #v1.258.0 + uses: ruby/setup-ruby@0481980f17b760ef6bca5e8c55809102a0af1e5a #v1.263.0 with: ruby-version: 3.3 - name: Setup bundler @@ -317,7 +317,7 @@ jobs: distribution: 'temurin' java-version: '11' - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@3fee6763234110473bd57dd4595c5199fce2c510 #v1.258.0 + uses: ruby/setup-ruby@0481980f17b760ef6bca5e8c55809102a0af1e5a #v1.263.0 with: ruby-version: 3.3 - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 612e93984e9..10e825f737d 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -630,7 +630,7 @@ jobs: distribution: 'temurin' java-version: '11' - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@3fee6763234110473bd57dd4595c5199fce2c510 #v1.258.0 + uses: ruby/setup-ruby@0481980f17b760ef6bca5e8c55809102a0af1e5a #v1.263.0 with: ruby-version: 3.3 - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 367e3488f0f..314ab506250 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -647,7 +647,7 @@ jobs: distribution: 'temurin' java-version: '11' - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@3fee6763234110473bd57dd4595c5199fce2c510 #v1.258.0 + uses: ruby/setup-ruby@0481980f17b760ef6bca5e8c55809102a0af1e5a #v1.263.0 with: ruby-version: 3.3 - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 From d00330b55f392e1064b0aa456274924fd103b967 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 09:42:48 +0200 Subject: [PATCH 1390/1962] chore(deps-dev): bump log4j.version from 2.25.1 to 2.25.2 (#6087) Bumps `log4j.version` from 2.25.1 to 2.25.2. Updates `org.apache.logging.log4j:log4j-api` from 2.25.1 to 2.25.2 Updates `org.apache.logging.log4j:log4j-core` from 2.25.1 to 2.25.2 --- updated-dependencies: - dependency-name: org.apache.logging.log4j:log4j-api dependency-version: 2.25.2 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: org.apache.logging.log4j:log4j-core dependency-version: 2.25.2 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-java/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 1024a030aa5..2a2b98d0bd3 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -12,7 +12,7 @@ - 2.25.1 + 2.25.2 From d760ac844ce8a5a392dc5c70dd09df6e232dde6e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 09:43:10 +0200 Subject: [PATCH 1391/1962] chore(deps): bump org.mockito:mockito-core from 5.19.0 to 5.20.0 (#6088) Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.19.0 to 5.20.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.19.0...v5.20.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-version: 5.20.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 95c5d61116f..48e28a08b8c 100644 --- a/pom.xml +++ b/pom.xml @@ -1028,7 +1028,7 @@ org.mockito mockito-core - 5.19.0 + 5.20.0 test From 6b5a613d16e13a750b684b68f6692bb80f599387 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 09:43:35 +0200 Subject: [PATCH 1392/1962] chore(deps): bump org.apache.maven.plugins:maven-javadoc-plugin from 3.11.3 to 3.12.0 (#6089) chore(deps): bump org.apache.maven.plugins:maven-javadoc-plugin Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.11.3 to 3.12.0. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.11.3...maven-javadoc-plugin-3.12.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-version: 3.12.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 48e28a08b8c..55b217bdce9 100644 --- a/pom.xml +++ b/pom.xml @@ -96,7 +96,7 @@ 3.6.0 3.27.0 1.10.15 - 3.11.3 + 3.12.0 4.9.3 1.7.36 12.5 From d3c32804d3ec5af73568d7c71b29c3fa84d0ad68 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 09:44:53 +0200 Subject: [PATCH 1393/1962] chore(deps): bump org.codehaus.mojo:versions-maven-plugin from 2.19.0 to 2.19.1 (#6090) chore(deps): bump org.codehaus.mojo:versions-maven-plugin Bumps [org.codehaus.mojo:versions-maven-plugin](https://github.com/mojohaus/versions) from 2.19.0 to 2.19.1. - [Release notes](https://github.com/mojohaus/versions/releases) - [Changelog](https://github.com/mojohaus/versions/blob/master/ReleaseNotes.md) - [Commits](https://github.com/mojohaus/versions/compare/2.19.0...2.19.1) --- updated-dependencies: - dependency-name: org.codehaus.mojo:versions-maven-plugin dependency-version: 2.19.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 55b217bdce9..52e6f35d4fc 100644 --- a/pom.xml +++ b/pom.xml @@ -641,7 +641,7 @@ org.codehaus.mojo versions-maven-plugin - 2.19.0 + 2.19.1 org.sonatype.central From 5b17810b1a8231a851469a5b65470aa5b8b8b001 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 09:45:17 +0200 Subject: [PATCH 1394/1962] chore(deps): bump org.apache.maven.plugins:maven-compiler-plugin from 3.14.0 to 3.14.1 (#6091) chore(deps): bump org.apache.maven.plugins:maven-compiler-plugin Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.14.0 to 3.14.1. - [Release notes](https://github.com/apache/maven-compiler-plugin/releases) - [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.14.0...maven-compiler-plugin-3.14.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-compiler-plugin dependency-version: 3.14.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 52e6f35d4fc..a691e81ba32 100644 --- a/pom.xml +++ b/pom.xml @@ -272,7 +272,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.14.0 + 3.14.1 ${java.version} From a421bcf6a587711c0d5a0f52a71c7596e1271719 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Mon, 8 Sep 2025 15:00:32 +0200 Subject: [PATCH 1395/1962] trim token before feeding it to the extractor --- .../pmd/properties/internal/PropertyParsingUtil.java | 7 ++++--- .../sourceforge/pmd/properties/PropertyDescriptorTest.java | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java index 7966886f59a..b4b24bab89a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java @@ -165,7 +165,7 @@ public static List parseListWithEscapes(String str, char delimiter, Funct inEscapeMode = false; currentToken.append(c); } else if (c == delimiter) { - result.add(extractor.apply(currentToken.toString())); + result.add(extractor.apply(currentToken.toString().trim())); currentToken = new StringBuilder(); } else if (c == ESCAPE_CHAR && i < str.length() - 1) { // this is ordered this way so that if the delimiter is @@ -176,8 +176,9 @@ public static List parseListWithEscapes(String str, char delimiter, Funct } } - if (currentToken.length() > 0) { - result.add(extractor.apply(currentToken.toString())); + String currentTokenString = currentToken.toString().trim(); + if (!currentTokenString.isEmpty()) { + result.add(extractor.apply(currentTokenString)); } return result; } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java index 35aa820e3f4..1847876af9c 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java @@ -191,6 +191,7 @@ void testStringListProperty() { assertEquals(Arrays.asList("v1", "v2"), listDescriptor.defaultValue()); assertEquals(Arrays.asList("foo", "bar"), listDescriptor.serializer().fromString("foo,bar")); assertEquals(Arrays.asList("foo", "bar"), listDescriptor.serializer().fromString(" foo , bar ")); + assertEquals(Arrays.asList("foo", "bar"), listDescriptor.serializer().fromString(" foo , bar , ")); // Github issue 4714 } private enum SampleEnum { A, B, C } From b2aacdc68d3d68ea7ee6431c3e623447d835b17e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Mon, 8 Sep 2025 16:50:33 +0200 Subject: [PATCH 1396/1962] update javadocs --- .../pmd/properties/internal/PropertyParsingUtil.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java index b4b24bab89a..69f56aaa3e5 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java @@ -148,6 +148,15 @@ public static > PropertySerializer delimitedString(P * "a\" -> [ "a\" ] (a backslash at the end of the string is just a backslash) * * } + * + * The list may end with a separator. Any whitespace around tokens is ignored: + * + *
    {@code
    +     * " a , c " -> [ "a", "c" ]
    +     * " a , c , " -> [ "a", "c" ]
    +     * }
    + * + * */ public static List parseListWithEscapes(String str, char delimiter, Function extractor) { if (str.isEmpty()) { From 815a0bf91c87eca78e34f090f0bb8ec334ff5eca Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 25 Sep 2025 09:55:10 +0200 Subject: [PATCH 1397/1962] [doc] Update release notes (#4714, #6039) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 5ee534fe541..29f830ac87f 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,6 +25,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy ### ๐Ÿ› Fixed Issues +* core + * [#4714](https://github.com/pmd/pmd/issues/4714): \[core] Allow trailing commas in multivalued properties * apex-design * [#6022](https://github.com/pmd/pmd/issues/6022): \[apex] ExcessiveClassLength/ExcessiveParameterList include the metric in the message * java-codestyle @@ -56,6 +58,7 @@ This is a {{ site.pmd.release_type }} release. * [#6024](https://github.com/pmd/pmd/pull/6024): \[java] Fix #5878: DontUseFloatTypeForLoopIndices now checks the UpdateStatement as well - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6029](https://github.com/pmd/pmd/pull/6029): \[java] Fix UnnecessaryCast false-negative in method calls - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6031](https://github.com/pmd/pmd/pull/6031): \[java] Fix #5880: False Negatives in DoubleCheckedLocking - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#6039](https://github.com/pmd/pmd/pull/6039): \[core] Fix #4714: trim token before feeding it to the extractor - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6040](https://github.com/pmd/pmd/pull/6040): \[java,apex,plsql,velocity] Change description of "minimum" parameter - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) ### ๐Ÿ“ฆ Dependency updates From dc0a557e2a3aff5a283205660213e60353b0412c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Tue, 9 Sep 2025 22:06:46 +0200 Subject: [PATCH 1398/1962] Reactivate deactivated test. See #3122. Turns out, the code already works. Just need to make sure the variable is used. --- .../lang/java/rule/codestyle/xml/LocalVariableCouldBeFinal.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LocalVariableCouldBeFinal.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LocalVariableCouldBeFinal.xml index ac5facdc56c..86884b921a1 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LocalVariableCouldBeFinal.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LocalVariableCouldBeFinal.xml @@ -83,7 +83,7 @@ public class Foo { ]]>
    - + #3122 Blank uninitialized local var 3 3,4,5 @@ -94,6 +94,7 @@ public class Foo { int b = 0; int c ; c = a + b; + System.out.println(c); } } ]]> From d3a8108a4ff663ccb66e2084da668ce953188192 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 25 Sep 2025 11:57:09 +0200 Subject: [PATCH 1399/1962] [doc] Update release notes (#6043) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 29f830ac87f..e88c684b2fe 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -60,6 +60,7 @@ This is a {{ site.pmd.release_type }} release. * [#6031](https://github.com/pmd/pmd/pull/6031): \[java] Fix #5880: False Negatives in DoubleCheckedLocking - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6039](https://github.com/pmd/pmd/pull/6039): \[core] Fix #4714: trim token before feeding it to the extractor - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6040](https://github.com/pmd/pmd/pull/6040): \[java,apex,plsql,velocity] Change description of "minimum" parameter - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6043](https://github.com/pmd/pmd/pull/6043): \[java] Reactivate deactivated test in LocalVariableCouldBeFinal - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) ### ๐Ÿ“ฆ Dependency updates From d2e8ac03f1972a853f9104294aaa24c06da517d9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 25 Sep 2025 15:20:54 +0200 Subject: [PATCH 1400/1962] Bump PMD from 7.16.0 to 7.17.0 (#6054) --- pom.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index a691e81ba32..13500f468a0 100644 --- a/pom.xml +++ b/pom.xml @@ -603,27 +603,27 @@ net.sourceforge.pmd pmd-core - 7.16.0 + 7.17.0 net.sourceforge.pmd pmd-java - 7.16.0 + 7.17.0 net.sourceforge.pmd pmd-jsp - 7.16.0 + 7.17.0 net.sourceforge.pmd pmd-javascript - 7.16.0 + 7.17.0 net.sourceforge.pmd pmd-xml - 7.16.0 + 7.17.0 From bcb31ebad46824b8dd2e7d9f93c1a2f183dd2b7d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 25 Sep 2025 15:21:27 +0200 Subject: [PATCH 1401/1962] chore(deps): Bump rexml from 3.4.1 to 3.4.4 (#6094) --- docs/Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index 0258a32d199..72b35ca1ff8 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -247,7 +247,7 @@ GEM rb-fsevent (0.11.2) rb-inotify (0.11.1) ffi (~> 1.0) - rexml (3.4.1) + rexml (3.4.4) rouge (3.30.0) rubyzip (2.4.1) safe_yaml (1.0.5) From c37b29c7995185862b702942487546dbbf3d895c Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Sat, 13 Sep 2025 10:36:03 +0200 Subject: [PATCH 1402/1962] [java] Fix #6058: DanglingJavadoc FP in module-info files --- .../rule/documentation/DanglingJavadocRule.java | 4 ++++ .../rule/documentation/xml/DanglingJavadoc.xml | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/DanglingJavadocRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/DanglingJavadocRule.java index 8298cca68d9..bb50f16fb39 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/DanglingJavadocRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/DanglingJavadocRule.java @@ -21,6 +21,10 @@ public DanglingJavadocRule() { @Override public Object visit(ASTCompilationUnit unit, Object data) { + if (unit.getModuleDeclaration() != null) { + return null; + } + for (JavaComment comment: unit.getComments()) { if (comment instanceof JavadocComment && ((JavadocComment) comment).getOwner() == null) { asCtx(data).addViolationWithPosition(comment.getToken(), diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/DanglingJavadoc.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/DanglingJavadoc.xml index 55e8c347489..631f8558398 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/DanglingJavadoc.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/DanglingJavadoc.xml @@ -78,4 +78,20 @@ public class Foo { /// violation ]]> + + + #6058: javadoc in module-info + 0 + + \ No newline at end of file From ae430a97386f5aace3fbcbca1f05ed30ac04f57e Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Sat, 13 Sep 2025 17:18:36 +0200 Subject: [PATCH 1403/1962] #6058: ASTModuleDeclaration now implements JavadocCommentOwner --- .../pmd/lang/java/ast/ASTModuleDeclaration.java | 2 +- .../java/rule/documentation/DanglingJavadocRule.java | 4 ---- .../pmd/lang/java/ast/CommentAssignmentTest.java | 9 +++++++++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleDeclaration.java index a61c9aea7c2..ac6ba5022e3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTModuleDeclaration.java @@ -18,7 +18,7 @@ * * */ -public final class ASTModuleDeclaration extends AbstractJavaNode implements Annotatable { +public final class ASTModuleDeclaration extends AbstractJavaNode implements Annotatable, JavadocCommentOwner { private boolean open; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/DanglingJavadocRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/DanglingJavadocRule.java index bb50f16fb39..8298cca68d9 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/DanglingJavadocRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/DanglingJavadocRule.java @@ -21,10 +21,6 @@ public DanglingJavadocRule() { @Override public Object visit(ASTCompilationUnit unit, Object data) { - if (unit.getModuleDeclaration() != null) { - return null; - } - for (JavaComment comment: unit.getComments()) { if (comment instanceof JavadocComment && ((JavadocComment) comment).getOwner() == null) { asCtx(data).addViolationWithPosition(comment.getToken(), diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/CommentAssignmentTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/CommentAssignmentTest.java index cddc461a408..3a9617357e0 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/CommentAssignmentTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/CommentAssignmentTest.java @@ -124,6 +124,15 @@ void testCommentAssignmentOnEnum() { assertHasNoComment(constants.get(3)); } + @Test + void testCommentAssignmentOnModuleInfo() { + final String moduleComment = "/** Module Description */"; + ASTCompilationUnit node = java.parse(moduleComment + "\n" + + "module my.module {}\n"); + + assertCommentEquals(node.descendants(ASTModuleDeclaration.class).firstOrThrow(), + moduleComment); + } private void assertCommentEquals(JavadocCommentOwner pack, String expected) { assertNotNull(pack.getJavadocComment(), "null comment on " + pack); From 121216b5b7c96a26e5bce7a2ef2150df22a7a898 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 25 Sep 2025 15:31:04 +0200 Subject: [PATCH 1404/1962] [doc] Update release notes (#6058, #6059) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index e88c684b2fe..17fd74a04c0 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -33,6 +33,8 @@ This is a {{ site.pmd.release_type }} release. * [#6029](https://github.com/pmd/pmd/issues/6029): \[java] Fix UnnecessaryCast false-negative in method calls * java-design * [#5569](https://github.com/pmd/pmd/issues/5569): \[java] ExcessivePublicCount should report number of public "things" +* java-documentation + * [#6058](https://github.com/pmd/pmd/issues/6058): \[java] DanglingJavadoc FP in module-info files * java-errorprone * [#5878](https://github.com/pmd/pmd/issues/5878): \[java] DontUseFloatTypeForLoopIndices false-negative if variable is declared before loop * java-multithreading @@ -61,6 +63,7 @@ This is a {{ site.pmd.release_type }} release. * [#6039](https://github.com/pmd/pmd/pull/6039): \[core] Fix #4714: trim token before feeding it to the extractor - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6040](https://github.com/pmd/pmd/pull/6040): \[java,apex,plsql,velocity] Change description of "minimum" parameter - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6043](https://github.com/pmd/pmd/pull/6043): \[java] Reactivate deactivated test in LocalVariableCouldBeFinal - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6059](https://github.com/pmd/pmd/pull/6059): \[java] Fix #6058: DanglingJavadoc FP in module-info files - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) ### ๐Ÿ“ฆ Dependency updates From 386c8ff0549097694d8499981eacb1b2b0cf71cf Mon Sep 17 00:00:00 2001 From: Anton Bobov Date: Wed, 17 Sep 2025 23:12:28 +0500 Subject: [PATCH 1405/1962] [java] Add integration tests to ClassNamingConventions testClassRegex Update the default regex pattern for test class naming conventions to include Maven Failsafe Plugin defaults: - Integration test prefix (IT) - Integration test suffixes (IT, ITCase) Refs #5919 --- .../codestyle/ClassNamingConventionsRule.java | 2 +- .../codestyle/xml/ClassNamingConventions.xml | 29 ++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ClassNamingConventionsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ClassNamingConventionsRule.java index 095a450ac9d..e7080c29937 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ClassNamingConventionsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ClassNamingConventionsRule.java @@ -30,7 +30,7 @@ public class ClassNamingConventionsRule extends AbstractNamingConventionRule utilityClassRegex = defaultProp("utility class").build(); private final PropertyDescriptor testClassRegex = defaultProp("test class") .desc("Regex which applies to test class names. Since PMD 6.52.0.") - .defaultValue("^Test.*$|^[A-Z][a-zA-Z0-9]*Test(s|Case)?$").build(); + .defaultValue("^(Test|IT).*$|^[A-Z][a-zA-Z0-9]*(Test|Tests|TestCase|IT|ITCase)$").build(); public ClassNamingConventionsRule() { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ClassNamingConventions.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ClassNamingConventions.xml index 8b924fd0a2a..c6cf2c99e0c 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ClassNamingConventions.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ClassNamingConventions.xml @@ -436,7 +436,34 @@ import junit.framework.TestCase; public class ExampleTestCase extends TestCase { } ]]> - + + + Integration test class with IT suffix should be valid #5919 + 0 + + + + + Integration test class with ITCase suffix should be valid #5919 + 0 + + + + + Integration test class with IT prefix should be valid + 0 + + + [java] ClassNamingConventions: interfaces are identified as abstract classes (regression in 7.0.0) #4881 Abstract[A-Z][a-zA-Z0-9]* From bdfe24bc8195072facb5569cb4eae15222159f72 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 25 Sep 2025 15:59:49 +0200 Subject: [PATCH 1406/1962] [doc] Update release notes (#5919, #6071) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 17fd74a04c0..8386795ae34 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -30,6 +30,7 @@ This is a {{ site.pmd.release_type }} release. * apex-design * [#6022](https://github.com/pmd/pmd/issues/6022): \[apex] ExcessiveClassLength/ExcessiveParameterList include the metric in the message * java-codestyle + * [#5919](https://github.com/pmd/pmd/issues/5919): \[java] ClassNamingConventions: Include integration tests in testClassPattern by default * [#6029](https://github.com/pmd/pmd/issues/6029): \[java] Fix UnnecessaryCast false-negative in method calls * java-design * [#5569](https://github.com/pmd/pmd/issues/5569): \[java] ExcessivePublicCount should report number of public "things" @@ -64,6 +65,7 @@ This is a {{ site.pmd.release_type }} release. * [#6040](https://github.com/pmd/pmd/pull/6040): \[java,apex,plsql,velocity] Change description of "minimum" parameter - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6043](https://github.com/pmd/pmd/pull/6043): \[java] Reactivate deactivated test in LocalVariableCouldBeFinal - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6059](https://github.com/pmd/pmd/pull/6059): \[java] Fix #6058: DanglingJavadoc FP in module-info files - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#6071](https://github.com/pmd/pmd/pull/6071): \[java] Fix #5919: Add integration tests to ClassNamingConventions testClassRegex - [Anton Bobov](https://github.com/abobov) (@abobov) ### ๐Ÿ“ฆ Dependency updates From eb36548bbd3e407f60b4203a7f49fd2661c183d7 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 25 Sep 2025 16:00:19 +0200 Subject: [PATCH 1407/1962] Add @abobov as a contributor --- .all-contributorsrc | 9 + docs/pages/pmd/projectdocs/credits.md | 241 +++++++++++++------------- 2 files changed, 130 insertions(+), 120 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 14dee6d8ef7..545fa8ac897 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8244,6 +8244,15 @@ "contributions": [ "bug" ] + }, + { + "login": "abobov", + "name": "Anton Bobov", + "avatar_url": "https://avatars.githubusercontent.com/u/162897?v=4", + "profile": "https://github.com/abobov", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 4386e8247af..7b3a144897e 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -93,1080 +93,1081 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
    - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + From 7628675dc2756e384b39ef8450206acd870cf71b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Thu, 18 Sep 2025 17:51:36 -0300 Subject: [PATCH 1408/1962] Add failing test for #5935 --- .../pmd/lang/apex/SuppressWarningsTest.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/SuppressWarningsTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/SuppressWarningsTest.java index c2131f234c1..ec553f21a3b 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/SuppressWarningsTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/SuppressWarningsTest.java @@ -145,6 +145,17 @@ void testSpecificSuppressionMulitpleValues() { + "}"); } + @Test + void testSpecificSuppressionMulitpleValuesReverseOrder() { + assertNoWarningsWithFoo("@SuppressWarnings('PMD.NoBar, PMD.NoFoo')" + + "\n" + "public class Bar {\n" + + " Integer foo;\n" + + " void bar() {" + "\n" + + " Integer foo;\n" + + " }\n" + + "}"); + } + @Test void testNoSuppressionBlank() { assertWarningsWithFoo(2, "public class Bar {\n" From df47037e4f90f5a8a96ca331ac9500ff7b75b8fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Thu, 18 Sep 2025 17:51:51 -0300 Subject: [PATCH 1409/1962] Fix #5935 --- .../net/sourceforge/pmd/lang/apex/ApexAnnotationSuppressor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexAnnotationSuppressor.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexAnnotationSuppressor.java index ec727c48b10..6d23c3eeacc 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexAnnotationSuppressor.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexAnnotationSuppressor.java @@ -41,7 +41,7 @@ protected boolean walkAnnotation(ASTAnnotation annot, AnnotationWalkCallbacks ca if (image != null) { for (String part : image.split(",")) { - if (callbacks.processNode(param, part)) { + if (callbacks.processNode(param, part.trim())) { return true; } } From 8c6a993920b7784cc8ec380dc9dd2836c7c1242d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Thu, 18 Sep 2025 17:53:38 -0300 Subject: [PATCH 1410/1962] [doc] Update release notes (#6074, #5935) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 8386795ae34..ac301af9f4f 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -27,6 +27,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿ› Fixed Issues * core * [#4714](https://github.com/pmd/pmd/issues/4714): \[core] Allow trailing commas in multivalued properties +* apex + * [#5935](https://github.com/pmd/pmd/issues/5935): \[apex] @SuppressWarnings - allow whitespace around comma when suppressing multiple rules * apex-design * [#6022](https://github.com/pmd/pmd/issues/6022): \[apex] ExcessiveClassLength/ExcessiveParameterList include the metric in the message * java-codestyle @@ -66,6 +68,7 @@ This is a {{ site.pmd.release_type }} release. * [#6043](https://github.com/pmd/pmd/pull/6043): \[java] Reactivate deactivated test in LocalVariableCouldBeFinal - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6059](https://github.com/pmd/pmd/pull/6059): \[java] Fix #6058: DanglingJavadoc FP in module-info files - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6071](https://github.com/pmd/pmd/pull/6071): \[java] Fix #5919: Add integration tests to ClassNamingConventions testClassRegex - [Anton Bobov](https://github.com/abobov) (@abobov) +* [#6074](https://github.com/pmd/pmd/pull/6074): \[apex] Fix @SuppressWarnings with whitespace around comma - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) ### ๐Ÿ“ฆ Dependency updates From 9f7989ff69b3a45bd44c6a428f90f6270af0b53e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 25 Sep 2025 15:53:59 +0200 Subject: [PATCH 1411/1962] [apex] Improved testcase for suppress warnings --- .../pmd/lang/apex/SuppressWarningsTest.java | 34 ++++++++----------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/SuppressWarningsTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/SuppressWarningsTest.java index ec553f21a3b..75f26904064 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/SuppressWarningsTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/SuppressWarningsTest.java @@ -11,6 +11,8 @@ import java.util.List; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import net.sourceforge.pmd.lang.apex.ast.ASTUserClass; import net.sourceforge.pmd.lang.apex.ast.ApexParserTestBase; @@ -134,26 +136,18 @@ void testSpecificSuppression() { + "}"); } - @Test - void testSpecificSuppressionMulitpleValues() { - assertNoWarningsWithFoo("@SuppressWarnings('PMD.NoFoo, PMD.NoBar')" - + "\n" + "public class Bar {\n" - + " Integer foo;\n" - + " void bar() {" + "\n" - + " Integer foo;\n" - + " }\n" - + "}"); - } - - @Test - void testSpecificSuppressionMulitpleValuesReverseOrder() { - assertNoWarningsWithFoo("@SuppressWarnings('PMD.NoBar, PMD.NoFoo')" - + "\n" + "public class Bar {\n" - + " Integer foo;\n" - + " void bar() {" + "\n" - + " Integer foo;\n" - + " }\n" - + "}"); + @ParameterizedTest + @ValueSource(strings = { + "PMD.NoFoo,PMD.NoBar", "PMD.NoFoo, PMD.NoBar", "PMD.NoFoo ,PMD.NoBar", "PMD.NoFoo , PMD.NoBar", + "PMD.NoBar,PMD.NoFoo", "PMD.NoBar, PMD.NoFoo", "PMD.NoBar ,PMD.NoFoo", "PMD.NoBar , PMD.NoFoo"}) + void testSpecificSuppressionMultipleValues(String suppressWarningsValue) { + assertNoWarningsWithFoo("@SuppressWarnings('" + suppressWarningsValue + "')" + + "\n" + "public class Bar {\n" + + " Integer foo;\n" + + " void bar() {" + "\n" + + " Integer foo;\n" + + " }\n" + + "}"); } @Test From fb58cce30dc5d40ced2913968892600e2b0ee27d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 25 Sep 2025 15:55:49 +0200 Subject: [PATCH 1412/1962] Add @AndrewStopchenko-SO as a contributor --- .all-contributorsrc | 9 + docs/pages/pmd/projectdocs/credits.md | 245 +++++++++++++------------- 2 files changed, 132 insertions(+), 122 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 545fa8ac897..a3217a6292b 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8253,6 +8253,15 @@ "contributions": [ "code" ] + }, + { + "login": "AndrewStopchenko-SO", + "name": "AndrewStopchenko-SO", + "avatar_url": "https://avatars.githubusercontent.com/u/63401193?v=4", + "profile": "https://github.com/AndrewStopchenko-SO", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 7b3a144897e..b68a5bfe263 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -73,1100 +73,1101 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + From d65a6983f7a7c41ddee12b398d0af0d92784262b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Fri, 19 Sep 2025 20:53:06 +0200 Subject: [PATCH 1413/1962] Fix FP in AssignmentInOperandRule --- .../lang/java/ast/internal/JavaAstUtils.java | 7 ++-- .../errorprone/AssignmentInOperandRule.java | 5 ++- .../errorprone/xml/AssignmentInOperand.xml | 33 +++++++++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java index 9b0808a15bf..e3a3dda8980 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtils.java @@ -54,6 +54,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTInfixExpression; import net.sourceforge.pmd.lang.java.ast.ASTInitializer; import net.sourceforge.pmd.lang.java.ast.ASTLabeledStatement; +import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression; import net.sourceforge.pmd.lang.java.ast.ASTList; import net.sourceforge.pmd.lang.java.ast.ASTLocalVariableDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTLoopStatement; @@ -300,8 +301,10 @@ public static boolean isAnonymousClassCreation(@Nullable ASTExpression expressio */ public static @NonNull ASTExpression getTopLevelExpr(ASTExpression expr) { JavaNode last = expr.ancestorsOrSelf() - .takeWhile(it -> it instanceof ASTExpression - || it instanceof ASTArgumentList && it.getParent() instanceof ASTExpression) + .takeWhile(it -> + it instanceof ASTExpression && !(it instanceof ASTLambdaExpression) + || it instanceof ASTArgumentList && it.getParent() instanceof ASTExpression + ) .last(); return (ASTExpression) Objects.requireNonNull(last); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java index 87170d23c80..038db6b86f0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java @@ -12,6 +12,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTExpressionStatement; import net.sourceforge.pmd.lang.java.ast.ASTForStatement; import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; +import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression; import net.sourceforge.pmd.lang.java.ast.ASTStatementExpressionList; import net.sourceforge.pmd.lang.java.ast.ASTSwitchStatement; import net.sourceforge.pmd.lang.java.ast.ASTUnaryExpression; @@ -89,7 +90,9 @@ private void checkAssignment(ASTExpression impureExpr, RuleContext ctx) { if (toplevel == impureExpr && (parent instanceof ASTExpressionStatement - || parent instanceof ASTStatementExpressionList) + || parent instanceof ASTStatementExpressionList + || parent instanceof ASTLambdaExpression + ) ) { // that's ok return; diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml index 1535d1a7343..0cba9c3dab9 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml @@ -297,4 +297,37 @@ public class Foo { } ]]> + + + Github issue #6075 - false positive in lambda expression + 0 + cons = s -> this.field = s; + cons.accept("pmd"); + } + } + ]]> + + + + But assignments inside statements inside lambdas should still be flagged + 1 + 6 + f(i++); + cons.accept(42); + } + + private static f(int i) {}; + } + ]]> + From d2b658a4a0fa2343bf46afaddee8200bb747fbc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Sat, 20 Sep 2025 16:48:15 +0200 Subject: [PATCH 1414/1962] Add some tests for JavaAstUtils.getTopLevelExpr() --- .../java/ast/internal/JavaAstUtilTest.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtilTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtilTest.java index 5bee56625df..a0b027aca96 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtilTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/internal/JavaAstUtilTest.java @@ -8,13 +8,17 @@ import static net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils.isStringConcatExpr; import static net.sourceforge.pmd.util.CollectionUtil.listOf; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; import net.sourceforge.pmd.lang.java.BaseParserTest; +import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; +import net.sourceforge.pmd.lang.java.ast.ASTConstructorCall; import net.sourceforge.pmd.lang.java.ast.ASTExpression; import net.sourceforge.pmd.lang.java.ast.ASTInfixExpression; +import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression; import net.sourceforge.pmd.lang.java.ast.ASTVariableAccess; class JavaAstUtilTest extends BaseParserTest { @@ -41,4 +45,21 @@ void testFlattenConcatOperandsRespectsTyping() { flattenOperands(e).toList()); } + @Test + void testGetTopLevelExprThroughArgumentList() { + ASTExpression e = parseExpr("foo(bar)"); + ASTVariableAccess bar = e.descendants(ASTVariableAccess.class).first(); + + ASTExpression topLevel = JavaAstUtils.getTopLevelExpr(bar); + assertSame(topLevel, e); + } + + @Test + void testGetTopLevelExprThroughLambda() { + ASTCompilationUnit acu = java.parse("class Foo { { new Thread(() -> new Object()); } }"); + ASTLambdaExpression lambda = acu.descendants(ASTLambdaExpression.class).first(); + ASTExpression inner = lambda.descendants(ASTConstructorCall.class).first(); + ASTExpression top = JavaAstUtils.getTopLevelExpr(inner); + assertSame(inner, top); // should not go up to `new Thread(...)` + } } From fbf33bcb610b70fdccfc06b3a0dc47f9aa47cb2f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 25 Sep 2025 16:15:40 +0200 Subject: [PATCH 1415/1962] [doc] Update release notes (#6075, #6078) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index ac301af9f4f..ea9179d3a0e 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -40,6 +40,7 @@ This is a {{ site.pmd.release_type }} release. * [#6058](https://github.com/pmd/pmd/issues/6058): \[java] DanglingJavadoc FP in module-info files * java-errorprone * [#5878](https://github.com/pmd/pmd/issues/5878): \[java] DontUseFloatTypeForLoopIndices false-negative if variable is declared before loop + * [#6075](https://github.com/pmd/pmd/issues/6075): \[java] AssignmentInOperand false positive with lambda expressions * java-multithreading * [#5880](https://github.com/pmd/pmd/issues/5880): \[java] DoubleCheckedLocking is not detected if more than 1 assignment or more than 2 if statements * misc @@ -69,6 +70,7 @@ This is a {{ site.pmd.release_type }} release. * [#6059](https://github.com/pmd/pmd/pull/6059): \[java] Fix #6058: DanglingJavadoc FP in module-info files - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6071](https://github.com/pmd/pmd/pull/6071): \[java] Fix #5919: Add integration tests to ClassNamingConventions testClassRegex - [Anton Bobov](https://github.com/abobov) (@abobov) * [#6074](https://github.com/pmd/pmd/pull/6074): \[apex] Fix @SuppressWarnings with whitespace around comma - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#6078](https://github.com/pmd/pmd/pull/6078): \[java] Fix #6075: Fix FP in AssignmentInOperandRule - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) ### ๐Ÿ“ฆ Dependency updates From 4ba55249780a303b3a5eee84f44d5faa9c898df9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 25 Sep 2025 16:16:06 +0200 Subject: [PATCH 1416/1962] Add @vzorge as a contributor --- .all-contributorsrc | 9 ++++ docs/pages/pmd/projectdocs/credits.md | 71 ++++++++++++++------------- 2 files changed, 45 insertions(+), 35 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index a3217a6292b..3c6879c7601 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8262,6 +8262,15 @@ "contributions": [ "bug" ] + }, + { + "login": "vzorge", + "name": "Vincent Zorge", + "avatar_url": "https://avatars.githubusercontent.com/u/3940229?v=4", + "profile": "https://nl.linkedin.com/in/vincentzorge", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index b68a5bfe263..85f771801fc 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -856,317 +856,318 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + From 1087c6ab6a7b6f6e8efa3814d2f747e692d32a55 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Thu, 25 Sep 2025 20:57:52 +0200 Subject: [PATCH 1417/1962] Update pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/IdenticalCatchBranches.xml Co-authored-by: Andreas Dangel --- .../pmd/lang/java/rule/codestyle/xml/IdenticalCatchBranches.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/IdenticalCatchBranches.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/IdenticalCatchBranches.xml index ee7494c4fca..fed504bbacd 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/IdenticalCatchBranches.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/IdenticalCatchBranches.xml @@ -211,7 +211,7 @@ class Foo { - Overridden method call: common supertype + Overridden method call: common supertype #6079 2 7,9 Date: Mon, 15 Sep 2025 21:24:00 +0200 Subject: [PATCH 1418/1962] [core] chore: Bump minimum required Java version to 17 This is only a build requirement. Java 17 is not required at runtime. --- .github/workflows/build.yml | 20 ++++++++++--------- .github/workflows/publish-release.yml | 8 +++++--- .github/workflows/publish-snapshot.yml | 12 ++++++----- .../pmd/devdocs/building/building_general.md | 6 +++--- docs/pages/release_notes.md | 5 +++++ .../sourceforge/pmd/lang/document/Chars.java | 2 +- pmd-dist/pom.xml | 10 +++++----- pom.xml | 2 +- 8 files changed, 38 insertions(+), 27 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index af136844c70..c926b35713b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,7 +27,7 @@ jobs: - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' - java-version: '11' + java-version: '17' - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: key: maven-${{ hashFiles('**/pom.xml') }} @@ -85,7 +85,7 @@ jobs: - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' - java-version: '11' + java-version: '17' - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: key: maven-${{ hashFiles('**/pom.xml') }} @@ -129,13 +129,13 @@ jobs: distribution: 'temurin' java-version: | 8 - 17 + 11 21 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 - # default java version for all os is 11 + # default java version for all os is 17 with: distribution: 'temurin' - java-version: '11' + java-version: '17' # only restore the cache, don't create a new cache # Note: this works under Windows only if pom.xml files use LF, so that hashFiles('**/pom.xml') # gives the same result (line endings...). @@ -159,7 +159,7 @@ jobs: verify \ -PfastSkip -Dcyclonedx.skip=false \ -Djava8.home="${JAVA_HOME_8_X64}" \ - -Djava17.home="${JAVA_HOME_17_X64}" \ + -Djava11.home="${JAVA_HOME_11_X64}" \ -Djava21.home="${JAVA_HOME_21_X64}" dogfood: @@ -174,7 +174,7 @@ jobs: - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' - java-version: '11' + java-version: '17' - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: key: maven-${{ hashFiles('**/pom.xml') }} @@ -260,7 +260,7 @@ jobs: - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' - java-version: '11' + java-version: '17' - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: key: maven-${{ hashFiles('**/pom.xml') }} @@ -315,7 +315,9 @@ jobs: - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' - java-version: '11' + java-version: | + 11 + 17 - name: Set up Ruby 3.3 uses: ruby/setup-ruby@0481980f17b760ef6bca5e8c55809102a0af1e5a #v1.263.0 with: diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 10e825f737d..9fc7d536042 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -37,7 +37,7 @@ jobs: - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' - java-version: '11' + java-version: '17' cache: 'maven' - name: Determine Version id: version @@ -91,7 +91,7 @@ jobs: - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' - java-version: '11' + java-version: '17' server-id: central server-username: MAVEN_USERNAME server-password: MAVEN_PASSWORD @@ -628,7 +628,9 @@ jobs: - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' - java-version: '11' + java-version: | + 11 + 17 - name: Set up Ruby 3.3 uses: ruby/setup-ruby@0481980f17b760ef6bca5e8c55809102a0af1e5a #v1.263.0 with: diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 314ab506250..b133d3b6453 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -36,7 +36,7 @@ jobs: - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' - java-version: '11' + java-version: '17' - name: Determine Version id: version run: | @@ -82,7 +82,7 @@ jobs: - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' - java-version: '11' + java-version: '17' server-id: central server-username: MAVEN_USERNAME server-password: MAVEN_PASSWORD @@ -645,7 +645,9 @@ jobs: - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' - java-version: '11' + java-version: | + 11 + 17 - name: Set up Ruby 3.3 uses: ruby/setup-ruby@0481980f17b760ef6bca5e8c55809102a0af1e5a #v1.263.0 with: @@ -730,7 +732,7 @@ jobs: - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' - java-version: '17' # sonar requires java 17 + java-version: '17' - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: key: maven-${{ hashFiles('**/pom.xml') }} @@ -767,7 +769,7 @@ jobs: - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' - java-version: '17' # coveralls requires java 17 + java-version: '17' - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 with: key: maven-${{ hashFiles('**/pom.xml') }} diff --git a/docs/pages/pmd/devdocs/building/building_general.md b/docs/pages/pmd/devdocs/building/building_general.md index ce9fdea1d04..4c684042476 100644 --- a/docs/pages/pmd/devdocs/building/building_general.md +++ b/docs/pages/pmd/devdocs/building/building_general.md @@ -3,14 +3,14 @@ title: Building PMD General Info tags: [devdocs] permalink: pmd_devdocs_building_general.html author: Andreas Dangel -last_updated: January 2025 (7.10.0) +last_updated: September 2025 (7.18.0) --- ## Before Development -1. Ensure that [Git](https://git-scm.com/) and Java JDK >= 11 are installed. +1. Ensure that [Git](https://git-scm.com/) and Java JDK >= 17 are installed. You can get a OpenJDK distribution from e.g. [Adoptium](https://adoptium.net/). - **Note:** While Java 11 is required for building, running PMD only requires Java 8. + **Note:** While Java 17 is required for building, running PMD only requires Java 8. 2. Fork the [PMD repository](https://github.com/pmd/pmd) on GitHub as explained in [Fork a repository](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo). 3. Clone your forked repository to your computer: ```shell diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index ea9179d3a0e..dda148a8f16 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -24,6 +24,11 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€ New and noteworthy +#### Build Requirement is Java 17 +From now on, Java 17 or newer is required to build PMD. PMD itself still remains compatible with Java 8, +so that it still can be used in a pure Java 8 environment. This allows us to use the latest +checkstyle version during the build. + ### ๐Ÿ› Fixed Issues * core * [#4714](https://github.com/pmd/pmd/issues/4714): \[core] Allow trailing commas in multivalued properties diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/Chars.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/Chars.java index 56c578d70f8..618c115f536 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/Chars.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/Chars.java @@ -76,7 +76,7 @@ private int idx(int off) { /** Whether this slice is the empty string. */ // @SuppressWarnings("PMD.MissingOverride") // with Java 15, isEmpty() has been added to java.lang.CharSequence (#4291) - // We compile against Java 8 and execute maven on GitHub Actions with Java 11. So there is no missing override. + // We compile against Java 8 and execute maven on GitHub Actions with Java 17. So there is no missing override. // However, when executing Maven with Java 15+, then we get MissingOverride (#5299). // This is suppressed via maven-pmd-plugin's excludeFromFailureFile public boolean isEmpty() { diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index cc8b1a3e27a..b73bc90ca87 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -216,10 +216,10 @@ - jdk17-compat-it + jdk11-compat-it - java17.home + java11.home @@ -229,15 +229,15 @@ maven-failsafe-plugin - jdk17-compat-it + jdk11-compat-it integration-test verify - ${java17.home} - ${java17.home}/bin:${env.PATH} + ${java11.home} + ${java11.home}/bin:${env.PATH} diff --git a/pom.xml b/pom.xml index 13500f468a0..a0f0859e92c 100644 --- a/pom.xml +++ b/pom.xml @@ -740,7 +740,7 @@ - [11,) + [17,) From 5e78f88b4d3761e1b82a16028a5105a920628dcf Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 26 Sep 2025 12:03:06 +0200 Subject: [PATCH 1419/1962] Add java11 to auxclasspath --- .ci/files/project-list.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.ci/files/project-list.xml b/.ci/files/project-list.xml index 98c2bf1c167..fed67b9658e 100644 --- a/.ci/files/project-list.xml +++ b/.ci/files/project-list.xml @@ -28,7 +28,7 @@ export PATH=$JAVA_HOME/bin:$PATH mvn test-compile -B mvn dependency:build-classpath -DincludeScope=test -Dmdep.outputFile=classpath.txt -B ]]> - echo -n "$(pwd)/target/classes:$(pwd)/target/test-classes:"; cat classpath.txt + echo -n "${HOME}/openjdk11/lib/jrt-fs.jar:$(pwd)/target/classes:$(pwd)/target/test-classes:"; cat classpath.txt @@ -156,7 +156,7 @@ EOF ./gradlew --console=plain --build-cache --no-daemon --max-workers=4 build testClasses -x test -x javadoc -x api -x asciidoctor -x asciidoctorPdf ./gradlew --console=plain --build-cache --no-daemon --max-workers=4 createSquishClasspath -q > classpath.txt ]]> - cat classpath.txt + echo -n "${HOME}/openjdk11/lib/jrt-fs.jar:"; cat classpath.txt @@ -165,6 +165,7 @@ EOF https://github.com/openjdk/jdk jdk-11+28 src/java.base + echo -n "${HOME}/openjdk11/lib/jrt-fs.jar" From def6517d4ee5b6b6963217032a838a309f01a1be Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Sun, 28 Sep 2025 01:01:44 +0200 Subject: [PATCH 1420/1962] [java] AvoidDeeplyNestedIfStmts: fix false negative with if-else --- .../design/AvoidDeeplyNestedIfStmtsRule.java | 17 ++- .../design/xml/AvoidDeeplyNestedIfStmts.xml | 114 ++++++++++++++++++ 2 files changed, 126 insertions(+), 5 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/AvoidDeeplyNestedIfStmtsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/AvoidDeeplyNestedIfStmtsRule.java index 136907f51a2..d57bb64625c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/AvoidDeeplyNestedIfStmtsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/AvoidDeeplyNestedIfStmtsRule.java @@ -8,6 +8,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; +import net.sourceforge.pmd.lang.java.ast.ASTStatement; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule; import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.properties.PropertyFactory; @@ -36,14 +37,20 @@ public Object visit(ASTCompilationUnit node, Object data) { @Override public Object visit(ASTIfStatement node, Object data) { - if (!node.hasElse()) { - depth++; - } - super.visit(node, data); - if (depth == depthLimit) { + if (depth + 1 == depthLimit) { asCtx(data).addViolation(node); + // return early so that if-else chains are only reported once + return data; } + // deep ifs if in condition are highly unlikely, but possible via lambdas + node.getCondition().acceptVisitor(this, data); + depth++; + node.getThenBranch().acceptVisitor(this, data); depth--; + ASTStatement elseBranch = node.getElseBranch(); + if (elseBranch != null) { + elseBranch.acceptVisitor(this, data); + } return data; } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidDeeplyNestedIfStmts.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidDeeplyNestedIfStmts.xml index b486e07d966..25522d73525 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidDeeplyNestedIfStmts.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidDeeplyNestedIfStmts.xml @@ -43,4 +43,118 @@ public class Foo { } ]]> + + Deep ifs with else + 1 + 7 + + + + + Sibling ifs reported separately + 2 + 5,6 + + + + + If-else reported once + 1 + 5 + + + + + Chained ifs, not deep enough + 0 + + + + Deep ifs in lambda + 1 + 7 + { + if (true) { + if (true) { + if (true) { + return true; + } + } + } + return false; + })) { + // do nothing + } + } + } + ]]> + From 3313dc8339434f533739e3f7b89b5def9952f3a9 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Thu, 2 Oct 2025 02:38:53 +0200 Subject: [PATCH 1421/1962] [java] DanglingJavadoc: fix false positive for compact constructors --- pmd-java/src/main/javacc/Java.jjt | 5 ++++- .../documentation/xml/DanglingJavadoc.xml | 21 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/javacc/Java.jjt b/pmd-java/src/main/javacc/Java.jjt index e87a27bb73d..8cb123eaf75 100644 --- a/pmd-java/src/main/javacc/Java.jjt +++ b/pmd-java/src/main/javacc/Java.jjt @@ -1287,7 +1287,10 @@ private void CompactConstructorDeclarationLookahead() #void: void CompactConstructorDeclaration(): {} { - { jjtThis.setIdentToken(token); } + { + jjtThis.setFirstToken(jjtree.peekNode().getFirstToken()); + jjtThis.setIdentToken(token); + } Block() } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/DanglingJavadoc.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/DanglingJavadoc.xml index 631f8558398..8d294a9da3e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/DanglingJavadoc.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/DanglingJavadoc.xml @@ -94,4 +94,25 @@ module my.module.name { } ]]> + + Record compact constructor #6103 + 0 + + /** + * Represents a position in source code with line and column information. + * + * @param line the line number (1-based) + * @param column the column number (1-based) + */ + public record SourcePosition(int line, int column) { + /** + * Compact constructor validating line and column are positive. + */ + public SourcePosition { + requireThat(line, "line").isPositive(); + requireThat(column, "column").isPositive(); + } + } + + \ No newline at end of file From 5cf2fc3ccd2cce9dd6ab0b0cdca8428fec39da15 Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Sat, 4 Oct 2025 21:26:10 +0200 Subject: [PATCH 1422/1962] [java] Fix #4122: CheckResultSet false-positive with local variable --- .../bestpractices/CheckResultSetRule.java | 10 ++++++--- .../rule/bestpractices/xml/CheckResultSet.xml | 22 +++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java index 6cd09c518f3..c6d9a69f47b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java @@ -7,9 +7,11 @@ import static net.sourceforge.pmd.util.CollectionUtil.setOf; import java.sql.ResultSet; +import java.util.Collections; import java.util.List; import java.util.Set; +import net.sourceforge.pmd.lang.ast.NodeStream; import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr; import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; @@ -56,12 +58,14 @@ private boolean isResultSetMethod(ASTMethodCall node) { } private boolean isCheckedIndirectly(ASTMethodCall node) { - if (!(node.getParent() instanceof ASTVariableDeclarator)) { + final NodeStream variableDeclarators = node.ancestors(ASTVariableDeclarator.class); + if (variableDeclarators.isEmpty()) { return false; } - final ASTVariableDeclarator declarator = (ASTVariableDeclarator) node.getParent(); - final List usages = declarator.getVarId().getLocalUsages(); + final List usages = variableDeclarators.firstOpt() + .map(varDecl -> varDecl.getVarId().getLocalUsages()) + .orElse(Collections.emptyList()); //check that the result is used and its first usage is not overwriting the result return !usages.isEmpty() && usages.get(0).getAccessType() == ASTAssignableExpr.AccessType.READ; } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml index 3da8abbf309..c7672c8f539 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml @@ -381,4 +381,26 @@ public class Foo { ]]> + + #4122: CheckResultSet false-positive with local variable + 0 + + From 438cd00a25a11289a2a0a170967bd7c664a42167 Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Sun, 5 Oct 2025 21:01:36 +0200 Subject: [PATCH 1423/1962] #4122: Apply suggestion of @zbynek to fix false negatives --- .../bestpractices/CheckResultSetRule.java | 6 ++++- .../rule/bestpractices/xml/CheckResultSet.xml | 27 ++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java index c6d9a69f47b..515c88683c3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java @@ -14,6 +14,7 @@ import net.sourceforge.pmd.lang.ast.NodeStream; import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr; import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; +import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression; import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement; import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator; @@ -58,7 +59,10 @@ private boolean isResultSetMethod(ASTMethodCall node) { } private boolean isCheckedIndirectly(ASTMethodCall node) { - final NodeStream variableDeclarators = node.ancestors(ASTVariableDeclarator.class); + final NodeStream variableDeclarators = node.ancestors() + .takeWhile(n -> !(n instanceof ASTLambdaExpression)) + .filterIs(ASTVariableDeclarator.class); + if (variableDeclarators.isEmpty()) { return false; } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml index c7672c8f539..154b10756bb 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml @@ -390,7 +390,7 @@ public class Foo { class Scratch { public void bar(Connection c, String tableName) throws Exception { - ResultSet created = c.getMetaData().getTables(null, null, tableName, null); // <--- false positive here + ResultSet created = c.getMetaData().getTables(null, null, tableName, null); boolean missing = !created.next(); reportTableName(tableName, !missing); } @@ -403,4 +403,29 @@ public class Foo { } ]]> + + + CheckResultSet in lambda + 1 + 7 + { + rs.next(); + }); + + System.out.println(x); + } + + private static int consumeResultSet(ResultSet resultSet, Consumer consumer) throws Exception { + consumer.accept(resultSet); + return rs.getInt(0); + } + } + ]]> + From b73fbf237cdf4d302c396d4c8d357fc4648d1a1a Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Mon, 6 Oct 2025 16:59:29 +0200 Subject: [PATCH 1424/1962] [java] ConfusingTernary: add configuration property for null checks --- .../rule/codestyle/ConfusingTernaryRule.java | 35 ++++++++-- .../rule/codestyle/xml/ConfusingTernary.xml | 68 +++++++++++++++++-- 2 files changed, 90 insertions(+), 13 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryRule.java index dcf79844cf4..6db4d9a8f1c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryRule.java @@ -5,6 +5,7 @@ package net.sourceforge.pmd.lang.java.rule.codestyle; import static net.sourceforge.pmd.properties.PropertyFactory.booleanProperty; +import static net.sourceforge.pmd.properties.PropertyFactory.enumProperty; import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression; import net.sourceforge.pmd.lang.java.ast.ASTExpression; @@ -56,15 +57,25 @@ public class ConfusingTernaryRule extends AbstractJavaRulechainRule { private static final PropertyDescriptor IGNORE_ELSE_IF = booleanProperty("ignoreElseIf") .desc("Ignore conditions with an else-if case").defaultValue(false).build(); + private static final PropertyDescriptor NULL_CHECK_BRANCH = enumProperty("nullCheckBranch", NullCheckBranch.class) + .desc("One of `Any`, `Then`, `Else`. For `Any` null checks may have any form," + + " for `Then` only `foo == null` is allowed, for `Else` only `foo != null` is allowed") + .defaultValue(NullCheckBranch.Any).build(); + + private enum NullCheckBranch { + Any, Then, Else + } + public ConfusingTernaryRule() { super(ASTIfStatement.class, ASTConditionalExpression.class); definePropertyDescriptor(IGNORE_ELSE_IF); + definePropertyDescriptor(NULL_CHECK_BRANCH); } @Override public Object visit(ASTIfStatement node, Object data) { // look for "if (match) ..; else .." - if (node.getNumChildren() == 3 + if (node.hasElse() && isMatch(node.getCondition())) { if (!getProperty(IGNORE_ELSE_IF) || !(node.getElseBranch() instanceof ASTIfStatement) @@ -85,7 +96,7 @@ public Object visit(ASTConditionalExpression node, Object data) { } // recursive! - private static boolean isMatch(ASTExpression node) { + private boolean isMatch(ASTExpression node) { return isUnaryNot(node) || isNotEquals(node) || isConditionalWithAllMatches(node); } @@ -95,18 +106,28 @@ private static boolean isUnaryNot(ASTExpression node) { && ((ASTUnaryExpression) node).getOperator().equals(UnaryOp.NEGATION); } - private static boolean isNotEquals(ASTExpression node) { + private boolean isNotEquals(ASTExpression node) { if (!(node instanceof ASTInfixExpression)) { return false; } ASTInfixExpression infix = (ASTInfixExpression) node; // look for "x != y" - return infix.getOperator().equals(BinaryOp.NE) - && !(infix.getLeftOperand() instanceof ASTNullLiteral) - && !(infix.getRightOperand() instanceof ASTNullLiteral); + if (infix.getOperator().equals(BinaryOp.NE)) { + return !isNullComparison(infix) + || getProperty(NULL_CHECK_BRANCH) == NullCheckBranch.Then; + + } + return infix.getOperator().equals(BinaryOp.EQ) + && isNullComparison(infix) + && getProperty(NULL_CHECK_BRANCH) == NullCheckBranch.Else; + } + + private boolean isNullComparison(ASTInfixExpression infix) { + return infix.getLeftOperand() instanceof ASTNullLiteral + || infix.getRightOperand() instanceof ASTNullLiteral; } - private static boolean isConditionalWithAllMatches(ASTExpression node) { + private boolean isConditionalWithAllMatches(ASTExpression node) { // look for "match && match" or "match || match" if (node instanceof ASTInfixExpression) { ASTInfixExpression infix = (ASTInfixExpression) node; diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ConfusingTernary.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ConfusingTernary.xml index 0ddd0a2a5c3..35072121944 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ConfusingTernary.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ConfusingTernary.xml @@ -27,11 +27,8 @@ public class Foo { } ]]> - - - null check, ok (if) - #278 - 0 - + + ]]> + + + + + + null check, ok (if) - #278 + 0 + + + + + null check, ok (if) - any branch + Any + 0 + + + + + null check, ok (if) - else branch + Else + 0 + + + + + null check, not ok (if) - then branch + Then + 1 + + + + + null check, ok (if) - any branch + Any + 0 + + + + + null check, not ok (if) - else branch + Else + 1 + + + + + null check, ok (if) - then branch + Then + 0 + From ae1677095e6b73ea5b1da13f44a6407b86657c30 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 7 Oct 2025 19:44:57 +0200 Subject: [PATCH 1425/1962] [doc] Update release notes (#6061) [skip ci] --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index dda148a8f16..88ccf173746 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -73,6 +73,7 @@ checkstyle version during the build. * [#6040](https://github.com/pmd/pmd/pull/6040): \[java,apex,plsql,velocity] Change description of "minimum" parameter - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6043](https://github.com/pmd/pmd/pull/6043): \[java] Reactivate deactivated test in LocalVariableCouldBeFinal - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6059](https://github.com/pmd/pmd/pull/6059): \[java] Fix #6058: DanglingJavadoc FP in module-info files - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#6061](https://github.com/pmd/pmd/pull/6061): \[core] chore: Bump minimum Java version required for building to 17 - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6071](https://github.com/pmd/pmd/pull/6071): \[java] Fix #5919: Add integration tests to ClassNamingConventions testClassRegex - [Anton Bobov](https://github.com/abobov) (@abobov) * [#6074](https://github.com/pmd/pmd/pull/6074): \[apex] Fix @SuppressWarnings with whitespace around comma - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) * [#6078](https://github.com/pmd/pmd/pull/6078): \[java] Fix #6075: Fix FP in AssignmentInOperandRule - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) From 1bb3acf56047f31f93573aeaeb2354bf8ecbd01d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 19:47:44 +0200 Subject: [PATCH 1426/1962] chore(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.5.1 to 3.6.0 (#6107) chore(deps): bump org.codehaus.mojo:exec-maven-plugin Bumps [org.codehaus.mojo:exec-maven-plugin](https://github.com/mojohaus/exec-maven-plugin) from 3.5.1 to 3.6.0. - [Release notes](https://github.com/mojohaus/exec-maven-plugin/releases) - [Commits](https://github.com/mojohaus/exec-maven-plugin/compare/3.5.1...3.6.0) --- updated-dependencies: - dependency-name: org.codehaus.mojo:exec-maven-plugin dependency-version: 3.6.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a0f0859e92c..85bd8bdda22 100644 --- a/pom.xml +++ b/pom.xml @@ -384,7 +384,7 @@ org.codehaus.mojo exec-maven-plugin - 3.5.1 + 3.6.0 org.apache.maven.plugins From fd531f9e1ab757845df4c880a8113a472970b9fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 19:48:23 +0200 Subject: [PATCH 1427/1962] chore(deps-dev): bump org.assertj:assertj-core from 3.27.4 to 3.27.6 (#6109) Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.27.4 to 3.27.6. - [Release notes](https://github.com/assertj/assertj/releases) - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.27.4...assertj-build-3.27.6) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-version: 3.27.6 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-java/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 2a2b98d0bd3..b2d1728f3ae 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -280,7 +280,7 @@ org.assertj assertj-core - 3.27.4 + 3.27.6 test From 5eb1288c2a25faff549c261a5216cf29afe60b5e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 19:48:57 +0200 Subject: [PATCH 1428/1962] chore(deps): bump org.sonatype.central:central-publishing-maven-plugin from 0.8.0 to 0.9.0 (#6110) chore(deps): bump org.sonatype.central:central-publishing-maven-plugin Bumps [org.sonatype.central:central-publishing-maven-plugin](https://github.com/sonatype/central-publishing-maven-plugin) from 0.8.0 to 0.9.0. - [Commits](https://github.com/sonatype/central-publishing-maven-plugin/commits) --- updated-dependencies: - dependency-name: org.sonatype.central:central-publishing-maven-plugin dependency-version: 0.9.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 85bd8bdda22..2d3b39705e4 100644 --- a/pom.xml +++ b/pom.xml @@ -646,7 +646,7 @@ org.sonatype.central central-publishing-maven-plugin - 0.8.0 + 0.9.0 org.jacoco From b9abbd966ca08814d3028a64059e3250a51e3ba4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 20:06:36 +0200 Subject: [PATCH 1429/1962] chore(deps): bump com.puppycrawl.tools:checkstyle from 10.26.1 to 11.1.0 (#6108) Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.26.1 to 11.1.0. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.26.1...checkstyle-11.1.0) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-version: 11.1.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2d3b39705e4..78823ab74ac 100644 --- a/pom.xml +++ b/pom.xml @@ -92,7 +92,7 @@ 5.0 3.5.4 - 10.26.1 + 11.1.0 3.6.0 3.27.0 1.10.15 From 2a719ddcb874060c4338b179a766221ba2aa34d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 20:08:14 +0200 Subject: [PATCH 1430/1962] chore(deps): bump actions/cache from 4.2.4 to 4.3.0 (#6104) Bumps [actions/cache](https://github.com/actions/cache) from 4.2.4 to 4.3.0. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/0400d5f644dc74513175e3cd8d07132dd4860809...0057852bfaa89a56745cba8c7296529d2fc39830) --- updated-dependencies: - dependency-name: actions/cache dependency-version: 4.3.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 12 ++++++------ .github/workflows/publish-release.yml | 2 +- .github/workflows/publish-snapshot.yml | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c926b35713b..916deb098ad 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,7 +28,7 @@ jobs: with: distribution: 'temurin' java-version: '17' - - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 + - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4.3.0 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- @@ -86,7 +86,7 @@ jobs: with: distribution: 'temurin' java-version: '17' - - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 + - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4.3.0 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- @@ -140,7 +140,7 @@ jobs: # Note: this works under Windows only if pom.xml files use LF, so that hashFiles('**/pom.xml') # gives the same result (line endings...). # see .gitattributes for pom.xml - it should always be using lf. - - uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 + - uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 #v4.3.0 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- @@ -175,7 +175,7 @@ jobs: with: distribution: 'temurin' java-version: '17' - - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 + - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4.3.0 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- @@ -261,7 +261,7 @@ jobs: with: distribution: 'temurin' java-version: '17' - - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 + - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4.3.0 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- @@ -322,7 +322,7 @@ jobs: uses: ruby/setup-ruby@0481980f17b760ef6bca5e8c55809102a0af1e5a #v1.263.0 with: ruby-version: 3.3 - - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 + - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4.3.0 with: path: | ~/.m2/repository diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 9fc7d536042..76903618f73 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -635,7 +635,7 @@ jobs: uses: ruby/setup-ruby@0481980f17b760ef6bca5e8c55809102a0af1e5a #v1.263.0 with: ruby-version: 3.3 - - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 + - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4.3.0 with: path: | ~/.m2/repository diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index b133d3b6453..746cd9f08f6 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -88,7 +88,7 @@ jobs: server-password: MAVEN_PASSWORD gpg-passphrase: MAVEN_GPG_PASSPHRASE gpg-private-key: ${{ secrets.PMD_CI_GPG_PRIVATE_KEY }} - - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 + - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4.3.0 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- @@ -652,7 +652,7 @@ jobs: uses: ruby/setup-ruby@0481980f17b760ef6bca5e8c55809102a0af1e5a #v1.263.0 with: ruby-version: 3.3 - - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 + - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4.3.0 with: path: | ~/.m2/repository @@ -733,7 +733,7 @@ jobs: with: distribution: 'temurin' java-version: '17' - - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 + - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4.3.0 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- @@ -770,7 +770,7 @@ jobs: with: distribution: 'temurin' java-version: '17' - - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4 + - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4.3.0 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- From a30a4f58eb9ef52613e0d938e5602b8082995161 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Oct 2025 10:27:07 +0200 Subject: [PATCH 1431/1962] chore(deps): bump com.google.protobuf:protobuf-java from 4.32.0 to 4.32.1 (#6118) chore(deps): bump com.google.protobuf:protobuf-java Bumps [com.google.protobuf:protobuf-java](https://github.com/protocolbuffers/protobuf) from 4.32.0 to 4.32.1. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl) - [Commits](https://github.com/protocolbuffers/protobuf/commits) --- updated-dependencies: - dependency-name: com.google.protobuf:protobuf-java dependency-version: 4.32.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 78823ab74ac..8e1ed9bfdce 100644 --- a/pom.xml +++ b/pom.xml @@ -1135,7 +1135,7 @@ com.google.protobuf protobuf-java - 4.32.0 + 4.32.1 From da0f020924fee7dce0c0f0a06b9caaa08576b314 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Oct 2025 15:04:28 +0200 Subject: [PATCH 1437/1962] chore(deps): bump junit.version from 5.13.4 to 6.0.0 (#6106) * chore(deps): bump junit5.platform.version from 1.13.4 to 6.0.0 Bumps `junit5.platform.version` from 1.13.4 to 6.0.0. Updates `org.junit.platform:junit-platform-launcher` from 1.13.4 to 6.0.0 - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/commits/r6.0.0) Updates `org.junit.platform:junit-platform-commons` from 1.13.4 to 6.0.0 - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/commits/r6.0.0) --- updated-dependencies: - dependency-name: org.junit.platform:junit-platform-launcher dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major - dependency-name: org.junit.platform:junit-platform-commons dependency-version: 6.0.0 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * chore(deps): bump junit.version from 5.13.4 to 6.0.0 --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andreas Dangel --- pom.xml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 5fd2c197cd6..cd59d4a2a02 100644 --- a/pom.xml +++ b/pom.xml @@ -86,8 +86,7 @@ ${maven.compiler.test.target} 2.2.10 5.9.1 - 5.13.4 - 1.13.4 + 6.0.0 2.0.0 5.0 @@ -377,7 +376,7 @@ org.junit.platform junit-platform-launcher - ${junit5.platform.version} + ${junit.version} @@ -1013,7 +1012,7 @@ org.junit junit-bom - ${junit5.version} + ${junit.version} pom import @@ -1138,13 +1137,13 @@ 4.32.1 - + see junit.version --> org.junit.platform junit-platform-commons - ${junit5.platform.version} + ${junit.version} test From c549004607704a966737f1744bdf41e801efb3fa Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 10 Oct 2025 16:52:31 +0200 Subject: [PATCH 1438/1962] [java] Fix #4904: Correct class name in violation decorator Also add tests for local and anonymous classes. --- docs/pages/release_notes.md | 2 + .../pmd/reporting/RuleViolation.java | 3 +- .../java/ast/AbstractTypeDeclaration.java | 2 +- .../java/internal/JavaViolationDecorator.java | 16 ++++- .../internal/JavaViolationDecoratorTest.java | 64 ++++++++++++++++--- 5 files changed, 75 insertions(+), 12 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 88ccf173746..04d0b5c3043 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -36,6 +36,8 @@ checkstyle version during the build. * [#5935](https://github.com/pmd/pmd/issues/5935): \[apex] @SuppressWarnings - allow whitespace around comma when suppressing multiple rules * apex-design * [#6022](https://github.com/pmd/pmd/issues/6022): \[apex] ExcessiveClassLength/ExcessiveParameterList include the metric in the message +* java + * [#4904](https://github.com/pmd/pmd/issues/4904): \[java] Renderers output wrong class qualified name for nested classes * java-codestyle * [#5919](https://github.com/pmd/pmd/issues/5919): \[java] ClassNamingConventions: Include integration tests in testClassPattern by default * [#6029](https://github.com/pmd/pmd/issues/6029): \[java] Fix UnnecessaryCast false-negative in method calls diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleViolation.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleViolation.java index 820fb4771c9..3f2ff0b4854 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleViolation.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleViolation.java @@ -39,7 +39,8 @@ public interface RuleViolation { /** * Key in {@link #getAdditionalInfo()} for the name of the class in - * which the violation was identified. + * which the violation was identified. If the class is a nested class, + * the name also contains the enclosing class. */ String CLASS_NAME = "className"; /** diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractTypeDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractTypeDeclaration.java index c1f8ebf2989..79e8c08725b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractTypeDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractTypeDeclaration.java @@ -56,7 +56,7 @@ final void setSimpleName(String simpleName) { @Override public @Nullable String getCanonicalName() { - assert binaryName != null : "Canonical name wasn't set"; + assert binaryName != null : "binary name and canonical name weren't set"; return canonicalName; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecorator.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecorator.java index 0e6a022bc7c..5b789778ede 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecorator.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecorator.java @@ -57,7 +57,21 @@ public void decorate(Node violationNode, Map additionalInfo) { enclosing = javaNode.getRoot().getTypeDeclarations().first(); } if (enclosing != null) { - return enclosing.getSimpleName(); + String className; + if (enclosing.isLocal()) { + className = enclosing.getEnclosingType().getCanonicalName() + "." + enclosing.getSimpleName(); + } else if (enclosing.isAnonymous()) { + className = enclosing.getEnclosingType().getCanonicalName(); + } else { + className = enclosing.getCanonicalName(); + } + + String packageName = enclosing.getPackageName(); + if (className != null && !packageName.isEmpty()) { + assert className.startsWith(packageName); + className = className.substring(packageName.length() + 1); + } + return className; } return null; } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecoratorTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecoratorTest.java index a08b86f42f4..adec88457db 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecoratorTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecoratorTest.java @@ -26,6 +26,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTNumericLiteral; +import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration; import net.sourceforge.pmd.lang.java.ast.JavaNode; /** @@ -33,8 +34,6 @@ */ class JavaViolationDecoratorTest { - // TODO there are no tests for anon or local classes - @Test void testASTFormalParameterVariableName() { ASTCompilationUnit ast = parse("class Foo { void bar(int x) {} }"); @@ -60,7 +59,7 @@ void testMethodName() { assertThat(decorate(md), hasEntry(METHOD_NAME, "bar")); } - static Map decorate(JavaNode md) { + private static Map decorate(JavaNode md) { Map result = new HashMap<>(); JavaViolationDecorator.INSTANCE.decorate(md, result); return result; @@ -118,7 +117,7 @@ void testPackageAndEnumName() { } @Test - void testDefaultPackageAndClassName() { + void testDefaultPackageAndClassNameOnImports() { ASTCompilationUnit ast = parse("import java.util.List; public class Foo { }"); ASTImportDeclaration importNode = ast.descendants(ASTImportDeclaration.class).first(); @@ -128,7 +127,7 @@ void testDefaultPackageAndClassName() { } @Test - void testPackageAndMultipleClassesName() { + void testPackageAndMultipleClassesNameOnImports() { ASTCompilationUnit ast = parse("package pkg; import java.util.List; class Foo { } public class Bar { }"); ASTImportDeclaration importNode = ast.descendants(ASTImportDeclaration.class).first(); @@ -153,18 +152,65 @@ void testPackageAndPackagePrivateClassesName() { */ @Test void testInnerClass() { - ASTCompilationUnit ast = parse("class Foo { int a; class Bar { int a; } }"); - List classes = ast.descendants(ASTClassDeclaration.class).toList(); + ASTCompilationUnit ast = parse("class Foo { int a; class Bar { int a; class Baz { int a; } } }"); + List classes = ast.descendants(ASTClassDeclaration.class).crossFindBoundaries().toList(); + assertEquals(3, classes.size()); + + assertThat(decorate(classes.get(0)), hasEntry(CLASS_NAME, "Foo")); + assertThat(decorate(classes.get(1)), hasEntry(CLASS_NAME, "Foo.Bar")); + assertThat(decorate(classes.get(2)), hasEntry(CLASS_NAME, "Foo.Bar.Baz")); + + List fields = ast.descendants(ASTFieldDeclaration.class).crossFindBoundaries().toList(); + assertEquals(3, fields.size()); + + assertThat(decorate(fields.get(0)), hasEntry(CLASS_NAME, "Foo")); + assertThat(decorate(fields.get(1)), hasEntry(CLASS_NAME, "Foo.Bar")); + assertThat(decorate(fields.get(2)), hasEntry(CLASS_NAME, "Foo.Bar.Baz")); + } + + @Test + void testInnerClassIncludingPackage() { + ASTCompilationUnit ast = parse("package pkg; class Foo { class Bar {} }"); + List classes = ast.descendants(ASTClassDeclaration.class).crossFindBoundaries().toList(); + assertEquals(2, classes.size()); + + assertThat(decorate(classes.get(0)), hasEntry(CLASS_NAME, "Foo")); + assertThat(decorate(classes.get(0)), hasEntry(PACKAGE_NAME, "pkg")); + + assertThat(decorate(classes.get(1)), hasEntry(CLASS_NAME, "Foo.Bar")); + assertThat(decorate(classes.get(1)), hasEntry(PACKAGE_NAME, "pkg")); + } + + @Test + void localClasses() { + ASTCompilationUnit ast = parse("class Foo { int a; void m() { class Local { int a; }; } }"); + List classes = ast.descendants(ASTClassDeclaration.class).crossFindBoundaries().toList(); + assertEquals(2, classes.size()); + + assertThat(decorate(classes.get(0)), hasEntry(CLASS_NAME, "Foo")); + assertThat(decorate(classes.get(1)), hasEntry(CLASS_NAME, "Foo.Local")); + + List fields = ast.descendants(ASTFieldDeclaration.class).crossFindBoundaries().toList(); + assertEquals(2, fields.size()); + + assertThat(decorate(fields.get(0)), hasEntry(CLASS_NAME, "Foo")); + assertThat(decorate(fields.get(1)), hasEntry(CLASS_NAME, "Foo.Local")); + } + + @Test + void anonymousClasses() { + ASTCompilationUnit ast = parse("class Foo { int a; void m() { new Object() { int a; }; } }"); + List classes = ast.descendants(ASTTypeDeclaration.class).crossFindBoundaries().toList(); assertEquals(2, classes.size()); assertThat(decorate(classes.get(0)), hasEntry(CLASS_NAME, "Foo")); - assertThat(decorate(classes.get(1)), hasEntry(CLASS_NAME, "Bar")); + assertThat(decorate(classes.get(1)), hasEntry(CLASS_NAME, "Foo")); // anonymous classes are unnamed List fields = ast.descendants(ASTFieldDeclaration.class).crossFindBoundaries().toList(); assertEquals(2, fields.size()); assertThat(decorate(fields.get(0)), hasEntry(CLASS_NAME, "Foo")); - assertThat(decorate(fields.get(1)), hasEntry(CLASS_NAME, "Bar")); + assertThat(decorate(fields.get(1)), hasEntry(CLASS_NAME, "Foo")); // anonymous classes are unnamed } @Test From ba89973712e21dd9da4e4d3dbdd26f23790422bd Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 10 Oct 2025 20:20:36 +0200 Subject: [PATCH 1439/1962] Consider nested local classes --- .../java/internal/JavaViolationDecorator.java | 23 ++++++++----- .../internal/JavaViolationDecoratorTest.java | 34 ++++++++++++++++++- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecorator.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecorator.java index 5b789778ede..c18acce6ec1 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecorator.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecorator.java @@ -57,15 +57,7 @@ public void decorate(Node violationNode, Map additionalInfo) { enclosing = javaNode.getRoot().getTypeDeclarations().first(); } if (enclosing != null) { - String className; - if (enclosing.isLocal()) { - className = enclosing.getEnclosingType().getCanonicalName() + "." + enclosing.getSimpleName(); - } else if (enclosing.isAnonymous()) { - className = enclosing.getEnclosingType().getCanonicalName(); - } else { - className = enclosing.getCanonicalName(); - } - + String className = determineCanoncialName(enclosing); String packageName = enclosing.getPackageName(); if (className != null && !packageName.isEmpty()) { assert className.startsWith(packageName); @@ -76,6 +68,19 @@ public void decorate(Node violationNode, Map additionalInfo) { return null; } + private String determineCanoncialName(ASTTypeDeclaration type) { + final String canonicalName; + ASTTypeDeclaration enclosingType = type.getEnclosingType(); + if (type.isLocal()) { + canonicalName = determineCanoncialName(enclosingType) + "." + type.getSimpleName(); + } else if (type.isAnonymous()) { + canonicalName = determineCanoncialName(enclosingType); + } else { + canonicalName = type.getCanonicalName(); + } + return canonicalName; + } + private void setIfNonNull(String key, String value, Map additionalInfo) { if (value != null) { additionalInfo.put(key, value); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecoratorTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecoratorTest.java index adec88457db..21961aa2649 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecoratorTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecoratorTest.java @@ -21,6 +21,7 @@ import net.sourceforge.pmd.lang.java.JavaParsingHelper; import net.sourceforge.pmd.lang.java.ast.ASTClassDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; +import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter; import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration; @@ -183,7 +184,7 @@ void testInnerClassIncludingPackage() { @Test void localClasses() { - ASTCompilationUnit ast = parse("class Foo { int a; void m() { class Local { int a; }; } }"); + ASTCompilationUnit ast = parse("class Foo { int a; void m() { class Local { int a; Local() {} }; } }"); List classes = ast.descendants(ASTClassDeclaration.class).crossFindBoundaries().toList(); assertEquals(2, classes.size()); @@ -195,6 +196,37 @@ void localClasses() { assertThat(decorate(fields.get(0)), hasEntry(CLASS_NAME, "Foo")); assertThat(decorate(fields.get(1)), hasEntry(CLASS_NAME, "Foo.Local")); + + List ctors = ast.descendants(ASTConstructorDeclaration.class).crossFindBoundaries().toList(); + assertEquals(1, ctors.size()); + + assertThat(decorate(ctors.get(0)), hasEntry(CLASS_NAME, "Foo.Local")); + } + + @Test + void localClassesNested() { + ASTCompilationUnit ast = parse("package pkg1.pkg2; class Foo { static void fooMethod() { class Local1 { void local1Method() { class Local2 { int field2; Local2() {} } } } } }"); + List classes = ast.descendants(ASTClassDeclaration.class).crossFindBoundaries().toList(); + assertEquals(3, classes.size()); + + assertThat(decorate(classes.get(0)), hasEntry(CLASS_NAME, "Foo")); + assertThat(decorate(classes.get(0)), hasEntry(PACKAGE_NAME, "pkg1.pkg2")); + assertThat(decorate(classes.get(1)), hasEntry(CLASS_NAME, "Foo.Local1")); + assertThat(decorate(classes.get(1)), hasEntry(PACKAGE_NAME, "pkg1.pkg2")); + assertThat(decorate(classes.get(2)), hasEntry(CLASS_NAME, "Foo.Local1.Local2")); + assertThat(decorate(classes.get(2)), hasEntry(PACKAGE_NAME, "pkg1.pkg2")); + + List fields = ast.descendants(ASTFieldDeclaration.class).crossFindBoundaries().toList(); + assertEquals(1, fields.size()); + + assertThat(decorate(fields.get(0)), hasEntry(CLASS_NAME, "Foo.Local1.Local2")); + assertThat(decorate(fields.get(0)), hasEntry(PACKAGE_NAME, "pkg1.pkg2")); + + List ctors = ast.descendants(ASTConstructorDeclaration.class).crossFindBoundaries().toList(); + assertEquals(1, ctors.size()); + + assertThat(decorate(ctors.get(0)), hasEntry(CLASS_NAME, "Foo.Local1.Local2")); + assertThat(decorate(ctors.get(0)), hasEntry(PACKAGE_NAME, "pkg1.pkg2")); } @Test From e6a0b6655c7479616f79139f09513fe19ecb132d Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Fri, 10 Oct 2025 23:14:43 +0200 Subject: [PATCH 1440/1962] [java] UnusedLocalVariable: fix false negatives in pattern matching --- .../UnusedLocalVariableRule.java | 23 +++- .../table/internal/SymbolTableResolver.java | 5 +- .../java21/GuardedPatterns.txt | 8 +- .../Jep441_PatternMatchingForSwitch.txt | 8 +- .../java21/RefiningPatternsInSwitch.txt | 4 +- .../ScopeOfPatternVariableDeclarations.txt | 2 +- .../bestpractices/xml/UnusedLocalVariable.xml | 100 ++++++++++++++++++ 7 files changed, 136 insertions(+), 14 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLocalVariableRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLocalVariableRule.java index d9d5267372e..516e0850a98 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLocalVariableRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLocalVariableRule.java @@ -7,7 +7,11 @@ import org.checkerframework.checker.nullness.qual.NonNull; import net.sourceforge.pmd.lang.java.ast.ASTLocalVariableDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTPatternList; +import net.sourceforge.pmd.lang.java.ast.ASTSwitchLabel; +import net.sourceforge.pmd.lang.java.ast.ASTTypePattern; import net.sourceforge.pmd.lang.java.ast.ASTVariableId; +import net.sourceforge.pmd.lang.java.ast.JavaNode; import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule; import net.sourceforge.pmd.lang.java.rule.internal.JavaRuleUtil; @@ -17,7 +21,7 @@ public class UnusedLocalVariableRule extends AbstractJavaRule { @Override protected @NonNull RuleTargetSelector buildTargetSelector() { - return RuleTargetSelector.forTypes(ASTLocalVariableDeclaration.class); + return RuleTargetSelector.forTypes(ASTLocalVariableDeclaration.class, ASTTypePattern.class); } @Override @@ -31,4 +35,21 @@ public Object visit(ASTLocalVariableDeclaration decl, Object data) { return data; } + @Override + public Object visit(ASTTypePattern pattern, Object data) { + ASTVariableId varId = pattern.getVarId(); + if (JavaAstUtils.isNeverUsed(varId) + && !JavaRuleUtil.isExplicitUnusedVarName(varId.getName()) + && !neededForSwitchOrRcord(pattern)) { + asCtx(data).addViolation(varId, varId.getName()); + } + return data; + } + + private boolean neededForSwitchOrRcord(ASTTypePattern pattern) { + JavaNode parent = pattern.getParent(); + return (parent instanceof ASTSwitchLabel || parent instanceof ASTPatternList) + && pattern.getLanguageVersion().compareToVersion("22") < 0; + } + } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java index 64258f2c711..815fecd6cb1 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java @@ -391,15 +391,16 @@ private Void visitSwitch(ASTSwitchLike node, @NonNull ReferenceCtx ctx) { .reduce(BindSet.EMPTY, (bindSet, pat) -> bindSet.union(bindersOfPattern(pat))); // visit guarded patterns in label + int pushBindings = pushOnStack(f.localVarSymTable(top(), enclosing(), bindings.getTrueBindings())); setTopSymbolTableAndVisit(label, ctx); if (branch instanceof ASTSwitchArrowBranch) { - pushed = pushOnStack(f.localVarSymTable(top(), enclosing(), bindings.getTrueBindings())); + pushed = pushBindings; setTopSymbolTableAndVisit(((ASTSwitchArrowBranch) branch).getRightHandSide(), ctx); popStack(pushed); pushed = 0; } else if (branch instanceof ASTSwitchFallthroughBranch) { - pushed += pushOnStack(f.localVarSymTable(top(), enclosing(), bindings.getTrueBindings())); + pushed += pushBindings; pushed += visitBlockLike(((ASTSwitchFallthroughBranch) branch).getStatements(), ctx); } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/GuardedPatterns.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/GuardedPatterns.txt index d80e6232574..bb6d75959ed 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/GuardedPatterns.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/GuardedPatterns.txt @@ -22,7 +22,7 @@ | | | +- Guard[] | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.EQ, @ParenthesisDepth = 0, @Parenthesized = false] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "length", @MethodName = "length", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- AmbiguousName[@CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- ArgumentList[@Empty = true, @Size = 0] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] @@ -52,7 +52,7 @@ | | | +- Guard[] | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.EQ, @ParenthesisDepth = 0, @Parenthesized = false] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "intValue", @MethodName = "intValue", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- AmbiguousName[@CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- ArgumentList[@Empty = true, @Size = 0] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] @@ -126,7 +126,7 @@ | | | +- Guard[] | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.EQ, @ParenthesisDepth = 1, @Parenthesized = true] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "length", @MethodName = "length", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- AmbiguousName[@CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- ArgumentList[@Empty = true, @Size = 0] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] @@ -156,7 +156,7 @@ | | | +- Guard[] | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.EQ, @ParenthesisDepth = 0, @Parenthesized = false] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "intValue", @MethodName = "intValue", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- AmbiguousName[@CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- ArgumentList[@Empty = true, @Size = 0] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt index 1ad645a2dc3..ed9c04bb01f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt @@ -128,7 +128,7 @@ | | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | | | +- Guard[] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "equalsIgnoreCase", @MethodName = "equalsIgnoreCase", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- AmbiguousName[@CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "YES", @Empty = false, @Image = "\"YES\"", @Length = 3, @LiteralText = "\"YES\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- Block[@Empty = false, @Size = 1, @containsComment = false] @@ -147,7 +147,7 @@ | | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | | | +- Guard[] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "equalsIgnoreCase", @MethodName = "equalsIgnoreCase", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- AmbiguousName[@CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "NO", @Empty = false, @Image = "\"NO\"", @Length = 2, @LiteralText = "\"NO\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- Block[@Empty = false, @Size = 1, @containsComment = false] @@ -219,7 +219,7 @@ | | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | | | +- Guard[] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "equalsIgnoreCase", @MethodName = "equalsIgnoreCase", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- AmbiguousName[@CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "YES", @Empty = false, @Image = "\"YES\"", @Length = 3, @LiteralText = "\"YES\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- Block[@Empty = false, @Size = 1, @containsComment = false] @@ -238,7 +238,7 @@ | | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | | | +- Guard[] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "equalsIgnoreCase", @MethodName = "equalsIgnoreCase", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- AmbiguousName[@CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "NO", @Empty = false, @Image = "\"NO\"", @Length = 2, @LiteralText = "\"NO\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- Block[@Empty = false, @Size = 1, @containsComment = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RefiningPatternsInSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RefiningPatternsInSwitch.txt index 974ccbd24bf..917529b5995 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RefiningPatternsInSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RefiningPatternsInSwitch.txt @@ -110,7 +110,7 @@ | | | +- Guard[] | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.GT, @ParenthesisDepth = 0, @Parenthesized = false] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "calculateArea", @MethodName = "calculateArea", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- AmbiguousName[@CompileTimeConstant = false, @Image = "t", @Name = "t", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "t", @Name = "t", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- ArgumentList[@Empty = true, @Size = 0] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "100", @IntLiteral = true, @Integral = true, @LiteralText = "100", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 100.0, @ValueAsFloat = 100.0, @ValueAsInt = 100, @ValueAsLong = 100] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] @@ -152,7 +152,7 @@ | | | +- Guard[] | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.GT, @ParenthesisDepth = 0, @Parenthesized = false] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "calculateArea", @MethodName = "calculateArea", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- AmbiguousName[@CompileTimeConstant = false, @Image = "t", @Name = "t", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "t", @Name = "t", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- ArgumentList[@Empty = true, @Size = 0] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "100", @IntLiteral = true, @Integral = true, @LiteralText = "100", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 100.0, @ValueAsFloat = 100.0, @ValueAsInt = 100, @ValueAsLong = 100] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ScopeOfPatternVariableDeclarations.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ScopeOfPatternVariableDeclarations.txt index 6d448620011..955704a522a 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ScopeOfPatternVariableDeclarations.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ScopeOfPatternVariableDeclarations.txt @@ -22,7 +22,7 @@ | | | +- Guard[] | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.EQ, @ParenthesisDepth = 0, @Parenthesized = false] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "charValue", @MethodName = "charValue", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- AmbiguousName[@CompileTimeConstant = false, @Image = "c", @Name = "c", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "c", @Name = "c", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- ArgumentList[@Empty = true, @Size = 0] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "7", @IntLiteral = true, @Integral = true, @LiteralText = "7", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 7.0, @ValueAsFloat = 7.0, @ValueAsInt = 7, @ValueAsLong = 7] | | +- ExpressionStatement[] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml index 517db4e2c45..30d130476a1 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml @@ -614,4 +614,104 @@ class Foo { } ]]> + + Instanceof pattern + 1 + + public class Tester { + public void foo(Object arg) { + if (arg instanceof String s) { + } + if (arg instanceof String s) { + System.out.println(s); + } + } + } + + + + Type pattern in switch + 0 + + public class Switcher { + public static void foo(Object r) { + switch (r) { + case String s -> System.out.println("a string"); + default -> System.out.println("not a string"); + } + } + } + + java 21 + + + Type pattern in switch, Java 22 + 1 + System.out.println("a string"); + default -> System.out.println("not a string"); + } + } + } + ]]> + java 22 + + + Record pattern Java 21 + 0 + System.out.println("a wrapped int"); + default -> System.out.println("not a wrapped int"); + } + if (r instanceof Wrap(int k)) { + } + } + } + ]]> + java 21 + + + Record pattern Java 22 + 2 + System.out.println("a wrapped int"); + default -> System.out.println("not a wrapped int"); + } + if (r instanceof Wrap(int k)) { + } + } + } + ]]> + java 22 + + + Record pattern with guard Java 22 + 0 + System.out.println("a wrapped negative int"); + default -> System.out.println("not a wrapped int"); + } + } + } + ]]> + java 22 + From 2b90399916851d7b3ca8a6e08324eea3a1bd1ff7 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Sat, 11 Oct 2025 01:03:30 +0200 Subject: [PATCH 1441/1962] [java] UselessParentheses: fix false positives for switch expressions --- .../codestyle/UselessParenthesesRule.java | 12 +++- .../rule/codestyle/xml/UselessParentheses.xml | 59 +++++++++++++++++++ 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java index 8aa0e2900ac..ee150cac740 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java @@ -11,12 +11,15 @@ import static net.sourceforge.pmd.lang.java.rule.codestyle.UselessParenthesesRule.Necessity.definitely; import static net.sourceforge.pmd.lang.java.rule.codestyle.UselessParenthesesRule.Necessity.necessaryIf; +import net.sourceforge.pmd.lang.java.ast.ASTArrayAccess; import net.sourceforge.pmd.lang.java.ast.ASTAssignmentExpression; import net.sourceforge.pmd.lang.java.ast.ASTCastExpression; import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression; import net.sourceforge.pmd.lang.java.ast.ASTExpression; +import net.sourceforge.pmd.lang.java.ast.ASTFieldAccess; import net.sourceforge.pmd.lang.java.ast.ASTInfixExpression; import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression; +import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression; import net.sourceforge.pmd.lang.java.ast.ASTSwitchExpression; import net.sourceforge.pmd.lang.java.ast.ASTUnaryExpression; @@ -111,10 +114,15 @@ public static Necessity needsParentheses(ASTExpression inner, JavaNode outer) { return NEVER; } - if (inner instanceof ASTPrimaryExpression - || inner instanceof ASTSwitchExpression) { + if (inner instanceof ASTPrimaryExpression) { return NEVER; } + if (inner instanceof ASTSwitchExpression) { + return (outer instanceof ASTMethodCall + || outer instanceof ASTArrayAccess + || outer instanceof ASTFieldAccess) && inner.getIndexInParent() == 0 + ? ALWAYS : NEVER; + } if (outer instanceof ASTLambdaExpression) { // () -> (a + b) unnecessary diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml index afb580c6cdf..f719fda5d43 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml @@ -705,4 +705,63 @@ public class Test { } ]]> + + Switch expression + 0 + new int[1]; + })[0]; + int length = (switch (k) { + default -> new int[0]; + }).length; + return (switch (e) { + default -> "bar"; + }).toUpperCase(); + } + } + ]]> + + + Switch expression unnecessary + 8 + new int[1]; + })); + boolean flag = !(switch (k2) { + default -> true; + }); + int num = ~(switch (k3) { + default -> 0; + }); + double cast = (double) (switch (k4) { + default -> 0; + }); + Supplier factory = () -> (switch (k5) { + default -> 0; + }); + int nest = switch (k6) { + default -> (switch (k6) { + default -> 4; + }); + }; + boolean check = (switch (k7) { + default -> "5"; + }) instanceof String; + int[] ints = {1,2}; + int first = ints[(switch (k8) { + default -> 0; + })]; + } + } + ]]> + From b1347993b68657ce6894e84d05a826c069aed886 Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Mon, 13 Oct 2025 20:56:37 +0200 Subject: [PATCH 1442/1962] #4122: Check for ReturnScopeNode instead of ASTLambdaExpression to also cover anonymous classes --- .../rule/bestpractices/CheckResultSetRule.java | 4 ++-- .../rule/bestpractices/xml/CheckResultSet.xml | 15 +++++++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java index 515c88683c3..317f4153c78 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java @@ -14,11 +14,11 @@ import net.sourceforge.pmd.lang.ast.NodeStream; import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr; import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; -import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression; import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement; import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator; import net.sourceforge.pmd.lang.java.ast.ASTWhileStatement; +import net.sourceforge.pmd.lang.java.ast.ReturnScopeNode; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule; import net.sourceforge.pmd.lang.java.types.TypeTestUtil; @@ -60,7 +60,7 @@ private boolean isResultSetMethod(ASTMethodCall node) { private boolean isCheckedIndirectly(ASTMethodCall node) { final NodeStream variableDeclarators = node.ancestors() - .takeWhile(n -> !(n instanceof ASTLambdaExpression)) + .takeWhile(n -> !(n instanceof ReturnScopeNode)) .filterIs(ASTVariableDeclarator.class); if (variableDeclarators.isEmpty()) { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml index 154b10756bb..ab8352e953c 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/CheckResultSet.xml @@ -405,9 +405,9 @@ public class Foo { - CheckResultSet in lambda - 1 - 7 + CheckResultSet in lambda and anonymous class + 2 + 7,14 { rs.next(); }); - System.out.println(x); + + int y = consumeResultSet(resultSet, new Consumer() { + @Override + public void accept(ResultSet rs) { + rs.next(); + } + }); + System.out.println(y); } private static int consumeResultSet(ResultSet resultSet, Consumer consumer) throws Exception { From 9db288b635f85fd83948117edd215290011c22be Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Tue, 14 Oct 2025 22:30:05 +0200 Subject: [PATCH 1443/1962] #4122: Review finding: Simplify implementation --- .../java/rule/bestpractices/CheckResultSetRule.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java index 317f4153c78..56d616f0de2 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/CheckResultSetRule.java @@ -7,11 +7,9 @@ import static net.sourceforge.pmd.util.CollectionUtil.setOf; import java.sql.ResultSet; -import java.util.Collections; import java.util.List; import java.util.Set; -import net.sourceforge.pmd.lang.ast.NodeStream; import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr; import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; @@ -59,17 +57,15 @@ private boolean isResultSetMethod(ASTMethodCall node) { } private boolean isCheckedIndirectly(ASTMethodCall node) { - final NodeStream variableDeclarators = node.ancestors() + final ASTVariableDeclarator variableDeclarator = node.ancestors() .takeWhile(n -> !(n instanceof ReturnScopeNode)) - .filterIs(ASTVariableDeclarator.class); + .first(ASTVariableDeclarator.class); - if (variableDeclarators.isEmpty()) { + if (variableDeclarator == null) { return false; } - final List usages = variableDeclarators.firstOpt() - .map(varDecl -> varDecl.getVarId().getLocalUsages()) - .orElse(Collections.emptyList()); + final List usages = variableDeclarator.getVarId().getLocalUsages(); //check that the result is used and its first usage is not overwriting the result return !usages.isEmpty() && usages.get(0).getAccessType() == ASTAssignableExpr.AccessType.READ; } From 7df9f714488402168091f7d2086479b7a4bd56b8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 12 Sep 2025 15:56:51 +0200 Subject: [PATCH 1444/1962] Use build-tools 35-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cd59d4a2a02..088a0513e50 100644 --- a/pom.xml +++ b/pom.xml @@ -107,7 +107,7 @@ -Xmx512m -Dfile.encoding=${project.build.sourceEncoding} ${extraArgLine} - 34 + 35-SNAPSHOT 7.10.0 From ba4a0bfb6ba856b43e5369006df62d47e1f18139 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 12 Sep 2025 16:09:05 +0200 Subject: [PATCH 1445/1962] Fixes for OverrideBothEqualsAndHashCodeOnComparable --- .../main/java/net/sourceforge/pmd/cpd/Match.java | 1 + .../pmd/lang/ast/impl/antlr4/AntlrToken.java | 1 + .../DeterministicOutputListenerWrapper.java | 14 ++++++++++++++ .../lang/groovy/ast/impl/antlr4/GroovyToken.java | 1 + 4 files changed, 17 insertions(+) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Match.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Match.java index 3e7cc7953f1..31db2b92a23 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Match.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Match.java @@ -60,6 +60,7 @@ public Iterator iterator() { } @Override + @SuppressWarnings("PMD.OverrideBothEqualsAndHashCodeOnComparable") public int compareTo(Match other) { int diff = other.getTokenCount() - getTokenCount(); if (diff != 0) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrToken.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrToken.java index 4a12e8388d5..5195beaa456 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrToken.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrToken.java @@ -79,6 +79,7 @@ public boolean isEof() { } @Override + @SuppressWarnings("PMD.OverrideBothEqualsAndHashCodeOnComparable") public int compareTo(AntlrToken o) { return getRegion().compareTo(o.getRegion()); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/DeterministicOutputListenerWrapper.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/DeterministicOutputListenerWrapper.java index e95906b2e53..69800163051 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/DeterministicOutputListenerWrapper.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/DeterministicOutputListenerWrapper.java @@ -174,5 +174,19 @@ private static final class ReportWrapper implements Comparable { public int compareTo(ReportWrapper o) { return Integer.compare(this.idx, o.idx); } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + ReportWrapper that = (ReportWrapper) o; + return idx == that.idx && Objects.equals(report, that.report) && Objects.equals(textFile, that.textFile); + } + + @Override + public int hashCode() { + return Objects.hash(report, textFile, idx); + } } } diff --git a/pmd-groovy/src/main/java/net/sourceforge/pmd/lang/groovy/ast/impl/antlr4/GroovyToken.java b/pmd-groovy/src/main/java/net/sourceforge/pmd/lang/groovy/ast/impl/antlr4/GroovyToken.java index 197e40d78dc..5f78ff19b97 100644 --- a/pmd-groovy/src/main/java/net/sourceforge/pmd/lang/groovy/ast/impl/antlr4/GroovyToken.java +++ b/pmd-groovy/src/main/java/net/sourceforge/pmd/lang/groovy/ast/impl/antlr4/GroovyToken.java @@ -72,6 +72,7 @@ public boolean isEof() { } @Override + @SuppressWarnings("PMD.OverrideBothEqualsAndHashCodeOnComparable") public int compareTo(GroovyToken o) { return getRegion().compareTo(o.getRegion()); } From f1c0b1647a80374274c56aaa1b2e952b905eea9b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 12 Sep 2025 16:16:11 +0200 Subject: [PATCH 1446/1962] Fixes for RelianceOnDefaultCharset --- .../pmd/cli/commands/internal/PmdCommand.java | 3 ++- .../pmd/internal/util/ClasspathClassLoader.java | 3 ++- .../pmd/util/treeexport/TreeExporter.java | 3 ++- .../lang/rule/AbstractRuleSetFactoryTest.java | 16 ++++++++-------- .../pmd/lang/xml/ast/internal/XmlParserImpl.java | 2 +- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java index 152e73e7762..7b8bb4735e8 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java @@ -7,6 +7,7 @@ import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; +import java.nio.charset.Charset; import java.nio.file.Path; import java.util.ArrayList; import java.util.Iterator; @@ -358,7 +359,7 @@ private void finishBenchmarker(final PmdReporter pmdReporter) { try { // No try-with-resources, do not want to close STDERR @SuppressWarnings("PMD.CloseResource") - final Writer writer = new OutputStreamWriter(System.err); + final Writer writer = new OutputStreamWriter(System.err, Charset.defaultCharset()); renderer.render(timingReport, writer); } catch (final IOException e) { pmdReporter.errorEx("Error producing benchmark report", e); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java index 6f23edb3ebf..f3a1c3f59a9 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java @@ -14,6 +14,7 @@ import java.net.URI; import java.net.URL; import java.net.URLClassLoader; +import java.nio.charset.Charset; import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Files; @@ -121,7 +122,7 @@ private void addClasspathURLs(final List urls, final String classpath) thro } private void addFileURLs(List urls, URL fileURL) throws IOException { - try (BufferedReader in = new BufferedReader(new InputStreamReader(fileURL.openStream()))) { + try (BufferedReader in = new BufferedReader(new InputStreamReader(fileURL.openStream(), Charset.defaultCharset()))) { String line; while ((line = in.readLine()) != null) { LOG.debug("Read classpath entry line: <{}>", line); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/treeexport/TreeExporter.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/treeexport/TreeExporter.java index 60a7f7a52f1..91c8d6e208b 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/treeexport/TreeExporter.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/treeexport/TreeExporter.java @@ -8,6 +8,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; +import java.nio.charset.Charset; import java.util.Collections; import java.util.Map.Entry; import java.util.Properties; @@ -88,7 +89,7 @@ private void run(LanguageProcessorRegistry langRegistry, final TreeRenderer rend } private Reader readFromSystemIn() { - return new BufferedReader(new InputStreamReader(io.stdin)); + return new BufferedReader(new InputStreamReader(io.stdin, Charset.defaultCharset())); } private T parseProperties(T bundle, Properties properties) { diff --git a/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java b/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java index 3ab0f9f7d76..de24a72c066 100644 --- a/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java +++ b/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java @@ -426,7 +426,7 @@ private boolean validateAgainstDtd(InputStream inputStream) throws IOException, + file; } - try (InputStream modifiedStream = new ByteArrayInputStream(file.getBytes())) { + try (InputStream modifiedStream = new ByteArrayInputStream(file.getBytes(StandardCharsets.UTF_8))) { saxParser.parse(modifiedStream, validateDefaultHandler.resetValid()); } return validateDefaultHandler.isValid(); @@ -434,7 +434,7 @@ private boolean validateAgainstDtd(InputStream inputStream) throws IOException, private String readFullyToString(InputStream inputStream) throws IOException { StringBuilder buf = new StringBuilder(64 * 1024); - try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) { String line; while ((line = reader.readLine()) != null) { buf.append(line); @@ -463,7 +463,7 @@ private void testRuleSet(String fileName) throws IOException, SAXException { RuleSetWriter writer1 = new RuleSetWriter(outputStream1); writer1.write(ruleSet1); writer1.close(); - String xml2 = new String(outputStream1.toByteArray()); + String xml2 = new String(outputStream1.toByteArray(), StandardCharsets.UTF_8); // System.out.println("xml2: " + xml2); // Read RuleSet from XML, first time @@ -477,20 +477,20 @@ private void testRuleSet(String fileName) throws IOException, SAXException { RuleSetWriter writer2 = new RuleSetWriter(outputStream2); writer2.write(ruleSet2); writer2.close(); - String xml3 = new String(outputStream2.toByteArray()); + String xml3 = new String(outputStream2.toByteArray(), StandardCharsets.UTF_8); // System.out.println("xml3: " + xml3); // Read RuleSet from XML, second time RuleSet ruleSet3 = loader.loadFromString("readRuleSet2.xml", xml3); // The 2 written XMLs should all be valid w.r.t Schema/DTD - assertTrue(validateAgainstSchema(new ByteArrayInputStream(xml2.getBytes())), + assertTrue(validateAgainstSchema(new ByteArrayInputStream(xml2.getBytes(StandardCharsets.UTF_8))), "1st roundtrip RuleSet XML is not valid against Schema (filename: " + fileName + ")"); - assertTrue(validateAgainstSchema(new ByteArrayInputStream(xml3.getBytes())), + assertTrue(validateAgainstSchema(new ByteArrayInputStream(xml3.getBytes(StandardCharsets.UTF_8))), "2nd roundtrip RuleSet XML is not valid against Schema (filename: " + fileName + ")"); - assertTrue(validateAgainstDtd(new ByteArrayInputStream(xml2.getBytes())), + assertTrue(validateAgainstDtd(new ByteArrayInputStream(xml2.getBytes(StandardCharsets.UTF_8))), "1st roundtrip RuleSet XML is not valid against DTD (filename: " + fileName + ")"); - assertTrue(validateAgainstDtd(new ByteArrayInputStream(xml3.getBytes())), + assertTrue(validateAgainstDtd(new ByteArrayInputStream(xml3.getBytes(StandardCharsets.UTF_8))), "2nd roundtrip RuleSet XML is not valid against DTD (filename: " + fileName + ")"); // All 3 versions of the RuleSet should be the same diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/ast/internal/XmlParserImpl.java b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/ast/internal/XmlParserImpl.java index 14c8886bbad..a94b9b3bda2 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/ast/internal/XmlParserImpl.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/lang/xml/ast/internal/XmlParserImpl.java @@ -30,7 +30,7 @@ public final class XmlParserImpl { // never throws on unresolved resource - private static final EntityResolver SILENT_ENTITY_RESOLVER = (publicId, systemId) -> new InputSource(new ByteArrayInputStream("".getBytes())); + private static final EntityResolver SILENT_ENTITY_RESOLVER = (publicId, systemId) -> new InputSource(new ByteArrayInputStream(new byte[0])); private final Map nodeCache = new HashMap<>(); From 935151e1b0d7e3e830abc778b6dd31d059899b72 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 12 Sep 2025 16:16:58 +0200 Subject: [PATCH 1447/1962] Fixes for ModifierOrder --- .../java/net/sourceforge/pmd/lang/ast/internal/StreamImpl.java | 3 ++- .../src/main/java/net/sourceforge/pmd/util/CollectionUtil.java | 3 ++- .../main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/StreamImpl.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/StreamImpl.java index 8a356d18aa2..3f36fcc5c8c 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/StreamImpl.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/StreamImpl.java @@ -222,7 +222,8 @@ protected NodeStream mapIter(Function, Iterator< } @Override - protected @NonNull DescendantNodeStream flatMapDescendants(Function> mapper) { + @NonNull + protected DescendantNodeStream flatMapDescendants(Function> mapper) { return StreamImpl.empty(); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java index 4aa5c7b8f98..c5340f7837b 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java @@ -711,7 +711,8 @@ public static PSet union(PSet as, PSet bs) { return as.plusAll(bs); } - public static @NonNull List makeUnmodifiableAndNonNull(@Nullable List list) { + @NonNull + public static List makeUnmodifiableAndNonNull(@Nullable List list) { if (list instanceof PSequence) { return (List) list; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java index 6c6945fe9c5..3b127a7ae87 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java @@ -991,7 +991,8 @@ public static List substInBoundsOnly(List ts, Function List mapPreservingSelf(List ts, Function subst) { + @NonNull + private static List mapPreservingSelf(List ts, Function subst) { // Profiling shows, only 10% of calls to this method need to // create a new list. Substitution in general is a hot spot // of the framework, so optimizing this out is nice From 5024a14f36df4ca2b8ad100ec3eba3162f0ceafc Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 12 Sep 2025 16:17:24 +0200 Subject: [PATCH 1448/1962] Fixes for DanglingJavadoc --- .../java/net/sourceforge/pmd/util/database/DBType.java | 8 -------- .../pmd/lang/plsql/symboltable/PLSQLNameOccurrence.java | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/database/DBType.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/database/DBType.java index 916826b8daf..1e092b3dae9 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/database/DBType.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/database/DBType.java @@ -230,14 +230,6 @@ private Properties loadDBProperties(String matchString) throws IOException { return matchedProperties; } - /** - * Options that are specific to a type of database. E.g. things like - * host, port or db, but don't - * have a setter in this class. - * - * @param dbSpecificOptions - */ - /** * Convert resourceBundle to usable {@link Properties}. * diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/PLSQLNameOccurrence.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/PLSQLNameOccurrence.java index 865c2fdfe2d..410d5dd8443 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/PLSQLNameOccurrence.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/symboltable/PLSQLNameOccurrence.java @@ -120,7 +120,7 @@ public boolean isOnLeftHandSide() { * thirdChild).getImage().indexOf('.') == -1; } */ - /** + /* * Assert it the occurrence is a self assignment such as: * * i += 3; From abc7a61b9211febaf8db98e79f59dd356a93fa2f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 12 Sep 2025 16:20:42 +0200 Subject: [PATCH 1449/1962] Fixes for ExhaustiveSwitchHasDefault --- .../internal/SaxonExtensionFunctionDefinitionAdapter.java | 5 +++-- .../sourceforge/pmd/renderers/CodeClimateRenderer.java | 1 - .../pmd/renderers/internal/sarif/SarifLogBuilder.java | 5 +++-- .../pmd/util/log/internal/SimpleMessageReporter.java | 7 +++---- .../java/net/sourceforge/pmd/lang/java/ast/BinaryOp.java | 4 ++-- .../net/sourceforge/pmd/lang/java/ast/ConstantFolder.java | 6 ++---- .../pmd/lang/java/rule/codestyle/ModifierOrderRule.java | 3 +-- .../lang/java/rule/documentation/CommentRequiredRule.java | 2 -- .../lang/java/types/ast/internal/LazyTypeResolver.java | 8 +++----- .../pmd/lang/java/types/internal/infer/OverloadSet.java | 2 -- 10 files changed, 17 insertions(+), 26 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/SaxonExtensionFunctionDefinitionAdapter.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/SaxonExtensionFunctionDefinitionAdapter.java index 85926ad7e6b..bb2d05e3b76 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/SaxonExtensionFunctionDefinitionAdapter.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/SaxonExtensionFunctionDefinitionAdapter.java @@ -12,6 +12,7 @@ import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.rule.xpath.impl.XPathFunctionDefinition; import net.sourceforge.pmd.lang.rule.xpath.impl.XPathFunctionException; +import net.sourceforge.pmd.util.AssertionUtil; import net.sf.saxon.expr.Expression; import net.sf.saxon.expr.StaticContext; @@ -53,9 +54,9 @@ private SequenceType convertToSequenceType(XPathFunctionDefinition.Type type) { case STRING_SEQUENCE: return SequenceType.STRING_SEQUENCE; case OPTIONAL_STRING: return SequenceType.OPTIONAL_STRING; case OPTIONAL_DECIMAL: return SequenceType.OPTIONAL_DECIMAL; - default: - throw new UnsupportedOperationException("Type " + type + " is not supported"); } + // should not occur, above switch is exhaustive + throw AssertionUtil.shouldNotReachHere("Type " + type + " is not supported"); } private SequenceType[] convertToSequenceTypes(XPathFunctionDefinition.Type[] types) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateRenderer.java index f88741a3de4..e022b821d05 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateRenderer.java @@ -89,7 +89,6 @@ private CodeClimateIssue asIssue(RuleViolation rv) { issue.severity = "minor"; break; case LOW: - default: issue.severity = "info"; break; } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java index fcb825b12e0..0cee7e3d091 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java @@ -32,6 +32,7 @@ import net.sourceforge.pmd.renderers.internal.sarif.SarifLog.ToolExecutionNotification; import net.sourceforge.pmd.reporting.Report; import net.sourceforge.pmd.reporting.RuleViolation; +import net.sourceforge.pmd.util.AssertionUtil; public class SarifLogBuilder { private final List rules = new ArrayList<>(); @@ -222,8 +223,8 @@ private String pmdPriorityToSarifSeverityLevel(RulePriority rulePriority) { case MEDIUM_LOW: case LOW: return "note"; - default: - return "none"; // should not occur } + // should not occur, above switch is exhaustive + throw AssertionUtil.shouldNotReachHere("invalid rule priority " + rulePriority); } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/log/internal/SimpleMessageReporter.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/log/internal/SimpleMessageReporter.java index fd6189dbe67..f54a11b551c 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/log/internal/SimpleMessageReporter.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/log/internal/SimpleMessageReporter.java @@ -7,6 +7,7 @@ import org.slf4j.Logger; import org.slf4j.event.Level; +import net.sourceforge.pmd.util.AssertionUtil; import net.sourceforge.pmd.util.log.PmdReporter; /** @@ -35,9 +36,9 @@ protected boolean isLoggableImpl(Level level) { return backend.isDebugEnabled(); case TRACE: return backend.isTraceEnabled(); - default: - return false; } + // should not occur, above switch is exhaustive + throw AssertionUtil.shouldNotReachHere("Invalid log level: " + level); } @Override @@ -58,8 +59,6 @@ protected void logImpl(Level level, String message) { case TRACE: backend.trace(message); break; - default: - throw new AssertionError("Invalid log level: " + level); } } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/BinaryOp.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/BinaryOp.java index e9957e5b325..9ad3bf81f03 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/BinaryOp.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/BinaryOp.java @@ -12,6 +12,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; +import net.sourceforge.pmd.util.AssertionUtil; import net.sourceforge.pmd.util.CollectionUtil; /** @@ -183,9 +184,8 @@ private int precedenceClass() { case DIV: case MOD: return 0; - default: - return -1; } + throw AssertionUtil.shouldNotReachHere("Invalid binary op " + this); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ConstantFolder.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ConstantFolder.java index 1a2ca1208d5..258a458c8cc 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ConstantFolder.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ConstantFolder.java @@ -481,9 +481,8 @@ public strictfp ConstResult visit(ASTInfixExpression node, Void data) { } return null; } - default: - throw AssertionUtil.shouldNotReachHere("Unknown operator '" + node.getOperator() + "' in " + node); } + throw AssertionUtil.shouldNotReachHere("Unknown operator '" + node.getOperator() + "' in " + node); } private static @Nullable Object compLE(Object left, Object right) { @@ -618,9 +617,8 @@ private static Object numericCoercion(Object v, JTypeMirror target) { return floatValue(v); case DOUBLE: return doubleValue(v); - default: - throw AssertionUtil.shouldNotReachHere("exhaustive enum: " + target); } + throw AssertionUtil.shouldNotReachHere("exhaustive enum: " + target); } return null; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ModifierOrderRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ModifierOrderRule.java index f2742200fc8..13a19d3e3ad 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ModifierOrderRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ModifierOrderRule.java @@ -62,9 +62,8 @@ String label() { return "ondecl"; case ANYWHERE: return "anywhere"; - default: - throw AssertionUtil.shouldNotReachHere("exhaustive switch"); } + throw AssertionUtil.shouldNotReachHere("exhaustive switch"); } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredRule.java index 7928fc21ee0..5a97a21c3c6 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredRule.java @@ -104,8 +104,6 @@ private void checkCommentMeetsRequirement(Object data, JavadocCommentOwner node, commentRequiredViolation(data, node, descriptor); } break; - default: - break; } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/LazyTypeResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/LazyTypeResolver.java index 7ccbd5a963c..a030f1c20e6 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/LazyTypeResolver.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/LazyTypeResolver.java @@ -94,6 +94,7 @@ import net.sourceforge.pmd.lang.java.types.ast.ExprContext.ExprContextKind; import net.sourceforge.pmd.lang.java.types.internal.infer.Infer; import net.sourceforge.pmd.lang.java.types.internal.infer.TypeInferenceLogger; +import net.sourceforge.pmd.util.AssertionUtil; /** * Resolves types of expressions. This is used as the implementation of @@ -467,10 +468,8 @@ public JTypeMirror visit(ASTInfixExpression node, TypingContext ctx) { } else { return binaryNumericPromotion(lhs, rhs); } - - default: - throw new AssertionError("Unknown operator for " + node); } + throw AssertionUtil.shouldNotReachHere("Unknown operator for " + node); } private boolean isUnresolved(JTypeMirror t) { @@ -495,9 +494,8 @@ public JTypeMirror visit(ASTUnaryExpression node, TypingContext ctx) { case POST_INCREMENT: case POST_DECREMENT: return node.getOperand().getTypeMirror(ctx); - default: - throw new AssertionError("Unknown operator for " + node); } + throw AssertionUtil.shouldNotReachHere("Unknown operator for " + node); } @Override diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadSet.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadSet.java index 640c0165991..71f69452803 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadSet.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadSet.java @@ -56,8 +56,6 @@ void add(T sig) { case UNKNOWN: // neither sig is more specific break; - default: - throw new AssertionError(); } } overloads.add(sig); From 178d00114d98911a05e9d309ffa2ef79fbe4f318 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 12 Sep 2025 16:21:06 +0200 Subject: [PATCH 1450/1962] Fixes for UselessPureMethodCall Refs #6055 --- .../main/java/net/sourceforge/pmd/benchmark/TimeTracker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimeTracker.java b/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimeTracker.java index 13c39b7b967..bcd0e2f12e6 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimeTracker.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimeTracker.java @@ -209,7 +209,7 @@ public String toString() { totalTimeNanos.getAndAdd(delta); selfTimeNanos.getAndAdd(delta - timerEntry.inNestedOperationsNanos); - callCount.getAndIncrement(); + callCount.getAndIncrement(); // NOPMD: UselessPureMethodCall false-positive #6055 extraDataCounter.getAndAdd(extraData); return delta; From ffc71cd1d6b0dedd05282af13743a4231ecd8ab8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 16 Oct 2025 09:30:33 +0200 Subject: [PATCH 1451/1962] Revert "Fixes for ModifierOrder" This reverts commit 4a790672c1f5513b4e083283b335d5611ce66335. --- .../java/net/sourceforge/pmd/lang/ast/internal/StreamImpl.java | 3 +-- .../src/main/java/net/sourceforge/pmd/util/CollectionUtil.java | 3 +-- .../main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/StreamImpl.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/StreamImpl.java index 3f36fcc5c8c..8a356d18aa2 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/StreamImpl.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/StreamImpl.java @@ -222,8 +222,7 @@ protected NodeStream mapIter(Function, Iterator< } @Override - @NonNull - protected DescendantNodeStream flatMapDescendants(Function> mapper) { + protected @NonNull DescendantNodeStream flatMapDescendants(Function> mapper) { return StreamImpl.empty(); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java index c5340f7837b..4aa5c7b8f98 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java @@ -711,8 +711,7 @@ public static PSet union(PSet as, PSet bs) { return as.plusAll(bs); } - @NonNull - public static List makeUnmodifiableAndNonNull(@Nullable List list) { + public static @NonNull List makeUnmodifiableAndNonNull(@Nullable List list) { if (list instanceof PSequence) { return (List) list; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java index 3b127a7ae87..6c6945fe9c5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java @@ -991,8 +991,7 @@ public static List substInBoundsOnly(List ts, Function List mapPreservingSelf(List ts, Function subst) { + private static @NonNull List mapPreservingSelf(List ts, Function subst) { // Profiling shows, only 10% of calls to this method need to // create a new list. Substitution in general is a hot spot // of the framework, so optimizing this out is nice From f7c49d862219de147f3dc71564cdfa1855502be4 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 16 Oct 2025 09:55:31 +0200 Subject: [PATCH 1452/1962] [doc] Update release notes (#6056) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 88ccf173746..58b2b61e447 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -72,6 +72,7 @@ checkstyle version during the build. * [#6039](https://github.com/pmd/pmd/pull/6039): \[core] Fix #4714: trim token before feeding it to the extractor - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6040](https://github.com/pmd/pmd/pull/6040): \[java,apex,plsql,velocity] Change description of "minimum" parameter - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6043](https://github.com/pmd/pmd/pull/6043): \[java] Reactivate deactivated test in LocalVariableCouldBeFinal - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6056](https://github.com/pmd/pmd/pull/6056): chore: fix dogfood issues from new rules - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6059](https://github.com/pmd/pmd/pull/6059): \[java] Fix #6058: DanglingJavadoc FP in module-info files - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6061](https://github.com/pmd/pmd/pull/6061): \[core] chore: Bump minimum Java version required for building to 17 - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6071](https://github.com/pmd/pmd/pull/6071): \[java] Fix #5919: Add integration tests to ClassNamingConventions testClassRegex - [Anton Bobov](https://github.com/abobov) (@abobov) From 99fafd894a78fe51c78cc540a54fe609f9ffa5aa Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 16 Oct 2025 09:59:11 +0200 Subject: [PATCH 1453/1962] Use build-tools 35 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 088a0513e50..be34cf71963 100644 --- a/pom.xml +++ b/pom.xml @@ -107,7 +107,7 @@ -Xmx512m -Dfile.encoding=${project.build.sourceEncoding} ${extraArgLine} - 35-SNAPSHOT + 35 7.10.0 From 02620ab156600797f6590b8e5ae5f93bea83eaee Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Fri, 17 Oct 2025 20:34:33 +0200 Subject: [PATCH 1454/1962] Clarify comments for modifier order --- .../sourceforge/pmd/lang/java/ast/JModifier.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JModifier.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JModifier.java index e215b56e7d3..9c8a2d123e3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JModifier.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/JModifier.java @@ -15,13 +15,16 @@ import net.sourceforge.pmd.lang.java.symbols.JMethodSymbol; /** - * A Java modifier. The ordering of constants respects the ordering - * recommended by the JLS. + * A Java modifier. The ordering of constants must respects the ordering recommended by the JLS: + * */ // Note: the class is named JModifier and not Modifier to avoid conflict // with java.lang.reflect.Modifier public enum JModifier { - // for anything PUBLIC(Modifier.PUBLIC), PROTECTED(Modifier.PROTECTED), PRIVATE(Modifier.PRIVATE), @@ -36,15 +39,14 @@ public enum JModifier { /** Modifier {@code "non-sealed"} (since Java 17). */ NON_SEALED("non-sealed", 0), - // for fields TRANSIENT(Modifier.TRANSIENT), VOLATILE(Modifier.VOLATILE), - // for methods + SYNCHRONIZED(Modifier.SYNCHRONIZED), NATIVE(Modifier.NATIVE), - // not for fields STRICTFP(Modifier.STRICT); + /* IMPORTANT: when adding a constant, keep the order aligned with JLS (links in JavaDoc) */ private final String token; private final int reflect; From 4fcd9f50636ad3a864c7b11f1de8bf8c71f69fcd Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Sat, 18 Oct 2025 12:37:14 +0200 Subject: [PATCH 1455/1962] Simplify check for primary expressions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Clรฉment Fournier --- .../pmd/lang/java/rule/codestyle/UselessParenthesesRule.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java index ee150cac740..8f215cfb580 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java @@ -118,9 +118,7 @@ public static Necessity needsParentheses(ASTExpression inner, JavaNode outer) { return NEVER; } if (inner instanceof ASTSwitchExpression) { - return (outer instanceof ASTMethodCall - || outer instanceof ASTArrayAccess - || outer instanceof ASTFieldAccess) && inner.getIndexInParent() == 0 + return outer instanceof ASTPrimaryExpression && inner.getIndexInParent() == 0 ? ALWAYS : NEVER; } From fb9be2f5384ba57cb1f1f3ca41e45f97461cb89f Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Sat, 18 Oct 2025 13:04:39 +0200 Subject: [PATCH 1456/1962] Remove unused imports --- .../pmd/lang/java/rule/codestyle/UselessParenthesesRule.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java index 8f215cfb580..4a00deae809 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UselessParenthesesRule.java @@ -11,15 +11,12 @@ import static net.sourceforge.pmd.lang.java.rule.codestyle.UselessParenthesesRule.Necessity.definitely; import static net.sourceforge.pmd.lang.java.rule.codestyle.UselessParenthesesRule.Necessity.necessaryIf; -import net.sourceforge.pmd.lang.java.ast.ASTArrayAccess; import net.sourceforge.pmd.lang.java.ast.ASTAssignmentExpression; import net.sourceforge.pmd.lang.java.ast.ASTCastExpression; import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression; import net.sourceforge.pmd.lang.java.ast.ASTExpression; -import net.sourceforge.pmd.lang.java.ast.ASTFieldAccess; import net.sourceforge.pmd.lang.java.ast.ASTInfixExpression; import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression; -import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression; import net.sourceforge.pmd.lang.java.ast.ASTSwitchExpression; import net.sourceforge.pmd.lang.java.ast.ASTUnaryExpression; From 452258f24c37e0a31b248fec1570c4c26cfc7db1 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Sat, 18 Oct 2025 13:23:37 +0200 Subject: [PATCH 1457/1962] Use LeftRecursiveNode instead of tweaking the parser --- .../java/ast/ASTCompactConstructorDeclaration.java | 3 ++- pmd-java/src/main/javacc/Java.jjt | 5 +---- .../ast/ASTCompactConstructorDeclarationTest.java | 13 +++++++++++++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompactConstructorDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompactConstructorDeclaration.java index 7c33d284e16..df236e237b4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompactConstructorDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCompactConstructorDeclaration.java @@ -30,7 +30,8 @@ */ // TODO make implicit formal parameter node and implement ASTExecutableDeclaration. // This might help UnusedAssignmentRule / DataflowPass.ReachingDefsVisitor, see also #4603 -public final class ASTCompactConstructorDeclaration extends AbstractJavaNode implements ASTBodyDeclaration, SymbolDeclaratorNode, ModifierOwner, JavadocCommentOwner, ReturnScopeNode { +public final class ASTCompactConstructorDeclaration extends AbstractJavaNode + implements ASTBodyDeclaration, SymbolDeclaratorNode, ModifierOwner, JavadocCommentOwner, ReturnScopeNode, LeftRecursiveNode { private JavaccToken identToken; diff --git a/pmd-java/src/main/javacc/Java.jjt b/pmd-java/src/main/javacc/Java.jjt index 8cb123eaf75..e87a27bb73d 100644 --- a/pmd-java/src/main/javacc/Java.jjt +++ b/pmd-java/src/main/javacc/Java.jjt @@ -1287,10 +1287,7 @@ private void CompactConstructorDeclarationLookahead() #void: void CompactConstructorDeclaration(): {} { - { - jjtThis.setFirstToken(jjtree.peekNode().getFirstToken()); - jjtThis.setIdentToken(token); - } + { jjtThis.setIdentToken(token); } Block() } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTCompactConstructorDeclarationTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTCompactConstructorDeclarationTest.java index 604b4a09c22..b7500869288 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTCompactConstructorDeclarationTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTCompactConstructorDeclarationTest.java @@ -24,4 +24,17 @@ void compactConstructorWithLambda() { .get(0); assertEquals(1, compactConstructor.getBody().getNumChildren()); } + + @Test + void compactConstructorRange() { + ASTCompactConstructorDeclaration compactConstructor = java.getNodes(ASTCompactConstructorDeclaration.class, + "record RecordWithDocumentation(String foo) {" + + "/** JavaDoc */" + + " RecordWithDocumentation {" + + " assert foo != null;" + + " }" + + "}") + .get(0); + assertEquals("/** JavaDoc */", compactConstructor.getFirstToken().getImage()); + } } From a9a8bbfa3c454431e9c126ca4a47bbcd32e7f5a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 19 Oct 2025 23:06:30 +0200 Subject: [PATCH 1458/1962] Update release notes, ref #6100 --- .idea/vcs.xml | 1 + docs/pages/release_notes.md | 1 + 2 files changed, 2 insertions(+) diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 13f1d386bbf..39eb3fa282f 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -23,5 +23,6 @@ + \ No newline at end of file diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 58b2b61e447..a8ae7f2f472 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -40,6 +40,7 @@ checkstyle version during the build. * [#5919](https://github.com/pmd/pmd/issues/5919): \[java] ClassNamingConventions: Include integration tests in testClassPattern by default * [#6029](https://github.com/pmd/pmd/issues/6029): \[java] Fix UnnecessaryCast false-negative in method calls * java-design + * [#1499](https://github.com/pmd/pmd/issues/1499): \[java] AvoidDeeplyNestedIfStmts violations can be unintentionally undetected * [#5569](https://github.com/pmd/pmd/issues/5569): \[java] ExcessivePublicCount should report number of public "things" * java-documentation * [#6058](https://github.com/pmd/pmd/issues/6058): \[java] DanglingJavadoc FP in module-info files From f3e4e71abab61503a239aa73bde9ab5befd15caf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 19 Oct 2025 23:20:53 +0200 Subject: [PATCH 1459/1962] Update release notes, ref #6114 --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index a8ae7f2f472..fe70679bdd9 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -36,6 +36,8 @@ checkstyle version during the build. * [#5935](https://github.com/pmd/pmd/issues/5935): \[apex] @SuppressWarnings - allow whitespace around comma when suppressing multiple rules * apex-design * [#6022](https://github.com/pmd/pmd/issues/6022): \[apex] ExcessiveClassLength/ExcessiveParameterList include the metric in the message +* java-bestpractices + * [#4122](https://github.com/pmd/pmd/issues/4122): \[java] CheckResultSet false-positive with local variable * java-codestyle * [#5919](https://github.com/pmd/pmd/issues/5919): \[java] ClassNamingConventions: Include integration tests in testClassPattern by default * [#6029](https://github.com/pmd/pmd/issues/6029): \[java] Fix UnnecessaryCast false-negative in method calls From b465198a912a2933bee0209fe19909958698f6ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 19 Oct 2025 23:25:37 +0200 Subject: [PATCH 1460/1962] Update release notes, ref #6124 --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index fe70679bdd9..38e8e0a8277 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -38,6 +38,7 @@ checkstyle version during the build. * [#6022](https://github.com/pmd/pmd/issues/6022): \[apex] ExcessiveClassLength/ExcessiveParameterList include the metric in the message * java-bestpractices * [#4122](https://github.com/pmd/pmd/issues/4122): \[java] CheckResultSet false-positive with local variable + * [#6124](https://github.com/pmd/pmd/issues/6124): \[java] UnusedLocalVariable: fix false negatives in pattern matching * java-codestyle * [#5919](https://github.com/pmd/pmd/issues/5919): \[java] ClassNamingConventions: Include integration tests in testClassPattern by default * [#6029](https://github.com/pmd/pmd/issues/6029): \[java] Fix UnnecessaryCast false-negative in method calls From 818e372056fdeee34ca3ef4b8b34ee6d2a162c74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 19 Oct 2025 23:27:16 +0200 Subject: [PATCH 1461/1962] Update release notes, ref #6080 --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 38e8e0a8277..574a2dab9dc 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -42,6 +42,7 @@ checkstyle version during the build. * java-codestyle * [#5919](https://github.com/pmd/pmd/issues/5919): \[java] ClassNamingConventions: Include integration tests in testClassPattern by default * [#6029](https://github.com/pmd/pmd/issues/6029): \[java] Fix UnnecessaryCast false-negative in method calls + * [#6079](https://github.com/pmd/pmd/issues/6079): \[java] IdenticalCatchBranches: False negative for overriden method calls * java-design * [#1499](https://github.com/pmd/pmd/issues/1499): \[java] AvoidDeeplyNestedIfStmts violations can be unintentionally undetected * [#5569](https://github.com/pmd/pmd/issues/5569): \[java] ExcessivePublicCount should report number of public "things" From 9bd4b62e72564ee6672880ef7160de86f0ab337d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 19 Oct 2025 23:28:25 +0200 Subject: [PATCH 1462/1962] Update release notes, ref #6085 --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 574a2dab9dc..82ffe725d17 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -42,6 +42,7 @@ checkstyle version during the build. * java-codestyle * [#5919](https://github.com/pmd/pmd/issues/5919): \[java] ClassNamingConventions: Include integration tests in testClassPattern by default * [#6029](https://github.com/pmd/pmd/issues/6029): \[java] Fix UnnecessaryCast false-negative in method calls + * [#6057](https://github.com/pmd/pmd/issues/6057): \[java] ModifierOrder false positive on "abstract sealed class" * [#6079](https://github.com/pmd/pmd/issues/6079): \[java] IdenticalCatchBranches: False negative for overriden method calls * java-design * [#1499](https://github.com/pmd/pmd/issues/1499): \[java] AvoidDeeplyNestedIfStmts violations can be unintentionally undetected From 2651b8da8c2b45ab00381f79ccc70eacf1aa28d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 19 Oct 2025 23:29:17 +0200 Subject: [PATCH 1463/1962] Update release notes, ref #6112 --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 82ffe725d17..b65d7ef325a 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -49,6 +49,7 @@ checkstyle version during the build. * [#5569](https://github.com/pmd/pmd/issues/5569): \[java] ExcessivePublicCount should report number of public "things" * java-documentation * [#6058](https://github.com/pmd/pmd/issues/6058): \[java] DanglingJavadoc FP in module-info files + * [#6103](https://github.com/pmd/pmd/issues/6103): \[java] DanglingJavadoc false positive on record compact constructors * java-errorprone * [#5878](https://github.com/pmd/pmd/issues/5878): \[java] DontUseFloatTypeForLoopIndices false-negative if variable is declared before loop * [#6075](https://github.com/pmd/pmd/issues/6075): \[java] AssignmentInOperand false positive with lambda expressions From 09c316c3a6f8a7af0983c7823b5b26aa6ce54017 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 19 Oct 2025 23:33:29 +0200 Subject: [PATCH 1464/1962] Update release notes, ref #6130 --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 88ccf173746..f874345532c 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -39,6 +39,7 @@ checkstyle version during the build. * java-codestyle * [#5919](https://github.com/pmd/pmd/issues/5919): \[java] ClassNamingConventions: Include integration tests in testClassPattern by default * [#6029](https://github.com/pmd/pmd/issues/6029): \[java] Fix UnnecessaryCast false-negative in method calls + * [#6123](https://github.com/pmd/pmd/issues/6123): \[java] UselessParentheses FP around switch expression * java-design * [#5569](https://github.com/pmd/pmd/issues/5569): \[java] ExcessivePublicCount should report number of public "things" * java-documentation From 450dfe6a230a910083056bf9ff8d2a8824d168bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 19 Oct 2025 23:43:30 +0200 Subject: [PATCH 1465/1962] Fix reviow comments on #6116 --- .../pmd/lang/java/rule/codestyle/ConfusingTernaryRule.java | 4 ++-- pmd-java/src/main/resources/category/java/codestyle.xml | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryRule.java index 6db4d9a8f1c..1a2b44b3ce0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryRule.java @@ -112,12 +112,12 @@ private boolean isNotEquals(ASTExpression node) { } ASTInfixExpression infix = (ASTInfixExpression) node; // look for "x != y" - if (infix.getOperator().equals(BinaryOp.NE)) { + if (infix.getOperator() == BinaryOp.NE) { return !isNullComparison(infix) || getProperty(NULL_CHECK_BRANCH) == NullCheckBranch.Then; } - return infix.getOperator().equals(BinaryOp.EQ) + return infix.getOperator() == BinaryOp.EQ && isNullComparison(infix) && getProperty(NULL_CHECK_BRANCH) == NullCheckBranch.Else; } diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml index cdb6ed2256d..79d99dab7d3 100644 --- a/pmd-java/src/main/resources/category/java/codestyle.xml +++ b/pmd-java/src/main/resources/category/java/codestyle.xml @@ -343,6 +343,10 @@ Avoid negation within an "if" expression with an "else" clause. For example, re Most "if (x != y)" cases without an "else" are often return cases, so consistent use of this rule makes the code easier to read. Also, this resolves trivial ordering problems, such as "does the error case go first?" or "does the common case go first?". + +Since null checks are commonly considered a positive condition, they are by default ignored +by this rule. This means both `a == null` and `a != null` are allowed. If you want +to enforce either style and disallow the other, use the property `nullCheckBranch`. 3 From 4245337383705bb5edd7b5e3fc67923ad950100b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 21 Oct 2025 20:09:29 +0200 Subject: [PATCH 1466/1962] [doc] Update release notes (#6004) --- docs/pages/release_notes.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 23b231b22f9..09b961a073a 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -29,6 +29,10 @@ From now on, Java 17 or newer is required to build PMD. PMD itself still remains so that it still can be used in a pure Java 8 environment. This allows us to use the latest checkstyle version during the build. +### ๐ŸŒŸ Changed Rules +* {%rule java/codestyle/ConfusingTernary %} has a new property `nullCheckBranch` to control, whether null-checks + should be allowed (the default case) or should lead to a violation. + ### ๐Ÿ› Fixed Issues * core * [#4714](https://github.com/pmd/pmd/issues/4714): \[core] Allow trailing commas in multivalued properties @@ -43,6 +47,7 @@ checkstyle version during the build. * [#6124](https://github.com/pmd/pmd/issues/6124): \[java] UnusedLocalVariable: fix false negatives in pattern matching * java-codestyle * [#5919](https://github.com/pmd/pmd/issues/5919): \[java] ClassNamingConventions: Include integration tests in testClassPattern by default + * [#6004](https://github.com/pmd/pmd/issues/6004): \[java] Make ConfusingTernary != null configurable * [#6029](https://github.com/pmd/pmd/issues/6029): \[java] Fix UnnecessaryCast false-negative in method calls * [#6057](https://github.com/pmd/pmd/issues/6057): \[java] ModifierOrder false positive on "abstract sealed class" * [#6079](https://github.com/pmd/pmd/issues/6079): \[java] IdenticalCatchBranches: False negative for overriden method calls From 8d558129601c9960376d68578981149ff079738a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 21 Oct 2025 20:14:03 +0200 Subject: [PATCH 1467/1962] [doc] Update release notes (merged prs) --- 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 09b961a073a..7569bb9b731 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -93,6 +93,14 @@ checkstyle version during the build. * [#6071](https://github.com/pmd/pmd/pull/6071): \[java] Fix #5919: Add integration tests to ClassNamingConventions testClassRegex - [Anton Bobov](https://github.com/abobov) (@abobov) * [#6074](https://github.com/pmd/pmd/pull/6074): \[apex] Fix @SuppressWarnings with whitespace around comma - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) * [#6078](https://github.com/pmd/pmd/pull/6078): \[java] Fix #6075: Fix FP in AssignmentInOperandRule - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6080](https://github.com/pmd/pmd/pull/6080): \[java] Fix #6079: IdenticalCatchBranches for overriden method calls - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6085](https://github.com/pmd/pmd/pull/6085): \[java] Fix false positive for ModifierOrder - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6100](https://github.com/pmd/pmd/pull/6100): \[java] AvoidDeeplyNestedIfStmts: fix false negative with if-else - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6112](https://github.com/pmd/pmd/pull/6112): \[java] DanglingJavadoc: fix false positive for compact constructors - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6114](https://github.com/pmd/pmd/pull/6114): \[java] Fix #4122: CheckResultSet false-positive with local variable - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#6116](https://github.com/pmd/pmd/pull/6116): \[java] ConfusingTernary: add configuration property for null checks - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6124](https://github.com/pmd/pmd/pull/6124): \[java] UnusedLocalVariable: fix false negatives in pattern matching - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6130](https://github.com/pmd/pmd/pull/6130): \[java] UselessParentheses: fix false positives for switch expressions - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) ### ๐Ÿ“ฆ Dependency updates From ae8838dfd99153aa4e0604aa39ef40b2379c3607 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Oct 2025 20:25:14 +0200 Subject: [PATCH 1468/1962] chore(deps): bump ruby/setup-ruby from 1.263.0 to 1.265.0 (#6136) Bumps [ruby/setup-ruby](https://github.com/ruby/setup-ruby) from 1.263.0 to 1.265.0. - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/0481980f17b760ef6bca5e8c55809102a0af1e5a...ab177d40ee5483edb974554986f56b33477e21d0) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-version: 1.265.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 4 ++-- .github/workflows/publish-release.yml | 2 +- .github/workflows/publish-snapshot.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 916deb098ad..bd67a004a71 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -278,7 +278,7 @@ jobs: -Pgenerate-rule-docs,fastSkip \ -DskipTests -Dassembly.skipAssembly=true - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@0481980f17b760ef6bca5e8c55809102a0af1e5a #v1.263.0 + uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 #v1.265.0 with: ruby-version: 3.3 - name: Setup bundler @@ -319,7 +319,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@0481980f17b760ef6bca5e8c55809102a0af1e5a #v1.263.0 + uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 #v1.265.0 with: ruby-version: 3.3 - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4.3.0 diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 76903618f73..50884b75fd9 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -632,7 +632,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@0481980f17b760ef6bca5e8c55809102a0af1e5a #v1.263.0 + uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 #v1.265.0 with: ruby-version: 3.3 - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4.3.0 diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 746cd9f08f6..eea282fa5cb 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -649,7 +649,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@0481980f17b760ef6bca5e8c55809102a0af1e5a #v1.263.0 + uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 #v1.265.0 with: ruby-version: 3.3 - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4.3.0 From 45f80d112985e1049f8aef3b73ea3bccc964e7eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Oct 2025 20:25:38 +0200 Subject: [PATCH 1469/1962] chore(deps): bump org.apache.maven.plugins:maven-enforcer-plugin from 3.6.1 to 3.6.2 (#6137) chore(deps): bump org.apache.maven.plugins:maven-enforcer-plugin Bumps [org.apache.maven.plugins:maven-enforcer-plugin](https://github.com/apache/maven-enforcer) from 3.6.1 to 3.6.2. - [Release notes](https://github.com/apache/maven-enforcer/releases) - [Commits](https://github.com/apache/maven-enforcer/compare/enforcer-3.6.1...enforcer-3.6.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-enforcer-plugin dependency-version: 3.6.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index be34cf71963..d57fdb40dfa 100644 --- a/pom.xml +++ b/pom.xml @@ -527,7 +527,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 3.6.1 + 3.6.2 org.apache.maven.plugins From 2a0ecbac41eaaea7873fa87943ce532a8334ea17 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Oct 2025 20:26:20 +0200 Subject: [PATCH 1470/1962] chore(deps): bump scalameta.version from 4.13.10 to 4.14.0 (#6138) Bumps `scalameta.version` from 4.13.10 to 4.14.0. Updates `org.scalameta:parsers_2.13` from 4.13.10 to 4.14.0 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.10...v4.14.0) Updates `org.scalameta:trees_2.13` from 4.13.10 to 4.14.0 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.10...v4.14.0) Updates `org.scalameta:parsers_2.12` from 4.13.10 to 4.14.0 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.10...v4.14.0) Updates `org.scalameta:trees_2.12` from 4.13.10 to 4.14.0 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.13.10...v4.14.0) --- updated-dependencies: - dependency-name: org.scalameta:parsers_2.13 dependency-version: 4.14.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.scalameta:trees_2.13 dependency-version: 4.14.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.scalameta:parsers_2.12 dependency-version: 4.14.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.scalameta:trees_2.12 dependency-version: 4.14.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index 325cbac4724..be351d79d70 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -13,7 +13,7 @@ - 4.13.10 + 4.14.0 From ea2f2c7630767e480fbef538add5a49b41c17230 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Oct 2025 20:26:48 +0200 Subject: [PATCH 1471/1962] chore(deps): bump com.puppycrawl.tools:checkstyle from 11.1.0 to 12.0.1 (#6139) Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 11.1.0 to 12.0.1. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-11.1.0...checkstyle-12.0.1) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-version: 12.0.1 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d57fdb40dfa..155d3c346d9 100644 --- a/pom.xml +++ b/pom.xml @@ -91,7 +91,7 @@ 5.0 3.5.4 - 11.1.0 + 12.0.1 3.6.0 3.27.0 1.10.15 From 76bcc7b1d9af25747de7268dc08ccdbce2254262 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Oct 2025 20:27:06 +0200 Subject: [PATCH 1472/1962] chore(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.6.0 to 3.6.1 (#6140) chore(deps): bump org.codehaus.mojo:exec-maven-plugin Bumps [org.codehaus.mojo:exec-maven-plugin](https://github.com/mojohaus/exec-maven-plugin) from 3.6.0 to 3.6.1. - [Release notes](https://github.com/mojohaus/exec-maven-plugin/releases) - [Commits](https://github.com/mojohaus/exec-maven-plugin/compare/3.6.0...3.6.1) --- updated-dependencies: - dependency-name: org.codehaus.mojo:exec-maven-plugin dependency-version: 3.6.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 155d3c346d9..bc718a547a3 100644 --- a/pom.xml +++ b/pom.xml @@ -383,7 +383,7 @@ org.codehaus.mojo exec-maven-plugin - 3.6.0 + 3.6.1 org.apache.maven.plugins From 7c811e242f0e09ba50262f0df6569affe1506211 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Oct 2025 20:27:22 +0200 Subject: [PATCH 1473/1962] chore(deps): bump org.ow2.asm:asm from 9.8 to 9.9 (#6141) Bumps org.ow2.asm:asm from 9.8 to 9.9. --- updated-dependencies: - dependency-name: org.ow2.asm:asm dependency-version: '9.9' dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bc718a547a3..5896db8e268 100644 --- a/pom.xml +++ b/pom.xml @@ -878,7 +878,7 @@ org.ow2.asm asm - 9.8 + 9.9 org.pcollections From 523f31678313e19aa8a287a83e14a8ec37d2de2c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Oct 2025 20:27:41 +0200 Subject: [PATCH 1474/1962] chore(deps): bump org.apache.commons:commons-lang3 from 3.18.0 to 3.19.0 (#6142) Bumps org.apache.commons:commons-lang3 from 3.18.0 to 3.19.0. --- updated-dependencies: - dependency-name: org.apache.commons:commons-lang3 dependency-version: 3.19.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5896db8e268..1b70aa60093 100644 --- a/pom.xml +++ b/pom.xml @@ -913,7 +913,7 @@ org.apache.commons commons-lang3 - 3.18.0 + 3.19.0 org.apache.commons From fc589a8e8bbf14fe917405b0a71b70cce52b0e88 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Oct 2025 20:28:05 +0200 Subject: [PATCH 1475/1962] chore(deps): bump bigdecimal from 3.3.0 to 3.3.1 in /docs (#6143) Bumps [bigdecimal](https://github.com/ruby/bigdecimal) from 3.3.0 to 3.3.1. - [Release notes](https://github.com/ruby/bigdecimal/releases) - [Changelog](https://github.com/ruby/bigdecimal/blob/master/CHANGES.md) - [Commits](https://github.com/ruby/bigdecimal/compare/v3.3.0...v3.3.1) --- updated-dependencies: - dependency-name: bigdecimal dependency-version: 3.3.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index 776b45f133e..07e739fe497 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -18,7 +18,7 @@ GEM public_suffix (>= 2.0.2, < 7.0) base64 (0.2.0) benchmark (0.4.1) - bigdecimal (3.3.0) + bigdecimal (3.3.1) coffee-script (2.4.1) coffee-script-source execjs From 24db12efa6447915f04e9394082ff0eeaf61c081 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Oct 2025 10:24:38 +0200 Subject: [PATCH 1476/1962] chore(deps-dev): bump com.google.guava:guava from 33.4.8-jre to 33.5.0-jre (#6157) chore(deps-dev): bump com.google.guava:guava Bumps [com.google.guava:guava](https://github.com/google/guava) from 33.4.8-jre to 33.5.0-jre. - [Release notes](https://github.com/google/guava/releases) - [Commits](https://github.com/google/guava/commits) --- updated-dependencies: - dependency-name: com.google.guava:guava dependency-version: 33.5.0-jre dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1b70aa60093..f3e89fad711 100644 --- a/pom.xml +++ b/pom.xml @@ -953,7 +953,7 @@ com.google.guava guava - 33.4.8-jre + 33.5.0-jre From 6778ff1613ff69a6c2c30f2e02853113f8985f16 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Oct 2025 10:25:08 +0200 Subject: [PATCH 1477/1962] chore(deps): bump scalameta.version from 4.14.0 to 4.14.1 (#6158) Bumps `scalameta.version` from 4.14.0 to 4.14.1. Updates `org.scalameta:parsers_2.13` from 4.14.0 to 4.14.1 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.14.0...v4.14.1) Updates `org.scalameta:trees_2.13` from 4.14.0 to 4.14.1 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.14.0...v4.14.1) Updates `org.scalameta:parsers_2.12` from 4.14.0 to 4.14.1 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.14.0...v4.14.1) Updates `org.scalameta:trees_2.12` from 4.14.0 to 4.14.1 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.14.0...v4.14.1) --- updated-dependencies: - dependency-name: org.scalameta:parsers_2.13 dependency-version: 4.14.1 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:trees_2.13 dependency-version: 4.14.1 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:parsers_2.12 dependency-version: 4.14.1 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:trees_2.12 dependency-version: 4.14.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index be351d79d70..bbaa3b3a538 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -13,7 +13,7 @@ - 4.14.0 + 4.14.1 From 80ada8513213afa37da3ec52c957b5d14f52cbcb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Oct 2025 10:25:44 +0200 Subject: [PATCH 1478/1962] chore(deps): bump org.apache.maven.plugins:maven-dependency-plugin from 3.8.1 to 3.9.0 (#6159) chore(deps): bump org.apache.maven.plugins:maven-dependency-plugin Bumps [org.apache.maven.plugins:maven-dependency-plugin](https://github.com/apache/maven-dependency-plugin) from 3.8.1 to 3.9.0. - [Release notes](https://github.com/apache/maven-dependency-plugin/releases) - [Commits](https://github.com/apache/maven-dependency-plugin/compare/maven-dependency-plugin-3.8.1...maven-dependency-plugin-3.9.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-dependency-plugin dependency-version: 3.9.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f3e89fad711..de7043cbef9 100644 --- a/pom.xml +++ b/pom.xml @@ -178,7 +178,7 @@ org.apache.maven.plugins maven-dependency-plugin - 3.8.1 + 3.9.0 org.apache.maven.plugins From d067dfe8212c6f40f06879ad360f6cf2ae1a6c9e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Oct 2025 10:26:11 +0200 Subject: [PATCH 1479/1962] chore(deps): bump com.github.siom79.japicmp:japicmp-maven-plugin from 0.24.1 to 0.24.2 (#6160) chore(deps): bump com.github.siom79.japicmp:japicmp-maven-plugin Bumps [com.github.siom79.japicmp:japicmp-maven-plugin](https://github.com/siom79/japicmp) from 0.24.1 to 0.24.2. - [Release notes](https://github.com/siom79/japicmp/releases) - [Changelog](https://github.com/siom79/japicmp/blob/master/release.py) - [Commits](https://github.com/siom79/japicmp/compare/japicmp-base-0.24.1...japicmp-base-0.24.2) --- updated-dependencies: - dependency-name: com.github.siom79.japicmp:japicmp-maven-plugin dependency-version: 0.24.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index de7043cbef9..c82c4e8ed74 100644 --- a/pom.xml +++ b/pom.xml @@ -690,7 +690,7 @@ com.github.siom79.japicmp japicmp-maven-plugin - 0.24.1 + 0.24.2 true From 6bab2ed7f2a4029309d0b11cd18b8ef59c36d624 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Oct 2025 10:26:59 +0200 Subject: [PATCH 1480/1962] chore(deps): bump org.apache.maven.plugins:maven-pmd-plugin from 3.27.0 to 3.28.0 (#6161) chore(deps): bump org.apache.maven.plugins:maven-pmd-plugin Bumps [org.apache.maven.plugins:maven-pmd-plugin](https://github.com/apache/maven-pmd-plugin) from 3.27.0 to 3.28.0. - [Release notes](https://github.com/apache/maven-pmd-plugin/releases) - [Commits](https://github.com/apache/maven-pmd-plugin/compare/maven-pmd-plugin-3.27.0...maven-pmd-plugin-3.28.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-pmd-plugin dependency-version: 3.28.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c82c4e8ed74..b9d1cbf2085 100644 --- a/pom.xml +++ b/pom.xml @@ -93,7 +93,7 @@ 3.5.4 12.0.1 3.6.0 - 3.27.0 + 3.28.0 1.10.15 3.12.0 4.9.3 From 6747046401d03f2b2be95930f90b8da95781d246 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Oct 2025 10:27:33 +0200 Subject: [PATCH 1481/1962] chore(deps): bump org.apache.maven.plugins:maven-antrun-plugin from 3.1.0 to 3.2.0 (#6162) chore(deps): bump org.apache.maven.plugins:maven-antrun-plugin Bumps [org.apache.maven.plugins:maven-antrun-plugin](https://github.com/apache/maven-antrun-plugin) from 3.1.0 to 3.2.0. - [Release notes](https://github.com/apache/maven-antrun-plugin/releases) - [Commits](https://github.com/apache/maven-antrun-plugin/compare/maven-antrun-plugin-3.1.0...maven-antrun-plugin-3.2.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-antrun-plugin dependency-version: 3.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b9d1cbf2085..dd7bb8b400d 100644 --- a/pom.xml +++ b/pom.xml @@ -150,7 +150,7 @@ org.apache.maven.plugins maven-antrun-plugin - 3.1.0 + 3.2.0 net.java.dev.javacc From 70a7be3ba9188bf75989790103d80ce7b4bd2020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Wed, 10 Sep 2025 16:59:52 +0200 Subject: [PATCH 1482/1962] Make AvoidCatchingGenericException configurable Add java.lang.Throwable and java.lang.Error to the default list --- .../main/resources/category/java/design.xml | 18 +++++++-- .../xml/AvoidCatchingGenericException.xml | 39 ++++++++++++++++++- 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/design.xml b/pmd-java/src/main/resources/category/java/design.xml index ee833f2f16e..ebca6aab8e2 100644 --- a/pmd-java/src/main/resources/category/java/design.xml +++ b/pmd-java/src/main/resources/category/java/design.xml @@ -58,13 +58,25 @@ Avoid catching generic exceptions such as NullPointerException, RuntimeException 3 + + + java.lang.NullPointerException, + java.lang.Exception, + java.lang.RuntimeException, + java.lang.Throwable, + java.lang.Error + + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidCatchingGenericException.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidCatchingGenericException.xml index db5d1ed7a06..594bda19ee6 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidCatchingGenericException.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidCatchingGenericException.xml @@ -6,7 +6,7 @@ failure case - 3 + 5 + + + catching another type - violation, if so configured + java.lang.IllegalStateException + 1 + + + + + no longer a failure, because of configuration + java.lang.IllegalStateException + 0 + + + catching subclass of NPE, ok 0 From cb4f161379bcc78d5688b0eaf651c5652cf702a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Wed, 10 Sep 2025 17:25:21 +0200 Subject: [PATCH 1483/1962] Include exception in violation message --- .../src/main/resources/category/java/design.xml | 2 +- .../xml/AvoidCatchingGenericException.xml | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/resources/category/java/design.xml b/pmd-java/src/main/resources/category/java/design.xml index ebca6aab8e2..59d6dd8cac7 100644 --- a/pmd-java/src/main/resources/category/java/design.xml +++ b/pmd-java/src/main/resources/category/java/design.xml @@ -50,7 +50,7 @@ public abstract class Example { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidCatchingGenericException.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidCatchingGenericException.xml index 594bda19ee6..e810dad6402 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidCatchingGenericException.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidCatchingGenericException.xml @@ -71,6 +71,23 @@ public class Foo { ]]> + + validate violation message + 1 + + Avoid catching generic exception NullPointerException in try-catch block + + + + catching subclass of NPE, ok 0 From 69dd92df05046b225f0d8403b42e84e6462e2ca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Wed, 10 Sep 2025 17:36:41 +0200 Subject: [PATCH 1484/1962] Deprecate AvoidCatchingNPE and AvoidCatchingThrowable --- .../src/main/resources/category/java/errorprone.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index f8eeefbec7d..fd22acd866c 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -229,12 +229,17 @@ void foo() { Code should never throw NullPointerExceptions under normal circumstances. A catch block may hide the original error, causing other, more subtle problems later on. + +**Deprecated:** This rule is deprecated since PMD 7.17.0 and will be removed with PMD 8.0.0. +This rule has been subsumed by {% rule AvoidCatchingGenericException %}, +which is now configurable as to which exceptions cause a violation. 3 @@ -263,12 +268,17 @@ public class Foo { Catching Throwable errors is not recommended since its scope is very broad. It includes runtime issues such as OutOfMemoryError that should be exposed and managed separately. + +**Deprecated:** This rule is deprecated since PMD 7.17.0 and will be removed with PMD 8.0.0. +This rule has been subsumed by {% rule AvoidCatchingGenericException %}, +which is now configurable as to which exceptions cause a violation. 3 From 51863dd9d41aeaa7c9faae99edb348542f830e12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Wed, 10 Sep 2025 18:02:16 +0200 Subject: [PATCH 1485/1962] update description ofAvoidCatchingGenericException --- .../main/resources/category/java/design.xml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/resources/category/java/design.xml b/pmd-java/src/main/resources/category/java/design.xml index 59d6dd8cac7..cf79d61836c 100644 --- a/pmd-java/src/main/resources/category/java/design.xml +++ b/pmd-java/src/main/resources/category/java/design.xml @@ -54,7 +54,24 @@ public abstract class Example { class="net.sourceforge.pmd.lang.rule.xpath.XPathRule" externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#avoidcatchinggenericexception"> -Avoid catching generic exceptions such as NullPointerException, RuntimeException, Exception in try-catch block. +Avoid catching generic exceptions in try-catch blocks. Catching overly broad exception types makes it difficult to understand what can actually go wrong in your code and can hide real problems. + +**Why these exceptions should not be caught:** + +* **Exception**: This is the base class for all checked exceptions. Catching it means you're handling all possible checked exceptions the same way, which is rarely appropriate and makes error handling less precise. + +* **RuntimeException**: These represent programming errors (like logic bugs) that should typically be fixed in code rather than caught and handled. Catching them can hide bugs that should be addressed during development. + +* **NullPointerException**: This usually indicates a programming error (accessing null references). Rather than catching it, code should be written to avoid null pointer dereferences through null checks or defensive programming. + +* **Throwable**: This is the superclass of all errors and exceptions. Catching it means you're trying to handle both recoverable exceptions and serious errors (like OutOfMemoryError) the same way, which is dangerous. + +* **Error**: These represent serious problems that applications should not try to handle (like OutOfMemoryError, StackOverflowError). Catching Error can prevent the JVM from properly terminating when it encounters unrecoverable situations. + +**Better approaches:** +- Catch specific exception types that you can meaningfully handle +- Use multiple catch blocks for different exception types that require different handling +- Consider using defensive programming techniques to prevent exceptions rather than catching them 3 From 117230c527ffcf373fa6f395610db6bf1be3e542 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Wed, 10 Sep 2025 18:14:53 +0200 Subject: [PATCH 1486/1962] Remove deprecated rules from quickstart.xml activate AvoidCatchingGenericException in quickstart.xml, but configure it so that it is roughly equivalent to the old config. --- pmd-java/src/main/resources/rulesets/java/quickstart.xml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pmd-java/src/main/resources/rulesets/java/quickstart.xml b/pmd-java/src/main/resources/rulesets/java/quickstart.xml index 18d886fbea9..ce18b39d3d4 100644 --- a/pmd-java/src/main/resources/rulesets/java/quickstart.xml +++ b/pmd-java/src/main/resources/rulesets/java/quickstart.xml @@ -125,7 +125,11 @@ - + + + + + @@ -195,8 +199,6 @@ - - From d548af00279fde7aa9569c821ef7631fc74093c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Wed, 10 Sep 2025 18:23:18 +0200 Subject: [PATCH 1487/1962] Don't use shortened language for parameters --- pmd-java/src/main/resources/category/java/design.xml | 4 ++-- pmd-java/src/main/resources/rulesets/java/quickstart.xml | 2 +- .../java/rule/design/xml/AvoidCatchingGenericException.xml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/design.xml b/pmd-java/src/main/resources/category/java/design.xml index cf79d61836c..42f95865c4e 100644 --- a/pmd-java/src/main/resources/category/java/design.xml +++ b/pmd-java/src/main/resources/category/java/design.xml @@ -76,7 +76,7 @@ Avoid catching generic exceptions in try-catch blocks. Catching overly broad exc 3 @@ -92,7 +92,7 @@ Avoid catching generic exceptions in try-catch blocks. Catching overly broad exc diff --git a/pmd-java/src/main/resources/rulesets/java/quickstart.xml b/pmd-java/src/main/resources/rulesets/java/quickstart.xml index ce18b39d3d4..33f92ee2fa0 100644 --- a/pmd-java/src/main/resources/rulesets/java/quickstart.xml +++ b/pmd-java/src/main/resources/rulesets/java/quickstart.xml @@ -127,7 +127,7 @@ - + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidCatchingGenericException.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidCatchingGenericException.xml index e810dad6402..5b0d9c45c79 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidCatchingGenericException.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidCatchingGenericException.xml @@ -39,7 +39,7 @@ class FooException extends RuntimeException {} catching another type - violation, if so configured - java.lang.IllegalStateException + java.lang.IllegalStateException 1 no longer a failure, because of configuration - java.lang.IllegalStateException + java.lang.IllegalStateException 0 Date: Wed, 10 Sep 2025 19:10:27 +0200 Subject: [PATCH 1488/1962] Change message again Technically speaking, Error and Throwable aren't Exceptions, so we shouldn't refer to them as such. --- pmd-java/src/main/resources/category/java/design.xml | 2 +- .../lang/java/rule/design/xml/AvoidCatchingGenericException.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/design.xml b/pmd-java/src/main/resources/category/java/design.xml index 42f95865c4e..99be22ac6c4 100644 --- a/pmd-java/src/main/resources/category/java/design.xml +++ b/pmd-java/src/main/resources/category/java/design.xml @@ -50,7 +50,7 @@ public abstract class Example { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidCatchingGenericException.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidCatchingGenericException.xml index 5b0d9c45c79..13ddc20288d 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidCatchingGenericException.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/AvoidCatchingGenericException.xml @@ -75,7 +75,7 @@ public class Foo { validate violation message 1 - Avoid catching generic exception NullPointerException in try-catch block + Avoid catching NullPointerException in try-catch block Date: Tue, 16 Sep 2025 22:14:16 +0200 Subject: [PATCH 1489/1962] Update deprecation version --- pmd-java/src/main/resources/category/java/errorprone.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index fd22acd866c..424bb5a4140 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -237,7 +237,7 @@ void foo() { Code should never throw NullPointerExceptions under normal circumstances. A catch block may hide the original error, causing other, more subtle problems later on. -**Deprecated:** This rule is deprecated since PMD 7.17.0 and will be removed with PMD 8.0.0. +**Deprecated:** This rule is deprecated since PMD 7.18.0 and will be removed with PMD 8.0.0. This rule has been subsumed by {% rule AvoidCatchingGenericException %}, which is now configurable as to which exceptions cause a violation. @@ -276,7 +276,7 @@ public class Foo { Catching Throwable errors is not recommended since its scope is very broad. It includes runtime issues such as OutOfMemoryError that should be exposed and managed separately. -**Deprecated:** This rule is deprecated since PMD 7.17.0 and will be removed with PMD 8.0.0. +**Deprecated:** This rule is deprecated since PMD 7.18.0 and will be removed with PMD 8.0.0. This rule has been subsumed by {% rule AvoidCatchingGenericException %}, which is now configurable as to which exceptions cause a violation. From 251c4c793f109577f855e176a3c860ddcfdde37d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 23 Oct 2025 12:14:22 +0200 Subject: [PATCH 1490/1962] [java] Move AvoidCatchingGenericException to category errorprone --- .../main/resources/category/java/design.xml | 73 +----------------- .../resources/category/java/errorprone.xml | 76 +++++++++++++++++++ .../resources/rulesets/java/quickstart.xml | 15 ++-- .../pmd/lang/java/RuleSetFactoryTest.java | 24 ++++++ .../AvoidCatchingGenericExceptionTest.java | 2 +- .../xml/AvoidCatchingGenericException.xml | 0 .../lang/rule/AbstractRuleSetFactoryTest.java | 22 +++++- 7 files changed, 132 insertions(+), 80 deletions(-) rename pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/{design => errorprone}/AvoidCatchingGenericExceptionTest.java (80%) rename pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/{design => errorprone}/xml/AvoidCatchingGenericException.xml (100%) diff --git a/pmd-java/src/main/resources/category/java/design.xml b/pmd-java/src/main/resources/category/java/design.xml index 99be22ac6c4..20aade890cf 100644 --- a/pmd-java/src/main/resources/category/java/design.xml +++ b/pmd-java/src/main/resources/category/java/design.xml @@ -47,78 +47,7 @@ public abstract class Example { - - -Avoid catching generic exceptions in try-catch blocks. Catching overly broad exception types makes it difficult to understand what can actually go wrong in your code and can hide real problems. - -**Why these exceptions should not be caught:** - -* **Exception**: This is the base class for all checked exceptions. Catching it means you're handling all possible checked exceptions the same way, which is rarely appropriate and makes error handling less precise. - -* **RuntimeException**: These represent programming errors (like logic bugs) that should typically be fixed in code rather than caught and handled. Catching them can hide bugs that should be addressed during development. - -* **NullPointerException**: This usually indicates a programming error (accessing null references). Rather than catching it, code should be written to avoid null pointer dereferences through null checks or defensive programming. - -* **Throwable**: This is the superclass of all errors and exceptions. Catching it means you're trying to handle both recoverable exceptions and serious errors (like OutOfMemoryError) the same way, which is dangerous. - -* **Error**: These represent serious problems that applications should not try to handle (like OutOfMemoryError, StackOverflowError). Catching Error can prevent the JVM from properly terminating when it encounters unrecoverable situations. - -**Better approaches:** -- Catch specific exception types that you can meaningfully handle -- Use multiple catch blocks for different exception types that require different handling -- Consider using defensive programming techniques to prevent exceptions rather than catching them - - 3 - - - - java.lang.NullPointerException, - java.lang.Exception, - java.lang.RuntimeException, - java.lang.Throwable, - java.lang.Error - - - - - - - - - - - - + + + +Avoid catching generic exceptions in try-catch blocks. Catching overly broad exception types makes it difficult +to understand what can actually go wrong in your code and can hide real problems. + +**Why these exceptions should not be caught:** + +* **Exception**: This is the base class for all checked exceptions. Catching it means you're handling all possible + checked exceptions the same way, which is rarely appropriate and makes error handling less precise. + +* **RuntimeException**: These represent programming errors (like logic bugs) that should typically be fixed in + code rather than caught and handled. Catching them can hide bugs that should be addressed during development. + +* **NullPointerException**: This usually indicates a programming error (accessing null references). Rather than + catching it, code should be written to avoid null pointer dereferences through null checks or defensive programming. + +* **Throwable**: This is the superclass of all errors and exceptions. Catching it means you're trying to handle + both recoverable exceptions and serious errors (like OutOfMemoryError) the same way, which is dangerous. + +* **Error**: These represent serious problems that applications should not try to handle (like OutOfMemoryError, + StackOverflowError). Catching Error can prevent the JVM from properly terminating when it encounters unrecoverable situations. + +**Better approaches:** +- Catch specific exception types that you can meaningfully handle +- Use multiple catch blocks for different exception types that require different handling +- Consider using defensive programming techniques to prevent exceptions rather than catching them + + 3 + + + + java.lang.NullPointerException, + java.lang.Exception, + java.lang.RuntimeException, + java.lang.Throwable, + java.lang.Error + + + + + + + + + + + + + - - - - - @@ -199,6 +194,16 @@ + + + + + + diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/RuleSetFactoryTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/RuleSetFactoryTest.java index 210ad6f3e42..377bdc74854 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/RuleSetFactoryTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/RuleSetFactoryTest.java @@ -4,11 +4,35 @@ package net.sourceforge.pmd.lang.java; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + import net.sourceforge.pmd.test.lang.rule.AbstractRuleSetFactoryTest; /** * Test java's rulesets */ class RuleSetFactoryTest extends AbstractRuleSetFactoryTest { + RuleSetFactoryTest() { + super(getExpectedMessages()); + } + + private static Map> getExpectedMessages() { + Map> messages = new HashMap<>(); + Set designMessages = new HashSet<>(); + // AvoidCatchingGenericException has been moved from Design to Error Prone with PMD 7.18.0 + designMessages.add("Warning at category/java/design.xml:50:5\n" + + " 48| \n" + + " 49| \n" + + " 50| \n" + + " ^^^^^ Use Rule name category/java/errorprone.xml/AvoidCatchingGenericException instead of the deprecated Rule name category/java/design.xml/AvoidCatchingGenericException. PMD 8.0.0 will remove support for this deprecated Rule name usage.\n" + + "\n" + + " 51| \n" + + " 52| validXPathClassNames = new HashSet<>(); private final Set languagesToSkip = new HashSet<>(); + private final Map> expectedMessagesPerRuleset = new HashMap<>(); public AbstractRuleSetFactoryTest() { this(new String[0]); } + public AbstractRuleSetFactoryTest(Map> expectedMessagesPerRuleset) { + this(); + this.expectedMessagesPerRuleset.putAll(expectedMessagesPerRuleset); + } + /** * Constructor used when a module that depends on another module wants to filter out the dependee's rulesets. * @@ -368,8 +375,19 @@ protected void logImpl(Level level, String message) { RuleSet ruleSet = InternalApiBridge.withReporter(new RuleSetLoader(), new Reporter()) .loadFromResource(ruleSetFileName); - assertThat("There should be no warnings while loading the ruleset", - messages.toString(), emptyString()); + String allMessages = messages.toString(); + + if (expectedMessagesPerRuleset.containsKey(ruleSetFileName)) { + for (String expectedMessage : expectedMessagesPerRuleset.get(ruleSetFileName)) { + assertThat(allMessages, containsString(expectedMessage)); + allMessages = allMessages.replace(expectedMessage, ""); + } + assertThat("There should be no other warnings while loading the ruleset, but found: " + allMessages, + allMessages, emptyString()); + } else { + assertThat("There should be no warnings while loading the ruleset, but found: " + allMessages, + allMessages, emptyString()); + } return ruleSet; } From 3f952d064359a1012f7dcac08af4c7c8f5eb2c51 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 23 Oct 2025 16:04:39 +0200 Subject: [PATCH 1491/1962] [doc] Update release notes (#6051, #6038) --- docs/pages/release_notes.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 7569bb9b731..35f63ea2b23 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -29,9 +29,25 @@ From now on, Java 17 or newer is required to build PMD. PMD itself still remains so that it still can be used in a pure Java 8 environment. This allows us to use the latest checkstyle version during the build. -### ๐ŸŒŸ Changed Rules +### ๐ŸŒŸ Rules changes + +#### Modified rules * {%rule java/codestyle/ConfusingTernary %} has a new property `nullCheckBranch` to control, whether null-checks should be allowed (the default case) or should lead to a violation. +* {%rule java/errorprone/AvoidCatchingGenericException %} is now configurable with the new property + `typesThatShouldNotBeCaught`. + โš ๏ธ The rule has also been moved from category "Design" to category "Error Prone". If you are currently bulk-adding + all the rules from the "Design" category into your custom ruleset, then you need to add the rule explicitly + again (otherwise it won't be included anymore): + ```xml + + ``` + +#### Deprecated rules +* The Java rule {% rule java/errorprone/AvoidCatchingNPE %} has been deprecated in favor of the updated rule + {% rule java/errorprone/AvoidCatchingGenericException %}, which is now configurable. +* The Java rule {% rule java/errorprone/AvoidCatchingThrowable %} has been deprecated in favor of the updated rule + {% rule java/errorprone/AvoidCatchingGenericException %}, which is now configurable. ### ๐Ÿ› Fixed Issues * core @@ -60,6 +76,7 @@ checkstyle version during the build. * [#6103](https://github.com/pmd/pmd/issues/6103): \[java] DanglingJavadoc false positive on record compact constructors * java-errorprone * [#5878](https://github.com/pmd/pmd/issues/5878): \[java] DontUseFloatTypeForLoopIndices false-negative if variable is declared before loop + * [#6038](https://github.com/pmd/pmd/issues/6038): \[java] Merge AvoidCatchingNPE and AvoidCatchingThrowable into AvoidCatchingGenericException * [#6075](https://github.com/pmd/pmd/issues/6075): \[java] AssignmentInOperand false positive with lambda expressions * java-multithreading * [#5880](https://github.com/pmd/pmd/issues/5880): \[java] DoubleCheckedLocking is not detected if more than 1 assignment or more than 2 if statements @@ -87,6 +104,7 @@ checkstyle version during the build. * [#6039](https://github.com/pmd/pmd/pull/6039): \[core] Fix #4714: trim token before feeding it to the extractor - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6040](https://github.com/pmd/pmd/pull/6040): \[java,apex,plsql,velocity] Change description of "minimum" parameter - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6043](https://github.com/pmd/pmd/pull/6043): \[java] Reactivate deactivated test in LocalVariableCouldBeFinal - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6051](https://github.com/pmd/pmd/pull/6051): \[java] Fix #6038: Make AvoidCatchingGenericException configurable - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6056](https://github.com/pmd/pmd/pull/6056): chore: fix dogfood issues from new rules - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6059](https://github.com/pmd/pmd/pull/6059): \[java] Fix #6058: DanglingJavadoc FP in module-info files - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6061](https://github.com/pmd/pmd/pull/6061): \[core] chore: Bump minimum Java version required for building to 17 - [Andreas Dangel](https://github.com/adangel) (@adangel) From 9995420d25835a8f755b02db8f3c7a806bfd7ffc Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 23 Oct 2025 16:53:00 +0200 Subject: [PATCH 1492/1962] Normalize line-endings --- .../pmd/test/lang/rule/AbstractRuleSetFactoryTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java b/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java index 8d0b21d9de7..b6324568dc6 100644 --- a/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java +++ b/pmd-test/src/main/java/net/sourceforge/pmd/test/lang/rule/AbstractRuleSetFactoryTest.java @@ -375,7 +375,8 @@ protected void logImpl(Level level, String message) { RuleSet ruleSet = InternalApiBridge.withReporter(new RuleSetLoader(), new Reporter()) .loadFromResource(ruleSetFileName); - String allMessages = messages.toString(); + // normalize all line-endings to \n - in case we run under Windows... + String allMessages = messages.toString().replaceAll("\\R", "\n"); if (expectedMessagesPerRuleset.containsKey(ruleSetFileName)) { for (String expectedMessage : expectedMessagesPerRuleset.get(ruleSetFileName)) { From 5ecf5579d3b98e802a892aa84af3e0d0059ac641 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Sun, 21 Sep 2025 11:44:43 +0200 Subject: [PATCH 1493/1962] [java] Fix false positives in UselessPureMethodCall for streams and atomics --- .../lang/java/rule/internal/JavaRuleUtil.java | 17 ++++++--- .../errorprone/xml/UselessPureMethodCall.xml | 38 +++++++++++++++++++ 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/JavaRuleUtil.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/JavaRuleUtil.java index 8886585a745..dc0773d78b8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/JavaRuleUtil.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/JavaRuleUtil.java @@ -44,7 +44,7 @@ import net.sourceforge.pmd.lang.java.symbols.JVariableSymbol; import net.sourceforge.pmd.lang.java.types.InvocationMatcher; import net.sourceforge.pmd.lang.java.types.InvocationMatcher.CompoundInvocationMatcher; -import net.sourceforge.pmd.lang.java.types.JTypeMirror; +import net.sourceforge.pmd.lang.java.types.JMethodSig; import net.sourceforge.pmd.lang.java.types.TypeTestUtil; /** @@ -74,6 +74,12 @@ public final class JavaRuleUtil { "java.time.Period#_(_*)" ); + private static final Set KNOWN_SIDE_EFFECT_METHODS = immutableSetOf( + "getAndIncrement", + "getAndDecrement", + "getNextEntry" + ); + public static final Set LOMBOK_ANNOTATIONS = immutableSetOf( "lombok.Data", "lombok.Getter", @@ -404,18 +410,19 @@ private static boolean isPure(ASTMethodCall call) { */ public static boolean isKnownPure(ASTMethodCall call) { return isGetterCall(call) - && hasPureGetters(call.getMethodType().getDeclaringType()) + && isPureGetter(call.getMethodType()) || KNOWN_PURE_METHODS.anyMatch(call) && !call.getMethodType().getReturnType().isVoid(); } - private static boolean hasPureGetters(JTypeMirror type) { - JTypeDeclSymbol symbol = type.getSymbol(); + private static boolean isPureGetter(JMethodSig signature) { + JTypeDeclSymbol symbol = signature.getDeclaringType().getSymbol(); if (symbol == null) { return false; } String pkg = symbol.getPackageName(); return pkg.startsWith("java.") - && !pkg.startsWith("java.nio") && !pkg.startsWith("java.net"); + && !pkg.startsWith("java.nio") && !pkg.startsWith("java.net") + && !KNOWN_SIDE_EFFECT_METHODS.contains(signature.getName()); } public static @Nullable ASTVariableId getReferencedNode(ASTNamedReferenceExpr expr) { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessPureMethodCall.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessPureMethodCall.xml index c4b76988df3..2d31dfea9b2 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessPureMethodCall.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessPureMethodCall.xml @@ -417,4 +417,42 @@ class Tester { } ]]> + + + Atomic increments + 0 + + + + + Stream methods with side-effects + 0 + + From 0a9935dba54a3f3b4f96a5ac22df451073ca31d5 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Sat, 18 Oct 2025 13:00:39 +0200 Subject: [PATCH 1494/1962] Use InvocationMatcher for checking --- .../lang/java/rule/internal/JavaRuleUtil.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/JavaRuleUtil.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/JavaRuleUtil.java index dc0773d78b8..0d0404ca694 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/JavaRuleUtil.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/JavaRuleUtil.java @@ -44,7 +44,6 @@ import net.sourceforge.pmd.lang.java.symbols.JVariableSymbol; import net.sourceforge.pmd.lang.java.types.InvocationMatcher; import net.sourceforge.pmd.lang.java.types.InvocationMatcher.CompoundInvocationMatcher; -import net.sourceforge.pmd.lang.java.types.JMethodSig; import net.sourceforge.pmd.lang.java.types.TypeTestUtil; /** @@ -74,11 +73,12 @@ public final class JavaRuleUtil { "java.time.Period#_(_*)" ); - private static final Set KNOWN_SIDE_EFFECT_METHODS = immutableSetOf( - "getAndIncrement", - "getAndDecrement", - "getNextEntry" - ); + private static final CompoundInvocationMatcher KNOWN_SIDE_EFFECT_METHODS = + InvocationMatcher.parseAll( + "_#getAndIncrement()", + "_#getAndDecrement()", + "_#getNextEntry()" + ); public static final Set LOMBOK_ANNOTATIONS = immutableSetOf( "lombok.Data", @@ -410,19 +410,19 @@ private static boolean isPure(ASTMethodCall call) { */ public static boolean isKnownPure(ASTMethodCall call) { return isGetterCall(call) - && isPureGetter(call.getMethodType()) + && isPureGetter(call) || KNOWN_PURE_METHODS.anyMatch(call) && !call.getMethodType().getReturnType().isVoid(); } - private static boolean isPureGetter(JMethodSig signature) { - JTypeDeclSymbol symbol = signature.getDeclaringType().getSymbol(); + private static boolean isPureGetter(ASTMethodCall call) { + JTypeDeclSymbol symbol = call.getMethodType().getDeclaringType().getSymbol(); if (symbol == null) { return false; } String pkg = symbol.getPackageName(); return pkg.startsWith("java.") && !pkg.startsWith("java.nio") && !pkg.startsWith("java.net") - && !KNOWN_SIDE_EFFECT_METHODS.contains(signature.getName()); + && !KNOWN_SIDE_EFFECT_METHODS.anyMatch(call); } public static @Nullable ASTVariableId getReferencedNode(ASTNamedReferenceExpr expr) { From b9e0d1989908334b8643efdbc50971913e0af294 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 24 Oct 2025 10:22:17 +0200 Subject: [PATCH 1495/1962] Ignore UnnecessaryWarningSuppression --- pmd-core/pmd-core-exclude-pmd.properties | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pmd-core/pmd-core-exclude-pmd.properties b/pmd-core/pmd-core-exclude-pmd.properties index 6e636acc2fe..790678997f9 100644 --- a/pmd-core/pmd-core-exclude-pmd.properties +++ b/pmd-core/pmd-core-exclude-pmd.properties @@ -1,2 +1,5 @@ # ignore missing override for isEmpty() method, see #4291 #5299 net.sourceforge.pmd.lang.document.Chars=MissingOverride +# FP fixed by #6082 - with PMD 7.18.0 the suppression is not needed anymore +net.sourceforge.pmd.benchmark.TimedResult=UnnecessaryWarningSuppression +net.sourceforge.pmd.benchmark.TimeTracker.TimedResult=UnnecessaryWarningSuppression From 315e497d268c58ca553750d302cf7e1cedaa0683 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 24 Oct 2025 10:55:09 +0200 Subject: [PATCH 1496/1962] [java] UselessPureMethodCall - test descriptions --- .../lang/java/rule/errorprone/xml/UselessPureMethodCall.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessPureMethodCall.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessPureMethodCall.xml index 2d31dfea9b2..1acb034b7dc 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessPureMethodCall.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessPureMethodCall.xml @@ -419,7 +419,7 @@ class Tester { - Atomic increments + #6055 Atomic increments 0 - Stream methods with side-effects + #6060 Stream methods with side-effects 0 Date: Fri, 24 Oct 2025 10:55:34 +0200 Subject: [PATCH 1497/1962] [doc] Update release notes (#6082, #6055, #6060) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 35f63ea2b23..42c85f19faa 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -77,6 +77,8 @@ checkstyle version during the build. * java-errorprone * [#5878](https://github.com/pmd/pmd/issues/5878): \[java] DontUseFloatTypeForLoopIndices false-negative if variable is declared before loop * [#6038](https://github.com/pmd/pmd/issues/6038): \[java] Merge AvoidCatchingNPE and AvoidCatchingThrowable into AvoidCatchingGenericException + * [#6055](https://github.com/pmd/pmd/issues/6055): \[java] UselessPureMethodCall false positive with AtomicInteger::getAndIncrement + * [#6060](https://github.com/pmd/pmd/issues/6060): \[java] UselessPureMethodCall false positive on ZipInputStream::getNextEntry * [#6075](https://github.com/pmd/pmd/issues/6075): \[java] AssignmentInOperand false positive with lambda expressions * java-multithreading * [#5880](https://github.com/pmd/pmd/issues/5880): \[java] DoubleCheckedLocking is not detected if more than 1 assignment or more than 2 if statements @@ -112,6 +114,7 @@ checkstyle version during the build. * [#6074](https://github.com/pmd/pmd/pull/6074): \[apex] Fix @SuppressWarnings with whitespace around comma - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) * [#6078](https://github.com/pmd/pmd/pull/6078): \[java] Fix #6075: Fix FP in AssignmentInOperandRule - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6080](https://github.com/pmd/pmd/pull/6080): \[java] Fix #6079: IdenticalCatchBranches for overriden method calls - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6082](https://github.com/pmd/pmd/pull/6082): \[java] Fix false positives in UselessPureMethodCall for streams and atomics - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6085](https://github.com/pmd/pmd/pull/6085): \[java] Fix false positive for ModifierOrder - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6100](https://github.com/pmd/pmd/pull/6100): \[java] AvoidDeeplyNestedIfStmts: fix false negative with if-else - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6112](https://github.com/pmd/pmd/pull/6112): \[java] DanglingJavadoc: fix false positive for compact constructors - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) From 1bd602507225e2b49d3a0070b2adebadc3da8a2d Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Sun, 21 Sep 2025 11:40:46 +0200 Subject: [PATCH 1498/1962] [java] new rule for useless conditions --- .../rule/errorprone/UselessConditionRule.java | 35 +++++++++++++++++++ .../resources/category/java/errorprone.xml | 30 ++++++++++++++++ .../rule/errorprone/UselessConditionTest.java | 14 ++++++++ .../rule/errorprone/xml/UselessCondition.xml | 33 +++++++++++++++++ 4 files changed, 112 insertions(+) create mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessConditionRule.java create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessConditionTest.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessCondition.xml diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessConditionRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessConditionRule.java new file mode 100644 index 00000000000..c6842d456a1 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessConditionRule.java @@ -0,0 +1,35 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.errorprone; + +import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression; +import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; +import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; +import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; + +public class UselessConditionRule extends AbstractJavaRulechainRule { + + public UselessConditionRule() { + super(ASTIfStatement.class, ASTConditionalExpression.class); + } + + @Override + public Object visit(ASTIfStatement node, Object data) { + if (node.getElseBranch() != null + && JavaAstUtils.tokenEquals(node.getThenBranch(), node.getElseBranch())) { + asCtx(data).addViolation(node); + } + return data; + } + + @Override + public Object visit(ASTConditionalExpression node, Object data) { + if (node.getElseBranch() != null + && JavaAstUtils.tokenEquals(node.getThenBranch(), node.getElseBranch())) { + asCtx(data).addViolation(node); + } + return data; + } +} diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 35dad871c5c..7690ff46b73 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -3466,6 +3466,36 @@ public boolean test(String s) { + + + Conditional statement that does the same thing when the condition is true and false + is either incorrect (one of the branches should be changed) or redundant + (can be replaced by one of its branches). + + 3 + + 0.5) { + return 1; + } else { + return 1; + } + } + int method2() { + return Math.random() > 0.5 ? 1 : 1; + } +} +]]> + + + + + + + Useless if + 1 + 0.5) { + return 1; + } else { + return 1; + } + } + } + ]]> + + + Useless conditional expression + 1 + + + From a2b948763e1b093bfaab39280e413bac1d74b116 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Mon, 20 Oct 2025 08:55:20 +0200 Subject: [PATCH 1499/1962] Rename rule, normalize nodes, add tests --- .../IdenticalConditionalBranchesRule.java | 59 ++++++++++++++ .../rule/errorprone/UselessConditionRule.java | 35 --------- .../resources/category/java/errorprone.xml | 60 +++++++-------- ... => IdenticalConditionalBranchesTest.java} | 4 +- .../xml/IdenticalConditionalBranches.xml | 76 +++++++++++++++++++ .../rule/errorprone/xml/UselessCondition.xml | 33 -------- 6 files changed, 167 insertions(+), 100 deletions(-) create mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/IdenticalConditionalBranchesRule.java delete mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessConditionRule.java rename pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/{UselessConditionTest.java => IdenticalConditionalBranchesTest.java} (66%) create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/IdenticalConditionalBranches.xml delete mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessCondition.xml diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/IdenticalConditionalBranchesRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/IdenticalConditionalBranchesRule.java new file mode 100644 index 00000000000..070fd295a3e --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/IdenticalConditionalBranchesRule.java @@ -0,0 +1,59 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.errorprone; + +import net.sourceforge.pmd.lang.java.ast.ASTBlock; +import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression; +import net.sourceforge.pmd.lang.java.ast.ASTEmptyStatement; +import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; +import net.sourceforge.pmd.lang.java.ast.JavaNode; +import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; +import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; + +/** + * Detects conditional expressions and statements where both branches are equal. + * @since 7.18 + */ +public class IdenticalConditionalBranchesRule extends AbstractJavaRulechainRule { + + public IdenticalConditionalBranchesRule() { + super(ASTIfStatement.class, ASTConditionalExpression.class); + } + + @Override + public Object visit(ASTIfStatement node, Object data) { + if (node.getElseBranch() != null + && areEquivalent(normalize(node.getThenBranch()), + normalize(node.getElseBranch()))) { + asCtx(data).addViolation(node); + } + return data; + } + + private boolean areEquivalent(JavaNode thenBranch, JavaNode elseBranch) { + JavaNode normalizedThen = normalize(thenBranch); + JavaNode normalizedElse = normalize(elseBranch); + return normalizedElse == null && normalizedThen == null + || (normalizedElse != null && normalizedThen != null + && JavaAstUtils.tokenEquals(normalizedElse, normalizedThen)); + } + + private JavaNode normalize(JavaNode firstBranch) { + JavaNode first = firstBranch; + while (first instanceof ASTBlock && ((ASTBlock) first).size() <= 1) { + first = first.getFirstChild(); + } + return first instanceof ASTEmptyStatement ? null : first; + } + + @Override + public Object visit(ASTConditionalExpression node, Object data) { + if (node.getElseBranch() != null + && JavaAstUtils.tokenEquals(node.getThenBranch(), node.getElseBranch())) { + asCtx(data).addViolation(node); + } + return data; + } +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessConditionRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessConditionRule.java deleted file mode 100644 index c6842d456a1..00000000000 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/UselessConditionRule.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.rule.errorprone; - -import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression; -import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; -import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; -import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; - -public class UselessConditionRule extends AbstractJavaRulechainRule { - - public UselessConditionRule() { - super(ASTIfStatement.class, ASTConditionalExpression.class); - } - - @Override - public Object visit(ASTIfStatement node, Object data) { - if (node.getElseBranch() != null - && JavaAstUtils.tokenEquals(node.getThenBranch(), node.getElseBranch())) { - asCtx(data).addViolation(node); - } - return data; - } - - @Override - public Object visit(ASTConditionalExpression node, Object data) { - if (node.getElseBranch() != null - && JavaAstUtils.tokenEquals(node.getThenBranch(), node.getElseBranch())) { - asCtx(data).addViolation(node); - } - return data; - } -} diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 7690ff46b73..f9f35b884e9 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -1882,6 +1882,36 @@ public class Foo { + + + Conditional statement that does the same thing when the condition is true and false + is either incorrect (one of the branches should be changed) or redundant + (can be replaced by one of its branches). + + 3 + + 0.5) { + return 1; + } else { + return 1; + } + } + int method2() { + return Math.random() > 0.5 ? 1 : 1; + } +} +]]> + + + - - - Conditional statement that does the same thing when the condition is true and false - is either incorrect (one of the branches should be changed) or redundant - (can be replaced by one of its branches). - - 3 - - 0.5) { - return 1; - } else { - return 1; - } - } - int method2() { - return Math.random() > 0.5 ? 1 : 1; - } -} -]]> - - - + + + + Useless if + 1 + 0.5) { + return 1; + } else { + return 1; + } + } + } + ]]> + + + Useless conditional expression + 1 + + + + Useless if with empty statements + 4 + + + + + Useless if with wrapped statements + 2 + + + + + Useless if with comments + 4 + + + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessCondition.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessCondition.xml deleted file mode 100644 index ab3223ad688..00000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UselessCondition.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - Useless if - 1 - 0.5) { - return 1; - } else { - return 1; - } - } - } - ]]> - - - Useless conditional expression - 1 - - - From 986937371783304847666037d84b00ce8745ce54 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 24 Oct 2025 11:39:48 +0200 Subject: [PATCH 1500/1962] Apply suggestions from code review --- .../java/rule/errorprone/IdenticalConditionalBranchesRule.java | 2 +- pmd-java/src/main/resources/category/java/errorprone.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/IdenticalConditionalBranchesRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/IdenticalConditionalBranchesRule.java index 070fd295a3e..44d0ce0ccf9 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/IdenticalConditionalBranchesRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/IdenticalConditionalBranchesRule.java @@ -14,7 +14,7 @@ /** * Detects conditional expressions and statements where both branches are equal. - * @since 7.18 + * @since 7.18.0 */ public class IdenticalConditionalBranchesRule extends AbstractJavaRulechainRule { diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index f9f35b884e9..41c5a667b9a 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -1884,7 +1884,7 @@ public class Foo { From 1c95557500751dec6749b4523f5e4d3c1d1766ce Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 24 Oct 2025 11:51:19 +0200 Subject: [PATCH 1501/1962] [doc] Update release notes (#6083) --- docs/pages/release_notes.md | 5 +++++ pmd-java/src/main/resources/rulesets/java/quickstart.xml | 1 + 2 files changed, 6 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 42c85f19faa..2a866816f0e 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -30,6 +30,9 @@ so that it still can be used in a pure Java 8 environment. This allows us to use checkstyle version during the build. ### ๐ŸŒŸ Rules changes +#### New Rules +* The new Java rule {% java/errorprone/IdenticalConditionalBranches %} finds conditional statements + that do the same thing when the condition is true and false. This is either incorrect or redundant. #### Modified rules * {%rule java/codestyle/ConfusingTernary %} has a new property `nullCheckBranch` to control, whether null-checks @@ -80,6 +83,7 @@ checkstyle version during the build. * [#6055](https://github.com/pmd/pmd/issues/6055): \[java] UselessPureMethodCall false positive with AtomicInteger::getAndIncrement * [#6060](https://github.com/pmd/pmd/issues/6060): \[java] UselessPureMethodCall false positive on ZipInputStream::getNextEntry * [#6075](https://github.com/pmd/pmd/issues/6075): \[java] AssignmentInOperand false positive with lambda expressions + * [#6083](https://github.com/pmd/pmd/issues/6083): \[java] New rule IdenticalConditionalBranches * java-multithreading * [#5880](https://github.com/pmd/pmd/issues/5880): \[java] DoubleCheckedLocking is not detected if more than 1 assignment or more than 2 if statements * misc @@ -115,6 +119,7 @@ checkstyle version during the build. * [#6078](https://github.com/pmd/pmd/pull/6078): \[java] Fix #6075: Fix FP in AssignmentInOperandRule - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6080](https://github.com/pmd/pmd/pull/6080): \[java] Fix #6079: IdenticalCatchBranches for overriden method calls - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6082](https://github.com/pmd/pmd/pull/6082): \[java] Fix false positives in UselessPureMethodCall for streams and atomics - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6083](https://github.com/pmd/pmd/pull/6083): \[java] New rule IdenticalConditionalBranches - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6085](https://github.com/pmd/pmd/pull/6085): \[java] Fix false positive for ModifierOrder - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6100](https://github.com/pmd/pmd/pull/6100): \[java] AvoidDeeplyNestedIfStmts: fix false negative with if-else - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6112](https://github.com/pmd/pmd/pull/6112): \[java] DanglingJavadoc: fix false positive for compact constructors - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) diff --git a/pmd-java/src/main/resources/rulesets/java/quickstart.xml b/pmd-java/src/main/resources/rulesets/java/quickstart.xml index 6fffe6d63af..5d69842346b 100644 --- a/pmd-java/src/main/resources/rulesets/java/quickstart.xml +++ b/pmd-java/src/main/resources/rulesets/java/quickstart.xml @@ -244,6 +244,7 @@ + From ffa480c5508f505770c4ba45e5951d8c172b88f8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 24 Oct 2025 12:28:28 +0200 Subject: [PATCH 1502/1962] Fix release notes --- docs/pages/release_notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 2a866816f0e..802d37e9c5f 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -31,7 +31,7 @@ checkstyle version during the build. ### ๐ŸŒŸ Rules changes #### New Rules -* The new Java rule {% java/errorprone/IdenticalConditionalBranches %} finds conditional statements +* The new Java rule {% rule java/errorprone/IdenticalConditionalBranches %} finds conditional statements that do the same thing when the condition is true and false. This is either incorrect or redundant. #### Modified rules From 9f82b1b4571169b0279ec268070724dc6eb7b3b1 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 24 Oct 2025 14:11:20 +0200 Subject: [PATCH 1503/1962] Bump pmdtester from 1.6.1 to 1.6.2 (#6165) --- .ci/files/Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/files/Gemfile.lock b/.ci/files/Gemfile.lock index 3811d713dab..c2a1bfe6f08 100644 --- a/.ci/files/Gemfile.lock +++ b/.ci/files/Gemfile.lock @@ -18,7 +18,7 @@ GEM nokogiri (1.18.10-x86_64-linux-gnu) racc (~> 1.4) ostruct (0.6.3) - pmdtester (1.6.1) + pmdtester (1.6.2) base64 (~> 0.3) bigdecimal (~> 3.2) differ (~> 0.1) From db1cc73bca3c47159841ff1f48059cd3eb311399 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 18 Sep 2025 11:56:59 +0200 Subject: [PATCH 1504/1962] [doc] Improve search index - split rule names - disable fuzzy search - correctly escape search index - remove unused news.html and news_archive.html --- docs/_data/strings.yml | 5 -- docs/_includes/topnav.html | 2 +- docs/_plugins/custom_filters.rb | 23 +++++++-- docs/js/customscripts.js | 5 +- docs/pages/news/news.html | 33 ------------ docs/pages/news/news_archive.html | 35 ------------- docs/search.json | 84 +++++++++++++++++-------------- 7 files changed, 71 insertions(+), 116 deletions(-) delete mode 100644 docs/_data/strings.yml delete mode 100644 docs/pages/news/news.html delete mode 100644 docs/pages/news/news_archive.html diff --git a/docs/_data/strings.yml b/docs/_data/strings.yml deleted file mode 100644 index d7c13924f5a..00000000000 --- a/docs/_data/strings.yml +++ /dev/null @@ -1,5 +0,0 @@ - - -# placed here for translation purposes -search_placeholder_text: search... -search_no_results_text: No results found. diff --git a/docs/_includes/topnav.html b/docs/_includes/topnav.html index daf50ba7c40..83c928bcd2c 100644 --- a/docs/_includes/topnav.html +++ b/docs/_includes/topnav.html @@ -45,7 +45,7 @@ {% endfor %}
    - +
      diff --git a/docs/_plugins/custom_filters.rb b/docs/_plugins/custom_filters.rb index 04c39351f23..0ec56094f75 100644 --- a/docs/_plugins/custom_filters.rb +++ b/docs/_plugins/custom_filters.rb @@ -107,18 +107,35 @@ def random_alphabetic(length) end def escape_json(text) - if text + if text && text.is_a?(String) res = text - res = res.gsub(/\\/, '\\\\') + res = res.gsub(/\\/, '\\\\\\') res = res.gsub(/"/, '\\"') res = res.gsub(/\n/, '\\n') res = res.gsub(/\r/, '\\r') res = res.gsub(/\f/, '\\f') res = res.gsub(/\t/, '\\t') - res = res.gsub(/\b/, '\\b') + res = res.gsub(/[\b]/, '\\b') + elsif text && text.is_a?(Array) + text.map {|s| escape_json(s) } end end + def escape_regex(text) + if text && text.is_a?(String) + res = text + res = res.gsub(/\+/, '\\\+') + res = res.gsub(/\*/, '\*') + res = res.gsub(/\?/, '\?') + elsif text && text.is_a?(Array) + text.map {|s| escape_regex(s) } + end + end + + def separate_words(text) + text.gsub(/([A-Z][a-z])/, ' \1').strip if text + end + private def flatten_rec(seq) diff --git a/docs/js/customscripts.js b/docs/js/customscripts.js index 20e128de1db..084dcad5b31 100644 --- a/docs/js/customscripts.js +++ b/docs/js/customscripts.js @@ -66,9 +66,10 @@ $(document).ready(function () { resultsContainer: document.getElementById('results-container'), json: 'search.json', searchResultTemplate: '
    • {title}
    • ', - noResultsText: '{{site.data.strings.search_no_results_text}}', + noResultsText: 'No results found.', + exclude: ['type', 'source'], limit: 10, - fuzzy: true, + fuzzy: false, }); // Make sure to close and empty the search results after clicking one result item. // This is necessary, if we don't switch the page but only jump to a anchor on the diff --git a/docs/pages/news/news.html b/docs/pages/news/news.html deleted file mode 100644 index 9230f358086..00000000000 --- a/docs/pages/news/news.html +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: News -sidebar: pmd_sidebar -keywords: news, blog, updates, release notes, announcements -permalink: news.html -toc: false -folder: news ---- - -
      - -
      - {% for post in site.posts limit:10 %} - - -

      {{ post.title }}

      - -

      {% if page.summary %} {{ page.summary | strip_html | strip_newlines | truncate: 160 }} {% else %} {{ post.content | truncatewords: 50 | strip_html }} {% endif %}

      - - {% endfor %} - -

      RSS Subscribe{{tag}}

      - -
      -

      See more posts from the News Archive.

      - -
      -
      diff --git a/docs/pages/news/news_archive.html b/docs/pages/news/news_archive.html deleted file mode 100644 index e31fa34a8d8..00000000000 --- a/docs/pages/news/news_archive.html +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: News -sidebar: pmd_sidebar -keywords: news, blog, updates, release notes, announcements -permalink: news_archive.html -toc: false -folder: news ---- - -
      - -
      - - -
      -

      This year's posts

      - {%for post in site.posts %} - {% unless post.next %} -
        - {% else %} - {% capture year %}{{ post.date | date: '%Y' }}{% endcapture %} - {% capture nyear %}{{ post.next.date | date: '%Y' }}{% endcapture %} - {% if year != nyear %} -
      -

      {{ post.date | date: '%Y' }}

      -
        - {% endif %} - {% endunless %} -
      • {{ post.title }}
      • - {% endfor %} -
      -
      -
      -
      -
      diff --git a/docs/search.json b/docs/search.json index 3847c638aa5..0a8c4e95e19 100644 --- a/docs/search.json +++ b/docs/search.json @@ -3,48 +3,58 @@ title: search layout: none search: exclude --- - +{% capture comma %}, +{% endcapture %} [ -{% for page in site.pages %} -{% unless page.search == "exclude" %} - -{% if page.permalink contains "pmd_rules_" and page.keywords %} -{% assign rules = page.keywords | split: ", " %} -{% for rule in rules %} +{%- assign sorted_pages = site.pages | sort: "path" | where_exp:"item", "item.search != 'exclude'" -%} +{%- for page in sorted_pages -%} + {%- if page.permalink contains "pmd_rules_" and page.keywords -%} + {%- assign rules = page.keywords | split: ", " -%} + {%- assign ruleset = rules[0] -%} { -"title": "{{ rule | escape }} ({{page.language}}, {{page.title}})", -"tags": "{{ page.tags }}", -"keywords": "{{rule}}", -"url": "{{ page.url | remove: "/"}}#{{ rule | downcase }}", -"summary": "{{page.summary | strip | escape_json }}" + "type": "ruledoc ruleset", + "source": "{{ page.path }}", + "title": "{{ ruleset | escape | escape_regex | escape_json }} ({{page.language}}, {{page.title}})", + "tags": "{{ page.tags | escape_regex | escape_json }}", + "keywords": "{{ ruleset | escape_regex | escape_json }}", + "url": "{{ page.url | remove: "/"}}", + "summary": "{{ page.summary | strip | escape_regex | escape_json }}" +}, + {%- for rule in rules offset:1 -%} +{ + "type": "ruledoc", + "source": "{{ page.path }}", + "title": "{{ rule | escape | escape_regex | escape_json }} ({{page.language}}, {{page.title}})", + "tags": "{{ page.tags | escape_regex | escape_json }}", + "keywords": "{{ rule | separate_words | escape_regex | escape_json }}", + "url": "{{ page.url | remove: "/"}}#{{ rule | downcase }}", + "summary": "{{ page.summary | strip | escape_regex | escape_json }}" } -{% unless forloop.last %},{% endunless %} -{% endfor %} -{% else %} + {%- unless forloop.last -%}{{ comma }}{%- endunless -%} + {%- endfor -%} + {%- else -%} { -"title": "{{ page.title | escape }}", -"tags": "{{ page.tags }}", -"keywords": "{{page.keywords}}", -"url": "{{ page.url | remove: "/"}}", -"summary": "{{page.summary | strip | escape_json }}" + "type": "page", + "source": "{{ page.path }}", + "title": "{{ page.title | escape | escape_regex | escape_json }}", + "tags": "{{ page.tags | escape_regex | escape_json }}", + "keywords": "{{ page.keywords | escape_regex | escape_json }}", + "url": "{{ page.url | remove: "/"}}", + "summary": "{{ page.summary | strip | escape_regex | escape_json }}" } -{% endif %} - - -{% unless forloop.last and site.posts.size < 1 %},{% endunless %} -{% endunless %} -{% endfor %} - -{% for post in site.posts %} - + {%- endif -%} + {%- unless forloop.last or site.posts.size > 0 -%}{{ comma }}{%- endunless -%} +{%- endfor -%} +{%- for post in site.posts -%} { -"title": "{{ post.title | escape }}", -"tags": "{{ post.tags }}", -"keywords": "{{post.keywords}}", -"url": "{{ post.url | remove: "/" }}", -"summary": "{{post.summary | strip | escape_json }}" + "type": "post", + "source": "{{ post.path }}", + "title": "{{ post.title | escape | escape_regex | escape_json }}", + "tags": "{{ post.tags | escape_regex | escape_json }}", + "keywords": "{{ post.keywords | escape_regex | escape_json }}", + "url": "{{ post.url | remove: "/" }}", + "summary": "{{post.summary | strip | escape_regex | escape_json }}" } -{% unless forloop.last %},{% endunless %} -{% endfor %} - + {%- unless forloop.last -%}{{ comma }}{%- endunless -%} +{%- endfor -%} ] From 1e5c40a8578b53970aeae8c871760a91a7de1b22 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 18 Sep 2025 15:42:24 +0200 Subject: [PATCH 1505/1962] [doc] Improve search UI - display title and summary - navigation with arrow keys up/down - keyboard shortcut "s" for search - display 20 search results with scrolling --- docs/_includes/topnav.html | 2 +- docs/css/customstyles.css | 24 ++++++++++------- docs/js/customscripts.js | 53 +++++++++++++++++++++++++++++++++++--- docs/search.json | 8 +++--- 4 files changed, 69 insertions(+), 18 deletions(-) diff --git a/docs/_includes/topnav.html b/docs/_includes/topnav.html index 83c928bcd2c..7a742f060fb 100644 --- a/docs/_includes/topnav.html +++ b/docs/_includes/topnav.html @@ -45,7 +45,7 @@ {% endfor %}
      - +
        diff --git a/docs/css/customstyles.css b/docs/css/customstyles.css index ba7a6b256d4..bce3bd5c224 100644 --- a/docs/css/customstyles.css +++ b/docs/css/customstyles.css @@ -297,25 +297,29 @@ ul#results-container { position: absolute; top: 50px; /* if you change anything about the nav, you'll prob. need to reset the top and left values here.*/ z-index: -1; - width: 223px; + max-width: 500px; border-left: 1px solid #dedede; box-shadow: 2px 3px 2px #dedede; padding: 0px; + max-height: 500px; + overflow: scroll; +} +ul#results-container li { + padding: 10px; + border-bottom: 1px black solid; +} +ul#results-container li:hover, ul#results-container li.selected { + background-color: #d8ffde; } - ul#results-container a { background-color: transparent; -} - -ul#results-container a:hover { + text-decoration: none; color: black; + display: block; } - -ul#results-container li a { - border-top:1px solid whitesmoke; - margin:10px; +ul#results-container a > strong { + color: #007bff; } - /* end search */ .filter-options { diff --git a/docs/js/customscripts.js b/docs/js/customscripts.js index 084dcad5b31..0ebe1b21b0d 100644 --- a/docs/js/customscripts.js +++ b/docs/js/customscripts.js @@ -65,10 +65,10 @@ $(document).ready(function () { searchInput: document.getElementById('search-input'), resultsContainer: document.getElementById('results-container'), json: 'search.json', - searchResultTemplate: '
      • {title}
      • ', - noResultsText: 'No results found.', + searchResultTemplate: '
      • {title}
        {summary}
      • ', + noResultsText: '
      • No results found.
      • ', exclude: ['type', 'source'], - limit: 10, + limit: 20, fuzzy: false, }); // Make sure to close and empty the search results after clicking one result item. @@ -78,6 +78,53 @@ $(document).ready(function () { $('#search-input').val(''); $(this).empty(); }); + // simple keyboard control of search results + $('#search-input, body').on('keyup', function(e) { + // arrow down: 40, arrow up: 38 + if (e.which !== 40 && e.which !== 38) { + return; + } + if ($('#results-container li').length === 0) { + return; + } + + var current = $('#results-container li.selected'); + if (current.length === 0) { + current = $('#results-container li')[0]; + } else { + current = current[0]; + $(current).removeClass('selected'); + if (e.which === 40) { + if (current.nextSibling !== null) { + current = current.nextSibling; + } + } else if (e.which === 38) { + if (current.previousSibling !== null) { + current = current.previousSibling; + } + } + } + $(current).addClass('selected'); + $('a', current).focus(); + e.preventDefault(); + e.stopImmediatePropagation(); // avoid triggering another search and rerender the results + }); + $('#results-container').on('mouseover', function(e) { + $('#results-container li.selected').removeClass('selected'); + var selected = $(e.target).closest('li')[0]; + $(selected).addClass('selected'); + $('a', selected).focus(); + }); + $('body').on('keyup', function(e) { + // keyboard shortcut "s" for search + if (e.which === 83) { // 83 = "s" + $('#search-input').focus(); + } + // keyboard shortcut "esc" for closing search result + if (e.which === 27) { // 27 = "" + $('#results-container').empty(); + } + }); // Topnav toggle button for displaying/hiding nav sidebar $("#tg-sb-link").click(function(event) { diff --git a/docs/search.json b/docs/search.json index 0a8c4e95e19..176d96ea26f 100644 --- a/docs/search.json +++ b/docs/search.json @@ -18,7 +18,7 @@ search: exclude "tags": "{{ page.tags | escape_regex | escape_json }}", "keywords": "{{ ruleset | escape_regex | escape_json }}", "url": "{{ page.url | remove: "/"}}", - "summary": "{{ page.summary | strip | escape_regex | escape_json }}" + "summary": "{{ page.summary | strip | escape_regex | escape_json | default: ' ' }}" }, {%- for rule in rules offset:1 -%} { @@ -28,7 +28,7 @@ search: exclude "tags": "{{ page.tags | escape_regex | escape_json }}", "keywords": "{{ rule | separate_words | escape_regex | escape_json }}", "url": "{{ page.url | remove: "/"}}#{{ rule | downcase }}", - "summary": "{{ page.summary | strip | escape_regex | escape_json }}" + "summary": "{{ page.summary | strip | escape_regex | escape_json | default: ' ' }}" } {%- unless forloop.last -%}{{ comma }}{%- endunless -%} {%- endfor -%} @@ -40,7 +40,7 @@ search: exclude "tags": "{{ page.tags | escape_regex | escape_json }}", "keywords": "{{ page.keywords | escape_regex | escape_json }}", "url": "{{ page.url | remove: "/"}}", - "summary": "{{ page.summary | strip | escape_regex | escape_json }}" + "summary": "{{ page.summary | strip | escape_regex | escape_json | default: ' ' }}" } {%- endif -%} {%- unless forloop.last or site.posts.size > 0 -%}{{ comma }}{%- endunless -%} @@ -53,7 +53,7 @@ search: exclude "tags": "{{ post.tags | escape_regex | escape_json }}", "keywords": "{{ post.keywords | escape_regex | escape_json }}", "url": "{{ post.url | remove: "/" }}", - "summary": "{{post.summary | strip | escape_regex | escape_json }}" + "summary": "{{ post.summary | strip | escape_regex | escape_json | default: ' ' }}" } {%- unless forloop.last -%}{{ comma }}{%- endunless -%} {%- endfor -%} From 9185483e63e1dc374b4a67dd4cd9ea2bef9ae752 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 18 Sep 2025 16:20:16 +0200 Subject: [PATCH 1506/1962] [doc] Improve search UI - close search results when clicking somewhere --- docs/js/customscripts.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/js/customscripts.js b/docs/js/customscripts.js index 0ebe1b21b0d..6fe0e2e3eb1 100644 --- a/docs/js/customscripts.js +++ b/docs/js/customscripts.js @@ -112,8 +112,10 @@ $(document).ready(function () { $('#results-container').on('mouseover', function(e) { $('#results-container li.selected').removeClass('selected'); var selected = $(e.target).closest('li')[0]; - $(selected).addClass('selected'); - $('a', selected).focus(); + if (selected) { + $(selected).addClass('selected'); + $('a', selected).focus(); + } }); $('body').on('keyup', function(e) { // keyboard shortcut "s" for search @@ -125,6 +127,11 @@ $(document).ready(function () { $('#results-container').empty(); } }); + $('body').on('click', function(e) { + if ($('#results-container li').length > 0) { + $('#results-container').empty(); + } + }); // Topnav toggle button for displaying/hiding nav sidebar $("#tg-sb-link").click(function(event) { From 59cc68467bbb4c62b63abe3be0af6a4a24f84db0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 18 Sep 2025 16:24:59 +0200 Subject: [PATCH 1507/1962] [doc] Display rule descriptions in search - extracts rule descriptions into frontmatter - use rule descriptions as summary for search result - remove exclude configuration from search as it is not excluding data from search.json by key, but by regexing the content... - remove escape_regex again --- docs/_plugins/custom_filters.rb | 11 --- docs/js/customscripts.js | 1 - docs/search.json | 32 ++++----- .../pmd/doc/internal/RuleDocGenerator.java | 22 ++++-- pmd-doc/src/test/resources/expected/sample.md | 71 ++++++++++++++++++- 5 files changed, 103 insertions(+), 34 deletions(-) diff --git a/docs/_plugins/custom_filters.rb b/docs/_plugins/custom_filters.rb index 0ec56094f75..4c67f80f5bd 100644 --- a/docs/_plugins/custom_filters.rb +++ b/docs/_plugins/custom_filters.rb @@ -121,17 +121,6 @@ def escape_json(text) end end - def escape_regex(text) - if text && text.is_a?(String) - res = text - res = res.gsub(/\+/, '\\\+') - res = res.gsub(/\*/, '\*') - res = res.gsub(/\?/, '\?') - elsif text && text.is_a?(Array) - text.map {|s| escape_regex(s) } - end - end - def separate_words(text) text.gsub(/([A-Z][a-z])/, ' \1').strip if text end diff --git a/docs/js/customscripts.js b/docs/js/customscripts.js index 6fe0e2e3eb1..971233d0a79 100644 --- a/docs/js/customscripts.js +++ b/docs/js/customscripts.js @@ -67,7 +67,6 @@ $(document).ready(function () { json: 'search.json', searchResultTemplate: '
      • {title}
        {summary}
      • ', noResultsText: '
      • No results found.
      • ', - exclude: ['type', 'source'], limit: 20, fuzzy: false, }); diff --git a/docs/search.json b/docs/search.json index 176d96ea26f..a7175c9e51f 100644 --- a/docs/search.json +++ b/docs/search.json @@ -14,21 +14,21 @@ search: exclude { "type": "ruledoc ruleset", "source": "{{ page.path }}", - "title": "{{ ruleset | escape | escape_regex | escape_json }} ({{page.language}}, {{page.title}})", - "tags": "{{ page.tags | escape_regex | escape_json }}", - "keywords": "{{ ruleset | escape_regex | escape_json }}", + "title": "{{ ruleset | escape | escape_json }} ({{page.language}}, {{page.title}})", + "tags": "{{ page.tags | escape_json }}", + "keywords": "{{ ruleset | escape_json }}", "url": "{{ page.url | remove: "/"}}", - "summary": "{{ page.summary | strip | escape_regex | escape_json | default: ' ' }}" + "summary": "{{ page.summary | strip | escape_json | default: ' ' }}" }, {%- for rule in rules offset:1 -%} { "type": "ruledoc", "source": "{{ page.path }}", - "title": "{{ rule | escape | escape_regex | escape_json }} ({{page.language}}, {{page.title}})", - "tags": "{{ page.tags | escape_regex | escape_json }}", - "keywords": "{{ rule | separate_words | escape_regex | escape_json }}", + "title": "{{ rule | escape | escape_json }} ({{page.language}}, {{page.title}})", + "tags": "{{ page.tags | escape_json }}", + "keywords": "{{ rule | separate_words | escape_json }}", "url": "{{ page.url | remove: "/"}}#{{ rule | downcase }}", - "summary": "{{ page.summary | strip | escape_regex | escape_json | default: ' ' }}" + "summary": "{{ page.rules[rule] | truncatewords: 15 | strip | escape_json | default: ' ' }}" } {%- unless forloop.last -%}{{ comma }}{%- endunless -%} {%- endfor -%} @@ -36,11 +36,11 @@ search: exclude { "type": "page", "source": "{{ page.path }}", - "title": "{{ page.title | escape | escape_regex | escape_json }}", - "tags": "{{ page.tags | escape_regex | escape_json }}", - "keywords": "{{ page.keywords | escape_regex | escape_json }}", + "title": "{{ page.title | escape | escape_json }}", + "tags": "{{ page.tags | escape_json }}", + "keywords": "{{ page.keywords | escape_json }}", "url": "{{ page.url | remove: "/"}}", - "summary": "{{ page.summary | strip | escape_regex | escape_json | default: ' ' }}" + "summary": "{{ page.summary | strip | escape_json | default: ' ' }}" } {%- endif -%} {%- unless forloop.last or site.posts.size > 0 -%}{{ comma }}{%- endunless -%} @@ -49,11 +49,11 @@ search: exclude { "type": "post", "source": "{{ post.path }}", - "title": "{{ post.title | escape | escape_regex | escape_json }}", - "tags": "{{ post.tags | escape_regex | escape_json }}", - "keywords": "{{ post.keywords | escape_regex | escape_json }}", + "title": "{{ post.title | escape | escape_json }}", + "tags": "{{ post.tags | escape_json }}", + "keywords": "{{ post.keywords | escape_json }}", "url": "{{ post.url | remove: "/" }}", - "summary": "{{ post.summary | strip | escape_regex | escape_json | default: ' ' }}" + "summary": "{{ post.summary | strip | escape_json | default: ' ' }}" } {%- unless forloop.last -%}{{ comma }}{%- endunless -%} {%- endfor -%} diff --git a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java index 33de5b42f55..b58880c635b 100644 --- a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java +++ b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java @@ -375,6 +375,8 @@ private void generateRuleSetIndex(Map> rulesets) throws .replace("${ruleset.name}", rulesetFilename); String ruleSetSourceFilepath = "../" + allRulesets.get(ruleset.getFileName()); + List sortedRules = getSortedRules(ruleset); + List lines = new LinkedList<>(); lines.add("---"); lines.add("title: " + ruleset.getName()); @@ -383,12 +385,18 @@ private void generateRuleSetIndex(Map> rulesets) throws lines.add("folder: pmd/rules/" + languageTersename); lines.add("sidebaractiveurl: /" + LANGUAGE_INDEX_PERMALINK_PATTERN.replace("${language.tersename}", languageTersename)); lines.add("editmepath: " + ruleSetSourceFilepath); - lines.add("keywords: " + getRuleSetKeywords(ruleset)); + lines.add("keywords: " + ruleset.getName() + getRuleSetKeywords(sortedRules)); + lines.add("rules:"); + for (Rule rule : sortedRules) { + lines.add(" " + rule.getName() + ": |"); + List description = EscapeUtils.escapeLines(toLines(stripIndentation(rule.getDescription()))); + lines.addAll(description.stream().map(line -> " " + line).collect(Collectors.toList())); + } lines.add("language: " + languageName); lines.add("---"); lines.add(GENERATED_WARNING.replace("${source}", ruleSetSourceFilepath)); - for (Rule rule : getSortedRules(ruleset)) { + for (Rule rule : sortedRules) { lines.add("## " + rule.getName()); lines.add(""); @@ -608,12 +616,16 @@ private static String mapLanguageForHighlighting(String languageTersename) { return languageTersename; } - private String getRuleSetKeywords(RuleSet ruleset) { + private String getRuleSetKeywords(List rules) { + if (rules.isEmpty()) { + return ""; + } + List ruleNames = new LinkedList<>(); - for (Rule rule : ruleset.getRules()) { + for (Rule rule : rules) { ruleNames.add(rule.getName()); } - return ruleset.getName() + ", " + StringUtils.join(ruleNames, ", "); + return ", " + StringUtils.join(ruleNames, ", "); } private List getSortedRules(RuleSet ruleset) { diff --git a/pmd-doc/src/test/resources/expected/sample.md b/pmd-doc/src/test/resources/expected/sample.md index e6377e0198b..b39f2b8b616 100644 --- a/pmd-doc/src/test/resources/expected/sample.md +++ b/pmd-doc/src/test/resources/expected/sample.md @@ -5,7 +5,76 @@ permalink: pmd_rules_java_sample.html folder: pmd/rules/java sidebaractiveurl: /pmd_rules_java.html editmepath: ../rulesets/ruledoctest/sample.xml -keywords: Sample, XSSInDocumentation, OverrideBothEqualsAndHashcode, JumbledIncrementer, DeprecatedSample, RenamedRule1, RenamedRule2, RenamedRule3, RenamedRule4, MovedRule +keywords: Sample, DeprecatedSample, JumbledIncrementer, MovedRule, OverrideBothEqualsAndHashcode, RenamedRule1, RenamedRule2, RenamedRule3, RenamedRule4, XSSInDocumentation +rules: + DeprecatedSample: | + Just some description of a deprecated rule. + + RuleTag with quotes: Use {% rule "RenamedRule" %} instead. + + RuleTag without quotes: Use {% rule RenamedRule %} instead. + + RuleTag with full category and quotes: Use {% rule "java/sample/RenamedRule" %} instead. + + RuleTag with full category and without quotes: Use {% rule java/sample/RenamedRule %} instead. + JumbledIncrementer: | + Avoid jumbled loop incrementers - it's usually a mistake, and is confusing even if intentional. + MovedRule: | + Avoid jumbled loop incrementers - it's usually a mistake, and is confusing even if intentional. + OverrideBothEqualsAndHashcode: | + Override both `public boolean Object.equals(Object other)`, and `public int Object.hashCode()`, or override neither. + Even if you are inheriting a `hashCode()` from a parent class, consider implementing hashCode and explicitly + delegating to your superclass. + + Second paragraph. + + Code sample + + Third paragraph. + RenamedRule1: | + Avoid jumbled loop incrementers - it's usually a mistake, and is confusing even if intentional. + RenamedRule2: | + Avoid jumbled loop incrementers - it's usually a mistake, and is confusing even if intentional. + RenamedRule3: | + Avoid jumbled loop incrementers - it's usually a mistake, and is confusing even if intentional. + RenamedRule4: | + Avoid jumbled loop incrementers - it's usually a mistake, and is confusing even if intentional. + XSSInDocumentation: | + <script>alert('XSS at the beginning');</script> HTML tags might appear at various places. + Sometimes they should be escaped, sometimes not: + + For example, in a code sample, it should not be escaped. + This means, is no problem here. + + Also in backticks `` like here it is no problem. + + The tags are already escaped in the text, e.g. <script>alert('XSS');</script>. + + A valid case in markdown is a + + + If using CDATA you don't need to escape, but this <script>alert('XSS');</script> + should still not be executed. + + + > this is a + > block quote + > in markdown + + The paragraph after the quotation. + + + > block quote + > in cdata + + + If the description contains a code example, then e.g. "quotes" should not be escaped: + + ``` + if (0 > 1 && 0 < 1) { + System.out.println("impossible"); + } + ``` language: Java --- From fb72c09565c69187ef3d14eaef50556bb0e1f629 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 19 Sep 2025 16:55:05 +0200 Subject: [PATCH 1508/1962] [doc] search: Only show scrollbars when needed in results-container --- docs/css/customstyles.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/css/customstyles.css b/docs/css/customstyles.css index bce3bd5c224..3a1007f5993 100644 --- a/docs/css/customstyles.css +++ b/docs/css/customstyles.css @@ -302,7 +302,7 @@ ul#results-container { box-shadow: 2px 3px 2px #dedede; padding: 0px; max-height: 500px; - overflow: scroll; + overflow-y: auto; } ul#results-container li { padding: 10px; From 3e61127d3e09a4e608c684600371d875b71ab00f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 19 Sep 2025 17:15:51 +0200 Subject: [PATCH 1509/1962] [doc] For deprecated rules, provide deprecation notice in search result --- .../pmd/doc/internal/RuleDocGenerator.java | 84 ++++++++++++++----- pmd-doc/src/test/resources/expected/sample.md | 25 ++++-- 2 files changed, 82 insertions(+), 27 deletions(-) diff --git a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java index b58880c635b..5842133ea62 100644 --- a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java +++ b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java @@ -389,8 +389,21 @@ private void generateRuleSetIndex(Map> rulesets) throws lines.add("rules:"); for (Rule rule : sortedRules) { lines.add(" " + rule.getName() + ": |"); - List description = EscapeUtils.escapeLines(toLines(stripIndentation(rule.getDescription()))); - lines.addAll(description.stream().map(line -> " " + line).collect(Collectors.toList())); + + if (isRuleRenamed(rule, ruleset)) { + getRuleRenamedDeprecationNotice(rule).stream() + .map(line -> " " + line) + .forEachOrdered(lines::add); + } else if (isRuleMoved(rule, ruleset)) { + getRuleMovedDeprecationNotice(rule, languageTersename).stream() + .map(line -> " " + line) + .forEachOrdered(lines::add); + } else { + List description = EscapeUtils.escapeLines(toLines(stripIndentation(rule.getDescription()))); + description.stream() + .map(line -> " " + line) + .forEachOrdered(lines::add); + } } lines.add("language: " + languageName); lines.add("---"); @@ -400,26 +413,12 @@ private void generateRuleSetIndex(Map> rulesets) throws lines.add("## " + rule.getName()); lines.add(""); - if (rule instanceof RuleReference) { - RuleReference ref = (RuleReference) rule; - if (ruleset.getFileName().equals(ref.getRuleSetReference().getRuleSetFileName())) { - // rule renamed within same ruleset - lines.add(DEPRECATION_LABEL); - lines.add(""); - lines.add("This rule has been renamed. Use instead: [" - + ref.getRule().getName() + "](" + "#" + ref.getRule().getName().toLowerCase(Locale.ROOT) + ")"); - lines.add(""); - } else { - // rule moved to another ruleset - String otherLink = RULESET_INDEX_PERMALINK_PATTERN - .replace("${language.tersename}", languageTersename) - .replace("${ruleset.name}", RuleSetUtils.getRuleSetFilename(ref.getRuleSetReference().getRuleSetFileName())); - lines.add(DEPRECATION_LABEL); - lines.add(""); - lines.add("The rule has been moved to another ruleset. Use instead: [" - + ref.getRule().getName() + "](" + otherLink + "#" + ref.getRule().getName().toLowerCase(Locale.ROOT) + ")"); - lines.add(""); - } + if (isRuleRenamed(rule, ruleset)) { + // rule renamed within same ruleset + lines.addAll(getRuleRenamedDeprecationNotice(rule)); + } else if (isRuleMoved(rule, ruleset)) { + // rule moved to another ruleset + lines.addAll(getRuleMovedDeprecationNotice(rule, languageTersename)); } if (rule.isDeprecated()) { @@ -540,6 +539,47 @@ private void generateRuleSetIndex(Map> rulesets) throws } } + private Collection getRuleMovedDeprecationNotice(Rule rule, String languageTersename) { + RuleReference ref = (RuleReference) rule; + List lines = new LinkedList<>(); + String otherLink = RULESET_INDEX_PERMALINK_PATTERN + .replace("${language.tersename}", languageTersename) + .replace("${ruleset.name}", RuleSetUtils.getRuleSetFilename(ref.getRuleSetReference().getRuleSetFileName())); + lines.add(DEPRECATION_LABEL); + lines.add(""); + lines.add("The rule has been moved to another ruleset. Use instead: [" + + ref.getRule().getName() + "](" + otherLink + "#" + ref.getRule().getName().toLowerCase(Locale.ROOT) + ")"); + lines.add(""); + return lines; + } + + private Collection getRuleRenamedDeprecationNotice(Rule rule) { + RuleReference ref = (RuleReference) rule; + List lines = new LinkedList<>(); + lines.add(DEPRECATION_LABEL); + lines.add(""); + lines.add("This rule has been renamed. Use instead: [" + + ref.getRule().getName() + "](" + "#" + ref.getRule().getName().toLowerCase(Locale.ROOT) + ")"); + lines.add(""); + return lines; + } + + private boolean isRuleRenamed(Rule rule, RuleSet ruleset) { + if (rule instanceof RuleReference) { + RuleReference ref = (RuleReference) rule; + return ruleset.getFileName().equals(ref.getRuleSetReference().getRuleSetFileName()); + } + return false; + } + + private boolean isRuleMoved(Rule rule, RuleSet ruleset) { + if (rule instanceof RuleReference) { + RuleReference ref = (RuleReference) rule; + return !ruleset.getFileName().equals(ref.getRuleSetReference().getRuleSetFileName()); + } + return false; + } + private XPathRule asXPathRule(Rule rule) { if (rule instanceof XPathRule) { return (XPathRule) rule; diff --git a/pmd-doc/src/test/resources/expected/sample.md b/pmd-doc/src/test/resources/expected/sample.md index b39f2b8b616..1785c771522 100644 --- a/pmd-doc/src/test/resources/expected/sample.md +++ b/pmd-doc/src/test/resources/expected/sample.md @@ -20,7 +20,10 @@ rules: JumbledIncrementer: | Avoid jumbled loop incrementers - it's usually a mistake, and is confusing even if intentional. MovedRule: | - Avoid jumbled loop incrementers - it's usually a mistake, and is confusing even if intentional. + Deprecated + + The rule has been moved to another ruleset. Use instead: [JumbledIncrementer](pmd_rules_java_sample2.html#jumbledincrementer) + OverrideBothEqualsAndHashcode: | Override both `public boolean Object.equals(Object other)`, and `public int Object.hashCode()`, or override neither. Even if you are inheriting a `hashCode()` from a parent class, consider implementing hashCode and explicitly @@ -32,13 +35,25 @@ rules: Third paragraph. RenamedRule1: | - Avoid jumbled loop incrementers - it's usually a mistake, and is confusing even if intentional. + Deprecated + + This rule has been renamed. Use instead: [JumbledIncrementer](#jumbledincrementer) + RenamedRule2: | - Avoid jumbled loop incrementers - it's usually a mistake, and is confusing even if intentional. + Deprecated + + This rule has been renamed. Use instead: [JumbledIncrementer](#jumbledincrementer) + RenamedRule3: | - Avoid jumbled loop incrementers - it's usually a mistake, and is confusing even if intentional. + Deprecated + + This rule has been renamed. Use instead: [JumbledIncrementer](#jumbledincrementer) + RenamedRule4: | - Avoid jumbled loop incrementers - it's usually a mistake, and is confusing even if intentional. + Deprecated + + This rule has been renamed. Use instead: [JumbledIncrementer](#jumbledincrementer) + XSSInDocumentation: | <script>alert('XSS at the beginning');</script> HTML tags might appear at various places. Sometimes they should be escaped, sometimes not: From f329ab38d97d277347bf523f9474d15bc7bea3e2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 19 Sep 2025 17:24:49 +0200 Subject: [PATCH 1510/1962] [doc] search: avoid losing focus while searching --- docs/js/customscripts.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/js/customscripts.js b/docs/js/customscripts.js index 971233d0a79..380ca33c580 100644 --- a/docs/js/customscripts.js +++ b/docs/js/customscripts.js @@ -113,7 +113,9 @@ $(document).ready(function () { var selected = $(e.target).closest('li')[0]; if (selected) { $(selected).addClass('selected'); - $('a', selected).focus(); + if (document.activeElement !== document.getElementById('search-input')) { + $('a', selected).focus(); + } } }); $('body').on('keyup', function(e) { From f614ba1e697aee5fb08b015ec6689ca5dce52f97 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 26 Sep 2025 20:00:09 +0200 Subject: [PATCH 1511/1962] [doc] search: refactor to not use jquery anymore --- docs/js/customscripts.js | 90 ++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/docs/js/customscripts.js b/docs/js/customscripts.js index 380ca33c580..53c83dfb254 100644 --- a/docs/js/customscripts.js +++ b/docs/js/customscripts.js @@ -73,64 +73,66 @@ $(document).ready(function () { // Make sure to close and empty the search results after clicking one result item. // This is necessary, if we don't switch the page but only jump to a anchor on the // same page. - $('#results-container').click(function() { - $('#search-input').val(''); - $(this).empty(); + document.getElementById('results-container').addEventListener('click', e => { + document.getElementById('search-input').value = ''; + e.target.innerHTML = ''; }); // simple keyboard control of search results - $('#search-input, body').on('keyup', function(e) { - // arrow down: 40, arrow up: 38 - if (e.which !== 40 && e.which !== 38) { - return; - } - if ($('#results-container li').length === 0) { - return; - } + document.querySelectorAll('#search-input, body').forEach(element => { + element.addEventListener('keyup', e => { + if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp') { + return; + } + if (document.querySelectorAll('#results-container li').length === 0) { + return; + } - var current = $('#results-container li.selected'); - if (current.length === 0) { - current = $('#results-container li')[0]; - } else { - current = current[0]; - $(current).removeClass('selected'); - if (e.which === 40) { - if (current.nextSibling !== null) { - current = current.nextSibling; - } - } else if (e.which === 38) { - if (current.previousSibling !== null) { - current = current.previousSibling; + let current = document.querySelector('#results-container li.selected'); + if (!current) { + current = document.querySelector('#results-container li'); + } else { + current.classList.remove('selected'); + if (e.key === 'ArrowDown') { + if (current.nextSibling != null) { + current = current.nextSibling; + } + } else if (e.key === 'ArrowUp') { + if (current.previousSibling !== null) { + current = current.previousSibling; + } } } - } - $(current).addClass('selected'); - $('a', current).focus(); - e.preventDefault(); - e.stopImmediatePropagation(); // avoid triggering another search and rerender the results + current.classList.add('selected'); + current.querySelector('a').focus(); + e.preventDefault(); + e.stopImmediatePropagation(); // avoid triggering another search and rerender the results + }); }); - $('#results-container').on('mouseover', function(e) { - $('#results-container li.selected').removeClass('selected'); - var selected = $(e.target).closest('li')[0]; + document.getElementById('results-container').addEventListener('mouseover', e => { + let selected = document.getElementById('results-container').querySelector('li.selected') if (selected) { - $(selected).addClass('selected'); + selected.classList.remove('selected'); + } + let newSelected = e.target.closest('li'); + if (newSelected) { + newSelected.classList.add('selected'); if (document.activeElement !== document.getElementById('search-input')) { - $('a', selected).focus(); + newSelected.querySelector('a').focus(); } } }); - $('body').on('keyup', function(e) { - // keyboard shortcut "s" for search - if (e.which === 83) { // 83 = "s" - $('#search-input').focus(); + document.body.addEventListener('keyup', e => { + if (e.key === 's') { + document.getElementById('search-input').focus(); } - // keyboard shortcut "esc" for closing search result - if (e.which === 27) { // 27 = "" - $('#results-container').empty(); + if (e.key === 'Escape') { + document.getElementById('results-container').innerHTML = ''; } }); - $('body').on('click', function(e) { - if ($('#results-container li').length > 0) { - $('#results-container').empty(); + document.body.addEventListener('click', e => { + const resultsContainer = document.getElementById('results-container'); + if (resultsContainer.querySelectorAll('li').length > 0) { + resultsContainer.innerHTML = ''; } }); From 48cbabd7a0263f36286b0a848a10bb7d4878c7a7 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 26 Sep 2025 20:07:37 +0200 Subject: [PATCH 1512/1962] [doc] search: Update Simple Jekyll Search from 1.0.8 to 1.14.0 --- docs/_layouts/default.html | 2 +- docs/assets/README.md | 2 +- .../assets/Simple-Jekyll-Search-1.0.8/dest/jekyll-search.js | 1 - .../dest/simple-jekyll-search.min.js | 6 ++++++ docs/js/customscripts.js | 2 +- 5 files changed, 9 insertions(+), 4 deletions(-) delete mode 100644 docs/assets/Simple-Jekyll-Search-1.0.8/dest/jekyll-search.js create mode 100644 docs/assets/Simple-Jekyll-Search-1.14.0/dest/simple-jekyll-search.min.js diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html index 5e0065208f0..11d31e6136a 100644 --- a/docs/_layouts/default.html +++ b/docs/_layouts/default.html @@ -47,7 +47,7 @@ - + diff --git a/docs/assets/README.md b/docs/assets/README.md index 48125954f80..f6fffb6f798 100644 --- a/docs/assets/README.md +++ b/docs/assets/README.md @@ -33,7 +33,7 @@ https://jqueryui.com/resources/download/jquery-ui-1.12.1.zip ## Simple Jekyll Search -https://github.com/christian-fei/Simple-Jekyll-Search +https://github.com/neilboyd/Simple-Jekyll-Search ## Shuffle diff --git a/docs/assets/Simple-Jekyll-Search-1.0.8/dest/jekyll-search.js b/docs/assets/Simple-Jekyll-Search-1.0.8/dest/jekyll-search.js deleted file mode 100644 index 32eba0f36db..00000000000 --- a/docs/assets/Simple-Jekyll-Search-1.0.8/dest/jekyll-search.js +++ /dev/null @@ -1 +0,0 @@ -!function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a="function"==typeof require&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o=0)}}module.exports=new LiteralSearchStrategy},{}],5:[function(require,module,exports){function setOptions(_opt){opt=_opt||{},opt.templatePattern=_opt.templatePattern||/\{(.*?)\}/g}function render(t,data){return t.replace(opt.templatePattern,function(match,prop){return data[prop]||match})}module.exports={render:render,setOptions:setOptions};var opt={};opt.templatePattern=/\{(.*?)\}/g},{}],6:[function(require,module,exports){!function(window,document,undefined){"use strict";function initWithJSON(json){store.put(opt.json),registerInput()}function initWithURL(url){jsonLoader.load(url,function(err,json){err?throwError("failed to get JSON ("+url+")"):(store.put(json),registerInput())})}function throwError(message){throw new Error("SimpleJekyllSearch --- "+message)}function validateOptions(_opt){for(var i=0;i{title}',noResultsText:"No results found",limit:10,fuzzy:!1,exclude:[]};window.SimpleJekyllSearch=function(_opt){opt=validateOptions(_opt),store.setOptions(_opt),isJSON(opt.json)?initWithJSON(opt.json):initWithURL(opt.json)},window.SimpleJekyllSearch.init=window.SimpleJekyllSearch}(window,document)},{"./JSONLoader":1,"./Repository":2,"./Templater":5}]},{},[6]); \ No newline at end of file diff --git a/docs/assets/Simple-Jekyll-Search-1.14.0/dest/simple-jekyll-search.min.js b/docs/assets/Simple-Jekyll-Search-1.14.0/dest/simple-jekyll-search.min.js new file mode 100644 index 00000000000..47c14d6c810 --- /dev/null +++ b/docs/assets/Simple-Jekyll-Search-1.14.0/dest/simple-jekyll-search.min.js @@ -0,0 +1,6 @@ +/*! + * Simple-Jekyll-Search 1.14.0 + * Copyright 2015-2025, Christian Fei, Neil Boyd + * Licensed under the MIT License. + */ +!function(){"use strict";var u={compile:function(n){return i.template.replace(i.pattern,function(t,e){var r=i.middleware(e,n[e],i.template,n.query);return void 0!==r?r:n[e]||t})},setOptions:function(t){i.pattern=t.pattern||i.pattern,i.template=t.template||i.template,"function"==typeof t.middleware&&(i.middleware=t.middleware)}};const i={};i.pattern=/\{(.*?)\}/g,i.template="",i.middleware=function(){};var e=function(t,e){var r=e.length,n=t.length;if(rt.isWordLike).map(t=>t.segment)),this},this.matches=function(e){return!!e&&0!==this.critArray.length&&(e=e.trim().toUpperCase(),this.critArray.filter(t=>0<=e.indexOf(t)).length===this.critArray.length)}};const o=new Intl.Segmenter([],{granularity:"word"});var s={put:function(t){if(f(t))return h(t);if(function(t){return Boolean(t)&&"[object Array]"===Object.prototype.toString.call(t)}(t))return function(r){var n=[];l();for(let t=0,e=r.length;t=r.limit));t++){var i=function(t,e){for(const r in t)if("query"!==r&&!function(r,n){for(let t=0,e=n.length;t{if(0!==e.length){let t=0;for(;;){if((t=i.toUpperCase().indexOf(e.toUpperCase(),t))<0)break;var r=t+e.length,n=""+i.substring(t,r)+"";i=i.substring(0,t)+n+i.substring(r),t+=n.length}}});let n=i.indexOf("");n>r?n-=r:n=0;t=(i=i.substring(n,n+e)).indexOf("<",e-3);-1!==t&&(i=i.substring(0,t));r=i.lastIndexOf(""),e=i.lastIndexOf("");if(e";return i}};{var g=window;let i={searchInput:null,resultsContainer:null,json:[],success:Function.prototype,searchResultTemplate:'
      • {title}
      • ',templateMiddleware:Function.prototype,sortMiddleware:function(){return 0},noResultsText:"No results found",limit:10,fuzzy:!1,debounceTime:null,exclude:[],onSearch:Function.prototype},r;const x=function(t,e){e?(clearTimeout(r),r=setTimeout(t,e)):t.call()},S=["searchInput","resultsContainer","json"],z=t({required:S});function m(t){s.put(t),i.searchInput.addEventListener("input",function(t){-1===[13,16,20,37,38,39,40,91].indexOf(t.which)&&(y(),x(function(){v(t.target.value)},i.debounceTime))})}function y(){i.resultsContainer.innerHTML=""}function w(t){i.resultsContainer.innerHTML+=t}function v(t){var e;(e=t)&&0 Date: Tue, 30 Sep 2025 20:26:27 +0200 Subject: [PATCH 1513/1962] [doc] Make search working in local mode Move search index into an own js file, that is loaded via + {% if page.additional_js %} {% for js in page.additional_js %} diff --git a/docs/js/customscripts.js b/docs/js/customscripts.js index 2cc350cc44c..288f48ecd7b 100644 --- a/docs/js/customscripts.js +++ b/docs/js/customscripts.js @@ -60,82 +60,6 @@ $(document).ready(function () { } }); - // Initialize jekyll search in topnav. - var sjs = SimpleJekyllSearch({ - searchInput: document.getElementById('search-input'), - resultsContainer: document.getElementById('results-container'), - json: 'search.json', - searchResultTemplate: '
      • {title}
        {summary}
      • ', - noResultsText: '
      • No results found.
      • ', - limit: 20, - fuzzy: false, - }); - // Make sure to close and empty the search results after clicking one result item. - // This is necessary, if we don't switch the page but only jump to a anchor on the - // same page. - document.getElementById('results-container').addEventListener('click', e => { - document.getElementById('search-input').value = ''; - e.target.innerHTML = ''; - }); - // simple keyboard control of search results - document.querySelectorAll('#search-input, body').forEach(element => { - element.addEventListener('keyup', e => { - if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp') { - return; - } - if (document.querySelectorAll('#results-container li').length === 0) { - return; - } - - let current = document.querySelector('#results-container li.selected'); - if (!current) { - current = document.querySelector('#results-container li'); - } else { - current.classList.remove('selected'); - if (e.key === 'ArrowDown') { - if (current.nextSibling != null) { - current = current.nextSibling; - } - } else if (e.key === 'ArrowUp') { - if (current.previousSibling !== null) { - current = current.previousSibling; - } - } - } - current.classList.add('selected'); - current.querySelector('a').focus(); - e.preventDefault(); - e.stopImmediatePropagation(); // avoid triggering another search and rerender the results - }); - }); - document.getElementById('results-container').addEventListener('mouseover', e => { - let selected = document.getElementById('results-container').querySelector('li.selected') - if (selected) { - selected.classList.remove('selected'); - } - let newSelected = e.target.closest('li'); - if (newSelected) { - newSelected.classList.add('selected'); - if (document.activeElement !== document.getElementById('search-input')) { - newSelected.querySelector('a').focus(); - } - } - }); - document.body.addEventListener('keyup', e => { - if (e.key === 's') { - document.getElementById('search-input').focus(); - } - if (e.key === 'Escape') { - document.getElementById('results-container').innerHTML = ''; - } - }); - document.body.addEventListener('click', e => { - const resultsContainer = document.getElementById('results-container'); - if (resultsContainer.querySelectorAll('li').length > 0) { - resultsContainer.innerHTML = ''; - } - }); - // Topnav toggle button for displaying/hiding nav sidebar $("#tg-sb-link").click(function(event) { $("#tg-sb-sidebar").toggle(); diff --git a/docs/js/search.js b/docs/js/search.js new file mode 100644 index 00000000000..da6a87fe6cf --- /dev/null +++ b/docs/js/search.js @@ -0,0 +1,142 @@ +--- +title: search +layout: none +search: exclude +--- +{%- capture comma -%}, +{%- endcapture -%} + +document.addEventListener("DOMContentLoaded", (event) => { + +let pmd_doc_search_index = [ +{% assign sorted_pages = site.pages | sort: "path" | where_exp:"item", "item.search != 'exclude'" -%} +{%- for page in sorted_pages -%} + {%- if page.permalink contains "pmd_rules_" and page.keywords -%} + {%- assign rules = page.keywords | split: ", " -%} + {%- assign ruleset = rules[0] -%} +{ + "type": "ruledoc ruleset", + "source": "{{ page.path }}", + "title": "{{ ruleset | escape | escape_json }} ({{page.language}}, {{page.title}})", + "tags": "{{ page.tags | escape_json }}", + "keywords": "{{ ruleset | escape_json }}", + "url": "{{ page.url | remove: "/"}}", + "summary": "{{ page.summary | strip | escape_json | default: ' ' }}" +}, + {%- for rule in rules offset:1 -%} +{ + "type": "ruledoc", + "source": "{{ page.path }}", + "title": "{{ rule | escape | escape_json }} ({{page.language}}, {{page.title}})", + "tags": "{{ page.tags | escape_json }}", + "keywords": "{{ rule | separate_words | escape_json }}", + "url": "{{ page.url | remove: "/"}}#{{ rule | downcase }}", + "summary": "{{ page.rules[rule] | truncatewords: 15 | strip | escape_json | default: ' ' }}" +} + {%- unless forloop.last -%}{{ comma }}{%- endunless -%} + {%- endfor -%} + {%- else -%} +{ + "type": "page", + "source": "{{ page.path }}", + "title": "{{ page.title | escape | escape_json }}", + "tags": "{{ page.tags | escape_json }}", + "keywords": "{{ page.keywords | escape_json }}", + "url": "{{ page.url | remove: "/"}}", + "summary": "{{ page.summary | strip | escape_json | default: ' ' }}" +} + {%- endif -%} + {%- unless forloop.last or site.posts.size > 0 -%}{{ comma }}{%- endunless -%} +{%- endfor -%} +{%- for post in site.posts -%} +{ + "type": "post", + "source": "{{ post.path }}", + "title": "{{ post.title | escape | escape_json }}", + "tags": "{{ post.tags | escape_json }}", + "keywords": "{{ post.keywords | escape_json }}", + "url": "{{ post.url | remove: "/" }}", + "summary": "{{ post.summary | strip | escape_json | default: ' ' }}" +} + {%- unless forloop.last -%}{{ comma }}{%- endunless -%} +{%- endfor %} +]; + + + // Initialize jekyll search in topnav. + SimpleJekyllSearch({ + searchInput: document.getElementById('search-input'), + resultsContainer: document.getElementById('results-container'), + json: pmd_doc_search_index, + searchResultTemplate: '
      • {title}
        {summary}
      • ', + noResultsText: '
      • No results found.
      • ', + limit: 20, + fuzzy: false, + }); + // Make sure to close and empty the search results after clicking one result item. + // This is necessary, if we don't switch the page but only jump to a anchor on the + // same page. + document.getElementById('results-container').addEventListener('click', e => { + document.getElementById('search-input').value = ''; + e.target.innerHTML = ''; + }); + // simple keyboard control of search results + document.querySelectorAll('#search-input, body').forEach(element => { + element.addEventListener('keyup', e => { + if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp') { + return; + } + if (document.querySelectorAll('#results-container li').length === 0) { + return; + } + + let current = document.querySelector('#results-container li.selected'); + if (!current) { + current = document.querySelector('#results-container li'); + } else { + current.classList.remove('selected'); + if (e.key === 'ArrowDown') { + if (current.nextSibling != null) { + current = current.nextSibling; + } + } else if (e.key === 'ArrowUp') { + if (current.previousSibling !== null) { + current = current.previousSibling; + } + } + } + current.classList.add('selected'); + current.querySelector('a').focus(); + e.preventDefault(); + e.stopImmediatePropagation(); // avoid triggering another search and rerender the results + }); + }); + document.getElementById('results-container').addEventListener('mouseover', e => { + let selected = document.getElementById('results-container').querySelector('li.selected') + if (selected) { + selected.classList.remove('selected'); + } + let newSelected = e.target.closest('li'); + if (newSelected) { + newSelected.classList.add('selected'); + if (document.activeElement !== document.getElementById('search-input')) { + newSelected.querySelector('a').focus(); + } + } + }); + document.body.addEventListener('keyup', e => { + if (e.key === 's') { + document.getElementById('search-input').focus(); + } + if (e.key === 'Escape') { + document.getElementById('results-container').innerHTML = ''; + } + }); + document.body.addEventListener('click', e => { + const resultsContainer = document.getElementById('results-container'); + if (resultsContainer.querySelectorAll('li').length > 0) { + resultsContainer.innerHTML = ''; + } + }); + +}); diff --git a/docs/search.json b/docs/search.json deleted file mode 100644 index a7175c9e51f..00000000000 --- a/docs/search.json +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: search -layout: none -search: exclude ---- -{% capture comma %}, -{% endcapture %} -[ -{%- assign sorted_pages = site.pages | sort: "path" | where_exp:"item", "item.search != 'exclude'" -%} -{%- for page in sorted_pages -%} - {%- if page.permalink contains "pmd_rules_" and page.keywords -%} - {%- assign rules = page.keywords | split: ", " -%} - {%- assign ruleset = rules[0] -%} -{ - "type": "ruledoc ruleset", - "source": "{{ page.path }}", - "title": "{{ ruleset | escape | escape_json }} ({{page.language}}, {{page.title}})", - "tags": "{{ page.tags | escape_json }}", - "keywords": "{{ ruleset | escape_json }}", - "url": "{{ page.url | remove: "/"}}", - "summary": "{{ page.summary | strip | escape_json | default: ' ' }}" -}, - {%- for rule in rules offset:1 -%} -{ - "type": "ruledoc", - "source": "{{ page.path }}", - "title": "{{ rule | escape | escape_json }} ({{page.language}}, {{page.title}})", - "tags": "{{ page.tags | escape_json }}", - "keywords": "{{ rule | separate_words | escape_json }}", - "url": "{{ page.url | remove: "/"}}#{{ rule | downcase }}", - "summary": "{{ page.rules[rule] | truncatewords: 15 | strip | escape_json | default: ' ' }}" -} - {%- unless forloop.last -%}{{ comma }}{%- endunless -%} - {%- endfor -%} - {%- else -%} -{ - "type": "page", - "source": "{{ page.path }}", - "title": "{{ page.title | escape | escape_json }}", - "tags": "{{ page.tags | escape_json }}", - "keywords": "{{ page.keywords | escape_json }}", - "url": "{{ page.url | remove: "/"}}", - "summary": "{{ page.summary | strip | escape_json | default: ' ' }}" -} - {%- endif -%} - {%- unless forloop.last or site.posts.size > 0 -%}{{ comma }}{%- endunless -%} -{%- endfor -%} -{%- for post in site.posts -%} -{ - "type": "post", - "source": "{{ post.path }}", - "title": "{{ post.title | escape | escape_json }}", - "tags": "{{ post.tags | escape_json }}", - "keywords": "{{ post.keywords | escape_json }}", - "url": "{{ post.url | remove: "/" }}", - "summary": "{{ post.summary | strip | escape_json | default: ' ' }}" -} - {%- unless forloop.last -%}{{ comma }}{%- endunless -%} -{%- endfor -%} -] From f111bb2feccb6215cf001f7bc1c492088522b26a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 24 Oct 2025 14:17:00 +0200 Subject: [PATCH 1514/1962] [doc] Update release notes (#6073) --- docs/pages/release_notes.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 802d37e9c5f..268d63cd9b2 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -53,8 +53,10 @@ checkstyle version during the build. {% rule java/errorprone/AvoidCatchingGenericException %}, which is now configurable. ### ๐Ÿ› Fixed Issues -* core +* general * [#4714](https://github.com/pmd/pmd/issues/4714): \[core] Allow trailing commas in multivalued properties + * [#6012](https://github.com/pmd/pmd/issues/6012): \[pmd-rulesets] Rulesets should be in alphabetical order + * [#6073](https://github.com/pmd/pmd/issues/6073): \[doc] Search improvements * apex * [#5935](https://github.com/pmd/pmd/issues/5935): \[apex] @SuppressWarnings - allow whitespace around comma when suppressing multiple rules * apex-design @@ -86,8 +88,6 @@ checkstyle version during the build. * [#6083](https://github.com/pmd/pmd/issues/6083): \[java] New rule IdenticalConditionalBranches * java-multithreading * [#5880](https://github.com/pmd/pmd/issues/5880): \[java] DoubleCheckedLocking is not detected if more than 1 assignment or more than 2 if statements -* misc - * [#6012](https://github.com/pmd/pmd/issues/6012): \[pmd-rulesets] Rulesets should be in alphabetical order ### ๐Ÿšจ API Changes @@ -115,6 +115,7 @@ checkstyle version during the build. * [#6059](https://github.com/pmd/pmd/pull/6059): \[java] Fix #6058: DanglingJavadoc FP in module-info files - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6061](https://github.com/pmd/pmd/pull/6061): \[core] chore: Bump minimum Java version required for building to 17 - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6071](https://github.com/pmd/pmd/pull/6071): \[java] Fix #5919: Add integration tests to ClassNamingConventions testClassRegex - [Anton Bobov](https://github.com/abobov) (@abobov) +* [#6073](https://github.com/pmd/pmd/pull/6073): \[doc] Search improvements - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6074](https://github.com/pmd/pmd/pull/6074): \[apex] Fix @SuppressWarnings with whitespace around comma - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) * [#6078](https://github.com/pmd/pmd/pull/6078): \[java] Fix #6075: Fix FP in AssignmentInOperandRule - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6080](https://github.com/pmd/pmd/pull/6080): \[java] Fix #6079: IdenticalCatchBranches for overriden method calls - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) From 8b0adebbaa394d50d868c2e71374378308e1375b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 24 Oct 2025 14:38:51 +0200 Subject: [PATCH 1515/1962] [doc] Use emoji variant --- docs/_includes/topnav.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_includes/topnav.html b/docs/_includes/topnav.html index 7a742f060fb..11890923f6f 100644 --- a/docs/_includes/topnav.html +++ b/docs/_includes/topnav.html @@ -45,7 +45,7 @@ {% endfor %}
        - +
          From 5f260cb009c632345fb8d555bc5e98f4cbef2cb8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 19 Sep 2025 12:15:11 +0200 Subject: [PATCH 1516/1962] [plsql] Excessive*/Ncss*Count/NPathComplexity include the metric Refs #5569 --- .../rule/design/AbstractCounterCheckRule.java | 9 +++++---- .../plsql/rule/design/NPathComplexityRule.java | 10 +++++++++- .../plsql/rule/design/NcssMethodCountRule.java | 12 ++++++++++-- .../plsql/rule/design/NcssObjectCountRule.java | 12 ++++++++++-- .../main/resources/category/plsql/design.xml | 18 +++++++++--------- .../rule/design/xml/ExcessiveMethodLength.xml | 3 +++ .../rule/design/xml/ExcessiveObjectLength.xml | 3 +++ .../design/xml/ExcessivePackageBodyLength.xml | 3 +++ .../ExcessivePackageSpecificationLength.xml | 3 +++ .../rule/design/xml/ExcessiveParameterList.xml | 3 +++ .../rule/design/xml/ExcessiveTypeLength.xml | 3 +++ .../plsql/rule/design/xml/NPathComplexity.xml | 3 +++ .../plsql/rule/design/xml/NcssMethodCount.xml | 3 +++ .../plsql/rule/design/xml/NcssObjectCount.xml | 3 +++ 14 files changed, 70 insertions(+), 18 deletions(-) diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/AbstractCounterCheckRule.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/AbstractCounterCheckRule.java index b65b0247522..076adee6f04 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/AbstractCounterCheckRule.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/AbstractCounterCheckRule.java @@ -90,8 +90,8 @@ protected boolean isIgnored(T node) { return false; } - protected Object[] getViolationParameters(T node, int metric) { - return new Object[] {metric}; + protected Object[] getViolationParameters(T node, int metric, int limit) { + return new Object[] {metric, limit}; } @@ -105,8 +105,9 @@ public Object visitPlsqlNode(PLSQLNode node, Object data) { if (!isIgnored(t)) { int metric = getMetric(t); - if (metric >= getProperty(reportLevel)) { - asCtx(data).addViolation(node, getViolationParameters(t, metric)); + int limit = getProperty(reportLevel); + if (metric >= limit) { + asCtx(data).addViolation(node, getViolationParameters(t, metric, limit)); } } diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/NPathComplexityRule.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/NPathComplexityRule.java index 484da52ec6e..f6be8d85d3d 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/NPathComplexityRule.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/NPathComplexityRule.java @@ -35,8 +35,16 @@ protected int getMetric(ExecutableCode node) { } @Override + protected Object[] getViolationParameters(ExecutableCode node, int metric, int limit) { + return new Object[] {node.getMethodName(), metric, limit}; + } + + /** + * @deprecated Since 7.18.0. Use {@link #getViolationParameters(ExecutableCode, int, int)} instead. + */ + @Deprecated protected Object[] getViolationParameters(ExecutableCode node, int metric) { - return new Object[] {node.getMethodName(), metric}; + return getViolationParameters(node, metric, -1); } /** diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/NcssMethodCountRule.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/NcssMethodCountRule.java index 7f5a22c6c8d..350b91db3f0 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/NcssMethodCountRule.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/NcssMethodCountRule.java @@ -26,9 +26,17 @@ protected int defaultReportLevel() { } @Override - protected Object[] getViolationParameters(ExecutableCode node, int metric) { + protected Object[] getViolationParameters(ExecutableCode node, int metric, int limit) { String name = node.getMethodName(); - return new Object[] {name == null ? "(unnamed)" : name, metric}; + return new Object[] {name == null ? "(unnamed)" : name, metric, limit}; + } + + /** + * @deprecated Since 7.18.0. Use {@link #getViolationParameters(ExecutableCode, int, int)} instead. + */ + @Deprecated + protected Object[] getViolationParameters(ExecutableCode node, int metric) { + return getViolationParameters(node, metric, -1); } diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/NcssObjectCountRule.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/NcssObjectCountRule.java index 28f072447ec..65eec95b2ff 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/NcssObjectCountRule.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/NcssObjectCountRule.java @@ -35,8 +35,16 @@ protected boolean isIgnored(OracleObject node) { } @Override - protected Object[] getViolationParameters(OracleObject node, int metric) { + protected Object[] getViolationParameters(OracleObject node, int metric, int limit) { String name = node.getObjectName(); - return new Object[] {name == null ? "(unnamed)" : name, metric}; + return new Object[] {name == null ? "(unnamed)" : name, metric, limit}; + } + + /** + * @deprecated Since 7.18.0. Use {@link #getViolationParameters(OracleObject, int, int)} instead. + */ + @Deprecated + protected Object[] getViolationParameters(OracleObject node, int metric) { + return getViolationParameters(node, metric, -1); } } diff --git a/pmd-plsql/src/main/resources/category/plsql/design.xml b/pmd-plsql/src/main/resources/category/plsql/design.xml index f11ccc7fbfd..10a9fda90f7 100644 --- a/pmd-plsql/src/main/resources/category/plsql/design.xml +++ b/pmd-plsql/src/main/resources/category/plsql/design.xml @@ -145,7 +145,7 @@ END; @@ -170,7 +170,7 @@ END; @@ -205,7 +205,7 @@ END; @@ -240,7 +240,7 @@ END; @@ -268,7 +268,7 @@ END; @@ -330,7 +330,7 @@ public class Foo { @@ -363,7 +363,7 @@ END; diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/rule/design/xml/ExcessiveMethodLength.xml b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/rule/design/xml/ExcessiveMethodLength.xml index 62389f8ee8b..e1b82798c85 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/rule/design/xml/ExcessiveMethodLength.xml +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/rule/design/xml/ExcessiveMethodLength.xml @@ -8,6 +8,9 @@ short 10 1 + + Avoid really long methods (3,187 lines found, threshold is 10). + short 10 1 + + Avoid really long Oracle object specifications and bodies (2,071 lines found, threshold is 10). + A too complex procedure which triggers ExcessivePackageBodyLengthRule 1 1 + + Avoid really long Object Type and Package bodies (33 lines found, threshold is 1). + A too complex procedure which triggers ExcessivePackageSpecificationLengthRule 1 1 + + Avoid really long Package Specifications (2,067 lines found, threshold is 1). + A too complex procedure which triggers ExcessiveParameterListRule 1 1 + + Avoid long parameter lists (1,027 parameters found, threshold is 1). + A too complex procedure which triggers ExcessiveTypeLengthRule 1 1 + + Avoid really long Object Type specifications (2,071 lines found, threshold is 1). + A too complex procedure which triggers NPathComplexityRule 1 1 + + The method bar() has an NPath complexity of 10 (threshold is 1) + A too complex procedure which triggers ExcessiveNcssMethodCountRule 10 1 + + The method prc_test_unreserved_keyword() has an NCSS line count of 1,061 (threshold is 10) + A too complex procedure which triggers NcssObjectCountRule 1 1 + + The Oracle object pkg_test_unreserved_keyword has a NCSS line count of 1,061 (threshold is 1) + Date: Fri, 19 Sep 2025 16:46:34 +0200 Subject: [PATCH 1517/1962] [core] Make rule violation messages locale independent --- .../main/java/net/sourceforge/pmd/reporting/RuleContext.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java index 0d1042f4878..38c5a75230e 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java @@ -8,6 +8,7 @@ import java.text.MessageFormat; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -253,7 +254,7 @@ private String makeMessage(@NonNull String message, Object[] args, Map Date: Fri, 19 Sep 2025 16:47:06 +0200 Subject: [PATCH 1518/1962] [doc] Update release notes (#6077) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 268d63cd9b2..278fd6a8ee0 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -88,6 +88,8 @@ checkstyle version during the build. * [#6083](https://github.com/pmd/pmd/issues/6083): \[java] New rule IdenticalConditionalBranches * java-multithreading * [#5880](https://github.com/pmd/pmd/issues/5880): \[java] DoubleCheckedLocking is not detected if more than 1 assignment or more than 2 if statements +* plsql-design + * [#6077](https://github.com/pmd/pmd/issues/6077): \[plsql] Excessive\*/Ncss\*Count/NPathComplexity include the metric ### ๐Ÿšจ API Changes @@ -117,6 +119,7 @@ checkstyle version during the build. * [#6071](https://github.com/pmd/pmd/pull/6071): \[java] Fix #5919: Add integration tests to ClassNamingConventions testClassRegex - [Anton Bobov](https://github.com/abobov) (@abobov) * [#6073](https://github.com/pmd/pmd/pull/6073): \[doc] Search improvements - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6074](https://github.com/pmd/pmd/pull/6074): \[apex] Fix @SuppressWarnings with whitespace around comma - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#6077](https://github.com/pmd/pmd/pull/6077): \[plsql] Excessive*/Ncss*Count/NPathComplexity include the metric - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6078](https://github.com/pmd/pmd/pull/6078): \[java] Fix #6075: Fix FP in AssignmentInOperandRule - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6080](https://github.com/pmd/pmd/pull/6080): \[java] Fix #6079: IdenticalCatchBranches for overriden method calls - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6082](https://github.com/pmd/pmd/pull/6082): \[java] Fix false positives in UselessPureMethodCall for streams and atomics - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) From 33447d5d6cdc79b47c55a3b90464d855ad85407e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 25 Sep 2025 09:19:36 +0200 Subject: [PATCH 1519/1962] [ci] Fix #5873: Run integration tests with Java 25 additionally --- .github/workflows/build.yml | 4 +++- docs/pages/release_notes.md | 2 ++ pmd-dist/pom.xml | 31 +++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bd67a004a71..708c28bee03 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -131,6 +131,7 @@ jobs: 8 11 21 + 25 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 # default java version for all os is 17 with: @@ -160,7 +161,8 @@ jobs: -PfastSkip -Dcyclonedx.skip=false \ -Djava8.home="${JAVA_HOME_8_X64}" \ -Djava11.home="${JAVA_HOME_11_X64}" \ - -Djava21.home="${JAVA_HOME_21_X64}" + -Djava21.home="${JAVA_HOME_21_X64}" \ + -Djava25.home="${JAVA_HOME_25_X64}" dogfood: needs: compile diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 278fd6a8ee0..8c236110ede 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -55,6 +55,7 @@ checkstyle version during the build. ### ๐Ÿ› Fixed Issues * general * [#4714](https://github.com/pmd/pmd/issues/4714): \[core] Allow trailing commas in multivalued properties + * [#5873](https://github.com/pmd/pmd/issues/5873): \[ci] Run integration test with Java 25 * [#6012](https://github.com/pmd/pmd/issues/6012): \[pmd-rulesets] Rulesets should be in alphabetical order * [#6073](https://github.com/pmd/pmd/issues/6073): \[doc] Search improvements * apex @@ -125,6 +126,7 @@ checkstyle version during the build. * [#6082](https://github.com/pmd/pmd/pull/6082): \[java] Fix false positives in UselessPureMethodCall for streams and atomics - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6083](https://github.com/pmd/pmd/pull/6083): \[java] New rule IdenticalConditionalBranches - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6085](https://github.com/pmd/pmd/pull/6085): \[java] Fix false positive for ModifierOrder - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6093](https://github.com/pmd/pmd/pull/6093): \[ci] Fix #5873: Run integration tests with Java 25 additionally - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6100](https://github.com/pmd/pmd/pull/6100): \[java] AvoidDeeplyNestedIfStmts: fix false negative with if-else - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6112](https://github.com/pmd/pmd/pull/6112): \[java] DanglingJavadoc: fix false positive for compact constructors - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6114](https://github.com/pmd/pmd/pull/6114): \[java] Fix #4122: CheckResultSet false-positive with local variable - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index b73bc90ca87..4c3ca4add3f 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -277,5 +277,36 @@ + + jdk25-compat-it + + + java25.home + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + jdk25-compat-it + + integration-test + verify + + + + ${java25.home} + ${java25.home}/bin:${env.PATH} + + + + + + + + From 7b1ca772636f9c6c10318936b4eb6f12496c9a45 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 26 Sep 2025 10:06:18 +0200 Subject: [PATCH 1520/1962] [doc] Simplify topnav --- docs/_data/topnav.yml | 4 ---- docs/_includes/topnav.html | 13 ++----------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/docs/_data/topnav.yml b/docs/_data/topnav.yml index 0a4aa13660d..db6f2f8fdc8 100644 --- a/docs/_data/topnav.yml +++ b/docs/_data/topnav.yml @@ -3,10 +3,6 @@ topnav: - title: Topnav items: - - title: Download - external_url: https://github.com/pmd/pmd/releases/latest - - title: Fork us on github - external_url: https://github.com/pmd/pmd #Topnav dropdowns topnav_dropdowns: diff --git a/docs/_includes/topnav.html b/docs/_includes/topnav.html index 11890923f6f..b62b7d37066 100644 --- a/docs/_includes/topnav.html +++ b/docs/_includes/topnav.html @@ -12,17 +12,8 @@ - {% for entry in site.data.topnav.topnav %} - {% for item in entry.items %} - {% if item.external_url %} - - {% elsif page.url contains item.url %} - - {% else %} - - {% endif %} - {% endfor %} - {% endfor %} + + {% for entry in site.data.topnav.topnav_dropdowns %} From ccb3dc06d6d702d7f74c4f5d8942c61ef4c956d3 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 26 Sep 2025 11:40:50 +0200 Subject: [PATCH 1521/1962] [doc] Add PMD Versions Dropdown --- docs/_includes/topnav.html | 24 +++++------------------- docs/js/customscripts.js | 30 ++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/docs/_includes/topnav.html b/docs/_includes/topnav.html index b62b7d37066..d4bcca7189e 100644 --- a/docs/_includes/topnav.html +++ b/docs/_includes/topnav.html @@ -15,25 +15,11 @@ - - {% for entry in site.data.topnav.topnav_dropdowns %} - {% for folder in entry.folders %} - - {% endfor %} - {% endfor %} +
          diff --git a/docs/js/customscripts.js b/docs/js/customscripts.js index 288f48ecd7b..6243665715d 100644 --- a/docs/js/customscripts.js +++ b/docs/js/customscripts.js @@ -69,6 +69,36 @@ $(document).ready(function () { $("#tg-sb-icon").toggleClass('fa-toggle-off'); event.preventDefault(); }); + + // PMD Versions Dropdown in topnav + const versionsList = document.querySelector("#pmdVersions"); + const releasesRequest = new Request("https://api.github.com/repos/pmd/pmd/releases?per_page=5&page=1"); + window + .fetch(releasesRequest) + .then((response) => { + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`); + } + return response.json(); + }) + .then((response) => response.map((r) => r.tag_name.replace('pmd_releases/', ''))) + .then((versions) => { + versions.push('6.55.0'); + return versions.map((version) => { + if (version.endsWith('-SNAPSHOT')) { + return `${version}`; + } else { + return `${version}`; + } + }); + }) + .then((items) => { + versionsList.innerHTML = items.join(); + }) + .catch((error) => { + versionsList.innerHTML = "Couldn't download releases from api.github.com"; + console.log(error); + }); }); // Check if TOC needs to be moved on window resizing From dce2c79ccec4e893a1022f844d5d488051369b30 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 26 Sep 2025 11:41:11 +0200 Subject: [PATCH 1522/1962] [doc] Remove topnav data --- docs/_data/topnav.yml | 8 -------- docs/_includes/links.html | 24 ------------------------ 2 files changed, 32 deletions(-) delete mode 100644 docs/_data/topnav.yml diff --git a/docs/_data/topnav.yml b/docs/_data/topnav.yml deleted file mode 100644 index db6f2f8fdc8..00000000000 --- a/docs/_data/topnav.yml +++ /dev/null @@ -1,8 +0,0 @@ -## Topnav single links -## if you want to list an external url, use external_url instead of url. the theme will apply a different link base. -topnav: -- title: Topnav - items: - -#Topnav dropdowns -topnav_dropdowns: diff --git a/docs/_includes/links.html b/docs/_includes/links.html index 004229987a7..61c64a3f34a 100644 --- a/docs/_includes/links.html +++ b/docs/_includes/links.html @@ -20,27 +20,3 @@ {% endfor %} {% endfor %} {% endfor %} - - -{% comment %} Get links from topnav {% endcomment %} - -{% for entry in site.data.topnav.topnav %} -{% for item in entry.items %} -{% if item.external_url == null %} -[{{item.url | remove: "/" | remove: ".html"}}]: {{item.url | remove: "/"}} -{% endif %} -{% endfor %} -{% endfor %} - -{% comment %}Get links from topnav dropdowns {% endcomment %} - -{% for entry in site.data.topnav.topnav_dropdowns %} -{% for folder in entry.folders %} -{% for folderitem in folder.folderitems %} -{% if folderitem.external_url == null %} -[{{folderitem.url | remove: "/" | remove: ".html"}}]: {{folderitem.url | remove: "/"}} -{% endif %} -{% endfor %} -{% endfor %} -{% endfor %} - From d8f6d4ffbcc61704a1464ebc32bbfc99fec576fd Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 27 Oct 2025 09:14:54 +0100 Subject: [PATCH 1523/1962] [doc] Update release notes (#6097) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 8c236110ede..74041c6829a 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -58,6 +58,7 @@ checkstyle version during the build. * [#5873](https://github.com/pmd/pmd/issues/5873): \[ci] Run integration test with Java 25 * [#6012](https://github.com/pmd/pmd/issues/6012): \[pmd-rulesets] Rulesets should be in alphabetical order * [#6073](https://github.com/pmd/pmd/issues/6073): \[doc] Search improvements + * [#6097](https://github.com/pmd/pmd/issues/6097): \[doc] Add PMD versions dropdown * apex * [#5935](https://github.com/pmd/pmd/issues/5935): \[apex] @SuppressWarnings - allow whitespace around comma when suppressing multiple rules * apex-design @@ -127,6 +128,7 @@ checkstyle version during the build. * [#6083](https://github.com/pmd/pmd/pull/6083): \[java] New rule IdenticalConditionalBranches - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6085](https://github.com/pmd/pmd/pull/6085): \[java] Fix false positive for ModifierOrder - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6093](https://github.com/pmd/pmd/pull/6093): \[ci] Fix #5873: Run integration tests with Java 25 additionally - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6097](https://github.com/pmd/pmd/pull/6097): \[doc] Add PMD versions dropdown - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6100](https://github.com/pmd/pmd/pull/6100): \[java] AvoidDeeplyNestedIfStmts: fix false negative with if-else - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6112](https://github.com/pmd/pmd/pull/6112): \[java] DanglingJavadoc: fix false positive for compact constructors - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6114](https://github.com/pmd/pmd/pull/6114): \[java] Fix #4122: CheckResultSet false-positive with local variable - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) From dd9cca799dc75740a2debfbcc5e30fd5af59f42b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 26 Sep 2025 16:21:00 +0200 Subject: [PATCH 1524/1962] [doc] Add copy url button --- docs/css/customstyles.css | 8 +++++++ docs/js/customscripts.js | 45 ++++++++++++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/docs/css/customstyles.css b/docs/css/customstyles.css index 3a1007f5993..678b8d05baa 100644 --- a/docs/css/customstyles.css +++ b/docs/css/customstyles.css @@ -1272,6 +1272,14 @@ a.edit-header { font-size: 15px; } +.copy-anchor-url { + opacity: 0; +} +:hover > .copy-anchor-url { + opacity: 1; + cursor: pointer; +} + .language-info { margin: 2em; } diff --git a/docs/js/customscripts.js b/docs/js/customscripts.js index 6243665715d..4d160beb68a 100644 --- a/docs/js/customscripts.js +++ b/docs/js/customscripts.js @@ -17,11 +17,6 @@ $(document).ready(function () { headers: 'h2,h3,h4', }); - // activate tooltips. although this is a bootstrap js function, it must be activated this way in your theme. - $('[data-toggle="tooltip"]').tooltip({ - placement: 'top', - }); - /** * AnchorJS */ @@ -39,6 +34,41 @@ $(document).ready(function () { ); } + // Add an "copy url" button to each header + document.querySelectorAll('.anchorjs-link') + .forEach(e => { + const template = document.createElement('template'); + template.innerHTML = ''; + e.parentNode.append(template.content.firstChild); + }); + document.addEventListener('click', event => { + let target = null; + if (event.target.classList.contains('copy-anchor-url')) { + target = event.target; + } else if (event.target.parentNode.classList.contains('copy-anchor-url')) { + target = event.target.parentNode; + } + + if (target) { + if (navigator.clipboard) { + const url = new URL(location.href); + url.hash = event.target.parentNode.id; + event.preventDefault(); + event.stopImmediatePropagation(); + + navigator.clipboard.writeText(url) + .then(() => { + target.firstChild.classList.remove('fa-copy'); + target.firstChild.classList.add('fa-check'); + window.setTimeout(() => { + target.firstChild.classList.remove('fa-check'); + target.firstChild.classList.add('fa-copy'); + }, 500); + }); + } + } + }); + // Check if TOC needs to be moved on page load moveToc(); @@ -99,6 +129,11 @@ $(document).ready(function () { versionsList.innerHTML = "Couldn't download releases from api.github.com"; console.log(error); }); + + // activate tooltips. although this is a bootstrap js function, it must be activated this way in your theme. + $('[data-toggle="tooltip"]').tooltip({ + placement: 'top', + }); }); // Check if TOC needs to be moved on window resizing From 8bcd2d9d4385fbd4f150d3917789ccc4fb00b879 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 26 Sep 2025 16:22:05 +0200 Subject: [PATCH 1525/1962] [doc] Use fontawesome for anchorjs and edit-header links --- docs/css/customstyles.css | 10 +++++++++- docs/js/customscripts.js | 5 ++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/css/customstyles.css b/docs/css/customstyles.css index 678b8d05baa..9f503483bff 100644 --- a/docs/css/customstyles.css +++ b/docs/css/customstyles.css @@ -1269,7 +1269,15 @@ h4.panel-title { } a.edit-header { - font-size: 15px; + opacity: 0; +} +:hover > a.edit-header { + text-decoration: none !important; + opacity: 1; + cursor: pointer; +} +a.edit-header::after { + content: '' !important; /* hide the external link marker */ } .copy-anchor-url { diff --git a/docs/js/customscripts.js b/docs/js/customscripts.js index 4d160beb68a..7ba72abcdba 100644 --- a/docs/js/customscripts.js +++ b/docs/js/customscripts.js @@ -15,11 +15,14 @@ $(document).ready(function () { listType: 'ul', showSpeed: 0, headers: 'h2,h3,h4', + noBackToTopLinks: true, }); /** * AnchorJS */ + anchors.options.icon=''; + anchors.options.class='fas fa-link fa-xs'; anchors.add('h2,h3,h4,h5'); // Add an "Edit on GitHub" button to each header (except h1) @@ -30,7 +33,7 @@ $(document).ready(function () { .append( ' โœ๏ธ๏ธ' + ' role="button" data-toggle="tooltip" data-placement="top" title="Edit on GitHub">๏ธ' ); } From 5f0e6ee19a5139ec048dc8264ba3f541b9ddf09b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 26 Sep 2025 16:22:46 +0200 Subject: [PATCH 1526/1962] [doc] Remove jquery-ui It conflicts with bootstrap's tooltip() and it was only used for the highlight effect of a selected shuffle box. --- docs/assets/README.md | 5 ----- docs/assets/jquery-ui-1.12.1/jquery-ui.min.css | 7 ------- docs/assets/jquery-ui-1.12.1/jquery-ui.min.js | 13 ------------- docs/index.md | 1 - docs/js/shuffle.js | 7 +++++-- 5 files changed, 5 insertions(+), 28 deletions(-) delete mode 100644 docs/assets/jquery-ui-1.12.1/jquery-ui.min.css delete mode 100644 docs/assets/jquery-ui-1.12.1/jquery-ui.min.js diff --git a/docs/assets/README.md b/docs/assets/README.md index f6fffb6f798..15b0b7f6c68 100644 --- a/docs/assets/README.md +++ b/docs/assets/README.md @@ -26,11 +26,6 @@ https://github.com/bryanbraun/anchorjs/releases/tag/4.2.2 https://github.com/tefra/navgoco/releases/tag/0.2.1 -## JQuery UI - -https://jqueryui.com/ -https://jqueryui.com/resources/download/jquery-ui-1.12.1.zip - ## Simple Jekyll Search https://github.com/neilboyd/Simple-Jekyll-Search diff --git a/docs/assets/jquery-ui-1.12.1/jquery-ui.min.css b/docs/assets/jquery-ui-1.12.1/jquery-ui.min.css deleted file mode 100644 index 776e2595ad3..00000000000 --- a/docs/assets/jquery-ui-1.12.1/jquery-ui.min.css +++ /dev/null @@ -1,7 +0,0 @@ -/*! jQuery UI - v1.12.1 - 2016-09-14 -* http://jqueryui.com -* Includes: core.css, accordion.css, autocomplete.css, menu.css, button.css, controlgroup.css, checkboxradio.css, datepicker.css, dialog.css, draggable.css, resizable.css, progressbar.css, selectable.css, selectmenu.css, slider.css, sortable.css, spinner.css, tabs.css, tooltip.css, theme.css -* To view and modify this theme, visit http://jqueryui.com/themeroller/?bgShadowXPos=&bgOverlayXPos=&bgErrorXPos=&bgHighlightXPos=&bgContentXPos=&bgHeaderXPos=&bgActiveXPos=&bgHoverXPos=&bgDefaultXPos=&bgShadowYPos=&bgOverlayYPos=&bgErrorYPos=&bgHighlightYPos=&bgContentYPos=&bgHeaderYPos=&bgActiveYPos=&bgHoverYPos=&bgDefaultYPos=&bgShadowRepeat=&bgOverlayRepeat=&bgErrorRepeat=&bgHighlightRepeat=&bgContentRepeat=&bgHeaderRepeat=&bgActiveRepeat=&bgHoverRepeat=&bgDefaultRepeat=&iconsHover=url(%22images%2Fui-icons_555555_256x240.png%22)&iconsHighlight=url(%22images%2Fui-icons_777620_256x240.png%22)&iconsHeader=url(%22images%2Fui-icons_444444_256x240.png%22)&iconsError=url(%22images%2Fui-icons_cc0000_256x240.png%22)&iconsDefault=url(%22images%2Fui-icons_777777_256x240.png%22)&iconsContent=url(%22images%2Fui-icons_444444_256x240.png%22)&iconsActive=url(%22images%2Fui-icons_ffffff_256x240.png%22)&bgImgUrlShadow=&bgImgUrlOverlay=&bgImgUrlHover=&bgImgUrlHighlight=&bgImgUrlHeader=&bgImgUrlError=&bgImgUrlDefault=&bgImgUrlContent=&bgImgUrlActive=&opacityFilterShadow=Alpha(Opacity%3D30)&opacityFilterOverlay=Alpha(Opacity%3D30)&opacityShadowPerc=30&opacityOverlayPerc=30&iconColorHover=%23555555&iconColorHighlight=%23777620&iconColorHeader=%23444444&iconColorError=%23cc0000&iconColorDefault=%23777777&iconColorContent=%23444444&iconColorActive=%23ffffff&bgImgOpacityShadow=0&bgImgOpacityOverlay=0&bgImgOpacityError=95&bgImgOpacityHighlight=55&bgImgOpacityContent=75&bgImgOpacityHeader=75&bgImgOpacityActive=65&bgImgOpacityHover=75&bgImgOpacityDefault=75&bgTextureShadow=flat&bgTextureOverlay=flat&bgTextureError=flat&bgTextureHighlight=flat&bgTextureContent=flat&bgTextureHeader=flat&bgTextureActive=flat&bgTextureHover=flat&bgTextureDefault=flat&cornerRadius=3px&fwDefault=normal&ffDefault=Arial%2CHelvetica%2Csans-serif&fsDefault=1em&cornerRadiusShadow=8px&thicknessShadow=5px&offsetLeftShadow=0px&offsetTopShadow=0px&opacityShadow=.3&bgColorShadow=%23666666&opacityOverlay=.3&bgColorOverlay=%23aaaaaa&fcError=%235f3f3f&borderColorError=%23f1a899&bgColorError=%23fddfdf&fcHighlight=%23777620&borderColorHighlight=%23dad55e&bgColorHighlight=%23fffa90&fcContent=%23333333&borderColorContent=%23dddddd&bgColorContent=%23ffffff&fcHeader=%23333333&borderColorHeader=%23dddddd&bgColorHeader=%23e9e9e9&fcActive=%23ffffff&borderColorActive=%23003eff&bgColorActive=%23007fff&fcHover=%232b2b2b&borderColorHover=%23cccccc&bgColorHover=%23ededed&fcDefault=%23454545&borderColorDefault=%23c5c5c5&bgColorDefault=%23f6f6f6 -* Copyright jQuery Foundation and other contributors; Licensed MIT */ - -.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important;pointer-events:none}.ui-icon{display:inline-block;vertical-align:middle;margin-top:-.25em;position:relative;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-icon-block{left:50%;margin-left:-8px;display:block}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin:2px 0 0 0;padding:.5em .5em .5em .7em;font-size:100%}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:0}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{margin:0;cursor:pointer;list-style-image:url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")}.ui-menu .ui-menu-item-wrapper{position:relative;padding:3px 1em 3px .4em}.ui-menu .ui-menu-divider{margin:5px 0;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-state-focus,.ui-menu .ui-state-active{margin:-1px}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item-wrapper{padding-left:2em}.ui-menu .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0}.ui-button{padding:.4em 1em;display:inline-block;position:relative;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2em;box-sizing:border-box;text-indent:-9999px;white-space:nowrap}input.ui-button.ui-button-icon-only{text-indent:0}.ui-button-icon-only .ui-icon{position:absolute;top:50%;left:50%;margin-top:-8px;margin-left:-8px}.ui-button.ui-icon-notext .ui-icon{padding:0;width:2.1em;height:2.1em;text-indent:-9999px;white-space:nowrap}input.ui-button.ui-icon-notext .ui-icon{width:auto;height:auto;text-indent:0;white-space:normal;padding:.4em 1em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-controlgroup{vertical-align:middle;display:inline-block}.ui-controlgroup > .ui-controlgroup-item{float:left;margin-left:0;margin-right:0}.ui-controlgroup > .ui-controlgroup-item:focus,.ui-controlgroup > .ui-controlgroup-item.ui-visual-focus{z-index:9999}.ui-controlgroup-vertical > .ui-controlgroup-item{display:block;float:none;width:100%;margin-top:0;margin-bottom:0;text-align:left}.ui-controlgroup-vertical .ui-controlgroup-item{box-sizing:border-box}.ui-controlgroup .ui-controlgroup-label{padding:.4em 1em}.ui-controlgroup .ui-controlgroup-label span{font-size:80%}.ui-controlgroup-horizontal .ui-controlgroup-label + .ui-controlgroup-item{border-left:none}.ui-controlgroup-vertical .ui-controlgroup-label + .ui-controlgroup-item{border-top:none}.ui-controlgroup-horizontal .ui-controlgroup-label.ui-widget-content{border-right:none}.ui-controlgroup-vertical .ui-controlgroup-label.ui-widget-content{border-bottom:none}.ui-controlgroup-vertical .ui-spinner-input{width:75%;width:calc( 100% - 2.4em )}.ui-controlgroup-vertical .ui-spinner .ui-spinner-up{border-top-style:solid}.ui-checkboxradio-label .ui-icon-background{box-shadow:inset 1px 1px 1px #ccc;border-radius:.12em;border:none}.ui-checkboxradio-radio-label .ui-icon-background{width:16px;height:16px;border-radius:1em;overflow:visible;border:none}.ui-checkboxradio-radio-label.ui-checkboxradio-checked .ui-icon,.ui-checkboxradio-radio-label.ui-checkboxradio-checked:hover .ui-icon{background-image:none;width:8px;height:8px;border-width:4px;border-style:solid}.ui-checkboxradio-disabled{pointer-events:none}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:45%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-datepicker .ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat;left:.5em;top:.3em}.ui-dialog{position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:20px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-n{height:2px;top:0}.ui-dialog .ui-resizable-e{width:2px;right:0}.ui-dialog .ui-resizable-s{height:2px;bottom:0}.ui-dialog .ui-resizable-w{width:2px;left:0}.ui-dialog .ui-resizable-se,.ui-dialog .ui-resizable-sw,.ui-dialog .ui-resizable-ne,.ui-dialog .ui-resizable-nw{width:7px;height:7px}.ui-dialog .ui-resizable-se{right:0;bottom:0}.ui-dialog .ui-resizable-sw{left:0;bottom:0}.ui-dialog .ui-resizable-ne{right:0;top:0}.ui-dialog .ui-resizable-nw{left:0;top:0}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");height:100%;filter:alpha(opacity=25);opacity:0.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-selectable{-ms-touch-action:none;touch-action:none}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-selectmenu-menu{padding:0;margin:0;position:absolute;top:0;left:0;display:none}.ui-selectmenu-menu .ui-menu{overflow:auto;overflow-x:hidden;padding-bottom:1px}.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup{font-size:1em;font-weight:bold;line-height:1.5;padding:2px 0.4em;margin:0.5em 0 0 0;height:auto;border:0}.ui-selectmenu-open{display:block}.ui-selectmenu-text{display:block;margin-right:20px;overflow:hidden;text-overflow:ellipsis}.ui-selectmenu-button.ui-button{text-align:left;white-space:nowrap;width:14em}.ui-selectmenu-icon.ui-icon{float:right;margin-top:0}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;-ms-touch-action:none;touch-action:none}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-sortable-handle{-ms-touch-action:none;touch-action:none}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;color:inherit;padding:.222em 0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:2em}.ui-spinner-button{width:1.6em;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top-style:none;border-bottom-style:none;border-right-style:none}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav .ui-tabs-anchor{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor{cursor:text}.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px}body .ui-tooltip{border-width:2px}.ui-widget{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget.ui-widget-content{border:1px solid #c5c5c5}.ui-widget-content{border:1px solid #ddd;background:#fff;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #ddd;background:#e9e9e9;color:#333;font-weight:bold}.ui-widget-header a{color:#333}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default,.ui-button,html .ui-button.ui-state-disabled:hover,html .ui-button.ui-state-disabled:active{border:1px solid #c5c5c5;background:#f6f6f6;font-weight:normal;color:#454545}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited,a.ui-button,a:link.ui-button,a:visited.ui-button,.ui-button{color:#454545;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus,.ui-button:hover,.ui-button:focus{border:1px solid #ccc;background:#ededed;font-weight:normal;color:#2b2b2b}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited,a.ui-button:hover,a.ui-button:focus{color:#2b2b2b;text-decoration:none}.ui-visual-focus{box-shadow:0 0 3px 1px rgb(94,158,214)}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active,a.ui-button:active,.ui-button:active,.ui-button.ui-state-active:hover{border:1px solid #003eff;background:#007fff;font-weight:normal;color:#fff}.ui-icon-background,.ui-state-active .ui-icon-background{border:#003eff;background-color:#fff}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#fff;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #dad55e;background:#fffa90;color:#777620}.ui-state-checked{border:1px solid #dad55e;background:#fffa90}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#777620}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #f1a899;background:#fddfdf;color:#5f3f3f}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#5f3f3f}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#5f3f3f}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon,.ui-button:hover .ui-icon,.ui-button:focus .ui-icon{background-image:url("images/ui-icons_555555_256x240.png")}.ui-state-active .ui-icon,.ui-button:active .ui-icon{background-image:url("images/ui-icons_ffffff_256x240.png")}.ui-state-highlight .ui-icon,.ui-button .ui-state-highlight.ui-icon{background-image:url("images/ui-icons_777620_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cc0000_256x240.png")}.ui-button .ui-icon{background-image:url("images/ui-icons_777777_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-caret-1-n{background-position:0 0}.ui-icon-caret-1-ne{background-position:-16px 0}.ui-icon-caret-1-e{background-position:-32px 0}.ui-icon-caret-1-se{background-position:-48px 0}.ui-icon-caret-1-s{background-position:-65px 0}.ui-icon-caret-1-sw{background-position:-80px 0}.ui-icon-caret-1-w{background-position:-96px 0}.ui-icon-caret-1-nw{background-position:-112px 0}.ui-icon-caret-2-n-s{background-position:-128px 0}.ui-icon-caret-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-65px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-65px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:1px -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:3px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:3px}.ui-widget-overlay{background:#aaa;opacity:.003;filter:Alpha(Opacity=.3)}.ui-widget-shadow{-webkit-box-shadow:0 0 5px #666;box-shadow:0 0 5px #666} \ No newline at end of file diff --git a/docs/assets/jquery-ui-1.12.1/jquery-ui.min.js b/docs/assets/jquery-ui-1.12.1/jquery-ui.min.js deleted file mode 100644 index 25398a16741..00000000000 --- a/docs/assets/jquery-ui-1.12.1/jquery-ui.min.js +++ /dev/null @@ -1,13 +0,0 @@ -/*! jQuery UI - v1.12.1 - 2016-09-14 -* http://jqueryui.com -* Includes: widget.js, position.js, data.js, disable-selection.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/draggable.js, widgets/droppable.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/resizable.js, widgets/selectable.js, widgets/selectmenu.js, widgets/slider.js, widgets/sortable.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js -* Copyright jQuery Foundation and other contributors; Licensed MIT */ - -(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)})(function(t){function e(t){for(var e=t.css("visibility");"inherit"===e;)t=t.parent(),e=t.css("visibility");return"hidden"!==e}function i(t){for(var e,i;t.length&&t[0]!==document;){if(e=t.css("position"),("absolute"===e||"relative"===e||"fixed"===e)&&(i=parseInt(t.css("zIndex"),10),!isNaN(i)&&0!==i))return i;t=t.parent()}return 0}function s(){this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},t.extend(this._defaults,this.regional[""]),this.regional.en=t.extend(!0,{},this.regional[""]),this.regional["en-US"]=t.extend(!0,{},this.regional.en),this.dpDiv=n(t("
          "))}function n(e){var i="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return e.on("mouseout",i,function(){t(this).removeClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).removeClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).removeClass("ui-datepicker-next-hover")}).on("mouseover",i,o)}function o(){t.datepicker._isDisabledDatepicker(m.inline?m.dpDiv.parent()[0]:m.input[0])||(t(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),t(this).addClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).addClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).addClass("ui-datepicker-next-hover"))}function a(e,i){t.extend(e,i);for(var s in i)null==i[s]&&(e[s]=i[s]);return e}function r(t){return function(){var e=this.element.val();t.apply(this,arguments),this._refresh(),e!==this.element.val()&&this._trigger("change")}}t.ui=t.ui||{},t.ui.version="1.12.1";var h=0,l=Array.prototype.slice;t.cleanData=function(e){return function(i){var s,n,o;for(o=0;null!=(n=i[o]);o++)try{s=t._data(n,"events"),s&&s.remove&&t(n).triggerHandler("remove")}catch(a){}e(i)}}(t.cleanData),t.widget=function(e,i,s){var n,o,a,r={},h=e.split(".")[0];e=e.split(".")[1];var l=h+"-"+e;return s||(s=i,i=t.Widget),t.isArray(s)&&(s=t.extend.apply(null,[{}].concat(s))),t.expr[":"][l.toLowerCase()]=function(e){return!!t.data(e,l)},t[h]=t[h]||{},n=t[h][e],o=t[h][e]=function(t,e){return this._createWidget?(arguments.length&&this._createWidget(t,e),void 0):new o(t,e)},t.extend(o,n,{version:s.version,_proto:t.extend({},s),_childConstructors:[]}),a=new i,a.options=t.widget.extend({},a.options),t.each(s,function(e,s){return t.isFunction(s)?(r[e]=function(){function t(){return i.prototype[e].apply(this,arguments)}function n(t){return i.prototype[e].apply(this,t)}return function(){var e,i=this._super,o=this._superApply;return this._super=t,this._superApply=n,e=s.apply(this,arguments),this._super=i,this._superApply=o,e}}(),void 0):(r[e]=s,void 0)}),o.prototype=t.widget.extend(a,{widgetEventPrefix:n?a.widgetEventPrefix||e:e},r,{constructor:o,namespace:h,widgetName:e,widgetFullName:l}),n?(t.each(n._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete n._childConstructors):i._childConstructors.push(o),t.widget.bridge(e,o),o},t.widget.extend=function(e){for(var i,s,n=l.call(arguments,1),o=0,a=n.length;a>o;o++)for(i in n[o])s=n[o][i],n[o].hasOwnProperty(i)&&void 0!==s&&(e[i]=t.isPlainObject(s)?t.isPlainObject(e[i])?t.widget.extend({},e[i],s):t.widget.extend({},s):s);return e},t.widget.bridge=function(e,i){var s=i.prototype.widgetFullName||e;t.fn[e]=function(n){var o="string"==typeof n,a=l.call(arguments,1),r=this;return o?this.length||"instance"!==n?this.each(function(){var i,o=t.data(this,s);return"instance"===n?(r=o,!1):o?t.isFunction(o[n])&&"_"!==n.charAt(0)?(i=o[n].apply(o,a),i!==o&&void 0!==i?(r=i&&i.jquery?r.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+n+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+n+"'")}):r=void 0:(a.length&&(n=t.widget.extend.apply(null,[n].concat(a))),this.each(function(){var e=t.data(this,s);e?(e.option(n||{}),e._init&&e._init()):t.data(this,s,new i(n,this))})),r}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
          ",options:{classes:{},disabled:!1,create:null},_createWidget:function(e,i){i=t(i||this.defaultElement||this)[0],this.element=t(i),this.uuid=h++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},i!==this&&(t.data(i,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===i&&this.destroy()}}),this.document=t(i.style?i.ownerDocument:i.document||i),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+o.eventNamespace,c=h[2];c?n.on(l,c,r):i.on(l,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var n,o=Math.max,a=Math.abs,r=/left|center|right/,h=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,d=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("
          "),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.widthi?"left":e>0?"right":"center",vertical:0>r?"top":s>0?"bottom":"middle"};l>p&&p>a(e+i)&&(u.horizontal="center"),c>f&&f>a(s+r)&&(u.vertical="middle"),u.important=o(a(e),a(i))>o(a(s),a(r))?"horizontal":"vertical",n.using.call(this,t,u)}),h.offset(t.extend(D,{using:r}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-a-n;e.collisionWidth>a?h>0&&0>=l?(i=t.left+h+e.collisionWidth-a-n,t.left+=h-i):t.left=l>0&&0>=h?n:h>l?n+a-e.collisionWidth:n:h>0?t.left+=h:l>0?t.left-=l:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,h=n-r,l=r+e.collisionHeight-a-n;e.collisionHeight>a?h>0&&0>=l?(i=t.top+h+e.collisionHeight-a-n,t.top+=h-i):t.top=l>0&&0>=h?n:h>l?n+a-e.collisionHeight:n:h>0?t.top+=h:l>0?t.top-=l:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,r=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,u=l+e.collisionWidth-r-h,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-r-o,(0>i||a(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-h,(s>0||u>a(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,r=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-r-h,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,g=-2*e.offset[1];0>c?(s=t.top+p+f+g+e.collisionHeight-r-o,(0>s||a(c)>s)&&(t.top+=p+f+g)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+g-h,(i>0||u>a(i))&&(t.top+=p+f+g))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.off(".ui-disableSelection")}});var c="ui-effects-",u="ui-effects-style",d="ui-effects-animated",p=t;t.effects={effect:{}},function(t,e){function i(t,e,i){var s=u[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:0>t?0:t>s.max?s.max:t)}function s(i){var s=l(),n=s._rgba=[];return i=i.toLowerCase(),f(h,function(t,o){var a,r=o.re.exec(i),h=r&&o.parse(r),l=o.space||"rgba";return h?(a=s[l](h),s[c[l].cache]=a[c[l].cache],n=s._rgba=a._rgba,!1):e}),n.length?("0,0,0,0"===n.join()&&t.extend(n,o.transparent),s):o[i]}function n(t,e,i){return i=(i+1)%1,1>6*i?t+6*(e-t)*i:1>2*i?e:2>3*i?t+6*(e-t)*(2/3-i):t}var o,a="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",r=/^([\-+])=\s*(\d+\.?\d*)/,h=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[2.55*t[1],2.55*t[2],2.55*t[3],t[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(t){return[t[1],t[2]/100,t[3]/100,t[4]]}}],l=t.Color=function(e,i,s,n){return new t.Color.fn.parse(e,i,s,n)},c={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},u={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},d=l.support={},p=t("

          ")[0],f=t.each;p.style.cssText="background-color:rgba(1,1,1,.5)",d.rgba=p.style.backgroundColor.indexOf("rgba")>-1,f(c,function(t,e){e.cache="_"+t,e.props.alpha={idx:3,type:"percent",def:1}}),l.fn=t.extend(l.prototype,{parse:function(n,a,r,h){if(n===e)return this._rgba=[null,null,null,null],this;(n.jquery||n.nodeType)&&(n=t(n).css(a),a=e);var u=this,d=t.type(n),p=this._rgba=[];return a!==e&&(n=[n,a,r,h],d="array"),"string"===d?this.parse(s(n)||o._default):"array"===d?(f(c.rgba.props,function(t,e){p[e.idx]=i(n[e.idx],e)}),this):"object"===d?(n instanceof l?f(c,function(t,e){n[e.cache]&&(u[e.cache]=n[e.cache].slice())}):f(c,function(e,s){var o=s.cache;f(s.props,function(t,e){if(!u[o]&&s.to){if("alpha"===t||null==n[t])return;u[o]=s.to(u._rgba)}u[o][e.idx]=i(n[t],e,!0)}),u[o]&&0>t.inArray(null,u[o].slice(0,3))&&(u[o][3]=1,s.from&&(u._rgba=s.from(u[o])))}),this):e},is:function(t){var i=l(t),s=!0,n=this;return f(c,function(t,o){var a,r=i[o.cache];return r&&(a=n[o.cache]||o.to&&o.to(n._rgba)||[],f(o.props,function(t,i){return null!=r[i.idx]?s=r[i.idx]===a[i.idx]:e})),s}),s},_space:function(){var t=[],e=this;return f(c,function(i,s){e[s.cache]&&t.push(i)}),t.pop()},transition:function(t,e){var s=l(t),n=s._space(),o=c[n],a=0===this.alpha()?l("transparent"):this,r=a[o.cache]||o.to(a._rgba),h=r.slice();return s=s[o.cache],f(o.props,function(t,n){var o=n.idx,a=r[o],l=s[o],c=u[n.type]||{};null!==l&&(null===a?h[o]=l:(c.mod&&(l-a>c.mod/2?a+=c.mod:a-l>c.mod/2&&(a-=c.mod)),h[o]=i((l-a)*e+a,n)))}),this[n](h)},blend:function(e){if(1===this._rgba[3])return this;var i=this._rgba.slice(),s=i.pop(),n=l(e)._rgba;return l(t.map(i,function(t,e){return(1-s)*n[e]+s*t}))},toRgbaString:function(){var e="rgba(",i=t.map(this._rgba,function(t,e){return null==t?e>2?1:0:t});return 1===i[3]&&(i.pop(),e="rgb("),e+i.join()+")"},toHslaString:function(){var e="hsla(",i=t.map(this.hsla(),function(t,e){return null==t&&(t=e>2?1:0),e&&3>e&&(t=Math.round(100*t)+"%"),t});return 1===i[3]&&(i.pop(),e="hsl("),e+i.join()+")"},toHexString:function(e){var i=this._rgba.slice(),s=i.pop();return e&&i.push(~~(255*s)),"#"+t.map(i,function(t){return t=(t||0).toString(16),1===t.length?"0"+t:t}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),l.fn.parse.prototype=l.fn,c.hsla.to=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e,i,s=t[0]/255,n=t[1]/255,o=t[2]/255,a=t[3],r=Math.max(s,n,o),h=Math.min(s,n,o),l=r-h,c=r+h,u=.5*c;return e=h===r?0:s===r?60*(n-o)/l+360:n===r?60*(o-s)/l+120:60*(s-n)/l+240,i=0===l?0:.5>=u?l/c:l/(2-c),[Math.round(e)%360,i,u,null==a?1:a]},c.hsla.from=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e=t[0]/360,i=t[1],s=t[2],o=t[3],a=.5>=s?s*(1+i):s+i-s*i,r=2*s-a;return[Math.round(255*n(r,a,e+1/3)),Math.round(255*n(r,a,e)),Math.round(255*n(r,a,e-1/3)),o]},f(c,function(s,n){var o=n.props,a=n.cache,h=n.to,c=n.from;l.fn[s]=function(s){if(h&&!this[a]&&(this[a]=h(this._rgba)),s===e)return this[a].slice();var n,r=t.type(s),u="array"===r||"object"===r?s:arguments,d=this[a].slice();return f(o,function(t,e){var s=u["object"===r?t:e.idx];null==s&&(s=d[e.idx]),d[e.idx]=i(s,e)}),c?(n=l(c(d)),n[a]=d,n):l(d)},f(o,function(e,i){l.fn[e]||(l.fn[e]=function(n){var o,a=t.type(n),h="alpha"===e?this._hsla?"hsla":"rgba":s,l=this[h](),c=l[i.idx];return"undefined"===a?c:("function"===a&&(n=n.call(this,c),a=t.type(n)),null==n&&i.empty?this:("string"===a&&(o=r.exec(n),o&&(n=c+parseFloat(o[2])*("+"===o[1]?1:-1))),l[i.idx]=n,this[h](l)))})})}),l.hook=function(e){var i=e.split(" ");f(i,function(e,i){t.cssHooks[i]={set:function(e,n){var o,a,r="";if("transparent"!==n&&("string"!==t.type(n)||(o=s(n)))){if(n=l(o||n),!d.rgba&&1!==n._rgba[3]){for(a="backgroundColor"===i?e.parentNode:e;(""===r||"transparent"===r)&&a&&a.style;)try{r=t.css(a,"backgroundColor"),a=a.parentNode}catch(h){}n=n.blend(r&&"transparent"!==r?r:"_default")}n=n.toRgbaString()}try{e.style[i]=n}catch(h){}}},t.fx.step[i]=function(e){e.colorInit||(e.start=l(e.elem,i),e.end=l(e.end),e.colorInit=!0),t.cssHooks[i].set(e.elem,e.start.transition(e.end,e.pos))}})},l.hook(a),t.cssHooks.borderColor={expand:function(t){var e={};return f(["Top","Right","Bottom","Left"],function(i,s){e["border"+s+"Color"]=t}),e}},o=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(p),function(){function e(e){var i,s,n=e.ownerDocument.defaultView?e.ownerDocument.defaultView.getComputedStyle(e,null):e.currentStyle,o={};if(n&&n.length&&n[0]&&n[n[0]])for(s=n.length;s--;)i=n[s],"string"==typeof n[i]&&(o[t.camelCase(i)]=n[i]);else for(i in n)"string"==typeof n[i]&&(o[i]=n[i]);return o}function i(e,i){var s,o,a={};for(s in i)o=i[s],e[s]!==o&&(n[s]||(t.fx.step[s]||!isNaN(parseFloat(o)))&&(a[s]=o));return a}var s=["add","remove","toggle"],n={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};t.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(e,i){t.fx.step[i]=function(t){("none"!==t.end&&!t.setAttr||1===t.pos&&!t.setAttr)&&(p.style(t.elem,i,t.end),t.setAttr=!0)}}),t.fn.addBack||(t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.effects.animateClass=function(n,o,a,r){var h=t.speed(o,a,r);return this.queue(function(){var o,a=t(this),r=a.attr("class")||"",l=h.children?a.find("*").addBack():a;l=l.map(function(){var i=t(this);return{el:i,start:e(this)}}),o=function(){t.each(s,function(t,e){n[e]&&a[e+"Class"](n[e])})},o(),l=l.map(function(){return this.end=e(this.el[0]),this.diff=i(this.start,this.end),this}),a.attr("class",r),l=l.map(function(){var e=this,i=t.Deferred(),s=t.extend({},h,{queue:!1,complete:function(){i.resolve(e)}});return this.el.animate(this.diff,s),i.promise()}),t.when.apply(t,l.get()).done(function(){o(),t.each(arguments,function(){var e=this.el;t.each(this.diff,function(t){e.css(t,"")})}),h.complete.call(a[0])})})},t.fn.extend({addClass:function(e){return function(i,s,n,o){return s?t.effects.animateClass.call(this,{add:i},s,n,o):e.apply(this,arguments)}}(t.fn.addClass),removeClass:function(e){return function(i,s,n,o){return arguments.length>1?t.effects.animateClass.call(this,{remove:i},s,n,o):e.apply(this,arguments)}}(t.fn.removeClass),toggleClass:function(e){return function(i,s,n,o,a){return"boolean"==typeof s||void 0===s?n?t.effects.animateClass.call(this,s?{add:i}:{remove:i},n,o,a):e.apply(this,arguments):t.effects.animateClass.call(this,{toggle:i},s,n,o)}}(t.fn.toggleClass),switchClass:function(e,i,s,n,o){return t.effects.animateClass.call(this,{add:i,remove:e},s,n,o)}})}(),function(){function e(e,i,s,n){return t.isPlainObject(e)&&(i=e,e=e.effect),e={effect:e},null==i&&(i={}),t.isFunction(i)&&(n=i,s=null,i={}),("number"==typeof i||t.fx.speeds[i])&&(n=s,s=i,i={}),t.isFunction(s)&&(n=s,s=null),i&&t.extend(e,i),s=s||i.duration,e.duration=t.fx.off?0:"number"==typeof s?s:s in t.fx.speeds?t.fx.speeds[s]:t.fx.speeds._default,e.complete=n||i.complete,e}function i(e){return!e||"number"==typeof e||t.fx.speeds[e]?!0:"string"!=typeof e||t.effects.effect[e]?t.isFunction(e)?!0:"object"!=typeof e||e.effect?!1:!0:!0}function s(t,e){var i=e.outerWidth(),s=e.outerHeight(),n=/^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/,o=n.exec(t)||["",0,i,s,0];return{top:parseFloat(o[1])||0,right:"auto"===o[2]?i:parseFloat(o[2]),bottom:"auto"===o[3]?s:parseFloat(o[3]),left:parseFloat(o[4])||0}}t.expr&&t.expr.filters&&t.expr.filters.animated&&(t.expr.filters.animated=function(e){return function(i){return!!t(i).data(d)||e(i)}}(t.expr.filters.animated)),t.uiBackCompat!==!1&&t.extend(t.effects,{save:function(t,e){for(var i=0,s=e.length;s>i;i++)null!==e[i]&&t.data(c+e[i],t[0].style[e[i]])},restore:function(t,e){for(var i,s=0,n=e.length;n>s;s++)null!==e[s]&&(i=t.data(c+e[s]),t.css(e[s],i))},setMode:function(t,e){return"toggle"===e&&(e=t.is(":hidden")?"show":"hide"),e},createWrapper:function(e){if(e.parent().is(".ui-effects-wrapper"))return e.parent();var i={width:e.outerWidth(!0),height:e.outerHeight(!0),"float":e.css("float")},s=t("

          ").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),n={width:e.width(),height:e.height()},o=document.activeElement;try{o.id}catch(a){o=document.body}return e.wrap(s),(e[0]===o||t.contains(e[0],o))&&t(o).trigger("focus"),s=e.parent(),"static"===e.css("position")?(s.css({position:"relative"}),e.css({position:"relative"})):(t.extend(i,{position:e.css("position"),zIndex:e.css("z-index")}),t.each(["top","left","bottom","right"],function(t,s){i[s]=e.css(s),isNaN(parseInt(i[s],10))&&(i[s]="auto")}),e.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),e.css(n),s.css(i).show()},removeWrapper:function(e){var i=document.activeElement;return e.parent().is(".ui-effects-wrapper")&&(e.parent().replaceWith(e),(e[0]===i||t.contains(e[0],i))&&t(i).trigger("focus")),e}}),t.extend(t.effects,{version:"1.12.1",define:function(e,i,s){return s||(s=i,i="effect"),t.effects.effect[e]=s,t.effects.effect[e].mode=i,s},scaledDimensions:function(t,e,i){if(0===e)return{height:0,width:0,outerHeight:0,outerWidth:0};var s="horizontal"!==i?(e||100)/100:1,n="vertical"!==i?(e||100)/100:1;return{height:t.height()*n,width:t.width()*s,outerHeight:t.outerHeight()*n,outerWidth:t.outerWidth()*s}},clipToBox:function(t){return{width:t.clip.right-t.clip.left,height:t.clip.bottom-t.clip.top,left:t.clip.left,top:t.clip.top}},unshift:function(t,e,i){var s=t.queue();e>1&&s.splice.apply(s,[1,0].concat(s.splice(e,i))),t.dequeue()},saveStyle:function(t){t.data(u,t[0].style.cssText)},restoreStyle:function(t){t[0].style.cssText=t.data(u)||"",t.removeData(u)},mode:function(t,e){var i=t.is(":hidden");return"toggle"===e&&(e=i?"show":"hide"),(i?"hide"===e:"show"===e)&&(e="none"),e},getBaseline:function(t,e){var i,s;switch(t[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=t[0]/e.height}switch(t[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=t[1]/e.width}return{x:s,y:i}},createPlaceholder:function(e){var i,s=e.css("position"),n=e.position();return e.css({marginTop:e.css("marginTop"),marginBottom:e.css("marginBottom"),marginLeft:e.css("marginLeft"),marginRight:e.css("marginRight")}).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()),/^(static|relative)/.test(s)&&(s="absolute",i=t("<"+e[0].nodeName+">").insertAfter(e).css({display:/^(inline|ruby)/.test(e.css("display"))?"inline-block":"block",visibility:"hidden",marginTop:e.css("marginTop"),marginBottom:e.css("marginBottom"),marginLeft:e.css("marginLeft"),marginRight:e.css("marginRight"),"float":e.css("float")}).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).addClass("ui-effects-placeholder"),e.data(c+"placeholder",i)),e.css({position:s,left:n.left,top:n.top}),i},removePlaceholder:function(t){var e=c+"placeholder",i=t.data(e);i&&(i.remove(),t.removeData(e))},cleanUp:function(e){t.effects.restoreStyle(e),t.effects.removePlaceholder(e)},setTransition:function(e,i,s,n){return n=n||{},t.each(i,function(t,i){var o=e.cssUnit(i);o[0]>0&&(n[i]=o[0]*s+o[1])}),n}}),t.fn.extend({effect:function(){function i(e){function i(){r.removeData(d),t.effects.cleanUp(r),"hide"===s.mode&&r.hide(),a()}function a(){t.isFunction(h)&&h.call(r[0]),t.isFunction(e)&&e()}var r=t(this);s.mode=c.shift(),t.uiBackCompat===!1||o?"none"===s.mode?(r[l](),a()):n.call(r[0],s,i):(r.is(":hidden")?"hide"===l:"show"===l)?(r[l](),a()):n.call(r[0],s,a)}var s=e.apply(this,arguments),n=t.effects.effect[s.effect],o=n.mode,a=s.queue,r=a||"fx",h=s.complete,l=s.mode,c=[],u=function(e){var i=t(this),s=t.effects.mode(i,l)||o;i.data(d,!0),c.push(s),o&&("show"===s||s===o&&"hide"===s)&&i.show(),o&&"none"===s||t.effects.saveStyle(i),t.isFunction(e)&&e()};return t.fx.off||!n?l?this[l](s.duration,h):this.each(function(){h&&h.call(this)}):a===!1?this.each(u).each(i):this.queue(r,u).queue(r,i)},show:function(t){return function(s){if(i(s))return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="show",this.effect.call(this,n) -}}(t.fn.show),hide:function(t){return function(s){if(i(s))return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="hide",this.effect.call(this,n)}}(t.fn.hide),toggle:function(t){return function(s){if(i(s)||"boolean"==typeof s)return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="toggle",this.effect.call(this,n)}}(t.fn.toggle),cssUnit:function(e){var i=this.css(e),s=[];return t.each(["em","px","%","pt"],function(t,e){i.indexOf(e)>0&&(s=[parseFloat(i),e])}),s},cssClip:function(t){return t?this.css("clip","rect("+t.top+"px "+t.right+"px "+t.bottom+"px "+t.left+"px)"):s(this.css("clip"),this)},transfer:function(e,i){var s=t(this),n=t(e.to),o="fixed"===n.css("position"),a=t("body"),r=o?a.scrollTop():0,h=o?a.scrollLeft():0,l=n.offset(),c={top:l.top-r,left:l.left-h,height:n.innerHeight(),width:n.innerWidth()},u=s.offset(),d=t("
          ").appendTo("body").addClass(e.className).css({top:u.top-r,left:u.left-h,height:s.innerHeight(),width:s.innerWidth(),position:o?"fixed":"absolute"}).animate(c,e.duration,e.easing,function(){d.remove(),t.isFunction(i)&&i()})}}),t.fx.step.clip=function(e){e.clipInit||(e.start=t(e.elem).cssClip(),"string"==typeof e.end&&(e.end=s(e.end,e.elem)),e.clipInit=!0),t(e.elem).cssClip({top:e.pos*(e.end.top-e.start.top)+e.start.top,right:e.pos*(e.end.right-e.start.right)+e.start.right,bottom:e.pos*(e.end.bottom-e.start.bottom)+e.start.bottom,left:e.pos*(e.end.left-e.start.left)+e.start.left})}}(),function(){var e={};t.each(["Quad","Cubic","Quart","Quint","Expo"],function(t,i){e[i]=function(e){return Math.pow(e,t+2)}}),t.extend(e,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;((e=Math.pow(2,--i))-1)/11>t;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),t.each(e,function(e,i){t.easing["easeIn"+e]=i,t.easing["easeOut"+e]=function(t){return 1-i(1-t)},t.easing["easeInOut"+e]=function(t){return.5>t?i(2*t)/2:1-i(-2*t+2)/2}})}();var f=t.effects;t.effects.define("blind","hide",function(e,i){var s={up:["bottom","top"],vertical:["bottom","top"],down:["top","bottom"],left:["right","left"],horizontal:["right","left"],right:["left","right"]},n=t(this),o=e.direction||"up",a=n.cssClip(),r={clip:t.extend({},a)},h=t.effects.createPlaceholder(n);r.clip[s[o][0]]=r.clip[s[o][1]],"show"===e.mode&&(n.cssClip(r.clip),h&&h.css(t.effects.clipToBox(r)),r.clip=a),h&&h.animate(t.effects.clipToBox(r),e.duration,e.easing),n.animate(r,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("bounce",function(e,i){var s,n,o,a=t(this),r=e.mode,h="hide"===r,l="show"===r,c=e.direction||"up",u=e.distance,d=e.times||5,p=2*d+(l||h?1:0),f=e.duration/p,g=e.easing,m="up"===c||"down"===c?"top":"left",_="up"===c||"left"===c,v=0,b=a.queue().length;for(t.effects.createPlaceholder(a),o=a.css(m),u||(u=a["top"===m?"outerHeight":"outerWidth"]()/3),l&&(n={opacity:1},n[m]=o,a.css("opacity",0).css(m,_?2*-u:2*u).animate(n,f,g)),h&&(u/=Math.pow(2,d-1)),n={},n[m]=o;d>v;v++)s={},s[m]=(_?"-=":"+=")+u,a.animate(s,f,g).animate(n,f,g),u=h?2*u:u/2;h&&(s={opacity:0},s[m]=(_?"-=":"+=")+u,a.animate(s,f,g)),a.queue(i),t.effects.unshift(a,b,p+1)}),t.effects.define("clip","hide",function(e,i){var s,n={},o=t(this),a=e.direction||"vertical",r="both"===a,h=r||"horizontal"===a,l=r||"vertical"===a;s=o.cssClip(),n.clip={top:l?(s.bottom-s.top)/2:s.top,right:h?(s.right-s.left)/2:s.right,bottom:l?(s.bottom-s.top)/2:s.bottom,left:h?(s.right-s.left)/2:s.left},t.effects.createPlaceholder(o),"show"===e.mode&&(o.cssClip(n.clip),n.clip=s),o.animate(n,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("drop","hide",function(e,i){var s,n=t(this),o=e.mode,a="show"===o,r=e.direction||"left",h="up"===r||"down"===r?"top":"left",l="up"===r||"left"===r?"-=":"+=",c="+="===l?"-=":"+=",u={opacity:0};t.effects.createPlaceholder(n),s=e.distance||n["top"===h?"outerHeight":"outerWidth"](!0)/2,u[h]=l+s,a&&(n.css(u),u[h]=c+s,u.opacity=1),n.animate(u,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("explode","hide",function(e,i){function s(){b.push(this),b.length===u*d&&n()}function n(){p.css({visibility:"visible"}),t(b).remove(),i()}var o,a,r,h,l,c,u=e.pieces?Math.round(Math.sqrt(e.pieces)):3,d=u,p=t(this),f=e.mode,g="show"===f,m=p.show().css("visibility","hidden").offset(),_=Math.ceil(p.outerWidth()/d),v=Math.ceil(p.outerHeight()/u),b=[];for(o=0;u>o;o++)for(h=m.top+o*v,c=o-(u-1)/2,a=0;d>a;a++)r=m.left+a*_,l=a-(d-1)/2,p.clone().appendTo("body").wrap("
          ").css({position:"absolute",visibility:"visible",left:-a*_,top:-o*v}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:_,height:v,left:r+(g?l*_:0),top:h+(g?c*v:0),opacity:g?0:1}).animate({left:r+(g?0:l*_),top:h+(g?0:c*v),opacity:g?1:0},e.duration||500,e.easing,s)}),t.effects.define("fade","toggle",function(e,i){var s="show"===e.mode;t(this).css("opacity",s?0:1).animate({opacity:s?1:0},{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("fold","hide",function(e,i){var s=t(this),n=e.mode,o="show"===n,a="hide"===n,r=e.size||15,h=/([0-9]+)%/.exec(r),l=!!e.horizFirst,c=l?["right","bottom"]:["bottom","right"],u=e.duration/2,d=t.effects.createPlaceholder(s),p=s.cssClip(),f={clip:t.extend({},p)},g={clip:t.extend({},p)},m=[p[c[0]],p[c[1]]],_=s.queue().length;h&&(r=parseInt(h[1],10)/100*m[a?0:1]),f.clip[c[0]]=r,g.clip[c[0]]=r,g.clip[c[1]]=0,o&&(s.cssClip(g.clip),d&&d.css(t.effects.clipToBox(g)),g.clip=p),s.queue(function(i){d&&d.animate(t.effects.clipToBox(f),u,e.easing).animate(t.effects.clipToBox(g),u,e.easing),i()}).animate(f,u,e.easing).animate(g,u,e.easing).queue(i),t.effects.unshift(s,_,4)}),t.effects.define("highlight","show",function(e,i){var s=t(this),n={backgroundColor:s.css("backgroundColor")};"hide"===e.mode&&(n.opacity=0),t.effects.saveStyle(s),s.css({backgroundImage:"none",backgroundColor:e.color||"#ffff99"}).animate(n,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("size",function(e,i){var s,n,o,a=t(this),r=["fontSize"],h=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],l=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],c=e.mode,u="effect"!==c,d=e.scale||"both",p=e.origin||["middle","center"],f=a.css("position"),g=a.position(),m=t.effects.scaledDimensions(a),_=e.from||m,v=e.to||t.effects.scaledDimensions(a,0);t.effects.createPlaceholder(a),"show"===c&&(o=_,_=v,v=o),n={from:{y:_.height/m.height,x:_.width/m.width},to:{y:v.height/m.height,x:v.width/m.width}},("box"===d||"both"===d)&&(n.from.y!==n.to.y&&(_=t.effects.setTransition(a,h,n.from.y,_),v=t.effects.setTransition(a,h,n.to.y,v)),n.from.x!==n.to.x&&(_=t.effects.setTransition(a,l,n.from.x,_),v=t.effects.setTransition(a,l,n.to.x,v))),("content"===d||"both"===d)&&n.from.y!==n.to.y&&(_=t.effects.setTransition(a,r,n.from.y,_),v=t.effects.setTransition(a,r,n.to.y,v)),p&&(s=t.effects.getBaseline(p,m),_.top=(m.outerHeight-_.outerHeight)*s.y+g.top,_.left=(m.outerWidth-_.outerWidth)*s.x+g.left,v.top=(m.outerHeight-v.outerHeight)*s.y+g.top,v.left=(m.outerWidth-v.outerWidth)*s.x+g.left),a.css(_),("content"===d||"both"===d)&&(h=h.concat(["marginTop","marginBottom"]).concat(r),l=l.concat(["marginLeft","marginRight"]),a.find("*[width]").each(function(){var i=t(this),s=t.effects.scaledDimensions(i),o={height:s.height*n.from.y,width:s.width*n.from.x,outerHeight:s.outerHeight*n.from.y,outerWidth:s.outerWidth*n.from.x},a={height:s.height*n.to.y,width:s.width*n.to.x,outerHeight:s.height*n.to.y,outerWidth:s.width*n.to.x};n.from.y!==n.to.y&&(o=t.effects.setTransition(i,h,n.from.y,o),a=t.effects.setTransition(i,h,n.to.y,a)),n.from.x!==n.to.x&&(o=t.effects.setTransition(i,l,n.from.x,o),a=t.effects.setTransition(i,l,n.to.x,a)),u&&t.effects.saveStyle(i),i.css(o),i.animate(a,e.duration,e.easing,function(){u&&t.effects.restoreStyle(i)})})),a.animate(v,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){var e=a.offset();0===v.opacity&&a.css("opacity",_.opacity),u||(a.css("position","static"===f?"relative":f).offset(e),t.effects.saveStyle(a)),i()}})}),t.effects.define("scale",function(e,i){var s=t(this),n=e.mode,o=parseInt(e.percent,10)||(0===parseInt(e.percent,10)?0:"effect"!==n?0:100),a=t.extend(!0,{from:t.effects.scaledDimensions(s),to:t.effects.scaledDimensions(s,o,e.direction||"both"),origin:e.origin||["middle","center"]},e);e.fade&&(a.from.opacity=1,a.to.opacity=0),t.effects.effect.size.call(this,a,i)}),t.effects.define("puff","hide",function(e,i){var s=t.extend(!0,{},e,{fade:!0,percent:parseInt(e.percent,10)||150});t.effects.effect.scale.call(this,s,i)}),t.effects.define("pulsate","show",function(e,i){var s=t(this),n=e.mode,o="show"===n,a="hide"===n,r=o||a,h=2*(e.times||5)+(r?1:0),l=e.duration/h,c=0,u=1,d=s.queue().length;for((o||!s.is(":visible"))&&(s.css("opacity",0).show(),c=1);h>u;u++)s.animate({opacity:c},l,e.easing),c=1-c;s.animate({opacity:c},l,e.easing),s.queue(i),t.effects.unshift(s,d,h+1)}),t.effects.define("shake",function(e,i){var s=1,n=t(this),o=e.direction||"left",a=e.distance||20,r=e.times||3,h=2*r+1,l=Math.round(e.duration/h),c="up"===o||"down"===o?"top":"left",u="up"===o||"left"===o,d={},p={},f={},g=n.queue().length;for(t.effects.createPlaceholder(n),d[c]=(u?"-=":"+=")+a,p[c]=(u?"+=":"-=")+2*a,f[c]=(u?"-=":"+=")+2*a,n.animate(d,l,e.easing);r>s;s++)n.animate(p,l,e.easing).animate(f,l,e.easing);n.animate(p,l,e.easing).animate(d,l/2,e.easing).queue(i),t.effects.unshift(n,g,h+1)}),t.effects.define("slide","show",function(e,i){var s,n,o=t(this),a={up:["bottom","top"],down:["top","bottom"],left:["right","left"],right:["left","right"]},r=e.mode,h=e.direction||"left",l="up"===h||"down"===h?"top":"left",c="up"===h||"left"===h,u=e.distance||o["top"===l?"outerHeight":"outerWidth"](!0),d={};t.effects.createPlaceholder(o),s=o.cssClip(),n=o.position()[l],d[l]=(c?-1:1)*u+n,d.clip=o.cssClip(),d.clip[a[h][1]]=d.clip[a[h][0]],"show"===r&&(o.cssClip(d.clip),o.css(l,d[l]),d.clip=s,d[l]=n),o.animate(d,{queue:!1,duration:e.duration,easing:e.easing,complete:i})});var f;t.uiBackCompat!==!1&&(f=t.effects.define("transfer",function(e,i){t(this).transfer(e,i)})),t.ui.focusable=function(i,s){var n,o,a,r,h,l=i.nodeName.toLowerCase();return"area"===l?(n=i.parentNode,o=n.name,i.href&&o&&"map"===n.nodeName.toLowerCase()?(a=t("img[usemap='#"+o+"']"),a.length>0&&a.is(":visible")):!1):(/^(input|select|textarea|button|object)$/.test(l)?(r=!i.disabled,r&&(h=t(i).closest("fieldset")[0],h&&(r=!h.disabled))):r="a"===l?i.href||s:s,r&&t(i).is(":visible")&&e(t(i)))},t.extend(t.expr[":"],{focusable:function(e){return t.ui.focusable(e,null!=t.attr(e,"tabindex"))}}),t.ui.focusable,t.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):t(this[0].form)},t.ui.formResetMixin={_formResetHandler:function(){var e=t(this);setTimeout(function(){var i=e.data("ui-form-reset-instances");t.each(i,function(){this.refresh()})})},_bindFormResetHandler:function(){if(this.form=this.element.form(),this.form.length){var t=this.form.data("ui-form-reset-instances")||[];t.length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t)}},_unbindFormResetHandler:function(){if(this.form.length){var e=this.form.data("ui-form-reset-instances");e.splice(t.inArray(this,e),1),e.length?this.form.data("ui-form-reset-instances",e):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset")}}},"1.7"===t.fn.jquery.substring(0,3)&&(t.each(["Width","Height"],function(e,i){function s(e,i,s,o){return t.each(n,function(){i-=parseFloat(t.css(e,"padding"+this))||0,s&&(i-=parseFloat(t.css(e,"border"+this+"Width"))||0),o&&(i-=parseFloat(t.css(e,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],o=i.toLowerCase(),a={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+i]=function(e){return void 0===e?a["inner"+i].call(this):this.each(function(){t(this).css(o,s(this,e)+"px")})},t.fn["outer"+i]=function(e,n){return"number"!=typeof e?a["outer"+i].call(this,e):this.each(function(){t(this).css(o,s(this,e,!0,n)+"px")})}}),t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.ui.escapeSelector=function(){var t=/([!"#$%&'()*+,.\/:;<=>?@[\]^`{|}~])/g;return function(e){return e.replace(t,"\\$1")}}(),t.fn.labels=function(){var e,i,s,n,o;return this[0].labels&&this[0].labels.length?this.pushStack(this[0].labels):(n=this.eq(0).parents("label"),s=this.attr("id"),s&&(e=this.eq(0).parents().last(),o=e.add(e.length?e.siblings():this.siblings()),i="label[for='"+t.ui.escapeSelector(s)+"']",n=n.add(o.find(i).addBack(i))),this.pushStack(n))},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.extend(t.expr[":"],{tabbable:function(e){var i=t.attr(e,"tabindex"),s=null!=i;return(!s||i>=0)&&t.ui.focusable(e,s)}}),t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.widget("ui.accordion",{version:"1.12.1",options:{active:0,animate:{},classes:{"ui-accordion-header":"ui-corner-top","ui-accordion-header-collapsed":"ui-corner-all","ui-accordion-content":"ui-corner-bottom"},collapsible:!1,event:"click",header:"> li > :first-child, > :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},hideProps:{borderTopWidth:"hide",borderBottomWidth:"hide",paddingTop:"hide",paddingBottom:"hide",height:"hide"},showProps:{borderTopWidth:"show",borderBottomWidth:"show",paddingTop:"show",paddingBottom:"show",height:"show"},_create:function(){var e=this.options;this.prevShow=this.prevHide=t(),this._addClass("ui-accordion","ui-widget ui-helper-reset"),this.element.attr("role","tablist"),e.collapsible||e.active!==!1&&null!=e.active||(e.active=0),this._processPanels(),0>e.active&&(e.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():t()}},_createIcons:function(){var e,i,s=this.options.icons;s&&(e=t(""),this._addClass(e,"ui-accordion-header-icon","ui-icon "+s.header),e.prependTo(this.headers),i=this.active.children(".ui-accordion-header-icon"),this._removeClass(i,s.header)._addClass(i,null,s.activeHeader)._addClass(this.headers,"ui-accordion-icons"))},_destroyIcons:function(){this._removeClass(this.headers,"ui-accordion-icons"),this.headers.children(".ui-accordion-header-icon").remove()},_destroy:function(){var t;this.element.removeAttr("role"),this.headers.removeAttr("role aria-expanded aria-selected aria-controls tabIndex").removeUniqueId(),this._destroyIcons(),t=this.headers.next().css("display","").removeAttr("role aria-hidden aria-labelledby").removeUniqueId(),"content"!==this.options.heightStyle&&t.css("height","")},_setOption:function(t,e){return"active"===t?(this._activate(e),void 0):("event"===t&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(e)),this._super(t,e),"collapsible"!==t||e||this.options.active!==!1||this._activate(0),"icons"===t&&(this._destroyIcons(),e&&this._createIcons()),void 0)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t),this._toggleClass(null,"ui-state-disabled",!!t),this._toggleClass(this.headers.add(this.headers.next()),null,"ui-state-disabled",!!t)},_keydown:function(e){if(!e.altKey&&!e.ctrlKey){var i=t.ui.keyCode,s=this.headers.length,n=this.headers.index(e.target),o=!1;switch(e.keyCode){case i.RIGHT:case i.DOWN:o=this.headers[(n+1)%s];break;case i.LEFT:case i.UP:o=this.headers[(n-1+s)%s];break;case i.SPACE:case i.ENTER:this._eventHandler(e);break;case i.HOME:o=this.headers[0];break;case i.END:o=this.headers[s-1]}o&&(t(e.target).attr("tabIndex",-1),t(o).attr("tabIndex",0),t(o).trigger("focus"),e.preventDefault())}},_panelKeyDown:function(e){e.keyCode===t.ui.keyCode.UP&&e.ctrlKey&&t(e.currentTarget).prev().trigger("focus")},refresh:function(){var e=this.options;this._processPanels(),e.active===!1&&e.collapsible===!0||!this.headers.length?(e.active=!1,this.active=t()):e.active===!1?this._activate(0):this.active.length&&!t.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(e.active=!1,this.active=t()):this._activate(Math.max(0,e.active-1)):e.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){var t=this.headers,e=this.panels;this.headers=this.element.find(this.options.header),this._addClass(this.headers,"ui-accordion-header ui-accordion-header-collapsed","ui-state-default"),this.panels=this.headers.next().filter(":not(.ui-accordion-content-active)").hide(),this._addClass(this.panels,"ui-accordion-content","ui-helper-reset ui-widget-content"),e&&(this._off(t.not(this.headers)),this._off(e.not(this.panels)))},_refresh:function(){var e,i=this.options,s=i.heightStyle,n=this.element.parent();this.active=this._findActive(i.active),this._addClass(this.active,"ui-accordion-header-active","ui-state-active")._removeClass(this.active,"ui-accordion-header-collapsed"),this._addClass(this.active.next(),"ui-accordion-content-active"),this.active.next().show(),this.headers.attr("role","tab").each(function(){var e=t(this),i=e.uniqueId().attr("id"),s=e.next(),n=s.uniqueId().attr("id");e.attr("aria-controls",n),s.attr("aria-labelledby",i)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}).next().attr({"aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}).next().attr({"aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(i.event),"fill"===s?(e=n.height(),this.element.siblings(":visible").each(function(){var i=t(this),s=i.css("position");"absolute"!==s&&"fixed"!==s&&(e-=i.outerHeight(!0))}),this.headers.each(function(){e-=t(this).outerHeight(!0)}),this.headers.next().each(function(){t(this).height(Math.max(0,e-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===s&&(e=0,this.headers.next().each(function(){var i=t(this).is(":visible");i||t(this).show(),e=Math.max(e,t(this).css("height","").height()),i||t(this).hide()}).height(e))},_activate:function(e){var i=this._findActive(e)[0];i!==this.active[0]&&(i=i||this.active[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return"number"==typeof e?this.headers.eq(e):t()},_setupEvents:function(e){var i={keydown:"_keydown"};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(e){var i,s,n=this.options,o=this.active,a=t(e.currentTarget),r=a[0]===o[0],h=r&&n.collapsible,l=h?t():a.next(),c=o.next(),u={oldHeader:o,oldPanel:c,newHeader:h?t():a,newPanel:l};e.preventDefault(),r&&!n.collapsible||this._trigger("beforeActivate",e,u)===!1||(n.active=h?!1:this.headers.index(a),this.active=r?t():a,this._toggle(u),this._removeClass(o,"ui-accordion-header-active","ui-state-active"),n.icons&&(i=o.children(".ui-accordion-header-icon"),this._removeClass(i,null,n.icons.activeHeader)._addClass(i,null,n.icons.header)),r||(this._removeClass(a,"ui-accordion-header-collapsed")._addClass(a,"ui-accordion-header-active","ui-state-active"),n.icons&&(s=a.children(".ui-accordion-header-icon"),this._removeClass(s,null,n.icons.header)._addClass(s,null,n.icons.activeHeader)),this._addClass(a.next(),"ui-accordion-content-active")))},_toggle:function(e){var i=e.newPanel,s=this.prevShow.length?this.prevShow:e.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=i,this.prevHide=s,this.options.animate?this._animate(i,s,e):(s.hide(),i.show(),this._toggleComplete(e)),s.attr({"aria-hidden":"true"}),s.prev().attr({"aria-selected":"false","aria-expanded":"false"}),i.length&&s.length?s.prev().attr({tabIndex:-1,"aria-expanded":"false"}):i.length&&this.headers.filter(function(){return 0===parseInt(t(this).attr("tabIndex"),10)}).attr("tabIndex",-1),i.attr("aria-hidden","false").prev().attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_animate:function(t,e,i){var s,n,o,a=this,r=0,h=t.css("box-sizing"),l=t.length&&(!e.length||t.index()",delay:300,options:{icons:{submenu:"ui-icon-caret-1-e"},items:"> *",menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().attr({role:this.options.role,tabIndex:0}),this._addClass("ui-menu","ui-widget ui-widget-content"),this._on({"mousedown .ui-menu-item":function(t){t.preventDefault()},"click .ui-menu-item":function(e){var i=t(e.target),s=t(t.ui.safeActiveElement(this.document[0]));!this.mouseHandled&&i.not(".ui-state-disabled").length&&(this.select(e),e.isPropagationStopped()||(this.mouseHandled=!0),i.has(".ui-menu").length?this.expand(e):!this.element.is(":focus")&&s.closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(e){if(!this.previousFilter){var i=t(e.target).closest(".ui-menu-item"),s=t(e.currentTarget);i[0]===s[0]&&(this._removeClass(s.siblings().children(".ui-state-active"),null,"ui-state-active"),this.focus(e,s))}},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this.element.find(this.options.items).eq(0);e||this.focus(t,i)},blur:function(e){this._delay(function(){var i=!t.contains(this.element[0],t.ui.safeActiveElement(this.document[0]));i&&this.collapseAll(e)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){this._closeOnDocumentClick(t)&&this.collapseAll(t),this.mouseHandled=!1}})},_destroy:function(){var e=this.element.find(".ui-menu-item").removeAttr("role aria-disabled"),i=e.children(".ui-menu-item-wrapper").removeUniqueId().removeAttr("tabIndex role aria-haspopup");this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled tabIndex").removeUniqueId().show(),i.children().each(function(){var e=t(this);e.data("ui-menu-submenu-caret")&&e.remove()})},_keydown:function(e){var i,s,n,o,a=!0;switch(e.keyCode){case t.ui.keyCode.PAGE_UP:this.previousPage(e);break;case t.ui.keyCode.PAGE_DOWN:this.nextPage(e);break;case t.ui.keyCode.HOME:this._move("first","first",e);break;case t.ui.keyCode.END:this._move("last","last",e);break;case t.ui.keyCode.UP:this.previous(e);break;case t.ui.keyCode.DOWN:this.next(e);break;case t.ui.keyCode.LEFT:this.collapse(e);break;case t.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(e);break;case t.ui.keyCode.ENTER:case t.ui.keyCode.SPACE:this._activate(e);break;case t.ui.keyCode.ESCAPE:this.collapse(e);break;default:a=!1,s=this.previousFilter||"",o=!1,n=e.keyCode>=96&&105>=e.keyCode?""+(e.keyCode-96):String.fromCharCode(e.keyCode),clearTimeout(this.filterTimer),n===s?o=!0:n=s+n,i=this._filterMenuItems(n),i=o&&-1!==i.index(this.active.next())?this.active.nextAll(".ui-menu-item"):i,i.length||(n=String.fromCharCode(e.keyCode),i=this._filterMenuItems(n)),i.length?(this.focus(e,i),this.previousFilter=n,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}a&&e.preventDefault()},_activate:function(t){this.active&&!this.active.is(".ui-state-disabled")&&(this.active.children("[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var e,i,s,n,o,a=this,r=this.options.icons.submenu,h=this.element.find(this.options.menus);this._toggleClass("ui-menu-icons",null,!!this.element.find(".ui-icon").length),s=h.filter(":not(.ui-menu)").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var e=t(this),i=e.prev(),s=t("").data("ui-menu-submenu-caret",!0);a._addClass(s,"ui-menu-icon","ui-icon "+r),i.attr("aria-haspopup","true").prepend(s),e.attr("aria-labelledby",i.attr("id"))}),this._addClass(s,"ui-menu","ui-widget ui-widget-content ui-front"),e=h.add(this.element),i=e.find(this.options.items),i.not(".ui-menu-item").each(function(){var e=t(this);a._isDivider(e)&&a._addClass(e,"ui-menu-divider","ui-widget-content")}),n=i.not(".ui-menu-item, .ui-menu-divider"),o=n.children().not(".ui-menu").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),this._addClass(n,"ui-menu-item")._addClass(o,"ui-menu-item-wrapper"),i.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!t.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){if("icons"===t){var i=this.element.find(".ui-menu-icon");this._removeClass(i,null,this.options.icons.submenu)._addClass(i,null,e.submenu)}this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t+""),this._toggleClass(null,"ui-state-disabled",!!t)},focus:function(t,e){var i,s,n;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),s=this.active.children(".ui-menu-item-wrapper"),this._addClass(s,null,"ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",s.attr("id")),n=this.active.parent().closest(".ui-menu-item").children(".ui-menu-item-wrapper"),this._addClass(n,null,"ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),i=e.children(".ui-menu"),i.length&&t&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(e){var i,s,n,o,a,r;this._hasScroll()&&(i=parseFloat(t.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(t.css(this.activeMenu[0],"paddingTop"))||0,n=e.offset().top-this.activeMenu.offset().top-i-s,o=this.activeMenu.scrollTop(),a=this.activeMenu.height(),r=e.outerHeight(),0>n?this.activeMenu.scrollTop(o+n):n+r>a&&this.activeMenu.scrollTop(o+n-a+r))},blur:function(t,e){e||clearTimeout(this.timer),this.active&&(this._removeClass(this.active.children(".ui-menu-item-wrapper"),null,"ui-state-active"),this._trigger("blur",t,{item:this.active}),this.active=null)},_startOpening:function(t){clearTimeout(this.timer),"true"===t.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(t)},this.delay))},_open:function(e){var i=t.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(e.parents(".ui-menu")).hide().attr("aria-hidden","true"),e.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(i)},collapseAll:function(e,i){clearTimeout(this.timer),this.timer=this._delay(function(){var s=i?this.element:t(e&&e.target).closest(this.element.find(".ui-menu"));s.length||(s=this.element),this._close(s),this.blur(e),this._removeClass(s.find(".ui-state-active"),null,"ui-state-active"),this.activeMenu=s},this.delay)},_close:function(t){t||(t=this.active?this.active.parent():this.element),t.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false")},_closeOnDocumentClick:function(e){return!t(e.target).closest(".ui-menu").length},_isDivider:function(t){return!/[^\-\u2014\u2013\s]/.test(t.text())},collapse:function(t){var e=this.active&&this.active.parent().closest(".ui-menu-item",this.element);e&&e.length&&(this._close(),this.focus(t,e))},expand:function(t){var e=this.active&&this.active.children(".ui-menu ").find(this.options.items).first();e&&e.length&&(this._open(e.parent()),this._delay(function(){this.focus(t,e)}))},next:function(t){this._move("next","first",t)},previous:function(t){this._move("prev","last",t)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(t,e,i){var s;this.active&&(s="first"===t||"last"===t?this.active["first"===t?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[t+"All"](".ui-menu-item").eq(0)),s&&s.length&&this.active||(s=this.activeMenu.find(this.options.items)[e]()),this.focus(i,s)},nextPage:function(e){var i,s,n;return this.active?(this.isLastItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return i=t(this),0>i.offset().top-s-n}),this.focus(e,i)):this.focus(e,this.activeMenu.find(this.options.items)[this.active?"last":"first"]())),void 0):(this.next(e),void 0)},previousPage:function(e){var i,s,n;return this.active?(this.isFirstItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return i=t(this),i.offset().top-s+n>0}),this.focus(e,i)):this.focus(e,this.activeMenu.find(this.options.items).first())),void 0):(this.next(e),void 0)},_hasScroll:function(){return this.element.outerHeight()",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,_create:function(){var e,i,s,n=this.element[0].nodeName.toLowerCase(),o="textarea"===n,a="input"===n; -this.isMultiLine=o||!a&&this._isContentEditable(this.element),this.valueMethod=this.element[o||a?"val":"text"],this.isNewMenu=!0,this._addClass("ui-autocomplete-input"),this.element.attr("autocomplete","off"),this._on(this.element,{keydown:function(n){if(this.element.prop("readOnly"))return e=!0,s=!0,i=!0,void 0;e=!1,s=!1,i=!1;var o=t.ui.keyCode;switch(n.keyCode){case o.PAGE_UP:e=!0,this._move("previousPage",n);break;case o.PAGE_DOWN:e=!0,this._move("nextPage",n);break;case o.UP:e=!0,this._keyEvent("previous",n);break;case o.DOWN:e=!0,this._keyEvent("next",n);break;case o.ENTER:this.menu.active&&(e=!0,n.preventDefault(),this.menu.select(n));break;case o.TAB:this.menu.active&&this.menu.select(n);break;case o.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(n),n.preventDefault());break;default:i=!0,this._searchTimeout(n)}},keypress:function(s){if(e)return e=!1,(!this.isMultiLine||this.menu.element.is(":visible"))&&s.preventDefault(),void 0;if(!i){var n=t.ui.keyCode;switch(s.keyCode){case n.PAGE_UP:this._move("previousPage",s);break;case n.PAGE_DOWN:this._move("nextPage",s);break;case n.UP:this._keyEvent("previous",s);break;case n.DOWN:this._keyEvent("next",s)}}},input:function(t){return s?(s=!1,t.preventDefault(),void 0):(this._searchTimeout(t),void 0)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,void 0):(clearTimeout(this.searching),this.close(t),this._change(t),void 0)}}),this._initSource(),this.menu=t("
            ").appendTo(this._appendTo()).menu({role:null}).hide().menu("instance"),this._addClass(this.menu.element,"ui-autocomplete","ui-front"),this._on(this.menu.element,{mousedown:function(e){e.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,this.element[0]!==t.ui.safeActiveElement(this.document[0])&&this.element.trigger("focus")})},menufocus:function(e,i){var s,n;return this.isNewMenu&&(this.isNewMenu=!1,e.originalEvent&&/^mouse/.test(e.originalEvent.type))?(this.menu.blur(),this.document.one("mousemove",function(){t(e.target).trigger(e.originalEvent)}),void 0):(n=i.item.data("ui-autocomplete-item"),!1!==this._trigger("focus",e,{item:n})&&e.originalEvent&&/^key/.test(e.originalEvent.type)&&this._value(n.value),s=i.item.attr("aria-label")||n.value,s&&t.trim(s).length&&(this.liveRegion.children().hide(),t("
            ").text(s).appendTo(this.liveRegion)),void 0)},menuselect:function(e,i){var s=i.item.data("ui-autocomplete-item"),n=this.previous;this.element[0]!==t.ui.safeActiveElement(this.document[0])&&(this.element.trigger("focus"),this.previous=n,this._delay(function(){this.previous=n,this.selectedItem=s})),!1!==this._trigger("select",e,{item:s})&&this._value(s.value),this.term=this._value(),this.close(e),this.selectedItem=s}}),this.liveRegion=t("
            ",{role:"status","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(t,e){this._super(t,e),"source"===t&&this._initSource(),"appendTo"===t&&this.menu.element.appendTo(this._appendTo()),"disabled"===t&&e&&this.xhr&&this.xhr.abort()},_isEventTargetInWidget:function(e){var i=this.menu.element[0];return e.target===this.element[0]||e.target===i||t.contains(i,e.target)},_closeOnClickOutside:function(t){this._isEventTargetInWidget(t)||this.close()},_appendTo:function(){var e=this.options.appendTo;return e&&(e=e.jquery||e.nodeType?t(e):this.document.find(e).eq(0)),e&&e[0]||(e=this.element.closest(".ui-front, dialog")),e.length||(e=this.document[0].body),e},_initSource:function(){var e,i,s=this;t.isArray(this.options.source)?(e=this.options.source,this.source=function(i,s){s(t.ui.autocomplete.filter(e,i.term))}):"string"==typeof this.options.source?(i=this.options.source,this.source=function(e,n){s.xhr&&s.xhr.abort(),s.xhr=t.ajax({url:i,data:e,dataType:"json",success:function(t){n(t)},error:function(){n([])}})}):this.source=this.options.source},_searchTimeout:function(t){clearTimeout(this.searching),this.searching=this._delay(function(){var e=this.term===this._value(),i=this.menu.element.is(":visible"),s=t.altKey||t.ctrlKey||t.metaKey||t.shiftKey;(!e||e&&!i&&!s)&&(this.selectedItem=null,this.search(null,t))},this.options.delay)},search:function(t,e){return t=null!=t?t:this._value(),this.term=this._value(),t.length").append(t("
            ").text(i.label)).appendTo(e)},_move:function(t,e){return this.menu.element.is(":visible")?this.menu.isFirstItem()&&/^previous/.test(t)||this.menu.isLastItem()&&/^next/.test(t)?(this.isMultiLine||this._value(this.term),this.menu.blur(),void 0):(this.menu[t](e),void 0):(this.search(null,e),void 0)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(t,e){(!this.isMultiLine||this.menu.element.is(":visible"))&&(this._move(t,e),e.preventDefault())},_isContentEditable:function(t){if(!t.length)return!1;var e=t.prop("contentEditable");return"inherit"===e?this._isContentEditable(t.parent()):"true"===e}}),t.extend(t.ui.autocomplete,{escapeRegex:function(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(e,i){var s=RegExp(t.ui.autocomplete.escapeRegex(i),"i");return t.grep(e,function(t){return s.test(t.label||t.value||t)})}}),t.widget("ui.autocomplete",t.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(t){return t+(t>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(e){var i;this._superApply(arguments),this.options.disabled||this.cancelSearch||(i=e&&e.length?this.options.messages.results(e.length):this.options.messages.noResults,this.liveRegion.children().hide(),t("
            ").text(i).appendTo(this.liveRegion))}}),t.ui.autocomplete;var g=/ui-corner-([a-z]){2,6}/g;t.widget("ui.controlgroup",{version:"1.12.1",defaultElement:"
            ",options:{direction:"horizontal",disabled:null,onlyVisible:!0,items:{button:"input[type=button], input[type=submit], input[type=reset], button, a",controlgroupLabel:".ui-controlgroup-label",checkboxradio:"input[type='checkbox'], input[type='radio']",selectmenu:"select",spinner:".ui-spinner-input"}},_create:function(){this._enhance()},_enhance:function(){this.element.attr("role","toolbar"),this.refresh()},_destroy:function(){this._callChildMethod("destroy"),this.childWidgets.removeData("ui-controlgroup-data"),this.element.removeAttr("role"),this.options.items.controlgroupLabel&&this.element.find(this.options.items.controlgroupLabel).find(".ui-controlgroup-label-contents").contents().unwrap()},_initWidgets:function(){var e=this,i=[];t.each(this.options.items,function(s,n){var o,a={};return n?"controlgroupLabel"===s?(o=e.element.find(n),o.each(function(){var e=t(this);e.children(".ui-controlgroup-label-contents").length||e.contents().wrapAll("")}),e._addClass(o,null,"ui-widget ui-widget-content ui-state-default"),i=i.concat(o.get()),void 0):(t.fn[s]&&(a=e["_"+s+"Options"]?e["_"+s+"Options"]("middle"):{classes:{}},e.element.find(n).each(function(){var n=t(this),o=n[s]("instance"),r=t.widget.extend({},a);if("button"!==s||!n.parent(".ui-spinner").length){o||(o=n[s]()[s]("instance")),o&&(r.classes=e._resolveClassesValues(r.classes,o)),n[s](r);var h=n[s]("widget");t.data(h[0],"ui-controlgroup-data",o?o:n[s]("instance")),i.push(h[0])}})),void 0):void 0}),this.childWidgets=t(t.unique(i)),this._addClass(this.childWidgets,"ui-controlgroup-item")},_callChildMethod:function(e){this.childWidgets.each(function(){var i=t(this),s=i.data("ui-controlgroup-data");s&&s[e]&&s[e]()})},_updateCornerClass:function(t,e){var i="ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all",s=this._buildSimpleOptions(e,"label").classes.label;this._removeClass(t,null,i),this._addClass(t,null,s)},_buildSimpleOptions:function(t,e){var i="vertical"===this.options.direction,s={classes:{}};return s.classes[e]={middle:"",first:"ui-corner-"+(i?"top":"left"),last:"ui-corner-"+(i?"bottom":"right"),only:"ui-corner-all"}[t],s},_spinnerOptions:function(t){var e=this._buildSimpleOptions(t,"ui-spinner");return e.classes["ui-spinner-up"]="",e.classes["ui-spinner-down"]="",e},_buttonOptions:function(t){return this._buildSimpleOptions(t,"ui-button")},_checkboxradioOptions:function(t){return this._buildSimpleOptions(t,"ui-checkboxradio-label")},_selectmenuOptions:function(t){var e="vertical"===this.options.direction;return{width:e?"auto":!1,classes:{middle:{"ui-selectmenu-button-open":"","ui-selectmenu-button-closed":""},first:{"ui-selectmenu-button-open":"ui-corner-"+(e?"top":"tl"),"ui-selectmenu-button-closed":"ui-corner-"+(e?"top":"left")},last:{"ui-selectmenu-button-open":e?"":"ui-corner-tr","ui-selectmenu-button-closed":"ui-corner-"+(e?"bottom":"right")},only:{"ui-selectmenu-button-open":"ui-corner-top","ui-selectmenu-button-closed":"ui-corner-all"}}[t]}},_resolveClassesValues:function(e,i){var s={};return t.each(e,function(n){var o=i.options.classes[n]||"";o=t.trim(o.replace(g,"")),s[n]=(o+" "+e[n]).replace(/\s+/g," ")}),s},_setOption:function(t,e){return"direction"===t&&this._removeClass("ui-controlgroup-"+this.options.direction),this._super(t,e),"disabled"===t?(this._callChildMethod(e?"disable":"enable"),void 0):(this.refresh(),void 0)},refresh:function(){var e,i=this;this._addClass("ui-controlgroup ui-controlgroup-"+this.options.direction),"horizontal"===this.options.direction&&this._addClass(null,"ui-helper-clearfix"),this._initWidgets(),e=this.childWidgets,this.options.onlyVisible&&(e=e.filter(":visible")),e.length&&(t.each(["first","last"],function(t,s){var n=e[s]().data("ui-controlgroup-data");if(n&&i["_"+n.widgetName+"Options"]){var o=i["_"+n.widgetName+"Options"](1===e.length?"only":s);o.classes=i._resolveClassesValues(o.classes,n),n.element[n.widgetName](o)}else i._updateCornerClass(e[s](),s)}),this._callChildMethod("refresh"))}}),t.widget("ui.checkboxradio",[t.ui.formResetMixin,{version:"1.12.1",options:{disabled:null,label:null,icon:!0,classes:{"ui-checkboxradio-label":"ui-corner-all","ui-checkboxradio-icon":"ui-corner-all"}},_getCreateOptions:function(){var e,i,s=this,n=this._super()||{};return this._readType(),i=this.element.labels(),this.label=t(i[i.length-1]),this.label.length||t.error("No label found for checkboxradio widget"),this.originalLabel="",this.label.contents().not(this.element[0]).each(function(){s.originalLabel+=3===this.nodeType?t(this).text():this.outerHTML}),this.originalLabel&&(n.label=this.originalLabel),e=this.element[0].disabled,null!=e&&(n.disabled=e),n},_create:function(){var t=this.element[0].checked;this._bindFormResetHandler(),null==this.options.disabled&&(this.options.disabled=this.element[0].disabled),this._setOption("disabled",this.options.disabled),this._addClass("ui-checkboxradio","ui-helper-hidden-accessible"),this._addClass(this.label,"ui-checkboxradio-label","ui-button ui-widget"),"radio"===this.type&&this._addClass(this.label,"ui-checkboxradio-radio-label"),this.options.label&&this.options.label!==this.originalLabel?this._updateLabel():this.originalLabel&&(this.options.label=this.originalLabel),this._enhance(),t&&(this._addClass(this.label,"ui-checkboxradio-checked","ui-state-active"),this.icon&&this._addClass(this.icon,null,"ui-state-hover")),this._on({change:"_toggleClasses",focus:function(){this._addClass(this.label,null,"ui-state-focus ui-visual-focus")},blur:function(){this._removeClass(this.label,null,"ui-state-focus ui-visual-focus")}})},_readType:function(){var e=this.element[0].nodeName.toLowerCase();this.type=this.element[0].type,"input"===e&&/radio|checkbox/.test(this.type)||t.error("Can't create checkboxradio on element.nodeName="+e+" and element.type="+this.type)},_enhance:function(){this._updateIcon(this.element[0].checked)},widget:function(){return this.label},_getRadioGroup:function(){var e,i=this.element[0].name,s="input[name='"+t.ui.escapeSelector(i)+"']";return i?(e=this.form.length?t(this.form[0].elements).filter(s):t(s).filter(function(){return 0===t(this).form().length}),e.not(this.element)):t([])},_toggleClasses:function(){var e=this.element[0].checked;this._toggleClass(this.label,"ui-checkboxradio-checked","ui-state-active",e),this.options.icon&&"checkbox"===this.type&&this._toggleClass(this.icon,null,"ui-icon-check ui-state-checked",e)._toggleClass(this.icon,null,"ui-icon-blank",!e),"radio"===this.type&&this._getRadioGroup().each(function(){var e=t(this).checkboxradio("instance");e&&e._removeClass(e.label,"ui-checkboxradio-checked","ui-state-active")})},_destroy:function(){this._unbindFormResetHandler(),this.icon&&(this.icon.remove(),this.iconSpace.remove())},_setOption:function(t,e){return"label"!==t||e?(this._super(t,e),"disabled"===t?(this._toggleClass(this.label,null,"ui-state-disabled",e),this.element[0].disabled=e,void 0):(this.refresh(),void 0)):void 0},_updateIcon:function(e){var i="ui-icon ui-icon-background ";this.options.icon?(this.icon||(this.icon=t(""),this.iconSpace=t(" "),this._addClass(this.iconSpace,"ui-checkboxradio-icon-space")),"checkbox"===this.type?(i+=e?"ui-icon-check ui-state-checked":"ui-icon-blank",this._removeClass(this.icon,null,e?"ui-icon-blank":"ui-icon-check")):i+="ui-icon-blank",this._addClass(this.icon,"ui-checkboxradio-icon",i),e||this._removeClass(this.icon,null,"ui-icon-check ui-state-checked"),this.icon.prependTo(this.label).after(this.iconSpace)):void 0!==this.icon&&(this.icon.remove(),this.iconSpace.remove(),delete this.icon)},_updateLabel:function(){var t=this.label.contents().not(this.element[0]);this.icon&&(t=t.not(this.icon[0])),this.iconSpace&&(t=t.not(this.iconSpace[0])),t.remove(),this.label.append(this.options.label)},refresh:function(){var t=this.element[0].checked,e=this.element[0].disabled;this._updateIcon(t),this._toggleClass(this.label,"ui-checkboxradio-checked","ui-state-active",t),null!==this.options.label&&this._updateLabel(),e!==this.options.disabled&&this._setOptions({disabled:e})}}]),t.ui.checkboxradio,t.widget("ui.button",{version:"1.12.1",defaultElement:"").addClass(this._triggerClass).html(o?t("").attr({src:o,alt:n,title:n}):n)),e[r?"before":"after"](i.trigger),i.trigger.on("click",function(){return t.datepicker._datepickerShowing&&t.datepicker._lastInput===e[0]?t.datepicker._hideDatepicker():t.datepicker._datepickerShowing&&t.datepicker._lastInput!==e[0]?(t.datepicker._hideDatepicker(),t.datepicker._showDatepicker(e[0])):t.datepicker._showDatepicker(e[0]),!1}))},_autoSize:function(t){if(this._get(t,"autoSize")&&!t.inline){var e,i,s,n,o=new Date(2009,11,20),a=this._get(t,"dateFormat");a.match(/[DM]/)&&(e=function(t){for(i=0,s=0,n=0;t.length>n;n++)t[n].length>i&&(i=t[n].length,s=n);return s},o.setMonth(e(this._get(t,a.match(/MM/)?"monthNames":"monthNamesShort"))),o.setDate(e(this._get(t,a.match(/DD/)?"dayNames":"dayNamesShort"))+20-o.getDay())),t.input.attr("size",this._formatDate(t,o).length)}},_inlineDatepicker:function(e,i){var s=t(e);s.hasClass(this.markerClassName)||(s.addClass(this.markerClassName).append(i.dpDiv),t.data(e,"datepicker",i),this._setDate(i,this._getDefaultDate(i),!0),this._updateDatepicker(i),this._updateAlternate(i),i.settings.disabled&&this._disableDatepicker(e),i.dpDiv.css("display","block"))},_dialogDatepicker:function(e,i,s,n,o){var r,h,l,c,u,d=this._dialogInst;return d||(this.uuid+=1,r="dp"+this.uuid,this._dialogInput=t(""),this._dialogInput.on("keydown",this._doKeyDown),t("body").append(this._dialogInput),d=this._dialogInst=this._newInst(this._dialogInput,!1),d.settings={},t.data(this._dialogInput[0],"datepicker",d)),a(d.settings,n||{}),i=i&&i.constructor===Date?this._formatDate(d,i):i,this._dialogInput.val(i),this._pos=o?o.length?o:[o.pageX,o.pageY]:null,this._pos||(h=document.documentElement.clientWidth,l=document.documentElement.clientHeight,c=document.documentElement.scrollLeft||document.body.scrollLeft,u=document.documentElement.scrollTop||document.body.scrollTop,this._pos=[h/2-100+c,l/2-150+u]),this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),d.settings.onSelect=s,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),t.blockUI&&t.blockUI(this.dpDiv),t.data(this._dialogInput[0],"datepicker",d),this},_destroyDatepicker:function(e){var i,s=t(e),n=t.data(e,"datepicker");s.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),t.removeData(e,"datepicker"),"input"===i?(n.append.remove(),n.trigger.remove(),s.removeClass(this.markerClassName).off("focus",this._showDatepicker).off("keydown",this._doKeyDown).off("keypress",this._doKeyPress).off("keyup",this._doKeyUp)):("div"===i||"span"===i)&&s.removeClass(this.markerClassName).empty(),m===n&&(m=null))},_enableDatepicker:function(e){var i,s,n=t(e),o=t.data(e,"datepicker");n.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),"input"===i?(e.disabled=!1,o.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().removeClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)),this._disabledInputs=t.map(this._disabledInputs,function(t){return t===e?null:t}))},_disableDatepicker:function(e){var i,s,n=t(e),o=t.data(e,"datepicker");n.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),"input"===i?(e.disabled=!0,o.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().addClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)),this._disabledInputs=t.map(this._disabledInputs,function(t){return t===e?null:t}),this._disabledInputs[this._disabledInputs.length]=e)},_isDisabledDatepicker:function(t){if(!t)return!1;for(var e=0;this._disabledInputs.length>e;e++)if(this._disabledInputs[e]===t)return!0;return!1},_getInst:function(e){try{return t.data(e,"datepicker")}catch(i){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(e,i,s){var n,o,r,h,l=this._getInst(e);return 2===arguments.length&&"string"==typeof i?"defaults"===i?t.extend({},t.datepicker._defaults):l?"all"===i?t.extend({},l.settings):this._get(l,i):null:(n=i||{},"string"==typeof i&&(n={},n[i]=s),l&&(this._curInst===l&&this._hideDatepicker(),o=this._getDateDatepicker(e,!0),r=this._getMinMaxDate(l,"min"),h=this._getMinMaxDate(l,"max"),a(l.settings,n),null!==r&&void 0!==n.dateFormat&&void 0===n.minDate&&(l.settings.minDate=this._formatDate(l,r)),null!==h&&void 0!==n.dateFormat&&void 0===n.maxDate&&(l.settings.maxDate=this._formatDate(l,h)),"disabled"in n&&(n.disabled?this._disableDatepicker(e):this._enableDatepicker(e)),this._attachments(t(e),l),this._autoSize(l),this._setDate(l,o),this._updateAlternate(l),this._updateDatepicker(l)),void 0)},_changeDatepicker:function(t,e,i){this._optionDatepicker(t,e,i)},_refreshDatepicker:function(t){var e=this._getInst(t);e&&this._updateDatepicker(e)},_setDateDatepicker:function(t,e){var i=this._getInst(t);i&&(this._setDate(i,e),this._updateDatepicker(i),this._updateAlternate(i))},_getDateDatepicker:function(t,e){var i=this._getInst(t);return i&&!i.inline&&this._setDateFromField(i,e),i?this._getDate(i):null},_doKeyDown:function(e){var i,s,n,o=t.datepicker._getInst(e.target),a=!0,r=o.dpDiv.is(".ui-datepicker-rtl");if(o._keyEvent=!0,t.datepicker._datepickerShowing)switch(e.keyCode){case 9:t.datepicker._hideDatepicker(),a=!1;break;case 13:return n=t("td."+t.datepicker._dayOverClass+":not(."+t.datepicker._currentClass+")",o.dpDiv),n[0]&&t.datepicker._selectDay(e.target,o.selectedMonth,o.selectedYear,n[0]),i=t.datepicker._get(o,"onSelect"),i?(s=t.datepicker._formatDate(o),i.apply(o.input?o.input[0]:null,[s,o])):t.datepicker._hideDatepicker(),!1;case 27:t.datepicker._hideDatepicker();break;case 33:t.datepicker._adjustDate(e.target,e.ctrlKey?-t.datepicker._get(o,"stepBigMonths"):-t.datepicker._get(o,"stepMonths"),"M");break;case 34:t.datepicker._adjustDate(e.target,e.ctrlKey?+t.datepicker._get(o,"stepBigMonths"):+t.datepicker._get(o,"stepMonths"),"M");break;case 35:(e.ctrlKey||e.metaKey)&&t.datepicker._clearDate(e.target),a=e.ctrlKey||e.metaKey;break;case 36:(e.ctrlKey||e.metaKey)&&t.datepicker._gotoToday(e.target),a=e.ctrlKey||e.metaKey;break;case 37:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,r?1:-1,"D"),a=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&t.datepicker._adjustDate(e.target,e.ctrlKey?-t.datepicker._get(o,"stepBigMonths"):-t.datepicker._get(o,"stepMonths"),"M");break;case 38:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,-7,"D"),a=e.ctrlKey||e.metaKey;break;case 39:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,r?-1:1,"D"),a=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&t.datepicker._adjustDate(e.target,e.ctrlKey?+t.datepicker._get(o,"stepBigMonths"):+t.datepicker._get(o,"stepMonths"),"M");break;case 40:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,7,"D"),a=e.ctrlKey||e.metaKey;break;default:a=!1}else 36===e.keyCode&&e.ctrlKey?t.datepicker._showDatepicker(this):a=!1;a&&(e.preventDefault(),e.stopPropagation())},_doKeyPress:function(e){var i,s,n=t.datepicker._getInst(e.target);return t.datepicker._get(n,"constrainInput")?(i=t.datepicker._possibleChars(t.datepicker._get(n,"dateFormat")),s=String.fromCharCode(null==e.charCode?e.keyCode:e.charCode),e.ctrlKey||e.metaKey||" ">s||!i||i.indexOf(s)>-1):void 0},_doKeyUp:function(e){var i,s=t.datepicker._getInst(e.target);if(s.input.val()!==s.lastVal)try{i=t.datepicker.parseDate(t.datepicker._get(s,"dateFormat"),s.input?s.input.val():null,t.datepicker._getFormatConfig(s)),i&&(t.datepicker._setDateFromField(s),t.datepicker._updateAlternate(s),t.datepicker._updateDatepicker(s))}catch(n){}return!0},_showDatepicker:function(e){if(e=e.target||e,"input"!==e.nodeName.toLowerCase()&&(e=t("input",e.parentNode)[0]),!t.datepicker._isDisabledDatepicker(e)&&t.datepicker._lastInput!==e){var s,n,o,r,h,l,c;s=t.datepicker._getInst(e),t.datepicker._curInst&&t.datepicker._curInst!==s&&(t.datepicker._curInst.dpDiv.stop(!0,!0),s&&t.datepicker._datepickerShowing&&t.datepicker._hideDatepicker(t.datepicker._curInst.input[0])),n=t.datepicker._get(s,"beforeShow"),o=n?n.apply(e,[e,s]):{},o!==!1&&(a(s.settings,o),s.lastVal=null,t.datepicker._lastInput=e,t.datepicker._setDateFromField(s),t.datepicker._inDialog&&(e.value=""),t.datepicker._pos||(t.datepicker._pos=t.datepicker._findPos(e),t.datepicker._pos[1]+=e.offsetHeight),r=!1,t(e).parents().each(function(){return r|="fixed"===t(this).css("position"),!r}),h={left:t.datepicker._pos[0],top:t.datepicker._pos[1]},t.datepicker._pos=null,s.dpDiv.empty(),s.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),t.datepicker._updateDatepicker(s),h=t.datepicker._checkOffset(s,h,r),s.dpDiv.css({position:t.datepicker._inDialog&&t.blockUI?"static":r?"fixed":"absolute",display:"none",left:h.left+"px",top:h.top+"px"}),s.inline||(l=t.datepicker._get(s,"showAnim"),c=t.datepicker._get(s,"duration"),s.dpDiv.css("z-index",i(t(e))+1),t.datepicker._datepickerShowing=!0,t.effects&&t.effects.effect[l]?s.dpDiv.show(l,t.datepicker._get(s,"showOptions"),c):s.dpDiv[l||"show"](l?c:null),t.datepicker._shouldFocusInput(s)&&s.input.trigger("focus"),t.datepicker._curInst=s)) -}},_updateDatepicker:function(e){this.maxRows=4,m=e,e.dpDiv.empty().append(this._generateHTML(e)),this._attachHandlers(e);var i,s=this._getNumberOfMonths(e),n=s[1],a=17,r=e.dpDiv.find("."+this._dayOverClass+" a");r.length>0&&o.apply(r.get(0)),e.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),n>1&&e.dpDiv.addClass("ui-datepicker-multi-"+n).css("width",a*n+"em"),e.dpDiv[(1!==s[0]||1!==s[1]?"add":"remove")+"Class"]("ui-datepicker-multi"),e.dpDiv[(this._get(e,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),e===t.datepicker._curInst&&t.datepicker._datepickerShowing&&t.datepicker._shouldFocusInput(e)&&e.input.trigger("focus"),e.yearshtml&&(i=e.yearshtml,setTimeout(function(){i===e.yearshtml&&e.yearshtml&&e.dpDiv.find("select.ui-datepicker-year:first").replaceWith(e.yearshtml),i=e.yearshtml=null},0))},_shouldFocusInput:function(t){return t.input&&t.input.is(":visible")&&!t.input.is(":disabled")&&!t.input.is(":focus")},_checkOffset:function(e,i,s){var n=e.dpDiv.outerWidth(),o=e.dpDiv.outerHeight(),a=e.input?e.input.outerWidth():0,r=e.input?e.input.outerHeight():0,h=document.documentElement.clientWidth+(s?0:t(document).scrollLeft()),l=document.documentElement.clientHeight+(s?0:t(document).scrollTop());return i.left-=this._get(e,"isRTL")?n-a:0,i.left-=s&&i.left===e.input.offset().left?t(document).scrollLeft():0,i.top-=s&&i.top===e.input.offset().top+r?t(document).scrollTop():0,i.left-=Math.min(i.left,i.left+n>h&&h>n?Math.abs(i.left+n-h):0),i.top-=Math.min(i.top,i.top+o>l&&l>o?Math.abs(o+r):0),i},_findPos:function(e){for(var i,s=this._getInst(e),n=this._get(s,"isRTL");e&&("hidden"===e.type||1!==e.nodeType||t.expr.filters.hidden(e));)e=e[n?"previousSibling":"nextSibling"];return i=t(e).offset(),[i.left,i.top]},_hideDatepicker:function(e){var i,s,n,o,a=this._curInst;!a||e&&a!==t.data(e,"datepicker")||this._datepickerShowing&&(i=this._get(a,"showAnim"),s=this._get(a,"duration"),n=function(){t.datepicker._tidyDialog(a)},t.effects&&(t.effects.effect[i]||t.effects[i])?a.dpDiv.hide(i,t.datepicker._get(a,"showOptions"),s,n):a.dpDiv["slideDown"===i?"slideUp":"fadeIn"===i?"fadeOut":"hide"](i?s:null,n),i||n(),this._datepickerShowing=!1,o=this._get(a,"onClose"),o&&o.apply(a.input?a.input[0]:null,[a.input?a.input.val():"",a]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),t.blockUI&&(t.unblockUI(),t("body").append(this.dpDiv))),this._inDialog=!1)},_tidyDialog:function(t){t.dpDiv.removeClass(this._dialogClass).off(".ui-datepicker-calendar")},_checkExternalClick:function(e){if(t.datepicker._curInst){var i=t(e.target),s=t.datepicker._getInst(i[0]);(i[0].id!==t.datepicker._mainDivId&&0===i.parents("#"+t.datepicker._mainDivId).length&&!i.hasClass(t.datepicker.markerClassName)&&!i.closest("."+t.datepicker._triggerClass).length&&t.datepicker._datepickerShowing&&(!t.datepicker._inDialog||!t.blockUI)||i.hasClass(t.datepicker.markerClassName)&&t.datepicker._curInst!==s)&&t.datepicker._hideDatepicker()}},_adjustDate:function(e,i,s){var n=t(e),o=this._getInst(n[0]);this._isDisabledDatepicker(n[0])||(this._adjustInstDate(o,i+("M"===s?this._get(o,"showCurrentAtPos"):0),s),this._updateDatepicker(o))},_gotoToday:function(e){var i,s=t(e),n=this._getInst(s[0]);this._get(n,"gotoCurrent")&&n.currentDay?(n.selectedDay=n.currentDay,n.drawMonth=n.selectedMonth=n.currentMonth,n.drawYear=n.selectedYear=n.currentYear):(i=new Date,n.selectedDay=i.getDate(),n.drawMonth=n.selectedMonth=i.getMonth(),n.drawYear=n.selectedYear=i.getFullYear()),this._notifyChange(n),this._adjustDate(s)},_selectMonthYear:function(e,i,s){var n=t(e),o=this._getInst(n[0]);o["selected"+("M"===s?"Month":"Year")]=o["draw"+("M"===s?"Month":"Year")]=parseInt(i.options[i.selectedIndex].value,10),this._notifyChange(o),this._adjustDate(n)},_selectDay:function(e,i,s,n){var o,a=t(e);t(n).hasClass(this._unselectableClass)||this._isDisabledDatepicker(a[0])||(o=this._getInst(a[0]),o.selectedDay=o.currentDay=t("a",n).html(),o.selectedMonth=o.currentMonth=i,o.selectedYear=o.currentYear=s,this._selectDate(e,this._formatDate(o,o.currentDay,o.currentMonth,o.currentYear)))},_clearDate:function(e){var i=t(e);this._selectDate(i,"")},_selectDate:function(e,i){var s,n=t(e),o=this._getInst(n[0]);i=null!=i?i:this._formatDate(o),o.input&&o.input.val(i),this._updateAlternate(o),s=this._get(o,"onSelect"),s?s.apply(o.input?o.input[0]:null,[i,o]):o.input&&o.input.trigger("change"),o.inline?this._updateDatepicker(o):(this._hideDatepicker(),this._lastInput=o.input[0],"object"!=typeof o.input[0]&&o.input.trigger("focus"),this._lastInput=null)},_updateAlternate:function(e){var i,s,n,o=this._get(e,"altField");o&&(i=this._get(e,"altFormat")||this._get(e,"dateFormat"),s=this._getDate(e),n=this.formatDate(i,s,this._getFormatConfig(e)),t(o).val(n))},noWeekends:function(t){var e=t.getDay();return[e>0&&6>e,""]},iso8601Week:function(t){var e,i=new Date(t.getTime());return i.setDate(i.getDate()+4-(i.getDay()||7)),e=i.getTime(),i.setMonth(0),i.setDate(1),Math.floor(Math.round((e-i)/864e5)/7)+1},parseDate:function(e,i,s){if(null==e||null==i)throw"Invalid arguments";if(i="object"==typeof i?""+i:i+"",""===i)return null;var n,o,a,r,h=0,l=(s?s.shortYearCutoff:null)||this._defaults.shortYearCutoff,c="string"!=typeof l?l:(new Date).getFullYear()%100+parseInt(l,10),u=(s?s.dayNamesShort:null)||this._defaults.dayNamesShort,d=(s?s.dayNames:null)||this._defaults.dayNames,p=(s?s.monthNamesShort:null)||this._defaults.monthNamesShort,f=(s?s.monthNames:null)||this._defaults.monthNames,g=-1,m=-1,_=-1,v=-1,b=!1,y=function(t){var i=e.length>n+1&&e.charAt(n+1)===t;return i&&n++,i},w=function(t){var e=y(t),s="@"===t?14:"!"===t?20:"y"===t&&e?4:"o"===t?3:2,n="y"===t?s:1,o=RegExp("^\\d{"+n+","+s+"}"),a=i.substring(h).match(o);if(!a)throw"Missing number at position "+h;return h+=a[0].length,parseInt(a[0],10)},k=function(e,s,n){var o=-1,a=t.map(y(e)?n:s,function(t,e){return[[e,t]]}).sort(function(t,e){return-(t[1].length-e[1].length)});if(t.each(a,function(t,e){var s=e[1];return i.substr(h,s.length).toLowerCase()===s.toLowerCase()?(o=e[0],h+=s.length,!1):void 0}),-1!==o)return o+1;throw"Unknown name at position "+h},x=function(){if(i.charAt(h)!==e.charAt(n))throw"Unexpected literal at position "+h;h++};for(n=0;e.length>n;n++)if(b)"'"!==e.charAt(n)||y("'")?x():b=!1;else switch(e.charAt(n)){case"d":_=w("d");break;case"D":k("D",u,d);break;case"o":v=w("o");break;case"m":m=w("m");break;case"M":m=k("M",p,f);break;case"y":g=w("y");break;case"@":r=new Date(w("@")),g=r.getFullYear(),m=r.getMonth()+1,_=r.getDate();break;case"!":r=new Date((w("!")-this._ticksTo1970)/1e4),g=r.getFullYear(),m=r.getMonth()+1,_=r.getDate();break;case"'":y("'")?x():b=!0;break;default:x()}if(i.length>h&&(a=i.substr(h),!/^\s+/.test(a)))throw"Extra/unparsed characters found in date: "+a;if(-1===g?g=(new Date).getFullYear():100>g&&(g+=(new Date).getFullYear()-(new Date).getFullYear()%100+(c>=g?0:-100)),v>-1)for(m=1,_=v;;){if(o=this._getDaysInMonth(g,m-1),o>=_)break;m++,_-=o}if(r=this._daylightSavingAdjust(new Date(g,m-1,_)),r.getFullYear()!==g||r.getMonth()+1!==m||r.getDate()!==_)throw"Invalid date";return r},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:1e7*60*60*24*(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925)),formatDate:function(t,e,i){if(!e)return"";var s,n=(i?i.dayNamesShort:null)||this._defaults.dayNamesShort,o=(i?i.dayNames:null)||this._defaults.dayNames,a=(i?i.monthNamesShort:null)||this._defaults.monthNamesShort,r=(i?i.monthNames:null)||this._defaults.monthNames,h=function(e){var i=t.length>s+1&&t.charAt(s+1)===e;return i&&s++,i},l=function(t,e,i){var s=""+e;if(h(t))for(;i>s.length;)s="0"+s;return s},c=function(t,e,i,s){return h(t)?s[e]:i[e]},u="",d=!1;if(e)for(s=0;t.length>s;s++)if(d)"'"!==t.charAt(s)||h("'")?u+=t.charAt(s):d=!1;else switch(t.charAt(s)){case"d":u+=l("d",e.getDate(),2);break;case"D":u+=c("D",e.getDay(),n,o);break;case"o":u+=l("o",Math.round((new Date(e.getFullYear(),e.getMonth(),e.getDate()).getTime()-new Date(e.getFullYear(),0,0).getTime())/864e5),3);break;case"m":u+=l("m",e.getMonth()+1,2);break;case"M":u+=c("M",e.getMonth(),a,r);break;case"y":u+=h("y")?e.getFullYear():(10>e.getFullYear()%100?"0":"")+e.getFullYear()%100;break;case"@":u+=e.getTime();break;case"!":u+=1e4*e.getTime()+this._ticksTo1970;break;case"'":h("'")?u+="'":d=!0;break;default:u+=t.charAt(s)}return u},_possibleChars:function(t){var e,i="",s=!1,n=function(i){var s=t.length>e+1&&t.charAt(e+1)===i;return s&&e++,s};for(e=0;t.length>e;e++)if(s)"'"!==t.charAt(e)||n("'")?i+=t.charAt(e):s=!1;else switch(t.charAt(e)){case"d":case"m":case"y":case"@":i+="0123456789";break;case"D":case"M":return null;case"'":n("'")?i+="'":s=!0;break;default:i+=t.charAt(e)}return i},_get:function(t,e){return void 0!==t.settings[e]?t.settings[e]:this._defaults[e]},_setDateFromField:function(t,e){if(t.input.val()!==t.lastVal){var i=this._get(t,"dateFormat"),s=t.lastVal=t.input?t.input.val():null,n=this._getDefaultDate(t),o=n,a=this._getFormatConfig(t);try{o=this.parseDate(i,s,a)||n}catch(r){s=e?"":s}t.selectedDay=o.getDate(),t.drawMonth=t.selectedMonth=o.getMonth(),t.drawYear=t.selectedYear=o.getFullYear(),t.currentDay=s?o.getDate():0,t.currentMonth=s?o.getMonth():0,t.currentYear=s?o.getFullYear():0,this._adjustInstDate(t)}},_getDefaultDate:function(t){return this._restrictMinMax(t,this._determineDate(t,this._get(t,"defaultDate"),new Date))},_determineDate:function(e,i,s){var n=function(t){var e=new Date;return e.setDate(e.getDate()+t),e},o=function(i){try{return t.datepicker.parseDate(t.datepicker._get(e,"dateFormat"),i,t.datepicker._getFormatConfig(e))}catch(s){}for(var n=(i.toLowerCase().match(/^c/)?t.datepicker._getDate(e):null)||new Date,o=n.getFullYear(),a=n.getMonth(),r=n.getDate(),h=/([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,l=h.exec(i);l;){switch(l[2]||"d"){case"d":case"D":r+=parseInt(l[1],10);break;case"w":case"W":r+=7*parseInt(l[1],10);break;case"m":case"M":a+=parseInt(l[1],10),r=Math.min(r,t.datepicker._getDaysInMonth(o,a));break;case"y":case"Y":o+=parseInt(l[1],10),r=Math.min(r,t.datepicker._getDaysInMonth(o,a))}l=h.exec(i)}return new Date(o,a,r)},a=null==i||""===i?s:"string"==typeof i?o(i):"number"==typeof i?isNaN(i)?s:n(i):new Date(i.getTime());return a=a&&"Invalid Date"==""+a?s:a,a&&(a.setHours(0),a.setMinutes(0),a.setSeconds(0),a.setMilliseconds(0)),this._daylightSavingAdjust(a)},_daylightSavingAdjust:function(t){return t?(t.setHours(t.getHours()>12?t.getHours()+2:0),t):null},_setDate:function(t,e,i){var s=!e,n=t.selectedMonth,o=t.selectedYear,a=this._restrictMinMax(t,this._determineDate(t,e,new Date));t.selectedDay=t.currentDay=a.getDate(),t.drawMonth=t.selectedMonth=t.currentMonth=a.getMonth(),t.drawYear=t.selectedYear=t.currentYear=a.getFullYear(),n===t.selectedMonth&&o===t.selectedYear||i||this._notifyChange(t),this._adjustInstDate(t),t.input&&t.input.val(s?"":this._formatDate(t))},_getDate:function(t){var e=!t.currentYear||t.input&&""===t.input.val()?null:this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return e},_attachHandlers:function(e){var i=this._get(e,"stepMonths"),s="#"+e.id.replace(/\\\\/g,"\\");e.dpDiv.find("[data-handler]").map(function(){var e={prev:function(){t.datepicker._adjustDate(s,-i,"M")},next:function(){t.datepicker._adjustDate(s,+i,"M")},hide:function(){t.datepicker._hideDatepicker()},today:function(){t.datepicker._gotoToday(s)},selectDay:function(){return t.datepicker._selectDay(s,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return t.datepicker._selectMonthYear(s,this,"M"),!1},selectYear:function(){return t.datepicker._selectMonthYear(s,this,"Y"),!1}};t(this).on(this.getAttribute("data-event"),e[this.getAttribute("data-handler")])})},_generateHTML:function(t){var e,i,s,n,o,a,r,h,l,c,u,d,p,f,g,m,_,v,b,y,w,k,x,C,D,I,T,P,M,S,H,z,O,A,N,W,E,F,L,R=new Date,B=this._daylightSavingAdjust(new Date(R.getFullYear(),R.getMonth(),R.getDate())),Y=this._get(t,"isRTL"),j=this._get(t,"showButtonPanel"),q=this._get(t,"hideIfNoPrevNext"),K=this._get(t,"navigationAsDateFormat"),U=this._getNumberOfMonths(t),V=this._get(t,"showCurrentAtPos"),$=this._get(t,"stepMonths"),X=1!==U[0]||1!==U[1],G=this._daylightSavingAdjust(t.currentDay?new Date(t.currentYear,t.currentMonth,t.currentDay):new Date(9999,9,9)),Q=this._getMinMaxDate(t,"min"),J=this._getMinMaxDate(t,"max"),Z=t.drawMonth-V,te=t.drawYear;if(0>Z&&(Z+=12,te--),J)for(e=this._daylightSavingAdjust(new Date(J.getFullYear(),J.getMonth()-U[0]*U[1]+1,J.getDate())),e=Q&&Q>e?Q:e;this._daylightSavingAdjust(new Date(te,Z,1))>e;)Z--,0>Z&&(Z=11,te--);for(t.drawMonth=Z,t.drawYear=te,i=this._get(t,"prevText"),i=K?this.formatDate(i,this._daylightSavingAdjust(new Date(te,Z-$,1)),this._getFormatConfig(t)):i,s=this._canAdjustMonth(t,-1,te,Z)?""+i+"":q?"":""+i+"",n=this._get(t,"nextText"),n=K?this.formatDate(n,this._daylightSavingAdjust(new Date(te,Z+$,1)),this._getFormatConfig(t)):n,o=this._canAdjustMonth(t,1,te,Z)?""+n+"":q?"":""+n+"",a=this._get(t,"currentText"),r=this._get(t,"gotoCurrent")&&t.currentDay?G:B,a=K?this.formatDate(a,r,this._getFormatConfig(t)):a,h=t.inline?"":"",l=j?"
            "+(Y?h:"")+(this._isInRange(t,r)?"":"")+(Y?"":h)+"
            ":"",c=parseInt(this._get(t,"firstDay"),10),c=isNaN(c)?0:c,u=this._get(t,"showWeek"),d=this._get(t,"dayNames"),p=this._get(t,"dayNamesMin"),f=this._get(t,"monthNames"),g=this._get(t,"monthNamesShort"),m=this._get(t,"beforeShowDay"),_=this._get(t,"showOtherMonths"),v=this._get(t,"selectOtherMonths"),b=this._getDefaultDate(t),y="",k=0;U[0]>k;k++){for(x="",this.maxRows=4,C=0;U[1]>C;C++){if(D=this._daylightSavingAdjust(new Date(te,Z,t.selectedDay)),I=" ui-corner-all",T="",X){if(T+="
            "}for(T+="
            "+(/all|left/.test(I)&&0===k?Y?o:s:"")+(/all|right/.test(I)&&0===k?Y?s:o:"")+this._generateMonthYearHeader(t,Z,te,Q,J,k>0||C>0,f,g)+"
          OptionFilippo Nova
          Filippo Nova

          ๐Ÿ›
          Francesco la Torre
          Francesco la Torre

          ๐Ÿ›
          Francisco Duarte
          Francisco Duarte

          ๐Ÿ›
          Frieder Bluemle
          Frieder Bluemle

          ๐Ÿ›
          Frederick Zhang
          Frederick Zhang

          ๐Ÿ›
          Frieder Bluemle
          Frieder Bluemle

          ๐Ÿ›
          Frits Jalvingh
          Frits Jalvingh

          ๐Ÿ’ป ๐Ÿ›
          G. Bazior
          G. Bazior

          ๐Ÿ›
          Gabe Henkes
          Gabe Henkes

          ๐Ÿ›
          Gary Gregory
          Gary Gregory

          ๐Ÿ›
          Genoud Magloire
          Genoud Magloire

          ๐Ÿ›
          Geoffrey555
          Geoffrey555

          ๐Ÿ›
          Georg Romstorfer
          Georg Romstorfer

          ๐Ÿ›
          Georg Romstorfer
          Georg Romstorfer

          ๐Ÿ›
          Gili Tzabari
          Gili Tzabari

          ๐Ÿ› ๐Ÿ’ป
          Gio
          Gio

          ๐Ÿ›
          Gol
          Gol

          ๐Ÿ›
          Gold856
          Gold856

          ๐Ÿ› ๐Ÿ’ป
          Gonzalo Exequiel Ibars Ingman
          Gonzalo Exequiel Ibars Ingman

          ๐Ÿ’ป ๐Ÿ›
          GooDer
          GooDer

          ๐Ÿ›
          Gregor Riegler
          Gregor Riegler

          ๐Ÿ›
          Gregor Riegler
          Gregor Riegler

          ๐Ÿ›
          Grzegorz Olszewski
          Grzegorz Olszewski

          ๐Ÿ›
          Gunther Schrijvers
          Gunther Schrijvers

          ๐Ÿ’ป ๐Ÿ›
          Gustavo Krieger
          Gustavo Krieger

          ๐Ÿ›
          Guy Elsmore-Paddock
          Guy Elsmore-Paddock

          ๐Ÿ›
          Gรถrkem Mรผlayim
          Gรถrkem Mรผlayim

          ๐Ÿ›
          Hanzel Godinez
          Hanzel Godinez

          ๐Ÿ›
          Haoliang Chen
          Haoliang Chen

          ๐Ÿ›
          Haoliang Chen
          Haoliang Chen

          ๐Ÿ›
          Harsh Kukreja
          Harsh Kukreja

          ๐Ÿ›
          Hassan ALAMI
          Hassan ALAMI

          ๐Ÿ›
          Heber
          Heber

          ๐Ÿ›
          Hector Miuler Malpica Gallegos
          Hector Miuler Malpica Gallegos

          ๐Ÿ›
          Henning Schmiedehausen
          Henning Schmiedehausen

          ๐Ÿ’ป ๐Ÿ›
          Henning von Bargen
          Henning von Bargen

          ๐Ÿ’ป
          Hervรฉ Boutemy
          Hervรฉ Boutemy

          ๐Ÿ›
          Hervรฉ Boutemy
          Hervรฉ Boutemy

          ๐Ÿ›
          Himanshu Pandey
          Himanshu Pandey

          ๐Ÿ›
          Hokwang Lee
          Hokwang Lee

          ๐Ÿ›
          Hooperbloob
          Hooperbloob

          ๐Ÿ’ป
          Hung PHAN
          Hung PHAN

          ๐Ÿ›
          IDoCodingStuffs
          IDoCodingStuffs

          ๐Ÿ’ป ๐Ÿ›
          Iccen Gan
          Iccen Gan

          ๐Ÿ›
          Ignacio Mariano Tirabasso
          Ignacio Mariano Tirabasso

          ๐Ÿ›
          Ignacio Mariano Tirabasso
          Ignacio Mariano Tirabasso

          ๐Ÿ›
          Igor Melnichenko
          Igor Melnichenko

          ๐Ÿ›
          Igor Moreno
          Igor Moreno

          ๐Ÿ›
          Intelesis-MS
          Intelesis-MS

          ๐Ÿ›
          Iroha_
          Iroha_

          ๐Ÿ›
          Ishan Srivastava
          Ishan Srivastava

          ๐Ÿ›
          Iskren Stanislavov
          Iskren Stanislavov

          ๐Ÿ›
          Ivan Vakhrushev
          Ivan Vakhrushev

          ๐Ÿ›
          Ivan Vakhrushev
          Ivan Vakhrushev

          ๐Ÿ›
          Ivano Guerini
          Ivano Guerini

          ๐Ÿ›
          Ivar Andreas Bonsaksen
          Ivar Andreas Bonsaksen

          ๐Ÿ›
          Ivo ล mรญd
          Ivo ล mรญd

          ๐Ÿ›
          JJengility
          JJengility

          ๐Ÿ›
          Jake Hemmerle
          Jake Hemmerle

          ๐Ÿ›
          Jakub Dupak
          Jakub Dupak

          ๐Ÿ’ป
          James Harrison
          James Harrison

          ๐Ÿ› ๐Ÿ’ป
          James Harrison
          James Harrison

          ๐Ÿ› ๐Ÿ’ป
          Jamie Bisotti
          Jamie Bisotti

          ๐Ÿ›
          Jan
          Jan

          ๐Ÿ›
          Jan Aertgeerts
          Jan Aertgeerts

          ๐Ÿ’ป ๐Ÿ›
          Jan Brรผmmer
          Jan Brรผmmer

          ๐Ÿ›
          Jan Tล™รญska
          Jan Tล™รญska

          ๐Ÿ›
          Jan-Lukas Else
          Jan-Lukas Else

          ๐Ÿ›
          Jason Qiu
          Jason Qiu

          ๐Ÿ’ป ๐Ÿ“–
          Jason Qiu
          Jason Qiu

          ๐Ÿ’ป ๐Ÿ“–
          Jason Williams
          Jason Williams

          ๐Ÿ›
          Javier Spagnoletti
          Javier Spagnoletti

          ๐Ÿ›
          Jean-Paul Mayer
          Jean-Paul Mayer

          ๐Ÿ›
          Jean-Simon Larochelle
          Jean-Simon Larochelle

          ๐Ÿ›
          Jeff Bartolotta
          Jeff Bartolotta

          ๐Ÿ’ป ๐Ÿ›
          Jeff Hube
          Jeff Hube

          ๐Ÿ’ป ๐Ÿ›
          Jeff Jensen
          Jeff Jensen

          ๐Ÿ›
          Jeff Jensen
          Jeff Jensen

          ๐Ÿ›
          Jeff May
          Jeff May

          ๐Ÿ›
          Jens Gerdes
          Jens Gerdes

          ๐Ÿ›
          Jeroen Borgers
          Jeroen Borgers

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข
          Jeroen Meijer
          Jeroen Meijer

          ๐Ÿ›
          Jeroen van Wilgenburg
          Jeroen van Wilgenburg

          ๐Ÿ“–
          Jerome Russ
          Jerome Russ

          ๐Ÿ›
          JerritEic
          JerritEic

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
          JerritEic
          JerritEic

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
          Jiri Pejchal
          Jiri Pejchal

          ๐Ÿ›
          Jithin Sunny
          Jithin Sunny

          ๐Ÿ›
          Jiล™รญ ล korpil
          Jiล™รญ ล korpil

          ๐Ÿ›
          Joao Machado
          Joao Machado

          ๐Ÿ›
          Jochen Krauss
          Jochen Krauss

          ๐Ÿ›
          Johan Hammar
          Johan Hammar

          ๐Ÿ›
          John Jetmore
          John Jetmore

          ๐Ÿ“–
          John Jetmore
          John Jetmore

          ๐Ÿ“–
          John Karp
          John Karp

          ๐Ÿ›
          John Zhang
          John Zhang

          ๐Ÿ›
          John-Teng
          John-Teng

          ๐Ÿ’ป ๐Ÿ›
          Jon Moroney
          Jon Moroney

          ๐Ÿ’ป ๐Ÿ›
          Jonas Geiregat
          Jonas Geiregat

          ๐Ÿ›
          Jonas KeรŸler
          Jonas KeรŸler

          ๐Ÿ›
          Jonathan Wiesel
          Jonathan Wiesel

          ๐Ÿ’ป ๐Ÿ›
          Jonathan Wiesel
          Jonathan Wiesel

          ๐Ÿ’ป ๐Ÿ›
          Jordan
          Jordan

          ๐Ÿ›
          Jordi Llach
          Jordi Llach

          ๐Ÿ›
          Jorge Solรณrzano
          Jorge Solรณrzano

          ๐Ÿ›
          JorneVL
          JorneVL

          ๐Ÿ›
          Jose Palafox
          Jose Palafox

          ๐Ÿ›
          Jose Stovall
          Jose Stovall

          ๐Ÿ›
          Joseph
          Joseph

          ๐Ÿ’ป
          Joseph
          Joseph

          ๐Ÿ’ป
          Joseph Heenan
          Joseph Heenan

          ๐Ÿ›
          Josh Feingold
          Josh Feingold

          ๐Ÿ’ป ๐Ÿ›
          Josh Holthaus
          Josh Holthaus

          ๐Ÿ›
          Joshua S Arquilevich
          Joshua S Arquilevich

          ๐Ÿ›
          Joรฃo Dinis Ferreira
          Joรฃo Dinis Ferreira

          ๐Ÿ“–
          Joรฃo Ferreira
          Joรฃo Ferreira

          ๐Ÿ’ป ๐Ÿ›
          Joรฃo Pedro Schmitt
          Joรฃo Pedro Schmitt

          ๐Ÿ›
          Joรฃo Pedro Schmitt
          Joรฃo Pedro Schmitt

          ๐Ÿ›
          Juan Martรญn Sotuyo Dodero
          Juan Martรญn Sotuyo Dodero

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง
          Juan Pablo Civile
          Juan Pablo Civile

          ๐Ÿ›
          Julian Voronetsky
          Julian Voronetsky

          ๐Ÿ›
          Julien
          Julien

          ๐Ÿ›
          Julius
          Julius

          ๐Ÿ›
          JustPRV
          JustPRV

          ๐Ÿ›
          Justin Stroud
          Justin Stroud

          ๐Ÿ’ป
          Justin Stroud
          Justin Stroud

          ๐Ÿ’ป
          Jรถrn Huxhorn
          Jรถrn Huxhorn

          ๐Ÿ›
          KThompso
          KThompso

          ๐Ÿ›
          Kai Amundsen
          Kai Amundsen

          ๐Ÿ›
          Karel Vervaeke
          Karel Vervaeke

          ๐Ÿ›
          Karl-Andero Mere
          Karl-Andero Mere

          ๐Ÿ›
          Karl-Philipp Richter
          Karl-Philipp Richter

          ๐Ÿ›
          Karsten Silz
          Karsten Silz

          ๐Ÿ›
          Karsten Silz
          Karsten Silz

          ๐Ÿ›
          Kazuma Watanabe
          Kazuma Watanabe

          ๐Ÿ›
          Kev
          Kev

          ๐Ÿ›
          Keve Mรผller
          Keve Mรผller

          ๐Ÿ›
          Kevin Guerra
          Kevin Guerra

          ๐Ÿ’ป
          Kevin Jones
          Kevin Jones

          ๐Ÿ› ๐Ÿ’ป
          Kevin Poorman
          Kevin Poorman

          ๐Ÿ›
          Kevin Wayne
          Kevin Wayne

          ๐Ÿ›
          Kevin Wayne
          Kevin Wayne

          ๐Ÿ›
          Kieran Black
          Kieran Black

          ๐Ÿ›
          Kirill Zubov
          Kirill Zubov

          ๐Ÿ›
          Kirk Clemens
          Kirk Clemens

          ๐Ÿ’ป ๐Ÿ›
          Klaus Hartl
          Klaus Hartl

          ๐Ÿ›
          Koen Van Looveren
          Koen Van Looveren

          ๐Ÿ›
          Kris Scheibe
          Kris Scheibe

          ๐Ÿ’ป ๐Ÿ›
          Krystian Dabrowski
          Krystian Dabrowski

          ๐Ÿ› ๐Ÿ’ป
          Krystian Dabrowski
          Krystian Dabrowski

          ๐Ÿ› ๐Ÿ’ป
          Krzysztof Dymek
          Krzysztof Dymek

          ๐Ÿ›
          Kunal Thanki
          Kunal Thanki

          ๐Ÿ›
          Kursat Aktas
          Kursat Aktas

          ๐Ÿ“–
          LaLucid
          LaLucid

          ๐Ÿ’ป
          Larry Diamond
          Larry Diamond

          ๐Ÿ’ป ๐Ÿ›
          Lars Knickrehm
          Lars Knickrehm

          ๐Ÿ›
          Laurent Bovet
          Laurent Bovet

          ๐Ÿ› ๐Ÿ’ป
          Laurent Bovet
          Laurent Bovet

          ๐Ÿ› ๐Ÿ’ป
          Leo Gutierrez
          Leo Gutierrez

          ๐Ÿ›
          LiGaOg
          LiGaOg

          ๐Ÿ’ป
          Liam Sharp
          Liam Sharp

          ๐Ÿ›
          Lintsi
          Lintsi

          ๐Ÿ›
          Linus Fernandes
          Linus Fernandes

          ๐Ÿ›
          Lixon Lookose
          Lixon Lookose

          ๐Ÿ›
          Logesh
          Logesh

          ๐Ÿ›
          Logesh
          Logesh

          ๐Ÿ›
          Lorenzo Gabriele
          Lorenzo Gabriele

          ๐Ÿ›
          Loรฏc Ledoyen
          Loรฏc Ledoyen

          ๐Ÿ›
          Lucas
          Lucas

          ๐Ÿ›
          Lucas Silva
          Lucas Silva

          ๐Ÿ›
          Lucas Soncini
          Lucas Soncini

          ๐Ÿ’ป ๐Ÿ›
          Luis Alcantar
          Luis Alcantar

          ๐Ÿ’ป
          Lukas Grรคf
          Lukas Grรคf

          ๐Ÿ’ป
          Lukas Grรคf
          Lukas Grรคf

          ๐Ÿ’ป
          Lukasz Slonina
          Lukasz Slonina

          ๐Ÿ›
          Lukebray
          Lukebray

          ๐Ÿ›
          Lynn
          Lynn

          ๐Ÿ’ป ๐Ÿ›
          Lyor Goldstein
          Lyor Goldstein

          ๐Ÿ›
          MCMicS
          MCMicS

          ๐Ÿ›
          Macarse
          Macarse

          ๐Ÿ›
          Machine account for PMD
          Machine account for PMD

          ๐Ÿ’ป
          Machine account for PMD
          Machine account for PMD

          ๐Ÿ’ป
          Maciek Siemczyk
          Maciek Siemczyk

          ๐Ÿ›
          Maikel Steneker
          Maikel Steneker

          ๐Ÿ’ป ๐Ÿ›
          Maksim Moiseikin
          Maksim Moiseikin

          ๐Ÿ›
          Manfred Koch
          Manfred Koch

          ๐Ÿ›
          Manuel Moya Ferrer
          Manuel Moya Ferrer

          ๐Ÿ’ป ๐Ÿ›
          Manuel Romeiro
          Manuel Romeiro

          ๐Ÿ›
          Manuel Ryan
          Manuel Ryan

          ๐Ÿ›
          Manuel Ryan
          Manuel Ryan

          ๐Ÿ›
          Marat Vyshegorodtsev
          Marat Vyshegorodtsev

          ๐Ÿ›
          Marcel Hรคrle
          Marcel Hรคrle

          ๐Ÿ›
          Marcello Fialho
          Marcello Fialho

          ๐Ÿ›
          Marcin Dฤ…browski
          Marcin Dฤ…browski

          ๐Ÿ’ป
          Marcin Rataj
          Marcin Rataj

          ๐Ÿ›
          Marcono1234
          Marcono1234

          ๐Ÿ›
          Mark Adamcin
          Mark Adamcin

          ๐Ÿ›
          Mark Adamcin
          Mark Adamcin

          ๐Ÿ›
          Mark Hall
          Mark Hall

          ๐Ÿ’ป ๐Ÿ›
          Mark Kolich
          Mark Kolich

          ๐Ÿ›
          Mark Pritchard
          Mark Pritchard

          ๐Ÿ›
          Markus Rathgeb
          Markus Rathgeb

          ๐Ÿ›
          Marquis Wang
          Marquis Wang

          ๐Ÿ›
          MartGit
          MartGit

          ๐Ÿ›
          Martin Feldsztejn
          Martin Feldsztejn

          ๐Ÿ›
          Martin Feldsztejn
          Martin Feldsztejn

          ๐Ÿ›
          Martin Lehmann
          Martin Lehmann

          ๐Ÿ›
          Martin Spamer
          Martin Spamer

          ๐Ÿ›
          Martin Tarjรกnyi
          Martin Tarjรกnyi

          ๐Ÿ›
          MatFl
          MatFl

          ๐Ÿ›
          Mateusz Stefanski
          Mateusz Stefanski

          ๐Ÿ›
          Mathias Lagerwall
          Mathias Lagerwall

          ๐Ÿ›
          Mathieu Gouin
          Mathieu Gouin

          ๐Ÿ›
          Mathieu Gouin
          Mathieu Gouin

          ๐Ÿ›
          MatiasComercio
          MatiasComercio

          ๐Ÿ’ป ๐Ÿ›
          Matt Benson
          Matt Benson

          ๐Ÿ›
          Matt De Poorter
          Matt De Poorter

          ๐Ÿ›
          Matt Hargett
          Matt Hargett

          ๐Ÿ’ป ๐Ÿ’ต
          Matt Harrah
          Matt Harrah

          ๐Ÿ›
          Matt Nelson
          Matt Nelson

          ๐Ÿ›
          Matthew Amos
          Matthew Amos

          ๐Ÿ›
          Matthew Amos
          Matthew Amos

          ๐Ÿ›
          Matthew Duggan
          Matthew Duggan

          ๐Ÿ›
          Matthew Hall
          Matthew Hall

          ๐Ÿ›
          Matthew Rossner
          Matthew Rossner

          ๐Ÿ›
          Matรญas Fraga
          Matรญas Fraga

          ๐Ÿ’ป ๐Ÿ›
          Maxime Robert
          Maxime Robert

          ๐Ÿ’ป ๐Ÿ›
          MetaBF
          MetaBF

          ๐Ÿ›
          Metin Dagcilar
          Metin Dagcilar

          ๐Ÿ›
          Metin Dagcilar
          Metin Dagcilar

          ๐Ÿ›
          Michael
          Michael

          ๐Ÿ›
          Michael Bell
          Michael Bell

          ๐Ÿ›
          Michael Bernstein
          Michael Bernstein

          ๐Ÿ›
          Michael Clay
          Michael Clay

          ๐Ÿ›
          Michael Dombrowski
          Michael Dombrowski

          ๐Ÿ›
          Michael Hausegger
          Michael Hausegger

          ๐Ÿ›
          Michael Hoefer
          Michael Hoefer

          ๐Ÿ›
          Michael Hoefer
          Michael Hoefer

          ๐Ÿ›
          Michael Kolesnikov
          Michael Kolesnikov

          ๐Ÿ›
          Michael Mรถbius
          Michael Mรถbius

          ๐Ÿ›
          Michael N. Lipp
          Michael N. Lipp

          ๐Ÿ›
          Michael Pellegrini
          Michael Pellegrini

          ๐Ÿ›
          Michal Kordas
          Michal Kordas

          ๐Ÿ›
          Michaล‚ Borek
          Michaล‚ Borek

          ๐Ÿ›
          Michaล‚ Kuliล„ski
          Michaล‚ Kuliล„ski

          ๐Ÿ›
          Michaล‚ Kuliล„ski
          Michaล‚ Kuliล„ski

          ๐Ÿ›
          Miguel Nรบรฑez Dรญaz-Montes
          Miguel Nรบรฑez Dรญaz-Montes

          ๐Ÿ›
          Mihai Ionut
          Mihai Ionut

          ๐Ÿ›
          Mikhail Kuchma
          Mikhail Kuchma

          ๐Ÿ›
          Mirek Hankus
          Mirek Hankus

          ๐Ÿ›
          Mitch Spano
          Mitch Spano

          ๐Ÿ’ป ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          MrAngry52
          MrAngry52

          ๐Ÿ›
          Muminur Choudhury
          Muminur Choudhury

          ๐Ÿ›
          Mykhailo Palahuta
          Mykhailo Palahuta

          ๐Ÿ’ป ๐Ÿ›
          Nagendra Kumar Singh
          Nagendra Kumar Singh

          ๐Ÿ›
          Nahuel Barrios
          Nahuel Barrios

          ๐Ÿ›
          Nakul Sharma
          Nakul Sharma

          ๐Ÿ›
          Nathan Braun
          Nathan Braun

          ๐Ÿ›
          Nathan Braun
          Nathan Braun

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathanaรซl
          Nathanaรซl

          ๐Ÿ›
          Naveen
          Naveen

          ๐Ÿ’ป
          Nazdravi
          Nazdravi

          ๐Ÿ›
          Neha-Dhonde
          Neha-Dhonde

          ๐Ÿ›
          Nicholas Doyle
          Nicholas Doyle

          ๐Ÿ›
          Nicholas Doyle
          Nicholas Doyle

          ๐Ÿ›
          Nick Butcher
          Nick Butcher

          ๐Ÿ›
          Nico Gallinal
          Nico Gallinal

          ๐Ÿ›
          Nicola Dal Maso
          Nicola Dal Maso

          ๐Ÿ›
          Nicolas Filotto
          Nicolas Filotto

          ๐Ÿ’ป
          Nicolas Vervelle
          Nicolas Vervelle

          ๐Ÿ›
          Nicolas Vuillamy
          Nicolas Vuillamy

          ๐Ÿ“–
          Nikita Chursin
          Nikita Chursin

          ๐Ÿ›
          Nikita Chursin
          Nikita Chursin

          ๐Ÿ›
          Niklas Baudy
          Niklas Baudy

          ๐Ÿ›
          Nikolas Havrikov
          Nikolas Havrikov

          ๐Ÿ›
          Nilesh Virkar
          Nilesh Virkar

          ๐Ÿ›
          Nimit Patel
          Nimit Patel

          ๐Ÿ›
          Niranjan Harpale
          Niranjan Harpale

          ๐Ÿ›
          Nirvik Patel
          Nirvik Patel

          ๐Ÿ’ป
          Noah Sussman
          Noah Sussman

          ๐Ÿ›
          Noah Sussman
          Noah Sussman

          ๐Ÿ›
          Noah0120
          Noah0120

          ๐Ÿ›
          Noam Tamim
          Noam Tamim

          ๐Ÿ›
          Noel Grandin
          Noel Grandin

          ๐Ÿ›
          Olaf Haalstra
          Olaf Haalstra

          ๐Ÿ›
          Oleg Andreych
          Oleg Andreych

          ๐Ÿ’ป ๐Ÿ›
          Oleg Pavlenko
          Oleg Pavlenko

          ๐Ÿ›
          Oleksii Dykov
          Oleksii Dykov

          ๐Ÿ’ป ๐Ÿ›
          Oleksii Dykov
          Oleksii Dykov

          ๐Ÿ’ป ๐Ÿ›
          Oliver Eikemeier
          Oliver Eikemeier

          ๐Ÿ›
          Oliver Siegmar
          Oliver Siegmar

          ๐Ÿ’ต
          Olivier Parent
          Olivier Parent

          ๐Ÿ’ป ๐Ÿ›
          Ollie Abbey
          Ollie Abbey

          ๐Ÿ’ป ๐Ÿ›
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)

          ๐Ÿ›
          Ondrej Kratochvil
          Ondrej Kratochvil

          ๐Ÿ›
          OverDrone
          OverDrone

          ๐Ÿ›
          OverDrone
          OverDrone

          ๐Ÿ›
          Ozan Gulle
          Ozan Gulle

          ๐Ÿ’ป ๐Ÿ›
          PUNEET JAIN
          PUNEET JAIN

          ๐Ÿ›
          Parbati Bose
          Parbati Bose

          ๐Ÿ›
          Paul Berg
          Paul Berg

          ๐Ÿ›
          Paul Guyot
          Paul Guyot

          ๐Ÿ’ป
          Pavel Bludov
          Pavel Bludov

          ๐Ÿ›
          Pavel Miฤka
          Pavel Miฤka

          ๐Ÿ›
          Pavel Miฤka
          Pavel Miฤka

          ๐Ÿ›
          Pedro Nuno Santos
          Pedro Nuno Santos

          ๐Ÿ›
          Pedro Rijo
          Pedro Rijo

          ๐Ÿ›
          Pelisse Romain
          Pelisse Romain

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
          Per Abich
          Per Abich

          ๐Ÿ’ป
          Pete Davids
          Pete Davids

          ๐Ÿ›
          Peter Bruin
          Peter Bruin

          ๐Ÿ›
          Peter Chittum
          Peter Chittum

          ๐Ÿ’ป ๐Ÿ›
          Peter Chittum
          Peter Chittum

          ๐Ÿ’ป ๐Ÿ›
          Peter Cudmore
          Peter Cudmore

          ๐Ÿ›
          Peter Kasson
          Peter Kasson

          ๐Ÿ›
          Peter Kofler
          Peter Kofler

          ๐Ÿ›
          Peter Paul Bakker
          Peter Paul Bakker

          ๐Ÿ’ป ๐Ÿ›
          Peter Rader
          Peter Rader

          ๐Ÿ›
          Pham Hai Trung
          Pham Hai Trung

          ๐Ÿ›
          Philip Graf
          Philip Graf

          ๐Ÿ’ป ๐Ÿ›
          Philip Graf
          Philip Graf

          ๐Ÿ’ป ๐Ÿ›
          Philip Hachey
          Philip Hachey

          ๐Ÿ›
          Philippe Ozil
          Philippe Ozil

          ๐Ÿ›
          Phinehas Artemix
          Phinehas Artemix

          ๐Ÿ›
          Phokham Nonava
          Phokham Nonava

          ๐Ÿ›
          Pim van der Loos
          Pim van der Loos

          ๐Ÿ’ป โš ๏ธ
          Piotr Szymaล„ski
          Piotr Szymaล„ski

          ๐Ÿ›
          Piotrek ลปygieล‚o
          Piotrek ลปygieล‚o

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“–
          Piotrek ลปygieล‚o
          Piotrek ลปygieล‚o

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“–
          Pranay Jaiswal
          Pranay Jaiswal

          ๐Ÿ›
          Prasad Kamath
          Prasad Kamath

          ๐Ÿ›
          Prasanna
          Prasanna

          ๐Ÿ›
          Presh-AR
          Presh-AR

          ๐Ÿ›
          Puneet1726
          Puneet1726

          ๐Ÿ›
          RBRi
          RBRi

          ๐Ÿ›
          Rafael Cortรชs
          Rafael Cortรชs

          ๐Ÿ›
          Rafael Cortรชs
          Rafael Cortรชs

          ๐Ÿ›
          RaheemShaik999
          RaheemShaik999

          ๐Ÿ›
          RajeshR
          RajeshR

          ๐Ÿ’ป ๐Ÿ›
          Ramachandra Mohan
          Ramachandra Mohan

          ๐Ÿ›
          Ramel0921
          Ramel0921

          ๐Ÿ›
          Raquel Pau
          Raquel Pau

          ๐Ÿ›
          Ravikiran Janardhana
          Ravikiran Janardhana

          ๐Ÿ›
          Reda Benhemmouche
          Reda Benhemmouche

          ๐Ÿ›
          Reda Benhemmouche
          Reda Benhemmouche

          ๐Ÿ›
          Reinhard Schiedermeier
          Reinhard Schiedermeier

          ๐Ÿ›
          Renato Oliveira
          Renato Oliveira

          ๐Ÿ’ป ๐Ÿ›
          Rich DiCroce
          Rich DiCroce

          ๐Ÿ›
          Richard Corfield
          Richard Corfield

          ๐Ÿ’ป
          Richard Corfield
          Richard Corfield

          ๐Ÿ› ๐Ÿ’ป
          Riot R1cket
          Riot R1cket

          ๐Ÿ›
          Rishabh Jain
          Rishabh Jain

          ๐Ÿ›
          Rishabh Jain
          Rishabh Jain

          ๐Ÿ›
          RishabhDeep Singh
          RishabhDeep Singh

          ๐Ÿ›
          Rob Baillie
          Rob Baillie

          ๐Ÿ›
          Robbie Martinus
          Robbie Martinus

          ๐Ÿ’ป ๐Ÿ›
          Robert Henry
          Robert Henry

          ๐Ÿ›
          Robert Mihaly
          Robert Mihaly

          ๐Ÿ›
          Robert Painsi
          Robert Painsi

          ๐Ÿ›
          Robert Russell
          Robert Russell

          ๐Ÿ›
          Robert Russell
          Robert Russell

          ๐Ÿ›
          Robert Sรถsemann
          Robert Sรถsemann

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ›
          Robert Whitebit
          Robert Whitebit

          ๐Ÿ›
          Robin Richtsfeld
          Robin Richtsfeld

          ๐Ÿ›
          Robin Stocker
          Robin Stocker

          ๐Ÿ’ป ๐Ÿ›
          Robin Wils
          Robin Wils

          ๐Ÿ›
          RochusOest
          RochusOest

          ๐Ÿ›
          Rodolfo Noviski
          Rodolfo Noviski

          ๐Ÿ›
          Rodolfo Noviski
          Rodolfo Noviski

          ๐Ÿ›
          Rodrigo Casara
          Rodrigo Casara

          ๐Ÿ›
          Rodrigo Fernandes
          Rodrigo Fernandes

          ๐Ÿ›
          Roman Salvador
          Roman Salvador

          ๐Ÿ’ป ๐Ÿ›
          Ronald Blaschke
          Ronald Blaschke

          ๐Ÿ›
          Rรณbert Papp
          Rรณbert Papp

          ๐Ÿ›
          Saikat Sengupta
          Saikat Sengupta

          ๐Ÿ›
          Saksham Handu
          Saksham Handu

          ๐Ÿ›
          Saksham Handu
          Saksham Handu

          ๐Ÿ›
          Saladoc
          Saladoc

          ๐Ÿ›
          Salesforce Bob Lightning
          Salesforce Bob Lightning

          ๐Ÿ›
          Sam Carlberg
          Sam Carlberg

          ๐Ÿ›
          Sascha Riemer
          Sascha Riemer

          ๐Ÿ›
          Sashko
          Sashko

          ๐Ÿ’ป
          Satoshi Kubo
          Satoshi Kubo

          ๐Ÿ›
          Scott Kennedy
          Scott Kennedy

          ๐Ÿ›
          Scott Kennedy
          Scott Kennedy

          ๐Ÿ›
          Scott Wells
          Scott Wells

          ๐Ÿ› ๐Ÿ’ป
          Scrates1
          Scrates1

          ๐Ÿ› ๐Ÿ’ป
          Scrsloota
          Scrsloota

          ๐Ÿ’ป
          Sebastian Bรถgl
          Sebastian Bรถgl

          ๐Ÿ›
          Sebastian Davids
          Sebastian Davids

          ๐Ÿ›
          Sebastian Lรถvdahl
          Sebastian Lรถvdahl

          ๐Ÿ›
          Sebastian Schuberth
          Sebastian Schuberth

          ๐Ÿ›
          Sebastian Schuberth
          Sebastian Schuberth

          ๐Ÿ›
          Sebastian Schwarz
          Sebastian Schwarz

          ๐Ÿ›
          Seren
          Seren

          ๐Ÿ› ๐Ÿ’ป
          Sergey Gorbaty
          Sergey Gorbaty

          ๐Ÿ›
          Sergey Kozlov
          Sergey Kozlov

          ๐Ÿ›
          Sergey Yanzin
          Sergey Yanzin

          ๐Ÿ’ป ๐Ÿ›
          Seth Wilcox
          Seth Wilcox

          ๐Ÿ’ป
          Shai Bennathan
          Shai Bennathan

          ๐Ÿ› ๐Ÿ’ป
          Shai Bennathan
          Shai Bennathan

          ๐Ÿ› ๐Ÿ’ป
          Shubham
          Shubham

          ๐Ÿ’ป ๐Ÿ›
          Simon Abykov
          Simon Abykov

          ๐Ÿ’ป ๐Ÿ›
          Simon Xiao
          Simon Xiao

          ๐Ÿ›
          Srinivasan Venkatachalam
          Srinivasan Venkatachalam

          ๐Ÿ›
          Stanislav Gromov
          Stanislav Gromov

          ๐Ÿ›
          Stanislav Myachenkov
          Stanislav Myachenkov

          ๐Ÿ’ป
          Stefan Birkner
          Stefan Birkner

          ๐Ÿ›
          Stefan Birkner
          Stefan Birkner

          ๐Ÿ›
          Stefan Bohn
          Stefan Bohn

          ๐Ÿ›
          Stefan Endrullis
          Stefan Endrullis

          ๐Ÿ›
          Stefan Klรถss-Schuster
          Stefan Klรถss-Schuster

          ๐Ÿ›
          Stefan Wolf
          Stefan Wolf

          ๐Ÿ›
          Stephan H. Wissel
          Stephan H. Wissel

          ๐Ÿ›
          Stephen
          Stephen

          ๐Ÿ›
          Stephen Carter
          Stephen Carter

          ๐Ÿ›
          Stephen Carter
          Stephen Carter

          ๐Ÿ›
          Stephen Friedrich
          Stephen Friedrich

          ๐Ÿ›
          Steve Babula
          Steve Babula

          ๐Ÿ’ป
          Steven Stearns
          Steven Stearns

          ๐Ÿ› ๐Ÿ’ป
          Stexxe
          Stexxe

          ๐Ÿ›
          Stian Lรฅgstad
          Stian Lรฅgstad

          ๐Ÿ›
          StuartClayton5
          StuartClayton5

          ๐Ÿ›
          Supun Arunoda
          Supun Arunoda

          ๐Ÿ›
          Supun Arunoda
          Supun Arunoda

          ๐Ÿ›
          Suren Abrahamyan
          Suren Abrahamyan

          ๐Ÿ›
          Suvashri
          Suvashri

          ๐Ÿ“–
          Sven Barden
          Sven Barden

          ๐Ÿ›
          SwatiBGupta1110
          SwatiBGupta1110

          ๐Ÿ›
          SyedThoufich
          SyedThoufich

          ๐Ÿ›
          Szymon Sasin
          Szymon Sasin

          ๐Ÿ›
          T-chuangxin
          T-chuangxin

          ๐Ÿ›
          T-chuangxin
          T-chuangxin

          ๐Ÿ›
          TERAI Atsuhiro
          TERAI Atsuhiro

          ๐Ÿ›
          TIOBE Software
          TIOBE Software

          ๐Ÿ’ป ๐Ÿ›
          Tarush Singh
          Tarush Singh

          ๐Ÿ’ป
          Taylor Smock
          Taylor Smock

          ๐Ÿ›
          Techeira Damiรกn
          Techeira Damiรกn

          ๐Ÿ’ป ๐Ÿ›
          Ted Husted
          Ted Husted

          ๐Ÿ›
          TehBakker
          TehBakker

          ๐Ÿ›
          TehBakker
          TehBakker

          ๐Ÿ›
          The Gitter Badger
          The Gitter Badger

          ๐Ÿ›
          Theodoor
          Theodoor

          ๐Ÿ›
          Thiago Henrique Hรผpner
          Thiago Henrique Hรผpner

          ๐Ÿ›
          Thibault Meyer
          Thibault Meyer

          ๐Ÿ›
          Thomas Gรผttler
          Thomas Gรผttler

          ๐Ÿ›
          Thomas Jones-Low
          Thomas Jones-Low

          ๐Ÿ›
          Thomas Smith
          Thomas Smith

          ๐Ÿ’ป ๐Ÿ›
          Thomas Smith
          Thomas Smith

          ๐Ÿ’ป ๐Ÿ›
          ThrawnCA
          ThrawnCA

          ๐Ÿ›
          Thu Vo
          Thu Vo

          ๐Ÿ›
          Thunderforge
          Thunderforge

          ๐Ÿ’ป ๐Ÿ›
          Tim van der Lippe
          Tim van der Lippe

          ๐Ÿ›
          Tobias Weimer
          Tobias Weimer

          ๐Ÿ’ป ๐Ÿ›
          Tom Copeland
          Tom Copeland

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–
          Tom Daly
          Tom Daly

          ๐Ÿ›
          Tom Daly
          Tom Daly

          ๐Ÿ›
          Tomas
          Tomas

          ๐Ÿ›
          Tomer Figenblat
          Tomer Figenblat

          ๐Ÿ›
          Tomi De Lucca
          Tomi De Lucca

          ๐Ÿ’ป ๐Ÿ›
          Tony
          Tony

          ๐Ÿ“–
          Torsten Kleiber
          Torsten Kleiber

          ๐Ÿ›
          Torsten Krause
          Torsten Krause

          ๐Ÿ›
          TrackerSB
          TrackerSB

          ๐Ÿ›
          TrackerSB
          TrackerSB

          ๐Ÿ›
          Tyson Stewart
          Tyson Stewart

          ๐Ÿ›
          Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ›
          Utku Cuhadaroglu
          Utku Cuhadaroglu

          ๐Ÿ’ป ๐Ÿ›
          Valentin Brandl
          Valentin Brandl

          ๐Ÿ›
          Valeria
          Valeria

          ๐Ÿ›
          Valery Yatsynovich
          Valery Yatsynovich

          ๐Ÿ“–
          Vasily Anisimov
          Vasily Anisimov

          ๐Ÿ›
          Vasily Anisimov
          Vasily Anisimov

          ๐Ÿ›
          Vedant Chokshi
          Vedant Chokshi

          ๐Ÿ›
          Vibhor Goyal
          Vibhor Goyal

          ๐Ÿ›
          Vickenty Fesunov
          Vickenty Fesunov

          ๐Ÿ›
          Victor Noรซl
          Victor Noรซl

          ๐Ÿ›
          Vincent Galloy
          Vincent Galloy

          ๐Ÿ’ป
          Vincent HUYNH
          Vincent HUYNH

          ๐Ÿ›
          Vincent Maurin
          Vincent Maurin

          ๐Ÿ›
          Vincent Maurin
          Vincent Maurin

          ๐Ÿ›
          Vincent Potucek
          Vincent Potucek

          ๐Ÿ’ป
          Vincent Privat
          Vincent Privat

          ๐Ÿ›
          Vishhwas
          Vishhwas

          ๐Ÿ›
          Vishv_Android
          Vishv_Android

          ๐Ÿ›
          Vitalii Yevtushenko
          Vitalii Yevtushenko

          ๐Ÿ›
          Vitaly
          Vitaly

          ๐Ÿ›
          Vitaly Polonetsky
          Vitaly Polonetsky

          ๐Ÿ›
          Vitaly Polonetsky
          Vitaly Polonetsky

          ๐Ÿ›
          Vojtech Polivka
          Vojtech Polivka

          ๐Ÿ›
          Vsevolod Zholobov
          Vsevolod Zholobov

          ๐Ÿ›
          Vyom Yadav
          Vyom Yadav

          ๐Ÿ’ป
          Wang Shidong
          Wang Shidong

          ๐Ÿ›
          Waqas Ahmed
          Waqas Ahmed

          ๐Ÿ›
          Wayne J. Earl
          Wayne J. Earl

          ๐Ÿ›
          Wchenghui
          Wchenghui

          ๐Ÿ›
          Wchenghui
          Wchenghui

          ๐Ÿ›
          Wener
          Wener

          ๐Ÿ’ป
          Will Winder
          Will Winder

          ๐Ÿ›
          Willem A. Hajenius
          Willem A. Hajenius

          ๐Ÿ’ป
          William Brockhus
          William Brockhus

          ๐Ÿ’ป ๐Ÿ›
          Wilson Kurniawan
          Wilson Kurniawan

          ๐Ÿ›
          Wim Deblauwe
          Wim Deblauwe

          ๐Ÿ›
          Wolf2323
          Wolf2323

          ๐Ÿ›
          Wolf2323
          Wolf2323

          ๐Ÿ›
          Woongsik Choi
          Woongsik Choi

          ๐Ÿ›
          XenoAmess
          XenoAmess

          ๐Ÿ’ป ๐Ÿ›
          Yang
          Yang

          ๐Ÿ’ป
          YaroslavTER
          YaroslavTER

          ๐Ÿ›
          Yasar Shaikh
          Yasar Shaikh

          ๐Ÿ’ป
          Young Chan
          Young Chan

          ๐Ÿ’ป ๐Ÿ›
          YuJin Kim
          YuJin Kim

          ๐Ÿ›
          YuJin Kim
          YuJin Kim

          ๐Ÿ›
          Yuri Dolzhenko
          Yuri Dolzhenko

          ๐Ÿ›
          Yurii Dubinka
          Yurii Dubinka

          ๐Ÿ›
          Zoltan Farkas
          Zoltan Farkas

          ๐Ÿ›
          Zustin
          Zustin

          ๐Ÿ›
          aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป
          alexmodis
          alexmodis

          ๐Ÿ›
          andreoss
          andreoss

          ๐Ÿ›
          andreoss
          andreoss

          ๐Ÿ›
          andrey81inmd
          andrey81inmd

          ๐Ÿ’ป ๐Ÿ›
          anicoara
          anicoara

          ๐Ÿ›
          arunprasathav
          arunprasathav

          ๐Ÿ›
          asiercamara
          asiercamara

          ๐Ÿ›
          astillich-igniti
          astillich-igniti

          ๐Ÿ’ป
          avesolovksyy
          avesolovksyy

          ๐Ÿ›
          avishvat
          avishvat

          ๐Ÿ›
          avishvat
          avishvat

          ๐Ÿ›
          avivmu
          avivmu

          ๐Ÿ›
          axelbarfod1
          axelbarfod1

          ๐Ÿ›
          b-3-n
          b-3-n

          ๐Ÿ›
          balbhadra9
          balbhadra9

          ๐Ÿ›
          base23de
          base23de

          ๐Ÿ›
          bergander
          bergander

          ๐Ÿ› ๐Ÿ’ป
          berkam
          berkam

          ๐Ÿ’ป ๐Ÿ›
          berkam
          berkam

          ๐Ÿ’ป ๐Ÿ›
          breizh31
          breizh31

          ๐Ÿ›
          caesarkim
          caesarkim

          ๐Ÿ›
          caiocarvalhotero
          caiocarvalhotero

          ๐Ÿ›
          carolyujing
          carolyujing

          ๐Ÿ›
          cbfiddle
          cbfiddle

          ๐Ÿ›
          cesares-basilico
          cesares-basilico

          ๐Ÿ›
          chrite
          chrite

          ๐Ÿ›
          chrite
          chrite

          ๐Ÿ›
          ciufudean
          ciufudean

          ๐Ÿ“–
          cobratbq
          cobratbq

          ๐Ÿ›
          coladict
          coladict

          ๐Ÿ›
          cosmoJFH
          cosmoJFH

          ๐Ÿ›
          cristalp
          cristalp

          ๐Ÿ›
          crunsk
          crunsk

          ๐Ÿ›
          cwholmes
          cwholmes

          ๐Ÿ›
          cwholmes
          cwholmes

          ๐Ÿ›
          cyberjj999
          cyberjj999

          ๐Ÿ›
          cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“–
          d1ss0nanz
          d1ss0nanz

          ๐Ÿ›
          dague1
          dague1

          ๐Ÿ“–
          dalizi007
          dalizi007

          ๐Ÿ’ป
          danbrycefairsailcom
          danbrycefairsailcom

          ๐Ÿ›
          dariansanity
          dariansanity

          ๐Ÿ›
          dariansanity
          dariansanity

          ๐Ÿ›
          darrenmiliband
          darrenmiliband

          ๐Ÿ›
          davidburstrom
          davidburstrom

          ๐Ÿ›
          dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ›
          deepak-patra
          deepak-patra

          ๐Ÿ›
          dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ›
          dinesh150
          dinesh150

          ๐Ÿ›
          diziaq
          diziaq

          ๐Ÿ›
          diziaq
          diziaq

          ๐Ÿ›
          dreaminpast123
          dreaminpast123

          ๐Ÿ›
          duanyanan
          duanyanan

          ๐Ÿ›
          dutt-sanjay
          dutt-sanjay

          ๐Ÿ›
          duursma
          duursma

          ๐Ÿ’ป
          dylanleung
          dylanleung

          ๐Ÿ›
          dzeigler
          dzeigler

          ๐Ÿ›
          eant60
          eant60

          ๐Ÿ›
          eant60
          eant60

          ๐Ÿ›
          ekkirala
          ekkirala

          ๐Ÿ›
          emersonmoura
          emersonmoura

          ๐Ÿ›
          emouty
          emouty

          ๐Ÿ’ป ๐Ÿ›
          eugenepugach
          eugenepugach

          ๐Ÿ›
          fairy
          fairy

          ๐Ÿ›
          filiprafalowicz
          filiprafalowicz

          ๐Ÿ’ป
          flxbl-io
          flxbl-io

          ๐Ÿ’ต
          flxbl-io
          flxbl-io

          ๐Ÿ’ต
          foxmason
          foxmason

          ๐Ÿ›
          frankegabor
          frankegabor

          ๐Ÿ›
          frankl
          frankl

          ๐Ÿ›
          freafrea
          freafrea

          ๐Ÿ›
          fsapatin
          fsapatin

          ๐Ÿ›
          gearsethenry
          gearsethenry

          ๐Ÿ›
          gracia19
          gracia19

          ๐Ÿ›
          gracia19
          gracia19

          ๐Ÿ›
          gudzpoz
          gudzpoz

          ๐Ÿ›
          guo fei
          guo fei

          ๐Ÿ›
          gurmsc5
          gurmsc5

          ๐Ÿ›
          gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ›
          haigsn
          haigsn

          ๐Ÿ›
          hemanshu070
          hemanshu070

          ๐Ÿ›
          henrik242
          henrik242

          ๐Ÿ›
          henrik242
          henrik242

          ๐Ÿ›
          hongpuwu
          hongpuwu

          ๐Ÿ›
          hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ›
          igniti GmbH
          igniti GmbH

          ๐Ÿ›
          ilovezfs
          ilovezfs

          ๐Ÿ›
          imax-erik
          imax-erik

          ๐Ÿ›
          itaigilo
          itaigilo

          ๐Ÿ›
          jakivey32
          jakivey32

          ๐Ÿ›
          jakivey32
          jakivey32

          ๐Ÿ›
          jbennett2091
          jbennett2091

          ๐Ÿ›
          jcamerin
          jcamerin

          ๐Ÿ›
          jkeener1
          jkeener1

          ๐Ÿ›
          jmetertea
          jmetertea

          ๐Ÿ›
          johnra2
          johnra2

          ๐Ÿ’ป
          johnzhao9
          johnzhao9

          ๐Ÿ›
          josemanuelrolon
          josemanuelrolon

          ๐Ÿ’ป ๐Ÿ›
          josemanuelrolon
          josemanuelrolon

          ๐Ÿ’ป ๐Ÿ›
          julees7
          julees7

          ๐Ÿ’ป ๐Ÿ›
          kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ›
          karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“–
          karwer
          karwer

          ๐Ÿ›
          kaulonline
          kaulonline

          ๐Ÿ›
          kdaemonv
          kdaemonv

          ๐Ÿ›
          kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป
          kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป
          kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ›
          kfranic
          kfranic

          ๐Ÿ›
          khalidkh
          khalidkh

          ๐Ÿ›
          koalalam
          koalalam

          ๐Ÿ›
          krzyk
          krzyk

          ๐Ÿ›
          lasselindqvist
          lasselindqvist

          ๐Ÿ›
          lgemeinhardt
          lgemeinhardt

          ๐Ÿ›
          lgemeinhardt
          lgemeinhardt

          ๐Ÿ›
          lihuaib
          lihuaib

          ๐Ÿ›
          liqingjun123
          liqingjun123

          ๐Ÿ›
          lonelyma1021
          lonelyma1021

          ๐Ÿ›
          lpeddy
          lpeddy

          ๐Ÿ›
          lujiefsi
          lujiefsi

          ๐Ÿ’ป
          lukelukes
          lukelukes

          ๐Ÿ’ป
          lyriccoder
          lyriccoder

          ๐Ÿ›
          lyriccoder
          lyriccoder

          ๐Ÿ›
          marcelmore
          marcelmore

          ๐Ÿ›
          matchbox
          matchbox

          ๐Ÿ›
          matthiaskraaz
          matthiaskraaz

          ๐Ÿ›
          meandonlyme
          meandonlyme

          ๐Ÿ›
          mikesive
          mikesive

          ๐Ÿ›
          milossesic
          milossesic

          ๐Ÿ›
          mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ›
          mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ›
          mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป
          mriddell95
          mriddell95

          ๐Ÿ›
          mrlzh
          mrlzh

          ๐Ÿ›
          msloan
          msloan

          ๐Ÿ›
          mucharlaravalika
          mucharlaravalika

          ๐Ÿ›
          mvenneman
          mvenneman

          ๐Ÿ›
          nareshl119
          nareshl119

          ๐Ÿ›
          nareshl119
          nareshl119

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          noerremark
          noerremark

          ๐Ÿ›
          novsirion
          novsirion

          ๐Ÿ›
          nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป
          oggboy
          oggboy

          ๐Ÿ›
          oinume
          oinume

          ๐Ÿ›
          orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ›
          orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pacvz
          pacvz

          ๐Ÿ’ป
          pallavi agarwal
          pallavi agarwal

          ๐Ÿ›
          pankratz76
          pankratz76

          ๐Ÿ›
          parksungrin
          parksungrin

          ๐Ÿ›
          patpatpat123
          patpatpat123

          ๐Ÿ›
          patriksevallius
          patriksevallius

          ๐Ÿ›
          patriksevallius
          patriksevallius

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          phoenix384
          phoenix384

          ๐Ÿ›
          piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป
          plan3d
          plan3d

          ๐Ÿ›
          poojasix
          poojasix

          ๐Ÿ›
          prabhushrikant
          prabhushrikant

          ๐Ÿ›
          pujitha8783
          pujitha8783

          ๐Ÿ›
          pujitha8783
          pujitha8783

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          raghujayjunk
          raghujayjunk

          ๐Ÿ›
          rajeshveera
          rajeshveera

          ๐Ÿ›
          rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ›
          recdevs
          recdevs

          ๐Ÿ›
          reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ›
          rijkt
          rijkt

          ๐Ÿ›
          rijkt
          rijkt

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ›
          rnveach
          rnveach

          ๐Ÿ›
          rxmicro
          rxmicro

          ๐Ÿ›
          ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ›
          sabi0
          sabi0

          ๐Ÿ›
          samc-gearset
          samc-gearset

          ๐Ÿ“–
          samc-gearset
          samc-gearset

          ๐Ÿ“–
          scais
          scais

          ๐Ÿ›
          schosin
          schosin

          ๐Ÿ›
          screamingfrog
          screamingfrog

          ๐Ÿ’ต
          sebbASF
          sebbASF

          ๐Ÿ›
          sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป
          shilko2013
          shilko2013

          ๐Ÿ›
          shiomiyan
          shiomiyan

          ๐Ÿ“–
          shiomiyan
          shiomiyan

          ๐Ÿ“–
          simeonKondr
          simeonKondr

          ๐Ÿ›
          snajberk
          snajberk

          ๐Ÿ›
          sniperrifle2004
          sniperrifle2004

          ๐Ÿ›
          snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป
          soloturn
          soloturn

          ๐Ÿ›
          soyodream
          soyodream

          ๐Ÿ›
          sratz
          sratz

          ๐Ÿ›
          sratz
          sratz

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          sturton
          sturton

          ๐Ÿ’ป ๐Ÿ›
          sudharmohan
          sudharmohan

          ๐Ÿ›
          suruchidawar
          suruchidawar

          ๐Ÿ›
          svenfinitiv
          svenfinitiv

          ๐Ÿ›
          szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป
          tashiscool
          tashiscool

          ๐Ÿ›
          tashiscool
          tashiscool

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          testation21
          testation21

          ๐Ÿ’ป ๐Ÿ›
          thanosa
          thanosa

          ๐Ÿ›
          tiandiyixian
          tiandiyixian

          ๐Ÿ›
          tobwoerk
          tobwoerk

          ๐Ÿ›
          tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป
          trentchilders
          trentchilders

          ๐Ÿ›
          trentchilders
          trentchilders

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          trishul14
          trishul14

          ๐Ÿ›
          tsui
          tsui

          ๐Ÿ›
          wangzitom12306
          wangzitom12306

          ๐Ÿ›
          winhkey
          winhkey

          ๐Ÿ›
          witherspore
          witherspore

          ๐Ÿ›
          wjljack
          wjljack

          ๐Ÿ›
          wjljack
          wjljack

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          xingsong
          xingsong

          ๐Ÿ›
          xioayuge
          xioayuge

          ๐Ÿ›
          xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ›
          xuanuy
          xuanuy

          ๐Ÿ›
          xyf0921
          xyf0921

          ๐Ÿ›
          yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ›
          yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yasuharu-sato
          yasuharu-sato

          ๐Ÿ›
          zenglian
          zenglian

          ๐Ÿ›
          zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ›
          zh3ng
          zh3ng

          ๐Ÿ›
          zt_soft
          zt_soft

          ๐Ÿ›
          ztt79
          ztt79

          ๐Ÿ›
          ztt79
          ztt79

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ›
          ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ›
          Elan P. Kugelmass
          Elan P. Kugelmass

          ๐Ÿ›
          Elder S.
          Elder S.

          ๐Ÿ›
          Eldrick Wega
          Eldrick Wega

          ๐Ÿ“–
          Elliotte Rusty Harold
          Elliotte Rusty Harold

          ๐Ÿ’ป
          Emile
          Emile

          ๐Ÿ›
          Eric
          Eric

          ๐Ÿ›
          Eric
          Eric

          ๐Ÿ›
          Eric Kintzer
          Eric Kintzer

          ๐Ÿ›
          Eric Perret
          Eric Perret

          ๐Ÿ›
          Eric Squires
          Eric Squires

          ๐Ÿ›
          Erich L Foster
          Erich L Foster

          ๐Ÿ›
          Erik Bleske
          Erik Bleske

          ๐Ÿ›
          Erik C. Thauvin
          Erik C. Thauvin

          ๐Ÿ“–
          Ernst Reissner
          Ernst Reissner

          ๐Ÿ›
          Ernst Reissner
          Ernst Reissner

          ๐Ÿ›
          Ethan Sargent
          Ethan Sargent

          ๐Ÿ›
          Ewan Tempero
          Ewan Tempero

          ๐Ÿ›
          F.W. Dekker
          F.W. Dekker

          ๐Ÿ›
          FSchliephacke
          FSchliephacke

          ๐Ÿ›
          Facundo
          Facundo

          ๐Ÿ›
          Federico Giust
          Federico Giust

          ๐Ÿ›
          Fedor Sherstobitov
          Fedor Sherstobitov

          ๐Ÿ›
          Fedor Sherstobitov
          Fedor Sherstobitov

          ๐Ÿ›
          Felix Lampe
          Felix Lampe

          ๐Ÿ›
          Filip Golonka
          Filip Golonka

          ๐Ÿ›
          Filipe Esperandio
          Filipe Esperandio

          ๐Ÿ’ป ๐Ÿ›
          Filippo Nova
          Filippo Nova

          ๐Ÿ›
          Francesco la Torre
          Francesco la Torre

          ๐Ÿ›
          Francisco Duarte
          Francisco Duarte

          ๐Ÿ›
          Frederick Zhang
          Frederick Zhang

          ๐Ÿ›
          Frederick Zhang
          Frederick Zhang

          ๐Ÿ›
          Frieder Bluemle
          Frieder Bluemle

          ๐Ÿ›
          Frits Jalvingh
          Frits Jalvingh

          ๐Ÿ’ป ๐Ÿ›
          G. Bazior
          G. Bazior

          ๐Ÿ›
          Gabe Henkes
          Gabe Henkes

          ๐Ÿ›
          Gary Gregory
          Gary Gregory

          ๐Ÿ›
          Genoud Magloire
          Genoud Magloire

          ๐Ÿ›
          Geoffrey555
          Geoffrey555

          ๐Ÿ›
          Geoffrey555
          Geoffrey555

          ๐Ÿ›
          Georg Romstorfer
          Georg Romstorfer

          ๐Ÿ›
          Gili Tzabari
          Gili Tzabari

          ๐Ÿ› ๐Ÿ’ป
          Gio
          Gio

          ๐Ÿ›
          Gol
          Gol

          ๐Ÿ›
          Gold856
          Gold856

          ๐Ÿ› ๐Ÿ’ป
          Gonzalo Exequiel Ibars Ingman
          Gonzalo Exequiel Ibars Ingman

          ๐Ÿ’ป ๐Ÿ›
          GooDer
          GooDer

          ๐Ÿ›
          GooDer
          GooDer

          ๐Ÿ›
          Gregor Riegler
          Gregor Riegler

          ๐Ÿ›
          Grzegorz Olszewski
          Grzegorz Olszewski

          ๐Ÿ›
          Gunther Schrijvers
          Gunther Schrijvers

          ๐Ÿ’ป ๐Ÿ›
          Gustavo Krieger
          Gustavo Krieger

          ๐Ÿ›
          Guy Elsmore-Paddock
          Guy Elsmore-Paddock

          ๐Ÿ›
          Gรถrkem Mรผlayim
          Gรถrkem Mรผlayim

          ๐Ÿ›
          Hanzel Godinez
          Hanzel Godinez

          ๐Ÿ›
          Hanzel Godinez
          Hanzel Godinez

          ๐Ÿ›
          Haoliang Chen
          Haoliang Chen

          ๐Ÿ›
          Harsh Kukreja
          Harsh Kukreja

          ๐Ÿ›
          Hassan ALAMI
          Hassan ALAMI

          ๐Ÿ›
          Heber
          Heber

          ๐Ÿ›
          Hector Miuler Malpica Gallegos
          Hector Miuler Malpica Gallegos

          ๐Ÿ›
          Henning Schmiedehausen
          Henning Schmiedehausen

          ๐Ÿ’ป ๐Ÿ›
          Henning von Bargen
          Henning von Bargen

          ๐Ÿ’ป
          Henning von Bargen
          Henning von Bargen

          ๐Ÿ’ป
          Hervรฉ Boutemy
          Hervรฉ Boutemy

          ๐Ÿ›
          Himanshu Pandey
          Himanshu Pandey

          ๐Ÿ›
          Hokwang Lee
          Hokwang Lee

          ๐Ÿ›
          Hooperbloob
          Hooperbloob

          ๐Ÿ’ป
          Hung PHAN
          Hung PHAN

          ๐Ÿ›
          IDoCodingStuffs
          IDoCodingStuffs

          ๐Ÿ’ป ๐Ÿ›
          Iccen Gan
          Iccen Gan

          ๐Ÿ›
          Iccen Gan
          Iccen Gan

          ๐Ÿ›
          Ignacio Mariano Tirabasso
          Ignacio Mariano Tirabasso

          ๐Ÿ›
          Igor Melnichenko
          Igor Melnichenko

          ๐Ÿ›
          Igor Moreno
          Igor Moreno

          ๐Ÿ›
          Intelesis-MS
          Intelesis-MS

          ๐Ÿ›
          Iroha_
          Iroha_

          ๐Ÿ›
          Ishan Srivastava
          Ishan Srivastava

          ๐Ÿ›
          Iskren Stanislavov
          Iskren Stanislavov

          ๐Ÿ›
          Iskren Stanislavov
          Iskren Stanislavov

          ๐Ÿ›
          Ivan Vakhrushev
          Ivan Vakhrushev

          ๐Ÿ›
          Ivano Guerini
          Ivano Guerini

          ๐Ÿ›
          Ivar Andreas Bonsaksen
          Ivar Andreas Bonsaksen

          ๐Ÿ›
          Ivo ล mรญd
          Ivo ล mรญd

          ๐Ÿ›
          JJengility
          JJengility

          ๐Ÿ›
          Jake Hemmerle
          Jake Hemmerle

          ๐Ÿ›
          Jakub Dupak
          Jakub Dupak

          ๐Ÿ’ป
          Jakub Dupak
          Jakub Dupak

          ๐Ÿ’ป
          James Harrison
          James Harrison

          ๐Ÿ› ๐Ÿ’ป
          Jamie Bisotti
          Jamie Bisotti

          ๐Ÿ›
          Jan
          Jan

          ๐Ÿ›
          Jan Aertgeerts
          Jan Aertgeerts

          ๐Ÿ’ป ๐Ÿ›
          Jan Brรผmmer
          Jan Brรผmmer

          ๐Ÿ›
          Jan Tล™รญska
          Jan Tล™รญska

          ๐Ÿ›
          Jan-Lukas Else
          Jan-Lukas Else

          ๐Ÿ›
          Jan-Lukas Else
          Jan-Lukas Else

          ๐Ÿ›
          Jason Qiu
          Jason Qiu

          ๐Ÿ’ป ๐Ÿ“–
          Jason Williams
          Jason Williams

          ๐Ÿ›
          Javier Spagnoletti
          Javier Spagnoletti

          ๐Ÿ›
          Jean-Paul Mayer
          Jean-Paul Mayer

          ๐Ÿ›
          Jean-Simon Larochelle
          Jean-Simon Larochelle

          ๐Ÿ›
          Jeff Bartolotta
          Jeff Bartolotta

          ๐Ÿ’ป ๐Ÿ›
          Jeff Hube
          Jeff Hube

          ๐Ÿ’ป ๐Ÿ›
          Jeff Hube
          Jeff Hube

          ๐Ÿ’ป ๐Ÿ›
          Jeff Jensen
          Jeff Jensen

          ๐Ÿ›
          Jeff May
          Jeff May

          ๐Ÿ›
          Jens Gerdes
          Jens Gerdes

          ๐Ÿ›
          Jeroen Borgers
          Jeroen Borgers

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข
          Jeroen Meijer
          Jeroen Meijer

          ๐Ÿ›
          Jeroen van Wilgenburg
          Jeroen van Wilgenburg

          ๐Ÿ“–
          Jerome Russ
          Jerome Russ

          ๐Ÿ›
          Jerome Russ
          Jerome Russ

          ๐Ÿ›
          JerritEic
          JerritEic

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
          Jiri Pejchal
          Jiri Pejchal

          ๐Ÿ›
          Jithin Sunny
          Jithin Sunny

          ๐Ÿ›
          Jiล™รญ ล korpil
          Jiล™รญ ล korpil

          ๐Ÿ›
          Joao Machado
          Joao Machado

          ๐Ÿ›
          Jochen Krauss
          Jochen Krauss

          ๐Ÿ›
          Johan Hammar
          Johan Hammar

          ๐Ÿ›
          Johan Hammar
          Johan Hammar

          ๐Ÿ›
          John Jetmore
          John Jetmore

          ๐Ÿ“–
          John Karp
          John Karp

          ๐Ÿ›
          John Zhang
          John Zhang

          ๐Ÿ›
          John-Teng
          John-Teng

          ๐Ÿ’ป ๐Ÿ›
          Jon Moroney
          Jon Moroney

          ๐Ÿ’ป ๐Ÿ›
          Jonas Geiregat
          Jonas Geiregat

          ๐Ÿ›
          Jonas KeรŸler
          Jonas KeรŸler

          ๐Ÿ›
          Jonas KeรŸler
          Jonas KeรŸler

          ๐Ÿ›
          Jonathan Wiesel
          Jonathan Wiesel

          ๐Ÿ’ป ๐Ÿ›
          Jordan
          Jordan

          ๐Ÿ›
          Jordi Llach
          Jordi Llach

          ๐Ÿ›
          Jorge Solรณrzano
          Jorge Solรณrzano

          ๐Ÿ›
          JorneVL
          JorneVL

          ๐Ÿ›
          Jose Palafox
          Jose Palafox

          ๐Ÿ›
          Jose Stovall
          Jose Stovall

          ๐Ÿ›
          Jose Stovall
          Jose Stovall

          ๐Ÿ›
          Joseph
          Joseph

          ๐Ÿ’ป
          Joseph Heenan
          Joseph Heenan

          ๐Ÿ›
          Josh Feingold
          Josh Feingold

          ๐Ÿ’ป ๐Ÿ›
          Josh Holthaus
          Josh Holthaus

          ๐Ÿ›
          Joshua S Arquilevich
          Joshua S Arquilevich

          ๐Ÿ›
          Joรฃo Dinis Ferreira
          Joรฃo Dinis Ferreira

          ๐Ÿ“–
          Joรฃo Ferreira
          Joรฃo Ferreira

          ๐Ÿ’ป ๐Ÿ›
          Joรฃo Ferreira
          Joรฃo Ferreira

          ๐Ÿ’ป ๐Ÿ›
          Joรฃo Pedro Schmitt
          Joรฃo Pedro Schmitt

          ๐Ÿ›
          Juan Martรญn Sotuyo Dodero
          Juan Martรญn Sotuyo Dodero

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง
          Juan Pablo Civile
          Juan Pablo Civile

          ๐Ÿ›
          Julian Voronetsky
          Julian Voronetsky

          ๐Ÿ›
          Julien
          Julien

          ๐Ÿ›
          Julius
          Julius

          ๐Ÿ›
          JustPRV
          JustPRV

          ๐Ÿ›
          JustPRV
          JustPRV

          ๐Ÿ›
          Justin Stroud
          Justin Stroud

          ๐Ÿ’ป
          Jรถrn Huxhorn
          Jรถrn Huxhorn

          ๐Ÿ›
          KThompso
          KThompso

          ๐Ÿ›
          Kai Amundsen
          Kai Amundsen

          ๐Ÿ›
          Karel Vervaeke
          Karel Vervaeke

          ๐Ÿ›
          Karl-Andero Mere
          Karl-Andero Mere

          ๐Ÿ›
          Karl-Philipp Richter
          Karl-Philipp Richter

          ๐Ÿ›
          Karl-Philipp Richter
          Karl-Philipp Richter

          ๐Ÿ›
          Karsten Silz
          Karsten Silz

          ๐Ÿ›
          Kazuma Watanabe
          Kazuma Watanabe

          ๐Ÿ›
          Kev
          Kev

          ๐Ÿ›
          Keve Mรผller
          Keve Mรผller

          ๐Ÿ›
          Kevin Guerra
          Kevin Guerra

          ๐Ÿ’ป
          Kevin Jones
          Kevin Jones

          ๐Ÿ› ๐Ÿ’ป
          Kevin Poorman
          Kevin Poorman

          ๐Ÿ›
          Kevin Poorman
          Kevin Poorman

          ๐Ÿ›
          Kevin Wayne
          Kevin Wayne

          ๐Ÿ›
          Kieran Black
          Kieran Black

          ๐Ÿ›
          Kirill Zubov
          Kirill Zubov

          ๐Ÿ›
          Kirk Clemens
          Kirk Clemens

          ๐Ÿ’ป ๐Ÿ›
          Klaus Hartl
          Klaus Hartl

          ๐Ÿ›
          Koen Van Looveren
          Koen Van Looveren

          ๐Ÿ›
          Kris Scheibe
          Kris Scheibe

          ๐Ÿ’ป ๐Ÿ›
          Kris Scheibe
          Kris Scheibe

          ๐Ÿ’ป ๐Ÿ›
          Krystian Dabrowski
          Krystian Dabrowski

          ๐Ÿ› ๐Ÿ’ป
          Krzysztof Dymek
          Krzysztof Dymek

          ๐Ÿ›
          Kunal Thanki
          Kunal Thanki

          ๐Ÿ›
          Kursat Aktas
          Kursat Aktas

          ๐Ÿ“–
          LaLucid
          LaLucid

          ๐Ÿ’ป
          Larry Diamond
          Larry Diamond

          ๐Ÿ’ป ๐Ÿ›
          Lars Knickrehm
          Lars Knickrehm

          ๐Ÿ›
          Lars Knickrehm
          Lars Knickrehm

          ๐Ÿ›
          Laurent Bovet
          Laurent Bovet

          ๐Ÿ› ๐Ÿ’ป
          Leo Gutierrez
          Leo Gutierrez

          ๐Ÿ›
          LiGaOg
          LiGaOg

          ๐Ÿ’ป
          Liam Sharp
          Liam Sharp

          ๐Ÿ›
          Lintsi
          Lintsi

          ๐Ÿ›
          Linus Fernandes
          Linus Fernandes

          ๐Ÿ›
          Lixon Lookose
          Lixon Lookose

          ๐Ÿ›
          Lixon Lookose
          Lixon Lookose

          ๐Ÿ›
          Logesh
          Logesh

          ๐Ÿ›
          Lorenzo Gabriele
          Lorenzo Gabriele

          ๐Ÿ›
          Loรฏc Ledoyen
          Loรฏc Ledoyen

          ๐Ÿ›
          Lucas
          Lucas

          ๐Ÿ›
          Lucas Silva
          Lucas Silva

          ๐Ÿ›
          Lucas Soncini
          Lucas Soncini

          ๐Ÿ’ป ๐Ÿ›
          Luis Alcantar
          Luis Alcantar

          ๐Ÿ’ป
          Luis Alcantar
          Luis Alcantar

          ๐Ÿ’ป
          Lukas Grรคf
          Lukas Grรคf

          ๐Ÿ’ป
          Lukasz Slonina
          Lukasz Slonina

          ๐Ÿ›
          Lukebray
          Lukebray

          ๐Ÿ›
          Lynn
          Lynn

          ๐Ÿ’ป ๐Ÿ›
          Lyor Goldstein
          Lyor Goldstein

          ๐Ÿ›
          MCMicS
          MCMicS

          ๐Ÿ›
          Macarse
          Macarse

          ๐Ÿ›
          Macarse
          Macarse

          ๐Ÿ›
          Machine account for PMD
          Machine account for PMD

          ๐Ÿ’ป
          Maciek Siemczyk
          Maciek Siemczyk

          ๐Ÿ›
          Maikel Steneker
          Maikel Steneker

          ๐Ÿ’ป ๐Ÿ›
          Maksim Moiseikin
          Maksim Moiseikin

          ๐Ÿ›
          Manfred Koch
          Manfred Koch

          ๐Ÿ›
          Manuel Moya Ferrer
          Manuel Moya Ferrer

          ๐Ÿ’ป ๐Ÿ›
          Manuel Romeiro
          Manuel Romeiro

          ๐Ÿ›
          Manuel Romeiro
          Manuel Romeiro

          ๐Ÿ›
          Manuel Ryan
          Manuel Ryan

          ๐Ÿ›
          Marat Vyshegorodtsev
          Marat Vyshegorodtsev

          ๐Ÿ›
          Marcel Hรคrle
          Marcel Hรคrle

          ๐Ÿ›
          Marcello Fialho
          Marcello Fialho

          ๐Ÿ›
          Marcin Dฤ…browski
          Marcin Dฤ…browski

          ๐Ÿ’ป
          Marcin Rataj
          Marcin Rataj

          ๐Ÿ›
          Marcono1234
          Marcono1234

          ๐Ÿ›
          Marcono1234
          Marcono1234

          ๐Ÿ›
          Mark Adamcin
          Mark Adamcin

          ๐Ÿ›
          Mark Hall
          Mark Hall

          ๐Ÿ’ป ๐Ÿ›
          Mark Kolich
          Mark Kolich

          ๐Ÿ›
          Mark Pritchard
          Mark Pritchard

          ๐Ÿ›
          Markus Rathgeb
          Markus Rathgeb

          ๐Ÿ›
          Marquis Wang
          Marquis Wang

          ๐Ÿ›
          MartGit
          MartGit

          ๐Ÿ›
          MartGit
          MartGit

          ๐Ÿ›
          Martin Feldsztejn
          Martin Feldsztejn

          ๐Ÿ›
          Martin Lehmann
          Martin Lehmann

          ๐Ÿ›
          Martin Spamer
          Martin Spamer

          ๐Ÿ›
          Martin Tarjรกnyi
          Martin Tarjรกnyi

          ๐Ÿ›
          MatFl
          MatFl

          ๐Ÿ›
          Mateusz Stefanski
          Mateusz Stefanski

          ๐Ÿ›
          Mathias Lagerwall
          Mathias Lagerwall

          ๐Ÿ›
          Mathias Lagerwall
          Mathias Lagerwall

          ๐Ÿ›
          Mathieu Gouin
          Mathieu Gouin

          ๐Ÿ›
          MatiasComercio
          MatiasComercio

          ๐Ÿ’ป ๐Ÿ›
          Matt Benson
          Matt Benson

          ๐Ÿ›
          Matt De Poorter
          Matt De Poorter

          ๐Ÿ›
          Matt Hargett
          Matt Hargett

          ๐Ÿ’ป ๐Ÿ’ต
          Matt Harrah
          Matt Harrah

          ๐Ÿ›
          Matt Nelson
          Matt Nelson

          ๐Ÿ›
          Matt Nelson
          Matt Nelson

          ๐Ÿ›
          Matthew Amos
          Matthew Amos

          ๐Ÿ›
          Matthew Duggan
          Matthew Duggan

          ๐Ÿ›
          Matthew Hall
          Matthew Hall

          ๐Ÿ›
          Matthew Rossner
          Matthew Rossner

          ๐Ÿ›
          Matรญas Fraga
          Matรญas Fraga

          ๐Ÿ’ป ๐Ÿ›
          Maxime Robert
          Maxime Robert

          ๐Ÿ’ป ๐Ÿ›
          MetaBF
          MetaBF

          ๐Ÿ›
          MetaBF
          MetaBF

          ๐Ÿ›
          Metin Dagcilar
          Metin Dagcilar

          ๐Ÿ›
          Michael
          Michael

          ๐Ÿ›
          Michael Bell
          Michael Bell

          ๐Ÿ›
          Michael Bernstein
          Michael Bernstein

          ๐Ÿ›
          Michael Clay
          Michael Clay

          ๐Ÿ›
          Michael Dombrowski
          Michael Dombrowski

          ๐Ÿ›
          Michael Hausegger
          Michael Hausegger

          ๐Ÿ›
          Michael Hausegger
          Michael Hausegger

          ๐Ÿ›
          Michael Hoefer
          Michael Hoefer

          ๐Ÿ›
          Michael Kolesnikov
          Michael Kolesnikov

          ๐Ÿ›
          Michael Mรถbius
          Michael Mรถbius

          ๐Ÿ›
          Michael N. Lipp
          Michael N. Lipp

          ๐Ÿ›
          Michael Pellegrini
          Michael Pellegrini

          ๐Ÿ›
          Michal Kordas
          Michal Kordas

          ๐Ÿ›
          Michaล‚ Borek
          Michaล‚ Borek

          ๐Ÿ›
          Michaล‚ Borek
          Michaล‚ Borek

          ๐Ÿ›
          Michaล‚ Kuliล„ski
          Michaล‚ Kuliล„ski

          ๐Ÿ›
          Miguel Nรบรฑez Dรญaz-Montes
          Miguel Nรบรฑez Dรญaz-Montes

          ๐Ÿ›
          Mihai Ionut
          Mihai Ionut

          ๐Ÿ›
          Mikhail Kuchma
          Mikhail Kuchma

          ๐Ÿ›
          MiladSadinam
          MiladSadinam

          ๐Ÿ›
          Mirek Hankus
          Mirek Hankus

          ๐Ÿ›
          Mitch Spano
          Mitch Spano

          ๐Ÿ’ป ๐Ÿ›
          Mitch Spano
          Mitch Spano

          ๐Ÿ’ป ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          MrAngry52
          MrAngry52

          ๐Ÿ›
          Muminur Choudhury
          Muminur Choudhury

          ๐Ÿ›
          Mykhailo Palahuta
          Mykhailo Palahuta

          ๐Ÿ’ป ๐Ÿ›
          Nagendra Kumar Singh
          Nagendra Kumar Singh

          ๐Ÿ›
          Nahuel Barrios
          Nahuel Barrios

          ๐Ÿ›
          Nahuel Barrios
          Nahuel Barrios

          ๐Ÿ›
          Nakul Sharma
          Nakul Sharma

          ๐Ÿ›
          Nathan Braun
          Nathan Braun

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathanaรซl
          Nathanaรซl

          ๐Ÿ›
          Naveen
          Naveen

          ๐Ÿ’ป
          Nazdravi
          Nazdravi

          ๐Ÿ›
          Nazdravi
          Nazdravi

          ๐Ÿ›
          Neha-Dhonde
          Neha-Dhonde

          ๐Ÿ›
          Nicholas Doyle
          Nicholas Doyle

          ๐Ÿ›
          Nick Butcher
          Nick Butcher

          ๐Ÿ›
          Nico Gallinal
          Nico Gallinal

          ๐Ÿ›
          Nicola Dal Maso
          Nicola Dal Maso

          ๐Ÿ›
          Nicolas Filotto
          Nicolas Filotto

          ๐Ÿ’ป
          Nicolas Vervelle
          Nicolas Vervelle

          ๐Ÿ›
          Nicolas Vervelle
          Nicolas Vervelle

          ๐Ÿ›
          Nicolas Vuillamy
          Nicolas Vuillamy

          ๐Ÿ“–
          Nikita Chursin
          Nikita Chursin

          ๐Ÿ›
          Niklas Baudy
          Niklas Baudy

          ๐Ÿ›
          Nikolas Havrikov
          Nikolas Havrikov

          ๐Ÿ›
          Nilesh Virkar
          Nilesh Virkar

          ๐Ÿ›
          Nimit Patel
          Nimit Patel

          ๐Ÿ›
          Niranjan Harpale
          Niranjan Harpale

          ๐Ÿ›
          Niranjan Harpale
          Niranjan Harpale

          ๐Ÿ›
          Nirvik Patel
          Nirvik Patel

          ๐Ÿ’ป
          Noah Sussman
          Noah Sussman

          ๐Ÿ›
          Noah0120
          Noah0120

          ๐Ÿ›
          Noam Tamim
          Noam Tamim

          ๐Ÿ›
          Noel Grandin
          Noel Grandin

          ๐Ÿ›
          Olaf Haalstra
          Olaf Haalstra

          ๐Ÿ›
          Oleg Andreych
          Oleg Andreych

          ๐Ÿ’ป ๐Ÿ›
          Oleg Andreych
          Oleg Andreych

          ๐Ÿ’ป ๐Ÿ›
          Oleg Pavlenko
          Oleg Pavlenko

          ๐Ÿ›
          Oleksii Dykov
          Oleksii Dykov

          ๐Ÿ’ป ๐Ÿ›
          Oliver Eikemeier
          Oliver Eikemeier

          ๐Ÿ›
          Oliver Siegmar
          Oliver Siegmar

          ๐Ÿ’ต
          Olivier Parent
          Olivier Parent

          ๐Ÿ’ป ๐Ÿ›
          Ollie Abbey
          Ollie Abbey

          ๐Ÿ’ป ๐Ÿ›
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)

          ๐Ÿ›
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)

          ๐Ÿ›
          Ondrej Kratochvil
          Ondrej Kratochvil

          ๐Ÿ›
          OverDrone
          OverDrone

          ๐Ÿ›
          Ozan Gulle
          Ozan Gulle

          ๐Ÿ’ป ๐Ÿ›
          PUNEET JAIN
          PUNEET JAIN

          ๐Ÿ›
          Parbati Bose
          Parbati Bose

          ๐Ÿ›
          Paul Berg
          Paul Berg

          ๐Ÿ›
          Paul Guyot
          Paul Guyot

          ๐Ÿ’ป
          Paul Guyot
          Paul Guyot

          ๐Ÿ’ป
          Pavel Bludov
          Pavel Bludov

          ๐Ÿ›
          Pavel Miฤka
          Pavel Miฤka

          ๐Ÿ›
          Pedro Nuno Santos
          Pedro Nuno Santos

          ๐Ÿ›
          Pedro Rijo
          Pedro Rijo

          ๐Ÿ›
          Pelisse Romain
          Pelisse Romain

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
          Per Abich
          Per Abich

          ๐Ÿ’ป
          Pete Davids
          Pete Davids

          ๐Ÿ›
          Pete Davids
          Pete Davids

          ๐Ÿ›
          Peter Bruin
          Peter Bruin

          ๐Ÿ›
          Peter Chittum
          Peter Chittum

          ๐Ÿ’ป ๐Ÿ›
          Peter Cudmore
          Peter Cudmore

          ๐Ÿ›
          Peter Kasson
          Peter Kasson

          ๐Ÿ›
          Peter Kofler
          Peter Kofler

          ๐Ÿ›
          Peter Paul Bakker
          Peter Paul Bakker

          ๐Ÿ’ป ๐Ÿ›
          Peter Rader
          Peter Rader

          ๐Ÿ›
          Peter Rader
          Peter Rader

          ๐Ÿ›
          Pham Hai Trung
          Pham Hai Trung

          ๐Ÿ›
          Philip Graf
          Philip Graf

          ๐Ÿ’ป ๐Ÿ›
          Philip Hachey
          Philip Hachey

          ๐Ÿ›
          Philippe Ozil
          Philippe Ozil

          ๐Ÿ›
          Phinehas Artemix
          Phinehas Artemix

          ๐Ÿ›
          Phokham Nonava
          Phokham Nonava

          ๐Ÿ›
          Pim van der Loos
          Pim van der Loos

          ๐Ÿ’ป โš ๏ธ
          Pim van der Loos
          Pim van der Loos

          ๐Ÿ’ป โš ๏ธ
          Piotr Szymaล„ski
          Piotr Szymaล„ski

          ๐Ÿ›
          Piotrek ลปygieล‚o
          Piotrek ลปygieล‚o

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“–
          Pranay Jaiswal
          Pranay Jaiswal

          ๐Ÿ›
          Prasad Kamath
          Prasad Kamath

          ๐Ÿ›
          Prasanna
          Prasanna

          ๐Ÿ›
          Presh-AR
          Presh-AR

          ๐Ÿ›
          Puneet1726
          Puneet1726

          ๐Ÿ›
          Puneet1726
          Puneet1726

          ๐Ÿ›
          RBRi
          RBRi

          ๐Ÿ›
          Rafael Cortรชs
          Rafael Cortรชs

          ๐Ÿ›
          RaheemShaik999
          RaheemShaik999

          ๐Ÿ›
          RajeshR
          RajeshR

          ๐Ÿ’ป ๐Ÿ›
          Ramachandra Mohan
          Ramachandra Mohan

          ๐Ÿ›
          Ramel0921
          Ramel0921

          ๐Ÿ›
          Raquel Pau
          Raquel Pau

          ๐Ÿ›
          Raquel Pau
          Raquel Pau

          ๐Ÿ›
          Ravikiran Janardhana
          Ravikiran Janardhana

          ๐Ÿ›
          Reda Benhemmouche
          Reda Benhemmouche

          ๐Ÿ›
          Reinhard Schiedermeier
          Reinhard Schiedermeier

          ๐Ÿ›
          Renato Oliveira
          Renato Oliveira

          ๐Ÿ’ป ๐Ÿ›
          Rich DiCroce
          Rich DiCroce

          ๐Ÿ›
          Richard Corfield
          Richard Corfield

          ๐Ÿ’ป
          Richard Corfield
          Richard Corfield

          ๐Ÿ› ๐Ÿ’ป
          Richard Corfield
          Richard Corfield

          ๐Ÿ› ๐Ÿ’ป
          Riot R1cket
          Riot R1cket

          ๐Ÿ›
          Rishabh Jain
          Rishabh Jain

          ๐Ÿ›
          RishabhDeep Singh
          RishabhDeep Singh

          ๐Ÿ›
          Rob Baillie
          Rob Baillie

          ๐Ÿ›
          Robbie Martinus
          Robbie Martinus

          ๐Ÿ’ป ๐Ÿ›
          Robert Henry
          Robert Henry

          ๐Ÿ›
          Robert Mihaly
          Robert Mihaly

          ๐Ÿ›
          Robert Mihaly
          Robert Mihaly

          ๐Ÿ›
          Robert Painsi
          Robert Painsi

          ๐Ÿ›
          Robert Russell
          Robert Russell

          ๐Ÿ›
          Robert Sรถsemann
          Robert Sรถsemann

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ›
          Robert Whitebit
          Robert Whitebit

          ๐Ÿ›
          Robin Richtsfeld
          Robin Richtsfeld

          ๐Ÿ›
          Robin Stocker
          Robin Stocker

          ๐Ÿ’ป ๐Ÿ›
          Robin Wils
          Robin Wils

          ๐Ÿ›
          Robin Wils
          Robin Wils

          ๐Ÿ›
          RochusOest
          RochusOest

          ๐Ÿ›
          Rodolfo Noviski
          Rodolfo Noviski

          ๐Ÿ›
          Rodrigo Casara
          Rodrigo Casara

          ๐Ÿ›
          Rodrigo Fernandes
          Rodrigo Fernandes

          ๐Ÿ›
          Roman Salvador
          Roman Salvador

          ๐Ÿ’ป ๐Ÿ›
          Ronald Blaschke
          Ronald Blaschke

          ๐Ÿ›
          Rรณbert Papp
          Rรณbert Papp

          ๐Ÿ›
          Rรณbert Papp
          Rรณbert Papp

          ๐Ÿ›
          Saikat Sengupta
          Saikat Sengupta

          ๐Ÿ›
          Saksham Handu
          Saksham Handu

          ๐Ÿ›
          Saladoc
          Saladoc

          ๐Ÿ›
          Salesforce Bob Lightning
          Salesforce Bob Lightning

          ๐Ÿ›
          Sam Carlberg
          Sam Carlberg

          ๐Ÿ›
          Sascha Riemer
          Sascha Riemer

          ๐Ÿ›
          Sashko
          Sashko

          ๐Ÿ’ป
          Sashko
          Sashko

          ๐Ÿ’ป
          Satoshi Kubo
          Satoshi Kubo

          ๐Ÿ›
          Scott Kennedy
          Scott Kennedy

          ๐Ÿ›
          Scott Wells
          Scott Wells

          ๐Ÿ› ๐Ÿ’ป
          Scrates1
          Scrates1

          ๐Ÿ› ๐Ÿ’ป
          Scrsloota
          Scrsloota

          ๐Ÿ’ป
          Sebastian Bรถgl
          Sebastian Bรถgl

          ๐Ÿ›
          Sebastian Davids
          Sebastian Davids

          ๐Ÿ›
          Sebastian Davids
          Sebastian Davids

          ๐Ÿ›
          Sebastian Lรถvdahl
          Sebastian Lรถvdahl

          ๐Ÿ›
          Sebastian Schuberth
          Sebastian Schuberth

          ๐Ÿ›
          Sebastian Schwarz
          Sebastian Schwarz

          ๐Ÿ›
          Seren
          Seren

          ๐Ÿ› ๐Ÿ’ป
          Sergey Gorbaty
          Sergey Gorbaty

          ๐Ÿ›
          Sergey Kozlov
          Sergey Kozlov

          ๐Ÿ›
          Sergey Yanzin
          Sergey Yanzin

          ๐Ÿ’ป ๐Ÿ›
          Sergey Yanzin
          Sergey Yanzin

          ๐Ÿ’ป ๐Ÿ›
          Seth Wilcox
          Seth Wilcox

          ๐Ÿ’ป
          Shai Bennathan
          Shai Bennathan

          ๐Ÿ› ๐Ÿ’ป
          Shubham
          Shubham

          ๐Ÿ’ป ๐Ÿ›
          Simon Abykov
          Simon Abykov

          ๐Ÿ’ป ๐Ÿ›
          Simon Xiao
          Simon Xiao

          ๐Ÿ›
          Srinivasan Venkatachalam
          Srinivasan Venkatachalam

          ๐Ÿ›
          Stanislav Gromov
          Stanislav Gromov

          ๐Ÿ›
          Stanislav Gromov
          Stanislav Gromov

          ๐Ÿ›
          Stanislav Myachenkov
          Stanislav Myachenkov

          ๐Ÿ’ป
          Stefan Birkner
          Stefan Birkner

          ๐Ÿ›
          Stefan Bohn
          Stefan Bohn

          ๐Ÿ›
          Stefan Endrullis
          Stefan Endrullis

          ๐Ÿ›
          Stefan Klรถss-Schuster
          Stefan Klรถss-Schuster

          ๐Ÿ›
          Stefan Wolf
          Stefan Wolf

          ๐Ÿ›
          Stephan H. Wissel
          Stephan H. Wissel

          ๐Ÿ›
          Stephan H. Wissel
          Stephan H. Wissel

          ๐Ÿ›
          Stephen
          Stephen

          ๐Ÿ›
          Stephen Carter
          Stephen Carter

          ๐Ÿ›
          Stephen Friedrich
          Stephen Friedrich

          ๐Ÿ›
          Steve Babula
          Steve Babula

          ๐Ÿ’ป
          Steven Stearns
          Steven Stearns

          ๐Ÿ› ๐Ÿ’ป
          Stexxe
          Stexxe

          ๐Ÿ›
          Stian Lรฅgstad
          Stian Lรฅgstad

          ๐Ÿ›
          Stian Lรฅgstad
          Stian Lรฅgstad

          ๐Ÿ›
          StuartClayton5
          StuartClayton5

          ๐Ÿ›
          Supun Arunoda
          Supun Arunoda

          ๐Ÿ›
          Suren Abrahamyan
          Suren Abrahamyan

          ๐Ÿ›
          Suvashri
          Suvashri

          ๐Ÿ“–
          Sven Barden
          Sven Barden

          ๐Ÿ›
          SwatiBGupta1110
          SwatiBGupta1110

          ๐Ÿ›
          SyedThoufich
          SyedThoufich

          ๐Ÿ›
          SyedThoufich
          SyedThoufich

          ๐Ÿ›
          Szymon Sasin
          Szymon Sasin

          ๐Ÿ›
          T-chuangxin
          T-chuangxin

          ๐Ÿ›
          TERAI Atsuhiro
          TERAI Atsuhiro

          ๐Ÿ›
          TIOBE Software
          TIOBE Software

          ๐Ÿ’ป ๐Ÿ›
          Tarush Singh
          Tarush Singh

          ๐Ÿ’ป
          Taylor Smock
          Taylor Smock

          ๐Ÿ›
          Techeira Damiรกn
          Techeira Damiรกn

          ๐Ÿ’ป ๐Ÿ›
          Techeira Damiรกn
          Techeira Damiรกn

          ๐Ÿ’ป ๐Ÿ›
          Ted Husted
          Ted Husted

          ๐Ÿ›
          TehBakker
          TehBakker

          ๐Ÿ›
          The Gitter Badger
          The Gitter Badger

          ๐Ÿ›
          Theodoor
          Theodoor

          ๐Ÿ›
          Thiago Henrique Hรผpner
          Thiago Henrique Hรผpner

          ๐Ÿ›
          Thibault Meyer
          Thibault Meyer

          ๐Ÿ›
          Thomas Gรผttler
          Thomas Gรผttler

          ๐Ÿ›
          Thomas Gรผttler
          Thomas Gรผttler

          ๐Ÿ›
          Thomas Jones-Low
          Thomas Jones-Low

          ๐Ÿ›
          Thomas Smith
          Thomas Smith

          ๐Ÿ’ป ๐Ÿ›
          ThrawnCA
          ThrawnCA

          ๐Ÿ›
          Thu Vo
          Thu Vo

          ๐Ÿ›
          Thunderforge
          Thunderforge

          ๐Ÿ’ป ๐Ÿ›
          Tim van der Lippe
          Tim van der Lippe

          ๐Ÿ›
          Tobias Weimer
          Tobias Weimer

          ๐Ÿ’ป ๐Ÿ›
          Tobias Weimer
          Tobias Weimer

          ๐Ÿ’ป ๐Ÿ›
          Tom Copeland
          Tom Copeland

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–
          Tom Daly
          Tom Daly

          ๐Ÿ›
          Tomas
          Tomas

          ๐Ÿ›
          Tomer Figenblat
          Tomer Figenblat

          ๐Ÿ›
          Tomi De Lucca
          Tomi De Lucca

          ๐Ÿ’ป ๐Ÿ›
          Tony
          Tony

          ๐Ÿ“–
          Torsten Kleiber
          Torsten Kleiber

          ๐Ÿ›
          Torsten Kleiber
          Torsten Kleiber

          ๐Ÿ›
          Torsten Krause
          Torsten Krause

          ๐Ÿ›
          TrackerSB
          TrackerSB

          ๐Ÿ›
          Tyson Stewart
          Tyson Stewart

          ๐Ÿ›
          Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ›
          Utku Cuhadaroglu
          Utku Cuhadaroglu

          ๐Ÿ’ป ๐Ÿ›
          Valentin Brandl
          Valentin Brandl

          ๐Ÿ›
          Valeria
          Valeria

          ๐Ÿ›
          Valeria
          Valeria

          ๐Ÿ›
          Valery Yatsynovich
          Valery Yatsynovich

          ๐Ÿ“–
          Vasily Anisimov
          Vasily Anisimov

          ๐Ÿ›
          Vedant Chokshi
          Vedant Chokshi

          ๐Ÿ›
          Vibhor Goyal
          Vibhor Goyal

          ๐Ÿ›
          Vickenty Fesunov
          Vickenty Fesunov

          ๐Ÿ›
          Victor Noรซl
          Victor Noรซl

          ๐Ÿ›
          Vincent Galloy
          Vincent Galloy

          ๐Ÿ’ป
          Vincent Galloy
          Vincent Galloy

          ๐Ÿ’ป
          Vincent HUYNH
          Vincent HUYNH

          ๐Ÿ›
          Vincent Maurin
          Vincent Maurin

          ๐Ÿ›
          Vincent Potucek
          Vincent Potucek

          ๐Ÿ’ป
          Vincent Privat
          Vincent Privat

          ๐Ÿ›
          Vishhwas
          Vishhwas

          ๐Ÿ›
          Vishv_Android
          Vishv_Android

          ๐Ÿ›
          Vitalii Yevtushenko
          Vitalii Yevtushenko

          ๐Ÿ›
          Vitalii Yevtushenko
          Vitalii Yevtushenko

          ๐Ÿ›
          Vitaly
          Vitaly

          ๐Ÿ›
          Vitaly Polonetsky
          Vitaly Polonetsky

          ๐Ÿ›
          Vojtech Polivka
          Vojtech Polivka

          ๐Ÿ›
          Vsevolod Zholobov
          Vsevolod Zholobov

          ๐Ÿ›
          Vyom Yadav
          Vyom Yadav

          ๐Ÿ’ป
          Wang Shidong
          Wang Shidong

          ๐Ÿ›
          Waqas Ahmed
          Waqas Ahmed

          ๐Ÿ›
          Waqas Ahmed
          Waqas Ahmed

          ๐Ÿ›
          Wayne J. Earl
          Wayne J. Earl

          ๐Ÿ›
          Wchenghui
          Wchenghui

          ๐Ÿ›
          Wener
          Wener

          ๐Ÿ’ป
          Will Winder
          Will Winder

          ๐Ÿ›
          Willem A. Hajenius
          Willem A. Hajenius

          ๐Ÿ’ป
          William Brockhus
          William Brockhus

          ๐Ÿ’ป ๐Ÿ›
          Wilson Kurniawan
          Wilson Kurniawan

          ๐Ÿ›
          Wilson Kurniawan
          Wilson Kurniawan

          ๐Ÿ›
          Wim Deblauwe
          Wim Deblauwe

          ๐Ÿ›
          Wolf2323
          Wolf2323

          ๐Ÿ›
          Woongsik Choi
          Woongsik Choi

          ๐Ÿ›
          XenoAmess
          XenoAmess

          ๐Ÿ’ป ๐Ÿ›
          Yang
          Yang

          ๐Ÿ’ป
          YaroslavTER
          YaroslavTER

          ๐Ÿ›
          Yasar Shaikh
          Yasar Shaikh

          ๐Ÿ’ป
          Yasar Shaikh
          Yasar Shaikh

          ๐Ÿ’ป
          Young Chan
          Young Chan

          ๐Ÿ’ป ๐Ÿ›
          YuJin Kim
          YuJin Kim

          ๐Ÿ›
          Yuri Dolzhenko
          Yuri Dolzhenko

          ๐Ÿ›
          Yurii Dubinka
          Yurii Dubinka

          ๐Ÿ›
          Zoltan Farkas
          Zoltan Farkas

          ๐Ÿ›
          Zustin
          Zustin

          ๐Ÿ›
          aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป
          aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป
          alexmodis
          alexmodis

          ๐Ÿ›
          andreoss
          andreoss

          ๐Ÿ›
          andrey81inmd
          andrey81inmd

          ๐Ÿ’ป ๐Ÿ›
          anicoara
          anicoara

          ๐Ÿ›
          arunprasathav
          arunprasathav

          ๐Ÿ›
          asiercamara
          asiercamara

          ๐Ÿ›
          astillich-igniti
          astillich-igniti

          ๐Ÿ’ป
          astillich-igniti
          astillich-igniti

          ๐Ÿ’ป
          avesolovksyy
          avesolovksyy

          ๐Ÿ›
          avishvat
          avishvat

          ๐Ÿ›
          avivmu
          avivmu

          ๐Ÿ›
          axelbarfod1
          axelbarfod1

          ๐Ÿ›
          b-3-n
          b-3-n

          ๐Ÿ›
          balbhadra9
          balbhadra9

          ๐Ÿ›
          base23de
          base23de

          ๐Ÿ›
          base23de
          base23de

          ๐Ÿ›
          bergander
          bergander

          ๐Ÿ› ๐Ÿ’ป
          berkam
          berkam

          ๐Ÿ’ป ๐Ÿ›
          breizh31
          breizh31

          ๐Ÿ›
          caesarkim
          caesarkim

          ๐Ÿ›
          caiocarvalhotero
          caiocarvalhotero

          ๐Ÿ›
          carolyujing
          carolyujing

          ๐Ÿ›
          cbfiddle
          cbfiddle

          ๐Ÿ›
          cbfiddle
          cbfiddle

          ๐Ÿ›
          cesares-basilico
          cesares-basilico

          ๐Ÿ›
          chrite
          chrite

          ๐Ÿ›
          ciufudean
          ciufudean

          ๐Ÿ“–
          cobratbq
          cobratbq

          ๐Ÿ›
          coladict
          coladict

          ๐Ÿ›
          cosmoJFH
          cosmoJFH

          ๐Ÿ›
          cristalp
          cristalp

          ๐Ÿ›
          cristalp
          cristalp

          ๐Ÿ›
          crunsk
          crunsk

          ๐Ÿ›
          cwholmes
          cwholmes

          ๐Ÿ›
          cyberjj999
          cyberjj999

          ๐Ÿ›
          cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“–
          d1ss0nanz
          d1ss0nanz

          ๐Ÿ›
          dague1
          dague1

          ๐Ÿ“–
          dalizi007
          dalizi007

          ๐Ÿ’ป
          dalizi007
          dalizi007

          ๐Ÿ’ป
          danbrycefairsailcom
          danbrycefairsailcom

          ๐Ÿ›
          dariansanity
          dariansanity

          ๐Ÿ›
          darrenmiliband
          darrenmiliband

          ๐Ÿ›
          davidburstrom
          davidburstrom

          ๐Ÿ›
          dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ›
          deepak-patra
          deepak-patra

          ๐Ÿ›
          dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ›
          dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ›
          dinesh150
          dinesh150

          ๐Ÿ›
          diziaq
          diziaq

          ๐Ÿ›
          dreaminpast123
          dreaminpast123

          ๐Ÿ›
          duanyanan
          duanyanan

          ๐Ÿ›
          dutt-sanjay
          dutt-sanjay

          ๐Ÿ›
          duursma
          duursma

          ๐Ÿ’ป
          dylanleung
          dylanleung

          ๐Ÿ›
          dylanleung
          dylanleung

          ๐Ÿ›
          dzeigler
          dzeigler

          ๐Ÿ›
          eant60
          eant60

          ๐Ÿ›
          ekkirala
          ekkirala

          ๐Ÿ›
          emersonmoura
          emersonmoura

          ๐Ÿ›
          emouty
          emouty

          ๐Ÿ’ป ๐Ÿ›
          eugenepugach
          eugenepugach

          ๐Ÿ›
          fairy
          fairy

          ๐Ÿ›
          fairy
          fairy

          ๐Ÿ›
          filiprafalowicz
          filiprafalowicz

          ๐Ÿ’ป
          flxbl-io
          flxbl-io

          ๐Ÿ’ต
          foxmason
          foxmason

          ๐Ÿ›
          frankegabor
          frankegabor

          ๐Ÿ›
          frankl
          frankl

          ๐Ÿ›
          freafrea
          freafrea

          ๐Ÿ›
          fsapatin
          fsapatin

          ๐Ÿ›
          fsapatin
          fsapatin

          ๐Ÿ›
          gearsethenry
          gearsethenry

          ๐Ÿ›
          gracia19
          gracia19

          ๐Ÿ›
          gudzpoz
          gudzpoz

          ๐Ÿ›
          guo fei
          guo fei

          ๐Ÿ›
          gurmsc5
          gurmsc5

          ๐Ÿ›
          gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ›
          haigsn
          haigsn

          ๐Ÿ›
          haigsn
          haigsn

          ๐Ÿ›
          hemanshu070
          hemanshu070

          ๐Ÿ›
          henrik242
          henrik242

          ๐Ÿ›
          hongpuwu
          hongpuwu

          ๐Ÿ›
          hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ›
          igniti GmbH
          igniti GmbH

          ๐Ÿ›
          ilovezfs
          ilovezfs

          ๐Ÿ›
          imax-erik
          imax-erik

          ๐Ÿ›
          imax-erik
          imax-erik

          ๐Ÿ›
          itaigilo
          itaigilo

          ๐Ÿ›
          jakivey32
          jakivey32

          ๐Ÿ›
          jbennett2091
          jbennett2091

          ๐Ÿ›
          jcamerin
          jcamerin

          ๐Ÿ›
          jkeener1
          jkeener1

          ๐Ÿ›
          jmetertea
          jmetertea

          ๐Ÿ›
          johnra2
          johnra2

          ๐Ÿ’ป
          johnra2
          johnra2

          ๐Ÿ’ป
          johnzhao9
          johnzhao9

          ๐Ÿ›
          josemanuelrolon
          josemanuelrolon

          ๐Ÿ’ป ๐Ÿ›
          julees7
          julees7

          ๐Ÿ’ป ๐Ÿ›
          kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ›
          karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“–
          karwer
          karwer

          ๐Ÿ›
          kaulonline
          kaulonline

          ๐Ÿ›
          kaulonline
          kaulonline

          ๐Ÿ›
          kdaemonv
          kdaemonv

          ๐Ÿ›
          kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป
          kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ›
          kfranic
          kfranic

          ๐Ÿ›
          khalidkh
          khalidkh

          ๐Ÿ›
          koalalam
          koalalam

          ๐Ÿ›
          krzyk
          krzyk

          ๐Ÿ›
          krzyk
          krzyk

          ๐Ÿ›
          lasselindqvist
          lasselindqvist

          ๐Ÿ›
          lgemeinhardt
          lgemeinhardt

          ๐Ÿ›
          lihuaib
          lihuaib

          ๐Ÿ›
          liqingjun123
          liqingjun123

          ๐Ÿ›
          lonelyma1021
          lonelyma1021

          ๐Ÿ›
          lpeddy
          lpeddy

          ๐Ÿ›
          lujiefsi
          lujiefsi

          ๐Ÿ’ป
          lujiefsi
          lujiefsi

          ๐Ÿ’ป
          lukelukes
          lukelukes

          ๐Ÿ’ป
          lyriccoder
          lyriccoder

          ๐Ÿ›
          marcelmore
          marcelmore

          ๐Ÿ›
          matchbox
          matchbox

          ๐Ÿ›
          matthiaskraaz
          matthiaskraaz

          ๐Ÿ›
          meandonlyme
          meandonlyme

          ๐Ÿ›
          mikesive
          mikesive

          ๐Ÿ›
          mikesive
          mikesive

          ๐Ÿ›
          milossesic
          milossesic

          ๐Ÿ›
          mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ›
          mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป
          mriddell95
          mriddell95

          ๐Ÿ›
          mrlzh
          mrlzh

          ๐Ÿ›
          msloan
          msloan

          ๐Ÿ›
          mucharlaravalika
          mucharlaravalika

          ๐Ÿ›
          mucharlaravalika
          mucharlaravalika

          ๐Ÿ›
          mvenneman
          mvenneman

          ๐Ÿ›
          nareshl119
          nareshl119

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          noerremark
          noerremark

          ๐Ÿ›
          novsirion
          novsirion

          ๐Ÿ›
          nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป
          oggboy
          oggboy

          ๐Ÿ›
          oggboy
          oggboy

          ๐Ÿ›
          oinume
          oinume

          ๐Ÿ›
          orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pacvz
          pacvz

          ๐Ÿ’ป
          pallavi agarwal
          pallavi agarwal

          ๐Ÿ›
          pankratz76
          pankratz76

          ๐Ÿ›
          parksungrin
          parksungrin

          ๐Ÿ›
          parksungrin
          parksungrin

          ๐Ÿ›
          patpatpat123
          patpatpat123

          ๐Ÿ›
          patriksevallius
          patriksevallius

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          phoenix384
          phoenix384

          ๐Ÿ›
          piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป
          plan3d
          plan3d

          ๐Ÿ›
          poojasix
          poojasix

          ๐Ÿ›
          poojasix
          poojasix

          ๐Ÿ›
          prabhushrikant
          prabhushrikant

          ๐Ÿ›
          pujitha8783
          pujitha8783

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          raghujayjunk
          raghujayjunk

          ๐Ÿ›
          rajeshveera
          rajeshveera

          ๐Ÿ›
          rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ›
          recdevs
          recdevs

          ๐Ÿ›
          recdevs
          recdevs

          ๐Ÿ›
          reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ›
          rijkt
          rijkt

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ›
          rnveach
          rnveach

          ๐Ÿ›
          rxmicro
          rxmicro

          ๐Ÿ›
          ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ›
          ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ›
          sabi0
          sabi0

          ๐Ÿ›
          samc-gearset
          samc-gearset

          ๐Ÿ“–
          scais
          scais

          ๐Ÿ›
          schosin
          schosin

          ๐Ÿ›
          screamingfrog
          screamingfrog

          ๐Ÿ’ต
          sebbASF
          sebbASF

          ๐Ÿ›
          sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป
          sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป
          shilko2013
          shilko2013

          ๐Ÿ›
          shiomiyan
          shiomiyan

          ๐Ÿ“–
          simeonKondr
          simeonKondr

          ๐Ÿ›
          snajberk
          snajberk

          ๐Ÿ›
          sniperrifle2004
          sniperrifle2004

          ๐Ÿ›
          snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป
          soloturn
          soloturn

          ๐Ÿ›
          soloturn
          soloturn

          ๐Ÿ›
          soyodream
          soyodream

          ๐Ÿ›
          sratz
          sratz

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          sturton
          sturton

          ๐Ÿ’ป ๐Ÿ›
          sudharmohan
          sudharmohan

          ๐Ÿ›
          suruchidawar
          suruchidawar

          ๐Ÿ›
          svenfinitiv
          svenfinitiv

          ๐Ÿ›
          svenfinitiv
          svenfinitiv

          ๐Ÿ›
          szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป
          tashiscool
          tashiscool

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          testation21
          testation21

          ๐Ÿ’ป ๐Ÿ›
          thanosa
          thanosa

          ๐Ÿ›
          tiandiyixian
          tiandiyixian

          ๐Ÿ›
          tobwoerk
          tobwoerk

          ๐Ÿ›
          tobwoerk
          tobwoerk

          ๐Ÿ›
          tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป
          trentchilders
          trentchilders

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          trishul14
          trishul14

          ๐Ÿ›
          tsui
          tsui

          ๐Ÿ›
          wangzitom12306
          wangzitom12306

          ๐Ÿ›
          winhkey
          winhkey

          ๐Ÿ›
          winhkey
          winhkey

          ๐Ÿ›
          witherspore
          witherspore

          ๐Ÿ›
          wjljack
          wjljack

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          xingsong
          xingsong

          ๐Ÿ›
          xioayuge
          xioayuge

          ๐Ÿ›
          xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ›
          xuanuy
          xuanuy

          ๐Ÿ›
          xuanuy
          xuanuy

          ๐Ÿ›
          xyf0921
          xyf0921

          ๐Ÿ›
          yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yasuharu-sato
          yasuharu-sato

          ๐Ÿ›
          zenglian
          zenglian

          ๐Ÿ›
          zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ›
          zh3ng
          zh3ng

          ๐Ÿ›
          zh3ng
          zh3ng

          ๐Ÿ›
          zt_soft
          zt_soft

          ๐Ÿ›
          ztt79
          ztt79

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ›
          ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ›
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ

          ๐Ÿ›
          ่Œ…ๅปถๅฎ‰
          ่Œ…ๅปถๅฎ‰

          ๐Ÿ’ป
          lihuaib
          lihuaib

          ๐Ÿ›
          liqingjun123
          liqingjun123

          ๐Ÿ›
          lonelyma1021
          lonelyma1021

          ๐Ÿ›
          lothas
          lothas

          ๐Ÿ›
          lpeddy
          lpeddy

          ๐Ÿ›
          lujiefsi
          lujiefsi

          ๐Ÿ’ป
          lukelukes
          lukelukes

          ๐Ÿ’ป
          lukelukes
          lukelukes

          ๐Ÿ’ป
          lyriccoder
          lyriccoder

          ๐Ÿ›
          marcelmore
          marcelmore

          ๐Ÿ›
          matchbox
          matchbox

          ๐Ÿ›
          matthiaskraaz
          matthiaskraaz

          ๐Ÿ›
          meandonlyme
          meandonlyme

          ๐Ÿ›
          mikesive
          mikesive

          ๐Ÿ›
          milossesic
          milossesic

          ๐Ÿ›
          milossesic
          milossesic

          ๐Ÿ›
          mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ›
          mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป
          mriddell95
          mriddell95

          ๐Ÿ›
          mrlzh
          mrlzh

          ๐Ÿ›
          msloan
          msloan

          ๐Ÿ›
          mucharlaravalika
          mucharlaravalika

          ๐Ÿ›
          mvenneman
          mvenneman

          ๐Ÿ›
          mvenneman
          mvenneman

          ๐Ÿ›
          nareshl119
          nareshl119

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          noerremark
          noerremark

          ๐Ÿ›
          novsirion
          novsirion

          ๐Ÿ›
          nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป
          oggboy
          oggboy

          ๐Ÿ›
          oinume
          oinume

          ๐Ÿ›
          oinume
          oinume

          ๐Ÿ›
          orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pacvz
          pacvz

          ๐Ÿ’ป
          pallavi agarwal
          pallavi agarwal

          ๐Ÿ›
          pankratz76
          pankratz76

          ๐Ÿ›
          parksungrin
          parksungrin

          ๐Ÿ›
          patpatpat123
          patpatpat123

          ๐Ÿ›
          patpatpat123
          patpatpat123

          ๐Ÿ›
          patriksevallius
          patriksevallius

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          phoenix384
          phoenix384

          ๐Ÿ›
          piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป
          plan3d
          plan3d

          ๐Ÿ›
          poojasix
          poojasix

          ๐Ÿ›
          prabhushrikant
          prabhushrikant

          ๐Ÿ›
          prabhushrikant
          prabhushrikant

          ๐Ÿ›
          pujitha8783
          pujitha8783

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          raghujayjunk
          raghujayjunk

          ๐Ÿ›
          rajeshveera
          rajeshveera

          ๐Ÿ›
          rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ›
          recdevs
          recdevs

          ๐Ÿ›
          reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ›
          reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ›
          rijkt
          rijkt

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ›
          rnveach
          rnveach

          ๐Ÿ›
          rxmicro
          rxmicro

          ๐Ÿ›
          ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ›
          sabi0
          sabi0

          ๐Ÿ›
          sabi0
          sabi0

          ๐Ÿ›
          samc-gearset
          samc-gearset

          ๐Ÿ“–
          scais
          scais

          ๐Ÿ›
          schosin
          schosin

          ๐Ÿ›
          screamingfrog
          screamingfrog

          ๐Ÿ’ต
          sebbASF
          sebbASF

          ๐Ÿ›
          sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป
          shilko2013
          shilko2013

          ๐Ÿ›
          shilko2013
          shilko2013

          ๐Ÿ›
          shiomiyan
          shiomiyan

          ๐Ÿ“–
          simeonKondr
          simeonKondr

          ๐Ÿ›
          snajberk
          snajberk

          ๐Ÿ›
          sniperrifle2004
          sniperrifle2004

          ๐Ÿ›
          snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป
          soloturn
          soloturn

          ๐Ÿ›
          soyodream
          soyodream

          ๐Ÿ›
          soyodream
          soyodream

          ๐Ÿ›
          sratz
          sratz

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          sturton
          sturton

          ๐Ÿ’ป ๐Ÿ›
          sudharmohan
          sudharmohan

          ๐Ÿ›
          suruchidawar
          suruchidawar

          ๐Ÿ›
          svenfinitiv
          svenfinitiv

          ๐Ÿ›
          szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป
          szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป
          tashiscool
          tashiscool

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          testation21
          testation21

          ๐Ÿ’ป ๐Ÿ›
          thanosa
          thanosa

          ๐Ÿ›
          tiandiyixian
          tiandiyixian

          ๐Ÿ›
          tobwoerk
          tobwoerk

          ๐Ÿ›
          tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป
          tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป
          trentchilders
          trentchilders

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          trishul14
          trishul14

          ๐Ÿ›
          tsui
          tsui

          ๐Ÿ›
          wangzitom12306
          wangzitom12306

          ๐Ÿ›
          winhkey
          winhkey

          ๐Ÿ›
          witherspore
          witherspore

          ๐Ÿ›
          witherspore
          witherspore

          ๐Ÿ›
          wjljack
          wjljack

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          xingsong
          xingsong

          ๐Ÿ›
          xioayuge
          xioayuge

          ๐Ÿ›
          xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ›
          xuanuy
          xuanuy

          ๐Ÿ›
          xyf0921
          xyf0921

          ๐Ÿ›
          xyf0921
          xyf0921

          ๐Ÿ›
          yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yasuharu-sato
          yasuharu-sato

          ๐Ÿ›
          zenglian
          zenglian

          ๐Ÿ›
          zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ›
          zh3ng
          zh3ng

          ๐Ÿ›
          zt_soft
          zt_soft

          ๐Ÿ›
          zt_soft
          zt_soft

          ๐Ÿ›
          ztt79
          ztt79

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ›
          Marat Vyshegorodtsev
          Marat Vyshegorodtsev

          ๐Ÿ›
          Marcel Hรคrle
          Marcel Hรคrle

          ๐Ÿ›
          Marcello Fialho
          Marcello Fialho

          ๐Ÿ›
          Marcin Dฤ…browski
          Marcin Dฤ…browski

          ๐Ÿ’ป
          Marcin Dฤ…browski
          Marcin Dฤ…browski

          ๐Ÿ’ป ๐Ÿ›
          Marcin Rataj
          Marcin Rataj

          ๐Ÿ›
          Marcono1234
          Marcono1234

          ๐Ÿ›
          Mark Adamcin
          Mark Adamcin

          ๐Ÿ›
          Daniel Paul Searles
          Daniel Paul Searles

          ๐Ÿ’ป
          Daniel Reigada
          Daniel Reigada

          ๐Ÿ›
          Daniel Ventura
          Daniel Ventura

          ๐Ÿ›
          Danilo Pianini
          Danilo Pianini

          ๐Ÿ›
          Darko
          Darko

          ๐Ÿ›
          David
          David

          ๐Ÿ›
          David Atkinson
          David Atkinson

          ๐Ÿ›
          David Burstrรถm
          David Burstrรถm

          ๐Ÿ’ป ๐Ÿ›
          David Burstrรถm
          David Burstrรถm

          ๐Ÿ’ป ๐Ÿ›
          David Goatรฉ
          David Goatรฉ

          ๐Ÿ›
          David Golpira
          David Golpira

          ๐Ÿ›
          David Kovaล™รญk
          David Kovaล™รญk

          ๐Ÿ›
          David M. Karr (fullname at gmail.com)
          David M. Karr (fullname at gmail.com)

          ๐Ÿ›
          David Renz
          David Renz

          ๐Ÿ’ป ๐Ÿ›
          David Renz
          David Renz

          ๐Ÿ›
          David Schach
          David Schach

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–
          David Schach
          David Schach

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–
          Dawid Ciok
          Dawid Ciok

          ๐Ÿ› ๐Ÿ’ป
          Debamoy Datta
          Debamoy Datta

          ๐Ÿ’ป
          Deleted user
          Deleted user

          ๐Ÿ›
          Dell Green
          Dell Green

          ๐Ÿ›
          Dem Pilafian
          Dem Pilafian

          ๐Ÿ›
          Den
          Den

          ๐Ÿ›
          Denis Borovikov
          Denis Borovikov

          ๐Ÿ’ป ๐Ÿ›
          Denis Borovikov
          Denis Borovikov

          ๐Ÿ’ป ๐Ÿ›
          Dennie Reniers
          Dennie Reniers

          ๐Ÿ’ป ๐Ÿ›
          Dennis Kieselhorst
          Dennis Kieselhorst

          ๐Ÿ›
          Derek P. Moore
          Derek P. Moore

          ๐Ÿ›
          Dichotomia
          Dichotomia

          ๐Ÿ›
          Dionisio Cortรฉs Fernรกndez
          Dionisio Cortรฉs Fernรกndez

          ๐Ÿ’ป ๐Ÿ›
          Dmitri Bourlatchkov
          Dmitri Bourlatchkov

          ๐Ÿ›
          Dmitriy Kuzmin
          Dmitriy Kuzmin

          ๐Ÿ›
          Dmitriy Kuzmin
          Dmitriy Kuzmin

          ๐Ÿ›
          Dmytro Dashenkov
          Dmytro Dashenkov

          ๐Ÿ›
          Douglas Griffith
          Douglas Griffith

          ๐Ÿ“–
          Dr. Christian Kohlschรผtter
          Dr. Christian Kohlschรผtter

          ๐Ÿ›
          Drew Hall
          Drew Hall

          ๐Ÿ›
          Dumitru Postoronca
          Dumitru Postoronca

          ๐Ÿ›
          Dylan Adams
          Dylan Adams

          ๐Ÿ›
          Eden Hao
          Eden Hao

          ๐Ÿ›
          Eden Hao
          Eden Hao

          ๐Ÿ›
          Edward Klimoshenko
          Edward Klimoshenko

          ๐Ÿ› ๐Ÿ’ป
          Egor Bredikhin
          Egor Bredikhin

          ๐Ÿ›
          Elan P. Kugelmass
          Elan P. Kugelmass

          ๐Ÿ›
          Elder S.
          Elder S.

          ๐Ÿ›
          Eldrick Wega
          Eldrick Wega

          ๐Ÿ“–
          Elliotte Rusty Harold
          Elliotte Rusty Harold

          ๐Ÿ’ป
          Emile
          Emile

          ๐Ÿ›
          Emile
          Emile

          ๐Ÿ›
          Eric
          Eric

          ๐Ÿ›
          Eric Kintzer
          Eric Kintzer

          ๐Ÿ›
          Eric Perret
          Eric Perret

          ๐Ÿ›
          Eric Squires
          Eric Squires

          ๐Ÿ›
          Erich L Foster
          Erich L Foster

          ๐Ÿ›
          Erik Bleske
          Erik Bleske

          ๐Ÿ›
          Erik C. Thauvin
          Erik C. Thauvin

          ๐Ÿ“–
          Erik C. Thauvin
          Erik C. Thauvin

          ๐Ÿ“–
          Ernst Reissner
          Ernst Reissner

          ๐Ÿ›
          Ethan Sargent
          Ethan Sargent

          ๐Ÿ›
          Ewan Tempero
          Ewan Tempero

          ๐Ÿ›
          F.W. Dekker
          F.W. Dekker

          ๐Ÿ›
          FSchliephacke
          FSchliephacke

          ๐Ÿ›
          Facundo
          Facundo

          ๐Ÿ›
          Federico Giust
          Federico Giust

          ๐Ÿ›
          Federico Giust
          Federico Giust

          ๐Ÿ›
          Fedor Sherstobitov
          Fedor Sherstobitov

          ๐Ÿ›
          Felix Lampe
          Felix Lampe

          ๐Ÿ›
          Filip Golonka
          Filip Golonka

          ๐Ÿ›
          Filipe Esperandio
          Filipe Esperandio

          ๐Ÿ’ป ๐Ÿ›
          Filippo Nova
          Filippo Nova

          ๐Ÿ›
          Francesco la Torre
          Francesco la Torre

          ๐Ÿ›
          Francisco Duarte
          Francisco Duarte

          ๐Ÿ›
          Francisco Duarte
          Francisco Duarte

          ๐Ÿ›
          Frederick Zhang
          Frederick Zhang

          ๐Ÿ›
          Frieder Bluemle
          Frieder Bluemle

          ๐Ÿ›
          Frits Jalvingh
          Frits Jalvingh

          ๐Ÿ’ป ๐Ÿ›
          G. Bazior
          G. Bazior

          ๐Ÿ›
          Gabe Henkes
          Gabe Henkes

          ๐Ÿ›
          Gary Gregory
          Gary Gregory

          ๐Ÿ›
          Genoud Magloire
          Genoud Magloire

          ๐Ÿ›
          Genoud Magloire
          Genoud Magloire

          ๐Ÿ›
          Geoffrey555
          Geoffrey555

          ๐Ÿ›
          Georg Romstorfer
          Georg Romstorfer

          ๐Ÿ›
          Gili Tzabari
          Gili Tzabari

          ๐Ÿ› ๐Ÿ’ป
          Gio
          Gio

          ๐Ÿ›
          Gol
          Gol

          ๐Ÿ›
          Gold856
          Gold856

          ๐Ÿ› ๐Ÿ’ป
          Gonzalo Exequiel Ibars Ingman
          Gonzalo Exequiel Ibars Ingman

          ๐Ÿ’ป ๐Ÿ›
          Gonzalo Exequiel Ibars Ingman
          Gonzalo Exequiel Ibars Ingman

          ๐Ÿ’ป ๐Ÿ›
          GooDer
          GooDer

          ๐Ÿ›
          Gregor Riegler
          Gregor Riegler

          ๐Ÿ›
          Grzegorz Olszewski
          Grzegorz Olszewski

          ๐Ÿ›
          Gunther Schrijvers
          Gunther Schrijvers

          ๐Ÿ’ป ๐Ÿ›
          Gustavo Krieger
          Gustavo Krieger

          ๐Ÿ›
          Guy Elsmore-Paddock
          Guy Elsmore-Paddock

          ๐Ÿ›
          Gรถrkem Mรผlayim
          Gรถrkem Mรผlayim

          ๐Ÿ›
          Gรถrkem Mรผlayim
          Gรถrkem Mรผlayim

          ๐Ÿ›
          Hanzel Godinez
          Hanzel Godinez

          ๐Ÿ›
          Haoliang Chen
          Haoliang Chen

          ๐Ÿ›
          Harsh Kukreja
          Harsh Kukreja

          ๐Ÿ›
          Hassan ALAMI
          Hassan ALAMI

          ๐Ÿ›
          Heber
          Heber

          ๐Ÿ›
          Hector Miuler Malpica Gallegos
          Hector Miuler Malpica Gallegos

          ๐Ÿ›
          Henning Schmiedehausen
          Henning Schmiedehausen

          ๐Ÿ’ป ๐Ÿ›
          Henning Schmiedehausen
          Henning Schmiedehausen

          ๐Ÿ’ป ๐Ÿ›
          Henning von Bargen
          Henning von Bargen

          ๐Ÿ’ป
          Hervรฉ Boutemy
          Hervรฉ Boutemy

          ๐Ÿ›
          Himanshu Pandey
          Himanshu Pandey

          ๐Ÿ›
          Hokwang Lee
          Hokwang Lee

          ๐Ÿ›
          Hooperbloob
          Hooperbloob

          ๐Ÿ’ป
          Hung PHAN
          Hung PHAN

          ๐Ÿ›
          IDoCodingStuffs
          IDoCodingStuffs

          ๐Ÿ’ป ๐Ÿ›
          IDoCodingStuffs
          IDoCodingStuffs

          ๐Ÿ’ป ๐Ÿ›
          Iccen Gan
          Iccen Gan

          ๐Ÿ›
          Ignacio Mariano Tirabasso
          Ignacio Mariano Tirabasso

          ๐Ÿ›
          Igor Melnichenko
          Igor Melnichenko

          ๐Ÿ›
          Igor Moreno
          Igor Moreno

          ๐Ÿ›
          Intelesis-MS
          Intelesis-MS

          ๐Ÿ›
          Iroha_
          Iroha_

          ๐Ÿ›
          Ishan Srivastava
          Ishan Srivastava

          ๐Ÿ›
          Ishan Srivastava
          Ishan Srivastava

          ๐Ÿ›
          Iskren Stanislavov
          Iskren Stanislavov

          ๐Ÿ›
          Ivan Vakhrushev
          Ivan Vakhrushev

          ๐Ÿ›
          Ivano Guerini
          Ivano Guerini

          ๐Ÿ›
          Ivar Andreas Bonsaksen
          Ivar Andreas Bonsaksen

          ๐Ÿ›
          Ivo ล mรญd
          Ivo ล mรญd

          ๐Ÿ›
          JJengility
          JJengility

          ๐Ÿ›
          Jake Hemmerle
          Jake Hemmerle

          ๐Ÿ›
          Jake Hemmerle
          Jake Hemmerle

          ๐Ÿ›
          Jakub Dupak
          Jakub Dupak

          ๐Ÿ’ป
          James Harrison
          James Harrison

          ๐Ÿ› ๐Ÿ’ป
          Jamie Bisotti
          Jamie Bisotti

          ๐Ÿ›
          Jan
          Jan

          ๐Ÿ›
          Jan Aertgeerts
          Jan Aertgeerts

          ๐Ÿ’ป ๐Ÿ›
          Jan Brรผmmer
          Jan Brรผmmer

          ๐Ÿ›
          Jan Tล™รญska
          Jan Tล™รญska

          ๐Ÿ›
          Jan Tล™รญska
          Jan Tล™รญska

          ๐Ÿ›
          Jan-Lukas Else
          Jan-Lukas Else

          ๐Ÿ›
          Jason Qiu
          Jason Qiu

          ๐Ÿ’ป ๐Ÿ“–
          Jason Williams
          Jason Williams

          ๐Ÿ›
          Javier Spagnoletti
          Javier Spagnoletti

          ๐Ÿ›
          Jean-Paul Mayer
          Jean-Paul Mayer

          ๐Ÿ›
          Jean-Simon Larochelle
          Jean-Simon Larochelle

          ๐Ÿ›
          Jeff Bartolotta
          Jeff Bartolotta

          ๐Ÿ’ป ๐Ÿ›
          Jeff Bartolotta
          Jeff Bartolotta

          ๐Ÿ’ป ๐Ÿ›
          Jeff Hube
          Jeff Hube

          ๐Ÿ’ป ๐Ÿ›
          Jeff Jensen
          Jeff Jensen

          ๐Ÿ›
          Jeff May
          Jeff May

          ๐Ÿ›
          Jens Gerdes
          Jens Gerdes

          ๐Ÿ›
          Jeroen Borgers
          Jeroen Borgers

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข
          Jeroen Meijer
          Jeroen Meijer

          ๐Ÿ›
          Jeroen van Wilgenburg
          Jeroen van Wilgenburg

          ๐Ÿ“–
          Jeroen van Wilgenburg
          Jeroen van Wilgenburg

          ๐Ÿ“–
          Jerome Russ
          Jerome Russ

          ๐Ÿ›
          JerritEic
          JerritEic

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
          Jiri Pejchal
          Jiri Pejchal

          ๐Ÿ›
          Jithin Sunny
          Jithin Sunny

          ๐Ÿ›
          Jiล™รญ ล korpil
          Jiล™รญ ล korpil

          ๐Ÿ›
          Joao Machado
          Joao Machado

          ๐Ÿ›
          Jochen Krauss
          Jochen Krauss

          ๐Ÿ›
          Jochen Krauss
          Jochen Krauss

          ๐Ÿ›
          Johan Hammar
          Johan Hammar

          ๐Ÿ›
          John Jetmore
          John Jetmore

          ๐Ÿ“–
          John Karp
          John Karp

          ๐Ÿ›
          John Zhang
          John Zhang

          ๐Ÿ›
          John-Teng
          John-Teng

          ๐Ÿ’ป ๐Ÿ›
          Jon Moroney
          Jon Moroney

          ๐Ÿ’ป ๐Ÿ›
          Jonas Geiregat
          Jonas Geiregat

          ๐Ÿ›
          Jonas Geiregat
          Jonas Geiregat

          ๐Ÿ›
          Jonas KeรŸler
          Jonas KeรŸler

          ๐Ÿ›
          Jonathan Wiesel
          Jonathan Wiesel

          ๐Ÿ’ป ๐Ÿ›
          Jordan
          Jordan

          ๐Ÿ›
          Jordi Llach
          Jordi Llach

          ๐Ÿ›
          Jorge Solรณrzano
          Jorge Solรณrzano

          ๐Ÿ›
          JorneVL
          JorneVL

          ๐Ÿ›
          Jose Palafox
          Jose Palafox

          ๐Ÿ›
          Jose Palafox
          Jose Palafox

          ๐Ÿ›
          Jose Stovall
          Jose Stovall

          ๐Ÿ›
          Joseph
          Joseph

          ๐Ÿ’ป
          Joseph Heenan
          Joseph Heenan

          ๐Ÿ›
          Josh Feingold
          Josh Feingold

          ๐Ÿ’ป ๐Ÿ›
          Josh Holthaus
          Josh Holthaus

          ๐Ÿ›
          Joshua S Arquilevich
          Joshua S Arquilevich

          ๐Ÿ›
          Joรฃo Dinis Ferreira
          Joรฃo Dinis Ferreira

          ๐Ÿ“–
          Joรฃo Dinis Ferreira
          Joรฃo Dinis Ferreira

          ๐Ÿ“–
          Joรฃo Ferreira
          Joรฃo Ferreira

          ๐Ÿ’ป ๐Ÿ›
          Joรฃo Pedro Schmitt
          Joรฃo Pedro Schmitt

          ๐Ÿ›
          Juan Martรญn Sotuyo Dodero
          Juan Martรญn Sotuyo Dodero

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง
          Juan Pablo Civile
          Juan Pablo Civile

          ๐Ÿ›
          Julian Voronetsky
          Julian Voronetsky

          ๐Ÿ›
          Julien
          Julien

          ๐Ÿ›
          Julius
          Julius

          ๐Ÿ›
          Julius
          Julius

          ๐Ÿ›
          JustPRV
          JustPRV

          ๐Ÿ›
          Justin Stroud
          Justin Stroud

          ๐Ÿ’ป
          Jรถrn Huxhorn
          Jรถrn Huxhorn

          ๐Ÿ›
          KThompso
          KThompso

          ๐Ÿ›
          Kai Amundsen
          Kai Amundsen

          ๐Ÿ›
          Karel Vervaeke
          Karel Vervaeke

          ๐Ÿ›
          Karl-Andero Mere
          Karl-Andero Mere

          ๐Ÿ›
          Karl-Andero Mere
          Karl-Andero Mere

          ๐Ÿ›
          Karl-Philipp Richter
          Karl-Philipp Richter

          ๐Ÿ›
          Karsten Silz
          Karsten Silz

          ๐Ÿ›
          Kazuma Watanabe
          Kazuma Watanabe

          ๐Ÿ›
          Kev
          Kev

          ๐Ÿ›
          Keve Mรผller
          Keve Mรผller

          ๐Ÿ›
          Kevin Guerra
          Kevin Guerra

          ๐Ÿ’ป
          Kevin Jones
          Kevin Jones

          ๐Ÿ› ๐Ÿ’ป
          Kevin Jones
          Kevin Jones

          ๐Ÿ› ๐Ÿ’ป
          Kevin Poorman
          Kevin Poorman

          ๐Ÿ›
          Kevin Wayne
          Kevin Wayne

          ๐Ÿ›
          Kieran Black
          Kieran Black

          ๐Ÿ›
          Kirill Zubov
          Kirill Zubov

          ๐Ÿ›
          Kirk Clemens
          Kirk Clemens

          ๐Ÿ’ป ๐Ÿ›
          Klaus Hartl
          Klaus Hartl

          ๐Ÿ›
          Koen Van Looveren
          Koen Van Looveren

          ๐Ÿ›
          Koen Van Looveren
          Koen Van Looveren

          ๐Ÿ›
          Kris Scheibe
          Kris Scheibe

          ๐Ÿ’ป ๐Ÿ›
          Krystian Dabrowski
          Krystian Dabrowski

          ๐Ÿ› ๐Ÿ’ป
          Krzysztof Dymek
          Krzysztof Dymek

          ๐Ÿ›
          Kunal Thanki
          Kunal Thanki

          ๐Ÿ›
          Kursat Aktas
          Kursat Aktas

          ๐Ÿ“–
          LaLucid
          LaLucid

          ๐Ÿ’ป
          Larry Diamond
          Larry Diamond

          ๐Ÿ’ป ๐Ÿ›
          Larry Diamond
          Larry Diamond

          ๐Ÿ’ป ๐Ÿ›
          Lars Knickrehm
          Lars Knickrehm

          ๐Ÿ›
          Laurent Bovet
          Laurent Bovet

          ๐Ÿ› ๐Ÿ’ป
          Leo Gutierrez
          Leo Gutierrez

          ๐Ÿ›
          LiGaOg
          LiGaOg

          ๐Ÿ’ป
          Liam Sharp
          Liam Sharp

          ๐Ÿ›
          Lintsi
          Lintsi

          ๐Ÿ›
          Linus Fernandes
          Linus Fernandes

          ๐Ÿ›
          Linus Fernandes
          Linus Fernandes

          ๐Ÿ›
          Lixon Lookose
          Lixon Lookose

          ๐Ÿ›
          Logesh
          Logesh

          ๐Ÿ›
          Lorenzo Gabriele
          Lorenzo Gabriele

          ๐Ÿ›
          Loรฏc Ledoyen
          Loรฏc Ledoyen

          ๐Ÿ›
          Lucas
          Lucas

          ๐Ÿ›
          Lucas Silva
          Lucas Silva

          ๐Ÿ›
          Lucas Soncini
          Lucas Soncini

          ๐Ÿ’ป ๐Ÿ›
          Lucas Soncini
          Lucas Soncini

          ๐Ÿ’ป ๐Ÿ›
          Luis Alcantar
          Luis Alcantar

          ๐Ÿ’ป
          Lukas Grรคf
          Lukas Grรคf

          ๐Ÿ’ป
          Lukasz Slonina
          Lukasz Slonina

          ๐Ÿ›
          Lukebray
          Lukebray

          ๐Ÿ›
          Lynn
          Lynn

          ๐Ÿ’ป ๐Ÿ›
          Lyor Goldstein
          Lyor Goldstein

          ๐Ÿ›
          MCMicS
          MCMicS

          ๐Ÿ›
          MCMicS
          MCMicS

          ๐Ÿ›
          Macarse
          Macarse

          ๐Ÿ›
          Machine account for PMD
          Machine account for PMD

          ๐Ÿ’ป
          Maciek Siemczyk
          Maciek Siemczyk

          ๐Ÿ›
          Maikel Steneker
          Maikel Steneker

          ๐Ÿ’ป ๐Ÿ›
          Maksim Moiseikin
          Maksim Moiseikin

          ๐Ÿ›
          Manfred Koch
          Manfred Koch

          ๐Ÿ›
          Manuel Moya Ferrer
          Manuel Moya Ferrer

          ๐Ÿ’ป ๐Ÿ›
          Manuel Moya Ferrer
          Manuel Moya Ferrer

          ๐Ÿ’ป ๐Ÿ›
          Manuel Romeiro
          Manuel Romeiro

          ๐Ÿ›
          Manuel Ryan
          Manuel Ryan

          ๐Ÿ›
          Marat Vyshegorodtsev
          Marat Vyshegorodtsev

          ๐Ÿ›
          Marcel Hรคrle
          Marcel Hรคrle

          ๐Ÿ›
          Marcello Fialho
          Marcello Fialho

          ๐Ÿ›
          Marcin Dฤ…browski
          Marcin Dฤ…browski

          ๐Ÿ’ป ๐Ÿ›
          Marcin Rataj
          Marcin Rataj

          ๐Ÿ›
          Marcin Rataj
          Marcin Rataj

          ๐Ÿ›
          Marcono1234
          Marcono1234

          ๐Ÿ›
          Mark Adamcin
          Mark Adamcin

          ๐Ÿ›
          Mark Hall
          Mark Hall

          ๐Ÿ’ป ๐Ÿ›
          Mark Kolich
          Mark Kolich

          ๐Ÿ›
          Mark Pritchard
          Mark Pritchard

          ๐Ÿ›
          Markus Rathgeb
          Markus Rathgeb

          ๐Ÿ›
          Marquis Wang
          Marquis Wang

          ๐Ÿ›
          Marquis Wang
          Marquis Wang

          ๐Ÿ›
          MartGit
          MartGit

          ๐Ÿ›
          Martin Feldsztejn
          Martin Feldsztejn

          ๐Ÿ›
          Martin Lehmann
          Martin Lehmann

          ๐Ÿ›
          Martin Spamer
          Martin Spamer

          ๐Ÿ›
          Martin Tarjรกnyi
          Martin Tarjรกnyi

          ๐Ÿ›
          MatFl
          MatFl

          ๐Ÿ›
          Mateusz Stefanski
          Mateusz Stefanski

          ๐Ÿ›
          Mateusz Stefanski
          Mateusz Stefanski

          ๐Ÿ›
          Mathias Lagerwall
          Mathias Lagerwall

          ๐Ÿ›
          Mathieu Gouin
          Mathieu Gouin

          ๐Ÿ›
          MatiasComercio
          MatiasComercio

          ๐Ÿ’ป ๐Ÿ›
          Matt Benson
          Matt Benson

          ๐Ÿ›
          Matt De Poorter
          Matt De Poorter

          ๐Ÿ›
          Matt Hargett
          Matt Hargett

          ๐Ÿ’ป ๐Ÿ’ต
          Matt Harrah
          Matt Harrah

          ๐Ÿ›
          Matt Harrah
          Matt Harrah

          ๐Ÿ›
          Matt Nelson
          Matt Nelson

          ๐Ÿ›
          Matthew Amos
          Matthew Amos

          ๐Ÿ›
          Matthew Duggan
          Matthew Duggan

          ๐Ÿ›
          Matthew Hall
          Matthew Hall

          ๐Ÿ›
          Matthew Rossner
          Matthew Rossner

          ๐Ÿ›
          Matรญas Fraga
          Matรญas Fraga

          ๐Ÿ’ป ๐Ÿ›
          Maxime Robert
          Maxime Robert

          ๐Ÿ’ป ๐Ÿ›
          Maxime Robert
          Maxime Robert

          ๐Ÿ’ป ๐Ÿ›
          MetaBF
          MetaBF

          ๐Ÿ›
          Metin Dagcilar
          Metin Dagcilar

          ๐Ÿ›
          Michael
          Michael

          ๐Ÿ›
          Michael Bell
          Michael Bell

          ๐Ÿ›
          Michael Bernstein
          Michael Bernstein

          ๐Ÿ›
          Michael Clay
          Michael Clay

          ๐Ÿ›
          Michael Dombrowski
          Michael Dombrowski

          ๐Ÿ›
          Michael Dombrowski
          Michael Dombrowski

          ๐Ÿ›
          Michael Hausegger
          Michael Hausegger

          ๐Ÿ›
          Michael Hoefer
          Michael Hoefer

          ๐Ÿ›
          Michael Kolesnikov
          Michael Kolesnikov

          ๐Ÿ›
          Michael Mรถbius
          Michael Mรถbius

          ๐Ÿ›
          Michael N. Lipp
          Michael N. Lipp

          ๐Ÿ›
          Michael Pellegrini
          Michael Pellegrini

          ๐Ÿ›
          Michal Kordas
          Michal Kordas

          ๐Ÿ›
          Michal Kordas
          Michal Kordas

          ๐Ÿ›
          Michaล‚ Borek
          Michaล‚ Borek

          ๐Ÿ›
          Michaล‚ Kuliล„ski
          Michaล‚ Kuliล„ski

          ๐Ÿ›
          Miguel Nรบรฑez Dรญaz-Montes
          Miguel Nรบรฑez Dรญaz-Montes

          ๐Ÿ›
          Mihai Ionut
          Mihai Ionut

          ๐Ÿ›
          Mikhail Kuchma
          Mikhail Kuchma

          ๐Ÿ›
          MiladSadinam
          MiladSadinam

          ๐Ÿ›
          Mirek Hankus
          Mirek Hankus

          ๐Ÿ›
          Mirek Hankus
          Mirek Hankus

          ๐Ÿ›
          Mitch Spano
          Mitch Spano

          ๐Ÿ’ป ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          MrAngry52
          MrAngry52

          ๐Ÿ›
          Muminur Choudhury
          Muminur Choudhury

          ๐Ÿ›
          Mykhailo Palahuta
          Mykhailo Palahuta

          ๐Ÿ’ป ๐Ÿ›
          Nagendra Kumar Singh
          Nagendra Kumar Singh

          ๐Ÿ›
          Nagendra Kumar Singh
          Nagendra Kumar Singh

          ๐Ÿ›
          Nahuel Barrios
          Nahuel Barrios

          ๐Ÿ›
          Nakul Sharma
          Nakul Sharma

          ๐Ÿ›
          Nathan Braun
          Nathan Braun

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathanaรซl
          Nathanaรซl

          ๐Ÿ›
          Naveen
          Naveen

          ๐Ÿ’ป
          Naveen
          Naveen

          ๐Ÿ’ป
          Nazdravi
          Nazdravi

          ๐Ÿ›
          Neha-Dhonde
          Neha-Dhonde

          ๐Ÿ›
          Nicholas Doyle
          Nicholas Doyle

          ๐Ÿ›
          Nick Butcher
          Nick Butcher

          ๐Ÿ›
          Nico Gallinal
          Nico Gallinal

          ๐Ÿ›
          Nicola Dal Maso
          Nicola Dal Maso

          ๐Ÿ›
          Nicolas Filotto
          Nicolas Filotto

          ๐Ÿ’ป
          Nicolas Filotto
          Nicolas Filotto

          ๐Ÿ’ป
          Nicolas Vervelle
          Nicolas Vervelle

          ๐Ÿ›
          Nicolas Vuillamy
          Nicolas Vuillamy

          ๐Ÿ“–
          Nikita Chursin
          Nikita Chursin

          ๐Ÿ›
          Niklas Baudy
          Niklas Baudy

          ๐Ÿ›
          Nikolas Havrikov
          Nikolas Havrikov

          ๐Ÿ›
          Nilesh Virkar
          Nilesh Virkar

          ๐Ÿ›
          Nimit Patel
          Nimit Patel

          ๐Ÿ›
          Nimit Patel
          Nimit Patel

          ๐Ÿ›
          Niranjan Harpale
          Niranjan Harpale

          ๐Ÿ›
          Nirvik Patel
          Nirvik Patel

          ๐Ÿ’ป
          Noah Sussman
          Noah Sussman

          ๐Ÿ›
          Noah0120
          Noah0120

          ๐Ÿ›
          Noam Tamim
          Noam Tamim

          ๐Ÿ›
          Noel Grandin
          Noel Grandin

          ๐Ÿ›
          Olaf Haalstra
          Olaf Haalstra

          ๐Ÿ›
          Olaf Haalstra
          Olaf Haalstra

          ๐Ÿ›
          Oleg Andreych
          Oleg Andreych

          ๐Ÿ’ป ๐Ÿ›
          Oleg Pavlenko
          Oleg Pavlenko

          ๐Ÿ›
          Oleksii Dykov
          Oleksii Dykov

          ๐Ÿ’ป ๐Ÿ›
          Oliver Eikemeier
          Oliver Eikemeier

          ๐Ÿ›
          Oliver Siegmar
          Oliver Siegmar

          ๐Ÿ’ต
          Olivier Parent
          Olivier Parent

          ๐Ÿ’ป ๐Ÿ›
          Ollie Abbey
          Ollie Abbey

          ๐Ÿ’ป ๐Ÿ›
          Ollie Abbey
          Ollie Abbey

          ๐Ÿ’ป ๐Ÿ›
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)

          ๐Ÿ›
          Ondrej Kratochvil
          Ondrej Kratochvil

          ๐Ÿ›
          OverDrone
          OverDrone

          ๐Ÿ›
          Ozan Gulle
          Ozan Gulle

          ๐Ÿ’ป ๐Ÿ›
          PUNEET JAIN
          PUNEET JAIN

          ๐Ÿ›
          Parbati Bose
          Parbati Bose

          ๐Ÿ›
          Paul Berg
          Paul Berg

          ๐Ÿ›
          Paul Berg
          Paul Berg

          ๐Ÿ›
          Paul Guyot
          Paul Guyot

          ๐Ÿ’ป
          Pavel Bludov
          Pavel Bludov

          ๐Ÿ›
          Pavel Miฤka
          Pavel Miฤka

          ๐Ÿ›
          Pedro Nuno Santos
          Pedro Nuno Santos

          ๐Ÿ›
          Pedro Rijo
          Pedro Rijo

          ๐Ÿ›
          Pelisse Romain
          Pelisse Romain

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
          Per Abich
          Per Abich

          ๐Ÿ’ป
          Per Abich
          Per Abich

          ๐Ÿ’ป
          Pete Davids
          Pete Davids

          ๐Ÿ›
          Peter Bruin
          Peter Bruin

          ๐Ÿ›
          Peter Chittum
          Peter Chittum

          ๐Ÿ’ป ๐Ÿ›
          Peter Cudmore
          Peter Cudmore

          ๐Ÿ›
          Peter Kasson
          Peter Kasson

          ๐Ÿ›
          Peter Kofler
          Peter Kofler

          ๐Ÿ›
          Peter Paul Bakker
          Peter Paul Bakker

          ๐Ÿ’ป ๐Ÿ›
          Peter Paul Bakker
          Peter Paul Bakker

          ๐Ÿ’ป ๐Ÿ›
          Peter Rader
          Peter Rader

          ๐Ÿ›
          Pham Hai Trung
          Pham Hai Trung

          ๐Ÿ›
          Philip Graf
          Philip Graf

          ๐Ÿ’ป ๐Ÿ›
          Philip Hachey
          Philip Hachey

          ๐Ÿ›
          Philippe Ozil
          Philippe Ozil

          ๐Ÿ›
          Phinehas Artemix
          Phinehas Artemix

          ๐Ÿ›
          Phokham Nonava
          Phokham Nonava

          ๐Ÿ›
          Phokham Nonava
          Phokham Nonava

          ๐Ÿ›
          Pim van der Loos
          Pim van der Loos

          ๐Ÿ’ป โš ๏ธ
          Piotr Szymaล„ski
          Piotr Szymaล„ski

          ๐Ÿ›
          Piotrek ลปygieล‚o
          Piotrek ลปygieล‚o

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“–
          Pranay Jaiswal
          Pranay Jaiswal

          ๐Ÿ›
          Prasad Kamath
          Prasad Kamath

          ๐Ÿ›
          Prasanna
          Prasanna

          ๐Ÿ›
          Presh-AR
          Presh-AR

          ๐Ÿ›
          Presh-AR
          Presh-AR

          ๐Ÿ›
          Puneet1726
          Puneet1726

          ๐Ÿ›
          RBRi
          RBRi

          ๐Ÿ›
          Rafael Cortรชs
          Rafael Cortรชs

          ๐Ÿ›
          RaheemShaik999
          RaheemShaik999

          ๐Ÿ›
          RajeshR
          RajeshR

          ๐Ÿ’ป ๐Ÿ›
          Ramachandra Mohan
          Ramachandra Mohan

          ๐Ÿ›
          Ramel0921
          Ramel0921

          ๐Ÿ›
          Ramel0921
          Ramel0921

          ๐Ÿ›
          Raquel Pau
          Raquel Pau

          ๐Ÿ›
          Ravikiran Janardhana
          Ravikiran Janardhana

          ๐Ÿ›
          Reda Benhemmouche
          Reda Benhemmouche

          ๐Ÿ›
          Reinhard Schiedermeier
          Reinhard Schiedermeier

          ๐Ÿ›
          Renato Oliveira
          Renato Oliveira

          ๐Ÿ’ป ๐Ÿ›
          Rich DiCroce
          Rich DiCroce

          ๐Ÿ›
          Richard Corfield
          Richard Corfield

          ๐Ÿ’ป
          Richard Corfield
          Richard Corfield

          ๐Ÿ’ป
          Richard Corfield
          Richard Corfield

          ๐Ÿ› ๐Ÿ’ป
          Riot R1cket
          Riot R1cket

          ๐Ÿ›
          Rishabh Jain
          Rishabh Jain

          ๐Ÿ›
          RishabhDeep Singh
          RishabhDeep Singh

          ๐Ÿ›
          Rob Baillie
          Rob Baillie

          ๐Ÿ›
          Robbie Martinus
          Robbie Martinus

          ๐Ÿ’ป ๐Ÿ›
          Robert Henry
          Robert Henry

          ๐Ÿ›
          Robert Henry
          Robert Henry

          ๐Ÿ›
          Robert Mihaly
          Robert Mihaly

          ๐Ÿ›
          Robert Painsi
          Robert Painsi

          ๐Ÿ›
          Robert Russell
          Robert Russell

          ๐Ÿ›
          Robert Sรถsemann
          Robert Sรถsemann

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ›
          Robert Whitebit
          Robert Whitebit

          ๐Ÿ›
          Robin Richtsfeld
          Robin Richtsfeld

          ๐Ÿ›
          Robin Stocker
          Robin Stocker

          ๐Ÿ’ป ๐Ÿ›
          Robin Stocker
          Robin Stocker

          ๐Ÿ’ป ๐Ÿ›
          Robin Wils
          Robin Wils

          ๐Ÿ›
          RochusOest
          RochusOest

          ๐Ÿ›
          Rodolfo Noviski
          Rodolfo Noviski

          ๐Ÿ›
          Rodrigo Casara
          Rodrigo Casara

          ๐Ÿ›
          Rodrigo Fernandes
          Rodrigo Fernandes

          ๐Ÿ›
          Roman Salvador
          Roman Salvador

          ๐Ÿ’ป ๐Ÿ›
          Ronald Blaschke
          Ronald Blaschke

          ๐Ÿ›
          Ronald Blaschke
          Ronald Blaschke

          ๐Ÿ›
          Rรณbert Papp
          Rรณbert Papp

          ๐Ÿ›
          Saikat Sengupta
          Saikat Sengupta

          ๐Ÿ›
          Saksham Handu
          Saksham Handu

          ๐Ÿ›
          Saladoc
          Saladoc

          ๐Ÿ›
          Salesforce Bob Lightning
          Salesforce Bob Lightning

          ๐Ÿ›
          Sam Carlberg
          Sam Carlberg

          ๐Ÿ›
          Sascha Riemer
          Sascha Riemer

          ๐Ÿ›
          Sascha Riemer
          Sascha Riemer

          ๐Ÿ›
          Sashko
          Sashko

          ๐Ÿ’ป
          Satoshi Kubo
          Satoshi Kubo

          ๐Ÿ›
          Scott Kennedy
          Scott Kennedy

          ๐Ÿ›
          Scott Wells
          Scott Wells

          ๐Ÿ› ๐Ÿ’ป
          Scrates1
          Scrates1

          ๐Ÿ› ๐Ÿ’ป
          Scrsloota
          Scrsloota

          ๐Ÿ’ป
          Sebastian Bรถgl
          Sebastian Bรถgl

          ๐Ÿ›
          Sebastian Bรถgl
          Sebastian Bรถgl

          ๐Ÿ›
          Sebastian Davids
          Sebastian Davids

          ๐Ÿ›
          Sebastian Lรถvdahl
          Sebastian Lรถvdahl

          ๐Ÿ›
          Sebastian Schuberth
          Sebastian Schuberth

          ๐Ÿ›
          Sebastian Schwarz
          Sebastian Schwarz

          ๐Ÿ›
          Seren
          Seren

          ๐Ÿ› ๐Ÿ’ป
          Sergey Gorbaty
          Sergey Gorbaty

          ๐Ÿ›
          Sergey Kozlov
          Sergey Kozlov

          ๐Ÿ›
          Sergey Kozlov
          Sergey Kozlov

          ๐Ÿ›
          Sergey Yanzin
          Sergey Yanzin

          ๐Ÿ’ป ๐Ÿ›
          Seth Wilcox
          Seth Wilcox

          ๐Ÿ’ป
          Shai Bennathan
          Shai Bennathan

          ๐Ÿ› ๐Ÿ’ป
          Shubham
          Shubham

          ๐Ÿ’ป ๐Ÿ›
          Simon Abykov
          Simon Abykov

          ๐Ÿ’ป ๐Ÿ›
          Simon Xiao
          Simon Xiao

          ๐Ÿ›
          Srinivasan Venkatachalam
          Srinivasan Venkatachalam

          ๐Ÿ›
          Srinivasan Venkatachalam
          Srinivasan Venkatachalam

          ๐Ÿ›
          Stanislav Gromov
          Stanislav Gromov

          ๐Ÿ›
          Stanislav Myachenkov
          Stanislav Myachenkov

          ๐Ÿ’ป
          Stefan Birkner
          Stefan Birkner

          ๐Ÿ›
          Stefan Bohn
          Stefan Bohn

          ๐Ÿ›
          Stefan Endrullis
          Stefan Endrullis

          ๐Ÿ›
          Stefan Klรถss-Schuster
          Stefan Klรถss-Schuster

          ๐Ÿ›
          Stefan Wolf
          Stefan Wolf

          ๐Ÿ›
          Stefan Wolf
          Stefan Wolf

          ๐Ÿ›
          Stephan H. Wissel
          Stephan H. Wissel

          ๐Ÿ›
          Stephen
          Stephen

          ๐Ÿ›
          Stephen Carter
          Stephen Carter

          ๐Ÿ›
          Stephen Friedrich
          Stephen Friedrich

          ๐Ÿ›
          Steve Babula
          Steve Babula

          ๐Ÿ’ป
          Steven Stearns
          Steven Stearns

          ๐Ÿ› ๐Ÿ’ป
          Stexxe
          Stexxe

          ๐Ÿ›
          Stexxe
          Stexxe

          ๐Ÿ›
          Stian Lรฅgstad
          Stian Lรฅgstad

          ๐Ÿ›
          StuartClayton5
          StuartClayton5

          ๐Ÿ›
          Supun Arunoda
          Supun Arunoda

          ๐Ÿ›
          Suren Abrahamyan
          Suren Abrahamyan

          ๐Ÿ›
          Suvashri
          Suvashri

          ๐Ÿ“–
          Sven Barden
          Sven Barden

          ๐Ÿ›
          SwatiBGupta1110
          SwatiBGupta1110

          ๐Ÿ›
          SwatiBGupta1110
          SwatiBGupta1110

          ๐Ÿ›
          SyedThoufich
          SyedThoufich

          ๐Ÿ›
          Szymon Sasin
          Szymon Sasin

          ๐Ÿ›
          T-chuangxin
          T-chuangxin

          ๐Ÿ›
          TERAI Atsuhiro
          TERAI Atsuhiro

          ๐Ÿ›
          TIOBE Software
          TIOBE Software

          ๐Ÿ’ป ๐Ÿ›
          Tarush Singh
          Tarush Singh

          ๐Ÿ’ป
          Taylor Smock
          Taylor Smock

          ๐Ÿ›
          Taylor Smock
          Taylor Smock

          ๐Ÿ›
          Techeira Damiรกn
          Techeira Damiรกn

          ๐Ÿ’ป ๐Ÿ›
          Ted Husted
          Ted Husted

          ๐Ÿ›
          TehBakker
          TehBakker

          ๐Ÿ›
          The Gitter Badger
          The Gitter Badger

          ๐Ÿ›
          Theodoor
          Theodoor

          ๐Ÿ›
          Thiago Henrique Hรผpner
          Thiago Henrique Hรผpner

          ๐Ÿ›
          Thibault Meyer
          Thibault Meyer

          ๐Ÿ›
          Thibault Meyer
          Thibault Meyer

          ๐Ÿ›
          Thomas Gรผttler
          Thomas Gรผttler

          ๐Ÿ›
          Thomas Jones-Low
          Thomas Jones-Low

          ๐Ÿ›
          Thomas Smith
          Thomas Smith

          ๐Ÿ’ป ๐Ÿ›
          ThrawnCA
          ThrawnCA

          ๐Ÿ›
          Thu Vo
          Thu Vo

          ๐Ÿ›
          Thunderforge
          Thunderforge

          ๐Ÿ’ป ๐Ÿ›
          Tim van der Lippe
          Tim van der Lippe

          ๐Ÿ›
          Tim van der Lippe
          Tim van der Lippe

          ๐Ÿ›
          Tobias Weimer
          Tobias Weimer

          ๐Ÿ’ป ๐Ÿ›
          Tom Copeland
          Tom Copeland

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–
          Tom Daly
          Tom Daly

          ๐Ÿ›
          Tomas
          Tomas

          ๐Ÿ›
          Tomer Figenblat
          Tomer Figenblat

          ๐Ÿ›
          Tomi De Lucca
          Tomi De Lucca

          ๐Ÿ’ป ๐Ÿ›
          Tony
          Tony

          ๐Ÿ“–
          Tony
          Tony

          ๐Ÿ“–
          Torsten Kleiber
          Torsten Kleiber

          ๐Ÿ›
          Torsten Krause
          Torsten Krause

          ๐Ÿ›
          TrackerSB
          TrackerSB

          ๐Ÿ›
          Tyson Stewart
          Tyson Stewart

          ๐Ÿ›
          Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ›
          Utku Cuhadaroglu
          Utku Cuhadaroglu

          ๐Ÿ’ป ๐Ÿ›
          Valentin Brandl
          Valentin Brandl

          ๐Ÿ›
          Valentin Brandl
          Valentin Brandl

          ๐Ÿ›
          Valeria
          Valeria

          ๐Ÿ›
          Valery Yatsynovich
          Valery Yatsynovich

          ๐Ÿ“–
          Vasily Anisimov
          Vasily Anisimov

          ๐Ÿ›
          Vedant Chokshi
          Vedant Chokshi

          ๐Ÿ›
          Vibhor Goyal
          Vibhor Goyal

          ๐Ÿ›
          Vickenty Fesunov
          Vickenty Fesunov

          ๐Ÿ›
          Victor Noรซl
          Victor Noรซl

          ๐Ÿ›
          Victor Noรซl
          Victor Noรซl

          ๐Ÿ›
          Vincent Galloy
          Vincent Galloy

          ๐Ÿ’ป
          Vincent HUYNH
          Vincent HUYNH

          ๐Ÿ›
          Vincent Maurin
          Vincent Maurin

          ๐Ÿ›
          Vincent Potucek
          Vincent Potucek

          ๐Ÿ’ป
          Vincent Privat
          Vincent Privat

          ๐Ÿ›
          Vishhwas
          Vishhwas

          ๐Ÿ›
          Vishv_Android
          Vishv_Android

          ๐Ÿ›
          Vishv_Android
          Vishv_Android

          ๐Ÿ›
          Vitalii Yevtushenko
          Vitalii Yevtushenko

          ๐Ÿ›
          Vitaly
          Vitaly

          ๐Ÿ›
          Vitaly Polonetsky
          Vitaly Polonetsky

          ๐Ÿ›
          Vojtech Polivka
          Vojtech Polivka

          ๐Ÿ›
          Vsevolod Zholobov
          Vsevolod Zholobov

          ๐Ÿ›
          Vyom Yadav
          Vyom Yadav

          ๐Ÿ’ป
          Wang Shidong
          Wang Shidong

          ๐Ÿ›
          Wang Shidong
          Wang Shidong

          ๐Ÿ›
          Waqas Ahmed
          Waqas Ahmed

          ๐Ÿ›
          Wayne J. Earl
          Wayne J. Earl

          ๐Ÿ›
          Wchenghui
          Wchenghui

          ๐Ÿ›
          Wener
          Wener

          ๐Ÿ’ป
          Will Winder
          Will Winder

          ๐Ÿ›
          Willem A. Hajenius
          Willem A. Hajenius

          ๐Ÿ’ป
          William Brockhus
          William Brockhus

          ๐Ÿ’ป ๐Ÿ›
          William Brockhus
          William Brockhus

          ๐Ÿ’ป ๐Ÿ›
          Wilson Kurniawan
          Wilson Kurniawan

          ๐Ÿ›
          Wim Deblauwe
          Wim Deblauwe

          ๐Ÿ›
          Wolf2323
          Wolf2323

          ๐Ÿ›
          Woongsik Choi
          Woongsik Choi

          ๐Ÿ›
          XenoAmess
          XenoAmess

          ๐Ÿ’ป ๐Ÿ›
          Yang
          Yang

          ๐Ÿ’ป
          YaroslavTER
          YaroslavTER

          ๐Ÿ›
          YaroslavTER
          YaroslavTER

          ๐Ÿ›
          Yasar Shaikh
          Yasar Shaikh

          ๐Ÿ’ป
          Young Chan
          Young Chan

          ๐Ÿ’ป ๐Ÿ›
          YuJin Kim
          YuJin Kim

          ๐Ÿ›
          Yuri Dolzhenko
          Yuri Dolzhenko

          ๐Ÿ›
          Yurii Dubinka
          Yurii Dubinka

          ๐Ÿ›
          Zoltan Farkas
          Zoltan Farkas

          ๐Ÿ›
          Zustin
          Zustin

          ๐Ÿ›
          Zustin
          Zustin

          ๐Ÿ›
          aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป
          alexmodis
          alexmodis

          ๐Ÿ›
          andreoss
          andreoss

          ๐Ÿ›
          andrey81inmd
          andrey81inmd

          ๐Ÿ’ป ๐Ÿ›
          anicoara
          anicoara

          ๐Ÿ›
          arunprasathav
          arunprasathav

          ๐Ÿ›
          asiercamara
          asiercamara

          ๐Ÿ›
          asiercamara
          asiercamara

          ๐Ÿ›
          astillich-igniti
          astillich-igniti

          ๐Ÿ’ป
          avesolovksyy
          avesolovksyy

          ๐Ÿ›
          avishvat
          avishvat

          ๐Ÿ›
          avivmu
          avivmu

          ๐Ÿ›
          axelbarfod1
          axelbarfod1

          ๐Ÿ›
          b-3-n
          b-3-n

          ๐Ÿ›
          balbhadra9
          balbhadra9

          ๐Ÿ›
          balbhadra9
          balbhadra9

          ๐Ÿ›
          base23de
          base23de

          ๐Ÿ›
          bergander
          bergander

          ๐Ÿ› ๐Ÿ’ป
          berkam
          berkam

          ๐Ÿ’ป ๐Ÿ›
          breizh31
          breizh31

          ๐Ÿ›
          caesarkim
          caesarkim

          ๐Ÿ›
          caiocarvalhotero
          caiocarvalhotero

          ๐Ÿ›
          carolyujing
          carolyujing

          ๐Ÿ›
          carolyujing
          carolyujing

          ๐Ÿ›
          cbfiddle
          cbfiddle

          ๐Ÿ›
          cesares-basilico
          cesares-basilico

          ๐Ÿ›
          chrite
          chrite

          ๐Ÿ›
          ciufudean
          ciufudean

          ๐Ÿ“–
          cobratbq
          cobratbq

          ๐Ÿ›
          coladict
          coladict

          ๐Ÿ›
          cosmoJFH
          cosmoJFH

          ๐Ÿ›
          cosmoJFH
          cosmoJFH

          ๐Ÿ›
          cristalp
          cristalp

          ๐Ÿ›
          crunsk
          crunsk

          ๐Ÿ›
          cwholmes
          cwholmes

          ๐Ÿ›
          cyberjj999
          cyberjj999

          ๐Ÿ›
          cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“–
          d1ss0nanz
          d1ss0nanz

          ๐Ÿ›
          dague1
          dague1

          ๐Ÿ“–
          dague1
          dague1

          ๐Ÿ“–
          dalizi007
          dalizi007

          ๐Ÿ’ป
          danbrycefairsailcom
          danbrycefairsailcom

          ๐Ÿ›
          dariansanity
          dariansanity

          ๐Ÿ›
          darrenmiliband
          darrenmiliband

          ๐Ÿ›
          davidburstrom
          davidburstrom

          ๐Ÿ›
          dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ›
          deepak-patra
          deepak-patra

          ๐Ÿ›
          deepak-patra
          deepak-patra

          ๐Ÿ›
          dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ›
          dinesh150
          dinesh150

          ๐Ÿ›
          diziaq
          diziaq

          ๐Ÿ›
          dreaminpast123
          dreaminpast123

          ๐Ÿ›
          duanyanan
          duanyanan

          ๐Ÿ›
          dutt-sanjay
          dutt-sanjay

          ๐Ÿ›
          duursma
          duursma

          ๐Ÿ’ป
          duursma
          duursma

          ๐Ÿ’ป
          dylanleung
          dylanleung

          ๐Ÿ›
          dzeigler
          dzeigler

          ๐Ÿ›
          eant60
          eant60

          ๐Ÿ›
          ekkirala
          ekkirala

          ๐Ÿ›
          emersonmoura
          emersonmoura

          ๐Ÿ›
          emouty
          emouty

          ๐Ÿ’ป ๐Ÿ›
          eugenepugach
          eugenepugach

          ๐Ÿ›
          eugenepugach
          eugenepugach

          ๐Ÿ›
          fairy
          fairy

          ๐Ÿ›
          filiprafalowicz
          filiprafalowicz

          ๐Ÿ’ป
          flxbl-io
          flxbl-io

          ๐Ÿ’ต
          foxmason
          foxmason

          ๐Ÿ›
          frankegabor
          frankegabor

          ๐Ÿ›
          frankl
          frankl

          ๐Ÿ›
          freafrea
          freafrea

          ๐Ÿ›
          freafrea
          freafrea

          ๐Ÿ›
          fsapatin
          fsapatin

          ๐Ÿ›
          gearsethenry
          gearsethenry

          ๐Ÿ›
          gracia19
          gracia19

          ๐Ÿ›
          gudzpoz
          gudzpoz

          ๐Ÿ›
          guo fei
          guo fei

          ๐Ÿ›
          gurmsc5
          gurmsc5

          ๐Ÿ›
          gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ›
          gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ›
          haigsn
          haigsn

          ๐Ÿ›
          hemanshu070
          hemanshu070

          ๐Ÿ›
          henrik242
          henrik242

          ๐Ÿ›
          hongpuwu
          hongpuwu

          ๐Ÿ›
          hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ›
          igniti GmbH
          igniti GmbH

          ๐Ÿ›
          ilovezfs
          ilovezfs

          ๐Ÿ›
          ilovezfs
          ilovezfs

          ๐Ÿ›
          imax-erik
          imax-erik

          ๐Ÿ›
          itaigilo
          itaigilo

          ๐Ÿ›
          jakivey32
          jakivey32

          ๐Ÿ›
          jbennett2091
          jbennett2091

          ๐Ÿ›
          jcamerin
          jcamerin

          ๐Ÿ›
          jkeener1
          jkeener1

          ๐Ÿ›
          jmetertea
          jmetertea

          ๐Ÿ›
          jmetertea
          jmetertea

          ๐Ÿ›
          johnra2
          johnra2

          ๐Ÿ’ป
          johnzhao9
          johnzhao9

          ๐Ÿ›
          josemanuelrolon
          josemanuelrolon

          ๐Ÿ’ป ๐Ÿ›
          julees7
          julees7

          ๐Ÿ’ป ๐Ÿ›
          kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ›
          karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“–
          karwer
          karwer

          ๐Ÿ›
          karwer
          karwer

          ๐Ÿ›
          kaulonline
          kaulonline

          ๐Ÿ›
          kdaemonv
          kdaemonv

          ๐Ÿ›
          kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป
          kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ›
          kfranic
          kfranic

          ๐Ÿ›
          khalidkh
          khalidkh

          ๐Ÿ›
          koalalam
          koalalam

          ๐Ÿ›
          koalalam
          koalalam

          ๐Ÿ›
          krzyk
          krzyk

          ๐Ÿ›
          lasselindqvist
          lasselindqvist

          ๐Ÿ›
          lgemeinhardt
          lgemeinhardt

          ๐Ÿ›
          lihuaib
          lihuaib

          ๐Ÿ›
          liqingjun123
          liqingjun123

          ๐Ÿ›
          lonelyma1021
          lonelyma1021

          ๐Ÿ›
          lothas
          lothas

          ๐Ÿ›
          lothas
          lothas

          ๐Ÿ›
          lpeddy
          lpeddy

          ๐Ÿ›
          lujiefsi
          lujiefsi

          ๐Ÿ’ป
          lukelukes
          lukelukes

          ๐Ÿ’ป
          lyriccoder
          lyriccoder

          ๐Ÿ›
          marcelmore
          marcelmore

          ๐Ÿ›
          matchbox
          matchbox

          ๐Ÿ›
          matthiaskraaz
          matthiaskraaz

          ๐Ÿ›
          matthiaskraaz
          matthiaskraaz

          ๐Ÿ›
          meandonlyme
          meandonlyme

          ๐Ÿ›
          mikesive
          mikesive

          ๐Ÿ›
          milossesic
          milossesic

          ๐Ÿ›
          mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ›
          mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป
          mriddell95
          mriddell95

          ๐Ÿ›
          mrlzh
          mrlzh

          ๐Ÿ›
          mrlzh
          mrlzh

          ๐Ÿ›
          msloan
          msloan

          ๐Ÿ›
          mucharlaravalika
          mucharlaravalika

          ๐Ÿ›
          mvenneman
          mvenneman

          ๐Ÿ›
          nareshl119
          nareshl119

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          noerremark
          noerremark

          ๐Ÿ›
          novsirion
          novsirion

          ๐Ÿ›
          novsirion
          novsirion

          ๐Ÿ›
          nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป
          oggboy
          oggboy

          ๐Ÿ›
          oinume
          oinume

          ๐Ÿ›
          orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pacvz
          pacvz

          ๐Ÿ’ป
          pallavi agarwal
          pallavi agarwal

          ๐Ÿ›
          pallavi agarwal
          pallavi agarwal

          ๐Ÿ›
          pankratz76
          pankratz76

          ๐Ÿ›
          parksungrin
          parksungrin

          ๐Ÿ›
          patpatpat123
          patpatpat123

          ๐Ÿ›
          patriksevallius
          patriksevallius

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          phoenix384
          phoenix384

          ๐Ÿ›
          piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป
          piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป
          plan3d
          plan3d

          ๐Ÿ›
          poojasix
          poojasix

          ๐Ÿ›
          prabhushrikant
          prabhushrikant

          ๐Ÿ›
          pujitha8783
          pujitha8783

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          raghujayjunk
          raghujayjunk

          ๐Ÿ›
          rajeshveera
          rajeshveera

          ๐Ÿ›
          rajeshveera
          rajeshveera

          ๐Ÿ›
          rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ›
          recdevs
          recdevs

          ๐Ÿ›
          reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ›
          rijkt
          rijkt

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ›
          rnveach
          rnveach

          ๐Ÿ›
          rnveach
          rnveach

          ๐Ÿ›
          rxmicro
          rxmicro

          ๐Ÿ›
          ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ›
          sabi0
          sabi0

          ๐Ÿ›
          samc-gearset
          samc-gearset

          ๐Ÿ“–
          scais
          scais

          ๐Ÿ›
          schosin
          schosin

          ๐Ÿ›
          screamingfrog
          screamingfrog

          ๐Ÿ’ต
          screamingfrog
          screamingfrog

          ๐Ÿ’ต
          sebbASF
          sebbASF

          ๐Ÿ›
          sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป
          shilko2013
          shilko2013

          ๐Ÿ›
          shiomiyan
          shiomiyan

          ๐Ÿ“–
          simeonKondr
          simeonKondr

          ๐Ÿ›
          snajberk
          snajberk

          ๐Ÿ›
          sniperrifle2004
          sniperrifle2004

          ๐Ÿ›
          sniperrifle2004
          sniperrifle2004

          ๐Ÿ›
          snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป
          soloturn
          soloturn

          ๐Ÿ›
          soyodream
          soyodream

          ๐Ÿ›
          sratz
          sratz

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          sturton
          sturton

          ๐Ÿ’ป ๐Ÿ›
          sudharmohan
          sudharmohan

          ๐Ÿ›
          sudharmohan
          sudharmohan

          ๐Ÿ›
          suruchidawar
          suruchidawar

          ๐Ÿ›
          svenfinitiv
          svenfinitiv

          ๐Ÿ›
          szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป
          tashiscool
          tashiscool

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          testation21
          testation21

          ๐Ÿ’ป ๐Ÿ›
          thanosa
          thanosa

          ๐Ÿ›
          thanosa
          thanosa

          ๐Ÿ›
          tiandiyixian
          tiandiyixian

          ๐Ÿ›
          tobwoerk
          tobwoerk

          ๐Ÿ›
          tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป
          trentchilders
          trentchilders

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          trishul14
          trishul14

          ๐Ÿ›
          tsui
          tsui

          ๐Ÿ›
          tsui
          tsui

          ๐Ÿ›
          wangzitom12306
          wangzitom12306

          ๐Ÿ›
          winhkey
          winhkey

          ๐Ÿ›
          witherspore
          witherspore

          ๐Ÿ›
          wjljack
          wjljack

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          xingsong
          xingsong

          ๐Ÿ›
          xioayuge
          xioayuge

          ๐Ÿ›
          xioayuge
          xioayuge

          ๐Ÿ›
          xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ›
          xuanuy
          xuanuy

          ๐Ÿ›
          xyf0921
          xyf0921

          ๐Ÿ›
          yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yasuharu-sato
          yasuharu-sato

          ๐Ÿ›
          zenglian
          zenglian

          ๐Ÿ›
          zenglian
          zenglian

          ๐Ÿ›
          zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ›
          zh3ng
          zh3ng

          ๐Ÿ›
          zt_soft
          zt_soft

          ๐Ÿ›
          ztt79
          ztt79

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ›
          ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ›
          ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ›
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ

          ๐Ÿ›
          ่Œ…ๅปถๅฎ‰
          ่Œ…ๅปถๅฎ‰

          ๐Ÿ’ป
          Felix Lampe
          Felix Lampe

          ๐Ÿ›
          Filip Golonka
          Filip Golonka

          ๐Ÿ›
          Filipe Esperandio
          Filipe Esperandio

          ๐Ÿ’ป ๐Ÿ›
          Filippo Barbari
          Filippo Barbari

          ๐Ÿ›
          Filippo Nova
          Filippo Nova

          ๐Ÿ›
          Francesco la Torre
          Francesco la Torre

          ๐Ÿ›
          Francesco la Torre
          Francesco la Torre

          ๐Ÿ›
          Francisco Duarte
          Francisco Duarte

          ๐Ÿ›
          Frederick Zhang
          Frederick Zhang

          ๐Ÿ›
          Frieder Bluemle
          Frieder Bluemle

          ๐Ÿ›
          Frits Jalvingh
          Frits Jalvingh

          ๐Ÿ’ป ๐Ÿ›
          G. Bazior
          G. Bazior

          ๐Ÿ›
          Gabe Henkes
          Gabe Henkes

          ๐Ÿ›
          Gary Gregory
          Gary Gregory

          ๐Ÿ›
          Gary Gregory
          Gary Gregory

          ๐Ÿ›
          Genoud Magloire
          Genoud Magloire

          ๐Ÿ›
          Geoffrey555
          Geoffrey555

          ๐Ÿ›
          Georg Romstorfer
          Georg Romstorfer

          ๐Ÿ›
          Gili Tzabari
          Gili Tzabari

          ๐Ÿ› ๐Ÿ’ป
          Gio
          Gio

          ๐Ÿ›
          Gol
          Gol

          ๐Ÿ›
          Gold856
          Gold856

          ๐Ÿ› ๐Ÿ’ป
          Gold856
          Gold856

          ๐Ÿ› ๐Ÿ’ป
          Gonzalo Exequiel Ibars Ingman
          Gonzalo Exequiel Ibars Ingman

          ๐Ÿ’ป ๐Ÿ›
          GooDer
          GooDer

          ๐Ÿ›
          Gregor Riegler
          Gregor Riegler

          ๐Ÿ›
          Grzegorz Olszewski
          Grzegorz Olszewski

          ๐Ÿ›
          Gunther Schrijvers
          Gunther Schrijvers

          ๐Ÿ’ป ๐Ÿ›
          Gustavo Krieger
          Gustavo Krieger

          ๐Ÿ›
          Guy Elsmore-Paddock
          Guy Elsmore-Paddock

          ๐Ÿ›
          Guy Elsmore-Paddock
          Guy Elsmore-Paddock

          ๐Ÿ›
          Gรถrkem Mรผlayim
          Gรถrkem Mรผlayim

          ๐Ÿ›
          Hanzel Godinez
          Hanzel Godinez

          ๐Ÿ›
          Haoliang Chen
          Haoliang Chen

          ๐Ÿ›
          Harsh Kukreja
          Harsh Kukreja

          ๐Ÿ›
          Hassan ALAMI
          Hassan ALAMI

          ๐Ÿ›
          Heber
          Heber

          ๐Ÿ›
          Hector Miuler Malpica Gallegos
          Hector Miuler Malpica Gallegos

          ๐Ÿ›
          Hector Miuler Malpica Gallegos
          Hector Miuler Malpica Gallegos

          ๐Ÿ›
          Henning Schmiedehausen
          Henning Schmiedehausen

          ๐Ÿ’ป ๐Ÿ›
          Henning von Bargen
          Henning von Bargen

          ๐Ÿ’ป
          Hervรฉ Boutemy
          Hervรฉ Boutemy

          ๐Ÿ›
          Himanshu Pandey
          Himanshu Pandey

          ๐Ÿ›
          Hokwang Lee
          Hokwang Lee

          ๐Ÿ›
          Hooperbloob
          Hooperbloob

          ๐Ÿ’ป
          Hung PHAN
          Hung PHAN

          ๐Ÿ›
          Hung PHAN
          Hung PHAN

          ๐Ÿ›
          IDoCodingStuffs
          IDoCodingStuffs

          ๐Ÿ’ป ๐Ÿ›
          Iccen Gan
          Iccen Gan

          ๐Ÿ›
          Ignacio Mariano Tirabasso
          Ignacio Mariano Tirabasso

          ๐Ÿ›
          Igor Melnichenko
          Igor Melnichenko

          ๐Ÿ›
          Igor Moreno
          Igor Moreno

          ๐Ÿ›
          Intelesis-MS
          Intelesis-MS

          ๐Ÿ›
          Iroha_
          Iroha_

          ๐Ÿ›
          Iroha_
          Iroha_

          ๐Ÿ›
          Ishan Srivastava
          Ishan Srivastava

          ๐Ÿ›
          Iskren Stanislavov
          Iskren Stanislavov

          ๐Ÿ›
          Ivan Vakhrushev
          Ivan Vakhrushev

          ๐Ÿ›
          Ivano Guerini
          Ivano Guerini

          ๐Ÿ›
          Ivar Andreas Bonsaksen
          Ivar Andreas Bonsaksen

          ๐Ÿ›
          Ivo ล mรญd
          Ivo ล mรญd

          ๐Ÿ›
          JJengility
          JJengility

          ๐Ÿ›
          JJengility
          JJengility

          ๐Ÿ›
          Jake Hemmerle
          Jake Hemmerle

          ๐Ÿ›
          Jakub Dupak
          Jakub Dupak

          ๐Ÿ’ป
          James Harrison
          James Harrison

          ๐Ÿ› ๐Ÿ’ป
          Jamie Bisotti
          Jamie Bisotti

          ๐Ÿ›
          Jan
          Jan

          ๐Ÿ›
          Jan Aertgeerts
          Jan Aertgeerts

          ๐Ÿ’ป ๐Ÿ›
          Jan Brรผmmer
          Jan Brรผmmer

          ๐Ÿ›
          Jan Brรผmmer
          Jan Brรผmmer

          ๐Ÿ›
          Jan Tล™รญska
          Jan Tล™รญska

          ๐Ÿ›
          Jan-Lukas Else
          Jan-Lukas Else

          ๐Ÿ›
          Jason Qiu
          Jason Qiu

          ๐Ÿ’ป ๐Ÿ“–
          Jason Williams
          Jason Williams

          ๐Ÿ›
          Javier Spagnoletti
          Javier Spagnoletti

          ๐Ÿ›
          Jean-Paul Mayer
          Jean-Paul Mayer

          ๐Ÿ›
          Jean-Simon Larochelle
          Jean-Simon Larochelle

          ๐Ÿ›
          Jean-Simon Larochelle
          Jean-Simon Larochelle

          ๐Ÿ›
          Jeff Bartolotta
          Jeff Bartolotta

          ๐Ÿ’ป ๐Ÿ›
          Jeff Hube
          Jeff Hube

          ๐Ÿ’ป ๐Ÿ›
          Jeff Jensen
          Jeff Jensen

          ๐Ÿ›
          Jeff May
          Jeff May

          ๐Ÿ›
          Jens Gerdes
          Jens Gerdes

          ๐Ÿ›
          Jeroen Borgers
          Jeroen Borgers

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข
          Jeroen Meijer
          Jeroen Meijer

          ๐Ÿ›
          Jeroen Meijer
          Jeroen Meijer

          ๐Ÿ›
          Jeroen van Wilgenburg
          Jeroen van Wilgenburg

          ๐Ÿ“–
          Jerome Russ
          Jerome Russ

          ๐Ÿ›
          JerritEic
          JerritEic

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
          Jiri Pejchal
          Jiri Pejchal

          ๐Ÿ›
          Jithin Sunny
          Jithin Sunny

          ๐Ÿ›
          Jiล™รญ ล korpil
          Jiล™รญ ล korpil

          ๐Ÿ›
          Joao Machado
          Joao Machado

          ๐Ÿ›
          Joao Machado
          Joao Machado

          ๐Ÿ›
          Jochen Krauss
          Jochen Krauss

          ๐Ÿ›
          Johan Hammar
          Johan Hammar

          ๐Ÿ›
          John Jetmore
          John Jetmore

          ๐Ÿ“–
          John Karp
          John Karp

          ๐Ÿ›
          John Zhang
          John Zhang

          ๐Ÿ›
          John-Teng
          John-Teng

          ๐Ÿ’ป ๐Ÿ›
          Jon Moroney
          Jon Moroney

          ๐Ÿ’ป ๐Ÿ›
          Jon Moroney
          Jon Moroney

          ๐Ÿ’ป ๐Ÿ›
          Jonas Geiregat
          Jonas Geiregat

          ๐Ÿ›
          Jonas KeรŸler
          Jonas KeรŸler

          ๐Ÿ›
          Jonathan Wiesel
          Jonathan Wiesel

          ๐Ÿ’ป ๐Ÿ›
          Jordan
          Jordan

          ๐Ÿ›
          Jordi Llach
          Jordi Llach

          ๐Ÿ›
          Jorge Solรณrzano
          Jorge Solรณrzano

          ๐Ÿ›
          JorneVL
          JorneVL

          ๐Ÿ›
          JorneVL
          JorneVL

          ๐Ÿ›
          Jose Palafox
          Jose Palafox

          ๐Ÿ›
          Jose Stovall
          Jose Stovall

          ๐Ÿ›
          Joseph
          Joseph

          ๐Ÿ’ป
          Joseph Heenan
          Joseph Heenan

          ๐Ÿ›
          Josh Feingold
          Josh Feingold

          ๐Ÿ’ป ๐Ÿ›
          Josh Holthaus
          Josh Holthaus

          ๐Ÿ›
          Joshua S Arquilevich
          Joshua S Arquilevich

          ๐Ÿ›
          Joshua S Arquilevich
          Joshua S Arquilevich

          ๐Ÿ›
          Joรฃo Dinis Ferreira
          Joรฃo Dinis Ferreira

          ๐Ÿ“–
          Joรฃo Ferreira
          Joรฃo Ferreira

          ๐Ÿ’ป ๐Ÿ›
          Joรฃo Pedro Schmitt
          Joรฃo Pedro Schmitt

          ๐Ÿ›
          Juan Martรญn Sotuyo Dodero
          Juan Martรญn Sotuyo Dodero

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง
          Juan Pablo Civile
          Juan Pablo Civile

          ๐Ÿ›
          Julian Voronetsky
          Julian Voronetsky

          ๐Ÿ›
          Julien
          Julien

          ๐Ÿ›
          Julien
          Julien

          ๐Ÿ›
          Julius
          Julius

          ๐Ÿ›
          JustPRV
          JustPRV

          ๐Ÿ›
          Justin Stroud
          Justin Stroud

          ๐Ÿ’ป
          Jรถrn Huxhorn
          Jรถrn Huxhorn

          ๐Ÿ›
          KThompso
          KThompso

          ๐Ÿ›
          Kai Amundsen
          Kai Amundsen

          ๐Ÿ›
          Karel Vervaeke
          Karel Vervaeke

          ๐Ÿ›
          Karel Vervaeke
          Karel Vervaeke

          ๐Ÿ›
          Karl-Andero Mere
          Karl-Andero Mere

          ๐Ÿ›
          Karl-Philipp Richter
          Karl-Philipp Richter

          ๐Ÿ›
          Karsten Silz
          Karsten Silz

          ๐Ÿ›
          Kazuma Watanabe
          Kazuma Watanabe

          ๐Ÿ›
          Kev
          Kev

          ๐Ÿ›
          Keve Mรผller
          Keve Mรผller

          ๐Ÿ›
          Kevin Guerra
          Kevin Guerra

          ๐Ÿ’ป
          Kevin Guerra
          Kevin Guerra

          ๐Ÿ’ป
          Kevin Jones
          Kevin Jones

          ๐Ÿ› ๐Ÿ’ป
          Kevin Poorman
          Kevin Poorman

          ๐Ÿ›
          Kevin Wayne
          Kevin Wayne

          ๐Ÿ›
          Kieran Black
          Kieran Black

          ๐Ÿ›
          Kirill Zubov
          Kirill Zubov

          ๐Ÿ›
          Kirk Clemens
          Kirk Clemens

          ๐Ÿ’ป ๐Ÿ›
          Klaus Hartl
          Klaus Hartl

          ๐Ÿ›
          Klaus Hartl
          Klaus Hartl

          ๐Ÿ›
          Koen Van Looveren
          Koen Van Looveren

          ๐Ÿ›
          Kris Scheibe
          Kris Scheibe

          ๐Ÿ’ป ๐Ÿ›
          Krystian Dabrowski
          Krystian Dabrowski

          ๐Ÿ› ๐Ÿ’ป
          Krzysztof Dymek
          Krzysztof Dymek

          ๐Ÿ›
          Kunal Thanki
          Kunal Thanki

          ๐Ÿ›
          Kursat Aktas
          Kursat Aktas

          ๐Ÿ“–
          LaLucid
          LaLucid

          ๐Ÿ’ป
          LaLucid
          LaLucid

          ๐Ÿ’ป
          Larry Diamond
          Larry Diamond

          ๐Ÿ’ป ๐Ÿ›
          Lars Knickrehm
          Lars Knickrehm

          ๐Ÿ›
          Laurent Bovet
          Laurent Bovet

          ๐Ÿ› ๐Ÿ’ป
          Leo Gutierrez
          Leo Gutierrez

          ๐Ÿ›
          LiGaOg
          LiGaOg

          ๐Ÿ’ป
          Liam Sharp
          Liam Sharp

          ๐Ÿ›
          Lintsi
          Lintsi

          ๐Ÿ›
          Lintsi
          Lintsi

          ๐Ÿ›
          Linus Fernandes
          Linus Fernandes

          ๐Ÿ›
          Lixon Lookose
          Lixon Lookose

          ๐Ÿ›
          Logesh
          Logesh

          ๐Ÿ›
          Lorenzo Gabriele
          Lorenzo Gabriele

          ๐Ÿ›
          Loรฏc Ledoyen
          Loรฏc Ledoyen

          ๐Ÿ›
          Lucas
          Lucas

          ๐Ÿ›
          Lucas Silva
          Lucas Silva

          ๐Ÿ›
          Lucas Silva
          Lucas Silva

          ๐Ÿ›
          Lucas Soncini
          Lucas Soncini

          ๐Ÿ’ป ๐Ÿ›
          Luis Alcantar
          Luis Alcantar

          ๐Ÿ’ป
          Lukas Grรคf
          Lukas Grรคf

          ๐Ÿ’ป
          Lukasz Slonina
          Lukasz Slonina

          ๐Ÿ›
          Lukebray
          Lukebray

          ๐Ÿ›
          Lynn
          Lynn

          ๐Ÿ’ป ๐Ÿ›
          Lyor Goldstein
          Lyor Goldstein

          ๐Ÿ›
          Lyor Goldstein
          Lyor Goldstein

          ๐Ÿ›
          MCMicS
          MCMicS

          ๐Ÿ›
          Macarse
          Macarse

          ๐Ÿ›
          Machine account for PMD
          Machine account for PMD

          ๐Ÿ’ป
          Maciek Siemczyk
          Maciek Siemczyk

          ๐Ÿ›
          Maikel Steneker
          Maikel Steneker

          ๐Ÿ’ป ๐Ÿ›
          Maksim Moiseikin
          Maksim Moiseikin

          ๐Ÿ›
          Manfred Koch
          Manfred Koch

          ๐Ÿ›
          Manfred Koch
          Manfred Koch

          ๐Ÿ›
          Manuel Moya Ferrer
          Manuel Moya Ferrer

          ๐Ÿ’ป ๐Ÿ›
          Manuel Romeiro
          Manuel Romeiro

          ๐Ÿ›
          Manuel Ryan
          Manuel Ryan

          ๐Ÿ›
          Marat Vyshegorodtsev
          Marat Vyshegorodtsev

          ๐Ÿ›
          Marcel Hรคrle
          Marcel Hรคrle

          ๐Ÿ›
          Marcello Fialho
          Marcello Fialho

          ๐Ÿ›
          Marcin Dฤ…browski
          Marcin Dฤ…browski

          ๐Ÿ’ป ๐Ÿ›
          Marcin Dฤ…browski
          Marcin Dฤ…browski

          ๐Ÿ’ป ๐Ÿ›
          Marcin Rataj
          Marcin Rataj

          ๐Ÿ›
          Marcono1234
          Marcono1234

          ๐Ÿ›
          Mark Adamcin
          Mark Adamcin

          ๐Ÿ›
          Mark Hall
          Mark Hall

          ๐Ÿ’ป ๐Ÿ›
          Mark Kolich
          Mark Kolich

          ๐Ÿ›
          Mark Pritchard
          Mark Pritchard

          ๐Ÿ›
          Markus Rathgeb
          Markus Rathgeb

          ๐Ÿ›
          Markus Rathgeb
          Markus Rathgeb

          ๐Ÿ›
          Marquis Wang
          Marquis Wang

          ๐Ÿ›
          MartGit
          MartGit

          ๐Ÿ›
          Martin Feldsztejn
          Martin Feldsztejn

          ๐Ÿ›
          Martin Lehmann
          Martin Lehmann

          ๐Ÿ›
          Martin Spamer
          Martin Spamer

          ๐Ÿ›
          Martin Tarjรกnyi
          Martin Tarjรกnyi

          ๐Ÿ›
          MatFl
          MatFl

          ๐Ÿ›
          MatFl
          MatFl

          ๐Ÿ›
          Mateusz Stefanski
          Mateusz Stefanski

          ๐Ÿ›
          Mathias Lagerwall
          Mathias Lagerwall

          ๐Ÿ›
          Mathieu Gouin
          Mathieu Gouin

          ๐Ÿ›
          MatiasComercio
          MatiasComercio

          ๐Ÿ’ป ๐Ÿ›
          Matt Benson
          Matt Benson

          ๐Ÿ›
          Matt De Poorter
          Matt De Poorter

          ๐Ÿ›
          Matt Hargett
          Matt Hargett

          ๐Ÿ’ป ๐Ÿ’ต
          Matt Hargett
          Matt Hargett

          ๐Ÿ’ป ๐Ÿ’ต
          Matt Harrah
          Matt Harrah

          ๐Ÿ›
          Matt Nelson
          Matt Nelson

          ๐Ÿ›
          Matthew Amos
          Matthew Amos

          ๐Ÿ›
          Matthew Duggan
          Matthew Duggan

          ๐Ÿ›
          Matthew Hall
          Matthew Hall

          ๐Ÿ›
          Matthew Rossner
          Matthew Rossner

          ๐Ÿ›
          Matรญas Fraga
          Matรญas Fraga

          ๐Ÿ’ป ๐Ÿ›
          Matรญas Fraga
          Matรญas Fraga

          ๐Ÿ’ป ๐Ÿ›
          Maxime Robert
          Maxime Robert

          ๐Ÿ’ป ๐Ÿ›
          MetaBF
          MetaBF

          ๐Ÿ›
          Metin Dagcilar
          Metin Dagcilar

          ๐Ÿ›
          Michael
          Michael

          ๐Ÿ›
          Michael Bell
          Michael Bell

          ๐Ÿ›
          Michael Bernstein
          Michael Bernstein

          ๐Ÿ›
          Michael Clay
          Michael Clay

          ๐Ÿ›
          Michael Clay
          Michael Clay

          ๐Ÿ›
          Michael Dombrowski
          Michael Dombrowski

          ๐Ÿ›
          Michael Hausegger
          Michael Hausegger

          ๐Ÿ›
          Michael Hoefer
          Michael Hoefer

          ๐Ÿ›
          Michael Kolesnikov
          Michael Kolesnikov

          ๐Ÿ›
          Michael Mรถbius
          Michael Mรถbius

          ๐Ÿ›
          Michael N. Lipp
          Michael N. Lipp

          ๐Ÿ›
          Michael Pellegrini
          Michael Pellegrini

          ๐Ÿ›
          Michael Pellegrini
          Michael Pellegrini

          ๐Ÿ›
          Michal Kordas
          Michal Kordas

          ๐Ÿ›
          Michaล‚ Borek
          Michaล‚ Borek

          ๐Ÿ›
          Michaล‚ Kuliล„ski
          Michaล‚ Kuliล„ski

          ๐Ÿ›
          Miguel Nรบรฑez Dรญaz-Montes
          Miguel Nรบรฑez Dรญaz-Montes

          ๐Ÿ›
          Mihai Ionut
          Mihai Ionut

          ๐Ÿ›
          Mikhail Kuchma
          Mikhail Kuchma

          ๐Ÿ›
          MiladSadinam
          MiladSadinam

          ๐Ÿ›
          MiladSadinam
          MiladSadinam

          ๐Ÿ›
          Mirek Hankus
          Mirek Hankus

          ๐Ÿ›
          Mitch Spano
          Mitch Spano

          ๐Ÿ’ป ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          MrAngry52
          MrAngry52

          ๐Ÿ›
          Muminur Choudhury
          Muminur Choudhury

          ๐Ÿ›
          Mykhailo Palahuta
          Mykhailo Palahuta

          ๐Ÿ’ป ๐Ÿ›
          Mykhailo Palahuta
          Mykhailo Palahuta

          ๐Ÿ’ป ๐Ÿ›
          Nagendra Kumar Singh
          Nagendra Kumar Singh

          ๐Ÿ›
          Nahuel Barrios
          Nahuel Barrios

          ๐Ÿ›
          Nakul Sharma
          Nakul Sharma

          ๐Ÿ›
          Nathan Braun
          Nathan Braun

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathanaรซl
          Nathanaรซl

          ๐Ÿ›
          Nathanaรซl
          Nathanaรซl

          ๐Ÿ›
          Naveen
          Naveen

          ๐Ÿ’ป
          Nazdravi
          Nazdravi

          ๐Ÿ›
          Neha-Dhonde
          Neha-Dhonde

          ๐Ÿ›
          Nicholas Doyle
          Nicholas Doyle

          ๐Ÿ›
          Nick Butcher
          Nick Butcher

          ๐Ÿ›
          Nico Gallinal
          Nico Gallinal

          ๐Ÿ›
          Nicola Dal Maso
          Nicola Dal Maso

          ๐Ÿ›
          Nicola Dal Maso
          Nicola Dal Maso

          ๐Ÿ›
          Nicolas Filotto
          Nicolas Filotto

          ๐Ÿ’ป
          Nicolas Vervelle
          Nicolas Vervelle

          ๐Ÿ›
          Nicolas Vuillamy
          Nicolas Vuillamy

          ๐Ÿ“–
          Nikita Chursin
          Nikita Chursin

          ๐Ÿ›
          Niklas Baudy
          Niklas Baudy

          ๐Ÿ›
          Nikolas Havrikov
          Nikolas Havrikov

          ๐Ÿ›
          Nilesh Virkar
          Nilesh Virkar

          ๐Ÿ›
          Nilesh Virkar
          Nilesh Virkar

          ๐Ÿ›
          Nimit Patel
          Nimit Patel

          ๐Ÿ›
          Niranjan Harpale
          Niranjan Harpale

          ๐Ÿ›
          Nirvik Patel
          Nirvik Patel

          ๐Ÿ’ป
          Noah Sussman
          Noah Sussman

          ๐Ÿ›
          Noah0120
          Noah0120

          ๐Ÿ›
          Noam Tamim
          Noam Tamim

          ๐Ÿ›
          Noel Grandin
          Noel Grandin

          ๐Ÿ›
          Noel Grandin
          Noel Grandin

          ๐Ÿ›
          Olaf Haalstra
          Olaf Haalstra

          ๐Ÿ›
          Oleg Andreych
          Oleg Andreych

          ๐Ÿ’ป ๐Ÿ›
          Oleg Pavlenko
          Oleg Pavlenko

          ๐Ÿ›
          Oleksii Dykov
          Oleksii Dykov

          ๐Ÿ’ป ๐Ÿ›
          Oliver Eikemeier
          Oliver Eikemeier

          ๐Ÿ›
          Oliver Siegmar
          Oliver Siegmar

          ๐Ÿ’ต
          Olivier Parent
          Olivier Parent

          ๐Ÿ’ป ๐Ÿ›
          Olivier Parent
          Olivier Parent

          ๐Ÿ’ป ๐Ÿ›
          Ollie Abbey
          Ollie Abbey

          ๐Ÿ’ป ๐Ÿ›
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)

          ๐Ÿ›
          Ondrej Kratochvil
          Ondrej Kratochvil

          ๐Ÿ›
          OverDrone
          OverDrone

          ๐Ÿ›
          Ozan Gulle
          Ozan Gulle

          ๐Ÿ’ป ๐Ÿ›
          PUNEET JAIN
          PUNEET JAIN

          ๐Ÿ›
          Parbati Bose
          Parbati Bose

          ๐Ÿ›
          Parbati Bose
          Parbati Bose

          ๐Ÿ›
          Paul Berg
          Paul Berg

          ๐Ÿ›
          Paul Guyot
          Paul Guyot

          ๐Ÿ’ป
          Pavel Bludov
          Pavel Bludov

          ๐Ÿ›
          Pavel Miฤka
          Pavel Miฤka

          ๐Ÿ›
          Pedro Nuno Santos
          Pedro Nuno Santos

          ๐Ÿ›
          Pedro Rijo
          Pedro Rijo

          ๐Ÿ›
          Pelisse Romain
          Pelisse Romain

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
          Pelisse Romain
          Pelisse Romain

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
          Per Abich
          Per Abich

          ๐Ÿ’ป
          Pete Davids
          Pete Davids

          ๐Ÿ›
          Peter Bruin
          Peter Bruin

          ๐Ÿ›
          Peter Chittum
          Peter Chittum

          ๐Ÿ’ป ๐Ÿ›
          Peter Cudmore
          Peter Cudmore

          ๐Ÿ›
          Peter Kasson
          Peter Kasson

          ๐Ÿ›
          Peter Kofler
          Peter Kofler

          ๐Ÿ›
          Peter Kofler
          Peter Kofler

          ๐Ÿ›
          Peter Paul Bakker
          Peter Paul Bakker

          ๐Ÿ’ป ๐Ÿ›
          Peter Rader
          Peter Rader

          ๐Ÿ›
          Pham Hai Trung
          Pham Hai Trung

          ๐Ÿ›
          Philip Graf
          Philip Graf

          ๐Ÿ’ป ๐Ÿ›
          Philip Hachey
          Philip Hachey

          ๐Ÿ›
          Philippe Ozil
          Philippe Ozil

          ๐Ÿ›
          Phinehas Artemix
          Phinehas Artemix

          ๐Ÿ›
          Phinehas Artemix
          Phinehas Artemix

          ๐Ÿ›
          Phokham Nonava
          Phokham Nonava

          ๐Ÿ›
          Pim van der Loos
          Pim van der Loos

          ๐Ÿ’ป โš ๏ธ
          Piotr Szymaล„ski
          Piotr Szymaล„ski

          ๐Ÿ›
          Piotrek ลปygieล‚o
          Piotrek ลปygieล‚o

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“–
          Pranay Jaiswal
          Pranay Jaiswal

          ๐Ÿ›
          Prasad Kamath
          Prasad Kamath

          ๐Ÿ›
          Prasanna
          Prasanna

          ๐Ÿ›
          Prasanna
          Prasanna

          ๐Ÿ›
          Presh-AR
          Presh-AR

          ๐Ÿ›
          Puneet1726
          Puneet1726

          ๐Ÿ›
          RBRi
          RBRi

          ๐Ÿ›
          Rafael Cortรชs
          Rafael Cortรชs

          ๐Ÿ›
          RaheemShaik999
          RaheemShaik999

          ๐Ÿ›
          RajeshR
          RajeshR

          ๐Ÿ’ป ๐Ÿ›
          Ramachandra Mohan
          Ramachandra Mohan

          ๐Ÿ›
          Ramachandra Mohan
          Ramachandra Mohan

          ๐Ÿ›
          Ramel0921
          Ramel0921

          ๐Ÿ›
          Raquel Pau
          Raquel Pau

          ๐Ÿ›
          Ravikiran Janardhana
          Ravikiran Janardhana

          ๐Ÿ›
          Reda Benhemmouche
          Reda Benhemmouche

          ๐Ÿ›
          Reinhard Schiedermeier
          Reinhard Schiedermeier

          ๐Ÿ›
          Renato Oliveira
          Renato Oliveira

          ๐Ÿ’ป ๐Ÿ›
          Rich DiCroce
          Rich DiCroce

          ๐Ÿ›
          Rich DiCroce
          Rich DiCroce

          ๐Ÿ›
          Richard Corfield
          Richard Corfield

          ๐Ÿ’ป
          Richard Corfield
          Richard Corfield

          ๐Ÿ› ๐Ÿ’ป
          Riot R1cket
          Riot R1cket

          ๐Ÿ›
          Rishabh Jain
          Rishabh Jain

          ๐Ÿ›
          RishabhDeep Singh
          RishabhDeep Singh

          ๐Ÿ›
          Rob Baillie
          Rob Baillie

          ๐Ÿ›
          Robbie Martinus
          Robbie Martinus

          ๐Ÿ’ป ๐Ÿ›
          Robbie Martinus
          Robbie Martinus

          ๐Ÿ’ป ๐Ÿ›
          Robert Henry
          Robert Henry

          ๐Ÿ›
          Robert Mihaly
          Robert Mihaly

          ๐Ÿ›
          Robert Painsi
          Robert Painsi

          ๐Ÿ›
          Robert Russell
          Robert Russell

          ๐Ÿ›
          Robert Sรถsemann
          Robert Sรถsemann

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ›
          Robert Whitebit
          Robert Whitebit

          ๐Ÿ›
          Robin Richtsfeld
          Robin Richtsfeld

          ๐Ÿ›
          Robin Richtsfeld
          Robin Richtsfeld

          ๐Ÿ›
          Robin Stocker
          Robin Stocker

          ๐Ÿ’ป ๐Ÿ›
          Robin Wils
          Robin Wils

          ๐Ÿ›
          RochusOest
          RochusOest

          ๐Ÿ›
          Rodolfo Noviski
          Rodolfo Noviski

          ๐Ÿ›
          Rodrigo Casara
          Rodrigo Casara

          ๐Ÿ›
          Rodrigo Fernandes
          Rodrigo Fernandes

          ๐Ÿ›
          Roman Salvador
          Roman Salvador

          ๐Ÿ’ป ๐Ÿ›
          Roman Salvador
          Roman Salvador

          ๐Ÿ’ป ๐Ÿ›
          Ronald Blaschke
          Ronald Blaschke

          ๐Ÿ›
          Rรณbert Papp
          Rรณbert Papp

          ๐Ÿ›
          Saikat Sengupta
          Saikat Sengupta

          ๐Ÿ›
          Saksham Handu
          Saksham Handu

          ๐Ÿ›
          Saladoc
          Saladoc

          ๐Ÿ›
          Salesforce Bob Lightning
          Salesforce Bob Lightning

          ๐Ÿ›
          Sam Carlberg
          Sam Carlberg

          ๐Ÿ›
          Sam Carlberg
          Sam Carlberg

          ๐Ÿ›
          Sascha Riemer
          Sascha Riemer

          ๐Ÿ›
          Sashko
          Sashko

          ๐Ÿ’ป
          Satoshi Kubo
          Satoshi Kubo

          ๐Ÿ›
          Scott Kennedy
          Scott Kennedy

          ๐Ÿ›
          Scott Wells
          Scott Wells

          ๐Ÿ› ๐Ÿ’ป
          Scrates1
          Scrates1

          ๐Ÿ› ๐Ÿ’ป
          Scrsloota
          Scrsloota

          ๐Ÿ’ป
          Scrsloota
          Scrsloota

          ๐Ÿ’ป
          Sebastian Bรถgl
          Sebastian Bรถgl

          ๐Ÿ›
          Sebastian Davids
          Sebastian Davids

          ๐Ÿ›
          Sebastian Lรถvdahl
          Sebastian Lรถvdahl

          ๐Ÿ›
          Sebastian Schuberth
          Sebastian Schuberth

          ๐Ÿ›
          Sebastian Schwarz
          Sebastian Schwarz

          ๐Ÿ›
          Seren
          Seren

          ๐Ÿ› ๐Ÿ’ป
          Sergey Gorbaty
          Sergey Gorbaty

          ๐Ÿ›
          Sergey Gorbaty
          Sergey Gorbaty

          ๐Ÿ›
          Sergey Kozlov
          Sergey Kozlov

          ๐Ÿ›
          Sergey Yanzin
          Sergey Yanzin

          ๐Ÿ’ป ๐Ÿ›
          Seth Wilcox
          Seth Wilcox

          ๐Ÿ’ป
          Shai Bennathan
          Shai Bennathan

          ๐Ÿ› ๐Ÿ’ป
          Shubham
          Shubham

          ๐Ÿ’ป ๐Ÿ›
          Simon Abykov
          Simon Abykov

          ๐Ÿ’ป ๐Ÿ›
          Simon Xiao
          Simon Xiao

          ๐Ÿ›
          Simon Xiao
          Simon Xiao

          ๐Ÿ›
          Srinivasan Venkatachalam
          Srinivasan Venkatachalam

          ๐Ÿ›
          Stanislav Gromov
          Stanislav Gromov

          ๐Ÿ›
          Stanislav Myachenkov
          Stanislav Myachenkov

          ๐Ÿ’ป
          Stefan Birkner
          Stefan Birkner

          ๐Ÿ›
          Stefan Bohn
          Stefan Bohn

          ๐Ÿ›
          Stefan Endrullis
          Stefan Endrullis

          ๐Ÿ›
          Stefan Klรถss-Schuster
          Stefan Klรถss-Schuster

          ๐Ÿ›
          Stefan Klรถss-Schuster
          Stefan Klรถss-Schuster

          ๐Ÿ›
          Stefan Wolf
          Stefan Wolf

          ๐Ÿ›
          Stephan H. Wissel
          Stephan H. Wissel

          ๐Ÿ›
          Stephen
          Stephen

          ๐Ÿ›
          Stephen Carter
          Stephen Carter

          ๐Ÿ›
          Stephen Friedrich
          Stephen Friedrich

          ๐Ÿ›
          Steve Babula
          Steve Babula

          ๐Ÿ’ป
          Steven Stearns
          Steven Stearns

          ๐Ÿ› ๐Ÿ’ป
          Steven Stearns
          Steven Stearns

          ๐Ÿ› ๐Ÿ’ป
          Stexxe
          Stexxe

          ๐Ÿ›
          Stian Lรฅgstad
          Stian Lรฅgstad

          ๐Ÿ›
          StuartClayton5
          StuartClayton5

          ๐Ÿ›
          Supun Arunoda
          Supun Arunoda

          ๐Ÿ›
          Suren Abrahamyan
          Suren Abrahamyan

          ๐Ÿ›
          Suvashri
          Suvashri

          ๐Ÿ“–
          Sven Barden
          Sven Barden

          ๐Ÿ›
          Sven Barden
          Sven Barden

          ๐Ÿ›
          SwatiBGupta1110
          SwatiBGupta1110

          ๐Ÿ›
          SyedThoufich
          SyedThoufich

          ๐Ÿ›
          Szymon Sasin
          Szymon Sasin

          ๐Ÿ›
          T-chuangxin
          T-chuangxin

          ๐Ÿ›
          TERAI Atsuhiro
          TERAI Atsuhiro

          ๐Ÿ›
          TIOBE Software
          TIOBE Software

          ๐Ÿ’ป ๐Ÿ›
          Tarush Singh
          Tarush Singh

          ๐Ÿ’ป
          Tarush Singh
          Tarush Singh

          ๐Ÿ’ป
          Taylor Smock
          Taylor Smock

          ๐Ÿ›
          Techeira Damiรกn
          Techeira Damiรกn

          ๐Ÿ’ป ๐Ÿ›
          Ted Husted
          Ted Husted

          ๐Ÿ›
          TehBakker
          TehBakker

          ๐Ÿ›
          The Gitter Badger
          The Gitter Badger

          ๐Ÿ›
          Theodoor
          Theodoor

          ๐Ÿ›
          Thiago Henrique Hรผpner
          Thiago Henrique Hรผpner

          ๐Ÿ›
          Thiago Henrique Hรผpner
          Thiago Henrique Hรผpner

          ๐Ÿ›
          Thibault Meyer
          Thibault Meyer

          ๐Ÿ›
          Thomas Gรผttler
          Thomas Gรผttler

          ๐Ÿ›
          Thomas Jones-Low
          Thomas Jones-Low

          ๐Ÿ›
          Thomas Smith
          Thomas Smith

          ๐Ÿ’ป ๐Ÿ›
          ThrawnCA
          ThrawnCA

          ๐Ÿ›
          Thu Vo
          Thu Vo

          ๐Ÿ›
          Thunderforge
          Thunderforge

          ๐Ÿ’ป ๐Ÿ›
          Thunderforge
          Thunderforge

          ๐Ÿ’ป ๐Ÿ›
          Tim van der Lippe
          Tim van der Lippe

          ๐Ÿ›
          Tobias Weimer
          Tobias Weimer

          ๐Ÿ’ป ๐Ÿ›
          Tom Copeland
          Tom Copeland

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–
          Tom Daly
          Tom Daly

          ๐Ÿ›
          Tomas
          Tomas

          ๐Ÿ›
          Tomer Figenblat
          Tomer Figenblat

          ๐Ÿ›
          Tomi De Lucca
          Tomi De Lucca

          ๐Ÿ’ป ๐Ÿ›
          Tomi De Lucca
          Tomi De Lucca

          ๐Ÿ’ป ๐Ÿ›
          Tony
          Tony

          ๐Ÿ“–
          Torsten Kleiber
          Torsten Kleiber

          ๐Ÿ›
          Torsten Krause
          Torsten Krause

          ๐Ÿ›
          TrackerSB
          TrackerSB

          ๐Ÿ›
          Tyson Stewart
          Tyson Stewart

          ๐Ÿ›
          Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ›
          Utku Cuhadaroglu
          Utku Cuhadaroglu

          ๐Ÿ’ป ๐Ÿ›
          Utku Cuhadaroglu
          Utku Cuhadaroglu

          ๐Ÿ’ป ๐Ÿ›
          Valentin Brandl
          Valentin Brandl

          ๐Ÿ›
          Valeria
          Valeria

          ๐Ÿ›
          Valery Yatsynovich
          Valery Yatsynovich

          ๐Ÿ“–
          Vasily Anisimov
          Vasily Anisimov

          ๐Ÿ›
          Vedant Chokshi
          Vedant Chokshi

          ๐Ÿ›
          Vibhor Goyal
          Vibhor Goyal

          ๐Ÿ›
          Vickenty Fesunov
          Vickenty Fesunov

          ๐Ÿ›
          Vickenty Fesunov
          Vickenty Fesunov

          ๐Ÿ›
          Victor Noรซl
          Victor Noรซl

          ๐Ÿ›
          Vincent Galloy
          Vincent Galloy

          ๐Ÿ’ป
          Vincent HUYNH
          Vincent HUYNH

          ๐Ÿ›
          Vincent Maurin
          Vincent Maurin

          ๐Ÿ›
          Vincent Potucek
          Vincent Potucek

          ๐Ÿ’ป
          Vincent Privat
          Vincent Privat

          ๐Ÿ›
          Vishhwas
          Vishhwas

          ๐Ÿ›
          Vishhwas
          Vishhwas

          ๐Ÿ›
          Vishv_Android
          Vishv_Android

          ๐Ÿ›
          Vitalii Yevtushenko
          Vitalii Yevtushenko

          ๐Ÿ›
          Vitaly
          Vitaly

          ๐Ÿ›
          Vitaly Polonetsky
          Vitaly Polonetsky

          ๐Ÿ›
          Vojtech Polivka
          Vojtech Polivka

          ๐Ÿ›
          Vsevolod Zholobov
          Vsevolod Zholobov

          ๐Ÿ›
          Vyom Yadav
          Vyom Yadav

          ๐Ÿ’ป
          Vyom Yadav
          Vyom Yadav

          ๐Ÿ’ป
          Wang Shidong
          Wang Shidong

          ๐Ÿ›
          Waqas Ahmed
          Waqas Ahmed

          ๐Ÿ›
          Wayne J. Earl
          Wayne J. Earl

          ๐Ÿ›
          Wchenghui
          Wchenghui

          ๐Ÿ›
          Wener
          Wener

          ๐Ÿ’ป
          Will Winder
          Will Winder

          ๐Ÿ›
          Willem A. Hajenius
          Willem A. Hajenius

          ๐Ÿ’ป
          Willem A. Hajenius
          Willem A. Hajenius

          ๐Ÿ’ป
          William Brockhus
          William Brockhus

          ๐Ÿ’ป ๐Ÿ›
          Wilson Kurniawan
          Wilson Kurniawan

          ๐Ÿ›
          Wim Deblauwe
          Wim Deblauwe

          ๐Ÿ›
          Wolf2323
          Wolf2323

          ๐Ÿ›
          Woongsik Choi
          Woongsik Choi

          ๐Ÿ›
          XenoAmess
          XenoAmess

          ๐Ÿ’ป ๐Ÿ›
          Yang
          Yang

          ๐Ÿ’ป
          Yang
          Yang

          ๐Ÿ’ป
          YaroslavTER
          YaroslavTER

          ๐Ÿ›
          Yasar Shaikh
          Yasar Shaikh

          ๐Ÿ’ป
          Young Chan
          Young Chan

          ๐Ÿ’ป ๐Ÿ›
          YuJin Kim
          YuJin Kim

          ๐Ÿ›
          Yuri Dolzhenko
          Yuri Dolzhenko

          ๐Ÿ›
          Yurii Dubinka
          Yurii Dubinka

          ๐Ÿ›
          Zoltan Farkas
          Zoltan Farkas

          ๐Ÿ›
          Zoltan Farkas
          Zoltan Farkas

          ๐Ÿ›
          Zustin
          Zustin

          ๐Ÿ›
          aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป
          alexmodis
          alexmodis

          ๐Ÿ›
          andreoss
          andreoss

          ๐Ÿ›
          andrey81inmd
          andrey81inmd

          ๐Ÿ’ป ๐Ÿ›
          anicoara
          anicoara

          ๐Ÿ›
          arunprasathav
          arunprasathav

          ๐Ÿ›
          arunprasathav
          arunprasathav

          ๐Ÿ›
          asiercamara
          asiercamara

          ๐Ÿ›
          astillich-igniti
          astillich-igniti

          ๐Ÿ’ป
          avesolovksyy
          avesolovksyy

          ๐Ÿ›
          avishvat
          avishvat

          ๐Ÿ›
          avivmu
          avivmu

          ๐Ÿ›
          axelbarfod1
          axelbarfod1

          ๐Ÿ›
          b-3-n
          b-3-n

          ๐Ÿ›
          b-3-n
          b-3-n

          ๐Ÿ›
          balbhadra9
          balbhadra9

          ๐Ÿ›
          base23de
          base23de

          ๐Ÿ›
          bergander
          bergander

          ๐Ÿ› ๐Ÿ’ป
          berkam
          berkam

          ๐Ÿ’ป ๐Ÿ›
          breizh31
          breizh31

          ๐Ÿ›
          caesarkim
          caesarkim

          ๐Ÿ›
          caiocarvalhotero
          caiocarvalhotero

          ๐Ÿ›
          caiocarvalhotero
          caiocarvalhotero

          ๐Ÿ›
          carolyujing
          carolyujing

          ๐Ÿ›
          cbfiddle
          cbfiddle

          ๐Ÿ›
          cesares-basilico
          cesares-basilico

          ๐Ÿ›
          chrite
          chrite

          ๐Ÿ›
          ciufudean
          ciufudean

          ๐Ÿ“–
          cobratbq
          cobratbq

          ๐Ÿ›
          coladict
          coladict

          ๐Ÿ›
          coladict
          coladict

          ๐Ÿ›
          cosmoJFH
          cosmoJFH

          ๐Ÿ›
          cristalp
          cristalp

          ๐Ÿ›
          crunsk
          crunsk

          ๐Ÿ›
          cwholmes
          cwholmes

          ๐Ÿ›
          cyberjj999
          cyberjj999

          ๐Ÿ›
          cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“–
          d1ss0nanz
          d1ss0nanz

          ๐Ÿ›
          d1ss0nanz
          d1ss0nanz

          ๐Ÿ›
          dague1
          dague1

          ๐Ÿ“–
          dalizi007
          dalizi007

          ๐Ÿ’ป
          danbrycefairsailcom
          danbrycefairsailcom

          ๐Ÿ›
          dariansanity
          dariansanity

          ๐Ÿ›
          darrenmiliband
          darrenmiliband

          ๐Ÿ›
          davidburstrom
          davidburstrom

          ๐Ÿ›
          dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ›
          dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ›
          deepak-patra
          deepak-patra

          ๐Ÿ›
          dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ›
          dinesh150
          dinesh150

          ๐Ÿ›
          diziaq
          diziaq

          ๐Ÿ›
          dreaminpast123
          dreaminpast123

          ๐Ÿ›
          duanyanan
          duanyanan

          ๐Ÿ›
          dutt-sanjay
          dutt-sanjay

          ๐Ÿ›
          dutt-sanjay
          dutt-sanjay

          ๐Ÿ›
          duursma
          duursma

          ๐Ÿ’ป
          dylanleung
          dylanleung

          ๐Ÿ›
          dzeigler
          dzeigler

          ๐Ÿ›
          eant60
          eant60

          ๐Ÿ›
          ekkirala
          ekkirala

          ๐Ÿ›
          emersonmoura
          emersonmoura

          ๐Ÿ›
          emouty
          emouty

          ๐Ÿ’ป ๐Ÿ›
          emouty
          emouty

          ๐Ÿ’ป ๐Ÿ›
          eugenepugach
          eugenepugach

          ๐Ÿ›
          fairy
          fairy

          ๐Ÿ›
          filiprafalowicz
          filiprafalowicz

          ๐Ÿ’ป
          flxbl-io
          flxbl-io

          ๐Ÿ’ต
          foxmason
          foxmason

          ๐Ÿ›
          frankegabor
          frankegabor

          ๐Ÿ›
          frankl
          frankl

          ๐Ÿ›
          frankl
          frankl

          ๐Ÿ›
          freafrea
          freafrea

          ๐Ÿ›
          fsapatin
          fsapatin

          ๐Ÿ›
          gearsethenry
          gearsethenry

          ๐Ÿ›
          gracia19
          gracia19

          ๐Ÿ›
          gudzpoz
          gudzpoz

          ๐Ÿ›
          guo fei
          guo fei

          ๐Ÿ›
          gurmsc5
          gurmsc5

          ๐Ÿ›
          gurmsc5
          gurmsc5

          ๐Ÿ›
          gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ›
          haigsn
          haigsn

          ๐Ÿ›
          hemanshu070
          hemanshu070

          ๐Ÿ›
          henrik242
          henrik242

          ๐Ÿ›
          hongpuwu
          hongpuwu

          ๐Ÿ›
          hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ›
          igniti GmbH
          igniti GmbH

          ๐Ÿ›
          igniti GmbH
          igniti GmbH

          ๐Ÿ›
          ilovezfs
          ilovezfs

          ๐Ÿ›
          imax-erik
          imax-erik

          ๐Ÿ›
          itaigilo
          itaigilo

          ๐Ÿ›
          jakivey32
          jakivey32

          ๐Ÿ›
          jbennett2091
          jbennett2091

          ๐Ÿ›
          jcamerin
          jcamerin

          ๐Ÿ›
          jkeener1
          jkeener1

          ๐Ÿ›
          jkeener1
          jkeener1

          ๐Ÿ›
          jmetertea
          jmetertea

          ๐Ÿ›
          johnra2
          johnra2

          ๐Ÿ’ป
          johnzhao9
          johnzhao9

          ๐Ÿ›
          josemanuelrolon
          josemanuelrolon

          ๐Ÿ’ป ๐Ÿ›
          julees7
          julees7

          ๐Ÿ’ป ๐Ÿ›
          kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ›
          karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“–
          karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“–
          karwer
          karwer

          ๐Ÿ›
          kaulonline
          kaulonline

          ๐Ÿ›
          kdaemonv
          kdaemonv

          ๐Ÿ›
          kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป
          kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ›
          kfranic
          kfranic

          ๐Ÿ›
          khalidkh
          khalidkh

          ๐Ÿ›
          khalidkh
          khalidkh

          ๐Ÿ›
          koalalam
          koalalam

          ๐Ÿ›
          krzyk
          krzyk

          ๐Ÿ›
          lasselindqvist
          lasselindqvist

          ๐Ÿ›
          lgemeinhardt
          lgemeinhardt

          ๐Ÿ›
          lihuaib
          lihuaib

          ๐Ÿ›
          liqingjun123
          liqingjun123

          ๐Ÿ›
          lonelyma1021
          lonelyma1021

          ๐Ÿ›
          lonelyma1021
          lonelyma1021

          ๐Ÿ›
          lothas
          lothas

          ๐Ÿ›
          lpeddy
          lpeddy

          ๐Ÿ›
          lujiefsi
          lujiefsi

          ๐Ÿ’ป
          lukelukes
          lukelukes

          ๐Ÿ’ป
          lyriccoder
          lyriccoder

          ๐Ÿ›
          marcelmore
          marcelmore

          ๐Ÿ›
          matchbox
          matchbox

          ๐Ÿ›
          matchbox
          matchbox

          ๐Ÿ›
          matthiaskraaz
          matthiaskraaz

          ๐Ÿ›
          meandonlyme
          meandonlyme

          ๐Ÿ›
          mikesive
          mikesive

          ๐Ÿ›
          milossesic
          milossesic

          ๐Ÿ›
          mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ›
          mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป
          mriddell95
          mriddell95

          ๐Ÿ›
          mriddell95
          mriddell95

          ๐Ÿ›
          mrlzh
          mrlzh

          ๐Ÿ›
          msloan
          msloan

          ๐Ÿ›
          mucharlaravalika
          mucharlaravalika

          ๐Ÿ›
          mvenneman
          mvenneman

          ๐Ÿ›
          nareshl119
          nareshl119

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          noerremark
          noerremark

          ๐Ÿ›
          noerremark
          noerremark

          ๐Ÿ›
          novsirion
          novsirion

          ๐Ÿ›
          nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป
          oggboy
          oggboy

          ๐Ÿ›
          oinume
          oinume

          ๐Ÿ›
          orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pacvz
          pacvz

          ๐Ÿ’ป
          pacvz
          pacvz

          ๐Ÿ’ป
          pallavi agarwal
          pallavi agarwal

          ๐Ÿ›
          pankratz76
          pankratz76

          ๐Ÿ›
          parksungrin
          parksungrin

          ๐Ÿ›
          patpatpat123
          patpatpat123

          ๐Ÿ›
          patriksevallius
          patriksevallius

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          phoenix384
          phoenix384

          ๐Ÿ›
          phoenix384
          phoenix384

          ๐Ÿ›
          piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป
          plan3d
          plan3d

          ๐Ÿ›
          poojasix
          poojasix

          ๐Ÿ›
          prabhushrikant
          prabhushrikant

          ๐Ÿ›
          pujitha8783
          pujitha8783

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          raghujayjunk
          raghujayjunk

          ๐Ÿ›
          raghujayjunk
          raghujayjunk

          ๐Ÿ›
          rajeshveera
          rajeshveera

          ๐Ÿ›
          rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ›
          recdevs
          recdevs

          ๐Ÿ›
          reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ›
          rijkt
          rijkt

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ›
          rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ›
          rnveach
          rnveach

          ๐Ÿ›
          rxmicro
          rxmicro

          ๐Ÿ›
          ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ›
          sabi0
          sabi0

          ๐Ÿ›
          samc-gearset
          samc-gearset

          ๐Ÿ“–
          scais
          scais

          ๐Ÿ›
          schosin
          schosin

          ๐Ÿ›
          schosin
          schosin

          ๐Ÿ›
          screamingfrog
          screamingfrog

          ๐Ÿ’ต
          sebbASF
          sebbASF

          ๐Ÿ›
          sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป
          shilko2013
          shilko2013

          ๐Ÿ›
          shiomiyan
          shiomiyan

          ๐Ÿ“–
          simeonKondr
          simeonKondr

          ๐Ÿ›
          snajberk
          snajberk

          ๐Ÿ›
          snajberk
          snajberk

          ๐Ÿ›
          sniperrifle2004
          sniperrifle2004

          ๐Ÿ›
          snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป
          soloturn
          soloturn

          ๐Ÿ›
          soyodream
          soyodream

          ๐Ÿ›
          sratz
          sratz

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          sturton
          sturton

          ๐Ÿ’ป ๐Ÿ›
          sturton
          sturton

          ๐Ÿ’ป ๐Ÿ›
          sudharmohan
          sudharmohan

          ๐Ÿ›
          suruchidawar
          suruchidawar

          ๐Ÿ›
          svenfinitiv
          svenfinitiv

          ๐Ÿ›
          szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป
          tashiscool
          tashiscool

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          testation21
          testation21

          ๐Ÿ’ป ๐Ÿ›
          testation21
          testation21

          ๐Ÿ’ป ๐Ÿ›
          thanosa
          thanosa

          ๐Ÿ›
          tiandiyixian
          tiandiyixian

          ๐Ÿ›
          tobwoerk
          tobwoerk

          ๐Ÿ›
          tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป
          trentchilders
          trentchilders

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          trishul14
          trishul14

          ๐Ÿ›
          trishul14
          trishul14

          ๐Ÿ›
          tsui
          tsui

          ๐Ÿ›
          wangzitom12306
          wangzitom12306

          ๐Ÿ›
          winhkey
          winhkey

          ๐Ÿ›
          witherspore
          witherspore

          ๐Ÿ›
          wjljack
          wjljack

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          xingsong
          xingsong

          ๐Ÿ›
          xingsong
          xingsong

          ๐Ÿ›
          xioayuge
          xioayuge

          ๐Ÿ›
          xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ›
          xuanuy
          xuanuy

          ๐Ÿ›
          xyf0921
          xyf0921

          ๐Ÿ›
          yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yasuharu-sato
          yasuharu-sato

          ๐Ÿ›
          yasuharu-sato
          yasuharu-sato

          ๐Ÿ›
          zenglian
          zenglian

          ๐Ÿ›
          zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ›
          zh3ng
          zh3ng

          ๐Ÿ›
          zt_soft
          zt_soft

          ๐Ÿ›
          ztt79
          ztt79

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ›
          รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ›
          ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ›
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ

          ๐Ÿ›
          ่Œ…ๅปถๅฎ‰
          ่Œ…ๅปถๅฎ‰

          ๐Ÿ’ป
          Erik Bleske
          Erik Bleske

          ๐Ÿ›
          Erik C. Thauvin
          Erik C. Thauvin

          ๐Ÿ“–
          Erik C. Thauvin
          Erik C. Thauvin

          ๐Ÿ“– ๐Ÿ›
          Ernst Reissner
          Ernst Reissner

          ๐Ÿ›
          Ethan Sargent
          Ethan Sargent

          ๐Ÿ›
          Ewan Tempero
          Ewan Tempero

          ๐Ÿ›
          Jon Moroney
          Jon Moroney

          ๐Ÿ’ป ๐Ÿ›
          Jonas Geiregat
          Jonas Geiregat

          ๐Ÿ›
          Jonas KeรŸler
          Jonas KeรŸler

          ๐Ÿ›
          Jonathan Gillespie
          Jonathan Gillespie

          ๐Ÿ’ต
          Jonathan Wiesel
          Jonathan Wiesel

          ๐Ÿ’ป ๐Ÿ›
          Jordan
          Jordan

          ๐Ÿ›
          Jordi Llach
          Jordi Llach

          ๐Ÿ›
          Jorge Solรณrzano
          Jorge Solรณrzano

          ๐Ÿ›
          Jorge Solรณrzano
          Jorge Solรณrzano

          ๐Ÿ›
          JorneVL
          JorneVL

          ๐Ÿ›
          Jose Palafox
          Jose Palafox

          ๐Ÿ›
          Jose Stovall
          Jose Stovall

          ๐Ÿ›
          Joseph
          Joseph

          ๐Ÿ’ป
          Joseph Heenan
          Joseph Heenan

          ๐Ÿ›
          Josh Feingold
          Josh Feingold

          ๐Ÿ’ป ๐Ÿ›
          Josh Holthaus
          Josh Holthaus

          ๐Ÿ›
          Josh Holthaus
          Josh Holthaus

          ๐Ÿ›
          Joshua S Arquilevich
          Joshua S Arquilevich

          ๐Ÿ›
          Joรฃo Dinis Ferreira
          Joรฃo Dinis Ferreira

          ๐Ÿ“–
          Joรฃo Ferreira
          Joรฃo Ferreira

          ๐Ÿ’ป ๐Ÿ›
          Joรฃo Pedro Schmitt
          Joรฃo Pedro Schmitt

          ๐Ÿ›
          Juan Martรญn Sotuyo Dodero
          Juan Martรญn Sotuyo Dodero

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง
          Juan Pablo Civile
          Juan Pablo Civile

          ๐Ÿ›
          Julian Voronetsky
          Julian Voronetsky

          ๐Ÿ›
          Julian Voronetsky
          Julian Voronetsky

          ๐Ÿ›
          Julien
          Julien

          ๐Ÿ›
          Julius
          Julius

          ๐Ÿ›
          JustPRV
          JustPRV

          ๐Ÿ›
          Justin Stroud
          Justin Stroud

          ๐Ÿ’ป
          Jรถrn Huxhorn
          Jรถrn Huxhorn

          ๐Ÿ›
          KThompso
          KThompso

          ๐Ÿ›
          Kai Amundsen
          Kai Amundsen

          ๐Ÿ›
          Kai Amundsen
          Kai Amundsen

          ๐Ÿ›
          Karel Vervaeke
          Karel Vervaeke

          ๐Ÿ›
          Karl-Andero Mere
          Karl-Andero Mere

          ๐Ÿ›
          Karl-Philipp Richter
          Karl-Philipp Richter

          ๐Ÿ›
          Karsten Silz
          Karsten Silz

          ๐Ÿ›
          Kazuma Watanabe
          Kazuma Watanabe

          ๐Ÿ›
          Kev
          Kev

          ๐Ÿ›
          Keve Mรผller
          Keve Mรผller

          ๐Ÿ›
          Keve Mรผller
          Keve Mรผller

          ๐Ÿ›
          Kevin Guerra
          Kevin Guerra

          ๐Ÿ’ป
          Kevin Jones
          Kevin Jones

          ๐Ÿ› ๐Ÿ’ป
          Kevin Poorman
          Kevin Poorman

          ๐Ÿ›
          Kevin Wayne
          Kevin Wayne

          ๐Ÿ›
          Kieran Black
          Kieran Black

          ๐Ÿ›
          Kirill Zubov
          Kirill Zubov

          ๐Ÿ›
          Kirk Clemens
          Kirk Clemens

          ๐Ÿ’ป ๐Ÿ›
          Kirk Clemens
          Kirk Clemens

          ๐Ÿ’ป ๐Ÿ›
          Klaus Hartl
          Klaus Hartl

          ๐Ÿ›
          Koen Van Looveren
          Koen Van Looveren

          ๐Ÿ›
          Kris Scheibe
          Kris Scheibe

          ๐Ÿ’ป ๐Ÿ›
          Krystian Dabrowski
          Krystian Dabrowski

          ๐Ÿ› ๐Ÿ’ป
          Krzysztof Dymek
          Krzysztof Dymek

          ๐Ÿ›
          Kunal Thanki
          Kunal Thanki

          ๐Ÿ›
          Kursat Aktas
          Kursat Aktas

          ๐Ÿ“–
          Kursat Aktas
          Kursat Aktas

          ๐Ÿ“–
          LaLucid
          LaLucid

          ๐Ÿ’ป
          Larry Diamond
          Larry Diamond

          ๐Ÿ’ป ๐Ÿ›
          Lars Knickrehm
          Lars Knickrehm

          ๐Ÿ›
          Laurent Bovet
          Laurent Bovet

          ๐Ÿ› ๐Ÿ’ป
          Leo Gutierrez
          Leo Gutierrez

          ๐Ÿ›
          LiGaOg
          LiGaOg

          ๐Ÿ’ป
          Liam Sharp
          Liam Sharp

          ๐Ÿ›
          Liam Sharp
          Liam Sharp

          ๐Ÿ›
          Lintsi
          Lintsi

          ๐Ÿ›
          Linus Fernandes
          Linus Fernandes

          ๐Ÿ›
          Lixon Lookose
          Lixon Lookose

          ๐Ÿ›
          Logesh
          Logesh

          ๐Ÿ›
          Lorenzo Gabriele
          Lorenzo Gabriele

          ๐Ÿ›
          Loรฏc Ledoyen
          Loรฏc Ledoyen

          ๐Ÿ›
          Lucas
          Lucas

          ๐Ÿ›
          Lucas
          Lucas

          ๐Ÿ›
          Lucas Silva
          Lucas Silva

          ๐Ÿ›
          Lucas Soncini
          Lucas Soncini

          ๐Ÿ’ป ๐Ÿ›
          Luis Alcantar
          Luis Alcantar

          ๐Ÿ’ป
          Lukas Grรคf
          Lukas Grรคf

          ๐Ÿ’ป
          Lukasz Slonina
          Lukasz Slonina

          ๐Ÿ›
          Lukebray
          Lukebray

          ๐Ÿ›
          Lynn
          Lynn

          ๐Ÿ’ป ๐Ÿ›
          Lynn
          Lynn

          ๐Ÿ’ป ๐Ÿ›
          Lyor Goldstein
          Lyor Goldstein

          ๐Ÿ›
          MCMicS
          MCMicS

          ๐Ÿ›
          Macarse
          Macarse

          ๐Ÿ›
          Machine account for PMD
          Machine account for PMD

          ๐Ÿ’ป
          Maciek Siemczyk
          Maciek Siemczyk

          ๐Ÿ›
          Maikel Steneker
          Maikel Steneker

          ๐Ÿ’ป ๐Ÿ›
          Maksim Moiseikin
          Maksim Moiseikin

          ๐Ÿ›
          Maksim Moiseikin
          Maksim Moiseikin

          ๐Ÿ›
          Manfred Koch
          Manfred Koch

          ๐Ÿ›
          Manuel Moya Ferrer
          Manuel Moya Ferrer

          ๐Ÿ’ป ๐Ÿ›
          Manuel Romeiro
          Manuel Romeiro

          ๐Ÿ›
          Manuel Ryan
          Manuel Ryan

          ๐Ÿ›
          Marat Vyshegorodtsev
          Marat Vyshegorodtsev

          ๐Ÿ›
          Marcel Hรคrle
          Marcel Hรคrle

          ๐Ÿ›
          Marcello Fialho
          Marcello Fialho

          ๐Ÿ›
          Marcello Fialho
          Marcello Fialho

          ๐Ÿ›
          Marcin Dฤ…browski
          Marcin Dฤ…browski

          ๐Ÿ’ป ๐Ÿ›
          Marcin Rataj
          Marcin Rataj

          ๐Ÿ›
          Marcono1234
          Marcono1234

          ๐Ÿ›
          Mark Adamcin
          Mark Adamcin

          ๐Ÿ›
          Mark Hall
          Mark Hall

          ๐Ÿ’ป ๐Ÿ›
          Mark Kolich
          Mark Kolich

          ๐Ÿ›
          Mark Pritchard
          Mark Pritchard

          ๐Ÿ›
          Mark Pritchard
          Mark Pritchard

          ๐Ÿ›
          Markus Rathgeb
          Markus Rathgeb

          ๐Ÿ›
          Marquis Wang
          Marquis Wang

          ๐Ÿ›
          MartGit
          MartGit

          ๐Ÿ›
          Martin Feldsztejn
          Martin Feldsztejn

          ๐Ÿ›
          Martin Lehmann
          Martin Lehmann

          ๐Ÿ›
          Martin Spamer
          Martin Spamer

          ๐Ÿ›
          Martin Tarjรกnyi
          Martin Tarjรกnyi

          ๐Ÿ›
          Martin Tarjรกnyi
          Martin Tarjรกnyi

          ๐Ÿ›
          MatFl
          MatFl

          ๐Ÿ›
          Mateusz Stefanski
          Mateusz Stefanski

          ๐Ÿ›
          Mathias Lagerwall
          Mathias Lagerwall

          ๐Ÿ›
          Mathieu Gouin
          Mathieu Gouin

          ๐Ÿ›
          MatiasComercio
          MatiasComercio

          ๐Ÿ’ป ๐Ÿ›
          Matt Benson
          Matt Benson

          ๐Ÿ›
          Matt De Poorter
          Matt De Poorter

          ๐Ÿ›
          Matt De Poorter
          Matt De Poorter

          ๐Ÿ›
          Matt Hargett
          Matt Hargett

          ๐Ÿ’ป ๐Ÿ’ต
          Matt Harrah
          Matt Harrah

          ๐Ÿ›
          Matt Nelson
          Matt Nelson

          ๐Ÿ›
          Matthew Amos
          Matthew Amos

          ๐Ÿ›
          Matthew Duggan
          Matthew Duggan

          ๐Ÿ›
          Matthew Hall
          Matthew Hall

          ๐Ÿ›
          Matthew Rossner
          Matthew Rossner

          ๐Ÿ›
          Matthew Rossner
          Matthew Rossner

          ๐Ÿ›
          Matรญas Fraga
          Matรญas Fraga

          ๐Ÿ’ป ๐Ÿ›
          Maxime Robert
          Maxime Robert

          ๐Ÿ’ป ๐Ÿ›
          MetaBF
          MetaBF

          ๐Ÿ›
          Metin Dagcilar
          Metin Dagcilar

          ๐Ÿ›
          Michael
          Michael

          ๐Ÿ›
          Michael Bell
          Michael Bell

          ๐Ÿ›
          Michael Bernstein
          Michael Bernstein

          ๐Ÿ›
          Michael Bernstein
          Michael Bernstein

          ๐Ÿ›
          Michael Clay
          Michael Clay

          ๐Ÿ›
          Michael Dombrowski
          Michael Dombrowski

          ๐Ÿ›
          Michael Hausegger
          Michael Hausegger

          ๐Ÿ›
          Michael Hoefer
          Michael Hoefer

          ๐Ÿ›
          Michael Kolesnikov
          Michael Kolesnikov

          ๐Ÿ›
          Michael Mรถbius
          Michael Mรถbius

          ๐Ÿ›
          Michael N. Lipp
          Michael N. Lipp

          ๐Ÿ›
          Michael N. Lipp
          Michael N. Lipp

          ๐Ÿ›
          Michael Pellegrini
          Michael Pellegrini

          ๐Ÿ›
          Michal Kordas
          Michal Kordas

          ๐Ÿ›
          Michaล‚ Borek
          Michaล‚ Borek

          ๐Ÿ›
          Michaล‚ Kuliล„ski
          Michaล‚ Kuliล„ski

          ๐Ÿ›
          Miguel Nรบรฑez Dรญaz-Montes
          Miguel Nรบรฑez Dรญaz-Montes

          ๐Ÿ›
          Mihai Ionut
          Mihai Ionut

          ๐Ÿ›
          Mikhail Kuchma
          Mikhail Kuchma

          ๐Ÿ›
          Mikhail Kuchma
          Mikhail Kuchma

          ๐Ÿ›
          MiladSadinam
          MiladSadinam

          ๐Ÿ›
          Mirek Hankus
          Mirek Hankus

          ๐Ÿ›
          Mitch Spano
          Mitch Spano

          ๐Ÿ’ป ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          MrAngry52
          MrAngry52

          ๐Ÿ›
          Muminur Choudhury
          Muminur Choudhury

          ๐Ÿ›
          Muminur Choudhury
          Muminur Choudhury

          ๐Ÿ›
          Mykhailo Palahuta
          Mykhailo Palahuta

          ๐Ÿ’ป ๐Ÿ›
          Nagendra Kumar Singh
          Nagendra Kumar Singh

          ๐Ÿ›
          Nahuel Barrios
          Nahuel Barrios

          ๐Ÿ›
          Nakul Sharma
          Nakul Sharma

          ๐Ÿ›
          Nathan Braun
          Nathan Braun

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathanaรซl
          Nathanaรซl

          ๐Ÿ›
          Naveen
          Naveen

          ๐Ÿ’ป
          Nazdravi
          Nazdravi

          ๐Ÿ›
          Neha-Dhonde
          Neha-Dhonde

          ๐Ÿ›
          Nicholas Doyle
          Nicholas Doyle

          ๐Ÿ›
          Nick Butcher
          Nick Butcher

          ๐Ÿ›
          Nico Gallinal
          Nico Gallinal

          ๐Ÿ›
          Nico Gallinal
          Nico Gallinal

          ๐Ÿ›
          Nicola Dal Maso
          Nicola Dal Maso

          ๐Ÿ›
          Nicolas Filotto
          Nicolas Filotto

          ๐Ÿ’ป
          Nicolas Vervelle
          Nicolas Vervelle

          ๐Ÿ›
          Nicolas Vuillamy
          Nicolas Vuillamy

          ๐Ÿ“–
          Nikita Chursin
          Nikita Chursin

          ๐Ÿ›
          Niklas Baudy
          Niklas Baudy

          ๐Ÿ›
          Nikolas Havrikov
          Nikolas Havrikov

          ๐Ÿ›
          Nikolas Havrikov
          Nikolas Havrikov

          ๐Ÿ›
          Nilesh Virkar
          Nilesh Virkar

          ๐Ÿ›
          Nimit Patel
          Nimit Patel

          ๐Ÿ›
          Niranjan Harpale
          Niranjan Harpale

          ๐Ÿ›
          Nirvik Patel
          Nirvik Patel

          ๐Ÿ’ป
          Noah Sussman
          Noah Sussman

          ๐Ÿ›
          Noah0120
          Noah0120

          ๐Ÿ›
          Noam Tamim
          Noam Tamim

          ๐Ÿ›
          Noam Tamim
          Noam Tamim

          ๐Ÿ›
          Noel Grandin
          Noel Grandin

          ๐Ÿ›
          Olaf Haalstra
          Olaf Haalstra

          ๐Ÿ›
          Oleg Andreych
          Oleg Andreych

          ๐Ÿ’ป ๐Ÿ›
          Oleg Pavlenko
          Oleg Pavlenko

          ๐Ÿ›
          Oleksii Dykov
          Oleksii Dykov

          ๐Ÿ’ป ๐Ÿ›
          Oliver Eikemeier
          Oliver Eikemeier

          ๐Ÿ›
          Oliver Siegmar
          Oliver Siegmar

          ๐Ÿ’ต
          Oliver Siegmar
          Oliver Siegmar

          ๐Ÿ’ต
          Olivier Parent
          Olivier Parent

          ๐Ÿ’ป ๐Ÿ›
          Ollie Abbey
          Ollie Abbey

          ๐Ÿ’ป ๐Ÿ›
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)

          ๐Ÿ›
          Ondrej Kratochvil
          Ondrej Kratochvil

          ๐Ÿ›
          OverDrone
          OverDrone

          ๐Ÿ›
          Ozan Gulle
          Ozan Gulle

          ๐Ÿ’ป ๐Ÿ›
          PUNEET JAIN
          PUNEET JAIN

          ๐Ÿ›
          PUNEET JAIN
          PUNEET JAIN

          ๐Ÿ›
          Parbati Bose
          Parbati Bose

          ๐Ÿ›
          Paul Berg
          Paul Berg

          ๐Ÿ›
          Paul Guyot
          Paul Guyot

          ๐Ÿ’ป
          Pavel Bludov
          Pavel Bludov

          ๐Ÿ›
          Pavel Miฤka
          Pavel Miฤka

          ๐Ÿ›
          Pedro Nuno Santos
          Pedro Nuno Santos

          ๐Ÿ›
          Pedro Rijo
          Pedro Rijo

          ๐Ÿ›
          Pedro Rijo
          Pedro Rijo

          ๐Ÿ›
          Pelisse Romain
          Pelisse Romain

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
          Per Abich
          Per Abich

          ๐Ÿ’ป
          Pete Davids
          Pete Davids

          ๐Ÿ›
          Peter Bruin
          Peter Bruin

          ๐Ÿ›
          Peter Chittum
          Peter Chittum

          ๐Ÿ’ป ๐Ÿ›
          Peter Cudmore
          Peter Cudmore

          ๐Ÿ›
          Peter Kasson
          Peter Kasson

          ๐Ÿ›
          Peter Kasson
          Peter Kasson

          ๐Ÿ›
          Peter Kofler
          Peter Kofler

          ๐Ÿ›
          Peter Paul Bakker
          Peter Paul Bakker

          ๐Ÿ’ป ๐Ÿ›
          Peter Rader
          Peter Rader

          ๐Ÿ›
          Pham Hai Trung
          Pham Hai Trung

          ๐Ÿ›
          Philip Graf
          Philip Graf

          ๐Ÿ’ป ๐Ÿ›
          Philip Hachey
          Philip Hachey

          ๐Ÿ›
          Philippe Ozil
          Philippe Ozil

          ๐Ÿ›
          Philippe Ozil
          Philippe Ozil

          ๐Ÿ›
          Phinehas Artemix
          Phinehas Artemix

          ๐Ÿ›
          Phokham Nonava
          Phokham Nonava

          ๐Ÿ›
          Pim van der Loos
          Pim van der Loos

          ๐Ÿ’ป โš ๏ธ
          Piotr Szymaล„ski
          Piotr Szymaล„ski

          ๐Ÿ›
          Piotrek ลปygieล‚o
          Piotrek ลปygieล‚o

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“–
          Pranay Jaiswal
          Pranay Jaiswal

          ๐Ÿ›
          Prasad Kamath
          Prasad Kamath

          ๐Ÿ›
          Prasad Kamath
          Prasad Kamath

          ๐Ÿ›
          Prasanna
          Prasanna

          ๐Ÿ›
          Presh-AR
          Presh-AR

          ๐Ÿ›
          Puneet1726
          Puneet1726

          ๐Ÿ›
          RBRi
          RBRi

          ๐Ÿ›
          Rafael Cortรชs
          Rafael Cortรชs

          ๐Ÿ›
          RaheemShaik999
          RaheemShaik999

          ๐Ÿ›
          RajeshR
          RajeshR

          ๐Ÿ’ป ๐Ÿ›
          RajeshR
          RajeshR

          ๐Ÿ’ป ๐Ÿ›
          Ramachandra Mohan
          Ramachandra Mohan

          ๐Ÿ›
          Ramel0921
          Ramel0921

          ๐Ÿ›
          Raquel Pau
          Raquel Pau

          ๐Ÿ›
          Ravikiran Janardhana
          Ravikiran Janardhana

          ๐Ÿ›
          Reda Benhemmouche
          Reda Benhemmouche

          ๐Ÿ›
          Reinhard Schiedermeier
          Reinhard Schiedermeier

          ๐Ÿ›
          Renato Oliveira
          Renato Oliveira

          ๐Ÿ’ป ๐Ÿ›
          Renato Oliveira
          Renato Oliveira

          ๐Ÿ’ป ๐Ÿ›
          Rich DiCroce
          Rich DiCroce

          ๐Ÿ›
          Richard Corfield
          Richard Corfield

          ๐Ÿ’ป
          Richard Corfield
          Richard Corfield

          ๐Ÿ› ๐Ÿ’ป
          Riot R1cket
          Riot R1cket

          ๐Ÿ›
          Rishabh Jain
          Rishabh Jain

          ๐Ÿ›
          RishabhDeep Singh
          RishabhDeep Singh

          ๐Ÿ›
          Rob Baillie
          Rob Baillie

          ๐Ÿ›
          Rob Baillie
          Rob Baillie

          ๐Ÿ›
          Robbie Martinus
          Robbie Martinus

          ๐Ÿ’ป ๐Ÿ›
          Robert Henry
          Robert Henry

          ๐Ÿ›
          Robert Mihaly
          Robert Mihaly

          ๐Ÿ›
          Robert Painsi
          Robert Painsi

          ๐Ÿ›
          Robert Russell
          Robert Russell

          ๐Ÿ›
          Robert Sรถsemann
          Robert Sรถsemann

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ›
          Robert Whitebit
          Robert Whitebit

          ๐Ÿ›
          Robert Whitebit
          Robert Whitebit

          ๐Ÿ›
          Robin Richtsfeld
          Robin Richtsfeld

          ๐Ÿ›
          Robin Stocker
          Robin Stocker

          ๐Ÿ’ป ๐Ÿ›
          Robin Wils
          Robin Wils

          ๐Ÿ›
          RochusOest
          RochusOest

          ๐Ÿ›
          Rodolfo Noviski
          Rodolfo Noviski

          ๐Ÿ›
          Rodrigo Casara
          Rodrigo Casara

          ๐Ÿ›
          Rodrigo Fernandes
          Rodrigo Fernandes

          ๐Ÿ›
          Rodrigo Fernandes
          Rodrigo Fernandes

          ๐Ÿ›
          Roman Salvador
          Roman Salvador

          ๐Ÿ’ป ๐Ÿ›
          Ronald Blaschke
          Ronald Blaschke

          ๐Ÿ›
          Rรณbert Papp
          Rรณbert Papp

          ๐Ÿ›
          Saikat Sengupta
          Saikat Sengupta

          ๐Ÿ›
          Saksham Handu
          Saksham Handu

          ๐Ÿ›
          Saladoc
          Saladoc

          ๐Ÿ›
          Salesforce Bob Lightning
          Salesforce Bob Lightning

          ๐Ÿ›
          Salesforce Bob Lightning
          Salesforce Bob Lightning

          ๐Ÿ›
          Sam Carlberg
          Sam Carlberg

          ๐Ÿ›
          Sascha Riemer
          Sascha Riemer

          ๐Ÿ›
          Sashko
          Sashko

          ๐Ÿ’ป
          Satoshi Kubo
          Satoshi Kubo

          ๐Ÿ›
          Scott Kennedy
          Scott Kennedy

          ๐Ÿ›
          Scott Wells
          Scott Wells

          ๐Ÿ› ๐Ÿ’ป
          Scrates1
          Scrates1

          ๐Ÿ› ๐Ÿ’ป
          Scrates1
          Scrates1

          ๐Ÿ› ๐Ÿ’ป
          Scrsloota
          Scrsloota

          ๐Ÿ’ป
          Sebastian Bรถgl
          Sebastian Bรถgl

          ๐Ÿ›
          Sebastian Davids
          Sebastian Davids

          ๐Ÿ›
          Sebastian Lรถvdahl
          Sebastian Lรถvdahl

          ๐Ÿ›
          Sebastian Schuberth
          Sebastian Schuberth

          ๐Ÿ›
          Sebastian Schwarz
          Sebastian Schwarz

          ๐Ÿ›
          Seren
          Seren

          ๐Ÿ› ๐Ÿ’ป
          Seren
          Seren

          ๐Ÿ› ๐Ÿ’ป
          Sergey Gorbaty
          Sergey Gorbaty

          ๐Ÿ›
          Sergey Kozlov
          Sergey Kozlov

          ๐Ÿ›
          Sergey Yanzin
          Sergey Yanzin

          ๐Ÿ’ป ๐Ÿ›
          Seth Wilcox
          Seth Wilcox

          ๐Ÿ’ป
          Shai Bennathan
          Shai Bennathan

          ๐Ÿ› ๐Ÿ’ป
          Shubham
          Shubham

          ๐Ÿ’ป ๐Ÿ›
          Simon Abykov
          Simon Abykov

          ๐Ÿ’ป ๐Ÿ›
          Simon Abykov
          Simon Abykov

          ๐Ÿ’ป ๐Ÿ›
          Simon Xiao
          Simon Xiao

          ๐Ÿ›
          Srinivasan Venkatachalam
          Srinivasan Venkatachalam

          ๐Ÿ›
          Stanislav Gromov
          Stanislav Gromov

          ๐Ÿ›
          Stanislav Myachenkov
          Stanislav Myachenkov

          ๐Ÿ’ป
          Stefan Birkner
          Stefan Birkner

          ๐Ÿ›
          Stefan Bohn
          Stefan Bohn

          ๐Ÿ›
          Stefan Endrullis
          Stefan Endrullis

          ๐Ÿ›
          Stefan Endrullis
          Stefan Endrullis

          ๐Ÿ›
          Stefan Klรถss-Schuster
          Stefan Klรถss-Schuster

          ๐Ÿ›
          Stefan Wolf
          Stefan Wolf

          ๐Ÿ›
          Stephan H. Wissel
          Stephan H. Wissel

          ๐Ÿ›
          Stephen
          Stephen

          ๐Ÿ›
          Stephen Carter
          Stephen Carter

          ๐Ÿ›
          Stephen Friedrich
          Stephen Friedrich

          ๐Ÿ›
          Steve Babula
          Steve Babula

          ๐Ÿ’ป
          Steve Babula
          Steve Babula

          ๐Ÿ’ป
          Steven Stearns
          Steven Stearns

          ๐Ÿ› ๐Ÿ’ป
          Stexxe
          Stexxe

          ๐Ÿ›
          Stian Lรฅgstad
          Stian Lรฅgstad

          ๐Ÿ›
          StuartClayton5
          StuartClayton5

          ๐Ÿ›
          Supun Arunoda
          Supun Arunoda

          ๐Ÿ›
          Suren Abrahamyan
          Suren Abrahamyan

          ๐Ÿ›
          Suvashri
          Suvashri

          ๐Ÿ“–
          Suvashri
          Suvashri

          ๐Ÿ“–
          Sven Barden
          Sven Barden

          ๐Ÿ›
          SwatiBGupta1110
          SwatiBGupta1110

          ๐Ÿ›
          SyedThoufich
          SyedThoufich

          ๐Ÿ›
          Szymon Sasin
          Szymon Sasin

          ๐Ÿ›
          T-chuangxin
          T-chuangxin

          ๐Ÿ›
          TERAI Atsuhiro
          TERAI Atsuhiro

          ๐Ÿ›
          TIOBE Software
          TIOBE Software

          ๐Ÿ’ป ๐Ÿ›
          TIOBE Software
          TIOBE Software

          ๐Ÿ’ป ๐Ÿ›
          Tarush Singh
          Tarush Singh

          ๐Ÿ’ป
          Taylor Smock
          Taylor Smock

          ๐Ÿ›
          Techeira Damiรกn
          Techeira Damiรกn

          ๐Ÿ’ป ๐Ÿ›
          Ted Husted
          Ted Husted

          ๐Ÿ›
          TehBakker
          TehBakker

          ๐Ÿ›
          The Gitter Badger
          The Gitter Badger

          ๐Ÿ›
          Theodoor
          Theodoor

          ๐Ÿ›
          Theodoor
          Theodoor

          ๐Ÿ›
          Thiago Henrique Hรผpner
          Thiago Henrique Hรผpner

          ๐Ÿ›
          Thibault Meyer
          Thibault Meyer

          ๐Ÿ›
          Thomas Gรผttler
          Thomas Gรผttler

          ๐Ÿ›
          Thomas Jones-Low
          Thomas Jones-Low

          ๐Ÿ›
          Thomas Smith
          Thomas Smith

          ๐Ÿ’ป ๐Ÿ›
          ThrawnCA
          ThrawnCA

          ๐Ÿ›
          Thu Vo
          Thu Vo

          ๐Ÿ›
          Thu Vo
          Thu Vo

          ๐Ÿ›
          Thunderforge
          Thunderforge

          ๐Ÿ’ป ๐Ÿ›
          Tim van der Lippe
          Tim van der Lippe

          ๐Ÿ›
          Tobias Weimer
          Tobias Weimer

          ๐Ÿ’ป ๐Ÿ›
          Tom Copeland
          Tom Copeland

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–
          Tom Daly
          Tom Daly

          ๐Ÿ›
          Tomas
          Tomas

          ๐Ÿ›
          Tomer Figenblat
          Tomer Figenblat

          ๐Ÿ›
          Tomer Figenblat
          Tomer Figenblat

          ๐Ÿ›
          Tomi De Lucca
          Tomi De Lucca

          ๐Ÿ’ป ๐Ÿ›
          Tony
          Tony

          ๐Ÿ“–
          Torsten Kleiber
          Torsten Kleiber

          ๐Ÿ›
          Torsten Krause
          Torsten Krause

          ๐Ÿ›
          TrackerSB
          TrackerSB

          ๐Ÿ›
          Tyson Stewart
          Tyson Stewart

          ๐Ÿ›
          Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ›
          Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ›
          Utku Cuhadaroglu
          Utku Cuhadaroglu

          ๐Ÿ’ป ๐Ÿ›
          Valentin Brandl
          Valentin Brandl

          ๐Ÿ›
          Valeria
          Valeria

          ๐Ÿ›
          Valery Yatsynovich
          Valery Yatsynovich

          ๐Ÿ“–
          Vasily Anisimov
          Vasily Anisimov

          ๐Ÿ›
          Vedant Chokshi
          Vedant Chokshi

          ๐Ÿ›
          Vibhor Goyal
          Vibhor Goyal

          ๐Ÿ›
          Vibhor Goyal
          Vibhor Goyal

          ๐Ÿ›
          Vickenty Fesunov
          Vickenty Fesunov

          ๐Ÿ›
          Victor Noรซl
          Victor Noรซl

          ๐Ÿ›
          Vincent Galloy
          Vincent Galloy

          ๐Ÿ’ป
          Vincent HUYNH
          Vincent HUYNH

          ๐Ÿ›
          Vincent Maurin
          Vincent Maurin

          ๐Ÿ›
          Vincent Potucek
          Vincent Potucek

          ๐Ÿ’ป
          Vincent Privat
          Vincent Privat

          ๐Ÿ›
          Vincent Privat
          Vincent Privat

          ๐Ÿ›
          Vishhwas
          Vishhwas

          ๐Ÿ›
          Vishv_Android
          Vishv_Android

          ๐Ÿ›
          Vitalii Yevtushenko
          Vitalii Yevtushenko

          ๐Ÿ›
          Vitaly
          Vitaly

          ๐Ÿ›
          Vitaly Polonetsky
          Vitaly Polonetsky

          ๐Ÿ›
          Vojtech Polivka
          Vojtech Polivka

          ๐Ÿ›
          Vsevolod Zholobov
          Vsevolod Zholobov

          ๐Ÿ›
          Vsevolod Zholobov
          Vsevolod Zholobov

          ๐Ÿ›
          Vyom Yadav
          Vyom Yadav

          ๐Ÿ’ป
          Wang Shidong
          Wang Shidong

          ๐Ÿ›
          Waqas Ahmed
          Waqas Ahmed

          ๐Ÿ›
          Wayne J. Earl
          Wayne J. Earl

          ๐Ÿ›
          Wchenghui
          Wchenghui

          ๐Ÿ›
          Wener
          Wener

          ๐Ÿ’ป
          Will Winder
          Will Winder

          ๐Ÿ›
          Will Winder
          Will Winder

          ๐Ÿ›
          Willem A. Hajenius
          Willem A. Hajenius

          ๐Ÿ’ป
          William Brockhus
          William Brockhus

          ๐Ÿ’ป ๐Ÿ›
          Wilson Kurniawan
          Wilson Kurniawan

          ๐Ÿ›
          Wim Deblauwe
          Wim Deblauwe

          ๐Ÿ›
          Wolf2323
          Wolf2323

          ๐Ÿ›
          Woongsik Choi
          Woongsik Choi

          ๐Ÿ›
          XenoAmess
          XenoAmess

          ๐Ÿ’ป ๐Ÿ›
          XenoAmess
          XenoAmess

          ๐Ÿ’ป ๐Ÿ›
          Yang
          Yang

          ๐Ÿ’ป
          YaroslavTER
          YaroslavTER

          ๐Ÿ›
          Yasar Shaikh
          Yasar Shaikh

          ๐Ÿ’ป
          Young Chan
          Young Chan

          ๐Ÿ’ป ๐Ÿ›
          YuJin Kim
          YuJin Kim

          ๐Ÿ›
          Yuri Dolzhenko
          Yuri Dolzhenko

          ๐Ÿ›
          Yurii Dubinka
          Yurii Dubinka

          ๐Ÿ›
          Yurii Dubinka
          Yurii Dubinka

          ๐Ÿ›
          Zoltan Farkas
          Zoltan Farkas

          ๐Ÿ›
          Zustin
          Zustin

          ๐Ÿ›
          aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป
          alexmodis
          alexmodis

          ๐Ÿ›
          andreoss
          andreoss

          ๐Ÿ›
          andrey81inmd
          andrey81inmd

          ๐Ÿ’ป ๐Ÿ›
          anicoara
          anicoara

          ๐Ÿ›
          anicoara
          anicoara

          ๐Ÿ›
          arunprasathav
          arunprasathav

          ๐Ÿ›
          asiercamara
          asiercamara

          ๐Ÿ›
          astillich-igniti
          astillich-igniti

          ๐Ÿ’ป
          avesolovksyy
          avesolovksyy

          ๐Ÿ›
          avishvat
          avishvat

          ๐Ÿ›
          avivmu
          avivmu

          ๐Ÿ›
          axelbarfod1
          axelbarfod1

          ๐Ÿ›
          axelbarfod1
          axelbarfod1

          ๐Ÿ›
          b-3-n
          b-3-n

          ๐Ÿ›
          balbhadra9
          balbhadra9

          ๐Ÿ›
          base23de
          base23de

          ๐Ÿ›
          bergander
          bergander

          ๐Ÿ› ๐Ÿ’ป
          berkam
          berkam

          ๐Ÿ’ป ๐Ÿ›
          breizh31
          breizh31

          ๐Ÿ›
          caesarkim
          caesarkim

          ๐Ÿ›
          caesarkim
          caesarkim

          ๐Ÿ›
          caiocarvalhotero
          caiocarvalhotero

          ๐Ÿ›
          carolyujing
          carolyujing

          ๐Ÿ›
          cbfiddle
          cbfiddle

          ๐Ÿ›
          cesares-basilico
          cesares-basilico

          ๐Ÿ›
          chrite
          chrite

          ๐Ÿ›
          ciufudean
          ciufudean

          ๐Ÿ“–
          cobratbq
          cobratbq

          ๐Ÿ›
          cobratbq
          cobratbq

          ๐Ÿ›
          coladict
          coladict

          ๐Ÿ›
          cosmoJFH
          cosmoJFH

          ๐Ÿ›
          cristalp
          cristalp

          ๐Ÿ›
          crunsk
          crunsk

          ๐Ÿ›
          cwholmes
          cwholmes

          ๐Ÿ›
          cyberjj999
          cyberjj999

          ๐Ÿ›
          cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“–
          cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“–
          d1ss0nanz
          d1ss0nanz

          ๐Ÿ›
          dague1
          dague1

          ๐Ÿ“–
          dalizi007
          dalizi007

          ๐Ÿ’ป
          danbrycefairsailcom
          danbrycefairsailcom

          ๐Ÿ›
          dariansanity
          dariansanity

          ๐Ÿ›
          darrenmiliband
          darrenmiliband

          ๐Ÿ›
          davidburstrom
          davidburstrom

          ๐Ÿ›
          davidburstrom
          davidburstrom

          ๐Ÿ›
          dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ›
          deepak-patra
          deepak-patra

          ๐Ÿ›
          dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ›
          dinesh150
          dinesh150

          ๐Ÿ›
          diziaq
          diziaq

          ๐Ÿ›
          dreaminpast123
          dreaminpast123

          ๐Ÿ›
          duanyanan
          duanyanan

          ๐Ÿ›
          duanyanan
          duanyanan

          ๐Ÿ›
          dutt-sanjay
          dutt-sanjay

          ๐Ÿ›
          duursma
          duursma

          ๐Ÿ’ป
          dylanleung
          dylanleung

          ๐Ÿ›
          dzeigler
          dzeigler

          ๐Ÿ›
          eant60
          eant60

          ๐Ÿ›
          ekkirala
          ekkirala

          ๐Ÿ›
          emersonmoura
          emersonmoura

          ๐Ÿ›
          emersonmoura
          emersonmoura

          ๐Ÿ›
          emouty
          emouty

          ๐Ÿ’ป ๐Ÿ›
          eugenepugach
          eugenepugach

          ๐Ÿ›
          fairy
          fairy

          ๐Ÿ›
          filiprafalowicz
          filiprafalowicz

          ๐Ÿ’ป
          flxbl-io
          flxbl-io

          ๐Ÿ’ต
          foxmason
          foxmason

          ๐Ÿ›
          frankegabor
          frankegabor

          ๐Ÿ›
          frankegabor
          frankegabor

          ๐Ÿ›
          frankl
          frankl

          ๐Ÿ›
          freafrea
          freafrea

          ๐Ÿ›
          fsapatin
          fsapatin

          ๐Ÿ›
          gearsethenry
          gearsethenry

          ๐Ÿ›
          gracia19
          gracia19

          ๐Ÿ›
          gudzpoz
          gudzpoz

          ๐Ÿ›
          guo fei
          guo fei

          ๐Ÿ›
          guo fei
          guo fei

          ๐Ÿ›
          gurmsc5
          gurmsc5

          ๐Ÿ›
          gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ›
          haigsn
          haigsn

          ๐Ÿ›
          hemanshu070
          hemanshu070

          ๐Ÿ›
          henrik242
          henrik242

          ๐Ÿ›
          hongpuwu
          hongpuwu

          ๐Ÿ›
          hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ›
          hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ›
          igniti GmbH
          igniti GmbH

          ๐Ÿ›
          ilovezfs
          ilovezfs

          ๐Ÿ›
          imax-erik
          imax-erik

          ๐Ÿ›
          itaigilo
          itaigilo

          ๐Ÿ›
          jakivey32
          jakivey32

          ๐Ÿ›
          jbennett2091
          jbennett2091

          ๐Ÿ›
          jcamerin
          jcamerin

          ๐Ÿ›
          jcamerin
          jcamerin

          ๐Ÿ›
          jkeener1
          jkeener1

          ๐Ÿ›
          jmetertea
          jmetertea

          ๐Ÿ›
          johnra2
          johnra2

          ๐Ÿ’ป
          johnzhao9
          johnzhao9

          ๐Ÿ›
          josemanuelrolon
          josemanuelrolon

          ๐Ÿ’ป ๐Ÿ›
          julees7
          julees7

          ๐Ÿ’ป ๐Ÿ›
          kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ›
          kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ›
          karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“–
          karwer
          karwer

          ๐Ÿ›
          kaulonline
          kaulonline

          ๐Ÿ›
          kdaemonv
          kdaemonv

          ๐Ÿ›
          kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป
          kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ›
          kfranic
          kfranic

          ๐Ÿ›
          kfranic
          kfranic

          ๐Ÿ›
          khalidkh
          khalidkh

          ๐Ÿ›
          koalalam
          koalalam

          ๐Ÿ›
          krzyk
          krzyk

          ๐Ÿ›
          lasselindqvist
          lasselindqvist

          ๐Ÿ›
          lgemeinhardt
          lgemeinhardt

          ๐Ÿ›
          lihuaib
          lihuaib

          ๐Ÿ›
          liqingjun123
          liqingjun123

          ๐Ÿ›
          liqingjun123
          liqingjun123

          ๐Ÿ›
          lonelyma1021
          lonelyma1021

          ๐Ÿ›
          lothas
          lothas

          ๐Ÿ›
          lpeddy
          lpeddy

          ๐Ÿ›
          lujiefsi
          lujiefsi

          ๐Ÿ’ป
          lukelukes
          lukelukes

          ๐Ÿ’ป
          lyriccoder
          lyriccoder

          ๐Ÿ›
          marcelmore
          marcelmore

          ๐Ÿ›
          marcelmore
          marcelmore

          ๐Ÿ›
          matchbox
          matchbox

          ๐Ÿ›
          matthiaskraaz
          matthiaskraaz

          ๐Ÿ›
          meandonlyme
          meandonlyme

          ๐Ÿ›
          mikesive
          mikesive

          ๐Ÿ›
          milossesic
          milossesic

          ๐Ÿ›
          mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ›
          mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป
          mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป
          mriddell95
          mriddell95

          ๐Ÿ›
          mrlzh
          mrlzh

          ๐Ÿ›
          msloan
          msloan

          ๐Ÿ›
          mucharlaravalika
          mucharlaravalika

          ๐Ÿ›
          mvenneman
          mvenneman

          ๐Ÿ›
          nareshl119
          nareshl119

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          noerremark
          noerremark

          ๐Ÿ›
          novsirion
          novsirion

          ๐Ÿ›
          nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป
          oggboy
          oggboy

          ๐Ÿ›
          oinume
          oinume

          ๐Ÿ›
          orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pacvz
          pacvz

          ๐Ÿ’ป
          pallavi agarwal
          pallavi agarwal

          ๐Ÿ›
          pankratz76
          pankratz76

          ๐Ÿ›
          parksungrin
          parksungrin

          ๐Ÿ›
          patpatpat123
          patpatpat123

          ๐Ÿ›
          patriksevallius
          patriksevallius

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          phoenix384
          phoenix384

          ๐Ÿ›
          piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป
          plan3d
          plan3d

          ๐Ÿ›
          poojasix
          poojasix

          ๐Ÿ›
          prabhushrikant
          prabhushrikant

          ๐Ÿ›
          pujitha8783
          pujitha8783

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          raghujayjunk
          raghujayjunk

          ๐Ÿ›
          rajeshveera
          rajeshveera

          ๐Ÿ›
          rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ›
          recdevs
          recdevs

          ๐Ÿ›
          reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ›
          rijkt
          rijkt

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ›
          rnveach
          rnveach

          ๐Ÿ›
          rxmicro
          rxmicro

          ๐Ÿ›
          ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ›
          sabi0
          sabi0

          ๐Ÿ›
          samc-gearset
          samc-gearset

          ๐Ÿ“–
          scais
          scais

          ๐Ÿ›
          scais
          scais

          ๐Ÿ›
          schosin
          schosin

          ๐Ÿ›
          screamingfrog
          screamingfrog

          ๐Ÿ’ต
          sebbASF
          sebbASF

          ๐Ÿ›
          sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป
          shilko2013
          shilko2013

          ๐Ÿ›
          shiomiyan
          shiomiyan

          ๐Ÿ“–
          simeonKondr
          simeonKondr

          ๐Ÿ›
          simeonKondr
          simeonKondr

          ๐Ÿ›
          snajberk
          snajberk

          ๐Ÿ›
          sniperrifle2004
          sniperrifle2004

          ๐Ÿ›
          snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป
          soloturn
          soloturn

          ๐Ÿ›
          soyodream
          soyodream

          ๐Ÿ›
          sratz
          sratz

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          sturton
          sturton

          ๐Ÿ’ป ๐Ÿ›
          sudharmohan
          sudharmohan

          ๐Ÿ›
          suruchidawar
          suruchidawar

          ๐Ÿ›
          svenfinitiv
          svenfinitiv

          ๐Ÿ›
          szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป
          tashiscool
          tashiscool

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          testation21
          testation21

          ๐Ÿ’ป ๐Ÿ›
          thanosa
          thanosa

          ๐Ÿ›
          tiandiyixian
          tiandiyixian

          ๐Ÿ›
          tobwoerk
          tobwoerk

          ๐Ÿ›
          tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป
          trentchilders
          trentchilders

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          trishul14
          trishul14

          ๐Ÿ›
          tsui
          tsui

          ๐Ÿ›
          wangzitom12306
          wangzitom12306

          ๐Ÿ›
          winhkey
          winhkey

          ๐Ÿ›
          witherspore
          witherspore

          ๐Ÿ›
          wjljack
          wjljack

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          xingsong
          xingsong

          ๐Ÿ›
          xioayuge
          xioayuge

          ๐Ÿ›
          xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ›
          xuanuy
          xuanuy

          ๐Ÿ›
          xyf0921
          xyf0921

          ๐Ÿ›
          yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yasuharu-sato
          yasuharu-sato

          ๐Ÿ›
          zenglian
          zenglian

          ๐Ÿ›
          zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ›
          zh3ng
          zh3ng

          ๐Ÿ›
          zt_soft
          zt_soft

          ๐Ÿ›
          ztt79
          ztt79

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ›
          ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ›
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ

          ๐Ÿ›
          Colin Ingarfield
          Colin Ingarfield

          ๐Ÿ›
          Craig Andrews
          Craig Andrews

          ๐Ÿ›
          Craig Muchinsky
          Craig Muchinsky

          ๐Ÿ›
          Cyril
          Cyril

          ๐Ÿ’ป ๐Ÿ›
          Cybozu
          Cybozu

          ๐Ÿ’ต
          Cyril
          Cyril

          ๐Ÿ’ป ๐Ÿ›
          Dale
          Dale

          ๐Ÿ’ป
          Damien Jiang
          Damien Jiang

          ๐Ÿ›
          Dan Berindei
          Dan Berindei

          ๐Ÿ›
          Dan Rollo
          Dan Rollo

          ๐Ÿ›
          Dan Ziemba
          Dan Ziemba

          ๐Ÿ›
          Daniel Gredler
          Daniel Gredler

          ๐Ÿ’ป ๐Ÿ›
          Daniel Jipa
          Daniel Jipa

          ๐Ÿ›
          Daniel Jipa
          Daniel Jipa

          ๐Ÿ›
          Daniel Paul Searles
          Daniel Paul Searles

          ๐Ÿ’ป
          Daniel Reigada
          Daniel Reigada

          ๐Ÿ›
          Daniel Ventura
          Daniel Ventura

          ๐Ÿ›
          Danilo Pianini
          Danilo Pianini

          ๐Ÿ›
          Darko
          Darko

          ๐Ÿ›
          David
          David

          ๐Ÿ›
          David Atkinson
          David Atkinson

          ๐Ÿ›
          David Atkinson
          David Atkinson

          ๐Ÿ›
          David Burstrรถm
          David Burstrรถm

          ๐Ÿ’ป ๐Ÿ›
          David Goatรฉ
          David Goatรฉ

          ๐Ÿ›
          David Golpira
          David Golpira

          ๐Ÿ›
          David Kovaล™รญk
          David Kovaล™รญk

          ๐Ÿ›
          David M. Karr (fullname at gmail.com)
          David M. Karr (fullname at gmail.com)

          ๐Ÿ›
          David Renz
          David Renz

          ๐Ÿ’ป ๐Ÿ›
          David Renz
          David Renz

          ๐Ÿ›
          David Renz
          David Renz

          ๐Ÿ›
          David Schach
          David Schach

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–
          Dawid Ciok
          Dawid Ciok

          ๐Ÿ› ๐Ÿ’ป
          Debamoy Datta
          Debamoy Datta

          ๐Ÿ’ป
          Deleted user
          Deleted user

          ๐Ÿ›
          Dell Green
          Dell Green

          ๐Ÿ›
          Dem Pilafian
          Dem Pilafian

          ๐Ÿ›
          Den
          Den

          ๐Ÿ›
          Den
          Den

          ๐Ÿ›
          Denis Borovikov
          Denis Borovikov

          ๐Ÿ’ป ๐Ÿ›
          Dennie Reniers
          Dennie Reniers

          ๐Ÿ’ป ๐Ÿ›
          Dennis Kieselhorst
          Dennis Kieselhorst

          ๐Ÿ›
          Derek P. Moore
          Derek P. Moore

          ๐Ÿ›
          Dichotomia
          Dichotomia

          ๐Ÿ›
          Dionisio Cortรฉs Fernรกndez
          Dionisio Cortรฉs Fernรกndez

          ๐Ÿ’ป ๐Ÿ›
          Dmitri Bourlatchkov
          Dmitri Bourlatchkov

          ๐Ÿ›
          Dmitri Bourlatchkov
          Dmitri Bourlatchkov

          ๐Ÿ›
          Dmitriy Kuzmin
          Dmitriy Kuzmin

          ๐Ÿ›
          Dmytro Dashenkov
          Dmytro Dashenkov

          ๐Ÿ›
          Douglas Griffith
          Douglas Griffith

          ๐Ÿ“–
          Dr. Christian Kohlschรผtter
          Dr. Christian Kohlschรผtter

          ๐Ÿ›
          Drew Hall
          Drew Hall

          ๐Ÿ›
          Dumitru Postoronca
          Dumitru Postoronca

          ๐Ÿ›
          Dylan Adams
          Dylan Adams

          ๐Ÿ›
          Dylan Adams
          Dylan Adams

          ๐Ÿ›
          Eden Hao
          Eden Hao

          ๐Ÿ›
          Edward Klimoshenko
          Edward Klimoshenko

          ๐Ÿ› ๐Ÿ’ป
          Egor Bredikhin
          Egor Bredikhin

          ๐Ÿ›
          Elan P. Kugelmass
          Elan P. Kugelmass

          ๐Ÿ›
          Elder S.
          Elder S.

          ๐Ÿ›
          Eldrick Wega
          Eldrick Wega

          ๐Ÿ“–
          Elliotte Rusty Harold
          Elliotte Rusty Harold

          ๐Ÿ’ป
          Elliotte Rusty Harold
          Elliotte Rusty Harold

          ๐Ÿ’ป
          Emile
          Emile

          ๐Ÿ›
          Eric
          Eric

          ๐Ÿ›
          Eric Kintzer
          Eric Kintzer

          ๐Ÿ›
          Eric Perret
          Eric Perret

          ๐Ÿ›
          Eric Squires
          Eric Squires

          ๐Ÿ›
          Erich L Foster
          Erich L Foster

          ๐Ÿ›
          Erik Bleske
          Erik Bleske

          ๐Ÿ›
          Erik Bleske
          Erik Bleske

          ๐Ÿ›
          Erik C. Thauvin
          Erik C. Thauvin

          ๐Ÿ“–
          Ernst Reissner
          Ernst Reissner

          ๐Ÿ›
          Ethan Sargent
          Ethan Sargent

          ๐Ÿ›
          Ewan Tempero
          Ewan Tempero

          ๐Ÿ›
          F.W. Dekker
          F.W. Dekker

          ๐Ÿ›
          FSchliephacke
          FSchliephacke

          ๐Ÿ›
          Facundo
          Facundo

          ๐Ÿ›
          Facundo
          Facundo

          ๐Ÿ›
          Federico Giust
          Federico Giust

          ๐Ÿ›
          Fedor Sherstobitov
          Fedor Sherstobitov

          ๐Ÿ›
          Felix Lampe
          Felix Lampe

          ๐Ÿ›
          Filip Golonka
          Filip Golonka

          ๐Ÿ›
          Filipe Esperandio
          Filipe Esperandio

          ๐Ÿ’ป ๐Ÿ›
          Filippo Barbari
          Filippo Barbari

          ๐Ÿ›
          Filippo Nova
          Filippo Nova

          ๐Ÿ›
          Filippo Nova
          Filippo Nova

          ๐Ÿ›
          Francesco la Torre
          Francesco la Torre

          ๐Ÿ›
          Francisco Duarte
          Francisco Duarte

          ๐Ÿ›
          Frederick Zhang
          Frederick Zhang

          ๐Ÿ›
          Frieder Bluemle
          Frieder Bluemle

          ๐Ÿ›
          Frits Jalvingh
          Frits Jalvingh

          ๐Ÿ’ป ๐Ÿ›
          G. Bazior
          G. Bazior

          ๐Ÿ›
          Gabe Henkes
          Gabe Henkes

          ๐Ÿ›
          Gabe Henkes
          Gabe Henkes

          ๐Ÿ›
          Gary Gregory
          Gary Gregory

          ๐Ÿ›
          Genoud Magloire
          Genoud Magloire

          ๐Ÿ›
          Geoffrey555
          Geoffrey555

          ๐Ÿ›
          Georg Romstorfer
          Georg Romstorfer

          ๐Ÿ›
          Gili Tzabari
          Gili Tzabari

          ๐Ÿ› ๐Ÿ’ป
          Gio
          Gio

          ๐Ÿ›
          Gol
          Gol

          ๐Ÿ›
          Gol
          Gol

          ๐Ÿ›
          Gold856
          Gold856

          ๐Ÿ› ๐Ÿ’ป
          Gonzalo Exequiel Ibars Ingman
          Gonzalo Exequiel Ibars Ingman

          ๐Ÿ’ป ๐Ÿ›
          GooDer
          GooDer

          ๐Ÿ›
          Gregor Riegler
          Gregor Riegler

          ๐Ÿ›
          Grzegorz Olszewski
          Grzegorz Olszewski

          ๐Ÿ›
          Gunther Schrijvers
          Gunther Schrijvers

          ๐Ÿ’ป ๐Ÿ›
          Gustavo Krieger
          Gustavo Krieger

          ๐Ÿ›
          Gustavo Krieger
          Gustavo Krieger

          ๐Ÿ›
          Guy Elsmore-Paddock
          Guy Elsmore-Paddock

          ๐Ÿ›
          Gรถrkem Mรผlayim
          Gรถrkem Mรผlayim

          ๐Ÿ›
          Hanzel Godinez
          Hanzel Godinez

          ๐Ÿ›
          Haoliang Chen
          Haoliang Chen

          ๐Ÿ›
          Harsh Kukreja
          Harsh Kukreja

          ๐Ÿ›
          Hassan ALAMI
          Hassan ALAMI

          ๐Ÿ›
          Heber
          Heber

          ๐Ÿ›
          Heber
          Heber

          ๐Ÿ›
          Hector Miuler Malpica Gallegos
          Hector Miuler Malpica Gallegos

          ๐Ÿ›
          Henning Schmiedehausen
          Henning Schmiedehausen

          ๐Ÿ’ป ๐Ÿ›
          Henning von Bargen
          Henning von Bargen

          ๐Ÿ’ป
          Hervรฉ Boutemy
          Hervรฉ Boutemy

          ๐Ÿ›
          Himanshu Pandey
          Himanshu Pandey

          ๐Ÿ›
          Hokwang Lee
          Hokwang Lee

          ๐Ÿ›
          Hooperbloob
          Hooperbloob

          ๐Ÿ’ป
          Hooperbloob
          Hooperbloob

          ๐Ÿ’ป
          Hung PHAN
          Hung PHAN

          ๐Ÿ›
          IDoCodingStuffs
          IDoCodingStuffs

          ๐Ÿ’ป ๐Ÿ›
          Iccen Gan
          Iccen Gan

          ๐Ÿ›
          Ignacio Mariano Tirabasso
          Ignacio Mariano Tirabasso

          ๐Ÿ›
          Igor Melnichenko
          Igor Melnichenko

          ๐Ÿ›
          Igor Moreno
          Igor Moreno

          ๐Ÿ›
          Intelesis-MS
          Intelesis-MS

          ๐Ÿ›
          Intelesis-MS
          Intelesis-MS

          ๐Ÿ›
          Iroha_
          Iroha_

          ๐Ÿ›
          Ishan Srivastava
          Ishan Srivastava

          ๐Ÿ›
          Iskren Stanislavov
          Iskren Stanislavov

          ๐Ÿ›
          Ivan Vakhrushev
          Ivan Vakhrushev

          ๐Ÿ›
          Ivano Guerini
          Ivano Guerini

          ๐Ÿ›
          Ivar Andreas Bonsaksen
          Ivar Andreas Bonsaksen

          ๐Ÿ›
          Ivo ล mรญd
          Ivo ล mรญd

          ๐Ÿ›
          Ivo ล mรญd
          Ivo ล mรญd

          ๐Ÿ›
          JJengility
          JJengility

          ๐Ÿ›
          Jake Hemmerle
          Jake Hemmerle

          ๐Ÿ›
          Jakub Dupak
          Jakub Dupak

          ๐Ÿ’ป
          James Harrison
          James Harrison

          ๐Ÿ› ๐Ÿ’ป
          Jamie Bisotti
          Jamie Bisotti

          ๐Ÿ›
          Jan
          Jan

          ๐Ÿ›
          Jan Aertgeerts
          Jan Aertgeerts

          ๐Ÿ’ป ๐Ÿ›
          Jan Aertgeerts
          Jan Aertgeerts

          ๐Ÿ’ป ๐Ÿ›
          Jan Brรผmmer
          Jan Brรผmmer

          ๐Ÿ›
          Jan Tล™รญska
          Jan Tล™รญska

          ๐Ÿ›
          Jan-Lukas Else
          Jan-Lukas Else

          ๐Ÿ›
          Jason Qiu
          Jason Qiu

          ๐Ÿ’ป ๐Ÿ“–
          Jason Williams
          Jason Williams

          ๐Ÿ›
          Javier Spagnoletti
          Javier Spagnoletti

          ๐Ÿ›
          Jean-Paul Mayer
          Jean-Paul Mayer

          ๐Ÿ›
          Jean-Paul Mayer
          Jean-Paul Mayer

          ๐Ÿ›
          Jean-Simon Larochelle
          Jean-Simon Larochelle

          ๐Ÿ›
          Jeff Bartolotta
          Jeff Bartolotta

          ๐Ÿ’ป ๐Ÿ›
          Jeff Hube
          Jeff Hube

          ๐Ÿ’ป ๐Ÿ›
          Jeff Jensen
          Jeff Jensen

          ๐Ÿ›
          Jeff May
          Jeff May

          ๐Ÿ›
          Jens Gerdes
          Jens Gerdes

          ๐Ÿ›
          Jeroen Borgers
          Jeroen Borgers

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข
          Jeroen Borgers
          Jeroen Borgers

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข
          Jeroen Meijer
          Jeroen Meijer

          ๐Ÿ›
          Jeroen van Wilgenburg
          Jeroen van Wilgenburg

          ๐Ÿ“–
          Jerome Russ
          Jerome Russ

          ๐Ÿ›
          JerritEic
          JerritEic

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
          Jiri Pejchal
          Jiri Pejchal

          ๐Ÿ›
          Jithin Sunny
          Jithin Sunny

          ๐Ÿ›
          Jiล™รญ ล korpil
          Jiล™รญ ล korpil

          ๐Ÿ›
          Jiล™รญ ล korpil
          Jiล™รญ ล korpil

          ๐Ÿ›
          Joao Machado
          Joao Machado

          ๐Ÿ›
          Jochen Krauss
          Jochen Krauss

          ๐Ÿ›
          Johan Hammar
          Johan Hammar

          ๐Ÿ›
          John Jetmore
          John Jetmore

          ๐Ÿ“–
          John Karp
          John Karp

          ๐Ÿ›
          John Zhang
          John Zhang

          ๐Ÿ›
          John-Teng
          John-Teng

          ๐Ÿ’ป ๐Ÿ›
          John-Teng
          John-Teng

          ๐Ÿ’ป ๐Ÿ›
          Jon Moroney
          Jon Moroney

          ๐Ÿ’ป ๐Ÿ›
          Jonas Geiregat
          Jonas Geiregat

          ๐Ÿ›
          Jonas KeรŸler
          Jonas KeรŸler

          ๐Ÿ›
          Jonathan Gillespie
          Jonathan Gillespie

          ๐Ÿ’ต
          Jonathan Wiesel
          Jonathan Wiesel

          ๐Ÿ’ป ๐Ÿ›
          Jordan
          Jordan

          ๐Ÿ›
          Jordi Llach
          Jordi Llach

          ๐Ÿ›
          Jordi Llach
          Jordi Llach

          ๐Ÿ›
          Jorge Solรณrzano
          Jorge Solรณrzano

          ๐Ÿ›
          JorneVL
          JorneVL

          ๐Ÿ›
          Jose Palafox
          Jose Palafox

          ๐Ÿ›
          Jose Stovall
          Jose Stovall

          ๐Ÿ›
          Joseph
          Joseph

          ๐Ÿ’ป
          Joseph Heenan
          Joseph Heenan

          ๐Ÿ›
          Josh Feingold
          Josh Feingold

          ๐Ÿ’ป ๐Ÿ›
          Josh Feingold
          Josh Feingold

          ๐Ÿ’ป ๐Ÿ›
          Josh Holthaus
          Josh Holthaus

          ๐Ÿ›
          Joshua S Arquilevich
          Joshua S Arquilevich

          ๐Ÿ›
          Joรฃo Dinis Ferreira
          Joรฃo Dinis Ferreira

          ๐Ÿ“–
          Joรฃo Ferreira
          Joรฃo Ferreira

          ๐Ÿ’ป ๐Ÿ›
          Joรฃo Pedro Schmitt
          Joรฃo Pedro Schmitt

          ๐Ÿ›
          Juan Martรญn Sotuyo Dodero
          Juan Martรญn Sotuyo Dodero

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง
          Juan Pablo Civile
          Juan Pablo Civile

          ๐Ÿ›
          Juan Pablo Civile
          Juan Pablo Civile

          ๐Ÿ›
          Julian Voronetsky
          Julian Voronetsky

          ๐Ÿ›
          Julien
          Julien

          ๐Ÿ›
          Julius
          Julius

          ๐Ÿ›
          JustPRV
          JustPRV

          ๐Ÿ›
          Justin Stroud
          Justin Stroud

          ๐Ÿ’ป
          Jรถrn Huxhorn
          Jรถrn Huxhorn

          ๐Ÿ›
          KThompso
          KThompso

          ๐Ÿ›
          KThompso
          KThompso

          ๐Ÿ›
          Kai Amundsen
          Kai Amundsen

          ๐Ÿ›
          Karel Vervaeke
          Karel Vervaeke

          ๐Ÿ›
          Karl-Andero Mere
          Karl-Andero Mere

          ๐Ÿ›
          Karl-Philipp Richter
          Karl-Philipp Richter

          ๐Ÿ›
          Karsten Silz
          Karsten Silz

          ๐Ÿ›
          Kazuma Watanabe
          Kazuma Watanabe

          ๐Ÿ›
          Kev
          Kev

          ๐Ÿ›
          Kev
          Kev

          ๐Ÿ›
          Keve Mรผller
          Keve Mรผller

          ๐Ÿ›
          Kevin Guerra
          Kevin Guerra

          ๐Ÿ’ป
          Kevin Jones
          Kevin Jones

          ๐Ÿ› ๐Ÿ’ป
          Kevin Poorman
          Kevin Poorman

          ๐Ÿ›
          Kevin Wayne
          Kevin Wayne

          ๐Ÿ›
          Kieran Black
          Kieran Black

          ๐Ÿ›
          Kirill Zubov
          Kirill Zubov

          ๐Ÿ›
          Kirill Zubov
          Kirill Zubov

          ๐Ÿ›
          Kirk Clemens
          Kirk Clemens

          ๐Ÿ’ป ๐Ÿ›
          Klaus Hartl
          Klaus Hartl

          ๐Ÿ›
          Koen Van Looveren
          Koen Van Looveren

          ๐Ÿ›
          Kris Scheibe
          Kris Scheibe

          ๐Ÿ’ป ๐Ÿ›
          Krystian Dabrowski
          Krystian Dabrowski

          ๐Ÿ› ๐Ÿ’ป
          Krzysztof Dymek
          Krzysztof Dymek

          ๐Ÿ›
          Kunal Thanki
          Kunal Thanki

          ๐Ÿ›
          Kunal Thanki
          Kunal Thanki

          ๐Ÿ›
          Kursat Aktas
          Kursat Aktas

          ๐Ÿ“–
          LaLucid
          LaLucid

          ๐Ÿ’ป
          Larry Diamond
          Larry Diamond

          ๐Ÿ’ป ๐Ÿ›
          Lars Knickrehm
          Lars Knickrehm

          ๐Ÿ›
          Laurent Bovet
          Laurent Bovet

          ๐Ÿ› ๐Ÿ’ป
          Leo Gutierrez
          Leo Gutierrez

          ๐Ÿ›
          LiGaOg
          LiGaOg

          ๐Ÿ’ป
          LiGaOg
          LiGaOg

          ๐Ÿ’ป
          Liam Sharp
          Liam Sharp

          ๐Ÿ›
          Lintsi
          Lintsi

          ๐Ÿ›
          Linus Fernandes
          Linus Fernandes

          ๐Ÿ›
          Lixon Lookose
          Lixon Lookose

          ๐Ÿ›
          Logesh
          Logesh

          ๐Ÿ›
          Lorenzo Gabriele
          Lorenzo Gabriele

          ๐Ÿ›
          Loรฏc Ledoyen
          Loรฏc Ledoyen

          ๐Ÿ›
          Loรฏc Ledoyen
          Loรฏc Ledoyen

          ๐Ÿ›
          Lucas
          Lucas

          ๐Ÿ›
          Lucas Silva
          Lucas Silva

          ๐Ÿ›
          Lucas Soncini
          Lucas Soncini

          ๐Ÿ’ป ๐Ÿ›
          Luis Alcantar
          Luis Alcantar

          ๐Ÿ’ป
          Lukas Grรคf
          Lukas Grรคf

          ๐Ÿ’ป
          Lukasz Slonina
          Lukasz Slonina

          ๐Ÿ›
          Lukebray
          Lukebray

          ๐Ÿ›
          Lukebray
          Lukebray

          ๐Ÿ›
          Lynn
          Lynn

          ๐Ÿ’ป ๐Ÿ›
          Lyor Goldstein
          Lyor Goldstein

          ๐Ÿ›
          MCMicS
          MCMicS

          ๐Ÿ›
          Macarse
          Macarse

          ๐Ÿ›
          Machine account for PMD
          Machine account for PMD

          ๐Ÿ’ป
          Maciek Siemczyk
          Maciek Siemczyk

          ๐Ÿ›
          Maikel Steneker
          Maikel Steneker

          ๐Ÿ’ป ๐Ÿ›
          Maikel Steneker
          Maikel Steneker

          ๐Ÿ’ป ๐Ÿ›
          Maksim Moiseikin
          Maksim Moiseikin

          ๐Ÿ›
          Manfred Koch
          Manfred Koch

          ๐Ÿ›
          Manuel Moya Ferrer
          Manuel Moya Ferrer

          ๐Ÿ’ป ๐Ÿ›
          Manuel Romeiro
          Manuel Romeiro

          ๐Ÿ›
          Manuel Ryan
          Manuel Ryan

          ๐Ÿ›
          Marat Vyshegorodtsev
          Marat Vyshegorodtsev

          ๐Ÿ›
          Marcel Hรคrle
          Marcel Hรคrle

          ๐Ÿ›
          Marcel Hรคrle
          Marcel Hรคrle

          ๐Ÿ›
          Marcello Fialho
          Marcello Fialho

          ๐Ÿ›
          Marcin Dฤ…browski
          Marcin Dฤ…browski

          ๐Ÿ’ป ๐Ÿ›
          Marcin Rataj
          Marcin Rataj

          ๐Ÿ›
          Marcono1234
          Marcono1234

          ๐Ÿ›
          Mark Adamcin
          Mark Adamcin

          ๐Ÿ›
          Mark Hall
          Mark Hall

          ๐Ÿ’ป ๐Ÿ›
          Mark Kolich
          Mark Kolich

          ๐Ÿ›
          Mark Kolich
          Mark Kolich

          ๐Ÿ›
          Mark Pritchard
          Mark Pritchard

          ๐Ÿ›
          Markus Rathgeb
          Markus Rathgeb

          ๐Ÿ›
          Marquis Wang
          Marquis Wang

          ๐Ÿ›
          MartGit
          MartGit

          ๐Ÿ›
          Martin Feldsztejn
          Martin Feldsztejn

          ๐Ÿ›
          Martin Lehmann
          Martin Lehmann

          ๐Ÿ›
          Martin Spamer
          Martin Spamer

          ๐Ÿ›
          Martin Spamer
          Martin Spamer

          ๐Ÿ›
          Martin Tarjรกnyi
          Martin Tarjรกnyi

          ๐Ÿ›
          MatFl
          MatFl

          ๐Ÿ›
          Mateusz Stefanski
          Mateusz Stefanski

          ๐Ÿ›
          Mathias Lagerwall
          Mathias Lagerwall

          ๐Ÿ›
          Mathieu Gouin
          Mathieu Gouin

          ๐Ÿ›
          MatiasComercio
          MatiasComercio

          ๐Ÿ’ป ๐Ÿ›
          Matt Benson
          Matt Benson

          ๐Ÿ›
          Matt Benson
          Matt Benson

          ๐Ÿ›
          Matt De Poorter
          Matt De Poorter

          ๐Ÿ›
          Matt Hargett
          Matt Hargett

          ๐Ÿ’ป ๐Ÿ’ต
          Matt Harrah
          Matt Harrah

          ๐Ÿ›
          Matt Nelson
          Matt Nelson

          ๐Ÿ›
          Matthew Amos
          Matthew Amos

          ๐Ÿ›
          Matthew Duggan
          Matthew Duggan

          ๐Ÿ›
          Matthew Hall
          Matthew Hall

          ๐Ÿ›
          Matthew Hall
          Matthew Hall

          ๐Ÿ›
          Matthew Rossner
          Matthew Rossner

          ๐Ÿ›
          Matรญas Fraga
          Matรญas Fraga

          ๐Ÿ’ป ๐Ÿ›
          Maxime Robert
          Maxime Robert

          ๐Ÿ’ป ๐Ÿ›
          MetaBF
          MetaBF

          ๐Ÿ›
          Metin Dagcilar
          Metin Dagcilar

          ๐Ÿ›
          Michael
          Michael

          ๐Ÿ›
          Michael Bell
          Michael Bell

          ๐Ÿ›
          Michael Bell
          Michael Bell

          ๐Ÿ›
          Michael Bernstein
          Michael Bernstein

          ๐Ÿ›
          Michael Clay
          Michael Clay

          ๐Ÿ›
          Michael Dombrowski
          Michael Dombrowski

          ๐Ÿ›
          Michael Hausegger
          Michael Hausegger

          ๐Ÿ›
          Michael Hoefer
          Michael Hoefer

          ๐Ÿ›
          Michael Kolesnikov
          Michael Kolesnikov

          ๐Ÿ›
          Michael Mรถbius
          Michael Mรถbius

          ๐Ÿ›
          Michael Mรถbius
          Michael Mรถbius

          ๐Ÿ›
          Michael N. Lipp
          Michael N. Lipp

          ๐Ÿ›
          Michael Pellegrini
          Michael Pellegrini

          ๐Ÿ›
          Michal Kordas
          Michal Kordas

          ๐Ÿ›
          Michaล‚ Borek
          Michaล‚ Borek

          ๐Ÿ›
          Michaล‚ Kuliล„ski
          Michaล‚ Kuliล„ski

          ๐Ÿ›
          Miguel Nรบรฑez Dรญaz-Montes
          Miguel Nรบรฑez Dรญaz-Montes

          ๐Ÿ›
          Mihai Ionut
          Mihai Ionut

          ๐Ÿ›
          Mihai Ionut
          Mihai Ionut

          ๐Ÿ›
          Mikhail Kuchma
          Mikhail Kuchma

          ๐Ÿ›
          MiladSadinam
          MiladSadinam

          ๐Ÿ›
          Mirek Hankus
          Mirek Hankus

          ๐Ÿ›
          Mitch Spano
          Mitch Spano

          ๐Ÿ’ป ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          MrAngry52
          MrAngry52

          ๐Ÿ›
          MrAngry52
          MrAngry52

          ๐Ÿ›
          Muminur Choudhury
          Muminur Choudhury

          ๐Ÿ›
          Mykhailo Palahuta
          Mykhailo Palahuta

          ๐Ÿ’ป ๐Ÿ›
          Nagendra Kumar Singh
          Nagendra Kumar Singh

          ๐Ÿ›
          Nahuel Barrios
          Nahuel Barrios

          ๐Ÿ›
          Nakul Sharma
          Nakul Sharma

          ๐Ÿ›
          Nathan Braun
          Nathan Braun

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathanaรซl
          Nathanaรซl

          ๐Ÿ›
          Naveen
          Naveen

          ๐Ÿ’ป
          Nazdravi
          Nazdravi

          ๐Ÿ›
          Neha-Dhonde
          Neha-Dhonde

          ๐Ÿ›
          Nicholas Doyle
          Nicholas Doyle

          ๐Ÿ›
          Nick Butcher
          Nick Butcher

          ๐Ÿ›
          Nick Butcher
          Nick Butcher

          ๐Ÿ›
          Nico Gallinal
          Nico Gallinal

          ๐Ÿ›
          Nicola Dal Maso
          Nicola Dal Maso

          ๐Ÿ›
          Nicolas Filotto
          Nicolas Filotto

          ๐Ÿ’ป
          Nicolas Vervelle
          Nicolas Vervelle

          ๐Ÿ›
          Nicolas Vuillamy
          Nicolas Vuillamy

          ๐Ÿ“–
          Nikita Chursin
          Nikita Chursin

          ๐Ÿ›
          Niklas Baudy
          Niklas Baudy

          ๐Ÿ›
          Niklas Baudy
          Niklas Baudy

          ๐Ÿ›
          Nikolas Havrikov
          Nikolas Havrikov

          ๐Ÿ›
          Nilesh Virkar
          Nilesh Virkar

          ๐Ÿ›
          Nimit Patel
          Nimit Patel

          ๐Ÿ›
          Niranjan Harpale
          Niranjan Harpale

          ๐Ÿ›
          Nirvik Patel
          Nirvik Patel

          ๐Ÿ’ป
          Noah Sussman
          Noah Sussman

          ๐Ÿ›
          Noah0120
          Noah0120

          ๐Ÿ›
          Noah0120
          Noah0120

          ๐Ÿ›
          Noam Tamim
          Noam Tamim

          ๐Ÿ›
          Noel Grandin
          Noel Grandin

          ๐Ÿ›
          Olaf Haalstra
          Olaf Haalstra

          ๐Ÿ›
          Oleg Andreych
          Oleg Andreych

          ๐Ÿ’ป ๐Ÿ›
          Oleg Pavlenko
          Oleg Pavlenko

          ๐Ÿ›
          Oleksii Dykov
          Oleksii Dykov

          ๐Ÿ’ป ๐Ÿ›
          Oliver Eikemeier
          Oliver Eikemeier

          ๐Ÿ›
          Oliver Eikemeier
          Oliver Eikemeier

          ๐Ÿ›
          Oliver Siegmar
          Oliver Siegmar

          ๐Ÿ’ต
          Olivier Parent
          Olivier Parent

          ๐Ÿ’ป ๐Ÿ›
          Ollie Abbey
          Ollie Abbey

          ๐Ÿ’ป ๐Ÿ›
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)

          ๐Ÿ›
          Ondrej Kratochvil
          Ondrej Kratochvil

          ๐Ÿ›
          OverDrone
          OverDrone

          ๐Ÿ›
          Ozan Gulle
          Ozan Gulle

          ๐Ÿ’ป ๐Ÿ›
          Ozan Gulle
          Ozan Gulle

          ๐Ÿ’ป ๐Ÿ›
          PUNEET JAIN
          PUNEET JAIN

          ๐Ÿ›
          Parbati Bose
          Parbati Bose

          ๐Ÿ›
          Paul Berg
          Paul Berg

          ๐Ÿ›
          Paul Guyot
          Paul Guyot

          ๐Ÿ’ป
          Pavel Bludov
          Pavel Bludov

          ๐Ÿ›
          Pavel Miฤka
          Pavel Miฤka

          ๐Ÿ›
          Pedro Nuno Santos
          Pedro Nuno Santos

          ๐Ÿ›
          Pedro Nuno Santos
          Pedro Nuno Santos

          ๐Ÿ›
          Pedro Rijo
          Pedro Rijo

          ๐Ÿ›
          Pelisse Romain
          Pelisse Romain

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
          Per Abich
          Per Abich

          ๐Ÿ’ป
          Pete Davids
          Pete Davids

          ๐Ÿ›
          Peter Bruin
          Peter Bruin

          ๐Ÿ›
          Peter Chittum
          Peter Chittum

          ๐Ÿ’ป ๐Ÿ›
          Peter Cudmore
          Peter Cudmore

          ๐Ÿ›
          Peter Cudmore
          Peter Cudmore

          ๐Ÿ›
          Peter Kasson
          Peter Kasson

          ๐Ÿ›
          Peter Kofler
          Peter Kofler

          ๐Ÿ›
          Peter Paul Bakker
          Peter Paul Bakker

          ๐Ÿ’ป ๐Ÿ›
          Peter Rader
          Peter Rader

          ๐Ÿ›
          Pham Hai Trung
          Pham Hai Trung

          ๐Ÿ›
          Philip Graf
          Philip Graf

          ๐Ÿ’ป ๐Ÿ›
          Philip Hachey
          Philip Hachey

          ๐Ÿ›
          Philip Hachey
          Philip Hachey

          ๐Ÿ›
          Philippe Ozil
          Philippe Ozil

          ๐Ÿ›
          Phinehas Artemix
          Phinehas Artemix

          ๐Ÿ›
          Phokham Nonava
          Phokham Nonava

          ๐Ÿ›
          Pim van der Loos
          Pim van der Loos

          ๐Ÿ’ป โš ๏ธ
          Piotr Szymaล„ski
          Piotr Szymaล„ski

          ๐Ÿ›
          Piotrek ลปygieล‚o
          Piotrek ลปygieล‚o

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“–
          Pranay Jaiswal
          Pranay Jaiswal

          ๐Ÿ›
          Pranay Jaiswal
          Pranay Jaiswal

          ๐Ÿ›
          Prasad Kamath
          Prasad Kamath

          ๐Ÿ›
          Prasanna
          Prasanna

          ๐Ÿ›
          Presh-AR
          Presh-AR

          ๐Ÿ›
          Puneet1726
          Puneet1726

          ๐Ÿ›
          RBRi
          RBRi

          ๐Ÿ›
          Rafael Cortรชs
          Rafael Cortรชs

          ๐Ÿ›
          RaheemShaik999
          RaheemShaik999

          ๐Ÿ›
          RaheemShaik999
          RaheemShaik999

          ๐Ÿ›
          RajeshR
          RajeshR

          ๐Ÿ’ป ๐Ÿ›
          Ramachandra Mohan
          Ramachandra Mohan

          ๐Ÿ›
          Ramel0921
          Ramel0921

          ๐Ÿ›
          Raquel Pau
          Raquel Pau

          ๐Ÿ›
          Ravikiran Janardhana
          Ravikiran Janardhana

          ๐Ÿ›
          Reda Benhemmouche
          Reda Benhemmouche

          ๐Ÿ›
          Reinhard Schiedermeier
          Reinhard Schiedermeier

          ๐Ÿ›
          Reinhard Schiedermeier
          Reinhard Schiedermeier

          ๐Ÿ›
          Renato Oliveira
          Renato Oliveira

          ๐Ÿ’ป ๐Ÿ›
          Rich DiCroce
          Rich DiCroce

          ๐Ÿ›
          Richard Corfield
          Richard Corfield

          ๐Ÿ’ป
          Richard Corfield
          Richard Corfield

          ๐Ÿ› ๐Ÿ’ป
          Riot R1cket
          Riot R1cket

          ๐Ÿ›
          Rishabh Jain
          Rishabh Jain

          ๐Ÿ›
          RishabhDeep Singh
          RishabhDeep Singh

          ๐Ÿ›
          RishabhDeep Singh
          RishabhDeep Singh

          ๐Ÿ›
          Rob Baillie
          Rob Baillie

          ๐Ÿ›
          Robbie Martinus
          Robbie Martinus

          ๐Ÿ’ป ๐Ÿ›
          Robert Henry
          Robert Henry

          ๐Ÿ›
          Robert Mihaly
          Robert Mihaly

          ๐Ÿ›
          Robert Painsi
          Robert Painsi

          ๐Ÿ›
          Robert Russell
          Robert Russell

          ๐Ÿ›
          Robert Sรถsemann
          Robert Sรถsemann

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ›
          Robert Sรถsemann
          Robert Sรถsemann

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ›
          Robert Whitebit
          Robert Whitebit

          ๐Ÿ›
          Robin Richtsfeld
          Robin Richtsfeld

          ๐Ÿ›
          Robin Stocker
          Robin Stocker

          ๐Ÿ’ป ๐Ÿ›
          Robin Wils
          Robin Wils

          ๐Ÿ›
          RochusOest
          RochusOest

          ๐Ÿ›
          Rodolfo Noviski
          Rodolfo Noviski

          ๐Ÿ›
          Rodrigo Casara
          Rodrigo Casara

          ๐Ÿ›
          Rodrigo Casara
          Rodrigo Casara

          ๐Ÿ›
          Rodrigo Fernandes
          Rodrigo Fernandes

          ๐Ÿ›
          Roman Salvador
          Roman Salvador

          ๐Ÿ’ป ๐Ÿ›
          Ronald Blaschke
          Ronald Blaschke

          ๐Ÿ›
          Rรณbert Papp
          Rรณbert Papp

          ๐Ÿ›
          Saikat Sengupta
          Saikat Sengupta

          ๐Ÿ›
          Saksham Handu
          Saksham Handu

          ๐Ÿ›
          Saladoc
          Saladoc

          ๐Ÿ›
          Saladoc
          Saladoc

          ๐Ÿ›
          Salesforce Bob Lightning
          Salesforce Bob Lightning

          ๐Ÿ›
          Sam Carlberg
          Sam Carlberg

          ๐Ÿ›
          Sascha Riemer
          Sascha Riemer

          ๐Ÿ›
          Sashko
          Sashko

          ๐Ÿ’ป
          Satoshi Kubo
          Satoshi Kubo

          ๐Ÿ›
          Scott Kennedy
          Scott Kennedy

          ๐Ÿ›
          Scott Wells
          Scott Wells

          ๐Ÿ› ๐Ÿ’ป
          Scott Wells
          Scott Wells

          ๐Ÿ› ๐Ÿ’ป
          Scrates1
          Scrates1

          ๐Ÿ› ๐Ÿ’ป
          Scrsloota
          Scrsloota

          ๐Ÿ’ป
          Sebastian Bรถgl
          Sebastian Bรถgl

          ๐Ÿ›
          Sebastian Davids
          Sebastian Davids

          ๐Ÿ›
          Sebastian Lรถvdahl
          Sebastian Lรถvdahl

          ๐Ÿ›
          Sebastian Schuberth
          Sebastian Schuberth

          ๐Ÿ›
          Sebastian Schwarz
          Sebastian Schwarz

          ๐Ÿ›
          Sebastian Schwarz
          Sebastian Schwarz

          ๐Ÿ›
          Seren
          Seren

          ๐Ÿ› ๐Ÿ’ป
          Sergey Gorbaty
          Sergey Gorbaty

          ๐Ÿ›
          Sergey Kozlov
          Sergey Kozlov

          ๐Ÿ›
          Sergey Yanzin
          Sergey Yanzin

          ๐Ÿ’ป ๐Ÿ›
          Seth Wilcox
          Seth Wilcox

          ๐Ÿ’ป
          Shai Bennathan
          Shai Bennathan

          ๐Ÿ› ๐Ÿ’ป
          Shubham
          Shubham

          ๐Ÿ’ป ๐Ÿ›
          Shubham
          Shubham

          ๐Ÿ’ป ๐Ÿ›
          Simon Abykov
          Simon Abykov

          ๐Ÿ’ป ๐Ÿ›
          Simon Xiao
          Simon Xiao

          ๐Ÿ›
          Srinivasan Venkatachalam
          Srinivasan Venkatachalam

          ๐Ÿ›
          Stanislav Gromov
          Stanislav Gromov

          ๐Ÿ›
          Stanislav Myachenkov
          Stanislav Myachenkov

          ๐Ÿ’ป
          Stefan Birkner
          Stefan Birkner

          ๐Ÿ›
          Stefan Bohn
          Stefan Bohn

          ๐Ÿ›
          Stefan Bohn
          Stefan Bohn

          ๐Ÿ›
          Stefan Endrullis
          Stefan Endrullis

          ๐Ÿ›
          Stefan Klรถss-Schuster
          Stefan Klรถss-Schuster

          ๐Ÿ›
          Stefan Wolf
          Stefan Wolf

          ๐Ÿ›
          Stephan H. Wissel
          Stephan H. Wissel

          ๐Ÿ›
          Stephen
          Stephen

          ๐Ÿ›
          Stephen Carter
          Stephen Carter

          ๐Ÿ›
          Stephen Friedrich
          Stephen Friedrich

          ๐Ÿ›
          Stephen Friedrich
          Stephen Friedrich

          ๐Ÿ›
          Steve Babula
          Steve Babula

          ๐Ÿ’ป
          Steven Stearns
          Steven Stearns

          ๐Ÿ› ๐Ÿ’ป
          Stexxe
          Stexxe

          ๐Ÿ›
          Stian Lรฅgstad
          Stian Lรฅgstad

          ๐Ÿ›
          StuartClayton5
          StuartClayton5

          ๐Ÿ›
          Supun Arunoda
          Supun Arunoda

          ๐Ÿ›
          Suren Abrahamyan
          Suren Abrahamyan

          ๐Ÿ›
          Suren Abrahamyan
          Suren Abrahamyan

          ๐Ÿ›
          Suvashri
          Suvashri

          ๐Ÿ“–
          Sven Barden
          Sven Barden

          ๐Ÿ›
          SwatiBGupta1110
          SwatiBGupta1110

          ๐Ÿ›
          SyedThoufich
          SyedThoufich

          ๐Ÿ›
          Szymon Sasin
          Szymon Sasin

          ๐Ÿ›
          T-chuangxin
          T-chuangxin

          ๐Ÿ›
          TERAI Atsuhiro
          TERAI Atsuhiro

          ๐Ÿ›
          TERAI Atsuhiro
          TERAI Atsuhiro

          ๐Ÿ›
          TIOBE Software
          TIOBE Software

          ๐Ÿ’ป ๐Ÿ›
          Tarush Singh
          Tarush Singh

          ๐Ÿ’ป
          Taylor Smock
          Taylor Smock

          ๐Ÿ›
          Techeira Damiรกn
          Techeira Damiรกn

          ๐Ÿ’ป ๐Ÿ›
          Ted Husted
          Ted Husted

          ๐Ÿ›
          TehBakker
          TehBakker

          ๐Ÿ›
          The Gitter Badger
          The Gitter Badger

          ๐Ÿ›
          The Gitter Badger
          The Gitter Badger

          ๐Ÿ›
          Theodoor
          Theodoor

          ๐Ÿ›
          Thiago Henrique Hรผpner
          Thiago Henrique Hรผpner

          ๐Ÿ›
          Thibault Meyer
          Thibault Meyer

          ๐Ÿ›
          Thomas Gรผttler
          Thomas Gรผttler

          ๐Ÿ›
          Thomas Jones-Low
          Thomas Jones-Low

          ๐Ÿ›
          Thomas Smith
          Thomas Smith

          ๐Ÿ’ป ๐Ÿ›
          ThrawnCA
          ThrawnCA

          ๐Ÿ›
          ThrawnCA
          ThrawnCA

          ๐Ÿ›
          Thu Vo
          Thu Vo

          ๐Ÿ›
          Thunderforge
          Thunderforge

          ๐Ÿ’ป ๐Ÿ›
          Tim van der Lippe
          Tim van der Lippe

          ๐Ÿ›
          Tobias Weimer
          Tobias Weimer

          ๐Ÿ’ป ๐Ÿ›
          Tom Copeland
          Tom Copeland

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–
          Tom Daly
          Tom Daly

          ๐Ÿ›
          Tomas
          Tomas

          ๐Ÿ›
          Tomas
          Tomas

          ๐Ÿ›
          Tomer Figenblat
          Tomer Figenblat

          ๐Ÿ›
          Tomi De Lucca
          Tomi De Lucca

          ๐Ÿ’ป ๐Ÿ›
          Tony
          Tony

          ๐Ÿ“–
          Torsten Kleiber
          Torsten Kleiber

          ๐Ÿ›
          Torsten Krause
          Torsten Krause

          ๐Ÿ›
          TrackerSB
          TrackerSB

          ๐Ÿ›
          Tyson Stewart
          Tyson Stewart

          ๐Ÿ›
          Tyson Stewart
          Tyson Stewart

          ๐Ÿ›
          Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ›
          Utku Cuhadaroglu
          Utku Cuhadaroglu

          ๐Ÿ’ป ๐Ÿ›
          Valentin Brandl
          Valentin Brandl

          ๐Ÿ›
          Valeria
          Valeria

          ๐Ÿ›
          Valery Yatsynovich
          Valery Yatsynovich

          ๐Ÿ“–
          Vasily Anisimov
          Vasily Anisimov

          ๐Ÿ›
          Vedant Chokshi
          Vedant Chokshi

          ๐Ÿ›
          Vedant Chokshi
          Vedant Chokshi

          ๐Ÿ›
          Vibhor Goyal
          Vibhor Goyal

          ๐Ÿ›
          Vickenty Fesunov
          Vickenty Fesunov

          ๐Ÿ›
          Victor Noรซl
          Victor Noรซl

          ๐Ÿ›
          Vincent Galloy
          Vincent Galloy

          ๐Ÿ’ป
          Vincent HUYNH
          Vincent HUYNH

          ๐Ÿ›
          Vincent Maurin
          Vincent Maurin

          ๐Ÿ›
          Vincent Potucek
          Vincent Potucek

          ๐Ÿ’ป
          Vincent Potucek
          Vincent Potucek

          ๐Ÿ’ป
          Vincent Privat
          Vincent Privat

          ๐Ÿ›
          Vishhwas
          Vishhwas

          ๐Ÿ›
          Vishv_Android
          Vishv_Android

          ๐Ÿ›
          Vitalii Yevtushenko
          Vitalii Yevtushenko

          ๐Ÿ›
          Vitaly
          Vitaly

          ๐Ÿ›
          Vitaly Polonetsky
          Vitaly Polonetsky

          ๐Ÿ›
          Vojtech Polivka
          Vojtech Polivka

          ๐Ÿ›
          Vojtech Polivka
          Vojtech Polivka

          ๐Ÿ›
          Vsevolod Zholobov
          Vsevolod Zholobov

          ๐Ÿ›
          Vyom Yadav
          Vyom Yadav

          ๐Ÿ’ป
          Wang Shidong
          Wang Shidong

          ๐Ÿ›
          Waqas Ahmed
          Waqas Ahmed

          ๐Ÿ›
          Wayne J. Earl
          Wayne J. Earl

          ๐Ÿ›
          Wchenghui
          Wchenghui

          ๐Ÿ›
          Wener
          Wener

          ๐Ÿ’ป
          Wener
          Wener

          ๐Ÿ’ป
          Will Winder
          Will Winder

          ๐Ÿ›
          Willem A. Hajenius
          Willem A. Hajenius

          ๐Ÿ’ป
          William Brockhus
          William Brockhus

          ๐Ÿ’ป ๐Ÿ›
          Wilson Kurniawan
          Wilson Kurniawan

          ๐Ÿ›
          Wim Deblauwe
          Wim Deblauwe

          ๐Ÿ›
          Wolf2323
          Wolf2323

          ๐Ÿ›
          Woongsik Choi
          Woongsik Choi

          ๐Ÿ›
          Woongsik Choi
          Woongsik Choi

          ๐Ÿ›
          XenoAmess
          XenoAmess

          ๐Ÿ’ป ๐Ÿ›
          Yang
          Yang

          ๐Ÿ’ป
          YaroslavTER
          YaroslavTER

          ๐Ÿ›
          Yasar Shaikh
          Yasar Shaikh

          ๐Ÿ’ป
          Young Chan
          Young Chan

          ๐Ÿ’ป ๐Ÿ›
          YuJin Kim
          YuJin Kim

          ๐Ÿ›
          Yuri Dolzhenko
          Yuri Dolzhenko

          ๐Ÿ›
          Yuri Dolzhenko
          Yuri Dolzhenko

          ๐Ÿ›
          Yurii Dubinka
          Yurii Dubinka

          ๐Ÿ›
          Zoltan Farkas
          Zoltan Farkas

          ๐Ÿ›
          Zustin
          Zustin

          ๐Ÿ›
          aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป
          alexmodis
          alexmodis

          ๐Ÿ›
          andreoss
          andreoss

          ๐Ÿ›
          andrey81inmd
          andrey81inmd

          ๐Ÿ’ป ๐Ÿ›
          andrey81inmd
          andrey81inmd

          ๐Ÿ’ป ๐Ÿ›
          anicoara
          anicoara

          ๐Ÿ›
          arunprasathav
          arunprasathav

          ๐Ÿ›
          asiercamara
          asiercamara

          ๐Ÿ›
          astillich-igniti
          astillich-igniti

          ๐Ÿ’ป
          avesolovksyy
          avesolovksyy

          ๐Ÿ›
          avishvat
          avishvat

          ๐Ÿ›
          avivmu
          avivmu

          ๐Ÿ›
          avivmu
          avivmu

          ๐Ÿ›
          axelbarfod1
          axelbarfod1

          ๐Ÿ›
          b-3-n
          b-3-n

          ๐Ÿ›
          balbhadra9
          balbhadra9

          ๐Ÿ›
          base23de
          base23de

          ๐Ÿ›
          bergander
          bergander

          ๐Ÿ› ๐Ÿ’ป
          berkam
          berkam

          ๐Ÿ’ป ๐Ÿ›
          breizh31
          breizh31

          ๐Ÿ›
          breizh31
          breizh31

          ๐Ÿ›
          caesarkim
          caesarkim

          ๐Ÿ›
          caiocarvalhotero
          caiocarvalhotero

          ๐Ÿ›
          carolyujing
          carolyujing

          ๐Ÿ›
          cbfiddle
          cbfiddle

          ๐Ÿ›
          cesares-basilico
          cesares-basilico

          ๐Ÿ›
          chrite
          chrite

          ๐Ÿ›
          ciufudean
          ciufudean

          ๐Ÿ“–
          ciufudean
          ciufudean

          ๐Ÿ“–
          cobratbq
          cobratbq

          ๐Ÿ›
          coladict
          coladict

          ๐Ÿ›
          cosmoJFH
          cosmoJFH

          ๐Ÿ›
          cristalp
          cristalp

          ๐Ÿ›
          crunsk
          crunsk

          ๐Ÿ›
          cwholmes
          cwholmes

          ๐Ÿ›
          cyberjj999
          cyberjj999

          ๐Ÿ›
          cyberjj999
          cyberjj999

          ๐Ÿ›
          cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“–
          d1ss0nanz
          d1ss0nanz

          ๐Ÿ›
          dague1
          dague1

          ๐Ÿ“–
          dalizi007
          dalizi007

          ๐Ÿ’ป
          danbrycefairsailcom
          danbrycefairsailcom

          ๐Ÿ›
          dariansanity
          dariansanity

          ๐Ÿ›
          darrenmiliband
          darrenmiliband

          ๐Ÿ›
          darrenmiliband
          darrenmiliband

          ๐Ÿ›
          davidburstrom
          davidburstrom

          ๐Ÿ›
          dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ›
          deepak-patra
          deepak-patra

          ๐Ÿ›
          dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ›
          dinesh150
          dinesh150

          ๐Ÿ›
          diziaq
          diziaq

          ๐Ÿ›
          dreaminpast123
          dreaminpast123

          ๐Ÿ›
          dreaminpast123
          dreaminpast123

          ๐Ÿ›
          duanyanan
          duanyanan

          ๐Ÿ›
          dutt-sanjay
          dutt-sanjay

          ๐Ÿ›
          duursma
          duursma

          ๐Ÿ’ป
          dylanleung
          dylanleung

          ๐Ÿ›
          dzeigler
          dzeigler

          ๐Ÿ›
          eant60
          eant60

          ๐Ÿ›
          ekkirala
          ekkirala

          ๐Ÿ›
          ekkirala
          ekkirala

          ๐Ÿ›
          emersonmoura
          emersonmoura

          ๐Ÿ›
          emouty
          emouty

          ๐Ÿ’ป ๐Ÿ›
          eugenepugach
          eugenepugach

          ๐Ÿ›
          fairy
          fairy

          ๐Ÿ›
          filiprafalowicz
          filiprafalowicz

          ๐Ÿ’ป
          flxbl-io
          flxbl-io

          ๐Ÿ’ต
          foxmason
          foxmason

          ๐Ÿ›
          foxmason
          foxmason

          ๐Ÿ›
          frankegabor
          frankegabor

          ๐Ÿ›
          frankl
          frankl

          ๐Ÿ›
          freafrea
          freafrea

          ๐Ÿ›
          fsapatin
          fsapatin

          ๐Ÿ›
          gearsethenry
          gearsethenry

          ๐Ÿ›
          gracia19
          gracia19

          ๐Ÿ›
          gudzpoz
          gudzpoz

          ๐Ÿ›
          gudzpoz
          gudzpoz

          ๐Ÿ›
          guo fei
          guo fei

          ๐Ÿ›
          gurmsc5
          gurmsc5

          ๐Ÿ›
          gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ›
          haigsn
          haigsn

          ๐Ÿ›
          hemanshu070
          hemanshu070

          ๐Ÿ›
          henrik242
          henrik242

          ๐Ÿ›
          hongpuwu
          hongpuwu

          ๐Ÿ›
          hongpuwu
          hongpuwu

          ๐Ÿ›
          hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ›
          igniti GmbH
          igniti GmbH

          ๐Ÿ›
          ilovezfs
          ilovezfs

          ๐Ÿ›
          imax-erik
          imax-erik

          ๐Ÿ›
          itaigilo
          itaigilo

          ๐Ÿ›
          jakivey32
          jakivey32

          ๐Ÿ›
          jbennett2091
          jbennett2091

          ๐Ÿ›
          jbennett2091
          jbennett2091

          ๐Ÿ›
          jcamerin
          jcamerin

          ๐Ÿ›
          jkeener1
          jkeener1

          ๐Ÿ›
          jmetertea
          jmetertea

          ๐Ÿ›
          johnra2
          johnra2

          ๐Ÿ’ป
          johnzhao9
          johnzhao9

          ๐Ÿ›
          josemanuelrolon
          josemanuelrolon

          ๐Ÿ’ป ๐Ÿ›
          julees7
          julees7

          ๐Ÿ’ป ๐Ÿ›
          julees7
          julees7

          ๐Ÿ’ป ๐Ÿ›
          kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ›
          karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“–
          karwer
          karwer

          ๐Ÿ›
          kaulonline
          kaulonline

          ๐Ÿ›
          kdaemonv
          kdaemonv

          ๐Ÿ›
          kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป
          kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ›
          kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ›
          kfranic
          kfranic

          ๐Ÿ›
          khalidkh
          khalidkh

          ๐Ÿ›
          koalalam
          koalalam

          ๐Ÿ›
          krzyk
          krzyk

          ๐Ÿ›
          lasselindqvist
          lasselindqvist

          ๐Ÿ›
          lgemeinhardt
          lgemeinhardt

          ๐Ÿ›
          lihuaib
          lihuaib

          ๐Ÿ›
          lihuaib
          lihuaib

          ๐Ÿ›
          liqingjun123
          liqingjun123

          ๐Ÿ›
          lonelyma1021
          lonelyma1021

          ๐Ÿ›
          lothas
          lothas

          ๐Ÿ›
          lpeddy
          lpeddy

          ๐Ÿ›
          lujiefsi
          lujiefsi

          ๐Ÿ’ป
          lukelukes
          lukelukes

          ๐Ÿ’ป
          lyriccoder
          lyriccoder

          ๐Ÿ›
          lyriccoder
          lyriccoder

          ๐Ÿ›
          marcelmore
          marcelmore

          ๐Ÿ›
          matchbox
          matchbox

          ๐Ÿ›
          matthiaskraaz
          matthiaskraaz

          ๐Ÿ›
          meandonlyme
          meandonlyme

          ๐Ÿ›
          mikesive
          mikesive

          ๐Ÿ›
          milossesic
          milossesic

          ๐Ÿ›
          mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ›
          mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ›
          mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป
          mriddell95
          mriddell95

          ๐Ÿ›
          mrlzh
          mrlzh

          ๐Ÿ›
          msloan
          msloan

          ๐Ÿ›
          mucharlaravalika
          mucharlaravalika

          ๐Ÿ›
          mvenneman
          mvenneman

          ๐Ÿ›
          nareshl119
          nareshl119

          ๐Ÿ›
          nareshl119
          nareshl119

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          noerremark
          noerremark

          ๐Ÿ›
          novsirion
          novsirion

          ๐Ÿ›
          nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป
          oggboy
          oggboy

          ๐Ÿ›
          oinume
          oinume

          ๐Ÿ›
          orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ›
          orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pacvz
          pacvz

          ๐Ÿ’ป
          pallavi agarwal
          pallavi agarwal

          ๐Ÿ›
          pankratz76
          pankratz76

          ๐Ÿ›
          parksungrin
          parksungrin

          ๐Ÿ›
          patpatpat123
          patpatpat123

          ๐Ÿ›
          patriksevallius
          patriksevallius

          ๐Ÿ›
          patriksevallius
          patriksevallius

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          phoenix384
          phoenix384

          ๐Ÿ›
          piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป
          plan3d
          plan3d

          ๐Ÿ›
          poojasix
          poojasix

          ๐Ÿ›
          prabhushrikant
          prabhushrikant

          ๐Ÿ›
          pujitha8783
          pujitha8783

          ๐Ÿ›
          pujitha8783
          pujitha8783

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          raghujayjunk
          raghujayjunk

          ๐Ÿ›
          rajeshveera
          rajeshveera

          ๐Ÿ›
          rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ›
          recdevs
          recdevs

          ๐Ÿ›
          reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ›
          rijkt
          rijkt

          ๐Ÿ›
          rijkt
          rijkt

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ›
          rnveach
          rnveach

          ๐Ÿ›
          rxmicro
          rxmicro

          ๐Ÿ›
          ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ›
          sabi0
          sabi0

          ๐Ÿ›
          samc-gearset
          samc-gearset

          ๐Ÿ“–
          samc-gearset
          samc-gearset

          ๐Ÿ“–
          scais
          scais

          ๐Ÿ›
          schosin
          schosin

          ๐Ÿ›
          screamingfrog
          screamingfrog

          ๐Ÿ’ต
          sebbASF
          sebbASF

          ๐Ÿ›
          sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป
          shilko2013
          shilko2013

          ๐Ÿ›
          shiomiyan
          shiomiyan

          ๐Ÿ“–
          shiomiyan
          shiomiyan

          ๐Ÿ“–
          simeonKondr
          simeonKondr

          ๐Ÿ›
          snajberk
          snajberk

          ๐Ÿ›
          sniperrifle2004
          sniperrifle2004

          ๐Ÿ›
          snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป
          soloturn
          soloturn

          ๐Ÿ›
          soyodream
          soyodream

          ๐Ÿ›
          sratz
          sratz

          ๐Ÿ›
          sratz
          sratz

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          sturton
          sturton

          ๐Ÿ’ป ๐Ÿ›
          sudharmohan
          sudharmohan

          ๐Ÿ›
          suruchidawar
          suruchidawar

          ๐Ÿ›
          svenfinitiv
          svenfinitiv

          ๐Ÿ›
          szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป
          tashiscool
          tashiscool

          ๐Ÿ›
          tashiscool
          tashiscool

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          testation21
          testation21

          ๐Ÿ’ป ๐Ÿ›
          thanosa
          thanosa

          ๐Ÿ›
          tiandiyixian
          tiandiyixian

          ๐Ÿ›
          tobwoerk
          tobwoerk

          ๐Ÿ›
          tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป
          trentchilders
          trentchilders

          ๐Ÿ›
          trentchilders
          trentchilders

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          trishul14
          trishul14

          ๐Ÿ›
          tsui
          tsui

          ๐Ÿ›
          wangzitom12306
          wangzitom12306

          ๐Ÿ›
          winhkey
          winhkey

          ๐Ÿ›
          witherspore
          witherspore

          ๐Ÿ›
          wjljack
          wjljack

          ๐Ÿ›
          wjljack
          wjljack

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          xingsong
          xingsong

          ๐Ÿ›
          xioayuge
          xioayuge

          ๐Ÿ›
          xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ›
          xuanuy
          xuanuy

          ๐Ÿ›
          xyf0921
          xyf0921

          ๐Ÿ›
          yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ›
          yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yasuharu-sato
          yasuharu-sato

          ๐Ÿ›
          zenglian
          zenglian

          ๐Ÿ›
          zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ›
          zh3ng
          zh3ng

          ๐Ÿ›
          zt_soft
          zt_soft

          ๐Ÿ›
          ztt79
          ztt79

          ๐Ÿ›
          ztt79
          ztt79

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ›
          ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ›
          Karl-Philipp Richter
          Karl-Philipp Richter

          ๐Ÿ›
          Karsten Silz
          Karsten Silz

          ๐Ÿ›
          Kazuma Watanabe
          Kazuma Watanabe

          ๐Ÿ›
          Kernevez
          Kernevez

          ๐Ÿ›
          Kev
          Kev

          ๐Ÿ›
          Keve Mรผller
          Keve Mรผller

          ๐Ÿ›
          Keve Mรผller
          Keve Mรผller

          ๐Ÿ›
          Kevin Guerra
          Kevin Guerra

          ๐Ÿ’ป
          Kevin Jones
          Kevin Jones

          ๐Ÿ› ๐Ÿ’ป
          Kevin Poorman
          Kevin Poorman

          ๐Ÿ›
          Kevin Wayne
          Kevin Wayne

          ๐Ÿ›
          Kieran Black
          Kieran Black

          ๐Ÿ›
          Kirill Zubov
          Kirill Zubov

          ๐Ÿ›
          Kirk Clemens
          Kirk Clemens

          ๐Ÿ’ป ๐Ÿ›
          Kirk Clemens
          Kirk Clemens

          ๐Ÿ’ป ๐Ÿ›
          Klaus Hartl
          Klaus Hartl

          ๐Ÿ›
          Koen Van Looveren
          Koen Van Looveren

          ๐Ÿ›
          Kris Scheibe
          Kris Scheibe

          ๐Ÿ’ป ๐Ÿ›
          Krystian Dabrowski
          Krystian Dabrowski

          ๐Ÿ› ๐Ÿ’ป
          Krzysztof Dymek
          Krzysztof Dymek

          ๐Ÿ›
          Kunal Thanki
          Kunal Thanki

          ๐Ÿ›
          Kursat Aktas
          Kursat Aktas

          ๐Ÿ“–
          Kursat Aktas
          Kursat Aktas

          ๐Ÿ“–
          LaLucid
          LaLucid

          ๐Ÿ’ป
          Larry Diamond
          Larry Diamond

          ๐Ÿ’ป ๐Ÿ›
          Lars Knickrehm
          Lars Knickrehm

          ๐Ÿ›
          Laurent Bovet
          Laurent Bovet

          ๐Ÿ› ๐Ÿ’ป
          Leo Gutierrez
          Leo Gutierrez

          ๐Ÿ›
          LiGaOg
          LiGaOg

          ๐Ÿ’ป
          Liam Sharp
          Liam Sharp

          ๐Ÿ›
          Liam Sharp
          Liam Sharp

          ๐Ÿ›
          Lintsi
          Lintsi

          ๐Ÿ›
          Linus Fernandes
          Linus Fernandes

          ๐Ÿ›
          Lixon Lookose
          Lixon Lookose

          ๐Ÿ›
          Logesh
          Logesh

          ๐Ÿ›
          Lorenzo Gabriele
          Lorenzo Gabriele

          ๐Ÿ›
          Loรฏc Ledoyen
          Loรฏc Ledoyen

          ๐Ÿ›
          Lucas
          Lucas

          ๐Ÿ›
          Lucas
          Lucas

          ๐Ÿ›
          Lucas Silva
          Lucas Silva

          ๐Ÿ›
          Lucas Soncini
          Lucas Soncini

          ๐Ÿ’ป ๐Ÿ›
          Luis Alcantar
          Luis Alcantar

          ๐Ÿ’ป
          Lukas Grรคf
          Lukas Grรคf

          ๐Ÿ’ป
          Lukasz Slonina
          Lukasz Slonina

          ๐Ÿ›
          Lukebray
          Lukebray

          ๐Ÿ›
          Lynn
          Lynn

          ๐Ÿ’ป ๐Ÿ›
          Lynn
          Lynn

          ๐Ÿ’ป ๐Ÿ›
          Lyor Goldstein
          Lyor Goldstein

          ๐Ÿ›
          MCMicS
          MCMicS

          ๐Ÿ›
          Macarse
          Macarse

          ๐Ÿ›
          Machine account for PMD
          Machine account for PMD

          ๐Ÿ’ป
          Maciek Siemczyk
          Maciek Siemczyk

          ๐Ÿ›
          Maikel Steneker
          Maikel Steneker

          ๐Ÿ’ป ๐Ÿ›
          Maksim Moiseikin
          Maksim Moiseikin

          ๐Ÿ›
          Maksim Moiseikin
          Maksim Moiseikin

          ๐Ÿ›
          Manfred Koch
          Manfred Koch

          ๐Ÿ›
          Manuel Moya Ferrer
          Manuel Moya Ferrer

          ๐Ÿ’ป ๐Ÿ›
          Manuel Romeiro
          Manuel Romeiro

          ๐Ÿ›
          Manuel Ryan
          Manuel Ryan

          ๐Ÿ›
          Marat Vyshegorodtsev
          Marat Vyshegorodtsev

          ๐Ÿ›
          Marcel Hรคrle
          Marcel Hรคrle

          ๐Ÿ›
          Marcello Fialho
          Marcello Fialho

          ๐Ÿ›
          Marcello Fialho
          Marcello Fialho

          ๐Ÿ›
          Marcin Dฤ…browski
          Marcin Dฤ…browski

          ๐Ÿ’ป ๐Ÿ›
          Marcin Rataj
          Marcin Rataj

          ๐Ÿ›
          Marcono1234
          Marcono1234

          ๐Ÿ›
          Mark Adamcin
          Mark Adamcin

          ๐Ÿ›
          Mark Hall
          Mark Hall

          ๐Ÿ’ป ๐Ÿ›
          Mark Kolich
          Mark Kolich

          ๐Ÿ›
          Mark Pritchard
          Mark Pritchard

          ๐Ÿ›
          Mark Pritchard
          Mark Pritchard

          ๐Ÿ›
          Markus Rathgeb
          Markus Rathgeb

          ๐Ÿ›
          Marquis Wang
          Marquis Wang

          ๐Ÿ›
          MartGit
          MartGit

          ๐Ÿ›
          Martin Feldsztejn
          Martin Feldsztejn

          ๐Ÿ›
          Martin Lehmann
          Martin Lehmann

          ๐Ÿ›
          Martin Spamer
          Martin Spamer

          ๐Ÿ›
          Martin Tarjรกnyi
          Martin Tarjรกnyi

          ๐Ÿ›
          Martin Tarjรกnyi
          Martin Tarjรกnyi

          ๐Ÿ›
          MatFl
          MatFl

          ๐Ÿ›
          Mateusz Stefanski
          Mateusz Stefanski

          ๐Ÿ›
          Mathias Lagerwall
          Mathias Lagerwall

          ๐Ÿ›
          Mathieu Gouin
          Mathieu Gouin

          ๐Ÿ›
          MatiasComercio
          MatiasComercio

          ๐Ÿ’ป ๐Ÿ›
          Matt Benson
          Matt Benson

          ๐Ÿ›
          Matt De Poorter
          Matt De Poorter

          ๐Ÿ›
          Matt De Poorter
          Matt De Poorter

          ๐Ÿ›
          Matt Hargett
          Matt Hargett

          ๐Ÿ’ป ๐Ÿ’ต
          Matt Harrah
          Matt Harrah

          ๐Ÿ›
          Matt Nelson
          Matt Nelson

          ๐Ÿ›
          Matthew Amos
          Matthew Amos

          ๐Ÿ›
          Matthew Duggan
          Matthew Duggan

          ๐Ÿ›
          Matthew Hall
          Matthew Hall

          ๐Ÿ›
          Matthew Rossner
          Matthew Rossner

          ๐Ÿ›
          Matthew Rossner
          Matthew Rossner

          ๐Ÿ›
          Matรญas Fraga
          Matรญas Fraga

          ๐Ÿ’ป ๐Ÿ›
          Maxime Robert
          Maxime Robert

          ๐Ÿ’ป ๐Ÿ›
          MetaBF
          MetaBF

          ๐Ÿ›
          Metin Dagcilar
          Metin Dagcilar

          ๐Ÿ›
          Michael
          Michael

          ๐Ÿ›
          Michael Bell
          Michael Bell

          ๐Ÿ›
          Michael Bernstein
          Michael Bernstein

          ๐Ÿ›
          Michael Bernstein
          Michael Bernstein

          ๐Ÿ›
          Michael Clay
          Michael Clay

          ๐Ÿ›
          Michael Dombrowski
          Michael Dombrowski

          ๐Ÿ›
          Michael Hausegger
          Michael Hausegger

          ๐Ÿ›
          Michael Hoefer
          Michael Hoefer

          ๐Ÿ›
          Michael Kolesnikov
          Michael Kolesnikov

          ๐Ÿ›
          Michael Mรถbius
          Michael Mรถbius

          ๐Ÿ›
          Michael N. Lipp
          Michael N. Lipp

          ๐Ÿ›
          Michael N. Lipp
          Michael N. Lipp

          ๐Ÿ›
          Michael Pellegrini
          Michael Pellegrini

          ๐Ÿ›
          Michal Kordas
          Michal Kordas

          ๐Ÿ›
          Michaล‚ Borek
          Michaล‚ Borek

          ๐Ÿ›
          Michaล‚ Kuliล„ski
          Michaล‚ Kuliล„ski

          ๐Ÿ›
          Miguel Nรบรฑez Dรญaz-Montes
          Miguel Nรบรฑez Dรญaz-Montes

          ๐Ÿ›
          Mihai Ionut
          Mihai Ionut

          ๐Ÿ›
          Mikhail Kuchma
          Mikhail Kuchma

          ๐Ÿ›
          Mikhail Kuchma
          Mikhail Kuchma

          ๐Ÿ›
          MiladSadinam
          MiladSadinam

          ๐Ÿ›
          Mirek Hankus
          Mirek Hankus

          ๐Ÿ›
          Mitch Spano
          Mitch Spano

          ๐Ÿ’ป ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          MrAngry52
          MrAngry52

          ๐Ÿ›
          Muminur Choudhury
          Muminur Choudhury

          ๐Ÿ›
          Muminur Choudhury
          Muminur Choudhury

          ๐Ÿ›
          Mykhailo Palahuta
          Mykhailo Palahuta

          ๐Ÿ’ป ๐Ÿ›
          Nagendra Kumar Singh
          Nagendra Kumar Singh

          ๐Ÿ›
          Nahuel Barrios
          Nahuel Barrios

          ๐Ÿ›
          Nakul Sharma
          Nakul Sharma

          ๐Ÿ›
          Nathan Braun
          Nathan Braun

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathanaรซl
          Nathanaรซl

          ๐Ÿ›
          Naveen
          Naveen

          ๐Ÿ’ป
          Nazdravi
          Nazdravi

          ๐Ÿ›
          Neha-Dhonde
          Neha-Dhonde

          ๐Ÿ›
          Nicholas Doyle
          Nicholas Doyle

          ๐Ÿ›
          Nick Butcher
          Nick Butcher

          ๐Ÿ›
          Nico Gallinal
          Nico Gallinal

          ๐Ÿ›
          Nico Gallinal
          Nico Gallinal

          ๐Ÿ›
          Nicola Dal Maso
          Nicola Dal Maso

          ๐Ÿ›
          Nicolas Filotto
          Nicolas Filotto

          ๐Ÿ’ป
          Nicolas Vervelle
          Nicolas Vervelle

          ๐Ÿ›
          Nicolas Vuillamy
          Nicolas Vuillamy

          ๐Ÿ“–
          Nikita Chursin
          Nikita Chursin

          ๐Ÿ›
          Niklas Baudy
          Niklas Baudy

          ๐Ÿ›
          Nikolas Havrikov
          Nikolas Havrikov

          ๐Ÿ›
          Nikolas Havrikov
          Nikolas Havrikov

          ๐Ÿ›
          Nilesh Virkar
          Nilesh Virkar

          ๐Ÿ›
          Nimit Patel
          Nimit Patel

          ๐Ÿ›
          Niranjan Harpale
          Niranjan Harpale

          ๐Ÿ›
          Nirvik Patel
          Nirvik Patel

          ๐Ÿ’ป
          Noah Sussman
          Noah Sussman

          ๐Ÿ›
          Noah0120
          Noah0120

          ๐Ÿ›
          Noam Tamim
          Noam Tamim

          ๐Ÿ›
          Noam Tamim
          Noam Tamim

          ๐Ÿ›
          Noel Grandin
          Noel Grandin

          ๐Ÿ›
          Olaf Haalstra
          Olaf Haalstra

          ๐Ÿ›
          Oleg Andreych
          Oleg Andreych

          ๐Ÿ’ป ๐Ÿ›
          Oleg Pavlenko
          Oleg Pavlenko

          ๐Ÿ›
          Oleksii Dykov
          Oleksii Dykov

          ๐Ÿ’ป ๐Ÿ›
          Oliver Eikemeier
          Oliver Eikemeier

          ๐Ÿ›
          Oliver Siegmar
          Oliver Siegmar

          ๐Ÿ’ต
          Oliver Siegmar
          Oliver Siegmar

          ๐Ÿ’ต
          Olivier Parent
          Olivier Parent

          ๐Ÿ’ป ๐Ÿ›
          Ollie Abbey
          Ollie Abbey

          ๐Ÿ’ป ๐Ÿ›
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)

          ๐Ÿ›
          Ondrej Kratochvil
          Ondrej Kratochvil

          ๐Ÿ›
          OverDrone
          OverDrone

          ๐Ÿ›
          Ozan Gulle
          Ozan Gulle

          ๐Ÿ’ป ๐Ÿ›
          PUNEET JAIN
          PUNEET JAIN

          ๐Ÿ›
          PUNEET JAIN
          PUNEET JAIN

          ๐Ÿ›
          Parbati Bose
          Parbati Bose

          ๐Ÿ›
          Paul Berg
          Paul Berg

          ๐Ÿ›
          Paul Guyot
          Paul Guyot

          ๐Ÿ’ป
          Pavel Bludov
          Pavel Bludov

          ๐Ÿ›
          Pavel Miฤka
          Pavel Miฤka

          ๐Ÿ›
          Pedro Nuno Santos
          Pedro Nuno Santos

          ๐Ÿ›
          Pedro Rijo
          Pedro Rijo

          ๐Ÿ›
          Pedro Rijo
          Pedro Rijo

          ๐Ÿ›
          Pelisse Romain
          Pelisse Romain

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
          Per Abich
          Per Abich

          ๐Ÿ’ป
          Pete Davids
          Pete Davids

          ๐Ÿ›
          Peter Bruin
          Peter Bruin

          ๐Ÿ›
          Peter Chittum
          Peter Chittum

          ๐Ÿ’ป ๐Ÿ›
          Peter Cudmore
          Peter Cudmore

          ๐Ÿ›
          Peter Kasson
          Peter Kasson

          ๐Ÿ›
          Peter Kasson
          Peter Kasson

          ๐Ÿ›
          Peter Kofler
          Peter Kofler

          ๐Ÿ›
          Peter Paul Bakker
          Peter Paul Bakker

          ๐Ÿ’ป ๐Ÿ›
          Peter Rader
          Peter Rader

          ๐Ÿ›
          Pham Hai Trung
          Pham Hai Trung

          ๐Ÿ›
          Philip Graf
          Philip Graf

          ๐Ÿ’ป ๐Ÿ›
          Philip Hachey
          Philip Hachey

          ๐Ÿ›
          Philippe Ozil
          Philippe Ozil

          ๐Ÿ›
          Philippe Ozil
          Philippe Ozil

          ๐Ÿ›
          Phinehas Artemix
          Phinehas Artemix

          ๐Ÿ›
          Phokham Nonava
          Phokham Nonava

          ๐Ÿ›
          Pim van der Loos
          Pim van der Loos

          ๐Ÿ’ป โš ๏ธ
          Piotr Szymaล„ski
          Piotr Szymaล„ski

          ๐Ÿ›
          Piotrek ลปygieล‚o
          Piotrek ลปygieล‚o

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“–
          Pranay Jaiswal
          Pranay Jaiswal

          ๐Ÿ›
          Prasad Kamath
          Prasad Kamath

          ๐Ÿ›
          Prasad Kamath
          Prasad Kamath

          ๐Ÿ›
          Prasanna
          Prasanna

          ๐Ÿ›
          Presh-AR
          Presh-AR

          ๐Ÿ›
          Puneet1726
          Puneet1726

          ๐Ÿ›
          RBRi
          RBRi

          ๐Ÿ›
          Rafael Cortรชs
          Rafael Cortรชs

          ๐Ÿ›
          RaheemShaik999
          RaheemShaik999

          ๐Ÿ›
          RajeshR
          RajeshR

          ๐Ÿ’ป ๐Ÿ›
          RajeshR
          RajeshR

          ๐Ÿ’ป ๐Ÿ›
          Ramachandra Mohan
          Ramachandra Mohan

          ๐Ÿ›
          Ramel0921
          Ramel0921

          ๐Ÿ›
          Raquel Pau
          Raquel Pau

          ๐Ÿ›
          Ravikiran Janardhana
          Ravikiran Janardhana

          ๐Ÿ›
          Reda Benhemmouche
          Reda Benhemmouche

          ๐Ÿ›
          Reinhard Schiedermeier
          Reinhard Schiedermeier

          ๐Ÿ›
          Renato Oliveira
          Renato Oliveira

          ๐Ÿ’ป ๐Ÿ›
          Renato Oliveira
          Renato Oliveira

          ๐Ÿ’ป ๐Ÿ›
          Rich DiCroce
          Rich DiCroce

          ๐Ÿ›
          Richard Corfield
          Richard Corfield

          ๐Ÿ’ป
          Richard Corfield
          Richard Corfield

          ๐Ÿ› ๐Ÿ’ป
          Riot R1cket
          Riot R1cket

          ๐Ÿ›
          Rishabh Jain
          Rishabh Jain

          ๐Ÿ›
          RishabhDeep Singh
          RishabhDeep Singh

          ๐Ÿ›
          Rob Baillie
          Rob Baillie

          ๐Ÿ›
          Rob Baillie
          Rob Baillie

          ๐Ÿ›
          Robbie Martinus
          Robbie Martinus

          ๐Ÿ’ป ๐Ÿ›
          Robert Henry
          Robert Henry

          ๐Ÿ›
          Robert Mihaly
          Robert Mihaly

          ๐Ÿ›
          Robert Painsi
          Robert Painsi

          ๐Ÿ›
          Robert Russell
          Robert Russell

          ๐Ÿ›
          Robert Sรถsemann
          Robert Sรถsemann

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ›
          Robert Whitebit
          Robert Whitebit

          ๐Ÿ›
          Robert Whitebit
          Robert Whitebit

          ๐Ÿ›
          Robin Richtsfeld
          Robin Richtsfeld

          ๐Ÿ›
          Robin Stocker
          Robin Stocker

          ๐Ÿ’ป ๐Ÿ›
          Robin Wils
          Robin Wils

          ๐Ÿ›
          RochusOest
          RochusOest

          ๐Ÿ›
          Rodolfo Noviski
          Rodolfo Noviski

          ๐Ÿ›
          Rodrigo Casara
          Rodrigo Casara

          ๐Ÿ›
          Rodrigo Fernandes
          Rodrigo Fernandes

          ๐Ÿ›
          Rodrigo Fernandes
          Rodrigo Fernandes

          ๐Ÿ›
          Roman Salvador
          Roman Salvador

          ๐Ÿ’ป ๐Ÿ›
          Ronald Blaschke
          Ronald Blaschke

          ๐Ÿ›
          Rรณbert Papp
          Rรณbert Papp

          ๐Ÿ›
          Saikat Sengupta
          Saikat Sengupta

          ๐Ÿ›
          Saksham Handu
          Saksham Handu

          ๐Ÿ›
          Saladoc
          Saladoc

          ๐Ÿ›
          Salesforce Bob Lightning
          Salesforce Bob Lightning

          ๐Ÿ›
          Salesforce Bob Lightning
          Salesforce Bob Lightning

          ๐Ÿ›
          Sam Carlberg
          Sam Carlberg

          ๐Ÿ›
          Sascha Riemer
          Sascha Riemer

          ๐Ÿ›
          Sashko
          Sashko

          ๐Ÿ’ป
          Satoshi Kubo
          Satoshi Kubo

          ๐Ÿ›
          Scott Kennedy
          Scott Kennedy

          ๐Ÿ›
          Scott Wells
          Scott Wells

          ๐Ÿ› ๐Ÿ’ป
          Scrates1
          Scrates1

          ๐Ÿ› ๐Ÿ’ป
          Scrates1
          Scrates1

          ๐Ÿ› ๐Ÿ’ป
          Scrsloota
          Scrsloota

          ๐Ÿ’ป
          Sebastian Bรถgl
          Sebastian Bรถgl

          ๐Ÿ›
          Sebastian Davids
          Sebastian Davids

          ๐Ÿ›
          Sebastian Lรถvdahl
          Sebastian Lรถvdahl

          ๐Ÿ›
          Sebastian Schuberth
          Sebastian Schuberth

          ๐Ÿ›
          Sebastian Schwarz
          Sebastian Schwarz

          ๐Ÿ›
          Seren
          Seren

          ๐Ÿ› ๐Ÿ’ป
          Seren
          Seren

          ๐Ÿ› ๐Ÿ’ป
          Sergey Gorbaty
          Sergey Gorbaty

          ๐Ÿ›
          Sergey Kozlov
          Sergey Kozlov

          ๐Ÿ›
          Sergey Yanzin
          Sergey Yanzin

          ๐Ÿ’ป ๐Ÿ›
          Seth Wilcox
          Seth Wilcox

          ๐Ÿ’ป
          Shai Bennathan
          Shai Bennathan

          ๐Ÿ› ๐Ÿ’ป
          Shubham
          Shubham

          ๐Ÿ’ป ๐Ÿ›
          Simon Abykov
          Simon Abykov

          ๐Ÿ’ป ๐Ÿ›
          Simon Abykov
          Simon Abykov

          ๐Ÿ’ป ๐Ÿ›
          Simon Xiao
          Simon Xiao

          ๐Ÿ›
          Srinivasan Venkatachalam
          Srinivasan Venkatachalam

          ๐Ÿ›
          Stanislav Gromov
          Stanislav Gromov

          ๐Ÿ›
          Stanislav Myachenkov
          Stanislav Myachenkov

          ๐Ÿ’ป
          Stefan Birkner
          Stefan Birkner

          ๐Ÿ›
          Stefan Bohn
          Stefan Bohn

          ๐Ÿ›
          Stefan Endrullis
          Stefan Endrullis

          ๐Ÿ›
          Stefan Endrullis
          Stefan Endrullis

          ๐Ÿ›
          Stefan Klรถss-Schuster
          Stefan Klรถss-Schuster

          ๐Ÿ›
          Stefan Wolf
          Stefan Wolf

          ๐Ÿ›
          Stephan H. Wissel
          Stephan H. Wissel

          ๐Ÿ›
          Stephen
          Stephen

          ๐Ÿ›
          Stephen Carter
          Stephen Carter

          ๐Ÿ›
          Stephen Friedrich
          Stephen Friedrich

          ๐Ÿ›
          Steve Babula
          Steve Babula

          ๐Ÿ’ป
          Steve Babula
          Steve Babula

          ๐Ÿ’ป
          Steven Stearns
          Steven Stearns

          ๐Ÿ› ๐Ÿ’ป
          Stexxe
          Stexxe

          ๐Ÿ›
          Stian Lรฅgstad
          Stian Lรฅgstad

          ๐Ÿ›
          StuartClayton5
          StuartClayton5

          ๐Ÿ›
          Supun Arunoda
          Supun Arunoda

          ๐Ÿ›
          Suren Abrahamyan
          Suren Abrahamyan

          ๐Ÿ›
          Suvashri
          Suvashri

          ๐Ÿ“–
          Suvashri
          Suvashri

          ๐Ÿ“–
          Sven Barden
          Sven Barden

          ๐Ÿ›
          SwatiBGupta1110
          SwatiBGupta1110

          ๐Ÿ›
          SyedThoufich
          SyedThoufich

          ๐Ÿ›
          Szymon Sasin
          Szymon Sasin

          ๐Ÿ›
          T-chuangxin
          T-chuangxin

          ๐Ÿ›
          TERAI Atsuhiro
          TERAI Atsuhiro

          ๐Ÿ›
          TIOBE Software
          TIOBE Software

          ๐Ÿ’ป ๐Ÿ›
          TIOBE Software
          TIOBE Software

          ๐Ÿ’ป ๐Ÿ›
          Tarush Singh
          Tarush Singh

          ๐Ÿ’ป
          Taylor Smock
          Taylor Smock

          ๐Ÿ›
          Techeira Damiรกn
          Techeira Damiรกn

          ๐Ÿ’ป ๐Ÿ›
          Ted Husted
          Ted Husted

          ๐Ÿ›
          TehBakker
          TehBakker

          ๐Ÿ›
          The Gitter Badger
          The Gitter Badger

          ๐Ÿ›
          Theodoor
          Theodoor

          ๐Ÿ›
          Theodoor
          Theodoor

          ๐Ÿ›
          Thiago Henrique Hรผpner
          Thiago Henrique Hรผpner

          ๐Ÿ›
          Thibault Meyer
          Thibault Meyer

          ๐Ÿ›
          Thomas Gรผttler
          Thomas Gรผttler

          ๐Ÿ›
          Thomas Jones-Low
          Thomas Jones-Low

          ๐Ÿ›
          Thomas Smith
          Thomas Smith

          ๐Ÿ’ป ๐Ÿ›
          ThrawnCA
          ThrawnCA

          ๐Ÿ›
          Thu Vo
          Thu Vo

          ๐Ÿ›
          Thu Vo
          Thu Vo

          ๐Ÿ›
          Thunderforge
          Thunderforge

          ๐Ÿ’ป ๐Ÿ›
          Tim van der Lippe
          Tim van der Lippe

          ๐Ÿ›
          Tobias Weimer
          Tobias Weimer

          ๐Ÿ’ป ๐Ÿ›
          Tom Copeland
          Tom Copeland

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–
          Tom Daly
          Tom Daly

          ๐Ÿ›
          Tomas
          Tomas

          ๐Ÿ›
          Tomer Figenblat
          Tomer Figenblat

          ๐Ÿ›
          Tomer Figenblat
          Tomer Figenblat

          ๐Ÿ›
          Tomi De Lucca
          Tomi De Lucca

          ๐Ÿ’ป ๐Ÿ›
          Tony
          Tony

          ๐Ÿ“–
          Torsten Kleiber
          Torsten Kleiber

          ๐Ÿ›
          Torsten Krause
          Torsten Krause

          ๐Ÿ›
          TrackerSB
          TrackerSB

          ๐Ÿ›
          Tyson Stewart
          Tyson Stewart

          ๐Ÿ›
          Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ›
          Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ›
          Utku Cuhadaroglu
          Utku Cuhadaroglu

          ๐Ÿ’ป ๐Ÿ›
          Valentin Brandl
          Valentin Brandl

          ๐Ÿ›
          Valeria
          Valeria

          ๐Ÿ›
          Valery Yatsynovich
          Valery Yatsynovich

          ๐Ÿ“–
          Vasily Anisimov
          Vasily Anisimov

          ๐Ÿ›
          Vedant Chokshi
          Vedant Chokshi

          ๐Ÿ›
          Vibhor Goyal
          Vibhor Goyal

          ๐Ÿ›
          Vibhor Goyal
          Vibhor Goyal

          ๐Ÿ›
          Vickenty Fesunov
          Vickenty Fesunov

          ๐Ÿ›
          Victor Noรซl
          Victor Noรซl

          ๐Ÿ›
          Vincent Galloy
          Vincent Galloy

          ๐Ÿ’ป
          Vincent HUYNH
          Vincent HUYNH

          ๐Ÿ›
          Vincent Maurin
          Vincent Maurin

          ๐Ÿ›
          Vincent Potucek
          Vincent Potucek

          ๐Ÿ’ป
          Vincent Privat
          Vincent Privat

          ๐Ÿ›
          Vincent Privat
          Vincent Privat

          ๐Ÿ›
          Vishhwas
          Vishhwas

          ๐Ÿ›
          Vishv_Android
          Vishv_Android

          ๐Ÿ›
          Vitalii Yevtushenko
          Vitalii Yevtushenko

          ๐Ÿ›
          Vitaly
          Vitaly

          ๐Ÿ›
          Vitaly Polonetsky
          Vitaly Polonetsky

          ๐Ÿ›
          Vojtech Polivka
          Vojtech Polivka

          ๐Ÿ›
          Vsevolod Zholobov
          Vsevolod Zholobov

          ๐Ÿ›
          Vsevolod Zholobov
          Vsevolod Zholobov

          ๐Ÿ›
          Vyom Yadav
          Vyom Yadav

          ๐Ÿ’ป
          Wang Shidong
          Wang Shidong

          ๐Ÿ›
          Waqas Ahmed
          Waqas Ahmed

          ๐Ÿ›
          Wayne J. Earl
          Wayne J. Earl

          ๐Ÿ›
          Wchenghui
          Wchenghui

          ๐Ÿ›
          Wener
          Wener

          ๐Ÿ’ป
          Will Winder
          Will Winder

          ๐Ÿ›
          Will Winder
          Will Winder

          ๐Ÿ›
          Willem A. Hajenius
          Willem A. Hajenius

          ๐Ÿ’ป
          William Brockhus
          William Brockhus

          ๐Ÿ’ป ๐Ÿ›
          Wilson Kurniawan
          Wilson Kurniawan

          ๐Ÿ›
          Wim Deblauwe
          Wim Deblauwe

          ๐Ÿ›
          Wolf2323
          Wolf2323

          ๐Ÿ›
          Woongsik Choi
          Woongsik Choi

          ๐Ÿ›
          XenoAmess
          XenoAmess

          ๐Ÿ’ป ๐Ÿ›
          XenoAmess
          XenoAmess

          ๐Ÿ’ป ๐Ÿ›
          Yang
          Yang

          ๐Ÿ’ป
          YaroslavTER
          YaroslavTER

          ๐Ÿ›
          Yasar Shaikh
          Yasar Shaikh

          ๐Ÿ’ป
          Young Chan
          Young Chan

          ๐Ÿ’ป ๐Ÿ›
          YuJin Kim
          YuJin Kim

          ๐Ÿ›
          Yuri Dolzhenko
          Yuri Dolzhenko

          ๐Ÿ›
          Yurii Dubinka
          Yurii Dubinka

          ๐Ÿ›
          Yurii Dubinka
          Yurii Dubinka

          ๐Ÿ›
          Zoltan Farkas
          Zoltan Farkas

          ๐Ÿ›
          Zustin
          Zustin

          ๐Ÿ›
          aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป
          alexmodis
          alexmodis

          ๐Ÿ›
          andreoss
          andreoss

          ๐Ÿ›
          andrey81inmd
          andrey81inmd

          ๐Ÿ’ป ๐Ÿ›
          anicoara
          anicoara

          ๐Ÿ›
          anicoara
          anicoara

          ๐Ÿ›
          arunprasathav
          arunprasathav

          ๐Ÿ›
          asiercamara
          asiercamara

          ๐Ÿ›
          astillich-igniti
          astillich-igniti

          ๐Ÿ’ป
          avesolovksyy
          avesolovksyy

          ๐Ÿ›
          avishvat
          avishvat

          ๐Ÿ›
          avivmu
          avivmu

          ๐Ÿ›
          axelbarfod1
          axelbarfod1

          ๐Ÿ›
          axelbarfod1
          axelbarfod1

          ๐Ÿ›
          b-3-n
          b-3-n

          ๐Ÿ›
          balbhadra9
          balbhadra9

          ๐Ÿ›
          base23de
          base23de

          ๐Ÿ›
          bergander
          bergander

          ๐Ÿ› ๐Ÿ’ป
          berkam
          berkam

          ๐Ÿ’ป ๐Ÿ›
          breizh31
          breizh31

          ๐Ÿ›
          caesarkim
          caesarkim

          ๐Ÿ›
          caesarkim
          caesarkim

          ๐Ÿ›
          caiocarvalhotero
          caiocarvalhotero

          ๐Ÿ›
          carolyujing
          carolyujing

          ๐Ÿ›
          cbfiddle
          cbfiddle

          ๐Ÿ›
          cesares-basilico
          cesares-basilico

          ๐Ÿ›
          chrite
          chrite

          ๐Ÿ›
          ciufudean
          ciufudean

          ๐Ÿ“–
          cobratbq
          cobratbq

          ๐Ÿ›
          cobratbq
          cobratbq

          ๐Ÿ›
          coladict
          coladict

          ๐Ÿ›
          cosmoJFH
          cosmoJFH

          ๐Ÿ›
          cristalp
          cristalp

          ๐Ÿ›
          crunsk
          crunsk

          ๐Ÿ›
          cwholmes
          cwholmes

          ๐Ÿ›
          cyberjj999
          cyberjj999

          ๐Ÿ›
          cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“–
          cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“–
          d1ss0nanz
          d1ss0nanz

          ๐Ÿ›
          dague1
          dague1

          ๐Ÿ“–
          dalizi007
          dalizi007

          ๐Ÿ’ป
          danbrycefairsailcom
          danbrycefairsailcom

          ๐Ÿ›
          dariansanity
          dariansanity

          ๐Ÿ›
          darrenmiliband
          darrenmiliband

          ๐Ÿ›
          davidburstrom
          davidburstrom

          ๐Ÿ›
          davidburstrom
          davidburstrom

          ๐Ÿ›
          dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ›
          deepak-patra
          deepak-patra

          ๐Ÿ›
          dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ›
          dinesh150
          dinesh150

          ๐Ÿ›
          diziaq
          diziaq

          ๐Ÿ›
          dreaminpast123
          dreaminpast123

          ๐Ÿ›
          duanyanan
          duanyanan

          ๐Ÿ›
          duanyanan
          duanyanan

          ๐Ÿ›
          dutt-sanjay
          dutt-sanjay

          ๐Ÿ›
          duursma
          duursma

          ๐Ÿ’ป
          dylanleung
          dylanleung

          ๐Ÿ›
          dzeigler
          dzeigler

          ๐Ÿ›
          eant60
          eant60

          ๐Ÿ›
          ekkirala
          ekkirala

          ๐Ÿ›
          emersonmoura
          emersonmoura

          ๐Ÿ›
          emersonmoura
          emersonmoura

          ๐Ÿ›
          emouty
          emouty

          ๐Ÿ’ป ๐Ÿ›
          eugenepugach
          eugenepugach

          ๐Ÿ›
          fairy
          fairy

          ๐Ÿ›
          filiprafalowicz
          filiprafalowicz

          ๐Ÿ’ป
          flxbl-io
          flxbl-io

          ๐Ÿ’ต
          foxmason
          foxmason

          ๐Ÿ›
          frankegabor
          frankegabor

          ๐Ÿ›
          frankegabor
          frankegabor

          ๐Ÿ›
          frankl
          frankl

          ๐Ÿ›
          freafrea
          freafrea

          ๐Ÿ›
          fsapatin
          fsapatin

          ๐Ÿ›
          gearsethenry
          gearsethenry

          ๐Ÿ›
          gracia19
          gracia19

          ๐Ÿ›
          gudzpoz
          gudzpoz

          ๐Ÿ›
          guo fei
          guo fei

          ๐Ÿ›
          guo fei
          guo fei

          ๐Ÿ›
          gurmsc5
          gurmsc5

          ๐Ÿ›
          gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ›
          haigsn
          haigsn

          ๐Ÿ›
          hemanshu070
          hemanshu070

          ๐Ÿ›
          henrik242
          henrik242

          ๐Ÿ›
          hongpuwu
          hongpuwu

          ๐Ÿ›
          hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ›
          hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ›
          igniti GmbH
          igniti GmbH

          ๐Ÿ›
          ilovezfs
          ilovezfs

          ๐Ÿ›
          imax-erik
          imax-erik

          ๐Ÿ›
          itaigilo
          itaigilo

          ๐Ÿ›
          jakivey32
          jakivey32

          ๐Ÿ›
          jbennett2091
          jbennett2091

          ๐Ÿ›
          jcamerin
          jcamerin

          ๐Ÿ›
          jcamerin
          jcamerin

          ๐Ÿ›
          jkeener1
          jkeener1

          ๐Ÿ›
          jmetertea
          jmetertea

          ๐Ÿ›
          johnra2
          johnra2

          ๐Ÿ’ป
          johnzhao9
          johnzhao9

          ๐Ÿ›
          josemanuelrolon
          josemanuelrolon

          ๐Ÿ’ป ๐Ÿ›
          julees7
          julees7

          ๐Ÿ’ป ๐Ÿ›
          kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ›
          kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ›
          karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“–
          karwer
          karwer

          ๐Ÿ›
          kaulonline
          kaulonline

          ๐Ÿ›
          kdaemonv
          kdaemonv

          ๐Ÿ›
          kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป
          kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ›
          kfranic
          kfranic

          ๐Ÿ›
          kfranic
          kfranic

          ๐Ÿ›
          khalidkh
          khalidkh

          ๐Ÿ›
          koalalam
          koalalam

          ๐Ÿ›
          krzyk
          krzyk

          ๐Ÿ›
          lasselindqvist
          lasselindqvist

          ๐Ÿ›
          lgemeinhardt
          lgemeinhardt

          ๐Ÿ›
          lihuaib
          lihuaib

          ๐Ÿ›
          liqingjun123
          liqingjun123

          ๐Ÿ›
          liqingjun123
          liqingjun123

          ๐Ÿ›
          lonelyma1021
          lonelyma1021

          ๐Ÿ›
          lothas
          lothas

          ๐Ÿ›
          lpeddy
          lpeddy

          ๐Ÿ›
          lujiefsi
          lujiefsi

          ๐Ÿ’ป
          lukelukes
          lukelukes

          ๐Ÿ’ป
          lyriccoder
          lyriccoder

          ๐Ÿ›
          marcelmore
          marcelmore

          ๐Ÿ›
          marcelmore
          marcelmore

          ๐Ÿ›
          matchbox
          matchbox

          ๐Ÿ›
          matthiaskraaz
          matthiaskraaz

          ๐Ÿ›
          meandonlyme
          meandonlyme

          ๐Ÿ›
          mikesive
          mikesive

          ๐Ÿ›
          milossesic
          milossesic

          ๐Ÿ›
          mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ›
          mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป
          mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป
          mriddell95
          mriddell95

          ๐Ÿ›
          mrlzh
          mrlzh

          ๐Ÿ›
          msloan
          msloan

          ๐Ÿ›
          mucharlaravalika
          mucharlaravalika

          ๐Ÿ›
          mvenneman
          mvenneman

          ๐Ÿ›
          nareshl119
          nareshl119

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          noerremark
          noerremark

          ๐Ÿ›
          novsirion
          novsirion

          ๐Ÿ›
          nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป
          oggboy
          oggboy

          ๐Ÿ›
          oinume
          oinume

          ๐Ÿ›
          orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pacvz
          pacvz

          ๐Ÿ’ป
          pallavi agarwal
          pallavi agarwal

          ๐Ÿ›
          pankratz76
          pankratz76

          ๐Ÿ›
          parksungrin
          parksungrin

          ๐Ÿ›
          patpatpat123
          patpatpat123

          ๐Ÿ›
          patriksevallius
          patriksevallius

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          phoenix384
          phoenix384

          ๐Ÿ›
          piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป
          plan3d
          plan3d

          ๐Ÿ›
          poojasix
          poojasix

          ๐Ÿ›
          prabhushrikant
          prabhushrikant

          ๐Ÿ›
          pujitha8783
          pujitha8783

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          raghujayjunk
          raghujayjunk

          ๐Ÿ›
          rajeshveera
          rajeshveera

          ๐Ÿ›
          rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ›
          recdevs
          recdevs

          ๐Ÿ›
          reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ›
          rijkt
          rijkt

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ›
          rnveach
          rnveach

          ๐Ÿ›
          rxmicro
          rxmicro

          ๐Ÿ›
          ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ›
          sabi0
          sabi0

          ๐Ÿ›
          samc-gearset
          samc-gearset

          ๐Ÿ“–
          scais
          scais

          ๐Ÿ›
          scais
          scais

          ๐Ÿ›
          schosin
          schosin

          ๐Ÿ›
          screamingfrog
          screamingfrog

          ๐Ÿ’ต
          sebbASF
          sebbASF

          ๐Ÿ›
          sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป
          shilko2013
          shilko2013

          ๐Ÿ›
          shiomiyan
          shiomiyan

          ๐Ÿ“–
          simeonKondr
          simeonKondr

          ๐Ÿ›
          simeonKondr
          simeonKondr

          ๐Ÿ›
          snajberk
          snajberk

          ๐Ÿ›
          sniperrifle2004
          sniperrifle2004

          ๐Ÿ›
          snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป
          soloturn
          soloturn

          ๐Ÿ›
          soyodream
          soyodream

          ๐Ÿ›
          sratz
          sratz

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          sturton
          sturton

          ๐Ÿ’ป ๐Ÿ›
          sudharmohan
          sudharmohan

          ๐Ÿ›
          suruchidawar
          suruchidawar

          ๐Ÿ›
          svenfinitiv
          svenfinitiv

          ๐Ÿ›
          szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป
          tashiscool
          tashiscool

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          testation21
          testation21

          ๐Ÿ’ป ๐Ÿ›
          thanosa
          thanosa

          ๐Ÿ›
          tiandiyixian
          tiandiyixian

          ๐Ÿ›
          tobwoerk
          tobwoerk

          ๐Ÿ›
          tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป
          trentchilders
          trentchilders

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          trishul14
          trishul14

          ๐Ÿ›
          tsui
          tsui

          ๐Ÿ›
          wangzitom12306
          wangzitom12306

          ๐Ÿ›
          winhkey
          winhkey

          ๐Ÿ›
          witherspore
          witherspore

          ๐Ÿ›
          wjljack
          wjljack

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          xingsong
          xingsong

          ๐Ÿ›
          xioayuge
          xioayuge

          ๐Ÿ›
          xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ›
          xuanuy
          xuanuy

          ๐Ÿ›
          xyf0921
          xyf0921

          ๐Ÿ›
          yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yasuharu-sato
          yasuharu-sato

          ๐Ÿ›
          zenglian
          zenglian

          ๐Ÿ›
          zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ›
          zh3ng
          zh3ng

          ๐Ÿ›
          zt_soft
          zt_soft

          ๐Ÿ›
          ztt79
          ztt79

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ›
          ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ›
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ

          ๐Ÿ›
          PUNEET JAIN
          PUNEET JAIN

          ๐Ÿ›
          Pankraz76
          Pankraz76

          ๐Ÿ’ป
          Pankraz76
          Pankraz76

          ๐Ÿ’ป ๐Ÿ›
          Parbati Bose
          Parbati Bose

          ๐Ÿ›
          Paul Berg
          Paul Berg

          ๐Ÿ›
          Paul Guyot
          Paul Guyot

          ๐Ÿ’ป
          TrackerSB
          TrackerSB

          ๐Ÿ›
          Tyson Stewart
          Tyson Stewart

          ๐Ÿ›
          Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ›
          UncleOwen
          UncleOwen

          ๐Ÿ’ป
          Utku Cuhadaroglu
          Utku Cuhadaroglu

          ๐Ÿ’ป ๐Ÿ›
          Valentin Brandl
          Valentin Brandl

          ๐Ÿ›
          Valeria
          Valeria

          ๐Ÿ›
          Valeria
          Valeria

          ๐Ÿ›
          Valery Yatsynovich
          Valery Yatsynovich

          ๐Ÿ“–
          Vasily Anisimov
          Vasily Anisimov

          ๐Ÿ›
          Vedant Chokshi
          Vedant Chokshi

          ๐Ÿ›
          Vibhor Goyal
          Vibhor Goyal

          ๐Ÿ›
          Vickenty Fesunov
          Vickenty Fesunov

          ๐Ÿ›
          Victor Noรซl
          Victor Noรซl

          ๐Ÿ›
          Vincent Galloy
          Vincent Galloy

          ๐Ÿ’ป
          Vincent Galloy
          Vincent Galloy

          ๐Ÿ’ป
          Vincent HUYNH
          Vincent HUYNH

          ๐Ÿ›
          Vincent Maurin
          Vincent Maurin

          ๐Ÿ›
          Vincent Potucek
          Vincent Potucek

          ๐Ÿ’ป
          Vincent Privat
          Vincent Privat

          ๐Ÿ›
          Vishhwas
          Vishhwas

          ๐Ÿ›
          Vishv_Android
          Vishv_Android

          ๐Ÿ›
          Vitalii Yevtushenko
          Vitalii Yevtushenko

          ๐Ÿ›
          Vitalii Yevtushenko
          Vitalii Yevtushenko

          ๐Ÿ›
          Vitaly
          Vitaly

          ๐Ÿ›
          Vitaly Polonetsky
          Vitaly Polonetsky

          ๐Ÿ›
          Vojtech Polivka
          Vojtech Polivka

          ๐Ÿ›
          Vsevolod Zholobov
          Vsevolod Zholobov

          ๐Ÿ›
          Vyom Yadav
          Vyom Yadav

          ๐Ÿ’ป
          Wang Shidong
          Wang Shidong

          ๐Ÿ›
          Waqas Ahmed
          Waqas Ahmed

          ๐Ÿ›
          Waqas Ahmed
          Waqas Ahmed

          ๐Ÿ›
          Wayne J. Earl
          Wayne J. Earl

          ๐Ÿ›
          Wchenghui
          Wchenghui

          ๐Ÿ›
          Wener
          Wener

          ๐Ÿ’ป
          Will Winder
          Will Winder

          ๐Ÿ›
          Willem A. Hajenius
          Willem A. Hajenius

          ๐Ÿ’ป
          William Brockhus
          William Brockhus

          ๐Ÿ’ป ๐Ÿ›
          Wilson Kurniawan
          Wilson Kurniawan

          ๐Ÿ›
          Wilson Kurniawan
          Wilson Kurniawan

          ๐Ÿ›
          Wim Deblauwe
          Wim Deblauwe

          ๐Ÿ›
          Wolf2323
          Wolf2323

          ๐Ÿ›
          Woongsik Choi
          Woongsik Choi

          ๐Ÿ›
          XenoAmess
          XenoAmess

          ๐Ÿ’ป ๐Ÿ›
          Yang
          Yang

          ๐Ÿ’ป
          YaroslavTER
          YaroslavTER

          ๐Ÿ›
          Yasar Shaikh
          Yasar Shaikh

          ๐Ÿ’ป
          Yasar Shaikh
          Yasar Shaikh

          ๐Ÿ’ป
          Young Chan
          Young Chan

          ๐Ÿ’ป ๐Ÿ›
          YuJin Kim
          YuJin Kim

          ๐Ÿ›
          Yuri Dolzhenko
          Yuri Dolzhenko

          ๐Ÿ›
          Yurii Dubinka
          Yurii Dubinka

          ๐Ÿ›
          Zoltan Farkas
          Zoltan Farkas

          ๐Ÿ›
          Zustin
          Zustin

          ๐Ÿ›
          aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป
          aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป
          alexmodis
          alexmodis

          ๐Ÿ›
          andreoss
          andreoss

          ๐Ÿ›
          andrey81inmd
          andrey81inmd

          ๐Ÿ’ป ๐Ÿ›
          anicoara
          anicoara

          ๐Ÿ›
          arunprasathav
          arunprasathav

          ๐Ÿ›
          asiercamara
          asiercamara

          ๐Ÿ›
          astillich-igniti
          astillich-igniti

          ๐Ÿ’ป
          astillich-igniti
          astillich-igniti

          ๐Ÿ’ป
          avesolovksyy
          avesolovksyy

          ๐Ÿ›
          avishvat
          avishvat

          ๐Ÿ›
          avivmu
          avivmu

          ๐Ÿ›
          axelbarfod1
          axelbarfod1

          ๐Ÿ›
          b-3-n
          b-3-n

          ๐Ÿ›
          balbhadra9
          balbhadra9

          ๐Ÿ›
          base23de
          base23de

          ๐Ÿ›
          base23de
          base23de

          ๐Ÿ›
          bergander
          bergander

          ๐Ÿ› ๐Ÿ’ป
          berkam
          berkam

          ๐Ÿ’ป ๐Ÿ›
          breizh31
          breizh31

          ๐Ÿ›
          caesarkim
          caesarkim

          ๐Ÿ›
          caiocarvalhotero
          caiocarvalhotero

          ๐Ÿ›
          carolyujing
          carolyujing

          ๐Ÿ›
          cbfiddle
          cbfiddle

          ๐Ÿ›
          cbfiddle
          cbfiddle

          ๐Ÿ›
          cesares-basilico
          cesares-basilico

          ๐Ÿ›
          chrite
          chrite

          ๐Ÿ›
          ciufudean
          ciufudean

          ๐Ÿ“–
          cobratbq
          cobratbq

          ๐Ÿ›
          coladict
          coladict

          ๐Ÿ›
          cosmoJFH
          cosmoJFH

          ๐Ÿ›
          cristalp
          cristalp

          ๐Ÿ›
          cristalp
          cristalp

          ๐Ÿ›
          crunsk
          crunsk

          ๐Ÿ›
          cwholmes
          cwholmes

          ๐Ÿ›
          cyberjj999
          cyberjj999

          ๐Ÿ›
          cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“–
          d1ss0nanz
          d1ss0nanz

          ๐Ÿ›
          dague1
          dague1

          ๐Ÿ“–
          dalizi007
          dalizi007

          ๐Ÿ’ป
          dalizi007
          dalizi007

          ๐Ÿ’ป
          danbrycefairsailcom
          danbrycefairsailcom

          ๐Ÿ›
          dariansanity
          dariansanity

          ๐Ÿ›
          darrenmiliband
          darrenmiliband

          ๐Ÿ›
          davidburstrom
          davidburstrom

          ๐Ÿ›
          dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ›
          deepak-patra
          deepak-patra

          ๐Ÿ›
          dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ›
          dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ›
          dinesh150
          dinesh150

          ๐Ÿ›
          diziaq
          diziaq

          ๐Ÿ›
          dreaminpast123
          dreaminpast123

          ๐Ÿ›
          duanyanan
          duanyanan

          ๐Ÿ›
          dutt-sanjay
          dutt-sanjay

          ๐Ÿ›
          duursma
          duursma

          ๐Ÿ’ป
          dylanleung
          dylanleung

          ๐Ÿ›
          dylanleung
          dylanleung

          ๐Ÿ›
          dzeigler
          dzeigler

          ๐Ÿ›
          eant60
          eant60

          ๐Ÿ›
          ekkirala
          ekkirala

          ๐Ÿ›
          emersonmoura
          emersonmoura

          ๐Ÿ›
          emouty
          emouty

          ๐Ÿ’ป ๐Ÿ›
          eugenepugach
          eugenepugach

          ๐Ÿ›
          fairy
          fairy

          ๐Ÿ›
          fairy
          fairy

          ๐Ÿ›
          filiprafalowicz
          filiprafalowicz

          ๐Ÿ’ป
          flxbl-io
          flxbl-io

          ๐Ÿ’ต
          foxmason
          foxmason

          ๐Ÿ›
          frankegabor
          frankegabor

          ๐Ÿ›
          frankl
          frankl

          ๐Ÿ›
          freafrea
          freafrea

          ๐Ÿ›
          fsapatin
          fsapatin

          ๐Ÿ›
          fsapatin
          fsapatin

          ๐Ÿ›
          gearsethenry
          gearsethenry

          ๐Ÿ›
          gracia19
          gracia19

          ๐Ÿ›
          gudzpoz
          gudzpoz

          ๐Ÿ›
          guo fei
          guo fei

          ๐Ÿ›
          gurmsc5
          gurmsc5

          ๐Ÿ›
          gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ›
          haigsn
          haigsn

          ๐Ÿ›
          haigsn
          haigsn

          ๐Ÿ›
          hemanshu070
          hemanshu070

          ๐Ÿ›
          henrik242
          henrik242

          ๐Ÿ›
          hongpuwu
          hongpuwu

          ๐Ÿ›
          hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ›
          igniti GmbH
          igniti GmbH

          ๐Ÿ›
          ilovezfs
          ilovezfs

          ๐Ÿ›
          imax-erik
          imax-erik

          ๐Ÿ›
          imax-erik
          imax-erik

          ๐Ÿ›
          itaigilo
          itaigilo

          ๐Ÿ›
          jakivey32
          jakivey32

          ๐Ÿ›
          jbennett2091
          jbennett2091

          ๐Ÿ›
          jcamerin
          jcamerin

          ๐Ÿ›
          jkeener1
          jkeener1

          ๐Ÿ›
          jmetertea
          jmetertea

          ๐Ÿ›
          johnra2
          johnra2

          ๐Ÿ’ป
          johnra2
          johnra2

          ๐Ÿ’ป
          johnzhao9
          johnzhao9

          ๐Ÿ›
          josemanuelrolon
          josemanuelrolon

          ๐Ÿ’ป ๐Ÿ›
          julees7
          julees7

          ๐Ÿ’ป ๐Ÿ›
          kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ›
          karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“–
          karwer
          karwer

          ๐Ÿ›
          kaulonline
          kaulonline

          ๐Ÿ›
          kaulonline
          kaulonline

          ๐Ÿ›
          kdaemonv
          kdaemonv

          ๐Ÿ›
          kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป
          kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ›
          kfranic
          kfranic

          ๐Ÿ›
          khalidkh
          khalidkh

          ๐Ÿ›
          koalalam
          koalalam

          ๐Ÿ›
          krzyk
          krzyk

          ๐Ÿ›
          krzyk
          krzyk

          ๐Ÿ›
          lasselindqvist
          lasselindqvist

          ๐Ÿ›
          lgemeinhardt
          lgemeinhardt

          ๐Ÿ›
          lihuaib
          lihuaib

          ๐Ÿ›
          liqingjun123
          liqingjun123

          ๐Ÿ›
          lonelyma1021
          lonelyma1021

          ๐Ÿ›
          lothas
          lothas

          ๐Ÿ›
          lpeddy
          lpeddy

          ๐Ÿ›
          lpeddy
          lpeddy

          ๐Ÿ›
          lujiefsi
          lujiefsi

          ๐Ÿ’ป
          lukelukes
          lukelukes

          ๐Ÿ’ป
          lyriccoder
          lyriccoder

          ๐Ÿ›
          marcelmore
          marcelmore

          ๐Ÿ›
          matchbox
          matchbox

          ๐Ÿ›
          matthiaskraaz
          matthiaskraaz

          ๐Ÿ›
          meandonlyme
          meandonlyme

          ๐Ÿ›
          meandonlyme
          meandonlyme

          ๐Ÿ›
          mikesive
          mikesive

          ๐Ÿ›
          milossesic
          milossesic

          ๐Ÿ›
          mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ›
          mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป
          mriddell95
          mriddell95

          ๐Ÿ›
          mrlzh
          mrlzh

          ๐Ÿ›
          msloan
          msloan

          ๐Ÿ›
          msloan
          msloan

          ๐Ÿ›
          mucharlaravalika
          mucharlaravalika

          ๐Ÿ›
          mvenneman
          mvenneman

          ๐Ÿ›
          nareshl119
          nareshl119

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          noerremark
          noerremark

          ๐Ÿ›
          novsirion
          novsirion

          ๐Ÿ›
          nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป
          nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป
          oggboy
          oggboy

          ๐Ÿ›
          oinume
          oinume

          ๐Ÿ›
          orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pacvz
          pacvz

          ๐Ÿ’ป
          pallavi agarwal
          pallavi agarwal

          ๐Ÿ›
          pankratz76
          pankratz76

          ๐Ÿ›
          pankratz76
          pankratz76

          ๐Ÿ›
          parksungrin
          parksungrin

          ๐Ÿ›
          patpatpat123
          patpatpat123

          ๐Ÿ›
          patriksevallius
          patriksevallius

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          phoenix384
          phoenix384

          ๐Ÿ›
          piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป
          plan3d
          plan3d

          ๐Ÿ›
          plan3d
          plan3d

          ๐Ÿ›
          poojasix
          poojasix

          ๐Ÿ›
          prabhushrikant
          prabhushrikant

          ๐Ÿ›
          pujitha8783
          pujitha8783

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          raghujayjunk
          raghujayjunk

          ๐Ÿ›
          rajeshveera
          rajeshveera

          ๐Ÿ›
          rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ›
          rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ›
          recdevs
          recdevs

          ๐Ÿ›
          reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ›
          rijkt
          rijkt

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ›
          rnveach
          rnveach

          ๐Ÿ›
          rxmicro
          rxmicro

          ๐Ÿ›
          rxmicro
          rxmicro

          ๐Ÿ›
          ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ›
          sabi0
          sabi0

          ๐Ÿ›
          samc-gearset
          samc-gearset

          ๐Ÿ“–
          scais
          scais

          ๐Ÿ›
          schosin
          schosin

          ๐Ÿ›
          screamingfrog
          screamingfrog

          ๐Ÿ’ต
          sebbASF
          sebbASF

          ๐Ÿ›
          sebbASF
          sebbASF

          ๐Ÿ›
          sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป
          shilko2013
          shilko2013

          ๐Ÿ›
          shiomiyan
          shiomiyan

          ๐Ÿ“–
          simeonKondr
          simeonKondr

          ๐Ÿ›
          snajberk
          snajberk

          ๐Ÿ›
          sniperrifle2004
          sniperrifle2004

          ๐Ÿ›
          snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป
          snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป
          soloturn
          soloturn

          ๐Ÿ›
          soyodream
          soyodream

          ๐Ÿ›
          sratz
          sratz

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          sturton
          sturton

          ๐Ÿ’ป ๐Ÿ›
          sudharmohan
          sudharmohan

          ๐Ÿ›
          suruchidawar
          suruchidawar

          ๐Ÿ›
          suruchidawar
          suruchidawar

          ๐Ÿ›
          svenfinitiv
          svenfinitiv

          ๐Ÿ›
          szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป
          tashiscool
          tashiscool

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          testation21
          testation21

          ๐Ÿ’ป ๐Ÿ›
          thanosa
          thanosa

          ๐Ÿ›
          tiandiyixian
          tiandiyixian

          ๐Ÿ›
          tiandiyixian
          tiandiyixian

          ๐Ÿ›
          tobwoerk
          tobwoerk

          ๐Ÿ›
          tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป
          trentchilders
          trentchilders

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          trishul14
          trishul14

          ๐Ÿ›
          tsui
          tsui

          ๐Ÿ›
          wangzitom12306
          wangzitom12306

          ๐Ÿ›
          wangzitom12306
          wangzitom12306

          ๐Ÿ›
          winhkey
          winhkey

          ๐Ÿ›
          witherspore
          witherspore

          ๐Ÿ›
          wjljack
          wjljack

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          xingsong
          xingsong

          ๐Ÿ›
          xioayuge
          xioayuge

          ๐Ÿ›
          xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ›
          xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ›
          xuanuy
          xuanuy

          ๐Ÿ›
          xyf0921
          xyf0921

          ๐Ÿ›
          yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yasuharu-sato
          yasuharu-sato

          ๐Ÿ›
          zenglian
          zenglian

          ๐Ÿ›
          zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ›
          zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ›
          zh3ng
          zh3ng

          ๐Ÿ›
          zt_soft
          zt_soft

          ๐Ÿ›
          ztt79
          ztt79

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ›
          ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ›
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ

          ๐Ÿ›
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ

          ๐Ÿ›
          ่Œ…ๅปถๅฎ‰
          ่Œ…ๅปถๅฎ‰

          ๐Ÿ’ป
          YuJin Kim
          YuJin Kim

          ๐Ÿ›
          Yuri Dolzhenko
          Yuri Dolzhenko

          ๐Ÿ›
          Yurii Dubinka
          Yurii Dubinka

          ๐Ÿ›
          Zbynek Konecny
          Zbynek Konecny

          ๐Ÿ› ๐Ÿ’ป
          Zoltan Farkas
          Zoltan Farkas

          ๐Ÿ›
          Zustin
          Zustin

          ๐Ÿ›
          Zustin
          Zustin

          ๐Ÿ›
          aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป
          alexmodis
          alexmodis

          ๐Ÿ›
          andreoss
          andreoss

          ๐Ÿ›
          andrey81inmd
          andrey81inmd

          ๐Ÿ’ป ๐Ÿ›
          anicoara
          anicoara

          ๐Ÿ›
          arunprasathav
          arunprasathav

          ๐Ÿ›
          asiercamara
          asiercamara

          ๐Ÿ›
          asiercamara
          asiercamara

          ๐Ÿ›
          astillich-igniti
          astillich-igniti

          ๐Ÿ’ป
          avesolovksyy
          avesolovksyy

          ๐Ÿ›
          avishvat
          avishvat

          ๐Ÿ›
          avivmu
          avivmu

          ๐Ÿ›
          axelbarfod1
          axelbarfod1

          ๐Ÿ›
          b-3-n
          b-3-n

          ๐Ÿ›
          balbhadra9
          balbhadra9

          ๐Ÿ›
          balbhadra9
          balbhadra9

          ๐Ÿ›
          base23de
          base23de

          ๐Ÿ›
          bergander
          bergander

          ๐Ÿ› ๐Ÿ’ป
          berkam
          berkam

          ๐Ÿ’ป ๐Ÿ›
          breizh31
          breizh31

          ๐Ÿ›
          caesarkim
          caesarkim

          ๐Ÿ›
          caiocarvalhotero
          caiocarvalhotero

          ๐Ÿ›
          carolyujing
          carolyujing

          ๐Ÿ›
          carolyujing
          carolyujing

          ๐Ÿ›
          cbfiddle
          cbfiddle

          ๐Ÿ›
          cesares-basilico
          cesares-basilico

          ๐Ÿ›
          chrite
          chrite

          ๐Ÿ›
          ciufudean
          ciufudean

          ๐Ÿ“–
          cobratbq
          cobratbq

          ๐Ÿ›
          coladict
          coladict

          ๐Ÿ›
          cosmoJFH
          cosmoJFH

          ๐Ÿ›
          cosmoJFH
          cosmoJFH

          ๐Ÿ›
          cristalp
          cristalp

          ๐Ÿ›
          crunsk
          crunsk

          ๐Ÿ›
          cwholmes
          cwholmes

          ๐Ÿ›
          cyberjj999
          cyberjj999

          ๐Ÿ›
          cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“–
          d1ss0nanz
          d1ss0nanz

          ๐Ÿ›
          dague1
          dague1

          ๐Ÿ“–
          dague1
          dague1

          ๐Ÿ“–
          dalizi007
          dalizi007

          ๐Ÿ’ป
          danbrycefairsailcom
          danbrycefairsailcom

          ๐Ÿ›
          dariansanity
          dariansanity

          ๐Ÿ›
          darrenmiliband
          darrenmiliband

          ๐Ÿ›
          davidburstrom
          davidburstrom

          ๐Ÿ›
          dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ›
          deepak-patra
          deepak-patra

          ๐Ÿ›
          deepak-patra
          deepak-patra

          ๐Ÿ›
          dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ›
          dinesh150
          dinesh150

          ๐Ÿ›
          diziaq
          diziaq

          ๐Ÿ›
          dreaminpast123
          dreaminpast123

          ๐Ÿ›
          duanyanan
          duanyanan

          ๐Ÿ›
          dutt-sanjay
          dutt-sanjay

          ๐Ÿ›
          duursma
          duursma

          ๐Ÿ’ป
          duursma
          duursma

          ๐Ÿ’ป
          dylanleung
          dylanleung

          ๐Ÿ›
          dzeigler
          dzeigler

          ๐Ÿ›
          eant60
          eant60

          ๐Ÿ›
          ekkirala
          ekkirala

          ๐Ÿ›
          emersonmoura
          emersonmoura

          ๐Ÿ›
          emouty
          emouty

          ๐Ÿ’ป ๐Ÿ›
          eugenepugach
          eugenepugach

          ๐Ÿ›
          eugenepugach
          eugenepugach

          ๐Ÿ›
          fairy
          fairy

          ๐Ÿ›
          filiprafalowicz
          filiprafalowicz

          ๐Ÿ’ป
          flxbl-io
          flxbl-io

          ๐Ÿ’ต
          foxmason
          foxmason

          ๐Ÿ›
          frankegabor
          frankegabor

          ๐Ÿ›
          frankl
          frankl

          ๐Ÿ›
          freafrea
          freafrea

          ๐Ÿ›
          freafrea
          freafrea

          ๐Ÿ›
          fsapatin
          fsapatin

          ๐Ÿ›
          gearsethenry
          gearsethenry

          ๐Ÿ›
          gracia19
          gracia19

          ๐Ÿ›
          gudzpoz
          gudzpoz

          ๐Ÿ›
          guo fei
          guo fei

          ๐Ÿ›
          gurmsc5
          gurmsc5

          ๐Ÿ›
          gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ›
          gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ›
          haigsn
          haigsn

          ๐Ÿ›
          hemanshu070
          hemanshu070

          ๐Ÿ›
          henrik242
          henrik242

          ๐Ÿ›
          hongpuwu
          hongpuwu

          ๐Ÿ›
          hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ›
          igniti GmbH
          igniti GmbH

          ๐Ÿ›
          ilovezfs
          ilovezfs

          ๐Ÿ›
          ilovezfs
          ilovezfs

          ๐Ÿ›
          imax-erik
          imax-erik

          ๐Ÿ›
          itaigilo
          itaigilo

          ๐Ÿ›
          jakivey32
          jakivey32

          ๐Ÿ›
          jbennett2091
          jbennett2091

          ๐Ÿ›
          jcamerin
          jcamerin

          ๐Ÿ›
          jkeener1
          jkeener1

          ๐Ÿ›
          jmetertea
          jmetertea

          ๐Ÿ›
          jmetertea
          jmetertea

          ๐Ÿ›
          johnra2
          johnra2

          ๐Ÿ’ป
          johnzhao9
          johnzhao9

          ๐Ÿ›
          josemanuelrolon
          josemanuelrolon

          ๐Ÿ’ป ๐Ÿ›
          julees7
          julees7

          ๐Ÿ’ป ๐Ÿ›
          kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ›
          karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“–
          karwer
          karwer

          ๐Ÿ›
          karwer
          karwer

          ๐Ÿ›
          kaulonline
          kaulonline

          ๐Ÿ›
          kdaemonv
          kdaemonv

          ๐Ÿ›
          kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป
          kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ›
          kfranic
          kfranic

          ๐Ÿ›
          khalidkh
          khalidkh

          ๐Ÿ›
          koalalam
          koalalam

          ๐Ÿ›
          koalalam
          koalalam

          ๐Ÿ›
          krzyk
          krzyk

          ๐Ÿ›
          lasselindqvist
          lasselindqvist

          ๐Ÿ›
          lgemeinhardt
          lgemeinhardt

          ๐Ÿ›
          lihuaib
          lihuaib

          ๐Ÿ›
          liqingjun123
          liqingjun123

          ๐Ÿ›
          lonelyma1021
          lonelyma1021

          ๐Ÿ›
          lothas
          lothas

          ๐Ÿ›
          lothas
          lothas

          ๐Ÿ›
          lpeddy
          lpeddy

          ๐Ÿ›
          lujiefsi
          lujiefsi

          ๐Ÿ’ป
          lukelukes
          lukelukes

          ๐Ÿ’ป
          lyriccoder
          lyriccoder

          ๐Ÿ›
          marcelmore
          marcelmore

          ๐Ÿ›
          matchbox
          matchbox

          ๐Ÿ›
          matthiaskraaz
          matthiaskraaz

          ๐Ÿ›
          matthiaskraaz
          matthiaskraaz

          ๐Ÿ›
          meandonlyme
          meandonlyme

          ๐Ÿ›
          mikesive
          mikesive

          ๐Ÿ›
          milossesic
          milossesic

          ๐Ÿ›
          mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ›
          mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป
          mriddell95
          mriddell95

          ๐Ÿ›
          mrlzh
          mrlzh

          ๐Ÿ›
          mrlzh
          mrlzh

          ๐Ÿ›
          msloan
          msloan

          ๐Ÿ›
          mucharlaravalika
          mucharlaravalika

          ๐Ÿ›
          mvenneman
          mvenneman

          ๐Ÿ›
          nareshl119
          nareshl119

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          noerremark
          noerremark

          ๐Ÿ›
          novsirion
          novsirion

          ๐Ÿ›
          novsirion
          novsirion

          ๐Ÿ›
          nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป
          oggboy
          oggboy

          ๐Ÿ›
          oinume
          oinume

          ๐Ÿ›
          orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pacvz
          pacvz

          ๐Ÿ’ป
          pallavi agarwal
          pallavi agarwal

          ๐Ÿ›
          pallavi agarwal
          pallavi agarwal

          ๐Ÿ›
          pankratz76
          pankratz76

          ๐Ÿ›
          parksungrin
          parksungrin

          ๐Ÿ›
          patpatpat123
          patpatpat123

          ๐Ÿ›
          patriksevallius
          patriksevallius

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          phoenix384
          phoenix384

          ๐Ÿ›
          piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป
          piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป
          plan3d
          plan3d

          ๐Ÿ›
          poojasix
          poojasix

          ๐Ÿ›
          prabhushrikant
          prabhushrikant

          ๐Ÿ›
          pujitha8783
          pujitha8783

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          raghujayjunk
          raghujayjunk

          ๐Ÿ›
          rajeshveera
          rajeshveera

          ๐Ÿ›
          rajeshveera
          rajeshveera

          ๐Ÿ›
          rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ›
          recdevs
          recdevs

          ๐Ÿ›
          reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ›
          rijkt
          rijkt

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ›
          rnveach
          rnveach

          ๐Ÿ›
          rnveach
          rnveach

          ๐Ÿ›
          rxmicro
          rxmicro

          ๐Ÿ›
          ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ›
          sabi0
          sabi0

          ๐Ÿ›
          samc-gearset
          samc-gearset

          ๐Ÿ“–
          scais
          scais

          ๐Ÿ›
          schosin
          schosin

          ๐Ÿ›
          screamingfrog
          screamingfrog

          ๐Ÿ’ต
          screamingfrog
          screamingfrog

          ๐Ÿ’ต
          sebbASF
          sebbASF

          ๐Ÿ›
          sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป
          shilko2013
          shilko2013

          ๐Ÿ›
          shiomiyan
          shiomiyan

          ๐Ÿ“–
          simeonKondr
          simeonKondr

          ๐Ÿ›
          snajberk
          snajberk

          ๐Ÿ›
          sniperrifle2004
          sniperrifle2004

          ๐Ÿ›
          sniperrifle2004
          sniperrifle2004

          ๐Ÿ›
          snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป
          soloturn
          soloturn

          ๐Ÿ›
          soyodream
          soyodream

          ๐Ÿ›
          sratz
          sratz

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          sturton
          sturton

          ๐Ÿ’ป ๐Ÿ›
          sudharmohan
          sudharmohan

          ๐Ÿ›
          sudharmohan
          sudharmohan

          ๐Ÿ›
          suruchidawar
          suruchidawar

          ๐Ÿ›
          svenfinitiv
          svenfinitiv

          ๐Ÿ›
          szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป
          tashiscool
          tashiscool

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          testation21
          testation21

          ๐Ÿ’ป ๐Ÿ›
          thanosa
          thanosa

          ๐Ÿ›
          thanosa
          thanosa

          ๐Ÿ›
          tiandiyixian
          tiandiyixian

          ๐Ÿ›
          tobwoerk
          tobwoerk

          ๐Ÿ›
          tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป
          trentchilders
          trentchilders

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          trishul14
          trishul14

          ๐Ÿ›
          tsui
          tsui

          ๐Ÿ›
          tsui
          tsui

          ๐Ÿ›
          wangzitom12306
          wangzitom12306

          ๐Ÿ›
          winhkey
          winhkey

          ๐Ÿ›
          witherspore
          witherspore

          ๐Ÿ›
          wjljack
          wjljack

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          xingsong
          xingsong

          ๐Ÿ›
          xioayuge
          xioayuge

          ๐Ÿ›
          xioayuge
          xioayuge

          ๐Ÿ›
          xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ›
          xuanuy
          xuanuy

          ๐Ÿ›
          xyf0921
          xyf0921

          ๐Ÿ›
          yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yasuharu-sato
          yasuharu-sato

          ๐Ÿ›
          zenglian
          zenglian

          ๐Ÿ›
          zenglian
          zenglian

          ๐Ÿ›
          zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ›
          zh3ng
          zh3ng

          ๐Ÿ›
          zt_soft
          zt_soft

          ๐Ÿ›
          ztt79
          ztt79

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ›
          ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ›
          ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ›
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ

          ๐Ÿ›
          ่Œ…ๅปถๅฎ‰
          ่Œ…ๅปถๅฎ‰

          ๐Ÿ’ป
          milossesic
          milossesic

          ๐Ÿ›
          mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ›
          mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป
          mriddell95
          mriddell95

          ๐Ÿ›
          mrclmh
          mrclmh

          ๐Ÿ›
          mriddell95
          mriddell95

          ๐Ÿ›
          mrlzh
          mrlzh

          ๐Ÿ›
          msloan
          msloan

          ๐Ÿ›
          mucharlaravalika
          mucharlaravalika

          ๐Ÿ›
          mvenneman
          mvenneman

          ๐Ÿ›
          nareshl119
          nareshl119

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          noerremark
          noerremark

          ๐Ÿ›
          noerremark
          noerremark

          ๐Ÿ›
          novsirion
          novsirion

          ๐Ÿ›
          nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป
          oggboy
          oggboy

          ๐Ÿ›
          oinume
          oinume

          ๐Ÿ›
          orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pacvz
          pacvz

          ๐Ÿ’ป
          pacvz
          pacvz

          ๐Ÿ’ป
          pallavi agarwal
          pallavi agarwal

          ๐Ÿ›
          pankratz76
          pankratz76

          ๐Ÿ›
          parksungrin
          parksungrin

          ๐Ÿ›
          patpatpat123
          patpatpat123

          ๐Ÿ›
          patriksevallius
          patriksevallius

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          phoenix384
          phoenix384

          ๐Ÿ›
          phoenix384
          phoenix384

          ๐Ÿ›
          piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป
          plan3d
          plan3d

          ๐Ÿ›
          poojasix
          poojasix

          ๐Ÿ›
          prabhushrikant
          prabhushrikant

          ๐Ÿ›
          pujitha8783
          pujitha8783

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          raghujayjunk
          raghujayjunk

          ๐Ÿ›
          raghujayjunk
          raghujayjunk

          ๐Ÿ›
          rajeshveera
          rajeshveera

          ๐Ÿ›
          rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ›
          recdevs
          recdevs

          ๐Ÿ›
          reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ›
          rijkt
          rijkt

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ›
          rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ›
          rnveach
          rnveach

          ๐Ÿ›
          rxmicro
          rxmicro

          ๐Ÿ›
          ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ›
          sabi0
          sabi0

          ๐Ÿ›
          samc-gearset
          samc-gearset

          ๐Ÿ“–
          scais
          scais

          ๐Ÿ›
          schosin
          schosin

          ๐Ÿ›
          schosin
          schosin

          ๐Ÿ›
          screamingfrog
          screamingfrog

          ๐Ÿ’ต
          sebbASF
          sebbASF

          ๐Ÿ›
          sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป
          shilko2013
          shilko2013

          ๐Ÿ›
          shiomiyan
          shiomiyan

          ๐Ÿ“–
          simeonKondr
          simeonKondr

          ๐Ÿ›
          snajberk
          snajberk

          ๐Ÿ›
          snajberk
          snajberk

          ๐Ÿ›
          sniperrifle2004
          sniperrifle2004

          ๐Ÿ›
          snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป
          soloturn
          soloturn

          ๐Ÿ›
          soyodream
          soyodream

          ๐Ÿ›
          sratz
          sratz

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          sturton
          sturton

          ๐Ÿ’ป ๐Ÿ›
          sturton
          sturton

          ๐Ÿ’ป ๐Ÿ›
          sudharmohan
          sudharmohan

          ๐Ÿ›
          suruchidawar
          suruchidawar

          ๐Ÿ›
          svenfinitiv
          svenfinitiv

          ๐Ÿ›
          szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป
          tashiscool
          tashiscool

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          testation21
          testation21

          ๐Ÿ’ป ๐Ÿ›
          testation21
          testation21

          ๐Ÿ’ป ๐Ÿ›
          thanosa
          thanosa

          ๐Ÿ›
          tiandiyixian
          tiandiyixian

          ๐Ÿ›
          tobwoerk
          tobwoerk

          ๐Ÿ›
          tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป
          trentchilders
          trentchilders

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          trishul14
          trishul14

          ๐Ÿ›
          trishul14
          trishul14

          ๐Ÿ›
          tsui
          tsui

          ๐Ÿ›
          wangzitom12306
          wangzitom12306

          ๐Ÿ›
          winhkey
          winhkey

          ๐Ÿ›
          witherspore
          witherspore

          ๐Ÿ›
          wjljack
          wjljack

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          xingsong
          xingsong

          ๐Ÿ›
          xingsong
          xingsong

          ๐Ÿ›
          xioayuge
          xioayuge

          ๐Ÿ›
          xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ›
          xuanuy
          xuanuy

          ๐Ÿ›
          xyf0921
          xyf0921

          ๐Ÿ›
          yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yasuharu-sato
          yasuharu-sato

          ๐Ÿ›
          yasuharu-sato
          yasuharu-sato

          ๐Ÿ›
          zenglian
          zenglian

          ๐Ÿ›
          zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ›
          zh3ng
          zh3ng

          ๐Ÿ›
          zt_soft
          zt_soft

          ๐Ÿ›
          ztt79
          ztt79

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ›
          รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ›
          ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ›
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ

          ๐Ÿ›
          ่Œ…ๅปถๅฎ‰
          ่Œ…ๅปถๅฎ‰

          ๐Ÿ’ป
          TrackerSB
          TrackerSB

          ๐Ÿ›
          Tyson Stewart
          Tyson Stewart

          ๐Ÿ›
          Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ›
          UncleOwen
          UncleOwen

          ๐Ÿ’ป
          UncleOwen
          UncleOwen

          ๐Ÿ’ป ๐Ÿ›
          Utku Cuhadaroglu
          Utku Cuhadaroglu

          ๐Ÿ’ป ๐Ÿ›
          Valentin Brandl
          Valentin Brandl

          ๐Ÿ›
          TrackerSB
          TrackerSB

          ๐Ÿ›
          Tyson Stewart
          Tyson Stewart

          ๐Ÿ›
          Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ›
          UncleOwen
          UncleOwen

          ๐Ÿ’ป
          UncleOwen
          UncleOwen

          ๐Ÿ’ป ๐Ÿ“–
          Utku Cuhadaroglu
          Utku Cuhadaroglu

          ๐Ÿ’ป ๐Ÿ›
          Valentin Brandl
          Valentin Brandl

          ๐Ÿ›
          cosmoJFH
          cosmoJFH

          ๐Ÿ›
          cristalp
          cristalp

          ๐Ÿ›
          crunsk
          crunsk

          ๐Ÿ›
          csrma
          csrma

          ๐Ÿ›
          cwholmes
          cwholmes

          ๐Ÿ›
          cyberjj999
          cyberjj999

          ๐Ÿ›
          cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“–
          cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“–
          d1ss0nanz
          d1ss0nanz

          ๐Ÿ›
          dague1
          dague1

          ๐Ÿ“–
          dalizi007
          dalizi007

          ๐Ÿ’ป
          danbrycefairsailcom
          danbrycefairsailcom

          ๐Ÿ›
          dariansanity
          dariansanity

          ๐Ÿ›
          darrenmiliband
          darrenmiliband

          ๐Ÿ›
          davidburstrom
          davidburstrom

          ๐Ÿ›
          davidburstrom
          davidburstrom

          ๐Ÿ›
          dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ›
          deepak-patra
          deepak-patra

          ๐Ÿ›
          dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ›
          dinesh150
          dinesh150

          ๐Ÿ›
          diziaq
          diziaq

          ๐Ÿ›
          dreaminpast123
          dreaminpast123

          ๐Ÿ›
          duanyanan
          duanyanan

          ๐Ÿ›
          duanyanan
          duanyanan

          ๐Ÿ›
          dutt-sanjay
          dutt-sanjay

          ๐Ÿ›
          duursma
          duursma

          ๐Ÿ’ป
          dylanleung
          dylanleung

          ๐Ÿ›
          dzeigler
          dzeigler

          ๐Ÿ›
          eant60
          eant60

          ๐Ÿ›
          ekkirala
          ekkirala

          ๐Ÿ›
          emersonmoura
          emersonmoura

          ๐Ÿ›
          emersonmoura
          emersonmoura

          ๐Ÿ›
          emouty
          emouty

          ๐Ÿ’ป ๐Ÿ›
          eugenepugach
          eugenepugach

          ๐Ÿ›
          fairy
          fairy

          ๐Ÿ›
          filiprafalowicz
          filiprafalowicz

          ๐Ÿ’ป
          flxbl-io
          flxbl-io

          ๐Ÿ’ต
          foxmason
          foxmason

          ๐Ÿ›
          frankegabor
          frankegabor

          ๐Ÿ›
          frankegabor
          frankegabor

          ๐Ÿ›
          frankl
          frankl

          ๐Ÿ›
          freafrea
          freafrea

          ๐Ÿ›
          fsapatin
          fsapatin

          ๐Ÿ›
          gearsethenry
          gearsethenry

          ๐Ÿ›
          gracia19
          gracia19

          ๐Ÿ›
          gudzpoz
          gudzpoz

          ๐Ÿ›
          guo fei
          guo fei

          ๐Ÿ›
          guo fei
          guo fei

          ๐Ÿ›
          gurmsc5
          gurmsc5

          ๐Ÿ›
          gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ›
          haigsn
          haigsn

          ๐Ÿ›
          hemanshu070
          hemanshu070

          ๐Ÿ›
          henrik242
          henrik242

          ๐Ÿ›
          hongpuwu
          hongpuwu

          ๐Ÿ›
          hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ›
          hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ›
          igniti GmbH
          igniti GmbH

          ๐Ÿ›
          ilovezfs
          ilovezfs

          ๐Ÿ›
          imax-erik
          imax-erik

          ๐Ÿ›
          itaigilo
          itaigilo

          ๐Ÿ›
          jakivey32
          jakivey32

          ๐Ÿ›
          jbennett2091
          jbennett2091

          ๐Ÿ›
          jcamerin
          jcamerin

          ๐Ÿ›
          jcamerin
          jcamerin

          ๐Ÿ›
          jkeener1
          jkeener1

          ๐Ÿ›
          jmetertea
          jmetertea

          ๐Ÿ›
          johnra2
          johnra2

          ๐Ÿ’ป
          johnzhao9
          johnzhao9

          ๐Ÿ›
          josemanuelrolon
          josemanuelrolon

          ๐Ÿ’ป ๐Ÿ›
          julees7
          julees7

          ๐Ÿ’ป ๐Ÿ›
          kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ›
          kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ›
          karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“–
          karwer
          karwer

          ๐Ÿ›
          kaulonline
          kaulonline

          ๐Ÿ›
          kdaemonv
          kdaemonv

          ๐Ÿ›
          kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป
          kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ›
          kfranic
          kfranic

          ๐Ÿ›
          kfranic
          kfranic

          ๐Ÿ›
          khalidkh
          khalidkh

          ๐Ÿ›
          koalalam
          koalalam

          ๐Ÿ›
          krzyk
          krzyk

          ๐Ÿ›
          lasselindqvist
          lasselindqvist

          ๐Ÿ›
          lgemeinhardt
          lgemeinhardt

          ๐Ÿ›
          lihuaib
          lihuaib

          ๐Ÿ›
          liqingjun123
          liqingjun123

          ๐Ÿ›
          liqingjun123
          liqingjun123

          ๐Ÿ›
          lonelyma1021
          lonelyma1021

          ๐Ÿ›
          lothas
          lothas

          ๐Ÿ›
          lpeddy
          lpeddy

          ๐Ÿ›
          lujiefsi
          lujiefsi

          ๐Ÿ’ป
          lukelukes
          lukelukes

          ๐Ÿ’ป
          lyriccoder
          lyriccoder

          ๐Ÿ›
          marcelmore
          marcelmore

          ๐Ÿ›
          marcelmore
          marcelmore

          ๐Ÿ›
          matchbox
          matchbox

          ๐Ÿ›
          matthiaskraaz
          matthiaskraaz

          ๐Ÿ›
          meandonlyme
          meandonlyme

          ๐Ÿ›
          mikesive
          mikesive

          ๐Ÿ›
          milossesic
          milossesic

          ๐Ÿ›
          mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ›
          mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป
          mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป
          mrclmh
          mrclmh

          ๐Ÿ›
          mriddell95
          mriddell95

          ๐Ÿ›
          mrlzh
          mrlzh

          ๐Ÿ›
          msloan
          msloan

          ๐Ÿ›
          mucharlaravalika
          mucharlaravalika

          ๐Ÿ›
          mvenneman
          mvenneman

          ๐Ÿ›
          nareshl119
          nareshl119

          ๐Ÿ›
          nareshl119
          nareshl119

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          noerremark
          noerremark

          ๐Ÿ›
          novsirion
          novsirion

          ๐Ÿ›
          nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป
          oggboy
          oggboy

          ๐Ÿ›
          oinume
          oinume

          ๐Ÿ›
          orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ›
          orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pacvz
          pacvz

          ๐Ÿ’ป
          pallavi agarwal
          pallavi agarwal

          ๐Ÿ›
          pankratz76
          pankratz76

          ๐Ÿ›
          parksungrin
          parksungrin

          ๐Ÿ›
          patpatpat123
          patpatpat123

          ๐Ÿ›
          patriksevallius
          patriksevallius

          ๐Ÿ›
          patriksevallius
          patriksevallius

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          phoenix384
          phoenix384

          ๐Ÿ›
          piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป
          plan3d
          plan3d

          ๐Ÿ›
          poojasix
          poojasix

          ๐Ÿ›
          prabhushrikant
          prabhushrikant

          ๐Ÿ›
          pujitha8783
          pujitha8783

          ๐Ÿ›
          pujitha8783
          pujitha8783

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          raghujayjunk
          raghujayjunk

          ๐Ÿ›
          rajeshveera
          rajeshveera

          ๐Ÿ›
          rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ›
          recdevs
          recdevs

          ๐Ÿ›
          reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ›
          rijkt
          rijkt

          ๐Ÿ›
          rijkt
          rijkt

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ›
          rnveach
          rnveach

          ๐Ÿ›
          rxmicro
          rxmicro

          ๐Ÿ›
          ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ›
          sabi0
          sabi0

          ๐Ÿ›
          samc-gearset
          samc-gearset

          ๐Ÿ“–
          samc-gearset
          samc-gearset

          ๐Ÿ“–
          scais
          scais

          ๐Ÿ›
          schosin
          schosin

          ๐Ÿ›
          screamingfrog
          screamingfrog

          ๐Ÿ’ต
          sebbASF
          sebbASF

          ๐Ÿ›
          sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป
          shilko2013
          shilko2013

          ๐Ÿ›
          shiomiyan
          shiomiyan

          ๐Ÿ“–
          shiomiyan
          shiomiyan

          ๐Ÿ“–
          simeonKondr
          simeonKondr

          ๐Ÿ›
          snajberk
          snajberk

          ๐Ÿ›
          sniperrifle2004
          sniperrifle2004

          ๐Ÿ›
          snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป
          soloturn
          soloturn

          ๐Ÿ›
          soyodream
          soyodream

          ๐Ÿ›
          sratz
          sratz

          ๐Ÿ›
          sratz
          sratz

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          sturton
          sturton

          ๐Ÿ’ป ๐Ÿ›
          sudharmohan
          sudharmohan

          ๐Ÿ›
          suruchidawar
          suruchidawar

          ๐Ÿ›
          svenfinitiv
          svenfinitiv

          ๐Ÿ›
          szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป
          tashiscool
          tashiscool

          ๐Ÿ›
          tashiscool
          tashiscool

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          testation21
          testation21

          ๐Ÿ’ป ๐Ÿ›
          thanosa
          thanosa

          ๐Ÿ›
          tiandiyixian
          tiandiyixian

          ๐Ÿ›
          tobwoerk
          tobwoerk

          ๐Ÿ›
          tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป
          trentchilders
          trentchilders

          ๐Ÿ›
          trentchilders
          trentchilders

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          trishul14
          trishul14

          ๐Ÿ›
          tsui
          tsui

          ๐Ÿ›
          wangzitom12306
          wangzitom12306

          ๐Ÿ›
          winhkey
          winhkey

          ๐Ÿ›
          witherspore
          witherspore

          ๐Ÿ›
          wjljack
          wjljack

          ๐Ÿ›
          wjljack
          wjljack

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          xingsong
          xingsong

          ๐Ÿ›
          xioayuge
          xioayuge

          ๐Ÿ›
          xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ›
          xuanuy
          xuanuy

          ๐Ÿ›
          xyf0921
          xyf0921

          ๐Ÿ›
          yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ›
          yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yasuharu-sato
          yasuharu-sato

          ๐Ÿ›
          zenglian
          zenglian

          ๐Ÿ›
          zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ›
          zh3ng
          zh3ng

          ๐Ÿ›
          zt_soft
          zt_soft

          ๐Ÿ›
          ztt79
          ztt79

          ๐Ÿ›
          ztt79
          ztt79

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ›
          ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ›
          Stephen Carter
          Stephen Carter

          ๐Ÿ›
          Stephen Friedrich
          Stephen Friedrich

          ๐Ÿ›
          Steve Babula
          Steve Babula

          ๐Ÿ’ป
          Steven Schlansker
          Steven Schlansker

          ๐Ÿ›
          Steven Stearns
          Steven Stearns

          ๐Ÿ› ๐Ÿ’ป
          Stexxe
          Stexxe

          ๐Ÿ›
          Stexxe
          Stexxe

          ๐Ÿ›
          Stian Lรฅgstad
          Stian Lรฅgstad

          ๐Ÿ›
          StuartClayton5
          StuartClayton5

          ๐Ÿ›
          Supun Arunoda
          Supun Arunoda

          ๐Ÿ›
          Suren Abrahamyan
          Suren Abrahamyan

          ๐Ÿ›
          Suvashri
          Suvashri

          ๐Ÿ“–
          Sven Barden
          Sven Barden

          ๐Ÿ›
          SwatiBGupta1110
          SwatiBGupta1110

          ๐Ÿ›
          SwatiBGupta1110
          SwatiBGupta1110

          ๐Ÿ›
          SyedThoufich
          SyedThoufich

          ๐Ÿ›
          Szymon Sasin
          Szymon Sasin

          ๐Ÿ›
          T-chuangxin
          T-chuangxin

          ๐Ÿ›
          TERAI Atsuhiro
          TERAI Atsuhiro

          ๐Ÿ›
          TIOBE Software
          TIOBE Software

          ๐Ÿ’ป ๐Ÿ›
          Tarush Singh
          Tarush Singh

          ๐Ÿ’ป
          Taylor Smock
          Taylor Smock

          ๐Ÿ›
          Taylor Smock
          Taylor Smock

          ๐Ÿ›
          Techeira Damiรกn
          Techeira Damiรกn

          ๐Ÿ’ป ๐Ÿ›
          Ted Husted
          Ted Husted

          ๐Ÿ›
          TehBakker
          TehBakker

          ๐Ÿ›
          The Gitter Badger
          The Gitter Badger

          ๐Ÿ›
          Theodoor
          Theodoor

          ๐Ÿ›
          Thiago Henrique Hรผpner
          Thiago Henrique Hรผpner

          ๐Ÿ›
          Thibault Meyer
          Thibault Meyer

          ๐Ÿ›
          Thibault Meyer
          Thibault Meyer

          ๐Ÿ›
          Thomas Gรผttler
          Thomas Gรผttler

          ๐Ÿ›
          Thomas Jones-Low
          Thomas Jones-Low

          ๐Ÿ›
          Thomas Smith
          Thomas Smith

          ๐Ÿ’ป ๐Ÿ›
          ThrawnCA
          ThrawnCA

          ๐Ÿ›
          Thu Vo
          Thu Vo

          ๐Ÿ›
          Thunderforge
          Thunderforge

          ๐Ÿ’ป ๐Ÿ›
          Tim van der Lippe
          Tim van der Lippe

          ๐Ÿ›
          Tim van der Lippe
          Tim van der Lippe

          ๐Ÿ›
          Tobias Weimer
          Tobias Weimer

          ๐Ÿ’ป ๐Ÿ›
          Tom Copeland
          Tom Copeland

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–
          Tom Daly
          Tom Daly

          ๐Ÿ›
          Tomas
          Tomas

          ๐Ÿ›
          Tomer Figenblat
          Tomer Figenblat

          ๐Ÿ›
          Tomi De Lucca
          Tomi De Lucca

          ๐Ÿ’ป ๐Ÿ›
          Tony
          Tony

          ๐Ÿ“–
          Tony
          Tony

          ๐Ÿ“–
          Torsten Kleiber
          Torsten Kleiber

          ๐Ÿ›
          Torsten Krause
          Torsten Krause

          ๐Ÿ›
          TrackerSB
          TrackerSB

          ๐Ÿ›
          Tyson Stewart
          Tyson Stewart

          ๐Ÿ›
          Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ›
          UncleOwen
          UncleOwen

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“–
          Utku Cuhadaroglu
          Utku Cuhadaroglu

          ๐Ÿ’ป ๐Ÿ›
          Utku Cuhadaroglu
          Utku Cuhadaroglu

          ๐Ÿ’ป ๐Ÿ›
          Valentin Brandl
          Valentin Brandl

          ๐Ÿ›
          Valeria
          Valeria

          ๐Ÿ›
          Valery Yatsynovich
          Valery Yatsynovich

          ๐Ÿ“–
          Vasily Anisimov
          Vasily Anisimov

          ๐Ÿ›
          Vedant Chokshi
          Vedant Chokshi

          ๐Ÿ›
          Vibhor Goyal
          Vibhor Goyal

          ๐Ÿ›
          Vickenty Fesunov
          Vickenty Fesunov

          ๐Ÿ›
          Vickenty Fesunov
          Vickenty Fesunov

          ๐Ÿ›
          Victor Noรซl
          Victor Noรซl

          ๐Ÿ›
          Vincent Galloy
          Vincent Galloy

          ๐Ÿ’ป
          Vincent HUYNH
          Vincent HUYNH

          ๐Ÿ›
          Vincent Maurin
          Vincent Maurin

          ๐Ÿ›
          Vincent Potucek
          Vincent Potucek

          ๐Ÿ’ป
          Vincent Privat
          Vincent Privat

          ๐Ÿ›
          Vishhwas
          Vishhwas

          ๐Ÿ›
          Vishhwas
          Vishhwas

          ๐Ÿ›
          Vishv_Android
          Vishv_Android

          ๐Ÿ›
          Vitalii Yevtushenko
          Vitalii Yevtushenko

          ๐Ÿ›
          Vitaly
          Vitaly

          ๐Ÿ›
          Vitaly Polonetsky
          Vitaly Polonetsky

          ๐Ÿ›
          Vojtech Polivka
          Vojtech Polivka

          ๐Ÿ›
          Vsevolod Zholobov
          Vsevolod Zholobov

          ๐Ÿ›
          Vyom Yadav
          Vyom Yadav

          ๐Ÿ’ป
          Vyom Yadav
          Vyom Yadav

          ๐Ÿ’ป
          Wang Shidong
          Wang Shidong

          ๐Ÿ›
          Waqas Ahmed
          Waqas Ahmed

          ๐Ÿ›
          Wayne J. Earl
          Wayne J. Earl

          ๐Ÿ›
          Wchenghui
          Wchenghui

          ๐Ÿ›
          Wener
          Wener

          ๐Ÿ’ป
          Will Winder
          Will Winder

          ๐Ÿ›
          Willem A. Hajenius
          Willem A. Hajenius

          ๐Ÿ’ป
          Willem A. Hajenius
          Willem A. Hajenius

          ๐Ÿ’ป
          William Brockhus
          William Brockhus

          ๐Ÿ’ป ๐Ÿ›
          Wilson Kurniawan
          Wilson Kurniawan

          ๐Ÿ›
          Wim Deblauwe
          Wim Deblauwe

          ๐Ÿ›
          Wolf2323
          Wolf2323

          ๐Ÿ›
          Woongsik Choi
          Woongsik Choi

          ๐Ÿ›
          XenoAmess
          XenoAmess

          ๐Ÿ’ป ๐Ÿ›
          Yang
          Yang

          ๐Ÿ’ป
          Yang
          Yang

          ๐Ÿ’ป
          YaroslavTER
          YaroslavTER

          ๐Ÿ›
          Yasar Shaikh
          Yasar Shaikh

          ๐Ÿ’ป
          Young Chan
          Young Chan

          ๐Ÿ’ป ๐Ÿ›
          YuJin Kim
          YuJin Kim

          ๐Ÿ›
          Yuri Dolzhenko
          Yuri Dolzhenko

          ๐Ÿ›
          Yurii Dubinka
          Yurii Dubinka

          ๐Ÿ›
          Zbynek Konecny
          Zbynek Konecny

          ๐Ÿ› ๐Ÿ’ป
          Zbynek Konecny
          Zbynek Konecny

          ๐Ÿ› ๐Ÿ’ป
          Zoltan Farkas
          Zoltan Farkas

          ๐Ÿ›
          Zustin
          Zustin

          ๐Ÿ›
          aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป
          alexmodis
          alexmodis

          ๐Ÿ›
          andreoss
          andreoss

          ๐Ÿ›
          andrey81inmd
          andrey81inmd

          ๐Ÿ’ป ๐Ÿ›
          anicoara
          anicoara

          ๐Ÿ›
          anicoara
          anicoara

          ๐Ÿ›
          arunprasathav
          arunprasathav

          ๐Ÿ›
          asiercamara
          asiercamara

          ๐Ÿ›
          astillich-igniti
          astillich-igniti

          ๐Ÿ’ป
          avesolovksyy
          avesolovksyy

          ๐Ÿ›
          avishvat
          avishvat

          ๐Ÿ›
          avivmu
          avivmu

          ๐Ÿ›
          axelbarfod1
          axelbarfod1

          ๐Ÿ›
          axelbarfod1
          axelbarfod1

          ๐Ÿ›
          b-3-n
          b-3-n

          ๐Ÿ›
          balbhadra9
          balbhadra9

          ๐Ÿ›
          base23de
          base23de

          ๐Ÿ›
          bergander
          bergander

          ๐Ÿ› ๐Ÿ’ป
          berkam
          berkam

          ๐Ÿ’ป ๐Ÿ›
          breizh31
          breizh31

          ๐Ÿ›
          caesarkim
          caesarkim

          ๐Ÿ›
          caesarkim
          caesarkim

          ๐Ÿ›
          caiocarvalhotero
          caiocarvalhotero

          ๐Ÿ›
          carolyujing
          carolyujing

          ๐Ÿ›
          cbfiddle
          cbfiddle

          ๐Ÿ›
          cesares-basilico
          cesares-basilico

          ๐Ÿ›
          chrite
          chrite

          ๐Ÿ›
          ciufudean
          ciufudean

          ๐Ÿ“–
          cobratbq
          cobratbq

          ๐Ÿ›
          cobratbq
          cobratbq

          ๐Ÿ›
          coladict
          coladict

          ๐Ÿ›
          cosmoJFH
          cosmoJFH

          ๐Ÿ›
          cristalp
          cristalp

          ๐Ÿ›
          crunsk
          crunsk

          ๐Ÿ›
          csrma
          csrma

          ๐Ÿ›
          cwholmes
          cwholmes

          ๐Ÿ›
          cyberjj999
          cyberjj999

          ๐Ÿ›
          cyberjj999
          cyberjj999

          ๐Ÿ›
          cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“–
          d1ss0nanz
          d1ss0nanz

          ๐Ÿ›
          dague1
          dague1

          ๐Ÿ“–
          dalizi007
          dalizi007

          ๐Ÿ’ป
          danbrycefairsailcom
          danbrycefairsailcom

          ๐Ÿ›
          dariansanity
          dariansanity

          ๐Ÿ›
          darrenmiliband
          darrenmiliband

          ๐Ÿ›
          darrenmiliband
          darrenmiliband

          ๐Ÿ›
          davidburstrom
          davidburstrom

          ๐Ÿ›
          dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ›
          deepak-patra
          deepak-patra

          ๐Ÿ›
          dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ›
          dinesh150
          dinesh150

          ๐Ÿ›
          diziaq
          diziaq

          ๐Ÿ›
          dreaminpast123
          dreaminpast123

          ๐Ÿ›
          dreaminpast123
          dreaminpast123

          ๐Ÿ›
          duanyanan
          duanyanan

          ๐Ÿ›
          dutt-sanjay
          dutt-sanjay

          ๐Ÿ›
          duursma
          duursma

          ๐Ÿ’ป
          dylanleung
          dylanleung

          ๐Ÿ›
          dzeigler
          dzeigler

          ๐Ÿ›
          eant60
          eant60

          ๐Ÿ›
          ekkirala
          ekkirala

          ๐Ÿ›
          ekkirala
          ekkirala

          ๐Ÿ›
          emersonmoura
          emersonmoura

          ๐Ÿ›
          emouty
          emouty

          ๐Ÿ’ป ๐Ÿ›
          eugenepugach
          eugenepugach

          ๐Ÿ›
          fairy
          fairy

          ๐Ÿ›
          filiprafalowicz
          filiprafalowicz

          ๐Ÿ’ป
          flxbl-io
          flxbl-io

          ๐Ÿ’ต
          foxmason
          foxmason

          ๐Ÿ›
          foxmason
          foxmason

          ๐Ÿ›
          frankegabor
          frankegabor

          ๐Ÿ›
          frankl
          frankl

          ๐Ÿ›
          freafrea
          freafrea

          ๐Ÿ›
          fsapatin
          fsapatin

          ๐Ÿ›
          gearsethenry
          gearsethenry

          ๐Ÿ›
          gracia19
          gracia19

          ๐Ÿ›
          gudzpoz
          gudzpoz

          ๐Ÿ›
          gudzpoz
          gudzpoz

          ๐Ÿ›
          guo fei
          guo fei

          ๐Ÿ›
          gurmsc5
          gurmsc5

          ๐Ÿ›
          gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ›
          haigsn
          haigsn

          ๐Ÿ›
          hemanshu070
          hemanshu070

          ๐Ÿ›
          henrik242
          henrik242

          ๐Ÿ›
          hongpuwu
          hongpuwu

          ๐Ÿ›
          hongpuwu
          hongpuwu

          ๐Ÿ›
          hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ›
          igniti GmbH
          igniti GmbH

          ๐Ÿ›
          ilovezfs
          ilovezfs

          ๐Ÿ›
          imax-erik
          imax-erik

          ๐Ÿ›
          itaigilo
          itaigilo

          ๐Ÿ›
          jakivey32
          jakivey32

          ๐Ÿ›
          jbennett2091
          jbennett2091

          ๐Ÿ›
          jbennett2091
          jbennett2091

          ๐Ÿ›
          jcamerin
          jcamerin

          ๐Ÿ›
          jkeener1
          jkeener1

          ๐Ÿ›
          jmetertea
          jmetertea

          ๐Ÿ›
          johnra2
          johnra2

          ๐Ÿ’ป
          johnzhao9
          johnzhao9

          ๐Ÿ›
          josemanuelrolon
          josemanuelrolon

          ๐Ÿ’ป ๐Ÿ›
          julees7
          julees7

          ๐Ÿ’ป ๐Ÿ›
          julees7
          julees7

          ๐Ÿ’ป ๐Ÿ›
          kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ›
          karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“–
          karwer
          karwer

          ๐Ÿ›
          kaulonline
          kaulonline

          ๐Ÿ›
          kdaemonv
          kdaemonv

          ๐Ÿ›
          kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป
          kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ›
          kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ›
          kfranic
          kfranic

          ๐Ÿ›
          khalidkh
          khalidkh

          ๐Ÿ›
          koalalam
          koalalam

          ๐Ÿ›
          krzyk
          krzyk

          ๐Ÿ›
          lasselindqvist
          lasselindqvist

          ๐Ÿ›
          lgemeinhardt
          lgemeinhardt

          ๐Ÿ›
          lihuaib
          lihuaib

          ๐Ÿ›
          lihuaib
          lihuaib

          ๐Ÿ›
          liqingjun123
          liqingjun123

          ๐Ÿ›
          lonelyma1021
          lonelyma1021

          ๐Ÿ›
          lothas
          lothas

          ๐Ÿ›
          lpeddy
          lpeddy

          ๐Ÿ›
          lujiefsi
          lujiefsi

          ๐Ÿ’ป
          lukelukes
          lukelukes

          ๐Ÿ’ป
          lyriccoder
          lyriccoder

          ๐Ÿ›
          lyriccoder
          lyriccoder

          ๐Ÿ›
          marcelmore
          marcelmore

          ๐Ÿ›
          matchbox
          matchbox

          ๐Ÿ›
          matthiaskraaz
          matthiaskraaz

          ๐Ÿ›
          meandonlyme
          meandonlyme

          ๐Ÿ›
          mikesive
          mikesive

          ๐Ÿ›
          milossesic
          milossesic

          ๐Ÿ›
          mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ›
          mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ›
          mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป
          mrclmh
          mrclmh

          ๐Ÿ›
          mriddell95
          mriddell95

          ๐Ÿ›
          mrlzh
          mrlzh

          ๐Ÿ›
          msloan
          msloan

          ๐Ÿ›
          mucharlaravalika
          mucharlaravalika

          ๐Ÿ›
          mvenneman
          mvenneman

          ๐Ÿ›
          mvenneman
          mvenneman

          ๐Ÿ›
          nareshl119
          nareshl119

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          noerremark
          noerremark

          ๐Ÿ›
          novsirion
          novsirion

          ๐Ÿ›
          nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป
          oggboy
          oggboy

          ๐Ÿ›
          oinume
          oinume

          ๐Ÿ›
          oinume
          oinume

          ๐Ÿ›
          orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pacvz
          pacvz

          ๐Ÿ’ป
          pallavi agarwal
          pallavi agarwal

          ๐Ÿ›
          pankratz76
          pankratz76

          ๐Ÿ›
          parksungrin
          parksungrin

          ๐Ÿ›
          patpatpat123
          patpatpat123

          ๐Ÿ›
          patpatpat123
          patpatpat123

          ๐Ÿ›
          patriksevallius
          patriksevallius

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          phoenix384
          phoenix384

          ๐Ÿ›
          piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป
          plan3d
          plan3d

          ๐Ÿ›
          poojasix
          poojasix

          ๐Ÿ›
          prabhushrikant
          prabhushrikant

          ๐Ÿ›
          prabhushrikant
          prabhushrikant

          ๐Ÿ›
          pujitha8783
          pujitha8783

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          raghujayjunk
          raghujayjunk

          ๐Ÿ›
          rajeshveera
          rajeshveera

          ๐Ÿ›
          rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ›
          recdevs
          recdevs

          ๐Ÿ›
          reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ›
          reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ›
          rijkt
          rijkt

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ›
          rnveach
          rnveach

          ๐Ÿ›
          rxmicro
          rxmicro

          ๐Ÿ›
          ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ›
          sabi0
          sabi0

          ๐Ÿ›
          sabi0
          sabi0

          ๐Ÿ›
          samc-gearset
          samc-gearset

          ๐Ÿ“–
          scais
          scais

          ๐Ÿ›
          schosin
          schosin

          ๐Ÿ›
          screamingfrog
          screamingfrog

          ๐Ÿ’ต
          sebbASF
          sebbASF

          ๐Ÿ›
          sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป
          shilko2013
          shilko2013

          ๐Ÿ›
          shilko2013
          shilko2013

          ๐Ÿ›
          shiomiyan
          shiomiyan

          ๐Ÿ“–
          simeonKondr
          simeonKondr

          ๐Ÿ›
          snajberk
          snajberk

          ๐Ÿ›
          sniperrifle2004
          sniperrifle2004

          ๐Ÿ›
          snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป
          soloturn
          soloturn

          ๐Ÿ›
          soyodream
          soyodream

          ๐Ÿ›
          soyodream
          soyodream

          ๐Ÿ›
          sratz
          sratz

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          sturton
          sturton

          ๐Ÿ’ป ๐Ÿ›
          sudharmohan
          sudharmohan

          ๐Ÿ›
          suruchidawar
          suruchidawar

          ๐Ÿ›
          svenfinitiv
          svenfinitiv

          ๐Ÿ›
          szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป
          szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป
          tashiscool
          tashiscool

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          testation21
          testation21

          ๐Ÿ’ป ๐Ÿ›
          thanosa
          thanosa

          ๐Ÿ›
          tiandiyixian
          tiandiyixian

          ๐Ÿ›
          tobwoerk
          tobwoerk

          ๐Ÿ›
          tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป
          tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป
          trentchilders
          trentchilders

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          trishul14
          trishul14

          ๐Ÿ›
          tsui
          tsui

          ๐Ÿ›
          wangzitom12306
          wangzitom12306

          ๐Ÿ›
          winhkey
          winhkey

          ๐Ÿ›
          witherspore
          witherspore

          ๐Ÿ›
          witherspore
          witherspore

          ๐Ÿ›
          wjljack
          wjljack

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          xingsong
          xingsong

          ๐Ÿ›
          xioayuge
          xioayuge

          ๐Ÿ›
          xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ›
          xuanuy
          xuanuy

          ๐Ÿ›
          xyf0921
          xyf0921

          ๐Ÿ›
          xyf0921
          xyf0921

          ๐Ÿ›
          yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yasuharu-sato
          yasuharu-sato

          ๐Ÿ›
          zenglian
          zenglian

          ๐Ÿ›
          zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ›
          zh3ng
          zh3ng

          ๐Ÿ›
          zt_soft
          zt_soft

          ๐Ÿ›
          zt_soft
          zt_soft

          ๐Ÿ›
          ztt79
          ztt79

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ›
          Stephen Carter
          Stephen Carter

          ๐Ÿ›
          Stephen Friedrich
          Stephen Friedrich

          ๐Ÿ›
          Steve Babula
          Steve Babula

          ๐Ÿ’ป
          Steve White
          Steve White

          ๐Ÿ›
          Steven Stearns
          Steven Stearns

          ๐Ÿ› ๐Ÿ’ป
          Stexxe
          Stexxe

          ๐Ÿ›
          Stian Lรฅgstad
          Stian Lรฅgstad

          ๐Ÿ›
          Stian Lรฅgstad
          Stian Lรฅgstad

          ๐Ÿ›
          StuartClayton5
          StuartClayton5

          ๐Ÿ›
          Supun Arunoda
          Supun Arunoda

          ๐Ÿ›
          Suren Abrahamyan
          Suren Abrahamyan

          ๐Ÿ›
          Suvashri
          Suvashri

          ๐Ÿ“–
          Sven Barden
          Sven Barden

          ๐Ÿ›
          SwatiBGupta1110
          SwatiBGupta1110

          ๐Ÿ›
          SyedThoufich
          SyedThoufich

          ๐Ÿ›
          SyedThoufich
          SyedThoufich

          ๐Ÿ›
          Szymon Sasin
          Szymon Sasin

          ๐Ÿ›
          T-chuangxin
          T-chuangxin

          ๐Ÿ›
          TERAI Atsuhiro
          TERAI Atsuhiro

          ๐Ÿ›
          TIOBE Software
          TIOBE Software

          ๐Ÿ’ป ๐Ÿ›
          Tarush Singh
          Tarush Singh

          ๐Ÿ’ป
          Taylor Smock
          Taylor Smock

          ๐Ÿ›
          Techeira Damiรกn
          Techeira Damiรกn

          ๐Ÿ’ป ๐Ÿ›
          Techeira Damiรกn
          Techeira Damiรกn

          ๐Ÿ’ป ๐Ÿ›
          Ted Husted
          Ted Husted

          ๐Ÿ›
          TehBakker
          TehBakker

          ๐Ÿ›
          The Gitter Badger
          The Gitter Badger

          ๐Ÿ›
          Theodoor
          Theodoor

          ๐Ÿ›
          Thiago Henrique Hรผpner
          Thiago Henrique Hรผpner

          ๐Ÿ›
          Thibault Meyer
          Thibault Meyer

          ๐Ÿ›
          Thomas Gรผttler
          Thomas Gรผttler

          ๐Ÿ›
          Thomas Gรผttler
          Thomas Gรผttler

          ๐Ÿ›
          Thomas Jones-Low
          Thomas Jones-Low

          ๐Ÿ›
          Thomas Smith
          Thomas Smith

          ๐Ÿ’ป ๐Ÿ›
          ThrawnCA
          ThrawnCA

          ๐Ÿ›
          Thu Vo
          Thu Vo

          ๐Ÿ›
          Thunderforge
          Thunderforge

          ๐Ÿ’ป ๐Ÿ›
          Tim van der Lippe
          Tim van der Lippe

          ๐Ÿ›
          Tobias Weimer
          Tobias Weimer

          ๐Ÿ’ป ๐Ÿ›
          Tobias Weimer
          Tobias Weimer

          ๐Ÿ’ป ๐Ÿ›
          Tom Copeland
          Tom Copeland

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–
          Tom Daly
          Tom Daly

          ๐Ÿ›
          Tomas
          Tomas

          ๐Ÿ›
          Tomer Figenblat
          Tomer Figenblat

          ๐Ÿ›
          Tomi De Lucca
          Tomi De Lucca

          ๐Ÿ’ป ๐Ÿ›
          Tony
          Tony

          ๐Ÿ“–
          Torsten Kleiber
          Torsten Kleiber

          ๐Ÿ›
          Torsten Kleiber
          Torsten Kleiber

          ๐Ÿ›
          Torsten Krause
          Torsten Krause

          ๐Ÿ›
          TrackerSB
          TrackerSB

          ๐Ÿ›
          Tyson Stewart
          Tyson Stewart

          ๐Ÿ›
          Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ›
          UncleOwen
          UncleOwen

          ๐Ÿ’ป ๐Ÿ“–
          Utku Cuhadaroglu
          Utku Cuhadaroglu

          ๐Ÿ’ป ๐Ÿ›
          Valentin Brandl
          Valentin Brandl

          ๐Ÿ›
          Valentin Brandl
          Valentin Brandl

          ๐Ÿ›
          Valeria
          Valeria

          ๐Ÿ›
          Valery Yatsynovich
          Valery Yatsynovich

          ๐Ÿ“–
          Vasily Anisimov
          Vasily Anisimov

          ๐Ÿ›
          Vedant Chokshi
          Vedant Chokshi

          ๐Ÿ›
          Vibhor Goyal
          Vibhor Goyal

          ๐Ÿ›
          Vickenty Fesunov
          Vickenty Fesunov

          ๐Ÿ›
          Victor Noรซl
          Victor Noรซl

          ๐Ÿ›
          Victor Noรซl
          Victor Noรซl

          ๐Ÿ›
          Vincent Galloy
          Vincent Galloy

          ๐Ÿ’ป
          Vincent HUYNH
          Vincent HUYNH

          ๐Ÿ›
          Vincent Maurin
          Vincent Maurin

          ๐Ÿ›
          Vincent Potucek
          Vincent Potucek

          ๐Ÿ’ป
          Vincent Privat
          Vincent Privat

          ๐Ÿ›
          Vishhwas
          Vishhwas

          ๐Ÿ›
          Vishv_Android
          Vishv_Android

          ๐Ÿ›
          Vishv_Android
          Vishv_Android

          ๐Ÿ›
          Vitalii Yevtushenko
          Vitalii Yevtushenko

          ๐Ÿ›
          Vitaly
          Vitaly

          ๐Ÿ›
          Vitaly Polonetsky
          Vitaly Polonetsky

          ๐Ÿ›
          Vojtech Polivka
          Vojtech Polivka

          ๐Ÿ›
          Vsevolod Zholobov
          Vsevolod Zholobov

          ๐Ÿ›
          Vyom Yadav
          Vyom Yadav

          ๐Ÿ’ป
          Wang Shidong
          Wang Shidong

          ๐Ÿ›
          Wang Shidong
          Wang Shidong

          ๐Ÿ›
          Waqas Ahmed
          Waqas Ahmed

          ๐Ÿ›
          Wayne J. Earl
          Wayne J. Earl

          ๐Ÿ›
          Wchenghui
          Wchenghui

          ๐Ÿ›
          Wener
          Wener

          ๐Ÿ’ป
          Will Winder
          Will Winder

          ๐Ÿ›
          Willem A. Hajenius
          Willem A. Hajenius

          ๐Ÿ’ป
          William Brockhus
          William Brockhus

          ๐Ÿ’ป ๐Ÿ›
          William Brockhus
          William Brockhus

          ๐Ÿ’ป ๐Ÿ›
          Wilson Kurniawan
          Wilson Kurniawan

          ๐Ÿ›
          Wim Deblauwe
          Wim Deblauwe

          ๐Ÿ›
          Wolf2323
          Wolf2323

          ๐Ÿ›
          Woongsik Choi
          Woongsik Choi

          ๐Ÿ›
          XenoAmess
          XenoAmess

          ๐Ÿ’ป ๐Ÿ›
          Yang
          Yang

          ๐Ÿ’ป
          YaroslavTER
          YaroslavTER

          ๐Ÿ›
          YaroslavTER
          YaroslavTER

          ๐Ÿ›
          Yasar Shaikh
          Yasar Shaikh

          ๐Ÿ’ป
          Young Chan
          Young Chan

          ๐Ÿ’ป ๐Ÿ›
          YuJin Kim
          YuJin Kim

          ๐Ÿ›
          Yuri Dolzhenko
          Yuri Dolzhenko

          ๐Ÿ›
          Yurii Dubinka
          Yurii Dubinka

          ๐Ÿ›
          Zbynek Konecny
          Zbynek Konecny

          ๐Ÿ› ๐Ÿ’ป
          Zoltan Farkas
          Zoltan Farkas

          ๐Ÿ›
          Zoltan Farkas
          Zoltan Farkas

          ๐Ÿ›
          Zustin
          Zustin

          ๐Ÿ›
          aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป
          alexmodis
          alexmodis

          ๐Ÿ›
          andreoss
          andreoss

          ๐Ÿ›
          andrey81inmd
          andrey81inmd

          ๐Ÿ’ป ๐Ÿ›
          anicoara
          anicoara

          ๐Ÿ›
          arunprasathav
          arunprasathav

          ๐Ÿ›
          arunprasathav
          arunprasathav

          ๐Ÿ›
          asiercamara
          asiercamara

          ๐Ÿ›
          astillich-igniti
          astillich-igniti

          ๐Ÿ’ป
          avesolovksyy
          avesolovksyy

          ๐Ÿ›
          avishvat
          avishvat

          ๐Ÿ›
          avivmu
          avivmu

          ๐Ÿ›
          axelbarfod1
          axelbarfod1

          ๐Ÿ›
          b-3-n
          b-3-n

          ๐Ÿ›
          b-3-n
          b-3-n

          ๐Ÿ›
          balbhadra9
          balbhadra9

          ๐Ÿ›
          base23de
          base23de

          ๐Ÿ›
          bergander
          bergander

          ๐Ÿ› ๐Ÿ’ป
          berkam
          berkam

          ๐Ÿ’ป ๐Ÿ›
          breizh31
          breizh31

          ๐Ÿ›
          caesarkim
          caesarkim

          ๐Ÿ›
          caiocarvalhotero
          caiocarvalhotero

          ๐Ÿ›
          caiocarvalhotero
          caiocarvalhotero

          ๐Ÿ›
          carolyujing
          carolyujing

          ๐Ÿ›
          cbfiddle
          cbfiddle

          ๐Ÿ›
          cesares-basilico
          cesares-basilico

          ๐Ÿ›
          chrite
          chrite

          ๐Ÿ›
          ciufudean
          ciufudean

          ๐Ÿ“–
          cobratbq
          cobratbq

          ๐Ÿ›
          coladict
          coladict

          ๐Ÿ›
          coladict
          coladict

          ๐Ÿ›
          cosmoJFH
          cosmoJFH

          ๐Ÿ›
          cristalp
          cristalp

          ๐Ÿ›
          crunsk
          crunsk

          ๐Ÿ›
          cwholmes
          cwholmes

          ๐Ÿ›
          cyberjj999
          cyberjj999

          ๐Ÿ›
          cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“–
          d1ss0nanz
          d1ss0nanz

          ๐Ÿ›
          d1ss0nanz
          d1ss0nanz

          ๐Ÿ›
          dague1
          dague1

          ๐Ÿ“–
          dalizi007
          dalizi007

          ๐Ÿ’ป
          danbrycefairsailcom
          danbrycefairsailcom

          ๐Ÿ›
          dariansanity
          dariansanity

          ๐Ÿ›
          darrenmiliband
          darrenmiliband

          ๐Ÿ›
          davidburstrom
          davidburstrom

          ๐Ÿ›
          dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ›
          dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ›
          deepak-patra
          deepak-patra

          ๐Ÿ›
          dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ›
          dinesh150
          dinesh150

          ๐Ÿ›
          diziaq
          diziaq

          ๐Ÿ›
          dreaminpast123
          dreaminpast123

          ๐Ÿ›
          duanyanan
          duanyanan

          ๐Ÿ›
          dutt-sanjay
          dutt-sanjay

          ๐Ÿ›
          dutt-sanjay
          dutt-sanjay

          ๐Ÿ›
          duursma
          duursma

          ๐Ÿ’ป
          dylanleung
          dylanleung

          ๐Ÿ›
          dzeigler
          dzeigler

          ๐Ÿ›
          eant60
          eant60

          ๐Ÿ›
          ekkirala
          ekkirala

          ๐Ÿ›
          emersonmoura
          emersonmoura

          ๐Ÿ›
          emouty
          emouty

          ๐Ÿ’ป ๐Ÿ›
          emouty
          emouty

          ๐Ÿ’ป ๐Ÿ›
          eugenepugach
          eugenepugach

          ๐Ÿ›
          fairy
          fairy

          ๐Ÿ›
          filiprafalowicz
          filiprafalowicz

          ๐Ÿ’ป
          flxbl-io
          flxbl-io

          ๐Ÿ’ต
          foxmason
          foxmason

          ๐Ÿ›
          frankegabor
          frankegabor

          ๐Ÿ›
          frankl
          frankl

          ๐Ÿ›
          frankl
          frankl

          ๐Ÿ›
          freafrea
          freafrea

          ๐Ÿ›
          fsapatin
          fsapatin

          ๐Ÿ›
          gearsethenry
          gearsethenry

          ๐Ÿ›
          gracia19
          gracia19

          ๐Ÿ›
          gudzpoz
          gudzpoz

          ๐Ÿ›
          guo fei
          guo fei

          ๐Ÿ›
          gurmsc5
          gurmsc5

          ๐Ÿ›
          gurmsc5
          gurmsc5

          ๐Ÿ›
          gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ›
          haigsn
          haigsn

          ๐Ÿ›
          hemanshu070
          hemanshu070

          ๐Ÿ›
          henrik242
          henrik242

          ๐Ÿ›
          hongpuwu
          hongpuwu

          ๐Ÿ›
          hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ›
          igniti GmbH
          igniti GmbH

          ๐Ÿ›
          igniti GmbH
          igniti GmbH

          ๐Ÿ›
          ilovezfs
          ilovezfs

          ๐Ÿ›
          imax-erik
          imax-erik

          ๐Ÿ›
          itaigilo
          itaigilo

          ๐Ÿ›
          jakivey32
          jakivey32

          ๐Ÿ›
          jbennett2091
          jbennett2091

          ๐Ÿ›
          jcamerin
          jcamerin

          ๐Ÿ›
          jkeener1
          jkeener1

          ๐Ÿ›
          jkeener1
          jkeener1

          ๐Ÿ›
          jmetertea
          jmetertea

          ๐Ÿ›
          johnra2
          johnra2

          ๐Ÿ’ป
          johnzhao9
          johnzhao9

          ๐Ÿ›
          josemanuelrolon
          josemanuelrolon

          ๐Ÿ’ป ๐Ÿ›
          julees7
          julees7

          ๐Ÿ’ป ๐Ÿ›
          kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ›
          karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“–
          karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“–
          karwer
          karwer

          ๐Ÿ›
          kaulonline
          kaulonline

          ๐Ÿ›
          kdaemonv
          kdaemonv

          ๐Ÿ›
          kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป
          kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ›
          kfranic
          kfranic

          ๐Ÿ›
          khalidkh
          khalidkh

          ๐Ÿ›
          khalidkh
          khalidkh

          ๐Ÿ›
          koalalam
          koalalam

          ๐Ÿ›
          krzyk
          krzyk

          ๐Ÿ›
          lasselindqvist
          lasselindqvist

          ๐Ÿ›
          lgemeinhardt
          lgemeinhardt

          ๐Ÿ›
          lihuaib
          lihuaib

          ๐Ÿ›
          liqingjun123
          liqingjun123

          ๐Ÿ›
          lonelyma1021
          lonelyma1021

          ๐Ÿ›
          lonelyma1021
          lonelyma1021

          ๐Ÿ›
          lothas
          lothas

          ๐Ÿ›
          lpeddy
          lpeddy

          ๐Ÿ›
          lujiefsi
          lujiefsi

          ๐Ÿ’ป
          lukelukes
          lukelukes

          ๐Ÿ’ป
          lyriccoder
          lyriccoder

          ๐Ÿ›
          marcelmore
          marcelmore

          ๐Ÿ›
          matchbox
          matchbox

          ๐Ÿ›
          matchbox
          matchbox

          ๐Ÿ›
          matthiaskraaz
          matthiaskraaz

          ๐Ÿ›
          meandonlyme
          meandonlyme

          ๐Ÿ›
          mikesive
          mikesive

          ๐Ÿ›
          milossesic
          milossesic

          ๐Ÿ›
          mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ›
          mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป
          mrclmh
          mrclmh

          ๐Ÿ›
          mrclmh
          mrclmh

          ๐Ÿ›
          mriddell95
          mriddell95

          ๐Ÿ›
          mrlzh
          mrlzh

          ๐Ÿ›
          msloan
          msloan

          ๐Ÿ›
          mucharlaravalika
          mucharlaravalika

          ๐Ÿ›
          mvenneman
          mvenneman

          ๐Ÿ›
          nareshl119
          nareshl119

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          noerremark
          noerremark

          ๐Ÿ›
          novsirion
          novsirion

          ๐Ÿ›
          nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป
          oggboy
          oggboy

          ๐Ÿ›
          oinume
          oinume

          ๐Ÿ›
          orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pacvz
          pacvz

          ๐Ÿ’ป
          pallavi agarwal
          pallavi agarwal

          ๐Ÿ›
          pankratz76
          pankratz76

          ๐Ÿ›
          parksungrin
          parksungrin

          ๐Ÿ›
          patpatpat123
          patpatpat123

          ๐Ÿ›
          patriksevallius
          patriksevallius

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          phoenix384
          phoenix384

          ๐Ÿ›
          piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป
          plan3d
          plan3d

          ๐Ÿ›
          poojasix
          poojasix

          ๐Ÿ›
          prabhushrikant
          prabhushrikant

          ๐Ÿ›
          pujitha8783
          pujitha8783

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          raghujayjunk
          raghujayjunk

          ๐Ÿ›
          rajeshveera
          rajeshveera

          ๐Ÿ›
          rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ›
          recdevs
          recdevs

          ๐Ÿ›
          reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ›
          rijkt
          rijkt

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ›
          rnveach
          rnveach

          ๐Ÿ›
          rxmicro
          rxmicro

          ๐Ÿ›
          ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ›
          sabi0
          sabi0

          ๐Ÿ›
          samc-gearset
          samc-gearset

          ๐Ÿ“–
          scais
          scais

          ๐Ÿ›
          scais
          scais

          ๐Ÿ›
          schosin
          schosin

          ๐Ÿ›
          screamingfrog
          screamingfrog

          ๐Ÿ’ต
          sebbASF
          sebbASF

          ๐Ÿ›
          sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป
          shilko2013
          shilko2013

          ๐Ÿ›
          shiomiyan
          shiomiyan

          ๐Ÿ“–
          simeonKondr
          simeonKondr

          ๐Ÿ›
          simeonKondr
          simeonKondr

          ๐Ÿ›
          snajberk
          snajberk

          ๐Ÿ›
          sniperrifle2004
          sniperrifle2004

          ๐Ÿ›
          snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป
          soloturn
          soloturn

          ๐Ÿ›
          soyodream
          soyodream

          ๐Ÿ›
          sratz
          sratz

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          sturton
          sturton

          ๐Ÿ’ป ๐Ÿ›
          sudharmohan
          sudharmohan

          ๐Ÿ›
          suruchidawar
          suruchidawar

          ๐Ÿ›
          svenfinitiv
          svenfinitiv

          ๐Ÿ›
          szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป
          tashiscool
          tashiscool

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          testation21
          testation21

          ๐Ÿ’ป ๐Ÿ›
          thanosa
          thanosa

          ๐Ÿ›
          tiandiyixian
          tiandiyixian

          ๐Ÿ›
          tobwoerk
          tobwoerk

          ๐Ÿ›
          tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป
          trentchilders
          trentchilders

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          trishul14
          trishul14

          ๐Ÿ›
          tsui
          tsui

          ๐Ÿ›
          wangzitom12306
          wangzitom12306

          ๐Ÿ›
          winhkey
          winhkey

          ๐Ÿ›
          witherspore
          witherspore

          ๐Ÿ›
          wjljack
          wjljack

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          xingsong
          xingsong

          ๐Ÿ›
          xioayuge
          xioayuge

          ๐Ÿ›
          xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ›
          xuanuy
          xuanuy

          ๐Ÿ›
          xyf0921
          xyf0921

          ๐Ÿ›
          yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yasuharu-sato
          yasuharu-sato

          ๐Ÿ›
          zenglian
          zenglian

          ๐Ÿ›
          zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ›
          zh3ng
          zh3ng

          ๐Ÿ›
          zt_soft
          zt_soft

          ๐Ÿ›
          ztt79
          ztt79

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ›
          ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ›
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ

          ๐Ÿ›
          Maciek Siemczyk
          Maciek Siemczyk

          ๐Ÿ›
          Maikel Steneker
          Maikel Steneker

          ๐Ÿ’ป ๐Ÿ›
          Maksim Moiseikin
          Maksim Moiseikin

          ๐Ÿ›
          Malik
          Malik

          ๐Ÿ›
          Manfred Koch
          Manfred Koch

          ๐Ÿ›
          Manuel Moya Ferrer
          Manuel Moya Ferrer

          ๐Ÿ’ป ๐Ÿ›
          Manuel Romeiro
          Manuel Romeiro

          ๐Ÿ›
          Manuel Ryan
          Manuel Ryan

          ๐Ÿ›
          Manuel Ryan
          Manuel Ryan

          ๐Ÿ›
          Marat Vyshegorodtsev
          Marat Vyshegorodtsev

          ๐Ÿ›
          Marcel Hรคrle
          Marcel Hรคrle

          ๐Ÿ›
          Marcello Fialho
          Marcello Fialho

          ๐Ÿ›
          Marcin Dฤ…browski
          Marcin Dฤ…browski

          ๐Ÿ’ป ๐Ÿ›
          Marcin Rataj
          Marcin Rataj

          ๐Ÿ›
          Marcono1234
          Marcono1234

          ๐Ÿ›
          Mark Adamcin
          Mark Adamcin

          ๐Ÿ›
          Mark Adamcin
          Mark Adamcin

          ๐Ÿ›
          Mark Hall
          Mark Hall

          ๐Ÿ’ป ๐Ÿ›
          Mark Kolich
          Mark Kolich

          ๐Ÿ›
          Mark Pritchard
          Mark Pritchard

          ๐Ÿ›
          Markus Rathgeb
          Markus Rathgeb

          ๐Ÿ›
          Marquis Wang
          Marquis Wang

          ๐Ÿ›
          MartGit
          MartGit

          ๐Ÿ›
          Martin Feldsztejn
          Martin Feldsztejn

          ๐Ÿ›
          Martin Feldsztejn
          Martin Feldsztejn

          ๐Ÿ›
          Martin Lehmann
          Martin Lehmann

          ๐Ÿ›
          Martin Spamer
          Martin Spamer

          ๐Ÿ›
          Martin Tarjรกnyi
          Martin Tarjรกnyi

          ๐Ÿ›
          MatFl
          MatFl

          ๐Ÿ›
          Mateusz Stefanski
          Mateusz Stefanski

          ๐Ÿ›
          Mathias Lagerwall
          Mathias Lagerwall

          ๐Ÿ›
          Mathieu Gouin
          Mathieu Gouin

          ๐Ÿ›
          Mathieu Gouin
          Mathieu Gouin

          ๐Ÿ›
          MatiasComercio
          MatiasComercio

          ๐Ÿ’ป ๐Ÿ›
          Matt Benson
          Matt Benson

          ๐Ÿ›
          Matt De Poorter
          Matt De Poorter

          ๐Ÿ›
          Matt Hargett
          Matt Hargett

          ๐Ÿ’ป ๐Ÿ’ต
          Matt Harrah
          Matt Harrah

          ๐Ÿ›
          Matt Nelson
          Matt Nelson

          ๐Ÿ›
          Matthew Amos
          Matthew Amos

          ๐Ÿ›
          Matthew Amos
          Matthew Amos

          ๐Ÿ›
          Matthew Duggan
          Matthew Duggan

          ๐Ÿ›
          Matthew Hall
          Matthew Hall

          ๐Ÿ›
          Matthew Rossner
          Matthew Rossner

          ๐Ÿ›
          Matรญas Fraga
          Matรญas Fraga

          ๐Ÿ’ป ๐Ÿ›
          Maxime Robert
          Maxime Robert

          ๐Ÿ’ป ๐Ÿ›
          MetaBF
          MetaBF

          ๐Ÿ›
          Metin Dagcilar
          Metin Dagcilar

          ๐Ÿ›
          Metin Dagcilar
          Metin Dagcilar

          ๐Ÿ›
          Michael
          Michael

          ๐Ÿ›
          Michael Bell
          Michael Bell

          ๐Ÿ›
          Michael Bernstein
          Michael Bernstein

          ๐Ÿ›
          Michael Clay
          Michael Clay

          ๐Ÿ›
          Michael Dombrowski
          Michael Dombrowski

          ๐Ÿ›
          Michael Hausegger
          Michael Hausegger

          ๐Ÿ›
          Michael Hoefer
          Michael Hoefer

          ๐Ÿ›
          Michael Hoefer
          Michael Hoefer

          ๐Ÿ›
          Michael Kolesnikov
          Michael Kolesnikov

          ๐Ÿ›
          Michael Mรถbius
          Michael Mรถbius

          ๐Ÿ›
          Michael N. Lipp
          Michael N. Lipp

          ๐Ÿ›
          Michael Pellegrini
          Michael Pellegrini

          ๐Ÿ›
          Michal Kordas
          Michal Kordas

          ๐Ÿ›
          Michaล‚ Borek
          Michaล‚ Borek

          ๐Ÿ›
          Michaล‚ Kuliล„ski
          Michaล‚ Kuliล„ski

          ๐Ÿ›
          Michaล‚ Kuliล„ski
          Michaล‚ Kuliล„ski

          ๐Ÿ›
          Miguel Nรบรฑez Dรญaz-Montes
          Miguel Nรบรฑez Dรญaz-Montes

          ๐Ÿ›
          Mihai Ionut
          Mihai Ionut

          ๐Ÿ›
          Mikhail Kuchma
          Mikhail Kuchma

          ๐Ÿ›
          MiladSadinam
          MiladSadinam

          ๐Ÿ›
          Mirek Hankus
          Mirek Hankus

          ๐Ÿ›
          Mitch Spano
          Mitch Spano

          ๐Ÿ’ป ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          MrAngry52
          MrAngry52

          ๐Ÿ›
          Muminur Choudhury
          Muminur Choudhury

          ๐Ÿ›
          Mykhailo Palahuta
          Mykhailo Palahuta

          ๐Ÿ’ป ๐Ÿ›
          Nagendra Kumar Singh
          Nagendra Kumar Singh

          ๐Ÿ›
          Nahuel Barrios
          Nahuel Barrios

          ๐Ÿ›
          Nakul Sharma
          Nakul Sharma

          ๐Ÿ›
          Nakul Sharma
          Nakul Sharma

          ๐Ÿ›
          Nathan Braun
          Nathan Braun

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathanaรซl
          Nathanaรซl

          ๐Ÿ›
          Naveen
          Naveen

          ๐Ÿ’ป
          Nazdravi
          Nazdravi

          ๐Ÿ›
          Neha-Dhonde
          Neha-Dhonde

          ๐Ÿ›
          Neha-Dhonde
          Neha-Dhonde

          ๐Ÿ›
          Nicholas Doyle
          Nicholas Doyle

          ๐Ÿ›
          Nick Butcher
          Nick Butcher

          ๐Ÿ›
          Nico Gallinal
          Nico Gallinal

          ๐Ÿ›
          Nicola Dal Maso
          Nicola Dal Maso

          ๐Ÿ›
          Nicolas Filotto
          Nicolas Filotto

          ๐Ÿ’ป
          Nicolas Vervelle
          Nicolas Vervelle

          ๐Ÿ›
          Nicolas Vuillamy
          Nicolas Vuillamy

          ๐Ÿ“–
          Nicolas Vuillamy
          Nicolas Vuillamy

          ๐Ÿ“–
          Nikita Chursin
          Nikita Chursin

          ๐Ÿ›
          Niklas Baudy
          Niklas Baudy

          ๐Ÿ›
          Nikolas Havrikov
          Nikolas Havrikov

          ๐Ÿ›
          Nilesh Virkar
          Nilesh Virkar

          ๐Ÿ›
          Nimit Patel
          Nimit Patel

          ๐Ÿ›
          Niranjan Harpale
          Niranjan Harpale

          ๐Ÿ›
          Nirvik Patel
          Nirvik Patel

          ๐Ÿ’ป
          Nirvik Patel
          Nirvik Patel

          ๐Ÿ’ป
          Noah Sussman
          Noah Sussman

          ๐Ÿ›
          Noah0120
          Noah0120

          ๐Ÿ›
          Noam Tamim
          Noam Tamim

          ๐Ÿ›
          Noel Grandin
          Noel Grandin

          ๐Ÿ›
          Olaf Haalstra
          Olaf Haalstra

          ๐Ÿ›
          Oleg Andreych
          Oleg Andreych

          ๐Ÿ’ป ๐Ÿ›
          Oleg Pavlenko
          Oleg Pavlenko

          ๐Ÿ›
          Oleg Pavlenko
          Oleg Pavlenko

          ๐Ÿ›
          Oleksii Dykov
          Oleksii Dykov

          ๐Ÿ’ป ๐Ÿ›
          Oliver Eikemeier
          Oliver Eikemeier

          ๐Ÿ›
          Oliver Siegmar
          Oliver Siegmar

          ๐Ÿ’ต
          Olivier Parent
          Olivier Parent

          ๐Ÿ’ป ๐Ÿ›
          Ollie Abbey
          Ollie Abbey

          ๐Ÿ’ป ๐Ÿ›
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)

          ๐Ÿ›
          Ondrej Kratochvil
          Ondrej Kratochvil

          ๐Ÿ›
          Ondrej Kratochvil
          Ondrej Kratochvil

          ๐Ÿ›
          OverDrone
          OverDrone

          ๐Ÿ›
          Ozan Gulle
          Ozan Gulle

          ๐Ÿ’ป ๐Ÿ›
          PUNEET JAIN
          PUNEET JAIN

          ๐Ÿ›
          Pankraz76
          Pankraz76

          ๐Ÿ’ป ๐Ÿ›
          Parbati Bose
          Parbati Bose

          ๐Ÿ›
          Paul Berg
          Paul Berg

          ๐Ÿ›
          Paul Guyot
          Paul Guyot

          ๐Ÿ’ป
          Paul Guyot
          Paul Guyot

          ๐Ÿ’ป
          Pavel Bludov
          Pavel Bludov

          ๐Ÿ›
          Pavel Miฤka
          Pavel Miฤka

          ๐Ÿ›
          Pedro Nuno Santos
          Pedro Nuno Santos

          ๐Ÿ›
          Pedro Rijo
          Pedro Rijo

          ๐Ÿ›
          Pelisse Romain
          Pelisse Romain

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
          Per Abich
          Per Abich

          ๐Ÿ’ป
          Pete Davids
          Pete Davids

          ๐Ÿ›
          Pete Davids
          Pete Davids

          ๐Ÿ›
          Peter Bruin
          Peter Bruin

          ๐Ÿ›
          Peter Chittum
          Peter Chittum

          ๐Ÿ’ป ๐Ÿ›
          Peter Cudmore
          Peter Cudmore

          ๐Ÿ›
          Peter Kasson
          Peter Kasson

          ๐Ÿ›
          Peter Kofler
          Peter Kofler

          ๐Ÿ›
          Peter Paul Bakker
          Peter Paul Bakker

          ๐Ÿ’ป ๐Ÿ›
          Peter Rader
          Peter Rader

          ๐Ÿ›
          Peter Rader
          Peter Rader

          ๐Ÿ›
          Pham Hai Trung
          Pham Hai Trung

          ๐Ÿ›
          Philip Graf
          Philip Graf

          ๐Ÿ’ป ๐Ÿ›
          Philip Hachey
          Philip Hachey

          ๐Ÿ›
          Philippe Ozil
          Philippe Ozil

          ๐Ÿ›
          Phinehas Artemix
          Phinehas Artemix

          ๐Ÿ›
          Phokham Nonava
          Phokham Nonava

          ๐Ÿ›
          Pim van der Loos
          Pim van der Loos

          ๐Ÿ’ป โš ๏ธ
          Pim van der Loos
          Pim van der Loos

          ๐Ÿ’ป โš ๏ธ
          Piotr Szymaล„ski
          Piotr Szymaล„ski

          ๐Ÿ›
          Piotrek ลปygieล‚o
          Piotrek ลปygieล‚o

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“–
          Pranay Jaiswal
          Pranay Jaiswal

          ๐Ÿ›
          Prasad Kamath
          Prasad Kamath

          ๐Ÿ›
          Prasanna
          Prasanna

          ๐Ÿ›
          Presh-AR
          Presh-AR

          ๐Ÿ›
          Puneet1726
          Puneet1726

          ๐Ÿ›
          Puneet1726
          Puneet1726

          ๐Ÿ›
          RBRi
          RBRi

          ๐Ÿ›
          Rafael Cortรชs
          Rafael Cortรชs

          ๐Ÿ›
          RaheemShaik999
          RaheemShaik999

          ๐Ÿ›
          RajeshR
          RajeshR

          ๐Ÿ’ป ๐Ÿ›
          Ramachandra Mohan
          Ramachandra Mohan

          ๐Ÿ›
          Ramel0921
          Ramel0921

          ๐Ÿ›
          Raquel Pau
          Raquel Pau

          ๐Ÿ›
          Raquel Pau
          Raquel Pau

          ๐Ÿ›
          Ravikiran Janardhana
          Ravikiran Janardhana

          ๐Ÿ›
          Reda Benhemmouche
          Reda Benhemmouche

          ๐Ÿ›
          Reinhard Schiedermeier
          Reinhard Schiedermeier

          ๐Ÿ›
          Renato Oliveira
          Renato Oliveira

          ๐Ÿ’ป ๐Ÿ›
          Rich DiCroce
          Rich DiCroce

          ๐Ÿ›
          Richard Corfield
          Richard Corfield

          ๐Ÿ’ป
          Richard Corfield
          Richard Corfield

          ๐Ÿ› ๐Ÿ’ป
          Richard Corfield
          Richard Corfield

          ๐Ÿ› ๐Ÿ’ป
          Riot R1cket
          Riot R1cket

          ๐Ÿ›
          Rishabh Jain
          Rishabh Jain

          ๐Ÿ›
          RishabhDeep Singh
          RishabhDeep Singh

          ๐Ÿ›
          Rob Baillie
          Rob Baillie

          ๐Ÿ›
          Robbie Martinus
          Robbie Martinus

          ๐Ÿ’ป ๐Ÿ›
          Robert Henry
          Robert Henry

          ๐Ÿ›
          Robert Mihaly
          Robert Mihaly

          ๐Ÿ›
          Robert Mihaly
          Robert Mihaly

          ๐Ÿ›
          Robert Painsi
          Robert Painsi

          ๐Ÿ›
          Robert Russell
          Robert Russell

          ๐Ÿ›
          Robert Sรถsemann
          Robert Sรถsemann

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ›
          Robert Whitebit
          Robert Whitebit

          ๐Ÿ›
          Robin Richtsfeld
          Robin Richtsfeld

          ๐Ÿ›
          Robin Stocker
          Robin Stocker

          ๐Ÿ’ป ๐Ÿ›
          Robin Wils
          Robin Wils

          ๐Ÿ›
          Robin Wils
          Robin Wils

          ๐Ÿ›
          RochusOest
          RochusOest

          ๐Ÿ›
          Rodolfo Noviski
          Rodolfo Noviski

          ๐Ÿ›
          Rodrigo Casara
          Rodrigo Casara

          ๐Ÿ›
          Rodrigo Fernandes
          Rodrigo Fernandes

          ๐Ÿ›
          Roman Salvador
          Roman Salvador

          ๐Ÿ’ป ๐Ÿ›
          Ronald Blaschke
          Ronald Blaschke

          ๐Ÿ›
          Rรณbert Papp
          Rรณbert Papp

          ๐Ÿ›
          Rรณbert Papp
          Rรณbert Papp

          ๐Ÿ›
          Saikat Sengupta
          Saikat Sengupta

          ๐Ÿ›
          Saksham Handu
          Saksham Handu

          ๐Ÿ›
          Saladoc
          Saladoc

          ๐Ÿ›
          Salesforce Bob Lightning
          Salesforce Bob Lightning

          ๐Ÿ›
          Sam Carlberg
          Sam Carlberg

          ๐Ÿ›
          Sascha Riemer
          Sascha Riemer

          ๐Ÿ›
          Sashko
          Sashko

          ๐Ÿ’ป
          Sashko
          Sashko

          ๐Ÿ’ป
          Satoshi Kubo
          Satoshi Kubo

          ๐Ÿ›
          Scott Kennedy
          Scott Kennedy

          ๐Ÿ›
          Scott Wells
          Scott Wells

          ๐Ÿ› ๐Ÿ’ป
          Scrates1
          Scrates1

          ๐Ÿ› ๐Ÿ’ป
          Scrsloota
          Scrsloota

          ๐Ÿ’ป
          Sebastian Bรถgl
          Sebastian Bรถgl

          ๐Ÿ›
          Sebastian Davids
          Sebastian Davids

          ๐Ÿ›
          Sebastian Davids
          Sebastian Davids

          ๐Ÿ›
          Sebastian Lรถvdahl
          Sebastian Lรถvdahl

          ๐Ÿ›
          Sebastian Schuberth
          Sebastian Schuberth

          ๐Ÿ›
          Sebastian Schwarz
          Sebastian Schwarz

          ๐Ÿ›
          Seren
          Seren

          ๐Ÿ› ๐Ÿ’ป
          Sergey Gorbaty
          Sergey Gorbaty

          ๐Ÿ›
          Sergey Kozlov
          Sergey Kozlov

          ๐Ÿ›
          Sergey Yanzin
          Sergey Yanzin

          ๐Ÿ’ป ๐Ÿ›
          Sergey Yanzin
          Sergey Yanzin

          ๐Ÿ’ป ๐Ÿ›
          Seth Wilcox
          Seth Wilcox

          ๐Ÿ’ป
          Shai Bennathan
          Shai Bennathan

          ๐Ÿ› ๐Ÿ’ป
          Shubham
          Shubham

          ๐Ÿ’ป ๐Ÿ›
          Simon Abykov
          Simon Abykov

          ๐Ÿ’ป ๐Ÿ›
          Simon Xiao
          Simon Xiao

          ๐Ÿ›
          Srinivasan Venkatachalam
          Srinivasan Venkatachalam

          ๐Ÿ›
          Stanislav Gromov
          Stanislav Gromov

          ๐Ÿ›
          Stanislav Gromov
          Stanislav Gromov

          ๐Ÿ›
          Stanislav Myachenkov
          Stanislav Myachenkov

          ๐Ÿ’ป
          Stefan Birkner
          Stefan Birkner

          ๐Ÿ›
          Stefan Bohn
          Stefan Bohn

          ๐Ÿ›
          Stefan Endrullis
          Stefan Endrullis

          ๐Ÿ›
          Stefan Klรถss-Schuster
          Stefan Klรถss-Schuster

          ๐Ÿ›
          Stefan Wolf
          Stefan Wolf

          ๐Ÿ›
          Stephan H. Wissel
          Stephan H. Wissel

          ๐Ÿ›
          Stephan H. Wissel
          Stephan H. Wissel

          ๐Ÿ›
          Stephen
          Stephen

          ๐Ÿ›
          Stephen Carter
          Stephen Carter

          ๐Ÿ›
          Stephen Friedrich
          Stephen Friedrich

          ๐Ÿ›
          Steve Babula
          Steve Babula

          ๐Ÿ’ป
          Steven Stearns
          Steven Stearns

          ๐Ÿ› ๐Ÿ’ป
          Stexxe
          Stexxe

          ๐Ÿ›
          Stian Lรฅgstad
          Stian Lรฅgstad

          ๐Ÿ›
          Stian Lรฅgstad
          Stian Lรฅgstad

          ๐Ÿ›
          StuartClayton5
          StuartClayton5

          ๐Ÿ›
          Supun Arunoda
          Supun Arunoda

          ๐Ÿ›
          Suren Abrahamyan
          Suren Abrahamyan

          ๐Ÿ›
          Suvashri
          Suvashri

          ๐Ÿ“–
          Sven Barden
          Sven Barden

          ๐Ÿ›
          SwatiBGupta1110
          SwatiBGupta1110

          ๐Ÿ›
          SyedThoufich
          SyedThoufich

          ๐Ÿ›
          SyedThoufich
          SyedThoufich

          ๐Ÿ›
          Szymon Sasin
          Szymon Sasin

          ๐Ÿ›
          T-chuangxin
          T-chuangxin

          ๐Ÿ›
          TERAI Atsuhiro
          TERAI Atsuhiro

          ๐Ÿ›
          TIOBE Software
          TIOBE Software

          ๐Ÿ’ป ๐Ÿ›
          Tarush Singh
          Tarush Singh

          ๐Ÿ’ป
          Taylor Smock
          Taylor Smock

          ๐Ÿ›
          Techeira Damiรกn
          Techeira Damiรกn

          ๐Ÿ’ป ๐Ÿ›
          Techeira Damiรกn
          Techeira Damiรกn

          ๐Ÿ’ป ๐Ÿ›
          Ted Husted
          Ted Husted

          ๐Ÿ›
          TehBakker
          TehBakker

          ๐Ÿ›
          The Gitter Badger
          The Gitter Badger

          ๐Ÿ›
          Theodoor
          Theodoor

          ๐Ÿ›
          Thiago Henrique Hรผpner
          Thiago Henrique Hรผpner

          ๐Ÿ›
          Thibault Meyer
          Thibault Meyer

          ๐Ÿ›
          Thomas Gรผttler
          Thomas Gรผttler

          ๐Ÿ›
          Thomas Gรผttler
          Thomas Gรผttler

          ๐Ÿ›
          Thomas Jones-Low
          Thomas Jones-Low

          ๐Ÿ›
          Thomas Smith
          Thomas Smith

          ๐Ÿ’ป ๐Ÿ›
          ThrawnCA
          ThrawnCA

          ๐Ÿ›
          Thu Vo
          Thu Vo

          ๐Ÿ›
          Thunderforge
          Thunderforge

          ๐Ÿ’ป ๐Ÿ›
          Tim van der Lippe
          Tim van der Lippe

          ๐Ÿ›
          Tobias Weimer
          Tobias Weimer

          ๐Ÿ’ป ๐Ÿ›
          Tobias Weimer
          Tobias Weimer

          ๐Ÿ’ป ๐Ÿ›
          Tom Copeland
          Tom Copeland

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–
          Tom Daly
          Tom Daly

          ๐Ÿ›
          Tomas
          Tomas

          ๐Ÿ›
          Tomer Figenblat
          Tomer Figenblat

          ๐Ÿ›
          Tomi De Lucca
          Tomi De Lucca

          ๐Ÿ’ป ๐Ÿ›
          Tony
          Tony

          ๐Ÿ“–
          Torsten Kleiber
          Torsten Kleiber

          ๐Ÿ›
          Torsten Kleiber
          Torsten Kleiber

          ๐Ÿ›
          Torsten Krause
          Torsten Krause

          ๐Ÿ›
          TrackerSB
          TrackerSB

          ๐Ÿ›
          Tyson Stewart
          Tyson Stewart

          ๐Ÿ›
          Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ›
          UncleOwen
          UncleOwen

          ๐Ÿ’ป ๐Ÿ“–
          Utku Cuhadaroglu
          Utku Cuhadaroglu

          ๐Ÿ’ป ๐Ÿ›
          Valentin Brandl
          Valentin Brandl

          ๐Ÿ›
          Valentin Brandl
          Valentin Brandl

          ๐Ÿ›
          Valeria
          Valeria

          ๐Ÿ›
          Valery Yatsynovich
          Valery Yatsynovich

          ๐Ÿ“–
          Vasily Anisimov
          Vasily Anisimov

          ๐Ÿ›
          Vedant Chokshi
          Vedant Chokshi

          ๐Ÿ›
          Vibhor Goyal
          Vibhor Goyal

          ๐Ÿ›
          Vickenty Fesunov
          Vickenty Fesunov

          ๐Ÿ›
          Victor Noรซl
          Victor Noรซl

          ๐Ÿ›
          Victor Noรซl
          Victor Noรซl

          ๐Ÿ›
          Vincent Galloy
          Vincent Galloy

          ๐Ÿ’ป
          Vincent HUYNH
          Vincent HUYNH

          ๐Ÿ›
          Vincent Maurin
          Vincent Maurin

          ๐Ÿ›
          Vincent Potucek
          Vincent Potucek

          ๐Ÿ’ป
          Vincent Privat
          Vincent Privat

          ๐Ÿ›
          Vishhwas
          Vishhwas

          ๐Ÿ›
          Vishv_Android
          Vishv_Android

          ๐Ÿ›
          Vishv_Android
          Vishv_Android

          ๐Ÿ›
          Vitalii Yevtushenko
          Vitalii Yevtushenko

          ๐Ÿ›
          Vitaly
          Vitaly

          ๐Ÿ›
          Vitaly Polonetsky
          Vitaly Polonetsky

          ๐Ÿ›
          Vojtech Polivka
          Vojtech Polivka

          ๐Ÿ›
          Vsevolod Zholobov
          Vsevolod Zholobov

          ๐Ÿ›
          Vyom Yadav
          Vyom Yadav

          ๐Ÿ’ป
          Wang Shidong
          Wang Shidong

          ๐Ÿ›
          Wang Shidong
          Wang Shidong

          ๐Ÿ›
          Waqas Ahmed
          Waqas Ahmed

          ๐Ÿ›
          Wayne J. Earl
          Wayne J. Earl

          ๐Ÿ›
          Wchenghui
          Wchenghui

          ๐Ÿ›
          Wener
          Wener

          ๐Ÿ’ป
          Will Winder
          Will Winder

          ๐Ÿ›
          Willem A. Hajenius
          Willem A. Hajenius

          ๐Ÿ’ป
          William Brockhus
          William Brockhus

          ๐Ÿ’ป ๐Ÿ›
          William Brockhus
          William Brockhus

          ๐Ÿ’ป ๐Ÿ›
          Wilson Kurniawan
          Wilson Kurniawan

          ๐Ÿ›
          Wim Deblauwe
          Wim Deblauwe

          ๐Ÿ›
          Wolf2323
          Wolf2323

          ๐Ÿ›
          Woongsik Choi
          Woongsik Choi

          ๐Ÿ›
          XenoAmess
          XenoAmess

          ๐Ÿ’ป ๐Ÿ›
          Yang
          Yang

          ๐Ÿ’ป
          YaroslavTER
          YaroslavTER

          ๐Ÿ›
          YaroslavTER
          YaroslavTER

          ๐Ÿ›
          Yasar Shaikh
          Yasar Shaikh

          ๐Ÿ’ป
          Young Chan
          Young Chan

          ๐Ÿ’ป ๐Ÿ›
          YuJin Kim
          YuJin Kim

          ๐Ÿ›
          Yuri Dolzhenko
          Yuri Dolzhenko

          ๐Ÿ›
          Yurii Dubinka
          Yurii Dubinka

          ๐Ÿ›
          Zbynek Konecny
          Zbynek Konecny

          ๐Ÿ› ๐Ÿ’ป
          Zoltan Farkas
          Zoltan Farkas

          ๐Ÿ›
          Zoltan Farkas
          Zoltan Farkas

          ๐Ÿ›
          Zustin
          Zustin

          ๐Ÿ›
          aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป
          alexmodis
          alexmodis

          ๐Ÿ›
          andreoss
          andreoss

          ๐Ÿ›
          andrey81inmd
          andrey81inmd

          ๐Ÿ’ป ๐Ÿ›
          anicoara
          anicoara

          ๐Ÿ›
          arunprasathav
          arunprasathav

          ๐Ÿ›
          arunprasathav
          arunprasathav

          ๐Ÿ›
          asiercamara
          asiercamara

          ๐Ÿ›
          astillich-igniti
          astillich-igniti

          ๐Ÿ’ป
          avesolovksyy
          avesolovksyy

          ๐Ÿ›
          avishvat
          avishvat

          ๐Ÿ›
          avivmu
          avivmu

          ๐Ÿ›
          axelbarfod1
          axelbarfod1

          ๐Ÿ›
          b-3-n
          b-3-n

          ๐Ÿ›
          b-3-n
          b-3-n

          ๐Ÿ›
          balbhadra9
          balbhadra9

          ๐Ÿ›
          base23de
          base23de

          ๐Ÿ›
          bergander
          bergander

          ๐Ÿ› ๐Ÿ’ป
          berkam
          berkam

          ๐Ÿ’ป ๐Ÿ›
          breizh31
          breizh31

          ๐Ÿ›
          caesarkim
          caesarkim

          ๐Ÿ›
          caiocarvalhotero
          caiocarvalhotero

          ๐Ÿ›
          caiocarvalhotero
          caiocarvalhotero

          ๐Ÿ›
          carolyujing
          carolyujing

          ๐Ÿ›
          cbfiddle
          cbfiddle

          ๐Ÿ›
          cesares-basilico
          cesares-basilico

          ๐Ÿ›
          chrite
          chrite

          ๐Ÿ›
          ciufudean
          ciufudean

          ๐Ÿ“–
          cobratbq
          cobratbq

          ๐Ÿ›
          coladict
          coladict

          ๐Ÿ›
          coladict
          coladict

          ๐Ÿ›
          cosmoJFH
          cosmoJFH

          ๐Ÿ›
          cristalp
          cristalp

          ๐Ÿ›
          crunsk
          crunsk

          ๐Ÿ›
          cwholmes
          cwholmes

          ๐Ÿ›
          cyberjj999
          cyberjj999

          ๐Ÿ›
          cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“–
          d1ss0nanz
          d1ss0nanz

          ๐Ÿ›
          d1ss0nanz
          d1ss0nanz

          ๐Ÿ›
          dague1
          dague1

          ๐Ÿ“–
          dalizi007
          dalizi007

          ๐Ÿ’ป
          danbrycefairsailcom
          danbrycefairsailcom

          ๐Ÿ›
          dariansanity
          dariansanity

          ๐Ÿ›
          darrenmiliband
          darrenmiliband

          ๐Ÿ›
          davidburstrom
          davidburstrom

          ๐Ÿ›
          dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ›
          dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ›
          deepak-patra
          deepak-patra

          ๐Ÿ›
          dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ›
          dinesh150
          dinesh150

          ๐Ÿ›
          diziaq
          diziaq

          ๐Ÿ›
          dreaminpast123
          dreaminpast123

          ๐Ÿ›
          duanyanan
          duanyanan

          ๐Ÿ›
          dutt-sanjay
          dutt-sanjay

          ๐Ÿ›
          dutt-sanjay
          dutt-sanjay

          ๐Ÿ›
          duursma
          duursma

          ๐Ÿ’ป
          dylanleung
          dylanleung

          ๐Ÿ›
          dzeigler
          dzeigler

          ๐Ÿ›
          eant60
          eant60

          ๐Ÿ›
          ekkirala
          ekkirala

          ๐Ÿ›
          emersonmoura
          emersonmoura

          ๐Ÿ›
          emouty
          emouty

          ๐Ÿ’ป ๐Ÿ›
          emouty
          emouty

          ๐Ÿ’ป ๐Ÿ›
          eugenepugach
          eugenepugach

          ๐Ÿ›
          fairy
          fairy

          ๐Ÿ›
          filiprafalowicz
          filiprafalowicz

          ๐Ÿ’ป
          flxbl-io
          flxbl-io

          ๐Ÿ’ต
          foxmason
          foxmason

          ๐Ÿ›
          frankegabor
          frankegabor

          ๐Ÿ›
          frankl
          frankl

          ๐Ÿ›
          frankl
          frankl

          ๐Ÿ›
          freafrea
          freafrea

          ๐Ÿ›
          fsapatin
          fsapatin

          ๐Ÿ›
          gearsethenry
          gearsethenry

          ๐Ÿ›
          gracia19
          gracia19

          ๐Ÿ›
          gudzpoz
          gudzpoz

          ๐Ÿ›
          guo fei
          guo fei

          ๐Ÿ›
          gurmsc5
          gurmsc5

          ๐Ÿ›
          gurmsc5
          gurmsc5

          ๐Ÿ›
          gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ›
          haigsn
          haigsn

          ๐Ÿ›
          hemanshu070
          hemanshu070

          ๐Ÿ›
          henrik242
          henrik242

          ๐Ÿ›
          hongpuwu
          hongpuwu

          ๐Ÿ›
          hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ›
          igniti GmbH
          igniti GmbH

          ๐Ÿ›
          igniti GmbH
          igniti GmbH

          ๐Ÿ›
          ilovezfs
          ilovezfs

          ๐Ÿ›
          imax-erik
          imax-erik

          ๐Ÿ›
          itaigilo
          itaigilo

          ๐Ÿ›
          jakivey32
          jakivey32

          ๐Ÿ›
          jbennett2091
          jbennett2091

          ๐Ÿ›
          jcamerin
          jcamerin

          ๐Ÿ›
          jkeener1
          jkeener1

          ๐Ÿ›
          jkeener1
          jkeener1

          ๐Ÿ›
          jmetertea
          jmetertea

          ๐Ÿ›
          johnra2
          johnra2

          ๐Ÿ’ป
          johnzhao9
          johnzhao9

          ๐Ÿ›
          josemanuelrolon
          josemanuelrolon

          ๐Ÿ’ป ๐Ÿ›
          julees7
          julees7

          ๐Ÿ’ป ๐Ÿ›
          kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ›
          karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“–
          karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“–
          karwer
          karwer

          ๐Ÿ›
          kaulonline
          kaulonline

          ๐Ÿ›
          kdaemonv
          kdaemonv

          ๐Ÿ›
          kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป
          kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ›
          kfranic
          kfranic

          ๐Ÿ›
          khalidkh
          khalidkh

          ๐Ÿ›
          khalidkh
          khalidkh

          ๐Ÿ›
          koalalam
          koalalam

          ๐Ÿ›
          krzyk
          krzyk

          ๐Ÿ›
          lasselindqvist
          lasselindqvist

          ๐Ÿ›
          lgemeinhardt
          lgemeinhardt

          ๐Ÿ›
          lihuaib
          lihuaib

          ๐Ÿ›
          liqingjun123
          liqingjun123

          ๐Ÿ›
          lonelyma1021
          lonelyma1021

          ๐Ÿ›
          lonelyma1021
          lonelyma1021

          ๐Ÿ›
          lothas
          lothas

          ๐Ÿ›
          lpeddy
          lpeddy

          ๐Ÿ›
          lujiefsi
          lujiefsi

          ๐Ÿ’ป
          lukelukes
          lukelukes

          ๐Ÿ’ป
          lyriccoder
          lyriccoder

          ๐Ÿ›
          marcelmore
          marcelmore

          ๐Ÿ›
          matchbox
          matchbox

          ๐Ÿ›
          matchbox
          matchbox

          ๐Ÿ›
          matthiaskraaz
          matthiaskraaz

          ๐Ÿ›
          meandonlyme
          meandonlyme

          ๐Ÿ›
          mikesive
          mikesive

          ๐Ÿ›
          milossesic
          milossesic

          ๐Ÿ›
          mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ›
          mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป
          mrclmh
          mrclmh

          ๐Ÿ›
          mrclmh
          mrclmh

          ๐Ÿ›
          mriddell95
          mriddell95

          ๐Ÿ›
          mrlzh
          mrlzh

          ๐Ÿ›
          msloan
          msloan

          ๐Ÿ›
          mucharlaravalika
          mucharlaravalika

          ๐Ÿ›
          mvenneman
          mvenneman

          ๐Ÿ›
          nareshl119
          nareshl119

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          noerremark
          noerremark

          ๐Ÿ›
          novsirion
          novsirion

          ๐Ÿ›
          nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป
          oggboy
          oggboy

          ๐Ÿ›
          oinume
          oinume

          ๐Ÿ›
          orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pacvz
          pacvz

          ๐Ÿ’ป
          pallavi agarwal
          pallavi agarwal

          ๐Ÿ›
          pankratz76
          pankratz76

          ๐Ÿ›
          parksungrin
          parksungrin

          ๐Ÿ›
          patpatpat123
          patpatpat123

          ๐Ÿ›
          patriksevallius
          patriksevallius

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          phoenix384
          phoenix384

          ๐Ÿ›
          piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป
          plan3d
          plan3d

          ๐Ÿ›
          poojasix
          poojasix

          ๐Ÿ›
          prabhushrikant
          prabhushrikant

          ๐Ÿ›
          pujitha8783
          pujitha8783

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          raghujayjunk
          raghujayjunk

          ๐Ÿ›
          rajeshveera
          rajeshveera

          ๐Ÿ›
          rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ›
          recdevs
          recdevs

          ๐Ÿ›
          reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ›
          rijkt
          rijkt

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ›
          rnveach
          rnveach

          ๐Ÿ›
          rxmicro
          rxmicro

          ๐Ÿ›
          ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ›
          sabi0
          sabi0

          ๐Ÿ›
          samc-gearset
          samc-gearset

          ๐Ÿ“–
          scais
          scais

          ๐Ÿ›
          scais
          scais

          ๐Ÿ›
          schosin
          schosin

          ๐Ÿ›
          screamingfrog
          screamingfrog

          ๐Ÿ’ต
          sebbASF
          sebbASF

          ๐Ÿ›
          sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป
          shilko2013
          shilko2013

          ๐Ÿ›
          shiomiyan
          shiomiyan

          ๐Ÿ“–
          simeonKondr
          simeonKondr

          ๐Ÿ›
          simeonKondr
          simeonKondr

          ๐Ÿ›
          snajberk
          snajberk

          ๐Ÿ›
          sniperrifle2004
          sniperrifle2004

          ๐Ÿ›
          snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป
          soloturn
          soloturn

          ๐Ÿ›
          soyodream
          soyodream

          ๐Ÿ›
          sratz
          sratz

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          sturton
          sturton

          ๐Ÿ’ป ๐Ÿ›
          sudharmohan
          sudharmohan

          ๐Ÿ›
          suruchidawar
          suruchidawar

          ๐Ÿ›
          svenfinitiv
          svenfinitiv

          ๐Ÿ›
          szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป
          tashiscool
          tashiscool

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          testation21
          testation21

          ๐Ÿ’ป ๐Ÿ›
          thanosa
          thanosa

          ๐Ÿ›
          tiandiyixian
          tiandiyixian

          ๐Ÿ›
          tobwoerk
          tobwoerk

          ๐Ÿ›
          tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป
          trentchilders
          trentchilders

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          trishul14
          trishul14

          ๐Ÿ›
          tsui
          tsui

          ๐Ÿ›
          wangzitom12306
          wangzitom12306

          ๐Ÿ›
          winhkey
          winhkey

          ๐Ÿ›
          witherspore
          witherspore

          ๐Ÿ›
          wjljack
          wjljack

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          xingsong
          xingsong

          ๐Ÿ›
          xioayuge
          xioayuge

          ๐Ÿ›
          xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ›
          xuanuy
          xuanuy

          ๐Ÿ›
          xyf0921
          xyf0921

          ๐Ÿ›
          yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yasuharu-sato
          yasuharu-sato

          ๐Ÿ›
          zenglian
          zenglian

          ๐Ÿ›
          zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ›
          zh3ng
          zh3ng

          ๐Ÿ›
          zt_soft
          zt_soft

          ๐Ÿ›
          ztt79
          ztt79

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ›
          ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ›
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ

          ๐Ÿ›
          Malik
          Malik

          ๐Ÿ›
          Manfred Koch
          Manfred Koch

          ๐Ÿ›
          Manuel Moya Ferrer
          Manuel Moya Ferrer

          ๐Ÿ’ป ๐Ÿ›
          Manuel Romeiro
          Manuel Romeiro

          ๐Ÿ›
          Manuel Romeiro
          Manuel Romeiro

          ๐Ÿ›
          Manuel Ryan
          Manuel Ryan

          ๐Ÿ›
          Marat Vyshegorodtsev
          Marat Vyshegorodtsev

          ๐Ÿ›
          Marcel Hรคrle
          Marcel Hรคrle

          ๐Ÿ›
          Marcello Fialho
          Marcello Fialho

          ๐Ÿ›
          Marcin Dฤ…browski
          Marcin Dฤ…browski

          ๐Ÿ’ป ๐Ÿ›
          Marcin Rataj
          Marcin Rataj

          ๐Ÿ›
          Marcono1234
          Marcono1234

          ๐Ÿ›
          Marcono1234
          Marcono1234

          ๐Ÿ›
          Mark Adamcin
          Mark Adamcin

          ๐Ÿ›
          Mark Hall
          Mark Hall

          ๐Ÿ’ป ๐Ÿ›
          Mark Kolich
          Mark Kolich

          ๐Ÿ›
          Mark Pritchard
          Mark Pritchard

          ๐Ÿ›
          Markus Rathgeb
          Markus Rathgeb

          ๐Ÿ›
          Marquis Wang
          Marquis Wang

          ๐Ÿ›
          MartGit
          MartGit

          ๐Ÿ›
          MartGit
          MartGit

          ๐Ÿ›
          Martin Feldsztejn
          Martin Feldsztejn

          ๐Ÿ›
          Martin Lehmann
          Martin Lehmann

          ๐Ÿ›
          Martin Spamer
          Martin Spamer

          ๐Ÿ›
          Martin Tarjรกnyi
          Martin Tarjรกnyi

          ๐Ÿ›
          MatFl
          MatFl

          ๐Ÿ›
          Mateusz Stefanski
          Mateusz Stefanski

          ๐Ÿ›
          Mathias Lagerwall
          Mathias Lagerwall

          ๐Ÿ›
          Mathias Lagerwall
          Mathias Lagerwall

          ๐Ÿ›
          Mathieu Gouin
          Mathieu Gouin

          ๐Ÿ›
          MatiasComercio
          MatiasComercio

          ๐Ÿ’ป ๐Ÿ›
          Matt Benson
          Matt Benson

          ๐Ÿ›
          Matt De Poorter
          Matt De Poorter

          ๐Ÿ›
          Matt Hargett
          Matt Hargett

          ๐Ÿ’ป ๐Ÿ’ต
          Matt Harrah
          Matt Harrah

          ๐Ÿ›
          Matt Nelson
          Matt Nelson

          ๐Ÿ›
          Matt Nelson
          Matt Nelson

          ๐Ÿ›
          Matthew Amos
          Matthew Amos

          ๐Ÿ›
          Matthew Duggan
          Matthew Duggan

          ๐Ÿ›
          Matthew Hall
          Matthew Hall

          ๐Ÿ›
          Matthew Rossner
          Matthew Rossner

          ๐Ÿ›
          Matรญas Fraga
          Matรญas Fraga

          ๐Ÿ’ป ๐Ÿ›
          Maxime Robert
          Maxime Robert

          ๐Ÿ’ป ๐Ÿ›
          MetaBF
          MetaBF

          ๐Ÿ›
          MetaBF
          MetaBF

          ๐Ÿ›
          Metin Dagcilar
          Metin Dagcilar

          ๐Ÿ›
          Michael
          Michael

          ๐Ÿ›
          Michael Bell
          Michael Bell

          ๐Ÿ›
          Michael Bernstein
          Michael Bernstein

          ๐Ÿ›
          Michael Clay
          Michael Clay

          ๐Ÿ›
          Michael Dombrowski
          Michael Dombrowski

          ๐Ÿ›
          Michael Hausegger
          Michael Hausegger

          ๐Ÿ›
          Michael Hausegger
          Michael Hausegger

          ๐Ÿ›
          Michael Hoefer
          Michael Hoefer

          ๐Ÿ›
          Michael Kolesnikov
          Michael Kolesnikov

          ๐Ÿ›
          Michael Mรถbius
          Michael Mรถbius

          ๐Ÿ›
          Michael N. Lipp
          Michael N. Lipp

          ๐Ÿ›
          Michael Pellegrini
          Michael Pellegrini

          ๐Ÿ›
          Michal Kordas
          Michal Kordas

          ๐Ÿ›
          Michaล‚ Borek
          Michaล‚ Borek

          ๐Ÿ›
          Michaล‚ Borek
          Michaล‚ Borek

          ๐Ÿ›
          Michaล‚ Kuliล„ski
          Michaล‚ Kuliล„ski

          ๐Ÿ›
          Miguel Nรบรฑez Dรญaz-Montes
          Miguel Nรบรฑez Dรญaz-Montes

          ๐Ÿ›
          Mihai Ionut
          Mihai Ionut

          ๐Ÿ›
          Mikhail Kuchma
          Mikhail Kuchma

          ๐Ÿ›
          MiladSadinam
          MiladSadinam

          ๐Ÿ›
          Mirek Hankus
          Mirek Hankus

          ๐Ÿ›
          Mitch Spano
          Mitch Spano

          ๐Ÿ’ป ๐Ÿ›
          Mitch Spano
          Mitch Spano

          ๐Ÿ’ป ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          MrAngry52
          MrAngry52

          ๐Ÿ›
          Muminur Choudhury
          Muminur Choudhury

          ๐Ÿ›
          Mykhailo Palahuta
          Mykhailo Palahuta

          ๐Ÿ’ป ๐Ÿ›
          Nagendra Kumar Singh
          Nagendra Kumar Singh

          ๐Ÿ›
          Nahuel Barrios
          Nahuel Barrios

          ๐Ÿ›
          Nahuel Barrios
          Nahuel Barrios

          ๐Ÿ›
          Nakul Sharma
          Nakul Sharma

          ๐Ÿ›
          Nathan Braun
          Nathan Braun

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathanaรซl
          Nathanaรซl

          ๐Ÿ›
          Naveen
          Naveen

          ๐Ÿ’ป
          Nazdravi
          Nazdravi

          ๐Ÿ›
          Nazdravi
          Nazdravi

          ๐Ÿ›
          Neha-Dhonde
          Neha-Dhonde

          ๐Ÿ›
          Nicholas Doyle
          Nicholas Doyle

          ๐Ÿ›
          Nick Butcher
          Nick Butcher

          ๐Ÿ›
          Nico Gallinal
          Nico Gallinal

          ๐Ÿ›
          Nicola Dal Maso
          Nicola Dal Maso

          ๐Ÿ›
          Nicolas Filotto
          Nicolas Filotto

          ๐Ÿ’ป
          Nicolas Vervelle
          Nicolas Vervelle

          ๐Ÿ›
          Nicolas Vervelle
          Nicolas Vervelle

          ๐Ÿ›
          Nicolas Vuillamy
          Nicolas Vuillamy

          ๐Ÿ“–
          Nikita Chursin
          Nikita Chursin

          ๐Ÿ›
          Niklas Baudy
          Niklas Baudy

          ๐Ÿ›
          Nikolas Havrikov
          Nikolas Havrikov

          ๐Ÿ›
          Nilesh Virkar
          Nilesh Virkar

          ๐Ÿ›
          Nimit Patel
          Nimit Patel

          ๐Ÿ›
          Niranjan Harpale
          Niranjan Harpale

          ๐Ÿ›
          Niranjan Harpale
          Niranjan Harpale

          ๐Ÿ›
          Nirvik Patel
          Nirvik Patel

          ๐Ÿ’ป
          Noah Sussman
          Noah Sussman

          ๐Ÿ›
          Noah0120
          Noah0120

          ๐Ÿ›
          Noam Tamim
          Noam Tamim

          ๐Ÿ›
          Noel Grandin
          Noel Grandin

          ๐Ÿ›
          Olaf Haalstra
          Olaf Haalstra

          ๐Ÿ›
          Oleg Andreych
          Oleg Andreych

          ๐Ÿ’ป ๐Ÿ›
          Oleg Andreych
          Oleg Andreych

          ๐Ÿ’ป ๐Ÿ›
          Oleg Pavlenko
          Oleg Pavlenko

          ๐Ÿ›
          Oleksii Dykov
          Oleksii Dykov

          ๐Ÿ’ป ๐Ÿ›
          Oliver Eikemeier
          Oliver Eikemeier

          ๐Ÿ›
          Oliver Siegmar
          Oliver Siegmar

          ๐Ÿ’ต
          Olivier Parent
          Olivier Parent

          ๐Ÿ’ป ๐Ÿ›
          Ollie Abbey
          Ollie Abbey

          ๐Ÿ’ป ๐Ÿ›
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)

          ๐Ÿ›
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)

          ๐Ÿ›
          Ondrej Kratochvil
          Ondrej Kratochvil

          ๐Ÿ›
          OverDrone
          OverDrone

          ๐Ÿ›
          Ozan Gulle
          Ozan Gulle

          ๐Ÿ’ป ๐Ÿ›
          PUNEET JAIN
          PUNEET JAIN

          ๐Ÿ›
          Pankraz76
          Pankraz76

          ๐Ÿ’ป ๐Ÿ›
          Parbati Bose
          Parbati Bose

          ๐Ÿ›
          Paul Berg
          Paul Berg

          ๐Ÿ›
          Paul Berg
          Paul Berg

          ๐Ÿ›
          Paul Guyot
          Paul Guyot

          ๐Ÿ’ป
          Pavel Bludov
          Pavel Bludov

          ๐Ÿ›
          Pavel Miฤka
          Pavel Miฤka

          ๐Ÿ›
          Pedro Nuno Santos
          Pedro Nuno Santos

          ๐Ÿ›
          Pedro Rijo
          Pedro Rijo

          ๐Ÿ›
          Pelisse Romain
          Pelisse Romain

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
          Per Abich
          Per Abich

          ๐Ÿ’ป
          Per Abich
          Per Abich

          ๐Ÿ’ป
          Pete Davids
          Pete Davids

          ๐Ÿ›
          Peter Bruin
          Peter Bruin

          ๐Ÿ›
          Peter Chittum
          Peter Chittum

          ๐Ÿ’ป ๐Ÿ›
          Peter Cudmore
          Peter Cudmore

          ๐Ÿ›
          Peter Kasson
          Peter Kasson

          ๐Ÿ›
          Peter Kofler
          Peter Kofler

          ๐Ÿ›
          Peter Paul Bakker
          Peter Paul Bakker

          ๐Ÿ’ป ๐Ÿ›
          Peter Paul Bakker
          Peter Paul Bakker

          ๐Ÿ’ป ๐Ÿ›
          Peter Rader
          Peter Rader

          ๐Ÿ›
          Pham Hai Trung
          Pham Hai Trung

          ๐Ÿ›
          Philip Graf
          Philip Graf

          ๐Ÿ’ป ๐Ÿ›
          Philip Hachey
          Philip Hachey

          ๐Ÿ›
          Philippe Ozil
          Philippe Ozil

          ๐Ÿ›
          Phinehas Artemix
          Phinehas Artemix

          ๐Ÿ›
          Phokham Nonava
          Phokham Nonava

          ๐Ÿ›
          Phokham Nonava
          Phokham Nonava

          ๐Ÿ›
          Pim van der Loos
          Pim van der Loos

          ๐Ÿ’ป โš ๏ธ
          Piotr Szymaล„ski
          Piotr Szymaล„ski

          ๐Ÿ›
          Piotrek ลปygieล‚o
          Piotrek ลปygieล‚o

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“–
          Pranay Jaiswal
          Pranay Jaiswal

          ๐Ÿ›
          Prasad Kamath
          Prasad Kamath

          ๐Ÿ›
          Prasanna
          Prasanna

          ๐Ÿ›
          Presh-AR
          Presh-AR

          ๐Ÿ›
          Presh-AR
          Presh-AR

          ๐Ÿ›
          Puneet1726
          Puneet1726

          ๐Ÿ›
          RBRi
          RBRi

          ๐Ÿ›
          Rafael Cortรชs
          Rafael Cortรชs

          ๐Ÿ›
          RaheemShaik999
          RaheemShaik999

          ๐Ÿ›
          RajeshR
          RajeshR

          ๐Ÿ’ป ๐Ÿ›
          Ramachandra Mohan
          Ramachandra Mohan

          ๐Ÿ›
          Ramel0921
          Ramel0921

          ๐Ÿ›
          Ramel0921
          Ramel0921

          ๐Ÿ›
          Raquel Pau
          Raquel Pau

          ๐Ÿ›
          Ravikiran Janardhana
          Ravikiran Janardhana

          ๐Ÿ›
          Reda Benhemmouche
          Reda Benhemmouche

          ๐Ÿ›
          Reinhard Schiedermeier
          Reinhard Schiedermeier

          ๐Ÿ›
          Renato Oliveira
          Renato Oliveira

          ๐Ÿ’ป ๐Ÿ›
          Rich DiCroce
          Rich DiCroce

          ๐Ÿ›
          Richard Corfield
          Richard Corfield

          ๐Ÿ’ป
          Richard Corfield
          Richard Corfield

          ๐Ÿ’ป
          Richard Corfield
          Richard Corfield

          ๐Ÿ› ๐Ÿ’ป
          Riot R1cket
          Riot R1cket

          ๐Ÿ›
          Rishabh Jain
          Rishabh Jain

          ๐Ÿ›
          RishabhDeep Singh
          RishabhDeep Singh

          ๐Ÿ›
          Rob Baillie
          Rob Baillie

          ๐Ÿ›
          Robbie Martinus
          Robbie Martinus

          ๐Ÿ’ป ๐Ÿ›
          Robert Henry
          Robert Henry

          ๐Ÿ›
          Robert Henry
          Robert Henry

          ๐Ÿ›
          Robert Mihaly
          Robert Mihaly

          ๐Ÿ›
          Robert Painsi
          Robert Painsi

          ๐Ÿ›
          Robert Russell
          Robert Russell

          ๐Ÿ›
          Robert Sรถsemann
          Robert Sรถsemann

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ›
          Robert Whitebit
          Robert Whitebit

          ๐Ÿ›
          Robin Richtsfeld
          Robin Richtsfeld

          ๐Ÿ›
          Robin Stocker
          Robin Stocker

          ๐Ÿ’ป ๐Ÿ›
          Robin Stocker
          Robin Stocker

          ๐Ÿ’ป ๐Ÿ›
          Robin Wils
          Robin Wils

          ๐Ÿ›
          RochusOest
          RochusOest

          ๐Ÿ›
          Rodolfo Noviski
          Rodolfo Noviski

          ๐Ÿ›
          Rodrigo Casara
          Rodrigo Casara

          ๐Ÿ›
          Rodrigo Fernandes
          Rodrigo Fernandes

          ๐Ÿ›
          Roman Salvador
          Roman Salvador

          ๐Ÿ’ป ๐Ÿ›
          Ronald Blaschke
          Ronald Blaschke

          ๐Ÿ›
          Ronald Blaschke
          Ronald Blaschke

          ๐Ÿ›
          Rรณbert Papp
          Rรณbert Papp

          ๐Ÿ›
          Saikat Sengupta
          Saikat Sengupta

          ๐Ÿ›
          Saksham Handu
          Saksham Handu

          ๐Ÿ›
          Saladoc
          Saladoc

          ๐Ÿ›
          Salesforce Bob Lightning
          Salesforce Bob Lightning

          ๐Ÿ›
          Sam Carlberg
          Sam Carlberg

          ๐Ÿ›
          Sascha Riemer
          Sascha Riemer

          ๐Ÿ›
          Sascha Riemer
          Sascha Riemer

          ๐Ÿ›
          Sashko
          Sashko

          ๐Ÿ’ป
          Satoshi Kubo
          Satoshi Kubo

          ๐Ÿ›
          Scott Kennedy
          Scott Kennedy

          ๐Ÿ›
          Scott Wells
          Scott Wells

          ๐Ÿ› ๐Ÿ’ป
          Scrates1
          Scrates1

          ๐Ÿ› ๐Ÿ’ป
          Scrsloota
          Scrsloota

          ๐Ÿ’ป
          Sebastian Bรถgl
          Sebastian Bรถgl

          ๐Ÿ›
          Sebastian Bรถgl
          Sebastian Bรถgl

          ๐Ÿ›
          Sebastian Davids
          Sebastian Davids

          ๐Ÿ›
          Sebastian Lรถvdahl
          Sebastian Lรถvdahl

          ๐Ÿ›
          Sebastian Schuberth
          Sebastian Schuberth

          ๐Ÿ›
          Sebastian Schwarz
          Sebastian Schwarz

          ๐Ÿ›
          Seren
          Seren

          ๐Ÿ› ๐Ÿ’ป
          Sergey Gorbaty
          Sergey Gorbaty

          ๐Ÿ›
          Sergey Kozlov
          Sergey Kozlov

          ๐Ÿ›
          Sergey Kozlov
          Sergey Kozlov

          ๐Ÿ›
          Sergey Yanzin
          Sergey Yanzin

          ๐Ÿ’ป ๐Ÿ›
          Seth Wilcox
          Seth Wilcox

          ๐Ÿ’ป
          Shai Bennathan
          Shai Bennathan

          ๐Ÿ› ๐Ÿ’ป
          Shubham
          Shubham

          ๐Ÿ’ป ๐Ÿ›
          Simon Abykov
          Simon Abykov

          ๐Ÿ’ป ๐Ÿ›
          Simon Xiao
          Simon Xiao

          ๐Ÿ›
          Srinivasan Venkatachalam
          Srinivasan Venkatachalam

          ๐Ÿ›
          Srinivasan Venkatachalam
          Srinivasan Venkatachalam

          ๐Ÿ›
          Stanislav Gromov
          Stanislav Gromov

          ๐Ÿ›
          Stanislav Myachenkov
          Stanislav Myachenkov

          ๐Ÿ’ป
          Stefan Birkner
          Stefan Birkner

          ๐Ÿ›
          Stefan Bohn
          Stefan Bohn

          ๐Ÿ›
          Stefan Endrullis
          Stefan Endrullis

          ๐Ÿ›
          Stefan Klรถss-Schuster
          Stefan Klรถss-Schuster

          ๐Ÿ›
          Stefan Wolf
          Stefan Wolf

          ๐Ÿ›
          Stefan Wolf
          Stefan Wolf

          ๐Ÿ›
          Stephan H. Wissel
          Stephan H. Wissel

          ๐Ÿ›
          Stephen
          Stephen

          ๐Ÿ›
          Stephen Carter
          Stephen Carter

          ๐Ÿ›
          Stephen Friedrich
          Stephen Friedrich

          ๐Ÿ›
          Steve Babula
          Steve Babula

          ๐Ÿ’ป
          Steve White
          Steve White

          ๐Ÿ›
          Steven Stearns
          Steven Stearns

          ๐Ÿ› ๐Ÿ’ป
          Stexxe
          Stexxe

          ๐Ÿ›
          Steven Schlansker
          Steven Schlansker

          ๐Ÿ›
          Steven Stearns
          Steven Stearns

          ๐Ÿ› ๐Ÿ’ป
          Stexxe
          Stexxe

          ๐Ÿ›
          Stian Lรฅgstad
          Stian Lรฅgstad

          ๐Ÿ›
          StuartClayton5
          StuartClayton5

          ๐Ÿ›
          Supun Arunoda
          Supun Arunoda

          ๐Ÿ›
          Suren Abrahamyan
          Suren Abrahamyan

          ๐Ÿ›
          Suvashri
          Suvashri

          ๐Ÿ“–
          Sven Barden
          Sven Barden

          ๐Ÿ›
          SwatiBGupta1110
          SwatiBGupta1110

          ๐Ÿ›
          Suvashri
          Suvashri

          ๐Ÿ“–
          Sven Barden
          Sven Barden

          ๐Ÿ›
          SwatiBGupta1110
          SwatiBGupta1110

          ๐Ÿ›
          SyedThoufich
          SyedThoufich

          ๐Ÿ›
          Szymon Sasin
          Szymon Sasin

          ๐Ÿ›
          T-chuangxin
          T-chuangxin

          ๐Ÿ›
          TERAI Atsuhiro
          TERAI Atsuhiro

          ๐Ÿ›
          TIOBE Software
          TIOBE Software

          ๐Ÿ’ป ๐Ÿ›
          Tarush Singh
          Tarush Singh

          ๐Ÿ’ป
          Taylor Smock
          Taylor Smock

          ๐Ÿ›
          TIOBE Software
          TIOBE Software

          ๐Ÿ’ป ๐Ÿ›
          Tarush Singh
          Tarush Singh

          ๐Ÿ’ป
          Taylor Smock
          Taylor Smock

          ๐Ÿ›
          Techeira Damiรกn
          Techeira Damiรกn

          ๐Ÿ’ป ๐Ÿ›
          Ted Husted
          Ted Husted

          ๐Ÿ›
          TehBakker
          TehBakker

          ๐Ÿ›
          The Gitter Badger
          The Gitter Badger

          ๐Ÿ›
          Theodoor
          Theodoor

          ๐Ÿ›
          Thiago Henrique Hรผpner
          Thiago Henrique Hรผpner

          ๐Ÿ›
          Thibault Meyer
          Thibault Meyer

          ๐Ÿ›
          Theodoor
          Theodoor

          ๐Ÿ›
          Thiago Henrique Hรผpner
          Thiago Henrique Hรผpner

          ๐Ÿ›
          Thibault Meyer
          Thibault Meyer

          ๐Ÿ›
          Thomas Gรผttler
          Thomas Gรผttler

          ๐Ÿ›
          Thomas Jones-Low
          Thomas Jones-Low

          ๐Ÿ›
          Thomas Smith
          Thomas Smith

          ๐Ÿ’ป ๐Ÿ›
          ThrawnCA
          ThrawnCA

          ๐Ÿ›
          Thu Vo
          Thu Vo

          ๐Ÿ›
          Thunderforge
          Thunderforge

          ๐Ÿ’ป ๐Ÿ›
          Tim van der Lippe
          Tim van der Lippe

          ๐Ÿ›
          Thu Vo
          Thu Vo

          ๐Ÿ›
          Thunderforge
          Thunderforge

          ๐Ÿ’ป ๐Ÿ›
          Tim van der Lippe
          Tim van der Lippe

          ๐Ÿ›
          Tobias Weimer
          Tobias Weimer

          ๐Ÿ’ป ๐Ÿ›
          Tom Copeland
          Tom Copeland

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–
          Tom Daly
          Tom Daly

          ๐Ÿ›
          Tomas
          Tomas

          ๐Ÿ›
          Tomer Figenblat
          Tomer Figenblat

          ๐Ÿ›
          Tomi De Lucca
          Tomi De Lucca

          ๐Ÿ’ป ๐Ÿ›
          Tony
          Tony

          ๐Ÿ“–
          Tomer Figenblat
          Tomer Figenblat

          ๐Ÿ›
          Tomi De Lucca
          Tomi De Lucca

          ๐Ÿ’ป ๐Ÿ›
          Tony
          Tony

          ๐Ÿ“–
          Torsten Kleiber
          Torsten Kleiber

          ๐Ÿ›
          Torsten Krause
          Torsten Krause

          ๐Ÿ›
          TrackerSB
          TrackerSB

          ๐Ÿ›
          Tyson Stewart
          Tyson Stewart

          ๐Ÿ›
          Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ›
          UncleOwen
          UncleOwen

          ๐Ÿ’ป ๐Ÿ“–
          Utku Cuhadaroglu
          Utku Cuhadaroglu

          ๐Ÿ’ป ๐Ÿ›
          Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ›
          UncleOwen
          UncleOwen

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“–
          Utku Cuhadaroglu
          Utku Cuhadaroglu

          ๐Ÿ’ป ๐Ÿ›
          Valentin Brandl
          Valentin Brandl

          ๐Ÿ›
          Valeria
          Valeria

          ๐Ÿ›
          Valery Yatsynovich
          Valery Yatsynovich

          ๐Ÿ“–
          Vasily Anisimov
          Vasily Anisimov

          ๐Ÿ›
          Vedant Chokshi
          Vedant Chokshi

          ๐Ÿ›
          Vibhor Goyal
          Vibhor Goyal

          ๐Ÿ›
          Vickenty Fesunov
          Vickenty Fesunov

          ๐Ÿ›
          Vedant Chokshi
          Vedant Chokshi

          ๐Ÿ›
          Vibhor Goyal
          Vibhor Goyal

          ๐Ÿ›
          Vickenty Fesunov
          Vickenty Fesunov

          ๐Ÿ›
          Victor Noรซl
          Victor Noรซl

          ๐Ÿ›
          Vincent Galloy
          Vincent Galloy

          ๐Ÿ’ป
          Vincent HUYNH
          Vincent HUYNH

          ๐Ÿ›
          Vincent Maurin
          Vincent Maurin

          ๐Ÿ›
          Vincent Potucek
          Vincent Potucek

          ๐Ÿ’ป
          Vincent Privat
          Vincent Privat

          ๐Ÿ›
          Vishhwas
          Vishhwas

          ๐Ÿ›
          Vincent Potucek
          Vincent Potucek

          ๐Ÿ’ป
          Vincent Privat
          Vincent Privat

          ๐Ÿ›
          Vishhwas
          Vishhwas

          ๐Ÿ›
          Vishv_Android
          Vishv_Android

          ๐Ÿ›
          Vitalii Yevtushenko
          Vitalii Yevtushenko

          ๐Ÿ›
          Vitaly
          Vitaly

          ๐Ÿ›
          Vitaly Polonetsky
          Vitaly Polonetsky

          ๐Ÿ›
          Vojtech Polivka
          Vojtech Polivka

          ๐Ÿ›
          Vsevolod Zholobov
          Vsevolod Zholobov

          ๐Ÿ›
          Vyom Yadav
          Vyom Yadav

          ๐Ÿ’ป
          Vojtech Polivka
          Vojtech Polivka

          ๐Ÿ›
          Vsevolod Zholobov
          Vsevolod Zholobov

          ๐Ÿ›
          Vyom Yadav
          Vyom Yadav

          ๐Ÿ’ป
          Wang Shidong
          Wang Shidong

          ๐Ÿ›
          Waqas Ahmed
          Waqas Ahmed

          ๐Ÿ›
          Wayne J. Earl
          Wayne J. Earl

          ๐Ÿ›
          Wchenghui
          Wchenghui

          ๐Ÿ›
          Wener
          Wener

          ๐Ÿ’ป
          Will Winder
          Will Winder

          ๐Ÿ›
          Willem A. Hajenius
          Willem A. Hajenius

          ๐Ÿ’ป
          Wener
          Wener

          ๐Ÿ’ป
          Will Winder
          Will Winder

          ๐Ÿ›
          Willem A. Hajenius
          Willem A. Hajenius

          ๐Ÿ’ป
          William Brockhus
          William Brockhus

          ๐Ÿ’ป ๐Ÿ›
          Wilson Kurniawan
          Wilson Kurniawan

          ๐Ÿ›
          Wim Deblauwe
          Wim Deblauwe

          ๐Ÿ›
          Wolf2323
          Wolf2323

          ๐Ÿ›
          Woongsik Choi
          Woongsik Choi

          ๐Ÿ›
          XenoAmess
          XenoAmess

          ๐Ÿ’ป ๐Ÿ›
          Yang
          Yang

          ๐Ÿ’ป
          Woongsik Choi
          Woongsik Choi

          ๐Ÿ›
          XenoAmess
          XenoAmess

          ๐Ÿ’ป ๐Ÿ›
          Yang
          Yang

          ๐Ÿ’ป
          YaroslavTER
          YaroslavTER

          ๐Ÿ›
          Yasar Shaikh
          Yasar Shaikh

          ๐Ÿ’ป
          Young Chan
          Young Chan

          ๐Ÿ’ป ๐Ÿ›
          YuJin Kim
          YuJin Kim

          ๐Ÿ›
          Yuri Dolzhenko
          Yuri Dolzhenko

          ๐Ÿ›
          Yurii Dubinka
          Yurii Dubinka

          ๐Ÿ›
          Zbynek Konecny
          Zbynek Konecny

          ๐Ÿ› ๐Ÿ’ป
          Yuri Dolzhenko
          Yuri Dolzhenko

          ๐Ÿ›
          Yurii Dubinka
          Yurii Dubinka

          ๐Ÿ›
          Zbynek Konecny
          Zbynek Konecny

          ๐Ÿ› ๐Ÿ’ป
          Zoltan Farkas
          Zoltan Farkas

          ๐Ÿ›
          Zustin
          Zustin

          ๐Ÿ›
          aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป
          alexmodis
          alexmodis

          ๐Ÿ›
          andreoss
          andreoss

          ๐Ÿ›
          andrey81inmd
          andrey81inmd

          ๐Ÿ’ป ๐Ÿ›
          anicoara
          anicoara

          ๐Ÿ›
          andreoss
          andreoss

          ๐Ÿ›
          andrey81inmd
          andrey81inmd

          ๐Ÿ’ป ๐Ÿ›
          anicoara
          anicoara

          ๐Ÿ›
          arunprasathav
          arunprasathav

          ๐Ÿ›
          asiercamara
          asiercamara

          ๐Ÿ›
          astillich-igniti
          astillich-igniti

          ๐Ÿ’ป
          avesolovksyy
          avesolovksyy

          ๐Ÿ›
          avishvat
          avishvat

          ๐Ÿ›
          avivmu
          avivmu

          ๐Ÿ›
          axelbarfod1
          axelbarfod1

          ๐Ÿ›
          avishvat
          avishvat

          ๐Ÿ›
          avivmu
          avivmu

          ๐Ÿ›
          axelbarfod1
          axelbarfod1

          ๐Ÿ›
          b-3-n
          b-3-n

          ๐Ÿ›
          balbhadra9
          balbhadra9

          ๐Ÿ›
          base23de
          base23de

          ๐Ÿ›
          bergander
          bergander

          ๐Ÿ› ๐Ÿ’ป
          berkam
          berkam

          ๐Ÿ’ป ๐Ÿ›
          breizh31
          breizh31

          ๐Ÿ›
          caesarkim
          caesarkim

          ๐Ÿ›
          berkam
          berkam

          ๐Ÿ’ป ๐Ÿ›
          breizh31
          breizh31

          ๐Ÿ›
          caesarkim
          caesarkim

          ๐Ÿ›
          caiocarvalhotero
          caiocarvalhotero

          ๐Ÿ›
          carolyujing
          carolyujing

          ๐Ÿ›
          cbfiddle
          cbfiddle

          ๐Ÿ›
          cesares-basilico
          cesares-basilico

          ๐Ÿ›
          chrite
          chrite

          ๐Ÿ›
          ciufudean
          ciufudean

          ๐Ÿ“–
          cobratbq
          cobratbq

          ๐Ÿ›
          chrite
          chrite

          ๐Ÿ›
          ciufudean
          ciufudean

          ๐Ÿ“–
          cobratbq
          cobratbq

          ๐Ÿ›
          coladict
          coladict

          ๐Ÿ›
          cosmoJFH
          cosmoJFH

          ๐Ÿ›
          cristalp
          cristalp

          ๐Ÿ›
          crunsk
          crunsk

          ๐Ÿ›
          csrma
          csrma

          ๐Ÿ›
          cwholmes
          cwholmes

          ๐Ÿ›
          cyberjj999
          cyberjj999

          ๐Ÿ›
          cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“–
          csrma
          csrma

          ๐Ÿ›
          cwholmes
          cwholmes

          ๐Ÿ›
          cyberjj999
          cyberjj999

          ๐Ÿ›
          cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“–
          d1ss0nanz
          d1ss0nanz

          ๐Ÿ›
          dague1
          dague1

          ๐Ÿ“–
          dalizi007
          dalizi007

          ๐Ÿ’ป
          danbrycefairsailcom
          danbrycefairsailcom

          ๐Ÿ›
          dariansanity
          dariansanity

          ๐Ÿ›
          darrenmiliband
          darrenmiliband

          ๐Ÿ›
          davidburstrom
          davidburstrom

          ๐Ÿ›
          danbrycefairsailcom
          danbrycefairsailcom

          ๐Ÿ›
          dariansanity
          dariansanity

          ๐Ÿ›
          darrenmiliband
          darrenmiliband

          ๐Ÿ›
          davidburstrom
          davidburstrom

          ๐Ÿ›
          dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ›
          deepak-patra
          deepak-patra

          ๐Ÿ›
          dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ›
          dinesh150
          dinesh150

          ๐Ÿ›
          diziaq
          diziaq

          ๐Ÿ›
          dreaminpast123
          dreaminpast123

          ๐Ÿ›
          duanyanan
          duanyanan

          ๐Ÿ›
          dinesh150
          dinesh150

          ๐Ÿ›
          diziaq
          diziaq

          ๐Ÿ›
          dreaminpast123
          dreaminpast123

          ๐Ÿ›
          duanyanan
          duanyanan

          ๐Ÿ›
          dutt-sanjay
          dutt-sanjay

          ๐Ÿ›
          duursma
          duursma

          ๐Ÿ’ป
          dylanleung
          dylanleung

          ๐Ÿ›
          dzeigler
          dzeigler

          ๐Ÿ›
          eant60
          eant60

          ๐Ÿ›
          ekkirala
          ekkirala

          ๐Ÿ›
          emersonmoura
          emersonmoura

          ๐Ÿ›
          dzeigler
          dzeigler

          ๐Ÿ›
          eant60
          eant60

          ๐Ÿ›
          ekkirala
          ekkirala

          ๐Ÿ›
          emersonmoura
          emersonmoura

          ๐Ÿ›
          emouty
          emouty

          ๐Ÿ’ป ๐Ÿ›
          eugenepugach
          eugenepugach

          ๐Ÿ›
          fairy
          fairy

          ๐Ÿ›
          filiprafalowicz
          filiprafalowicz

          ๐Ÿ’ป
          flxbl-io
          flxbl-io

          ๐Ÿ’ต
          foxmason
          foxmason

          ๐Ÿ›
          frankegabor
          frankegabor

          ๐Ÿ›
          filiprafalowicz
          filiprafalowicz

          ๐Ÿ’ป
          flxbl-io
          flxbl-io

          ๐Ÿ’ต
          foxmason
          foxmason

          ๐Ÿ›
          frankegabor
          frankegabor

          ๐Ÿ›
          frankl
          frankl

          ๐Ÿ›
          freafrea
          freafrea

          ๐Ÿ›
          fsapatin
          fsapatin

          ๐Ÿ›
          gearsethenry
          gearsethenry

          ๐Ÿ›
          gracia19
          gracia19

          ๐Ÿ›
          gudzpoz
          gudzpoz

          ๐Ÿ›
          guo fei
          guo fei

          ๐Ÿ›
          gearsethenry
          gearsethenry

          ๐Ÿ›
          gracia19
          gracia19

          ๐Ÿ›
          gudzpoz
          gudzpoz

          ๐Ÿ›
          guo fei
          guo fei

          ๐Ÿ›
          gurmsc5
          gurmsc5

          ๐Ÿ›
          gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ›
          haigsn
          haigsn

          ๐Ÿ›
          hemanshu070
          hemanshu070

          ๐Ÿ›
          henrik242
          henrik242

          ๐Ÿ›
          hongpuwu
          hongpuwu

          ๐Ÿ›
          hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ›
          hemanshu070
          hemanshu070

          ๐Ÿ›
          henrik242
          henrik242

          ๐Ÿ›
          hongpuwu
          hongpuwu

          ๐Ÿ›
          hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ›
          igniti GmbH
          igniti GmbH

          ๐Ÿ›
          ilovezfs
          ilovezfs

          ๐Ÿ›
          imax-erik
          imax-erik

          ๐Ÿ›
          itaigilo
          itaigilo

          ๐Ÿ›
          jakivey32
          jakivey32

          ๐Ÿ›
          jbennett2091
          jbennett2091

          ๐Ÿ›
          jcamerin
          jcamerin

          ๐Ÿ›
          itaigilo
          itaigilo

          ๐Ÿ›
          jakivey32
          jakivey32

          ๐Ÿ›
          jbennett2091
          jbennett2091

          ๐Ÿ›
          jcamerin
          jcamerin

          ๐Ÿ›
          jkeener1
          jkeener1

          ๐Ÿ›
          jmetertea
          jmetertea

          ๐Ÿ›
          johnra2
          johnra2

          ๐Ÿ’ป
          johnzhao9
          johnzhao9

          ๐Ÿ›
          josemanuelrolon
          josemanuelrolon

          ๐Ÿ’ป ๐Ÿ›
          julees7
          julees7

          ๐Ÿ’ป ๐Ÿ›
          kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ›
          johnzhao9
          johnzhao9

          ๐Ÿ›
          josemanuelrolon
          josemanuelrolon

          ๐Ÿ’ป ๐Ÿ›
          julees7
          julees7

          ๐Ÿ’ป ๐Ÿ›
          kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ›
          karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“–
          karwer
          karwer

          ๐Ÿ›
          kaulonline
          kaulonline

          ๐Ÿ›
          kdaemonv
          kdaemonv

          ๐Ÿ›
          kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป
          kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ›
          kfranic
          kfranic

          ๐Ÿ›
          kdaemonv
          kdaemonv

          ๐Ÿ›
          kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป
          kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ›
          kfranic
          kfranic

          ๐Ÿ›
          khalidkh
          khalidkh

          ๐Ÿ›
          koalalam
          koalalam

          ๐Ÿ›
          krzyk
          krzyk

          ๐Ÿ›
          lasselindqvist
          lasselindqvist

          ๐Ÿ›
          lgemeinhardt
          lgemeinhardt

          ๐Ÿ›
          lihuaib
          lihuaib

          ๐Ÿ›
          liqingjun123
          liqingjun123

          ๐Ÿ›
          lasselindqvist
          lasselindqvist

          ๐Ÿ›
          lgemeinhardt
          lgemeinhardt

          ๐Ÿ›
          lihuaib
          lihuaib

          ๐Ÿ›
          liqingjun123
          liqingjun123

          ๐Ÿ›
          lonelyma1021
          lonelyma1021

          ๐Ÿ›
          lothas
          lothas

          ๐Ÿ›
          lpeddy
          lpeddy

          ๐Ÿ›
          lujiefsi
          lujiefsi

          ๐Ÿ’ป
          lukelukes
          lukelukes

          ๐Ÿ’ป
          lyriccoder
          lyriccoder

          ๐Ÿ›
          marcelmore
          marcelmore

          ๐Ÿ›
          lujiefsi
          lujiefsi

          ๐Ÿ’ป
          lukelukes
          lukelukes

          ๐Ÿ’ป
          lyriccoder
          lyriccoder

          ๐Ÿ›
          marcelmore
          marcelmore

          ๐Ÿ›
          matchbox
          matchbox

          ๐Ÿ›
          matthiaskraaz
          matthiaskraaz

          ๐Ÿ›
          meandonlyme
          meandonlyme

          ๐Ÿ›
          mikesive
          mikesive

          ๐Ÿ›
          milossesic
          milossesic

          ๐Ÿ›
          mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ›
          mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป
          mikesive
          mikesive

          ๐Ÿ›
          milossesic
          milossesic

          ๐Ÿ›
          mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ›
          mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป
          mrclmh
          mrclmh

          ๐Ÿ›
          mriddell95
          mriddell95

          ๐Ÿ›
          mrlzh
          mrlzh

          ๐Ÿ›
          msloan
          msloan

          ๐Ÿ›
          mucharlaravalika
          mucharlaravalika

          ๐Ÿ›
          mvenneman
          mvenneman

          ๐Ÿ›
          nareshl119
          nareshl119

          ๐Ÿ›
          msloan
          msloan

          ๐Ÿ›
          mucharlaravalika
          mucharlaravalika

          ๐Ÿ›
          mvenneman
          mvenneman

          ๐Ÿ›
          nareshl119
          nareshl119

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          noerremark
          noerremark

          ๐Ÿ›
          novsirion
          novsirion

          ๐Ÿ›
          nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป
          oggboy
          oggboy

          ๐Ÿ›
          oinume
          oinume

          ๐Ÿ›
          orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ›
          nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป
          oggboy
          oggboy

          ๐Ÿ›
          oinume
          oinume

          ๐Ÿ›
          orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pacvz
          pacvz

          ๐Ÿ’ป
          pallavi agarwal
          pallavi agarwal

          ๐Ÿ›
          pankratz76
          pankratz76

          ๐Ÿ›
          parksungrin
          parksungrin

          ๐Ÿ›
          patpatpat123
          patpatpat123

          ๐Ÿ›
          patriksevallius
          patriksevallius

          ๐Ÿ›
          pankratz76
          pankratz76

          ๐Ÿ›
          parksungrin
          parksungrin

          ๐Ÿ›
          patpatpat123
          patpatpat123

          ๐Ÿ›
          patriksevallius
          patriksevallius

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          phoenix384
          phoenix384

          ๐Ÿ›
          piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป
          plan3d
          plan3d

          ๐Ÿ›
          poojasix
          poojasix

          ๐Ÿ›
          prabhushrikant
          prabhushrikant

          ๐Ÿ›
          pujitha8783
          pujitha8783

          ๐Ÿ›
          plan3d
          plan3d

          ๐Ÿ›
          poojasix
          poojasix

          ๐Ÿ›
          prabhushrikant
          prabhushrikant

          ๐Ÿ›
          pujitha8783
          pujitha8783

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          raghujayjunk
          raghujayjunk

          ๐Ÿ›
          rajeshveera
          rajeshveera

          ๐Ÿ›
          rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ›
          recdevs
          recdevs

          ๐Ÿ›
          reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ›
          rijkt
          rijkt

          ๐Ÿ›
          rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ›
          recdevs
          recdevs

          ๐Ÿ›
          reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ›
          rijkt
          rijkt

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ›
          rnveach
          rnveach

          ๐Ÿ›
          rxmicro
          rxmicro

          ๐Ÿ›
          ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ›
          sabi0
          sabi0

          ๐Ÿ›
          samc-gearset
          samc-gearset

          ๐Ÿ“–
          rxmicro
          rxmicro

          ๐Ÿ›
          ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ›
          sabi0
          sabi0

          ๐Ÿ›
          samc-gearset
          samc-gearset

          ๐Ÿ“–
          scais
          scais

          ๐Ÿ›
          schosin
          schosin

          ๐Ÿ›
          screamingfrog
          screamingfrog

          ๐Ÿ’ต
          sebbASF
          sebbASF

          ๐Ÿ›
          sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป
          shilko2013
          shilko2013

          ๐Ÿ›
          shiomiyan
          shiomiyan

          ๐Ÿ“–
          sebbASF
          sebbASF

          ๐Ÿ›
          sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป
          shilko2013
          shilko2013

          ๐Ÿ›
          shiomiyan
          shiomiyan

          ๐Ÿ“–
          simeonKondr
          simeonKondr

          ๐Ÿ›
          snajberk
          snajberk

          ๐Ÿ›
          sniperrifle2004
          sniperrifle2004

          ๐Ÿ›
          snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป
          soloturn
          soloturn

          ๐Ÿ›
          soyodream
          soyodream

          ๐Ÿ›
          sratz
          sratz

          ๐Ÿ›
          snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป
          soloturn
          soloturn

          ๐Ÿ›
          soyodream
          soyodream

          ๐Ÿ›
          sratz
          sratz

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          sturton
          sturton

          ๐Ÿ’ป ๐Ÿ›
          sudharmohan
          sudharmohan

          ๐Ÿ›
          suruchidawar
          suruchidawar

          ๐Ÿ›
          svenfinitiv
          svenfinitiv

          ๐Ÿ›
          szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป
          tashiscool
          tashiscool

          ๐Ÿ›
          suruchidawar
          suruchidawar

          ๐Ÿ›
          svenfinitiv
          svenfinitiv

          ๐Ÿ›
          szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป
          tashiscool
          tashiscool

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          testation21
          testation21

          ๐Ÿ’ป ๐Ÿ›
          thanosa
          thanosa

          ๐Ÿ›
          tiandiyixian
          tiandiyixian

          ๐Ÿ›
          tobwoerk
          tobwoerk

          ๐Ÿ›
          tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป
          trentchilders
          trentchilders

          ๐Ÿ›
          tiandiyixian
          tiandiyixian

          ๐Ÿ›
          tobwoerk
          tobwoerk

          ๐Ÿ›
          tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป
          trentchilders
          trentchilders

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          trishul14
          trishul14

          ๐Ÿ›
          tsui
          tsui

          ๐Ÿ›
          wangzitom12306
          wangzitom12306

          ๐Ÿ›
          winhkey
          winhkey

          ๐Ÿ›
          witherspore
          witherspore

          ๐Ÿ›
          wjljack
          wjljack

          ๐Ÿ›
          wangzitom12306
          wangzitom12306

          ๐Ÿ›
          winhkey
          winhkey

          ๐Ÿ›
          witherspore
          witherspore

          ๐Ÿ›
          wjljack
          wjljack

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          xingsong
          xingsong

          ๐Ÿ›
          xioayuge
          xioayuge

          ๐Ÿ›
          xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ›
          xuanuy
          xuanuy

          ๐Ÿ›
          xyf0921
          xyf0921

          ๐Ÿ›
          yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ›
          xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ›
          xuanuy
          xuanuy

          ๐Ÿ›
          xyf0921
          xyf0921

          ๐Ÿ›
          yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yasuharu-sato
          yasuharu-sato

          ๐Ÿ›
          zenglian
          zenglian

          ๐Ÿ›
          zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ›
          zh3ng
          zh3ng

          ๐Ÿ›
          zt_soft
          zt_soft

          ๐Ÿ›
          ztt79
          ztt79

          ๐Ÿ›
          zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ›
          zh3ng
          zh3ng

          ๐Ÿ›
          zt_soft
          zt_soft

          ๐Ÿ›
          ztt79
          ztt79

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ›
          ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ›
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ

          ๐Ÿ›
          ่Œ…ๅปถๅฎ‰
          ่Œ…ๅปถๅฎ‰

          ๐Ÿ’ป
          Anmol Kumar
          Anmol Kumar

          ๐Ÿ›
          Anthony Whitford
          Anthony Whitford

          ๐Ÿ›
          AnthonyKot
          AnthonyKot

          ๐Ÿ›
          Anurag Agarwal
          Anurag Agarwal

          ๐Ÿ›
          Anton Bobov
          Anton Bobov

          ๐Ÿ’ป
          Anurag Agarwal
          Anurag Agarwal

          ๐Ÿ›
          Aravind Hegde
          Aravind Hegde

          ๐Ÿ›
          Arda Aslan
          Arda Aslan

          ๐Ÿ›
          Ari Fogel
          Ari Fogel

          ๐Ÿ›
          Arnaud Jeansen
          Arnaud Jeansen

          ๐Ÿ’ป ๐Ÿ›
          Arpit Koolwal
          Arpit Koolwal

          ๐Ÿ›
          Artem
          Artem

          ๐Ÿ’ป ๐Ÿ›
          Artem
          Artem

          ๐Ÿ›
          Artem
          Artem

          ๐Ÿ›
          Artem Sheremet
          Artem Sheremet

          ๐Ÿ›
          Artur
          Artur

          ๐Ÿ›
          Artur Bosch
          Artur Bosch

          ๐Ÿ›
          Artur Dryomov
          Artur Dryomov

          ๐Ÿ›
          Artur Ossowski
          Artur Ossowski

          ๐Ÿ›
          Aryant Tripathi
          Aryant Tripathi

          ๐Ÿ’ป
          AshTheMash
          AshTheMash

          ๐Ÿ›
          AshTheMash
          AshTheMash

          ๐Ÿ›
          Ashish Rana
          Ashish Rana

          ๐Ÿ›
          Atul Kaushal
          Atul Kaushal

          ๐Ÿ›
          August Boland
          August Boland

          ๐Ÿ›
          Aurel Hudec
          Aurel Hudec

          ๐Ÿ›
          Austin
          Austin

          ๐Ÿ›
          Austin Shalit
          Austin Shalit

          ๐Ÿ›
          Austin Tice
          Austin Tice

          ๐Ÿ›
          Austin Tice
          Austin Tice

          ๐Ÿ›
          Ayoub Kaanich
          Ayoub Kaanich

          ๐Ÿ›
          BBG
          BBG

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
          Bailey Tjiong
          Bailey Tjiong

          ๐Ÿ’ป
          Balazs Glatz
          Balazs Glatz

          ๐Ÿ“–
          Barthรฉlemy L.
          Barthรฉlemy L.

          ๐Ÿ›
          Basavaraj K N
          Basavaraj K N

          ๐Ÿ›
          Basil Peace
          Basil Peace

          ๐Ÿ›
          Basil Peace
          Basil Peace

          ๐Ÿ›
          Belle
          Belle

          ๐Ÿ›
          Ben Lerner
          Ben Lerner

          ๐Ÿ›
          Ben Manes
          Ben Manes

          ๐Ÿ›
          Ben McCann
          Ben McCann

          ๐Ÿ›
          Bendegรบz Nagy
          Bendegรบz Nagy

          ๐Ÿ›
          Bennet S Yee
          Bennet S Yee

          ๐Ÿ›
          Benoit Lacelle
          Benoit Lacelle

          ๐Ÿ›
          Benoit Lacelle
          Benoit Lacelle

          ๐Ÿ›
          Bernardo Macรชdo
          Bernardo Macรชdo

          ๐Ÿ›
          Bernd Farka
          Bernd Farka

          ๐Ÿ›
          Betina Cynthia Mamani
          Betina Cynthia Mamani

          ๐Ÿ›
          Bhanu Prakash Pamidi
          Bhanu Prakash Pamidi

          ๐Ÿ’ป ๐Ÿ›
          Bhargav Thanki
          Bhargav Thanki

          ๐Ÿ›
          Binu R J
          Binu R J

          ๐Ÿ›
          Bjรถrn Kautler
          Bjรถrn Kautler

          ๐Ÿ’ป ๐Ÿ›
          Bjรถrn Kautler
          Bjรถrn Kautler

          ๐Ÿ’ป ๐Ÿ›
          Blightbuster
          Blightbuster

          ๐Ÿ›
          Bo Zhang
          Bo Zhang

          ๐Ÿ›
          Bob "Wombat" Hogg
          Bob "Wombat" Hogg

          ๐Ÿ›
          Bobby Wertman
          Bobby Wertman

          ๐Ÿ›
          Bolarinwa Saheed Olayemi
          Bolarinwa Saheed Olayemi

          ๐Ÿ’ป ๐Ÿ›
          Boris Petrov
          Boris Petrov

          ๐Ÿ›
          Brad Kent
          Brad Kent

          ๐Ÿ›
          Brad Kent
          Brad Kent

          ๐Ÿ›
          Brandon Mikeska
          Brandon Mikeska

          ๐Ÿ›
          Brian Batronis
          Brian Batronis

          ๐Ÿ›
          Brian Johnson
          Brian Johnson

          ๐Ÿ›
          Brice Dutheil
          Brice Dutheil

          ๐Ÿ’ป ๐Ÿ›
          Bruno Ferreira
          Bruno Ferreira

          ๐Ÿ›
          Bruno Harbulot
          Bruno Harbulot

          ๐Ÿ›
          Bruno Ritz
          Bruno Ritz

          ๐Ÿ›
          Bruno Ritz
          Bruno Ritz

          ๐Ÿ›
          BurovnikovEvgeniy
          BurovnikovEvgeniy

          ๐Ÿ›
          Cameron Donaldson
          Cameron Donaldson

          ๐Ÿ›
          Carlos Macasaet
          Carlos Macasaet

          ๐Ÿ›
          Carsten Otto
          Carsten Otto

          ๐Ÿ›
          Charlie Housh
          Charlie Housh

          ๐Ÿ›
          Charlie Jonas
          Charlie Jonas

          ๐Ÿ›
          Chas Honton
          Chas Honton

          ๐Ÿ› ๐Ÿ’ป
          Chas Honton
          Chas Honton

          ๐Ÿ› ๐Ÿ’ป
          Chen Yang
          Chen Yang

          ๐Ÿ›
          Chotu
          Chotu

          ๐Ÿ›
          Chris Smith
          Chris Smith

          ๐Ÿ›
          Chris Toomey
          Chris Toomey

          ๐Ÿ›
          Christian Hujer
          Christian Hujer

          ๐Ÿ›
          Christian Pontesegger
          Christian Pontesegger

          ๐Ÿ›
          ChristianWulf
          ChristianWulf

          ๐Ÿ›
          ChristianWulf
          ChristianWulf

          ๐Ÿ›
          Christofer Dutz
          Christofer Dutz

          ๐Ÿ’ป
          Christoffer Anselm
          Christoffer Anselm

          ๐Ÿ›
          Christophe Vidal
          Christophe Vidal

          ๐Ÿ›
          Christopher Dancy
          Christopher Dancy

          ๐Ÿ›
          Clemens Prill
          Clemens Prill

          ๐Ÿ›
          Clint Chester
          Clint Chester

          ๐Ÿ’ป ๐Ÿ›
          Clรฉment Fournier
          Clรฉment Fournier

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง
          Clรฉment Fournier
          Clรฉment Fournier

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง
          Codacy Badger
          Codacy Badger

          ๐Ÿ›
          Code-Nil
          Code-Nil

          ๐Ÿ›
          ColColonCleaner
          ColColonCleaner

          ๐Ÿ›
          Colin Ingarfield
          Colin Ingarfield

          ๐Ÿ›
          Craig Andrews
          Craig Andrews

          ๐Ÿ›
          Craig Muchinsky
          Craig Muchinsky

          ๐Ÿ›
          Cybozu
          Cybozu

          ๐Ÿ’ต
          Cybozu
          Cybozu

          ๐Ÿ’ต
          Cyril
          Cyril

          ๐Ÿ’ป ๐Ÿ›
          Dale
          Dale

          ๐Ÿ’ป
          Damien Jiang
          Damien Jiang

          ๐Ÿ›
          Dan Berindei
          Dan Berindei

          ๐Ÿ›
          Dan Rollo
          Dan Rollo

          ๐Ÿ›
          Dan Ziemba
          Dan Ziemba

          ๐Ÿ›
          Daniel Gredler
          Daniel Gredler

          ๐Ÿ’ป ๐Ÿ›
          Daniel Gredler
          Daniel Gredler

          ๐Ÿ’ป ๐Ÿ›
          Daniel Jipa
          Daniel Jipa

          ๐Ÿ›
          Daniel Paul Searles
          Daniel Paul Searles

          ๐Ÿ’ป
          Daniel Reigada
          Daniel Reigada

          ๐Ÿ›
          Daniel Ventura
          Daniel Ventura

          ๐Ÿ›
          Danilo Pianini
          Danilo Pianini

          ๐Ÿ›
          Darko
          Darko

          ๐Ÿ›
          David
          David

          ๐Ÿ›
          David
          David

          ๐Ÿ›
          David Atkinson
          David Atkinson

          ๐Ÿ›
          David Burstrรถm
          David Burstrรถm

          ๐Ÿ’ป ๐Ÿ›
          David Goatรฉ
          David Goatรฉ

          ๐Ÿ›
          David Golpira
          David Golpira

          ๐Ÿ›
          David Kovaล™รญk
          David Kovaล™รญk

          ๐Ÿ›
          David M. Karr (fullname at gmail.com)
          David M. Karr (fullname at gmail.com)

          ๐Ÿ›
          David Renz
          David Renz

          ๐Ÿ’ป ๐Ÿ›
          David Renz
          David Renz

          ๐Ÿ’ป ๐Ÿ›
          David Renz
          David Renz

          ๐Ÿ›
          David Schach
          David Schach

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–
          Dawid Ciok
          Dawid Ciok

          ๐Ÿ› ๐Ÿ’ป
          Debamoy Datta
          Debamoy Datta

          ๐Ÿ’ป
          Deleted user
          Deleted user

          ๐Ÿ›
          Dell Green
          Dell Green

          ๐Ÿ›
          Dem Pilafian
          Dem Pilafian

          ๐Ÿ›
          Dem Pilafian
          Dem Pilafian

          ๐Ÿ›
          Den
          Den

          ๐Ÿ›
          Denis Borovikov
          Denis Borovikov

          ๐Ÿ’ป ๐Ÿ›
          Dennie Reniers
          Dennie Reniers

          ๐Ÿ’ป ๐Ÿ›
          Dennis Kieselhorst
          Dennis Kieselhorst

          ๐Ÿ›
          Derek P. Moore
          Derek P. Moore

          ๐Ÿ›
          Dichotomia
          Dichotomia

          ๐Ÿ›
          Dionisio Cortรฉs Fernรกndez
          Dionisio Cortรฉs Fernรกndez

          ๐Ÿ’ป ๐Ÿ›
          Dionisio Cortรฉs Fernรกndez
          Dionisio Cortรฉs Fernรกndez

          ๐Ÿ’ป ๐Ÿ›
          Dmitri Bourlatchkov
          Dmitri Bourlatchkov

          ๐Ÿ›
          Dmitriy Kuzmin
          Dmitriy Kuzmin

          ๐Ÿ›
          Dmytro Dashenkov
          Dmytro Dashenkov

          ๐Ÿ›
          Douglas Griffith
          Douglas Griffith

          ๐Ÿ“–
          Dr. Christian Kohlschรผtter
          Dr. Christian Kohlschรผtter

          ๐Ÿ›
          Drew Hall
          Drew Hall

          ๐Ÿ›
          Dumitru Postoronca
          Dumitru Postoronca

          ๐Ÿ›
          Dumitru Postoronca
          Dumitru Postoronca

          ๐Ÿ›
          Dylan Adams
          Dylan Adams

          ๐Ÿ›
          Eden Hao
          Eden Hao

          ๐Ÿ›
          Edward Klimoshenko
          Edward Klimoshenko

          ๐Ÿ› ๐Ÿ’ป
          Egor Bredikhin
          Egor Bredikhin

          ๐Ÿ›
          Elan P. Kugelmass
          Elan P. Kugelmass

          ๐Ÿ›
          Elder S.
          Elder S.

          ๐Ÿ›
          Eldrick Wega
          Eldrick Wega

          ๐Ÿ“–
          Eldrick Wega
          Eldrick Wega

          ๐Ÿ“–
          Elliotte Rusty Harold
          Elliotte Rusty Harold

          ๐Ÿ’ป
          Emile
          Emile

          ๐Ÿ›
          Eric
          Eric

          ๐Ÿ›
          Eric Kintzer
          Eric Kintzer

          ๐Ÿ›
          Eric Perret
          Eric Perret

          ๐Ÿ›
          Eric Squires
          Eric Squires

          ๐Ÿ›
          Erich L Foster
          Erich L Foster

          ๐Ÿ›
          Erich L Foster
          Erich L Foster

          ๐Ÿ›
          Erik Bleske
          Erik Bleske

          ๐Ÿ›
          Erik C. Thauvin
          Erik C. Thauvin

          ๐Ÿ“– ๐Ÿ›
          Ernst Reissner
          Ernst Reissner

          ๐Ÿ›
          Ethan Sargent
          Ethan Sargent

          ๐Ÿ›
          Ewan Tempero
          Ewan Tempero

          ๐Ÿ›
          F.W. Dekker
          F.W. Dekker

          ๐Ÿ›
          FSchliephacke
          FSchliephacke

          ๐Ÿ›
          FSchliephacke
          FSchliephacke

          ๐Ÿ›
          Facundo
          Facundo

          ๐Ÿ›
          Federico Giust
          Federico Giust

          ๐Ÿ›
          Fedor Sherstobitov
          Fedor Sherstobitov

          ๐Ÿ›
          Felix Lampe
          Felix Lampe

          ๐Ÿ›
          Filip Golonka
          Filip Golonka

          ๐Ÿ›
          Filipe Esperandio
          Filipe Esperandio

          ๐Ÿ’ป ๐Ÿ›
          Filippo Barbari
          Filippo Barbari

          ๐Ÿ›
          Filippo Barbari
          Filippo Barbari

          ๐Ÿ›
          Filippo Nova
          Filippo Nova

          ๐Ÿ›
          Francesco la Torre
          Francesco la Torre

          ๐Ÿ›
          Francisco Duarte
          Francisco Duarte

          ๐Ÿ›
          Frederick Zhang
          Frederick Zhang

          ๐Ÿ›
          Frieder Bluemle
          Frieder Bluemle

          ๐Ÿ›
          Frits Jalvingh
          Frits Jalvingh

          ๐Ÿ’ป ๐Ÿ›
          G. Bazior
          G. Bazior

          ๐Ÿ›
          G. Bazior
          G. Bazior

          ๐Ÿ›
          Gabe Henkes
          Gabe Henkes

          ๐Ÿ›
          Gary Gregory
          Gary Gregory

          ๐Ÿ›
          Genoud Magloire
          Genoud Magloire

          ๐Ÿ›
          Geoffrey555
          Geoffrey555

          ๐Ÿ›
          Georg Romstorfer
          Georg Romstorfer

          ๐Ÿ›
          Gili Tzabari
          Gili Tzabari

          ๐Ÿ› ๐Ÿ’ป
          Gio
          Gio

          ๐Ÿ›
          Gio
          Gio

          ๐Ÿ›
          Gol
          Gol

          ๐Ÿ›
          Gold856
          Gold856

          ๐Ÿ› ๐Ÿ’ป
          Gonzalo Exequiel Ibars Ingman
          Gonzalo Exequiel Ibars Ingman

          ๐Ÿ’ป ๐Ÿ›
          GooDer
          GooDer

          ๐Ÿ›
          Gregor Riegler
          Gregor Riegler

          ๐Ÿ›
          Grzegorz Olszewski
          Grzegorz Olszewski

          ๐Ÿ›
          Gunther Schrijvers
          Gunther Schrijvers

          ๐Ÿ’ป ๐Ÿ›
          Gunther Schrijvers
          Gunther Schrijvers

          ๐Ÿ’ป ๐Ÿ›
          Gustavo Krieger
          Gustavo Krieger

          ๐Ÿ›
          Guy Elsmore-Paddock
          Guy Elsmore-Paddock

          ๐Ÿ›
          Gรถrkem Mรผlayim
          Gรถrkem Mรผlayim

          ๐Ÿ›
          Hanzel Godinez
          Hanzel Godinez

          ๐Ÿ›
          Haoliang Chen
          Haoliang Chen

          ๐Ÿ›
          Harsh Kukreja
          Harsh Kukreja

          ๐Ÿ›
          Hassan ALAMI
          Hassan ALAMI

          ๐Ÿ›
          Hassan ALAMI
          Hassan ALAMI

          ๐Ÿ›
          Heber
          Heber

          ๐Ÿ›
          Hector Miuler Malpica Gallegos
          Hector Miuler Malpica Gallegos

          ๐Ÿ›
          Henning Schmiedehausen
          Henning Schmiedehausen

          ๐Ÿ’ป ๐Ÿ›
          Henning von Bargen
          Henning von Bargen

          ๐Ÿ’ป
          Hervรฉ Boutemy
          Hervรฉ Boutemy

          ๐Ÿ›
          Himanshu Pandey
          Himanshu Pandey

          ๐Ÿ›
          Hokwang Lee
          Hokwang Lee

          ๐Ÿ›
          Hokwang Lee
          Hokwang Lee

          ๐Ÿ›
          Hooperbloob
          Hooperbloob

          ๐Ÿ’ป
          Hung PHAN
          Hung PHAN

          ๐Ÿ›
          IDoCodingStuffs
          IDoCodingStuffs

          ๐Ÿ’ป ๐Ÿ›
          Iccen Gan
          Iccen Gan

          ๐Ÿ›
          Ignacio Mariano Tirabasso
          Ignacio Mariano Tirabasso

          ๐Ÿ›
          Igor Melnichenko
          Igor Melnichenko

          ๐Ÿ›
          Igor Moreno
          Igor Moreno

          ๐Ÿ›
          Igor Moreno
          Igor Moreno

          ๐Ÿ›
          Intelesis-MS
          Intelesis-MS

          ๐Ÿ›
          Iroha_
          Iroha_

          ๐Ÿ›
          Ishan Srivastava
          Ishan Srivastava

          ๐Ÿ›
          Iskren Stanislavov
          Iskren Stanislavov

          ๐Ÿ›
          Ivan Vakhrushev
          Ivan Vakhrushev

          ๐Ÿ›
          Ivano Guerini
          Ivano Guerini

          ๐Ÿ›
          Ivar Andreas Bonsaksen
          Ivar Andreas Bonsaksen

          ๐Ÿ›
          Ivar Andreas Bonsaksen
          Ivar Andreas Bonsaksen

          ๐Ÿ›
          Ivo ล mรญd
          Ivo ล mรญd

          ๐Ÿ›
          JJengility
          JJengility

          ๐Ÿ›
          Jake Hemmerle
          Jake Hemmerle

          ๐Ÿ›
          Jakub Dupak
          Jakub Dupak

          ๐Ÿ’ป
          James Harrison
          James Harrison

          ๐Ÿ› ๐Ÿ’ป
          Jamie Bisotti
          Jamie Bisotti

          ๐Ÿ›
          Jan
          Jan

          ๐Ÿ›
          Jan
          Jan

          ๐Ÿ›
          Jan Aertgeerts
          Jan Aertgeerts

          ๐Ÿ’ป ๐Ÿ›
          Jan Brรผmmer
          Jan Brรผmmer

          ๐Ÿ›
          Jan Tล™รญska
          Jan Tล™รญska

          ๐Ÿ›
          Jan-Lukas Else
          Jan-Lukas Else

          ๐Ÿ›
          Jason Qiu
          Jason Qiu

          ๐Ÿ’ป ๐Ÿ“–
          Jason Williams
          Jason Williams

          ๐Ÿ›
          Javier Spagnoletti
          Javier Spagnoletti

          ๐Ÿ›
          Javier Spagnoletti
          Javier Spagnoletti

          ๐Ÿ›
          Jean-Paul Mayer
          Jean-Paul Mayer

          ๐Ÿ›
          Jean-Simon Larochelle
          Jean-Simon Larochelle

          ๐Ÿ›
          Jeff Bartolotta
          Jeff Bartolotta

          ๐Ÿ’ป ๐Ÿ›
          Jeff Hube
          Jeff Hube

          ๐Ÿ’ป ๐Ÿ›
          Jeff Jensen
          Jeff Jensen

          ๐Ÿ›
          Jeff May
          Jeff May

          ๐Ÿ›
          Jens Gerdes
          Jens Gerdes

          ๐Ÿ›
          Jens Gerdes
          Jens Gerdes

          ๐Ÿ›
          Jeroen Borgers
          Jeroen Borgers

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข
          Jeroen Meijer
          Jeroen Meijer

          ๐Ÿ›
          Jeroen van Wilgenburg
          Jeroen van Wilgenburg

          ๐Ÿ“–
          Jerome Russ
          Jerome Russ

          ๐Ÿ›
          JerritEic
          JerritEic

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
          Jiri Pejchal
          Jiri Pejchal

          ๐Ÿ›
          Jithin Sunny
          Jithin Sunny

          ๐Ÿ›
          Jithin Sunny
          Jithin Sunny

          ๐Ÿ›
          Jiล™รญ ล korpil
          Jiล™รญ ล korpil

          ๐Ÿ›
          Joao Machado
          Joao Machado

          ๐Ÿ›
          Jochen Krauss
          Jochen Krauss

          ๐Ÿ›
          Johan Hammar
          Johan Hammar

          ๐Ÿ›
          John Jetmore
          John Jetmore

          ๐Ÿ“–
          John Karp
          John Karp

          ๐Ÿ›
          John Zhang
          John Zhang

          ๐Ÿ›
          John Zhang
          John Zhang

          ๐Ÿ›
          John-Teng
          John-Teng

          ๐Ÿ’ป ๐Ÿ›
          Jon Moroney
          Jon Moroney

          ๐Ÿ’ป ๐Ÿ›
          Jonas Geiregat
          Jonas Geiregat

          ๐Ÿ›
          Jonas KeรŸler
          Jonas KeรŸler

          ๐Ÿ›
          Jonathan Gillespie
          Jonathan Gillespie

          ๐Ÿ’ต
          Jonathan Wiesel
          Jonathan Wiesel

          ๐Ÿ’ป ๐Ÿ›
          Jordan
          Jordan

          ๐Ÿ›
          Jordan
          Jordan

          ๐Ÿ›
          Jordi Llach
          Jordi Llach

          ๐Ÿ›
          Jorge Solรณrzano
          Jorge Solรณrzano

          ๐Ÿ›
          JorneVL
          JorneVL

          ๐Ÿ›
          Jose Palafox
          Jose Palafox

          ๐Ÿ›
          Jose Stovall
          Jose Stovall

          ๐Ÿ›
          Joseph
          Joseph

          ๐Ÿ’ป
          Joseph Heenan
          Joseph Heenan

          ๐Ÿ›
          Joseph Heenan
          Joseph Heenan

          ๐Ÿ›
          Josh Feingold
          Josh Feingold

          ๐Ÿ’ป ๐Ÿ›
          Josh Holthaus
          Josh Holthaus

          ๐Ÿ›
          Joshua S Arquilevich
          Joshua S Arquilevich

          ๐Ÿ›
          Joรฃo Dinis Ferreira
          Joรฃo Dinis Ferreira

          ๐Ÿ“–
          Joรฃo Ferreira
          Joรฃo Ferreira

          ๐Ÿ’ป ๐Ÿ›
          Joรฃo Pedro Schmitt
          Joรฃo Pedro Schmitt

          ๐Ÿ›
          Juan Martรญn Sotuyo Dodero
          Juan Martรญn Sotuyo Dodero

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง
          Juan Martรญn Sotuyo Dodero
          Juan Martรญn Sotuyo Dodero

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง
          Juan Pablo Civile
          Juan Pablo Civile

          ๐Ÿ›
          Jude Pereira
          Jude Pereira

          ๐Ÿ’ป
          Julian Voronetsky
          Julian Voronetsky

          ๐Ÿ›
          Julien
          Julien

          ๐Ÿ›
          Julius
          Julius

          ๐Ÿ›
          JustPRV
          JustPRV

          ๐Ÿ›
          Justin Stroud
          Justin Stroud

          ๐Ÿ’ป
          Justin Stroud
          Justin Stroud

          ๐Ÿ’ป
          Jรถrn Huxhorn
          Jรถrn Huxhorn

          ๐Ÿ›
          KThompso
          KThompso

          ๐Ÿ›
          Kai Amundsen
          Kai Amundsen

          ๐Ÿ›
          Karel Vervaeke
          Karel Vervaeke

          ๐Ÿ›
          Karl-Andero Mere
          Karl-Andero Mere

          ๐Ÿ›
          Karl-Philipp Richter
          Karl-Philipp Richter

          ๐Ÿ›
          Karsten Silz
          Karsten Silz

          ๐Ÿ›
          Karsten Silz
          Karsten Silz

          ๐Ÿ›
          Kazuma Watanabe
          Kazuma Watanabe

          ๐Ÿ›
          Kernevez
          Kernevez

          ๐Ÿ›
          Kev
          Kev

          ๐Ÿ›
          Keve Mรผller
          Keve Mรผller

          ๐Ÿ›
          Kevin Guerra
          Kevin Guerra

          ๐Ÿ’ป
          Kevin Jones
          Kevin Jones

          ๐Ÿ› ๐Ÿ’ป
          Kevin Poorman
          Kevin Poorman

          ๐Ÿ›
          Kevin Poorman
          Kevin Poorman

          ๐Ÿ›
          Kevin Wayne
          Kevin Wayne

          ๐Ÿ›
          Kieran Black
          Kieran Black

          ๐Ÿ›
          Kirill Zubov
          Kirill Zubov

          ๐Ÿ›
          Kirk Clemens
          Kirk Clemens

          ๐Ÿ’ป ๐Ÿ›
          Klaus Hartl
          Klaus Hartl

          ๐Ÿ›
          Koen Van Looveren
          Koen Van Looveren

          ๐Ÿ›
          Kris Scheibe
          Kris Scheibe

          ๐Ÿ’ป ๐Ÿ›
          Kris Scheibe
          Kris Scheibe

          ๐Ÿ’ป ๐Ÿ›
          Krystian Dabrowski
          Krystian Dabrowski

          ๐Ÿ› ๐Ÿ’ป
          Krzysztof Dymek
          Krzysztof Dymek

          ๐Ÿ›
          Kunal Thanki
          Kunal Thanki

          ๐Ÿ›
          Kursat Aktas
          Kursat Aktas

          ๐Ÿ“–
          LaLucid
          LaLucid

          ๐Ÿ’ป
          Larry Diamond
          Larry Diamond

          ๐Ÿ’ป ๐Ÿ›
          Lars Knickrehm
          Lars Knickrehm

          ๐Ÿ›
          Lars Knickrehm
          Lars Knickrehm

          ๐Ÿ›
          Laurent Bovet
          Laurent Bovet

          ๐Ÿ› ๐Ÿ’ป
          Leo Gutierrez
          Leo Gutierrez

          ๐Ÿ›
          LiGaOg
          LiGaOg

          ๐Ÿ’ป
          Liam Sharp
          Liam Sharp

          ๐Ÿ›
          Lintsi
          Lintsi

          ๐Ÿ›
          Linus Fernandes
          Linus Fernandes

          ๐Ÿ›
          Lixon Lookose
          Lixon Lookose

          ๐Ÿ›
          Lixon Lookose
          Lixon Lookose

          ๐Ÿ›
          Logesh
          Logesh

          ๐Ÿ›
          Lorenzo Gabriele
          Lorenzo Gabriele

          ๐Ÿ›
          Loรฏc Ledoyen
          Loรฏc Ledoyen

          ๐Ÿ›
          Lucas
          Lucas

          ๐Ÿ›
          Lucas Silva
          Lucas Silva

          ๐Ÿ›
          Lucas Soncini
          Lucas Soncini

          ๐Ÿ’ป ๐Ÿ›
          Luis Alcantar
          Luis Alcantar

          ๐Ÿ’ป
          Luis Alcantar
          Luis Alcantar

          ๐Ÿ’ป
          Lukas Grรคf
          Lukas Grรคf

          ๐Ÿ’ป
          Lukasz Slonina
          Lukasz Slonina

          ๐Ÿ›
          Lukebray
          Lukebray

          ๐Ÿ›
          Lynn
          Lynn

          ๐Ÿ’ป ๐Ÿ›
          Lyor Goldstein
          Lyor Goldstein

          ๐Ÿ›
          MCMicS
          MCMicS

          ๐Ÿ›
          Macarse
          Macarse

          ๐Ÿ›
          Macarse
          Macarse

          ๐Ÿ›
          Machine account for PMD
          Machine account for PMD

          ๐Ÿ’ป
          Maciek Siemczyk
          Maciek Siemczyk

          ๐Ÿ›
          Maikel Steneker
          Maikel Steneker

          ๐Ÿ’ป ๐Ÿ›
          Maksim Moiseikin
          Maksim Moiseikin

          ๐Ÿ›
          Malik
          Malik

          ๐Ÿ›
          Manfred Koch
          Manfred Koch

          ๐Ÿ›
          Manuel Moya Ferrer
          Manuel Moya Ferrer

          ๐Ÿ’ป ๐Ÿ›
          Manuel Moya Ferrer
          Manuel Moya Ferrer

          ๐Ÿ’ป ๐Ÿ›
          Manuel Romeiro
          Manuel Romeiro

          ๐Ÿ›
          Manuel Ryan
          Manuel Ryan

          ๐Ÿ›
          Marat Vyshegorodtsev
          Marat Vyshegorodtsev

          ๐Ÿ›
          Marcel Hรคrle
          Marcel Hรคrle

          ๐Ÿ›
          Marcello Fialho
          Marcello Fialho

          ๐Ÿ›
          Marcin Dฤ…browski
          Marcin Dฤ…browski

          ๐Ÿ’ป ๐Ÿ›
          Marcin Rataj
          Marcin Rataj

          ๐Ÿ›
          Marcin Rataj
          Marcin Rataj

          ๐Ÿ›
          Marcono1234
          Marcono1234

          ๐Ÿ›
          Mark Adamcin
          Mark Adamcin

          ๐Ÿ›
          Mark Hall
          Mark Hall

          ๐Ÿ’ป ๐Ÿ›
          Mark Kolich
          Mark Kolich

          ๐Ÿ›
          Mark Pritchard
          Mark Pritchard

          ๐Ÿ›
          Markus Rathgeb
          Markus Rathgeb

          ๐Ÿ›
          Marquis Wang
          Marquis Wang

          ๐Ÿ›
          Marquis Wang
          Marquis Wang

          ๐Ÿ›
          MartGit
          MartGit

          ๐Ÿ›
          Martin Feldsztejn
          Martin Feldsztejn

          ๐Ÿ›
          Martin Lehmann
          Martin Lehmann

          ๐Ÿ›
          Martin Spamer
          Martin Spamer

          ๐Ÿ›
          Martin Tarjรกnyi
          Martin Tarjรกnyi

          ๐Ÿ›
          MatFl
          MatFl

          ๐Ÿ›
          Mateusz Stefanski
          Mateusz Stefanski

          ๐Ÿ›
          Mateusz Stefanski
          Mateusz Stefanski

          ๐Ÿ›
          Mathias Lagerwall
          Mathias Lagerwall

          ๐Ÿ›
          Mathieu Gouin
          Mathieu Gouin

          ๐Ÿ›
          MatiasComercio
          MatiasComercio

          ๐Ÿ’ป ๐Ÿ›
          Matt Benson
          Matt Benson

          ๐Ÿ›
          Matt De Poorter
          Matt De Poorter

          ๐Ÿ›
          Matt Hargett
          Matt Hargett

          ๐Ÿ’ป ๐Ÿ’ต
          Matt Harrah
          Matt Harrah

          ๐Ÿ›
          Matt Harrah
          Matt Harrah

          ๐Ÿ›
          Matt Nelson
          Matt Nelson

          ๐Ÿ›
          Matthew Amos
          Matthew Amos

          ๐Ÿ›
          Matthew Duggan
          Matthew Duggan

          ๐Ÿ›
          Matthew Hall
          Matthew Hall

          ๐Ÿ›
          Matthew Rossner
          Matthew Rossner

          ๐Ÿ›
          Matรญas Fraga
          Matรญas Fraga

          ๐Ÿ’ป ๐Ÿ›
          Maxime Robert
          Maxime Robert

          ๐Ÿ’ป ๐Ÿ›
          Maxime Robert
          Maxime Robert

          ๐Ÿ’ป ๐Ÿ›
          MetaBF
          MetaBF

          ๐Ÿ›
          Metin Dagcilar
          Metin Dagcilar

          ๐Ÿ›
          Michael
          Michael

          ๐Ÿ›
          Michael Bell
          Michael Bell

          ๐Ÿ›
          Michael Bernstein
          Michael Bernstein

          ๐Ÿ›
          Michael Clay
          Michael Clay

          ๐Ÿ›
          Michael Dombrowski
          Michael Dombrowski

          ๐Ÿ›
          Michael Dombrowski
          Michael Dombrowski

          ๐Ÿ›
          Michael Hausegger
          Michael Hausegger

          ๐Ÿ›
          Michael Hoefer
          Michael Hoefer

          ๐Ÿ›
          Michael Kolesnikov
          Michael Kolesnikov

          ๐Ÿ›
          Michael Mรถbius
          Michael Mรถbius

          ๐Ÿ›
          Michael N. Lipp
          Michael N. Lipp

          ๐Ÿ›
          Michael Pellegrini
          Michael Pellegrini

          ๐Ÿ›
          Michal Kordas
          Michal Kordas

          ๐Ÿ›
          Michal Kordas
          Michal Kordas

          ๐Ÿ›
          Michaล‚ Borek
          Michaล‚ Borek

          ๐Ÿ›
          Michaล‚ Kuliล„ski
          Michaล‚ Kuliล„ski

          ๐Ÿ›
          Miguel Nรบรฑez Dรญaz-Montes
          Miguel Nรบรฑez Dรญaz-Montes

          ๐Ÿ›
          Mihai Ionut
          Mihai Ionut

          ๐Ÿ›
          Mikhail Kuchma
          Mikhail Kuchma

          ๐Ÿ›
          MiladSadinam
          MiladSadinam

          ๐Ÿ›
          Mirek Hankus
          Mirek Hankus

          ๐Ÿ›
          Mirek Hankus
          Mirek Hankus

          ๐Ÿ›
          Mitch Spano
          Mitch Spano

          ๐Ÿ’ป ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          MrAngry52
          MrAngry52

          ๐Ÿ›
          Muminur Choudhury
          Muminur Choudhury

          ๐Ÿ›
          Mykhailo Palahuta
          Mykhailo Palahuta

          ๐Ÿ’ป ๐Ÿ›
          Nagendra Kumar Singh
          Nagendra Kumar Singh

          ๐Ÿ›
          Nagendra Kumar Singh
          Nagendra Kumar Singh

          ๐Ÿ›
          Nahuel Barrios
          Nahuel Barrios

          ๐Ÿ›
          Nakul Sharma
          Nakul Sharma

          ๐Ÿ›
          Nathan Braun
          Nathan Braun

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathanaรซl
          Nathanaรซl

          ๐Ÿ›
          Naveen
          Naveen

          ๐Ÿ’ป
          Naveen
          Naveen

          ๐Ÿ’ป
          Nazdravi
          Nazdravi

          ๐Ÿ›
          Neha-Dhonde
          Neha-Dhonde

          ๐Ÿ›
          Nicholas Doyle
          Nicholas Doyle

          ๐Ÿ›
          Nick Butcher
          Nick Butcher

          ๐Ÿ›
          Nico Gallinal
          Nico Gallinal

          ๐Ÿ›
          Nicola Dal Maso
          Nicola Dal Maso

          ๐Ÿ›
          Nicolas Filotto
          Nicolas Filotto

          ๐Ÿ’ป
          Nicolas Filotto
          Nicolas Filotto

          ๐Ÿ’ป
          Nicolas Vervelle
          Nicolas Vervelle

          ๐Ÿ›
          Nicolas Vuillamy
          Nicolas Vuillamy

          ๐Ÿ“–
          Nikita Chursin
          Nikita Chursin

          ๐Ÿ›
          Niklas Baudy
          Niklas Baudy

          ๐Ÿ›
          Nikolas Havrikov
          Nikolas Havrikov

          ๐Ÿ›
          Nilesh Virkar
          Nilesh Virkar

          ๐Ÿ›
          Nimit Patel
          Nimit Patel

          ๐Ÿ›
          Nimit Patel
          Nimit Patel

          ๐Ÿ›
          Niranjan Harpale
          Niranjan Harpale

          ๐Ÿ›
          Nirvik Patel
          Nirvik Patel

          ๐Ÿ’ป
          Noah Sussman
          Noah Sussman

          ๐Ÿ›
          Noah0120
          Noah0120

          ๐Ÿ›
          Noam Tamim
          Noam Tamim

          ๐Ÿ›
          Noel Grandin
          Noel Grandin

          ๐Ÿ›
          Olaf Haalstra
          Olaf Haalstra

          ๐Ÿ›
          Olaf Haalstra
          Olaf Haalstra

          ๐Ÿ›
          Oleg Andreych
          Oleg Andreych

          ๐Ÿ’ป ๐Ÿ›
          Oleg Pavlenko
          Oleg Pavlenko

          ๐Ÿ›
          Oleksii Dykov
          Oleksii Dykov

          ๐Ÿ’ป ๐Ÿ›
          Oliver Eikemeier
          Oliver Eikemeier

          ๐Ÿ›
          Oliver Siegmar
          Oliver Siegmar

          ๐Ÿ’ต
          Olivier Parent
          Olivier Parent

          ๐Ÿ’ป ๐Ÿ›
          Ollie Abbey
          Ollie Abbey

          ๐Ÿ’ป ๐Ÿ›
          Ollie Abbey
          Ollie Abbey

          ๐Ÿ’ป ๐Ÿ›
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)

          ๐Ÿ›
          Ondrej Kratochvil
          Ondrej Kratochvil

          ๐Ÿ›
          OverDrone
          OverDrone

          ๐Ÿ›
          Ozan Gulle
          Ozan Gulle

          ๐Ÿ’ป ๐Ÿ›
          PUNEET JAIN
          PUNEET JAIN

          ๐Ÿ›
          Pankraz76
          Pankraz76

          ๐Ÿ’ป ๐Ÿ›
          Parbati Bose
          Parbati Bose

          ๐Ÿ›
          Parbati Bose
          Parbati Bose

          ๐Ÿ›
          Paul Berg
          Paul Berg

          ๐Ÿ›
          Paul Guyot
          Paul Guyot

          ๐Ÿ’ป
          Pavel Bludov
          Pavel Bludov

          ๐Ÿ›
          Pavel Miฤka
          Pavel Miฤka

          ๐Ÿ›
          Pedro Nuno Santos
          Pedro Nuno Santos

          ๐Ÿ›
          Pedro Rijo
          Pedro Rijo

          ๐Ÿ›
          Pelisse Romain
          Pelisse Romain

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
          Pelisse Romain
          Pelisse Romain

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
          Per Abich
          Per Abich

          ๐Ÿ’ป
          Pete Davids
          Pete Davids

          ๐Ÿ›
          Peter Bruin
          Peter Bruin

          ๐Ÿ›
          Peter Chittum
          Peter Chittum

          ๐Ÿ’ป ๐Ÿ›
          Peter Cudmore
          Peter Cudmore

          ๐Ÿ›
          Peter Kasson
          Peter Kasson

          ๐Ÿ›
          Peter Kofler
          Peter Kofler

          ๐Ÿ›
          Peter Kofler
          Peter Kofler

          ๐Ÿ›
          Peter Paul Bakker
          Peter Paul Bakker

          ๐Ÿ’ป ๐Ÿ›
          Peter Rader
          Peter Rader

          ๐Ÿ›
          Pham Hai Trung
          Pham Hai Trung

          ๐Ÿ›
          Philip Graf
          Philip Graf

          ๐Ÿ’ป ๐Ÿ›
          Philip Hachey
          Philip Hachey

          ๐Ÿ›
          Philippe Ozil
          Philippe Ozil

          ๐Ÿ›
          Phinehas Artemix
          Phinehas Artemix

          ๐Ÿ›
          Phinehas Artemix
          Phinehas Artemix

          ๐Ÿ›
          Phokham Nonava
          Phokham Nonava

          ๐Ÿ›
          Pim van der Loos
          Pim van der Loos

          ๐Ÿ’ป โš ๏ธ
          Piotr Szymaล„ski
          Piotr Szymaล„ski

          ๐Ÿ›
          Piotrek ลปygieล‚o
          Piotrek ลปygieล‚o

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“–
          Pranay Jaiswal
          Pranay Jaiswal

          ๐Ÿ›
          Prasad Kamath
          Prasad Kamath

          ๐Ÿ›
          Prasanna
          Prasanna

          ๐Ÿ›
          Prasanna
          Prasanna

          ๐Ÿ›
          Presh-AR
          Presh-AR

          ๐Ÿ›
          Puneet1726
          Puneet1726

          ๐Ÿ›
          RBRi
          RBRi

          ๐Ÿ›
          Rafael Cortรชs
          Rafael Cortรชs

          ๐Ÿ›
          RaheemShaik999
          RaheemShaik999

          ๐Ÿ›
          RajeshR
          RajeshR

          ๐Ÿ’ป ๐Ÿ›
          Ramachandra Mohan
          Ramachandra Mohan

          ๐Ÿ›
          Ramachandra Mohan
          Ramachandra Mohan

          ๐Ÿ›
          Ramel0921
          Ramel0921

          ๐Ÿ›
          Raquel Pau
          Raquel Pau

          ๐Ÿ›
          Ravikiran Janardhana
          Ravikiran Janardhana

          ๐Ÿ›
          Reda Benhemmouche
          Reda Benhemmouche

          ๐Ÿ›
          Reinhard Schiedermeier
          Reinhard Schiedermeier

          ๐Ÿ›
          Renato Oliveira
          Renato Oliveira

          ๐Ÿ’ป ๐Ÿ›
          Rich DiCroce
          Rich DiCroce

          ๐Ÿ›
          Rich DiCroce
          Rich DiCroce

          ๐Ÿ›
          Richard Corfield
          Richard Corfield

          ๐Ÿ’ป
          Richard Corfield
          Richard Corfield

          ๐Ÿ› ๐Ÿ’ป
          Riot R1cket
          Riot R1cket

          ๐Ÿ›
          Rishabh Jain
          Rishabh Jain

          ๐Ÿ›
          RishabhDeep Singh
          RishabhDeep Singh

          ๐Ÿ›
          Rob Baillie
          Rob Baillie

          ๐Ÿ›
          Robbie Martinus
          Robbie Martinus

          ๐Ÿ’ป ๐Ÿ›
          Robbie Martinus
          Robbie Martinus

          ๐Ÿ’ป ๐Ÿ›
          Robert Henry
          Robert Henry

          ๐Ÿ›
          Robert Mihaly
          Robert Mihaly

          ๐Ÿ›
          Robert Painsi
          Robert Painsi

          ๐Ÿ›
          Robert Russell
          Robert Russell

          ๐Ÿ›
          Robert Sรถsemann
          Robert Sรถsemann

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ›
          Robert Whitebit
          Robert Whitebit

          ๐Ÿ›
          Robin Richtsfeld
          Robin Richtsfeld

          ๐Ÿ›
          Robin Richtsfeld
          Robin Richtsfeld

          ๐Ÿ›
          Robin Stocker
          Robin Stocker

          ๐Ÿ’ป ๐Ÿ›
          Robin Wils
          Robin Wils

          ๐Ÿ›
          RochusOest
          RochusOest

          ๐Ÿ›
          Rodolfo Noviski
          Rodolfo Noviski

          ๐Ÿ›
          Rodrigo Casara
          Rodrigo Casara

          ๐Ÿ›
          Rodrigo Fernandes
          Rodrigo Fernandes

          ๐Ÿ›
          Roman Salvador
          Roman Salvador

          ๐Ÿ’ป ๐Ÿ›
          Roman Salvador
          Roman Salvador

          ๐Ÿ’ป ๐Ÿ›
          Ronald Blaschke
          Ronald Blaschke

          ๐Ÿ›
          Rรณbert Papp
          Rรณbert Papp

          ๐Ÿ›
          Saikat Sengupta
          Saikat Sengupta

          ๐Ÿ›
          Saksham Handu
          Saksham Handu

          ๐Ÿ›
          Saladoc
          Saladoc

          ๐Ÿ›
          Salesforce Bob Lightning
          Salesforce Bob Lightning

          ๐Ÿ›
          Sam Carlberg
          Sam Carlberg

          ๐Ÿ›
          Sam Carlberg
          Sam Carlberg

          ๐Ÿ›
          Sascha Riemer
          Sascha Riemer

          ๐Ÿ›
          Sashko
          Sashko

          ๐Ÿ’ป
          Satoshi Kubo
          Satoshi Kubo

          ๐Ÿ›
          Scott Kennedy
          Scott Kennedy

          ๐Ÿ›
          Scott Wells
          Scott Wells

          ๐Ÿ› ๐Ÿ’ป
          Scrates1
          Scrates1

          ๐Ÿ› ๐Ÿ’ป
          Scrsloota
          Scrsloota

          ๐Ÿ’ป
          Scrsloota
          Scrsloota

          ๐Ÿ’ป
          Sebastian Bรถgl
          Sebastian Bรถgl

          ๐Ÿ›
          Sebastian Davids
          Sebastian Davids

          ๐Ÿ›
          Sebastian Lรถvdahl
          Sebastian Lรถvdahl

          ๐Ÿ›
          Sebastian Schuberth
          Sebastian Schuberth

          ๐Ÿ›
          Sebastian Schwarz
          Sebastian Schwarz

          ๐Ÿ›
          Seren
          Seren

          ๐Ÿ› ๐Ÿ’ป
          Sergey Gorbaty
          Sergey Gorbaty

          ๐Ÿ›
          Sergey Gorbaty
          Sergey Gorbaty

          ๐Ÿ›
          Sergey Kozlov
          Sergey Kozlov

          ๐Ÿ›
          Sergey Yanzin
          Sergey Yanzin

          ๐Ÿ’ป ๐Ÿ›
          Seth Wilcox
          Seth Wilcox

          ๐Ÿ’ป
          Shai Bennathan
          Shai Bennathan

          ๐Ÿ› ๐Ÿ’ป
          Shubham
          Shubham

          ๐Ÿ’ป ๐Ÿ›
          Simon Abykov
          Simon Abykov

          ๐Ÿ’ป ๐Ÿ›
          Simon Xiao
          Simon Xiao

          ๐Ÿ›
          Simon Xiao
          Simon Xiao

          ๐Ÿ›
          Srinivasan Venkatachalam
          Srinivasan Venkatachalam

          ๐Ÿ›
          Stanislav Gromov
          Stanislav Gromov

          ๐Ÿ›
          Stanislav Myachenkov
          Stanislav Myachenkov

          ๐Ÿ’ป
          Stefan Birkner
          Stefan Birkner

          ๐Ÿ›
          Stefan Bohn
          Stefan Bohn

          ๐Ÿ›
          Stefan Endrullis
          Stefan Endrullis

          ๐Ÿ›
          Stefan Klรถss-Schuster
          Stefan Klรถss-Schuster

          ๐Ÿ›
          Stefan Klรถss-Schuster
          Stefan Klรถss-Schuster

          ๐Ÿ›
          Stefan Wolf
          Stefan Wolf

          ๐Ÿ›
          Stephan H. Wissel
          Stephan H. Wissel

          ๐Ÿ›
          Stephen
          Stephen

          ๐Ÿ›
          Stephen Carter
          Stephen Carter

          ๐Ÿ›
          Stephen Friedrich
          Stephen Friedrich

          ๐Ÿ›
          Steve Babula
          Steve Babula

          ๐Ÿ’ป
          Steve White
          Steve White

          ๐Ÿ›
          Steve White
          Steve White

          ๐Ÿ›
          Steven Schlansker
          Steven Schlansker

          ๐Ÿ›
          Steven Stearns
          Steven Stearns

          ๐Ÿ› ๐Ÿ’ป
          Stexxe
          Stexxe

          ๐Ÿ›
          Stian Lรฅgstad
          Stian Lรฅgstad

          ๐Ÿ›
          StuartClayton5
          StuartClayton5

          ๐Ÿ›
          Supun Arunoda
          Supun Arunoda

          ๐Ÿ›
          Suren Abrahamyan
          Suren Abrahamyan

          ๐Ÿ›
          Suren Abrahamyan
          Suren Abrahamyan

          ๐Ÿ›
          Suvashri
          Suvashri

          ๐Ÿ“–
          Sven Barden
          Sven Barden

          ๐Ÿ›
          SwatiBGupta1110
          SwatiBGupta1110

          ๐Ÿ›
          SyedThoufich
          SyedThoufich

          ๐Ÿ›
          Szymon Sasin
          Szymon Sasin

          ๐Ÿ›
          T-chuangxin
          T-chuangxin

          ๐Ÿ›
          TERAI Atsuhiro
          TERAI Atsuhiro

          ๐Ÿ›
          TERAI Atsuhiro
          TERAI Atsuhiro

          ๐Ÿ›
          TIOBE Software
          TIOBE Software

          ๐Ÿ’ป ๐Ÿ›
          Tarush Singh
          Tarush Singh

          ๐Ÿ’ป
          Taylor Smock
          Taylor Smock

          ๐Ÿ›
          Techeira Damiรกn
          Techeira Damiรกn

          ๐Ÿ’ป ๐Ÿ›
          Ted Husted
          Ted Husted

          ๐Ÿ›
          TehBakker
          TehBakker

          ๐Ÿ›
          The Gitter Badger
          The Gitter Badger

          ๐Ÿ›
          The Gitter Badger
          The Gitter Badger

          ๐Ÿ›
          Theodoor
          Theodoor

          ๐Ÿ›
          Thiago Henrique Hรผpner
          Thiago Henrique Hรผpner

          ๐Ÿ›
          Thibault Meyer
          Thibault Meyer

          ๐Ÿ›
          Thomas Gรผttler
          Thomas Gรผttler

          ๐Ÿ›
          Thomas Jones-Low
          Thomas Jones-Low

          ๐Ÿ›
          Thomas Smith
          Thomas Smith

          ๐Ÿ’ป ๐Ÿ›
          ThrawnCA
          ThrawnCA

          ๐Ÿ›
          ThrawnCA
          ThrawnCA

          ๐Ÿ›
          Thu Vo
          Thu Vo

          ๐Ÿ›
          Thunderforge
          Thunderforge

          ๐Ÿ’ป ๐Ÿ›
          Tim van der Lippe
          Tim van der Lippe

          ๐Ÿ›
          Tobias Weimer
          Tobias Weimer

          ๐Ÿ’ป ๐Ÿ›
          Tom Copeland
          Tom Copeland

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–
          Tom Daly
          Tom Daly

          ๐Ÿ›
          Tomas
          Tomas

          ๐Ÿ›
          Tomas
          Tomas

          ๐Ÿ›
          Tomer Figenblat
          Tomer Figenblat

          ๐Ÿ›
          Tomi De Lucca
          Tomi De Lucca

          ๐Ÿ’ป ๐Ÿ›
          Tony
          Tony

          ๐Ÿ“–
          Torsten Kleiber
          Torsten Kleiber

          ๐Ÿ›
          Torsten Krause
          Torsten Krause

          ๐Ÿ›
          TrackerSB
          TrackerSB

          ๐Ÿ›
          Tyson Stewart
          Tyson Stewart

          ๐Ÿ›
          Tyson Stewart
          Tyson Stewart

          ๐Ÿ›
          Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ›
          UncleOwen
          UncleOwen

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“–
          Utku Cuhadaroglu
          Utku Cuhadaroglu

          ๐Ÿ’ป ๐Ÿ›
          Valentin Brandl
          Valentin Brandl

          ๐Ÿ›
          Valeria
          Valeria

          ๐Ÿ›
          Valery Yatsynovich
          Valery Yatsynovich

          ๐Ÿ“–
          Vasily Anisimov
          Vasily Anisimov

          ๐Ÿ›
          Vasily Anisimov
          Vasily Anisimov

          ๐Ÿ›
          Vedant Chokshi
          Vedant Chokshi

          ๐Ÿ›
          Vibhor Goyal
          Vibhor Goyal

          ๐Ÿ›
          Vickenty Fesunov
          Vickenty Fesunov

          ๐Ÿ›
          Victor Noรซl
          Victor Noรซl

          ๐Ÿ›
          Vincent Galloy
          Vincent Galloy

          ๐Ÿ’ป
          Vincent HUYNH
          Vincent HUYNH

          ๐Ÿ›
          Vincent Maurin
          Vincent Maurin

          ๐Ÿ›
          Vincent Maurin
          Vincent Maurin

          ๐Ÿ›
          Vincent Potucek
          Vincent Potucek

          ๐Ÿ’ป
          Vincent Privat
          Vincent Privat

          ๐Ÿ›
          Vishhwas
          Vishhwas

          ๐Ÿ›
          Vishv_Android
          Vishv_Android

          ๐Ÿ›
          Vitalii Yevtushenko
          Vitalii Yevtushenko

          ๐Ÿ›
          Vitaly
          Vitaly

          ๐Ÿ›
          Vitaly Polonetsky
          Vitaly Polonetsky

          ๐Ÿ›
          Vitaly Polonetsky
          Vitaly Polonetsky

          ๐Ÿ›
          Vojtech Polivka
          Vojtech Polivka

          ๐Ÿ›
          Vsevolod Zholobov
          Vsevolod Zholobov

          ๐Ÿ›
          Vyom Yadav
          Vyom Yadav

          ๐Ÿ’ป
          Wang Shidong
          Wang Shidong

          ๐Ÿ›
          Waqas Ahmed
          Waqas Ahmed

          ๐Ÿ›
          Wayne J. Earl
          Wayne J. Earl

          ๐Ÿ›
          Wchenghui
          Wchenghui

          ๐Ÿ›
          Wchenghui
          Wchenghui

          ๐Ÿ›
          Wener
          Wener

          ๐Ÿ’ป
          Will Winder
          Will Winder

          ๐Ÿ›
          Willem A. Hajenius
          Willem A. Hajenius

          ๐Ÿ’ป
          William Brockhus
          William Brockhus

          ๐Ÿ’ป ๐Ÿ›
          Wilson Kurniawan
          Wilson Kurniawan

          ๐Ÿ›
          Wim Deblauwe
          Wim Deblauwe

          ๐Ÿ›
          Wolf2323
          Wolf2323

          ๐Ÿ›
          Wolf2323
          Wolf2323

          ๐Ÿ›
          Woongsik Choi
          Woongsik Choi

          ๐Ÿ›
          XenoAmess
          XenoAmess

          ๐Ÿ’ป ๐Ÿ›
          Yang
          Yang

          ๐Ÿ’ป
          YaroslavTER
          YaroslavTER

          ๐Ÿ›
          Yasar Shaikh
          Yasar Shaikh

          ๐Ÿ’ป
          Young Chan
          Young Chan

          ๐Ÿ’ป ๐Ÿ›
          YuJin Kim
          YuJin Kim

          ๐Ÿ›
          YuJin Kim
          YuJin Kim

          ๐Ÿ›
          Yuri Dolzhenko
          Yuri Dolzhenko

          ๐Ÿ›
          Yurii Dubinka
          Yurii Dubinka

          ๐Ÿ›
          Zbynek Konecny
          Zbynek Konecny

          ๐Ÿ› ๐Ÿ’ป
          Zoltan Farkas
          Zoltan Farkas

          ๐Ÿ›
          Zustin
          Zustin

          ๐Ÿ›
          aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป
          alexmodis
          alexmodis

          ๐Ÿ›
          alexmodis
          alexmodis

          ๐Ÿ›
          andreoss
          andreoss

          ๐Ÿ›
          andrey81inmd
          andrey81inmd

          ๐Ÿ’ป ๐Ÿ›
          anicoara
          anicoara

          ๐Ÿ›
          arunprasathav
          arunprasathav

          ๐Ÿ›
          asiercamara
          asiercamara

          ๐Ÿ›
          astillich-igniti
          astillich-igniti

          ๐Ÿ’ป
          avesolovksyy
          avesolovksyy

          ๐Ÿ›
          avesolovksyy
          avesolovksyy

          ๐Ÿ›
          avishvat
          avishvat

          ๐Ÿ›
          avivmu
          avivmu

          ๐Ÿ›
          axelbarfod1
          axelbarfod1

          ๐Ÿ›
          b-3-n
          b-3-n

          ๐Ÿ›
          balbhadra9
          balbhadra9

          ๐Ÿ›
          base23de
          base23de

          ๐Ÿ›
          bergander
          bergander

          ๐Ÿ› ๐Ÿ’ป
          bergander
          bergander

          ๐Ÿ› ๐Ÿ’ป
          berkam
          berkam

          ๐Ÿ’ป ๐Ÿ›
          breizh31
          breizh31

          ๐Ÿ›
          caesarkim
          caesarkim

          ๐Ÿ›
          caiocarvalhotero
          caiocarvalhotero

          ๐Ÿ›
          carolyujing
          carolyujing

          ๐Ÿ›
          cbfiddle
          cbfiddle

          ๐Ÿ›
          cesares-basilico
          cesares-basilico

          ๐Ÿ›
          cesares-basilico
          cesares-basilico

          ๐Ÿ›
          chrite
          chrite

          ๐Ÿ›
          ciufudean
          ciufudean

          ๐Ÿ“–
          cobratbq
          cobratbq

          ๐Ÿ›
          coladict
          coladict

          ๐Ÿ›
          cosmoJFH
          cosmoJFH

          ๐Ÿ›
          cristalp
          cristalp

          ๐Ÿ›
          crunsk
          crunsk

          ๐Ÿ›
          crunsk
          crunsk

          ๐Ÿ›
          csrma
          csrma

          ๐Ÿ›
          cwholmes
          cwholmes

          ๐Ÿ›
          cyberjj999
          cyberjj999

          ๐Ÿ›
          cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“–
          d1ss0nanz
          d1ss0nanz

          ๐Ÿ›
          dague1
          dague1

          ๐Ÿ“–
          dalizi007
          dalizi007

          ๐Ÿ’ป
          dalizi007
          dalizi007

          ๐Ÿ’ป
          danbrycefairsailcom
          danbrycefairsailcom

          ๐Ÿ›
          dariansanity
          dariansanity

          ๐Ÿ›
          darrenmiliband
          darrenmiliband

          ๐Ÿ›
          davidburstrom
          davidburstrom

          ๐Ÿ›
          dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ›
          deepak-patra
          deepak-patra

          ๐Ÿ›
          dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ›
          dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ›
          dinesh150
          dinesh150

          ๐Ÿ›
          diziaq
          diziaq

          ๐Ÿ›
          dreaminpast123
          dreaminpast123

          ๐Ÿ›
          duanyanan
          duanyanan

          ๐Ÿ›
          dutt-sanjay
          dutt-sanjay

          ๐Ÿ›
          duursma
          duursma

          ๐Ÿ’ป
          dylanleung
          dylanleung

          ๐Ÿ›
          dylanleung
          dylanleung

          ๐Ÿ›
          dzeigler
          dzeigler

          ๐Ÿ›
          eant60
          eant60

          ๐Ÿ›
          ekkirala
          ekkirala

          ๐Ÿ›
          emersonmoura
          emersonmoura

          ๐Ÿ›
          emouty
          emouty

          ๐Ÿ’ป ๐Ÿ›
          eugenepugach
          eugenepugach

          ๐Ÿ›
          fairy
          fairy

          ๐Ÿ›
          fairy
          fairy

          ๐Ÿ›
          filiprafalowicz
          filiprafalowicz

          ๐Ÿ’ป
          flxbl-io
          flxbl-io

          ๐Ÿ’ต
          foxmason
          foxmason

          ๐Ÿ›
          frankegabor
          frankegabor

          ๐Ÿ›
          frankl
          frankl

          ๐Ÿ›
          freafrea
          freafrea

          ๐Ÿ›
          fsapatin
          fsapatin

          ๐Ÿ›
          fsapatin
          fsapatin

          ๐Ÿ›
          gearsethenry
          gearsethenry

          ๐Ÿ›
          gracia19
          gracia19

          ๐Ÿ›
          gudzpoz
          gudzpoz

          ๐Ÿ›
          guo fei
          guo fei

          ๐Ÿ›
          gurmsc5
          gurmsc5

          ๐Ÿ›
          gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ›
          haigsn
          haigsn

          ๐Ÿ›
          haigsn
          haigsn

          ๐Ÿ›
          hemanshu070
          hemanshu070

          ๐Ÿ›
          henrik242
          henrik242

          ๐Ÿ›
          hongpuwu
          hongpuwu

          ๐Ÿ›
          hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ›
          igniti GmbH
          igniti GmbH

          ๐Ÿ›
          ilovezfs
          ilovezfs

          ๐Ÿ›
          imax-erik
          imax-erik

          ๐Ÿ›
          imax-erik
          imax-erik

          ๐Ÿ›
          itaigilo
          itaigilo

          ๐Ÿ›
          jakivey32
          jakivey32

          ๐Ÿ›
          jbennett2091
          jbennett2091

          ๐Ÿ›
          jcamerin
          jcamerin

          ๐Ÿ›
          jkeener1
          jkeener1

          ๐Ÿ›
          jmetertea
          jmetertea

          ๐Ÿ›
          johnra2
          johnra2

          ๐Ÿ’ป
          johnra2
          johnra2

          ๐Ÿ’ป
          johnzhao9
          johnzhao9

          ๐Ÿ›
          josemanuelrolon
          josemanuelrolon

          ๐Ÿ’ป ๐Ÿ›
          julees7
          julees7

          ๐Ÿ’ป ๐Ÿ›
          kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ›
          karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“–
          karwer
          karwer

          ๐Ÿ›
          kaulonline
          kaulonline

          ๐Ÿ›
          kaulonline
          kaulonline

          ๐Ÿ›
          kdaemonv
          kdaemonv

          ๐Ÿ›
          kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป
          kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ›
          kfranic
          kfranic

          ๐Ÿ›
          khalidkh
          khalidkh

          ๐Ÿ›
          koalalam
          koalalam

          ๐Ÿ›
          krzyk
          krzyk

          ๐Ÿ›
          krzyk
          krzyk

          ๐Ÿ›
          lasselindqvist
          lasselindqvist

          ๐Ÿ›
          lgemeinhardt
          lgemeinhardt

          ๐Ÿ›
          lihuaib
          lihuaib

          ๐Ÿ›
          liqingjun123
          liqingjun123

          ๐Ÿ›
          lonelyma1021
          lonelyma1021

          ๐Ÿ›
          lothas
          lothas

          ๐Ÿ›
          lpeddy
          lpeddy

          ๐Ÿ›
          lpeddy
          lpeddy

          ๐Ÿ›
          lujiefsi
          lujiefsi

          ๐Ÿ’ป
          lukelukes
          lukelukes

          ๐Ÿ’ป
          lyriccoder
          lyriccoder

          ๐Ÿ›
          marcelmore
          marcelmore

          ๐Ÿ›
          matchbox
          matchbox

          ๐Ÿ›
          matthiaskraaz
          matthiaskraaz

          ๐Ÿ›
          meandonlyme
          meandonlyme

          ๐Ÿ›
          meandonlyme
          meandonlyme

          ๐Ÿ›
          mikesive
          mikesive

          ๐Ÿ›
          milossesic
          milossesic

          ๐Ÿ›
          mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ›
          mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป
          mrclmh
          mrclmh

          ๐Ÿ›
          mriddell95
          mriddell95

          ๐Ÿ›
          mrlzh
          mrlzh

          ๐Ÿ›
          mrlzh
          mrlzh

          ๐Ÿ›
          msloan
          msloan

          ๐Ÿ›
          mucharlaravalika
          mucharlaravalika

          ๐Ÿ›
          mvenneman
          mvenneman

          ๐Ÿ›
          nareshl119
          nareshl119

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          noerremark
          noerremark

          ๐Ÿ›
          novsirion
          novsirion

          ๐Ÿ›
          novsirion
          novsirion

          ๐Ÿ›
          nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป
          oggboy
          oggboy

          ๐Ÿ›
          oinume
          oinume

          ๐Ÿ›
          orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pacvz
          pacvz

          ๐Ÿ’ป
          pallavi agarwal
          pallavi agarwal

          ๐Ÿ›
          pallavi agarwal
          pallavi agarwal

          ๐Ÿ›
          pankratz76
          pankratz76

          ๐Ÿ›
          parksungrin
          parksungrin

          ๐Ÿ›
          patpatpat123
          patpatpat123

          ๐Ÿ›
          patriksevallius
          patriksevallius

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          phoenix384
          phoenix384

          ๐Ÿ›
          piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป
          piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป
          plan3d
          plan3d

          ๐Ÿ›
          poojasix
          poojasix

          ๐Ÿ›
          prabhushrikant
          prabhushrikant

          ๐Ÿ›
          pujitha8783
          pujitha8783

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          raghujayjunk
          raghujayjunk

          ๐Ÿ›
          rajeshveera
          rajeshveera

          ๐Ÿ›
          rajeshveera
          rajeshveera

          ๐Ÿ›
          rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ›
          recdevs
          recdevs

          ๐Ÿ›
          reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ›
          rijkt
          rijkt

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ›
          rnveach
          rnveach

          ๐Ÿ›
          rnveach
          rnveach

          ๐Ÿ›
          rxmicro
          rxmicro

          ๐Ÿ›
          ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ›
          sabi0
          sabi0

          ๐Ÿ›
          samc-gearset
          samc-gearset

          ๐Ÿ“–
          scais
          scais

          ๐Ÿ›
          schosin
          schosin

          ๐Ÿ›
          screamingfrog
          screamingfrog

          ๐Ÿ’ต
          screamingfrog
          screamingfrog

          ๐Ÿ’ต
          sebbASF
          sebbASF

          ๐Ÿ›
          sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป
          shilko2013
          shilko2013

          ๐Ÿ›
          shiomiyan
          shiomiyan

          ๐Ÿ“–
          simeonKondr
          simeonKondr

          ๐Ÿ›
          snajberk
          snajberk

          ๐Ÿ›
          sniperrifle2004
          sniperrifle2004

          ๐Ÿ›
          sniperrifle2004
          sniperrifle2004

          ๐Ÿ›
          snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป
          soloturn
          soloturn

          ๐Ÿ›
          soyodream
          soyodream

          ๐Ÿ›
          sratz
          sratz

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          sturton
          sturton

          ๐Ÿ’ป ๐Ÿ›
          sudharmohan
          sudharmohan

          ๐Ÿ›
          sudharmohan
          sudharmohan

          ๐Ÿ›
          suruchidawar
          suruchidawar

          ๐Ÿ›
          svenfinitiv
          svenfinitiv

          ๐Ÿ›
          szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป
          tashiscool
          tashiscool

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          testation21
          testation21

          ๐Ÿ’ป ๐Ÿ›
          thanosa
          thanosa

          ๐Ÿ›
          thanosa
          thanosa

          ๐Ÿ›
          tiandiyixian
          tiandiyixian

          ๐Ÿ›
          tobwoerk
          tobwoerk

          ๐Ÿ›
          tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป
          trentchilders
          trentchilders

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          trishul14
          trishul14

          ๐Ÿ›
          tsui
          tsui

          ๐Ÿ›
          tsui
          tsui

          ๐Ÿ›
          wangzitom12306
          wangzitom12306

          ๐Ÿ›
          winhkey
          winhkey

          ๐Ÿ›
          witherspore
          witherspore

          ๐Ÿ›
          wjljack
          wjljack

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          xingsong
          xingsong

          ๐Ÿ›
          xioayuge
          xioayuge

          ๐Ÿ›
          xioayuge
          xioayuge

          ๐Ÿ›
          xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ›
          xuanuy
          xuanuy

          ๐Ÿ›
          xyf0921
          xyf0921

          ๐Ÿ›
          yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yasuharu-sato
          yasuharu-sato

          ๐Ÿ›
          zenglian
          zenglian

          ๐Ÿ›
          zenglian
          zenglian

          ๐Ÿ›
          zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ›
          zh3ng
          zh3ng

          ๐Ÿ›
          zt_soft
          zt_soft

          ๐Ÿ›
          ztt79
          ztt79

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ›
          ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ›
          ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ›
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ

          ๐Ÿ›
          ่Œ…ๅปถๅฎ‰
          ่Œ…ๅปถๅฎ‰

          ๐Ÿ’ป
          Andrei Paikin
          Andrei Paikin

          ๐Ÿ›
          Andrew
          Andrew

          ๐Ÿ›
          Andrew Green
          Andrew Green

          ๐Ÿ›
          AndrewStopchenko-SO
          AndrewStopchenko-SO

          ๐Ÿ›
          Andrey Bozhko
          Andrey Bozhko

          ๐Ÿ“–
          Andrey Fomin
          Andrey Fomin

          ๐Ÿ›
          Andrey Hitrin
          Andrey Hitrin

          ๐Ÿ›
          Andrey Hitrin
          Andrey Hitrin

          ๐Ÿ›
          Andrey Mochalov
          Andrey Mochalov

          ๐Ÿ’ป ๐Ÿ›
          Andro72
          Andro72

          ๐Ÿ›
          Andrwyw
          Andrwyw

          ๐Ÿ›
          Andrรฉs Catalรกn
          Andrรฉs Catalรกn

          ๐Ÿ›
          Andy Goossens
          Andy Goossens

          ๐Ÿ›
          Andy Pattenden
          Andy Pattenden

          ๐Ÿ›
          Andy Ray
          Andy Ray

          ๐Ÿ›
          Andy Ray
          Andy Ray

          ๐Ÿ›
          Andy Robinson
          Andy Robinson

          ๐Ÿ›
          Andy-2639
          Andy-2639

          ๐Ÿ›
          Ankush Somani
          Ankush Somani

          ๐Ÿ›
          Anmol Kumar
          Anmol Kumar

          ๐Ÿ›
          Anthony Whitford
          Anthony Whitford

          ๐Ÿ›
          AnthonyKot
          AnthonyKot

          ๐Ÿ›
          Anton Bobov
          Anton Bobov

          ๐Ÿ’ป
          Anton Bobov
          Anton Bobov

          ๐Ÿ’ป
          Anurag Agarwal
          Anurag Agarwal

          ๐Ÿ›
          Aravind Hegde
          Aravind Hegde

          ๐Ÿ›
          Arda Aslan
          Arda Aslan

          ๐Ÿ›
          Ari Fogel
          Ari Fogel

          ๐Ÿ›
          Arnaud Jeansen
          Arnaud Jeansen

          ๐Ÿ’ป ๐Ÿ›
          Arpit Koolwal
          Arpit Koolwal

          ๐Ÿ›
          Artem
          Artem

          ๐Ÿ’ป ๐Ÿ›
          Artem
          Artem

          ๐Ÿ’ป ๐Ÿ›
          Artem
          Artem

          ๐Ÿ›
          Artem Sheremet
          Artem Sheremet

          ๐Ÿ›
          Artur
          Artur

          ๐Ÿ›
          Artur Bosch
          Artur Bosch

          ๐Ÿ›
          Artur Dryomov
          Artur Dryomov

          ๐Ÿ›
          Artur Ossowski
          Artur Ossowski

          ๐Ÿ›
          Aryant Tripathi
          Aryant Tripathi

          ๐Ÿ’ป
          Aryant Tripathi
          Aryant Tripathi

          ๐Ÿ’ป
          AshTheMash
          AshTheMash

          ๐Ÿ›
          Ashish Rana
          Ashish Rana

          ๐Ÿ›
          Atul Kaushal
          Atul Kaushal

          ๐Ÿ›
          August Boland
          August Boland

          ๐Ÿ›
          Aurel Hudec
          Aurel Hudec

          ๐Ÿ›
          Austin
          Austin

          ๐Ÿ›
          Austin Shalit
          Austin Shalit

          ๐Ÿ›
          Austin Shalit
          Austin Shalit

          ๐Ÿ›
          Austin Tice
          Austin Tice

          ๐Ÿ›
          Ayoub Kaanich
          Ayoub Kaanich

          ๐Ÿ›
          BBG
          BBG

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
          Bailey Tjiong
          Bailey Tjiong

          ๐Ÿ’ป
          Balazs Glatz
          Balazs Glatz

          ๐Ÿ“–
          Barthรฉlemy L.
          Barthรฉlemy L.

          ๐Ÿ›
          Basavaraj K N
          Basavaraj K N

          ๐Ÿ›
          Basavaraj K N
          Basavaraj K N

          ๐Ÿ›
          Basil Peace
          Basil Peace

          ๐Ÿ›
          Belle
          Belle

          ๐Ÿ›
          Ben Lerner
          Ben Lerner

          ๐Ÿ›
          Ben Manes
          Ben Manes

          ๐Ÿ›
          Ben McCann
          Ben McCann

          ๐Ÿ›
          Bendegรบz Nagy
          Bendegรบz Nagy

          ๐Ÿ›
          Bennet S Yee
          Bennet S Yee

          ๐Ÿ›
          Bennet S Yee
          Bennet S Yee

          ๐Ÿ›
          Benoit Lacelle
          Benoit Lacelle

          ๐Ÿ›
          Bernardo Macรชdo
          Bernardo Macรชdo

          ๐Ÿ›
          Bernd Farka
          Bernd Farka

          ๐Ÿ›
          Betina Cynthia Mamani
          Betina Cynthia Mamani

          ๐Ÿ›
          Bhanu Prakash Pamidi
          Bhanu Prakash Pamidi

          ๐Ÿ’ป ๐Ÿ›
          Bhargav Thanki
          Bhargav Thanki

          ๐Ÿ›
          Binu R J
          Binu R J

          ๐Ÿ›
          Binu R J
          Binu R J

          ๐Ÿ›
          Bjรถrn Kautler
          Bjรถrn Kautler

          ๐Ÿ’ป ๐Ÿ›
          Blightbuster
          Blightbuster

          ๐Ÿ›
          Bo Zhang
          Bo Zhang

          ๐Ÿ›
          Bob "Wombat" Hogg
          Bob "Wombat" Hogg

          ๐Ÿ›
          Bobby Wertman
          Bobby Wertman

          ๐Ÿ›
          Bolarinwa Saheed Olayemi
          Bolarinwa Saheed Olayemi

          ๐Ÿ’ป ๐Ÿ›
          Boris Petrov
          Boris Petrov

          ๐Ÿ›
          Boris Petrov
          Boris Petrov

          ๐Ÿ›
          Brad Kent
          Brad Kent

          ๐Ÿ›
          Brandon Mikeska
          Brandon Mikeska

          ๐Ÿ›
          Brian Batronis
          Brian Batronis

          ๐Ÿ›
          Brian Johnson
          Brian Johnson

          ๐Ÿ›
          Brice Dutheil
          Brice Dutheil

          ๐Ÿ’ป ๐Ÿ›
          Bruno Ferreira
          Bruno Ferreira

          ๐Ÿ›
          Bruno Harbulot
          Bruno Harbulot

          ๐Ÿ›
          Bruno Harbulot
          Bruno Harbulot

          ๐Ÿ›
          Bruno Ritz
          Bruno Ritz

          ๐Ÿ›
          BurovnikovEvgeniy
          BurovnikovEvgeniy

          ๐Ÿ›
          Cameron Donaldson
          Cameron Donaldson

          ๐Ÿ›
          Carlos Macasaet
          Carlos Macasaet

          ๐Ÿ›
          Carsten Otto
          Carsten Otto

          ๐Ÿ›
          Charlie Housh
          Charlie Housh

          ๐Ÿ›
          Charlie Jonas
          Charlie Jonas

          ๐Ÿ›
          Charlie Jonas
          Charlie Jonas

          ๐Ÿ›
          Chas Honton
          Chas Honton

          ๐Ÿ› ๐Ÿ’ป
          Chen Yang
          Chen Yang

          ๐Ÿ›
          Chotu
          Chotu

          ๐Ÿ›
          Chris Smith
          Chris Smith

          ๐Ÿ›
          Chris Toomey
          Chris Toomey

          ๐Ÿ›
          Christian Hujer
          Christian Hujer

          ๐Ÿ›
          Christian Pontesegger
          Christian Pontesegger

          ๐Ÿ›
          Christian Pontesegger
          Christian Pontesegger

          ๐Ÿ›
          ChristianWulf
          ChristianWulf

          ๐Ÿ›
          Christofer Dutz
          Christofer Dutz

          ๐Ÿ’ป
          Christoffer Anselm
          Christoffer Anselm

          ๐Ÿ›
          Christophe Vidal
          Christophe Vidal

          ๐Ÿ›
          Christopher Dancy
          Christopher Dancy

          ๐Ÿ›
          Clemens Prill
          Clemens Prill

          ๐Ÿ›
          Clint Chester
          Clint Chester

          ๐Ÿ’ป ๐Ÿ›
          Clint Chester
          Clint Chester

          ๐Ÿ’ป ๐Ÿ›
          Clรฉment Fournier
          Clรฉment Fournier

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง
          Codacy Badger
          Codacy Badger

          ๐Ÿ›
          Code-Nil
          Code-Nil

          ๐Ÿ›
          ColColonCleaner
          ColColonCleaner

          ๐Ÿ›
          Colin Ingarfield
          Colin Ingarfield

          ๐Ÿ›
          Craig Andrews
          Craig Andrews

          ๐Ÿ›
          Craig Muchinsky
          Craig Muchinsky

          ๐Ÿ›
          Craig Muchinsky
          Craig Muchinsky

          ๐Ÿ›
          Cybozu
          Cybozu

          ๐Ÿ’ต
          Cyril
          Cyril

          ๐Ÿ’ป ๐Ÿ›
          Dale
          Dale

          ๐Ÿ’ป
          Damien Jiang
          Damien Jiang

          ๐Ÿ›
          Dan Berindei
          Dan Berindei

          ๐Ÿ›
          Dan Rollo
          Dan Rollo

          ๐Ÿ›
          Dan Ziemba
          Dan Ziemba

          ๐Ÿ›
          Dan Ziemba
          Dan Ziemba

          ๐Ÿ›
          Daniel Gredler
          Daniel Gredler

          ๐Ÿ’ป ๐Ÿ›
          Daniel Jipa
          Daniel Jipa

          ๐Ÿ›
          Daniel Paul Searles
          Daniel Paul Searles

          ๐Ÿ’ป
          Daniel Reigada
          Daniel Reigada

          ๐Ÿ›
          Daniel Ventura
          Daniel Ventura

          ๐Ÿ›
          Danilo Pianini
          Danilo Pianini

          ๐Ÿ›
          Darko
          Darko

          ๐Ÿ›
          Darko
          Darko

          ๐Ÿ›
          David
          David

          ๐Ÿ›
          David Atkinson
          David Atkinson

          ๐Ÿ›
          David Burstrรถm
          David Burstrรถm

          ๐Ÿ’ป ๐Ÿ›
          David Goatรฉ
          David Goatรฉ

          ๐Ÿ›
          David Golpira
          David Golpira

          ๐Ÿ›
          David Kovaล™รญk
          David Kovaล™รญk

          ๐Ÿ›
          David M. Karr (fullname at gmail.com)
          David M. Karr (fullname at gmail.com)

          ๐Ÿ›
          David M. Karr (fullname at gmail.com)
          David M. Karr (fullname at gmail.com)

          ๐Ÿ›
          David Renz
          David Renz

          ๐Ÿ’ป ๐Ÿ›
          David Renz
          David Renz

          ๐Ÿ›
          David Schach
          David Schach

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–
          Dawid Ciok
          Dawid Ciok

          ๐Ÿ› ๐Ÿ’ป
          Debamoy Datta
          Debamoy Datta

          ๐Ÿ’ป
          Deleted user
          Deleted user

          ๐Ÿ›
          Dell Green
          Dell Green

          ๐Ÿ›
          Dell Green
          Dell Green

          ๐Ÿ›
          Dem Pilafian
          Dem Pilafian

          ๐Ÿ›
          Den
          Den

          ๐Ÿ›
          Denis Borovikov
          Denis Borovikov

          ๐Ÿ’ป ๐Ÿ›
          Dennie Reniers
          Dennie Reniers

          ๐Ÿ’ป ๐Ÿ›
          Dennis Kieselhorst
          Dennis Kieselhorst

          ๐Ÿ›
          Derek P. Moore
          Derek P. Moore

          ๐Ÿ›
          Dichotomia
          Dichotomia

          ๐Ÿ›
          Dichotomia
          Dichotomia

          ๐Ÿ›
          Dionisio Cortรฉs Fernรกndez
          Dionisio Cortรฉs Fernรกndez

          ๐Ÿ’ป ๐Ÿ›
          Dmitri Bourlatchkov
          Dmitri Bourlatchkov

          ๐Ÿ›
          Dmitriy Kuzmin
          Dmitriy Kuzmin

          ๐Ÿ›
          Dmytro Dashenkov
          Dmytro Dashenkov

          ๐Ÿ›
          Douglas Griffith
          Douglas Griffith

          ๐Ÿ“–
          Dr. Christian Kohlschรผtter
          Dr. Christian Kohlschรผtter

          ๐Ÿ›
          Drew Hall
          Drew Hall

          ๐Ÿ›
          Drew Hall
          Drew Hall

          ๐Ÿ›
          Dumitru Postoronca
          Dumitru Postoronca

          ๐Ÿ›
          Dylan Adams
          Dylan Adams

          ๐Ÿ›
          Eden Hao
          Eden Hao

          ๐Ÿ›
          Edward Klimoshenko
          Edward Klimoshenko

          ๐Ÿ› ๐Ÿ’ป
          Egor Bredikhin
          Egor Bredikhin

          ๐Ÿ›
          Elan P. Kugelmass
          Elan P. Kugelmass

          ๐Ÿ›
          Elder S.
          Elder S.

          ๐Ÿ›
          Elder S.
          Elder S.

          ๐Ÿ›
          Eldrick Wega
          Eldrick Wega

          ๐Ÿ“–
          Elliotte Rusty Harold
          Elliotte Rusty Harold

          ๐Ÿ’ป
          Emile
          Emile

          ๐Ÿ›
          Eric
          Eric

          ๐Ÿ›
          Eric Kintzer
          Eric Kintzer

          ๐Ÿ›
          Eric Perret
          Eric Perret

          ๐Ÿ›
          Eric Squires
          Eric Squires

          ๐Ÿ›
          Eric Squires
          Eric Squires

          ๐Ÿ›
          Erich L Foster
          Erich L Foster

          ๐Ÿ›
          Erik Bleske
          Erik Bleske

          ๐Ÿ›
          Erik C. Thauvin
          Erik C. Thauvin

          ๐Ÿ“– ๐Ÿ›
          Ernst Reissner
          Ernst Reissner

          ๐Ÿ›
          Ethan Sargent
          Ethan Sargent

          ๐Ÿ›
          Ewan Tempero
          Ewan Tempero

          ๐Ÿ›
          F.W. Dekker
          F.W. Dekker

          ๐Ÿ›
          F.W. Dekker
          F.W. Dekker

          ๐Ÿ›
          FSchliephacke
          FSchliephacke

          ๐Ÿ›
          Facundo
          Facundo

          ๐Ÿ›
          Federico Giust
          Federico Giust

          ๐Ÿ›
          Fedor Sherstobitov
          Fedor Sherstobitov

          ๐Ÿ›
          Felix Lampe
          Felix Lampe

          ๐Ÿ›
          Filip Golonka
          Filip Golonka

          ๐Ÿ›
          Filipe Esperandio
          Filipe Esperandio

          ๐Ÿ’ป ๐Ÿ›
          Filipe Esperandio
          Filipe Esperandio

          ๐Ÿ’ป ๐Ÿ›
          Filippo Barbari
          Filippo Barbari

          ๐Ÿ›
          Filippo Nova
          Filippo Nova

          ๐Ÿ›
          Francesco la Torre
          Francesco la Torre

          ๐Ÿ›
          Francisco Duarte
          Francisco Duarte

          ๐Ÿ›
          Frederick Zhang
          Frederick Zhang

          ๐Ÿ›
          Frieder Bluemle
          Frieder Bluemle

          ๐Ÿ›
          Frits Jalvingh
          Frits Jalvingh

          ๐Ÿ’ป ๐Ÿ›
          Frits Jalvingh
          Frits Jalvingh

          ๐Ÿ’ป ๐Ÿ›
          G. Bazior
          G. Bazior

          ๐Ÿ›
          Gabe Henkes
          Gabe Henkes

          ๐Ÿ›
          Gary Gregory
          Gary Gregory

          ๐Ÿ›
          Genoud Magloire
          Genoud Magloire

          ๐Ÿ›
          Geoffrey555
          Geoffrey555

          ๐Ÿ›
          Georg Romstorfer
          Georg Romstorfer

          ๐Ÿ›
          Gili Tzabari
          Gili Tzabari

          ๐Ÿ› ๐Ÿ’ป
          Gili Tzabari
          Gili Tzabari

          ๐Ÿ› ๐Ÿ’ป
          Gio
          Gio

          ๐Ÿ›
          Gol
          Gol

          ๐Ÿ›
          Gold856
          Gold856

          ๐Ÿ› ๐Ÿ’ป
          Gonzalo Exequiel Ibars Ingman
          Gonzalo Exequiel Ibars Ingman

          ๐Ÿ’ป ๐Ÿ›
          GooDer
          GooDer

          ๐Ÿ›
          Gregor Riegler
          Gregor Riegler

          ๐Ÿ›
          Grzegorz Olszewski
          Grzegorz Olszewski

          ๐Ÿ›
          Grzegorz Olszewski
          Grzegorz Olszewski

          ๐Ÿ›
          Gunther Schrijvers
          Gunther Schrijvers

          ๐Ÿ’ป ๐Ÿ›
          Gustavo Krieger
          Gustavo Krieger

          ๐Ÿ›
          Guy Elsmore-Paddock
          Guy Elsmore-Paddock

          ๐Ÿ›
          Gรถrkem Mรผlayim
          Gรถrkem Mรผlayim

          ๐Ÿ›
          Hanzel Godinez
          Hanzel Godinez

          ๐Ÿ›
          Haoliang Chen
          Haoliang Chen

          ๐Ÿ›
          Harsh Kukreja
          Harsh Kukreja

          ๐Ÿ›
          Harsh Kukreja
          Harsh Kukreja

          ๐Ÿ›
          Hassan ALAMI
          Hassan ALAMI

          ๐Ÿ›
          Heber
          Heber

          ๐Ÿ›
          Hector Miuler Malpica Gallegos
          Hector Miuler Malpica Gallegos

          ๐Ÿ›
          Henning Schmiedehausen
          Henning Schmiedehausen

          ๐Ÿ’ป ๐Ÿ›
          Henning von Bargen
          Henning von Bargen

          ๐Ÿ’ป
          Hervรฉ Boutemy
          Hervรฉ Boutemy

          ๐Ÿ›
          Himanshu Pandey
          Himanshu Pandey

          ๐Ÿ›
          Himanshu Pandey
          Himanshu Pandey

          ๐Ÿ›
          Hokwang Lee
          Hokwang Lee

          ๐Ÿ›
          Hooperbloob
          Hooperbloob

          ๐Ÿ’ป
          Hung PHAN
          Hung PHAN

          ๐Ÿ›
          IDoCodingStuffs
          IDoCodingStuffs

          ๐Ÿ’ป ๐Ÿ›
          Iccen Gan
          Iccen Gan

          ๐Ÿ›
          Ignacio Mariano Tirabasso
          Ignacio Mariano Tirabasso

          ๐Ÿ›
          Igor Melnichenko
          Igor Melnichenko

          ๐Ÿ›
          Igor Melnichenko
          Igor Melnichenko

          ๐Ÿ›
          Igor Moreno
          Igor Moreno

          ๐Ÿ›
          Intelesis-MS
          Intelesis-MS

          ๐Ÿ›
          Iroha_
          Iroha_

          ๐Ÿ›
          Ishan Srivastava
          Ishan Srivastava

          ๐Ÿ›
          Iskren Stanislavov
          Iskren Stanislavov

          ๐Ÿ›
          Ivan Vakhrushev
          Ivan Vakhrushev

          ๐Ÿ›
          Ivano Guerini
          Ivano Guerini

          ๐Ÿ›
          Ivano Guerini
          Ivano Guerini

          ๐Ÿ›
          Ivar Andreas Bonsaksen
          Ivar Andreas Bonsaksen

          ๐Ÿ›
          Ivo ล mรญd
          Ivo ล mรญd

          ๐Ÿ›
          JJengility
          JJengility

          ๐Ÿ›
          Jake Hemmerle
          Jake Hemmerle

          ๐Ÿ›
          Jakub Dupak
          Jakub Dupak

          ๐Ÿ’ป
          James Harrison
          James Harrison

          ๐Ÿ› ๐Ÿ’ป
          Jamie Bisotti
          Jamie Bisotti

          ๐Ÿ›
          Jamie Bisotti
          Jamie Bisotti

          ๐Ÿ›
          Jan
          Jan

          ๐Ÿ›
          Jan Aertgeerts
          Jan Aertgeerts

          ๐Ÿ’ป ๐Ÿ›
          Jan Brรผmmer
          Jan Brรผmmer

          ๐Ÿ›
          Jan Tล™รญska
          Jan Tล™รญska

          ๐Ÿ›
          Jan-Lukas Else
          Jan-Lukas Else

          ๐Ÿ›
          Jason Qiu
          Jason Qiu

          ๐Ÿ’ป ๐Ÿ“–
          Jason Williams
          Jason Williams

          ๐Ÿ›
          Jason Williams
          Jason Williams

          ๐Ÿ›
          Javier Spagnoletti
          Javier Spagnoletti

          ๐Ÿ›
          Jean-Paul Mayer
          Jean-Paul Mayer

          ๐Ÿ›
          Jean-Simon Larochelle
          Jean-Simon Larochelle

          ๐Ÿ›
          Jeff Bartolotta
          Jeff Bartolotta

          ๐Ÿ’ป ๐Ÿ›
          Jeff Hube
          Jeff Hube

          ๐Ÿ’ป ๐Ÿ›
          Jeff Jensen
          Jeff Jensen

          ๐Ÿ›
          Jeff May
          Jeff May

          ๐Ÿ›
          Jeff May
          Jeff May

          ๐Ÿ›
          Jens Gerdes
          Jens Gerdes

          ๐Ÿ›
          Jeroen Borgers
          Jeroen Borgers

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข
          Jeroen Meijer
          Jeroen Meijer

          ๐Ÿ›
          Jeroen van Wilgenburg
          Jeroen van Wilgenburg

          ๐Ÿ“–
          Jerome Russ
          Jerome Russ

          ๐Ÿ›
          JerritEic
          JerritEic

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
          Jiri Pejchal
          Jiri Pejchal

          ๐Ÿ›
          Jiri Pejchal
          Jiri Pejchal

          ๐Ÿ›
          Jithin Sunny
          Jithin Sunny

          ๐Ÿ›
          Jiล™รญ ล korpil
          Jiล™รญ ล korpil

          ๐Ÿ›
          Joao Machado
          Joao Machado

          ๐Ÿ›
          Jochen Krauss
          Jochen Krauss

          ๐Ÿ›
          Johan Hammar
          Johan Hammar

          ๐Ÿ›
          John Jetmore
          John Jetmore

          ๐Ÿ“–
          John Karp
          John Karp

          ๐Ÿ›
          John Karp
          John Karp

          ๐Ÿ›
          John Zhang
          John Zhang

          ๐Ÿ›
          John-Teng
          John-Teng

          ๐Ÿ’ป ๐Ÿ›
          Jon Moroney
          Jon Moroney

          ๐Ÿ’ป ๐Ÿ›
          Jonas Geiregat
          Jonas Geiregat

          ๐Ÿ›
          Jonas KeรŸler
          Jonas KeรŸler

          ๐Ÿ›
          Jonathan Gillespie
          Jonathan Gillespie

          ๐Ÿ’ต
          Jonathan Wiesel
          Jonathan Wiesel

          ๐Ÿ’ป ๐Ÿ›
          Jonathan Wiesel
          Jonathan Wiesel

          ๐Ÿ’ป ๐Ÿ›
          Jordan
          Jordan

          ๐Ÿ›
          Jordi Llach
          Jordi Llach

          ๐Ÿ›
          Jorge Solรณrzano
          Jorge Solรณrzano

          ๐Ÿ›
          JorneVL
          JorneVL

          ๐Ÿ›
          Jose Palafox
          Jose Palafox

          ๐Ÿ›
          Jose Stovall
          Jose Stovall

          ๐Ÿ›
          Joseph
          Joseph

          ๐Ÿ’ป
          Joseph
          Joseph

          ๐Ÿ’ป
          Joseph Heenan
          Joseph Heenan

          ๐Ÿ›
          Josh Feingold
          Josh Feingold

          ๐Ÿ’ป ๐Ÿ›
          Josh Holthaus
          Josh Holthaus

          ๐Ÿ›
          Joshua S Arquilevich
          Joshua S Arquilevich

          ๐Ÿ›
          Joรฃo Dinis Ferreira
          Joรฃo Dinis Ferreira

          ๐Ÿ“–
          Joรฃo Ferreira
          Joรฃo Ferreira

          ๐Ÿ’ป ๐Ÿ›
          Joรฃo Pedro Schmitt
          Joรฃo Pedro Schmitt

          ๐Ÿ›
          Joรฃo Pedro Schmitt
          Joรฃo Pedro Schmitt

          ๐Ÿ›
          Juan Martรญn Sotuyo Dodero
          Juan Martรญn Sotuyo Dodero

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง
          Juan Pablo Civile
          Juan Pablo Civile

          ๐Ÿ›
          Jude Pereira
          Jude Pereira

          ๐Ÿ’ป
          Julian Voronetsky
          Julian Voronetsky

          ๐Ÿ›
          Julien
          Julien

          ๐Ÿ›
          Julius
          Julius

          ๐Ÿ›
          JustPRV
          JustPRV

          ๐Ÿ›
          JustPRV
          JustPRV

          ๐Ÿ›
          Justin Stroud
          Justin Stroud

          ๐Ÿ’ป
          Jรถrn Huxhorn
          Jรถrn Huxhorn

          ๐Ÿ›
          KThompso
          KThompso

          ๐Ÿ›
          Kai Amundsen
          Kai Amundsen

          ๐Ÿ›
          Karel Vervaeke
          Karel Vervaeke

          ๐Ÿ›
          Karl-Andero Mere
          Karl-Andero Mere

          ๐Ÿ›
          Karl-Philipp Richter
          Karl-Philipp Richter

          ๐Ÿ›
          Karl-Philipp Richter
          Karl-Philipp Richter

          ๐Ÿ›
          Karsten Silz
          Karsten Silz

          ๐Ÿ›
          Kazuma Watanabe
          Kazuma Watanabe

          ๐Ÿ›
          Kernevez
          Kernevez

          ๐Ÿ›
          Kev
          Kev

          ๐Ÿ›
          Keve Mรผller
          Keve Mรผller

          ๐Ÿ›
          Kevin Guerra
          Kevin Guerra

          ๐Ÿ’ป
          Kevin Jones
          Kevin Jones

          ๐Ÿ› ๐Ÿ’ป
          Kevin Jones
          Kevin Jones

          ๐Ÿ› ๐Ÿ’ป
          Kevin Poorman
          Kevin Poorman

          ๐Ÿ›
          Kevin Wayne
          Kevin Wayne

          ๐Ÿ›
          Kieran Black
          Kieran Black

          ๐Ÿ›
          Kirill Zubov
          Kirill Zubov

          ๐Ÿ›
          Kirk Clemens
          Kirk Clemens

          ๐Ÿ’ป ๐Ÿ›
          Klaus Hartl
          Klaus Hartl

          ๐Ÿ›
          Koen Van Looveren
          Koen Van Looveren

          ๐Ÿ›
          Koen Van Looveren
          Koen Van Looveren

          ๐Ÿ›
          Kris Scheibe
          Kris Scheibe

          ๐Ÿ’ป ๐Ÿ›
          Krystian Dabrowski
          Krystian Dabrowski

          ๐Ÿ› ๐Ÿ’ป
          Krzysztof Dymek
          Krzysztof Dymek

          ๐Ÿ›
          Kunal Thanki
          Kunal Thanki

          ๐Ÿ›
          Kursat Aktas
          Kursat Aktas

          ๐Ÿ“–
          LaLucid
          LaLucid

          ๐Ÿ’ป
          Larry Diamond
          Larry Diamond

          ๐Ÿ’ป ๐Ÿ›
          Larry Diamond
          Larry Diamond

          ๐Ÿ’ป ๐Ÿ›
          Lars Knickrehm
          Lars Knickrehm

          ๐Ÿ›
          Laurent Bovet
          Laurent Bovet

          ๐Ÿ› ๐Ÿ’ป
          Leo Gutierrez
          Leo Gutierrez

          ๐Ÿ›
          LiGaOg
          LiGaOg

          ๐Ÿ’ป
          Liam Sharp
          Liam Sharp

          ๐Ÿ›
          Lintsi
          Lintsi

          ๐Ÿ›
          Linus Fernandes
          Linus Fernandes

          ๐Ÿ›
          Linus Fernandes
          Linus Fernandes

          ๐Ÿ›
          Lixon Lookose
          Lixon Lookose

          ๐Ÿ›
          Logesh
          Logesh

          ๐Ÿ›
          Lorenzo Gabriele
          Lorenzo Gabriele

          ๐Ÿ›
          Loรฏc Ledoyen
          Loรฏc Ledoyen

          ๐Ÿ›
          Lucas
          Lucas

          ๐Ÿ›
          Lucas Silva
          Lucas Silva

          ๐Ÿ›
          Lucas Soncini
          Lucas Soncini

          ๐Ÿ’ป ๐Ÿ›
          Lucas Soncini
          Lucas Soncini

          ๐Ÿ’ป ๐Ÿ›
          Luis Alcantar
          Luis Alcantar

          ๐Ÿ’ป
          Lukas Grรคf
          Lukas Grรคf

          ๐Ÿ’ป
          Lukasz Slonina
          Lukasz Slonina

          ๐Ÿ›
          Lukebray
          Lukebray

          ๐Ÿ›
          Lynn
          Lynn

          ๐Ÿ’ป ๐Ÿ›
          Lyor Goldstein
          Lyor Goldstein

          ๐Ÿ›
          MCMicS
          MCMicS

          ๐Ÿ›
          MCMicS
          MCMicS

          ๐Ÿ›
          Macarse
          Macarse

          ๐Ÿ›
          Machine account for PMD
          Machine account for PMD

          ๐Ÿ’ป
          Maciek Siemczyk
          Maciek Siemczyk

          ๐Ÿ›
          Maikel Steneker
          Maikel Steneker

          ๐Ÿ’ป ๐Ÿ›
          Maksim Moiseikin
          Maksim Moiseikin

          ๐Ÿ›
          Malik
          Malik

          ๐Ÿ›
          Manfred Koch
          Manfred Koch

          ๐Ÿ›
          Manfred Koch
          Manfred Koch

          ๐Ÿ›
          Manuel Moya Ferrer
          Manuel Moya Ferrer

          ๐Ÿ’ป ๐Ÿ›
          Manuel Romeiro
          Manuel Romeiro

          ๐Ÿ›
          Manuel Ryan
          Manuel Ryan

          ๐Ÿ›
          Marat Vyshegorodtsev
          Marat Vyshegorodtsev

          ๐Ÿ›
          Marcel Hรคrle
          Marcel Hรคrle

          ๐Ÿ›
          Marcello Fialho
          Marcello Fialho

          ๐Ÿ›
          Marcin Dฤ…browski
          Marcin Dฤ…browski

          ๐Ÿ’ป ๐Ÿ›
          Marcin Dฤ…browski
          Marcin Dฤ…browski

          ๐Ÿ’ป ๐Ÿ›
          Marcin Rataj
          Marcin Rataj

          ๐Ÿ›
          Marcono1234
          Marcono1234

          ๐Ÿ›
          Mark Adamcin
          Mark Adamcin

          ๐Ÿ›
          Mark Hall
          Mark Hall

          ๐Ÿ’ป ๐Ÿ›
          Mark Kolich
          Mark Kolich

          ๐Ÿ›
          Mark Pritchard
          Mark Pritchard

          ๐Ÿ›
          Markus Rathgeb
          Markus Rathgeb

          ๐Ÿ›
          Markus Rathgeb
          Markus Rathgeb

          ๐Ÿ›
          Marquis Wang
          Marquis Wang

          ๐Ÿ›
          MartGit
          MartGit

          ๐Ÿ›
          Martin Feldsztejn
          Martin Feldsztejn

          ๐Ÿ›
          Martin Lehmann
          Martin Lehmann

          ๐Ÿ›
          Martin Spamer
          Martin Spamer

          ๐Ÿ›
          Martin Tarjรกnyi
          Martin Tarjรกnyi

          ๐Ÿ›
          MatFl
          MatFl

          ๐Ÿ›
          MatFl
          MatFl

          ๐Ÿ›
          Mateusz Stefanski
          Mateusz Stefanski

          ๐Ÿ›
          Mathias Lagerwall
          Mathias Lagerwall

          ๐Ÿ›
          Mathieu Gouin
          Mathieu Gouin

          ๐Ÿ›
          MatiasComercio
          MatiasComercio

          ๐Ÿ’ป ๐Ÿ›
          Matt Benson
          Matt Benson

          ๐Ÿ›
          Matt De Poorter
          Matt De Poorter

          ๐Ÿ›
          Matt Hargett
          Matt Hargett

          ๐Ÿ’ป ๐Ÿ’ต
          Matt Hargett
          Matt Hargett

          ๐Ÿ’ป ๐Ÿ’ต
          Matt Harrah
          Matt Harrah

          ๐Ÿ›
          Matt Nelson
          Matt Nelson

          ๐Ÿ›
          Matthew Amos
          Matthew Amos

          ๐Ÿ›
          Matthew Duggan
          Matthew Duggan

          ๐Ÿ›
          Matthew Hall
          Matthew Hall

          ๐Ÿ›
          Matthew Rossner
          Matthew Rossner

          ๐Ÿ›
          Matรญas Fraga
          Matรญas Fraga

          ๐Ÿ’ป ๐Ÿ›
          Matรญas Fraga
          Matรญas Fraga

          ๐Ÿ’ป ๐Ÿ›
          Maxime Robert
          Maxime Robert

          ๐Ÿ’ป ๐Ÿ›
          MetaBF
          MetaBF

          ๐Ÿ›
          Metin Dagcilar
          Metin Dagcilar

          ๐Ÿ›
          Michael
          Michael

          ๐Ÿ›
          Michael Bell
          Michael Bell

          ๐Ÿ›
          Michael Bernstein
          Michael Bernstein

          ๐Ÿ›
          Michael Clay
          Michael Clay

          ๐Ÿ›
          Michael Clay
          Michael Clay

          ๐Ÿ›
          Michael Dombrowski
          Michael Dombrowski

          ๐Ÿ›
          Michael Hausegger
          Michael Hausegger

          ๐Ÿ›
          Michael Hoefer
          Michael Hoefer

          ๐Ÿ›
          Michael Kolesnikov
          Michael Kolesnikov

          ๐Ÿ›
          Michael Mรถbius
          Michael Mรถbius

          ๐Ÿ›
          Michael N. Lipp
          Michael N. Lipp

          ๐Ÿ›
          Michael Pellegrini
          Michael Pellegrini

          ๐Ÿ›
          Michael Pellegrini
          Michael Pellegrini

          ๐Ÿ›
          Michal Kordas
          Michal Kordas

          ๐Ÿ›
          Michaล‚ Borek
          Michaล‚ Borek

          ๐Ÿ›
          Michaล‚ Kuliล„ski
          Michaล‚ Kuliล„ski

          ๐Ÿ›
          Miguel Nรบรฑez Dรญaz-Montes
          Miguel Nรบรฑez Dรญaz-Montes

          ๐Ÿ›
          Mihai Ionut
          Mihai Ionut

          ๐Ÿ›
          Mikhail Kuchma
          Mikhail Kuchma

          ๐Ÿ›
          MiladSadinam
          MiladSadinam

          ๐Ÿ›
          MiladSadinam
          MiladSadinam

          ๐Ÿ›
          Mirek Hankus
          Mirek Hankus

          ๐Ÿ›
          Mitch Spano
          Mitch Spano

          ๐Ÿ’ป ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ›
          MrAngry52
          MrAngry52

          ๐Ÿ›
          Muminur Choudhury
          Muminur Choudhury

          ๐Ÿ›
          Mykhailo Palahuta
          Mykhailo Palahuta

          ๐Ÿ’ป ๐Ÿ›
          Mykhailo Palahuta
          Mykhailo Palahuta

          ๐Ÿ’ป ๐Ÿ›
          Nagendra Kumar Singh
          Nagendra Kumar Singh

          ๐Ÿ›
          Nahuel Barrios
          Nahuel Barrios

          ๐Ÿ›
          Nakul Sharma
          Nakul Sharma

          ๐Ÿ›
          Nathan Braun
          Nathan Braun

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ›
          Nathanaรซl
          Nathanaรซl

          ๐Ÿ›
          Nathanaรซl
          Nathanaรซl

          ๐Ÿ›
          Naveen
          Naveen

          ๐Ÿ’ป
          Nazdravi
          Nazdravi

          ๐Ÿ›
          Neha-Dhonde
          Neha-Dhonde

          ๐Ÿ›
          Nicholas Doyle
          Nicholas Doyle

          ๐Ÿ›
          Nick Butcher
          Nick Butcher

          ๐Ÿ›
          Nico Gallinal
          Nico Gallinal

          ๐Ÿ›
          Nicola Dal Maso
          Nicola Dal Maso

          ๐Ÿ›
          Nicola Dal Maso
          Nicola Dal Maso

          ๐Ÿ›
          Nicolas Filotto
          Nicolas Filotto

          ๐Ÿ’ป
          Nicolas Vervelle
          Nicolas Vervelle

          ๐Ÿ›
          Nicolas Vuillamy
          Nicolas Vuillamy

          ๐Ÿ“–
          Nikita Chursin
          Nikita Chursin

          ๐Ÿ›
          Niklas Baudy
          Niklas Baudy

          ๐Ÿ›
          Nikolas Havrikov
          Nikolas Havrikov

          ๐Ÿ›
          Nilesh Virkar
          Nilesh Virkar

          ๐Ÿ›
          Nilesh Virkar
          Nilesh Virkar

          ๐Ÿ›
          Nimit Patel
          Nimit Patel

          ๐Ÿ›
          Niranjan Harpale
          Niranjan Harpale

          ๐Ÿ›
          Nirvik Patel
          Nirvik Patel

          ๐Ÿ’ป
          Noah Sussman
          Noah Sussman

          ๐Ÿ›
          Noah0120
          Noah0120

          ๐Ÿ›
          Noam Tamim
          Noam Tamim

          ๐Ÿ›
          Noel Grandin
          Noel Grandin

          ๐Ÿ›
          Noel Grandin
          Noel Grandin

          ๐Ÿ›
          Olaf Haalstra
          Olaf Haalstra

          ๐Ÿ›
          Oleg Andreych
          Oleg Andreych

          ๐Ÿ’ป ๐Ÿ›
          Oleg Pavlenko
          Oleg Pavlenko

          ๐Ÿ›
          Oleksii Dykov
          Oleksii Dykov

          ๐Ÿ’ป ๐Ÿ›
          Oliver Eikemeier
          Oliver Eikemeier

          ๐Ÿ›
          Oliver Siegmar
          Oliver Siegmar

          ๐Ÿ’ต
          Olivier Parent
          Olivier Parent

          ๐Ÿ’ป ๐Ÿ›
          Olivier Parent
          Olivier Parent

          ๐Ÿ’ป ๐Ÿ›
          Ollie Abbey
          Ollie Abbey

          ๐Ÿ’ป ๐Ÿ›
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)

          ๐Ÿ›
          Ondrej Kratochvil
          Ondrej Kratochvil

          ๐Ÿ›
          OverDrone
          OverDrone

          ๐Ÿ›
          Ozan Gulle
          Ozan Gulle

          ๐Ÿ’ป ๐Ÿ›
          PUNEET JAIN
          PUNEET JAIN

          ๐Ÿ›
          Pankraz76
          Pankraz76

          ๐Ÿ’ป ๐Ÿ›
          Pankraz76
          Pankraz76

          ๐Ÿ’ป ๐Ÿ›
          Parbati Bose
          Parbati Bose

          ๐Ÿ›
          Paul Berg
          Paul Berg

          ๐Ÿ›
          Paul Guyot
          Paul Guyot

          ๐Ÿ’ป
          Pavel Bludov
          Pavel Bludov

          ๐Ÿ›
          Pavel Miฤka
          Pavel Miฤka

          ๐Ÿ›
          Pedro Nuno Santos
          Pedro Nuno Santos

          ๐Ÿ›
          Pedro Rijo
          Pedro Rijo

          ๐Ÿ›
          Pedro Rijo
          Pedro Rijo

          ๐Ÿ›
          Pelisse Romain
          Pelisse Romain

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ›
          Per Abich
          Per Abich

          ๐Ÿ’ป
          Pete Davids
          Pete Davids

          ๐Ÿ›
          Peter Bruin
          Peter Bruin

          ๐Ÿ›
          Peter Chittum
          Peter Chittum

          ๐Ÿ’ป ๐Ÿ›
          Peter Cudmore
          Peter Cudmore

          ๐Ÿ›
          Peter Kasson
          Peter Kasson

          ๐Ÿ›
          Peter Kasson
          Peter Kasson

          ๐Ÿ›
          Peter Kofler
          Peter Kofler

          ๐Ÿ›
          Peter Paul Bakker
          Peter Paul Bakker

          ๐Ÿ’ป ๐Ÿ›
          Peter Rader
          Peter Rader

          ๐Ÿ›
          Pham Hai Trung
          Pham Hai Trung

          ๐Ÿ›
          Philip Graf
          Philip Graf

          ๐Ÿ’ป ๐Ÿ›
          Philip Hachey
          Philip Hachey

          ๐Ÿ›
          Philippe Ozil
          Philippe Ozil

          ๐Ÿ›
          Philippe Ozil
          Philippe Ozil

          ๐Ÿ›
          Phinehas Artemix
          Phinehas Artemix

          ๐Ÿ›
          Phokham Nonava
          Phokham Nonava

          ๐Ÿ›
          Pim van der Loos
          Pim van der Loos

          ๐Ÿ’ป โš ๏ธ
          Piotr Szymaล„ski
          Piotr Szymaล„ski

          ๐Ÿ›
          Piotrek ลปygieล‚o
          Piotrek ลปygieล‚o

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“–
          Pranay Jaiswal
          Pranay Jaiswal

          ๐Ÿ›
          Prasad Kamath
          Prasad Kamath

          ๐Ÿ›
          Prasad Kamath
          Prasad Kamath

          ๐Ÿ›
          Prasanna
          Prasanna

          ๐Ÿ›
          Presh-AR
          Presh-AR

          ๐Ÿ›
          Puneet1726
          Puneet1726

          ๐Ÿ›
          RBRi
          RBRi

          ๐Ÿ›
          Rafael Cortรชs
          Rafael Cortรชs

          ๐Ÿ›
          RaheemShaik999
          RaheemShaik999

          ๐Ÿ›
          RajeshR
          RajeshR

          ๐Ÿ’ป ๐Ÿ›
          RajeshR
          RajeshR

          ๐Ÿ’ป ๐Ÿ›
          Ramachandra Mohan
          Ramachandra Mohan

          ๐Ÿ›
          Ramel0921
          Ramel0921

          ๐Ÿ›
          Raquel Pau
          Raquel Pau

          ๐Ÿ›
          Ravikiran Janardhana
          Ravikiran Janardhana

          ๐Ÿ›
          Reda Benhemmouche
          Reda Benhemmouche

          ๐Ÿ›
          Reinhard Schiedermeier
          Reinhard Schiedermeier

          ๐Ÿ›
          Renato Oliveira
          Renato Oliveira

          ๐Ÿ’ป ๐Ÿ›
          Renato Oliveira
          Renato Oliveira

          ๐Ÿ’ป ๐Ÿ›
          Rich DiCroce
          Rich DiCroce

          ๐Ÿ›
          Richard Corfield
          Richard Corfield

          ๐Ÿ’ป
          Richard Corfield
          Richard Corfield

          ๐Ÿ› ๐Ÿ’ป
          Riot R1cket
          Riot R1cket

          ๐Ÿ›
          Rishabh Jain
          Rishabh Jain

          ๐Ÿ›
          RishabhDeep Singh
          RishabhDeep Singh

          ๐Ÿ›
          Rob Baillie
          Rob Baillie

          ๐Ÿ›
          Rob Baillie
          Rob Baillie

          ๐Ÿ›
          Robbie Martinus
          Robbie Martinus

          ๐Ÿ’ป ๐Ÿ›
          Robert Henry
          Robert Henry

          ๐Ÿ›
          Robert Mihaly
          Robert Mihaly

          ๐Ÿ›
          Robert Painsi
          Robert Painsi

          ๐Ÿ›
          Robert Russell
          Robert Russell

          ๐Ÿ›
          Robert Sรถsemann
          Robert Sรถsemann

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ›
          Robert Whitebit
          Robert Whitebit

          ๐Ÿ›
          Robert Whitebit
          Robert Whitebit

          ๐Ÿ›
          Robin Richtsfeld
          Robin Richtsfeld

          ๐Ÿ›
          Robin Stocker
          Robin Stocker

          ๐Ÿ’ป ๐Ÿ›
          Robin Wils
          Robin Wils

          ๐Ÿ›
          RochusOest
          RochusOest

          ๐Ÿ›
          Rodolfo Noviski
          Rodolfo Noviski

          ๐Ÿ›
          Rodrigo Casara
          Rodrigo Casara

          ๐Ÿ›
          Rodrigo Fernandes
          Rodrigo Fernandes

          ๐Ÿ›
          Rodrigo Fernandes
          Rodrigo Fernandes

          ๐Ÿ›
          Roman Salvador
          Roman Salvador

          ๐Ÿ’ป ๐Ÿ›
          Ronald Blaschke
          Ronald Blaschke

          ๐Ÿ›
          Rรณbert Papp
          Rรณbert Papp

          ๐Ÿ›
          Saikat Sengupta
          Saikat Sengupta

          ๐Ÿ›
          Saksham Handu
          Saksham Handu

          ๐Ÿ›
          Saladoc
          Saladoc

          ๐Ÿ›
          Salesforce Bob Lightning
          Salesforce Bob Lightning

          ๐Ÿ›
          Salesforce Bob Lightning
          Salesforce Bob Lightning

          ๐Ÿ›
          Sam Carlberg
          Sam Carlberg

          ๐Ÿ›
          Sascha Riemer
          Sascha Riemer

          ๐Ÿ›
          Sashko
          Sashko

          ๐Ÿ’ป
          Satoshi Kubo
          Satoshi Kubo

          ๐Ÿ›
          Scott Kennedy
          Scott Kennedy

          ๐Ÿ›
          Scott Wells
          Scott Wells

          ๐Ÿ› ๐Ÿ’ป
          Scrates1
          Scrates1

          ๐Ÿ› ๐Ÿ’ป
          Scrates1
          Scrates1

          ๐Ÿ› ๐Ÿ’ป
          Scrsloota
          Scrsloota

          ๐Ÿ’ป
          Sebastian Bรถgl
          Sebastian Bรถgl

          ๐Ÿ›
          Sebastian Davids
          Sebastian Davids

          ๐Ÿ›
          Sebastian Lรถvdahl
          Sebastian Lรถvdahl

          ๐Ÿ›
          Sebastian Schuberth
          Sebastian Schuberth

          ๐Ÿ›
          Sebastian Schwarz
          Sebastian Schwarz

          ๐Ÿ›
          Seren
          Seren

          ๐Ÿ› ๐Ÿ’ป
          Seren
          Seren

          ๐Ÿ› ๐Ÿ’ป
          Sergey Gorbaty
          Sergey Gorbaty

          ๐Ÿ›
          Sergey Kozlov
          Sergey Kozlov

          ๐Ÿ›
          Sergey Yanzin
          Sergey Yanzin

          ๐Ÿ’ป ๐Ÿ›
          Seth Wilcox
          Seth Wilcox

          ๐Ÿ’ป
          Shai Bennathan
          Shai Bennathan

          ๐Ÿ› ๐Ÿ’ป
          Shubham
          Shubham

          ๐Ÿ’ป ๐Ÿ›
          Simon Abykov
          Simon Abykov

          ๐Ÿ’ป ๐Ÿ›
          Simon Abykov
          Simon Abykov

          ๐Ÿ’ป ๐Ÿ›
          Simon Xiao
          Simon Xiao

          ๐Ÿ›
          Srinivasan Venkatachalam
          Srinivasan Venkatachalam

          ๐Ÿ›
          Stanislav Gromov
          Stanislav Gromov

          ๐Ÿ›
          Stanislav Myachenkov
          Stanislav Myachenkov

          ๐Ÿ’ป
          Stefan Birkner
          Stefan Birkner

          ๐Ÿ›
          Stefan Bohn
          Stefan Bohn

          ๐Ÿ›
          Stefan Endrullis
          Stefan Endrullis

          ๐Ÿ›
          Stefan Endrullis
          Stefan Endrullis

          ๐Ÿ›
          Stefan Klรถss-Schuster
          Stefan Klรถss-Schuster

          ๐Ÿ›
          Stefan Wolf
          Stefan Wolf

          ๐Ÿ›
          Stephan H. Wissel
          Stephan H. Wissel

          ๐Ÿ›
          Stephen
          Stephen

          ๐Ÿ›
          Stephen Carter
          Stephen Carter

          ๐Ÿ›
          Stephen Friedrich
          Stephen Friedrich

          ๐Ÿ›
          Steve Babula
          Steve Babula

          ๐Ÿ’ป
          Steve Babula
          Steve Babula

          ๐Ÿ’ป
          Steve White
          Steve White

          ๐Ÿ›
          Steven Schlansker
          Steven Schlansker

          ๐Ÿ›
          Steven Stearns
          Steven Stearns

          ๐Ÿ› ๐Ÿ’ป
          Stexxe
          Stexxe

          ๐Ÿ›
          Stian Lรฅgstad
          Stian Lรฅgstad

          ๐Ÿ›
          StuartClayton5
          StuartClayton5

          ๐Ÿ›
          Supun Arunoda
          Supun Arunoda

          ๐Ÿ›
          Supun Arunoda
          Supun Arunoda

          ๐Ÿ›
          Suren Abrahamyan
          Suren Abrahamyan

          ๐Ÿ›
          Suvashri
          Suvashri

          ๐Ÿ“–
          Sven Barden
          Sven Barden

          ๐Ÿ›
          SwatiBGupta1110
          SwatiBGupta1110

          ๐Ÿ›
          SyedThoufich
          SyedThoufich

          ๐Ÿ›
          Szymon Sasin
          Szymon Sasin

          ๐Ÿ›
          T-chuangxin
          T-chuangxin

          ๐Ÿ›
          T-chuangxin
          T-chuangxin

          ๐Ÿ›
          TERAI Atsuhiro
          TERAI Atsuhiro

          ๐Ÿ›
          TIOBE Software
          TIOBE Software

          ๐Ÿ’ป ๐Ÿ›
          Tarush Singh
          Tarush Singh

          ๐Ÿ’ป
          Taylor Smock
          Taylor Smock

          ๐Ÿ›
          Techeira Damiรกn
          Techeira Damiรกn

          ๐Ÿ’ป ๐Ÿ›
          Ted Husted
          Ted Husted

          ๐Ÿ›
          TehBakker
          TehBakker

          ๐Ÿ›
          TehBakker
          TehBakker

          ๐Ÿ›
          The Gitter Badger
          The Gitter Badger

          ๐Ÿ›
          Theodoor
          Theodoor

          ๐Ÿ›
          Thiago Henrique Hรผpner
          Thiago Henrique Hรผpner

          ๐Ÿ›
          Thibault Meyer
          Thibault Meyer

          ๐Ÿ›
          Thomas Gรผttler
          Thomas Gรผttler

          ๐Ÿ›
          Thomas Jones-Low
          Thomas Jones-Low

          ๐Ÿ›
          Thomas Smith
          Thomas Smith

          ๐Ÿ’ป ๐Ÿ›
          Thomas Smith
          Thomas Smith

          ๐Ÿ’ป ๐Ÿ›
          ThrawnCA
          ThrawnCA

          ๐Ÿ›
          Thu Vo
          Thu Vo

          ๐Ÿ›
          Thunderforge
          Thunderforge

          ๐Ÿ’ป ๐Ÿ›
          Tim van der Lippe
          Tim van der Lippe

          ๐Ÿ›
          Tobias Weimer
          Tobias Weimer

          ๐Ÿ’ป ๐Ÿ›
          Tom Copeland
          Tom Copeland

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“–
          Tom Daly
          Tom Daly

          ๐Ÿ›
          Tom Daly
          Tom Daly

          ๐Ÿ›
          Tomas
          Tomas

          ๐Ÿ›
          Tomer Figenblat
          Tomer Figenblat

          ๐Ÿ›
          Tomi De Lucca
          Tomi De Lucca

          ๐Ÿ’ป ๐Ÿ›
          Tony
          Tony

          ๐Ÿ“–
          Torsten Kleiber
          Torsten Kleiber

          ๐Ÿ›
          Torsten Krause
          Torsten Krause

          ๐Ÿ›
          TrackerSB
          TrackerSB

          ๐Ÿ›
          TrackerSB
          TrackerSB

          ๐Ÿ›
          Tyson Stewart
          Tyson Stewart

          ๐Ÿ›
          Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ›
          UncleOwen
          UncleOwen

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“–
          Utku Cuhadaroglu
          Utku Cuhadaroglu

          ๐Ÿ’ป ๐Ÿ›
          Valentin Brandl
          Valentin Brandl

          ๐Ÿ›
          Valeria
          Valeria

          ๐Ÿ›
          Valery Yatsynovich
          Valery Yatsynovich

          ๐Ÿ“–
          Valery Yatsynovich
          Valery Yatsynovich

          ๐Ÿ“–
          Vasily Anisimov
          Vasily Anisimov

          ๐Ÿ›
          Vedant Chokshi
          Vedant Chokshi

          ๐Ÿ›
          Vibhor Goyal
          Vibhor Goyal

          ๐Ÿ›
          Vickenty Fesunov
          Vickenty Fesunov

          ๐Ÿ›
          Victor Noรซl
          Victor Noรซl

          ๐Ÿ›
          Vincent Galloy
          Vincent Galloy

          ๐Ÿ’ป
          Vincent HUYNH
          Vincent HUYNH

          ๐Ÿ›
          Vincent HUYNH
          Vincent HUYNH

          ๐Ÿ›
          Vincent Maurin
          Vincent Maurin

          ๐Ÿ›
          Vincent Potucek
          Vincent Potucek

          ๐Ÿ’ป
          Vincent Privat
          Vincent Privat

          ๐Ÿ›
          Vishhwas
          Vishhwas

          ๐Ÿ›
          Vishv_Android
          Vishv_Android

          ๐Ÿ›
          Vitalii Yevtushenko
          Vitalii Yevtushenko

          ๐Ÿ›
          Vitaly
          Vitaly

          ๐Ÿ›
          Vitaly
          Vitaly

          ๐Ÿ›
          Vitaly Polonetsky
          Vitaly Polonetsky

          ๐Ÿ›
          Vojtech Polivka
          Vojtech Polivka

          ๐Ÿ›
          Vsevolod Zholobov
          Vsevolod Zholobov

          ๐Ÿ›
          Vyom Yadav
          Vyom Yadav

          ๐Ÿ’ป
          Wang Shidong
          Wang Shidong

          ๐Ÿ›
          Waqas Ahmed
          Waqas Ahmed

          ๐Ÿ›
          Wayne J. Earl
          Wayne J. Earl

          ๐Ÿ›
          Wayne J. Earl
          Wayne J. Earl

          ๐Ÿ›
          Wchenghui
          Wchenghui

          ๐Ÿ›
          Wener
          Wener

          ๐Ÿ’ป
          Will Winder
          Will Winder

          ๐Ÿ›
          Willem A. Hajenius
          Willem A. Hajenius

          ๐Ÿ’ป
          William Brockhus
          William Brockhus

          ๐Ÿ’ป ๐Ÿ›
          Wilson Kurniawan
          Wilson Kurniawan

          ๐Ÿ›
          Wim Deblauwe
          Wim Deblauwe

          ๐Ÿ›
          Wim Deblauwe
          Wim Deblauwe

          ๐Ÿ›
          Wolf2323
          Wolf2323

          ๐Ÿ›
          Woongsik Choi
          Woongsik Choi

          ๐Ÿ›
          XenoAmess
          XenoAmess

          ๐Ÿ’ป ๐Ÿ›
          Yang
          Yang

          ๐Ÿ’ป
          YaroslavTER
          YaroslavTER

          ๐Ÿ›
          Yasar Shaikh
          Yasar Shaikh

          ๐Ÿ’ป
          Young Chan
          Young Chan

          ๐Ÿ’ป ๐Ÿ›
          Young Chan
          Young Chan

          ๐Ÿ’ป ๐Ÿ›
          YuJin Kim
          YuJin Kim

          ๐Ÿ›
          Yuri Dolzhenko
          Yuri Dolzhenko

          ๐Ÿ›
          Yurii Dubinka
          Yurii Dubinka

          ๐Ÿ›
          Zbynek Konecny
          Zbynek Konecny

          ๐Ÿ› ๐Ÿ’ป
          Zoltan Farkas
          Zoltan Farkas

          ๐Ÿ›
          Zustin
          Zustin

          ๐Ÿ›
          aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป
          aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป
          alexmodis
          alexmodis

          ๐Ÿ›
          andreoss
          andreoss

          ๐Ÿ›
          andrey81inmd
          andrey81inmd

          ๐Ÿ’ป ๐Ÿ›
          anicoara
          anicoara

          ๐Ÿ›
          arunprasathav
          arunprasathav

          ๐Ÿ›
          asiercamara
          asiercamara

          ๐Ÿ›
          astillich-igniti
          astillich-igniti

          ๐Ÿ’ป
          astillich-igniti
          astillich-igniti

          ๐Ÿ’ป
          avesolovksyy
          avesolovksyy

          ๐Ÿ›
          avishvat
          avishvat

          ๐Ÿ›
          avivmu
          avivmu

          ๐Ÿ›
          axelbarfod1
          axelbarfod1

          ๐Ÿ›
          b-3-n
          b-3-n

          ๐Ÿ›
          balbhadra9
          balbhadra9

          ๐Ÿ›
          base23de
          base23de

          ๐Ÿ›
          base23de
          base23de

          ๐Ÿ›
          bergander
          bergander

          ๐Ÿ› ๐Ÿ’ป
          berkam
          berkam

          ๐Ÿ’ป ๐Ÿ›
          breizh31
          breizh31

          ๐Ÿ›
          caesarkim
          caesarkim

          ๐Ÿ›
          caiocarvalhotero
          caiocarvalhotero

          ๐Ÿ›
          carolyujing
          carolyujing

          ๐Ÿ›
          cbfiddle
          cbfiddle

          ๐Ÿ›
          cbfiddle
          cbfiddle

          ๐Ÿ›
          cesares-basilico
          cesares-basilico

          ๐Ÿ›
          chrite
          chrite

          ๐Ÿ›
          ciufudean
          ciufudean

          ๐Ÿ“–
          cobratbq
          cobratbq

          ๐Ÿ›
          coladict
          coladict

          ๐Ÿ›
          cosmoJFH
          cosmoJFH

          ๐Ÿ›
          cristalp
          cristalp

          ๐Ÿ›
          cristalp
          cristalp

          ๐Ÿ›
          crunsk
          crunsk

          ๐Ÿ›
          csrma
          csrma

          ๐Ÿ›
          cwholmes
          cwholmes

          ๐Ÿ›
          cyberjj999
          cyberjj999

          ๐Ÿ›
          cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“–
          d1ss0nanz
          d1ss0nanz

          ๐Ÿ›
          dague1
          dague1

          ๐Ÿ“–
          dague1
          dague1

          ๐Ÿ“–
          dalizi007
          dalizi007

          ๐Ÿ’ป
          danbrycefairsailcom
          danbrycefairsailcom

          ๐Ÿ›
          dariansanity
          dariansanity

          ๐Ÿ›
          darrenmiliband
          darrenmiliband

          ๐Ÿ›
          davidburstrom
          davidburstrom

          ๐Ÿ›
          dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ›
          deepak-patra
          deepak-patra

          ๐Ÿ›
          deepak-patra
          deepak-patra

          ๐Ÿ›
          dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ›
          dinesh150
          dinesh150

          ๐Ÿ›
          diziaq
          diziaq

          ๐Ÿ›
          dreaminpast123
          dreaminpast123

          ๐Ÿ›
          duanyanan
          duanyanan

          ๐Ÿ›
          dutt-sanjay
          dutt-sanjay

          ๐Ÿ›
          duursma
          duursma

          ๐Ÿ’ป
          duursma
          duursma

          ๐Ÿ’ป
          dylanleung
          dylanleung

          ๐Ÿ›
          dzeigler
          dzeigler

          ๐Ÿ›
          eant60
          eant60

          ๐Ÿ›
          ekkirala
          ekkirala

          ๐Ÿ›
          emersonmoura
          emersonmoura

          ๐Ÿ›
          emouty
          emouty

          ๐Ÿ’ป ๐Ÿ›
          eugenepugach
          eugenepugach

          ๐Ÿ›
          eugenepugach
          eugenepugach

          ๐Ÿ›
          fairy
          fairy

          ๐Ÿ›
          filiprafalowicz
          filiprafalowicz

          ๐Ÿ’ป
          flxbl-io
          flxbl-io

          ๐Ÿ’ต
          foxmason
          foxmason

          ๐Ÿ›
          frankegabor
          frankegabor

          ๐Ÿ›
          frankl
          frankl

          ๐Ÿ›
          freafrea
          freafrea

          ๐Ÿ›
          freafrea
          freafrea

          ๐Ÿ›
          fsapatin
          fsapatin

          ๐Ÿ›
          gearsethenry
          gearsethenry

          ๐Ÿ›
          gracia19
          gracia19

          ๐Ÿ›
          gudzpoz
          gudzpoz

          ๐Ÿ›
          guo fei
          guo fei

          ๐Ÿ›
          gurmsc5
          gurmsc5

          ๐Ÿ›
          gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ›
          gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ›
          haigsn
          haigsn

          ๐Ÿ›
          hemanshu070
          hemanshu070

          ๐Ÿ›
          henrik242
          henrik242

          ๐Ÿ›
          hongpuwu
          hongpuwu

          ๐Ÿ›
          hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ›
          igniti GmbH
          igniti GmbH

          ๐Ÿ›
          ilovezfs
          ilovezfs

          ๐Ÿ›
          ilovezfs
          ilovezfs

          ๐Ÿ›
          imax-erik
          imax-erik

          ๐Ÿ›
          itaigilo
          itaigilo

          ๐Ÿ›
          jakivey32
          jakivey32

          ๐Ÿ›
          jbennett2091
          jbennett2091

          ๐Ÿ›
          jcamerin
          jcamerin

          ๐Ÿ›
          jkeener1
          jkeener1

          ๐Ÿ›
          jmetertea
          jmetertea

          ๐Ÿ›
          jmetertea
          jmetertea

          ๐Ÿ›
          johnra2
          johnra2

          ๐Ÿ’ป
          johnzhao9
          johnzhao9

          ๐Ÿ›
          josemanuelrolon
          josemanuelrolon

          ๐Ÿ’ป ๐Ÿ›
          julees7
          julees7

          ๐Ÿ’ป ๐Ÿ›
          kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ›
          karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“–
          karwer
          karwer

          ๐Ÿ›
          karwer
          karwer

          ๐Ÿ›
          kaulonline
          kaulonline

          ๐Ÿ›
          kdaemonv
          kdaemonv

          ๐Ÿ›
          kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป
          kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ›
          kfranic
          kfranic

          ๐Ÿ›
          khalidkh
          khalidkh

          ๐Ÿ›
          koalalam
          koalalam

          ๐Ÿ›
          koalalam
          koalalam

          ๐Ÿ›
          krzyk
          krzyk

          ๐Ÿ›
          lasselindqvist
          lasselindqvist

          ๐Ÿ›
          lgemeinhardt
          lgemeinhardt

          ๐Ÿ›
          lihuaib
          lihuaib

          ๐Ÿ›
          liqingjun123
          liqingjun123

          ๐Ÿ›
          lonelyma1021
          lonelyma1021

          ๐Ÿ›
          lothas
          lothas

          ๐Ÿ›
          lothas
          lothas

          ๐Ÿ›
          lpeddy
          lpeddy

          ๐Ÿ›
          lujiefsi
          lujiefsi

          ๐Ÿ’ป
          lukelukes
          lukelukes

          ๐Ÿ’ป
          lyriccoder
          lyriccoder

          ๐Ÿ›
          marcelmore
          marcelmore

          ๐Ÿ›
          matchbox
          matchbox

          ๐Ÿ›
          matthiaskraaz
          matthiaskraaz

          ๐Ÿ›
          matthiaskraaz
          matthiaskraaz

          ๐Ÿ›
          meandonlyme
          meandonlyme

          ๐Ÿ›
          mikesive
          mikesive

          ๐Ÿ›
          milossesic
          milossesic

          ๐Ÿ›
          mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ›
          mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป
          mrclmh
          mrclmh

          ๐Ÿ›
          mriddell95
          mriddell95

          ๐Ÿ›
          mriddell95
          mriddell95

          ๐Ÿ›
          mrlzh
          mrlzh

          ๐Ÿ›
          msloan
          msloan

          ๐Ÿ›
          mucharlaravalika
          mucharlaravalika

          ๐Ÿ›
          mvenneman
          mvenneman

          ๐Ÿ›
          nareshl119
          nareshl119

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          noerremark
          noerremark

          ๐Ÿ›
          noerremark
          noerremark

          ๐Ÿ›
          novsirion
          novsirion

          ๐Ÿ›
          nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป
          oggboy
          oggboy

          ๐Ÿ›
          oinume
          oinume

          ๐Ÿ›
          orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pacvz
          pacvz

          ๐Ÿ’ป
          pacvz
          pacvz

          ๐Ÿ’ป
          pallavi agarwal
          pallavi agarwal

          ๐Ÿ›
          pankratz76
          pankratz76

          ๐Ÿ›
          parksungrin
          parksungrin

          ๐Ÿ›
          patpatpat123
          patpatpat123

          ๐Ÿ›
          patriksevallius
          patriksevallius

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          phoenix384
          phoenix384

          ๐Ÿ›
          phoenix384
          phoenix384

          ๐Ÿ›
          piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป
          plan3d
          plan3d

          ๐Ÿ›
          poojasix
          poojasix

          ๐Ÿ›
          prabhushrikant
          prabhushrikant

          ๐Ÿ›
          pujitha8783
          pujitha8783

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          raghujayjunk
          raghujayjunk

          ๐Ÿ›
          raghujayjunk
          raghujayjunk

          ๐Ÿ›
          rajeshveera
          rajeshveera

          ๐Ÿ›
          rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ›
          recdevs
          recdevs

          ๐Ÿ›
          reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ›
          rijkt
          rijkt

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ›
          rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ›
          rnveach
          rnveach

          ๐Ÿ›
          rxmicro
          rxmicro

          ๐Ÿ›
          ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ›
          sabi0
          sabi0

          ๐Ÿ›
          samc-gearset
          samc-gearset

          ๐Ÿ“–
          scais
          scais

          ๐Ÿ›
          schosin
          schosin

          ๐Ÿ›
          schosin
          schosin

          ๐Ÿ›
          screamingfrog
          screamingfrog

          ๐Ÿ’ต
          sebbASF
          sebbASF

          ๐Ÿ›
          sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป
          shilko2013
          shilko2013

          ๐Ÿ›
          shiomiyan
          shiomiyan

          ๐Ÿ“–
          simeonKondr
          simeonKondr

          ๐Ÿ›
          snajberk
          snajberk

          ๐Ÿ›
          snajberk
          snajberk

          ๐Ÿ›
          sniperrifle2004
          sniperrifle2004

          ๐Ÿ›
          snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป
          soloturn
          soloturn

          ๐Ÿ›
          soyodream
          soyodream

          ๐Ÿ›
          sratz
          sratz

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          sturton
          sturton

          ๐Ÿ’ป ๐Ÿ›
          sturton
          sturton

          ๐Ÿ’ป ๐Ÿ›
          sudharmohan
          sudharmohan

          ๐Ÿ›
          suruchidawar
          suruchidawar

          ๐Ÿ›
          svenfinitiv
          svenfinitiv

          ๐Ÿ›
          szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป
          tashiscool
          tashiscool

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          testation21
          testation21

          ๐Ÿ’ป ๐Ÿ›
          testation21
          testation21

          ๐Ÿ’ป ๐Ÿ›
          thanosa
          thanosa

          ๐Ÿ›
          tiandiyixian
          tiandiyixian

          ๐Ÿ›
          tobwoerk
          tobwoerk

          ๐Ÿ›
          tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป
          trentchilders
          trentchilders

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          trishul14
          trishul14

          ๐Ÿ›
          trishul14
          trishul14

          ๐Ÿ›
          tsui
          tsui

          ๐Ÿ›
          wangzitom12306
          wangzitom12306

          ๐Ÿ›
          winhkey
          winhkey

          ๐Ÿ›
          witherspore
          witherspore

          ๐Ÿ›
          wjljack
          wjljack

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          xingsong
          xingsong

          ๐Ÿ›
          xingsong
          xingsong

          ๐Ÿ›
          xioayuge
          xioayuge

          ๐Ÿ›
          xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ›
          xuanuy
          xuanuy

          ๐Ÿ›
          xyf0921
          xyf0921

          ๐Ÿ›
          yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yasuharu-sato
          yasuharu-sato

          ๐Ÿ›
          yasuharu-sato
          yasuharu-sato

          ๐Ÿ›
          zenglian
          zenglian

          ๐Ÿ›
          zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ›
          zh3ng
          zh3ng

          ๐Ÿ›
          zt_soft
          zt_soft

          ๐Ÿ›
          ztt79
          ztt79

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ›
          รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ›
          ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ›
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ

          ๐Ÿ›
          ่Œ…ๅปถๅฎ‰
          ่Œ…ๅปถๅฎ‰

          ๐Ÿ’ป
          Vincent Maurin
          Vincent Maurin

          ๐Ÿ›
          Vincent Potucek
          Vincent Potucek

          ๐Ÿ’ป
          Vincent Privat
          Vincent Privat

          ๐Ÿ›
          Vincent Zorge
          Vincent Zorge

          ๐Ÿ›
          Vishhwas
          Vishhwas

          ๐Ÿ›
          Vishv_Android
          Vishv_Android

          ๐Ÿ›
          Vitalii Yevtushenko
          Vitalii Yevtushenko

          ๐Ÿ›
          Vitalii Yevtushenko
          Vitalii Yevtushenko

          ๐Ÿ›
          Vitaly
          Vitaly

          ๐Ÿ›
          Vitaly Polonetsky
          Vitaly Polonetsky

          ๐Ÿ›
          Vojtech Polivka
          Vojtech Polivka

          ๐Ÿ›
          Vsevolod Zholobov
          Vsevolod Zholobov

          ๐Ÿ›
          Vyom Yadav
          Vyom Yadav

          ๐Ÿ’ป
          Wang Shidong
          Wang Shidong

          ๐Ÿ›
          Waqas Ahmed
          Waqas Ahmed

          ๐Ÿ›
          Waqas Ahmed
          Waqas Ahmed

          ๐Ÿ›
          Wayne J. Earl
          Wayne J. Earl

          ๐Ÿ›
          Wchenghui
          Wchenghui

          ๐Ÿ›
          Wener
          Wener

          ๐Ÿ’ป
          Will Winder
          Will Winder

          ๐Ÿ›
          Willem A. Hajenius
          Willem A. Hajenius

          ๐Ÿ’ป
          William Brockhus
          William Brockhus

          ๐Ÿ’ป ๐Ÿ›
          Wilson Kurniawan
          Wilson Kurniawan

          ๐Ÿ›
          Wilson Kurniawan
          Wilson Kurniawan

          ๐Ÿ›
          Wim Deblauwe
          Wim Deblauwe

          ๐Ÿ›
          Wolf2323
          Wolf2323

          ๐Ÿ›
          Woongsik Choi
          Woongsik Choi

          ๐Ÿ›
          XenoAmess
          XenoAmess

          ๐Ÿ’ป ๐Ÿ›
          Yang
          Yang

          ๐Ÿ’ป
          YaroslavTER
          YaroslavTER

          ๐Ÿ›
          Yasar Shaikh
          Yasar Shaikh

          ๐Ÿ’ป
          Yasar Shaikh
          Yasar Shaikh

          ๐Ÿ’ป
          Young Chan
          Young Chan

          ๐Ÿ’ป ๐Ÿ›
          YuJin Kim
          YuJin Kim

          ๐Ÿ›
          Yuri Dolzhenko
          Yuri Dolzhenko

          ๐Ÿ›
          Yurii Dubinka
          Yurii Dubinka

          ๐Ÿ›
          Zbynek Konecny
          Zbynek Konecny

          ๐Ÿ› ๐Ÿ’ป
          Zoltan Farkas
          Zoltan Farkas

          ๐Ÿ›
          Zustin
          Zustin

          ๐Ÿ›
          Zustin
          Zustin

          ๐Ÿ›
          aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป
          alexmodis
          alexmodis

          ๐Ÿ›
          andreoss
          andreoss

          ๐Ÿ›
          andrey81inmd
          andrey81inmd

          ๐Ÿ’ป ๐Ÿ›
          anicoara
          anicoara

          ๐Ÿ›
          arunprasathav
          arunprasathav

          ๐Ÿ›
          asiercamara
          asiercamara

          ๐Ÿ›
          asiercamara
          asiercamara

          ๐Ÿ›
          astillich-igniti
          astillich-igniti

          ๐Ÿ’ป
          avesolovksyy
          avesolovksyy

          ๐Ÿ›
          avishvat
          avishvat

          ๐Ÿ›
          avivmu
          avivmu

          ๐Ÿ›
          axelbarfod1
          axelbarfod1

          ๐Ÿ›
          b-3-n
          b-3-n

          ๐Ÿ›
          balbhadra9
          balbhadra9

          ๐Ÿ›
          balbhadra9
          balbhadra9

          ๐Ÿ›
          base23de
          base23de

          ๐Ÿ›
          bergander
          bergander

          ๐Ÿ› ๐Ÿ’ป
          berkam
          berkam

          ๐Ÿ’ป ๐Ÿ›
          breizh31
          breizh31

          ๐Ÿ›
          caesarkim
          caesarkim

          ๐Ÿ›
          caiocarvalhotero
          caiocarvalhotero

          ๐Ÿ›
          carolyujing
          carolyujing

          ๐Ÿ›
          carolyujing
          carolyujing

          ๐Ÿ›
          cbfiddle
          cbfiddle

          ๐Ÿ›
          cesares-basilico
          cesares-basilico

          ๐Ÿ›
          chrite
          chrite

          ๐Ÿ›
          ciufudean
          ciufudean

          ๐Ÿ“–
          cobratbq
          cobratbq

          ๐Ÿ›
          coladict
          coladict

          ๐Ÿ›
          cosmoJFH
          cosmoJFH

          ๐Ÿ›
          cosmoJFH
          cosmoJFH

          ๐Ÿ›
          cristalp
          cristalp

          ๐Ÿ›
          crunsk
          crunsk

          ๐Ÿ›
          csrma
          csrma

          ๐Ÿ›
          cwholmes
          cwholmes

          ๐Ÿ›
          cyberjj999
          cyberjj999

          ๐Ÿ›
          cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“–
          d1ss0nanz
          d1ss0nanz

          ๐Ÿ›
          d1ss0nanz
          d1ss0nanz

          ๐Ÿ›
          dague1
          dague1

          ๐Ÿ“–
          dalizi007
          dalizi007

          ๐Ÿ’ป
          danbrycefairsailcom
          danbrycefairsailcom

          ๐Ÿ›
          dariansanity
          dariansanity

          ๐Ÿ›
          darrenmiliband
          darrenmiliband

          ๐Ÿ›
          davidburstrom
          davidburstrom

          ๐Ÿ›
          dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ›
          dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ›
          deepak-patra
          deepak-patra

          ๐Ÿ›
          dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ›
          dinesh150
          dinesh150

          ๐Ÿ›
          diziaq
          diziaq

          ๐Ÿ›
          dreaminpast123
          dreaminpast123

          ๐Ÿ›
          duanyanan
          duanyanan

          ๐Ÿ›
          dutt-sanjay
          dutt-sanjay

          ๐Ÿ›
          dutt-sanjay
          dutt-sanjay

          ๐Ÿ›
          duursma
          duursma

          ๐Ÿ’ป
          dylanleung
          dylanleung

          ๐Ÿ›
          dzeigler
          dzeigler

          ๐Ÿ›
          eant60
          eant60

          ๐Ÿ›
          ekkirala
          ekkirala

          ๐Ÿ›
          emersonmoura
          emersonmoura

          ๐Ÿ›
          emouty
          emouty

          ๐Ÿ’ป ๐Ÿ›
          emouty
          emouty

          ๐Ÿ’ป ๐Ÿ›
          eugenepugach
          eugenepugach

          ๐Ÿ›
          fairy
          fairy

          ๐Ÿ›
          filiprafalowicz
          filiprafalowicz

          ๐Ÿ’ป
          flxbl-io
          flxbl-io

          ๐Ÿ’ต
          foxmason
          foxmason

          ๐Ÿ›
          frankegabor
          frankegabor

          ๐Ÿ›
          frankl
          frankl

          ๐Ÿ›
          frankl
          frankl

          ๐Ÿ›
          freafrea
          freafrea

          ๐Ÿ›
          fsapatin
          fsapatin

          ๐Ÿ›
          gearsethenry
          gearsethenry

          ๐Ÿ›
          gracia19
          gracia19

          ๐Ÿ›
          gudzpoz
          gudzpoz

          ๐Ÿ›
          guo fei
          guo fei

          ๐Ÿ›
          gurmsc5
          gurmsc5

          ๐Ÿ›
          gurmsc5
          gurmsc5

          ๐Ÿ›
          gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ›
          haigsn
          haigsn

          ๐Ÿ›
          hemanshu070
          hemanshu070

          ๐Ÿ›
          henrik242
          henrik242

          ๐Ÿ›
          hongpuwu
          hongpuwu

          ๐Ÿ›
          hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ›
          igniti GmbH
          igniti GmbH

          ๐Ÿ›
          igniti GmbH
          igniti GmbH

          ๐Ÿ›
          ilovezfs
          ilovezfs

          ๐Ÿ›
          imax-erik
          imax-erik

          ๐Ÿ›
          itaigilo
          itaigilo

          ๐Ÿ›
          jakivey32
          jakivey32

          ๐Ÿ›
          jbennett2091
          jbennett2091

          ๐Ÿ›
          jcamerin
          jcamerin

          ๐Ÿ›
          jkeener1
          jkeener1

          ๐Ÿ›
          jkeener1
          jkeener1

          ๐Ÿ›
          jmetertea
          jmetertea

          ๐Ÿ›
          johnra2
          johnra2

          ๐Ÿ’ป
          johnzhao9
          johnzhao9

          ๐Ÿ›
          josemanuelrolon
          josemanuelrolon

          ๐Ÿ’ป ๐Ÿ›
          julees7
          julees7

          ๐Ÿ’ป ๐Ÿ›
          kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ›
          karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“–
          karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“–
          karwer
          karwer

          ๐Ÿ›
          kaulonline
          kaulonline

          ๐Ÿ›
          kdaemonv
          kdaemonv

          ๐Ÿ›
          kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป
          kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ›
          kfranic
          kfranic

          ๐Ÿ›
          khalidkh
          khalidkh

          ๐Ÿ›
          khalidkh
          khalidkh

          ๐Ÿ›
          koalalam
          koalalam

          ๐Ÿ›
          krzyk
          krzyk

          ๐Ÿ›
          lasselindqvist
          lasselindqvist

          ๐Ÿ›
          lgemeinhardt
          lgemeinhardt

          ๐Ÿ›
          lihuaib
          lihuaib

          ๐Ÿ›
          liqingjun123
          liqingjun123

          ๐Ÿ›
          lonelyma1021
          lonelyma1021

          ๐Ÿ›
          lonelyma1021
          lonelyma1021

          ๐Ÿ›
          lothas
          lothas

          ๐Ÿ›
          lpeddy
          lpeddy

          ๐Ÿ›
          lujiefsi
          lujiefsi

          ๐Ÿ’ป
          lukelukes
          lukelukes

          ๐Ÿ’ป
          lyriccoder
          lyriccoder

          ๐Ÿ›
          marcelmore
          marcelmore

          ๐Ÿ›
          matchbox
          matchbox

          ๐Ÿ›
          matchbox
          matchbox

          ๐Ÿ›
          matthiaskraaz
          matthiaskraaz

          ๐Ÿ›
          meandonlyme
          meandonlyme

          ๐Ÿ›
          mikesive
          mikesive

          ๐Ÿ›
          milossesic
          milossesic

          ๐Ÿ›
          mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ›
          mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป
          mrclmh
          mrclmh

          ๐Ÿ›
          mrclmh
          mrclmh

          ๐Ÿ›
          mriddell95
          mriddell95

          ๐Ÿ›
          mrlzh
          mrlzh

          ๐Ÿ›
          msloan
          msloan

          ๐Ÿ›
          mucharlaravalika
          mucharlaravalika

          ๐Ÿ›
          mvenneman
          mvenneman

          ๐Ÿ›
          nareshl119
          nareshl119

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ›
          noerremark
          noerremark

          ๐Ÿ›
          novsirion
          novsirion

          ๐Ÿ›
          nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป
          oggboy
          oggboy

          ๐Ÿ›
          oinume
          oinume

          ๐Ÿ›
          orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pablogomez2197
          pablogomez2197

          ๐Ÿ›
          pacvz
          pacvz

          ๐Ÿ’ป
          pallavi agarwal
          pallavi agarwal

          ๐Ÿ›
          pankratz76
          pankratz76

          ๐Ÿ›
          parksungrin
          parksungrin

          ๐Ÿ›
          patpatpat123
          patpatpat123

          ๐Ÿ›
          patriksevallius
          patriksevallius

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          pbrajesh1
          pbrajesh1

          ๐Ÿ›
          phoenix384
          phoenix384

          ๐Ÿ›
          piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป
          plan3d
          plan3d

          ๐Ÿ›
          poojasix
          poojasix

          ๐Ÿ›
          prabhushrikant
          prabhushrikant

          ๐Ÿ›
          pujitha8783
          pujitha8783

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          r-r-a-j
          r-r-a-j

          ๐Ÿ›
          raghujayjunk
          raghujayjunk

          ๐Ÿ›
          rajeshveera
          rajeshveera

          ๐Ÿ›
          rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ›
          recdevs
          recdevs

          ๐Ÿ›
          reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ›
          rijkt
          rijkt

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rillig-tk
          rillig-tk

          ๐Ÿ›
          rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ›
          rnveach
          rnveach

          ๐Ÿ›
          rxmicro
          rxmicro

          ๐Ÿ›
          ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ›
          sabi0
          sabi0

          ๐Ÿ›
          samc-gearset
          samc-gearset

          ๐Ÿ“–
          scais
          scais

          ๐Ÿ›
          scais
          scais

          ๐Ÿ›
          schosin
          schosin

          ๐Ÿ›
          screamingfrog
          screamingfrog

          ๐Ÿ’ต
          sebbASF
          sebbASF

          ๐Ÿ›
          sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป
          shilko2013
          shilko2013

          ๐Ÿ›
          shiomiyan
          shiomiyan

          ๐Ÿ“–
          simeonKondr
          simeonKondr

          ๐Ÿ›
          simeonKondr
          simeonKondr

          ๐Ÿ›
          snajberk
          snajberk

          ๐Ÿ›
          sniperrifle2004
          sniperrifle2004

          ๐Ÿ›
          snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป
          soloturn
          soloturn

          ๐Ÿ›
          soyodream
          soyodream

          ๐Ÿ›
          sratz
          sratz

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          stonio
          stonio

          ๐Ÿ›
          sturton
          sturton

          ๐Ÿ’ป ๐Ÿ›
          sudharmohan
          sudharmohan

          ๐Ÿ›
          suruchidawar
          suruchidawar

          ๐Ÿ›
          svenfinitiv
          svenfinitiv

          ๐Ÿ›
          szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป
          tashiscool
          tashiscool

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          test-git-hook
          test-git-hook

          ๐Ÿ›
          testation21
          testation21

          ๐Ÿ’ป ๐Ÿ›
          thanosa
          thanosa

          ๐Ÿ›
          tiandiyixian
          tiandiyixian

          ๐Ÿ›
          tobwoerk
          tobwoerk

          ๐Ÿ›
          tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป
          trentchilders
          trentchilders

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          triandicAnt
          triandicAnt

          ๐Ÿ›
          trishul14
          trishul14

          ๐Ÿ›
          tsui
          tsui

          ๐Ÿ›
          wangzitom12306
          wangzitom12306

          ๐Ÿ›
          winhkey
          winhkey

          ๐Ÿ›
          witherspore
          witherspore

          ๐Ÿ›
          wjljack
          wjljack

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          wuchiuwong
          wuchiuwong

          ๐Ÿ›
          xingsong
          xingsong

          ๐Ÿ›
          xioayuge
          xioayuge

          ๐Ÿ›
          xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ›
          xuanuy
          xuanuy

          ๐Ÿ›
          xyf0921
          xyf0921

          ๐Ÿ›
          yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ›
          yasuharu-sato
          yasuharu-sato

          ๐Ÿ›
          zenglian
          zenglian

          ๐Ÿ›
          zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ›
          zh3ng
          zh3ng

          ๐Ÿ›
          zt_soft
          zt_soft

          ๐Ÿ›
          ztt79
          ztt79

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          zzzzfeng
          zzzzfeng

          ๐Ÿ›
          รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ›
          ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ›
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ

          ๐Ÿ›
          "+"",P=u?"":"",w=0;7>w;w++)M=(w+c)%7,P+="";for(T+=P+"",S=this._getDaysInMonth(te,Z),te===t.selectedYear&&Z===t.selectedMonth&&(t.selectedDay=Math.min(t.selectedDay,S)),H=(this._getFirstDayOfMonth(te,Z)-c+7)%7,z=Math.ceil((H+S)/7),O=X?this.maxRows>z?this.maxRows:z:z,this.maxRows=O,A=this._daylightSavingAdjust(new Date(te,Z,1-H)),N=0;O>N;N++){for(T+="",W=u?"":"",w=0;7>w;w++)E=m?m.apply(t.input?t.input[0]:null,[A]):[!0,""],F=A.getMonth()!==Z,L=F&&!v||!E[0]||Q&&Q>A||J&&A>J,W+="",A.setDate(A.getDate()+1),A=this._daylightSavingAdjust(A);T+=W+""}Z++,Z>11&&(Z=0,te++),T+="
          "+this._get(t,"weekHeader")+"=5?" class='ui-datepicker-week-end'":"")+">"+""+p[M]+"
          "+this._get(t,"calculateWeek")(A)+""+(F&&!_?" ":L?""+A.getDate()+"":""+A.getDate()+"")+"
          "+(X?""+(U[0]>0&&C===U[1]-1?"
          ":""):""),x+=T}y+=x}return y+=l,t._keyEvent=!1,y},_generateMonthYearHeader:function(t,e,i,s,n,o,a,r){var h,l,c,u,d,p,f,g,m=this._get(t,"changeMonth"),_=this._get(t,"changeYear"),v=this._get(t,"showMonthAfterYear"),b="
          ",y="";if(o||!m)y+=""+a[e]+"";else{for(h=s&&s.getFullYear()===i,l=n&&n.getFullYear()===i,y+=""}if(v||(b+=y+(!o&&m&&_?"":" ")),!t.yearshtml)if(t.yearshtml="",o||!_)b+=""+i+"";else{for(u=this._get(t,"yearRange").split(":"),d=(new Date).getFullYear(),p=function(t){var e=t.match(/c[+\-].*/)?i+parseInt(t.substring(1),10):t.match(/[+\-].*/)?d+parseInt(t,10):parseInt(t,10);return isNaN(e)?d:e},f=p(u[0]),g=Math.max(f,p(u[1]||"")),f=s?Math.max(f,s.getFullYear()):f,g=n?Math.min(g,n.getFullYear()):g,t.yearshtml+="",b+=t.yearshtml,t.yearshtml=null}return b+=this._get(t,"yearSuffix"),v&&(b+=(!o&&m&&_?"":" ")+y),b+="
          "},_adjustInstDate:function(t,e,i){var s=t.selectedYear+("Y"===i?e:0),n=t.selectedMonth+("M"===i?e:0),o=Math.min(t.selectedDay,this._getDaysInMonth(s,n))+("D"===i?e:0),a=this._restrictMinMax(t,this._daylightSavingAdjust(new Date(s,n,o)));t.selectedDay=a.getDate(),t.drawMonth=t.selectedMonth=a.getMonth(),t.drawYear=t.selectedYear=a.getFullYear(),("M"===i||"Y"===i)&&this._notifyChange(t)},_restrictMinMax:function(t,e){var i=this._getMinMaxDate(t,"min"),s=this._getMinMaxDate(t,"max"),n=i&&i>e?i:e;return s&&n>s?s:n},_notifyChange:function(t){var e=this._get(t,"onChangeMonthYear");e&&e.apply(t.input?t.input[0]:null,[t.selectedYear,t.selectedMonth+1,t])},_getNumberOfMonths:function(t){var e=this._get(t,"numberOfMonths");return null==e?[1,1]:"number"==typeof e?[1,e]:e},_getMinMaxDate:function(t,e){return this._determineDate(t,this._get(t,e+"Date"),null)},_getDaysInMonth:function(t,e){return 32-this._daylightSavingAdjust(new Date(t,e,32)).getDate()},_getFirstDayOfMonth:function(t,e){return new Date(t,e,1).getDay()},_canAdjustMonth:function(t,e,i,s){var n=this._getNumberOfMonths(t),o=this._daylightSavingAdjust(new Date(i,s+(0>e?e:n[0]*n[1]),1));return 0>e&&o.setDate(this._getDaysInMonth(o.getFullYear(),o.getMonth())),this._isInRange(t,o)},_isInRange:function(t,e){var i,s,n=this._getMinMaxDate(t,"min"),o=this._getMinMaxDate(t,"max"),a=null,r=null,h=this._get(t,"yearRange");return h&&(i=h.split(":"),s=(new Date).getFullYear(),a=parseInt(i[0],10),r=parseInt(i[1],10),i[0].match(/[+\-].*/)&&(a+=s),i[1].match(/[+\-].*/)&&(r+=s)),(!n||e.getTime()>=n.getTime())&&(!o||e.getTime()<=o.getTime())&&(!a||e.getFullYear()>=a)&&(!r||r>=e.getFullYear())},_getFormatConfig:function(t){var e=this._get(t,"shortYearCutoff");return e="string"!=typeof e?e:(new Date).getFullYear()%100+parseInt(e,10),{shortYearCutoff:e,dayNamesShort:this._get(t,"dayNamesShort"),dayNames:this._get(t,"dayNames"),monthNamesShort:this._get(t,"monthNamesShort"),monthNames:this._get(t,"monthNames")}},_formatDate:function(t,e,i,s){e||(t.currentDay=t.selectedDay,t.currentMonth=t.selectedMonth,t.currentYear=t.selectedYear);var n=e?"object"==typeof e?e:this._daylightSavingAdjust(new Date(s,i,e)):this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return this.formatDate(this._get(t,"dateFormat"),n,this._getFormatConfig(t))}}),t.fn.datepicker=function(e){if(!this.length)return this;t.datepicker.initialized||(t(document).on("mousedown",t.datepicker._checkExternalClick),t.datepicker.initialized=!0),0===t("#"+t.datepicker._mainDivId).length&&t("body").append(t.datepicker.dpDiv);var i=Array.prototype.slice.call(arguments,1);return"string"!=typeof e||"isDisabled"!==e&&"getDate"!==e&&"widget"!==e?"option"===e&&2===arguments.length&&"string"==typeof arguments[1]?t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this[0]].concat(i)):this.each(function(){"string"==typeof e?t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this].concat(i)):t.datepicker._attachDatepicker(this,e)}):t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this[0]].concat(i))},t.datepicker=new s,t.datepicker.initialized=!1,t.datepicker.uuid=(new Date).getTime(),t.datepicker.version="1.12.1",t.datepicker,t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var _=!1;t(document).on("mouseup",function(){_=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!_){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,s=1===e.which,n="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return s&&!n&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),_=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,_=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;o.length>n;n++)t.options[o[n][0]]&&o[n][1].apply(t.element,i)}},t.ui.safeBlur=function(e){e&&"body"!==e.nodeName.toLowerCase()&&t(e).trigger("blur")},t.widget("ui.draggable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"===this.options.helper&&this._setPositionRelative(),this.options.addClasses&&this._addClass("ui-draggable"),this._setHandleClassName(),this._mouseInit()},_setOption:function(t,e){this._super(t,e),"handle"===t&&(this._removeHandleClassName(),this._setHandleClassName())},_destroy:function(){return(this.helper||this.element).is(".ui-draggable-dragging")?(this.destroyOnClear=!0,void 0):(this._removeHandleClassName(),this._mouseDestroy(),void 0)},_mouseCapture:function(e){var i=this.options;return this.helper||i.disabled||t(e.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(e),this.handle?(this._blurActiveElement(e),this._blockFrames(i.iframeFix===!0?"iframe":i.iframeFix),!0):!1)},_blockFrames:function(e){this.iframeBlocks=this.document.find(e).map(function(){var e=t(this);return t("
          ").css("position","absolute").appendTo(e.parent()).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(e){var i=t.ui.safeActiveElement(this.document[0]),s=t(e.target);s.closest(i).length||t.ui.safeBlur(i)},_mouseStart:function(e){var i=this.options;return this.helper=this._createHelper(e),this._addClass(this.helper,"ui-draggable-dragging"),this._cacheHelperProportions(),t.ui.ddmanager&&(t.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=this.helper.parents().filter(function(){return"fixed"===t(this).css("position")}).length>0,this.positionAbs=this.element.offset(),this._refreshOffsets(e),this.originalPosition=this.position=this._generatePosition(e,!1),this.originalPageX=e.pageX,this.originalPageY=e.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),this._trigger("start",e)===!1?(this._clear(),!1):(this._cacheHelperProportions(),t.ui.ddmanager&&!i.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this._mouseDrag(e,!0),t.ui.ddmanager&&t.ui.ddmanager.dragStart(this,e),!0)},_refreshOffsets:function(t){this.offset={top:this.positionAbs.top-this.margins.top,left:this.positionAbs.left-this.margins.left,scroll:!1,parent:this._getParentOffset(),relative:this._getRelativeOffset()},this.offset.click={left:t.pageX-this.offset.left,top:t.pageY-this.offset.top}},_mouseDrag:function(e,i){if(this.hasFixedAncestor&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(e,!0),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(this._trigger("drag",e,s)===!1)return this._mouseUp(new t.Event("mouseup",e)),!1;this.position=s.position}return this.helper[0].style.left=this.position.left+"px",this.helper[0].style.top=this.position.top+"px",t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),!1},_mouseStop:function(e){var i=this,s=!1;return t.ui.ddmanager&&!this.options.dropBehaviour&&(s=t.ui.ddmanager.drop(this,e)),this.dropped&&(s=this.dropped,this.dropped=!1),"invalid"===this.options.revert&&!s||"valid"===this.options.revert&&s||this.options.revert===!0||t.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?t(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){i._trigger("stop",e)!==!1&&i._clear()}):this._trigger("stop",e)!==!1&&this._clear(),!1},_mouseUp:function(e){return this._unblockFrames(),t.ui.ddmanager&&t.ui.ddmanager.dragStop(this,e),this.handleElement.is(e.target)&&this.element.trigger("focus"),t.ui.mouse.prototype._mouseUp.call(this,e)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp(new t.Event("mouseup",{target:this.element[0]})):this._clear(),this},_getHandle:function(e){return this.options.handle?!!t(e.target).closest(this.element.find(this.options.handle)).length:!0},_setHandleClassName:function(){this.handleElement=this.options.handle?this.element.find(this.options.handle):this.element,this._addClass(this.handleElement,"ui-draggable-handle")},_removeHandleClassName:function(){this._removeClass(this.handleElement,"ui-draggable-handle")},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper),n=s?t(i.helper.apply(this.element[0],[e])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return n.parents("body").length||n.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s&&n[0]===this.element[0]&&this._setPositionRelative(),n[0]===this.element[0]||/(fixed|absolute)/.test(n.css("position"))||n.css("position","absolute"),n},_setPositionRelative:function(){/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative")},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_isRootNode:function(t){return/(html|body)/i.test(t.tagName)||t===this.document[0]},_getParentOffset:function(){var e=this.offsetParent.offset(),i=this.document[0];return"absolute"===this.cssPosition&&this.scrollParent[0]!==i&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),this._isRootNode(this.offsetParent[0])&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var t=this.element.position(),e=this._isRootNode(this.scrollParent[0]);return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+(e?0:this.scrollParent.scrollTop()),left:t.left-(parseInt(this.helper.css("left"),10)||0)+(e?0:this.scrollParent.scrollLeft())} -},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options,o=this.document[0];return this.relativeContainer=null,n.containment?"window"===n.containment?(this.containment=[t(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,t(window).scrollLeft()+t(window).width()-this.helperProportions.width-this.margins.left,t(window).scrollTop()+(t(window).height()||o.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):"document"===n.containment?(this.containment=[0,0,t(o).width()-this.helperProportions.width-this.margins.left,(t(o).height()||o.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):n.containment.constructor===Array?(this.containment=n.containment,void 0):("parent"===n.containment&&(n.containment=this.helper[0].parentNode),i=t(n.containment),s=i[0],s&&(e=/(scroll|auto)/.test(i.css("overflow")),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(e?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(e?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relativeContainer=i),void 0):(this.containment=null,void 0)},_convertPositionTo:function(t,e){e||(e=this.position);var i="absolute"===t?1:-1,s=this._isRootNode(this.scrollParent[0]);return{top:e.top+this.offset.relative.top*i+this.offset.parent.top*i-("fixed"===this.cssPosition?-this.offset.scroll.top:s?0:this.offset.scroll.top)*i,left:e.left+this.offset.relative.left*i+this.offset.parent.left*i-("fixed"===this.cssPosition?-this.offset.scroll.left:s?0:this.offset.scroll.left)*i}},_generatePosition:function(t,e){var i,s,n,o,a=this.options,r=this._isRootNode(this.scrollParent[0]),h=t.pageX,l=t.pageY;return r&&this.offset.scroll||(this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}),e&&(this.containment&&(this.relativeContainer?(s=this.relativeContainer.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,t.pageX-this.offset.click.lefti[2]&&(h=i[2]+this.offset.click.left),t.pageY-this.offset.click.top>i[3]&&(l=i[3]+this.offset.click.top)),a.grid&&(n=a.grid[1]?this.originalPageY+Math.round((l-this.originalPageY)/a.grid[1])*a.grid[1]:this.originalPageY,l=i?n-this.offset.click.top>=i[1]||n-this.offset.click.top>i[3]?n:n-this.offset.click.top>=i[1]?n-a.grid[1]:n+a.grid[1]:n,o=a.grid[0]?this.originalPageX+Math.round((h-this.originalPageX)/a.grid[0])*a.grid[0]:this.originalPageX,h=i?o-this.offset.click.left>=i[0]||o-this.offset.click.left>i[2]?o:o-this.offset.click.left>=i[0]?o-a.grid[0]:o+a.grid[0]:o),"y"===a.axis&&(h=this.originalPageX),"x"===a.axis&&(l=this.originalPageY)),{top:l-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:r?0:this.offset.scroll.top),left:h-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:r?0:this.offset.scroll.left)}},_clear:function(){this._removeClass(this.helper,"ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_trigger:function(e,i,s){return s=s||this._uiHash(),t.ui.plugin.call(this,e,[i,s,this],!0),/^(drag|start|stop)/.test(e)&&(this.positionAbs=this._convertPositionTo("absolute"),s.offset=this.positionAbs),t.Widget.prototype._trigger.call(this,e,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),t.ui.plugin.add("draggable","connectToSortable",{start:function(e,i,s){var n=t.extend({},i,{item:s.element});s.sortables=[],t(s.options.connectToSortable).each(function(){var i=t(this).sortable("instance");i&&!i.options.disabled&&(s.sortables.push(i),i.refreshPositions(),i._trigger("activate",e,n))})},stop:function(e,i,s){var n=t.extend({},i,{item:s.element});s.cancelHelperRemoval=!1,t.each(s.sortables,function(){var t=this;t.isOver?(t.isOver=0,s.cancelHelperRemoval=!0,t.cancelHelperRemoval=!1,t._storedCSS={position:t.placeholder.css("position"),top:t.placeholder.css("top"),left:t.placeholder.css("left")},t._mouseStop(e),t.options.helper=t.options._helper):(t.cancelHelperRemoval=!0,t._trigger("deactivate",e,n))})},drag:function(e,i,s){t.each(s.sortables,function(){var n=!1,o=this;o.positionAbs=s.positionAbs,o.helperProportions=s.helperProportions,o.offset.click=s.offset.click,o._intersectsWith(o.containerCache)&&(n=!0,t.each(s.sortables,function(){return this.positionAbs=s.positionAbs,this.helperProportions=s.helperProportions,this.offset.click=s.offset.click,this!==o&&this._intersectsWith(this.containerCache)&&t.contains(o.element[0],this.element[0])&&(n=!1),n})),n?(o.isOver||(o.isOver=1,s._parent=i.helper.parent(),o.currentItem=i.helper.appendTo(o.element).data("ui-sortable-item",!0),o.options._helper=o.options.helper,o.options.helper=function(){return i.helper[0]},e.target=o.currentItem[0],o._mouseCapture(e,!0),o._mouseStart(e,!0,!0),o.offset.click.top=s.offset.click.top,o.offset.click.left=s.offset.click.left,o.offset.parent.left-=s.offset.parent.left-o.offset.parent.left,o.offset.parent.top-=s.offset.parent.top-o.offset.parent.top,s._trigger("toSortable",e),s.dropped=o.element,t.each(s.sortables,function(){this.refreshPositions()}),s.currentItem=s.element,o.fromOutside=s),o.currentItem&&(o._mouseDrag(e),i.position=o.position)):o.isOver&&(o.isOver=0,o.cancelHelperRemoval=!0,o.options._revert=o.options.revert,o.options.revert=!1,o._trigger("out",e,o._uiHash(o)),o._mouseStop(e,!0),o.options.revert=o.options._revert,o.options.helper=o.options._helper,o.placeholder&&o.placeholder.remove(),i.helper.appendTo(s._parent),s._refreshOffsets(e),i.position=s._generatePosition(e,!0),s._trigger("fromSortable",e),s.dropped=!1,t.each(s.sortables,function(){this.refreshPositions()}))})}}),t.ui.plugin.add("draggable","cursor",{start:function(e,i,s){var n=t("body"),o=s.options;n.css("cursor")&&(o._cursor=n.css("cursor")),n.css("cursor",o.cursor)},stop:function(e,i,s){var n=s.options;n._cursor&&t("body").css("cursor",n._cursor)}}),t.ui.plugin.add("draggable","opacity",{start:function(e,i,s){var n=t(i.helper),o=s.options;n.css("opacity")&&(o._opacity=n.css("opacity")),n.css("opacity",o.opacity)},stop:function(e,i,s){var n=s.options;n._opacity&&t(i.helper).css("opacity",n._opacity)}}),t.ui.plugin.add("draggable","scroll",{start:function(t,e,i){i.scrollParentNotHidden||(i.scrollParentNotHidden=i.helper.scrollParent(!1)),i.scrollParentNotHidden[0]!==i.document[0]&&"HTML"!==i.scrollParentNotHidden[0].tagName&&(i.overflowOffset=i.scrollParentNotHidden.offset())},drag:function(e,i,s){var n=s.options,o=!1,a=s.scrollParentNotHidden[0],r=s.document[0];a!==r&&"HTML"!==a.tagName?(n.axis&&"x"===n.axis||(s.overflowOffset.top+a.offsetHeight-e.pageY=0;d--)h=s.snapElements[d].left-s.margins.left,l=h+s.snapElements[d].width,c=s.snapElements[d].top-s.margins.top,u=c+s.snapElements[d].height,h-g>_||m>l+g||c-g>b||v>u+g||!t.contains(s.snapElements[d].item.ownerDocument,s.snapElements[d].item)?(s.snapElements[d].snapping&&s.options.snap.release&&s.options.snap.release.call(s.element,e,t.extend(s._uiHash(),{snapItem:s.snapElements[d].item})),s.snapElements[d].snapping=!1):("inner"!==f.snapMode&&(n=g>=Math.abs(c-b),o=g>=Math.abs(u-v),a=g>=Math.abs(h-_),r=g>=Math.abs(l-m),n&&(i.position.top=s._convertPositionTo("relative",{top:c-s.helperProportions.height,left:0}).top),o&&(i.position.top=s._convertPositionTo("relative",{top:u,left:0}).top),a&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h-s.helperProportions.width}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l}).left)),p=n||o||a||r,"outer"!==f.snapMode&&(n=g>=Math.abs(c-v),o=g>=Math.abs(u-b),a=g>=Math.abs(h-m),r=g>=Math.abs(l-_),n&&(i.position.top=s._convertPositionTo("relative",{top:c,left:0}).top),o&&(i.position.top=s._convertPositionTo("relative",{top:u-s.helperProportions.height,left:0}).top),a&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l-s.helperProportions.width}).left)),!s.snapElements[d].snapping&&(n||o||a||r||p)&&s.options.snap.snap&&s.options.snap.snap.call(s.element,e,t.extend(s._uiHash(),{snapItem:s.snapElements[d].item})),s.snapElements[d].snapping=n||o||a||r||p)}}),t.ui.plugin.add("draggable","stack",{start:function(e,i,s){var n,o=s.options,a=t.makeArray(t(o.stack)).sort(function(e,i){return(parseInt(t(e).css("zIndex"),10)||0)-(parseInt(t(i).css("zIndex"),10)||0)});a.length&&(n=parseInt(t(a[0]).css("zIndex"),10)||0,t(a).each(function(e){t(this).css("zIndex",n+e)}),this.css("zIndex",n+a.length))}}),t.ui.plugin.add("draggable","zIndex",{start:function(e,i,s){var n=t(i.helper),o=s.options;n.css("zIndex")&&(o._zIndex=n.css("zIndex")),n.css("zIndex",o.zIndex)},stop:function(e,i,s){var n=s.options;n._zIndex&&t(i.helper).css("zIndex",n._zIndex)}}),t.ui.draggable,t.widget("ui.resizable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return e[s]>0?!0:(e[s]=1,n=e[s]>0,e[s]=0,n)},_create:function(){var e,i=this.options,s=this;this._addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!i.aspectRatio,aspectRatio:i.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:i.helper||i.ghost||i.animate?i.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(t("
          ").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,e={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(e),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(e),this._proportionallyResize()),this._setupHandles(),i.autoHide&&t(this.element).on("mouseenter",function(){i.disabled||(s._removeClass("ui-resizable-autohide"),s._handles.show())}).on("mouseleave",function(){i.disabled||s.resizing||(s._addClass("ui-resizable-autohide"),s._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;default:}},_setupHandles:function(){var e,i,s,n,o,a=this.options,r=this;if(this.handles=a.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=t(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),s=this.handles.split(","),this.handles={},i=0;s.length>i;i++)e=t.trim(s[i]),n="ui-resizable-"+e,o=t("
          "),this._addClass(o,"ui-resizable-handle "+n),o.css({zIndex:a.zIndex}),this.handles[e]=".ui-resizable-"+e,this.element.append(o);this._renderAxis=function(e){var i,s,n,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=t(this.handles[i]),this._on(this.handles[i],{mousedown:r._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,o),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){r.resizing||(this.className&&(o=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=o&&o[1]?o[1]:"se")}),a.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(e){var i,s,n,o=this.options,a=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),o.containment&&(i+=t(o.containment).scrollLeft()||0,s+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:a.width(),height:a.height()},this.originalSize=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.sizeDiff={width:a.outerWidth()-a.width(),height:a.outerHeight()-a.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:e.pageX,top:e.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===n?this.axis+"-resize":n),this._addClass("ui-resizable-resizing"),this._propagate("start",e),!0},_mouseDrag:function(e){var i,s,n=this.originalMousePosition,o=this.axis,a=e.pageX-n.left||0,r=e.pageY-n.top||0,h=this._change[o];return this._updatePrevProperties(),h?(i=h.apply(this,[e,a,r]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",e,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,o,a,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&this._hasScroll(i[0],"left")?0:c.sizeDiff.height,o=s?0:c.sizeDiff.width,a={width:c.helper.width()-o,height:c.helper.height()-n},r=parseFloat(c.element.css("left"))+(c.position.left-c.originalPosition.left)||null,h=parseFloat(c.element.css("top"))+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(a,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,n,o,a=this.options;o={minWidth:this._isNumber(a.minWidth)?a.minWidth:0,maxWidth:this._isNumber(a.maxWidth)?a.maxWidth:1/0,minHeight:this._isNumber(a.minHeight)?a.minHeight:0,maxHeight:this._isNumber(a.maxHeight)?a.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,s=o.minWidth/this.aspectRatio,i=o.maxHeight*this.aspectRatio,n=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),s>o.minHeight&&(o.minHeight=s),o.maxWidth>i&&(o.maxWidth=i),o.maxHeight>n&&(o.maxHeight=n)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidtht.width,a=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,r=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),a&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=r-e.minWidth),s&&l&&(t.left=r-e.maxWidth),a&&c&&(t.top=h-e.minHeight),n&&c&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];4>e;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;this._proportionallyResizeElements.length>e;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("
          "),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).resizable("instance"),s=i.options,n=i._proportionallyResizeElements,o=n.length&&/textarea/i.test(n[0].nodeName),a=o&&i._hasScroll(n[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-a},l=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,c=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var e,i,s,n,o,a,r,h=t(this).resizable("instance"),l=h.options,c=h.element,u=l.containment,d=u instanceof t?u.get(0):/parent/.test(u)?c.parent().get(0):u;d&&(h.containerElement=t(d),/document/.test(u)||u===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(e=t(d),i=[],t(["Top","Right","Left","Bottom"]).each(function(t,s){i[t]=h._num(e.css("padding"+s))}),h.containerOffset=e.offset(),h.containerPosition=e.position(),h.containerSize={height:e.innerHeight()-i[3],width:e.innerWidth()-i[1]},s=h.containerOffset,n=h.containerSize.height,o=h.containerSize.width,a=h._hasScroll(d,"left")?d.scrollWidth:o,r=h._hasScroll(d)?d.scrollHeight:n,h.parentData={element:d,left:s.left,top:s.top,width:a,height:r}))},resize:function(e){var i,s,n,o,a=t(this).resizable("instance"),r=a.options,h=a.containerOffset,l=a.position,c=a._aspectRatio||e.shiftKey,u={top:0,left:0},d=a.containerElement,p=!0;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(a._helper?h.left:0)&&(a.size.width=a.size.width+(a._helper?a.position.left-h.left:a.position.left-u.left),c&&(a.size.height=a.size.width/a.aspectRatio,p=!1),a.position.left=r.helper?h.left:0),l.top<(a._helper?h.top:0)&&(a.size.height=a.size.height+(a._helper?a.position.top-h.top:a.position.top),c&&(a.size.width=a.size.height*a.aspectRatio,p=!1),a.position.top=a._helper?h.top:0),n=a.containerElement.get(0)===a.element.parent().get(0),o=/relative|absolute/.test(a.containerElement.css("position")),n&&o?(a.offset.left=a.parentData.left+a.position.left,a.offset.top=a.parentData.top+a.position.top):(a.offset.left=a.element.offset().left,a.offset.top=a.element.offset().top),i=Math.abs(a.sizeDiff.width+(a._helper?a.offset.left-u.left:a.offset.left-h.left)),s=Math.abs(a.sizeDiff.height+(a._helper?a.offset.top-u.top:a.offset.top-h.top)),i+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-i,c&&(a.size.height=a.size.width/a.aspectRatio,p=!1)),s+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-s,c&&(a.size.width=a.size.height*a.aspectRatio,p=!1)),p||(a.position.left=a.prevPosition.left,a.position.top=a.prevPosition.top,a.size.width=a.prevSize.width,a.size.height=a.prevSize.height)},stop:function(){var e=t(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.containerPosition,o=e.containerElement,a=t(e.helper),r=a.offset(),h=a.outerWidth()-e.sizeDiff.width,l=a.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).resizable("instance"),i=e.options;t(i.alsoResize).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseFloat(e.width()),height:parseFloat(e.height()),left:parseFloat(e.css("left")),top:parseFloat(e.css("top"))})})},resize:function(e,i){var s=t(this).resizable("instance"),n=s.options,o=s.originalSize,a=s.originalPosition,r={height:s.size.height-o.height||0,width:s.size.width-o.width||0,top:s.position.top-a.top||0,left:s.position.left-a.left||0};t(n.alsoResize).each(function(){var e=t(this),s=t(this).data("ui-resizable-alsoresize"),n={},o=e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,function(t,e){var i=(s[e]||0)+(r[e]||0);i&&i>=0&&(n[e]=i||null)}),e.css(n)})},stop:function(){t(this).removeData("ui-resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).resizable("instance"),i=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:i.height,width:i.width,margin:0,left:0,top:0}),e._addClass(e.ghost,"ui-resizable-ghost"),t.uiBackCompat!==!1&&"string"==typeof e.options.ghost&&e.ghost.addClass(this.options.ghost),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).resizable("instance");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).resizable("instance");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e,i=t(this).resizable("instance"),s=i.options,n=i.size,o=i.originalSize,a=i.originalPosition,r=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,c=h[1]||1,u=Math.round((n.width-o.width)/l)*l,d=Math.round((n.height-o.height)/c)*c,p=o.width+u,f=o.height+d,g=s.maxWidth&&p>s.maxWidth,m=s.maxHeight&&f>s.maxHeight,_=s.minWidth&&s.minWidth>p,v=s.minHeight&&s.minHeight>f;s.grid=h,_&&(p+=l),v&&(f+=c),g&&(p-=l),m&&(f-=c),/^(se|s|e)$/.test(r)?(i.size.width=p,i.size.height=f):/^(ne)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.top=a.top-d):/^(sw)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.left=a.left-u):((0>=f-c||0>=p-l)&&(e=i._getPaddingPlusBorderDimensions(this)),f-c>0?(i.size.height=f,i.position.top=a.top-d):(f=c-e.height,i.size.height=f,i.position.top=a.top+o.height-f),p-l>0?(i.size.width=p,i.position.left=a.left-u):(p=l-e.width,i.size.width=p,i.position.left=a.left+o.width-p))}}),t.ui.resizable,t.widget("ui.dialog",{version:"1.12.1",options:{appendTo:"body",autoOpen:!0,buttons:[],classes:{"ui-dialog":"ui-corner-all","ui-dialog-titlebar":"ui-corner-all"},closeOnEscape:!0,closeText:"Close",draggable:!0,hide:null,height:"auto",maxHeight:null,maxWidth:null,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(e){var i=t(this).css(e).offset().top;0>i&&t(this).css("top",e.top-i)}},resizable:!0,show:null,title:null,width:300,beforeClose:null,close:null,drag:null,dragStart:null,dragStop:null,focus:null,open:null,resize:null,resizeStart:null,resizeStop:null},sizeRelatedOptions:{buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},resizableRelatedOptions:{maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},_create:function(){this.originalCss={display:this.element[0].style.display,width:this.element[0].style.width,minHeight:this.element[0].style.minHeight,maxHeight:this.element[0].style.maxHeight,height:this.element[0].style.height},this.originalPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.originalTitle=this.element.attr("title"),null==this.options.title&&null!=this.originalTitle&&(this.options.title=this.originalTitle),this.options.disabled&&(this.options.disabled=!1),this._createWrapper(),this.element.show().removeAttr("title").appendTo(this.uiDialog),this._addClass("ui-dialog-content","ui-widget-content"),this._createTitlebar(),this._createButtonPane(),this.options.draggable&&t.fn.draggable&&this._makeDraggable(),this.options.resizable&&t.fn.resizable&&this._makeResizable(),this._isOpen=!1,this._trackFocus()},_init:function(){this.options.autoOpen&&this.open()},_appendTo:function(){var e=this.options.appendTo;return e&&(e.jquery||e.nodeType)?t(e):this.document.find(e||"body").eq(0)},_destroy:function(){var t,e=this.originalPosition;this._untrackInstance(),this._destroyOverlay(),this.element.removeUniqueId().css(this.originalCss).detach(),this.uiDialog.remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),t=e.parent.children().eq(e.index),t.length&&t[0]!==this.element[0]?t.before(this.element):e.parent.append(this.element)},widget:function(){return this.uiDialog -},disable:t.noop,enable:t.noop,close:function(e){var i=this;this._isOpen&&this._trigger("beforeClose",e)!==!1&&(this._isOpen=!1,this._focusedElement=null,this._destroyOverlay(),this._untrackInstance(),this.opener.filter(":focusable").trigger("focus").length||t.ui.safeBlur(t.ui.safeActiveElement(this.document[0])),this._hide(this.uiDialog,this.options.hide,function(){i._trigger("close",e)}))},isOpen:function(){return this._isOpen},moveToTop:function(){this._moveToTop()},_moveToTop:function(e,i){var s=!1,n=this.uiDialog.siblings(".ui-front:visible").map(function(){return+t(this).css("z-index")}).get(),o=Math.max.apply(null,n);return o>=+this.uiDialog.css("z-index")&&(this.uiDialog.css("z-index",o+1),s=!0),s&&!i&&this._trigger("focus",e),s},open:function(){var e=this;return this._isOpen?(this._moveToTop()&&this._focusTabbable(),void 0):(this._isOpen=!0,this.opener=t(t.ui.safeActiveElement(this.document[0])),this._size(),this._position(),this._createOverlay(),this._moveToTop(null,!0),this.overlay&&this.overlay.css("z-index",this.uiDialog.css("z-index")-1),this._show(this.uiDialog,this.options.show,function(){e._focusTabbable(),e._trigger("focus")}),this._makeFocusTarget(),this._trigger("open"),void 0)},_focusTabbable:function(){var t=this._focusedElement;t||(t=this.element.find("[autofocus]")),t.length||(t=this.element.find(":tabbable")),t.length||(t=this.uiDialogButtonPane.find(":tabbable")),t.length||(t=this.uiDialogTitlebarClose.filter(":tabbable")),t.length||(t=this.uiDialog),t.eq(0).trigger("focus")},_keepFocus:function(e){function i(){var e=t.ui.safeActiveElement(this.document[0]),i=this.uiDialog[0]===e||t.contains(this.uiDialog[0],e);i||this._focusTabbable()}e.preventDefault(),i.call(this),this._delay(i)},_createWrapper:function(){this.uiDialog=t("
          ").hide().attr({tabIndex:-1,role:"dialog"}).appendTo(this._appendTo()),this._addClass(this.uiDialog,"ui-dialog","ui-widget ui-widget-content ui-front"),this._on(this.uiDialog,{keydown:function(e){if(this.options.closeOnEscape&&!e.isDefaultPrevented()&&e.keyCode&&e.keyCode===t.ui.keyCode.ESCAPE)return e.preventDefault(),this.close(e),void 0;if(e.keyCode===t.ui.keyCode.TAB&&!e.isDefaultPrevented()){var i=this.uiDialog.find(":tabbable"),s=i.filter(":first"),n=i.filter(":last");e.target!==n[0]&&e.target!==this.uiDialog[0]||e.shiftKey?e.target!==s[0]&&e.target!==this.uiDialog[0]||!e.shiftKey||(this._delay(function(){n.trigger("focus")}),e.preventDefault()):(this._delay(function(){s.trigger("focus")}),e.preventDefault())}},mousedown:function(t){this._moveToTop(t)&&this._focusTabbable()}}),this.element.find("[aria-describedby]").length||this.uiDialog.attr({"aria-describedby":this.element.uniqueId().attr("id")})},_createTitlebar:function(){var e;this.uiDialogTitlebar=t("
          "),this._addClass(this.uiDialogTitlebar,"ui-dialog-titlebar","ui-widget-header ui-helper-clearfix"),this._on(this.uiDialogTitlebar,{mousedown:function(e){t(e.target).closest(".ui-dialog-titlebar-close")||this.uiDialog.trigger("focus")}}),this.uiDialogTitlebarClose=t("").button({label:t("").text(this.options.closeText).html(),icon:"ui-icon-closethick",showLabel:!1}).appendTo(this.uiDialogTitlebar),this._addClass(this.uiDialogTitlebarClose,"ui-dialog-titlebar-close"),this._on(this.uiDialogTitlebarClose,{click:function(t){t.preventDefault(),this.close(t)}}),e=t("").uniqueId().prependTo(this.uiDialogTitlebar),this._addClass(e,"ui-dialog-title"),this._title(e),this.uiDialogTitlebar.prependTo(this.uiDialog),this.uiDialog.attr({"aria-labelledby":e.attr("id")})},_title:function(t){this.options.title?t.text(this.options.title):t.html(" ")},_createButtonPane:function(){this.uiDialogButtonPane=t("
          "),this._addClass(this.uiDialogButtonPane,"ui-dialog-buttonpane","ui-widget-content ui-helper-clearfix"),this.uiButtonSet=t("
          ").appendTo(this.uiDialogButtonPane),this._addClass(this.uiButtonSet,"ui-dialog-buttonset"),this._createButtons()},_createButtons:function(){var e=this,i=this.options.buttons;return this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),t.isEmptyObject(i)||t.isArray(i)&&!i.length?(this._removeClass(this.uiDialog,"ui-dialog-buttons"),void 0):(t.each(i,function(i,s){var n,o;s=t.isFunction(s)?{click:s,text:i}:s,s=t.extend({type:"button"},s),n=s.click,o={icon:s.icon,iconPosition:s.iconPosition,showLabel:s.showLabel,icons:s.icons,text:s.text},delete s.click,delete s.icon,delete s.iconPosition,delete s.showLabel,delete s.icons,"boolean"==typeof s.text&&delete s.text,t("",s).button(o).appendTo(e.uiButtonSet).on("click",function(){n.apply(e.element[0],arguments)})}),this._addClass(this.uiDialog,"ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog),void 0)},_makeDraggable:function(){function e(t){return{position:t.position,offset:t.offset}}var i=this,s=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(s,n){i._addClass(t(this),"ui-dialog-dragging"),i._blockFrames(),i._trigger("dragStart",s,e(n))},drag:function(t,s){i._trigger("drag",t,e(s))},stop:function(n,o){var a=o.offset.left-i.document.scrollLeft(),r=o.offset.top-i.document.scrollTop();s.position={my:"left top",at:"left"+(a>=0?"+":"")+a+" "+"top"+(r>=0?"+":"")+r,of:i.window},i._removeClass(t(this),"ui-dialog-dragging"),i._unblockFrames(),i._trigger("dragStop",n,e(o))}})},_makeResizable:function(){function e(t){return{originalPosition:t.originalPosition,originalSize:t.originalSize,position:t.position,size:t.size}}var i=this,s=this.options,n=s.resizable,o=this.uiDialog.css("position"),a="string"==typeof n?n:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:s.maxWidth,maxHeight:s.maxHeight,minWidth:s.minWidth,minHeight:this._minHeight(),handles:a,start:function(s,n){i._addClass(t(this),"ui-dialog-resizing"),i._blockFrames(),i._trigger("resizeStart",s,e(n))},resize:function(t,s){i._trigger("resize",t,e(s))},stop:function(n,o){var a=i.uiDialog.offset(),r=a.left-i.document.scrollLeft(),h=a.top-i.document.scrollTop();s.height=i.uiDialog.height(),s.width=i.uiDialog.width(),s.position={my:"left top",at:"left"+(r>=0?"+":"")+r+" "+"top"+(h>=0?"+":"")+h,of:i.window},i._removeClass(t(this),"ui-dialog-resizing"),i._unblockFrames(),i._trigger("resizeStop",n,e(o))}}).css("position",o)},_trackFocus:function(){this._on(this.widget(),{focusin:function(e){this._makeFocusTarget(),this._focusedElement=t(e.target)}})},_makeFocusTarget:function(){this._untrackInstance(),this._trackingInstances().unshift(this)},_untrackInstance:function(){var e=this._trackingInstances(),i=t.inArray(this,e);-1!==i&&e.splice(i,1)},_trackingInstances:function(){var t=this.document.data("ui-dialog-instances");return t||(t=[],this.document.data("ui-dialog-instances",t)),t},_minHeight:function(){var t=this.options;return"auto"===t.height?t.minHeight:Math.min(t.minHeight,t.height)},_position:function(){var t=this.uiDialog.is(":visible");t||this.uiDialog.show(),this.uiDialog.position(this.options.position),t||this.uiDialog.hide()},_setOptions:function(e){var i=this,s=!1,n={};t.each(e,function(t,e){i._setOption(t,e),t in i.sizeRelatedOptions&&(s=!0),t in i.resizableRelatedOptions&&(n[t]=e)}),s&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",n)},_setOption:function(e,i){var s,n,o=this.uiDialog;"disabled"!==e&&(this._super(e,i),"appendTo"===e&&this.uiDialog.appendTo(this._appendTo()),"buttons"===e&&this._createButtons(),"closeText"===e&&this.uiDialogTitlebarClose.button({label:t("").text(""+this.options.closeText).html()}),"draggable"===e&&(s=o.is(":data(ui-draggable)"),s&&!i&&o.draggable("destroy"),!s&&i&&this._makeDraggable()),"position"===e&&this._position(),"resizable"===e&&(n=o.is(":data(ui-resizable)"),n&&!i&&o.resizable("destroy"),n&&"string"==typeof i&&o.resizable("option","handles",i),n||i===!1||this._makeResizable()),"title"===e&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")))},_size:function(){var t,e,i,s=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),s.minWidth>s.width&&(s.width=s.minWidth),t=this.uiDialog.css({height:"auto",width:s.width}).outerHeight(),e=Math.max(0,s.minHeight-t),i="number"==typeof s.maxHeight?Math.max(0,s.maxHeight-t):"none","auto"===s.height?this.element.css({minHeight:e,maxHeight:i,height:"auto"}):this.element.height(Math.max(0,s.height-t)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var e=t(this);return t("
          ").css({position:"absolute",width:e.outerWidth(),height:e.outerHeight()}).appendTo(e.parent()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(e){return t(e.target).closest(".ui-dialog").length?!0:!!t(e.target).closest(".ui-datepicker").length},_createOverlay:function(){if(this.options.modal){var e=!0;this._delay(function(){e=!1}),this.document.data("ui-dialog-overlays")||this._on(this.document,{focusin:function(t){e||this._allowInteraction(t)||(t.preventDefault(),this._trackingInstances()[0]._focusTabbable())}}),this.overlay=t("
          ").appendTo(this._appendTo()),this._addClass(this.overlay,null,"ui-widget-overlay ui-front"),this._on(this.overlay,{mousedown:"_keepFocus"}),this.document.data("ui-dialog-overlays",(this.document.data("ui-dialog-overlays")||0)+1)}},_destroyOverlay:function(){if(this.options.modal&&this.overlay){var t=this.document.data("ui-dialog-overlays")-1;t?this.document.data("ui-dialog-overlays",t):(this._off(this.document,"focusin"),this.document.removeData("ui-dialog-overlays")),this.overlay.remove(),this.overlay=null}}}),t.uiBackCompat!==!1&&t.widget("ui.dialog",t.ui.dialog,{options:{dialogClass:""},_createWrapper:function(){this._super(),this.uiDialog.addClass(this.options.dialogClass)},_setOption:function(t,e){"dialogClass"===t&&this.uiDialog.removeClass(this.options.dialogClass).addClass(e),this._superApply(arguments)}}),t.ui.dialog,t.widget("ui.droppable",{version:"1.12.1",widgetEventPrefix:"drop",options:{accept:"*",addClasses:!0,greedy:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var e,i=this.options,s=i.accept;this.isover=!1,this.isout=!0,this.accept=t.isFunction(s)?s:function(t){return t.is(s)},this.proportions=function(){return arguments.length?(e=arguments[0],void 0):e?e:e={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight}},this._addToManager(i.scope),i.addClasses&&this._addClass("ui-droppable")},_addToManager:function(e){t.ui.ddmanager.droppables[e]=t.ui.ddmanager.droppables[e]||[],t.ui.ddmanager.droppables[e].push(this)},_splice:function(t){for(var e=0;t.length>e;e++)t[e]===this&&t.splice(e,1)},_destroy:function(){var e=t.ui.ddmanager.droppables[this.options.scope];this._splice(e)},_setOption:function(e,i){if("accept"===e)this.accept=t.isFunction(i)?i:function(t){return t.is(i)};else if("scope"===e){var s=t.ui.ddmanager.droppables[this.options.scope];this._splice(s),this._addToManager(i)}this._super(e,i)},_activate:function(e){var i=t.ui.ddmanager.current;this._addActiveClass(),i&&this._trigger("activate",e,this.ui(i))},_deactivate:function(e){var i=t.ui.ddmanager.current;this._removeActiveClass(),i&&this._trigger("deactivate",e,this.ui(i))},_over:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this._addHoverClass(),this._trigger("over",e,this.ui(i)))},_out:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this._removeHoverClass(),this._trigger("out",e,this.ui(i)))},_drop:function(e,i){var s=i||t.ui.ddmanager.current,n=!1;return s&&(s.currentItem||s.element)[0]!==this.element[0]?(this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function(){var i=t(this).droppable("instance");return i.options.greedy&&!i.options.disabled&&i.options.scope===s.options.scope&&i.accept.call(i.element[0],s.currentItem||s.element)&&v(s,t.extend(i,{offset:i.element.offset()}),i.options.tolerance,e)?(n=!0,!1):void 0}),n?!1:this.accept.call(this.element[0],s.currentItem||s.element)?(this._removeActiveClass(),this._removeHoverClass(),this._trigger("drop",e,this.ui(s)),this.element):!1):!1},ui:function(t){return{draggable:t.currentItem||t.element,helper:t.helper,position:t.position,offset:t.positionAbs}},_addHoverClass:function(){this._addClass("ui-droppable-hover")},_removeHoverClass:function(){this._removeClass("ui-droppable-hover")},_addActiveClass:function(){this._addClass("ui-droppable-active")},_removeActiveClass:function(){this._removeClass("ui-droppable-active")}});var v=t.ui.intersect=function(){function t(t,e,i){return t>=e&&e+i>t}return function(e,i,s,n){if(!i.offset)return!1;var o=(e.positionAbs||e.position.absolute).left+e.margins.left,a=(e.positionAbs||e.position.absolute).top+e.margins.top,r=o+e.helperProportions.width,h=a+e.helperProportions.height,l=i.offset.left,c=i.offset.top,u=l+i.proportions().width,d=c+i.proportions().height;switch(s){case"fit":return o>=l&&u>=r&&a>=c&&d>=h;case"intersect":return o+e.helperProportions.width/2>l&&u>r-e.helperProportions.width/2&&a+e.helperProportions.height/2>c&&d>h-e.helperProportions.height/2;case"pointer":return t(n.pageY,c,i.proportions().height)&&t(n.pageX,l,i.proportions().width);case"touch":return(a>=c&&d>=a||h>=c&&d>=h||c>a&&h>d)&&(o>=l&&u>=o||r>=l&&u>=r||l>o&&r>u);default:return!1}}}();t.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(e,i){var s,n,o=t.ui.ddmanager.droppables[e.options.scope]||[],a=i?i.type:null,r=(e.currentItem||e.element).find(":data(ui-droppable)").addBack();t:for(s=0;o.length>s;s++)if(!(o[s].options.disabled||e&&!o[s].accept.call(o[s].element[0],e.currentItem||e.element))){for(n=0;r.length>n;n++)if(r[n]===o[s].element[0]){o[s].proportions().height=0;continue t}o[s].visible="none"!==o[s].element.css("display"),o[s].visible&&("mousedown"===a&&o[s]._activate.call(o[s],i),o[s].offset=o[s].element.offset(),o[s].proportions({width:o[s].element[0].offsetWidth,height:o[s].element[0].offsetHeight}))}},drop:function(e,i){var s=!1;return t.each((t.ui.ddmanager.droppables[e.options.scope]||[]).slice(),function(){this.options&&(!this.options.disabled&&this.visible&&v(e,this,this.options.tolerance,i)&&(s=this._drop.call(this,i)||s),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],e.currentItem||e.element)&&(this.isout=!0,this.isover=!1,this._deactivate.call(this,i)))}),s},dragStart:function(e,i){e.element.parentsUntil("body").on("scroll.droppable",function(){e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)})},drag:function(e,i){e.options.refreshPositions&&t.ui.ddmanager.prepareOffsets(e,i),t.each(t.ui.ddmanager.droppables[e.options.scope]||[],function(){if(!this.options.disabled&&!this.greedyChild&&this.visible){var s,n,o,a=v(e,this,this.options.tolerance,i),r=!a&&this.isover?"isout":a&&!this.isover?"isover":null;r&&(this.options.greedy&&(n=this.options.scope,o=this.element.parents(":data(ui-droppable)").filter(function(){return t(this).droppable("instance").options.scope===n}),o.length&&(s=t(o[0]).droppable("instance"),s.greedyChild="isover"===r)),s&&"isover"===r&&(s.isover=!1,s.isout=!0,s._out.call(s,i)),this[r]=!0,this["isout"===r?"isover":"isout"]=!1,this["isover"===r?"_over":"_out"].call(this,i),s&&"isout"===r&&(s.isout=!1,s.isover=!0,s._over.call(s,i)))}})},dragStop:function(e,i){e.element.parentsUntil("body").off("scroll.droppable"),e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)}},t.uiBackCompat!==!1&&t.widget("ui.droppable",t.ui.droppable,{options:{hoverClass:!1,activeClass:!1},_addActiveClass:function(){this._super(),this.options.activeClass&&this.element.addClass(this.options.activeClass)},_removeActiveClass:function(){this._super(),this.options.activeClass&&this.element.removeClass(this.options.activeClass)},_addHoverClass:function(){this._super(),this.options.hoverClass&&this.element.addClass(this.options.hoverClass)},_removeHoverClass:function(){this._super(),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass)}}),t.ui.droppable,t.widget("ui.progressbar",{version:"1.12.1",options:{classes:{"ui-progressbar":"ui-corner-all","ui-progressbar-value":"ui-corner-left","ui-progressbar-complete":"ui-corner-right"},max:100,value:0,change:null,complete:null},min:0,_create:function(){this.oldValue=this.options.value=this._constrainedValue(),this.element.attr({role:"progressbar","aria-valuemin":this.min}),this._addClass("ui-progressbar","ui-widget ui-widget-content"),this.valueDiv=t("
          ").appendTo(this.element),this._addClass(this.valueDiv,"ui-progressbar-value","ui-widget-header"),this._refreshValue()},_destroy:function(){this.element.removeAttr("role aria-valuemin aria-valuemax aria-valuenow"),this.valueDiv.remove()},value:function(t){return void 0===t?this.options.value:(this.options.value=this._constrainedValue(t),this._refreshValue(),void 0)},_constrainedValue:function(t){return void 0===t&&(t=this.options.value),this.indeterminate=t===!1,"number"!=typeof t&&(t=0),this.indeterminate?!1:Math.min(this.options.max,Math.max(this.min,t))},_setOptions:function(t){var e=t.value;delete t.value,this._super(t),this.options.value=this._constrainedValue(e),this._refreshValue()},_setOption:function(t,e){"max"===t&&(e=Math.max(this.min,e)),this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t),this._toggleClass(null,"ui-state-disabled",!!t)},_percentage:function(){return this.indeterminate?100:100*(this.options.value-this.min)/(this.options.max-this.min)},_refreshValue:function(){var e=this.options.value,i=this._percentage();this.valueDiv.toggle(this.indeterminate||e>this.min).width(i.toFixed(0)+"%"),this._toggleClass(this.valueDiv,"ui-progressbar-complete",null,e===this.options.max)._toggleClass("ui-progressbar-indeterminate",null,this.indeterminate),this.indeterminate?(this.element.removeAttr("aria-valuenow"),this.overlayDiv||(this.overlayDiv=t("
          ").appendTo(this.valueDiv),this._addClass(this.overlayDiv,"ui-progressbar-overlay"))):(this.element.attr({"aria-valuemax":this.options.max,"aria-valuenow":e}),this.overlayDiv&&(this.overlayDiv.remove(),this.overlayDiv=null)),this.oldValue!==e&&(this.oldValue=e,this._trigger("change")),e===this.options.max&&this._trigger("complete")}}),t.widget("ui.selectable",t.ui.mouse,{version:"1.12.1",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var e=this;this._addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){e.elementPos=t(e.element[0]).offset(),e.selectees=t(e.options.filter,e.element[0]),e._addClass(e.selectees,"ui-selectee"),e.selectees.each(function(){var i=t(this),s=i.offset(),n={left:s.left-e.elementPos.left,top:s.top-e.elementPos.top};t.data(this,"selectable-item",{element:this,$element:i,left:n.left,top:n.top,right:n.left+i.outerWidth(),bottom:n.top+i.outerHeight(),startselected:!1,selected:i.hasClass("ui-selected"),selecting:i.hasClass("ui-selecting"),unselecting:i.hasClass("ui-unselecting")})})},this.refresh(),this._mouseInit(),this.helper=t("
          "),this._addClass(this.helper,"ui-selectable-helper")},_destroy:function(){this.selectees.removeData("selectable-item"),this._mouseDestroy()},_mouseStart:function(e){var i=this,s=this.options;this.opos=[e.pageX,e.pageY],this.elementPos=t(this.element[0]).offset(),this.options.disabled||(this.selectees=t(s.filter,this.element[0]),this._trigger("start",e),t(s.appendTo).append(this.helper),this.helper.css({left:e.pageX,top:e.pageY,width:0,height:0}),s.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var s=t.data(this,"selectable-item");s.startselected=!0,e.metaKey||e.ctrlKey||(i._removeClass(s.$element,"ui-selected"),s.selected=!1,i._addClass(s.$element,"ui-unselecting"),s.unselecting=!0,i._trigger("unselecting",e,{unselecting:s.element}))}),t(e.target).parents().addBack().each(function(){var s,n=t.data(this,"selectable-item");return n?(s=!e.metaKey&&!e.ctrlKey||!n.$element.hasClass("ui-selected"),i._removeClass(n.$element,s?"ui-unselecting":"ui-selected")._addClass(n.$element,s?"ui-selecting":"ui-unselecting"),n.unselecting=!s,n.selecting=s,n.selected=s,s?i._trigger("selecting",e,{selecting:n.element}):i._trigger("unselecting",e,{unselecting:n.element}),!1):void 0}))},_mouseDrag:function(e){if(this.dragged=!0,!this.options.disabled){var i,s=this,n=this.options,o=this.opos[0],a=this.opos[1],r=e.pageX,h=e.pageY;return o>r&&(i=r,r=o,o=i),a>h&&(i=h,h=a,a=i),this.helper.css({left:o,top:a,width:r-o,height:h-a}),this.selectees.each(function(){var i=t.data(this,"selectable-item"),l=!1,c={};i&&i.element!==s.element[0]&&(c.left=i.left+s.elementPos.left,c.right=i.right+s.elementPos.left,c.top=i.top+s.elementPos.top,c.bottom=i.bottom+s.elementPos.top,"touch"===n.tolerance?l=!(c.left>r||o>c.right||c.top>h||a>c.bottom):"fit"===n.tolerance&&(l=c.left>o&&r>c.right&&c.top>a&&h>c.bottom),l?(i.selected&&(s._removeClass(i.$element,"ui-selected"),i.selected=!1),i.unselecting&&(s._removeClass(i.$element,"ui-unselecting"),i.unselecting=!1),i.selecting||(s._addClass(i.$element,"ui-selecting"),i.selecting=!0,s._trigger("selecting",e,{selecting:i.element}))):(i.selecting&&((e.metaKey||e.ctrlKey)&&i.startselected?(s._removeClass(i.$element,"ui-selecting"),i.selecting=!1,s._addClass(i.$element,"ui-selected"),i.selected=!0):(s._removeClass(i.$element,"ui-selecting"),i.selecting=!1,i.startselected&&(s._addClass(i.$element,"ui-unselecting"),i.unselecting=!0),s._trigger("unselecting",e,{unselecting:i.element}))),i.selected&&(e.metaKey||e.ctrlKey||i.startselected||(s._removeClass(i.$element,"ui-selected"),i.selected=!1,s._addClass(i.$element,"ui-unselecting"),i.unselecting=!0,s._trigger("unselecting",e,{unselecting:i.element})))))}),!1}},_mouseStop:function(e){var i=this;return this.dragged=!1,t(".ui-unselecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");i._removeClass(s.$element,"ui-unselecting"),s.unselecting=!1,s.startselected=!1,i._trigger("unselected",e,{unselected:s.element})}),t(".ui-selecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");i._removeClass(s.$element,"ui-selecting")._addClass(s.$element,"ui-selected"),s.selecting=!1,s.selected=!0,s.startselected=!0,i._trigger("selected",e,{selected:s.element})}),this._trigger("stop",e),this.helper.remove(),!1}}),t.widget("ui.selectmenu",[t.ui.formResetMixin,{version:"1.12.1",defaultElement:"",widgetEventPrefix:"spin",options:{classes:{"ui-spinner":"ui-corner-all","ui-spinner-down":"ui-corner-br","ui-spinner-up":"ui-corner-tr"},culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),""!==this.value()&&this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var e=this._super(),i=this.element;return t.each(["min","max","step"],function(t,s){var n=i.attr(s);null!=n&&n.length&&(e[s]=n)}),e},_events:{keydown:function(t){this._start(t)&&this._keydown(t)&&t.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,void 0):(this._stop(),this._refresh(),this.previous!==this.element.val()&&this._trigger("change",t),void 0)},mousewheel:function(t,e){if(e){if(!this.spinning&&!this._start(t))return!1;this._spin((e>0?1:-1)*this.options.step,t),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(t)},100),t.preventDefault()}},"mousedown .ui-spinner-button":function(e){function i(){var e=this.element[0]===t.ui.safeActiveElement(this.document[0]);e||(this.element.trigger("focus"),this.previous=s,this._delay(function(){this.previous=s}))}var s;s=this.element[0]===t.ui.safeActiveElement(this.document[0])?this.previous:this.element.val(),e.preventDefault(),i.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,i.call(this)}),this._start(e)!==!1&&this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(e){return t(e.currentTarget).hasClass("ui-state-active")?this._start(e)===!1?!1:(this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e),void 0):void 0},"mouseleave .ui-spinner-button":"_stop"},_enhance:function(){this.uiSpinner=this.element.attr("autocomplete","off").wrap("").parent().append("")},_draw:function(){this._enhance(),this._addClass(this.uiSpinner,"ui-spinner","ui-widget ui-widget-content"),this._addClass("ui-spinner-input"),this.element.attr("role","spinbutton"),this.buttons=this.uiSpinner.children("a").attr("tabIndex",-1).attr("aria-hidden",!0).button({classes:{"ui-button":""}}),this._removeClass(this.buttons,"ui-corner-all"),this._addClass(this.buttons.first(),"ui-spinner-button ui-spinner-up"),this._addClass(this.buttons.last(),"ui-spinner-button ui-spinner-down"),this.buttons.first().button({icon:this.options.icons.up,showLabel:!1}),this.buttons.last().button({icon:this.options.icons.down,showLabel:!1}),this.buttons.height()>Math.ceil(.5*this.uiSpinner.height())&&this.uiSpinner.height()>0&&this.uiSpinner.height(this.uiSpinner.height())},_keydown:function(e){var i=this.options,s=t.ui.keyCode;switch(e.keyCode){case s.UP:return this._repeat(null,1,e),!0;case s.DOWN:return this._repeat(null,-1,e),!0;case s.PAGE_UP:return this._repeat(null,i.page,e),!0;case s.PAGE_DOWN:return this._repeat(null,-i.page,e),!0}return!1},_start:function(t){return this.spinning||this._trigger("start",t)!==!1?(this.counter||(this.counter=1),this.spinning=!0,!0):!1},_repeat:function(t,e,i){t=t||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,e,i)},t),this._spin(e*this.options.step,i)},_spin:function(t,e){var i=this.value()||0;this.counter||(this.counter=1),i=this._adjustValue(i+t*this._increment(this.counter)),this.spinning&&this._trigger("spin",e,{value:i})===!1||(this._value(i),this.counter++)},_increment:function(e){var i=this.options.incremental;return i?t.isFunction(i)?i(e):Math.floor(e*e*e/5e4-e*e/500+17*e/200+1):1},_precision:function(){var t=this._precisionOf(this.options.step);return null!==this.options.min&&(t=Math.max(t,this._precisionOf(this.options.min))),t},_precisionOf:function(t){var e=""+t,i=e.indexOf(".");return-1===i?0:e.length-i-1},_adjustValue:function(t){var e,i,s=this.options;return e=null!==s.min?s.min:0,i=t-e,i=Math.round(i/s.step)*s.step,t=e+i,t=parseFloat(t.toFixed(this._precision())),null!==s.max&&t>s.max?s.max:null!==s.min&&s.min>t?s.min:t},_stop:function(t){this.spinning&&(clearTimeout(this.timer),clearTimeout(this.mousewheelTimer),this.counter=0,this.spinning=!1,this._trigger("stop",t))},_setOption:function(t,e){var i,s,n;return"culture"===t||"numberFormat"===t?(i=this._parse(this.element.val()),this.options[t]=e,this.element.val(this._format(i)),void 0):(("max"===t||"min"===t||"step"===t)&&"string"==typeof e&&(e=this._parse(e)),"icons"===t&&(s=this.buttons.first().find(".ui-icon"),this._removeClass(s,null,this.options.icons.up),this._addClass(s,null,e.up),n=this.buttons.last().find(".ui-icon"),this._removeClass(n,null,this.options.icons.down),this._addClass(n,null,e.down)),this._super(t,e),void 0)},_setOptionDisabled:function(t){this._super(t),this._toggleClass(this.uiSpinner,null,"ui-state-disabled",!!t),this.element.prop("disabled",!!t),this.buttons.button(t?"disable":"enable")},_setOptions:r(function(t){this._super(t)}),_parse:function(t){return"string"==typeof t&&""!==t&&(t=window.Globalize&&this.options.numberFormat?Globalize.parseFloat(t,10,this.options.culture):+t),""===t||isNaN(t)?null:t},_format:function(t){return""===t?"":window.Globalize&&this.options.numberFormat?Globalize.format(t,this.options.numberFormat,this.options.culture):t},_refresh:function(){this.element.attr({"aria-valuemin":this.options.min,"aria-valuemax":this.options.max,"aria-valuenow":this._parse(this.element.val())})},isValid:function(){var t=this.value();return null===t?!1:t===this._adjustValue(t)},_value:function(t,e){var i;""!==t&&(i=this._parse(t),null!==i&&(e||(i=this._adjustValue(i)),t=this._format(i))),this.element.val(t),this._refresh()},_destroy:function(){this.element.prop("disabled",!1).removeAttr("autocomplete role aria-valuemin aria-valuemax aria-valuenow"),this.uiSpinner.replaceWith(this.element)},stepUp:r(function(t){this._stepUp(t)}),_stepUp:function(t){this._start()&&(this._spin((t||1)*this.options.step),this._stop())},stepDown:r(function(t){this._stepDown(t)}),_stepDown:function(t){this._start()&&(this._spin((t||1)*-this.options.step),this._stop())},pageUp:r(function(t){this._stepUp((t||1)*this.options.page)}),pageDown:r(function(t){this._stepDown((t||1)*this.options.page)}),value:function(t){return arguments.length?(r(this._value).call(this,t),void 0):this._parse(this.element.val())},widget:function(){return this.uiSpinner}}),t.uiBackCompat!==!1&&t.widget("ui.spinner",t.ui.spinner,{_enhance:function(){this.uiSpinner=this.element.attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml())},_uiSpinnerHtml:function(){return""},_buttonHtml:function(){return""}}),t.ui.spinner,t.widget("ui.tabs",{version:"1.12.1",delay:300,options:{active:null,classes:{"ui-tabs":"ui-corner-all","ui-tabs-nav":"ui-corner-all","ui-tabs-panel":"ui-corner-bottom","ui-tabs-tab":"ui-corner-top"},collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_isLocal:function(){var t=/#.*$/;return function(e){var i,s;i=e.href.replace(t,""),s=location.href.replace(t,"");try{i=decodeURIComponent(i)}catch(n){}try{s=decodeURIComponent(s)}catch(n){}return e.hash.length>1&&i===s}}(),_create:function(){var e=this,i=this.options;this.running=!1,this._addClass("ui-tabs","ui-widget ui-widget-content"),this._toggleClass("ui-tabs-collapsible",null,i.collapsible),this._processTabs(),i.active=this._initialActive(),t.isArray(i.disabled)&&(i.disabled=t.unique(i.disabled.concat(t.map(this.tabs.filter(".ui-state-disabled"),function(t){return e.tabs.index(t)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(i.active):t(),this._refresh(),this.active.length&&this.load(i.active)},_initialActive:function(){var e=this.options.active,i=this.options.collapsible,s=location.hash.substring(1);return null===e&&(s&&this.tabs.each(function(i,n){return t(n).attr("aria-controls")===s?(e=i,!1):void 0}),null===e&&(e=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===e||-1===e)&&(e=this.tabs.length?0:!1)),e!==!1&&(e=this.tabs.index(this.tabs.eq(e)),-1===e&&(e=i?!1:0)),!i&&e===!1&&this.anchors.length&&(e=0),e},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):t()}},_tabKeydown:function(e){var i=t(t.ui.safeActiveElement(this.document[0])).closest("li"),s=this.tabs.index(i),n=!0;if(!this._handlePageNav(e)){switch(e.keyCode){case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:s++;break;case t.ui.keyCode.UP:case t.ui.keyCode.LEFT:n=!1,s--;break;case t.ui.keyCode.END:s=this.anchors.length-1;break;case t.ui.keyCode.HOME:s=0;break;case t.ui.keyCode.SPACE:return e.preventDefault(),clearTimeout(this.activating),this._activate(s),void 0;case t.ui.keyCode.ENTER:return e.preventDefault(),clearTimeout(this.activating),this._activate(s===this.options.active?!1:s),void 0;default:return}e.preventDefault(),clearTimeout(this.activating),s=this._focusNextTab(s,n),e.ctrlKey||e.metaKey||(i.attr("aria-selected","false"),this.tabs.eq(s).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",s)},this.delay))}},_panelKeydown:function(e){this._handlePageNav(e)||e.ctrlKey&&e.keyCode===t.ui.keyCode.UP&&(e.preventDefault(),this.active.trigger("focus"))},_handlePageNav:function(e){return e.altKey&&e.keyCode===t.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):e.altKey&&e.keyCode===t.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):void 0},_findNextTab:function(e,i){function s(){return e>n&&(e=0),0>e&&(e=n),e}for(var n=this.tabs.length-1;-1!==t.inArray(s(),this.options.disabled);)e=i?e+1:e-1;return e},_focusNextTab:function(t,e){return t=this._findNextTab(t,e),this.tabs.eq(t).trigger("focus"),t},_setOption:function(t,e){return"active"===t?(this._activate(e),void 0):(this._super(t,e),"collapsible"===t&&(this._toggleClass("ui-tabs-collapsible",null,e),e||this.options.active!==!1||this._activate(0)),"event"===t&&this._setupEvents(e),"heightStyle"===t&&this._setupHeightStyle(e),void 0)},_sanitizeSelector:function(t){return t?t.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var e=this.options,i=this.tablist.children(":has(a[href])");e.disabled=t.map(i.filter(".ui-state-disabled"),function(t){return i.index(t)}),this._processTabs(),e.active!==!1&&this.anchors.length?this.active.length&&!t.contains(this.tablist[0],this.active[0])?this.tabs.length===e.disabled.length?(e.active=!1,this.active=t()):this._activate(this._findNextTab(Math.max(0,e.active-1),!1)):e.active=this.tabs.index(this.active):(e.active=!1,this.active=t()),this._refresh()},_refresh:function(){this._setOptionDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-hidden":"true"}),this.active.length?(this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}),this._addClass(this.active,"ui-tabs-active","ui-state-active"),this._getPanelForTab(this.active).show().attr({"aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var e=this,i=this.tabs,s=this.anchors,n=this.panels;this.tablist=this._getList().attr("role","tablist"),this._addClass(this.tablist,"ui-tabs-nav","ui-helper-reset ui-helper-clearfix ui-widget-header"),this.tablist.on("mousedown"+this.eventNamespace,"> li",function(e){t(this).is(".ui-state-disabled")&&e.preventDefault()}).on("focus"+this.eventNamespace,".ui-tabs-anchor",function(){t(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this.tabs=this.tablist.find("> li:has(a[href])").attr({role:"tab",tabIndex:-1}),this._addClass(this.tabs,"ui-tabs-tab","ui-state-default"),this.anchors=this.tabs.map(function(){return t("a",this)[0]}).attr({role:"presentation",tabIndex:-1}),this._addClass(this.anchors,"ui-tabs-anchor"),this.panels=t(),this.anchors.each(function(i,s){var n,o,a,r=t(s).uniqueId().attr("id"),h=t(s).closest("li"),l=h.attr("aria-controls");e._isLocal(s)?(n=s.hash,a=n.substring(1),o=e.element.find(e._sanitizeSelector(n))):(a=h.attr("aria-controls")||t({}).uniqueId()[0].id,n="#"+a,o=e.element.find(n),o.length||(o=e._createPanel(a),o.insertAfter(e.panels[i-1]||e.tablist)),o.attr("aria-live","polite")),o.length&&(e.panels=e.panels.add(o)),l&&h.data("ui-tabs-aria-controls",l),h.attr({"aria-controls":a,"aria-labelledby":r}),o.attr("aria-labelledby",r)}),this.panels.attr("role","tabpanel"),this._addClass(this.panels,"ui-tabs-panel","ui-widget-content"),i&&(this._off(i.not(this.tabs)),this._off(s.not(this.anchors)),this._off(n.not(this.panels)))},_getList:function(){return this.tablist||this.element.find("ol, ul").eq(0)},_createPanel:function(e){return t("
          ").attr("id",e).data("ui-tabs-destroy",!0)},_setOptionDisabled:function(e){var i,s,n;for(t.isArray(e)&&(e.length?e.length===this.anchors.length&&(e=!0):e=!1),n=0;s=this.tabs[n];n++)i=t(s),e===!0||-1!==t.inArray(n,e)?(i.attr("aria-disabled","true"),this._addClass(i,null,"ui-state-disabled")):(i.removeAttr("aria-disabled"),this._removeClass(i,null,"ui-state-disabled"));this.options.disabled=e,this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,e===!0)},_setupEvents:function(e){var i={};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(!0,this.anchors,{click:function(t){t.preventDefault()}}),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(e){var i,s=this.element.parent();"fill"===e?(i=s.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var e=t(this),s=e.css("position");"absolute"!==s&&"fixed"!==s&&(i-=e.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=t(this).outerHeight(!0)}),this.panels.each(function(){t(this).height(Math.max(0,i-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===e&&(i=0,this.panels.each(function(){i=Math.max(i,t(this).height("").height())}).height(i))},_eventHandler:function(e){var i=this.options,s=this.active,n=t(e.currentTarget),o=n.closest("li"),a=o[0]===s[0],r=a&&i.collapsible,h=r?t():this._getPanelForTab(o),l=s.length?this._getPanelForTab(s):t(),c={oldTab:s,oldPanel:l,newTab:r?t():o,newPanel:h};e.preventDefault(),o.hasClass("ui-state-disabled")||o.hasClass("ui-tabs-loading")||this.running||a&&!i.collapsible||this._trigger("beforeActivate",e,c)===!1||(i.active=r?!1:this.tabs.index(o),this.active=a?t():o,this.xhr&&this.xhr.abort(),l.length||h.length||t.error("jQuery UI Tabs: Mismatching fragment identifier."),h.length&&this.load(this.tabs.index(o),e),this._toggle(e,c))},_toggle:function(e,i){function s(){o.running=!1,o._trigger("activate",e,i)}function n(){o._addClass(i.newTab.closest("li"),"ui-tabs-active","ui-state-active"),a.length&&o.options.show?o._show(a,o.options.show,s):(a.show(),s())}var o=this,a=i.newPanel,r=i.oldPanel;this.running=!0,r.length&&this.options.hide?this._hide(r,this.options.hide,function(){o._removeClass(i.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),n()}):(this._removeClass(i.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),r.hide(),n()),r.attr("aria-hidden","true"),i.oldTab.attr({"aria-selected":"false","aria-expanded":"false"}),a.length&&r.length?i.oldTab.attr("tabIndex",-1):a.length&&this.tabs.filter(function(){return 0===t(this).attr("tabIndex")}).attr("tabIndex",-1),a.attr("aria-hidden","false"),i.newTab.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_activate:function(e){var i,s=this._findActive(e);s[0]!==this.active[0]&&(s.length||(s=this.active),i=s.find(".ui-tabs-anchor")[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return e===!1?t():this.tabs.eq(e)},_getIndex:function(e){return"string"==typeof e&&(e=this.anchors.index(this.anchors.filter("[href$='"+t.ui.escapeSelector(e)+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.tablist.removeAttr("role").off(this.eventNamespace),this.anchors.removeAttr("role tabIndex").removeUniqueId(),this.tabs.add(this.panels).each(function(){t.data(this,"ui-tabs-destroy")?t(this).remove():t(this).removeAttr("role tabIndex aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded")}),this.tabs.each(function(){var e=t(this),i=e.data("ui-tabs-aria-controls");i?e.attr("aria-controls",i).removeData("ui-tabs-aria-controls"):e.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(e){var i=this.options.disabled;i!==!1&&(void 0===e?i=!1:(e=this._getIndex(e),i=t.isArray(i)?t.map(i,function(t){return t!==e?t:null}):t.map(this.tabs,function(t,i){return i!==e?i:null})),this._setOptionDisabled(i))},disable:function(e){var i=this.options.disabled;if(i!==!0){if(void 0===e)i=!0;else{if(e=this._getIndex(e),-1!==t.inArray(e,i))return;i=t.isArray(i)?t.merge([e],i).sort():[e]}this._setOptionDisabled(i)}},load:function(e,i){e=this._getIndex(e);var s=this,n=this.tabs.eq(e),o=n.find(".ui-tabs-anchor"),a=this._getPanelForTab(n),r={tab:n,panel:a},h=function(t,e){"abort"===e&&s.panels.stop(!1,!0),s._removeClass(n,"ui-tabs-loading"),a.removeAttr("aria-busy"),t===s.xhr&&delete s.xhr};this._isLocal(o[0])||(this.xhr=t.ajax(this._ajaxSettings(o,i,r)),this.xhr&&"canceled"!==this.xhr.statusText&&(this._addClass(n,"ui-tabs-loading"),a.attr("aria-busy","true"),this.xhr.done(function(t,e,n){setTimeout(function(){a.html(t),s._trigger("load",i,r),h(n,e)},1)}).fail(function(t,e){setTimeout(function(){h(t,e)},1)})))},_ajaxSettings:function(e,i,s){var n=this;return{url:e.attr("href").replace(/#.*$/,""),beforeSend:function(e,o){return n._trigger("beforeLoad",i,t.extend({jqXHR:e,ajaxSettings:o},s))}}},_getPanelForTab:function(e){var i=t(e).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+i))}}),t.uiBackCompat!==!1&&t.widget("ui.tabs",t.ui.tabs,{_processTabs:function(){this._superApply(arguments),this._addClass(this.tabs,"ui-tab")}}),t.ui.tabs,t.widget("ui.tooltip",{version:"1.12.1",options:{classes:{"ui-tooltip":"ui-corner-all ui-widget-shadow"},content:function(){var e=t(this).attr("title")||"";return t("").text(e).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,track:!1,close:null,open:null},_addDescribedBy:function(e,i){var s=(e.attr("aria-describedby")||"").split(/\s+/);s.push(i),e.data("ui-tooltip-id",i).attr("aria-describedby",t.trim(s.join(" ")))},_removeDescribedBy:function(e){var i=e.data("ui-tooltip-id"),s=(e.attr("aria-describedby")||"").split(/\s+/),n=t.inArray(i,s);-1!==n&&s.splice(n,1),e.removeData("ui-tooltip-id"),s=t.trim(s.join(" ")),s?e.attr("aria-describedby",s):e.removeAttr("aria-describedby")},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.liveRegion=t("
          ").attr({role:"log","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this.disabledTitles=t([])},_setOption:function(e,i){var s=this;this._super(e,i),"content"===e&&t.each(this.tooltips,function(t,e){s._updateContent(e.element)})},_setOptionDisabled:function(t){this[t?"_disable":"_enable"]()},_disable:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur");n.target=n.currentTarget=s.element[0],e.close(n,!0)}),this.disabledTitles=this.disabledTitles.add(this.element.find(this.options.items).addBack().filter(function(){var e=t(this);return e.is("[title]")?e.data("ui-tooltip-title",e.attr("title")).removeAttr("title"):void 0}))},_enable:function(){this.disabledTitles.each(function(){var e=t(this);e.data("ui-tooltip-title")&&e.attr("title",e.data("ui-tooltip-title"))}),this.disabledTitles=t([])},open:function(e){var i=this,s=t(e?e.target:this.element).closest(this.options.items);s.length&&!s.data("ui-tooltip-id")&&(s.attr("title")&&s.data("ui-tooltip-title",s.attr("title")),s.data("ui-tooltip-open",!0),e&&"mouseover"===e.type&&s.parents().each(function(){var e,s=t(this);s.data("ui-tooltip-open")&&(e=t.Event("blur"),e.target=e.currentTarget=this,i.close(e,!0)),s.attr("title")&&(s.uniqueId(),i.parents[this.id]={element:this,title:s.attr("title")},s.attr("title",""))}),this._registerCloseHandlers(e,s),this._updateContent(s,e))},_updateContent:function(t,e){var i,s=this.options.content,n=this,o=e?e.type:null;return"string"==typeof s||s.nodeType||s.jquery?this._open(e,t,s):(i=s.call(t[0],function(i){n._delay(function(){t.data("ui-tooltip-open")&&(e&&(e.type=o),this._open(e,t,i))})}),i&&this._open(e,t,i),void 0)},_open:function(e,i,s){function n(t){l.of=t,a.is(":hidden")||a.position(l)}var o,a,r,h,l=t.extend({},this.options.position);if(s){if(o=this._find(i))return o.tooltip.find(".ui-tooltip-content").html(s),void 0;i.is("[title]")&&(e&&"mouseover"===e.type?i.attr("title",""):i.removeAttr("title")),o=this._tooltip(i),a=o.tooltip,this._addDescribedBy(i,a.attr("id")),a.find(".ui-tooltip-content").html(s),this.liveRegion.children().hide(),h=t("
          ").html(a.find(".ui-tooltip-content").html()),h.removeAttr("name").find("[name]").removeAttr("name"),h.removeAttr("id").find("[id]").removeAttr("id"),h.appendTo(this.liveRegion),this.options.track&&e&&/^mouse/.test(e.type)?(this._on(this.document,{mousemove:n}),n(e)):a.position(t.extend({of:i},this.options.position)),a.hide(),this._show(a,this.options.show),this.options.track&&this.options.show&&this.options.show.delay&&(r=this.delayedShow=setInterval(function(){a.is(":visible")&&(n(l.of),clearInterval(r))},t.fx.interval)),this._trigger("open",e,{tooltip:a})}},_registerCloseHandlers:function(e,i){var s={keyup:function(e){if(e.keyCode===t.ui.keyCode.ESCAPE){var s=t.Event(e);s.currentTarget=i[0],this.close(s,!0)}}};i[0]!==this.element[0]&&(s.remove=function(){this._removeTooltip(this._find(i).tooltip)}),e&&"mouseover"!==e.type||(s.mouseleave="close"),e&&"focusin"!==e.type||(s.focusout="close"),this._on(!0,i,s)},close:function(e){var i,s=this,n=t(e?e.currentTarget:this.element),o=this._find(n);return o?(i=o.tooltip,o.closing||(clearInterval(this.delayedShow),n.data("ui-tooltip-title")&&!n.attr("title")&&n.attr("title",n.data("ui-tooltip-title")),this._removeDescribedBy(n),o.hiding=!0,i.stop(!0),this._hide(i,this.options.hide,function(){s._removeTooltip(t(this))}),n.removeData("ui-tooltip-open"),this._off(n,"mouseleave focusout keyup"),n[0]!==this.element[0]&&this._off(n,"remove"),this._off(this.document,"mousemove"),e&&"mouseleave"===e.type&&t.each(this.parents,function(e,i){t(i.element).attr("title",i.title),delete s.parents[e]}),o.closing=!0,this._trigger("close",e,{tooltip:i}),o.hiding||(o.closing=!1)),void 0):(n.removeData("ui-tooltip-open"),void 0)},_tooltip:function(e){var i=t("
          ").attr("role","tooltip"),s=t("
          ").appendTo(i),n=i.uniqueId().attr("id");return this._addClass(s,"ui-tooltip-content"),this._addClass(i,"ui-tooltip","ui-widget ui-widget-content"),i.appendTo(this._appendTo(e)),this.tooltips[n]={element:e,tooltip:i}},_find:function(t){var e=t.data("ui-tooltip-id");return e?this.tooltips[e]:null},_removeTooltip:function(t){t.remove(),delete this.tooltips[t.attr("id")]},_appendTo:function(t){var e=t.closest(".ui-front, dialog");return e.length||(e=this.document[0].body),e},_destroy:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur"),o=s.element;n.target=n.currentTarget=o[0],e.close(n,!0),t("#"+i).remove(),o.data("ui-tooltip-title")&&(o.attr("title")||o.attr("title",o.data("ui-tooltip-title")),o.removeData("ui-tooltip-title"))}),this.liveRegion.remove()}}),t.uiBackCompat!==!1&&t.widget("ui.tooltip",t.ui.tooltip,{options:{tooltipClass:null},_tooltip:function(){var t=this._superApply(arguments);return this.options.tooltipClass&&t.tooltip.addClass(this.options.tooltipClass),t}}),t.ui.tooltip}); \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index 1018fda2a87..f80dbf90f57 100644 --- a/docs/index.md +++ b/docs/index.md @@ -13,7 +13,6 @@ author: Jeff Jensen , Andreas Dangel Date: Mon, 27 Oct 2025 09:47:16 +0100 Subject: [PATCH 1527/1962] [doc] Update release notes (#6098) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 74041c6829a..d7ee57d97ca 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -59,6 +59,7 @@ checkstyle version during the build. * [#6012](https://github.com/pmd/pmd/issues/6012): \[pmd-rulesets] Rulesets should be in alphabetical order * [#6073](https://github.com/pmd/pmd/issues/6073): \[doc] Search improvements * [#6097](https://github.com/pmd/pmd/issues/6097): \[doc] Add PMD versions dropdown + * [#6098](https://github.com/pmd/pmd/issues/6098): \[doc] Add a copy URL button * apex * [#5935](https://github.com/pmd/pmd/issues/5935): \[apex] @SuppressWarnings - allow whitespace around comma when suppressing multiple rules * apex-design @@ -129,6 +130,7 @@ checkstyle version during the build. * [#6085](https://github.com/pmd/pmd/pull/6085): \[java] Fix false positive for ModifierOrder - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6093](https://github.com/pmd/pmd/pull/6093): \[ci] Fix #5873: Run integration tests with Java 25 additionally - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6097](https://github.com/pmd/pmd/pull/6097): \[doc] Add PMD versions dropdown - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6098](https://github.com/pmd/pmd/pull/6098): \[doc] Add a copy URL button - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6100](https://github.com/pmd/pmd/pull/6100): \[java] AvoidDeeplyNestedIfStmts: fix false negative with if-else - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6112](https://github.com/pmd/pmd/pull/6112): \[java] DanglingJavadoc: fix false positive for compact constructors - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6114](https://github.com/pmd/pmd/pull/6114): \[java] Fix #4122: CheckResultSet false-positive with local variable - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) From 977084be3974b79a954b67f6d47a765e21817488 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 29 Sep 2025 20:43:54 +0200 Subject: [PATCH 1528/1962] [doc] Highlight current header in TOC This adds a simple scroll spy using the intersection observer api. It highlights the current header in the TOC and also scrolls the TOC. --- docs/css/customstyles.css | 7 +++++++ docs/js/customscripts.js | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/docs/css/customstyles.css b/docs/css/customstyles.css index 9f503483bff..5c85b9656c6 100644 --- a/docs/css/customstyles.css +++ b/docs/css/customstyles.css @@ -1291,3 +1291,10 @@ a.edit-header::after { .language-info { margin: 2em; } + +#toc a.active { + font-weight: bold; +} +#toc a.active:before { + content: '>> ' +} \ No newline at end of file diff --git a/docs/js/customscripts.js b/docs/js/customscripts.js index 7ba72abcdba..9948510bd4a 100644 --- a/docs/js/customscripts.js +++ b/docs/js/customscripts.js @@ -143,3 +143,35 @@ $(document).ready(function () { $(window).resize(function () { moveToc(); }); + +// based on https://github.com/laolusrael/scroll-spy/blob/master/scroll-spy.js and +// using https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API +(function() { +let observer = new IntersectionObserver((entries, observer) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + let id = entry.target.getAttribute('id'); + let linkSelector = `#toc a[href='#${id}']`; + let nowActiveLink = document.querySelector(linkSelector); + + if (nowActiveLink != null){ + let curActiveLink = document.querySelector('#toc a.active'); + if (curActiveLink) { + if (curActiveLink.getAttribute('href') != '#' + id) { + curActiveLink.classList.remove('active'); + } + } + if (!nowActiveLink.classList.contains('active')) { + nowActiveLink.classList.add('active'); + nowActiveLink.scrollIntoView({ block: "center" }); + } + } + } + }); +}); + +document.querySelectorAll('h2,h3,h4,h5').forEach(el => { + observer.observe(el); +}); + +})(); \ No newline at end of file From 559ab681d99e57050eabec00180a83833b9156f2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 27 Oct 2025 10:17:41 +0100 Subject: [PATCH 1529/1962] [doc] Update release notes (#6101) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index d7ee57d97ca..edfd7533e49 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -60,6 +60,7 @@ checkstyle version during the build. * [#6073](https://github.com/pmd/pmd/issues/6073): \[doc] Search improvements * [#6097](https://github.com/pmd/pmd/issues/6097): \[doc] Add PMD versions dropdown * [#6098](https://github.com/pmd/pmd/issues/6098): \[doc] Add a copy URL button + * [#6101](https://github.com/pmd/pmd/issues/6101): \[doc] Highlight current header in TOC * apex * [#5935](https://github.com/pmd/pmd/issues/5935): \[apex] @SuppressWarnings - allow whitespace around comma when suppressing multiple rules * apex-design @@ -132,6 +133,7 @@ checkstyle version during the build. * [#6097](https://github.com/pmd/pmd/pull/6097): \[doc] Add PMD versions dropdown - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6098](https://github.com/pmd/pmd/pull/6098): \[doc] Add a copy URL button - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6100](https://github.com/pmd/pmd/pull/6100): \[java] AvoidDeeplyNestedIfStmts: fix false negative with if-else - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6101](https://github.com/pmd/pmd/pull/6101): \[doc] Highlight current header in TOC - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6112](https://github.com/pmd/pmd/pull/6112): \[java] DanglingJavadoc: fix false positive for compact constructors - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6114](https://github.com/pmd/pmd/pull/6114): \[java] Fix #4122: CheckResultSet false-positive with local variable - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6116](https://github.com/pmd/pmd/pull/6116): \[java] ConfusingTernary: add configuration property for null checks - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) From f02f7fcd600f040b1951397408f10ef6cc7035c0 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Sun, 12 Oct 2025 05:52:31 +0200 Subject: [PATCH 1530/1962] [java] CloseResource: fix false positive with pattern matching --- .../rule/errorprone/CloseResourceRule.java | 43 ++++++++++++++----- .../rule/errorprone/xml/CloseResource.xml | 28 ++++++++++++ 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceRule.java index 5f84092d72e..69ae0d9a888 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/CloseResourceRule.java @@ -37,9 +37,12 @@ import net.sourceforge.pmd.lang.java.ast.ASTNullLiteral; import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement; import net.sourceforge.pmd.lang.java.ast.ASTStatement; +import net.sourceforge.pmd.lang.java.ast.ASTSwitchLabel; +import net.sourceforge.pmd.lang.java.ast.ASTSwitchLike; import net.sourceforge.pmd.lang.java.ast.ASTTryStatement; import net.sourceforge.pmd.lang.java.ast.ASTType; import net.sourceforge.pmd.lang.java.ast.ASTTypeExpression; +import net.sourceforge.pmd.lang.java.ast.ASTTypePattern; import net.sourceforge.pmd.lang.java.ast.ASTVariableAccess; import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator; import net.sourceforge.pmd.lang.java.ast.ASTVariableId; @@ -345,19 +348,37 @@ private boolean isNotWrappingResourceMethodParameter(ASTVariableId var, */ private boolean isWrappingResourceMethodParameter(ASTVariableId var, ASTExecutableDeclaration method) { ASTVariableAccess wrappedVarName = getWrappedVariableName(var); + ASTFormalParameters methodParams = method.getFormalParameters(); if (wrappedVarName != null) { - ASTFormalParameters methodParams = method.getFormalParameters(); - for (ASTFormalParameter param : methodParams) { - // get the parent node where it's used (no casts) - Node parentUse = wrappedVarName.getParent(); - if (parentUse instanceof ASTCastExpression) { - parentUse = parentUse.getParent(); - } - if ((isResourceTypeOrSubtype(param) || parentUse instanceof ASTVariableDeclarator - || parentUse instanceof ASTAssignmentExpression) + // get the parent node where it's used (no casts) + Node parentUse = wrappedVarName.getParent(); + if (parentUse instanceof ASTCastExpression) { + parentUse = parentUse.getParent(); + } + return isReferencingMethodParameter(wrappedVarName, methodParams, + parentUse instanceof ASTVariableDeclarator || parentUse instanceof ASTAssignmentExpression); + } else if (var.getParent() instanceof ASTTypePattern && var.getIndexInParent() == 2) { + JavaNode check = null; + if (var.getParent().getParent().getParent() instanceof ASTInfixExpression) { + check = var.getParent().getParent().getParent().getChild(0); + } + if (var.getParent().getParent() instanceof ASTSwitchLabel) { + ASTSwitchLike sw = var.ancestors(ASTSwitchLike.class).firstOrThrow(); + check = sw.getTestedExpression(); + } + if (check instanceof ASTVariableAccess) { + return isReferencingMethodParameter((ASTVariableAccess) check, methodParams, false); + } + } + return false; + } + + private boolean isReferencingMethodParameter(ASTVariableAccess wrappedVarName, + ASTFormalParameters methodParams, boolean isAssignment) { + for (ASTFormalParameter param: methodParams) { + if ((isAssignment || isResourceTypeOrSubtype(param)) && JavaAstUtils.isReferenceToVar(wrappedVarName, param.getVarId().getSymbol())) { - return true; - } + return true; } } return false; diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml index 4b88205e7e4..4b5167d60ed 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml @@ -1260,6 +1260,34 @@ public class CloseResourceFP { ]]> + + #5042 [java] CloseResource false positive for pattern match + 0 + doCheck(fin); + case ByteArrayInputStream bin -> doCheck(bin); + default -> doCheck(new BufferedInputStream((InputStream) in)); + } + } +} + ]]> + + #1967 [java] CloseResource false positive with late assignment of variable 0 From 27a8c5261163d6d0f9de4913848b640c47c77493 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 27 Oct 2025 12:02:29 +0100 Subject: [PATCH 1531/1962] Remove focused=true --- .../pmd/lang/java/rule/errorprone/xml/CloseResource.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml index 4b5167d60ed..8ef835a9397 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/CloseResource.xml @@ -1260,7 +1260,7 @@ public class CloseResourceFP { ]]> - + #5042 [java] CloseResource false positive for pattern match 0 Date: Mon, 27 Oct 2025 12:03:31 +0100 Subject: [PATCH 1532/1962] [doc] Update release notes (#5042, #6133) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index edfd7533e49..1d341fe82b1 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -84,6 +84,7 @@ checkstyle version during the build. * [#6058](https://github.com/pmd/pmd/issues/6058): \[java] DanglingJavadoc FP in module-info files * [#6103](https://github.com/pmd/pmd/issues/6103): \[java] DanglingJavadoc false positive on record compact constructors * java-errorprone + * [#5042](https://github.com/pmd/pmd/issues/5042): \[java] CloseResource false-positive on Pattern Matching with instanceof * [#5878](https://github.com/pmd/pmd/issues/5878): \[java] DontUseFloatTypeForLoopIndices false-negative if variable is declared before loop * [#6038](https://github.com/pmd/pmd/issues/6038): \[java] Merge AvoidCatchingNPE and AvoidCatchingThrowable into AvoidCatchingGenericException * [#6055](https://github.com/pmd/pmd/issues/6055): \[java] UselessPureMethodCall false positive with AtomicInteger::getAndIncrement @@ -139,6 +140,7 @@ checkstyle version during the build. * [#6116](https://github.com/pmd/pmd/pull/6116): \[java] ConfusingTernary: add configuration property for null checks - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6124](https://github.com/pmd/pmd/pull/6124): \[java] UnusedLocalVariable: fix false negatives in pattern matching - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6130](https://github.com/pmd/pmd/pull/6130): \[java] UselessParentheses: fix false positives for switch expressions - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6133](https://github.com/pmd/pmd/pull/6133): \[java] Fix #5042: CloseResource: fix false positive with pattern matching - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) ### ๐Ÿ“ฆ Dependency updates From 7a21edfffbd8618507d9eb9be66abade3c605beb Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Tue, 21 Oct 2025 03:02:15 +0200 Subject: [PATCH 1533/1962] Update Saxon-HE to 12.9 --- .../pmd/lang/rule/xpath/internal/RuleChainAnalyzer.java | 7 ++++++- .../lang/rule/xpath/internal/SaxonXPathRuleQueryTest.java | 8 ++++---- pom.xml | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/RuleChainAnalyzer.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/RuleChainAnalyzer.java index afaf60ff6b6..ad10d5ffb23 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/RuleChainAnalyzer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/RuleChainAnalyzer.java @@ -77,7 +77,7 @@ public Expression visitSlashPreserveRootElement(SlashExpression e) { Expression step = visit(e.getStep()); - if (!(e.getStart() instanceof RootExpression)) { + if (!(getStart(e) instanceof RootExpression)) { // restore rootElement = elt; rootElementReplaced = replaced; @@ -86,6 +86,11 @@ public Expression visitSlashPreserveRootElement(SlashExpression e) { return new SlashExpression(start, step); } + private Object getStart(SlashExpression e) { + Expression ex = e.getStart(); + return ex instanceof SlashExpression ? getStart((SlashExpression) ex) : ex; + } + @Override public Expression visit(SlashExpression e) { if (!insideExpensiveExpr && rootElement == null) { diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/internal/SaxonXPathRuleQueryTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/internal/SaxonXPathRuleQueryTest.java index a1c8cd355bd..d24c4edc660 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/internal/SaxonXPathRuleQueryTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/internal/SaxonXPathRuleQueryTest.java @@ -174,8 +174,8 @@ void ruleChainVisitsCustomFunctions() { assertEquals(1, ruleChainVisits.size()); assertTrue(ruleChainVisits.contains("dummyNode")); assertEquals(2, query.nodeNameToXPaths.size()); - assertExpression("self::node()[Q{http://pmd.sourceforge.net/pmd-dummy}imageIs(exactly-one(convertTo_xs:string(data(attribute::attribute(Image)))))]", query.getExpressionsForLocalNameOrDefault("dummyNode").get(0)); - assertExpression("((/)/descendant::element(Q{}dummyNode))[Q{http://pmd.sourceforge.net/pmd-dummy}imageIs(exactly-one(convertTo_xs:string(data(attribute::attribute(Image)))))]", query.getFallbackExpr()); + assertExpression("self::node()[imageIs(exactly-one(convertTo_xs:string(data(((.) treat as node())/attribute::attribute(Image)))))]", query.getExpressionsForLocalNameOrDefault("dummyNode").get(0)); + assertExpression("docOrder(((/)/descendant-or-self::node())/(child::element(dummyNode)[imageIs(exactly-one(convertTo_xs:string(data(((.) treat as node())/attribute::attribute(Image)))))]))", query.getFallbackExpr()); } /** @@ -328,7 +328,7 @@ void ruleChainVisitWithTwoFunctions() { assertEquals(1, ruleChainVisits.size()); assertTrue(ruleChainVisits.contains("dummyNode")); assertEquals(2, query.nodeNameToXPaths.size()); - assertExpression("let $v0 := imageIs(bar) return ((self::node()[ends-with(zero-or-one(convertTo_xs:string(data(attribute::attribute(Image)))), foo)])[$v0])", query.nodeNameToXPaths.get("dummyNode").get(0)); + assertExpression("let $v0 := imageIs(bar) return ((self::node()[ends-with(zero-or-one(convertTo_xs:string(data(((.) treat as node())/attribute::attribute(Image)))), foo)])[$v0])", query.nodeNameToXPaths.get("dummyNode").get(0)); } @Test @@ -370,7 +370,7 @@ void ruleChainWithUnionsCustomFunctionsVariant3() { assertTrue(ruleChainVisits.contains("WhileStatement")); assertTrue(ruleChainVisits.contains("DoStatement")); - final String expectedSubexpression = "(self::node()/descendant::element(dummyNode))[imageIs(exactly-one(convertTo_xs:string(data(attribute::attribute(Image)))))]"; + final String expectedSubexpression = "((self::node()/descendant-or-self::node())/child::element(dummyNode))[imageIs(exactly-one(convertTo_xs:string(data(((.) treat as node())/attribute::attribute(Image)))))]"; assertExpression(expectedSubexpression, query.nodeNameToXPaths.get("ForStatement").get(0)); assertExpression(expectedSubexpression, query.nodeNameToXPaths.get("WhileStatement").get(0)); assertExpression(expectedSubexpression, query.nodeNameToXPaths.get("DoStatement").get(0)); diff --git a/pom.xml b/pom.xml index dd7bb8b400d..d3b2da9f904 100644 --- a/pom.xml +++ b/pom.xml @@ -98,7 +98,7 @@ 3.12.0 4.9.3 1.7.36 - 12.5 + 12.9 UTF-8 UTF-8 From 6f18b6cfcb5dc62cbfba3855ada42d9846e50efe Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 28 Oct 2025 08:17:18 +0100 Subject: [PATCH 1534/1962] [doc] Update release notes (#6152) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 1d341fe82b1..83a7fe9af33 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -141,6 +141,7 @@ checkstyle version during the build. * [#6124](https://github.com/pmd/pmd/pull/6124): \[java] UnusedLocalVariable: fix false negatives in pattern matching - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6130](https://github.com/pmd/pmd/pull/6130): \[java] UselessParentheses: fix false positives for switch expressions - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6133](https://github.com/pmd/pmd/pull/6133): \[java] Fix #5042: CloseResource: fix false positive with pattern matching - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6152](https://github.com/pmd/pmd/pull/6152): chore(deps): Update Saxon-HE from 12.5 to 12.9 - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) ### ๐Ÿ“ฆ Dependency updates From 0f3dcf22b8ebf1a2a707238c9b9a845809a76379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 20 Oct 2025 21:42:34 +0200 Subject: [PATCH 1535/1962] [java] Add tests related to #6146 - unknown constraint is compatible with other constraints To fix #6146 we still need to fix the underlying issue, which is that a resolution failure (ie, the `filter(...)`) call here fails resolving after having tried out the overload, and that doesn't clean up the whole tree from inference variables. As a last step we can check that the cast is feasible in TypeTestUtil, although it will brush future issues under the rug. --- .../pmd/lang/java/types/TypeOps.java | 7 ++- .../internal/infer/IncorporationAction.java | 11 +++- .../lang/java/types/TypeTestMockingUtil.kt | 7 ++- .../infer/UnresolvedTypesRecoveryTest.kt | 62 +++++++++++++++++++ .../xml/InvalidLogMessageFormat.xml | 18 ++++++ 5 files changed, 101 insertions(+), 4 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java index d43f3887193..eb3d6520589 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java @@ -40,6 +40,7 @@ import net.sourceforge.pmd.lang.java.types.internal.infer.InferenceVar; import net.sourceforge.pmd.lang.java.types.internal.infer.InferenceVar.BoundKind; import net.sourceforge.pmd.lang.java.types.internal.infer.OverloadSet; +import net.sourceforge.pmd.util.AssertionUtil; import net.sourceforge.pmd.util.CollectionUtil; import net.sourceforge.pmd.util.IteratorUtil; @@ -181,7 +182,11 @@ private SameTypeVisitor(boolean pure, boolean considerAnnotations) { @Override public Boolean visit(JTypeMirror t, JTypeMirror s) { - // for sentinel types + throw AssertionUtil.shouldNotReachHere("other overload should be chosen"); + } + + @Override + public Boolean visitSentinel(JTypeMirror t, JTypeMirror s) { return t == s; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/IncorporationAction.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/IncorporationAction.java index 74e89636f11..9826a8a23f5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/IncorporationAction.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/IncorporationAction.java @@ -5,6 +5,7 @@ package net.sourceforge.pmd.lang.java.types.internal.infer; import static net.sourceforge.pmd.lang.java.types.TypeOps.isConvertible; +import static net.sourceforge.pmd.lang.java.types.TypeOps.isSpecialUnresolved; import java.util.ArrayList; import java.util.Set; @@ -124,9 +125,15 @@ private boolean checkBound(JTypeMirror otherBound, BoundKind otherKind, Inferenc * If 'eq', checks that {@code T = S}, else checks that {@code T <: S}. */ static boolean checkBound(boolean eq, JTypeMirror t, JTypeMirror s, InferenceContext ctx) { + if (!eq) { + return checkSubtype(t, s, ctx); + } // eq bounds are so rare we shouldn't care if they're cached - return eq ? InternalApiBridge.isSameTypeInInference(t, s) - : checkSubtype(t, s, ctx); + if (InternalApiBridge.isSameTypeInInference(t, s)) { + return true; + } + // don't fail if one of those is (*unknown*) or (*error*) + return isSpecialUnresolved(t) || isSpecialUnresolved(s); } private static boolean checkSubtype(JTypeMirror t, JTypeMirror s, InferenceContext ctx) { diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TypeTestMockingUtil.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TypeTestMockingUtil.kt index fcb7fc40d50..fdb4e93fa23 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TypeTestMockingUtil.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/TypeTestMockingUtil.kt @@ -28,7 +28,7 @@ fun JavaParsingHelper.parseWithTypeInferenceSpy(code: String): Pair local = filter(unknown(), input -> input.debug()); + } + + public static Iterable filter(final Iterable unfiltered, + final java.util.function.Predicate retainIfTrue) { + return null; + } + } + """.trimIndent() + ) + + val (barClass) = acu.declaredTypeSignatures() + val (filterCall, unknownCall, debugCall) = acu.methodCalls().crossFindBoundaries().toList() + val (filter) = acu.methodDeclarations().toList { it.genericSignature } + + with(acu.typeDsl) { + filterCall shouldHaveType java.lang.Iterable::class[barClass] + filterCall.methodType shouldBeSomeInstantiationOf filter + spy.shouldHaveNoErrors() + debugCall.qualifier!! shouldHaveType barClass + debugCall shouldHaveType ts.UNKNOWN + } + } + parserTest("Constraints like 'a = Bar and 'a = (*unknown*) should not be considered incompatible: with no context there is no Bar hint") { + val (acu, spy) = parser.parseWithTypeInferenceSpy( + """ + class Bar {} + public class Foo { + + static { + var local = filter(unknown(), input -> input.debug()); + } + + public static Iterable filter(final Iterable unfiltered, + final java.util.function.Predicate retainIfTrue) { + return null; + } + } + """.trimIndent() + ) + + val (barClass) = acu.declaredTypeSignatures() + val (filterCall, unknownCall, debugCall) = acu.methodCalls().crossFindBoundaries().toList() + val (filter) = acu.methodDeclarations().toList { it.genericSignature } + + with(acu.typeDsl) { + filterCall shouldHaveType java.lang.Iterable::class[ts.UNKNOWN] + filterCall.methodType shouldBeSomeInstantiationOf filter + spy.shouldHaveNoErrors() + debugCall.qualifier!! shouldHaveType ts.UNKNOWN + debugCall shouldHaveType ts.UNKNOWN + } + } }) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml index 4b75a2d375e..3f4358a50ce 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml @@ -1330,4 +1330,22 @@ public class InvalidLogMessageFormat{ } ]]> + + #6146 [java] ClassCastException: class InferenceVarSym cannot be cast to class JClassSymbol + 0 + local = filter(unknown(), input -> input.debug()); + } + + public static Iterable filter(final Iterable unfiltered, + final java.util.function.Predicate retainIfTrue) { + return null; + } + } + ]]> + From 5afe9a47b64dac294e03f58e06458ba244edace2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 21 Oct 2025 19:09:55 +0200 Subject: [PATCH 1536/1962] Properly ground the tree when invocation fails This does not need to be done when testing for applicability as this really only affects lambdas, and they are not relevant to applicability --- .../types/ast/internal/LazyTypeResolver.java | 2 +- .../java/types/internal/infer/ExprMirror.java | 31 ++++++++++++++ .../lang/java/types/internal/infer/Infer.java | 4 ++ .../internal/infer/InferenceContext.java | 9 ++++- .../infer/ast/BaseFunctionalMirror.java | 7 ++++ .../internal/infer/ast/BaseInvocMirror.java | 8 ++++ .../internal/infer/ast/BasePolyMirror.java | 7 ++++ .../internal/infer/ast/LambdaMirrorImpl.java | 5 +++ .../infer/UnresolvedTypesRecoveryTest.kt | 40 +++++++++++++++++-- 9 files changed, 107 insertions(+), 6 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/LazyTypeResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/LazyTypeResolver.java index a030f1c20e6..8fa8d76ea44 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/LazyTypeResolver.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/LazyTypeResolver.java @@ -605,7 +605,7 @@ public JTypeMirror visit(ASTVariableAccess node, TypingContext ctx) { // then the type of the parameter depends on the type // of the lambda, which most likely depends on the overload // resolution of an enclosing invocation context - resultMirror = id.getTypeMirror(); + resultMirror = id.getTypeMirror(ctx); } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java index f32c8c1ab3d..61af4b3e773 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java @@ -126,6 +126,36 @@ default void finishStandaloneInference(@NonNull JTypeMirror standaloneType) { */ boolean isEquivalentToUnderlyingAst(); + + /** + * Ground this expression and any expressions that might have been + * assigned a type/ other data during type inference of this node. + * This is called when inference in a parent expression failed, to + * clean up partial data like type inference. + * + *

          This is only called if the invocation fails, not when testing + * for applicability. The reason is that this is really only relevant + * for lambdas (to reset the type of their parameters), and those are + * not relevant to applicability. + */ + default void groundTree() { + setInferredType(ensureNoTypeVariables(getInferredType())); + } + + static JTypeMirror ensureNoTypeVariables(JTypeMirror ty) { + if (ty == null) { + return null; + } + return ty.subst(InferenceContext.finalGroundSubst()); + } + + static JMethodSig ensureNoTypeVariables(JMethodSig ty) { + if (ty == null) { + return null; + } + return ty.subst(InferenceContext.finalGroundSubst()); + } + /** A general category of types. */ enum TypeSpecies { PRIMITIVE, @@ -476,6 +506,7 @@ interface InvocationMirror extends PolyExprMirror, MethodUsageMirror { return getReceiverType(); } + /** * Information about the overload-resolution for a specific method. */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java index 785df0ef5cd..2c2d38e0ad0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java @@ -224,6 +224,10 @@ private MethodCtDecl goToInvocationWithFallback(MethodCallSite site) { JMethodSig fallback = deleteTypeParams(cast(ctdecl.getMethodType()).adaptedMethod()); LOG.fallbackInvocation(fallback, site); + // When we fail in invocation we need to clean-up partial + // data from the tree. This means erasing inference variables + // from the types stored in AST nodes. + site.getExpr().groundTree(); return ctdecl.withMethod(fallback, true); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/InferenceContext.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/InferenceContext.java index 914211f942b..1eac845b2be 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/InferenceContext.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/InferenceContext.java @@ -19,6 +19,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.function.Function; import java.util.function.Supplier; import org.checkerframework.checker.nullness.qual.NonNull; @@ -291,14 +292,18 @@ private static JTypeMirror groundSubst(SubstVar var) { * or else replace them with a failed type. */ static JMethodSig finalGround(JMethodSig t) { - return t.subst(s -> { + return t.subst(finalGroundSubst()); + } + + public static Function finalGroundSubst() { + return s -> { if (!(s instanceof InferenceVar)) { return s; } else { InferenceVar ivar = (InferenceVar) s; return ivar.getInst() != null ? ivar.getInst() : s.getTypeSystem().ERROR; } - }); + }; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/BaseFunctionalMirror.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/BaseFunctionalMirror.java index db30b10b4ad..f4e048469af 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/BaseFunctionalMirror.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/BaseFunctionalMirror.java @@ -32,6 +32,13 @@ public void setFunctionalMethod(JMethodSig methodType) { } } + @Override + public void groundTree() { + if (mayMutateAst() && inferredMethod != null) { + InternalApiBridge.setFunctionalMethod(myNode, ExprMirror.ensureNoTypeVariables(inferredMethod)); + } + } + protected JMethodSig getInferredMethod() { return inferredMethod; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/BaseInvocMirror.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/BaseInvocMirror.java index 9430fa13a78..eb3f3ca4788 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/BaseInvocMirror.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/BaseInvocMirror.java @@ -44,6 +44,14 @@ abstract class BaseInvocMirror extends BasePolyMirror< mayBePoly = !mustBeStandalone; } + @Override + public void groundTree() { + super.groundTree(); + for (ExprMirror arg : getArgumentExpressions()) { + arg.groundTree(); + } + } + @Override public boolean isEquivalentToUnderlyingAst() { MethodCtDecl ctDecl = getCtDecl(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/BasePolyMirror.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/BasePolyMirror.java index 3f72514f411..cc418e06505 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/BasePolyMirror.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/BasePolyMirror.java @@ -39,6 +39,13 @@ public void setInferredType(JTypeMirror mirror) { } } + @Override + public void groundTree() { + if (inferredType != null) { + setInferredType(ExprMirror.ensureNoTypeVariables(inferredType)); + } + } + @Override public JTypeMirror getInferredType() { return inferredType; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/LambdaMirrorImpl.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/LambdaMirrorImpl.java index d83d1ec32d6..e6bd0d4923d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/LambdaMirrorImpl.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/LambdaMirrorImpl.java @@ -50,6 +50,11 @@ class LambdaMirrorImpl extends BaseFunctionalMirror impleme } } + @Override + public void setInferredType(JTypeMirror mirror) { + super.setInferredType(mirror); + } + @Override public boolean isEquivalentToUnderlyingAst() { JTypeMirror inferredType = getInferredType(); diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt index 5dc9514908c..8035f07e165 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt @@ -906,7 +906,7 @@ class C { ) val (barClass) = acu.declaredTypeSignatures() - val (filterCall, unknownCall, debugCall) = acu.methodCalls().crossFindBoundaries().toList() + val (filterCall, _, debugCall) = acu.methodCalls().crossFindBoundaries().toList() val (filter) = acu.methodDeclarations().toList { it.genericSignature } with(acu.typeDsl) { @@ -935,8 +935,7 @@ class C { """.trimIndent() ) - val (barClass) = acu.declaredTypeSignatures() - val (filterCall, unknownCall, debugCall) = acu.methodCalls().crossFindBoundaries().toList() + val (filterCall, _, debugCall) = acu.methodCalls().crossFindBoundaries().toList() val (filter) = acu.methodDeclarations().toList { it.genericSignature } with(acu.typeDsl) { @@ -947,4 +946,39 @@ class C { debugCall shouldHaveType ts.UNKNOWN } } + + parserTest("Invocation failure when there is a lambda should clean up the type of lambda parameters properly") { + val (acu, spy) = parser.parseWithTypeInferenceSpy( + """ + class Bar {} + class Baz {} + public class Foo { + + static { + // Here we need a method that is applicable, but where + // invocation fails because of the target type. + Iterable local = filter(unknown(), input -> input.debug()); + } + + + public static Iterable filter(final Iterable unfiltered, + final java.util.function.Predicate retainIfTrue) { + return null; + } + + static Iterable unknown() {} + } + """.trimIndent() + ) + + val (filterCall, _, debugCall) = acu.methodCalls().crossFindBoundaries().toList() + val (filter) = acu.methodDeclarations().toList { it.genericSignature } + + with(acu.typeDsl) { + filterCall shouldHaveType java.lang.Iterable::class[ts.ERROR] + filterCall.methodType shouldBeSomeInstantiationOf filter + spy.shouldUseFallback(filterCall) + debugCall.qualifier!! shouldHaveType ts.ERROR + } + } }) From cdfbd011f94f40af916452d8cb4b9a9617ca50a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 21 Oct 2025 19:13:19 +0200 Subject: [PATCH 1537/1962] Trim trailing whitespace --- .../infer/UnresolvedTypesRecoveryTest.kt | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt index 8035f07e165..d9024f8f34a 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt @@ -230,7 +230,8 @@ class C { static { // Creates bounds: `T >: ooo.Foo` and `T <: ooo.Bound` // Should not be deemed incompatible - id(foo()); + id(foo()); + } } """.trimIndent() @@ -347,9 +348,10 @@ class C { // Select the most general overload, append(Object)? // Just inverting the specificity relation, to select the most general, // would not work well when there are several parameters. - // Note that /*unresolved*/ and /*error*/ are the only types for which + // Note that /*unresolved*/ and /*error*/ are the only types for which + // there is ambiguity - + // For now, report an ambiguity error new StringBuilder().append(Unresolved.SOMETHING); } @@ -581,7 +583,6 @@ class C { } } - parserTest("Wrong syntax, return with expr in void method") { val (acu, spy) = parser.parseWithTypeInferenceSpy( """ @@ -641,7 +642,7 @@ class C { } interface Stream { Stream map(Function fun); - + // the point of this test is there is an ambiguity between both of these overloads static Stream of(U u) {} static Stream of(U... u) {} @@ -959,14 +960,14 @@ class C { // invocation fails because of the target type. Iterable local = filter(unknown(), input -> input.debug()); } - public static Iterable filter(final Iterable unfiltered, final java.util.function.Predicate retainIfTrue) { return null; } - - static Iterable unknown() {} + + static Iterable unknown() {} + } """.trimIndent() ) From 399b41c25514fcb5929bfedad1efe2a5cc4eaadb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 21 Oct 2025 19:33:13 +0200 Subject: [PATCH 1538/1962] Add unit tests, make sure resolution does not depend on order of constraints --- .../types/internal/infer/ReductionStep.java | 24 ++++++++++++- .../internal/infer/InferenceCtxUnitTests.java | 35 +++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ReductionStep.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ReductionStep.java index 11980b4587f..8e347d0ca6e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ReductionStep.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ReductionStep.java @@ -12,6 +12,7 @@ import net.sourceforge.pmd.lang.java.types.JTypeMirror; import net.sourceforge.pmd.lang.java.types.TypeOps; +import net.sourceforge.pmd.lang.java.types.TypeSystem; import net.sourceforge.pmd.lang.java.types.internal.infer.InferenceVar.BoundKind; import net.sourceforge.pmd.util.CollectionUtil; @@ -27,7 +28,28 @@ enum ReductionStep { EQ(BoundKind.EQ) { @Override JTypeMirror solve(InferenceVar uv, InferenceContext inferenceContext) { - return filterBounds(uv, inferenceContext).get(0); + List types = filterBounds(uv, inferenceContext); + if (types.size() == 1) { + return types.get(0); + } + + // If there are several EQ bounds, then they must be different + // types for Object#equals, but since incorporation did not fail, + // this means IncorporationAction#checkBound considers them compatible. + // This must mean either: + // 1. they are ERROR and another type (including UNKNOWN): return ERROR + // 2. they are UNKNOWN and another type (including UNKNOWN): return the other type. + TypeSystem ts = inferenceContext.ts; + if (types.contains(ts.ERROR)) { + return ts.ERROR; + } + if (types.contains(ts.UNKNOWN) && types.size() == 2) { + types.remove(ts.UNKNOWN); + return types.get(0); + } + + // there shouldn't be any other case but in that case we return error. + return ts.ERROR; } }, diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/internal/infer/InferenceCtxUnitTests.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/internal/infer/InferenceCtxUnitTests.java index ba1d8342618..75e7a846864 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/internal/infer/InferenceCtxUnitTests.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/internal/infer/InferenceCtxUnitTests.java @@ -8,6 +8,7 @@ import static net.sourceforge.pmd.lang.java.types.internal.infer.BaseTypeInferenceUnitTest.Bound.eqBound; import static net.sourceforge.pmd.lang.java.types.internal.infer.BaseTypeInferenceUnitTest.Bound.lower; import static net.sourceforge.pmd.lang.java.types.internal.infer.BaseTypeInferenceUnitTest.Bound.upper; +import static net.sourceforge.pmd.util.CollectionUtil.listOf; import static net.sourceforge.pmd.util.CollectionUtil.setOf; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; @@ -28,6 +29,7 @@ import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Test; +import net.sourceforge.pmd.lang.java.types.InternalApiBridge; import net.sourceforge.pmd.lang.java.types.JTypeMirror; import net.sourceforge.pmd.lang.java.types.TypeOps; import net.sourceforge.pmd.lang.java.types.internal.infer.InferenceVar.BoundKind; @@ -127,6 +129,39 @@ void testEqBoundWithGenerics() { assertEquals(listType(ts.OBJECT), v1.getInst()); } + @Test + void testEqBoundWithErrorYieldsError() { + testEqBoundMerging(listOf(ts.UNKNOWN, ts.ERROR), ts.ERROR); + testEqBoundMerging(listOf(ts.ERROR, ts.UNKNOWN), ts.ERROR); + + testEqBoundMerging(listOf(listType(ts.OBJECT), ts.ERROR), ts.ERROR); + testEqBoundMerging(listOf(ts.ERROR, listType(ts.OBJECT)), ts.ERROR); + } + + @Test + void testEqBoundWithUnknownYieldsOtherType() { + testEqBoundMerging(listOf(listType(ts.OBJECT), ts.UNKNOWN), listType(ts.OBJECT)); + testEqBoundMerging(listOf(ts.UNKNOWN, listType(ts.OBJECT)), listType(ts.OBJECT)); + } + + void testEqBoundMerging(List eqBounds, JTypeMirror result) { + TypeInferenceLogger log = spy(TypeInferenceLogger.noop()); + InferenceContext ctx = emptyCtx(log); + + InferenceVar v1 = newIvar(ctx); + + for (JTypeMirror eq : eqBounds) { + InternalApiBridge.isSameTypeInInference(v1, eq); + } + + ctx.incorporate(); + ctx.solve(); + + assertEquals(result, v1.getInst()); + } + + + @Test void testEqBoundMergesIvar() { From 5631f97149e32d3ab6bb3475a7ddb02b6443363e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 21 Oct 2025 19:34:41 +0200 Subject: [PATCH 1539/1962] Make TypeTestUtil more defensive Will not throw if an inference variable is found --- .../net/sourceforge/pmd/lang/java/types/TypeTestUtil.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeTestUtil.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeTestUtil.java index d2dc5500e5d..285e6911ba4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeTestUtil.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeTestUtil.java @@ -15,7 +15,6 @@ import net.sourceforge.pmd.lang.java.ast.TypeNode; import net.sourceforge.pmd.lang.java.symbols.JClassSymbol; import net.sourceforge.pmd.lang.java.symbols.JTypeDeclSymbol; -import net.sourceforge.pmd.lang.java.symbols.JTypeParameterSymbol; import net.sourceforge.pmd.lang.java.symbols.internal.UnresolvedClassStore; import net.sourceforge.pmd.util.AssertionUtil; import net.sourceforge.pmd.util.OptionalBool; @@ -272,17 +271,16 @@ static OptionalBool isExactlyAOrAnon(@NonNull String canonicalName, final @NonNu AssertionUtil.requireParamNotNull("canonicalName", canonicalName); JTypeDeclSymbol sym = node.getSymbol(); - if (sym == null || sym instanceof JTypeParameterSymbol) { + if (!(sym instanceof JClassSymbol)) { return OptionalBool.NO; } - canonicalName = StringUtils.deleteWhitespace(canonicalName); - JClassSymbol klass = (JClassSymbol) sym; String canonical = klass.getCanonicalName(); if (canonical == null) { return OptionalBool.UNKNOWN; // anonymous } + canonicalName = StringUtils.deleteWhitespace(canonicalName); return OptionalBool.definitely(canonical.equals(canonicalName)); } From de897ac6d9c7a35080683a9f9c11f449ddbbf313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 21 Oct 2025 20:18:20 +0200 Subject: [PATCH 1540/1962] Cleanup --- .../pmd/lang/java/types/internal/infer/ReductionStep.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ReductionStep.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ReductionStep.java index 8e347d0ca6e..9bf659ae66e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ReductionStep.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ReductionStep.java @@ -40,15 +40,10 @@ JTypeMirror solve(InferenceVar uv, InferenceContext inferenceContext) { // 1. they are ERROR and another type (including UNKNOWN): return ERROR // 2. they are UNKNOWN and another type (including UNKNOWN): return the other type. TypeSystem ts = inferenceContext.ts; - if (types.contains(ts.ERROR)) { - return ts.ERROR; - } if (types.contains(ts.UNKNOWN) && types.size() == 2) { types.remove(ts.UNKNOWN); - return types.get(0); + return types.get(0); // (this might be error) } - - // there shouldn't be any other case but in that case we return error. return ts.ERROR; } }, From 12efbbe78b8346231be3e79a0314b8bea3b458e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 22 Oct 2025 19:06:23 +0200 Subject: [PATCH 1541/1962] Fix PMD warning --- .../lang/java/types/internal/infer/ast/LambdaMirrorImpl.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/LambdaMirrorImpl.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/LambdaMirrorImpl.java index e6bd0d4923d..d83d1ec32d6 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/LambdaMirrorImpl.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ast/LambdaMirrorImpl.java @@ -50,11 +50,6 @@ class LambdaMirrorImpl extends BaseFunctionalMirror impleme } } - @Override - public void setInferredType(JTypeMirror mirror) { - super.setInferredType(mirror); - } - @Override public boolean isEquivalentToUnderlyingAst() { JTypeMirror inferredType = getInferredType(); From 76126d5b1f132821629f1fb550da582a5538b4b6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 28 Oct 2025 08:43:19 +0100 Subject: [PATCH 1542/1962] [doc] Update release notes (#6156, #6146) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 83a7fe9af33..b6359b825d8 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -67,6 +67,7 @@ checkstyle version during the build. * [#6022](https://github.com/pmd/pmd/issues/6022): \[apex] ExcessiveClassLength/ExcessiveParameterList include the metric in the message * java * [#4904](https://github.com/pmd/pmd/issues/4904): \[java] Renderers output wrong class qualified name for nested classes + * [#6146](https://github.com/pmd/pmd/issues/6146): \[java] ClassCastException: class InferenceVarSym cannot be cast to class JClassSymbol * java-bestpractices * [#4122](https://github.com/pmd/pmd/issues/4122): \[java] CheckResultSet false-positive with local variable * [#6124](https://github.com/pmd/pmd/issues/6124): \[java] UnusedLocalVariable: fix false negatives in pattern matching @@ -142,6 +143,7 @@ checkstyle version during the build. * [#6130](https://github.com/pmd/pmd/pull/6130): \[java] UselessParentheses: fix false positives for switch expressions - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6133](https://github.com/pmd/pmd/pull/6133): \[java] Fix #5042: CloseResource: fix false positive with pattern matching - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6152](https://github.com/pmd/pmd/pull/6152): chore(deps): Update Saxon-HE from 12.5 to 12.9 - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6156](https://github.com/pmd/pmd/pull/6156): \[java] Fix #6146: ClassCastException in TypeTestUtil - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) ### ๐Ÿ“ฆ Dependency updates From 282a04bc52856fd1b5aaa87964f9b06e59ded23f Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Sun, 19 Oct 2025 15:03:21 +0200 Subject: [PATCH 1543/1962] [core] Reduce memory usage of CPD's MatchCollector --- .../java/net/sourceforge/pmd/cpd/MatchCollector.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MatchCollector.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MatchCollector.java index 6fc84bdd81e..ec313dc35e7 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MatchCollector.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/MatchCollector.java @@ -5,19 +5,18 @@ package net.sourceforge.pmd.cpd; import java.util.ArrayList; +import java.util.BitSet; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.TreeMap; class MatchCollector { private final Map> matchTree = new TreeMap<>(); - private final Map> tokenMatchSets = new HashMap<>(); + private final Map tokenMatchSets = new HashMap<>(); private final MatchAlgorithm ma; @@ -68,7 +67,7 @@ private void reportMatch(TokenEntry mark1, TokenEntry mark2, int dupes) { * - BC * It should be reduced to a single match with 3 marks */ - if (tokenMatchSets.computeIfAbsent(mark1.getIndex(), (i) -> new HashSet<>()).contains(mark2.getIndex())) { + if (tokenMatchSets.computeIfAbsent(mark1.getIndex(), (i) -> new BitSet()).get(mark2.getIndex())) { return; } @@ -116,8 +115,8 @@ private void reportMatch(TokenEntry mark1, TokenEntry mark2, int dupes) { } private void registerTokenMatch(TokenEntry mark1, TokenEntry mark2) { - tokenMatchSets.computeIfAbsent(mark1.getIndex(), (i) -> new HashSet<>()).add(mark2.getIndex()); - tokenMatchSets.computeIfAbsent(mark2.getIndex(), (i) -> new HashSet<>()).add(mark1.getIndex()); + tokenMatchSets.computeIfAbsent(mark1.getIndex(), (i) -> new BitSet()).set(mark2.getIndex()); + tokenMatchSets.computeIfAbsent(mark2.getIndex(), (i) -> new BitSet()).set(mark1.getIndex()); } List getMatches() { From 4346bca1f23a3f31cd421124837c885f8b6fe7d5 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 29 Oct 2025 12:41:24 +0100 Subject: [PATCH 1544/1962] [doc] Update release notes (#6150) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index b6359b825d8..3a02aa41ec4 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -61,6 +61,7 @@ checkstyle version during the build. * [#6097](https://github.com/pmd/pmd/issues/6097): \[doc] Add PMD versions dropdown * [#6098](https://github.com/pmd/pmd/issues/6098): \[doc] Add a copy URL button * [#6101](https://github.com/pmd/pmd/issues/6101): \[doc] Highlight current header in TOC + * [#6150](https://github.com/pmd/pmd/issues/6150): \[core] Reduce memory usage of CPD's MatchCollector * apex * [#5935](https://github.com/pmd/pmd/issues/5935): \[apex] @SuppressWarnings - allow whitespace around comma when suppressing multiple rules * apex-design @@ -142,6 +143,7 @@ checkstyle version during the build. * [#6124](https://github.com/pmd/pmd/pull/6124): \[java] UnusedLocalVariable: fix false negatives in pattern matching - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6130](https://github.com/pmd/pmd/pull/6130): \[java] UselessParentheses: fix false positives for switch expressions - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6133](https://github.com/pmd/pmd/pull/6133): \[java] Fix #5042: CloseResource: fix false positive with pattern matching - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6150](https://github.com/pmd/pmd/pull/6150): \[core] Reduce memory usage of CPD's MatchCollector - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6152](https://github.com/pmd/pmd/pull/6152): chore(deps): Update Saxon-HE from 12.5 to 12.9 - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6156](https://github.com/pmd/pmd/pull/6156): \[java] Fix #6146: ClassCastException in TypeTestUtil - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) From d477f6380d561a8e85a50453b34dfa7d174dddee Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 10 Oct 2025 17:13:57 +0200 Subject: [PATCH 1545/1962] [java] Fix #6127: Correct var name in violation decorator --- docs/pages/release_notes.md | 1 + .../java/internal/JavaViolationDecorator.java | 2 +- .../java/internal/JavaViolationDecoratorTest.java | 15 +++++++++++++++ .../bestpractices/xml/AvoidUsingHardCodedIP.xml | 15 +++++++++++++++ 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 3a02aa41ec4..24d048ffb24 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -68,6 +68,7 @@ checkstyle version during the build. * [#6022](https://github.com/pmd/pmd/issues/6022): \[apex] ExcessiveClassLength/ExcessiveParameterList include the metric in the message * java * [#4904](https://github.com/pmd/pmd/issues/4904): \[java] Renderers output wrong class qualified name for nested classes + * [#6127](https://github.com/pmd/pmd/issues/6127): \[java] Incorrect variable name in violation * [#6146](https://github.com/pmd/pmd/issues/6146): \[java] ClassCastException: class InferenceVarSym cannot be cast to class JClassSymbol * java-bestpractices * [#4122](https://github.com/pmd/pmd/issues/4122): \[java] CheckResultSet false-positive with local variable diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecorator.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecorator.java index c18acce6ec1..309f83ce124 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecorator.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecorator.java @@ -119,7 +119,7 @@ private static String getVariableNames(Iterable iterable) { } else if (node instanceof ASTFormalParameter) { return getVariableNameIfExists(node.firstChild(ASTVariableId.class)); } else if (node instanceof ASTExpression) { - return getVariableNameIfExists(node.getParent()); + return getVariableNameIfExists(node.ancestors(ASTVariableDeclarator.class).first()); } return null; } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecoratorTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecoratorTest.java index 21961aa2649..ac9113d4044 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecoratorTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecoratorTest.java @@ -10,6 +10,8 @@ import static net.sourceforge.pmd.reporting.RuleViolation.VARIABLE_NAME; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasEntry; +import static org.hamcrest.Matchers.hasKey; +import static org.hamcrest.Matchers.not; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.HashMap; @@ -27,6 +29,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTNumericLiteral; +import net.sourceforge.pmd.lang.java.ast.ASTStringLiteral; import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration; import net.sourceforge.pmd.lang.java.ast.JavaNode; @@ -258,4 +261,16 @@ void testInitializers() { assertThat(decorate(expressions.get(1)), hasEntry(VARIABLE_NAME, "x")); } + @Test + void variableNameForStringLiterals() { + ASTCompilationUnit ast = parse("class Foo { { String var1 = new String(\"var1\"); new String(\"var2\"); } }"); + List literals = ast.descendants(ASTStringLiteral.class).toList(); + assertEquals(2, literals.size()); + + assertThat(decorate(literals.get(0)), hasEntry(CLASS_NAME, "Foo")); + assertThat(decorate(literals.get(0)), hasEntry(VARIABLE_NAME, "var1")); + + assertThat(decorate(literals.get(1)), hasEntry(CLASS_NAME, "Foo")); + assertThat(decorate(literals.get(1)), not(hasKey(VARIABLE_NAME))); + } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml index 0253557f281..fbda928bb59 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml @@ -150,4 +150,19 @@ public class Foo { 15 + + + #6127 missing var name in message + 1 + 3 + + Do not hard code the IP address address + + + From 465ee0933a258eba929f500b19166971e1878ad8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 27 Oct 2025 10:41:02 +0100 Subject: [PATCH 1546/1962] [java] ViolationDecorator - consider scope for var name --- .../java/internal/JavaViolationDecorator.java | 9 ++++++++- .../internal/JavaViolationDecoratorTest.java | 20 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecorator.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecorator.java index 309f83ce124..c7b4f77525b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecorator.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecorator.java @@ -24,6 +24,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTVariableId; import net.sourceforge.pmd.lang.java.ast.JavaNode; import net.sourceforge.pmd.lang.java.ast.ModifierOwner; +import net.sourceforge.pmd.lang.java.ast.ReturnScopeNode; import net.sourceforge.pmd.reporting.RuleViolation; import net.sourceforge.pmd.reporting.ViolationDecorator; import net.sourceforge.pmd.util.IteratorUtil; @@ -119,7 +120,13 @@ private static String getVariableNames(Iterable iterable) { } else if (node instanceof ASTFormalParameter) { return getVariableNameIfExists(node.firstChild(ASTVariableId.class)); } else if (node instanceof ASTExpression) { - return getVariableNameIfExists(node.ancestors(ASTVariableDeclarator.class).first()); + for (JavaNode n : node.ancestors()) { + if (n instanceof ReturnScopeNode) { + return null; + } else if (n instanceof ASTVariableDeclarator) { + return getVariableNameIfExists(n); + } + } } return null; } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecoratorTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecoratorTest.java index ac9113d4044..66b9a4b6dea 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecoratorTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecoratorTest.java @@ -273,4 +273,24 @@ void variableNameForStringLiterals() { assertThat(decorate(literals.get(1)), hasEntry(CLASS_NAME, "Foo")); assertThat(decorate(literals.get(1)), not(hasKey(VARIABLE_NAME))); } + + @Test + void noVariableNameForStringLiteralsInsideLambda() { + ASTCompilationUnit ast = parse("class Foo {\n" + + " void foo() {\n" + + " int otherVariable = 1;\n" + + " Runnable run = () -> {\n" + + " System.out.println(\"noVar\");\n" + + " };\n" + + " }\n" + + "}\n"); + List literals = ast.descendants(ASTStringLiteral.class).crossFindBoundaries().toList(); + assertEquals(1, literals.size()); + + Map decorated = decorate(literals.get(0)); + assertThat(decorated, hasEntry(CLASS_NAME, "Foo")); + assertThat(decorated, hasEntry(METHOD_NAME, "foo")); + assertThat(decorated, not(hasEntry(VARIABLE_NAME, "run"))); + assertThat(decorated, not(hasKey(VARIABLE_NAME))); + } } From 1e54bda15f7d6ff117845e0bbd07a4526b536fff Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 27 Oct 2025 10:41:42 +0100 Subject: [PATCH 1547/1962] [doc] Update release notes (#6129) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 24d048ffb24..a7909d03ccd 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -142,6 +142,7 @@ checkstyle version during the build. * [#6114](https://github.com/pmd/pmd/pull/6114): \[java] Fix #4122: CheckResultSet false-positive with local variable - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6116](https://github.com/pmd/pmd/pull/6116): \[java] ConfusingTernary: add configuration property for null checks - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6124](https://github.com/pmd/pmd/pull/6124): \[java] UnusedLocalVariable: fix false negatives in pattern matching - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6129](https://github.com/pmd/pmd/pull/6129): \[java] Fix #6127: Correct var name in violation decorator - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6130](https://github.com/pmd/pmd/pull/6130): \[java] UselessParentheses: fix false positives for switch expressions - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6133](https://github.com/pmd/pmd/pull/6133): \[java] Fix #5042: CloseResource: fix false positive with pattern matching - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6150](https://github.com/pmd/pmd/pull/6150): \[core] Reduce memory usage of CPD's MatchCollector - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) From 0c503850087211dacfc003e7683d95657847d636 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 23 Oct 2025 11:37:08 +0200 Subject: [PATCH 1548/1962] [doc] Update reproducible build info with Java 17 Fixes #6149 --- docs/pages/pmd/devdocs/building/building_general.md | 3 ++- docs/pages/release_notes.md | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/pages/pmd/devdocs/building/building_general.md b/docs/pages/pmd/devdocs/building/building_general.md index 4c684042476..d78ac25acd8 100644 --- a/docs/pages/pmd/devdocs/building/building_general.md +++ b/docs/pages/pmd/devdocs/building/building_general.md @@ -52,7 +52,8 @@ limitations apply: * Generally depend on the **major version of the JDK** used to compile. (Even with source/target defined, each major JDK version changes the generated bytecode.). - We build our releases using OpenJDK 11. + PMD 6.24.0 - 7.17.0 is built using OpenJDK 11. + Since PMD 7.18.0, we build our releases using OpenJDK 17. You can check the reproducible build status here: diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index a7909d03ccd..9b9816ac29a 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -61,6 +61,7 @@ checkstyle version during the build. * [#6097](https://github.com/pmd/pmd/issues/6097): \[doc] Add PMD versions dropdown * [#6098](https://github.com/pmd/pmd/issues/6098): \[doc] Add a copy URL button * [#6101](https://github.com/pmd/pmd/issues/6101): \[doc] Highlight current header in TOC + * [#6149](https://github.com/pmd/pmd/issues/6149): \[doc] Reproducible Build Documentation is outdated - PMD is now built using Java 17 * [#6150](https://github.com/pmd/pmd/issues/6150): \[core] Reduce memory usage of CPD's MatchCollector * apex * [#5935](https://github.com/pmd/pmd/issues/5935): \[apex] @SuppressWarnings - allow whitespace around comma when suppressing multiple rules @@ -148,6 +149,7 @@ checkstyle version during the build. * [#6150](https://github.com/pmd/pmd/pull/6150): \[core] Reduce memory usage of CPD's MatchCollector - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6152](https://github.com/pmd/pmd/pull/6152): chore(deps): Update Saxon-HE from 12.5 to 12.9 - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6156](https://github.com/pmd/pmd/pull/6156): \[java] Fix #6146: ClassCastException in TypeTestUtil - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#6164](https://github.com/pmd/pmd/pull/6164): \[doc] Update reproducible build info with Java 17 - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ Dependency updates From 0b7650d47342aba720117727f7e2ae2be37584d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Tue, 9 Sep 2025 16:26:34 +0200 Subject: [PATCH 1549/1962] New rule: AvoidLoopLabels --- .../resources/category/java/bestpractices.xml | 38 ++++ .../bestpractices/AvoidLoopLabelsTest.java | 11 + .../bestpractices/xml/AvoidLoopLabels.xml | 215 ++++++++++++++++++ 3 files changed, 264 insertions(+) create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidLoopLabelsTest.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidLoopLabels.xml diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index a1b250ad7f2..7cc1f3cdf72 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -179,6 +179,44 @@ public class AvoidMessageDigestFieldExample { + + +This rule detects the use of labeled break and continue statements with loops. +Labels make control flow difficult to understand and should be avoided. They can be confused +with the goto statement and make code harder to read and maintain. + +If you really need to jump out of an inner loop, think about refactoring the multiple +loops into a function - that way, you can replace the break with a return. + + 3 + + + + + + + + + + + + + + + + violation: labeled break in for loop + 1 + 6 + + Avoid using labeled break and continue statements + + + + + + violation: labeled continue in nested for loops + 1 + 6 + + Avoid using labeled break and continue statements + + + + + + violation: labeled break in while loop + 1 + 7 + + + + + violation: labeled continue in do-while loop + 1 + 7 + + + + + violation: labeled break in enhanced for loop + 1 + 7 + + + + + violation: multiple labeled breaks targeting different loops + 2 + 9,11 + 5) { + break middle; // violation + } + break outer; // violation + } + } + } + } +} + ]]> + + + + no violation: unlabeled break in for loop + 0 + + + + + no violation: unlabeled continue in while loop + 0 + + + + + no violation: break in switch statement + 0 + + + + + no violation: labeled statement without break/continue + 0 + + + + + no violation: mixed loops with unlabeled controls + 0 + + + + \ No newline at end of file From f5604768c4258ca2089360102e18f31144479ba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Glimm?= Date: Tue, 16 Sep 2025 22:11:43 +0200 Subject: [PATCH 1550/1962] Update "since" --- pmd-java/src/main/resources/category/java/bestpractices.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 7cc1f3cdf72..faa7a271844 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -181,7 +181,7 @@ public class AvoidMessageDigestFieldExample { From b5bd43cdb9b6bdaa8cb9d0df7402859cbdbe878c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 23 Oct 2025 10:02:53 +0200 Subject: [PATCH 1551/1962] Fix rule sort order --- .../resources/category/java/bestpractices.xml | 76 +++++++++---------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index faa7a271844..3a9a2edd1c5 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -129,6 +129,44 @@ public class Foo { + + + This rule detects the use of labeled break and continue statements with loops. + Labels make control flow difficult to understand and should be avoided. They can be confused + with the goto statement and make code harder to read and maintain. + + If you really need to jump out of an inner loop, think about refactoring the multiple + loops into a function - that way, you can replace the break with a return. + + 3 + + + + + + + + + + + + - - -This rule detects the use of labeled break and continue statements with loops. -Labels make control flow difficult to understand and should be avoided. They can be confused -with the goto statement and make code harder to read and maintain. - -If you really need to jump out of an inner loop, think about refactoring the multiple -loops into a function - that way, you can replace the break with a return. - - 3 - - - - - - - - - - - - Date: Thu, 23 Oct 2025 10:31:16 +0200 Subject: [PATCH 1552/1962] [java] New Rule UnusedLabel --- docs/pages/release_notes.md | 6 ++- .../resources/category/java/bestpractices.xml | 38 ++++++++++++++++ .../resources/rulesets/java/quickstart.xml | 1 + .../rule/bestpractices/UnusedLabelTest.java | 11 +++++ .../rule/bestpractices/xml/UnusedLabel.xml | 44 +++++++++++++++++++ 5 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLabelTest.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLabel.xml diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 9b9816ac29a..9d6f86b693f 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -29,12 +29,14 @@ From now on, Java 17 or newer is required to build PMD. PMD itself still remains so that it still can be used in a pure Java 8 environment. This allows us to use the latest checkstyle version during the build. -### ๐ŸŒŸ Rules changes +### ๐ŸŒŸ New and Changed Rules #### New Rules * The new Java rule {% rule java/errorprone/IdenticalConditionalBranches %} finds conditional statements that do the same thing when the condition is true and false. This is either incorrect or redundant. +* The new Java rule {%rule java/bestpractices/UnusedLabel %} finds unused labels which are unnecessary and + only make the code hard to read. This new rule will be part of the quickstart ruleset. -#### Modified rules +#### Changed Rules * {%rule java/codestyle/ConfusingTernary %} has a new property `nullCheckBranch` to control, whether null-checks should be allowed (the default case) or should lead to a violation. * {%rule java/errorprone/AvoidCatchingGenericException %} is now configurable with the new property diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 3a9a2edd1c5..16c2c11c7e5 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -1908,6 +1908,44 @@ public class Foo { + + +Unused labeled are unnecessary and may be confusing as you might be wondering what this label is used for. +To improve readability the unused label should simply be removed. + +This rule implements SonarSource rule [S1065](https://sonarsource.github.io/rspec/#/rspec/S1065). + + 3 + + + + + + + + + + + + --> + diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLabelTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLabelTest.java new file mode 100644 index 00000000000..62457fecec3 --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLabelTest.java @@ -0,0 +1,11 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.bestpractices; + +import net.sourceforge.pmd.test.PmdRuleTst; + +public class UnusedLabelTest extends PmdRuleTst { + // no additional unit tests +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLabel.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLabel.xml new file mode 100644 index 00000000000..045b16d16cf --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLabel.xml @@ -0,0 +1,44 @@ + + + + + Example + 1 + 3 + + Avoid unused labels such as 'lbl1'. + + + + + + Used label + 0 + + + \ No newline at end of file From 43c08cd145b189deb3fc93732fe7facfa1703d9f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 23 Oct 2025 10:59:39 +0200 Subject: [PATCH 1553/1962] [java] Rename Rule AvoidLoopLabels to LabeledStatement --- docs/pages/release_notes.md | 3 + .../resources/category/java/bestpractices.xml | 113 ++++++++++++------ .../resources/rulesets/java/quickstart.xml | 1 + ...elsTest.java => LabeledStatementTest.java} | 2 +- ...oidLoopLabels.xml => LabeledStatement.xml} | 69 +++++++++-- 5 files changed, 139 insertions(+), 49 deletions(-) rename pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/{AvoidLoopLabelsTest.java => LabeledStatementTest.java} (82%) rename pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/{AvoidLoopLabels.xml => LabeledStatement.xml} (68%) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 9d6f86b693f..1d3b4013287 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -33,6 +33,9 @@ checkstyle version during the build. #### New Rules * The new Java rule {% rule java/errorprone/IdenticalConditionalBranches %} finds conditional statements that do the same thing when the condition is true and false. This is either incorrect or redundant. +* The new Java rule {%rule java/bestpractices/LabeledStatement %} finds labeled statements in code. + Labels make control flow difficult to understand and should be avoided. By default, the rule allows labeled + loops (do, while, for). But it has a property to flag also those labeled loops. * The new Java rule {%rule java/bestpractices/UnusedLabel %} finds unused labels which are unnecessary and only make the code hard to read. This new rule will be part of the quickstart ruleset. diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 16c2c11c7e5..233b944ac04 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -129,44 +129,6 @@ public class Foo { - - - This rule detects the use of labeled break and continue statements with loops. - Labels make control flow difficult to understand and should be avoided. They can be confused - with the goto statement and make code harder to read and maintain. - - If you really need to jump out of an inner loop, think about refactoring the multiple - loops into a function - that way, you can replace the break with a return. - - 3 - - - - - - - - - - - - + + +This rule detects the use of labeled statements. By default, it allows labeled loops so that you can +use `break` / `continue` with labels. This can be changed with the property `allowLoops` to flag any +labels. + +Labels make control flow difficult to understand and should be avoided. They can be confused +with the goto statement and make code harder to read and maintain. + +If you really need to jump out of an inner loop, think about refactoring the multiple +loops into a function - that way, you can replace the break with a return. + +This rule implements SonarSource rule [S1119](https://sonarsource.github.io/rspec/#/rspec/S1119). + +To detect unused labels, use the rule {% rule UnusedLabel %}. + + 3 + + + + + + + + + + + + + + + + --> + diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidLoopLabelsTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/LabeledStatementTest.java similarity index 82% rename from pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidLoopLabelsTest.java rename to pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/LabeledStatementTest.java index 79c935550a2..69b6f18ca2a 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidLoopLabelsTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/LabeledStatementTest.java @@ -6,6 +6,6 @@ import net.sourceforge.pmd.test.PmdRuleTst; -class AvoidLoopLabelsTest extends PmdRuleTst { +class LabeledStatementTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidLoopLabels.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/LabeledStatement.xml similarity index 68% rename from pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidLoopLabels.xml rename to pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/LabeledStatement.xml index 90b7544df95..77f8696523f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidLoopLabels.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/LabeledStatement.xml @@ -4,12 +4,56 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests http://pmd.sourceforge.net/rule-tests_1_0_0.xsd"> + + + + + + Example + 1 + 5 + + Avoid using labeled statements such as 'lbl2'. + + + + + + Example (allowLoops=false) + false + 2 + 4,5 + + Avoid using labeled statements such as 'lbl1'. + Avoid using labeled statements such as 'lbl2'. + + + + violation: labeled break in for loop + false 1 - 6 + 3 - Avoid using labeled break and continue statements + Avoid using labeled statements such as 'outer'. violation: labeled continue in nested for loops + false 1 - 6 + 3 - Avoid using labeled break and continue statements + Avoid using labeled statements such as 'outer'. violation: labeled break in while loop + false 1 - 7 + 4 violation: labeled continue in do-while loop + false 1 - 7 + 4 violation: labeled break in enhanced for loop + false 1 - 7 + 4 violation: multiple labeled breaks targeting different loops + false 2 - 9,11 + 3,5 - no violation: labeled statement without break/continue + no violation: labeled statement without break/continue (unused label) 0 Date: Thu, 23 Oct 2025 11:01:06 +0200 Subject: [PATCH 1554/1962] [doc] Update release notes (#2928, #6042) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 1d3b4013287..b5a97052f30 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -77,6 +77,7 @@ checkstyle version during the build. * [#6127](https://github.com/pmd/pmd/issues/6127): \[java] Incorrect variable name in violation * [#6146](https://github.com/pmd/pmd/issues/6146): \[java] ClassCastException: class InferenceVarSym cannot be cast to class JClassSymbol * java-bestpractices + * [#2928](https://github.com/pmd/pmd/issues/2928): \[java] New rules about labeled statements * [#4122](https://github.com/pmd/pmd/issues/4122): \[java] CheckResultSet false-positive with local variable * [#6124](https://github.com/pmd/pmd/issues/6124): \[java] UnusedLocalVariable: fix false negatives in pattern matching * java-codestyle @@ -125,6 +126,7 @@ checkstyle version during the build. * [#6031](https://github.com/pmd/pmd/pull/6031): \[java] Fix #5880: False Negatives in DoubleCheckedLocking - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6039](https://github.com/pmd/pmd/pull/6039): \[core] Fix #4714: trim token before feeding it to the extractor - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6040](https://github.com/pmd/pmd/pull/6040): \[java,apex,plsql,velocity] Change description of "minimum" parameter - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6042](https://github.com/pmd/pmd/pull/6042): \[java] Fix #2928: New Rules UnusedLabel and LabeledStatement - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6043](https://github.com/pmd/pmd/pull/6043): \[java] Reactivate deactivated test in LocalVariableCouldBeFinal - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6051](https://github.com/pmd/pmd/pull/6051): \[java] Fix #6038: Make AvoidCatchingGenericException configurable - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6056](https://github.com/pmd/pmd/pull/6056): chore: fix dogfood issues from new rules - [Andreas Dangel](https://github.com/adangel) (@adangel) From 9ca1336763ea770de58085324b2824b2bf743730 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 24 Oct 2025 11:42:24 +0200 Subject: [PATCH 1555/1962] Apply suggestion from @adangel --- .../pmd/lang/java/rule/bestpractices/UnusedLabelTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLabelTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLabelTest.java index 62457fecec3..f930b4be810 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLabelTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLabelTest.java @@ -6,6 +6,6 @@ import net.sourceforge.pmd.test.PmdRuleTst; -public class UnusedLabelTest extends PmdRuleTst { +class UnusedLabelTest extends PmdRuleTst { // no additional unit tests } From a569384d73724412f638f14cbfdb98db24f7bebe Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 27 Oct 2025 10:53:26 +0100 Subject: [PATCH 1556/1962] [java] Fix #6169: AvoidUsingHardCodedIP - mention address in message --- docs/pages/release_notes.md | 2 ++ .../java/rule/bestpractices/AvoidUsingHardCodedIPRule.java | 4 ++-- pmd-java/src/main/resources/category/java/bestpractices.xml | 2 +- .../java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index b5a97052f30..7b8155c5f82 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -80,6 +80,7 @@ checkstyle version during the build. * [#2928](https://github.com/pmd/pmd/issues/2928): \[java] New rules about labeled statements * [#4122](https://github.com/pmd/pmd/issues/4122): \[java] CheckResultSet false-positive with local variable * [#6124](https://github.com/pmd/pmd/issues/6124): \[java] UnusedLocalVariable: fix false negatives in pattern matching + * [#6169](https://github.com/pmd/pmd/issues/6169): \[java] AvoidUsingHardCodedIP: violation message should mention the hard coded address * java-codestyle * [#5919](https://github.com/pmd/pmd/issues/5919): \[java] ClassNamingConventions: Include integration tests in testClassPattern by default * [#6004](https://github.com/pmd/pmd/issues/6004): \[java] Make ConfusingTernary != null configurable @@ -157,6 +158,7 @@ checkstyle version during the build. * [#6152](https://github.com/pmd/pmd/pull/6152): chore(deps): Update Saxon-HE from 12.5 to 12.9 - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6156](https://github.com/pmd/pmd/pull/6156): \[java] Fix #6146: ClassCastException in TypeTestUtil - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#6164](https://github.com/pmd/pmd/pull/6164): \[doc] Update reproducible build info with Java 17 - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6170](https://github.com/pmd/pmd/pull/6170): \[java] Fix #6169: AvoidUsingHardCodedIP - mention address in message - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ Dependency updates diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidUsingHardCodedIPRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidUsingHardCodedIPRule.java index 521ce072890..c7021d5cea0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidUsingHardCodedIPRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidUsingHardCodedIPRule.java @@ -72,7 +72,7 @@ public Object visit(ASTStringLiteral node, Object data) { // Note: We used to check the addresses using // InetAddress.getByName(String), but that's extremely slow, // so we created more robust checking methods. - if (image.length() > 0) { + if (!image.isEmpty()) { final char firstChar = Character.toUpperCase(image.charAt(0)); boolean checkIPv4 = kindsToCheck.contains(AddressKinds.IPV4); @@ -80,7 +80,7 @@ public Object visit(ASTStringLiteral node, Object data) { boolean checkIPv4MappedIPv6 = kindsToCheck.contains(AddressKinds.IPV4_MAPPED_IPV6); if (checkIPv4 && isIPv4(firstChar, image) || isIPv6(firstChar, image, checkIPv6, checkIPv4MappedIPv6)) { - asCtx(data).addViolation(node); + asCtx(data).addViolation(node, image); } } return data; diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 233b944ac04..7206103ac40 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -364,7 +364,7 @@ public class Foo { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml index fbda928bb59..a8e92139e46 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml @@ -67,7 +67,7 @@ public class Foo { Common basic case 1 - Do not hard code the IP address badIdea + Do not hard code the IP address '127.0.0.1' Date: Wed, 29 Oct 2025 14:28:23 +0100 Subject: [PATCH 1557/1962] [java] AvoidUsingHardCodedIP - remove now obsolete test case Refs #6127 --- .../bestpractices/xml/AvoidUsingHardCodedIP.xml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml index a8e92139e46..4134e65046d 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml @@ -150,19 +150,4 @@ public class Foo { 15 - - - #6127 missing var name in message - 1 - 3 - - Do not hard code the IP address address - - - From b4ef5a7ccf27e78716969846b55169101c62efcc Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 27 Oct 2025 11:48:43 +0100 Subject: [PATCH 1558/1962] [java] AvoidUsingHardCodedIP - fix false positive for IPv6 --- .../rule/bestpractices/AvoidUsingHardCodedIPRule.java | 9 +++++---- .../rule/bestpractices/xml/AvoidUsingHardCodedIP.xml | 10 ++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidUsingHardCodedIPRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidUsingHardCodedIPRule.java index c7021d5cea0..84ea62da0c4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidUsingHardCodedIPRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidUsingHardCodedIPRule.java @@ -141,9 +141,10 @@ private boolean isIPv6(final char firstChar, String s, final boolean checkIPv6, zeroSubstitution = true; } - // String.split() doesn't produce an empty String in the trailing - // case, but it does in the leading. - if (s.endsWith(":")) { + // leading/trailing "::" has already been dealt with. + // If the address still starts or ends with ":", then it + // is invalid + if (s.startsWith(":") || s.endsWith(":")) { return false; } @@ -153,7 +154,7 @@ private boolean isIPv6(final char firstChar, String s, final boolean checkIPv6, String[] parts = s.split(":"); for (int i = 0; i < parts.length; i++) { final String part = parts[i]; - // An empty part indicates :: was encountered. There can only be + // An empty part indicates :: was encountered in the middle. There can only be // 1 such instance. if (part.length() == 0) { if (zeroSubstitution) { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml index 4134e65046d..470f89b2631 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml @@ -117,6 +117,16 @@ public class Foo { ]]> + + #6171 Not an IPv6 address + 0 + + + Comprehensive, check IPv4, IPv6, and IPv4 mapped IPv6 21 From 4ba977c17a4aca5753f1d14aeaa68858278dd9d7 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 29 Oct 2025 14:31:42 +0100 Subject: [PATCH 1559/1962] [doc] Update release notes (#6171) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 7b8155c5f82..1cd09359e90 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -81,6 +81,7 @@ checkstyle version during the build. * [#4122](https://github.com/pmd/pmd/issues/4122): \[java] CheckResultSet false-positive with local variable * [#6124](https://github.com/pmd/pmd/issues/6124): \[java] UnusedLocalVariable: fix false negatives in pattern matching * [#6169](https://github.com/pmd/pmd/issues/6169): \[java] AvoidUsingHardCodedIP: violation message should mention the hard coded address + * [#6171](https://github.com/pmd/pmd/issues/6171): \[java] AvoidUsingHardCodedIP: fix false positive for IPv6 * java-codestyle * [#5919](https://github.com/pmd/pmd/issues/5919): \[java] ClassNamingConventions: Include integration tests in testClassPattern by default * [#6004](https://github.com/pmd/pmd/issues/6004): \[java] Make ConfusingTernary != null configurable @@ -159,6 +160,7 @@ checkstyle version during the build. * [#6156](https://github.com/pmd/pmd/pull/6156): \[java] Fix #6146: ClassCastException in TypeTestUtil - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#6164](https://github.com/pmd/pmd/pull/6164): \[doc] Update reproducible build info with Java 17 - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6170](https://github.com/pmd/pmd/pull/6170): \[java] Fix #6169: AvoidUsingHardCodedIP - mention address in message - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6171](https://github.com/pmd/pmd/pull/6171): \[java] AvoidUsingHardCodedIP: fix false positive for IPv6 - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ Dependency updates From f110b5c9a92a09367a810a3673361af8535d1030 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 24 Oct 2025 14:48:04 +0200 Subject: [PATCH 1560/1962] [doc] Use emoji variants - in README.md - in release notes - in documentation index --- .ci/tools/release-notes-add-pr.sh | 2 +- .ci/tools/release-notes-generate.sh | 16 ++++++++-------- README.md | 10 +++++----- do-release.sh | 12 ++++++------ docs/index.md | 8 ++++---- docs/pages/release_notes.md | 16 ++++++++-------- 6 files changed, 32 insertions(+), 32 deletions(-) diff --git a/.ci/tools/release-notes-add-pr.sh b/.ci/tools/release-notes-add-pr.sh index 723f3aa2550..df92ac559c0 100755 --- a/.ci/tools/release-notes-add-pr.sh +++ b/.ci/tools/release-notes-add-pr.sh @@ -38,7 +38,7 @@ PULL_ITEM="${PULL_ITEM//${search}/${replacement}}" RELEASE_NOTES_FILE="${BASEDIR}/docs/pages/release_notes.md" RELEASE_NOTES=$(cat "$RELEASE_NOTES_FILE") -line="$(echo "$RELEASE_NOTES" | grep -n "### ๐Ÿ“ฆ Dependency updates" | cut -d ":" -f 1)" +line="$(echo "$RELEASE_NOTES" | grep -n "### ๐Ÿ“ฆ๏ธ Dependency updates" | cut -d ":" -f 1)" RELEASE_NOTES="$(echo "$RELEASE_NOTES" | head -n "$((line - 1))") $PULL_ITEM $(echo "$RELEASE_NOTES" | tail -n "+$((line - 1))") diff --git a/.ci/tools/release-notes-generate.sh b/.ci/tools/release-notes-generate.sh index 9fe7711e5cc..549d38222ba 100755 --- a/.ci/tools/release-notes-generate.sh +++ b/.ci/tools/release-notes-generate.sh @@ -85,7 +85,7 @@ echo "Found $(echo "$ISSUES_JSON" | jq length) issues/pull requests" FIXED_ISSUES_JSON="$(echo "$ISSUES_JSON" | jq 'map(select(has("pull_request") | not))')" FIXED_ISSUES="$(echo "$FIXED_ISSUES_JSON" | jq --raw-output '.[] | "* [#\(.number)](https://github.com/pmd/pmd/issues/\(.number)): \(.title | gsub("@"; "@") | gsub("\\["; "\\["))"')" -FIXED_ISSUES="### ๐Ÿ› Fixed Issues +FIXED_ISSUES="### ๐Ÿ›๏ธ Fixed Issues $FIXED_ISSUES " @@ -106,7 +106,7 @@ for login in $AUTHORS; do PULL_REQUESTS="${PULL_REQUESTS//${search}/${replacement}}" done -PULL_REQUESTS="### โœจ Merged pull requests +PULL_REQUESTS="### โœจ๏ธ Merged pull requests $PULL_REQUESTS " @@ -115,7 +115,7 @@ DEPENDENCY_UPDATES_JSON="$(echo "$ISSUES_JSON" | jq 'map(select(has("pull_reques DEPENDENCY_UPDATES="$(echo "$DEPENDENCY_UPDATES_JSON" | jq --raw-output '.[] | "* [#\(.number)](https://github.com/pmd/pmd/pull/\(.number)): \(.title | gsub("@"; "@") | gsub("\\["; "\\["))"')" DEPENDENCY_UPDATES_COUNT=$(echo "$DEPENDENCY_UPDATES_JSON" | jq length) if [ -z "$DEPENDENCY_UPDATES" ]; then DEPENDENCY_UPDATES="No dependency updates."; fi -DEPENDENCY_UPDATES="### ๐Ÿ“ฆ Dependency updates +DEPENDENCY_UPDATES="### ๐Ÿ“ฆ๏ธ Dependency updates $DEPENDENCY_UPDATES " @@ -123,7 +123,7 @@ $DEPENDENCY_UPDATES # calculating stats for release notes (excluding dependency updates) STATS_CLOSED_ISSUES=$(echo "$MILESTONE_JSON" | jq .closed_issues) STATS=$( -echo "### ๐Ÿ“ˆ Stats" +echo "### ๐Ÿ“ˆ๏ธ Stats" echo "" echo "* $(git log pmd_releases/"${LAST_VERSION}"..HEAD --oneline --no-merges |wc -l) commits" echo "* $((STATS_CLOSED_ISSUES - DEPENDENCY_UPDATES_COUNT)) closed tickets & PRs" @@ -155,9 +155,9 @@ RELEASE_NOTES_FILE="${BASEDIR}/docs/pages/release_notes.md" echo "Updating $RELEASE_NOTES_FILE now..." RELEASE_NOTES=$(cat "$RELEASE_NOTES_FILE") -#RELEASE_NOTES="$(insert "$RELEASE_NOTES" "### ๐Ÿ› Fixed Issues" "### โœจ Merged pull requests" "$FIXED_ISSUES")" -RELEASE_NOTES="$(insert "$RELEASE_NOTES" "### โœจ Merged pull requests" "### ๐Ÿ“ฆ Dependency updates" "$PULL_REQUESTS")" -RELEASE_NOTES="$(insert "$RELEASE_NOTES" "### ๐Ÿ“ฆ Dependency updates" "### ๐Ÿ“ˆ Stats" "$DEPENDENCY_UPDATES")" -RELEASE_NOTES="$(insert "$RELEASE_NOTES" "### ๐Ÿ“ˆ Stats" "{% endtocmaker %}" "$STATS")" +#RELEASE_NOTES="$(insert "$RELEASE_NOTES" "### ๐Ÿ›๏ธ Fixed Issues" "### โœจ๏ธ Merged pull requests" "$FIXED_ISSUES")" +RELEASE_NOTES="$(insert "$RELEASE_NOTES" "### โœจ๏ธ Merged pull requests" "### ๐Ÿ“ฆ๏ธ Dependency updates" "$PULL_REQUESTS")" +RELEASE_NOTES="$(insert "$RELEASE_NOTES" "### ๐Ÿ“ฆ๏ธ Dependency updates" "### ๐Ÿ“ˆ๏ธ Stats" "$DEPENDENCY_UPDATES")" +RELEASE_NOTES="$(insert "$RELEASE_NOTES" "### ๐Ÿ“ˆ๏ธ Stats" "{% endtocmaker %}" "$STATS")" echo "$RELEASE_NOTES" > "$RELEASE_NOTES_FILE" diff --git a/README.md b/README.md index 466a4c67777..71ec501be7a 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Coco, C/C++, C#, CSS, Dart, Fortran, Gherkin, Go, Groovy, HTML, Java, JavaScript Lua, Matlab, Modelica, Objective-C, Perl, PHP, PL/SQL, Python, Ruby, Salesforce.com Apex and Visualforce, Scala, Swift, T-SQL, Typescript, Apache Velocity, WSDL, XML and XSL. -## ๐Ÿš€ Installation and Usage +## ๐Ÿš€๏ธ Installation and Usage Download the latest binary zip from the [releases](https://github.com/pmd/pmd/releases/latest) and extract it somewhere. @@ -58,7 +58,7 @@ See [Tools / Integrations](https://docs.pmd-code.org/latest/pmd_userdocs_tools.h or our [PMD Guru at Gurubase](https://gurubase.io/g/pmd). * Where's your documentation? -- -## ๐Ÿค Contributing +## ๐Ÿค๏ธ Contributing Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. @@ -70,17 +70,17 @@ The rule designer is developed over at [pmd/pmd-designer](https://github.com/pmd Please see [its README](https://github.com/pmd/pmd-designer#contributing) for developer documentation. -## ๐Ÿ’ต Financial Contributors +## ๐Ÿ’ต๏ธ Financial Contributors Become a financial contributor and help us sustain our community. [Contribute](https://opencollective.com/pmd/contribute) -## โœจ Contributors +## โœจ๏ธ Contributors This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! See [credits](docs/pages/pmd/projectdocs/credits.md) for the complete list. -## ๐Ÿ“ License +## ๐Ÿ“๏ธ License [BSD Style](LICENSE) diff --git a/do-release.sh b/do-release.sh index ab09ddd5f12..e2e8d820a99 100755 --- a/do-release.sh +++ b/do-release.sh @@ -275,19 +275,19 @@ This is a {{ site.pmd.release_type }} release. {% tocmaker is_release_notes_processor %} -### ๐Ÿš€ New and noteworthy +### ๐Ÿš€๏ธ New and noteworthy -### ๐Ÿ› Fixed Issues +### ๐Ÿ›๏ธ Fixed Issues -### ๐Ÿšจ API Changes +### ๐Ÿšจ๏ธ API Changes -### โœจ Merged pull requests +### โœจ๏ธ Merged pull requests -### ๐Ÿ“ฆ Dependency updates +### ๐Ÿ“ฆ๏ธ Dependency updates -### ๐Ÿ“ˆ Stats +### ๐Ÿ“ˆ๏ธ Stats {% endtocmaker %} diff --git a/docs/index.md b/docs/index.md index f80dbf90f57..d1141fb98ad 100644 --- a/docs/index.md +++ b/docs/index.md @@ -18,7 +18,7 @@ additional_js: -## ๐Ÿ’ก Overview +## ๐Ÿ’ก๏ธ Overview @@ -55,19 +55,19 @@ things, PMD can be run: **CPD**, the **copy-paste detector**, is also distributed with PMD. You can use it in a variety of ways, which are [documented here](pmd_userdocs_cpd.html). -## ๐Ÿ’พ Download +## ๐Ÿ’พ๏ธ Download The latest release of PMD can be downloaded from our [Github releases page](https://github.com/pmd/pmd/releases/latest). The Logo is available from the [Logo Project Page](pmd_projectdocs_logo.html). -## ๐Ÿ“– Documentation +## ๐Ÿ“–๏ธ Documentation The rest of this page exposes the contents of the documentation site thematically, which you can further scope down using the blue filter buttons. To navigate the site, you may also use the search bar in the top right, or the sidebar on the left. -## โœจ Contributors +## โœจ๏ธ Contributors This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 1cd09359e90..bfbfbf0ce58 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -22,14 +22,14 @@ This is a {{ site.pmd.release_type }} release. {% tocmaker is_release_notes_processor %} -### ๐Ÿš€ New and noteworthy +### ๐Ÿš€๏ธ New and noteworthy #### Build Requirement is Java 17 From now on, Java 17 or newer is required to build PMD. PMD itself still remains compatible with Java 8, so that it still can be used in a pure Java 8 environment. This allows us to use the latest checkstyle version during the build. -### ๐ŸŒŸ New and Changed Rules +### ๐ŸŒŸ๏ธ New and Changed Rules #### New Rules * The new Java rule {% rule java/errorprone/IdenticalConditionalBranches %} finds conditional statements that do the same thing when the condition is true and false. This is either incorrect or redundant. @@ -51,13 +51,13 @@ checkstyle version during the build. ``` -#### Deprecated rules +#### Deprecated Rules * The Java rule {% rule java/errorprone/AvoidCatchingNPE %} has been deprecated in favor of the updated rule {% rule java/errorprone/AvoidCatchingGenericException %}, which is now configurable. * The Java rule {% rule java/errorprone/AvoidCatchingThrowable %} has been deprecated in favor of the updated rule {% rule java/errorprone/AvoidCatchingGenericException %}, which is now configurable. -### ๐Ÿ› Fixed Issues +### ๐Ÿ›๏ธ Fixed Issues * general * [#4714](https://github.com/pmd/pmd/issues/4714): \[core] Allow trailing commas in multivalued properties * [#5873](https://github.com/pmd/pmd/issues/5873): \[ci] Run integration test with Java 25 @@ -108,7 +108,7 @@ checkstyle version during the build. * plsql-design * [#6077](https://github.com/pmd/pmd/issues/6077): \[plsql] Excessive\*/Ncss\*Count/NPathComplexity include the metric -### ๐Ÿšจ API Changes +### ๐Ÿšจ๏ธ API Changes #### Deprecations * java @@ -118,7 +118,7 @@ checkstyle version during the build. * {%jdoc !!java::lang.java.rule.design.ExcessiveParameterListRule#isViolation(java::lang.java.ast.ASTFormalParameters,int) %} * {%jdoc !!java::lang.java.rule.design.ExcessivePublicCountRule#isViolation(java::lang.java.ast.ASTTypeDeclaration,int) %} -### โœจ Merged pull requests +### โœจ๏ธ Merged pull requests * [#6021](https://github.com/pmd/pmd/pull/6021): \[java] Fix #5569: ExcessiveImports/ExcessiveParameterList/ExcessivePublicCount include the metric in the message - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6022](https://github.com/pmd/pmd/pull/6022): \[apex] ExcessiveClassLength/ExcessiveParameterList include the metric in the message - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) @@ -162,10 +162,10 @@ checkstyle version during the build. * [#6170](https://github.com/pmd/pmd/pull/6170): \[java] Fix #6169: AvoidUsingHardCodedIP - mention address in message - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6171](https://github.com/pmd/pmd/pull/6171): \[java] AvoidUsingHardCodedIP: fix false positive for IPv6 - [Andreas Dangel](https://github.com/adangel) (@adangel) -### ๐Ÿ“ฆ Dependency updates +### ๐Ÿ“ฆ๏ธ Dependency updates -### ๐Ÿ“ˆ Stats +### ๐Ÿ“ˆ๏ธ Stats {% endtocmaker %} From cea597a7e139a728253d279c9c19549f846ec7f1 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 29 Oct 2025 14:33:42 +0100 Subject: [PATCH 1561/1962] [doc] Update release notes (#6166) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index bfbfbf0ce58..1cadafa6250 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -159,6 +159,7 @@ checkstyle version during the build. * [#6152](https://github.com/pmd/pmd/pull/6152): chore(deps): Update Saxon-HE from 12.5 to 12.9 - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6156](https://github.com/pmd/pmd/pull/6156): \[java] Fix #6146: ClassCastException in TypeTestUtil - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#6164](https://github.com/pmd/pmd/pull/6164): \[doc] Update reproducible build info with Java 17 - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6166](https://github.com/pmd/pmd/pull/6166): \[doc] Use emoji variants - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6170](https://github.com/pmd/pmd/pull/6170): \[java] Fix #6169: AvoidUsingHardCodedIP - mention address in message - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6171](https://github.com/pmd/pmd/pull/6171): \[java] AvoidUsingHardCodedIP: fix false positive for IPv6 - [Andreas Dangel](https://github.com/adangel) (@adangel) From 2d4074507369fab1f32bed624cae5540396b7168 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 Oct 2025 15:49:06 +0100 Subject: [PATCH 1562/1962] chore(deps): bump actions/upload-artifact from 4.6.2 to 5.0.0 (#6173) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.2 to 5.0.0. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/ea165f8d65b6e75b540449e92b4886f43607fa02...330a01c490aca151604b8cf639adc76d48f6c5d4) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: 5.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 12 ++++++------ .github/workflows/publish-release.yml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 708c28bee03..1332dedd045 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -47,7 +47,7 @@ jobs: # version exactly is available in the staging repo. But if we rerun the build using the # older cache, it points to the old staging versions, which are not available anymore. find .m2/repository/net/sourceforge/pmd -type d -name "*-SNAPSHOT" -and -not -path "*/pmd-designer/*" -print0 | xargs -0 rm -vrf - - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 + - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 #v5.0.0 with: name: compile-artifact if-no-files-found: error @@ -58,12 +58,12 @@ jobs: !pmd-dist/target/pmd-dist-*-src.zip !pmd-dist/target/pmd-*-cyclonedx.xml !pmd-dist/target/pmd-*-cyclonedx.json - - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 + - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 #v5.0.0 with: name: staging-repository if-no-files-found: error path: target/staging - - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 + - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 #v5.0.0 with: name: dist-artifact if-no-files-found: error @@ -100,7 +100,7 @@ jobs: ./mvnw --show-version --errors --batch-mode \ -Dmaven.repo.local=.m2/repository \ verify -DskipTests - - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 + - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 #v5.0.0 with: name: javadocs-artifact if-no-files-found: error @@ -296,7 +296,7 @@ jobs: run: | cd docs bundle exec render_release_notes.rb pages/release_notes.md | tail -n +6 > _site/pmd_release_notes.md - - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 + - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 #v5.0.0 with: name: docs-artifact if-no-files-found: error @@ -354,7 +354,7 @@ jobs: run: | echo "artifacts_path=$(realpath ..)" >> "${GITHUB_ENV}" - name: Upload regression tester report - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 #v5.0.0 with: name: pmd-regression-tester if-no-files-found: error diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 50884b75fd9..9b61bbcaff1 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -699,7 +699,7 @@ jobs: cd ../../pmd mv ../target/reports/"${baseline_name}-baseline.zip" . scp "${baseline_name}-baseline.zip" pmd@pmd-code.org:/httpdocs/pmd-regression-tester/ - - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 + - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 #v5.0.0 with: name: regression-tester-baseline path: ${{ format('pmd_releases_{0}-baseline.zip', needs.check-version.outputs.PMD_VERSION) }} From 213e23856b1bd6b7885c1d9d5667d48c7973a75d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 Oct 2025 15:49:38 +0100 Subject: [PATCH 1563/1962] chore(deps): bump ruby/setup-ruby from 1.265.0 to 1.267.0 (#6174) Bumps [ruby/setup-ruby](https://github.com/ruby/setup-ruby) from 1.265.0 to 1.267.0. - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/ab177d40ee5483edb974554986f56b33477e21d0...d5126b9b3579e429dd52e51e68624dda2e05be25) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-version: 1.267.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 4 ++-- .github/workflows/publish-release.yml | 2 +- .github/workflows/publish-snapshot.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1332dedd045..e0e6f49e395 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -280,7 +280,7 @@ jobs: -Pgenerate-rule-docs,fastSkip \ -DskipTests -Dassembly.skipAssembly=true - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 #v1.265.0 + uses: ruby/setup-ruby@d5126b9b3579e429dd52e51e68624dda2e05be25 #v1.267.0 with: ruby-version: 3.3 - name: Setup bundler @@ -321,7 +321,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 #v1.265.0 + uses: ruby/setup-ruby@d5126b9b3579e429dd52e51e68624dda2e05be25 #v1.267.0 with: ruby-version: 3.3 - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4.3.0 diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 9b61bbcaff1..30652f645d9 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -632,7 +632,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 #v1.265.0 + uses: ruby/setup-ruby@d5126b9b3579e429dd52e51e68624dda2e05be25 #v1.267.0 with: ruby-version: 3.3 - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4.3.0 diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index eea282fa5cb..99d25e4dc43 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -649,7 +649,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 #v1.265.0 + uses: ruby/setup-ruby@d5126b9b3579e429dd52e51e68624dda2e05be25 #v1.267.0 with: ruby-version: 3.3 - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4.3.0 From 6daa887d6f00cdfdf167388ecfdf8b11a5bfb13c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 Oct 2025 15:50:06 +0100 Subject: [PATCH 1564/1962] chore(deps): bump actions/download-artifact from 5.0.0 to 6.0.0 (#6175) Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 5.0.0 to 6.0.0. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/634f93cb2916e3fdff6788551b99b062d0335ce0...018cc2cf5baa6db3ef3c5f8a56943fffe632ef53) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 12 ++++++------ .github/workflows/publish-release.yml | 22 +++++++++++----------- .github/workflows/publish-snapshot.yml | 20 ++++++++++---------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e0e6f49e395..2cf6990cc8c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -92,7 +92,7 @@ jobs: restore-keys: maven- path: .m2/repository enableCrossOsArchive: true - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: compile-artifact - name: Full Build with Maven @@ -147,7 +147,7 @@ jobs: restore-keys: maven- path: .m2/repository enableCrossOsArchive: true - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 # we can only reuse compile-artifacts under linux due to file timestamp issues and # platform specific line endings in test resource files. if: ${{ runner.os == 'Linux' }} @@ -183,10 +183,10 @@ jobs: restore-keys: maven- path: .m2/repository enableCrossOsArchive: true - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: compile-artifact - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: staging-repository path: target/staging @@ -269,7 +269,7 @@ jobs: restore-keys: maven- path: .m2/repository enableCrossOsArchive: true - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: compile-artifact - name: Generate rule docs @@ -333,7 +333,7 @@ jobs: .ci/files/vendor/bundle key: regressiontester-${{ hashFiles('.ci/files/project-list.xml', '.ci/files/Gemfile.lock') }} restore-keys: regressiontester- - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: dist-artifact path: pmd-dist/target diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 30652f645d9..8f7d514bd52 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -97,7 +97,7 @@ jobs: server-password: MAVEN_PASSWORD gpg-passphrase: MAVEN_GPG_PASSPHRASE gpg-private-key: ${{ secrets.PMD_CI_GPG_PRIVATE_KEY }} - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: compile-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -131,14 +131,14 @@ jobs: run: shell: bash steps: - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: dist-artifact github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id }} path: dist - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: docs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -250,7 +250,7 @@ jobs: run: shell: bash steps: - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: docs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -298,7 +298,7 @@ jobs: run: shell: bash steps: - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: docs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -378,7 +378,7 @@ jobs: run: shell: bash steps: - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: javadocs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -461,14 +461,14 @@ jobs: run: shell: bash steps: - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: dist-artifact github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id }} path: dist - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: docs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -567,7 +567,7 @@ jobs: run: shell: bash steps: - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: docs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -644,7 +644,7 @@ jobs: .ci/files/vendor/bundle key: regressiontester-${{ hashFiles('.ci/files/project-list.xml', '.ci/files/Gemfile.lock') }} restore-keys: regressiontester- - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: dist-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -735,7 +735,7 @@ jobs: IdentityFile=$HOME/.ssh/web.sourceforge.net_deploy_key " > "$HOME/.ssh/config" echo "${WEB_SF_KNOWN_HOSTS}" > "$HOME/.ssh/known_hosts" - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: regression-tester-baseline - name: Upload to sourceforge diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 99d25e4dc43..6e59aee88ca 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -94,7 +94,7 @@ jobs: restore-keys: maven- path: .m2/repository enableCrossOsArchive: true - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: compile-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -129,14 +129,14 @@ jobs: run: shell: bash steps: - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: dist-artifact github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id }} path: dist - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: docs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -232,7 +232,7 @@ jobs: run: shell: bash steps: - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: docs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -278,7 +278,7 @@ jobs: run: shell: bash steps: - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: docs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -351,7 +351,7 @@ jobs: run: shell: bash steps: - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: javadocs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -421,7 +421,7 @@ jobs: ref: gh-pages - name: Clear old files run: rm -rf * - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: docs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -456,14 +456,14 @@ jobs: run: shell: bash steps: - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: dist-artifact github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id }} path: dist - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: docs-artifact github-token: ${{ secrets.GITHUB_TOKEN }} @@ -661,7 +661,7 @@ jobs: .ci/files/vendor/bundle key: regressiontester-${{ hashFiles('.ci/files/project-list.xml', '.ci/files/Gemfile.lock') }} restore-keys: regressiontester- - - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 #v5.0.0 + - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 #v6.0.0 with: name: dist-artifact github-token: ${{ secrets.GITHUB_TOKEN }} From 8a0d66fd87f128eb445c8761a7a708f9c84b0918 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 Oct 2025 15:51:36 +0100 Subject: [PATCH 1565/1962] chore(deps): bump org.checkerframework:checker-qual from 3.49.5 to 3.51.1 (#6178) chore(deps): bump org.checkerframework:checker-qual Bumps [org.checkerframework:checker-qual](https://github.com/typetools/checker-framework) from 3.49.5 to 3.51.1. - [Release notes](https://github.com/typetools/checker-framework/releases) - [Changelog](https://github.com/typetools/checker-framework/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/typetools/checker-framework/compare/checker-framework-3.49.5...checker-framework-3.51.1) --- updated-dependencies: - dependency-name: org.checkerframework:checker-qual dependency-version: 3.51.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d3b2da9f904..de3c0dc2ead 100644 --- a/pom.xml +++ b/pom.xml @@ -903,7 +903,7 @@ org.checkerframework checker-qual - 3.49.5 + 3.51.1 net.sf.saxon From 00747b9471a25d1598757792c583b39d24ab367e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 Oct 2025 15:51:57 +0100 Subject: [PATCH 1566/1962] chore(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.6.1 to 3.6.2 (#6179) chore(deps): bump org.codehaus.mojo:exec-maven-plugin Bumps [org.codehaus.mojo:exec-maven-plugin](https://github.com/mojohaus/exec-maven-plugin) from 3.6.1 to 3.6.2. - [Release notes](https://github.com/mojohaus/exec-maven-plugin/releases) - [Commits](https://github.com/mojohaus/exec-maven-plugin/compare/3.6.1...3.6.2) --- updated-dependencies: - dependency-name: org.codehaus.mojo:exec-maven-plugin dependency-version: 3.6.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index de3c0dc2ead..e056fbd7a99 100644 --- a/pom.xml +++ b/pom.xml @@ -383,7 +383,7 @@ org.codehaus.mojo exec-maven-plugin - 3.6.1 + 3.6.2 org.apache.maven.plugins From ea4ec14055d06266c65cdb29773043dcbd4ddb3d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 Oct 2025 15:52:26 +0100 Subject: [PATCH 1567/1962] chore(deps): bump org.apache.groovy:groovy from 5.0.1 to 5.0.2 (#6181) Bumps [org.apache.groovy:groovy](https://github.com/apache/groovy) from 5.0.1 to 5.0.2. - [Commits](https://github.com/apache/groovy/commits) --- updated-dependencies: - dependency-name: org.apache.groovy:groovy dependency-version: 5.0.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e056fbd7a99..f458a9a446d 100644 --- a/pom.xml +++ b/pom.xml @@ -938,7 +938,7 @@ org.apache.groovy groovy - 5.0.1 + 5.0.2 com.google.code.gson From 2dffbed5a4b0a95b321273bbecca88430372f5db Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 Oct 2025 15:52:53 +0100 Subject: [PATCH 1568/1962] chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.17.7 to 1.17.8 (#6182) Bumps [net.bytebuddy:byte-buddy](https://github.com/raphw/byte-buddy) from 1.17.7 to 1.17.8. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.17.7...byte-buddy-1.17.8) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-version: 1.17.8 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f458a9a446d..1b6def36df3 100644 --- a/pom.xml +++ b/pom.xml @@ -1038,7 +1038,7 @@ net.bytebuddy byte-buddy - 1.17.7 + 1.17.8 test From 4196bb95ea6391ee30de8ef261a42e727cad95ec Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 30 Oct 2025 11:16:29 +0100 Subject: [PATCH 1569/1962] [java] Fix #6053: ModifierOrder - consider type params Type params can occur before or after (type) annotations. If the annotations occur after the type params, then they syntactically belong to the type they annotate. - with typeAnnotations=anywhere, type annotations should be also allowed after modifier keywords and before type parameters. - extend tests to verify "Annotations that are not type annotations are still required to be before keyword modifiers." - improve violation messages to distinguish between type and non-type annotation. --- .../rule/codestyle/ModifierOrderRule.java | 87 +++++++++++- .../resources/category/java/codestyle.xml | 2 +- .../java/rule/codestyle/xml/ModifierOrder.xml | 131 ++++++++++++++++-- 3 files changed, 202 insertions(+), 18 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ModifierOrderRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ModifierOrderRule.java index 13a19d3e3ad..05b7145dcbd 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ModifierOrderRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ModifierOrderRule.java @@ -15,6 +15,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTLocalVariableDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTModifierList; import net.sourceforge.pmd.lang.java.ast.ASTType; +import net.sourceforge.pmd.lang.java.ast.ASTTypeParameters; import net.sourceforge.pmd.lang.java.ast.ASTVoidType; import net.sourceforge.pmd.lang.java.ast.JModifier; import net.sourceforge.pmd.lang.java.ast.JavaNode; @@ -37,8 +38,11 @@ public class ModifierOrderRule extends AbstractJavaRulechainRule { private static final String MSG_KEYWORD_ORDER = "Missorted modifiers `{0} {1}`."; - private static final String MSG_ANNOTATIONS_SHOULD_BE_BEFORE_MODS = - "Missorted modifiers `{0} {1}`. Annotations should be placed before modifiers."; + private static final String MSG_TYPE_ANNOTATIONS_SHOULD_BE_BEFORE_MODS = + "Missorted modifiers `{0} {1}`. Type annotations should be placed before modifiers."; + + private static final String MSG_NON_TYPE_ANNOTATIONS_SHOULD_BE_BEFORE_MODS = + "Missorted modifiers `{0} {1}`. Non-type annotations should be placed before modifiers."; private static final String MSG_TYPE_ANNOT_SHOULD_BE_BEFORE_TYPE = "Missorted modifiers `{0} {1}`. Type annotations should be placed before the type they qualify."; @@ -85,6 +89,8 @@ abstract static class LastModSeen { abstract boolean checkNextAnnot(AnnotMod next, RuleContext ctx); + abstract boolean checkNextTypeParams(TypeParamsMod next, RuleContext ctx); + @Override public abstract String toString(); } @@ -115,18 +121,28 @@ boolean checkNextAnnot(AnnotMod next, RuleContext ctx) { if (next.isTypeAnnot != OptionalBool.NO && typeAnnotPosition != TypeAnnotationPosition.ON_DECL) { return false; } - ctx.addViolationWithPosition(reportNode, token, MSG_ANNOTATIONS_SHOULD_BE_BEFORE_MODS, this, next); + + if (next.isTypeAnnot.isTrue()) { + ctx.addViolationWithPosition(reportNode, token, MSG_TYPE_ANNOTATIONS_SHOULD_BE_BEFORE_MODS, this, next); + } else { + ctx.addViolationWithPosition(reportNode, token, MSG_NON_TYPE_ANNOTATIONS_SHOULD_BE_BEFORE_MODS, this, next); + } return true; } + @Override + boolean checkNextTypeParams(TypeParamsMod next, RuleContext ctx) { + return false; + } + @Override public String toString() { return mod.getToken(); } } - class AnnotMod extends ModifierOrderRule.LastModSeen { + class AnnotMod extends LastModSeen { private final @Nullable LastModSeen previous; private final ASTAnnotation annot; private final OptionalBool isTypeAnnot; @@ -149,8 +165,10 @@ boolean checkNextKeyword(KwMod next, RuleContext ctx) { // annotation sandwiched between keywords if (isTypeAnnot.isTrue() && typeAnnotPosition != TypeAnnotationPosition.ON_DECL) { ctx.addViolationWithMessage(annot, MSG_TYPE_ANNOT_SHOULD_BE_BEFORE_TYPE, this, next); + } else if (isTypeAnnot.isTrue()) { + ctx.addViolationWithMessage(annot, MSG_TYPE_ANNOTATIONS_SHOULD_BE_BEFORE_MODS, previous, this); } else { - ctx.addViolationWithMessage(annot, MSG_ANNOTATIONS_SHOULD_BE_BEFORE_MODS, previous, this); + ctx.addViolationWithMessage(annot, MSG_NON_TYPE_ANNOTATIONS_SHOULD_BE_BEFORE_MODS, previous, this); } return true; } @@ -164,12 +182,49 @@ boolean checkNextAnnot(AnnotMod next, RuleContext ctx) { return false; } + @Override + boolean checkNextTypeParams(TypeParamsMod next, RuleContext ctx) { + if (isTypeAnnot.isTrue() && typeAnnotPosition == TypeAnnotationPosition.ON_TYPE) { + ctx.addViolationWithMessage(annot, MSG_TYPE_ANNOT_SHOULD_BE_BEFORE_TYPE, this, next); + return true; + } + return false; + } + @Override public String toString() { return PrettyPrintingUtil.prettyPrintAnnot(annot); } } + class TypeParamsMod extends LastModSeen { + private final ASTTypeParameters typeParameters; + + TypeParamsMod(ASTTypeParameters typeParameters) { + this.typeParameters = typeParameters; + } + + @Override + boolean checkNextKeyword(KwMod next, RuleContext ctx) { + return false; + } + + @Override + boolean checkNextAnnot(AnnotMod next, RuleContext ctx) { + return false; + } + + @Override + boolean checkNextTypeParams(TypeParamsMod next, RuleContext ctx) { + return false; + } + + @Override + public String toString() { + return typeParameters.getText().toString(); + } + } + @Override public Object visit(ASTModifierList modList, Object data) { RuleContext ctx = asCtx(data); @@ -202,6 +257,18 @@ public boolean recordModifier(JModifier mod, JavaccToken token) { lastModSeen = kwMod; return false; } + + @Override + public boolean recordTypeParameters(ASTTypeParameters typeParameters) { + TypeParamsMod typeParamsMod = new TypeParamsMod(typeParameters); + if (lastModSeen != null) { + if (lastModSeen.checkNextTypeParams(typeParamsMod, ctx)) { + return true; + } + } + lastModSeen = typeParamsMod; + return false; + } }; readModifierList(modList, eventHandler); @@ -225,6 +292,9 @@ private static OptionalBool isTypeAnnotation(ASTAnnotation node) { private static @Nullable ASTType getFollowingType(ASTModifierList node) { JavaNode nextSibling = node.getNextSibling(); + if (nextSibling instanceof ASTTypeParameters) { + nextSibling = nextSibling.getNextSibling(); + } if (nextSibling instanceof ASTType) { return (ASTType) nextSibling; } @@ -252,6 +322,9 @@ interface ModifierOrderEvents { /** Record that the next modifier is the given one occurring at the given token. */ boolean recordModifier(JModifier mod, JavaccToken token); + + /** Record that the next "modifier" is the given type parameters. */ + boolean recordTypeParameters(ASTTypeParameters typeParameters); } /** @@ -301,7 +374,9 @@ private static void readModifierList(ASTModifierList modList, ModifierOrderEvent tok = tok.getNext(); } - + if (modList.getNextSibling() instanceof ASTTypeParameters) { + events.recordTypeParameters((ASTTypeParameters) modList.getNextSibling()); + } } private static JModifier getModFromToken(JavaccToken tok) { diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml index 79d99dab7d3..5173e8abc58 100644 --- a/pmd-java/src/main/resources/category/java/codestyle.xml +++ b/pmd-java/src/main/resources/category/java/codestyle.xml @@ -1150,7 +1150,7 @@ public class Foo { - `on type`: Type annotations must be placed next to the type they apply to - `on decl`: Type annotations must be placed with other annotations, before modifiers. This is not enforced if the type annotations syntactically appears within the type, e.g. - in `public Map.@Nullable Entry<K,V> method()`. + in `public Map.@Nullable Entry<K,V> method()` or `public <T> @NonNull T method()`. - `anywhere` (default): Either position fits. They still cannot be interspersed within keyword modifiers. Annotations that are not type annotations are still required to be before keyword modifiers. diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ModifierOrder.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ModifierOrder.xml index 78b36691b50..04af2665ff5 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ModifierOrder.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ModifierOrder.xml @@ -68,10 +68,10 @@ abstract public class Foo { // warn l1 5 8,14,17,22,24 - Missorted modifiers `public @Decl`. Annotations should be placed before modifiers. + Missorted modifiers `public @Decl`. Non-type annotations should be placed before modifiers. Missorted modifiers `@TypeA static`. Type annotations should be placed before the type they qualify. - Missorted modifiers `public @Decl`. Annotations should be placed before modifiers. - Missorted modifiers `static @Decl`. Annotations should be placed before modifiers. + Missorted modifiers `public @Decl`. Non-type annotations should be placed before modifiers. + Missorted modifiers `static @Decl`. Non-type annotations should be placed before modifiers. Missorted modifiers `@TypeA static`. Type annotations should be placed before the type they qualify. @@ -88,7 +88,7 @@ abstract public class Foo { // warn l1 Missorted modifiers `@TypeA static`. Type annotations should be placed before the type they qualify. Missorted modifiers `@TypeA public`. Type annotations should be placed before the type they qualify. Missorted modifiers `@TypeA public`. Type annotations should be placed before the type they qualify. - Missorted modifiers `static @Decl`. Annotations should be placed before modifiers. + Missorted modifiers `static @Decl`. Non-type annotations should be placed before modifiers. Missorted modifiers `@TypeA static`. Type annotations should be placed before the type they qualify. @@ -100,12 +100,12 @@ abstract public class Foo { // warn l1 6 5,8,14,17,22,24 - Missorted modifiers `public @TypeA`. Annotations should be placed before modifiers. - Missorted modifiers `public @Decl`. Annotations should be placed before modifiers. - Missorted modifiers `public @TypeA`. Annotations should be placed before modifiers. - Missorted modifiers `public @Decl`. Annotations should be placed before modifiers. - Missorted modifiers `static @Decl`. Annotations should be placed before modifiers. - Missorted modifiers `public @TypeA`. Annotations should be placed before modifiers. + Missorted modifiers `public @TypeA`. Type annotations should be placed before modifiers. + Missorted modifiers `public @Decl`. Non-type annotations should be placed before modifiers. + Missorted modifiers `public @TypeA`. Type annotations should be placed before modifiers. + Missorted modifiers `public @Decl`. Non-type annotations should be placed before modifiers. + Missorted modifiers `static @Decl`. Non-type annotations should be placed before modifiers. + Missorted modifiers `public @TypeA`. Type annotations should be placed before modifiers. @@ -269,7 +269,7 @@ abstract public class Foo { // warn l1 - Sealed class + #6057 Sealed class 0 + Foo bar3a() { return this; } // line 8 + public @TypeAnnotation Foo bar3b() { return this; } // line 9 + @TypeAnnotation public Foo bar3c() { return this; } // line 10 + + public @NotATypeAnnotation Foo bar4a() { return this; } // line 12 + public @NotATypeAnnotation Foo bar4b() { return this; } // line 13 + @NotATypeAnnotation public Foo bar4c() { return this; } // line 14 +} +@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE_USE) +@interface TypeAnnotation {} + +@interface NotATypeAnnotation {} +]]> + + + #6053 Annotation on method with modifiers/generic types (typeAnnotations=anywhere) + anywhere + 2 + 5,12 + + Missorted modifiers `public @NotATypeAnnotation`. Non-type annotations should be placed before modifiers. + Missorted modifiers `public @NotATypeAnnotation`. Non-type annotations should be placed before modifiers. + + + + + + #6053 Annotation on method with modifiers/generic types (typeAnnotations=ontype) + ontype + 5 + 3,5,8,10,12 + + Missorted modifiers `@TypeAnnotation public`. Type annotations should be placed before the type they qualify. + Missorted modifiers `public @NotATypeAnnotation`. Non-type annotations should be placed before modifiers. + Missorted modifiers `@TypeAnnotation <T>`. Type annotations should be placed before the type they qualify. + Missorted modifiers `@TypeAnnotation public`. Type annotations should be placed before the type they qualify. + Missorted modifiers `public @NotATypeAnnotation`. Non-type annotations should be placed before modifiers. + + + + + + #6053 Annotation on method with modifiers/generic types (typeAnnotations=ondecl) + ondecl + 4 + 2,5,8,12 + + Missorted modifiers `public @TypeAnnotation`. Type annotations should be placed before modifiers. + Missorted modifiers `public @NotATypeAnnotation`. Non-type annotations should be placed before modifiers. + Missorted modifiers `public @TypeAnnotation`. Type annotations should be placed before modifiers. + Missorted modifiers `public @NotATypeAnnotation`. Non-type annotations should be placed before modifiers. + + + + + + + #6053 Annotation on method parameter with modifiers/generic types (typeAnnotations=anywhere) + anywhere + 1 + 5 + + Missorted modifiers `final @NotATypeAnnotation`. Non-type annotations should be placed before modifiers. + + + + + #6053 Annotation on method parameter with modifiers/generic types (typeAnnotations=ontype) + ontype + 2 + 3,5 + + Missorted modifiers `@TypeAnnotation final`. Type annotations should be placed before the type they qualify. + Missorted modifiers `final @NotATypeAnnotation`. Non-type annotations should be placed before modifiers. + + + + + #6053 Annotation on method parameter with modifiers/generic types (typeAnnotations=ondecl) + ondecl + 2 + 2,5 + + Missorted modifiers `final @TypeAnnotation`. Type annotations should be placed before modifiers. + Missorted modifiers `final @NotATypeAnnotation`. Non-type annotations should be placed before modifiers. + + + From 4aab1e3508496ce8e280a1f1cd924ba8433c92cc Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Tue, 28 Oct 2025 02:29:43 +0100 Subject: [PATCH 1570/1962] [java] Implement main method launch protocol priorities --- .../lang/java/ast/ASTMethodDeclaration.java | 50 ++++++++----- .../ast/ASTMethodDeclarationMainTest.java | 75 +++++++++++++++++++ 2 files changed, 108 insertions(+), 17 deletions(-) create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclarationMainTest.java diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java index 258042cfc9a..5def2ddfd3a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java @@ -4,6 +4,8 @@ package net.sourceforge.pmd.lang.java.ast; +import java.util.function.Predicate; + import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -12,7 +14,6 @@ import net.sourceforge.pmd.lang.java.types.TypeSystem; import net.sourceforge.pmd.lang.java.types.TypeTestUtil; - /** * A method declaration, in a class or interface declaration. Since 7.0, * this also represents annotation methods. Annotation methods have a @@ -130,26 +131,41 @@ public ASTArrayDimensions getExtraDimensions() { /** * Returns whether this is a main method declaration. + * + * @see 12.1.4. Invoke a main Method */ public boolean isMainMethod() { - return this.hasModifiers(JModifier.PUBLIC, JModifier.STATIC) - && "main".equals(this.getName()) + if (!isMainMethodCandidate()) { + return false; + } + if (isStatic()) { + return getArity() == 1 || hasNoOtherMainMethodSibling( + m -> m.isStatic() && m.getArity() == 1); + } + if (getArity() == 1) { + return hasNoOtherMainMethodSibling(ASTExecutableDeclaration::isStatic); + } + return hasNoOtherMainMethodSibling(any -> true) + && !ancestors(ASTClassDeclaration.class).firstOpt() + .map(this::hasParametrizedMain).orElse(false); + } + + private boolean hasNoOtherMainMethodSibling(Predicate check) { + return getParent().children(ASTMethodDeclaration.class).toStream().filter(check) + .noneMatch(m -> m != this && m.isMainMethodCandidate()); + } + + private boolean isMainMethodCandidate() { + return "main".equals(this.getName()) + && !this.hasModifiers(JModifier.PRIVATE) && this.isVoid() - && this.getArity() == 1 - && TypeTestUtil.isExactlyA(String[].class, this.getFormalParameters().get(0)) - || isLaunchableMainMethod(); + && (this.getArity() == 0 + || this.getArity() == 1 && TypeTestUtil.isExactlyA(String[].class, this.getFormalParameters().get(0))); } - /** - * With JEP 445/463/477/495/512 (Java 24 Preview/Java 25) the main method does not need to be static anymore and - * does not need to be public or have a formal parameter. - */ - private boolean isLaunchableMainMethod() { - return this.getRoot().isCompact() - && "main".equals(this.getName()) - && !this.hasModifiers(JModifier.PRIVATE) - && this.isVoid() - && (this.getArity() == 0 - || this.getArity() == 1 && TypeTestUtil.isExactlyA(String[].class, this.getFormalParameters().get(0))); + private boolean hasParametrizedMain(ASTClassDeclaration astClassType) { + return astClassType.getTypeMirror().streamMethods( + m -> "main".equals(m.getSimpleName()) && m.getArity() == 1 && !m.isStatic()) + .anyMatch(m -> TypeTestUtil.isExactlyA(String[].class, m.getFormalParameters().get(0))); } } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclarationMainTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclarationMainTest.java new file mode 100644 index 00000000000..83d05232c3c --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclarationMainTest.java @@ -0,0 +1,75 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.ast; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; + +import net.sourceforge.pmd.lang.java.BaseParserTest; + +class ASTMethodDeclarationMainTest extends BaseParserTest { + + @ParameterizedTest + @CsvSource({ + "static void main(), static void main(String[] args)", + "void main(), static void main(String[] args)", + "void main(), void main(String[] args)", + "void main(String[] args), static void main()", + "private static void main(String[] args), void main()", + "void main(), void main(String... args)", + "void main(String... args), static void main()" + }) + void mainMethodPriorityTest(String lowPriority, String highPriority) { + ASTCompilationUnit nodes = java.parse( + "public class App {\n" + + lowPriority + "{ }\n" + + highPriority + "{ }\n" + + "}" + ); + List methods = nodes.descendants(ASTMethodDeclaration.class).toList(); + assertFalse(methods.get(0).isMainMethod()); + assertTrue(methods.get(1).isMainMethod()); + } + + @ParameterizedTest + @ValueSource(strings = { "String[]", "String..."}) + void mainMethodPriorityWithOverride(String parentArgType) { + ASTCompilationUnit nodes = java.parse( + "public class BaseApp {\n" + + " public void main(" + parentArgType + " args) { }\n" + + " public class App extends BaseApp {\n" + + " public void main() { }\n" + + " }\n" + + "}" + ); + List methods = nodes.descendants(ASTMethodDeclaration.class) + .crossFindBoundaries().toList(); + assertTrue(methods.get(0).isMainMethod()); + assertFalse(methods.get(1).isMainMethod()); + } + + @Test + void mainMethodPriorityWithStaticInSuperclass() { + ASTCompilationUnit nodes = java.parse( + "public class BaseApp {\n" + + " public static void main(String[] args) { }\n" + + " public class App extends BaseApp {\n" + + " public void main() { }\n" + + " }\n" + + "}" + ); + List methods = nodes.descendants(ASTMethodDeclaration.class) + .crossFindBoundaries().toList(); + assertTrue(methods.get(0).isMainMethod()); + assertTrue(methods.get(1).isMainMethod()); + } +} From 1fe72a38366db3a159baffdb5dfec1259f304396 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 30 Oct 2025 12:01:24 +0100 Subject: [PATCH 1571/1962] [doc] Update release notes (#6132) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 1cadafa6250..debfaefa03c 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -75,6 +75,7 @@ checkstyle version during the build. * java * [#4904](https://github.com/pmd/pmd/issues/4904): \[java] Renderers output wrong class qualified name for nested classes * [#6127](https://github.com/pmd/pmd/issues/6127): \[java] Incorrect variable name in violation + * [#6132](https://github.com/pmd/pmd/issues/6132): \[java] Implement main method launch protocol priorities * [#6146](https://github.com/pmd/pmd/issues/6146): \[java] ClassCastException: class InferenceVarSym cannot be cast to class JClassSymbol * java-bestpractices * [#2928](https://github.com/pmd/pmd/issues/2928): \[java] New rules about labeled statements @@ -154,6 +155,7 @@ checkstyle version during the build. * [#6124](https://github.com/pmd/pmd/pull/6124): \[java] UnusedLocalVariable: fix false negatives in pattern matching - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6129](https://github.com/pmd/pmd/pull/6129): \[java] Fix #6127: Correct var name in violation decorator - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6130](https://github.com/pmd/pmd/pull/6130): \[java] UselessParentheses: fix false positives for switch expressions - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6132](https://github.com/pmd/pmd/pull/6132): \[java] Implement main method launch protocol priorities - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6133](https://github.com/pmd/pmd/pull/6133): \[java] Fix #5042: CloseResource: fix false positive with pattern matching - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6150](https://github.com/pmd/pmd/pull/6150): \[core] Reduce memory usage of CPD's MatchCollector - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6152](https://github.com/pmd/pmd/pull/6152): chore(deps): Update Saxon-HE from 12.5 to 12.9 - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) From 5db7aadecc60825db675424dbebe83b639002fd3 Mon Sep 17 00:00:00 2001 From: Mitch Spano Date: Wed, 29 Oct 2025 11:37:50 -0500 Subject: [PATCH 1572/1962] `ApexDocRule` - enhance documentation validation and improve messages - Updated the ApexDocRule to validate comments according to the Salesforce ApexDoc specification. - Changed the handling of the main description to check for text before the first ApexDoc tag. - Updated error messages to reflect the new validation logic, specifically changing "Missing ApexDoc @description" to "Missing ApexDoc main description". --- .../apex/rule/documentation/ApexDocRule.java | 72 ++++-- .../apex/rule/documentation/xml/ApexDoc.xml | 210 ++++++++++++------ 2 files changed, 199 insertions(+), 83 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/documentation/ApexDocRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/documentation/ApexDocRule.java index e1ffea4a748..2b106f4ca5f 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/documentation/ApexDocRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/documentation/ApexDocRule.java @@ -27,33 +27,37 @@ import net.sourceforge.pmd.lang.rule.RuleTargetSelector; import net.sourceforge.pmd.properties.PropertyDescriptor; +/** + * Validates ApexDoc comments according to the Salesforce ApexDoc specification. + * + * For more information, see: + * ApexDoc Format Specification + */ public class ApexDocRule extends AbstractApexRule { - private static final Pattern DESCRIPTION_PATTERN = Pattern.compile("@description\\s"); + private static final Pattern FIRST_TAG_PATTERN = Pattern.compile( + "@(param|return|throws|exception|deprecated|since|see|author|version)\\s", Pattern.CASE_INSENSITIVE); private static final Pattern RETURN_PATTERN = Pattern.compile("@return\\s"); private static final Pattern PARAM_PATTERN = Pattern.compile("@param\\s+(\\w+)\\s"); private static final String MISSING_COMMENT_MESSAGE = "Missing ApexDoc comment"; - private static final String MISSING_DESCRIPTION_MESSAGE = "Missing ApexDoc @description"; + private static final String MISSING_DESCRIPTION_MESSAGE = "Missing ApexDoc main description"; private static final String MISSING_RETURN_MESSAGE = "Missing ApexDoc @return"; private static final String UNEXPECTED_RETURN_MESSAGE = "Unexpected ApexDoc @return"; private static final String MISMATCHED_PARAM_MESSAGE = "Missing or mismatched ApexDoc @param"; - private static final PropertyDescriptor REPORT_PRIVATE_DESCRIPTOR = - booleanProperty("reportPrivate") - .desc("Report private classes, methods and properties").defaultValue(false).build(); + private static final PropertyDescriptor REPORT_PRIVATE_DESCRIPTOR = booleanProperty("reportPrivate") + .desc("Report private classes, methods and properties").defaultValue(false).build(); - private static final PropertyDescriptor REPORT_PROTECTED_DESCRIPTOR = - booleanProperty("reportProtected") - .desc("Report protected classes, methods and properties").defaultValue(false).build(); + private static final PropertyDescriptor REPORT_PROTECTED_DESCRIPTOR = booleanProperty("reportProtected") + .desc("Report protected classes, methods and properties").defaultValue(false).build(); - private static final PropertyDescriptor REPORT_MISSING_DESCRIPTION_DESCRIPTOR = - booleanProperty("reportMissingDescription") - .desc("Report missing @description").defaultValue(true).build(); + private static final PropertyDescriptor REPORT_MISSING_DESCRIPTION_DESCRIPTOR = booleanProperty( + "reportMissingDescription").desc("Report missing main description").defaultValue(true).build(); - private static final PropertyDescriptor REPORT_PROPERTY_DESCRIPTOR = - booleanProperty("reportProperty") - .desc("Report properties without comments").defaultValue(true).build(); + private static final PropertyDescriptor REPORT_PROPERTY_DESCRIPTOR = booleanProperty("reportProperty") + .desc("Report properties without comments").defaultValue(true).build(); public ApexDocRule() { definePropertyDescriptor(REPORT_PRIVATE_DESCRIPTOR); @@ -64,7 +68,8 @@ public ApexDocRule() { @Override protected @NonNull RuleTargetSelector buildTargetSelector() { - return RuleTargetSelector.forTypes(ASTUserClass.class, ASTUserInterface.class, ASTMethod.class, ASTProperty.class); + return RuleTargetSelector.forTypes(ASTUserClass.class, ASTUserInterface.class, ASTMethod.class, + ASTProperty.class); } @Override @@ -107,8 +112,8 @@ public Object visit(ASTMethod node, Object data) { } // Collect parameter names in order - final List params = node.children(ASTParameter.class).toStream() - .map(ASTParameter::getImage).collect(Collectors.toList()); + final List params = node.children(ASTParameter.class).toStream().map(ASTParameter::getImage) + .collect(Collectors.toList()); if (!comment.params.equals(params)) { asCtx(data).addViolationWithMessage(node, MISMATCHED_PARAM_MESSAGE); @@ -169,7 +174,8 @@ private boolean shouldHaveApexDocs(ApexNode node) { if (modifier != null) { boolean flagPrivate = getProperty(REPORT_PRIVATE_DESCRIPTOR) && modifier.isPrivate(); boolean flagProtected = getProperty(REPORT_PROTECTED_DESCRIPTOR) && modifier.isProtected(); - return (modifier.isPublic() || modifier.isGlobal() || flagPrivate || flagProtected) && !modifier.isOverride(); + return (modifier.isPublic() || modifier.isGlobal() || flagPrivate || flagProtected) + && !modifier.isOverride(); } return false; @@ -180,7 +186,8 @@ private ApexDocComment getApexDocComment(ApexNode node) { if (comment != null) { String token = comment.getImage(); - boolean hasDescription = DESCRIPTION_PATTERN.matcher(token).find(); + // Find the main description: text before the first ApexDoc tag + boolean hasDescription = hasMainDescription(token); boolean hasReturn = RETURN_PATTERN.matcher(token).find(); List params = new ArrayList<>(); @@ -194,6 +201,33 @@ private ApexDocComment getApexDocComment(ApexNode node) { return null; } + /** + * Checks if the comment has a main description according to ApexDoc format. + * The main description is the text that appears before + * any @param, @return, @throws, or other ApexDoc tags. + */ + private boolean hasMainDescription(String comment) { + Matcher tagMatcher = FIRST_TAG_PATTERN.matcher(comment); + int firstTagPosition = tagMatcher.find() ? tagMatcher.start() : comment.length(); + String textBeforeTags = comment.substring(0, firstTagPosition); + String multilineCommentOpenRegex = "^/\\*\\*"; + String multilineCommentCloseRegex = "\\*/$"; + + String cleaned = textBeforeTags.replaceFirst(multilineCommentOpenRegex, "") + .replaceAll(multilineCommentCloseRegex, ""); + + // Remove leading asterisks and whitespace from each line + // This pattern matches: + // - Start of line (^) + // - Optional whitespace (\s*) + // - Literal asterisk (*) + // - Optional whitespace after asterisk (\s?) + // But only if it's not followed by / (to avoid matching */) + cleaned = cleaned.replaceAll("(?m)^\\s*\\*+(?!\\/)\\s?", ""); + + return !cleaned.trim().isEmpty(); + } + private static class ApexDocComment { boolean hasDescription; boolean hasReturn; diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/documentation/xml/ApexDoc.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/documentation/xml/ApexDoc.xml index 800b8632e6b..a2f747275ef 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/documentation/xml/ApexDoc.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/documentation/xml/ApexDoc.xml @@ -9,7 +9,7 @@ 1 @@ -62,7 +62,7 @@ private class Foo { } 1 3 - Missing ApexDoc @description + Missing ApexDoc main description 0 @@ -87,7 +87,7 @@ public class Foo { } 0 0 @@ -153,7 +153,7 @@ public interface Foo { } 0 1 1 0 1 0 1 0 1 1 0 1 1 0 0 0 0 1 1 0 1 0 1 1 0 0 0 12 2 2 0 5 property with missing description false 1 - 8 + 7 0 0 0 0 + + + method with params but missing main description + 1 + 8 + + + + + method with return but missing main description + 1 + 8 + + + + + method with params and return but missing main description + 1 + 10 + + + + + method with param but missing main description + 1 + 8 + + + + + method with complete documentation including main description + 0 + + From 671a92115886f020a47a24583148ad1e153dc0f7 Mon Sep 17 00:00:00 2001 From: Mitch Spano Date: Wed, 29 Oct 2025 12:11:02 -0500 Subject: [PATCH 1573/1962] Update ApexDoc comments in documentation.xml to clarify main description requirement --- pmd-apex/src/main/resources/category/apex/documentation.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pmd-apex/src/main/resources/category/apex/documentation.xml b/pmd-apex/src/main/resources/category/apex/documentation.xml index 22600c7ced7..f802cdee6db 100644 --- a/pmd-apex/src/main/resources/category/apex/documentation.xml +++ b/pmd-apex/src/main/resources/category/apex/documentation.xml @@ -22,7 +22,7 @@ This rule validates that: overrides and test classes (as well as the contents of test classes). * ApexDoc comments are present for classes, methods, and properties that are protected or private, depending on the properties `reportPrivate` and `reportProtected`. -* ApexDoc comments should contain @description depending on the property `reportMissingDescription`. +* ApexDoc comments should contain a main description depending on the property `reportMissingDescription`. * ApexDoc comments on non-void, non-constructor methods should contain @return. * ApexDoc comments on void or constructor methods should not contain @return. * ApexDoc comments on methods with parameters should contain @param for each parameter, in the same @@ -36,11 +36,11 @@ Method overrides and tests are both exempted from having ApexDoc. Date: Wed, 29 Oct 2025 12:12:06 -0500 Subject: [PATCH 1574/1962] Remove unnecessary comment. --- .../pmd/lang/apex/rule/documentation/ApexDocRule.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/documentation/ApexDocRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/documentation/ApexDocRule.java index 2b106f4ca5f..f7994d7e57c 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/documentation/ApexDocRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/documentation/ApexDocRule.java @@ -185,8 +185,6 @@ private ApexDocComment getApexDocComment(ApexNode node) { ASTFormalComment comment = node.firstChild(ASTFormalComment.class); if (comment != null) { String token = comment.getImage(); - - // Find the main description: text before the first ApexDoc tag boolean hasDescription = hasMainDescription(token); boolean hasReturn = RETURN_PATTERN.matcher(token).find(); From 4cb2549d467498a1fe5b2c3f53f067ad5ce3bda2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 30 Oct 2025 12:05:21 +0100 Subject: [PATCH 1575/1962] Remove duplicated test case --- .../apex/rule/documentation/xml/ApexDoc.xml | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/documentation/xml/ApexDoc.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/documentation/xml/ApexDoc.xml index a2f747275ef..098e5da744e 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/documentation/xml/ApexDoc.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/documentation/xml/ApexDoc.xml @@ -794,23 +794,6 @@ public class Foo { ]]> - - method with param but missing main description - 1 - 8 - - - method with complete documentation including main description 0 From 3a9eabaa85af8f718b8d33499052ced975372d18 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 30 Oct 2025 12:06:34 +0100 Subject: [PATCH 1576/1962] [doc] Update release notes (#6189, #6190) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index debfaefa03c..867b515919a 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -72,6 +72,8 @@ checkstyle version during the build. * [#5935](https://github.com/pmd/pmd/issues/5935): \[apex] @SuppressWarnings - allow whitespace around comma when suppressing multiple rules * apex-design * [#6022](https://github.com/pmd/pmd/issues/6022): \[apex] ExcessiveClassLength/ExcessiveParameterList include the metric in the message +* apex-documentation + * [#6189](https://github.com/pmd/pmd/issues/6189): \[apex] ApexDoc rule doesn't match published Salesforce ApexDoc specification * java * [#4904](https://github.com/pmd/pmd/issues/4904): \[java] Renderers output wrong class qualified name for nested classes * [#6127](https://github.com/pmd/pmd/issues/6127): \[java] Incorrect variable name in violation @@ -164,6 +166,7 @@ checkstyle version during the build. * [#6166](https://github.com/pmd/pmd/pull/6166): \[doc] Use emoji variants - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6170](https://github.com/pmd/pmd/pull/6170): \[java] Fix #6169: AvoidUsingHardCodedIP - mention address in message - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6171](https://github.com/pmd/pmd/pull/6171): \[java] AvoidUsingHardCodedIP: fix false positive for IPv6 - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6190](https://github.com/pmd/pmd/pull/6190): \[apex] Update ApexDoc rule to match the published specification - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) ### ๐Ÿ“ฆ๏ธ Dependency updates From 4d7cc3287d04215b1be6dc2f0cc75d21edfa71b4 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Thu, 30 Oct 2025 01:32:33 +0100 Subject: [PATCH 1577/1962] [java] HardCodedCryptoKey: report constants from parent class --- ...AbstractHardCodedConstructorArgsVisitor.java | 9 +++++++-- .../rule/security/HardCodedCryptoKeyTest.java | 4 ++++ .../rule/security/xml/HardCodedCryptoKey.xml | 17 +++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/security/AbstractHardCodedConstructorArgsVisitor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/security/AbstractHardCodedConstructorArgsVisitor.java index 66d7aedc998..29420afb9d0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/security/AbstractHardCodedConstructorArgsVisitor.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/security/AbstractHardCodedConstructorArgsVisitor.java @@ -65,8 +65,13 @@ private void validateProperKeyArgument(Object data, ASTExpression firstArgumentE if (varAccess != null && varAccess.getSignature() != null && varAccess.getSignature().getSymbol() != null) { // named variable or method call on named variable found ASTVariableId varDecl = varAccess.getSignature().getSymbol().tryGetNode(); - validateProperKeyArgument(data, varDecl.getInitializer()); - validateVarUsages(data, varDecl); + if (varDecl != null) { + validateProperKeyArgument(data, varDecl.getInitializer()); + validateVarUsages(data, varDecl); + } else if (varAccess.isCompileTimeConstant() + && varAccess.getConstValue() instanceof String) { + asCtx(data).addViolation(varAccess); + } } else if (firstArgumentExpression instanceof ASTArrayAllocation) { // hard coded array ASTArrayInitializer arrayInit = ((ASTArrayAllocation) firstArgumentExpression).getArrayInitializer(); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/security/HardCodedCryptoKeyTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/security/HardCodedCryptoKeyTest.java index df2d6542ad5..29454df6df9 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/security/HardCodedCryptoKeyTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/security/HardCodedCryptoKeyTest.java @@ -8,4 +8,8 @@ class HardCodedCryptoKeyTest extends PmdRuleTst { // no additional unit tests + public interface Constants { + String SOME_STRING = "NOT_SECRET"; + String DYNAMIC_STRING = "ALPHABET".substring((int) (Math.random() * 4)); + } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/security/xml/HardCodedCryptoKey.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/security/xml/HardCodedCryptoKey.xml index a7627a403f0..af1aef0fdd8 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/security/xml/HardCodedCryptoKey.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/security/xml/HardCodedCryptoKey.xml @@ -122,4 +122,21 @@ public class Foo { } ]]> + + [java] Hardcoded constant in parent interface #6191 + 1 + + + + From f412ba4bf533627900858400c464545a152c1a12 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 30 Oct 2025 12:51:23 +0100 Subject: [PATCH 1578/1962] [doc] Update release notes (#6191) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 867b515919a..e52de44e9e7 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -108,6 +108,8 @@ checkstyle version during the build. * [#6083](https://github.com/pmd/pmd/issues/6083): \[java] New rule IdenticalConditionalBranches * java-multithreading * [#5880](https://github.com/pmd/pmd/issues/5880): \[java] DoubleCheckedLocking is not detected if more than 1 assignment or more than 2 if statements +* java-security + * [#6191](https://github.com/pmd/pmd/issues/6191): \[java] HardCodedCryptoKey: NPE when constants from parent class are used * plsql-design * [#6077](https://github.com/pmd/pmd/issues/6077): \[plsql] Excessive\*/Ncss\*Count/NPathComplexity include the metric @@ -167,6 +169,7 @@ checkstyle version during the build. * [#6170](https://github.com/pmd/pmd/pull/6170): \[java] Fix #6169: AvoidUsingHardCodedIP - mention address in message - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6171](https://github.com/pmd/pmd/pull/6171): \[java] AvoidUsingHardCodedIP: fix false positive for IPv6 - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6190](https://github.com/pmd/pmd/pull/6190): \[apex] Update ApexDoc rule to match the published specification - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) +* [#6191](https://github.com/pmd/pmd/pull/6191): \[java] HardCodedCryptoKey: NPE when constants from parent class are used - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) ### ๐Ÿ“ฆ๏ธ Dependency updates From cd56910c0b748bb86723a89af89526ef5d8c1a5d Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Wed, 29 Oct 2025 02:03:13 +0100 Subject: [PATCH 1579/1962] [java] InefficientEmptyStringCheck should include String#strip --- .../InefficientEmptyStringCheckRule.java | 20 +++++---- .../resources/category/java/performance.xml | 27 ++++++------ .../xml/InefficientEmptyStringCheck.xml | 42 ++++++++++++++++++- 3 files changed, 64 insertions(+), 25 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientEmptyStringCheckRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientEmptyStringCheckRule.java index d24e2641e83..fa59efaac98 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientEmptyStringCheckRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InefficientEmptyStringCheckRule.java @@ -48,8 +48,8 @@ public InefficientEmptyStringCheckRule() { @Override public Object visit(ASTMethodCall call, Object data) { - if (isTrimCall(call.getQualifier()) - && (isLengthZeroCheck(call) || isIsEmptyCall(call))) { + if (isTrimOrStripCall(call.getQualifier()) + && (isLengthZeroCheck(call) || isIsEmptyOrIsBlankCall(call))) { asCtx(data).addViolation(call); } return null; @@ -57,26 +57,28 @@ public Object visit(ASTMethodCall call, Object data) { private static boolean isLengthZeroCheck(ASTMethodCall call) { return "length".equals(call.getMethodName()) - && call.getArguments().size() == 0 + && call.getArguments().isEmpty() && JavaRuleUtil.isZeroChecked(call); } - private static boolean isTrimCall(ASTExpression expr) { + private static boolean isTrimOrStripCall(ASTExpression expr) { if (expr instanceof ASTMethodCall) { ASTMethodCall call = (ASTMethodCall) expr; - return "trim".equals(call.getMethodName()) - && call.getArguments().size() == 0 + String methodName = call.getMethodName(); + return ("trim".equals(methodName) || "strip".equals(methodName)) + && call.getArguments().isEmpty() && TypeTestUtil.isA(String.class, call.getQualifier()); } return false; } - private static boolean isIsEmptyCall(ASTExpression expr) { + private static boolean isIsEmptyOrIsBlankCall(ASTExpression expr) { if (expr instanceof ASTMethodCall) { ASTMethodCall call = (ASTMethodCall) expr; - return "isEmpty".equals(call.getMethodName()) - && call.getArguments().size() == 0; + String methodName = call.getMethodName(); + return ("isEmpty".equals(methodName) || "isBlank".equals(methodName)) + && call.getArguments().isEmpty(); } return false; } diff --git a/pmd-java/src/main/resources/category/java/performance.xml b/pmd-java/src/main/resources/category/java/performance.xml index af8256b43b2..c00a066bb2f 100644 --- a/pmd-java/src/main/resources/category/java/performance.xml +++ b/pmd-java/src/main/resources/category/java/performance.xml @@ -399,27 +399,24 @@ buf.append("1m"); // good externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#inefficientemptystringcheck"> c <= 0x20); } ``` -You can refer to Apache's StringUtils#isBlank (in commons-lang), -Spring's StringUtils#hasText (in the Spring framework) or Google's -CharMatcher#whitespace (in Guava) for existing implementations (some might -include the check for != null). +You can also consider using library functions that include a null check +(e.g. Apache's `StringUtils#isBlank` in commons-lang, +Spring's `StringUtils#hasText` in the Spring framework) or use a different definition of whitespace +(e.g. Google's `CharMatcher#whitespace` in Guava). + +Calling `string.strip().isBlank()` is also redundant and should be simplified to `string.isBlank()`. ]]> 3 diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InefficientEmptyStringCheck.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InefficientEmptyStringCheck.xml index 9a7db9f41d1..87d2ac12bc0 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InefficientEmptyStringCheck.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InefficientEmptyStringCheck.xml @@ -12,7 +12,7 @@ public class Foo { void bar() { String foo = "foo"; if (foo.length() == 0) { - // this is bad + // this is OK } } } @@ -34,6 +34,46 @@ public class Foo { ]]> + + String.strip checked for emptiness, should have failed + 3 + + + + + String.strip length checks with inequalities + 2 + 4,7 + = 0 // different problem + || foo.strip().length() <= 1 // OK + || foo.strip().length() >= 1) { // bad + + } + } +} + ]]> + + String.trim.length not is called, ok 0 From c04e4284ace4917969549af4767443699692a025 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 30 Oct 2025 12:56:21 +0100 Subject: [PATCH 1580/1962] [doc] Update release notes (#6172) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index e52de44e9e7..d6a81d7e067 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -108,6 +108,8 @@ checkstyle version during the build. * [#6083](https://github.com/pmd/pmd/issues/6083): \[java] New rule IdenticalConditionalBranches * java-multithreading * [#5880](https://github.com/pmd/pmd/issues/5880): \[java] DoubleCheckedLocking is not detected if more than 1 assignment or more than 2 if statements +* java-performance + * [#6172](https://github.com/pmd/pmd/issues/6172): \[java] InefficientEmptyStringCheck should include String#strip * java-security * [#6191](https://github.com/pmd/pmd/issues/6191): \[java] HardCodedCryptoKey: NPE when constants from parent class are used * plsql-design @@ -168,6 +170,7 @@ checkstyle version during the build. * [#6166](https://github.com/pmd/pmd/pull/6166): \[doc] Use emoji variants - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6170](https://github.com/pmd/pmd/pull/6170): \[java] Fix #6169: AvoidUsingHardCodedIP - mention address in message - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6171](https://github.com/pmd/pmd/pull/6171): \[java] AvoidUsingHardCodedIP: fix false positive for IPv6 - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6172](https://github.com/pmd/pmd/pull/6172): \[java] InefficientEmptyStringCheck should include String#strip - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6190](https://github.com/pmd/pmd/pull/6190): \[apex] Update ApexDoc rule to match the published specification - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) * [#6191](https://github.com/pmd/pmd/pull/6191): \[java] HardCodedCryptoKey: NPE when constants from parent class are used - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) From e4f94a681052127b15b6be30a33ff8bdfc1e44f1 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 29 Oct 2025 15:11:19 +0100 Subject: [PATCH 1581/1962] [java] Fix #6131: Correct enum values for ModifierOrder --- docs/pages/release_notes.md | 1 + pmd-java/src/main/resources/category/java/codestyle.xml | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index d6a81d7e067..198a51f4816 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -92,6 +92,7 @@ checkstyle version during the build. * [#6057](https://github.com/pmd/pmd/issues/6057): \[java] ModifierOrder false positive on "abstract sealed class" * [#6079](https://github.com/pmd/pmd/issues/6079): \[java] IdenticalCatchBranches: False negative for overriden method calls * [#6123](https://github.com/pmd/pmd/issues/6123): \[java] UselessParentheses FP around switch expression + * [#6131](https://github.com/pmd/pmd/issues/6131): \[java] ModifierOrder: wrong enum values documented, indirectly causing xml parse errors * java-design * [#1499](https://github.com/pmd/pmd/issues/1499): \[java] AvoidDeeplyNestedIfStmts violations can be unintentionally undetected * [#5569](https://github.com/pmd/pmd/issues/5569): \[java] ExcessivePublicCount should report number of public "things" diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml index 79d99dab7d3..d98ab2a3262 100644 --- a/pmd-java/src/main/resources/category/java/codestyle.xml +++ b/pmd-java/src/main/resources/category/java/codestyle.xml @@ -1147,8 +1147,8 @@ public class Foo { By setting the property `typeAnnotations`, you can also enforce that type annotations appear right of the modifier keywords, next to the type they apply to. This property can have three values: - - `on type`: Type annotations must be placed next to the type they apply to - - `on decl`: Type annotations must be placed with other annotations, before modifiers. + - `ontype`: Type annotations must be placed next to the type they apply to + - `ondecl`: Type annotations must be placed with other annotations, before modifiers. This is not enforced if the type annotations syntactically appears within the type, e.g. in `public Map.@Nullable Entry<K,V> method()`. - `anywhere` (default): Either position fits. They still cannot be interspersed within keyword From 46f8b5fd20dea6a803c4b90c070fa672fb930bc3 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 30 Oct 2025 13:03:33 +0100 Subject: [PATCH 1582/1962] [doc] Update release notes --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 198a51f4816..713fd1aae64 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -160,6 +160,7 @@ checkstyle version during the build. * [#6114](https://github.com/pmd/pmd/pull/6114): \[java] Fix #4122: CheckResultSet false-positive with local variable - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6116](https://github.com/pmd/pmd/pull/6116): \[java] ConfusingTernary: add configuration property for null checks - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6124](https://github.com/pmd/pmd/pull/6124): \[java] UnusedLocalVariable: fix false negatives in pattern matching - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6128](https://github.com/pmd/pmd/pull/6128): \[java] Fix #4904: Correct class name in violation decorator - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6129](https://github.com/pmd/pmd/pull/6129): \[java] Fix #6127: Correct var name in violation decorator - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6130](https://github.com/pmd/pmd/pull/6130): \[java] UselessParentheses: fix false positives for switch expressions - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6132](https://github.com/pmd/pmd/pull/6132): \[java] Implement main method launch protocol priorities - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) @@ -172,6 +173,7 @@ checkstyle version during the build. * [#6170](https://github.com/pmd/pmd/pull/6170): \[java] Fix #6169: AvoidUsingHardCodedIP - mention address in message - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6171](https://github.com/pmd/pmd/pull/6171): \[java] AvoidUsingHardCodedIP: fix false positive for IPv6 - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6172](https://github.com/pmd/pmd/pull/6172): \[java] InefficientEmptyStringCheck should include String#strip - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6185](https://github.com/pmd/pmd/pull/6185): \[java] Fix #6131: Correct enum values for ModifierOrder - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6190](https://github.com/pmd/pmd/pull/6190): \[apex] Update ApexDoc rule to match the published specification - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) * [#6191](https://github.com/pmd/pmd/pull/6191): \[java] HardCodedCryptoKey: NPE when constants from parent class are used - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) From 7fdf46607c426702279f6c398f7844e40204c081 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 30 Oct 2025 13:06:22 +0100 Subject: [PATCH 1583/1962] Update contributors - Add @rubenporras as a contributor - Add @pkozuchowski as a contributor - Add @delanym as a contributor - Add @bmeier-pros as a contributor - Add @Jallibad as a contributor --- .all-contributorsrc | 45 +++ docs/pages/pmd/projectdocs/credits.md | 383 +++++++++++++------------- 2 files changed, 240 insertions(+), 188 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 3c6879c7601..7b047b0aeba 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8271,6 +8271,51 @@ "contributions": [ "bug" ] + }, + { + "login": "Jallibad", + "name": "Jordan Alligood", + "avatar_url": "https://avatars.githubusercontent.com/u/568244?v=4", + "profile": "https://github.com/Jallibad", + "contributions": [ + "bug" + ] + }, + { + "login": "bmeier-pros", + "name": "bmeier-pros", + "avatar_url": "https://avatars.githubusercontent.com/u/141971923?v=4", + "profile": "https://github.com/bmeier-pros", + "contributions": [ + "bug" + ] + }, + { + "login": "delanym", + "name": "Delany", + "avatar_url": "https://avatars.githubusercontent.com/u/5310238?v=4", + "profile": "https://github.com/delanym", + "contributions": [ + "bug" + ] + }, + { + "login": "pkozuchowski", + "name": "Piotr Koลผuchowski", + "avatar_url": "https://avatars.githubusercontent.com/u/4470967?v=4", + "profile": "https://github.com/pkozuchowski", + "contributions": [ + "bug" + ] + }, + { + "login": "rubenporras", + "name": "rubenporras", + "avatar_url": "https://avatars.githubusercontent.com/u/43636626?v=4", + "profile": "https://github.com/rubenporras", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 85f771801fc..4ed123a27e8 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -237,938 +237,945 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d David Schach
          David Schach

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– Dawid Ciok
          Dawid Ciok

          ๐Ÿ› ๐Ÿ’ป Debamoy Datta
          Debamoy Datta

          ๐Ÿ’ป - Deleted user
          Deleted user

          ๐Ÿ› + Delany
          Delany

          ๐Ÿ› + Deleted user
          Deleted user

          ๐Ÿ› Dell Green
          Dell Green

          ๐Ÿ› Dem Pilafian
          Dem Pilafian

          ๐Ÿ› Den
          Den

          ๐Ÿ› Denis Borovikov
          Denis Borovikov

          ๐Ÿ’ป ๐Ÿ› Dennie Reniers
          Dennie Reniers

          ๐Ÿ’ป ๐Ÿ› Dennis Kieselhorst
          Dennis Kieselhorst

          ๐Ÿ› - Derek P. Moore
          Derek P. Moore

          ๐Ÿ› + Derek P. Moore
          Derek P. Moore

          ๐Ÿ› Dichotomia
          Dichotomia

          ๐Ÿ› Dionisio Cortรฉs Fernรกndez
          Dionisio Cortรฉs Fernรกndez

          ๐Ÿ’ป ๐Ÿ› Dmitri Bourlatchkov
          Dmitri Bourlatchkov

          ๐Ÿ› Dmitriy Kuzmin
          Dmitriy Kuzmin

          ๐Ÿ› Dmytro Dashenkov
          Dmytro Dashenkov

          ๐Ÿ› Douglas Griffith
          Douglas Griffith

          ๐Ÿ“– - Dr. Christian Kohlschรผtter
          Dr. Christian Kohlschรผtter

          ๐Ÿ› + Dr. Christian Kohlschรผtter
          Dr. Christian Kohlschรผtter

          ๐Ÿ› Drew Hall
          Drew Hall

          ๐Ÿ› Dumitru Postoronca
          Dumitru Postoronca

          ๐Ÿ› Dylan Adams
          Dylan Adams

          ๐Ÿ› Eden Hao
          Eden Hao

          ๐Ÿ› Edward Klimoshenko
          Edward Klimoshenko

          ๐Ÿ› ๐Ÿ’ป Egor Bredikhin
          Egor Bredikhin

          ๐Ÿ› - Elan P. Kugelmass
          Elan P. Kugelmass

          ๐Ÿ› + Elan P. Kugelmass
          Elan P. Kugelmass

          ๐Ÿ› Elder S.
          Elder S.

          ๐Ÿ› Eldrick Wega
          Eldrick Wega

          ๐Ÿ“– Elliotte Rusty Harold
          Elliotte Rusty Harold

          ๐Ÿ’ป Emile
          Emile

          ๐Ÿ› Eric
          Eric

          ๐Ÿ› Eric Kintzer
          Eric Kintzer

          ๐Ÿ› - Eric Perret
          Eric Perret

          ๐Ÿ› + Eric Perret
          Eric Perret

          ๐Ÿ› Eric Squires
          Eric Squires

          ๐Ÿ› Erich L Foster
          Erich L Foster

          ๐Ÿ› Erik Bleske
          Erik Bleske

          ๐Ÿ› Erik C. Thauvin
          Erik C. Thauvin

          ๐Ÿ“– ๐Ÿ› Ernst Reissner
          Ernst Reissner

          ๐Ÿ› Ethan Sargent
          Ethan Sargent

          ๐Ÿ› - Ewan Tempero
          Ewan Tempero

          ๐Ÿ› + Ewan Tempero
          Ewan Tempero

          ๐Ÿ› F.W. Dekker
          F.W. Dekker

          ๐Ÿ› FSchliephacke
          FSchliephacke

          ๐Ÿ› Facundo
          Facundo

          ๐Ÿ› Federico Giust
          Federico Giust

          ๐Ÿ› Fedor Sherstobitov
          Fedor Sherstobitov

          ๐Ÿ› Felix Lampe
          Felix Lampe

          ๐Ÿ› - Filip Golonka
          Filip Golonka

          ๐Ÿ› + Filip Golonka
          Filip Golonka

          ๐Ÿ› Filipe Esperandio
          Filipe Esperandio

          ๐Ÿ’ป ๐Ÿ› Filippo Barbari
          Filippo Barbari

          ๐Ÿ› Filippo Nova
          Filippo Nova

          ๐Ÿ› Francesco la Torre
          Francesco la Torre

          ๐Ÿ› Francisco Duarte
          Francisco Duarte

          ๐Ÿ› Frederick Zhang
          Frederick Zhang

          ๐Ÿ› - Frieder Bluemle
          Frieder Bluemle

          ๐Ÿ› + Frieder Bluemle
          Frieder Bluemle

          ๐Ÿ› Frits Jalvingh
          Frits Jalvingh

          ๐Ÿ’ป ๐Ÿ› G. Bazior
          G. Bazior

          ๐Ÿ› Gabe Henkes
          Gabe Henkes

          ๐Ÿ› Gary Gregory
          Gary Gregory

          ๐Ÿ› Genoud Magloire
          Genoud Magloire

          ๐Ÿ› Geoffrey555
          Geoffrey555

          ๐Ÿ› - Georg Romstorfer
          Georg Romstorfer

          ๐Ÿ› + Georg Romstorfer
          Georg Romstorfer

          ๐Ÿ› Gili Tzabari
          Gili Tzabari

          ๐Ÿ› ๐Ÿ’ป Gio
          Gio

          ๐Ÿ› Gol
          Gol

          ๐Ÿ› Gold856
          Gold856

          ๐Ÿ› ๐Ÿ’ป Gonzalo Exequiel Ibars Ingman
          Gonzalo Exequiel Ibars Ingman

          ๐Ÿ’ป ๐Ÿ› GooDer
          GooDer

          ๐Ÿ› - Gregor Riegler
          Gregor Riegler

          ๐Ÿ› + Gregor Riegler
          Gregor Riegler

          ๐Ÿ› Grzegorz Olszewski
          Grzegorz Olszewski

          ๐Ÿ› Gunther Schrijvers
          Gunther Schrijvers

          ๐Ÿ’ป ๐Ÿ› Gustavo Krieger
          Gustavo Krieger

          ๐Ÿ› Guy Elsmore-Paddock
          Guy Elsmore-Paddock

          ๐Ÿ› Gรถrkem Mรผlayim
          Gรถrkem Mรผlayim

          ๐Ÿ› Hanzel Godinez
          Hanzel Godinez

          ๐Ÿ› - Haoliang Chen
          Haoliang Chen

          ๐Ÿ› + Haoliang Chen
          Haoliang Chen

          ๐Ÿ› Harsh Kukreja
          Harsh Kukreja

          ๐Ÿ› Hassan ALAMI
          Hassan ALAMI

          ๐Ÿ› Heber
          Heber

          ๐Ÿ› Hector Miuler Malpica Gallegos
          Hector Miuler Malpica Gallegos

          ๐Ÿ› Henning Schmiedehausen
          Henning Schmiedehausen

          ๐Ÿ’ป ๐Ÿ› Henning von Bargen
          Henning von Bargen

          ๐Ÿ’ป - Hervรฉ Boutemy
          Hervรฉ Boutemy

          ๐Ÿ› + Hervรฉ Boutemy
          Hervรฉ Boutemy

          ๐Ÿ› Himanshu Pandey
          Himanshu Pandey

          ๐Ÿ› Hokwang Lee
          Hokwang Lee

          ๐Ÿ› Hooperbloob
          Hooperbloob

          ๐Ÿ’ป Hung PHAN
          Hung PHAN

          ๐Ÿ› IDoCodingStuffs
          IDoCodingStuffs

          ๐Ÿ’ป ๐Ÿ› Iccen Gan
          Iccen Gan

          ๐Ÿ› - Ignacio Mariano Tirabasso
          Ignacio Mariano Tirabasso

          ๐Ÿ› + Ignacio Mariano Tirabasso
          Ignacio Mariano Tirabasso

          ๐Ÿ› Igor Melnichenko
          Igor Melnichenko

          ๐Ÿ› Igor Moreno
          Igor Moreno

          ๐Ÿ› Intelesis-MS
          Intelesis-MS

          ๐Ÿ› Iroha_
          Iroha_

          ๐Ÿ› Ishan Srivastava
          Ishan Srivastava

          ๐Ÿ› Iskren Stanislavov
          Iskren Stanislavov

          ๐Ÿ› - Ivan Vakhrushev
          Ivan Vakhrushev

          ๐Ÿ› + Ivan Vakhrushev
          Ivan Vakhrushev

          ๐Ÿ› Ivano Guerini
          Ivano Guerini

          ๐Ÿ› Ivar Andreas Bonsaksen
          Ivar Andreas Bonsaksen

          ๐Ÿ› Ivo ล mรญd
          Ivo ล mรญd

          ๐Ÿ› JJengility
          JJengility

          ๐Ÿ› Jake Hemmerle
          Jake Hemmerle

          ๐Ÿ› Jakub Dupak
          Jakub Dupak

          ๐Ÿ’ป - James Harrison
          James Harrison

          ๐Ÿ› ๐Ÿ’ป + James Harrison
          James Harrison

          ๐Ÿ› ๐Ÿ’ป Jamie Bisotti
          Jamie Bisotti

          ๐Ÿ› Jan
          Jan

          ๐Ÿ› Jan Aertgeerts
          Jan Aertgeerts

          ๐Ÿ’ป ๐Ÿ› Jan Brรผmmer
          Jan Brรผmmer

          ๐Ÿ› Jan Tล™รญska
          Jan Tล™รญska

          ๐Ÿ› Jan-Lukas Else
          Jan-Lukas Else

          ๐Ÿ› - Jason Qiu
          Jason Qiu

          ๐Ÿ’ป ๐Ÿ“– + Jason Qiu
          Jason Qiu

          ๐Ÿ’ป ๐Ÿ“– Jason Williams
          Jason Williams

          ๐Ÿ› Javier Spagnoletti
          Javier Spagnoletti

          ๐Ÿ› Jean-Paul Mayer
          Jean-Paul Mayer

          ๐Ÿ› Jean-Simon Larochelle
          Jean-Simon Larochelle

          ๐Ÿ› Jeff Bartolotta
          Jeff Bartolotta

          ๐Ÿ’ป ๐Ÿ› Jeff Hube
          Jeff Hube

          ๐Ÿ’ป ๐Ÿ› - Jeff Jensen
          Jeff Jensen

          ๐Ÿ› + Jeff Jensen
          Jeff Jensen

          ๐Ÿ› Jeff May
          Jeff May

          ๐Ÿ› Jens Gerdes
          Jens Gerdes

          ๐Ÿ› Jeroen Borgers
          Jeroen Borgers

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข Jeroen Meijer
          Jeroen Meijer

          ๐Ÿ› Jeroen van Wilgenburg
          Jeroen van Wilgenburg

          ๐Ÿ“– Jerome Russ
          Jerome Russ

          ๐Ÿ› - JerritEic
          JerritEic

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› + JerritEic
          JerritEic

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Jiri Pejchal
          Jiri Pejchal

          ๐Ÿ› Jithin Sunny
          Jithin Sunny

          ๐Ÿ› Jiล™รญ ล korpil
          Jiล™รญ ล korpil

          ๐Ÿ› Joao Machado
          Joao Machado

          ๐Ÿ› Jochen Krauss
          Jochen Krauss

          ๐Ÿ› Johan Hammar
          Johan Hammar

          ๐Ÿ› - John Jetmore
          John Jetmore

          ๐Ÿ“– + John Jetmore
          John Jetmore

          ๐Ÿ“– John Karp
          John Karp

          ๐Ÿ› John Zhang
          John Zhang

          ๐Ÿ› John-Teng
          John-Teng

          ๐Ÿ’ป ๐Ÿ› Jon Moroney
          Jon Moroney

          ๐Ÿ’ป ๐Ÿ› Jonas Geiregat
          Jonas Geiregat

          ๐Ÿ› Jonas KeรŸler
          Jonas KeรŸler

          ๐Ÿ› - Jonathan Gillespie
          Jonathan Gillespie

          ๐Ÿ’ต + Jonathan Gillespie
          Jonathan Gillespie

          ๐Ÿ’ต Jonathan Wiesel
          Jonathan Wiesel

          ๐Ÿ’ป ๐Ÿ› Jordan
          Jordan

          ๐Ÿ› + Jordan Alligood
          Jordan Alligood

          ๐Ÿ› Jordi Llach
          Jordi Llach

          ๐Ÿ› Jorge Solรณrzano
          Jorge Solรณrzano

          ๐Ÿ› JorneVL
          JorneVL

          ๐Ÿ› - Jose Palafox
          Jose Palafox

          ๐Ÿ› - Jose Stovall
          Jose Stovall

          ๐Ÿ› + Jose Palafox
          Jose Palafox

          ๐Ÿ› + Jose Stovall
          Jose Stovall

          ๐Ÿ› Joseph
          Joseph

          ๐Ÿ’ป Joseph Heenan
          Joseph Heenan

          ๐Ÿ› Josh Feingold
          Josh Feingold

          ๐Ÿ’ป ๐Ÿ› Josh Holthaus
          Josh Holthaus

          ๐Ÿ› Joshua S Arquilevich
          Joshua S Arquilevich

          ๐Ÿ› - Joรฃo Dinis Ferreira
          Joรฃo Dinis Ferreira

          ๐Ÿ“– - Joรฃo Ferreira
          Joรฃo Ferreira

          ๐Ÿ’ป ๐Ÿ› + Joรฃo Dinis Ferreira
          Joรฃo Dinis Ferreira

          ๐Ÿ“– + Joรฃo Ferreira
          Joรฃo Ferreira

          ๐Ÿ’ป ๐Ÿ› Joรฃo Pedro Schmitt
          Joรฃo Pedro Schmitt

          ๐Ÿ› Juan Martรญn Sotuyo Dodero
          Juan Martรญn Sotuyo Dodero

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง Juan Pablo Civile
          Juan Pablo Civile

          ๐Ÿ› Jude Pereira
          Jude Pereira

          ๐Ÿ’ป Julian Voronetsky
          Julian Voronetsky

          ๐Ÿ› - Julien
          Julien

          ๐Ÿ› - Julius
          Julius

          ๐Ÿ› + Julien
          Julien

          ๐Ÿ› + Julius
          Julius

          ๐Ÿ› JustPRV
          JustPRV

          ๐Ÿ› Justin Stroud
          Justin Stroud

          ๐Ÿ’ป Jรถrn Huxhorn
          Jรถrn Huxhorn

          ๐Ÿ› KThompso
          KThompso

          ๐Ÿ› Kai Amundsen
          Kai Amundsen

          ๐Ÿ› - Karel Vervaeke
          Karel Vervaeke

          ๐Ÿ› - Karl-Andero Mere
          Karl-Andero Mere

          ๐Ÿ› + Karel Vervaeke
          Karel Vervaeke

          ๐Ÿ› + Karl-Andero Mere
          Karl-Andero Mere

          ๐Ÿ› Karl-Philipp Richter
          Karl-Philipp Richter

          ๐Ÿ› Karsten Silz
          Karsten Silz

          ๐Ÿ› Kazuma Watanabe
          Kazuma Watanabe

          ๐Ÿ› Kernevez
          Kernevez

          ๐Ÿ› Kev
          Kev

          ๐Ÿ› - Keve Mรผller
          Keve Mรผller

          ๐Ÿ› - Kevin Guerra
          Kevin Guerra

          ๐Ÿ’ป + Keve Mรผller
          Keve Mรผller

          ๐Ÿ› + Kevin Guerra
          Kevin Guerra

          ๐Ÿ’ป Kevin Jones
          Kevin Jones

          ๐Ÿ› ๐Ÿ’ป Kevin Poorman
          Kevin Poorman

          ๐Ÿ› Kevin Wayne
          Kevin Wayne

          ๐Ÿ› Kieran Black
          Kieran Black

          ๐Ÿ› Kirill Zubov
          Kirill Zubov

          ๐Ÿ› - Kirk Clemens
          Kirk Clemens

          ๐Ÿ’ป ๐Ÿ› - Klaus Hartl
          Klaus Hartl

          ๐Ÿ› + Kirk Clemens
          Kirk Clemens

          ๐Ÿ’ป ๐Ÿ› + Klaus Hartl
          Klaus Hartl

          ๐Ÿ› Koen Van Looveren
          Koen Van Looveren

          ๐Ÿ› Kris Scheibe
          Kris Scheibe

          ๐Ÿ’ป ๐Ÿ› Krystian Dabrowski
          Krystian Dabrowski

          ๐Ÿ› ๐Ÿ’ป Krzysztof Dymek
          Krzysztof Dymek

          ๐Ÿ› Kunal Thanki
          Kunal Thanki

          ๐Ÿ› - Kursat Aktas
          Kursat Aktas

          ๐Ÿ“– - LaLucid
          LaLucid

          ๐Ÿ’ป + Kursat Aktas
          Kursat Aktas

          ๐Ÿ“– + LaLucid
          LaLucid

          ๐Ÿ’ป Larry Diamond
          Larry Diamond

          ๐Ÿ’ป ๐Ÿ› Lars Knickrehm
          Lars Knickrehm

          ๐Ÿ› Laurent Bovet
          Laurent Bovet

          ๐Ÿ› ๐Ÿ’ป Leo Gutierrez
          Leo Gutierrez

          ๐Ÿ› LiGaOg
          LiGaOg

          ๐Ÿ’ป - Liam Sharp
          Liam Sharp

          ๐Ÿ› - Lintsi
          Lintsi

          ๐Ÿ› + Liam Sharp
          Liam Sharp

          ๐Ÿ› + Lintsi
          Lintsi

          ๐Ÿ› Linus Fernandes
          Linus Fernandes

          ๐Ÿ› Lixon Lookose
          Lixon Lookose

          ๐Ÿ› Logesh
          Logesh

          ๐Ÿ› Lorenzo Gabriele
          Lorenzo Gabriele

          ๐Ÿ› Loรฏc Ledoyen
          Loรฏc Ledoyen

          ๐Ÿ› - Lucas
          Lucas

          ๐Ÿ› - Lucas Silva
          Lucas Silva

          ๐Ÿ› + Lucas
          Lucas

          ๐Ÿ› + Lucas Silva
          Lucas Silva

          ๐Ÿ› Lucas Soncini
          Lucas Soncini

          ๐Ÿ’ป ๐Ÿ› Luis Alcantar
          Luis Alcantar

          ๐Ÿ’ป Lukas Grรคf
          Lukas Grรคf

          ๐Ÿ’ป Lukasz Slonina
          Lukasz Slonina

          ๐Ÿ› Lukebray
          Lukebray

          ๐Ÿ› - Lynn
          Lynn

          ๐Ÿ’ป ๐Ÿ› - Lyor Goldstein
          Lyor Goldstein

          ๐Ÿ› + Lynn
          Lynn

          ๐Ÿ’ป ๐Ÿ› + Lyor Goldstein
          Lyor Goldstein

          ๐Ÿ› MCMicS
          MCMicS

          ๐Ÿ› Macarse
          Macarse

          ๐Ÿ› Machine account for PMD
          Machine account for PMD

          ๐Ÿ’ป Maciek Siemczyk
          Maciek Siemczyk

          ๐Ÿ› Maikel Steneker
          Maikel Steneker

          ๐Ÿ’ป ๐Ÿ› - Maksim Moiseikin
          Maksim Moiseikin

          ๐Ÿ› - Malik
          Malik

          ๐Ÿ› + Maksim Moiseikin
          Maksim Moiseikin

          ๐Ÿ› + Malik
          Malik

          ๐Ÿ› Manfred Koch
          Manfred Koch

          ๐Ÿ› Manuel Moya Ferrer
          Manuel Moya Ferrer

          ๐Ÿ’ป ๐Ÿ› Manuel Romeiro
          Manuel Romeiro

          ๐Ÿ› Manuel Ryan
          Manuel Ryan

          ๐Ÿ› Marat Vyshegorodtsev
          Marat Vyshegorodtsev

          ๐Ÿ› - Marcel Hรคrle
          Marcel Hรคrle

          ๐Ÿ› - Marcello Fialho
          Marcello Fialho

          ๐Ÿ› + Marcel Hรคrle
          Marcel Hรคrle

          ๐Ÿ› + Marcello Fialho
          Marcello Fialho

          ๐Ÿ› Marcin Dฤ…browski
          Marcin Dฤ…browski

          ๐Ÿ’ป ๐Ÿ› Marcin Rataj
          Marcin Rataj

          ๐Ÿ› Marcono1234
          Marcono1234

          ๐Ÿ› Mark Adamcin
          Mark Adamcin

          ๐Ÿ› Mark Hall
          Mark Hall

          ๐Ÿ’ป ๐Ÿ› - Mark Kolich
          Mark Kolich

          ๐Ÿ› - Mark Pritchard
          Mark Pritchard

          ๐Ÿ› + Mark Kolich
          Mark Kolich

          ๐Ÿ› + Mark Pritchard
          Mark Pritchard

          ๐Ÿ› Markus Rathgeb
          Markus Rathgeb

          ๐Ÿ› Marquis Wang
          Marquis Wang

          ๐Ÿ› MartGit
          MartGit

          ๐Ÿ› Martin Feldsztejn
          Martin Feldsztejn

          ๐Ÿ› Martin Lehmann
          Martin Lehmann

          ๐Ÿ› - Martin Spamer
          Martin Spamer

          ๐Ÿ› - Martin Tarjรกnyi
          Martin Tarjรกnyi

          ๐Ÿ› + Martin Spamer
          Martin Spamer

          ๐Ÿ› + Martin Tarjรกnyi
          Martin Tarjรกnyi

          ๐Ÿ› MatFl
          MatFl

          ๐Ÿ› Mateusz Stefanski
          Mateusz Stefanski

          ๐Ÿ› Mathias Lagerwall
          Mathias Lagerwall

          ๐Ÿ› Mathieu Gouin
          Mathieu Gouin

          ๐Ÿ› MatiasComercio
          MatiasComercio

          ๐Ÿ’ป ๐Ÿ› - Matt Benson
          Matt Benson

          ๐Ÿ› - Matt De Poorter
          Matt De Poorter

          ๐Ÿ› + Matt Benson
          Matt Benson

          ๐Ÿ› + Matt De Poorter
          Matt De Poorter

          ๐Ÿ› Matt Hargett
          Matt Hargett

          ๐Ÿ’ป ๐Ÿ’ต Matt Harrah
          Matt Harrah

          ๐Ÿ› Matt Nelson
          Matt Nelson

          ๐Ÿ› Matthew Amos
          Matthew Amos

          ๐Ÿ› Matthew Duggan
          Matthew Duggan

          ๐Ÿ› - Matthew Hall
          Matthew Hall

          ๐Ÿ› - Matthew Rossner
          Matthew Rossner

          ๐Ÿ› + Matthew Hall
          Matthew Hall

          ๐Ÿ› + Matthew Rossner
          Matthew Rossner

          ๐Ÿ› Matรญas Fraga
          Matรญas Fraga

          ๐Ÿ’ป ๐Ÿ› Maxime Robert
          Maxime Robert

          ๐Ÿ’ป ๐Ÿ› MetaBF
          MetaBF

          ๐Ÿ› Metin Dagcilar
          Metin Dagcilar

          ๐Ÿ› Michael
          Michael

          ๐Ÿ› - Michael Bell
          Michael Bell

          ๐Ÿ› - Michael Bernstein
          Michael Bernstein

          ๐Ÿ› + Michael Bell
          Michael Bell

          ๐Ÿ› + Michael Bernstein
          Michael Bernstein

          ๐Ÿ› Michael Clay
          Michael Clay

          ๐Ÿ› Michael Dombrowski
          Michael Dombrowski

          ๐Ÿ› Michael Hausegger
          Michael Hausegger

          ๐Ÿ› Michael Hoefer
          Michael Hoefer

          ๐Ÿ› Michael Kolesnikov
          Michael Kolesnikov

          ๐Ÿ› - Michael Mรถbius
          Michael Mรถbius

          ๐Ÿ› - Michael N. Lipp
          Michael N. Lipp

          ๐Ÿ› + Michael Mรถbius
          Michael Mรถbius

          ๐Ÿ› + Michael N. Lipp
          Michael N. Lipp

          ๐Ÿ› Michael Pellegrini
          Michael Pellegrini

          ๐Ÿ› Michal Kordas
          Michal Kordas

          ๐Ÿ› Michaล‚ Borek
          Michaล‚ Borek

          ๐Ÿ› Michaล‚ Kuliล„ski
          Michaล‚ Kuliล„ski

          ๐Ÿ› Miguel Nรบรฑez Dรญaz-Montes
          Miguel Nรบรฑez Dรญaz-Montes

          ๐Ÿ› - Mihai Ionut
          Mihai Ionut

          ๐Ÿ› - Mikhail Kuchma
          Mikhail Kuchma

          ๐Ÿ› + Mihai Ionut
          Mihai Ionut

          ๐Ÿ› + Mikhail Kuchma
          Mikhail Kuchma

          ๐Ÿ› MiladSadinam
          MiladSadinam

          ๐Ÿ› Mirek Hankus
          Mirek Hankus

          ๐Ÿ› Mitch Spano
          Mitch Spano

          ๐Ÿ’ป ๐Ÿ› Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ› Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ› - MrAngry52
          MrAngry52

          ๐Ÿ› - Muminur Choudhury
          Muminur Choudhury

          ๐Ÿ› + MrAngry52
          MrAngry52

          ๐Ÿ› + Muminur Choudhury
          Muminur Choudhury

          ๐Ÿ› Mykhailo Palahuta
          Mykhailo Palahuta

          ๐Ÿ’ป ๐Ÿ› Nagendra Kumar Singh
          Nagendra Kumar Singh

          ๐Ÿ› Nahuel Barrios
          Nahuel Barrios

          ๐Ÿ› Nakul Sharma
          Nakul Sharma

          ๐Ÿ› Nathan Braun
          Nathan Braun

          ๐Ÿ› - Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ› - Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ› + Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ› + Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ› Nathanaรซl
          Nathanaรซl

          ๐Ÿ› Naveen
          Naveen

          ๐Ÿ’ป Nazdravi
          Nazdravi

          ๐Ÿ› Neha-Dhonde
          Neha-Dhonde

          ๐Ÿ› Nicholas Doyle
          Nicholas Doyle

          ๐Ÿ› - Nick Butcher
          Nick Butcher

          ๐Ÿ› - Nico Gallinal
          Nico Gallinal

          ๐Ÿ› + Nick Butcher
          Nick Butcher

          ๐Ÿ› + Nico Gallinal
          Nico Gallinal

          ๐Ÿ› Nicola Dal Maso
          Nicola Dal Maso

          ๐Ÿ› Nicolas Filotto
          Nicolas Filotto

          ๐Ÿ’ป Nicolas Vervelle
          Nicolas Vervelle

          ๐Ÿ› Nicolas Vuillamy
          Nicolas Vuillamy

          ๐Ÿ“– Nikita Chursin
          Nikita Chursin

          ๐Ÿ› - Niklas Baudy
          Niklas Baudy

          ๐Ÿ› - Nikolas Havrikov
          Nikolas Havrikov

          ๐Ÿ› + Niklas Baudy
          Niklas Baudy

          ๐Ÿ› + Nikolas Havrikov
          Nikolas Havrikov

          ๐Ÿ› Nilesh Virkar
          Nilesh Virkar

          ๐Ÿ› Nimit Patel
          Nimit Patel

          ๐Ÿ› Niranjan Harpale
          Niranjan Harpale

          ๐Ÿ› Nirvik Patel
          Nirvik Patel

          ๐Ÿ’ป Noah Sussman
          Noah Sussman

          ๐Ÿ› - Noah0120
          Noah0120

          ๐Ÿ› - Noam Tamim
          Noam Tamim

          ๐Ÿ› + Noah0120
          Noah0120

          ๐Ÿ› + Noam Tamim
          Noam Tamim

          ๐Ÿ› Noel Grandin
          Noel Grandin

          ๐Ÿ› Olaf Haalstra
          Olaf Haalstra

          ๐Ÿ› Oleg Andreych
          Oleg Andreych

          ๐Ÿ’ป ๐Ÿ› Oleg Pavlenko
          Oleg Pavlenko

          ๐Ÿ› Oleksii Dykov
          Oleksii Dykov

          ๐Ÿ’ป ๐Ÿ› - Oliver Eikemeier
          Oliver Eikemeier

          ๐Ÿ› - Oliver Siegmar
          Oliver Siegmar

          ๐Ÿ’ต + Oliver Eikemeier
          Oliver Eikemeier

          ๐Ÿ› + Oliver Siegmar
          Oliver Siegmar

          ๐Ÿ’ต Olivier Parent
          Olivier Parent

          ๐Ÿ’ป ๐Ÿ› Ollie Abbey
          Ollie Abbey

          ๐Ÿ’ป ๐Ÿ› Olof-Joachim Frahm (ๆฌง้›…็ฆ)
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)

          ๐Ÿ› Ondrej Kratochvil
          Ondrej Kratochvil

          ๐Ÿ› OverDrone
          OverDrone

          ๐Ÿ› - Ozan Gulle
          Ozan Gulle

          ๐Ÿ’ป ๐Ÿ› - PUNEET JAIN
          PUNEET JAIN

          ๐Ÿ› + Ozan Gulle
          Ozan Gulle

          ๐Ÿ’ป ๐Ÿ› + PUNEET JAIN
          PUNEET JAIN

          ๐Ÿ› Pankraz76
          Pankraz76

          ๐Ÿ’ป ๐Ÿ› Parbati Bose
          Parbati Bose

          ๐Ÿ› Paul Berg
          Paul Berg

          ๐Ÿ› Paul Guyot
          Paul Guyot

          ๐Ÿ’ป Pavel Bludov
          Pavel Bludov

          ๐Ÿ› - Pavel Miฤka
          Pavel Miฤka

          ๐Ÿ› - Pedro Nuno Santos
          Pedro Nuno Santos

          ๐Ÿ› + Pavel Miฤka
          Pavel Miฤka

          ๐Ÿ› + Pedro Nuno Santos
          Pedro Nuno Santos

          ๐Ÿ› Pedro Rijo
          Pedro Rijo

          ๐Ÿ› Pelisse Romain
          Pelisse Romain

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Per Abich
          Per Abich

          ๐Ÿ’ป Pete Davids
          Pete Davids

          ๐Ÿ› Peter Bruin
          Peter Bruin

          ๐Ÿ› - Peter Chittum
          Peter Chittum

          ๐Ÿ’ป ๐Ÿ› - Peter Cudmore
          Peter Cudmore

          ๐Ÿ› + Peter Chittum
          Peter Chittum

          ๐Ÿ’ป ๐Ÿ› + Peter Cudmore
          Peter Cudmore

          ๐Ÿ› Peter Kasson
          Peter Kasson

          ๐Ÿ› Peter Kofler
          Peter Kofler

          ๐Ÿ› Peter Paul Bakker
          Peter Paul Bakker

          ๐Ÿ’ป ๐Ÿ› Peter Rader
          Peter Rader

          ๐Ÿ› Pham Hai Trung
          Pham Hai Trung

          ๐Ÿ› - Philip Graf
          Philip Graf

          ๐Ÿ’ป ๐Ÿ› - Philip Hachey
          Philip Hachey

          ๐Ÿ› + Philip Graf
          Philip Graf

          ๐Ÿ’ป ๐Ÿ› + Philip Hachey
          Philip Hachey

          ๐Ÿ› Philippe Ozil
          Philippe Ozil

          ๐Ÿ› Phinehas Artemix
          Phinehas Artemix

          ๐Ÿ› Phokham Nonava
          Phokham Nonava

          ๐Ÿ› Pim van der Loos
          Pim van der Loos

          ๐Ÿ’ป โš ๏ธ + Piotr Koลผuchowski
          Piotr Koลผuchowski

          ๐Ÿ› + + Piotr Szymaล„ski
          Piotr Szymaล„ski

          ๐Ÿ› Piotrek ลปygieล‚o
          Piotrek ลปygieล‚o

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– Pranay Jaiswal
          Pranay Jaiswal

          ๐Ÿ› - - Prasad Kamath
          Prasad Kamath

          ๐Ÿ› Prasanna
          Prasanna

          ๐Ÿ› Presh-AR
          Presh-AR

          ๐Ÿ› Puneet1726
          Puneet1726

          ๐Ÿ› + + RBRi
          RBRi

          ๐Ÿ› Rafael Cortรชs
          Rafael Cortรชs

          ๐Ÿ› RaheemShaik999
          RaheemShaik999

          ๐Ÿ› - - RajeshR
          RajeshR

          ๐Ÿ’ป ๐Ÿ› Ramachandra Mohan
          Ramachandra Mohan

          ๐Ÿ› Ramel0921
          Ramel0921

          ๐Ÿ› Raquel Pau
          Raquel Pau

          ๐Ÿ› + + Ravikiran Janardhana
          Ravikiran Janardhana

          ๐Ÿ› Reda Benhemmouche
          Reda Benhemmouche

          ๐Ÿ› Reinhard Schiedermeier
          Reinhard Schiedermeier

          ๐Ÿ› - - Renato Oliveira
          Renato Oliveira

          ๐Ÿ’ป ๐Ÿ› Rich DiCroce
          Rich DiCroce

          ๐Ÿ› Richard Corfield
          Richard Corfield

          ๐Ÿ’ป Richard Corfield
          Richard Corfield

          ๐Ÿ› ๐Ÿ’ป + + Riot R1cket
          Riot R1cket

          ๐Ÿ› Rishabh Jain
          Rishabh Jain

          ๐Ÿ› RishabhDeep Singh
          RishabhDeep Singh

          ๐Ÿ› - - Rob Baillie
          Rob Baillie

          ๐Ÿ› Robbie Martinus
          Robbie Martinus

          ๐Ÿ’ป ๐Ÿ› Robert Henry
          Robert Henry

          ๐Ÿ› Robert Mihaly
          Robert Mihaly

          ๐Ÿ› + + Robert Painsi
          Robert Painsi

          ๐Ÿ› Robert Russell
          Robert Russell

          ๐Ÿ› Robert Sรถsemann
          Robert Sรถsemann

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ› - - Robert Whitebit
          Robert Whitebit

          ๐Ÿ› Robin Richtsfeld
          Robin Richtsfeld

          ๐Ÿ› Robin Stocker
          Robin Stocker

          ๐Ÿ’ป ๐Ÿ› Robin Wils
          Robin Wils

          ๐Ÿ› + + RochusOest
          RochusOest

          ๐Ÿ› Rodolfo Noviski
          Rodolfo Noviski

          ๐Ÿ› Rodrigo Casara
          Rodrigo Casara

          ๐Ÿ› - - Rodrigo Fernandes
          Rodrigo Fernandes

          ๐Ÿ› Roman Salvador
          Roman Salvador

          ๐Ÿ’ป ๐Ÿ› Ronald Blaschke
          Ronald Blaschke

          ๐Ÿ› Rรณbert Papp
          Rรณbert Papp

          ๐Ÿ› + + Saikat Sengupta
          Saikat Sengupta

          ๐Ÿ› Saksham Handu
          Saksham Handu

          ๐Ÿ› Saladoc
          Saladoc

          ๐Ÿ› - - Salesforce Bob Lightning
          Salesforce Bob Lightning

          ๐Ÿ› Sam Carlberg
          Sam Carlberg

          ๐Ÿ› Sascha Riemer
          Sascha Riemer

          ๐Ÿ› Sashko
          Sashko

          ๐Ÿ’ป + + Satoshi Kubo
          Satoshi Kubo

          ๐Ÿ› Scott Kennedy
          Scott Kennedy

          ๐Ÿ› Scott Wells
          Scott Wells

          ๐Ÿ› ๐Ÿ’ป - - Scrates1
          Scrates1

          ๐Ÿ› ๐Ÿ’ป Scrsloota
          Scrsloota

          ๐Ÿ’ป Sebastian Bรถgl
          Sebastian Bรถgl

          ๐Ÿ› Sebastian Davids
          Sebastian Davids

          ๐Ÿ› + + Sebastian Lรถvdahl
          Sebastian Lรถvdahl

          ๐Ÿ› Sebastian Schuberth
          Sebastian Schuberth

          ๐Ÿ› Sebastian Schwarz
          Sebastian Schwarz

          ๐Ÿ› - - Seren
          Seren

          ๐Ÿ› ๐Ÿ’ป Sergey Gorbaty
          Sergey Gorbaty

          ๐Ÿ› Sergey Kozlov
          Sergey Kozlov

          ๐Ÿ› Sergey Yanzin
          Sergey Yanzin

          ๐Ÿ’ป ๐Ÿ› + + Seth Wilcox
          Seth Wilcox

          ๐Ÿ’ป Shai Bennathan
          Shai Bennathan

          ๐Ÿ› ๐Ÿ’ป Shubham
          Shubham

          ๐Ÿ’ป ๐Ÿ› - - Simon Abykov
          Simon Abykov

          ๐Ÿ’ป ๐Ÿ› Simon Xiao
          Simon Xiao

          ๐Ÿ› Srinivasan Venkatachalam
          Srinivasan Venkatachalam

          ๐Ÿ› Stanislav Gromov
          Stanislav Gromov

          ๐Ÿ› + + Stanislav Myachenkov
          Stanislav Myachenkov

          ๐Ÿ’ป Stefan Birkner
          Stefan Birkner

          ๐Ÿ› Stefan Bohn
          Stefan Bohn

          ๐Ÿ› - - Stefan Endrullis
          Stefan Endrullis

          ๐Ÿ› Stefan Klรถss-Schuster
          Stefan Klรถss-Schuster

          ๐Ÿ› Stefan Wolf
          Stefan Wolf

          ๐Ÿ› Stephan H. Wissel
          Stephan H. Wissel

          ๐Ÿ› + + Stephen
          Stephen

          ๐Ÿ› Stephen Carter
          Stephen Carter

          ๐Ÿ› Stephen Friedrich
          Stephen Friedrich

          ๐Ÿ› - - Steve Babula
          Steve Babula

          ๐Ÿ’ป Steve White
          Steve White

          ๐Ÿ› Steven Schlansker
          Steven Schlansker

          ๐Ÿ› Steven Stearns
          Steven Stearns

          ๐Ÿ› ๐Ÿ’ป + + Stexxe
          Stexxe

          ๐Ÿ› Stian Lรฅgstad
          Stian Lรฅgstad

          ๐Ÿ› StuartClayton5
          StuartClayton5

          ๐Ÿ› - - Supun Arunoda
          Supun Arunoda

          ๐Ÿ› Suren Abrahamyan
          Suren Abrahamyan

          ๐Ÿ› Suvashri
          Suvashri

          ๐Ÿ“– Sven Barden
          Sven Barden

          ๐Ÿ› + + SwatiBGupta1110
          SwatiBGupta1110

          ๐Ÿ› SyedThoufich
          SyedThoufich

          ๐Ÿ› Szymon Sasin
          Szymon Sasin

          ๐Ÿ› - - T-chuangxin
          T-chuangxin

          ๐Ÿ› TERAI Atsuhiro
          TERAI Atsuhiro

          ๐Ÿ› TIOBE Software
          TIOBE Software

          ๐Ÿ’ป ๐Ÿ› Tarush Singh
          Tarush Singh

          ๐Ÿ’ป + + Taylor Smock
          Taylor Smock

          ๐Ÿ› Techeira Damiรกn
          Techeira Damiรกn

          ๐Ÿ’ป ๐Ÿ› Ted Husted
          Ted Husted

          ๐Ÿ› - - TehBakker
          TehBakker

          ๐Ÿ› The Gitter Badger
          The Gitter Badger

          ๐Ÿ› Theodoor
          Theodoor

          ๐Ÿ› Thiago Henrique Hรผpner
          Thiago Henrique Hรผpner

          ๐Ÿ› + + Thibault Meyer
          Thibault Meyer

          ๐Ÿ› Thomas Gรผttler
          Thomas Gรผttler

          ๐Ÿ› Thomas Jones-Low
          Thomas Jones-Low

          ๐Ÿ› - - Thomas Smith
          Thomas Smith

          ๐Ÿ’ป ๐Ÿ› ThrawnCA
          ThrawnCA

          ๐Ÿ› Thu Vo
          Thu Vo

          ๐Ÿ› Thunderforge
          Thunderforge

          ๐Ÿ’ป ๐Ÿ› + + Tim van der Lippe
          Tim van der Lippe

          ๐Ÿ› Tobias Weimer
          Tobias Weimer

          ๐Ÿ’ป ๐Ÿ› Tom Copeland
          Tom Copeland

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– - - Tom Daly
          Tom Daly

          ๐Ÿ› Tomas
          Tomas

          ๐Ÿ› Tomer Figenblat
          Tomer Figenblat

          ๐Ÿ› Tomi De Lucca
          Tomi De Lucca

          ๐Ÿ’ป ๐Ÿ› + + Tony
          Tony

          ๐Ÿ“– Torsten Kleiber
          Torsten Kleiber

          ๐Ÿ› Torsten Krause
          Torsten Krause

          ๐Ÿ› - - TrackerSB
          TrackerSB

          ๐Ÿ› Tyson Stewart
          Tyson Stewart

          ๐Ÿ› Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ› UncleOwen
          UncleOwen

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– + + Utku Cuhadaroglu
          Utku Cuhadaroglu

          ๐Ÿ’ป ๐Ÿ› Valentin Brandl
          Valentin Brandl

          ๐Ÿ› Valeria
          Valeria

          ๐Ÿ› - - Valery Yatsynovich
          Valery Yatsynovich

          ๐Ÿ“– Vasily Anisimov
          Vasily Anisimov

          ๐Ÿ› Vedant Chokshi
          Vedant Chokshi

          ๐Ÿ› Vibhor Goyal
          Vibhor Goyal

          ๐Ÿ› + + Vickenty Fesunov
          Vickenty Fesunov

          ๐Ÿ› Victor Noรซl
          Victor Noรซl

          ๐Ÿ› Vincent Galloy
          Vincent Galloy

          ๐Ÿ’ป - - Vincent HUYNH
          Vincent HUYNH

          ๐Ÿ› Vincent Maurin
          Vincent Maurin

          ๐Ÿ› Vincent Potucek
          Vincent Potucek

          ๐Ÿ’ป Vincent Privat
          Vincent Privat

          ๐Ÿ› + + Vincent Zorge
          Vincent Zorge

          ๐Ÿ› Vishhwas
          Vishhwas

          ๐Ÿ› Vishv_Android
          Vishv_Android

          ๐Ÿ› - - Vitalii Yevtushenko
          Vitalii Yevtushenko

          ๐Ÿ› Vitaly
          Vitaly

          ๐Ÿ› Vitaly Polonetsky
          Vitaly Polonetsky

          ๐Ÿ› Vojtech Polivka
          Vojtech Polivka

          ๐Ÿ› + + Vsevolod Zholobov
          Vsevolod Zholobov

          ๐Ÿ› Vyom Yadav
          Vyom Yadav

          ๐Ÿ’ป Wang Shidong
          Wang Shidong

          ๐Ÿ› - - Waqas Ahmed
          Waqas Ahmed

          ๐Ÿ› Wayne J. Earl
          Wayne J. Earl

          ๐Ÿ› Wchenghui
          Wchenghui

          ๐Ÿ› Wener
          Wener

          ๐Ÿ’ป + + Will Winder
          Will Winder

          ๐Ÿ› Willem A. Hajenius
          Willem A. Hajenius

          ๐Ÿ’ป William Brockhus
          William Brockhus

          ๐Ÿ’ป ๐Ÿ› - - Wilson Kurniawan
          Wilson Kurniawan

          ๐Ÿ› Wim Deblauwe
          Wim Deblauwe

          ๐Ÿ› Wolf2323
          Wolf2323

          ๐Ÿ› Woongsik Choi
          Woongsik Choi

          ๐Ÿ› + + XenoAmess
          XenoAmess

          ๐Ÿ’ป ๐Ÿ› Yang
          Yang

          ๐Ÿ’ป YaroslavTER
          YaroslavTER

          ๐Ÿ› - - Yasar Shaikh
          Yasar Shaikh

          ๐Ÿ’ป Young Chan
          Young Chan

          ๐Ÿ’ป ๐Ÿ› YuJin Kim
          YuJin Kim

          ๐Ÿ› Yuri Dolzhenko
          Yuri Dolzhenko

          ๐Ÿ› + + Yurii Dubinka
          Yurii Dubinka

          ๐Ÿ› Zbynek Konecny
          Zbynek Konecny

          ๐Ÿ› ๐Ÿ’ป Zoltan Farkas
          Zoltan Farkas

          ๐Ÿ› - - Zustin
          Zustin

          ๐Ÿ› aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป alexmodis
          alexmodis

          ๐Ÿ› andreoss
          andreoss

          ๐Ÿ› + + andrey81inmd
          andrey81inmd

          ๐Ÿ’ป ๐Ÿ› anicoara
          anicoara

          ๐Ÿ› arunprasathav
          arunprasathav

          ๐Ÿ› - - asiercamara
          asiercamara

          ๐Ÿ› astillich-igniti
          astillich-igniti

          ๐Ÿ’ป avesolovksyy
          avesolovksyy

          ๐Ÿ› avishvat
          avishvat

          ๐Ÿ› + + avivmu
          avivmu

          ๐Ÿ› axelbarfod1
          axelbarfod1

          ๐Ÿ› b-3-n
          b-3-n

          ๐Ÿ› - - balbhadra9
          balbhadra9

          ๐Ÿ› base23de
          base23de

          ๐Ÿ› bergander
          bergander

          ๐Ÿ› ๐Ÿ’ป berkam
          berkam

          ๐Ÿ’ป ๐Ÿ› + + + bmeier-pros
          bmeier-pros

          ๐Ÿ› breizh31
          breizh31

          ๐Ÿ› caesarkim
          caesarkim

          ๐Ÿ› caiocarvalhotero
          caiocarvalhotero

          ๐Ÿ› - - carolyujing
          carolyujing

          ๐Ÿ› cbfiddle
          cbfiddle

          ๐Ÿ› cesares-basilico
          cesares-basilico

          ๐Ÿ› + + chrite
          chrite

          ๐Ÿ› ciufudean
          ciufudean

          ๐Ÿ“– cobratbq
          cobratbq

          ๐Ÿ› coladict
          coladict

          ๐Ÿ› - - cosmoJFH
          cosmoJFH

          ๐Ÿ› cristalp
          cristalp

          ๐Ÿ› crunsk
          crunsk

          ๐Ÿ› + + csrma
          csrma

          ๐Ÿ› cwholmes
          cwholmes

          ๐Ÿ› cyberjj999
          cyberjj999

          ๐Ÿ› cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“– - - d1ss0nanz
          d1ss0nanz

          ๐Ÿ› dague1
          dague1

          ๐Ÿ“– dalizi007
          dalizi007

          ๐Ÿ’ป + + danbrycefairsailcom
          danbrycefairsailcom

          ๐Ÿ› dariansanity
          dariansanity

          ๐Ÿ› darrenmiliband
          darrenmiliband

          ๐Ÿ› davidburstrom
          davidburstrom

          ๐Ÿ› - - dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ› deepak-patra
          deepak-patra

          ๐Ÿ› dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ› + + dinesh150
          dinesh150

          ๐Ÿ› diziaq
          diziaq

          ๐Ÿ› dreaminpast123
          dreaminpast123

          ๐Ÿ› duanyanan
          duanyanan

          ๐Ÿ› - - dutt-sanjay
          dutt-sanjay

          ๐Ÿ› duursma
          duursma

          ๐Ÿ’ป dylanleung
          dylanleung

          ๐Ÿ› + + dzeigler
          dzeigler

          ๐Ÿ› eant60
          eant60

          ๐Ÿ› ekkirala
          ekkirala

          ๐Ÿ› emersonmoura
          emersonmoura

          ๐Ÿ› - - emouty
          emouty

          ๐Ÿ’ป ๐Ÿ› eugenepugach
          eugenepugach

          ๐Ÿ› fairy
          fairy

          ๐Ÿ› + + filiprafalowicz
          filiprafalowicz

          ๐Ÿ’ป flxbl-io
          flxbl-io

          ๐Ÿ’ต foxmason
          foxmason

          ๐Ÿ› frankegabor
          frankegabor

          ๐Ÿ› - - frankl
          frankl

          ๐Ÿ› freafrea
          freafrea

          ๐Ÿ› fsapatin
          fsapatin

          ๐Ÿ› + + gearsethenry
          gearsethenry

          ๐Ÿ› gracia19
          gracia19

          ๐Ÿ› gudzpoz
          gudzpoz

          ๐Ÿ› guo fei
          guo fei

          ๐Ÿ› - - gurmsc5
          gurmsc5

          ๐Ÿ› gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ› haigsn
          haigsn

          ๐Ÿ› + + hemanshu070
          hemanshu070

          ๐Ÿ› henrik242
          henrik242

          ๐Ÿ› hongpuwu
          hongpuwu

          ๐Ÿ› hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ› - - igniti GmbH
          igniti GmbH

          ๐Ÿ› ilovezfs
          ilovezfs

          ๐Ÿ› imax-erik
          imax-erik

          ๐Ÿ› + + itaigilo
          itaigilo

          ๐Ÿ› jakivey32
          jakivey32

          ๐Ÿ› jbennett2091
          jbennett2091

          ๐Ÿ› jcamerin
          jcamerin

          ๐Ÿ› - - jkeener1
          jkeener1

          ๐Ÿ› jmetertea
          jmetertea

          ๐Ÿ› johnra2
          johnra2

          ๐Ÿ’ป + + johnzhao9
          johnzhao9

          ๐Ÿ› josemanuelrolon
          josemanuelrolon

          ๐Ÿ’ป ๐Ÿ› julees7
          julees7

          ๐Ÿ’ป ๐Ÿ› kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ› - - karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“– karwer
          karwer

          ๐Ÿ› kaulonline
          kaulonline

          ๐Ÿ› + + kdaemonv
          kdaemonv

          ๐Ÿ› kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ› kfranic
          kfranic

          ๐Ÿ› - - khalidkh
          khalidkh

          ๐Ÿ› koalalam
          koalalam

          ๐Ÿ› krzyk
          krzyk

          ๐Ÿ› + + lasselindqvist
          lasselindqvist

          ๐Ÿ› lgemeinhardt
          lgemeinhardt

          ๐Ÿ› lihuaib
          lihuaib

          ๐Ÿ› liqingjun123
          liqingjun123

          ๐Ÿ› - - lonelyma1021
          lonelyma1021

          ๐Ÿ› lothas
          lothas

          ๐Ÿ› lpeddy
          lpeddy

          ๐Ÿ› + + lujiefsi
          lujiefsi

          ๐Ÿ’ป lukelukes
          lukelukes

          ๐Ÿ’ป lyriccoder
          lyriccoder

          ๐Ÿ› marcelmore
          marcelmore

          ๐Ÿ› - - matchbox
          matchbox

          ๐Ÿ› matthiaskraaz
          matthiaskraaz

          ๐Ÿ› meandonlyme
          meandonlyme

          ๐Ÿ› + + mikesive
          mikesive

          ๐Ÿ› milossesic
          milossesic

          ๐Ÿ› mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป - - mrclmh
          mrclmh

          ๐Ÿ› mriddell95
          mriddell95

          ๐Ÿ› mrlzh
          mrlzh

          ๐Ÿ› + + msloan
          msloan

          ๐Ÿ› mucharlaravalika
          mucharlaravalika

          ๐Ÿ› mvenneman
          mvenneman

          ๐Ÿ› nareshl119
          nareshl119

          ๐Ÿ› - - nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ› noerremark
          noerremark

          ๐Ÿ› novsirion
          novsirion

          ๐Ÿ› + + nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
          oggboy

          ๐Ÿ› oinume
          oinume

          ๐Ÿ› orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ› - - pablogomez2197
          pablogomez2197

          ๐Ÿ› pacvz
          pacvz

          ๐Ÿ’ป pallavi agarwal
          pallavi agarwal

          ๐Ÿ› + + pankratz76
          pankratz76

          ๐Ÿ› parksungrin
          parksungrin

          ๐Ÿ› patpatpat123
          patpatpat123

          ๐Ÿ› patriksevallius
          patriksevallius

          ๐Ÿ› - - pbrajesh1
          pbrajesh1

          ๐Ÿ› phoenix384
          phoenix384

          ๐Ÿ› piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป + + plan3d
          plan3d

          ๐Ÿ› poojasix
          poojasix

          ๐Ÿ› prabhushrikant
          prabhushrikant

          ๐Ÿ› pujitha8783
          pujitha8783

          ๐Ÿ› - - r-r-a-j
          r-r-a-j

          ๐Ÿ› raghujayjunk
          raghujayjunk

          ๐Ÿ› rajeshveera
          rajeshveera

          ๐Ÿ› + + rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ› recdevs
          recdevs

          ๐Ÿ› reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ› rijkt
          rijkt

          ๐Ÿ› - - rillig-tk
          rillig-tk

          ๐Ÿ› rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ› rnveach
          rnveach

          ๐Ÿ› + + + rubenporras
          rubenporras

          ๐Ÿ› rxmicro
          rxmicro

          ๐Ÿ› ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ› sabi0
          sabi0

          ๐Ÿ› samc-gearset
          samc-gearset

          ๐Ÿ“– - - scais
          scais

          ๐Ÿ› schosin
          schosin

          ๐Ÿ› + + screamingfrog
          screamingfrog

          ๐Ÿ’ต sebbASF
          sebbASF

          ๐Ÿ› sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป shilko2013
          shilko2013

          ๐Ÿ› shiomiyan
          shiomiyan

          ๐Ÿ“– - - simeonKondr
          simeonKondr

          ๐Ÿ› snajberk
          snajberk

          ๐Ÿ› + + sniperrifle2004
          sniperrifle2004

          ๐Ÿ› snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป soloturn
          soloturn

          ๐Ÿ› soyodream
          soyodream

          ๐Ÿ› sratz
          sratz

          ๐Ÿ› - - stonio
          stonio

          ๐Ÿ› sturton
          sturton

          ๐Ÿ’ป ๐Ÿ› + + sudharmohan
          sudharmohan

          ๐Ÿ› suruchidawar
          suruchidawar

          ๐Ÿ› svenfinitiv
          svenfinitiv

          ๐Ÿ› szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป tashiscool
          tashiscool

          ๐Ÿ› - - test-git-hook
          test-git-hook

          ๐Ÿ› testation21
          testation21

          ๐Ÿ’ป ๐Ÿ› + + thanosa
          thanosa

          ๐Ÿ› tiandiyixian
          tiandiyixian

          ๐Ÿ› tobwoerk
          tobwoerk

          ๐Ÿ› tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป trentchilders
          trentchilders

          ๐Ÿ› - - triandicAnt
          triandicAnt

          ๐Ÿ› trishul14
          trishul14

          ๐Ÿ› + + tsui
          tsui

          ๐Ÿ› wangzitom12306
          wangzitom12306

          ๐Ÿ› winhkey
          winhkey

          ๐Ÿ› witherspore
          witherspore

          ๐Ÿ› wjljack
          wjljack

          ๐Ÿ› - - wuchiuwong
          wuchiuwong

          ๐Ÿ› xingsong
          xingsong

          ๐Ÿ› + + xioayuge
          xioayuge

          ๐Ÿ› xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ› xuanuy
          xuanuy

          ๐Ÿ› xyf0921
          xyf0921

          ๐Ÿ› yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ› - - yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ› yasuharu-sato
          yasuharu-sato

          ๐Ÿ› + + zenglian
          zenglian

          ๐Ÿ› zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ› zh3ng
          zh3ng

          ๐Ÿ› zt_soft
          zt_soft

          ๐Ÿ› ztt79
          ztt79

          ๐Ÿ› - - zzzzfeng
          zzzzfeng

          ๐Ÿ› รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ› + + ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ› ๅคฉ็ƒญๅƒ่ฅฟ็“œ
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ

          ๐Ÿ› ่Œ…ๅปถๅฎ‰
          ่Œ…ๅปถๅฎ‰

          ๐Ÿ’ป From aed481242341162e74dd16efcbec31f4052e9cfe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Oct 2025 15:31:04 +0100 Subject: [PATCH 1584/1962] chore(deps): bump io.github.apex-dev-tools:apex-ls_2.13 from 5.10.0 to 6.0.1 (#6180) chore(deps): bump io.github.apex-dev-tools:apex-ls_2.13 Bumps [io.github.apex-dev-tools:apex-ls_2.13](https://github.com/apex-dev-tools/apex-ls) from 5.10.0 to 6.0.1. - [Release notes](https://github.com/apex-dev-tools/apex-ls/releases) - [Changelog](https://github.com/apex-dev-tools/apex-ls/blob/main/CHANGELOG.md) - [Commits](https://github.com/apex-dev-tools/apex-ls/compare/v5.10.0...v6.0.1) --- updated-dependencies: - dependency-name: io.github.apex-dev-tools:apex-ls_2.13 dependency-version: 6.0.1 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-apex/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 21a347b37bc..0693e526f48 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -106,7 +106,7 @@ io.github.apex-dev-tools apex-ls_2.13 - 5.10.0 + 6.0.1 From aeeade6a6632717129fb8ff28a640df670b8c641 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 30 Oct 2025 16:14:48 +0100 Subject: [PATCH 1585/1962] chore: always place type annotations on the type This is ModifierOrder with typeAnnotations=ontype --- .../pmd/cli/commands/internal/PmdCommand.java | 3 +-- .../internal/util/ClasspathClassLoader.java | 3 +-- .../sourceforge/pmd/lang/ast/NodeStream.java | 3 +-- .../pmd/lang/ast/impl/GenericNode.java | 6 ++--- .../pmd/lang/ast/internal/StreamImpl.java | 2 +- .../pmd/lang/rule/AbstractRule.java | 3 +-- .../pmd/lang/rule/RuleSetWriter.java | 3 +-- .../lang/rule/internal/LatticeRelation.java | 6 ++--- .../rule/xpath/internal/DomainConversion.java | 6 ++--- .../sourceforge/pmd/util/CollectionUtil.java | 2 +- .../net/sourceforge/pmd/util/GraphUtil.java | 3 +-- .../pmd/lang/java/ast/ASTArrayAllocation.java | 3 +-- .../java/ast/ASTAssignmentExpression.java | 6 ++--- .../pmd/lang/java/ast/ASTCatchParameter.java | 3 +-- .../pmd/lang/java/ast/ASTClassType.java | 6 ++--- .../pmd/lang/java/ast/ASTConstructorCall.java | 3 +-- .../pmd/lang/java/ast/ASTEnumConstant.java | 3 +-- .../java/ast/ASTExecutableDeclaration.java | 6 ++--- .../ast/ASTExplicitConstructorInvocation.java | 9 +++---- .../lang/java/ast/ASTExpressionStatement.java | 3 +-- .../lang/java/ast/ASTForeachStatement.java | 6 ++--- .../lang/java/ast/ASTFormalParameters.java | 3 +-- .../pmd/lang/java/ast/ASTLambdaParameter.java | 6 ++--- .../pmd/lang/java/ast/ASTMethodCall.java | 6 ++--- .../lang/java/ast/ASTMethodDeclaration.java | 6 ++--- .../lang/java/ast/ASTReceiverParameter.java | 3 +-- .../lang/java/ast/ASTRecordDeclaration.java | 3 +-- .../pmd/lang/java/ast/ASTResource.java | 3 +-- .../pmd/lang/java/ast/ASTReturnStatement.java | 3 +-- .../pmd/lang/java/ast/ASTSuperExpression.java | 3 +-- .../pmd/lang/java/ast/ASTThisExpression.java | 3 +-- .../pmd/lang/java/ast/ASTTryStatement.java | 6 ++--- .../pmd/lang/java/ast/ASTTypeParameter.java | 3 +-- .../lang/java/ast/ASTVariableDeclarator.java | 6 ++--- .../pmd/lang/java/ast/ASTVariableId.java | 12 +++------ .../pmd/lang/java/ast/ASTYieldStatement.java | 3 +-- .../pmd/lang/java/ast/AssignmentOp.java | 3 +-- .../pmd/lang/java/ast/InternalInterfaces.java | 27 +++++++------------ .../pmd/lang/java/ast/TypeNode.java | 3 +-- .../java/internal/JavaDesignerBindings.java | 3 +-- ...ConstructorCallsOverridableMethodRule.java | 6 ++--- .../pmd/lang/java/symbols/JClassSymbol.java | 6 ++--- .../pmd/lang/java/symbols/JFieldSymbol.java | 3 +-- .../symbols/JTypeParameterOwnerSymbol.java | 3 +-- .../java/symbols/JTypeParameterSymbol.java | 6 ++--- .../pmd/lang/java/symbols/SymbolResolver.java | 9 +++---- .../java/symbols/internal/asm/Loader.java | 3 +-- .../symbols/internal/asm/TypeSigParser.java | 3 +-- .../internal/ast/AstSymbolMakerVisitor.java | 6 ++--- .../symbols/table/internal/JavaResolvers.java | 9 +++---- .../table/internal/SymTableFactory.java | 3 +-- .../pmd/lang/java/types/ArraySymbolImpl.java | 9 +++---- .../pmd/lang/java/types/TypeOps.java | 2 +- 53 files changed, 88 insertions(+), 173 deletions(-) diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java index 7b8bb4735e8..926b749f988 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java @@ -286,8 +286,7 @@ protected PMDConfiguration toConfiguration() { } @Override - @NonNull - protected CliExitCode doExecute(PMDConfiguration configuration) { + protected @NonNull CliExitCode doExecute(PMDConfiguration configuration) { if (benchmark) { TimeTracker.startGlobalTracking(); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java index f3a1c3f59a9..9c8ffe59b9f 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/ClasspathClassLoader.java @@ -211,8 +211,7 @@ public String toString() { // this is lazily initialized on first query of a module-info.class private Map moduleNameToModuleInfoUrls; - @Nullable - private static String extractModuleName(String name) { + private static @Nullable String extractModuleName(String name) { if (!name.endsWith(MODULE_INFO_SUFFIX_SLASH)) { return null; } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/NodeStream.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/NodeStream.java index e7041145e1f..1b4fc2a8c5e 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/NodeStream.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/NodeStream.java @@ -776,8 +776,7 @@ default boolean isEmpty() { * @see #first(Class) * @see #firstOpt() */ - @NonNull - default T firstOrThrow() { + default @NonNull T firstOrThrow() { T first = first(); if (first == null) { throw new NoSuchElementException("Empty node stream"); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/GenericNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/GenericNode.java index 4b15afabd09..cd1e6b91856 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/GenericNode.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/GenericNode.java @@ -38,14 +38,12 @@ public interface GenericNode> extends Node { N getParent(); @Override - @Nullable - default N getFirstChild() { + default @Nullable N getFirstChild() { return getNumChildren() > 0 ? getChild(0) : null; } @Override - @Nullable - default N getLastChild() { + default @Nullable N getLastChild() { return getNumChildren() > 0 ? getChild(getNumChildren() - 1) : null; } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/StreamImpl.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/StreamImpl.java index 8a356d18aa2..bf4bd7f9009 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/StreamImpl.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/StreamImpl.java @@ -222,7 +222,7 @@ protected NodeStream mapIter(Function, Iterator< } @Override - protected @NonNull DescendantNodeStream flatMapDescendants(Function> mapper) { + protected @NonNull DescendantNodeStream flatMapDescendants(Function> mapper) { return StreamImpl.empty(); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractRule.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractRule.java index 7a0e99deeb3..7b7331fc86e 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractRule.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractRule.java @@ -220,8 +220,7 @@ public final RuleTargetSelector getTargetSelector() { * Create the targeting strategy for this rule. * Use the factory methods of {@link RuleTargetSelector}. */ - @NonNull - protected RuleTargetSelector buildTargetSelector() { + protected @NonNull RuleTargetSelector buildTargetSelector() { Set> crvs = getClassRuleChainVisits(); return crvs.isEmpty() ? RuleTargetSelector.forRootOnly() : RuleTargetSelector.forTypes(crvs); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetWriter.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetWriter.java index 1a435cfea7b..f5bca5e7797 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetWriter.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetWriter.java @@ -260,8 +260,7 @@ private Element createRuleSetReferenceElement(RuleSetReference ruleSetReference) return ruleSetReferenceElement; } - @Nullable - private Element createPropertiesElement(PropertySource propertySource) { + private @Nullable Element createPropertiesElement(PropertySource propertySource) { Element propertiesElement = null; List> overridden = propertySource.getOverriddenPropertyDescriptors(); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/LatticeRelation.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/LatticeRelation.java index 91ac6c5a773..12bf345324a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/LatticeRelation.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/internal/LatticeRelation.java @@ -156,8 +156,7 @@ private void link(@Nullable Iterable preds, LNode n, @Nullable V val) { n.addValueTransitive(val); } - @NonNull - private IllegalStateException cycleError(@NonNull Deque preds, K k) { + private @NonNull IllegalStateException cycleError(@NonNull Deque preds, K k) { List toStrings = map(toMutableList(), preds, n -> keyToString.apply(n.key)); toStrings.add(keyToString.apply(k)); return new IllegalStateException("Cycle in graph: " + String.join(" -> ", toStrings)); @@ -201,8 +200,7 @@ private void putDontCheckParams(@NonNull K key, @Nullable V value) { * * @throws NullPointerException If the key is null */ - @NonNull - public C get(@NonNull K key) { + public @NonNull C get(@NonNull K key) { AssertionUtil.requireParamNotNull("key", key); LNode n = nodes.get(key); return n == null ? emptyValue : n.computeValue(); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/DomainConversion.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/DomainConversion.java index 2e692ee992f..2c919d4fbc2 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/DomainConversion.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/DomainConversion.java @@ -54,8 +54,7 @@ public static SchemaType buildType(java.lang.reflect.Type type) { } } - @NonNull - public static AtomicSequence convert(Object obj) { + public static @NonNull AtomicSequence convert(Object obj) { if (obj instanceof Collection) { return getSequenceRepresentation((Collection) obj); } @@ -122,8 +121,7 @@ private static void flattenInto(Collection list, List values) { * * @return The converted AtomicValue */ - @NonNull - public static AtomicValue getAtomicRepresentation(final Object value) { + public static @NonNull AtomicValue getAtomicRepresentation(final Object value) { /* FUTURE When supported, we should consider refactor this implementation to use Pattern Matching diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java index 4aa5c7b8f98..a8e2758a29c 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java @@ -711,7 +711,7 @@ public static PSet union(PSet as, PSet bs) { return as.plusAll(bs); } - public static @NonNull List makeUnmodifiableAndNonNull(@Nullable List list) { + public static @NonNull List makeUnmodifiableAndNonNull(@Nullable List list) { if (list instanceof PSequence) { return (List) list; } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/GraphUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/GraphUtil.java index 087e15d33fe..685d82efccd 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/GraphUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/GraphUtil.java @@ -74,8 +74,7 @@ public static String toDot( } - @NonNull - private static String escapeDotString(String string) { + private static @NonNull String escapeDotString(String string) { return string.replaceAll("\\R", "\\\n") .replaceAll("\"", "\\\""); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayAllocation.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayAllocation.java index 8f7c3707f3c..bef55498554 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayAllocation.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTArrayAllocation.java @@ -39,8 +39,7 @@ public ASTArrayType getTypeNode() { } /** Returns the initializer, if present. */ - @Nullable - public ASTArrayInitializer getArrayInitializer() { + public @Nullable ASTArrayInitializer getArrayInitializer() { return AstImplUtil.getChildAs(this, getNumChildren() - 1, ASTArrayInitializer.class); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAssignmentExpression.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAssignmentExpression.java index 0e5d4e57eb5..21d0c4a6f15 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAssignmentExpression.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTAssignmentExpression.java @@ -31,8 +31,7 @@ void setOp(AssignmentOp op) { /** Returns the left-hand side, ie the expression being assigned to. */ @Override - @NonNull - public ASTAssignableExpr getLeftOperand() { + public @NonNull ASTAssignableExpr getLeftOperand() { return (ASTAssignableExpr) getChild(0); } @@ -46,8 +45,7 @@ public boolean isCompound() { @Override - @NonNull - public AssignmentOp getOperator() { + public @NonNull AssignmentOp getOperator() { return operator; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCatchParameter.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCatchParameter.java index 37d3c7a29f9..c96b01e116a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCatchParameter.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTCatchParameter.java @@ -49,8 +49,7 @@ public boolean isMulticatch() { } @Override - @NonNull - public ASTVariableId getVarId() { + public @NonNull ASTVariableId getVarId() { return (ASTVariableId) getLastChild(); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassType.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassType.java index e1bc4fe1800..fabca54b936 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassType.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassType.java @@ -112,16 +112,14 @@ JTypeDeclSymbol getReferencedSym() { * * @return A type, or null if this is a base type */ - @Nullable - public ASTClassType getQualifier() { + public @Nullable ASTClassType getQualifier() { return firstChild(ASTClassType.class); } /** * Returns the type arguments of this segment if some are specified. */ - @Nullable - public ASTTypeArguments getTypeArguments() { + public @Nullable ASTTypeArguments getTypeArguments() { return firstChild(ASTTypeArguments.class); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorCall.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorCall.java index 51c55bd7154..326a88d9dc7 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorCall.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTConstructorCall.java @@ -97,8 +97,7 @@ public boolean isAnonymousClass() { } - @Nullable - public ASTAnonymousClassDeclaration getAnonymousClassDeclaration() { + public @Nullable ASTAnonymousClassDeclaration getAnonymousClassDeclaration() { return isAnonymousClass() ? (ASTAnonymousClassDeclaration) getLastChild() : null; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTEnumConstant.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTEnumConstant.java index e399113ba2b..e2cddd1ccb3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTEnumConstant.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTEnumConstant.java @@ -54,8 +54,7 @@ public String getImage() { } @Override - @Nullable - public ASTArgumentList getArguments() { + public @Nullable ASTArgumentList getArguments() { return firstChild(ASTArgumentList.class); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExecutableDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExecutableDeclaration.java index ea7a624cf98..af13eec6b22 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExecutableDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExecutableDeclaration.java @@ -71,8 +71,7 @@ default boolean isAbstract() { /** * Returns the formal parameters node of this method or constructor. */ - @NonNull - default ASTFormalParameters getFormalParameters() { + default @NonNull ASTFormalParameters getFormalParameters() { return firstChild(ASTFormalParameters.class); } @@ -99,8 +98,7 @@ default int getArity() { * Returns the {@code throws} clause of this declaration, or null * if there is none. */ - @Nullable - default ASTThrowsList getThrowsList() { + default @Nullable ASTThrowsList getThrowsList() { return firstChild(ASTThrowsList.class); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExplicitConstructorInvocation.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExplicitConstructorInvocation.java index 095e8c49196..3f2ca807af4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExplicitConstructorInvocation.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExplicitConstructorInvocation.java @@ -41,8 +41,7 @@ protected R acceptVisitor(JavaVisitor visitor, P @Override - @NonNull - public ASTArgumentList getArguments() { + public @NonNull ASTArgumentList getArguments() { return (ASTArgumentList) getLastChild(); } @@ -85,8 +84,7 @@ public boolean isQualified() { } @Override - @Nullable - public ASTTypeArguments getExplicitTypeArguments() { + public @Nullable ASTTypeArguments getExplicitTypeArguments() { return firstChild(ASTTypeArguments.class); } @@ -94,8 +92,7 @@ public ASTTypeArguments getExplicitTypeArguments() { * Returns the qualifying expression if this is a {@linkplain #isQualified() qualified superclass * constructor invocation}. */ - @Nullable - public ASTExpression getQualifier() { + public @Nullable ASTExpression getQualifier() { return AstImplUtil.getChildAs(this, 0, ASTExpression.class); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExpressionStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExpressionStatement.java index dbbd5204f19..4fa90c71117 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExpressionStatement.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTExpressionStatement.java @@ -29,8 +29,7 @@ protected R acceptVisitor(JavaVisitor visitor, P /** Returns the contained expression. */ - @NonNull - public ASTExpression getExpr() { + public @NonNull ASTExpression getExpr() { return (ASTExpression) getChild(0); } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTForeachStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTForeachStatement.java index 2b373b2f900..13df27af08c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTForeachStatement.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTForeachStatement.java @@ -33,8 +33,7 @@ protected R acceptVisitor(JavaVisitor visitor, P @Override - @NonNull - public ASTVariableId getVarId() { + public @NonNull ASTVariableId getVarId() { // in case of destructuring record patterns, there might be multiple vars return getFirstChild().descendants(ASTVariableId.class).first(); } @@ -43,8 +42,7 @@ public ASTVariableId getVarId() { * Returns the expression that evaluates to the {@link Iterable} * being looped upon. */ - @NonNull - public ASTExpression getIterableExpr() { + public @NonNull ASTExpression getIterableExpr() { return firstChild(ASTExpression.class); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameters.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameters.java index 2f167c1b29a..d9d1d862702 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameters.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFormalParameters.java @@ -48,8 +48,7 @@ protected R acceptVisitor(JavaVisitor visitor, P * Returns the receiver parameter if it is present, otherwise returns * null. */ - @Nullable - public ASTReceiverParameter getReceiverParameter() { + public @Nullable ASTReceiverParameter getReceiverParameter() { return AstImplUtil.getChildAs(this, 0, ASTReceiverParameter.class); } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLambdaParameter.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLambdaParameter.java index 9a876e50c56..4f83030e03f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLambdaParameter.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLambdaParameter.java @@ -67,14 +67,12 @@ public ASTLambdaExpression getOwner() { * Returns the declarator ID of this formal parameter. */ @Override - @NonNull - public ASTVariableId getVarId() { + public @NonNull ASTVariableId getVarId() { return firstChild(ASTVariableId.class); } /** Returns the type node of this formal parameter. */ - @Nullable - public ASTType getTypeNode() { + public @Nullable ASTType getTypeNode() { return firstChild(ASTType.class); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodCall.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodCall.java index 2730a7853c4..5fadce17d23 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodCall.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodCall.java @@ -54,15 +54,13 @@ public void jjtClose() { } @Override - @NonNull - public ASTArgumentList getArguments() { + public @NonNull ASTArgumentList getArguments() { return (ASTArgumentList) getChild(getNumChildren() - 1); } @Override - @Nullable - public ASTTypeArguments getExplicitTypeArguments() { + public @Nullable ASTTypeArguments getExplicitTypeArguments() { return firstChild(ASTTypeArguments.class); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java index 5def2ddfd3a..85af1a55b98 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTMethodDeclaration.java @@ -108,8 +108,7 @@ public boolean isVoid() { * Returns the default clause, if this is an annotation method declaration * that features one. Otherwise returns null. */ - @Nullable - public ASTDefaultValue getDefaultClause() { + public @Nullable ASTDefaultValue getDefaultClause() { return AstImplUtil.getChildAs(this, getNumChildren() - 1, ASTDefaultValue.class); } @@ -124,8 +123,7 @@ public ASTDefaultValue getDefaultClause() { * Returns the extra array dimensions that may be after the * formal parameters. */ - @Nullable - public ASTArrayDimensions getExtraDimensions() { + public @Nullable ASTArrayDimensions getExtraDimensions() { return children(ASTArrayDimensions.class).first(); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTReceiverParameter.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTReceiverParameter.java index ff614f0ebc6..763347998ce 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTReceiverParameter.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTReceiverParameter.java @@ -57,8 +57,7 @@ protected R acceptVisitor(JavaVisitor visitor, P * declaration of the inner class, call it C, and the name of the parameter * must be {@code Identifier.this} where {@code Identifier} is the simple name of C. */ - @NonNull - public ASTClassType getReceiverType() { + public @NonNull ASTClassType getReceiverType() { return (ASTClassType) getChild(0); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordDeclaration.java index 8b200646fa6..a17f4f04956 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordDeclaration.java @@ -44,8 +44,7 @@ public NodeStream getDeclarations() { } @Override - @NonNull - public ASTRecordComponentList getRecordComponents() { + public @NonNull ASTRecordComponentList getRecordComponents() { return firstChild(ASTRecordComponentList.class); } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTResource.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTResource.java index 6e6c56e4911..e85ba15ecae 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTResource.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTResource.java @@ -63,8 +63,7 @@ public String getStableName() { } } - @Nullable - public ASTLocalVariableDeclaration asLocalVariableDeclaration() { + public @Nullable ASTLocalVariableDeclaration asLocalVariableDeclaration() { return AstImplUtil.getChildAs(this, 0, ASTLocalVariableDeclaration.class); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTReturnStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTReturnStatement.java index 7e3978ad0c8..9da85eafd64 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTReturnStatement.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTReturnStatement.java @@ -31,8 +31,7 @@ protected R acceptVisitor(JavaVisitor visitor, P /** * Returns the returned expression, or null if this is a simple return. */ - @Nullable - public ASTExpression getExpr() { + public @Nullable ASTExpression getExpr() { return AstImplUtil.getChildAs(this, 0, ASTExpression.class); } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSuperExpression.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSuperExpression.java index fd05f47654f..0b0688a4401 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSuperExpression.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSuperExpression.java @@ -23,8 +23,7 @@ public final class ASTSuperExpression extends AbstractJavaExpr implements ASTPri } - @Nullable - public ASTClassType getQualifier() { + public @Nullable ASTClassType getQualifier() { return getNumChildren() > 0 ? (ASTClassType) getChild(0) : null; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTThisExpression.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTThisExpression.java index 7d903c967e2..f02590b56f7 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTThisExpression.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTThisExpression.java @@ -24,8 +24,7 @@ public final class ASTThisExpression extends AbstractJavaExpr implements ASTPrim } - @Nullable - public ASTClassType getQualifier() { + public @Nullable ASTClassType getQualifier() { return getNumChildren() > 0 ? (ASTClassType) getChild(0) : null; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTryStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTryStatement.java index 216faedd5e1..1174031158c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTryStatement.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTryStatement.java @@ -47,8 +47,7 @@ public boolean isTryWithResources() { * Returns the node for the resource list. This is null if this is * not a try-with-resources. */ - @Nullable - public ASTResourceList getResources() { + public @Nullable ASTResourceList getResources() { return AstImplUtil.getChildAs(this, 0, ASTResourceList.class); } @@ -74,8 +73,7 @@ public NodeStream getCatchClauses() { * * @return The finally statement, or null if there is none */ - @Nullable - public ASTFinallyClause getFinallyClause() { + public @Nullable ASTFinallyClause getFinallyClause() { return firstChild(ASTFinallyClause.class); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeParameter.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeParameter.java index 5e9b6599008..d8d7f6a07d3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeParameter.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeParameter.java @@ -54,8 +54,7 @@ public boolean hasTypeBound() { * Returns the type bound node of this parameter, * or null if it is not bounded. */ - @Nullable - public ASTType getTypeBoundNode() { + public @Nullable ASTType getTypeBoundNode() { return firstChild(ASTType.class); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclarator.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclarator.java index 1c12cd009b4..cd92a2f3668 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclarator.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclarator.java @@ -47,8 +47,7 @@ public String getName() { * Returns the id of the declared variable. */ @Override - @NonNull - public ASTVariableId getVarId() { + public @NonNull ASTVariableId getVarId() { return (ASTVariableId) getChild(0); } @@ -65,8 +64,7 @@ public boolean hasInitializer() { /** * Returns the initializer, of the variable, or null if it doesn't exist. */ - @Nullable - public ASTExpression getInitializer() { + public @Nullable ASTExpression getInitializer() { return hasInitializer() ? (ASTExpression) getLastChild() : null; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableId.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableId.java index 9fb49073851..ec5b3b557e0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableId.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableId.java @@ -84,14 +84,12 @@ void addUsage(ASTNamedReferenceExpr usage) { * returns {@code int}, and this method returns the dimensions that follow * the variable ID. Returns null if there are no such dimensions. */ - @Nullable - public ASTArrayDimensions getExtraDimensions() { + public @Nullable ASTArrayDimensions getExtraDimensions() { return children(ASTArrayDimensions.class).first(); } - @NonNull @Override - public ASTModifierList getModifiers() { + public @NonNull ASTModifierList getModifiers() { // delegates modifiers return getModifierOwnerParent().getModifiers(); } @@ -304,8 +302,7 @@ public boolean isPatternBinding() { /** * Returns the initializer of the variable, or null if it doesn't exist. */ - @Nullable - public ASTExpression getInitializer() { + public @Nullable ASTExpression getInitializer() { if (getParent() instanceof ASTVariableDeclarator) { return ((ASTVariableDeclarator) getParent()).getInitializer(); } @@ -318,8 +315,7 @@ public ASTExpression getInitializer() { * type. */ // TODO unreliable, not typesafe and not useful, should be deprecated - @Nullable - public Node getTypeNameNode() { + public @Nullable Node getTypeNameNode() { return getTypeNode(); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTYieldStatement.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTYieldStatement.java index e076f68a1d9..67779d7af6a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTYieldStatement.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTYieldStatement.java @@ -41,8 +41,7 @@ public ASTExpression getExpr() { * Returns the switch expression to which this statement yields a * value. */ - @NonNull - public ASTSwitchExpression getYieldTarget() { + public @NonNull ASTSwitchExpression getYieldTarget() { return Objects.requireNonNull(ancestors(ASTSwitchExpression.class).first(), "Yield statements should only be parsable inside switch expressions"); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AssignmentOp.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AssignmentOp.java index cfc411feb08..14259338625 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AssignmentOp.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AssignmentOp.java @@ -81,8 +81,7 @@ public boolean isCompound() { * if this is a compound operator, otherwise returns * null. */ - @Nullable - public BinaryOp getBinaryOp() { + public @Nullable BinaryOp getBinaryOp() { return binaryOp; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalInterfaces.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalInterfaces.java index 16e47fd046f..5f564ca2479 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalInterfaces.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalInterfaces.java @@ -38,22 +38,19 @@ interface OperatorLike { interface BinaryExpressionLike extends ASTExpression { /** Returns the left-hand-side operand. */ - @NonNull - default ASTExpression getLeftOperand() { + default @NonNull ASTExpression getLeftOperand() { return (ASTExpression) getChild(0); } /** Returns the right-hand side operand. */ - @NonNull - default ASTExpression getRightOperand() { + default @NonNull ASTExpression getRightOperand() { return (ASTExpression) getChild(1); } /** Returns the operator. */ - @NonNull - OperatorLike getOperator(); + @NonNull OperatorLike getOperator(); } /** @@ -65,8 +62,7 @@ interface AtLeastOneChild extends JavaNode { /** Returns the first child of this node, never null. */ @Override - @NonNull - default JavaNode getFirstChild() { + default @NonNull JavaNode getFirstChild() { assert getNumChildren() > 0; return getChild(0); } @@ -74,8 +70,7 @@ default JavaNode getFirstChild() { /** Returns the last child of this node, never null. */ @Override - @NonNull - default JavaNode getLastChild() { + default @NonNull JavaNode getLastChild() { assert getNumChildren() > 0; return getChild(getNumChildren() - 1); } @@ -84,8 +79,7 @@ default JavaNode getLastChild() { interface AllChildrenAreOfType extends JavaNode { @Override - @Nullable - default T getFirstChild() { + default @Nullable T getFirstChild() { if (getNumChildren() == 0) { return null; } @@ -94,8 +88,7 @@ default T getFirstChild() { @Override - @Nullable - default T getLastChild() { + default @Nullable T getLastChild() { if (getNumChildren() == 0) { return null; } @@ -111,8 +104,7 @@ interface AtLeastOneChildOfType extends AllChildrenAreOfType /** Returns the first child of this node, never null. */ @Override - @NonNull - default T getFirstChild() { + default @NonNull T getFirstChild() { assert getNumChildren() > 0 : "No children for node implementing AtLeastOneChild " + this; return (T) getChild(0); } @@ -120,8 +112,7 @@ default T getFirstChild() { /** Returns the last child of this node, never null. */ @Override - @NonNull - default T getLastChild() { + default @NonNull T getLastChild() { assert getNumChildren() > 0 : "No children for node implementing AtLeastOneChild " + this; return (T) getChild(getNumChildren() - 1); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/TypeNode.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/TypeNode.java index 7d977e644e5..b0293251ea5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/TypeNode.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/TypeNode.java @@ -35,8 +35,7 @@ public interface TypeNode extends JavaNode { * @return The type mirror. Never returns null; if the type is unresolved, returns * {@link TypeSystem#UNKNOWN}. */ - @NonNull - default JTypeMirror getTypeMirror() { + default @NonNull JTypeMirror getTypeMirror() { return getTypeMirror(TypingContext.DEFAULT); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaDesignerBindings.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaDesignerBindings.java index df944c2d1d2..b1be7580c0a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaDesignerBindings.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaDesignerBindings.java @@ -113,8 +113,7 @@ public Collection getAdditionalInfo(Node node) { return info; } - @NonNull - private String formatModifierSet(Set modifierSet) { + private @NonNull String formatModifierSet(Set modifierSet) { return modifierSet.stream().map(JModifier::toString).collect(Collectors.joining(", ", "(", ")")); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConstructorCallsOverridableMethodRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConstructorCallsOverridableMethodRule.java index ced24b66160..d028a129722 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConstructorCallsOverridableMethodRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/ConstructorCallsOverridableMethodRule.java @@ -92,8 +92,7 @@ public Object visit(ASTConstructorDeclaration node, Object data) { return null; } - @NonNull - private Deque getUnsafetyReason(ASTMethodCall call, PVector recursionGuard) { + private @NonNull Deque getUnsafetyReason(ASTMethodCall call, PVector recursionGuard) { if (!isCallOnThisInstance(call)) { return EMPTY_STACK; } @@ -113,8 +112,7 @@ private Deque getUnsafetyReason(ASTMethodCall call, PVector getUnsafetyReason(JMethodSymbol method, PVector recursionGuard) { + private @NonNull Deque getUnsafetyReason(JMethodSymbol method, PVector recursionGuard) { if (method.isStatic()) { return EMPTY_STACK; // no access to this instance anyway } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JClassSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JClassSymbol.java index 9bc0c239d63..33a213f5c3a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JClassSymbol.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JClassSymbol.java @@ -116,8 +116,7 @@ default JTypeParameterOwnerSymbol getEnclosingTypeParameterOwner() { /** Returns a class with the given name defined in this class. */ - @Nullable - default JClassSymbol getDeclaredClass(String name) { + default @Nullable JClassSymbol getDeclaredClass(String name) { for (JClassSymbol klass : getDeclaredClasses()) { if (klass.nameEquals(name)) { return klass; @@ -168,8 +167,7 @@ default JClassSymbol getDeclaredClass(String name) { /** Returns a field with the given name defined in this class. */ - @Nullable - default JFieldSymbol getDeclaredField(String name) { + default @Nullable JFieldSymbol getDeclaredField(String name) { for (JFieldSymbol field : getDeclaredFields()) { if (field.nameEquals(name)) { return field; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JFieldSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JFieldSymbol.java index f24bdb54210..9823bbd92f2 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JFieldSymbol.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JFieldSymbol.java @@ -44,8 +44,7 @@ default boolean isFinal() { @Override - @NonNull - default String getPackageName() { + default @NonNull String getPackageName() { return getEnclosingClass().getPackageName(); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JTypeParameterOwnerSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JTypeParameterOwnerSymbol.java index 14cae74f734..b6b1612c6f8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JTypeParameterOwnerSymbol.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JTypeParameterOwnerSymbol.java @@ -58,8 +58,7 @@ default boolean isGeneric() { * the {@link #getEnclosingClass() enclosing class}, in that order * of priority. */ - @Nullable - default JTypeParameterOwnerSymbol getEnclosingTypeParameterOwner() { + default @Nullable JTypeParameterOwnerSymbol getEnclosingTypeParameterOwner() { // may be overridden to add getEnclosingMethod return getEnclosingClass(); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JTypeParameterSymbol.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JTypeParameterSymbol.java index bd40a9eae9b..533fe8c23b0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JTypeParameterSymbol.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/JTypeParameterSymbol.java @@ -41,8 +41,7 @@ public interface JTypeParameterSymbol extends JTypeDeclSymbol, BoundToNode popList() { * non-null, if the symbol is not found (linkage error) then return * an unresolved symbol. */ - @NonNull - public abstract JClassSymbol makeClassSymbol(String internalName, int observedArity); + public abstract @NonNull JClassSymbol makeClassSymbol(String internalName, int observedArity); public JTypeMirror getBaseType(char baseType) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstSymbolMakerVisitor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstSymbolMakerVisitor.java index 391237eb6fc..ab04d39852f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstSymbolMakerVisitor.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ast/AstSymbolMakerVisitor.java @@ -107,8 +107,7 @@ public Void visitTypeDecl(ASTTypeDeclaration node, AstSymFactory data) { return null; } - @NonNull - private String makeBinaryName(ASTTypeDeclaration node) { + private @NonNull String makeBinaryName(ASTTypeDeclaration node) { String simpleName = node.getSimpleName(); if (node.isLocal()) { simpleName = getNextIndexFromHistogram(currentLocalIndices.getFirst(), node.getSimpleName(), 1) @@ -125,8 +124,7 @@ private String makeBinaryName(ASTTypeDeclaration node) { : packageName + "." + simpleName; } - @Nullable - private String makeCanonicalName(ASTTypeDeclaration node, String binaryName) { + private @Nullable String makeCanonicalName(ASTTypeDeclaration node, String binaryName) { if (node.isAnonymous() || node.isLocal() || node.isUnnamedToplevelClass()) { return null; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/JavaResolvers.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/JavaResolvers.java index 24202b1a065..7efabe670f4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/JavaResolvers.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/JavaResolvers.java @@ -74,8 +74,7 @@ static boolean canBeImportedIn(String thisPackage, JAccessibleElementSymbol memb return isAccessibleIn(null, thisPackage, member, false); } - @NonNull - static NameResolver moduleImport(Set moduleNames, + static @NonNull NameResolver moduleImport(Set moduleNames, final SymbolResolver symbolResolver, final String thisPackage) { return new SingleNameResolver() { @@ -107,8 +106,7 @@ public String toString() { }; } - @NonNull - static NameResolver importedOnDemand(Set lazyImportedPackagesAndTypes, + static @NonNull NameResolver importedOnDemand(Set lazyImportedPackagesAndTypes, final SymbolResolver symResolver, final String thisPackage) { return new SingleNameResolver() { @@ -133,8 +131,7 @@ public String toString() { }; } - @NonNull - static NameResolver packageResolver(SymbolResolver symResolver, String packageName) { + static @NonNull NameResolver packageResolver(SymbolResolver symResolver, String packageName) { return new SingleNameResolver() { @Nullable @Override diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymTableFactory.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymTableFactory.java index cd6240bc3b9..c365fb66953 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymTableFactory.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymTableFactory.java @@ -380,8 +380,7 @@ JSymbolTable samePackageSymTable(JSymbolTable parent) { return typesInPackage(parent, thisPackage, ScopeInfo.SAME_PACKAGE); } - @NonNull - private JSymbolTable typesInPackage(JSymbolTable parent, String packageName, ScopeInfo scopeTag) { + private @NonNull JSymbolTable typesInPackage(JSymbolTable parent, String packageName, ScopeInfo scopeTag) { assert isValidJavaPackageName(packageName) : "Not a package name: " + packageName; return SymbolTableImpl.withTypes( diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ArraySymbolImpl.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ArraySymbolImpl.java index fac1c853320..614b5f035fe 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ArraySymbolImpl.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ArraySymbolImpl.java @@ -145,14 +145,12 @@ public List getConstructors() { } @Override - @NonNull - public String getPackageName() { + public @NonNull String getPackageName() { return getArrayComponent().getPackageName(); } @Override - @NonNull - public String getSimpleName() { + public @NonNull String getSimpleName() { return getArrayComponent().getSimpleName() + "[]"; } @@ -168,8 +166,7 @@ public List getTypeParameters() { } @Override - @Nullable - public JClassSymbol getEnclosingClass() { + public @Nullable JClassSymbol getEnclosingClass() { return null; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java index eb3d6520589..d69d484ed3e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java @@ -996,7 +996,7 @@ public static List substInBoundsOnly(List ts, Function List mapPreservingSelf(List ts, Function subst) { + private static @NonNull List mapPreservingSelf(List ts, Function subst) { // Profiling shows, only 10% of calls to this method need to // create a new list. Substitution in general is a hot spot // of the framework, so optimizing this out is nice From f59b4d545b92189141ba366bb01ee50a783e4e93 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 30 Oct 2025 16:54:34 +0100 Subject: [PATCH 1586/1962] Update SPONSORS.md --- SPONSORS.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SPONSORS.md b/SPONSORS.md index 727b734bb9c..92b8fe2fe4b 100644 --- a/SPONSORS.md +++ b/SPONSORS.md @@ -8,7 +8,8 @@ Many thanks to all our sponsors: * John Kuhl via opencollective (11/2023) * [flxbl-io](https://github.com/flxbl-io) (@flxbl-io) (12/2024 till 05/2025) * [Jonathan Gillespie](https://github.com/jongpie) (@jongpie) (12/2024 till 04/2025) -* [Cybozu](https://github.com/cybozu) (@cybozu) (since 05/2025) +* [Cybozu](https://github.com/cybozu) (@cybozu) (05/2025 till 09/2025) +* [Cybozu](https://opencollective.com/cybozu) via opencollective (since 10/2025) If you also want to sponsor PMD, you have two options: From 825f6797829681ed0bea67bd8057beb3dc1d55d9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 31 Oct 2025 09:01:46 +0100 Subject: [PATCH 1587/1962] Prepare pmd release 7.18.0 --- docs/_config.yml | 2 +- docs/pages/release_notes.md | 57 ++++++++++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 4c140d5813a..6019af7ce5b 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,7 +1,7 @@ repository: pmd/pmd pmd: - version: 7.18.0-SNAPSHOT + version: 7.18.0 previous_version: 7.17.0 date: 2025-10-31 # release types: major, minor, bugfix diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 713fd1aae64..fbd0de053ab 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -179,9 +179,64 @@ checkstyle version during the build. ### ๐Ÿ“ฆ๏ธ Dependency updates +* [#6034](https://github.com/pmd/pmd/pull/6034): chore(deps): bump com.puppycrawl.tools:checkstyle from 10.26.1 to 11.0.1 +* [#6054](https://github.com/pmd/pmd/pull/6054): Bump PMD from 7.16.0 to 7.17.0 +* [#6062](https://github.com/pmd/pmd/pull/6062): chore(deps): bump surefire.version from 3.5.3 to 3.5.4 +* [#6063](https://github.com/pmd/pmd/pull/6063): chore(deps): bump ruby/setup-ruby from 1.257.0 to 1.258.0 +* [#6064](https://github.com/pmd/pmd/pull/6064): chore(deps): bump com.google.code.gson:gson from 2.13.1 to 2.13.2 +* [#6065](https://github.com/pmd/pmd/pull/6065): chore(deps): bump actions/create-github-app-token from 2.1.1 to 2.1.4 +* [#6066](https://github.com/pmd/pmd/pull/6066): chore(deps): bump org.apache.groovy:groovy from 5.0.0 to 5.0.1 +* [#6067](https://github.com/pmd/pmd/pull/6067): chore(deps): bump org.apache.maven.plugins:maven-shade-plugin from 3.6.0 to 3.6.1 +* [#6068](https://github.com/pmd/pmd/pull/6068): chore(deps): bump scalameta.version from 4.13.9 to 4.13.10 +* [#6076](https://github.com/pmd/pmd/pull/6076): Bump pmdtester from 1.6.0 to 1.6.1 +* [#6086](https://github.com/pmd/pmd/pull/6086): chore(deps): bump ruby/setup-ruby from 1.258.0 to 1.263.0 +* [#6087](https://github.com/pmd/pmd/pull/6087): chore(deps-dev): bump log4j.version from 2.25.1 to 2.25.2 +* [#6088](https://github.com/pmd/pmd/pull/6088): chore(deps): bump org.mockito:mockito-core from 5.19.0 to 5.20.0 +* [#6089](https://github.com/pmd/pmd/pull/6089): chore(deps): bump org.apache.maven.plugins:maven-javadoc-plugin from 3.11.3 to 3.12.0 +* [#6090](https://github.com/pmd/pmd/pull/6090): chore(deps): bump org.codehaus.mojo:versions-maven-plugin from 2.19.0 to 2.19.1 +* [#6091](https://github.com/pmd/pmd/pull/6091): chore(deps): bump org.apache.maven.plugins:maven-compiler-plugin from 3.14.0 to 3.14.1 +* [#6094](https://github.com/pmd/pmd/pull/6094): chore(deps): Bump rexml from 3.4.1 to 3.4.4 +* [#6104](https://github.com/pmd/pmd/pull/6104): chore(deps): bump actions/cache from 4.2.4 to 4.3.0 +* [#6105](https://github.com/pmd/pmd/pull/6105): chore(deps): bump org.scala-lang:scala-library from 2.13.16 to 2.13.17 +* [#6106](https://github.com/pmd/pmd/pull/6106): chore(deps): bump junit.version from 5.13.4 to 6.0.0 +* [#6107](https://github.com/pmd/pmd/pull/6107): chore(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.5.1 to 3.6.0 +* [#6108](https://github.com/pmd/pmd/pull/6108): chore(deps): bump com.puppycrawl.tools:checkstyle from 10.26.1 to 11.1.0 +* [#6109](https://github.com/pmd/pmd/pull/6109): chore(deps-dev): bump org.assertj:assertj-core from 3.27.4 to 3.27.6 +* [#6110](https://github.com/pmd/pmd/pull/6110): chore(deps): bump org.sonatype.central:central-publishing-maven-plugin from 0.8.0 to 0.9.0 +* [#6118](https://github.com/pmd/pmd/pull/6118): chore(deps): bump com.google.protobuf:protobuf-java from 4.32.0 to 4.32.1 +* [#6119](https://github.com/pmd/pmd/pull/6119): chore(deps): bump com.github.hazendaz.maven:coveralls-maven-plugin from 4.7.0 to 5.0.0 +* [#6120](https://github.com/pmd/pmd/pull/6120): chore(deps): bump org.scala-lang:scala-reflect from 2.13.16 to 2.13.17 +* [#6121](https://github.com/pmd/pmd/pull/6121): chore(deps): bump com.github.siom79.japicmp:japicmp-maven-plugin from 0.23.1 to 0.24.1 +* [#6122](https://github.com/pmd/pmd/pull/6122): chore(deps): bump bigdecimal from 3.2.3 to 3.3.0 in /docs +* [#6136](https://github.com/pmd/pmd/pull/6136): chore(deps): bump ruby/setup-ruby from 1.263.0 to 1.265.0 +* [#6137](https://github.com/pmd/pmd/pull/6137): chore(deps): bump org.apache.maven.plugins:maven-enforcer-plugin from 3.6.1 to 3.6.2 +* [#6138](https://github.com/pmd/pmd/pull/6138): chore(deps): bump scalameta.version from 4.13.10 to 4.14.0 +* [#6139](https://github.com/pmd/pmd/pull/6139): chore(deps): bump com.puppycrawl.tools:checkstyle from 11.1.0 to 12.0.1 +* [#6140](https://github.com/pmd/pmd/pull/6140): chore(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.6.0 to 3.6.1 +* [#6141](https://github.com/pmd/pmd/pull/6141): chore(deps): bump org.ow2.asm:asm from 9.8 to 9.9 +* [#6142](https://github.com/pmd/pmd/pull/6142): chore(deps): bump org.apache.commons:commons-lang3 from 3.18.0 to 3.19.0 +* [#6143](https://github.com/pmd/pmd/pull/6143): chore(deps): bump bigdecimal from 3.3.0 to 3.3.1 in /docs +* [#6152](https://github.com/pmd/pmd/pull/6152): chore(deps): Update Saxon-HE from 12.5 to 12.9 +* [#6157](https://github.com/pmd/pmd/pull/6157): chore(deps-dev): bump com.google.guava:guava from 33.4.8-jre to 33.5.0-jre +* [#6158](https://github.com/pmd/pmd/pull/6158): chore(deps): bump scalameta.version from 4.14.0 to 4.14.1 +* [#6159](https://github.com/pmd/pmd/pull/6159): chore(deps): bump org.apache.maven.plugins:maven-dependency-plugin from 3.8.1 to 3.9.0 +* [#6160](https://github.com/pmd/pmd/pull/6160): chore(deps): bump com.github.siom79.japicmp:japicmp-maven-plugin from 0.24.1 to 0.24.2 +* [#6161](https://github.com/pmd/pmd/pull/6161): chore(deps): bump org.apache.maven.plugins:maven-pmd-plugin from 3.27.0 to 3.28.0 +* [#6162](https://github.com/pmd/pmd/pull/6162): chore(deps): bump org.apache.maven.plugins:maven-antrun-plugin from 3.1.0 to 3.2.0 +* [#6165](https://github.com/pmd/pmd/pull/6165): Bump pmdtester from 1.6.1 to 1.6.2 +* [#6173](https://github.com/pmd/pmd/pull/6173): chore(deps): bump actions/upload-artifact from 4.6.2 to 5.0.0 +* [#6174](https://github.com/pmd/pmd/pull/6174): chore(deps): bump ruby/setup-ruby from 1.265.0 to 1.267.0 +* [#6175](https://github.com/pmd/pmd/pull/6175): chore(deps): bump actions/download-artifact from 5.0.0 to 6.0.0 +* [#6178](https://github.com/pmd/pmd/pull/6178): chore(deps): bump org.checkerframework:checker-qual from 3.49.5 to 3.51.1 +* [#6179](https://github.com/pmd/pmd/pull/6179): chore(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.6.1 to 3.6.2 +* [#6180](https://github.com/pmd/pmd/pull/6180): chore(deps): bump io.github.apex-dev-tools:apex-ls_2.13 from 5.10.0 to 6.0.1 +* [#6181](https://github.com/pmd/pmd/pull/6181): chore(deps): bump org.apache.groovy:groovy from 5.0.1 to 5.0.2 +* [#6182](https://github.com/pmd/pmd/pull/6182): chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.17.7 to 1.17.8 ### ๐Ÿ“ˆ๏ธ Stats +* 233 commits +* 76 closed tickets & PRs +* Days since last release: 49 {% endtocmaker %} - From c37a323e288202e21f69449a95d3d4c024455ec8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 31 Oct 2025 09:27:15 +0100 Subject: [PATCH 1588/1962] [release] prepare release pmd_releases/7.18.0 --- pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-css/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-rust/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 6 +++--- 44 files changed, 46 insertions(+), 46 deletions(-) diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index 441d81c8218..cf728eb022e 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.18.0-SNAPSHOT + 7.18.0 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 0693e526f48..960a40a7ac2 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index 037c3a2b6d4..d4ce9a42180 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index eed309d5bc7..5ba85a5cbf7 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index 346033b6609..6339fbf989d 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index 57d24fbeb1f..57d08c68e74 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index e685def3471..57f1e6a13e4 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-css/pom.xml b/pmd-css/pom.xml index 77e32daec39..1e7ce498e30 100644 --- a/pmd-css/pom.xml +++ b/pmd-css/pom.xml @@ -9,7 +9,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index bb602e339b4..028937b9f2c 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index 4c3ca4add3f..3c9dd46f5df 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index 04a216feb29..fcb2e76b5f0 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index 11850173a09..ef1f67bdc5d 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index 3626234cd90..2b8a4d59c72 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index 3b3e0d31a3e..53b576455b8 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index 68fd2736548..dd28850ad8d 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index 7056f919cae..7b41f17cc0b 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index b2d1728f3ae..bf5269afd41 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index f930eb79366..b31b21b6385 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index 64ebf7df5ff..23b9168f7e5 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index eebf33e5d79..5a653b90fd4 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index b5a32bf8d76..386f40db3cb 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index 7491a6cba4d..cb985d7e9fa 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index 03ec69f1317..59065b05244 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index 528e987ee15..8f1576c144d 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index 6df181160c9..aed87f4245c 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index c4e20044c71..e0808737d23 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index 1aea3d70ffd..62e72c91eaf 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index 5f9b21d2841..895aac0015c 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index c9346f08d8d..d3d25a52e4d 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index 47ebf5db7df..8e521d1ee35 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index 0cd7295f344..bdd882d2caf 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index c0d85656197..4d71f6a7642 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index dce6f86609f..919a58b309d 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index bbaa3b3a538..5273c30fd0a 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index fde399ff44d..2e92805d8aa 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.18.0-SNAPSHOT + 7.18.0 ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index 2b869116b3c..6dd5479ea7a 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.18.0-SNAPSHOT + 7.18.0 ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index 442e0af959d..af774c3c4f5 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index 97e7eb18d07..7ab36dd8112 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index 6b92ff7f318..8e57bf82619 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index b9ca7062cde..07c2f680c72 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index 15573942257..808fbeb897b 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index f814fa0bc7f..f9df738904e 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index 5ffef1ff41e..8467a6e7eb8 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 ../pom.xml diff --git a/pom.xml b/pom.xml index 1b6def36df3..4b6341a0c54 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.18.0-SNAPSHOT + 7.18.0 pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - HEAD + pmd_releases/7.18.0 PMD @@ -73,7 +73,7 @@ - 2025-09-12T07:17:26Z + 2025-10-31T08:02:02Z 8 From 3582098a230c613b1a9fb693a8e290eac7a36b96 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 31 Oct 2025 10:11:57 +0100 Subject: [PATCH 1589/1962] [release] Prepare next development version --- docs/_config.yml | 6 +- docs/pages/release_notes.md | 203 +---------------- docs/pages/release_notes_old.md | 240 +++++++++++++++++++++ pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-css/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-rust/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 4 +- 47 files changed, 289 insertions(+), 250 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 6019af7ce5b..65464430b8e 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,9 +1,9 @@ repository: pmd/pmd pmd: - version: 7.18.0 - previous_version: 7.17.0 - date: 2025-10-31 + version: 7.19.0-SNAPSHOT + previous_version: 7.18.0 + date: 2025-11-28 # release types: major, minor, bugfix release_type: minor diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index fbd0de053ab..48d7c2ca2f6 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -24,219 +24,18 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy -#### Build Requirement is Java 17 -From now on, Java 17 or newer is required to build PMD. PMD itself still remains compatible with Java 8, -so that it still can be used in a pure Java 8 environment. This allows us to use the latest -checkstyle version during the build. - -### ๐ŸŒŸ๏ธ New and Changed Rules -#### New Rules -* The new Java rule {% rule java/errorprone/IdenticalConditionalBranches %} finds conditional statements - that do the same thing when the condition is true and false. This is either incorrect or redundant. -* The new Java rule {%rule java/bestpractices/LabeledStatement %} finds labeled statements in code. - Labels make control flow difficult to understand and should be avoided. By default, the rule allows labeled - loops (do, while, for). But it has a property to flag also those labeled loops. -* The new Java rule {%rule java/bestpractices/UnusedLabel %} finds unused labels which are unnecessary and - only make the code hard to read. This new rule will be part of the quickstart ruleset. - -#### Changed Rules -* {%rule java/codestyle/ConfusingTernary %} has a new property `nullCheckBranch` to control, whether null-checks - should be allowed (the default case) or should lead to a violation. -* {%rule java/errorprone/AvoidCatchingGenericException %} is now configurable with the new property - `typesThatShouldNotBeCaught`. - โš ๏ธ The rule has also been moved from category "Design" to category "Error Prone". If you are currently bulk-adding - all the rules from the "Design" category into your custom ruleset, then you need to add the rule explicitly - again (otherwise it won't be included anymore): - ```xml - - ``` - -#### Deprecated Rules -* The Java rule {% rule java/errorprone/AvoidCatchingNPE %} has been deprecated in favor of the updated rule - {% rule java/errorprone/AvoidCatchingGenericException %}, which is now configurable. -* The Java rule {% rule java/errorprone/AvoidCatchingThrowable %} has been deprecated in favor of the updated rule - {% rule java/errorprone/AvoidCatchingGenericException %}, which is now configurable. - ### ๐Ÿ›๏ธ Fixed Issues -* general - * [#4714](https://github.com/pmd/pmd/issues/4714): \[core] Allow trailing commas in multivalued properties - * [#5873](https://github.com/pmd/pmd/issues/5873): \[ci] Run integration test with Java 25 - * [#6012](https://github.com/pmd/pmd/issues/6012): \[pmd-rulesets] Rulesets should be in alphabetical order - * [#6073](https://github.com/pmd/pmd/issues/6073): \[doc] Search improvements - * [#6097](https://github.com/pmd/pmd/issues/6097): \[doc] Add PMD versions dropdown - * [#6098](https://github.com/pmd/pmd/issues/6098): \[doc] Add a copy URL button - * [#6101](https://github.com/pmd/pmd/issues/6101): \[doc] Highlight current header in TOC - * [#6149](https://github.com/pmd/pmd/issues/6149): \[doc] Reproducible Build Documentation is outdated - PMD is now built using Java 17 - * [#6150](https://github.com/pmd/pmd/issues/6150): \[core] Reduce memory usage of CPD's MatchCollector -* apex - * [#5935](https://github.com/pmd/pmd/issues/5935): \[apex] @SuppressWarnings - allow whitespace around comma when suppressing multiple rules -* apex-design - * [#6022](https://github.com/pmd/pmd/issues/6022): \[apex] ExcessiveClassLength/ExcessiveParameterList include the metric in the message -* apex-documentation - * [#6189](https://github.com/pmd/pmd/issues/6189): \[apex] ApexDoc rule doesn't match published Salesforce ApexDoc specification -* java - * [#4904](https://github.com/pmd/pmd/issues/4904): \[java] Renderers output wrong class qualified name for nested classes - * [#6127](https://github.com/pmd/pmd/issues/6127): \[java] Incorrect variable name in violation - * [#6132](https://github.com/pmd/pmd/issues/6132): \[java] Implement main method launch protocol priorities - * [#6146](https://github.com/pmd/pmd/issues/6146): \[java] ClassCastException: class InferenceVarSym cannot be cast to class JClassSymbol -* java-bestpractices - * [#2928](https://github.com/pmd/pmd/issues/2928): \[java] New rules about labeled statements - * [#4122](https://github.com/pmd/pmd/issues/4122): \[java] CheckResultSet false-positive with local variable - * [#6124](https://github.com/pmd/pmd/issues/6124): \[java] UnusedLocalVariable: fix false negatives in pattern matching - * [#6169](https://github.com/pmd/pmd/issues/6169): \[java] AvoidUsingHardCodedIP: violation message should mention the hard coded address - * [#6171](https://github.com/pmd/pmd/issues/6171): \[java] AvoidUsingHardCodedIP: fix false positive for IPv6 -* java-codestyle - * [#5919](https://github.com/pmd/pmd/issues/5919): \[java] ClassNamingConventions: Include integration tests in testClassPattern by default - * [#6004](https://github.com/pmd/pmd/issues/6004): \[java] Make ConfusingTernary != null configurable - * [#6029](https://github.com/pmd/pmd/issues/6029): \[java] Fix UnnecessaryCast false-negative in method calls - * [#6057](https://github.com/pmd/pmd/issues/6057): \[java] ModifierOrder false positive on "abstract sealed class" - * [#6079](https://github.com/pmd/pmd/issues/6079): \[java] IdenticalCatchBranches: False negative for overriden method calls - * [#6123](https://github.com/pmd/pmd/issues/6123): \[java] UselessParentheses FP around switch expression - * [#6131](https://github.com/pmd/pmd/issues/6131): \[java] ModifierOrder: wrong enum values documented, indirectly causing xml parse errors -* java-design - * [#1499](https://github.com/pmd/pmd/issues/1499): \[java] AvoidDeeplyNestedIfStmts violations can be unintentionally undetected - * [#5569](https://github.com/pmd/pmd/issues/5569): \[java] ExcessivePublicCount should report number of public "things" -* java-documentation - * [#6058](https://github.com/pmd/pmd/issues/6058): \[java] DanglingJavadoc FP in module-info files - * [#6103](https://github.com/pmd/pmd/issues/6103): \[java] DanglingJavadoc false positive on record compact constructors -* java-errorprone - * [#5042](https://github.com/pmd/pmd/issues/5042): \[java] CloseResource false-positive on Pattern Matching with instanceof - * [#5878](https://github.com/pmd/pmd/issues/5878): \[java] DontUseFloatTypeForLoopIndices false-negative if variable is declared before loop - * [#6038](https://github.com/pmd/pmd/issues/6038): \[java] Merge AvoidCatchingNPE and AvoidCatchingThrowable into AvoidCatchingGenericException - * [#6055](https://github.com/pmd/pmd/issues/6055): \[java] UselessPureMethodCall false positive with AtomicInteger::getAndIncrement - * [#6060](https://github.com/pmd/pmd/issues/6060): \[java] UselessPureMethodCall false positive on ZipInputStream::getNextEntry - * [#6075](https://github.com/pmd/pmd/issues/6075): \[java] AssignmentInOperand false positive with lambda expressions - * [#6083](https://github.com/pmd/pmd/issues/6083): \[java] New rule IdenticalConditionalBranches -* java-multithreading - * [#5880](https://github.com/pmd/pmd/issues/5880): \[java] DoubleCheckedLocking is not detected if more than 1 assignment or more than 2 if statements -* java-performance - * [#6172](https://github.com/pmd/pmd/issues/6172): \[java] InefficientEmptyStringCheck should include String#strip -* java-security - * [#6191](https://github.com/pmd/pmd/issues/6191): \[java] HardCodedCryptoKey: NPE when constants from parent class are used -* plsql-design - * [#6077](https://github.com/pmd/pmd/issues/6077): \[plsql] Excessive\*/Ncss\*Count/NPathComplexity include the metric ### ๐Ÿšจ๏ธ API Changes -#### Deprecations -* java - * The following methods have been deprecated. Due to refactoring of the internal base class, these methods are not - used anymore and are not required to be implemented anymore: - * {%jdoc !!java::lang.java.rule.design.ExcessiveImportsRule#isViolation(java::lang.java.ast.ASTCompilationUnit,int) %} - * {%jdoc !!java::lang.java.rule.design.ExcessiveParameterListRule#isViolation(java::lang.java.ast.ASTFormalParameters,int) %} - * {%jdoc !!java::lang.java.rule.design.ExcessivePublicCountRule#isViolation(java::lang.java.ast.ASTTypeDeclaration,int) %} - ### โœจ๏ธ Merged pull requests -* [#6021](https://github.com/pmd/pmd/pull/6021): \[java] Fix #5569: ExcessiveImports/ExcessiveParameterList/ExcessivePublicCount include the metric in the message - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#6022](https://github.com/pmd/pmd/pull/6022): \[apex] ExcessiveClassLength/ExcessiveParameterList include the metric in the message - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#6023](https://github.com/pmd/pmd/pull/6023): \[test] Fix #6012: Alphabetically sort all default rules - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#6024](https://github.com/pmd/pmd/pull/6024): \[java] Fix #5878: DontUseFloatTypeForLoopIndices now checks the UpdateStatement as well - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#6029](https://github.com/pmd/pmd/pull/6029): \[java] Fix UnnecessaryCast false-negative in method calls - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#6031](https://github.com/pmd/pmd/pull/6031): \[java] Fix #5880: False Negatives in DoubleCheckedLocking - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) -* [#6039](https://github.com/pmd/pmd/pull/6039): \[core] Fix #4714: trim token before feeding it to the extractor - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#6040](https://github.com/pmd/pmd/pull/6040): \[java,apex,plsql,velocity] Change description of "minimum" parameter - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#6042](https://github.com/pmd/pmd/pull/6042): \[java] Fix #2928: New Rules UnusedLabel and LabeledStatement - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#6043](https://github.com/pmd/pmd/pull/6043): \[java] Reactivate deactivated test in LocalVariableCouldBeFinal - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#6051](https://github.com/pmd/pmd/pull/6051): \[java] Fix #6038: Make AvoidCatchingGenericException configurable - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#6056](https://github.com/pmd/pmd/pull/6056): chore: fix dogfood issues from new rules - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6059](https://github.com/pmd/pmd/pull/6059): \[java] Fix #6058: DanglingJavadoc FP in module-info files - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) -* [#6061](https://github.com/pmd/pmd/pull/6061): \[core] chore: Bump minimum Java version required for building to 17 - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6071](https://github.com/pmd/pmd/pull/6071): \[java] Fix #5919: Add integration tests to ClassNamingConventions testClassRegex - [Anton Bobov](https://github.com/abobov) (@abobov) -* [#6073](https://github.com/pmd/pmd/pull/6073): \[doc] Search improvements - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6074](https://github.com/pmd/pmd/pull/6074): \[apex] Fix @SuppressWarnings with whitespace around comma - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) -* [#6077](https://github.com/pmd/pmd/pull/6077): \[plsql] Excessive*/Ncss*Count/NPathComplexity include the metric - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6078](https://github.com/pmd/pmd/pull/6078): \[java] Fix #6075: Fix FP in AssignmentInOperandRule - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#6080](https://github.com/pmd/pmd/pull/6080): \[java] Fix #6079: IdenticalCatchBranches for overriden method calls - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#6082](https://github.com/pmd/pmd/pull/6082): \[java] Fix false positives in UselessPureMethodCall for streams and atomics - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#6083](https://github.com/pmd/pmd/pull/6083): \[java] New rule IdenticalConditionalBranches - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#6085](https://github.com/pmd/pmd/pull/6085): \[java] Fix false positive for ModifierOrder - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#6093](https://github.com/pmd/pmd/pull/6093): \[ci] Fix #5873: Run integration tests with Java 25 additionally - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6097](https://github.com/pmd/pmd/pull/6097): \[doc] Add PMD versions dropdown - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6098](https://github.com/pmd/pmd/pull/6098): \[doc] Add a copy URL button - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6100](https://github.com/pmd/pmd/pull/6100): \[java] AvoidDeeplyNestedIfStmts: fix false negative with if-else - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#6101](https://github.com/pmd/pmd/pull/6101): \[doc] Highlight current header in TOC - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6112](https://github.com/pmd/pmd/pull/6112): \[java] DanglingJavadoc: fix false positive for compact constructors - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#6114](https://github.com/pmd/pmd/pull/6114): \[java] Fix #4122: CheckResultSet false-positive with local variable - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) -* [#6116](https://github.com/pmd/pmd/pull/6116): \[java] ConfusingTernary: add configuration property for null checks - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#6124](https://github.com/pmd/pmd/pull/6124): \[java] UnusedLocalVariable: fix false negatives in pattern matching - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#6128](https://github.com/pmd/pmd/pull/6128): \[java] Fix #4904: Correct class name in violation decorator - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6129](https://github.com/pmd/pmd/pull/6129): \[java] Fix #6127: Correct var name in violation decorator - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6130](https://github.com/pmd/pmd/pull/6130): \[java] UselessParentheses: fix false positives for switch expressions - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#6132](https://github.com/pmd/pmd/pull/6132): \[java] Implement main method launch protocol priorities - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#6133](https://github.com/pmd/pmd/pull/6133): \[java] Fix #5042: CloseResource: fix false positive with pattern matching - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#6150](https://github.com/pmd/pmd/pull/6150): \[core] Reduce memory usage of CPD's MatchCollector - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) -* [#6152](https://github.com/pmd/pmd/pull/6152): chore(deps): Update Saxon-HE from 12.5 to 12.9 - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#6156](https://github.com/pmd/pmd/pull/6156): \[java] Fix #6146: ClassCastException in TypeTestUtil - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#6164](https://github.com/pmd/pmd/pull/6164): \[doc] Update reproducible build info with Java 17 - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6166](https://github.com/pmd/pmd/pull/6166): \[doc] Use emoji variants - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6170](https://github.com/pmd/pmd/pull/6170): \[java] Fix #6169: AvoidUsingHardCodedIP - mention address in message - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6171](https://github.com/pmd/pmd/pull/6171): \[java] AvoidUsingHardCodedIP: fix false positive for IPv6 - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6172](https://github.com/pmd/pmd/pull/6172): \[java] InefficientEmptyStringCheck should include String#strip - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#6185](https://github.com/pmd/pmd/pull/6185): \[java] Fix #6131: Correct enum values for ModifierOrder - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6190](https://github.com/pmd/pmd/pull/6190): \[apex] Update ApexDoc rule to match the published specification - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) -* [#6191](https://github.com/pmd/pmd/pull/6191): \[java] HardCodedCryptoKey: NPE when constants from parent class are used - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) ### ๐Ÿ“ฆ๏ธ Dependency updates -* [#6034](https://github.com/pmd/pmd/pull/6034): chore(deps): bump com.puppycrawl.tools:checkstyle from 10.26.1 to 11.0.1 -* [#6054](https://github.com/pmd/pmd/pull/6054): Bump PMD from 7.16.0 to 7.17.0 -* [#6062](https://github.com/pmd/pmd/pull/6062): chore(deps): bump surefire.version from 3.5.3 to 3.5.4 -* [#6063](https://github.com/pmd/pmd/pull/6063): chore(deps): bump ruby/setup-ruby from 1.257.0 to 1.258.0 -* [#6064](https://github.com/pmd/pmd/pull/6064): chore(deps): bump com.google.code.gson:gson from 2.13.1 to 2.13.2 -* [#6065](https://github.com/pmd/pmd/pull/6065): chore(deps): bump actions/create-github-app-token from 2.1.1 to 2.1.4 -* [#6066](https://github.com/pmd/pmd/pull/6066): chore(deps): bump org.apache.groovy:groovy from 5.0.0 to 5.0.1 -* [#6067](https://github.com/pmd/pmd/pull/6067): chore(deps): bump org.apache.maven.plugins:maven-shade-plugin from 3.6.0 to 3.6.1 -* [#6068](https://github.com/pmd/pmd/pull/6068): chore(deps): bump scalameta.version from 4.13.9 to 4.13.10 -* [#6076](https://github.com/pmd/pmd/pull/6076): Bump pmdtester from 1.6.0 to 1.6.1 -* [#6086](https://github.com/pmd/pmd/pull/6086): chore(deps): bump ruby/setup-ruby from 1.258.0 to 1.263.0 -* [#6087](https://github.com/pmd/pmd/pull/6087): chore(deps-dev): bump log4j.version from 2.25.1 to 2.25.2 -* [#6088](https://github.com/pmd/pmd/pull/6088): chore(deps): bump org.mockito:mockito-core from 5.19.0 to 5.20.0 -* [#6089](https://github.com/pmd/pmd/pull/6089): chore(deps): bump org.apache.maven.plugins:maven-javadoc-plugin from 3.11.3 to 3.12.0 -* [#6090](https://github.com/pmd/pmd/pull/6090): chore(deps): bump org.codehaus.mojo:versions-maven-plugin from 2.19.0 to 2.19.1 -* [#6091](https://github.com/pmd/pmd/pull/6091): chore(deps): bump org.apache.maven.plugins:maven-compiler-plugin from 3.14.0 to 3.14.1 -* [#6094](https://github.com/pmd/pmd/pull/6094): chore(deps): Bump rexml from 3.4.1 to 3.4.4 -* [#6104](https://github.com/pmd/pmd/pull/6104): chore(deps): bump actions/cache from 4.2.4 to 4.3.0 -* [#6105](https://github.com/pmd/pmd/pull/6105): chore(deps): bump org.scala-lang:scala-library from 2.13.16 to 2.13.17 -* [#6106](https://github.com/pmd/pmd/pull/6106): chore(deps): bump junit.version from 5.13.4 to 6.0.0 -* [#6107](https://github.com/pmd/pmd/pull/6107): chore(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.5.1 to 3.6.0 -* [#6108](https://github.com/pmd/pmd/pull/6108): chore(deps): bump com.puppycrawl.tools:checkstyle from 10.26.1 to 11.1.0 -* [#6109](https://github.com/pmd/pmd/pull/6109): chore(deps-dev): bump org.assertj:assertj-core from 3.27.4 to 3.27.6 -* [#6110](https://github.com/pmd/pmd/pull/6110): chore(deps): bump org.sonatype.central:central-publishing-maven-plugin from 0.8.0 to 0.9.0 -* [#6118](https://github.com/pmd/pmd/pull/6118): chore(deps): bump com.google.protobuf:protobuf-java from 4.32.0 to 4.32.1 -* [#6119](https://github.com/pmd/pmd/pull/6119): chore(deps): bump com.github.hazendaz.maven:coveralls-maven-plugin from 4.7.0 to 5.0.0 -* [#6120](https://github.com/pmd/pmd/pull/6120): chore(deps): bump org.scala-lang:scala-reflect from 2.13.16 to 2.13.17 -* [#6121](https://github.com/pmd/pmd/pull/6121): chore(deps): bump com.github.siom79.japicmp:japicmp-maven-plugin from 0.23.1 to 0.24.1 -* [#6122](https://github.com/pmd/pmd/pull/6122): chore(deps): bump bigdecimal from 3.2.3 to 3.3.0 in /docs -* [#6136](https://github.com/pmd/pmd/pull/6136): chore(deps): bump ruby/setup-ruby from 1.263.0 to 1.265.0 -* [#6137](https://github.com/pmd/pmd/pull/6137): chore(deps): bump org.apache.maven.plugins:maven-enforcer-plugin from 3.6.1 to 3.6.2 -* [#6138](https://github.com/pmd/pmd/pull/6138): chore(deps): bump scalameta.version from 4.13.10 to 4.14.0 -* [#6139](https://github.com/pmd/pmd/pull/6139): chore(deps): bump com.puppycrawl.tools:checkstyle from 11.1.0 to 12.0.1 -* [#6140](https://github.com/pmd/pmd/pull/6140): chore(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.6.0 to 3.6.1 -* [#6141](https://github.com/pmd/pmd/pull/6141): chore(deps): bump org.ow2.asm:asm from 9.8 to 9.9 -* [#6142](https://github.com/pmd/pmd/pull/6142): chore(deps): bump org.apache.commons:commons-lang3 from 3.18.0 to 3.19.0 -* [#6143](https://github.com/pmd/pmd/pull/6143): chore(deps): bump bigdecimal from 3.3.0 to 3.3.1 in /docs -* [#6152](https://github.com/pmd/pmd/pull/6152): chore(deps): Update Saxon-HE from 12.5 to 12.9 -* [#6157](https://github.com/pmd/pmd/pull/6157): chore(deps-dev): bump com.google.guava:guava from 33.4.8-jre to 33.5.0-jre -* [#6158](https://github.com/pmd/pmd/pull/6158): chore(deps): bump scalameta.version from 4.14.0 to 4.14.1 -* [#6159](https://github.com/pmd/pmd/pull/6159): chore(deps): bump org.apache.maven.plugins:maven-dependency-plugin from 3.8.1 to 3.9.0 -* [#6160](https://github.com/pmd/pmd/pull/6160): chore(deps): bump com.github.siom79.japicmp:japicmp-maven-plugin from 0.24.1 to 0.24.2 -* [#6161](https://github.com/pmd/pmd/pull/6161): chore(deps): bump org.apache.maven.plugins:maven-pmd-plugin from 3.27.0 to 3.28.0 -* [#6162](https://github.com/pmd/pmd/pull/6162): chore(deps): bump org.apache.maven.plugins:maven-antrun-plugin from 3.1.0 to 3.2.0 -* [#6165](https://github.com/pmd/pmd/pull/6165): Bump pmdtester from 1.6.1 to 1.6.2 -* [#6173](https://github.com/pmd/pmd/pull/6173): chore(deps): bump actions/upload-artifact from 4.6.2 to 5.0.0 -* [#6174](https://github.com/pmd/pmd/pull/6174): chore(deps): bump ruby/setup-ruby from 1.265.0 to 1.267.0 -* [#6175](https://github.com/pmd/pmd/pull/6175): chore(deps): bump actions/download-artifact from 5.0.0 to 6.0.0 -* [#6178](https://github.com/pmd/pmd/pull/6178): chore(deps): bump org.checkerframework:checker-qual from 3.49.5 to 3.51.1 -* [#6179](https://github.com/pmd/pmd/pull/6179): chore(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.6.1 to 3.6.2 -* [#6180](https://github.com/pmd/pmd/pull/6180): chore(deps): bump io.github.apex-dev-tools:apex-ls_2.13 from 5.10.0 to 6.0.1 -* [#6181](https://github.com/pmd/pmd/pull/6181): chore(deps): bump org.apache.groovy:groovy from 5.0.1 to 5.0.2 -* [#6182](https://github.com/pmd/pmd/pull/6182): chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.17.7 to 1.17.8 ### ๐Ÿ“ˆ๏ธ Stats -* 233 commits -* 76 closed tickets & PRs -* Days since last release: 49 {% endtocmaker %} + diff --git a/docs/pages/release_notes_old.md b/docs/pages/release_notes_old.md index fa93d9607f2..de3d5c551c7 100644 --- a/docs/pages/release_notes_old.md +++ b/docs/pages/release_notes_old.md @@ -7,6 +7,246 @@ Previous versions of PMD can be downloaded here: [Releases - pmd/pmd (GitHub)](h +## 31-October-2025 - 7.18.0 + +The PMD team is pleased to announce PMD 7.18.0. + +This is a minor release. + +### Table Of Contents + +* [๐Ÿš€๏ธ New and noteworthy](#new-and-noteworthy) + * [Build Requirement is Java 17](#build-requirement-is-java-17) +* [๐ŸŒŸ๏ธ New and Changed Rules](#new-and-changed-rules) + * [New Rules](#new-rules) + * [Changed Rules](#changed-rules) + * [Deprecated Rules](#deprecated-rules) +* [๐Ÿ›๏ธ Fixed Issues](#fixed-issues) +* [๐Ÿšจ๏ธ API Changes](#api-changes) + * [Deprecations](#deprecations) +* [โœจ๏ธ Merged pull requests](#merged-pull-requests) +* [๐Ÿ“ฆ๏ธ Dependency updates](#dependency-updates) +* [๐Ÿ“ˆ๏ธ Stats](#stats) + +### ๐Ÿš€๏ธ New and noteworthy + +#### Build Requirement is Java 17 +From now on, Java 17 or newer is required to build PMD. PMD itself still remains compatible with Java 8, +so that it still can be used in a pure Java 8 environment. This allows us to use the latest +checkstyle version during the build. + +### ๐ŸŒŸ๏ธ New and Changed Rules +#### New Rules +* The new Java rule [`IdenticalConditionalBranches`](https://docs.pmd-code.org/pmd-doc-7.18.0/pmd_rules_java_errorprone.html#identicalconditionalbranches) finds conditional statements + that do the same thing when the condition is true and false. This is either incorrect or redundant. +* The new Java rule [`LabeledStatement`](https://docs.pmd-code.org/pmd-doc-7.18.0/pmd_rules_java_bestpractices.html#labeledstatement) finds labeled statements in code. + Labels make control flow difficult to understand and should be avoided. By default, the rule allows labeled + loops (do, while, for). But it has a property to flag also those labeled loops. +* The new Java rule [`UnusedLabel`](https://docs.pmd-code.org/pmd-doc-7.18.0/pmd_rules_java_bestpractices.html#unusedlabel) finds unused labels which are unnecessary and + only make the code hard to read. This new rule will be part of the quickstart ruleset. + +#### Changed Rules +* [`ConfusingTernary`](https://docs.pmd-code.org/pmd-doc-7.18.0/pmd_rules_java_codestyle.html#confusingternary) has a new property `nullCheckBranch` to control, whether null-checks + should be allowed (the default case) or should lead to a violation. +* [`AvoidCatchingGenericException`](https://docs.pmd-code.org/pmd-doc-7.18.0/pmd_rules_java_errorprone.html#avoidcatchinggenericexception) is now configurable with the new property + `typesThatShouldNotBeCaught`. + โš ๏ธ The rule has also been moved from category "Design" to category "Error Prone". If you are currently bulk-adding + all the rules from the "Design" category into your custom ruleset, then you need to add the rule explicitly + again (otherwise it won't be included anymore): + ```xml + + ``` + +#### Deprecated Rules +* The Java rule [`AvoidCatchingNPE`](https://docs.pmd-code.org/pmd-doc-7.18.0/pmd_rules_java_errorprone.html#avoidcatchingnpe) has been deprecated in favor of the updated rule + [`AvoidCatchingGenericException`](https://docs.pmd-code.org/pmd-doc-7.18.0/pmd_rules_java_errorprone.html#avoidcatchinggenericexception), which is now configurable. +* The Java rule [`AvoidCatchingThrowable`](https://docs.pmd-code.org/pmd-doc-7.18.0/pmd_rules_java_errorprone.html#avoidcatchingthrowable) has been deprecated in favor of the updated rule + [`AvoidCatchingGenericException`](https://docs.pmd-code.org/pmd-doc-7.18.0/pmd_rules_java_errorprone.html#avoidcatchinggenericexception), which is now configurable. + +### ๐Ÿ›๏ธ Fixed Issues +* general + * [#4714](https://github.com/pmd/pmd/issues/4714): \[core] Allow trailing commas in multivalued properties + * [#5873](https://github.com/pmd/pmd/issues/5873): \[ci] Run integration test with Java 25 + * [#6012](https://github.com/pmd/pmd/issues/6012): \[pmd-rulesets] Rulesets should be in alphabetical order + * [#6073](https://github.com/pmd/pmd/issues/6073): \[doc] Search improvements + * [#6097](https://github.com/pmd/pmd/issues/6097): \[doc] Add PMD versions dropdown + * [#6098](https://github.com/pmd/pmd/issues/6098): \[doc] Add a copy URL button + * [#6101](https://github.com/pmd/pmd/issues/6101): \[doc] Highlight current header in TOC + * [#6149](https://github.com/pmd/pmd/issues/6149): \[doc] Reproducible Build Documentation is outdated - PMD is now built using Java 17 + * [#6150](https://github.com/pmd/pmd/issues/6150): \[core] Reduce memory usage of CPD's MatchCollector +* apex + * [#5935](https://github.com/pmd/pmd/issues/5935): \[apex] @SuppressWarnings - allow whitespace around comma when suppressing multiple rules +* apex-design + * [#6022](https://github.com/pmd/pmd/issues/6022): \[apex] ExcessiveClassLength/ExcessiveParameterList include the metric in the message +* apex-documentation + * [#6189](https://github.com/pmd/pmd/issues/6189): \[apex] ApexDoc rule doesn't match published Salesforce ApexDoc specification +* java + * [#4904](https://github.com/pmd/pmd/issues/4904): \[java] Renderers output wrong class qualified name for nested classes + * [#6127](https://github.com/pmd/pmd/issues/6127): \[java] Incorrect variable name in violation + * [#6132](https://github.com/pmd/pmd/issues/6132): \[java] Implement main method launch protocol priorities + * [#6146](https://github.com/pmd/pmd/issues/6146): \[java] ClassCastException: class InferenceVarSym cannot be cast to class JClassSymbol +* java-bestpractices + * [#2928](https://github.com/pmd/pmd/issues/2928): \[java] New rules about labeled statements + * [#4122](https://github.com/pmd/pmd/issues/4122): \[java] CheckResultSet false-positive with local variable + * [#6124](https://github.com/pmd/pmd/issues/6124): \[java] UnusedLocalVariable: fix false negatives in pattern matching + * [#6169](https://github.com/pmd/pmd/issues/6169): \[java] AvoidUsingHardCodedIP: violation message should mention the hard coded address + * [#6171](https://github.com/pmd/pmd/issues/6171): \[java] AvoidUsingHardCodedIP: fix false positive for IPv6 +* java-codestyle + * [#5919](https://github.com/pmd/pmd/issues/5919): \[java] ClassNamingConventions: Include integration tests in testClassPattern by default + * [#6004](https://github.com/pmd/pmd/issues/6004): \[java] Make ConfusingTernary != null configurable + * [#6029](https://github.com/pmd/pmd/issues/6029): \[java] Fix UnnecessaryCast false-negative in method calls + * [#6057](https://github.com/pmd/pmd/issues/6057): \[java] ModifierOrder false positive on "abstract sealed class" + * [#6079](https://github.com/pmd/pmd/issues/6079): \[java] IdenticalCatchBranches: False negative for overriden method calls + * [#6123](https://github.com/pmd/pmd/issues/6123): \[java] UselessParentheses FP around switch expression + * [#6131](https://github.com/pmd/pmd/issues/6131): \[java] ModifierOrder: wrong enum values documented, indirectly causing xml parse errors +* java-design + * [#1499](https://github.com/pmd/pmd/issues/1499): \[java] AvoidDeeplyNestedIfStmts violations can be unintentionally undetected + * [#5569](https://github.com/pmd/pmd/issues/5569): \[java] ExcessivePublicCount should report number of public "things" +* java-documentation + * [#6058](https://github.com/pmd/pmd/issues/6058): \[java] DanglingJavadoc FP in module-info files + * [#6103](https://github.com/pmd/pmd/issues/6103): \[java] DanglingJavadoc false positive on record compact constructors +* java-errorprone + * [#5042](https://github.com/pmd/pmd/issues/5042): \[java] CloseResource false-positive on Pattern Matching with instanceof + * [#5878](https://github.com/pmd/pmd/issues/5878): \[java] DontUseFloatTypeForLoopIndices false-negative if variable is declared before loop + * [#6038](https://github.com/pmd/pmd/issues/6038): \[java] Merge AvoidCatchingNPE and AvoidCatchingThrowable into AvoidCatchingGenericException + * [#6055](https://github.com/pmd/pmd/issues/6055): \[java] UselessPureMethodCall false positive with AtomicInteger::getAndIncrement + * [#6060](https://github.com/pmd/pmd/issues/6060): \[java] UselessPureMethodCall false positive on ZipInputStream::getNextEntry + * [#6075](https://github.com/pmd/pmd/issues/6075): \[java] AssignmentInOperand false positive with lambda expressions + * [#6083](https://github.com/pmd/pmd/issues/6083): \[java] New rule IdenticalConditionalBranches +* java-multithreading + * [#5880](https://github.com/pmd/pmd/issues/5880): \[java] DoubleCheckedLocking is not detected if more than 1 assignment or more than 2 if statements +* java-performance + * [#6172](https://github.com/pmd/pmd/issues/6172): \[java] InefficientEmptyStringCheck should include String#strip +* java-security + * [#6191](https://github.com/pmd/pmd/issues/6191): \[java] HardCodedCryptoKey: NPE when constants from parent class are used +* plsql-design + * [#6077](https://github.com/pmd/pmd/issues/6077): \[plsql] Excessive\*/Ncss\*Count/NPathComplexity include the metric + +### ๐Ÿšจ๏ธ API Changes + +#### Deprecations +* java + * The following methods have been deprecated. Due to refactoring of the internal base class, these methods are not + used anymore and are not required to be implemented anymore: + * ExcessiveImportsRule#isViolation + * ExcessiveParameterListRule#isViolation + * ExcessivePublicCountRule#isViolation + +### โœจ๏ธ Merged pull requests + +* [#6021](https://github.com/pmd/pmd/pull/6021): \[java] Fix #5569: ExcessiveImports/ExcessiveParameterList/ExcessivePublicCount include the metric in the message - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6022](https://github.com/pmd/pmd/pull/6022): \[apex] ExcessiveClassLength/ExcessiveParameterList include the metric in the message - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6023](https://github.com/pmd/pmd/pull/6023): \[test] Fix #6012: Alphabetically sort all default rules - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6024](https://github.com/pmd/pmd/pull/6024): \[java] Fix #5878: DontUseFloatTypeForLoopIndices now checks the UpdateStatement as well - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6029](https://github.com/pmd/pmd/pull/6029): \[java] Fix UnnecessaryCast false-negative in method calls - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6031](https://github.com/pmd/pmd/pull/6031): \[java] Fix #5880: False Negatives in DoubleCheckedLocking - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#6039](https://github.com/pmd/pmd/pull/6039): \[core] Fix #4714: trim token before feeding it to the extractor - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6040](https://github.com/pmd/pmd/pull/6040): \[java,apex,plsql,velocity] Change description of "minimum" parameter - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6042](https://github.com/pmd/pmd/pull/6042): \[java] Fix #2928: New Rules UnusedLabel and LabeledStatement - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6043](https://github.com/pmd/pmd/pull/6043): \[java] Reactivate deactivated test in LocalVariableCouldBeFinal - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6051](https://github.com/pmd/pmd/pull/6051): \[java] Fix #6038: Make AvoidCatchingGenericException configurable - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6056](https://github.com/pmd/pmd/pull/6056): chore: fix dogfood issues from new rules - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6059](https://github.com/pmd/pmd/pull/6059): \[java] Fix #6058: DanglingJavadoc FP in module-info files - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#6061](https://github.com/pmd/pmd/pull/6061): \[core] chore: Bump minimum Java version required for building to 17 - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6071](https://github.com/pmd/pmd/pull/6071): \[java] Fix #5919: Add integration tests to ClassNamingConventions testClassRegex - [Anton Bobov](https://github.com/abobov) (@abobov) +* [#6073](https://github.com/pmd/pmd/pull/6073): \[doc] Search improvements - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6074](https://github.com/pmd/pmd/pull/6074): \[apex] Fix @SuppressWarnings with whitespace around comma - [Juan Martรญn Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) +* [#6077](https://github.com/pmd/pmd/pull/6077): \[plsql] Excessive*/Ncss*Count/NPathComplexity include the metric - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6078](https://github.com/pmd/pmd/pull/6078): \[java] Fix #6075: Fix FP in AssignmentInOperandRule - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6080](https://github.com/pmd/pmd/pull/6080): \[java] Fix #6079: IdenticalCatchBranches for overriden method calls - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6082](https://github.com/pmd/pmd/pull/6082): \[java] Fix false positives in UselessPureMethodCall for streams and atomics - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6083](https://github.com/pmd/pmd/pull/6083): \[java] New rule IdenticalConditionalBranches - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6085](https://github.com/pmd/pmd/pull/6085): \[java] Fix false positive for ModifierOrder - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6093](https://github.com/pmd/pmd/pull/6093): \[ci] Fix #5873: Run integration tests with Java 25 additionally - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6097](https://github.com/pmd/pmd/pull/6097): \[doc] Add PMD versions dropdown - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6098](https://github.com/pmd/pmd/pull/6098): \[doc] Add a copy URL button - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6100](https://github.com/pmd/pmd/pull/6100): \[java] AvoidDeeplyNestedIfStmts: fix false negative with if-else - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6101](https://github.com/pmd/pmd/pull/6101): \[doc] Highlight current header in TOC - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6112](https://github.com/pmd/pmd/pull/6112): \[java] DanglingJavadoc: fix false positive for compact constructors - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6114](https://github.com/pmd/pmd/pull/6114): \[java] Fix #4122: CheckResultSet false-positive with local variable - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#6116](https://github.com/pmd/pmd/pull/6116): \[java] ConfusingTernary: add configuration property for null checks - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6124](https://github.com/pmd/pmd/pull/6124): \[java] UnusedLocalVariable: fix false negatives in pattern matching - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6128](https://github.com/pmd/pmd/pull/6128): \[java] Fix #4904: Correct class name in violation decorator - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6129](https://github.com/pmd/pmd/pull/6129): \[java] Fix #6127: Correct var name in violation decorator - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6130](https://github.com/pmd/pmd/pull/6130): \[java] UselessParentheses: fix false positives for switch expressions - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6132](https://github.com/pmd/pmd/pull/6132): \[java] Implement main method launch protocol priorities - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6133](https://github.com/pmd/pmd/pull/6133): \[java] Fix #5042: CloseResource: fix false positive with pattern matching - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6150](https://github.com/pmd/pmd/pull/6150): \[core] Reduce memory usage of CPD's MatchCollector - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#6152](https://github.com/pmd/pmd/pull/6152): chore(deps): Update Saxon-HE from 12.5 to 12.9 - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6156](https://github.com/pmd/pmd/pull/6156): \[java] Fix #6146: ClassCastException in TypeTestUtil - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#6164](https://github.com/pmd/pmd/pull/6164): \[doc] Update reproducible build info with Java 17 - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6166](https://github.com/pmd/pmd/pull/6166): \[doc] Use emoji variants - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6170](https://github.com/pmd/pmd/pull/6170): \[java] Fix #6169: AvoidUsingHardCodedIP - mention address in message - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6171](https://github.com/pmd/pmd/pull/6171): \[java] AvoidUsingHardCodedIP: fix false positive for IPv6 - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6172](https://github.com/pmd/pmd/pull/6172): \[java] InefficientEmptyStringCheck should include String#strip - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6185](https://github.com/pmd/pmd/pull/6185): \[java] Fix #6131: Correct enum values for ModifierOrder - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6190](https://github.com/pmd/pmd/pull/6190): \[apex] Update ApexDoc rule to match the published specification - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) +* [#6191](https://github.com/pmd/pmd/pull/6191): \[java] HardCodedCryptoKey: NPE when constants from parent class are used - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) + +### ๐Ÿ“ฆ๏ธ Dependency updates + +* [#6034](https://github.com/pmd/pmd/pull/6034): chore(deps): bump com.puppycrawl.tools:checkstyle from 10.26.1 to 11.0.1 +* [#6054](https://github.com/pmd/pmd/pull/6054): Bump PMD from 7.16.0 to 7.17.0 +* [#6062](https://github.com/pmd/pmd/pull/6062): chore(deps): bump surefire.version from 3.5.3 to 3.5.4 +* [#6063](https://github.com/pmd/pmd/pull/6063): chore(deps): bump ruby/setup-ruby from 1.257.0 to 1.258.0 +* [#6064](https://github.com/pmd/pmd/pull/6064): chore(deps): bump com.google.code.gson:gson from 2.13.1 to 2.13.2 +* [#6065](https://github.com/pmd/pmd/pull/6065): chore(deps): bump actions/create-github-app-token from 2.1.1 to 2.1.4 +* [#6066](https://github.com/pmd/pmd/pull/6066): chore(deps): bump org.apache.groovy:groovy from 5.0.0 to 5.0.1 +* [#6067](https://github.com/pmd/pmd/pull/6067): chore(deps): bump org.apache.maven.plugins:maven-shade-plugin from 3.6.0 to 3.6.1 +* [#6068](https://github.com/pmd/pmd/pull/6068): chore(deps): bump scalameta.version from 4.13.9 to 4.13.10 +* [#6076](https://github.com/pmd/pmd/pull/6076): Bump pmdtester from 1.6.0 to 1.6.1 +* [#6086](https://github.com/pmd/pmd/pull/6086): chore(deps): bump ruby/setup-ruby from 1.258.0 to 1.263.0 +* [#6087](https://github.com/pmd/pmd/pull/6087): chore(deps-dev): bump log4j.version from 2.25.1 to 2.25.2 +* [#6088](https://github.com/pmd/pmd/pull/6088): chore(deps): bump org.mockito:mockito-core from 5.19.0 to 5.20.0 +* [#6089](https://github.com/pmd/pmd/pull/6089): chore(deps): bump org.apache.maven.plugins:maven-javadoc-plugin from 3.11.3 to 3.12.0 +* [#6090](https://github.com/pmd/pmd/pull/6090): chore(deps): bump org.codehaus.mojo:versions-maven-plugin from 2.19.0 to 2.19.1 +* [#6091](https://github.com/pmd/pmd/pull/6091): chore(deps): bump org.apache.maven.plugins:maven-compiler-plugin from 3.14.0 to 3.14.1 +* [#6094](https://github.com/pmd/pmd/pull/6094): chore(deps): Bump rexml from 3.4.1 to 3.4.4 +* [#6104](https://github.com/pmd/pmd/pull/6104): chore(deps): bump actions/cache from 4.2.4 to 4.3.0 +* [#6105](https://github.com/pmd/pmd/pull/6105): chore(deps): bump org.scala-lang:scala-library from 2.13.16 to 2.13.17 +* [#6106](https://github.com/pmd/pmd/pull/6106): chore(deps): bump junit.version from 5.13.4 to 6.0.0 +* [#6107](https://github.com/pmd/pmd/pull/6107): chore(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.5.1 to 3.6.0 +* [#6108](https://github.com/pmd/pmd/pull/6108): chore(deps): bump com.puppycrawl.tools:checkstyle from 10.26.1 to 11.1.0 +* [#6109](https://github.com/pmd/pmd/pull/6109): chore(deps-dev): bump org.assertj:assertj-core from 3.27.4 to 3.27.6 +* [#6110](https://github.com/pmd/pmd/pull/6110): chore(deps): bump org.sonatype.central:central-publishing-maven-plugin from 0.8.0 to 0.9.0 +* [#6118](https://github.com/pmd/pmd/pull/6118): chore(deps): bump com.google.protobuf:protobuf-java from 4.32.0 to 4.32.1 +* [#6119](https://github.com/pmd/pmd/pull/6119): chore(deps): bump com.github.hazendaz.maven:coveralls-maven-plugin from 4.7.0 to 5.0.0 +* [#6120](https://github.com/pmd/pmd/pull/6120): chore(deps): bump org.scala-lang:scala-reflect from 2.13.16 to 2.13.17 +* [#6121](https://github.com/pmd/pmd/pull/6121): chore(deps): bump com.github.siom79.japicmp:japicmp-maven-plugin from 0.23.1 to 0.24.1 +* [#6122](https://github.com/pmd/pmd/pull/6122): chore(deps): bump bigdecimal from 3.2.3 to 3.3.0 in /docs +* [#6136](https://github.com/pmd/pmd/pull/6136): chore(deps): bump ruby/setup-ruby from 1.263.0 to 1.265.0 +* [#6137](https://github.com/pmd/pmd/pull/6137): chore(deps): bump org.apache.maven.plugins:maven-enforcer-plugin from 3.6.1 to 3.6.2 +* [#6138](https://github.com/pmd/pmd/pull/6138): chore(deps): bump scalameta.version from 4.13.10 to 4.14.0 +* [#6139](https://github.com/pmd/pmd/pull/6139): chore(deps): bump com.puppycrawl.tools:checkstyle from 11.1.0 to 12.0.1 +* [#6140](https://github.com/pmd/pmd/pull/6140): chore(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.6.0 to 3.6.1 +* [#6141](https://github.com/pmd/pmd/pull/6141): chore(deps): bump org.ow2.asm:asm from 9.8 to 9.9 +* [#6142](https://github.com/pmd/pmd/pull/6142): chore(deps): bump org.apache.commons:commons-lang3 from 3.18.0 to 3.19.0 +* [#6143](https://github.com/pmd/pmd/pull/6143): chore(deps): bump bigdecimal from 3.3.0 to 3.3.1 in /docs +* [#6152](https://github.com/pmd/pmd/pull/6152): chore(deps): Update Saxon-HE from 12.5 to 12.9 +* [#6157](https://github.com/pmd/pmd/pull/6157): chore(deps-dev): bump com.google.guava:guava from 33.4.8-jre to 33.5.0-jre +* [#6158](https://github.com/pmd/pmd/pull/6158): chore(deps): bump scalameta.version from 4.14.0 to 4.14.1 +* [#6159](https://github.com/pmd/pmd/pull/6159): chore(deps): bump org.apache.maven.plugins:maven-dependency-plugin from 3.8.1 to 3.9.0 +* [#6160](https://github.com/pmd/pmd/pull/6160): chore(deps): bump com.github.siom79.japicmp:japicmp-maven-plugin from 0.24.1 to 0.24.2 +* [#6161](https://github.com/pmd/pmd/pull/6161): chore(deps): bump org.apache.maven.plugins:maven-pmd-plugin from 3.27.0 to 3.28.0 +* [#6162](https://github.com/pmd/pmd/pull/6162): chore(deps): bump org.apache.maven.plugins:maven-antrun-plugin from 3.1.0 to 3.2.0 +* [#6165](https://github.com/pmd/pmd/pull/6165): Bump pmdtester from 1.6.1 to 1.6.2 +* [#6173](https://github.com/pmd/pmd/pull/6173): chore(deps): bump actions/upload-artifact from 4.6.2 to 5.0.0 +* [#6174](https://github.com/pmd/pmd/pull/6174): chore(deps): bump ruby/setup-ruby from 1.265.0 to 1.267.0 +* [#6175](https://github.com/pmd/pmd/pull/6175): chore(deps): bump actions/download-artifact from 5.0.0 to 6.0.0 +* [#6178](https://github.com/pmd/pmd/pull/6178): chore(deps): bump org.checkerframework:checker-qual from 3.49.5 to 3.51.1 +* [#6179](https://github.com/pmd/pmd/pull/6179): chore(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.6.1 to 3.6.2 +* [#6180](https://github.com/pmd/pmd/pull/6180): chore(deps): bump io.github.apex-dev-tools:apex-ls_2.13 from 5.10.0 to 6.0.1 +* [#6181](https://github.com/pmd/pmd/pull/6181): chore(deps): bump org.apache.groovy:groovy from 5.0.1 to 5.0.2 +* [#6182](https://github.com/pmd/pmd/pull/6182): chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.17.7 to 1.17.8 + +### ๐Ÿ“ˆ๏ธ Stats + +* 233 commits +* 76 closed tickets & PRs +* Days since last release: 49 + + + ## 12-September-2025 - 7.17.0 The PMD team is pleased to announce PMD 7.17.0. diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index cf728eb022e..9874ebe744b 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.18.0 + 7.19.0-SNAPSHOT 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 960a40a7ac2..d9e7a1e252a 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index d4ce9a42180..7383c5a600a 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index 5ba85a5cbf7..1aebd0b7605 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index 6339fbf989d..4cbe6d81232 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index 57d08c68e74..bd7bc3bca99 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index 57f1e6a13e4..d4c2b6b9b8c 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-css/pom.xml b/pmd-css/pom.xml index 1e7ce498e30..7bac6e1a7c7 100644 --- a/pmd-css/pom.xml +++ b/pmd-css/pom.xml @@ -9,7 +9,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index 028937b9f2c..f818ec775f6 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index 3c9dd46f5df..2399aa2069c 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index fcb2e76b5f0..2562b34b318 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index ef1f67bdc5d..cd5f574a543 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index 2b8a4d59c72..21943f10843 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index 53b576455b8..91ca5158ed5 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index dd28850ad8d..9a215f640e0 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index 7b41f17cc0b..c3ba03d2f10 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index bf5269afd41..55cb2f23d87 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index b31b21b6385..49cfe4f4f0c 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index 23b9168f7e5..2ff102a7125 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index 5a653b90fd4..663de183645 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index 386f40db3cb..c4e74dcf41b 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index cb985d7e9fa..969ab3273a5 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index 59065b05244..2c97f6a03f2 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index 8f1576c144d..edf7938a5a0 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index aed87f4245c..2fb784570d1 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index e0808737d23..b678c1a7ea5 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index 62e72c91eaf..8d9d530d044 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index 895aac0015c..2843453df2f 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index d3d25a52e4d..c4249ed7ab7 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index 8e521d1ee35..4a0a0546fb3 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index bdd882d2caf..429b1c08c54 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index 4d71f6a7642..0813ca82de9 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index 919a58b309d..6c4529a777b 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index 5273c30fd0a..3aee38eda20 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index 2e92805d8aa..fb3f90ed718 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.18.0 + 7.19.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index 6dd5479ea7a..858271309bb 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.18.0 + 7.19.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index af774c3c4f5..2d7401c62a3 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index 7ab36dd8112..c72de44766c 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index 8e57bf82619..4fc7e9bf064 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index 07c2f680c72..f1e6b2d1e36 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index 808fbeb897b..4d5ebb4b7e0 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index f9df738904e..45db26ff856 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index 8467a6e7eb8..377d0b55186 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index 4b6341a0c54..9129e07466d 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.18.0 + 7.19.0-SNAPSHOT pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - pmd_releases/7.18.0 + HEAD PMD From 7ea1c318ca704df945f2241aaf942e932639526f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 31 Oct 2025 12:35:35 +0100 Subject: [PATCH 1590/1962] chore: Make warning in do-release.sh more visible [skip ci] --- do-release.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/do-release.sh b/do-release.sh index e2e8d820a99..d0c36c101d0 100755 --- a/do-release.sh +++ b/do-release.sh @@ -134,7 +134,7 @@ echo echo "* Update **../pmd.github.io/_config.yml** to mention the new release" echo echo "* Update property \`pmd-designer.version\` in **pom.xml** to reference the version, that will be released" -echo " later in this process. โš  WARNING! This does not work. You need to select an already released version." +echo " later in this process. โš ๏ธ WARNING! This does not work. You need to select an already released version." echo " See ." echo echo "Press enter to continue..." From ac4121f9b9ffff2698cd82f2c11bb81ef4b73613 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 31 Oct 2025 16:12:44 +0100 Subject: [PATCH 1591/1962] [apex] Add NCSS metric --- .../pmd/lang/apex/ast/ASTStatement.java | 1 + .../pmd/lang/apex/ast/ApexVisitorBase.java | 10 + .../pmd/lang/apex/metrics/ApexMetrics.java | 10 + .../apex/metrics/internal/NcssVisitor.java | 172 +++++++++ .../apex/metrics/internal/AllMetricsTest.java | 3 +- .../apex/metrics/internal/NcssTestRule.java | 29 ++ .../apex/metrics/internal/xml/NcssTest.xml | 332 ++++++++++++++++++ .../resources/rulesets/apex/metrics_test.xml | 14 +- .../lang/java/metrics/impl/xml/NcssTest.xml | 27 +- 9 files changed, 590 insertions(+), 8 deletions(-) create mode 100644 pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/internal/NcssVisitor.java create mode 100644 pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/NcssTestRule.java create mode 100644 pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/metrics/internal/xml/NcssTest.xml diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTStatement.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTStatement.java index d0c7f78cbef..c2ca378c92e 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTStatement.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTStatement.java @@ -6,6 +6,7 @@ import com.google.summit.ast.Node; +//TODO: deprecate! not used by ApexTreeBuilder... public final class ASTStatement extends AbstractApexNode.Single { ASTStatement(Node statement) { diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexVisitorBase.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexVisitorBase.java index ff76e12b402..905820f237b 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexVisitorBase.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexVisitorBase.java @@ -18,6 +18,16 @@ public R visit(ASTUserClass node, P data) { return visitTypeDecl(node, data); } + @Override + public R visit(ASTUserEnum node, P data) { + return visitTypeDecl(node, data); + } + + @Override + public R visit(ASTUserTrigger node, P data) { + return visitTypeDecl(node, data); + } + public R visitTypeDecl(ASTUserClassOrInterface node, P data) { return visitApexNode(node, data); } diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetrics.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetrics.java index ddf1707119d..6d051eeee00 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetrics.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetrics.java @@ -15,6 +15,7 @@ import net.sourceforge.pmd.lang.apex.ast.ApexNode; import net.sourceforge.pmd.lang.apex.metrics.internal.CognitiveComplexityVisitor; import net.sourceforge.pmd.lang.apex.metrics.internal.CognitiveComplexityVisitor.State; +import net.sourceforge.pmd.lang.apex.metrics.internal.NcssVisitor; import net.sourceforge.pmd.lang.apex.metrics.internal.StandardCycloVisitor; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.metrics.Metric; @@ -96,6 +97,10 @@ public final class ApexMetrics { Metric.of(ApexMetrics::computeCognitiveComp, isRegularApexNode(), "Cognitive Complexity"); + // TODO: javadoc + public static final Metric, Integer> NCSS = + Metric.of(ApexMetrics::computeNcss, isRegularApexNode(), + "Non-commenting source statements", "NCSS"); /** * Sum of the statistical complexity of the operations in the class. @@ -133,6 +138,11 @@ private static int computeCognitiveComp(ApexNode node, MetricOptions ignored) return state.getComplexity(); } + private static int computeNcss(ApexNode node, MetricOptions ignored) { + MutableInt result = new MutableInt(0); + node.acceptVisitor(new NcssVisitor(), result); + return result.intValue(); + } private static int computeWmc(ASTUserClassOrInterface node, MetricOptions options) { diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/internal/NcssVisitor.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/internal/NcssVisitor.java new file mode 100644 index 00000000000..b32d0af24b5 --- /dev/null +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/internal/NcssVisitor.java @@ -0,0 +1,172 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.apex.metrics.internal; + +import org.apache.commons.lang3.mutable.MutableInt; + +import net.sourceforge.pmd.lang.apex.ast.ASTBreakStatement; +import net.sourceforge.pmd.lang.apex.ast.ASTCatchBlockStatement; +import net.sourceforge.pmd.lang.apex.ast.ASTContinueStatement; +import net.sourceforge.pmd.lang.apex.ast.ASTDoLoopStatement; +import net.sourceforge.pmd.lang.apex.ast.ASTElseWhenBlock; +import net.sourceforge.pmd.lang.apex.ast.ASTExpressionStatement; +import net.sourceforge.pmd.lang.apex.ast.ASTFieldDeclarationStatements; +import net.sourceforge.pmd.lang.apex.ast.ASTForEachStatement; +import net.sourceforge.pmd.lang.apex.ast.ASTForLoopStatement; +import net.sourceforge.pmd.lang.apex.ast.ASTIfBlockStatement; +import net.sourceforge.pmd.lang.apex.ast.ASTIfElseBlockStatement; +import net.sourceforge.pmd.lang.apex.ast.ASTMethod; +import net.sourceforge.pmd.lang.apex.ast.ASTReturnStatement; +import net.sourceforge.pmd.lang.apex.ast.ASTSwitchStatement; +import net.sourceforge.pmd.lang.apex.ast.ASTThrowStatement; +import net.sourceforge.pmd.lang.apex.ast.ASTTryCatchFinallyBlockStatement; +import net.sourceforge.pmd.lang.apex.ast.ASTTypeWhenBlock; +import net.sourceforge.pmd.lang.apex.ast.ASTUserClassOrInterface; +import net.sourceforge.pmd.lang.apex.ast.ASTValueWhenBlock; +import net.sourceforge.pmd.lang.apex.ast.ASTVariableDeclarationStatements; +import net.sourceforge.pmd.lang.apex.ast.ASTWhileLoopStatement; +import net.sourceforge.pmd.lang.apex.ast.ApexVisitorBase; + +/** + * @since 7.19.0 + */ +public class NcssVisitor extends ApexVisitorBase { + + @Override + public Void visit(ASTForLoopStatement node, MutableInt data) { + data.increment(); + return super.visit(node, data); + } + + @Override + public Void visit(ASTForEachStatement node, MutableInt data) { + data.increment(); + return super.visit(node, data); + } + + @Override + public Void visit(ASTDoLoopStatement node, MutableInt data) { + data.increment(); + return super.visit(node, data); + } + + @Override + public Void visit(ASTIfBlockStatement node, MutableInt data) { + data.increment(); + return super.visit(node, data); + } + + @Override + public Void visit(ASTIfElseBlockStatement node, MutableInt data) { + if (node.hasElseStatement()) { + data.increment(); + } + return super.visit(node, data); + } + + @Override + public Void visit(ASTWhileLoopStatement node, MutableInt data) { + data.increment(); + return super.visit(node, data); + } + + @Override + public Void visit(ASTBreakStatement node, MutableInt data) { + data.increment(); + return super.visit(node, data); + } + + @Override + public Void visit(ASTTryCatchFinallyBlockStatement node, MutableInt data) { + if (node.getFinallyBlock() != null) { + data.increment(); + } + return super.visit(node, data); + } + + @Override + public Void visit(ASTCatchBlockStatement node, MutableInt data) { + data.increment(); + return super.visit(node, data); + } + + @Override + public Void visit(ASTContinueStatement node, MutableInt data) { + data.increment(); + return super.visit(node, data); + } + + @Override + public Void visit(ASTReturnStatement node, MutableInt data) { + data.increment(); + return super.visit(node, data); + } + + @Override + public Void visit(ASTThrowStatement node, MutableInt data) { + data.increment(); + return super.visit(node, data); + } + + @Override + public Void visit(ASTSwitchStatement node, MutableInt data) { + data.increment(); + return super.visit(node, data); + } + + @Override + public Void visit(ASTValueWhenBlock node, MutableInt data) { + data.increment(); + return super.visit(node, data); + } + + @Override + public Void visit(ASTElseWhenBlock node, MutableInt data) { + data.increment(); + return super.visit(node, data); + } + + @Override + public Void visit(ASTTypeWhenBlock node, MutableInt data) { + data.increment(); + return super.visit(node, data); + } + + @Override + public Void visit(ASTExpressionStatement node, MutableInt data) { + data.increment(); + return super.visit(node, data); + } + + @Override + public Void visit(ASTMethod node, MutableInt data) { + data.increment(); + return super.visit(node, data); + } + + @Override + public Void visitTypeDecl(ASTUserClassOrInterface node, MutableInt data) { + data.increment(); + return super.visitTypeDecl(node, data); + } + + @Override + public Void visit(ASTVariableDeclarationStatements node, MutableInt data) { + // doesn't count variable declared inside a for initializer + // or in switch type when block + if (!(node.getParent() instanceof ASTForLoopStatement + || node.getParent() instanceof ASTTypeWhenBlock)) { + data.increment(); + } + + return super.visit(node, data); + } + + @Override + public Void visit(ASTFieldDeclarationStatements node, MutableInt data) { + data.increment(); + return super.visit(node, data); + } +} diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/AllMetricsTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/AllMetricsTest.java index 0f8c4c2c8ca..e05c2439e75 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/AllMetricsTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/AllMetricsTest.java @@ -20,9 +20,10 @@ class AllMetricsTest extends SimpleAggregatorTst { @Override public void setUp() { + addRule(RULESET, "CognitiveComplexityTest"); addRule(RULESET, "CycloTest"); + addRule(RULESET, "NcssTest"); addRule(RULESET, "WmcTest"); - addRule(RULESET, "CognitiveComplexityTest"); } static String formatApexMessage(Node node, Integer result, String defaultMessage) { diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/NcssTestRule.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/NcssTestRule.java new file mode 100644 index 00000000000..6cb7e33121d --- /dev/null +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/metrics/internal/NcssTestRule.java @@ -0,0 +1,29 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.apex.metrics.internal; + +import net.sourceforge.pmd.lang.apex.ast.ASTMethod; +import net.sourceforge.pmd.lang.apex.ast.ASTUserClassOrInterface; +import net.sourceforge.pmd.lang.apex.metrics.ApexMetrics; +import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.test.AbstractMetricTestRule; + +public class NcssTestRule extends AbstractMetricTestRule.OfInt { + + public NcssTestRule() { + super(ApexMetrics.NCSS); + } + + @Override + protected boolean reportOn(Node node) { + return super.reportOn(node) + && (node instanceof ASTMethod || node instanceof ASTUserClassOrInterface); + } + + @Override + protected String violationMessage(Node node, Integer result) { + return AllMetricsTest.formatApexMessage(node, result, super.violationMessage(node, result)); + } +} diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/metrics/internal/xml/NcssTest.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/metrics/internal/xml/NcssTest.xml new file mode 100644 index 00000000000..76bccb7e14f --- /dev/null +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/metrics/internal/xml/NcssTest.xml @@ -0,0 +1,332 @@ + + + + 12) { + continue; + } + } + } + + super.f(z); + } + + public void foo() { + int x = 0; + x++; + + do { + if (x == 0) { + x++; + } else if (x == 1) { + x = 0; + } else { + System.out.println('Bonjour'); + throw new ScaryException('Surprise!'); + } + } while (x != 2); + } + + public static void main(String[] args) { + String k, l, m; + int x; + + bar(); + + do { + x++; + } while (x < 2); + + while (x < 4) { + x++; + } + + for (int i = 1; x < 6; ) { + x += i; + } + + { + x++; + } + + int p = + 2 + 4 + 5; + + try { + x++; + } catch (ArrayIndexOutOfBoundsException e) { + e.printStackTrace(); + } catch (ThemAll pokemon) { + pokemon.train(); + } finally { + // Do nothing + } + + bar(); + x = (int) bar(); + /* + * This is + * a comment + */ + x.foobar(); + } +} + ]]> + + + Full example + 5 + + 'Foo' has value 59. + 'Foo#Foo()' has value 2. + 'Foo#Foo(int)' has value 10. + 'Foo#foo()' has value 11. + 'Foo#main(String[])' has value 21. + + + + + + Empty ctor and method + 3 + + 'Foo' has value 3. + 'Foo#Foo()' has value 1. + 'Foo#foo()' has value 1. + + + + + + Field Declarations + 1 + + 'Foo' has value 3. + + + + + + Switch statement + 2 + + 'Foo' has value 12. + 'Foo#foo()' has value 11. + + + + + + Multiple local variable declarations + 2 + + 'Foo' has value 3. + 'Foo#foo()' has value 2. + + + + + + Try is not counted, only catch clauses and finally + 2 + + 'Foo' has value 5. + 'Foo#foo()' has value 4. + + + + + + Blocks are not counted + 2 + + 'Boo' has value 4. + 'Boo#foo()' has value 3. + + + + + + For initialisations are not counted + 2 + + 'Hoo' has value 4. + 'Hoo#foo()' has value 3. + + + + + + Nested classes are counted + 4 + + 'Boo' has value 8. + 'Boo#foo()' has value 2. + 'Boo.Barnabee' has value 5. + 'Boo.Barnabee#getX()' has value 2. + + + + + + Enum constants are not counted + 1 + + 'Shoo' has value 1. + + + + + + Abstract methods are counted + 2 + + 'Koo' has value 2. + 'Koo#bar()' has value 1. + + + + + + While/do-while loops + 2 + + 'Foo' has value 4. + 'Foo#foo(int)' has value 3. + + + + diff --git a/pmd-apex/src/test/resources/rulesets/apex/metrics_test.xml b/pmd-apex/src/test/resources/rulesets/apex/metrics_test.xml index 5b6641fb8ae..c4fc630e4d0 100644 --- a/pmd-apex/src/test/resources/rulesets/apex/metrics_test.xml +++ b/pmd-apex/src/test/resources/rulesets/apex/metrics_test.xml @@ -9,22 +9,28 @@ Metrics testing ruleset. Each metric is tested through a dummy rule. + + + - + class="net.sourceforge.pmd.lang.apex.metrics.internal.NcssTestRule"> - + class="net.sourceforge.pmd.lang.apex.metrics.internal.WmcTestRule"> diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/metrics/impl/xml/NcssTest.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/metrics/impl/xml/NcssTest.xml index a1976ba0af0..89e4b187dfc 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/metrics/impl/xml/NcssTest.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/metrics/impl/xml/NcssTest.xml @@ -219,10 +219,10 @@ public class Foo {
          - First catch is not counted + Try is not counted, only catch clauses and finally 1 - 'Foo#foo()' has value 3. + 'Foo#foo()' has value 4. + + + While/do-while loops + true + 2 + + 'Foo' has value 4. + 'Foo#foo(int)' has value 3. + + + From 54e203e0b7e65d658ec06f575930e600b7d6031f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 31 Oct 2025 17:26:37 +0100 Subject: [PATCH 1592/1962] [apex] NCSS metric javadoc --- .../pmd/lang/apex/metrics/ApexMetrics.java | 46 ++++++++++++++++++- .../apex/metrics/internal/xml/NcssTest.xml | 33 +++++++++++++ .../lang/java/metrics/impl/xml/NcssTest.xml | 37 +++++++++++++++ 3 files changed, 115 insertions(+), 1 deletion(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetrics.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetrics.java index 6d051eeee00..e532d130484 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetrics.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetrics.java @@ -97,7 +97,51 @@ public final class ApexMetrics { Metric.of(ApexMetrics::computeCognitiveComp, isRegularApexNode(), "Cognitive Complexity"); - // TODO: javadoc + /** + * Number of statements in a class or operation. Thatโ€™s roughly + * equivalent to counting the number of semicolons and opening braces + * in the program. Comments and blank lines are ignored, and statements + * spread on multiple lines count as only one (e.g. {@code int\n a;} + * counts a single statement). + * + *

          The standard version of the metric is based off [JavaNCSS](http://www.kclee.de/clemens/java/javancss/): + *

            + *
          • +1 for any of the following statements: {@code if}, {@code else}, + * {@code while}, {@code do}, {@code for}, {@code switch}, {@code break}, + * {@code continue}, {@code return}, {@code throw}, + * {@code catch}, {@code finally}. + *
          • +1 for each assignment, variable declaration (except for loop initializers) + * or statement expression. We count variables declared on the same line (e.g. + * {@code int a, b, c;}) as a single statement. + *
          • Contrary to Sonarqube, but as JavaNCSS, we count type declarations (class, interface, enum, annotation), + * and method and field declarations. + *
          + * + *
          {@code
          +     * class Foo {                         // +1, total Ncss = 12
          +     *
          +     *   public void bigMethod()           // +1
          +     *   {
          +     *     int x = 0, y = 2;               // +1
          +     *     boolean a = false, b = true;    // +1
          +     *
          +     *     if (a || b) {                   // +1
          +     *       try {                         // +1
          +     *         do {                        // +1
          +     *           x += 2;                   // +1
          +     *         } while (x < 12);
          +     *
          +     *         System.exit(0);             // +1
          +     *       } catch (IOException ioe) {   // +1
          +     *         throw new PatheticFailException(ioe); // +1
          +     *       }
          +     *     } else {
          +     *       System.out.println('false');  // +1
          +     *     }
          +     *   }
          +     * }
          +     * }
          + */ public static final Metric, Integer> NCSS = Metric.of(ApexMetrics::computeNcss, isRegularApexNode(), "Non-commenting source statements", "NCSS"); diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/metrics/internal/xml/NcssTest.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/metrics/internal/xml/NcssTest.xml index 76bccb7e14f..39fbf65b346 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/metrics/internal/xml/NcssTest.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/metrics/internal/xml/NcssTest.xml @@ -327,6 +327,39 @@ class Foo { } while (x < 10); } } +]]> + + + + Javadoc Example (net.sourceforge.pmd.lang.apex.metrics.ApexMetrics.NCSS) + 2 + + 'Foo' has value 12. + 'Foo#bigMethod()' has value 11. + + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/metrics/impl/xml/NcssTest.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/metrics/impl/xml/NcssTest.xml index 89e4b187dfc..1bb3dbacc74 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/metrics/impl/xml/NcssTest.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/metrics/impl/xml/NcssTest.xml @@ -418,6 +418,43 @@ class Foo { } while (x < 10); } } +]]> + + + + Javadoc Example net.sourceforge.pmd.lang.java.metrics.JavaMetrics.NCSS + true + 2 + + 'Foo' has value 12. + 'Foo#bigMethod()' has value 11. + + From 2ac1acb47b7cdb6ad1e5ee49c7139229b0f6c0ba Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 31 Oct 2025 17:52:55 +0100 Subject: [PATCH 1593/1962] [apex] New rule: NcssCount --- .../lang/apex/rule/design/NcssCountRule.java | 132 +++++++++++++++++ .../main/resources/category/apex/design.xml | 41 +++++ .../resources/rulesets/apex/quickstart.xml | 1 + .../lang/apex/rule/design/NcssCountTest.java | 11 ++ .../lang/apex/rule/design/xml/NcssCount.xml | 140 ++++++++++++++++++ 5 files changed, 325 insertions(+) create mode 100644 pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountRule.java create mode 100644 pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountTest.java create mode 100644 pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssCount.xml diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountRule.java new file mode 100644 index 00000000000..5bfe03eaa53 --- /dev/null +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountRule.java @@ -0,0 +1,132 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.apex.rule.design; + +import static net.sourceforge.pmd.properties.NumericConstraints.positive; + +import java.util.stream.Collectors; + +import org.checkerframework.checker.nullness.qual.NonNull; + +import net.sourceforge.pmd.lang.apex.ast.ASTMethod; +import net.sourceforge.pmd.lang.apex.ast.ASTParameter; +import net.sourceforge.pmd.lang.apex.ast.ASTUserClass; +import net.sourceforge.pmd.lang.apex.ast.ASTUserClassOrInterface; +import net.sourceforge.pmd.lang.apex.ast.ASTUserEnum; +import net.sourceforge.pmd.lang.apex.ast.ASTUserInterface; +import net.sourceforge.pmd.lang.apex.ast.ASTUserTrigger; +import net.sourceforge.pmd.lang.apex.ast.ApexNode; +import net.sourceforge.pmd.lang.apex.metrics.ApexMetrics; +import net.sourceforge.pmd.lang.apex.rule.AbstractApexRule; +import net.sourceforge.pmd.lang.metrics.MetricsUtil; +import net.sourceforge.pmd.lang.rule.RuleTargetSelector; +import net.sourceforge.pmd.properties.PropertyDescriptor; +import net.sourceforge.pmd.properties.PropertyFactory; +import net.sourceforge.pmd.reporting.RuleContext; +import net.sourceforge.pmd.util.AssertionUtil; + + +/** + * Simple rule for Ncss. + */ +public final class NcssCountRule extends AbstractApexRule { + + + private static final PropertyDescriptor METHOD_REPORT_LEVEL_DESCRIPTOR = + PropertyFactory.intProperty("methodReportLevel") + .desc("NCSS reporting threshold for methods") + .require(positive()) + .defaultValue(60) + .build(); + + private static final PropertyDescriptor CLASS_REPORT_LEVEL_DESCRIPTOR = + PropertyFactory.intProperty("classReportLevel") + .desc("NCSS reporting threshold for classes") + .require(positive()) + .defaultValue(1500) + .build(); + + public NcssCountRule() { + definePropertyDescriptor(METHOD_REPORT_LEVEL_DESCRIPTOR); + definePropertyDescriptor(CLASS_REPORT_LEVEL_DESCRIPTOR); + } + + @Override + protected @NonNull RuleTargetSelector buildTargetSelector() { + return RuleTargetSelector.forTypes(ASTUserClassOrInterface.class, ASTMethod.class); + } + + @Override + public Object visitApexNode(ApexNode node, Object data) { + int methodReportLevel = getProperty(METHOD_REPORT_LEVEL_DESCRIPTOR); + int classReportLevel = getProperty(CLASS_REPORT_LEVEL_DESCRIPTOR); + + if (node instanceof ASTUserClassOrInterface) { + visitTypeDecl((ASTUserClassOrInterface) node, classReportLevel, (RuleContext) data); + } else if (node instanceof ASTMethod) { + visitMethod((ASTMethod) node, methodReportLevel, (RuleContext) data); + } else { + throw AssertionUtil.shouldNotReachHere("node is not handled: " + node); + } + return data; + } + + + private void visitTypeDecl(ASTUserClassOrInterface node, + int level, + RuleContext data) { + + if (ApexMetrics.NCSS.supports(node)) { + int classSize = MetricsUtil.computeMetric(ApexMetrics.NCSS, node); + int classHighest = (int) MetricsUtil.computeStatistics(ApexMetrics.NCSS, node.getMethods()).getMax(); + + if (classSize >= level) { + String[] messageParams = {getPrintableNodeKind(node), + node.getSimpleName(), + classSize + " (Highest = " + classHighest + ")", }; + + asCtx(data).addViolation(node, (Object[]) messageParams); + } + } + } + + private static String getPrintableNodeKind(ASTUserClassOrInterface node) { + if (node instanceof ASTUserClass) { + return "class"; + } else if (node instanceof ASTUserInterface) { + return "interface"; + } else if (node instanceof ASTUserEnum) { + return "enum"; + } else if (node instanceof ASTUserTrigger) { + return "trigger"; + } + throw new IllegalStateException("unknown type: " + node.getClass().getName()); + } + + + private void visitMethod(ASTMethod node, + int level, + RuleContext data) { + + if (ApexMetrics.NCSS.supports(node)) { + int methodSize = MetricsUtil.computeMetric(ApexMetrics.NCSS, node); + if (methodSize >= level) { + asCtx(data).addViolation(node, node.isConstructor() ? "constructor" : "method", + displaySignature(node), "" + methodSize); + } + } + } + + private String displaySignature(ASTMethod node) { + StringBuilder sb = new StringBuilder(node.getCanonicalName()).append('('); + if (node.getArity() > 0) { + sb.append(node.children(ASTParameter.class).toStream().map(ASTParameter::getType) + .collect(Collectors.joining(","))); + } + sb.append(')'); + return sb.toString(); + } + +} diff --git a/pmd-apex/src/main/resources/category/apex/design.xml b/pmd-apex/src/main/resources/category/apex/design.xml index bf3bc637cd4..86e8a97f018 100644 --- a/pmd-apex/src/main/resources/category/apex/design.xml +++ b/pmd-apex/src/main/resources/category/apex/design.xml @@ -322,6 +322,47 @@ public class Foo extends Bar { + + + This rule uses the NCSS (Non-Commenting Source Statements) metric to determine the number of lines + of code in a class, method or constructor. NCSS ignores comments, blank lines, and only counts actual + statements. For more details on the calculation, see the documentation + {% jdoc apex::lang.apex.metrics.ApexMetrics#NCSS %}. + + 3 + + + + + + 3 diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountTest.java new file mode 100644 index 00000000000..80c211c4c43 --- /dev/null +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountTest.java @@ -0,0 +1,11 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.apex.rule.design; + +import net.sourceforge.pmd.test.PmdRuleTst; + +class NcssCountTest extends PmdRuleTst { + // no additional unit tests +} diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssCount.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssCount.xml new file mode 100644 index 00000000000..121892a3fb0 --- /dev/null +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssCount.xml @@ -0,0 +1,140 @@ + + + + 12) { + continue; + } + } + } + + super.f(z); + } + + public void foo() { + int x = 0; + x++; + + do { + if (x == 0) { + x++; + } else if (x == 1) { + x = 0; + } else { + System.out.println('Bonjour'); + throw new ScaryException('Surprise!'); + } + } while (x != 2); + } + + public static void main(String[] args) { + String k, l, m; + int x; + + bar(); + + do { + x++; + } while (x < 2); + + while (x < 4) { + x++; + } + + for (int i = 1; x < 6; ) { + x += i; + } + + { + x++; + } + + int p = + 2 + 4 + 5; + + try { + x++; + } catch (ArrayIndexOutOfBoundsException e) { + e.printStackTrace(); + } catch (ThemAll pokemon) { + pokemon.train(); + } finally { + // Do nothing + } + + bar(); + x = (int) bar(); + /* + * This is + * a comment + */ + x.foobar(); + } +} + ]]> + + + Full example + 40 + 5 + 4 + + The class 'Foo' has a NCSS line count of 59 (Highest = 21). + The constructor '<init>(int)' has a NCSS line count of 10. + The method 'foo()' has a NCSS line count of 11. + The method 'main(String[])' has a NCSS line count of 21. + + + + + + Short ctor and method + 0 + + + From 0f5a910e20bf573776fc7343cdb366a1e5f40bcb Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 31 Oct 2025 18:33:11 +0100 Subject: [PATCH 1594/1962] [apex] Report limit for NcssCount --- .../pmd/lang/apex/rule/design/NcssCountRule.java | 4 ++-- .../pmd/lang/apex/rule/design/xml/NcssCount.xml | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountRule.java index 5bfe03eaa53..20a96e6048c 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountRule.java @@ -85,7 +85,7 @@ private void visitTypeDecl(ASTUserClassOrInterface node, if (classSize >= level) { String[] messageParams = {getPrintableNodeKind(node), node.getSimpleName(), - classSize + " (Highest = " + classHighest + ")", }; + classSize + " (highest = " + classHighest + ", limit = " + level + ")", }; asCtx(data).addViolation(node, (Object[]) messageParams); } @@ -114,7 +114,7 @@ private void visitMethod(ASTMethod node, int methodSize = MetricsUtil.computeMetric(ApexMetrics.NCSS, node); if (methodSize >= level) { asCtx(data).addViolation(node, node.isConstructor() ? "constructor" : "method", - displaySignature(node), "" + methodSize); + displaySignature(node), methodSize + " (limit = " + level + ")"); } } } diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssCount.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssCount.xml index 121892a3fb0..06891a44263 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssCount.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssCount.xml @@ -113,10 +113,10 @@ public class Foo extends Bar { 5 4 - The class 'Foo' has a NCSS line count of 59 (Highest = 21). - The constructor '<init>(int)' has a NCSS line count of 10. - The method 'foo()' has a NCSS line count of 11. - The method 'main(String[])' has a NCSS line count of 21. + The class 'Foo' has a NCSS line count of 59 (highest = 21, limit = 40). + The constructor '<init>(int)' has a NCSS line count of 10 (limit = 5). + The method 'foo()' has a NCSS line count of 11 (limit = 5). + The method 'main(String[])' has a NCSS line count of 21 (limit = 5). From bffe199d4a6946a2764ddab9d10a7d10e4f99569 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 31 Oct 2025 18:43:22 +0100 Subject: [PATCH 1595/1962] [apex] Deprecate rule ExcessiveClassLength --- .../pmd/lang/apex/rule/design/ExcessiveClassLengthRule.java | 4 ++++ pmd-apex/src/main/resources/category/apex/design.xml | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveClassLengthRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveClassLengthRule.java index ea95460f9c3..1dd63015e60 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveClassLengthRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveClassLengthRule.java @@ -10,7 +10,11 @@ /** * This rule detects when a class exceeds a certain threshold. i.e. if a class * has more than 1000 lines of code. + * + *

          Equivalent XPath: {@code //ApexFile[UserClass][@EndLine - @BeginLine > 1000]} + * @deprecated Since 7.19.0. Use the rule {@link NcssCountRule} instead to find big classes. */ +@Deprecated public class ExcessiveClassLengthRule extends AbstractCounterCheckRule.AbstractLineLengthCheckRule { public ExcessiveClassLengthRule() { diff --git a/pmd-apex/src/main/resources/category/apex/design.xml b/pmd-apex/src/main/resources/category/apex/design.xml index 86e8a97f018..d3eeef6857c 100644 --- a/pmd-apex/src/main/resources/category/apex/design.xml +++ b/pmd-apex/src/main/resources/category/apex/design.xml @@ -205,6 +205,7 @@ public class Complicated { Excessive class file lengths are usually indications that the class may be burdened with excessive responsibilities that could be provided by external classes or functions. In breaking these methods -apart the code becomes more managable and ripe for reuse. +apart the code becomes more manageable and ripe for reuse. + +**Deprecated:** This rule is deprecated since PMD 7.19.0 and will be removed with PMD 8.0.0. Use {%rule NcssCount %} to find big classes. 3 From cf3268814df00c3d1faeda8bccc935c78298f639 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 31 Oct 2025 18:45:27 +0100 Subject: [PATCH 1596/1962] [apex] Deprecate rules NcssConstructorCount, NcssMethodCount, NcssTypeCount --- .../pmd/lang/apex/rule/design/AbstractNcssCountRule.java | 2 ++ .../lang/apex/rule/design/NcssConstructorCountRule.java | 2 ++ .../pmd/lang/apex/rule/design/NcssMethodCountRule.java | 2 ++ .../pmd/lang/apex/rule/design/NcssTypeCountRule.java | 2 ++ pmd-apex/src/main/resources/category/apex/design.xml | 9 +++++++++ 5 files changed, 17 insertions(+) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AbstractNcssCountRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AbstractNcssCountRule.java index adc52a8888f..c71dc186a37 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AbstractNcssCountRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AbstractNcssCountRule.java @@ -32,7 +32,9 @@ * JavaNCSS rules. * * @author ported from Java original of Jason Bennett + * @deprecated Since 7.19.0. */ +@Deprecated abstract class AbstractNcssCountRule> extends AbstractCounterCheckRule { diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssConstructorCountRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssConstructorCountRule.java index 6d22f9bc2d8..eb1cbb67bb3 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssConstructorCountRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssConstructorCountRule.java @@ -10,7 +10,9 @@ * Non-commented source statement counter for constructors. * * @author ported from Java original by Jason Bennett + * @deprecated Since 7.19.0. Use the rule {@link NcssCountRule} instead. */ +@Deprecated public class NcssConstructorCountRule extends AbstractNcssCountRule { /** diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountRule.java index d4f54677bb9..2b33f634314 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountRule.java @@ -10,7 +10,9 @@ * Non-commented source statement counter for methods. * * @author ported from Java original of Jason Bennett + * @deprecated Since 7.19.0. Use the rule {@link NcssCountRule} instead. */ +@Deprecated public class NcssMethodCountRule extends AbstractNcssCountRule { /** diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssTypeCountRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssTypeCountRule.java index 62a1d585e0d..9afc002375f 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssTypeCountRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssTypeCountRule.java @@ -10,7 +10,9 @@ * Non-commented source statement counter for type declarations. * * @author ported from Java original of Jason Bennett + * @deprecated Since 7.19.0. Use the rule {@link NcssCountRule} instead. */ +@Deprecated public class NcssTypeCountRule extends AbstractNcssCountRule { /** diff --git a/pmd-apex/src/main/resources/category/apex/design.xml b/pmd-apex/src/main/resources/category/apex/design.xml index d3eeef6857c..d05bb79add4 100644 --- a/pmd-apex/src/main/resources/category/apex/design.xml +++ b/pmd-apex/src/main/resources/category/apex/design.xml @@ -298,6 +298,7 @@ public class Foo { 3 @@ -368,6 +371,7 @@ class Foo { // +1, total Ncss = 12 3 @@ -396,6 +402,7 @@ public class Foo extends Bar { 3 From a18d68ae2487754e25bce3ef24b82f4dd2e05e86 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 31 Oct 2025 18:46:05 +0100 Subject: [PATCH 1597/1962] [apex] Update quickstart.xml: use NcssCount Remove now deprecated rules. --- .../resources/rulesets/apex/quickstart.xml | 26 +------------------ 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml b/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml index 3dcdd894005..40851c560d9 100644 --- a/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml +++ b/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml @@ -6,12 +6,6 @@ Quickstart configuration of PMD for Salesforce.com Apex. Includes the rules that are most likely to apply everywhere. - - 3 - - - - 3 @@ -24,25 +18,7 @@ - - 3 - - - - - - - 3 - - - - - - 3 - - - - + 3 From 3062628f430e99d1694873ac7980f2b383f121be Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 31 Oct 2025 18:51:11 +0100 Subject: [PATCH 1598/1962] [apex] Deprecate ASTStatement The node ASTStatement is not used and doesn't appear in the tree. --- .../net/sourceforge/pmd/lang/apex/ast/ASTStatement.java | 5 ++++- .../java/net/sourceforge/pmd/lang/apex/ast/ApexVisitor.java | 4 ++++ .../ApexUnitTestClassShouldHaveAssertsRule.java | 3 --- .../pmd/lang/apex/rule/design/AbstractNcssCountRule.java | 6 ------ 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTStatement.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTStatement.java index c2ca378c92e..179e130064f 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTStatement.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTStatement.java @@ -6,7 +6,10 @@ import com.google.summit.ast.Node; -//TODO: deprecate! not used by ApexTreeBuilder... +/** + * @deprecated Since 7.19.0. This AST node is not used and doesn't appear in the tree. + */ +@Deprecated public final class ASTStatement extends AbstractApexNode.Single { ASTStatement(Node statement) { diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexVisitor.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexVisitor.java index e53229bda7c..9b67d83efc6 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexVisitor.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexVisitor.java @@ -296,6 +296,10 @@ default R visit(ASTStandardCondition node, P data) { return visitApexNode(node, data); } + /** + * @deprecated Since 7.19.0. The node ASTStatement is not used and doesn't appear in the tree. + */ + @Deprecated default R visit(ASTStatement node, P data) { return visitApexNode(node, data); } diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestClassShouldHaveAssertsRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestClassShouldHaveAssertsRule.java index c2446e1e9d1..8f1976d0cc3 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestClassShouldHaveAssertsRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/ApexUnitTestClassShouldHaveAssertsRule.java @@ -19,7 +19,6 @@ import net.sourceforge.pmd.lang.apex.ast.ASTBlockStatement; import net.sourceforge.pmd.lang.apex.ast.ASTMethod; import net.sourceforge.pmd.lang.apex.ast.ASTMethodCallExpression; -import net.sourceforge.pmd.lang.apex.ast.ASTStatement; import net.sourceforge.pmd.lang.apex.ast.ApexNode; import net.sourceforge.pmd.properties.PropertyDescriptor; @@ -86,10 +85,8 @@ public Object visit(ASTMethod node, Object data) { private Object checkForAssertStatements(ApexNode node, Object data) { final List blockStatements = node.descendants(ASTBlockStatement.class).toList(); - final List statements = new ArrayList<>(); final List methodCalls = new ArrayList<>(); for (ASTBlockStatement blockStatement : blockStatements) { - statements.addAll(blockStatement.descendants(ASTStatement.class).toList()); methodCalls.addAll(blockStatement.descendants(ASTMethodCallExpression.class).toList()); } boolean isAssertFound = false; diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AbstractNcssCountRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AbstractNcssCountRule.java index c71dc186a37..b2a199eb8a6 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AbstractNcssCountRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/AbstractNcssCountRule.java @@ -15,7 +15,6 @@ import net.sourceforge.pmd.lang.apex.ast.ASTMethod; import net.sourceforge.pmd.lang.apex.ast.ASTMethodCallExpression; import net.sourceforge.pmd.lang.apex.ast.ASTReturnStatement; -import net.sourceforge.pmd.lang.apex.ast.ASTStatement; import net.sourceforge.pmd.lang.apex.ast.ASTThrowStatement; import net.sourceforge.pmd.lang.apex.ast.ASTTryCatchFinallyBlockStatement; import net.sourceforge.pmd.lang.apex.ast.ASTUserClass; @@ -140,11 +139,6 @@ public Integer visit(ASTThrowStatement node, Void data) { return countNodeChildren(node, data) + 1; } - @Override - public Integer visit(ASTStatement node, Void data) { - return 1; - } - @Override public Integer visit(ASTMethodCallExpression node, Void data) { return 1; From 8cb62cc910be692f6bdc47436910ac0175864288 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 31 Oct 2025 19:06:58 +0100 Subject: [PATCH 1599/1962] [doc] Update release notes (#2128) --- docs/pages/release_notes.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..ce654cd566a 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -24,10 +24,36 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy +### ๐ŸŒŸ๏ธ New and Changed Rules +#### New Rules +* The new Apex rule {% rule apex/design/NcssCount %} replaces the four rules "ExcessiveClassLength", + "NcssConstructorCount", "NcssMethodCount", and "NcssTypeCount". The new rule uses the metrics framework + to achieve the same. It has two properties, to define the report level for method and class sizes separately. + Constructors and methods are considered the same. + The rule has been added to the quickstart ruleset. + +#### Deprecated Rules +* The Apex rule {% rule apex/design/ExcessiveClassLength %} has been deprecated. Use {%rule apex/design/NcssCount %} to + find big classes or create a custom XPath based rule using + `//ApexFile[UserClass][@EndLine - @BeginLine > 1000]`. +* The Apex rules {% rule apex/design/NcssConstructorCount %}, {%rule apex/design/NcssMethodCount %}, and + {% rule apex/design/NcssTypeCount %} have been deprecated in favor or the new rule {%rule apex/design/NcssCount %}. + ### ๐Ÿ›๏ธ Fixed Issues +* apex-design + * [#2128](https://github.com/pmd/pmd/issues/2128): \[apex] Merge NCSS count rules for Apex ### ๐Ÿšจ๏ธ API Changes +#### Deprecations +* apex + * {% jdoc apex::lang.apex.rule.design.ExcessiveClassLengthRule %} + * {% jdoc apex::lang.apex.rule.design.NcssConstructorCountRule %} + * {% jdoc apex::lang.apex.rule.design.NcssMethodCountRule %} + * {% jdoc apex::lang.apex.rule.design.NcssTypeCountRule %} + * {% jdoc apex::lang.apex.ast.ASTStatement %}: This AST node is not used and doesn't appear in the tree. + * {% jdoc !ac!apex::lang.apex.ast.ApexVisitor#visit(apex::lang.apex.ast.ASTStatement,P) %} + ### โœจ๏ธ Merged pull requests From 4c7a988644a20a02ccef8458b72c732151c6c911 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 31 Oct 2025 20:12:02 +0100 Subject: [PATCH 1600/1962] [apex] NcssCount: Adjust default values Use the same limits as the old rules. NcssMethodCount used 40, NcssTypeCount used 500. Note: ExcessiveClassLength used 1000 and NcssConstructorCount used 20. --- .../sourceforge/pmd/lang/apex/rule/design/NcssCountRule.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountRule.java index 20a96e6048c..ec5cc6357cb 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountRule.java @@ -38,14 +38,14 @@ public final class NcssCountRule extends AbstractApexRule { PropertyFactory.intProperty("methodReportLevel") .desc("NCSS reporting threshold for methods") .require(positive()) - .defaultValue(60) + .defaultValue(40) .build(); private static final PropertyDescriptor CLASS_REPORT_LEVEL_DESCRIPTOR = PropertyFactory.intProperty("classReportLevel") .desc("NCSS reporting threshold for classes") .require(positive()) - .defaultValue(1500) + .defaultValue(500) .build(); public NcssCountRule() { From 4669969da2ac957ad1f24ff621980665884b2ed0 Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Mon, 3 Nov 2025 21:22:48 +0100 Subject: [PATCH 1601/1962] [java] Fix #6199: AssignmentInOperandRule: Update description of allowIncrementDecrement property --- .../errorprone/AssignmentInOperandRule.java | 2 +- .../errorprone/xml/AssignmentInOperand.xml | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java index 038db6b86f0..bedf5caddd7 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java @@ -56,7 +56,7 @@ public class AssignmentInOperandRule extends AbstractJavaRulechainRule { private static final PropertyDescriptor ALLOW_INCREMENT_DECREMENT_DESCRIPTOR = booleanProperty("allowIncrementDecrement") - .desc("Allow increment or decrement operators within the conditional expression of an if, for, or while statement") + .desc("Allow increment or decrement operators in any context") .defaultValue(false).build(); diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml index 0cba9c3dab9..6b8cfe18efe 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml @@ -248,6 +248,25 @@ public class Foo { ]]> + + allowIncrementDecrement property: allowed usages + true + 0 + + + Distinct error messages for the same line 2 From 99fa0826c3a22b8870fc2fefe87ac2e5f50ad635 Mon Sep 17 00:00:00 2001 From: lukasgraef Date: Mon, 3 Nov 2025 21:54:18 +0100 Subject: [PATCH 1602/1962] [java] Fix #6188: UnitTestsShouldIncludeAssert - FP when TestNG @Test.expectedException is present --- .../rule/internal/TestFrameworksUtil.java | 4 ++-- .../xml/UnitTestShouldIncludeAssert.xml | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java index 18bf1140634..0e00cec5c01 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java @@ -195,9 +195,9 @@ public static boolean isSoftAssert(ASTMethodCall call) { */ public static boolean isExpectAnnotated(ASTMethodDeclaration method) { return method.getDeclaredAnnotations() - .filter(TestFrameworksUtil::isJunit4TestAnnotation) + .filter(annotation -> isJunit4TestAnnotation(annotation) || isTestNgMethod(method)) .flatMap(ASTAnnotation::getMembers) - .any(it -> "expected".equals(it.getName())); + .any(it -> "expected".equals(it.getName()) || "expectedExceptions".equals(it.getName())); } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldIncludeAssert.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldIncludeAssert.xml index 78eadd31469..76ed53a41c6 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldIncludeAssert.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnitTestShouldIncludeAssert.xml @@ -892,6 +892,25 @@ class ShouldIncludeAssertTest { Assertions.assertTrue(true); } } +]]> + + + + #6188 [java] UnitTestsShouldIncludeAssert - false positive when TestNG @Test.expectedException is present + 0 + From b8bb6df5ecd5b81103fb25bb87e3cdd74c8082c3 Mon Sep 17 00:00:00 2001 From: Mitch Spano Date: Tue, 4 Nov 2025 11:45:22 -0800 Subject: [PATCH 1603/1962] Add rule to limit usage of `@Future` annotation in Apex Introduces the `AvoidFutureAnnotation` rule to encourage the use of the `Queueable` interface over the legacy `@Future` annotation for asynchronous Apex execution. --- .../resources/category/apex/bestpractices.xml | 62 +++++++ .../AvoidFutureAnnotationTest.java | 11 ++ .../xml/AvoidFutureAnnotation.xml | 166 ++++++++++++++++++ 3 files changed, 239 insertions(+) create mode 100644 pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/AvoidFutureAnnotationTest.java create mode 100644 pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/bestpractices/xml/AvoidFutureAnnotation.xml diff --git a/pmd-apex/src/main/resources/category/apex/bestpractices.xml b/pmd-apex/src/main/resources/category/apex/bestpractices.xml index b617a6eff7d..8d80f7b15bb 100644 --- a/pmd-apex/src/main/resources/category/apex/bestpractices.xml +++ b/pmd-apex/src/main/resources/category/apex/bestpractices.xml @@ -337,4 +337,66 @@ Detects when a local variable is declared and/or assigned but not used. + + +Usage of the `@Future` annotation should be limited. The `@Future` annotation is a legacy way to execute asynchronous Apex code, but it has several limitations: +- Methods must be static +- Only primitive data types, primitive arrays, or collections of primitive data types can be parameters +- No way to monitor job status or handle failures +- No support for chaining jobs + +Consider implementing the `Queueable` interface instead, which provides: +- Better error handling and monitoring capabilities +- Support for more complex data types +- Ability to chain jobs + +See more here: <https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_queueing_jobs.htm> + + 4 + + + + + + + + + + + + diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/AvoidFutureAnnotationTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/AvoidFutureAnnotationTest.java new file mode 100644 index 00000000000..7ac259cbcdb --- /dev/null +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/bestpractices/AvoidFutureAnnotationTest.java @@ -0,0 +1,11 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.apex.rule.bestpractices; + +import net.sourceforge.pmd.test.PmdRuleTst; + +class AvoidFutureAnnotationTest extends PmdRuleTst { + // no additional unit tests +} diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/bestpractices/xml/AvoidFutureAnnotation.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/bestpractices/xml/AvoidFutureAnnotation.xml new file mode 100644 index 00000000000..3320413d050 --- /dev/null +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/bestpractices/xml/AvoidFutureAnnotation.xml @@ -0,0 +1,166 @@ + + + + + Problematic apex method - @Future annotation should be avoided + 1 + 3 + + + + + Multiple @Future methods should be detected + 2 + 3,8 + + + + + Test case insensitivity - @future in lowercase should be detected + 1 + 3 + + + + + Test case insensitivity - @FUTURE in uppercase should be detected + 1 + 3 + + + + + @Future with callout parameter should be detected + 1 + 3 + + + + + Recommended Queueable implementation should not be flagged + 0 + + + + + Regular methods without @Future should not be flagged + 0 + + + + + Methods with other annotations should not be flagged + 0 + + + + + Mixed scenario - @Future should be flagged, Queueable should not + 1 + 3 + + + + + @Future annotation on methods with different access modifiers + 2 + 3,7 + + + + + From b153743a64d0de4652bf460206c208428cb5f29c Mon Sep 17 00:00:00 2001 From: Mitch Spano Date: Tue, 4 Nov 2025 16:47:39 -0800 Subject: [PATCH 1604/1962] Update alphabetical sorting --- .../resources/category/apex/bestpractices.xml | 124 +++++++++--------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/pmd-apex/src/main/resources/category/apex/bestpractices.xml b/pmd-apex/src/main/resources/category/apex/bestpractices.xml index 8d80f7b15bb..589f4413927 100644 --- a/pmd-apex/src/main/resources/category/apex/bestpractices.xml +++ b/pmd-apex/src/main/resources/category/apex/bestpractices.xml @@ -172,6 +172,68 @@ public class Foo { + + +Usage of the `@Future` annotation should be limited. The `@Future` annotation is a legacy way to execute asynchronous Apex code, but it has several limitations: +- Methods must be static +- Only primitive data types, primitive arrays, or collections of primitive data types can be parameters +- No way to monitor job status or handle failures +- No support for chaining jobs + +Consider implementing the `Queueable` interface instead, which provides: +- Better error handling and monitoring capabilities +- Support for more complex data types +- Ability to chain jobs + +See more here: <https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_queueing_jobs.htm> + + 4 + + + + + + + + + + + + - - -Usage of the `@Future` annotation should be limited. The `@Future` annotation is a legacy way to execute asynchronous Apex code, but it has several limitations: -- Methods must be static -- Only primitive data types, primitive arrays, or collections of primitive data types can be parameters -- No way to monitor job status or handle failures -- No support for chaining jobs - -Consider implementing the `Queueable` interface instead, which provides: -- Better error handling and monitoring capabilities -- Support for more complex data types -- Ability to chain jobs - -See more here: <https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_queueing_jobs.htm> - - 4 - - - - - - - - - - - - From 8f186c026467da09d096e403de0e3c39f782b864 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 6 Nov 2025 10:24:31 +0100 Subject: [PATCH 1605/1962] [apex] NcssCount: Adjust messages --- .../pmd/lang/apex/rule/design/NcssCountRule.java | 9 +++------ pmd-apex/src/main/resources/category/apex/design.xml | 2 +- .../pmd/lang/apex/rule/design/xml/NcssCount.xml | 8 ++++---- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountRule.java index ec5cc6357cb..956f1bb53f7 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountRule.java @@ -83,11 +83,8 @@ private void visitTypeDecl(ASTUserClassOrInterface node, int classHighest = (int) MetricsUtil.computeStatistics(ApexMetrics.NCSS, node.getMethods()).getMax(); if (classSize >= level) { - String[] messageParams = {getPrintableNodeKind(node), - node.getSimpleName(), - classSize + " (highest = " + classHighest + ", limit = " + level + ")", }; - - asCtx(data).addViolation(node, (Object[]) messageParams); + asCtx(data).addViolation(node, getPrintableNodeKind(node), + node.getSimpleName(), classSize, level + ", highest: " + classHighest); } } } @@ -114,7 +111,7 @@ private void visitMethod(ASTMethod node, int methodSize = MetricsUtil.computeMetric(ApexMetrics.NCSS, node); if (methodSize >= level) { asCtx(data).addViolation(node, node.isConstructor() ? "constructor" : "method", - displaySignature(node), methodSize + " (limit = " + level + ")"); + displaySignature(node), methodSize, level); } } } diff --git a/pmd-apex/src/main/resources/category/apex/design.xml b/pmd-apex/src/main/resources/category/apex/design.xml index d05bb79add4..012f699d11a 100644 --- a/pmd-apex/src/main/resources/category/apex/design.xml +++ b/pmd-apex/src/main/resources/category/apex/design.xml @@ -330,7 +330,7 @@ public class Foo extends Bar { diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssCount.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssCount.xml index 06891a44263..10d1001b6d3 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssCount.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssCount.xml @@ -113,10 +113,10 @@ public class Foo extends Bar { 5 4 - The class 'Foo' has a NCSS line count of 59 (highest = 21, limit = 40). - The constructor '<init>(int)' has a NCSS line count of 10 (limit = 5). - The method 'foo()' has a NCSS line count of 11 (limit = 5). - The method 'main(String[])' has a NCSS line count of 21 (limit = 5). + The class 'Foo' has a NCSS line count of 59 (limit: 40, highest: 21). + The constructor '<init>(int)' has a NCSS line count of 10 (limit: 5). + The method 'foo()' has a NCSS line count of 11 (limit: 5). + The method 'main(String[])' has a NCSS line count of 21 (limit: 5). From a1a3b59619173e7aa644fb13555726d054634cfd Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 6 Nov 2025 12:13:41 +0100 Subject: [PATCH 1606/1962] [apex] NcssMetric: fix documentation about try/catch/finally --- .../pmd/lang/apex/metrics/ApexMetrics.java | 4 ++-- .../lang/apex/metrics/internal/xml/NcssTest.xml | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetrics.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetrics.java index e532d130484..9674c49159b 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetrics.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetrics.java @@ -126,7 +126,7 @@ public final class ApexMetrics { * boolean a = false, b = true; // +1 * * if (a || b) { // +1 - * try { // +1 + * try { * do { // +1 * x += 2; // +1 * } while (x < 12); @@ -135,7 +135,7 @@ public final class ApexMetrics { * } catch (IOException ioe) { // +1 * throw new PatheticFailException(ioe); // +1 * } - * } else { + * } else { // +1 * System.out.println('false'); // +1 * } * } diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/metrics/internal/xml/NcssTest.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/metrics/internal/xml/NcssTest.xml index 39fbf65b346..082a3345a96 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/metrics/internal/xml/NcssTest.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/metrics/internal/xml/NcssTest.xml @@ -202,12 +202,12 @@ public class Foo { 'Foo#foo()' has value 4. Date: Thu, 6 Nov 2025 12:14:14 +0100 Subject: [PATCH 1607/1962] [java] NcssMetric: fix documentation about try/catch/finally --- .../pmd/lang/java/metrics/JavaMetrics.java | 4 ++-- .../pmd/lang/java/metrics/impl/xml/NcssTest.xml | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java index 736ca5dd180..31fa04c75ba 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java @@ -282,7 +282,7 @@ public final class JavaMetrics { * boolean a = false, b = true; // +1 * * if (a || b) { // +1 - * try { // +1 + * try { * do { // +1 * x += 2; // +1 * } while (x < 12); @@ -291,7 +291,7 @@ public final class JavaMetrics { * } catch (IOException ioe) { // +1 * throw new PatheticFailException(ioe); // +1 * } - * } else { + * } else { // +1 * assert false; // +1 * } * } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/metrics/impl/xml/NcssTest.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/metrics/impl/xml/NcssTest.xml index 1bb3dbacc74..7a9490c88ba 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/metrics/impl/xml/NcssTest.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/metrics/impl/xml/NcssTest.xml @@ -226,11 +226,11 @@ public class Foo { Date: Thu, 6 Nov 2025 12:15:14 +0100 Subject: [PATCH 1608/1962] [apex] NcssMetric: test case to show differences to old rules --- docs/pages/release_notes.md | 7 +- .../apex/metrics/internal/xml/NcssTest.xml | 167 ++++++++++++++++++ 2 files changed, 173 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index ce654cd566a..7bcafec235d 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -30,7 +30,12 @@ This is a {{ site.pmd.release_type }} release. "NcssConstructorCount", "NcssMethodCount", and "NcssTypeCount". The new rule uses the metrics framework to achieve the same. It has two properties, to define the report level for method and class sizes separately. Constructors and methods are considered the same. - The rule has been added to the quickstart ruleset. + The rule has been added to the quickstart ruleset. + Note: The new metric is implemented more correct than in the old rules. E.g. it considers now also + switch statements and correctly counts if-statements only once and ignores method calls that are + part of an expression and not a statement on their own. This leads to different numbers. Keep in mind, + that NCSS counts statements and not lines of code. Statements that are split on multiple lines are + still counted as one. #### Deprecated Rules * The Apex rule {% rule apex/design/ExcessiveClassLength %} has been deprecated. Use {%rule apex/design/NcssCount %} to diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/metrics/internal/xml/NcssTest.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/metrics/internal/xml/NcssTest.xml index 082a3345a96..a3362390894 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/metrics/internal/xml/NcssTest.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/metrics/internal/xml/NcssTest.xml @@ -360,6 +360,173 @@ class Foo { // +1, total Ncss = 12 } } } +]]> + + + + Differences to old NcssTypeCount / NcssMethodCount rules + 2 + + 'Foo' has value 48. + 'Foo#start(Id)' has value 47. + + net.sourceforge.pmd.lang.apex.metrics.internal.NcssVisitor + * old == old AbstractNcssCountRule (base for NcssTypeCount and NcssMethodCount) + * + * sums (type): new = 48 | old = 68 + * sums (method): new = 47 | old = 67 + * + * Some helper XPaths to help count the nodes: + (: for old AbstractNcssCountRule :) +//Method[1+13+16+5+32 = + count(.//WhileLoopStatement) + + count(.//ForLoopStatement) + + count(.//ForEachStatement) + + count(.//DoLoopStatement) + + count(.//BreakStatement) + + count(.//ContinueStatement) + + count(.//ThrowStatement) + + count(.//FieldDeclaration) + + count(.//TryCatchFinallyBlockStatement) (: 1 :) + + count(.//IfBlockStatement) (: 13 :) + + 2*count(.//IfElseBlockStatement) (: 2*8=16 :) + + count(.//ReturnStatement) (: 5 :) + + count(.//MethodCallExpression[not(.//MethodCallExpression)]) (: 32 :) +] +| //IfBlockStatement (: for manual verification :) + + (: for new NCSS metric :) +//Method[13+2+1+5+22+3 = + count(.//ForLoopStatement) + + count(.//ForEachStatement) + + count(.//DoLoopStatement) + + count(.//IfBlockStatement) (: 13 :) + + count(.//IfElseBlockStatement[@ElseStatement = true()]) (: 2 :) + + count(.//WhileLoopStatement) + + count(.//BreakStatement) + + count(.//TryCatchFinallyBlockStatement[*[last()][local-name() != 'CatchBlockStatement']]) + + count(.//CatchBlockStatement) (: 1 :) + + count(.//ContinueStatement) + + count(.//ReturnStatement) (: 5 :) + + count(.//ThrowStatement) + + count(.//SwitchStatement) + + count(.//ValueWhenBlock) + + count(.//ElseWhenBlock) + + count(.//TypeWhenBlock) + + count(.//ExpressionStatement) (: 22 :) + + count(.//VariableDeclarationStatements) (: 3 :) +] +| //ExpressionStatement (: for manual verification :) + */ +class Foo { // new: +1 | old: +1 + void start(Id jobId) { // new: +1 | old: +0 + System.abortJob(jobId); // new: +1 | old: +1 + + try { // new: +0 | old: +1 + this.entry = [ // new: +1 | old: +0 + SELECT + Name, + AnonymousCode__c, + AsyncApexJobId__c, + BatchSize__c, + Class__c, + DailyEnd__c, + DailyStartDateTime__c, + End__c, + Flow__c, + IsBatchable__c, + IsDaily__c, + IsSchedulable__c, + NumberOfExecutions__c, + RepeatInterval__c, + RescheduleInterval__c, + Start__c, + OwnerId, + Owner.IsActive + FROM SchedulomaticEntry__c + WHERE Id = :entryId + ]; + + if (!this.entry.Owner.IsActive) { // new: +1 | old: +2 +1 + logExecutionError(entryId, EXECUTION_ERROR_INACTIVE_OWNER); // new: +1 | old: +1 + return; // new: +1 | old: +1 + } else if (!hasPermission(this.entry.OwnerId)) { // new: +1 | old: +1 +1 + logExecutionError(entryId, EXECUTION_ERROR_MISSING_PERMISSIONS); // new: +1 | old: +1 + return; // new: +1 | old: +1 + } + } catch (QueryException e) { // new: +1 | old: +0 + return; // new: +1 | old: +1 + } + + if (isBeforeOrNoEndDateTime()) { // new: +1 | old: +2 +1 +1 + if (String.isNotBlank(entry.Class__c)) { // new: +1 | old: +2 +1 +1 + String c = entry.Class__c; // new: +1 | old: +0 + String namespacePrefix; // new: +1 | old: +0 + String name; // new: +1 | old: +0 + + if (c.contains('__')) { // new: +1 | old: +2 +1 +1 + namespacePrefix = c.substringBefore('__'); // new: +1 | old: +1 + name = c.substringAfter('__'); // new: +1 | old: +1 + } else { // new: +1 | old: +0 + namespacePrefix = null; // new: +1 | old: +0 + name = c; // new: +1 | old: +0 + } + + classToExecute = Test.isRunningTest() // new: +1 | old: +1 + ? BATCHABLE_TYPE // new: +0 | old: +0 + : Type.forName(namespacePrefix, name); // new: +0 | old: +1 + + if (classToExecute == null) { // new: +1 | old: +2 +1 + logExecutionError(entry.Id, EXECUTION_ERROR_INVALID_CLASS); // new: +1 | old: +1 + return; // new: +1 | old: +1 + } else if ( // new: +1 | old: +1 + !(entry.IsBatchable__c && + BATCHABLE_TYPE.isAssignableFrom(classToExecute) || // new: +0 | old: +1 + entry.IsSchedulable__c && + SCHEDULABLE_TYPE.isAssignableFrom(classToExecute)) // new: +0 | old: +1 + ) { + logExecutionError(entry.Id, EXECUTION_ERROR_INVALID_CLASS); // new: +1 | old: +1 + return; // new: +1 | old: +1 + } + } + + if ( // new: +1 | old: +2 +1 + String.isNotBlank(entry.Class__c) || // new: +0 | old: +1 + String.isNotBlank(entry.Flow__c) || // new: +0 | old: +1 + String.isNotBlank(entry.AnonymousCode__c) // new: +0 | old: +1 + ) { + if (canStartMore()) { // new: +1 | old: +2 +1 +1 + executeJob(); // new: +1 | old: +1 + + if (isPositiveInteger(entry.RepeatInterval__c)) { // new: +1 | old: +2 +1 +1 + entry.Start__c = Datetime.now() // new: +1 | old: +1 + .addMinutes((Integer) entry.RepeatInterval__c); + incrementExecutions(); // new: +1 | old: +1 + reschedule(); // new: +1 | old: +1 + } else if (entry.IsDaily__c) { // new: +1 | old: +1 + incrementExecutions(); // new: +1 | old: +1 + rescheduleForTomorrow(); // new: +1 | old: +1 + } else { // new: +1 | old: +0 + incrementExecutions(); // new: +1 | old: +1 + updateEntry(); // new: +1 | old: +1 + } + } else if (isPositiveInteger(entry.RescheduleInterval__c)) { // new: +1 | old: +1 +1 + entry.Start__c = Datetime.now() // new: +1 | old: +1 + .addMinutes((Integer) entry.RescheduleInterval__c); + reschedule(); // new: +1 | old: +1 + } + } + } else if (entry.IsDaily__c) { // new: +1 | old: +1 + rescheduleForTomorrow(); // new: +1 | old: +1 + } + } +} ]]> From 77ed98db2fae205c8e13a94ac8283d5f83c724cc Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 6 Nov 2025 12:19:50 +0100 Subject: [PATCH 1609/1962] [apex] NcssMetric: javadoc since --- .../java/net/sourceforge/pmd/lang/apex/metrics/ApexMetrics.java | 1 + 1 file changed, 1 insertion(+) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetrics.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetrics.java index 9674c49159b..8b3af12e433 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetrics.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetrics.java @@ -141,6 +141,7 @@ public final class ApexMetrics { * } * } * } + * @since 7.19.0 */ public static final Metric, Integer> NCSS = Metric.of(ApexMetrics::computeNcss, isRegularApexNode(), From 5482af77d0e7b4be38742f8dd0feb641cfb9d7e9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 30 Oct 2025 17:16:08 +0100 Subject: [PATCH 1610/1962] [java] New Rule: EnumComparison --- .../resources/category/java/bestpractices.xml | 41 +++++++++++++++++++ .../bestpractices/EnumComparisonTest.java | 11 +++++ .../rule/bestpractices/xml/EnumComparison.xml | 38 +++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/bestpractices/EnumComparisonTest.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/EnumComparison.xml diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index 7206103ac40..d18ad2736a2 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -541,6 +541,47 @@ return a; + + +When comparing enums, `equals()` should be avoided and `==` should be preferred. + +Using `==` has some advantages: +* same semantic as `equals()` +* less problematic with possible null pointer exceptions +* supports static type check: If you compare two incompatible enum types, the compiler will tell you. + When using equals, you'll only get noticed at runtime or not at all. + +This rule implements SonarSource rule [S4551](https://sonarsource.github.io/rspec/#/rspec/S4551). + + 3 + + + + + + + + + + + + Example + 1 + 4-4 + + + + + Example 2 + 1 + 3-3 + + + \ No newline at end of file From e7de25f04d1fc0c725ebcb7e18df8819c173b4b6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 6 Nov 2025 15:23:35 +0100 Subject: [PATCH 1611/1962] [java] EnumComparison: only one side of equals is an enum --- .../resources/category/java/bestpractices.xml | 8 +++- .../rule/bestpractices/xml/EnumComparison.xml | 48 +++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml index d18ad2736a2..abfbff1ee8d 100644 --- a/pmd-java/src/main/resources/category/java/bestpractices.xml +++ b/pmd-java/src/main/resources/category/java/bestpractices.xml @@ -557,14 +557,18 @@ Using `==` has some advantages: When using equals, you'll only get noticed at runtime or not at all. This rule implements SonarSource rule [S4551](https://sonarsource.github.io/rspec/#/rspec/S4551). + +Note, that only primitive types and enums should be compared using `==`. To compare other +objects, `equals()` is the correct way. See {%rule java/errorprone/CompareObjectsWithEquals %} +and {%rule java/errorprone/UseEqualsToCompareStrings %}. 3 diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/EnumComparison.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/EnumComparison.xml index fb0022fa43b..89b2cd19393 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/EnumComparison.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/EnumComparison.xml @@ -33,6 +33,54 @@ class Foo { if (state1 == state2) {} // correct } } +]]> + + + + Four different cases, at least one enum + 4 + 6-6,7-7,10-10,11-11 + + + + + Incompatible enums + 2 + 9-9,10-10 + \ No newline at end of file From 38c35b9ce218ed2b539b44e28814a2a5b808885e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 30 Oct 2025 16:45:28 +0100 Subject: [PATCH 1612/1962] chore: always compare enums with == --- .../pmd/lang/visualforce/ast/ApexClassPropertyTypes.java | 2 +- .../sourceforge/pmd/lang/visualforce/ast/ObjectFieldTypes.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/ApexClassPropertyTypes.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/ApexClassPropertyTypes.java index 027379e3405..512045558db 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/ApexClassPropertyTypes.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/ApexClassPropertyTypes.java @@ -98,7 +98,7 @@ private Node parseApex(String contextExpr, Path apexFilePath) { @Override protected DataType putDataType(String name, DataType dataType) { DataType previousType = super.putDataType(name, dataType); - if (previousType != null && !previousType.equals(dataType)) { + if (previousType != null && previousType != dataType) { // It is possible to have a property and method with different types that appear the same to this code. An // example is an Apex class with a property "public String Foo {get; set;}" and a method of // "Integer getFoo() { return 1; }". In this case set the value as Unknown because we can't be sure which it diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/ObjectFieldTypes.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/ObjectFieldTypes.java index 8218ab6a0ef..27dfa348764 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/ObjectFieldTypes.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/ObjectFieldTypes.java @@ -299,7 +299,7 @@ private boolean endsWithIgnoreCase(String str, String suffix) { @Override protected DataType putDataType(String name, DataType dataType) { DataType previousType = super.putDataType(name, dataType); - if (previousType != null && !previousType.equals(dataType)) { + if (previousType != null && previousType != dataType) { // It should not be possible to have conflicting types for CustomFields throw new RuntimeException("Conflicting types for " + name From 6b6c555f29a40f75f012c538231de37e4c42f353 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 30 Oct 2025 18:38:48 +0100 Subject: [PATCH 1613/1962] more fixes --- .../pmd/lang/java/rule/codestyle/ConfusingTernaryRule.java | 2 +- .../visualforce/rule/security/internal/ElEscapeDetector.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryRule.java index 1a2b44b3ce0..9b589d25d2c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryRule.java @@ -103,7 +103,7 @@ private boolean isMatch(ASTExpression node) { private static boolean isUnaryNot(ASTExpression node) { // look for "!x" return node instanceof ASTUnaryExpression - && ((ASTUnaryExpression) node).getOperator().equals(UnaryOp.NEGATION); + && ((ASTUnaryExpression) node).getOperator() == UnaryOp.NEGATION; } private boolean isNotEquals(ASTExpression node) { diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/rule/security/internal/ElEscapeDetector.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/rule/security/internal/ElEscapeDetector.java index 5fad98694d9..aa525c2e969 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/rule/security/internal/ElEscapeDetector.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/rule/security/internal/ElEscapeDetector.java @@ -335,7 +335,7 @@ public static boolean doesElContainAnyUnescapedIdentifiers(final ASTElExpression break; } - if (e.equals(Escaping.ANY)) { + if (e == Escaping.ANY) { for (Escaping esc : Escaping.values()) { if (id.getImage().equalsIgnoreCase(esc.toString())) { isEscaped = true; From 356fbfd20193125f2805ec40a1f87c86c73d75fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Nov 2025 16:47:23 +0100 Subject: [PATCH 1614/1962] chore(deps): bump junit.version from 6.0.0 to 6.0.1 (#6205) Bumps `junit.version` from 6.0.0 to 6.0.1. Updates `org.junit.platform:junit-platform-launcher` from 6.0.0 to 6.0.1 - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r6.0.0...r6.0.1) Updates `org.junit:junit-bom` from 6.0.0 to 6.0.1 - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r6.0.0...r6.0.1) Updates `org.junit.platform:junit-platform-commons` from 6.0.0 to 6.0.1 - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r6.0.0...r6.0.1) --- updated-dependencies: - dependency-name: org.junit.platform:junit-platform-launcher dependency-version: 6.0.1 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.junit:junit-bom dependency-version: 6.0.1 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.junit.platform:junit-platform-commons dependency-version: 6.0.1 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9129e07466d..b48993cb8c8 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ ${maven.compiler.test.target} 2.2.10 5.9.1 - 6.0.0 + 6.0.1 2.0.0 5.0 From ccd94c4797f874b728dbc722713326899162d2ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Nov 2025 16:47:44 +0100 Subject: [PATCH 1615/1962] chore(deps): bump org.checkerframework:checker-qual from 3.51.1 to 3.52.0 (#6206) chore(deps): bump org.checkerframework:checker-qual Bumps [org.checkerframework:checker-qual](https://github.com/typetools/checker-framework) from 3.51.1 to 3.52.0. - [Release notes](https://github.com/typetools/checker-framework/releases) - [Changelog](https://github.com/typetools/checker-framework/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/typetools/checker-framework/compare/checker-framework-3.51.1...checker-framework-3.52.0) --- updated-dependencies: - dependency-name: org.checkerframework:checker-qual dependency-version: 3.52.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b48993cb8c8..669accb9422 100644 --- a/pom.xml +++ b/pom.xml @@ -903,7 +903,7 @@ org.checkerframework checker-qual - 3.51.1 + 3.52.0 net.sf.saxon From 85aa2b5f782a4dfb5f96475bf67ce27359d92838 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Nov 2025 16:48:19 +0100 Subject: [PATCH 1616/1962] chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.17.7 to 1.17.8 (#6207) chore(deps-dev): bump net.bytebuddy:byte-buddy-agent Bumps [net.bytebuddy:byte-buddy-agent](https://github.com/raphw/byte-buddy) from 1.17.7 to 1.17.8. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.17.7...byte-buddy-1.17.8) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy-agent dependency-version: 1.17.8 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 669accb9422..c766480716f 100644 --- a/pom.xml +++ b/pom.xml @@ -1044,7 +1044,7 @@ net.bytebuddy byte-buddy-agent - 1.17.7 + 1.17.8 test From 4f70f65e7cd64ac65148b9e7f8c3976b4b2b1406 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Nov 2025 16:48:38 +0100 Subject: [PATCH 1617/1962] chore(deps): bump com.google.protobuf:protobuf-java from 4.32.1 to 4.33.0 (#6208) chore(deps): bump com.google.protobuf:protobuf-java Bumps [com.google.protobuf:protobuf-java](https://github.com/protocolbuffers/protobuf) from 4.32.1 to 4.33.0. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl) - [Commits](https://github.com/protocolbuffers/protobuf/commits) --- updated-dependencies: - dependency-name: com.google.protobuf:protobuf-java dependency-version: 4.33.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c766480716f..cd734bbdd99 100644 --- a/pom.xml +++ b/pom.xml @@ -1134,7 +1134,7 @@ com.google.protobuf protobuf-java - 4.32.1 + 4.33.0 +* [#6214](https://github.com/pmd/pmd/pull/6214): \[plsql] New rule NcssCount to replace old Ncss*Count rules - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ๏ธ Dependency updates From e0ed2b99d24744889f5c41eb20cb5a199903d6d0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 13 Nov 2025 15:45:34 +0100 Subject: [PATCH 1628/1962] [apex] Deprecate old rule tests --- .../pmd/lang/apex/rule/design/ExcessiveClassLengthTest.java | 4 ++++ .../pmd/lang/apex/rule/design/NcssConstructorCountTest.java | 4 ++++ .../pmd/lang/apex/rule/design/NcssMethodCountTest.java | 4 ++++ .../pmd/lang/apex/rule/design/NcssTypeCountTest.java | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveClassLengthTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveClassLengthTest.java index f988c628f46..1d8a032fa60 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveClassLengthTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessiveClassLengthTest.java @@ -6,6 +6,10 @@ import net.sourceforge.pmd.test.PmdRuleTst; +/** + * @deprecated Since 7.19.0. + */ +@Deprecated class ExcessiveClassLengthTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssConstructorCountTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssConstructorCountTest.java index a6168f0f90b..ad2b8cdb7d2 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssConstructorCountTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssConstructorCountTest.java @@ -6,6 +6,10 @@ import net.sourceforge.pmd.test.PmdRuleTst; +/** + * @deprecated Since 7.19.0. + */ +@Deprecated class NcssConstructorCountTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountTest.java index c019fc10acb..9d8b53b6fff 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountTest.java @@ -6,6 +6,10 @@ import net.sourceforge.pmd.test.PmdRuleTst; +/** + * @deprecated Since 7.19.0. + */ +@Deprecated class NcssMethodCountTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssTypeCountTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssTypeCountTest.java index 463d797e57f..a33a04c09f8 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssTypeCountTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/rule/design/NcssTypeCountTest.java @@ -6,6 +6,10 @@ import net.sourceforge.pmd.test.PmdRuleTst; +/** + * @deprecated Since 7.19.0. + */ +@Deprecated class NcssTypeCountTest extends PmdRuleTst { // no additional unit tests } From f545bcea0539bf22a16be4a9853f22bef8c1af67 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 13 Nov 2025 15:45:46 +0100 Subject: [PATCH 1629/1962] [apex] Register NCSS metric --- .../java/net/sourceforge/pmd/lang/apex/ApexLanguageHandler.java | 1 + 1 file changed, 1 insertion(+) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexLanguageHandler.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexLanguageHandler.java index cf4ef96cb7e..c8ce564fda0 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexLanguageHandler.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexLanguageHandler.java @@ -48,6 +48,7 @@ private static final class ApexMetricsProvider implements LanguageMetricsProvide private final Set> metrics = setOf( ApexMetrics.COGNITIVE_COMPLEXITY, ApexMetrics.CYCLO, + ApexMetrics.NCSS, ApexMetrics.WEIGHED_METHOD_COUNT ); From 628ff805db9255f48eab2d18dbe3741de079bfb3 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 13 Nov 2025 15:46:11 +0100 Subject: [PATCH 1630/1962] [apex] Remove unneeded cast in NcssCountRule --- .../pmd/lang/apex/rule/design/NcssCountRule.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountRule.java index 956f1bb53f7..5982c8374e1 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssCountRule.java @@ -76,14 +76,14 @@ public Object visitApexNode(ApexNode node, Object data) { private void visitTypeDecl(ASTUserClassOrInterface node, int level, - RuleContext data) { + RuleContext ruleContext) { if (ApexMetrics.NCSS.supports(node)) { int classSize = MetricsUtil.computeMetric(ApexMetrics.NCSS, node); int classHighest = (int) MetricsUtil.computeStatistics(ApexMetrics.NCSS, node.getMethods()).getMax(); if (classSize >= level) { - asCtx(data).addViolation(node, getPrintableNodeKind(node), + ruleContext.addViolation(node, getPrintableNodeKind(node), node.getSimpleName(), classSize, level + ", highest: " + classHighest); } } @@ -105,12 +105,12 @@ private static String getPrintableNodeKind(ASTUserClassOrInterface node) { private void visitMethod(ASTMethod node, int level, - RuleContext data) { + RuleContext ruleContext) { if (ApexMetrics.NCSS.supports(node)) { int methodSize = MetricsUtil.computeMetric(ApexMetrics.NCSS, node); if (methodSize >= level) { - asCtx(data).addViolation(node, node.isConstructor() ? "constructor" : "method", + ruleContext.addViolation(node, node.isConstructor() ? "constructor" : "method", displaySignature(node), methodSize, level); } } From 50b368f03229c217872591ce190fc38a247a8b61 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 13 Nov 2025 15:46:44 +0100 Subject: [PATCH 1631/1962] [doc] Update release notes (#6198) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 7bcafec235d..14d66c56bf3 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -61,6 +61,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ๏ธ Merged pull requests +* [#6198](https://github.com/pmd/pmd/pull/6198): \[apex] New rule NcssCount to replace old Ncss*Count rules - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ๏ธ Dependency updates From 7e795a387b884930292a0e9b33c93404ab660789 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 13 Nov 2025 15:56:18 +0100 Subject: [PATCH 1632/1962] [java] UseArraysAsList: skip when if-statements Fixes #4577 --- docs/pages/release_notes.md | 2 ++ .../resources/category/java/performance.xml | 4 +-- .../rule/performance/xml/UseArraysAsList.xml | 33 +++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..527bf52da8f 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,6 +25,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy ### ๐Ÿ›๏ธ Fixed Issues +* java-performance + * [#4577](https://github.com/pmd/pmd/issues/4577): \[java] UseArraysAsList with condition in loop ### ๐Ÿšจ๏ธ API Changes diff --git a/pmd-java/src/main/resources/category/java/performance.xml b/pmd-java/src/main/resources/category/java/performance.xml index c00a066bb2f..38355b6cbb0 100644 --- a/pmd-java/src/main/resources/category/java/performance.xml +++ b/pmd-java/src/main/resources/category/java/performance.xml @@ -715,7 +715,7 @@ You must use `new ArrayList<>(Arrays.asList(...))` if that is inconvenient for y ] ] [*[2]//FieldAccess[@Name = 'length']/VariableAccess[pmd-java:typeIs("java.lang.Object[]")]] - /*[last()]/ExpressionStatement/ + /*[last()][not(IfStatement)]/ExpressionStatement/ MethodCall [pmd-java:matchesSig('java.util.List#add(_)')] [ArgumentList/ArrayAccess @@ -724,7 +724,7 @@ You must use `new ArrayList<>(Arrays.asList(...))` if that is inconvenient for y | //ForeachStatement [VariableAccess[pmd-java:typeIs("java.lang.Object[]")]] - /*[last()]/ExpressionStatement/MethodCall + /*[last()][not(IfStatement)]/ExpressionStatement/MethodCall [pmd-java:matchesSig('java.util.List#add(_)')] [ArgumentList [VariableAccess[@Name = ancestor::ForeachStatement/LocalVariableDeclaration/VariableDeclarator/VariableId/@Name]] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseArraysAsList.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseArraysAsList.xml index c561f360107..68cfd94dd34 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseArraysAsList.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseArraysAsList.xml @@ -274,6 +274,39 @@ public class Foo { // e.g. this.hashSet = Arrays.asList(myArray); won't compile } } +]]> + + + + #4577 [java] UseArraysAsList with condition in loop + 0 + convertToNonEmptyList(String[] arr) { + List resultList = new ArrayList<>(); + for (String item: arr) { + if (item.isEmpty()) { + continue; + } + resultList.add(item); + } + return resultList; + } + + public List convertToNonEmptyList2(String[] arr) { + List resultList = new ArrayList<>(); + for (int i = 0; i < arr.length; i++) { + if (arr[i].isEmpty()) { + continue; + } + resultList.add(arr[i]); + } + return resultList; + } +} ]]> From e5b634b5c2e354cb1f048a29584aa8a7da5c502c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 13 Nov 2025 16:10:54 +0100 Subject: [PATCH 1633/1962] [java] UseArraysAsList: check increment Fixes #5071 --- docs/pages/release_notes.md | 2 ++ .../resources/category/java/performance.xml | 6 +++++ .../rule/performance/xml/UseArraysAsList.xml | 24 +++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..402ac140640 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,6 +25,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy ### ๐Ÿ›๏ธ Fixed Issues +* java-performance + * [#5071](https://github.com/pmd/pmd/issues/5071): \[java] UseArraysAsList should not warn when elements are skipped in array ### ๐Ÿšจ๏ธ API Changes diff --git a/pmd-java/src/main/resources/category/java/performance.xml b/pmd-java/src/main/resources/category/java/performance.xml index c00a066bb2f..746f0bd0c61 100644 --- a/pmd-java/src/main/resources/category/java/performance.xml +++ b/pmd-java/src/main/resources/category/java/performance.xml @@ -715,6 +715,12 @@ You must use `new ArrayList<>(Arrays.asList(...))` if that is inconvenient for y ] ] [*[2]//FieldAccess[@Name = 'length']/VariableAccess[pmd-java:typeIs("java.lang.Object[]")]] + [ForUpdate + [StatementExpressionList + [UnaryExpression[@Operator = '++'] + | AssignmentExpression[@Operator = '+='][NumericLiteral[@IntLiteral][@Image = '1']]] + ] + ] /*[last()]/ExpressionStatement/ MethodCall [pmd-java:matchesSig('java.util.List#add(_)')] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseArraysAsList.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseArraysAsList.xml index c561f360107..bcb91b42d50 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseArraysAsList.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseArraysAsList.xml @@ -274,6 +274,30 @@ public class Foo { // e.g. this.hashSet = Arrays.asList(myArray); won't compile } } +]]> + + + + #5071 [java] UseArraysAsList should not warn when elements are skipped in array + 0 + keySet(String... entrySet) { + final List result = new ArrayList<>(entrySet.length / 2); + for (int i = 0; i < entrySet.length; i += 2) { + result.add(entrySet[i]); // false positive here + } + return result; + } +} ]]> From 7764d1d8976682106db3c6ef83a0e7d1f2d7dee9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 13 Nov 2025 16:46:10 +0100 Subject: [PATCH 1634/1962] chore: remove public methods from SourceManager SourceManager itself is package-private, so the effective visibility of those methods won't be public anyway. Fixes #5701 --- docs/pages/release_notes.md | 2 ++ .../main/java/net/sourceforge/pmd/cpd/SourceManager.java | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..0caa511c75e 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,6 +25,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy ### ๐Ÿ›๏ธ Fixed Issues +* general + * [#5701](https://github.com/pmd/pmd/issues/5701): \[core] net.sourceforge.pmd.cpd.SourceManager has public methods ### ๐Ÿšจ๏ธ API Changes diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceManager.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceManager.java index 3d2de6b3882..3e47e03cd26 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceManager.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/SourceManager.java @@ -66,7 +66,7 @@ TextDocument get(TextFile file) { return textDocument; } - public int size() { + int size() { return files.size(); } @@ -80,7 +80,7 @@ public void close() throws IOException { } @SuppressWarnings("PMD.CloseResource") - public Chars getSlice(Mark mark) { + Chars getSlice(Mark mark) { TextFile textFile = fileByPathId.get(mark.getToken().getFileId()); assert textFile != null : "No such file " + mark.getToken().getFileId(); TextDocument doc = get(textFile); @@ -90,7 +90,7 @@ public Chars getSlice(Mark mark) { return doc.sliceOriginalText(lineRange); } - public String getFileDisplayName(FileId fileId) { + String getFileDisplayName(FileId fileId) { return fileNameRenderer.getDisplayName(fileId); } } From a07e9173b24f26780eb44e1c14267b7ccf4ef65e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Nov 2025 17:41:19 +0100 Subject: [PATCH 1635/1962] chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.17.8 to 1.18.0 (#6219) chore(deps-dev): bump net.bytebuddy:byte-buddy-agent Bumps [net.bytebuddy:byte-buddy-agent](https://github.com/raphw/byte-buddy) from 1.17.8 to 1.18.0. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.17.8...byte-buddy-1.18.0) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy-agent dependency-version: 1.18.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 757071dddf7..cf3ed9d32ae 100644 --- a/pom.xml +++ b/pom.xml @@ -1044,7 +1044,7 @@ net.bytebuddy byte-buddy-agent - 1.17.8 + 1.18.0 test From 656569f57f4127194fbd868e5787e5fb76e4573e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Nov 2025 17:41:47 +0100 Subject: [PATCH 1636/1962] chore(deps): bump org.apache.maven.plugins:maven-release-plugin from 3.1.1 to 3.2.0 (#6220) chore(deps): bump org.apache.maven.plugins:maven-release-plugin Bumps [org.apache.maven.plugins:maven-release-plugin](https://github.com/apache/maven-release) from 3.1.1 to 3.2.0. - [Release notes](https://github.com/apache/maven-release/releases) - [Commits](https://github.com/apache/maven-release/compare/maven-release-3.1.1...maven-release-3.2.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-release-plugin dependency-version: 3.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cf3ed9d32ae..b5c3472bd5d 100644 --- a/pom.xml +++ b/pom.xml @@ -188,7 +188,7 @@ org.apache.maven.plugins maven-release-plugin - 3.1.1 + 3.2.0 pmd-release,sign true From 439a33251a11321c9319364e02b1b0885fb4a78a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Nov 2025 17:42:51 +0100 Subject: [PATCH 1637/1962] chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.17.8 to 1.18.0 (#6221) Bumps [net.bytebuddy:byte-buddy](https://github.com/raphw/byte-buddy) from 1.17.8 to 1.18.0. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.17.8...byte-buddy-1.18.0) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-version: 1.18.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b5c3472bd5d..f0386a8c3b1 100644 --- a/pom.xml +++ b/pom.xml @@ -1038,7 +1038,7 @@ net.bytebuddy byte-buddy - 1.17.8 + 1.18.0 test From 4e109606c08d5f3f77550626b4e0c0962c5cee7c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Nov 2025 17:43:24 +0100 Subject: [PATCH 1638/1962] chore(deps): bump com.puppycrawl.tools:checkstyle from 12.1.1 to 12.1.2 (#6222) Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 12.1.1 to 12.1.2. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-12.1.1...checkstyle-12.1.2) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-version: 12.1.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f0386a8c3b1..ac79f36ac60 100644 --- a/pom.xml +++ b/pom.xml @@ -91,7 +91,7 @@ 5.0 3.5.4 - 12.1.1 + 12.1.2 3.6.0 3.28.0 1.10.15 From 33f00ec1fa9e3581cb6d87582e7984017798a04b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Nov 2025 17:44:08 +0100 Subject: [PATCH 1639/1962] chore(deps): bump org.sonarsource.scanner.maven:sonar-maven-plugin from 5.2.0.4988 to 5.3.0.6276 (#6223) chore(deps): bump org.sonarsource.scanner.maven:sonar-maven-plugin Bumps [org.sonarsource.scanner.maven:sonar-maven-plugin](https://github.com/SonarSource/sonar-scanner-maven) from 5.2.0.4988 to 5.3.0.6276. - [Release notes](https://github.com/SonarSource/sonar-scanner-maven/releases) - [Commits](https://github.com/SonarSource/sonar-scanner-maven/compare/5.2.0.4988...5.3.0.6276) --- updated-dependencies: - dependency-name: org.sonarsource.scanner.maven:sonar-maven-plugin dependency-version: 5.3.0.6276 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ac79f36ac60..5cfd0c0cf79 100644 --- a/pom.xml +++ b/pom.xml @@ -1306,7 +1306,7 @@ org.sonarsource.scanner.maven sonar-maven-plugin - 5.2.0.4988 + 5.3.0.6276 From a9f54e52008f70e292f117c925357d63c4e1d8ff Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Mon, 17 Nov 2025 21:24:03 +0100 Subject: [PATCH 1640/1962] [java] Detect generated equals/hashCode in Comparable Detect generated equals and hashCode in Comparable when neither method has been implemented manually. --- ...BothEqualsAndHashCodeOnComparableRule.java | 14 ++++- ...rrideBothEqualsAndHashCodeOnComparable.xml | 55 +++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java index d6085df7320..04fa02db8d0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java @@ -4,8 +4,13 @@ package net.sourceforge.pmd.lang.java.rule.errorprone; +import static net.sourceforge.pmd.util.CollectionUtil.setOf; + +import java.util.Set; + import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration; +import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; import net.sourceforge.pmd.lang.java.types.JPrimitiveType; import net.sourceforge.pmd.lang.java.types.TypeTestUtil; import net.sourceforge.pmd.reporting.RuleContext; @@ -24,6 +29,11 @@ public class OverrideBothEqualsAndHashCodeOnComparableRule extends OverrideBothE private static final String MISSING_HASH_CODE = MESSAGE_PREFIX + "hashCode() should be overridden"; private static final String MISSING_EQUALS = MESSAGE_PREFIX + "equals() should be overridden"; private static final String MISSING_EQUALS_AND_HASH_CODE = MESSAGE_PREFIX + "both equals() and hashCode() should be overridden"; + private static final Set GENERATED_EQUALS_HASHCODE = setOf( + "lombok.EqualsAndHashCode", + "lombok.Data", + "lombok.Value" + ); @Override protected boolean skipType(ASTTypeDeclaration node) { @@ -47,7 +57,9 @@ protected void maybeReport(RuleContext ctx, ASTTypeDeclaration node, ASTMethodDe } if (equalsMethod == null && hashCodeMethod == null) { - ctx.addViolationWithMessage(compareToMethod, MISSING_EQUALS_AND_HASH_CODE); + if (!JavaAstUtils.hasAnyAnnotation(node, GENERATED_EQUALS_HASHCODE)) { + ctx.addViolationWithMessage(compareToMethod, MISSING_EQUALS_AND_HASH_CODE); + } } else if (equalsMethod == null) { ctx.addViolationWithMessage(hashCodeMethod, MISSING_EQUALS); } else if (hashCodeMethod == null) { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml index 652d837a21c..d84872bf6d2 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml @@ -363,4 +363,59 @@ } ]]> + + Equals and hashcode generated by Lombok + 2 + 34,45 + { + @Override + public int compareTo(Succeed other) { + return 0; + } + } + @Data + public class SucceedData implements Comparable { + @Override + public int compareTo(SucceedData other) { + return 0; + } + } + @Value + public class SucceedValue implements Comparable { + @Override + public int compareTo(SucceedValue other) { + return 0; + } + } + + @EqualsAndHashCode + public class FailManualEquals implements Comparable { + @Override + public int compareTo(FailManualEquals other) { + return 0; + } + @Override + public boolean equals(Object o) { + return false; + } + } + @EqualsAndHashCode + public class FailManualHashCode implements Comparable { + @Override + public int compareTo(FailManualHashCode other) { + return 0; + } + @Override + public int hashCode() { + return 0; + } + } + ]]> + From 4b54a448377172f335b64c5f3d03552bfb04c481 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Nov 2025 16:06:04 +0100 Subject: [PATCH 1641/1962] [core] Deprecate old symboltable API Fixes #4767 --- .../adding_a_new_javacc_based_language.md | 4 ++-- docs/pages/release_notes.md | 9 +++++++++ .../lang/symboltable/AbstractNameDeclaration.java | 3 +++ .../pmd/lang/symboltable/AbstractScope.java | 3 +++ .../sourceforge/pmd/lang/symboltable/Applier.java | 4 ++++ .../pmd/lang/symboltable/ImageFinderFunction.java | 4 ++++ .../pmd/lang/symboltable/NameDeclaration.java | 3 +++ .../pmd/lang/symboltable/NameOccurrence.java | 2 ++ .../net/sourceforge/pmd/lang/symboltable/Scope.java | 3 +++ .../sourceforge/pmd/lang/symboltable/ScopedNode.java | 3 +++ .../pmd/lang/symboltable/package-info.java | 12 ++++++++++++ .../pmd/lang/symboltable/ApplierTest.java | 4 ++++ 12 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/package-info.java diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md index 67023498937..2ef27ffc353 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md @@ -3,7 +3,7 @@ title: Adding PMD support for a new JavaCC grammar based language short_title: Adding a new language with JavaCC tags: [devdocs, extending] summary: "How to add a new language to PMD using JavaCC grammar." -last_updated: December 2023 (7.0.0) +last_updated: November 2025 (7.19.0) sidebar: pmd_sidebar permalink: pmd_devdocs_major_adding_new_language_javacc.html folder: pmd/devdocs @@ -293,7 +293,7 @@ see [Java-specific features and guidance](pmd_languages_java.html). {% capture deprecated_symbols_api_note %} With PMD 7.0.0 the symbol table and type resolution implementation has been rewritten from scratch. There is still an old API for symbol table support, that is used by PLSQL, -see {% jdoc_package core::lang.symboltable %}. This will be deprecated and should not be used. +see {% jdoc_package core::lang.symboltable %}. This has been deprecated and should not be used. {% endcapture %} {% include note.html content=deprecated_symbols_api_note %} diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..ac7e6be0936 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,9 +25,18 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy ### ๐Ÿ›๏ธ Fixed Issues +* core + * [#4767](https://github.com/pmd/pmd/issues/4767): \[core] Deprecate old symboltable API ### ๐Ÿšจ๏ธ API Changes +#### Deprecations +* core + * {%jdoc_package core::lang.symboltable %}: All classes in this package are deprecated. + The symbol table and type resolution implementation for Java has been rewritten from scratch + for PMD 7.0.0. This package is the remains of the old symbol table API, that is only used by + PL/SQL. For PMD 8.0.0 all these classes will be removed from pmd-core. + ### โœจ๏ธ Merged pull requests diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/AbstractNameDeclaration.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/AbstractNameDeclaration.java index 5e282fb3dba..39c9f3d7c78 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/AbstractNameDeclaration.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/AbstractNameDeclaration.java @@ -6,7 +6,10 @@ /** * Base class for all name declarations. + * + * @deprecated Since 7.19.0. For more info, see {@link net.sourceforge.pmd.lang.symboltable}. */ +@Deprecated public abstract class AbstractNameDeclaration implements NameDeclaration { protected ScopedNode node; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/AbstractScope.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/AbstractScope.java index 8c4bebedf2c..48381c339d6 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/AbstractScope.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/AbstractScope.java @@ -14,7 +14,10 @@ /** * Base class for any {@link Scope}. Provides useful default implementations. + * + * @deprecated Since 7.19.0. For more info, see {@link net.sourceforge.pmd.lang.symboltable}. */ +@Deprecated public abstract class AbstractScope implements Scope { private Scope parent; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/Applier.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/Applier.java index 2e7c968265a..45c5c47a8cd 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/Applier.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/Applier.java @@ -7,6 +7,10 @@ import java.util.Iterator; import java.util.function.Predicate; +/** + * @deprecated Since 7.19.0. For more info, see {@link net.sourceforge.pmd.lang.symboltable}. + */ +@Deprecated public final class Applier { private Applier() { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/ImageFinderFunction.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/ImageFinderFunction.java index 2ac2b9cba74..7dc0f3ce85c 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/ImageFinderFunction.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/ImageFinderFunction.java @@ -10,6 +10,10 @@ import java.util.Set; import java.util.function.Predicate; +/** + * @deprecated Since 7.19.0. For more info, see {@link net.sourceforge.pmd.lang.symboltable}. + */ +@Deprecated public class ImageFinderFunction implements Predicate { private final Set images; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/NameDeclaration.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/NameDeclaration.java index cf352b6be0a..0e48d709c91 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/NameDeclaration.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/NameDeclaration.java @@ -7,7 +7,10 @@ /** * This is a declaration of a name, e.g. a variable or method name. See * {@link AbstractNameDeclaration} for a base class. + * + * @deprecated Since 7.19.0. For more info, see {@link net.sourceforge.pmd.lang.symboltable}. */ +@Deprecated public interface NameDeclaration { /** diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/NameOccurrence.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/NameOccurrence.java index cc5b4de311a..be415f03d91 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/NameOccurrence.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/NameOccurrence.java @@ -7,7 +7,9 @@ /** * A {@link NameOccurrence} represents one usage of a name declaration. * + * @deprecated Since 7.19.0. For more info, see {@link net.sourceforge.pmd.lang.symboltable}. */ +@Deprecated public interface NameOccurrence { /** * Gets the location where the usage occurred. diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/Scope.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/Scope.java index c7a60b246eb..2bda65ebff5 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/Scope.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/Scope.java @@ -17,7 +17,10 @@ * @see Java * Language Specification, 6.3: Scope of a Declaration + * + * @deprecated Since 7.19.0. For more info, see {@link net.sourceforge.pmd.lang.symboltable}. */ +@Deprecated public interface Scope { /** * Retrieves this scope's parent diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/ScopedNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/ScopedNode.java index 612c9339d60..53bfbc2b021 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/ScopedNode.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/ScopedNode.java @@ -8,7 +8,10 @@ /** * A {@link Node} which knows about the scope within it has been declared. + * + * @deprecated Since 7.19.0. For more info, see {@link net.sourceforge.pmd.lang.symboltable}. */ +@Deprecated public interface ScopedNode extends Node { Scope getScope(); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/package-info.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/package-info.java new file mode 100644 index 00000000000..79d79b996c1 --- /dev/null +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/package-info.java @@ -0,0 +1,12 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +/** + * @deprecated Since 7.19.0. All classes in this package are deprecated. The symbol table and type + * resolution implementation for Java has been rewritten from scratch for PMD 7.0.0. This package + * is the remains of the old symbol table API, that is only used by PL/SQL. For PMD 8.0.0 all these + * classes will be removed from pmd-core. + */ +@Deprecated +package net.sourceforge.pmd.lang.symboltable; diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/symboltable/ApplierTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/symboltable/ApplierTest.java index 6699ac73c50..042a5f839e0 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/symboltable/ApplierTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/symboltable/ApplierTest.java @@ -12,6 +12,10 @@ import org.junit.jupiter.api.Test; +/** + * @deprecated Since 7.19.0. For more info, see {@link net.sourceforge.pmd.lang.symboltable}. + */ +@Deprecated class ApplierTest { private static class MyFunction implements Predicate { From 8be617a2ac161acf1687f117f4b0d3c089ffaa1b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Nov 2025 17:48:12 +0100 Subject: [PATCH 1642/1962] chore: fail build for compiler warnings --- .../net/sourceforge/pmd/lang/visualforce/DataType.java | 9 +-------- pom.xml | 4 ++++ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/DataType.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/DataType.java index bab5aa35b48..45efabccf9d 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/DataType.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/DataType.java @@ -119,15 +119,8 @@ public static DataType fromTypeName(String value) { return dataType; } - DataType(boolean requiresEscaping) { - this(requiresEscaping, null); - } - DataType(boolean requiresEscaping, String... basicTypeNames) { this.requiresEscaping = requiresEscaping; - this.basicTypeNames = new HashSet<>(); - if (basicTypeNames != null) { - this.basicTypeNames.addAll(Arrays.asList(basicTypeNames)); - } + this.basicTypeNames = new HashSet<>(Arrays.asList(basicTypeNames)); } } diff --git a/pom.xml b/pom.xml index 5cfd0c0cf79..6a03a61852d 100644 --- a/pom.xml +++ b/pom.xml @@ -274,6 +274,10 @@ 3.14.1 ${java.version} + true + + -Xlint:-options + From 1113abb6e895e9240dc63973f9e9d3b6254d07e1 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Nov 2025 18:58:17 +0100 Subject: [PATCH 1643/1962] [doc] tools - sort alphabetically --- docs/pages/pmd/userdocs/tools/tools.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/docs/pages/pmd/userdocs/tools/tools.md b/docs/pages/pmd/userdocs/tools/tools.md index bfe22149a2f..9fb272a945c 100644 --- a/docs/pages/pmd/userdocs/tools/tools.md +++ b/docs/pages/pmd/userdocs/tools/tools.md @@ -3,13 +3,24 @@ title: Tools / Integrations tags: [userdocs, tools] permalink: pmd_userdocs_tools.html author: David Dixon-Peugh -last_updated: December 2024 (7.9.0) +last_updated: November 2025 (7.19.0) --- ## Automated Code Review {% include note.html content="The tools are listed in alphabetical order without rating." %} +### Blue Cave + +[Blue Cave](https://bluecave.io) is a code quality and test coverage reporting platform, focused on large monorepos. +It integrates directly with GitHub to provide Pull Request merge checks and supports GitHub Actions amongst other CI using +[native plugins](https://docs.bluecave.io/languages/java/) for Gradle, Maven and Bazel. + +Blue Cave uses PMD for static analysis of Java code, enhancing it with code coverage and other features. + +* Homepage: +* Documentation: + ### CodeClimate Quality [CodeClimate Quality](https://codeclimate.com/quality) provides automatic code reviews and quality @@ -79,16 +90,6 @@ With TCA you have PMD analysis out-of-the-box, and it is open source under the M * Documentation: * Maintainer: TCA -### Blue Cave -[Blue Cave](https://bluecave.io) is a code quality and test coverage reporting platform, focused on large monorepos. -It integrates directly with GitHub to provide Pull Request merge checks and supports GitHub Actions amongst other CI using -[native plugins](https://docs.bluecave.io/languages/java/) for Gradle, Maven and Bazel. - -Blue Cave uses PMD for static analysis of Java code, enhancing it with code coverage and other features. - -* Homepage: -* Documentation: - ## Others ### MegaLinter From 81d592377e93e58f5a9bdd26bf0c141d9ee8ec36 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Nov 2025 18:58:48 +0100 Subject: [PATCH 1644/1962] [doc] Update release notes (#6217) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..cd7f35823b6 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -30,6 +30,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ๏ธ Merged pull requests +* [#6217](https://github.com/pmd/pmd/pull/6217): \[doc] Add Blue Cave to known tools using PMD - [Jude Pereira](https://github.com/judepereira) (@judepereira) ### ๐Ÿ“ฆ๏ธ Dependency updates From 26c17b2ba1a1bcf0a82653b6d7a1aa9dc8c15b37 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Nov 2025 19:11:14 +0100 Subject: [PATCH 1645/1962] [doc] Update release notes (#6203, #6204) --- docs/pages/release_notes.md | 9 +++++++++ pmd-apex/src/main/resources/rulesets/apex/quickstart.xml | 1 + 2 files changed, 10 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..61f8ace1739 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -24,12 +24,21 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy +### ๐ŸŒŸ๏ธ New and Changed Rules +#### New Rules +* The new Apex rule {%rule apex/bestpractices/AvoidFutureAnnotation %} finds usages of the `@Future` + annotation. It is a legacy way to execute asynchronous Apex code. New code should implement + the `Queueable` interface instead. + ### ๐Ÿ›๏ธ Fixed Issues +* apex-bestpractices + * [#6203](https://github.com/pmd/pmd/issues/6203): \[apex] New Rule: Avoid Future Annotation ### ๐Ÿšจ๏ธ API Changes ### โœจ๏ธ Merged pull requests +* [#6204](https://github.com/pmd/pmd/pull/6204): \[apex] Add rule to limit usage of @Future annotation - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) ### ๐Ÿ“ฆ๏ธ Dependency updates diff --git a/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml b/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml index 5ef4cf434a5..68d4d5b0002 100644 --- a/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml +++ b/pmd-apex/src/main/resources/rulesets/apex/quickstart.xml @@ -209,6 +209,7 @@ + 3 From c58108697b476db5045fee2419199a1cc7368012 Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Thu, 20 Nov 2025 20:48:41 +0100 Subject: [PATCH 1646/1962] Refactor: Specify that Lombok generates code --- .../OverrideBothEqualsAndHashCodeOnComparableRule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java index 04fa02db8d0..a9e009bd3cd 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java @@ -29,7 +29,7 @@ public class OverrideBothEqualsAndHashCodeOnComparableRule extends OverrideBothE private static final String MISSING_HASH_CODE = MESSAGE_PREFIX + "hashCode() should be overridden"; private static final String MISSING_EQUALS = MESSAGE_PREFIX + "equals() should be overridden"; private static final String MISSING_EQUALS_AND_HASH_CODE = MESSAGE_PREFIX + "both equals() and hashCode() should be overridden"; - private static final Set GENERATED_EQUALS_HASHCODE = setOf( + private static final Set LOMBOK_GENERATED_EQUALS_HASHCODE = setOf( "lombok.EqualsAndHashCode", "lombok.Data", "lombok.Value" From 2ab3618d7301fb8659e9bc819c42e9874779ff5a Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Thu, 20 Nov 2025 20:53:21 +0100 Subject: [PATCH 1647/1962] Refactor: Use annotation check as additional guard clause --- .../OverrideBothEqualsAndHashCodeOnComparableRule.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java index a9e009bd3cd..a2b18d9a28f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java @@ -56,10 +56,13 @@ protected void maybeReport(RuleContext ctx, ASTTypeDeclaration node, ASTMethodDe return; } + if (equalsMethod == null && hashCodeMethod == null + && JavaAstUtils.hasAnyAnnotation(node, LOMBOK_GENERATED_EQUALS_HASHCODE)) { + return; + } + if (equalsMethod == null && hashCodeMethod == null) { - if (!JavaAstUtils.hasAnyAnnotation(node, GENERATED_EQUALS_HASHCODE)) { - ctx.addViolationWithMessage(compareToMethod, MISSING_EQUALS_AND_HASH_CODE); - } + ctx.addViolationWithMessage(compareToMethod, MISSING_EQUALS_AND_HASH_CODE); } else if (equalsMethod == null) { ctx.addViolationWithMessage(hashCodeMethod, MISSING_EQUALS); } else if (hashCodeMethod == null) { From acf3f129d33c3fe1e364ed0f29c736b7b12bf20e Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Thu, 20 Nov 2025 21:23:06 +0100 Subject: [PATCH 1648/1962] Doc: Add comment about violations in tests --- .../xml/OverrideBothEqualsAndHashCodeOnComparable.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml index d84872bf6d2..116df9f962f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml @@ -401,7 +401,7 @@ return 0; } @Override - public boolean equals(Object o) { + public boolean equals(Object o) { // violation, line 35 return false; } } @@ -412,7 +412,7 @@ return 0; } @Override - public int hashCode() { + public int hashCode() { // violation, line 45 return 0; } } From 32247845572b740c5fe132c7faf9ebde9e128a8c Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Thu, 20 Nov 2025 21:52:49 +0100 Subject: [PATCH 1649/1962] Fix: Add switch arrow branch as additional exception Fixes false positives in switch arrow branches in AssignmentInOperand. --- .../pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java index 038db6b86f0..5e92f126f63 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java @@ -14,6 +14,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression; import net.sourceforge.pmd.lang.java.ast.ASTStatementExpressionList; +import net.sourceforge.pmd.lang.java.ast.ASTSwitchArrowBranch; import net.sourceforge.pmd.lang.java.ast.ASTSwitchStatement; import net.sourceforge.pmd.lang.java.ast.ASTUnaryExpression; import net.sourceforge.pmd.lang.java.ast.ASTVariableAccess; @@ -92,6 +93,7 @@ private void checkAssignment(ASTExpression impureExpr, RuleContext ctx) { && (parent instanceof ASTExpressionStatement || parent instanceof ASTStatementExpressionList || parent instanceof ASTLambdaExpression + || parent instanceof ASTSwitchArrowBranch ) ) { // that's ok From 5b64d0fdd6786882607eb754753315d8a3411388 Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Fri, 21 Nov 2025 15:17:19 +0100 Subject: [PATCH 1650/1962] Test: False positive in switch arrow branch --- .../rule/errorprone/xml/AssignmentInOperand.xml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml index 0cba9c3dab9..a77a795891e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml @@ -330,4 +330,21 @@ public class Foo { } ]]> + + + #6092 false positive for case statements + 0 + a = "a"; // fixed false positive in 'a = "a"' + default -> {} + } + } + } + ]]> + From 2f947fdbafc908be8a381fab38c6b3aa6b98fb6b Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Sun, 23 Nov 2025 20:44:55 +0100 Subject: [PATCH 1651/1962] Refactor: Add exception in EmptyFinalizer Add an exception to the EmptyFinalizer rule to avoid reporting an empty finalizer if it is marked as final in a non-final class. This is one possible security measure against finalizer attacks. --- pmd-java/src/main/resources/category/java/errorprone.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 41c5a667b9a..d01f58e8eb1 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -1683,8 +1683,10 @@ Empty finalize methods serve no purpose and should be removed. Note that Oracle From 8aca99987d54667493f7c659005179a1d9cfb05e Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Sun, 23 Nov 2025 20:57:48 +0100 Subject: [PATCH 1652/1962] Test: Allow empty, final finalize() in non-final class --- .../rule/errorprone/xml/EmptyFinalizer.xml | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/EmptyFinalizer.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/EmptyFinalizer.xml index c6937b30f89..696837590b1 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/EmptyFinalizer.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/EmptyFinalizer.xml @@ -22,6 +22,26 @@ public class Foo { void finalize() { int x = 2; } +} + ]]> + + + + #4742 EmptyFinalizer should not trigger if finalize method is final and class is not + 2 + 7,11 + From b76b219f232fd5d97c2ed20a3912da0821310d57 Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Mon, 24 Nov 2025 19:05:51 +0100 Subject: [PATCH 1653/1962] Refactor: Detect additional constants in GuardLogStatement Extend the check for additional parameters to also allow constant foldable expressions. --- .../java/rule/bestpractices/GuardLogStatementRule.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/GuardLogStatementRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/GuardLogStatementRule.java index 22975c940a4..85311d48761 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/GuardLogStatementRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/GuardLogStatementRule.java @@ -128,8 +128,8 @@ private boolean needsGuard(ASTMethodCall node) { return true; } - // if any additional params are not a direct access, we need a guard - return !areAdditionalParamsDirectAccess(node, messageArg + 1); + // if any additional params are not a direct access or constant foldable, we need a guard + return !areAdditionalParamsLowOverhead(node, messageArg + 1); } private boolean hasGuard(ASTMethodCall node, String logLevel) { @@ -195,12 +195,12 @@ private int getMessageArgIndex(ASTMethodCall methodCall) { return null; } - private boolean areAdditionalParamsDirectAccess(ASTMethodCall call, int messageArgIndex) { + private boolean areAdditionalParamsLowOverhead(ASTMethodCall call, int messageArgIndex) { // return true if the statement has limited overhead even if unguarded, // so that we can ignore it return call.getArguments().toStream() .drop(messageArgIndex) // remove the level argument if needed - .all(GuardLogStatementRule::isDirectAccess); + .all(it -> isDirectAccess(it) || it.getConstFoldingResult().hasValue()); } private static boolean isDirectAccess(ASTExpression it) { From 669b7478b0002988d2eeb4fc9c0cc6e14a6e601e Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Mon, 24 Nov 2025 19:06:52 +0100 Subject: [PATCH 1654/1962] Test: Constant foldable arguments in later positions --- .../bestpractices/xml/GuardLogStatement.xml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/GuardLogStatement.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/GuardLogStatement.xml index 5d53dbfa1d2..4c00360f382 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/GuardLogStatement.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/GuardLogStatement.xml @@ -789,6 +789,24 @@ class Test { LOGGER.debug("Logging string {}", s); // this is ok } } +]]> + + + + #5820 compile time constant only recognized in first position + 0 + From 3954371e603f1295e99102e5beaa19f412a8f864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 25 Nov 2025 12:24:03 +0100 Subject: [PATCH 1655/1962] Fix #5689 - issue with scoping of record members --- .../table/internal/SymbolTableResolver.java | 8 +++++ .../symbols/table/internal/VarScopingTest.kt | 31 +++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java index 815fecd6cb1..e68a1076aa5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java @@ -52,6 +52,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTLoopStatement; import net.sourceforge.pmd.lang.java.ast.ASTModifierList; import net.sourceforge.pmd.lang.java.ast.ASTPattern; +import net.sourceforge.pmd.lang.java.ast.ASTRecordDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTResource; import net.sourceforge.pmd.lang.java.ast.ASTResourceList; import net.sourceforge.pmd.lang.java.ast.ASTStatement; @@ -259,6 +260,9 @@ private void processTypeHeader(ASTTypeDeclaration node, ReferenceCtx ctx) { pushed += pushOnStack(f.typeHeader(top(), node.getSymbol())); NodeStream notBody = node.children().drop(1).dropLast(1); + if (node instanceof ASTRecordDeclaration) { + notBody = notBody.drop(1); // drop record components + } for (JavaNode it : notBody) { setTopSymbolTable(it); } @@ -287,6 +291,10 @@ public Void visitTypeDecl(ASTTypeDeclaration node, @NonNull ReferenceCtx ctx) { pushed += pushOnStack(f.typeBody(top(), node.getTypeMirror())); setTopSymbolTable(node.getBody()); + if (node instanceof ASTRecordDeclaration) { + // Members of a record declaration are in scope in the record header. + setTopSymbolTable(node.getRecordComponents()); + } // preprocess siblings node.getDeclarations(ASTTypeDeclaration.class) diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/VarScopingTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/VarScopingTest.kt index e5e89d3523a..be9d1ead15e 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/VarScopingTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/VarScopingTest.kt @@ -7,6 +7,7 @@ package net.sourceforge.pmd.lang.java.symbols.table.internal import io.kotest.assertions.withClue import io.kotest.matchers.collections.beEmpty import io.kotest.matchers.collections.shouldBeEmpty +import io.kotest.matchers.nulls.shouldNotBeNull import io.kotest.matchers.should import io.kotest.matchers.shouldBe import net.sourceforge.pmd.lang.java.ast.* @@ -15,8 +16,7 @@ import net.sourceforge.pmd.lang.java.ast.JavaVersion.J22 import net.sourceforge.pmd.lang.java.symbols.JFieldSymbol import net.sourceforge.pmd.lang.java.symbols.JFormalParamSymbol import net.sourceforge.pmd.lang.java.symbols.JLocalVariableSymbol -import net.sourceforge.pmd.lang.java.types.methodCalls -import net.sourceforge.pmd.lang.java.types.shouldHaveType +import net.sourceforge.pmd.lang.java.types.* import net.sourceforge.pmd.lang.test.ast.* import net.sourceforge.pmd.lang.test.ast.shouldBe import java.lang.reflect.Modifier @@ -503,4 +503,31 @@ class VarScopingTest : ProcessorTestSpec({ } } } + + parserTest("Record header has record fields in scope") { + val acu = parser.parse( + """ + + record Foo(@Annot(FIELD) // refer to members of Foo + long component) { + public static final int FIELD = 6; + @interface Annot { int value(); } + } + """.trimIndent() + ) + + val (typeFoo, typeAnnot) = acu.declaredTypeSignatures() + acu.withTypeDsl { + val ref = acu.varAccesses("FIELD").firstOrThrow() + ref.referencedSym.shouldNotBeNull() + ref.referencedSym.shouldBeA { + it.enclosingClass shouldBe typeFoo.symbol + } + ref shouldHaveType int + + val annot = acu.descendants(ASTAnnotation::class.java).firstOrThrow() + annot shouldHaveType typeAnnot + } + } + }) From aa5cb18fa3afdedfbb9e27c2d7f6411b608b6574 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Nov 2025 19:10:40 +0100 Subject: [PATCH 1656/1962] chore(deps): bump ruby/setup-ruby from 1.267.0 to 1.268.0 (#6240) Bumps [ruby/setup-ruby](https://github.com/ruby/setup-ruby) from 1.267.0 to 1.268.0. - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/d5126b9b3579e429dd52e51e68624dda2e05be25...8aeb6ff8030dd539317f8e1769a044873b56ea71) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-version: 1.268.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 4 ++-- .github/workflows/publish-release.yml | 2 +- .github/workflows/publish-snapshot.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2cf6990cc8c..9505a573455 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -280,7 +280,7 @@ jobs: -Pgenerate-rule-docs,fastSkip \ -DskipTests -Dassembly.skipAssembly=true - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@d5126b9b3579e429dd52e51e68624dda2e05be25 #v1.267.0 + uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 #v1.268.0 with: ruby-version: 3.3 - name: Setup bundler @@ -321,7 +321,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@d5126b9b3579e429dd52e51e68624dda2e05be25 #v1.267.0 + uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 #v1.268.0 with: ruby-version: 3.3 - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4.3.0 diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 8f7d514bd52..b5a96666bd8 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -632,7 +632,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@d5126b9b3579e429dd52e51e68624dda2e05be25 #v1.267.0 + uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 #v1.268.0 with: ruby-version: 3.3 - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4.3.0 diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 6e59aee88ca..54f17d9f8b5 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -649,7 +649,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@d5126b9b3579e429dd52e51e68624dda2e05be25 #v1.267.0 + uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 #v1.268.0 with: ruby-version: 3.3 - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4.3.0 From 49f1e2c6ea0c520cf0a6df2011f580c1dd9cee6b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Nov 2025 19:11:09 +0100 Subject: [PATCH 1657/1962] chore(deps): bump actions/checkout from 5.0.0 to 5.0.1 (#6241) Bumps [actions/checkout](https://github.com/actions/checkout) from 5.0.0 to 5.0.1. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/08c6903cd8c0fde910a37f88322edcfb5dd907a8...93cb6efe18208431cddfb8368fd83d5badbf9bfd) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 5.0.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 12 ++++++------ .github/workflows/git-repo-sync.yml | 2 +- .github/workflows/publish-release.yml | 6 +++--- .github/workflows/publish-snapshot.yml | 12 ++++++------ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9505a573455..105ce60d339 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,7 +23,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' @@ -81,7 +81,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' @@ -121,7 +121,7 @@ jobs: matrix: os: [ ubuntu-latest, windows-latest, macos-latest ] steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 # under linux we execute more extensive integration tests with various java versions if: ${{ runner.os == 'Linux' }} @@ -172,7 +172,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' @@ -258,7 +258,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' @@ -311,7 +311,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 with: fetch-depth: 2 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 diff --git a/.github/workflows/git-repo-sync.yml b/.github/workflows/git-repo-sync.yml index 30f71aed38c..06c097e65a1 100644 --- a/.github/workflows/git-repo-sync.yml +++ b/.github/workflows/git-repo-sync.yml @@ -28,7 +28,7 @@ jobs: shell: bash continue-on-error: false steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 with: fetch-depth: 100 - name: Setup ssh key for sourceforge diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index b5a96666bd8..4fd4b059739 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -31,7 +31,7 @@ jobs: outputs: PMD_VERSION: ${{ steps.version.outputs.PMD_VERSION }} steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 with: ref: ${{ github.event.workflow_run.head_branch }} - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 @@ -85,7 +85,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 with: ref: ${{ github.event.workflow_run.head_branch }} - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 @@ -622,7 +622,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 with: ref: ${{ github.event.workflow_run.head_branch }} - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 54f17d9f8b5..3e549e883ef 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -30,7 +30,7 @@ jobs: outputs: PMD_VERSION: ${{ steps.version.outputs.PMD_VERSION }} steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 with: ref: main - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 @@ -76,7 +76,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 with: ref: main - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 @@ -416,7 +416,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 with: ref: gh-pages - name: Clear old files @@ -639,7 +639,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 with: ref: main - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 @@ -726,7 +726,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 with: ref: main - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 @@ -763,7 +763,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 with: ref: main - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 From 11f93fc62c1503166861de0fd021b7eec284049a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Nov 2025 19:11:38 +0100 Subject: [PATCH 1658/1962] chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.18.0 to 1.18.1 (#6242) chore(deps-dev): bump net.bytebuddy:byte-buddy-agent Bumps [net.bytebuddy:byte-buddy-agent](https://github.com/raphw/byte-buddy) from 1.18.0 to 1.18.1. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.18.0...byte-buddy-1.18.1) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy-agent dependency-version: 1.18.1 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5cfd0c0cf79..af349744866 100644 --- a/pom.xml +++ b/pom.xml @@ -1044,7 +1044,7 @@ net.bytebuddy byte-buddy-agent - 1.18.0 + 1.18.1 test From 9049f006dda18081b774507d29971a5cd0f70233 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Nov 2025 19:12:05 +0100 Subject: [PATCH 1659/1962] chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.18.0 to 1.18.1 (#6244) Bumps [net.bytebuddy:byte-buddy](https://github.com/raphw/byte-buddy) from 1.18.0 to 1.18.1. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.18.0...byte-buddy-1.18.1) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-version: 1.18.1 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index af349744866..a0831e6b978 100644 --- a/pom.xml +++ b/pom.xml @@ -1038,7 +1038,7 @@ net.bytebuddy byte-buddy - 1.18.0 + 1.18.1 test From 0efb5647579c98d6b1c509561c5efa35fddbb5ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Nov 2025 19:12:39 +0100 Subject: [PATCH 1660/1962] chore(deps): bump org.apache.maven.plugins:maven-jar-plugin from 3.4.2 to 3.5.0 (#6245) chore(deps): bump org.apache.maven.plugins:maven-jar-plugin Bumps [org.apache.maven.plugins:maven-jar-plugin](https://github.com/apache/maven-jar-plugin) from 3.4.2 to 3.5.0. - [Release notes](https://github.com/apache/maven-jar-plugin/releases) - [Commits](https://github.com/apache/maven-jar-plugin/compare/maven-jar-plugin-3.4.2...maven-jar-plugin-3.5.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-jar-plugin dependency-version: 3.5.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a0831e6b978..af98f34f527 100644 --- a/pom.xml +++ b/pom.xml @@ -319,7 +319,7 @@ org.apache.maven.plugins maven-jar-plugin - 3.4.2 + 3.5.0 org.apache.maven.plugins From 1c216287ab683e1d52ec13cafb523494eb11b269 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Nov 2025 19:13:40 +0100 Subject: [PATCH 1661/1962] chore(deps): bump com.google.protobuf:protobuf-java from 4.33.0 to 4.33.1 (#6247) chore(deps): bump com.google.protobuf:protobuf-java Bumps [com.google.protobuf:protobuf-java](https://github.com/protocolbuffers/protobuf) from 4.33.0 to 4.33.1. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl) - [Commits](https://github.com/protocolbuffers/protobuf/commits) --- updated-dependencies: - dependency-name: com.google.protobuf:protobuf-java dependency-version: 4.33.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index af98f34f527..0e0da95e010 100644 --- a/pom.xml +++ b/pom.xml @@ -1134,7 +1134,7 @@ com.google.protobuf protobuf-java - 4.33.0 + 4.33.1 +* [#6201](https://github.com/pmd/pmd/pull/6201): \[java] Fix #6199: AssignmentInOperandRule: Update description of allowIncrementDecrement property - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) ### ๐Ÿ“ฆ๏ธ Dependency updates From a71df0e420b0ee224bd77240fc934d73813bc9ae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Nov 2025 19:38:37 +0100 Subject: [PATCH 1666/1962] chore(deps): bump org.scala-lang:scala-library from 2.13.17 to 2.13.18 (#6243) * chore(deps): bump org.scala-lang:scala-library from 2.12.20 to 2.13.18 Bumps [org.scala-lang:scala-library](https://github.com/scala/scala) from 2.12.20 to 2.13.18. - [Release notes](https://github.com/scala/scala/releases) - [Commits](https://github.com/scala/scala/compare/v2.12.20...v2.13.18) --- updated-dependencies: - dependency-name: org.scala-lang:scala-library dependency-version: 2.13.18 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Apply suggestions from code review --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andreas Dangel --- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index 858271309bb..fa2190f5111 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -36,7 +36,7 @@ org.scala-lang scala-library - ${scalaVersion}.17 + ${scalaVersion}.18 org.scalameta diff --git a/pom.xml b/pom.xml index e3451e13912..586a4be2965 100644 --- a/pom.xml +++ b/pom.xml @@ -965,7 +965,7 @@ org.scala-lang scala-library - 2.13.17 + 2.13.18 From dca9c000512170062192aee3ca0351f3507a5750 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 25 Nov 2025 20:06:22 +0100 Subject: [PATCH 1667/1962] [doc] Update release notes (#6188, #6202) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..0cf5cf4876a 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,11 +25,14 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy ### ๐Ÿ›๏ธ Fixed Issues +* java-bestpractices + * [#6188](https://github.com/pmd/pmd/issues/6188): \[java] UnitTestShouldIncludeAssert false positive when TestNG @Test.expectedException present ### ๐Ÿšจ๏ธ API Changes ### โœจ๏ธ Merged pull requests +* [#6202](https://github.com/pmd/pmd/pull/6202): \[java] Fix #6188: UnitTestsShouldIncludeAssert - FP when TestNG @Test.expectedException is present - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) ### ๐Ÿ“ฆ๏ธ Dependency updates From e87726c8eccb2e796b01fabf7ab97b41e0db0701 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 25 Nov 2025 20:09:44 +0100 Subject: [PATCH 1668/1962] Update @mrclmh as a contributor --- .all-contributorsrc | 3 ++- docs/pages/pmd/projectdocs/credits.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 7b047b0aeba..89d0cbf64fd 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8197,7 +8197,8 @@ "avatar_url": "https://avatars.githubusercontent.com/u/2975481?v=4", "profile": "https://github.com/mrclmh", "contributions": [ - "bug" + "bug", + "code" ] }, { diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 4ed123a27e8..2ed5ce6a96c 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -1054,7 +1054,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d milossesic
          milossesic

          ๐Ÿ› mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป - mrclmh
          mrclmh

          ๐Ÿ› + mrclmh
          mrclmh

          ๐Ÿ› ๐Ÿ’ป mriddell95
          mriddell95

          ๐Ÿ› mrlzh
          mrlzh

          ๐Ÿ› From a3866414f880c4e941ea5ec37a3432a91bd01301 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 25 Nov 2025 20:10:00 +0100 Subject: [PATCH 1669/1962] [doc] Update release notes (#6096, #6238) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index ae0365724dc..b05da6e706e 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -33,6 +33,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿ›๏ธ Fixed Issues * apex-bestpractices * [#6203](https://github.com/pmd/pmd/issues/6203): \[apex] New Rule: Avoid Future Annotation +* java-errorprone + * [#6096](https://github.com/pmd/pmd/issues/6096): \[java] OverrideBothEqualsAndHashCodeOnComparable on class with lombok.EqualsAndHashCode annotation ### ๐Ÿšจ๏ธ API Changes @@ -40,6 +42,7 @@ This is a {{ site.pmd.release_type }} release. * [#6204](https://github.com/pmd/pmd/pull/6204): \[apex] Add rule to limit usage of @Future annotation - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) * [#6217](https://github.com/pmd/pmd/pull/6217): \[doc] Add Blue Cave to known tools using PMD - [Jude Pereira](https://github.com/judepereira) (@judepereira) +* [#6238](https://github.com/pmd/pmd/pull/6238): \[java] Fix #6096: Detect Lombok generated equals/hashCode in Comparable - [Marcel](https://github.com/mrclmh) (@mrclmh) ### ๐Ÿ“ฆ๏ธ Dependency updates From 674f73bef57d0cf9efc3ca4043b274f98cf3d955 Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Tue, 25 Nov 2025 22:17:28 +0100 Subject: [PATCH 1670/1962] Doc: Add comment for test --- .../pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml index a77a795891e..d5a7f53ec0e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml @@ -335,6 +335,7 @@ public class Foo { #6092 false positive for case statements 0 Date: Tue, 25 Nov 2025 22:17:53 +0100 Subject: [PATCH 1671/1962] Doc: Make comment stand out more --- .../pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml index d5a7f53ec0e..d4bf06bc197 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml @@ -341,7 +341,7 @@ public class Foo { String a = null; switch (args[0]) { - case "A" -> a = "a"; // fixed false positive in 'a = "a"' + case "A" -> a = "a"; // fixed false positive in 'a = "a"' default -> {} } } From c1237c28a02a06bb42a956fc8db70fb56b0cf731 Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Tue, 25 Nov 2025 22:28:54 +0100 Subject: [PATCH 1672/1962] Fix: Detect violation in switch expression The previous fix created a false negative in switch expressions by globally allowing assignments in switch arrow branches. This is now restricted to only allow them in switch statements and not in switch expressions. --- .../errorprone/AssignmentInOperandRule.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java index 5e92f126f63..c4bc872070a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java @@ -89,15 +89,17 @@ private void checkAssignment(ASTExpression impureExpr, RuleContext ctx) { ASTExpression toplevel = JavaAstUtils.getTopLevelExpr(impureExpr); JavaNode parent = toplevel.getParent(); - if (toplevel == impureExpr - && (parent instanceof ASTExpressionStatement - || parent instanceof ASTStatementExpressionList - || parent instanceof ASTLambdaExpression - || parent instanceof ASTSwitchArrowBranch - ) - ) { - // that's ok - return; + if (toplevel == impureExpr) { + if (parent instanceof ASTExpressionStatement + || parent instanceof ASTStatementExpressionList + || parent instanceof ASTLambdaExpression) { + // that's ok + return; + } + if (parent instanceof ASTSwitchArrowBranch + && parent.getParent() instanceof ASTSwitchStatement) { // switch expression excluded + return; + } } if (parent instanceof ASTIfStatement && getProperty(ALLOW_IF_DESCRIPTOR) || parent instanceof ASTWhileStatement && getProperty(ALLOW_WHILE_DESCRIPTOR) From d6c8fe048fa4f64f77f4350325d679b38dc12bbc Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Tue, 25 Nov 2025 22:54:26 +0100 Subject: [PATCH 1673/1962] Test: Negative test for switch expression --- .../rule/errorprone/xml/AssignmentInOperand.xml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml index d4bf06bc197..47e4a66bfb8 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml @@ -333,7 +333,8 @@ public class Foo { #6092 false positive for case statements - 0 + 1 + 18 a = 1; // violation line 18 + default -> 0; + }; + + System.out.println("a = " + a); + System.out.println("b = " + b); + } + } ]]> From cdb82f06d3308d259e63aa0e32bcd4b072b81df7 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Tue, 25 Nov 2025 23:07:29 +0100 Subject: [PATCH 1674/1962] [java] UnusedLocalVariable: fix false positive with guard in switch --- .../bestpractices/UnusedLocalVariableRule.java | 4 ++-- .../table/internal/SymbolTableResolver.java | 2 +- .../bestpractices/xml/UnusedLocalVariable.xml | 15 +++++++++++++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLocalVariableRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLocalVariableRule.java index 516e0850a98..1bacb50cc43 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLocalVariableRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedLocalVariableRule.java @@ -40,13 +40,13 @@ public Object visit(ASTTypePattern pattern, Object data) { ASTVariableId varId = pattern.getVarId(); if (JavaAstUtils.isNeverUsed(varId) && !JavaRuleUtil.isExplicitUnusedVarName(varId.getName()) - && !neededForSwitchOrRcord(pattern)) { + && !neededForSwitchOrRecord(pattern)) { asCtx(data).addViolation(varId, varId.getName()); } return data; } - private boolean neededForSwitchOrRcord(ASTTypePattern pattern) { + private boolean neededForSwitchOrRecord(ASTTypePattern pattern) { JavaNode parent = pattern.getParent(); return (parent instanceof ASTSwitchLabel || parent instanceof ASTPatternList) && pattern.getLanguageVersion().compareToVersion("22") < 0; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java index 815fecd6cb1..85b8f14f33a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java @@ -387,7 +387,7 @@ private Void visitSwitch(ASTSwitchLike node, @NonNull ReferenceCtx ctx) { ASTSwitchLabel label = branch.getLabel(); // collect all bindings. Maybe it's illegal to use composite label with bindings, idk BindSet bindings = - label.children(ASTPattern.class) + label.descendants(ASTPattern.class) .reduce(BindSet.EMPTY, (bindSet, pat) -> bindSet.union(bindersOfPattern(pat))); // visit guarded patterns in label diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml index 30d130476a1..93de7c331ff 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml @@ -714,4 +714,19 @@ class Foo { ]]> java 22 + + pattern with guard + 0 + fooString.equals(barString); + default -> false; + }; + } + } + ]]> + java 21 + From f8da9c6f792ef716b8bc6990537f169926b87af6 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Thu, 27 Nov 2025 01:19:35 +0100 Subject: [PATCH 1675/1962] [docs] Add button to copy configuration snippet --- docs/css/customstyles.css | 15 +++++++++++++-- docs/js/customscripts.js | 31 ++++++++++++++++++------------- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/docs/css/customstyles.css b/docs/css/customstyles.css index 5c85b9656c6..50bdbb28703 100644 --- a/docs/css/customstyles.css +++ b/docs/css/customstyles.css @@ -899,6 +899,17 @@ table code { background-color: transparent !important; } +.highlighter-rouge { + position: relative; +} + +.highlighter-rouge .copy-clipboard-button { + position: absolute; + right: 1rem; + top: 0; + font-size: 1.5rem; +} + table p { margin-top: 12px; margin-bottom: 12px; @@ -1280,10 +1291,10 @@ a.edit-header::after { content: '' !important; /* hide the external link marker */ } -.copy-anchor-url { +.copy-clipboard-button { opacity: 0; } -:hover > .copy-anchor-url { +:hover > .copy-clipboard-button { opacity: 1; cursor: pointer; } diff --git a/docs/js/customscripts.js b/docs/js/customscripts.js index 9948510bd4a..6268724a2f8 100644 --- a/docs/js/customscripts.js +++ b/docs/js/customscripts.js @@ -36,30 +36,35 @@ $(document).ready(function () { ' role="button" data-toggle="tooltip" data-placement="top" title="Edit on GitHub">๏ธ' ); } + const addCopyButton = (parent, title, content) => { + const template = document.createElement('template'); + template.innerHTML = ``; + template.content.firstChild.dataset['copy'] = content; + parent.append(template.content.firstChild); + } - // Add an "copy url" button to each header + // Add a "copy url" button to each header document.querySelectorAll('.anchorjs-link') .forEach(e => { - const template = document.createElement('template'); - template.innerHTML = ''; - e.parentNode.append(template.content.firstChild); + const url = new URL(location.href); + url.hash = e.parentNode.id; + addCopyButton(e.parentElement, "Copy URL", url); }); + // Add a "copy snippet" button to each configuration snippet + document.querySelectorAll('.language-xml.highlighter-rouge') + .forEach(e => { + addCopyButton(e, 'Copy snippet', e.textContent); + }); + document.addEventListener('click', event => { - let target = null; - if (event.target.classList.contains('copy-anchor-url')) { - target = event.target; - } else if (event.target.parentNode.classList.contains('copy-anchor-url')) { - target = event.target.parentNode; - } + let target = event.target.closest('.copy-clipboard-button'); if (target) { if (navigator.clipboard) { - const url = new URL(location.href); - url.hash = event.target.parentNode.id; event.preventDefault(); event.stopImmediatePropagation(); - navigator.clipboard.writeText(url) + navigator.clipboard.writeText(target.dataset['copy']) .then(() => { target.firstChild.classList.remove('fa-copy'); target.firstChild.classList.add('fa-check'); From 0449259e461b6f03eef57bf0315c04cfa280a983 Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Thu, 27 Nov 2025 07:33:42 +0100 Subject: [PATCH 1676/1962] Doc: Mention classes with test prefixes --- pmd-java/src/main/resources/category/java/errorprone.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 41c5a667b9a..2b503192127 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -3193,12 +3193,12 @@ public void foo() { class="net.sourceforge.pmd.lang.java.rule.errorprone.TestClassWithoutTestCasesRule" externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#testclasswithouttestcases"> -Test classes typically end with the suffix "Test", "Tests" or "TestCase". Having a non-test class with that name +Test classes typically start or end with the affix "Test", "Tests" or "TestCase". Having a non-test class with that name is not a good practice, since most people will assume it is a test case. Test classes have test methods named "testXXX" (JUnit3) or use annotations (e.g. `@Test`). -The suffix can be configured using the property `testClassPattern`. To disable the detection of possible test classes -by name, set this property to an empty string. +The regular expression to match can be configured using the property `testClassPattern`. To disable the detection of +possible test classes by name, set this property to an empty string. 3 From 2447c0e6ca617498ff117e36ae5ac5799f7d3c6f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Nov 2025 09:25:50 +0100 Subject: [PATCH 1677/1962] chore(deps): bump actions/checkout from 5.0.1 to 6.0.0 (#6263) Bumps [actions/checkout](https://github.com/actions/checkout) from 5.0.1 to 6.0.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/93cb6efe18208431cddfb8368fd83d5badbf9bfd...1af3b93b6815bc44a9784bd300feb67ff0d1eeb3) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 12 ++++++------ .github/workflows/git-repo-sync.yml | 2 +- .github/workflows/publish-release.yml | 6 +++--- .github/workflows/publish-snapshot.yml | 12 ++++++------ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 105ce60d339..5dd3d24ecbd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,7 +23,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' @@ -81,7 +81,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' @@ -121,7 +121,7 @@ jobs: matrix: os: [ ubuntu-latest, windows-latest, macos-latest ] steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 # under linux we execute more extensive integration tests with various java versions if: ${{ runner.os == 'Linux' }} @@ -172,7 +172,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' @@ -258,7 +258,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' @@ -311,7 +311,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 with: fetch-depth: 2 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 diff --git a/.github/workflows/git-repo-sync.yml b/.github/workflows/git-repo-sync.yml index 06c097e65a1..23473a37d87 100644 --- a/.github/workflows/git-repo-sync.yml +++ b/.github/workflows/git-repo-sync.yml @@ -28,7 +28,7 @@ jobs: shell: bash continue-on-error: false steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 with: fetch-depth: 100 - name: Setup ssh key for sourceforge diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 4fd4b059739..2e7d2a924f2 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -31,7 +31,7 @@ jobs: outputs: PMD_VERSION: ${{ steps.version.outputs.PMD_VERSION }} steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 with: ref: ${{ github.event.workflow_run.head_branch }} - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 @@ -85,7 +85,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 with: ref: ${{ github.event.workflow_run.head_branch }} - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 @@ -622,7 +622,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 with: ref: ${{ github.event.workflow_run.head_branch }} - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 3e549e883ef..625adbb7b3e 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -30,7 +30,7 @@ jobs: outputs: PMD_VERSION: ${{ steps.version.outputs.PMD_VERSION }} steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 with: ref: main - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 @@ -76,7 +76,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 with: ref: main - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 @@ -416,7 +416,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 with: ref: gh-pages - name: Clear old files @@ -639,7 +639,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 with: ref: main - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 @@ -726,7 +726,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 with: ref: main - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 @@ -763,7 +763,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd #v5.0.1 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 with: ref: main - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 From 3de14bce22e9cd7ca631bc49be6de380742da9ac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Nov 2025 09:26:14 +0100 Subject: [PATCH 1678/1962] chore(deps): bump org.apache.commons:commons-lang3 from 3.19.0 to 3.20.0 (#6264) Bumps org.apache.commons:commons-lang3 from 3.19.0 to 3.20.0. --- updated-dependencies: - dependency-name: org.apache.commons:commons-lang3 dependency-version: 3.20.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 586a4be2965..e98a2cd02e9 100644 --- a/pom.xml +++ b/pom.xml @@ -913,7 +913,7 @@ org.apache.commons commons-lang3 - 3.19.0 + 3.20.0 org.apache.commons From cd965b052514c6239224878e1f1b29b67aa6bf94 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Nov 2025 09:26:36 +0100 Subject: [PATCH 1679/1962] chore(deps): bump actions/create-github-app-token from 2.1.4 to 2.2.0 (#6265) Bumps [actions/create-github-app-token](https://github.com/actions/create-github-app-token) from 2.1.4 to 2.2.0. - [Release notes](https://github.com/actions/create-github-app-token/releases) - [Commits](https://github.com/actions/create-github-app-token/compare/67018539274d69449ef7c02e8e71183d1719ab42...7e473efe3cb98aa54f8d4bac15400b15fad77d94) --- updated-dependencies: - dependency-name: actions/create-github-app-token dependency-version: 2.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/publish-pull-requests.yml | 2 +- .github/workflows/publish-release.yml | 4 ++-- .github/workflows/publish-snapshot.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish-pull-requests.yml b/.github/workflows/publish-pull-requests.yml index b822aa8aec8..294b16ab6ad 100644 --- a/.github/workflows/publish-pull-requests.yml +++ b/.github/workflows/publish-pull-requests.yml @@ -21,7 +21,7 @@ jobs: run: shell: bash steps: - - uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 #v2.1.4 + - uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94 #v2.2.0 id: pmd-actions-helper-app-token with: app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 2e7d2a924f2..94ce577e640 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -504,7 +504,7 @@ jobs: --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-src.zip" printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-doc.zip" - - uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 #v2.1.4 + - uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94 #v2.2.0 id: pmd-actions-helper-app-token with: app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} @@ -760,7 +760,7 @@ jobs: run: shell: bash steps: - - uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 #v2.1.4 + - uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94 #v2.2.0 id: pmd-actions-helper-app-token with: app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 625adbb7b3e..9a87ef2a98b 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -495,7 +495,7 @@ jobs: --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-src.zip" printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-doc.zip" - - uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 #v2.1.4 + - uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94 #v2.2.0 id: pmd-actions-helper-app-token with: app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} From 42ef26b524f2916485a8802839e450a7d8d00987 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Nov 2025 09:27:02 +0100 Subject: [PATCH 1680/1962] chore(deps): bump org.codehaus.mojo:versions-maven-plugin from 2.19.1 to 2.20.1 (#6267) chore(deps): bump org.codehaus.mojo:versions-maven-plugin Bumps [org.codehaus.mojo:versions-maven-plugin](https://github.com/mojohaus/versions) from 2.19.1 to 2.20.1. - [Release notes](https://github.com/mojohaus/versions/releases) - [Changelog](https://github.com/mojohaus/versions/blob/master/ReleaseNotes.md) - [Commits](https://github.com/mojohaus/versions/compare/2.19.1...2.20.1) --- updated-dependencies: - dependency-name: org.codehaus.mojo:versions-maven-plugin dependency-version: 2.20.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e98a2cd02e9..acf14046bf3 100644 --- a/pom.xml +++ b/pom.xml @@ -640,7 +640,7 @@ org.codehaus.mojo versions-maven-plugin - 2.19.1 + 2.20.1 org.sonatype.central From 0bb8fc7cdf391bd70163d57902aa3f9006039228 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Nov 2025 09:27:47 +0100 Subject: [PATCH 1681/1962] chore(deps): bump scalameta.version from 4.14.1 to 4.14.2 (#6266) Bumps `scalameta.version` from 4.14.1 to 4.14.2. Updates `org.scalameta:parsers_2.13` from 4.14.1 to 4.14.2 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.14.1...v4.14.2) Updates `org.scalameta:trees_2.13` from 4.14.1 to 4.14.2 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.14.1...v4.14.2) Updates `org.scalameta:parsers_2.12` from 4.14.1 to 4.14.2 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.14.1...v4.14.2) Updates `org.scalameta:trees_2.12` from 4.14.1 to 4.14.2 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.14.1...v4.14.2) --- updated-dependencies: - dependency-name: org.scalameta:parsers_2.13 dependency-version: 4.14.2 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:trees_2.13 dependency-version: 4.14.2 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:parsers_2.12 dependency-version: 4.14.2 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:trees_2.12 dependency-version: 4.14.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index 3aee38eda20..50cd7ff768e 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -13,7 +13,7 @@ - 4.14.1 + 4.14.2 From 4fa060c378fd90666a6f837b5e72c056a21351d4 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 09:57:19 +0100 Subject: [PATCH 1682/1962] [java] AssignmentInOperand - more tests for switch --- .../errorprone/AssignmentInOperandRule.java | 3 +- .../errorprone/xml/AssignmentInOperand.xml | 31 ++++++++++++++++--- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java index c4bc872070a..f648408f50c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AssignmentInOperandRule.java @@ -97,7 +97,8 @@ private void checkAssignment(ASTExpression impureExpr, RuleContext ctx) { return; } if (parent instanceof ASTSwitchArrowBranch - && parent.getParent() instanceof ASTSwitchStatement) { // switch expression excluded + && parent.getParent() instanceof ASTSwitchStatement) { + // assignments in modern (->) switch statements are ok return; } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml index 47e4a66bfb8..24824616302 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml @@ -333,8 +333,8 @@ public class Foo { #6092 false positive for case statements - 1 - 18 + 3 + 31,35,39 a = "a"; // fixed false positive in 'a = "a"' + case "A" -> a = "a"; // fixed false positive in 'a = "a"' default -> {} } + System.out.println("a = " + a); + + switch (args[0]) { + case "A": a = "b"; break; + default: + } + System.out.println("a = " + a); + + switch (args[0]) { + case "A": { a = "c"; break; } + default: + } + System.out.println("a = " + a); } } @@ -353,12 +366,22 @@ public class Foo { public static void main(String[] args) { int a = 2; int b = switch(a) { - case 2 -> a = 1; // violation line 18 + case 2 -> a = 1; // violation line 31 default -> 0; }; + int c = switch(a) { + case 1 -> { yield a = 1; } // violation line 35 + default -> 0; + }; + int d = switch(a) { + case 1: yield a = 1; // violation line 39 + default: yield 0; + }; System.out.println("a = " + a); System.out.println("b = " + b); + System.out.println("c = " + c); + System.out.println("d = " + d); } } ]]> From 6326a3970dff7835e4ee19d5908aca9146faa223 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 10:14:45 +0100 Subject: [PATCH 1683/1962] [java] OverrideBothEqualsAndHashCodeOnComparable - update desc and tests --- ...BothEqualsAndHashCodeOnComparableRule.java | 12 +-------- .../resources/category/java/errorprone.xml | 5 ++++ ...rrideBothEqualsAndHashCodeOnComparable.xml | 26 +++---------------- 3 files changed, 9 insertions(+), 34 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java index 83e5960b6e8..3f14b894a16 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/OverrideBothEqualsAndHashCodeOnComparableRule.java @@ -30,16 +30,6 @@ protected boolean skipType(ASTTypeDeclaration node) { return !TypeTestUtil.isA(Comparable.class, node) || TypeTestUtil.isA(Enum.class, node); } - private static boolean hasBrokenEqualsMethod(ASTTypeDeclaration node) { - for (ASTMethodDeclaration m : node.getDeclarations(ASTMethodDeclaration.class)) { - if ("equals".equals(m.getName()) && !JavaAstUtils.isEqualsMethod(m)) { - return true; - } - } - - return false; - } - @Override protected void maybeReport(RuleContext ctx, ASTTypeDeclaration node, ASTMethodDeclaration hashCodeMethod, ASTMethodDeclaration equalsMethod) { ASTMethodDeclaration compareToMethod = node @@ -50,7 +40,7 @@ protected void maybeReport(RuleContext ctx, ASTTypeDeclaration node, ASTMethodDe } if (equalsMethod == null && hashCodeMethod == null) { - if (!node.isRecord() || hasBrokenEqualsMethod(node)) { + if (!node.isRecord()) { ctx.addViolationWithMessage(compareToMethod, MISSING_EQUALS_AND_HASH_CODE); } } else if (equalsMethod == null) { diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 86ae23dab19..3ccb45c25fb 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -2440,6 +2440,11 @@ public class Foo { // perfect, both methods provided Note 1: This rule is related to {% rule OverrideBothEqualsAndHashcode %}. It will report missing `equals()` and/or `hashCode()` methods for classes only that implement `Comparable`. + + Note 2: This rule reports records only, if either `equals()` or `hashCode()` + have been overridden, but not both. If a record uses the generated + equals/hashCode methods, then the `compareTo()` implementation is only + consistent with `equals()` if all record components are considered. 3 diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml index 82a4f6c3140..76d6d4b183f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/OverrideBothEqualsAndHashCodeOnComparable.xml @@ -233,7 +233,7 @@ ]]> - Record with Comparable and no explicit equals/hashCode + #6072 Record with Comparable and no explicit equals/hashCode 0 { @@ -266,7 +266,7 @@ ]]> - Record with Comparable and explicit hashCode + #6072 Record with Comparable and explicit hashCode, missing equals 1 8 @@ -287,7 +287,7 @@ ]]> - Record with Comparable and both explicit equals and hashCode + #6072 Record with Comparable and both explicit equals and hashCode 0 { @@ -316,26 +316,6 @@ } ]]> - - Comparable Record with wrong equals signature - 1 - 3 - - When implementing Comparable, both equals() and hashCode() should be overridden - - { - @Override - public int compareTo(Foo o) { - return Integer.compare(this.x, o.x); - } - - public boolean equals(Foo o) { - return compareTo(o) == 0; - } - } - ]]> - Do report in inherited Comparables with compareTo 1 From 3ce26deb480f838c18a5708dc8f605ce4193475a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 10:23:03 +0100 Subject: [PATCH 1684/1962] Bump PMD from 7.17.0 to 7.18.0 (#6197) * Bump PMD from 7.17.0 to 7.18.0 Dogfood update... * Remove old pmd exclusions --- pmd-core/pmd-core-exclude-pmd.properties | 3 --- .../net/sourceforge/pmd/benchmark/TimeTracker.java | 2 +- pom.xml | 10 +++++----- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/pmd-core/pmd-core-exclude-pmd.properties b/pmd-core/pmd-core-exclude-pmd.properties index 790678997f9..6e636acc2fe 100644 --- a/pmd-core/pmd-core-exclude-pmd.properties +++ b/pmd-core/pmd-core-exclude-pmd.properties @@ -1,5 +1,2 @@ # ignore missing override for isEmpty() method, see #4291 #5299 net.sourceforge.pmd.lang.document.Chars=MissingOverride -# FP fixed by #6082 - with PMD 7.18.0 the suppression is not needed anymore -net.sourceforge.pmd.benchmark.TimedResult=UnnecessaryWarningSuppression -net.sourceforge.pmd.benchmark.TimeTracker.TimedResult=UnnecessaryWarningSuppression diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimeTracker.java b/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimeTracker.java index bcd0e2f12e6..13c39b7b967 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimeTracker.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/TimeTracker.java @@ -209,7 +209,7 @@ public String toString() { totalTimeNanos.getAndAdd(delta); selfTimeNanos.getAndAdd(delta - timerEntry.inNestedOperationsNanos); - callCount.getAndIncrement(); // NOPMD: UselessPureMethodCall false-positive #6055 + callCount.getAndIncrement(); extraDataCounter.getAndAdd(extraData); return delta; diff --git a/pom.xml b/pom.xml index acf14046bf3..23fa9d95702 100644 --- a/pom.xml +++ b/pom.xml @@ -602,27 +602,27 @@ net.sourceforge.pmd pmd-core - 7.17.0 + 7.18.0 net.sourceforge.pmd pmd-java - 7.17.0 + 7.18.0 net.sourceforge.pmd pmd-jsp - 7.17.0 + 7.18.0 net.sourceforge.pmd pmd-javascript - 7.17.0 + 7.18.0 net.sourceforge.pmd pmd-xml - 7.17.0 + 7.18.0 From 28b256e3b81e8a8716390593b7756c650bc84325 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 13:48:34 +0100 Subject: [PATCH 1685/1962] [doc] Update release notes (#6092, #6251) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..36f7daf95a5 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,11 +25,14 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy ### ๐Ÿ›๏ธ Fixed Issues +* java-errorprone + * [#6092](https://github.com/pmd/pmd/issues/6092): \[java] AssignmentInOperand false positive in 7.17.0 for case blocks in switch statements ### ๐Ÿšจ๏ธ API Changes ### โœจ๏ธ Merged pull requests +* [#6251](https://github.com/pmd/pmd/pull/6251): \[java] Fix #6092 AssignmentInOperand false positive in 7.17.0 for case statements - [Marcel](https://github.com/mrclmh) (@mrclmh) ### ๐Ÿ“ฆ๏ธ Dependency updates From d74696bc314620f79a31f58e20a62aeabe8b2dbd Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 13:50:02 +0100 Subject: [PATCH 1686/1962] Add @kdandoy107255 as a contributor --- .all-contributorsrc | 9 +++++++ docs/pages/pmd/projectdocs/credits.md | 35 ++++++++++++++------------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 7b047b0aeba..901c10460eb 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8316,6 +8316,15 @@ "contributions": [ "bug" ] + }, + { + "login": "kdandoy107255", + "name": "kdandoy107255", + "avatar_url": "https://avatars.githubusercontent.com/u/221576972?v=4", + "profile": "https://github.com/kdandoy107255", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 4ed123a27e8..32f38e37a46 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -1024,158 +1024,159 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d kdaemonv
          kdaemonv

          ๐Ÿ› + kdandoy107255
          kdandoy107255

          ๐Ÿ› kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ› kfranic
          kfranic

          ๐Ÿ› khalidkh
          khalidkh

          ๐Ÿ› koalalam
          koalalam

          ๐Ÿ› - krzyk
          krzyk

          ๐Ÿ› + krzyk
          krzyk

          ๐Ÿ› lasselindqvist
          lasselindqvist

          ๐Ÿ› lgemeinhardt
          lgemeinhardt

          ๐Ÿ› lihuaib
          lihuaib

          ๐Ÿ› liqingjun123
          liqingjun123

          ๐Ÿ› lonelyma1021
          lonelyma1021

          ๐Ÿ› lothas
          lothas

          ๐Ÿ› - lpeddy
          lpeddy

          ๐Ÿ› + lpeddy
          lpeddy

          ๐Ÿ› lujiefsi
          lujiefsi

          ๐Ÿ’ป lukelukes
          lukelukes

          ๐Ÿ’ป lyriccoder
          lyriccoder

          ๐Ÿ› marcelmore
          marcelmore

          ๐Ÿ› matchbox
          matchbox

          ๐Ÿ› matthiaskraaz
          matthiaskraaz

          ๐Ÿ› - meandonlyme
          meandonlyme

          ๐Ÿ› + meandonlyme
          meandonlyme

          ๐Ÿ› mikesive
          mikesive

          ๐Ÿ› milossesic
          milossesic

          ๐Ÿ› mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป mrclmh
          mrclmh

          ๐Ÿ› mriddell95
          mriddell95

          ๐Ÿ› - mrlzh
          mrlzh

          ๐Ÿ› + mrlzh
          mrlzh

          ๐Ÿ› msloan
          msloan

          ๐Ÿ› mucharlaravalika
          mucharlaravalika

          ๐Ÿ› mvenneman
          mvenneman

          ๐Ÿ› nareshl119
          nareshl119

          ๐Ÿ› nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ› noerremark
          noerremark

          ๐Ÿ› - novsirion
          novsirion

          ๐Ÿ› + novsirion
          novsirion

          ๐Ÿ› nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
          oggboy

          ๐Ÿ› oinume
          oinume

          ๐Ÿ› orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ› pablogomez2197
          pablogomez2197

          ๐Ÿ› pacvz
          pacvz

          ๐Ÿ’ป - pallavi agarwal
          pallavi agarwal

          ๐Ÿ› + pallavi agarwal
          pallavi agarwal

          ๐Ÿ› pankratz76
          pankratz76

          ๐Ÿ› parksungrin
          parksungrin

          ๐Ÿ› patpatpat123
          patpatpat123

          ๐Ÿ› patriksevallius
          patriksevallius

          ๐Ÿ› pbrajesh1
          pbrajesh1

          ๐Ÿ› phoenix384
          phoenix384

          ๐Ÿ› - piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป + piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป plan3d
          plan3d

          ๐Ÿ› poojasix
          poojasix

          ๐Ÿ› prabhushrikant
          prabhushrikant

          ๐Ÿ› pujitha8783
          pujitha8783

          ๐Ÿ› r-r-a-j
          r-r-a-j

          ๐Ÿ› raghujayjunk
          raghujayjunk

          ๐Ÿ› - rajeshveera
          rajeshveera

          ๐Ÿ› + rajeshveera
          rajeshveera

          ๐Ÿ› rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ› recdevs
          recdevs

          ๐Ÿ› reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ› rijkt
          rijkt

          ๐Ÿ› rillig-tk
          rillig-tk

          ๐Ÿ› rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ› - rnveach
          rnveach

          ๐Ÿ› + rnveach
          rnveach

          ๐Ÿ› rubenporras
          rubenporras

          ๐Ÿ› rxmicro
          rxmicro

          ๐Ÿ› ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ› sabi0
          sabi0

          ๐Ÿ› samc-gearset
          samc-gearset

          ๐Ÿ“– scais
          scais

          ๐Ÿ› - schosin
          schosin

          ๐Ÿ› + schosin
          schosin

          ๐Ÿ› screamingfrog
          screamingfrog

          ๐Ÿ’ต sebbASF
          sebbASF

          ๐Ÿ› sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป shilko2013
          shilko2013

          ๐Ÿ› shiomiyan
          shiomiyan

          ๐Ÿ“– simeonKondr
          simeonKondr

          ๐Ÿ› - snajberk
          snajberk

          ๐Ÿ› + snajberk
          snajberk

          ๐Ÿ› sniperrifle2004
          sniperrifle2004

          ๐Ÿ› snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป soloturn
          soloturn

          ๐Ÿ› soyodream
          soyodream

          ๐Ÿ› sratz
          sratz

          ๐Ÿ› stonio
          stonio

          ๐Ÿ› - sturton
          sturton

          ๐Ÿ’ป ๐Ÿ› + sturton
          sturton

          ๐Ÿ’ป ๐Ÿ› sudharmohan
          sudharmohan

          ๐Ÿ› suruchidawar
          suruchidawar

          ๐Ÿ› svenfinitiv
          svenfinitiv

          ๐Ÿ› szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป tashiscool
          tashiscool

          ๐Ÿ› test-git-hook
          test-git-hook

          ๐Ÿ› - testation21
          testation21

          ๐Ÿ’ป ๐Ÿ› + testation21
          testation21

          ๐Ÿ’ป ๐Ÿ› thanosa
          thanosa

          ๐Ÿ› tiandiyixian
          tiandiyixian

          ๐Ÿ› tobwoerk
          tobwoerk

          ๐Ÿ› tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป trentchilders
          trentchilders

          ๐Ÿ› triandicAnt
          triandicAnt

          ๐Ÿ› - trishul14
          trishul14

          ๐Ÿ› + trishul14
          trishul14

          ๐Ÿ› tsui
          tsui

          ๐Ÿ› wangzitom12306
          wangzitom12306

          ๐Ÿ› winhkey
          winhkey

          ๐Ÿ› witherspore
          witherspore

          ๐Ÿ› wjljack
          wjljack

          ๐Ÿ› wuchiuwong
          wuchiuwong

          ๐Ÿ› - xingsong
          xingsong

          ๐Ÿ› + xingsong
          xingsong

          ๐Ÿ› xioayuge
          xioayuge

          ๐Ÿ› xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ› xuanuy
          xuanuy

          ๐Ÿ› xyf0921
          xyf0921

          ๐Ÿ› yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ› yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ› - yasuharu-sato
          yasuharu-sato

          ๐Ÿ› + yasuharu-sato
          yasuharu-sato

          ๐Ÿ› zenglian
          zenglian

          ๐Ÿ› zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ› zh3ng
          zh3ng

          ๐Ÿ› zt_soft
          zt_soft

          ๐Ÿ› ztt79
          ztt79

          ๐Ÿ› zzzzfeng
          zzzzfeng

          ๐Ÿ› - รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ› + รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ› ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ› ๅคฉ็ƒญๅƒ่ฅฟ็“œ
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ

          ๐Ÿ› ่Œ…ๅปถๅฎ‰
          ่Œ…ๅปถๅฎ‰

          ๐Ÿ’ป From f031ceeb9ff34691a1b67a77b97bf21b8c01a075 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 13:54:24 +0100 Subject: [PATCH 1687/1962] [doc] Update release notes (#6072, #6081) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 687bdc45f5d..1755af83c19 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -36,6 +36,7 @@ This is a {{ site.pmd.release_type }} release. * java-bestpractices * [#6188](https://github.com/pmd/pmd/issues/6188): \[java] UnitTestShouldIncludeAssert false positive when TestNG @Test.expectedException present * java-errorprone + * [#6072](https://github.com/pmd/pmd/issues/6072): \[java] OverrideBothEqualsAndHashCodeOnComparable should not be required for record classes[ * [#6096](https://github.com/pmd/pmd/issues/6096): \[java] OverrideBothEqualsAndHashCodeOnComparable on class with lombok.EqualsAndHashCode annotation * [#6199](https://github.com/pmd/pmd/issues/6199): \[java] AssignmentInOperand: description of property allowIncrementDecrement is unclear @@ -43,6 +44,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ๏ธ Merged pull requests +* [#6081](https://github.com/pmd/pmd/pull/6081): \[java] Fix #6072: OverrideBothEqualsAndHashCodeOnComparable should not be required for record classes - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) * [#6201](https://github.com/pmd/pmd/pull/6201): \[java] Fix #6199: AssignmentInOperandRule: Update description of allowIncrementDecrement property - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6202](https://github.com/pmd/pmd/pull/6202): \[java] Fix #6188: UnitTestsShouldIncludeAssert - FP when TestNG @Test.expectedException is present - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6204](https://github.com/pmd/pmd/pull/6204): \[apex] Add rule to limit usage of @Future annotation - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) From 21dd21750e1aa542cd575e3406310c2cf3245b4f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 13:54:55 +0100 Subject: [PATCH 1688/1962] Add @Juneezee as a contributor --- .all-contributorsrc | 9 ++ docs/pages/pmd/projectdocs/credits.md | 203 +++++++++++++------------- 2 files changed, 111 insertions(+), 101 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 7307732110f..eabec6eddba 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8326,6 +8326,15 @@ "contributions": [ "bug" ] + }, + { + "login": "Juneezee", + "name": "Eng Zer Jun", + "avatar_url": "https://avatars.githubusercontent.com/u/20135478?v=4", + "profile": "https://github.com/Juneezee", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index a5c6a05ade9..89f5e163e79 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -273,909 +273,910 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Eldrick Wega
          Eldrick Wega

          ๐Ÿ“– Elliotte Rusty Harold
          Elliotte Rusty Harold

          ๐Ÿ’ป Emile
          Emile

          ๐Ÿ› - Eric
          Eric

          ๐Ÿ› + Eng Zer Jun
          Eng Zer Jun

          ๐Ÿ› + Eric
          Eric

          ๐Ÿ› Eric Kintzer
          Eric Kintzer

          ๐Ÿ› Eric Perret
          Eric Perret

          ๐Ÿ› Eric Squires
          Eric Squires

          ๐Ÿ› Erich L Foster
          Erich L Foster

          ๐Ÿ› Erik Bleske
          Erik Bleske

          ๐Ÿ› Erik C. Thauvin
          Erik C. Thauvin

          ๐Ÿ“– ๐Ÿ› - Ernst Reissner
          Ernst Reissner

          ๐Ÿ› + Ernst Reissner
          Ernst Reissner

          ๐Ÿ› Ethan Sargent
          Ethan Sargent

          ๐Ÿ› Ewan Tempero
          Ewan Tempero

          ๐Ÿ› F.W. Dekker
          F.W. Dekker

          ๐Ÿ› FSchliephacke
          FSchliephacke

          ๐Ÿ› Facundo
          Facundo

          ๐Ÿ› Federico Giust
          Federico Giust

          ๐Ÿ› - Fedor Sherstobitov
          Fedor Sherstobitov

          ๐Ÿ› + Fedor Sherstobitov
          Fedor Sherstobitov

          ๐Ÿ› Felix Lampe
          Felix Lampe

          ๐Ÿ› Filip Golonka
          Filip Golonka

          ๐Ÿ› Filipe Esperandio
          Filipe Esperandio

          ๐Ÿ’ป ๐Ÿ› Filippo Barbari
          Filippo Barbari

          ๐Ÿ› Filippo Nova
          Filippo Nova

          ๐Ÿ› Francesco la Torre
          Francesco la Torre

          ๐Ÿ› - Francisco Duarte
          Francisco Duarte

          ๐Ÿ› + Francisco Duarte
          Francisco Duarte

          ๐Ÿ› Frederick Zhang
          Frederick Zhang

          ๐Ÿ› Frieder Bluemle
          Frieder Bluemle

          ๐Ÿ› Frits Jalvingh
          Frits Jalvingh

          ๐Ÿ’ป ๐Ÿ› G. Bazior
          G. Bazior

          ๐Ÿ› Gabe Henkes
          Gabe Henkes

          ๐Ÿ› Gary Gregory
          Gary Gregory

          ๐Ÿ› - Genoud Magloire
          Genoud Magloire

          ๐Ÿ› + Genoud Magloire
          Genoud Magloire

          ๐Ÿ› Geoffrey555
          Geoffrey555

          ๐Ÿ› Georg Romstorfer
          Georg Romstorfer

          ๐Ÿ› Gili Tzabari
          Gili Tzabari

          ๐Ÿ› ๐Ÿ’ป Gio
          Gio

          ๐Ÿ› Gol
          Gol

          ๐Ÿ› Gold856
          Gold856

          ๐Ÿ› ๐Ÿ’ป - Gonzalo Exequiel Ibars Ingman
          Gonzalo Exequiel Ibars Ingman

          ๐Ÿ’ป ๐Ÿ› + Gonzalo Exequiel Ibars Ingman
          Gonzalo Exequiel Ibars Ingman

          ๐Ÿ’ป ๐Ÿ› GooDer
          GooDer

          ๐Ÿ› Gregor Riegler
          Gregor Riegler

          ๐Ÿ› Grzegorz Olszewski
          Grzegorz Olszewski

          ๐Ÿ› Gunther Schrijvers
          Gunther Schrijvers

          ๐Ÿ’ป ๐Ÿ› Gustavo Krieger
          Gustavo Krieger

          ๐Ÿ› Guy Elsmore-Paddock
          Guy Elsmore-Paddock

          ๐Ÿ› - Gรถrkem Mรผlayim
          Gรถrkem Mรผlayim

          ๐Ÿ› + Gรถrkem Mรผlayim
          Gรถrkem Mรผlayim

          ๐Ÿ› Hanzel Godinez
          Hanzel Godinez

          ๐Ÿ› Haoliang Chen
          Haoliang Chen

          ๐Ÿ› Harsh Kukreja
          Harsh Kukreja

          ๐Ÿ› Hassan ALAMI
          Hassan ALAMI

          ๐Ÿ› Heber
          Heber

          ๐Ÿ› Hector Miuler Malpica Gallegos
          Hector Miuler Malpica Gallegos

          ๐Ÿ› - Henning Schmiedehausen
          Henning Schmiedehausen

          ๐Ÿ’ป ๐Ÿ› + Henning Schmiedehausen
          Henning Schmiedehausen

          ๐Ÿ’ป ๐Ÿ› Henning von Bargen
          Henning von Bargen

          ๐Ÿ’ป Hervรฉ Boutemy
          Hervรฉ Boutemy

          ๐Ÿ› Himanshu Pandey
          Himanshu Pandey

          ๐Ÿ› Hokwang Lee
          Hokwang Lee

          ๐Ÿ› Hooperbloob
          Hooperbloob

          ๐Ÿ’ป Hung PHAN
          Hung PHAN

          ๐Ÿ› - IDoCodingStuffs
          IDoCodingStuffs

          ๐Ÿ’ป ๐Ÿ› + IDoCodingStuffs
          IDoCodingStuffs

          ๐Ÿ’ป ๐Ÿ› Iccen Gan
          Iccen Gan

          ๐Ÿ› Ignacio Mariano Tirabasso
          Ignacio Mariano Tirabasso

          ๐Ÿ› Igor Melnichenko
          Igor Melnichenko

          ๐Ÿ› Igor Moreno
          Igor Moreno

          ๐Ÿ› Intelesis-MS
          Intelesis-MS

          ๐Ÿ› Iroha_
          Iroha_

          ๐Ÿ› - Ishan Srivastava
          Ishan Srivastava

          ๐Ÿ› + Ishan Srivastava
          Ishan Srivastava

          ๐Ÿ› Iskren Stanislavov
          Iskren Stanislavov

          ๐Ÿ› Ivan Vakhrushev
          Ivan Vakhrushev

          ๐Ÿ› Ivano Guerini
          Ivano Guerini

          ๐Ÿ› Ivar Andreas Bonsaksen
          Ivar Andreas Bonsaksen

          ๐Ÿ› Ivo ล mรญd
          Ivo ล mรญd

          ๐Ÿ› JJengility
          JJengility

          ๐Ÿ› - Jake Hemmerle
          Jake Hemmerle

          ๐Ÿ› + Jake Hemmerle
          Jake Hemmerle

          ๐Ÿ› Jakub Dupak
          Jakub Dupak

          ๐Ÿ’ป James Harrison
          James Harrison

          ๐Ÿ› ๐Ÿ’ป Jamie Bisotti
          Jamie Bisotti

          ๐Ÿ› Jan
          Jan

          ๐Ÿ› Jan Aertgeerts
          Jan Aertgeerts

          ๐Ÿ’ป ๐Ÿ› Jan Brรผmmer
          Jan Brรผmmer

          ๐Ÿ› - Jan Tล™รญska
          Jan Tล™รญska

          ๐Ÿ› + Jan Tล™รญska
          Jan Tล™รญska

          ๐Ÿ› Jan-Lukas Else
          Jan-Lukas Else

          ๐Ÿ› Jason Qiu
          Jason Qiu

          ๐Ÿ’ป ๐Ÿ“– Jason Williams
          Jason Williams

          ๐Ÿ› Javier Spagnoletti
          Javier Spagnoletti

          ๐Ÿ› Jean-Paul Mayer
          Jean-Paul Mayer

          ๐Ÿ› Jean-Simon Larochelle
          Jean-Simon Larochelle

          ๐Ÿ› - Jeff Bartolotta
          Jeff Bartolotta

          ๐Ÿ’ป ๐Ÿ› + Jeff Bartolotta
          Jeff Bartolotta

          ๐Ÿ’ป ๐Ÿ› Jeff Hube
          Jeff Hube

          ๐Ÿ’ป ๐Ÿ› Jeff Jensen
          Jeff Jensen

          ๐Ÿ› Jeff May
          Jeff May

          ๐Ÿ› Jens Gerdes
          Jens Gerdes

          ๐Ÿ› Jeroen Borgers
          Jeroen Borgers

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข Jeroen Meijer
          Jeroen Meijer

          ๐Ÿ› - Jeroen van Wilgenburg
          Jeroen van Wilgenburg

          ๐Ÿ“– + Jeroen van Wilgenburg
          Jeroen van Wilgenburg

          ๐Ÿ“– Jerome Russ
          Jerome Russ

          ๐Ÿ› JerritEic
          JerritEic

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Jiri Pejchal
          Jiri Pejchal

          ๐Ÿ› Jithin Sunny
          Jithin Sunny

          ๐Ÿ› Jiล™รญ ล korpil
          Jiล™รญ ล korpil

          ๐Ÿ› Joao Machado
          Joao Machado

          ๐Ÿ› - Jochen Krauss
          Jochen Krauss

          ๐Ÿ› + Jochen Krauss
          Jochen Krauss

          ๐Ÿ› Johan Hammar
          Johan Hammar

          ๐Ÿ› John Jetmore
          John Jetmore

          ๐Ÿ“– John Karp
          John Karp

          ๐Ÿ› John Zhang
          John Zhang

          ๐Ÿ› John-Teng
          John-Teng

          ๐Ÿ’ป ๐Ÿ› Jon Moroney
          Jon Moroney

          ๐Ÿ’ป ๐Ÿ› - Jonas Geiregat
          Jonas Geiregat

          ๐Ÿ› + Jonas Geiregat
          Jonas Geiregat

          ๐Ÿ› Jonas KeรŸler
          Jonas KeรŸler

          ๐Ÿ› Jonathan Gillespie
          Jonathan Gillespie

          ๐Ÿ’ต Jonathan Wiesel
          Jonathan Wiesel

          ๐Ÿ’ป ๐Ÿ› Jordan
          Jordan

          ๐Ÿ› Jordan Alligood
          Jordan Alligood

          ๐Ÿ› Jordi Llach
          Jordi Llach

          ๐Ÿ› - Jorge Solรณrzano
          Jorge Solรณrzano

          ๐Ÿ› + Jorge Solรณrzano
          Jorge Solรณrzano

          ๐Ÿ› JorneVL
          JorneVL

          ๐Ÿ› Jose Palafox
          Jose Palafox

          ๐Ÿ› Jose Stovall
          Jose Stovall

          ๐Ÿ› Joseph
          Joseph

          ๐Ÿ’ป Joseph Heenan
          Joseph Heenan

          ๐Ÿ› Josh Feingold
          Josh Feingold

          ๐Ÿ’ป ๐Ÿ› - Josh Holthaus
          Josh Holthaus

          ๐Ÿ› + Josh Holthaus
          Josh Holthaus

          ๐Ÿ› Joshua S Arquilevich
          Joshua S Arquilevich

          ๐Ÿ› Joรฃo Dinis Ferreira
          Joรฃo Dinis Ferreira

          ๐Ÿ“– Joรฃo Ferreira
          Joรฃo Ferreira

          ๐Ÿ’ป ๐Ÿ› Joรฃo Pedro Schmitt
          Joรฃo Pedro Schmitt

          ๐Ÿ› Juan Martรญn Sotuyo Dodero
          Juan Martรญn Sotuyo Dodero

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง Juan Pablo Civile
          Juan Pablo Civile

          ๐Ÿ› - Jude Pereira
          Jude Pereira

          ๐Ÿ’ป + Jude Pereira
          Jude Pereira

          ๐Ÿ’ป Julian Voronetsky
          Julian Voronetsky

          ๐Ÿ› Julien
          Julien

          ๐Ÿ› Julius
          Julius

          ๐Ÿ› JustPRV
          JustPRV

          ๐Ÿ› Justin Stroud
          Justin Stroud

          ๐Ÿ’ป Jรถrn Huxhorn
          Jรถrn Huxhorn

          ๐Ÿ› - KThompso
          KThompso

          ๐Ÿ› + KThompso
          KThompso

          ๐Ÿ› Kai Amundsen
          Kai Amundsen

          ๐Ÿ› Karel Vervaeke
          Karel Vervaeke

          ๐Ÿ› Karl-Andero Mere
          Karl-Andero Mere

          ๐Ÿ› Karl-Philipp Richter
          Karl-Philipp Richter

          ๐Ÿ› Karsten Silz
          Karsten Silz

          ๐Ÿ› Kazuma Watanabe
          Kazuma Watanabe

          ๐Ÿ› - Kernevez
          Kernevez

          ๐Ÿ› + Kernevez
          Kernevez

          ๐Ÿ› Kev
          Kev

          ๐Ÿ› Keve Mรผller
          Keve Mรผller

          ๐Ÿ› Kevin Guerra
          Kevin Guerra

          ๐Ÿ’ป Kevin Jones
          Kevin Jones

          ๐Ÿ› ๐Ÿ’ป Kevin Poorman
          Kevin Poorman

          ๐Ÿ› Kevin Wayne
          Kevin Wayne

          ๐Ÿ› - Kieran Black
          Kieran Black

          ๐Ÿ› + Kieran Black
          Kieran Black

          ๐Ÿ› Kirill Zubov
          Kirill Zubov

          ๐Ÿ› Kirk Clemens
          Kirk Clemens

          ๐Ÿ’ป ๐Ÿ› Klaus Hartl
          Klaus Hartl

          ๐Ÿ› Koen Van Looveren
          Koen Van Looveren

          ๐Ÿ› Kris Scheibe
          Kris Scheibe

          ๐Ÿ’ป ๐Ÿ› Krystian Dabrowski
          Krystian Dabrowski

          ๐Ÿ› ๐Ÿ’ป - Krzysztof Dymek
          Krzysztof Dymek

          ๐Ÿ› + Krzysztof Dymek
          Krzysztof Dymek

          ๐Ÿ› Kunal Thanki
          Kunal Thanki

          ๐Ÿ› Kursat Aktas
          Kursat Aktas

          ๐Ÿ“– LaLucid
          LaLucid

          ๐Ÿ’ป Larry Diamond
          Larry Diamond

          ๐Ÿ’ป ๐Ÿ› Lars Knickrehm
          Lars Knickrehm

          ๐Ÿ› Laurent Bovet
          Laurent Bovet

          ๐Ÿ› ๐Ÿ’ป - Leo Gutierrez
          Leo Gutierrez

          ๐Ÿ› + Leo Gutierrez
          Leo Gutierrez

          ๐Ÿ› LiGaOg
          LiGaOg

          ๐Ÿ’ป Liam Sharp
          Liam Sharp

          ๐Ÿ› Lintsi
          Lintsi

          ๐Ÿ› Linus Fernandes
          Linus Fernandes

          ๐Ÿ› Lixon Lookose
          Lixon Lookose

          ๐Ÿ› Logesh
          Logesh

          ๐Ÿ› - Lorenzo Gabriele
          Lorenzo Gabriele

          ๐Ÿ› + Lorenzo Gabriele
          Lorenzo Gabriele

          ๐Ÿ› Loรฏc Ledoyen
          Loรฏc Ledoyen

          ๐Ÿ› Lucas
          Lucas

          ๐Ÿ› Lucas Silva
          Lucas Silva

          ๐Ÿ› Lucas Soncini
          Lucas Soncini

          ๐Ÿ’ป ๐Ÿ› Luis Alcantar
          Luis Alcantar

          ๐Ÿ’ป Lukas Grรคf
          Lukas Grรคf

          ๐Ÿ’ป - Lukasz Slonina
          Lukasz Slonina

          ๐Ÿ› + Lukasz Slonina
          Lukasz Slonina

          ๐Ÿ› Lukebray
          Lukebray

          ๐Ÿ› Lynn
          Lynn

          ๐Ÿ’ป ๐Ÿ› Lyor Goldstein
          Lyor Goldstein

          ๐Ÿ› MCMicS
          MCMicS

          ๐Ÿ› Macarse
          Macarse

          ๐Ÿ› Machine account for PMD
          Machine account for PMD

          ๐Ÿ’ป - Maciek Siemczyk
          Maciek Siemczyk

          ๐Ÿ› + Maciek Siemczyk
          Maciek Siemczyk

          ๐Ÿ› Maikel Steneker
          Maikel Steneker

          ๐Ÿ’ป ๐Ÿ› Maksim Moiseikin
          Maksim Moiseikin

          ๐Ÿ› Malik
          Malik

          ๐Ÿ› Manfred Koch
          Manfred Koch

          ๐Ÿ› Manuel Moya Ferrer
          Manuel Moya Ferrer

          ๐Ÿ’ป ๐Ÿ› Manuel Romeiro
          Manuel Romeiro

          ๐Ÿ› - Manuel Ryan
          Manuel Ryan

          ๐Ÿ› + Manuel Ryan
          Manuel Ryan

          ๐Ÿ› Marat Vyshegorodtsev
          Marat Vyshegorodtsev

          ๐Ÿ› Marcel Hรคrle
          Marcel Hรคrle

          ๐Ÿ› Marcello Fialho
          Marcello Fialho

          ๐Ÿ› Marcin Dฤ…browski
          Marcin Dฤ…browski

          ๐Ÿ’ป ๐Ÿ› Marcin Rataj
          Marcin Rataj

          ๐Ÿ› Marcono1234
          Marcono1234

          ๐Ÿ› - Mark Adamcin
          Mark Adamcin

          ๐Ÿ› + Mark Adamcin
          Mark Adamcin

          ๐Ÿ› Mark Hall
          Mark Hall

          ๐Ÿ’ป ๐Ÿ› Mark Kolich
          Mark Kolich

          ๐Ÿ› Mark Pritchard
          Mark Pritchard

          ๐Ÿ› Markus Rathgeb
          Markus Rathgeb

          ๐Ÿ› Marquis Wang
          Marquis Wang

          ๐Ÿ› MartGit
          MartGit

          ๐Ÿ› - Martin Feldsztejn
          Martin Feldsztejn

          ๐Ÿ› + Martin Feldsztejn
          Martin Feldsztejn

          ๐Ÿ› Martin Lehmann
          Martin Lehmann

          ๐Ÿ› Martin Spamer
          Martin Spamer

          ๐Ÿ› Martin Tarjรกnyi
          Martin Tarjรกnyi

          ๐Ÿ› MatFl
          MatFl

          ๐Ÿ› Mateusz Stefanski
          Mateusz Stefanski

          ๐Ÿ› Mathias Lagerwall
          Mathias Lagerwall

          ๐Ÿ› - Mathieu Gouin
          Mathieu Gouin

          ๐Ÿ› + Mathieu Gouin
          Mathieu Gouin

          ๐Ÿ› MatiasComercio
          MatiasComercio

          ๐Ÿ’ป ๐Ÿ› Matt Benson
          Matt Benson

          ๐Ÿ› Matt De Poorter
          Matt De Poorter

          ๐Ÿ› Matt Hargett
          Matt Hargett

          ๐Ÿ’ป ๐Ÿ’ต Matt Harrah
          Matt Harrah

          ๐Ÿ› Matt Nelson
          Matt Nelson

          ๐Ÿ› - Matthew Amos
          Matthew Amos

          ๐Ÿ› + Matthew Amos
          Matthew Amos

          ๐Ÿ› Matthew Duggan
          Matthew Duggan

          ๐Ÿ› Matthew Hall
          Matthew Hall

          ๐Ÿ› Matthew Rossner
          Matthew Rossner

          ๐Ÿ› Matรญas Fraga
          Matรญas Fraga

          ๐Ÿ’ป ๐Ÿ› Maxime Robert
          Maxime Robert

          ๐Ÿ’ป ๐Ÿ› MetaBF
          MetaBF

          ๐Ÿ› - Metin Dagcilar
          Metin Dagcilar

          ๐Ÿ› + Metin Dagcilar
          Metin Dagcilar

          ๐Ÿ› Michael
          Michael

          ๐Ÿ› Michael Bell
          Michael Bell

          ๐Ÿ› Michael Bernstein
          Michael Bernstein

          ๐Ÿ› Michael Clay
          Michael Clay

          ๐Ÿ› Michael Dombrowski
          Michael Dombrowski

          ๐Ÿ› Michael Hausegger
          Michael Hausegger

          ๐Ÿ› - Michael Hoefer
          Michael Hoefer

          ๐Ÿ› + Michael Hoefer
          Michael Hoefer

          ๐Ÿ› Michael Kolesnikov
          Michael Kolesnikov

          ๐Ÿ› Michael Mรถbius
          Michael Mรถbius

          ๐Ÿ› Michael N. Lipp
          Michael N. Lipp

          ๐Ÿ› Michael Pellegrini
          Michael Pellegrini

          ๐Ÿ› Michal Kordas
          Michal Kordas

          ๐Ÿ› Michaล‚ Borek
          Michaล‚ Borek

          ๐Ÿ› - Michaล‚ Kuliล„ski
          Michaล‚ Kuliล„ski

          ๐Ÿ› + Michaล‚ Kuliล„ski
          Michaล‚ Kuliล„ski

          ๐Ÿ› Miguel Nรบรฑez Dรญaz-Montes
          Miguel Nรบรฑez Dรญaz-Montes

          ๐Ÿ› Mihai Ionut
          Mihai Ionut

          ๐Ÿ› Mikhail Kuchma
          Mikhail Kuchma

          ๐Ÿ› MiladSadinam
          MiladSadinam

          ๐Ÿ› Mirek Hankus
          Mirek Hankus

          ๐Ÿ› Mitch Spano
          Mitch Spano

          ๐Ÿ’ป ๐Ÿ› - Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ› + Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ› Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ› MrAngry52
          MrAngry52

          ๐Ÿ› Muminur Choudhury
          Muminur Choudhury

          ๐Ÿ› Mykhailo Palahuta
          Mykhailo Palahuta

          ๐Ÿ’ป ๐Ÿ› Nagendra Kumar Singh
          Nagendra Kumar Singh

          ๐Ÿ› Nahuel Barrios
          Nahuel Barrios

          ๐Ÿ› - Nakul Sharma
          Nakul Sharma

          ๐Ÿ› + Nakul Sharma
          Nakul Sharma

          ๐Ÿ› Nathan Braun
          Nathan Braun

          ๐Ÿ› Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ› Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ› Nathanaรซl
          Nathanaรซl

          ๐Ÿ› Naveen
          Naveen

          ๐Ÿ’ป Nazdravi
          Nazdravi

          ๐Ÿ› - Neha-Dhonde
          Neha-Dhonde

          ๐Ÿ› + Neha-Dhonde
          Neha-Dhonde

          ๐Ÿ› Nicholas Doyle
          Nicholas Doyle

          ๐Ÿ› Nick Butcher
          Nick Butcher

          ๐Ÿ› Nico Gallinal
          Nico Gallinal

          ๐Ÿ› Nicola Dal Maso
          Nicola Dal Maso

          ๐Ÿ› Nicolas Filotto
          Nicolas Filotto

          ๐Ÿ’ป Nicolas Vervelle
          Nicolas Vervelle

          ๐Ÿ› - Nicolas Vuillamy
          Nicolas Vuillamy

          ๐Ÿ“– + Nicolas Vuillamy
          Nicolas Vuillamy

          ๐Ÿ“– Nikita Chursin
          Nikita Chursin

          ๐Ÿ› Niklas Baudy
          Niklas Baudy

          ๐Ÿ› Nikolas Havrikov
          Nikolas Havrikov

          ๐Ÿ› Nilesh Virkar
          Nilesh Virkar

          ๐Ÿ› Nimit Patel
          Nimit Patel

          ๐Ÿ› Niranjan Harpale
          Niranjan Harpale

          ๐Ÿ› - Nirvik Patel
          Nirvik Patel

          ๐Ÿ’ป + Nirvik Patel
          Nirvik Patel

          ๐Ÿ’ป Noah Sussman
          Noah Sussman

          ๐Ÿ› Noah0120
          Noah0120

          ๐Ÿ› Noam Tamim
          Noam Tamim

          ๐Ÿ› Noel Grandin
          Noel Grandin

          ๐Ÿ› Olaf Haalstra
          Olaf Haalstra

          ๐Ÿ› Oleg Andreych
          Oleg Andreych

          ๐Ÿ’ป ๐Ÿ› - Oleg Pavlenko
          Oleg Pavlenko

          ๐Ÿ› + Oleg Pavlenko
          Oleg Pavlenko

          ๐Ÿ› Oleksii Dykov
          Oleksii Dykov

          ๐Ÿ’ป ๐Ÿ› Oliver Eikemeier
          Oliver Eikemeier

          ๐Ÿ› Oliver Siegmar
          Oliver Siegmar

          ๐Ÿ’ต Olivier Parent
          Olivier Parent

          ๐Ÿ’ป ๐Ÿ› Ollie Abbey
          Ollie Abbey

          ๐Ÿ’ป ๐Ÿ› Olof-Joachim Frahm (ๆฌง้›…็ฆ)
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)

          ๐Ÿ› - Ondrej Kratochvil
          Ondrej Kratochvil

          ๐Ÿ› + Ondrej Kratochvil
          Ondrej Kratochvil

          ๐Ÿ› OverDrone
          OverDrone

          ๐Ÿ› Ozan Gulle
          Ozan Gulle

          ๐Ÿ’ป ๐Ÿ› PUNEET JAIN
          PUNEET JAIN

          ๐Ÿ› Pankraz76
          Pankraz76

          ๐Ÿ’ป ๐Ÿ› Parbati Bose
          Parbati Bose

          ๐Ÿ› Paul Berg
          Paul Berg

          ๐Ÿ› - Paul Guyot
          Paul Guyot

          ๐Ÿ’ป + Paul Guyot
          Paul Guyot

          ๐Ÿ’ป Pavel Bludov
          Pavel Bludov

          ๐Ÿ› Pavel Miฤka
          Pavel Miฤka

          ๐Ÿ› Pedro Nuno Santos
          Pedro Nuno Santos

          ๐Ÿ› Pedro Rijo
          Pedro Rijo

          ๐Ÿ› Pelisse Romain
          Pelisse Romain

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Per Abich
          Per Abich

          ๐Ÿ’ป - Pete Davids
          Pete Davids

          ๐Ÿ› + Pete Davids
          Pete Davids

          ๐Ÿ› Peter Bruin
          Peter Bruin

          ๐Ÿ› Peter Chittum
          Peter Chittum

          ๐Ÿ’ป ๐Ÿ› Peter Cudmore
          Peter Cudmore

          ๐Ÿ› Peter Kasson
          Peter Kasson

          ๐Ÿ› Peter Kofler
          Peter Kofler

          ๐Ÿ› Peter Paul Bakker
          Peter Paul Bakker

          ๐Ÿ’ป ๐Ÿ› - Peter Rader
          Peter Rader

          ๐Ÿ› + Peter Rader
          Peter Rader

          ๐Ÿ› Pham Hai Trung
          Pham Hai Trung

          ๐Ÿ› Philip Graf
          Philip Graf

          ๐Ÿ’ป ๐Ÿ› Philip Hachey
          Philip Hachey

          ๐Ÿ› Philippe Ozil
          Philippe Ozil

          ๐Ÿ› Phinehas Artemix
          Phinehas Artemix

          ๐Ÿ› Phokham Nonava
          Phokham Nonava

          ๐Ÿ› - Pim van der Loos
          Pim van der Loos

          ๐Ÿ’ป โš ๏ธ + Pim van der Loos
          Pim van der Loos

          ๐Ÿ’ป โš ๏ธ Piotr Koลผuchowski
          Piotr Koลผuchowski

          ๐Ÿ› Piotr Szymaล„ski
          Piotr Szymaล„ski

          ๐Ÿ› Piotrek ลปygieล‚o
          Piotrek ลปygieล‚o

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– Pranay Jaiswal
          Pranay Jaiswal

          ๐Ÿ› Prasad Kamath
          Prasad Kamath

          ๐Ÿ› Prasanna
          Prasanna

          ๐Ÿ› - Presh-AR
          Presh-AR

          ๐Ÿ› + Presh-AR
          Presh-AR

          ๐Ÿ› Puneet1726
          Puneet1726

          ๐Ÿ› RBRi
          RBRi

          ๐Ÿ› Rafael Cortรชs
          Rafael Cortรชs

          ๐Ÿ› RaheemShaik999
          RaheemShaik999

          ๐Ÿ› RajeshR
          RajeshR

          ๐Ÿ’ป ๐Ÿ› Ramachandra Mohan
          Ramachandra Mohan

          ๐Ÿ› - Ramel0921
          Ramel0921

          ๐Ÿ› + Ramel0921
          Ramel0921

          ๐Ÿ› Raquel Pau
          Raquel Pau

          ๐Ÿ› Ravikiran Janardhana
          Ravikiran Janardhana

          ๐Ÿ› Reda Benhemmouche
          Reda Benhemmouche

          ๐Ÿ› Reinhard Schiedermeier
          Reinhard Schiedermeier

          ๐Ÿ› Renato Oliveira
          Renato Oliveira

          ๐Ÿ’ป ๐Ÿ› Rich DiCroce
          Rich DiCroce

          ๐Ÿ› - Richard Corfield
          Richard Corfield

          ๐Ÿ’ป + Richard Corfield
          Richard Corfield

          ๐Ÿ’ป Richard Corfield
          Richard Corfield

          ๐Ÿ› ๐Ÿ’ป Riot R1cket
          Riot R1cket

          ๐Ÿ› Rishabh Jain
          Rishabh Jain

          ๐Ÿ› RishabhDeep Singh
          RishabhDeep Singh

          ๐Ÿ› Rob Baillie
          Rob Baillie

          ๐Ÿ› Robbie Martinus
          Robbie Martinus

          ๐Ÿ’ป ๐Ÿ› - Robert Henry
          Robert Henry

          ๐Ÿ› + Robert Henry
          Robert Henry

          ๐Ÿ› Robert Mihaly
          Robert Mihaly

          ๐Ÿ› Robert Painsi
          Robert Painsi

          ๐Ÿ› Robert Russell
          Robert Russell

          ๐Ÿ› Robert Sรถsemann
          Robert Sรถsemann

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ› Robert Whitebit
          Robert Whitebit

          ๐Ÿ› Robin Richtsfeld
          Robin Richtsfeld

          ๐Ÿ› - Robin Stocker
          Robin Stocker

          ๐Ÿ’ป ๐Ÿ› + Robin Stocker
          Robin Stocker

          ๐Ÿ’ป ๐Ÿ› Robin Wils
          Robin Wils

          ๐Ÿ› RochusOest
          RochusOest

          ๐Ÿ› Rodolfo Noviski
          Rodolfo Noviski

          ๐Ÿ› Rodrigo Casara
          Rodrigo Casara

          ๐Ÿ› Rodrigo Fernandes
          Rodrigo Fernandes

          ๐Ÿ› Roman Salvador
          Roman Salvador

          ๐Ÿ’ป ๐Ÿ› - Ronald Blaschke
          Ronald Blaschke

          ๐Ÿ› + Ronald Blaschke
          Ronald Blaschke

          ๐Ÿ› Rรณbert Papp
          Rรณbert Papp

          ๐Ÿ› Saikat Sengupta
          Saikat Sengupta

          ๐Ÿ› Saksham Handu
          Saksham Handu

          ๐Ÿ› Saladoc
          Saladoc

          ๐Ÿ› Salesforce Bob Lightning
          Salesforce Bob Lightning

          ๐Ÿ› Sam Carlberg
          Sam Carlberg

          ๐Ÿ› - Sascha Riemer
          Sascha Riemer

          ๐Ÿ› + Sascha Riemer
          Sascha Riemer

          ๐Ÿ› Sashko
          Sashko

          ๐Ÿ’ป Satoshi Kubo
          Satoshi Kubo

          ๐Ÿ› Scott Kennedy
          Scott Kennedy

          ๐Ÿ› Scott Wells
          Scott Wells

          ๐Ÿ› ๐Ÿ’ป Scrates1
          Scrates1

          ๐Ÿ› ๐Ÿ’ป Scrsloota
          Scrsloota

          ๐Ÿ’ป - Sebastian Bรถgl
          Sebastian Bรถgl

          ๐Ÿ› + Sebastian Bรถgl
          Sebastian Bรถgl

          ๐Ÿ› Sebastian Davids
          Sebastian Davids

          ๐Ÿ› Sebastian Lรถvdahl
          Sebastian Lรถvdahl

          ๐Ÿ› Sebastian Schuberth
          Sebastian Schuberth

          ๐Ÿ› Sebastian Schwarz
          Sebastian Schwarz

          ๐Ÿ› Seren
          Seren

          ๐Ÿ› ๐Ÿ’ป Sergey Gorbaty
          Sergey Gorbaty

          ๐Ÿ› - Sergey Kozlov
          Sergey Kozlov

          ๐Ÿ› + Sergey Kozlov
          Sergey Kozlov

          ๐Ÿ› Sergey Yanzin
          Sergey Yanzin

          ๐Ÿ’ป ๐Ÿ› Seth Wilcox
          Seth Wilcox

          ๐Ÿ’ป Shai Bennathan
          Shai Bennathan

          ๐Ÿ› ๐Ÿ’ป Shubham
          Shubham

          ๐Ÿ’ป ๐Ÿ› Simon Abykov
          Simon Abykov

          ๐Ÿ’ป ๐Ÿ› Simon Xiao
          Simon Xiao

          ๐Ÿ› - Srinivasan Venkatachalam
          Srinivasan Venkatachalam

          ๐Ÿ› + Srinivasan Venkatachalam
          Srinivasan Venkatachalam

          ๐Ÿ› Stanislav Gromov
          Stanislav Gromov

          ๐Ÿ› Stanislav Myachenkov
          Stanislav Myachenkov

          ๐Ÿ’ป Stefan Birkner
          Stefan Birkner

          ๐Ÿ› Stefan Bohn
          Stefan Bohn

          ๐Ÿ› Stefan Endrullis
          Stefan Endrullis

          ๐Ÿ› Stefan Klรถss-Schuster
          Stefan Klรถss-Schuster

          ๐Ÿ› - Stefan Wolf
          Stefan Wolf

          ๐Ÿ› + Stefan Wolf
          Stefan Wolf

          ๐Ÿ› Stephan H. Wissel
          Stephan H. Wissel

          ๐Ÿ› Stephen
          Stephen

          ๐Ÿ› Stephen Carter
          Stephen Carter

          ๐Ÿ› Stephen Friedrich
          Stephen Friedrich

          ๐Ÿ› Steve Babula
          Steve Babula

          ๐Ÿ’ป Steve White
          Steve White

          ๐Ÿ› - Steven Schlansker
          Steven Schlansker

          ๐Ÿ› + Steven Schlansker
          Steven Schlansker

          ๐Ÿ› Steven Stearns
          Steven Stearns

          ๐Ÿ› ๐Ÿ’ป Stexxe
          Stexxe

          ๐Ÿ› Stian Lรฅgstad
          Stian Lรฅgstad

          ๐Ÿ› StuartClayton5
          StuartClayton5

          ๐Ÿ› Supun Arunoda
          Supun Arunoda

          ๐Ÿ› Suren Abrahamyan
          Suren Abrahamyan

          ๐Ÿ› - Suvashri
          Suvashri

          ๐Ÿ“– + Suvashri
          Suvashri

          ๐Ÿ“– Sven Barden
          Sven Barden

          ๐Ÿ› SwatiBGupta1110
          SwatiBGupta1110

          ๐Ÿ› SyedThoufich
          SyedThoufich

          ๐Ÿ› Szymon Sasin
          Szymon Sasin

          ๐Ÿ› T-chuangxin
          T-chuangxin

          ๐Ÿ› TERAI Atsuhiro
          TERAI Atsuhiro

          ๐Ÿ› - TIOBE Software
          TIOBE Software

          ๐Ÿ’ป ๐Ÿ› + TIOBE Software
          TIOBE Software

          ๐Ÿ’ป ๐Ÿ› Tarush Singh
          Tarush Singh

          ๐Ÿ’ป Taylor Smock
          Taylor Smock

          ๐Ÿ› Techeira Damiรกn
          Techeira Damiรกn

          ๐Ÿ’ป ๐Ÿ› Ted Husted
          Ted Husted

          ๐Ÿ› TehBakker
          TehBakker

          ๐Ÿ› The Gitter Badger
          The Gitter Badger

          ๐Ÿ› - Theodoor
          Theodoor

          ๐Ÿ› + Theodoor
          Theodoor

          ๐Ÿ› Thiago Henrique Hรผpner
          Thiago Henrique Hรผpner

          ๐Ÿ› Thibault Meyer
          Thibault Meyer

          ๐Ÿ› Thomas Gรผttler
          Thomas Gรผttler

          ๐Ÿ› Thomas Jones-Low
          Thomas Jones-Low

          ๐Ÿ› Thomas Smith
          Thomas Smith

          ๐Ÿ’ป ๐Ÿ› ThrawnCA
          ThrawnCA

          ๐Ÿ› - Thu Vo
          Thu Vo

          ๐Ÿ› + Thu Vo
          Thu Vo

          ๐Ÿ› Thunderforge
          Thunderforge

          ๐Ÿ’ป ๐Ÿ› Tim van der Lippe
          Tim van der Lippe

          ๐Ÿ› Tobias Weimer
          Tobias Weimer

          ๐Ÿ’ป ๐Ÿ› Tom Copeland
          Tom Copeland

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– Tom Daly
          Tom Daly

          ๐Ÿ› Tomas
          Tomas

          ๐Ÿ› - Tomer Figenblat
          Tomer Figenblat

          ๐Ÿ› + Tomer Figenblat
          Tomer Figenblat

          ๐Ÿ› Tomi De Lucca
          Tomi De Lucca

          ๐Ÿ’ป ๐Ÿ› Tony
          Tony

          ๐Ÿ“– Torsten Kleiber
          Torsten Kleiber

          ๐Ÿ› Torsten Krause
          Torsten Krause

          ๐Ÿ› TrackerSB
          TrackerSB

          ๐Ÿ› Tyson Stewart
          Tyson Stewart

          ๐Ÿ› - Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ› + Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ› UncleOwen
          UncleOwen

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– Utku Cuhadaroglu
          Utku Cuhadaroglu

          ๐Ÿ’ป ๐Ÿ› Valentin Brandl
          Valentin Brandl

          ๐Ÿ› Valeria
          Valeria

          ๐Ÿ› Valery Yatsynovich
          Valery Yatsynovich

          ๐Ÿ“– Vasily Anisimov
          Vasily Anisimov

          ๐Ÿ› - Vedant Chokshi
          Vedant Chokshi

          ๐Ÿ› + Vedant Chokshi
          Vedant Chokshi

          ๐Ÿ› Vibhor Goyal
          Vibhor Goyal

          ๐Ÿ› Vickenty Fesunov
          Vickenty Fesunov

          ๐Ÿ› Victor Noรซl
          Victor Noรซl

          ๐Ÿ› Vincent Galloy
          Vincent Galloy

          ๐Ÿ’ป Vincent HUYNH
          Vincent HUYNH

          ๐Ÿ› Vincent Maurin
          Vincent Maurin

          ๐Ÿ› - Vincent Potucek
          Vincent Potucek

          ๐Ÿ’ป + Vincent Potucek
          Vincent Potucek

          ๐Ÿ’ป Vincent Privat
          Vincent Privat

          ๐Ÿ› Vincent Zorge
          Vincent Zorge

          ๐Ÿ› Vishhwas
          Vishhwas

          ๐Ÿ› Vishv_Android
          Vishv_Android

          ๐Ÿ› Vitalii Yevtushenko
          Vitalii Yevtushenko

          ๐Ÿ› Vitaly
          Vitaly

          ๐Ÿ› - Vitaly Polonetsky
          Vitaly Polonetsky

          ๐Ÿ› + Vitaly Polonetsky
          Vitaly Polonetsky

          ๐Ÿ› Vojtech Polivka
          Vojtech Polivka

          ๐Ÿ› Vsevolod Zholobov
          Vsevolod Zholobov

          ๐Ÿ› Vyom Yadav
          Vyom Yadav

          ๐Ÿ’ป Wang Shidong
          Wang Shidong

          ๐Ÿ› Waqas Ahmed
          Waqas Ahmed

          ๐Ÿ› Wayne J. Earl
          Wayne J. Earl

          ๐Ÿ› - Wchenghui
          Wchenghui

          ๐Ÿ› + Wchenghui
          Wchenghui

          ๐Ÿ› Wener
          Wener

          ๐Ÿ’ป Will Winder
          Will Winder

          ๐Ÿ› Willem A. Hajenius
          Willem A. Hajenius

          ๐Ÿ’ป William Brockhus
          William Brockhus

          ๐Ÿ’ป ๐Ÿ› Wilson Kurniawan
          Wilson Kurniawan

          ๐Ÿ› Wim Deblauwe
          Wim Deblauwe

          ๐Ÿ› - Wolf2323
          Wolf2323

          ๐Ÿ› + Wolf2323
          Wolf2323

          ๐Ÿ› Woongsik Choi
          Woongsik Choi

          ๐Ÿ› XenoAmess
          XenoAmess

          ๐Ÿ’ป ๐Ÿ› Yang
          Yang

          ๐Ÿ’ป YaroslavTER
          YaroslavTER

          ๐Ÿ› Yasar Shaikh
          Yasar Shaikh

          ๐Ÿ’ป Young Chan
          Young Chan

          ๐Ÿ’ป ๐Ÿ› - YuJin Kim
          YuJin Kim

          ๐Ÿ› + YuJin Kim
          YuJin Kim

          ๐Ÿ› Yuri Dolzhenko
          Yuri Dolzhenko

          ๐Ÿ› Yurii Dubinka
          Yurii Dubinka

          ๐Ÿ› Zbynek Konecny
          Zbynek Konecny

          ๐Ÿ› ๐Ÿ’ป Zoltan Farkas
          Zoltan Farkas

          ๐Ÿ› Zustin
          Zustin

          ๐Ÿ› aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป - alexmodis
          alexmodis

          ๐Ÿ› + alexmodis
          alexmodis

          ๐Ÿ› andreoss
          andreoss

          ๐Ÿ› andrey81inmd
          andrey81inmd

          ๐Ÿ’ป ๐Ÿ› anicoara
          anicoara

          ๐Ÿ› arunprasathav
          arunprasathav

          ๐Ÿ› asiercamara
          asiercamara

          ๐Ÿ› astillich-igniti
          astillich-igniti

          ๐Ÿ’ป - avesolovksyy
          avesolovksyy

          ๐Ÿ› + avesolovksyy
          avesolovksyy

          ๐Ÿ› avishvat
          avishvat

          ๐Ÿ› avivmu
          avivmu

          ๐Ÿ› axelbarfod1
          axelbarfod1

          ๐Ÿ› b-3-n
          b-3-n

          ๐Ÿ› balbhadra9
          balbhadra9

          ๐Ÿ› base23de
          base23de

          ๐Ÿ› - bergander
          bergander

          ๐Ÿ› ๐Ÿ’ป + bergander
          bergander

          ๐Ÿ› ๐Ÿ’ป berkam
          berkam

          ๐Ÿ’ป ๐Ÿ› bmeier-pros
          bmeier-pros

          ๐Ÿ› breizh31
          breizh31

          ๐Ÿ› caesarkim
          caesarkim

          ๐Ÿ› caiocarvalhotero
          caiocarvalhotero

          ๐Ÿ› carolyujing
          carolyujing

          ๐Ÿ› - cbfiddle
          cbfiddle

          ๐Ÿ› + cbfiddle
          cbfiddle

          ๐Ÿ› cesares-basilico
          cesares-basilico

          ๐Ÿ› chrite
          chrite

          ๐Ÿ› ciufudean
          ciufudean

          ๐Ÿ“– cobratbq
          cobratbq

          ๐Ÿ› coladict
          coladict

          ๐Ÿ› cosmoJFH
          cosmoJFH

          ๐Ÿ› - cristalp
          cristalp

          ๐Ÿ› + cristalp
          cristalp

          ๐Ÿ› crunsk
          crunsk

          ๐Ÿ› csrma
          csrma

          ๐Ÿ› cwholmes
          cwholmes

          ๐Ÿ› cyberjj999
          cyberjj999

          ๐Ÿ› cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“– d1ss0nanz
          d1ss0nanz

          ๐Ÿ› - dague1
          dague1

          ๐Ÿ“– + dague1
          dague1

          ๐Ÿ“– dalizi007
          dalizi007

          ๐Ÿ’ป danbrycefairsailcom
          danbrycefairsailcom

          ๐Ÿ› dariansanity
          dariansanity

          ๐Ÿ› darrenmiliband
          darrenmiliband

          ๐Ÿ› davidburstrom
          davidburstrom

          ๐Ÿ› dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ› - deepak-patra
          deepak-patra

          ๐Ÿ› + deepak-patra
          deepak-patra

          ๐Ÿ› dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ› dinesh150
          dinesh150

          ๐Ÿ› diziaq
          diziaq

          ๐Ÿ› dreaminpast123
          dreaminpast123

          ๐Ÿ› duanyanan
          duanyanan

          ๐Ÿ› dutt-sanjay
          dutt-sanjay

          ๐Ÿ› - duursma
          duursma

          ๐Ÿ’ป + duursma
          duursma

          ๐Ÿ’ป dylanleung
          dylanleung

          ๐Ÿ› dzeigler
          dzeigler

          ๐Ÿ› eant60
          eant60

          ๐Ÿ› ekkirala
          ekkirala

          ๐Ÿ› emersonmoura
          emersonmoura

          ๐Ÿ› emouty
          emouty

          ๐Ÿ’ป ๐Ÿ› - eugenepugach
          eugenepugach

          ๐Ÿ› + eugenepugach
          eugenepugach

          ๐Ÿ› fairy
          fairy

          ๐Ÿ› filiprafalowicz
          filiprafalowicz

          ๐Ÿ’ป flxbl-io
          flxbl-io

          ๐Ÿ’ต foxmason
          foxmason

          ๐Ÿ› frankegabor
          frankegabor

          ๐Ÿ› frankl
          frankl

          ๐Ÿ› - freafrea
          freafrea

          ๐Ÿ› + freafrea
          freafrea

          ๐Ÿ› fsapatin
          fsapatin

          ๐Ÿ› gearsethenry
          gearsethenry

          ๐Ÿ› gracia19
          gracia19

          ๐Ÿ› gudzpoz
          gudzpoz

          ๐Ÿ› guo fei
          guo fei

          ๐Ÿ› gurmsc5
          gurmsc5

          ๐Ÿ› - gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ› + gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ› haigsn
          haigsn

          ๐Ÿ› hemanshu070
          hemanshu070

          ๐Ÿ› henrik242
          henrik242

          ๐Ÿ› hongpuwu
          hongpuwu

          ๐Ÿ› hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ› igniti GmbH
          igniti GmbH

          ๐Ÿ› - ilovezfs
          ilovezfs

          ๐Ÿ› + ilovezfs
          ilovezfs

          ๐Ÿ› imax-erik
          imax-erik

          ๐Ÿ› itaigilo
          itaigilo

          ๐Ÿ› jakivey32
          jakivey32

          ๐Ÿ› jbennett2091
          jbennett2091

          ๐Ÿ› jcamerin
          jcamerin

          ๐Ÿ› jkeener1
          jkeener1

          ๐Ÿ› - jmetertea
          jmetertea

          ๐Ÿ› + jmetertea
          jmetertea

          ๐Ÿ› johnra2
          johnra2

          ๐Ÿ’ป johnzhao9
          johnzhao9

          ๐Ÿ› josemanuelrolon
          josemanuelrolon

          ๐Ÿ’ป ๐Ÿ› julees7
          julees7

          ๐Ÿ’ป ๐Ÿ› kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ› karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“– - karwer
          karwer

          ๐Ÿ› + karwer
          karwer

          ๐Ÿ› kaulonline
          kaulonline

          ๐Ÿ› kdaemonv
          kdaemonv

          ๐Ÿ› kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ› kfranic
          kfranic

          ๐Ÿ› khalidkh
          khalidkh

          ๐Ÿ› - koalalam
          koalalam

          ๐Ÿ› + koalalam
          koalalam

          ๐Ÿ› krzyk
          krzyk

          ๐Ÿ› lasselindqvist
          lasselindqvist

          ๐Ÿ› lgemeinhardt
          lgemeinhardt

          ๐Ÿ› lihuaib
          lihuaib

          ๐Ÿ› liqingjun123
          liqingjun123

          ๐Ÿ› lonelyma1021
          lonelyma1021

          ๐Ÿ› - lothas
          lothas

          ๐Ÿ› + lothas
          lothas

          ๐Ÿ› lpeddy
          lpeddy

          ๐Ÿ› lujiefsi
          lujiefsi

          ๐Ÿ’ป lukelukes
          lukelukes

          ๐Ÿ’ป lyriccoder
          lyriccoder

          ๐Ÿ› marcelmore
          marcelmore

          ๐Ÿ› matchbox
          matchbox

          ๐Ÿ› - matthiaskraaz
          matthiaskraaz

          ๐Ÿ› + matthiaskraaz
          matthiaskraaz

          ๐Ÿ› meandonlyme
          meandonlyme

          ๐Ÿ› mikesive
          mikesive

          ๐Ÿ› milossesic
          milossesic

          ๐Ÿ› mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป mrclmh
          mrclmh

          ๐Ÿ› ๐Ÿ’ป - mriddell95
          mriddell95

          ๐Ÿ› + mriddell95
          mriddell95

          ๐Ÿ› mrlzh
          mrlzh

          ๐Ÿ› msloan
          msloan

          ๐Ÿ› mucharlaravalika
          mucharlaravalika

          ๐Ÿ› mvenneman
          mvenneman

          ๐Ÿ› nareshl119
          nareshl119

          ๐Ÿ› nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ› - noerremark
          noerremark

          ๐Ÿ› + noerremark
          noerremark

          ๐Ÿ› novsirion
          novsirion

          ๐Ÿ› nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
          oggboy

          ๐Ÿ› oinume
          oinume

          ๐Ÿ› orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ› pablogomez2197
          pablogomez2197

          ๐Ÿ› - pacvz
          pacvz

          ๐Ÿ’ป + pacvz
          pacvz

          ๐Ÿ’ป pallavi agarwal
          pallavi agarwal

          ๐Ÿ› pankratz76
          pankratz76

          ๐Ÿ› parksungrin
          parksungrin

          ๐Ÿ› patpatpat123
          patpatpat123

          ๐Ÿ› patriksevallius
          patriksevallius

          ๐Ÿ› pbrajesh1
          pbrajesh1

          ๐Ÿ› - phoenix384
          phoenix384

          ๐Ÿ› + phoenix384
          phoenix384

          ๐Ÿ› piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป plan3d
          plan3d

          ๐Ÿ› poojasix
          poojasix

          ๐Ÿ› prabhushrikant
          prabhushrikant

          ๐Ÿ› pujitha8783
          pujitha8783

          ๐Ÿ› r-r-a-j
          r-r-a-j

          ๐Ÿ› - raghujayjunk
          raghujayjunk

          ๐Ÿ› + raghujayjunk
          raghujayjunk

          ๐Ÿ› rajeshveera
          rajeshveera

          ๐Ÿ› rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ› recdevs
          recdevs

          ๐Ÿ› reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ› rijkt
          rijkt

          ๐Ÿ› rillig-tk
          rillig-tk

          ๐Ÿ› - rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ› + rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ› rnveach
          rnveach

          ๐Ÿ› rubenporras
          rubenporras

          ๐Ÿ› rxmicro
          rxmicro

          ๐Ÿ› ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ› sabi0
          sabi0

          ๐Ÿ› samc-gearset
          samc-gearset

          ๐Ÿ“– - scais
          scais

          ๐Ÿ› + scais
          scais

          ๐Ÿ› schosin
          schosin

          ๐Ÿ› screamingfrog
          screamingfrog

          ๐Ÿ’ต sebbASF
          sebbASF

          ๐Ÿ› sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป shilko2013
          shilko2013

          ๐Ÿ› shiomiyan
          shiomiyan

          ๐Ÿ“– - simeonKondr
          simeonKondr

          ๐Ÿ› + simeonKondr
          simeonKondr

          ๐Ÿ› snajberk
          snajberk

          ๐Ÿ› sniperrifle2004
          sniperrifle2004

          ๐Ÿ› snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป soloturn
          soloturn

          ๐Ÿ› soyodream
          soyodream

          ๐Ÿ› sratz
          sratz

          ๐Ÿ› - stonio
          stonio

          ๐Ÿ› + stonio
          stonio

          ๐Ÿ› sturton
          sturton

          ๐Ÿ’ป ๐Ÿ› sudharmohan
          sudharmohan

          ๐Ÿ› suruchidawar
          suruchidawar

          ๐Ÿ› svenfinitiv
          svenfinitiv

          ๐Ÿ› szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป tashiscool
          tashiscool

          ๐Ÿ› - test-git-hook
          test-git-hook

          ๐Ÿ› + test-git-hook
          test-git-hook

          ๐Ÿ› testation21
          testation21

          ๐Ÿ’ป ๐Ÿ› thanosa
          thanosa

          ๐Ÿ› tiandiyixian
          tiandiyixian

          ๐Ÿ› tobwoerk
          tobwoerk

          ๐Ÿ› tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป trentchilders
          trentchilders

          ๐Ÿ› - triandicAnt
          triandicAnt

          ๐Ÿ› + triandicAnt
          triandicAnt

          ๐Ÿ› trishul14
          trishul14

          ๐Ÿ› tsui
          tsui

          ๐Ÿ› wangzitom12306
          wangzitom12306

          ๐Ÿ› winhkey
          winhkey

          ๐Ÿ› witherspore
          witherspore

          ๐Ÿ› wjljack
          wjljack

          ๐Ÿ› - wuchiuwong
          wuchiuwong

          ๐Ÿ› + wuchiuwong
          wuchiuwong

          ๐Ÿ› xingsong
          xingsong

          ๐Ÿ› xioayuge
          xioayuge

          ๐Ÿ› xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ› xuanuy
          xuanuy

          ๐Ÿ› xyf0921
          xyf0921

          ๐Ÿ› yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ› - yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ› + yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ› yasuharu-sato
          yasuharu-sato

          ๐Ÿ› zenglian
          zenglian

          ๐Ÿ› zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ› zh3ng
          zh3ng

          ๐Ÿ› zt_soft
          zt_soft

          ๐Ÿ› ztt79
          ztt79

          ๐Ÿ› - zzzzfeng
          zzzzfeng

          ๐Ÿ› + zzzzfeng
          zzzzfeng

          ๐Ÿ› รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ› ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ› ๅคฉ็ƒญๅƒ่ฅฟ็“œ
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ

          ๐Ÿ› From 879d067c4e323c6bd7e04a1b73fadf8f0cf4859c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 13:59:40 +0100 Subject: [PATCH 1689/1962] [doc] Update release notes (#6053, #6192) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 8298a6d3e56..b44d1221a89 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -35,6 +35,8 @@ This is a {{ site.pmd.release_type }} release. * [#6203](https://github.com/pmd/pmd/issues/6203): \[apex] New Rule: Avoid Future Annotation * java-bestpractices * [#6188](https://github.com/pmd/pmd/issues/6188): \[java] UnitTestShouldIncludeAssert false positive when TestNG @Test.expectedException present +* java-codestyle + * [#6053](https://github.com/pmd/pmd/issues/6053): \[java] ModifierOrder false-positives with type annotations and type parameters (typeAnnotations = anywhere) * java-errorprone * [#6072](https://github.com/pmd/pmd/issues/6072): \[java] OverrideBothEqualsAndHashCodeOnComparable should not be required for record classes * [#6092](https://github.com/pmd/pmd/issues/6092): \[java] AssignmentInOperand false positive in 7.17.0 for case blocks in switch statements @@ -46,6 +48,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ๏ธ Merged pull requests * [#6081](https://github.com/pmd/pmd/pull/6081): \[java] Fix #6072: OverrideBothEqualsAndHashCodeOnComparable should not be required for record classes - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6192](https://github.com/pmd/pmd/pull/6192): \[java] Fix #6053: ModifierOrder - consider type params - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6201](https://github.com/pmd/pmd/pull/6201): \[java] Fix #6199: AssignmentInOperandRule: Update description of allowIncrementDecrement property - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6202](https://github.com/pmd/pmd/pull/6202): \[java] Fix #6188: UnitTestsShouldIncludeAssert - FP when TestNG @Test.expectedException is present - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6204](https://github.com/pmd/pmd/pull/6204): \[apex] Add rule to limit usage of @Future annotation - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) From 926a3d2a94802538954170f2554dbf42069415f0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 14:03:21 +0100 Subject: [PATCH 1690/1962] [doc] Update release notes (#6194) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 713fd1aae64..08155fe2e9c 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -176,6 +176,7 @@ checkstyle version during the build. * [#6185](https://github.com/pmd/pmd/pull/6185): \[java] Fix #6131: Correct enum values for ModifierOrder - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6190](https://github.com/pmd/pmd/pull/6190): \[apex] Update ApexDoc rule to match the published specification - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) * [#6191](https://github.com/pmd/pmd/pull/6191): \[java] HardCodedCryptoKey: NPE when constants from parent class are used - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6194](https://github.com/pmd/pmd/pull/6194): chore: always place type annotations on the type - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ๏ธ Dependency updates From d440d3eb414d04db5e50a8ed70ece7a715e28674 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 14:06:13 +0100 Subject: [PATCH 1691/1962] [doc] Update release notes (#6195) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..5fb8025e956 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -30,6 +30,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ๏ธ Merged pull requests +* [#6195](https://github.com/pmd/pmd/pull/6195): chore: always compare enums with == - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ๏ธ Dependency updates From e5b80f3042fb7e2d5dbc0e646d4f2676bdbb9070 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 14:14:04 +0100 Subject: [PATCH 1692/1962] [doc] Update release notes (#6193, #6196) --- docs/pages/release_notes.md | 5 +++++ pmd-java/src/main/resources/rulesets/java/quickstart.xml | 1 + 2 files changed, 6 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index ee8cd73e43b..ece04a8bc87 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -29,12 +29,16 @@ This is a {{ site.pmd.release_type }} release. * The new Apex rule {%rule apex/bestpractices/AvoidFutureAnnotation %} finds usages of the `@Future` annotation. It is a legacy way to execute asynchronous Apex code. New code should implement the `Queueable` interface instead. +* The new Java rule {%rule java/bestpractices/EnumComparison %} finds usages of `equals()` on + enum constants or values. Enums should be compared directly with `==` instead of `equals()` which + has some advantages (e.g. static type checking at compile time). ### ๐Ÿ›๏ธ Fixed Issues * apex-bestpractices * [#6203](https://github.com/pmd/pmd/issues/6203): \[apex] New Rule: Avoid Future Annotation * java-bestpractices * [#6188](https://github.com/pmd/pmd/issues/6188): \[java] UnitTestShouldIncludeAssert false positive when TestNG @Test.expectedException present + * [#6193](https://github.com/pmd/pmd/issues/6193): \[java] New Rule: Always compare enum values with == * java-codestyle * [#6053](https://github.com/pmd/pmd/issues/6053): \[java] ModifierOrder false-positives with type annotations and type parameters (typeAnnotations = anywhere) * java-errorprone @@ -51,6 +55,7 @@ This is a {{ site.pmd.release_type }} release. * [#6192](https://github.com/pmd/pmd/pull/6192): \[java] Fix #6053: ModifierOrder - consider type params - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6194](https://github.com/pmd/pmd/pull/6194): chore: always place type annotations on the type - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6195](https://github.com/pmd/pmd/pull/6195): chore: always compare enums with == - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6196](https://github.com/pmd/pmd/pull/6196): \[java] New Rule: EnumComparison - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6201](https://github.com/pmd/pmd/pull/6201): \[java] Fix #6199: AssignmentInOperandRule: Update description of allowIncrementDecrement property - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6202](https://github.com/pmd/pmd/pull/6202): \[java] Fix #6188: UnitTestsShouldIncludeAssert - FP when TestNG @Test.expectedException is present - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6204](https://github.com/pmd/pmd/pull/6204): \[apex] Add rule to limit usage of @Future annotation - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) diff --git a/pmd-java/src/main/resources/rulesets/java/quickstart.xml b/pmd-java/src/main/resources/rulesets/java/quickstart.xml index c47a1f749d2..353730d99fd 100644 --- a/pmd-java/src/main/resources/rulesets/java/quickstart.xml +++ b/pmd-java/src/main/resources/rulesets/java/quickstart.xml @@ -20,6 +20,7 @@ + From 24ec8f4304c004bf082a7297b6764d03e1c23769 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 14:27:04 +0100 Subject: [PATCH 1693/1962] [doc] Update release notes (#6250) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..99c924291da 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -30,6 +30,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ๏ธ Merged pull requests +* [#6250](https://github.com/pmd/pmd/pull/6250): chore: fail build for compiler warnings - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ๏ธ Dependency updates From ab69741b0a35a0466e151a6d2dbdc79e13e5c22e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 14:29:52 +0100 Subject: [PATCH 1694/1962] [doc] Update release notes (#5701, #6229) --- docs/pages/release_notes.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 0caa511c75e..6104825ec56 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,13 +25,14 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy ### ๐Ÿ›๏ธ Fixed Issues -* general +* maintenance * [#5701](https://github.com/pmd/pmd/issues/5701): \[core] net.sourceforge.pmd.cpd.SourceManager has public methods ### ๐Ÿšจ๏ธ API Changes ### โœจ๏ธ Merged pull requests +* [#6229](https://github.com/pmd/pmd/pull/6229): chore: remove public methods from SourceManager - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ๏ธ Dependency updates From 30261f2e2986e5ccf8781d95ab5588d94e060db1 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 14:32:14 +0100 Subject: [PATCH 1695/1962] [doc] Update release notes (#6227) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 402ac140640..76e3f4ca8d0 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -32,6 +32,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ๏ธ Merged pull requests +* [#6227](https://github.com/pmd/pmd/pull/6227): \[java] UseArraysAsList: check increment - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ๏ธ Dependency updates From 64b00bcf58501b6ee1e29cde28d14ae87ad5eb7d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 14:35:17 +0100 Subject: [PATCH 1696/1962] [doc] Update release notes (#6228) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 527bf52da8f..3d8ae71e7ac 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -32,6 +32,7 @@ This is a {{ site.pmd.release_type }} release. ### โœจ๏ธ Merged pull requests +* [#6228](https://github.com/pmd/pmd/pull/6228): \[java] UseArraysAsList: skip when if-statements - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ๏ธ Dependency updates From 6093a7d78b86a8c01488f1a589d92dd383e6ec19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 27 Nov 2025 15:34:55 +0100 Subject: [PATCH 1697/1962] [ci] Exclude build resources from spring-framework for regression tester Added an exclude pattern for build resources. Those resources are copied from the source tree. The regression tester tries to link to those when violations occur, but those are not available in the github repo. The violations are anyway duplicates because they are also reported correctly on the file copy that is in the source tree. --- .ci/files/project-list.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci/files/project-list.xml b/.ci/files/project-list.xml index fed67b9658e..ffb92e23aed 100644 --- a/.ci/files/project-list.xml +++ b/.ci/files/project-list.xml @@ -38,6 +38,7 @@ mvn dependency:build-classpath -DincludeScope=test -Dmdep.outputFile=classpath.t v5.3.13 .*/build/generated-sources/.* + .*/build/resources/.* Date: Thu, 27 Nov 2025 17:25:31 +0100 Subject: [PATCH 1698/1962] Bump build-tools from 35 to 36 (#6281) * Bump build-tools from 35 to 36 * Fix more ModifierOrder * And one more... --- .../pmd/lang/ast/internal/IteratorBasedNStream.java | 3 +-- .../main/java/net/sourceforge/pmd/lang/rule/RuleSetWriter.java | 3 +-- .../src/main/java/net/sourceforge/pmd/util/AssertionUtil.java | 3 +-- .../java/net/sourceforge/pmd/lang/java/ast/AstImplUtil.java | 3 +-- .../pmd/lang/java/symbols/internal/asm/ParseLock.java | 2 +- pom.xml | 2 +- 6 files changed, 6 insertions(+), 10 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/IteratorBasedNStream.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/IteratorBasedNStream.java index 0319e8e9747..878f94f7ff0 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/IteratorBasedNStream.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/internal/IteratorBasedNStream.java @@ -91,8 +91,7 @@ public DescendantNodeStream descendants(Class r } - @NonNull - protected DescendantNodeStream flatMapDescendants(Function> mapper) { + protected @NonNull DescendantNodeStream flatMapDescendants(Function> mapper) { return new DescendantMapping<>(this, mapper); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetWriter.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetWriter.java index f5bca5e7797..c9546c6650a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetWriter.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetWriter.java @@ -292,8 +292,7 @@ private Element createRuleSetReferenceElement(RuleSetReference ruleSetReference) return propertiesElement; } - @NonNull - private Element propertyElementWithValueAttribute(PropertySource propertySource, PropertyDescriptor propertyDescriptor) { + private @NonNull Element propertyElementWithValueAttribute(PropertySource propertySource, PropertyDescriptor propertyDescriptor) { Element element = document.createElementNS(RULESET_2_0_0_NS_URI, "property"); SchemaConstants.NAME.setOn(element, propertyDescriptor.name()); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/AssertionUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/AssertionUtil.java index df713e464ec..161d66f6970 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/AssertionUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/AssertionUtil.java @@ -224,8 +224,7 @@ public static E mustBe(String name, Object value, S return exceptionMaker.apply(String.format("%s must be %s, got %s", name, condition, value)); } - @NonNull - public static T requireParamNotNull(String paramName, T obj) { + public static @NonNull T requireParamNotNull(String paramName, T obj) { if (obj == null) { throw new NullPointerException("Parameter " + paramName + " is null"); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AstImplUtil.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AstImplUtil.java index e82aa68a37b..2bf972ea3cf 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AstImplUtil.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AstImplUtil.java @@ -31,8 +31,7 @@ public static String getFirstSegment(String nameWithDots, char sep) { return lastIdx < 0 ? nameWithDots : nameWithDots.substring(0, lastIdx); } - @Nullable - public static T getChildAs(JavaNode javaNode, int idx, Class type) { + public static @Nullable T getChildAs(JavaNode javaNode, int idx, Class type) { if (javaNode.getNumChildren() <= idx || idx < 0) { return null; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java index 5299a1378b8..b119a74fd0d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ParseLock.java @@ -13,7 +13,7 @@ * A simple double-checked initializer, that parses something (a class, * or a type signature). */ -@SuppressWarnings({"PMD.AvoidUsingVolatile", "PMD.AvoidCatchingThrowable"}) +@SuppressWarnings({"PMD.AvoidUsingVolatile", "PMD.AvoidCatchingGenericException"}) abstract class ParseLock { private static final Logger LOG = LoggerFactory.getLogger(ParseLock.class); diff --git a/pom.xml b/pom.xml index 7bdfb0eeebd..9d67ebb31db 100644 --- a/pom.xml +++ b/pom.xml @@ -107,7 +107,7 @@ -Xmx512m -Dfile.encoding=${project.build.sourceEncoding} ${extraArgLine} - 35 + 36 7.10.0 From d7b3a8959852e37d58e59ca1ff00465f4da1758b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 19:00:12 +0100 Subject: [PATCH 1699/1962] [doc] Update release notes (#5689, #6259) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..62bfca8c7a3 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,11 +25,14 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy ### ๐Ÿ›๏ธ Fixed Issues +* java + * [#5689](https://github.com/pmd/pmd/issues/5689): [java] Members of record should be in scope in record header ### ๐Ÿšจ๏ธ API Changes ### โœจ๏ธ Merged pull requests +* [#6259](https://github.com/pmd/pmd/pull/6259): \[java] Fix #5689: Issue with scoping of record members - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) ### ๐Ÿ“ฆ๏ธ Dependency updates From d209b6e469b1ee0e24828a7f2d42cbc54b76553f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 19:02:45 +0100 Subject: [PATCH 1700/1962] [doc] Update release notes (#4742, #6255) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..a0b1f767170 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,11 +25,14 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy ### ๐Ÿ›๏ธ Fixed Issues +* java-errorprone + * [#4742](https://github.com/pmd/pmd/issues/4742): \[java] EmptyFinalizer should not trigger if finalize method is final and class is not ### ๐Ÿšจ๏ธ API Changes ### โœจ๏ธ Merged pull requests +* [#6255](https://github.com/pmd/pmd/pull/6255): \[java] Fix #4742: EmptyFinalizer should not trigger if finalize method is final and class is not - [Marcel](https://github.com/mrclmh) (@mrclmh) ### ๐Ÿ“ฆ๏ธ Dependency updates From 36a7fa8d77b7f5ace4252d84c8458e077416ca28 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 19:05:04 +0100 Subject: [PATCH 1701/1962] [doc] Update release notes (#5820, #6258) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..0857523f05c 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,11 +25,14 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy ### ๐Ÿ›๏ธ Fixed Issues +* java-bestpractices + * [#5820](https://github.com/pmd/pmd/issues/5820): \[java] GuardLogStatement recognizes that a string is a compile-time constant expression only if at first position ### ๐Ÿšจ๏ธ API Changes ### โœจ๏ธ Merged pull requests +* [#6258](https://github.com/pmd/pmd/pull/6258): \[java] Fix #5820: GuardLogStatement recognizes that a string is a compile-time constant expression only if at first position - [Marcel](https://github.com/mrclmh) (@mrclmh) ### ๐Ÿ“ฆ๏ธ Dependency updates From 53e795939e458642f38866221b0f45ebb3d8c66a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 19:07:14 +0100 Subject: [PATCH 1702/1962] [doc] Update release notes (#6277) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index ae0365724dc..00161167054 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -40,6 +40,7 @@ This is a {{ site.pmd.release_type }} release. * [#6204](https://github.com/pmd/pmd/pull/6204): \[apex] Add rule to limit usage of @Future annotation - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) * [#6217](https://github.com/pmd/pmd/pull/6217): \[doc] Add Blue Cave to known tools using PMD - [Jude Pereira](https://github.com/judepereira) (@judepereira) +* [#6277](https://github.com/pmd/pmd/pull/6277): \[doc] Add button to copy configuration snippet - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) ### ๐Ÿ“ฆ๏ธ Dependency updates From 6cd1551fc0bfe724b508c5b1e6d2be7a5ecc216b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 19:09:18 +0100 Subject: [PATCH 1703/1962] [doc] Update release notes (#6273, #6278) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..f3c523f5b76 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,11 +25,14 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy ### ๐Ÿ›๏ธ Fixed Issues +* java-errorprone + * [#6273](https://github.com/pmd/pmd/issues/6273): \[java] TestClassWithoutTestCases documentation does not mention test prefixes ### ๐Ÿšจ๏ธ API Changes ### โœจ๏ธ Merged pull requests +* [#6278](https://github.com/pmd/pmd/pull/6278): \[doc] TestClassWithoutTestCases: Mention test prefixes - [Marcel](https://github.com/mrclmh) (@mrclmh) ### ๐Ÿ“ฆ๏ธ Dependency updates From 91cdc8dd9a7497214aa2009bac11091abdb4aa6c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 20:01:18 +0100 Subject: [PATCH 1704/1962] [java] Fix #6256: ignore invalid annotation type --- docs/pages/release_notes.md | 1 + .../lang/java/symbols/internal/asm/GenericSigBase.java | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 67c0212873e..d9673e7b44d 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -83,6 +83,7 @@ This is a {{ site.pmd.release_type }} release. * [#2128](https://github.com/pmd/pmd/issues/2128): \[apex] Merge NCSS count rules for Apex * java * [#5689](https://github.com/pmd/pmd/issues/5689): \[java] Members of record should be in scope in record header + * [#6256](https://github.com/pmd/pmd/issues/6256): \[java] java.lang.IllegalArgumentException: Invalid target type of type annotation for method or ctor type annotation: 19 * java-bestpractices * [#5820](https://github.com/pmd/pmd/issues/5820): \[java] GuardLogStatement recognizes that a string is a compile-time constant expression only if at first position * [#6188](https://github.com/pmd/pmd/issues/6188): \[java] UnitTestShouldIncludeAssert false positive when TestNG @Test.expectedException present diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java index 4d0dfe00a68..406e92acade 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/GenericSigBase.java @@ -420,6 +420,14 @@ boolean acceptAnnotationAfterParse(TypeReference tyRef, @Nullable TypePath path, annot, ctx.getEnclosingClass().getCanonicalName(), ctx.getSimpleName()); return false; } + case TypeReference.FIELD: { + // avoid exception for Java 16+ bug + // see https://github.com/pmd/pmd/issues/6256 and https://bugs.openjdk.org/browse/JDK-8372382 + LOGGER.debug("Invalid target type FIELD of type annotation {} for method or ctor detected. " + + "The annotation is ignored. Method: {}#{}. See https://github.com/pmd/pmd/issues/6256.", + annot, ctx.getEnclosingClass().getCanonicalName(), ctx.getSimpleName()); + return false; + } default: throw new IllegalArgumentException( "Invalid target type of type annotation " + annot + " for method or ctor type annotation: " From c191161f63c1b27ff92084192453a38b10f6e001 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 20:15:17 +0100 Subject: [PATCH 1705/1962] [doc] Update release notes (#6280) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 488807006cd..8b5109d84f6 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -143,6 +143,7 @@ This is a {{ site.pmd.release_type }} release. * [#6249](https://github.com/pmd/pmd/pull/6249): \[core] Deprecate old symboltable API - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6250](https://github.com/pmd/pmd/pull/6250): chore: fail build for compiler warnings - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6251](https://github.com/pmd/pmd/pull/6251): \[java] Fix #6092: AssignmentInOperand false positive in 7.17.0 for case statements - [Marcel](https://github.com/mrclmh) (@mrclmh) +* [#6280](https://github.com/pmd/pmd/pull/6280): \[ci] Exclude build resources from spring-framework for regression tester - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) ### ๐Ÿ“ฆ๏ธ Dependency updates From ff6d32a6b639ac000967a7f28e39eff14c2adab4 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 20:26:05 +0100 Subject: [PATCH 1706/1962] [doc] Update release notes (#6282) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index d9673e7b44d..5b812a02584 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -154,6 +154,7 @@ This is a {{ site.pmd.release_type }} release. * [#6259](https://github.com/pmd/pmd/pull/6259): \[java] Fix #5689: Issue with scoping of record members - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#6277](https://github.com/pmd/pmd/pull/6277): \[doc] Add button to copy configuration snippet - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) * [#6278](https://github.com/pmd/pmd/pull/6278): \[doc] TestClassWithoutTestCases: Mention test prefixes - [Marcel](https://github.com/mrclmh) (@mrclmh) +* [#6282](https://github.com/pmd/pmd/pull/6282): \[java] Fix #6256: ignore invalid annotation type - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ๏ธ Dependency updates From bf27bece5457a785aae021032560a75469f720fb Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 27 Nov 2025 20:43:09 +0100 Subject: [PATCH 1707/1962] Bump PMD Designer from 7.10.0 to 7.19.1 (#6283) --- docs/pages/release_notes.md | 6 ++++++ pom.xml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 18e341cbbec..7bf7a22d39e 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -24,6 +24,12 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy +#### Updated PMD Designer + +This PMD release ships a new version of the pmd-designer. +For the changes, see [PMD Designer Changelog (7.19.0)](https://github.com/pmd/pmd-designer/releases/tag/7.19.0) +and [PMD Designer Changelog (7.19.1)](https://github.com/pmd/pmd-designer/releases/tag/7.19.1). + ### ๐ŸŒŸ๏ธ New and Changed Rules #### New Rules * The new Apex rule {%rule apex/bestpractices/AvoidFutureAnnotation %} finds usages of the `@Future` diff --git a/pom.xml b/pom.xml index 9d67ebb31db..fafd6007ff9 100644 --- a/pom.xml +++ b/pom.xml @@ -109,7 +109,7 @@ 36 - 7.10.0 + 7.19.1 ${project.build.directory}/generated-sources/javacc ${project.basedir}/../javacc-wrapper.xml From 1b792a64087da0606b4c41dc15b74ab950515ef2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 28 Nov 2025 11:40:57 +0100 Subject: [PATCH 1708/1962] Update all contributors * Add @frankk3 as a contributor * Add @estekhin as a contributor * Update @elharo as a contributor --- .all-contributorsrc | 21 +++- docs/pages/pmd/projectdocs/credits.md | 168 +++++++++++++------------- 2 files changed, 106 insertions(+), 83 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 4427cf22ea4..579dcdde4d5 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8103,7 +8103,8 @@ "avatar_url": "https://avatars.githubusercontent.com/u/1005544?v=4", "profile": "https://www.elharo.com/blog/", "contributions": [ - "code" + "code", + "bug" ] }, { @@ -8344,6 +8345,24 @@ "contributions": [ "bug" ] + }, + { + "login": "estekhin", + "name": "Oleg Estekhin", + "avatar_url": "https://avatars.githubusercontent.com/u/6337779?v=4", + "profile": "https://github.com/estekhin", + "contributions": [ + "bug" + ] + }, + { + "login": "frankk3", + "name": "frankk3", + "avatar_url": "https://avatars.githubusercontent.com/u/28110843?v=4", + "profile": "https://github.com/frankk3", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index ef26af5b6a8..0bb5e71935a 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -271,7 +271,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Elan P. Kugelmass
          Elan P. Kugelmass

          ๐Ÿ› Elder S.
          Elder S.

          ๐Ÿ› Eldrick Wega
          Eldrick Wega

          ๐Ÿ“– - Elliotte Rusty Harold
          Elliotte Rusty Harold

          ๐Ÿ’ป + Elliotte Rusty Harold
          Elliotte Rusty Harold

          ๐Ÿ’ป ๐Ÿ› Emile
          Emile

          ๐Ÿ› Eng Zer Jun
          Eng Zer Jun

          ๐Ÿ› @@ -636,551 +636,555 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Oleg Andreych
          Oleg Andreych

          ๐Ÿ’ป ๐Ÿ› + Oleg Estekhin
          Oleg Estekhin

          ๐Ÿ› Oleg Pavlenko
          Oleg Pavlenko

          ๐Ÿ› Oleksii Dykov
          Oleksii Dykov

          ๐Ÿ’ป ๐Ÿ› Oliver Eikemeier
          Oliver Eikemeier

          ๐Ÿ› Oliver Siegmar
          Oliver Siegmar

          ๐Ÿ’ต Olivier Parent
          Olivier Parent

          ๐Ÿ’ป ๐Ÿ› Ollie Abbey
          Ollie Abbey

          ๐Ÿ’ป ๐Ÿ› - Olof-Joachim Frahm (ๆฌง้›…็ฆ)
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)

          ๐Ÿ› + Olof-Joachim Frahm (ๆฌง้›…็ฆ)
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)

          ๐Ÿ› Ondrej Kratochvil
          Ondrej Kratochvil

          ๐Ÿ› OverDrone
          OverDrone

          ๐Ÿ› Ozan Gulle
          Ozan Gulle

          ๐Ÿ’ป ๐Ÿ› PUNEET JAIN
          PUNEET JAIN

          ๐Ÿ› Pankraz76
          Pankraz76

          ๐Ÿ’ป ๐Ÿ› Parbati Bose
          Parbati Bose

          ๐Ÿ› - Paul Berg
          Paul Berg

          ๐Ÿ› + Paul Berg
          Paul Berg

          ๐Ÿ› Paul Guyot
          Paul Guyot

          ๐Ÿ’ป Pavel Bludov
          Pavel Bludov

          ๐Ÿ› Pavel Miฤka
          Pavel Miฤka

          ๐Ÿ› Pedro Nuno Santos
          Pedro Nuno Santos

          ๐Ÿ› Pedro Rijo
          Pedro Rijo

          ๐Ÿ› Pelisse Romain
          Pelisse Romain

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› - Per Abich
          Per Abich

          ๐Ÿ’ป + Per Abich
          Per Abich

          ๐Ÿ’ป Pete Davids
          Pete Davids

          ๐Ÿ› Peter Bruin
          Peter Bruin

          ๐Ÿ› Peter Chittum
          Peter Chittum

          ๐Ÿ’ป ๐Ÿ› Peter Cudmore
          Peter Cudmore

          ๐Ÿ› Peter Kasson
          Peter Kasson

          ๐Ÿ› Peter Kofler
          Peter Kofler

          ๐Ÿ› - Peter Paul Bakker
          Peter Paul Bakker

          ๐Ÿ’ป ๐Ÿ› + Peter Paul Bakker
          Peter Paul Bakker

          ๐Ÿ’ป ๐Ÿ› Peter Rader
          Peter Rader

          ๐Ÿ› Pham Hai Trung
          Pham Hai Trung

          ๐Ÿ› Philip Graf
          Philip Graf

          ๐Ÿ’ป ๐Ÿ› Philip Hachey
          Philip Hachey

          ๐Ÿ› Philippe Ozil
          Philippe Ozil

          ๐Ÿ› Phinehas Artemix
          Phinehas Artemix

          ๐Ÿ› - Phokham Nonava
          Phokham Nonava

          ๐Ÿ› + Phokham Nonava
          Phokham Nonava

          ๐Ÿ› Pim van der Loos
          Pim van der Loos

          ๐Ÿ’ป โš ๏ธ Piotr Koลผuchowski
          Piotr Koลผuchowski

          ๐Ÿ› Piotr Szymaล„ski
          Piotr Szymaล„ski

          ๐Ÿ› Piotrek ลปygieล‚o
          Piotrek ลปygieล‚o

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– Pranay Jaiswal
          Pranay Jaiswal

          ๐Ÿ› Prasad Kamath
          Prasad Kamath

          ๐Ÿ› - Prasanna
          Prasanna

          ๐Ÿ› + Prasanna
          Prasanna

          ๐Ÿ› Presh-AR
          Presh-AR

          ๐Ÿ› Puneet1726
          Puneet1726

          ๐Ÿ› RBRi
          RBRi

          ๐Ÿ› Rafael Cortรชs
          Rafael Cortรชs

          ๐Ÿ› RaheemShaik999
          RaheemShaik999

          ๐Ÿ› RajeshR
          RajeshR

          ๐Ÿ’ป ๐Ÿ› - Ramachandra Mohan
          Ramachandra Mohan

          ๐Ÿ› + Ramachandra Mohan
          Ramachandra Mohan

          ๐Ÿ› Ramel0921
          Ramel0921

          ๐Ÿ› Raquel Pau
          Raquel Pau

          ๐Ÿ› Ravikiran Janardhana
          Ravikiran Janardhana

          ๐Ÿ› Reda Benhemmouche
          Reda Benhemmouche

          ๐Ÿ› Reinhard Schiedermeier
          Reinhard Schiedermeier

          ๐Ÿ› Renato Oliveira
          Renato Oliveira

          ๐Ÿ’ป ๐Ÿ› - Rich DiCroce
          Rich DiCroce

          ๐Ÿ› + Rich DiCroce
          Rich DiCroce

          ๐Ÿ› Richard Corfield
          Richard Corfield

          ๐Ÿ’ป Richard Corfield
          Richard Corfield

          ๐Ÿ› ๐Ÿ’ป Riot R1cket
          Riot R1cket

          ๐Ÿ› Rishabh Jain
          Rishabh Jain

          ๐Ÿ› RishabhDeep Singh
          RishabhDeep Singh

          ๐Ÿ› Rob Baillie
          Rob Baillie

          ๐Ÿ› - Robbie Martinus
          Robbie Martinus

          ๐Ÿ’ป ๐Ÿ› + Robbie Martinus
          Robbie Martinus

          ๐Ÿ’ป ๐Ÿ› Robert Henry
          Robert Henry

          ๐Ÿ› Robert Mihaly
          Robert Mihaly

          ๐Ÿ› Robert Painsi
          Robert Painsi

          ๐Ÿ› Robert Russell
          Robert Russell

          ๐Ÿ› Robert Sรถsemann
          Robert Sรถsemann

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ› Robert Whitebit
          Robert Whitebit

          ๐Ÿ› - Robin Richtsfeld
          Robin Richtsfeld

          ๐Ÿ› + Robin Richtsfeld
          Robin Richtsfeld

          ๐Ÿ› Robin Stocker
          Robin Stocker

          ๐Ÿ’ป ๐Ÿ› Robin Wils
          Robin Wils

          ๐Ÿ› RochusOest
          RochusOest

          ๐Ÿ› Rodolfo Noviski
          Rodolfo Noviski

          ๐Ÿ› Rodrigo Casara
          Rodrigo Casara

          ๐Ÿ› Rodrigo Fernandes
          Rodrigo Fernandes

          ๐Ÿ› - Roman Salvador
          Roman Salvador

          ๐Ÿ’ป ๐Ÿ› + Roman Salvador
          Roman Salvador

          ๐Ÿ’ป ๐Ÿ› Ronald Blaschke
          Ronald Blaschke

          ๐Ÿ› Rรณbert Papp
          Rรณbert Papp

          ๐Ÿ› Saikat Sengupta
          Saikat Sengupta

          ๐Ÿ› Saksham Handu
          Saksham Handu

          ๐Ÿ› Saladoc
          Saladoc

          ๐Ÿ› Salesforce Bob Lightning
          Salesforce Bob Lightning

          ๐Ÿ› - Sam Carlberg
          Sam Carlberg

          ๐Ÿ› + Sam Carlberg
          Sam Carlberg

          ๐Ÿ› Sascha Riemer
          Sascha Riemer

          ๐Ÿ› Sashko
          Sashko

          ๐Ÿ’ป Satoshi Kubo
          Satoshi Kubo

          ๐Ÿ› Scott Kennedy
          Scott Kennedy

          ๐Ÿ› Scott Wells
          Scott Wells

          ๐Ÿ› ๐Ÿ’ป Scrates1
          Scrates1

          ๐Ÿ› ๐Ÿ’ป - Scrsloota
          Scrsloota

          ๐Ÿ’ป + Scrsloota
          Scrsloota

          ๐Ÿ’ป Sebastian Bรถgl
          Sebastian Bรถgl

          ๐Ÿ› Sebastian Davids
          Sebastian Davids

          ๐Ÿ› Sebastian Lรถvdahl
          Sebastian Lรถvdahl

          ๐Ÿ› Sebastian Schuberth
          Sebastian Schuberth

          ๐Ÿ› Sebastian Schwarz
          Sebastian Schwarz

          ๐Ÿ› Seren
          Seren

          ๐Ÿ› ๐Ÿ’ป - Sergey Gorbaty
          Sergey Gorbaty

          ๐Ÿ› + Sergey Gorbaty
          Sergey Gorbaty

          ๐Ÿ› Sergey Kozlov
          Sergey Kozlov

          ๐Ÿ› Sergey Yanzin
          Sergey Yanzin

          ๐Ÿ’ป ๐Ÿ› Seth Wilcox
          Seth Wilcox

          ๐Ÿ’ป Shai Bennathan
          Shai Bennathan

          ๐Ÿ› ๐Ÿ’ป Shubham
          Shubham

          ๐Ÿ’ป ๐Ÿ› Simon Abykov
          Simon Abykov

          ๐Ÿ’ป ๐Ÿ› - Simon Xiao
          Simon Xiao

          ๐Ÿ› + Simon Xiao
          Simon Xiao

          ๐Ÿ› Srinivasan Venkatachalam
          Srinivasan Venkatachalam

          ๐Ÿ› Stanislav Gromov
          Stanislav Gromov

          ๐Ÿ› Stanislav Myachenkov
          Stanislav Myachenkov

          ๐Ÿ’ป Stefan Birkner
          Stefan Birkner

          ๐Ÿ› Stefan Bohn
          Stefan Bohn

          ๐Ÿ› Stefan Endrullis
          Stefan Endrullis

          ๐Ÿ› - Stefan Klรถss-Schuster
          Stefan Klรถss-Schuster

          ๐Ÿ› + Stefan Klรถss-Schuster
          Stefan Klรถss-Schuster

          ๐Ÿ› Stefan Wolf
          Stefan Wolf

          ๐Ÿ› Stephan H. Wissel
          Stephan H. Wissel

          ๐Ÿ› Stephen
          Stephen

          ๐Ÿ› Stephen Carter
          Stephen Carter

          ๐Ÿ› Stephen Friedrich
          Stephen Friedrich

          ๐Ÿ› Steve Babula
          Steve Babula

          ๐Ÿ’ป - Steve White
          Steve White

          ๐Ÿ› + Steve White
          Steve White

          ๐Ÿ› Steven Schlansker
          Steven Schlansker

          ๐Ÿ› Steven Stearns
          Steven Stearns

          ๐Ÿ› ๐Ÿ’ป Stexxe
          Stexxe

          ๐Ÿ› Stian Lรฅgstad
          Stian Lรฅgstad

          ๐Ÿ› StuartClayton5
          StuartClayton5

          ๐Ÿ› Supun Arunoda
          Supun Arunoda

          ๐Ÿ› - Suren Abrahamyan
          Suren Abrahamyan

          ๐Ÿ› + Suren Abrahamyan
          Suren Abrahamyan

          ๐Ÿ› Suvashri
          Suvashri

          ๐Ÿ“– Sven Barden
          Sven Barden

          ๐Ÿ› SwatiBGupta1110
          SwatiBGupta1110

          ๐Ÿ› SyedThoufich
          SyedThoufich

          ๐Ÿ› Szymon Sasin
          Szymon Sasin

          ๐Ÿ› T-chuangxin
          T-chuangxin

          ๐Ÿ› - TERAI Atsuhiro
          TERAI Atsuhiro

          ๐Ÿ› + TERAI Atsuhiro
          TERAI Atsuhiro

          ๐Ÿ› TIOBE Software
          TIOBE Software

          ๐Ÿ’ป ๐Ÿ› Tarush Singh
          Tarush Singh

          ๐Ÿ’ป Taylor Smock
          Taylor Smock

          ๐Ÿ› Techeira Damiรกn
          Techeira Damiรกn

          ๐Ÿ’ป ๐Ÿ› Ted Husted
          Ted Husted

          ๐Ÿ› TehBakker
          TehBakker

          ๐Ÿ› - The Gitter Badger
          The Gitter Badger

          ๐Ÿ› + The Gitter Badger
          The Gitter Badger

          ๐Ÿ› Theodoor
          Theodoor

          ๐Ÿ› Thiago Henrique Hรผpner
          Thiago Henrique Hรผpner

          ๐Ÿ› Thibault Meyer
          Thibault Meyer

          ๐Ÿ› Thomas Gรผttler
          Thomas Gรผttler

          ๐Ÿ› Thomas Jones-Low
          Thomas Jones-Low

          ๐Ÿ› Thomas Smith
          Thomas Smith

          ๐Ÿ’ป ๐Ÿ› - ThrawnCA
          ThrawnCA

          ๐Ÿ› + ThrawnCA
          ThrawnCA

          ๐Ÿ› Thu Vo
          Thu Vo

          ๐Ÿ› Thunderforge
          Thunderforge

          ๐Ÿ’ป ๐Ÿ› Tim van der Lippe
          Tim van der Lippe

          ๐Ÿ› Tobias Weimer
          Tobias Weimer

          ๐Ÿ’ป ๐Ÿ› Tom Copeland
          Tom Copeland

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– Tom Daly
          Tom Daly

          ๐Ÿ› - Tomas
          Tomas

          ๐Ÿ› + Tomas
          Tomas

          ๐Ÿ› Tomer Figenblat
          Tomer Figenblat

          ๐Ÿ› Tomi De Lucca
          Tomi De Lucca

          ๐Ÿ’ป ๐Ÿ› Tony
          Tony

          ๐Ÿ“– Torsten Kleiber
          Torsten Kleiber

          ๐Ÿ› Torsten Krause
          Torsten Krause

          ๐Ÿ› TrackerSB
          TrackerSB

          ๐Ÿ› - Tyson Stewart
          Tyson Stewart

          ๐Ÿ› + Tyson Stewart
          Tyson Stewart

          ๐Ÿ› Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ› UncleOwen
          UncleOwen

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– Utku Cuhadaroglu
          Utku Cuhadaroglu

          ๐Ÿ’ป ๐Ÿ› Valentin Brandl
          Valentin Brandl

          ๐Ÿ› Valeria
          Valeria

          ๐Ÿ› Valery Yatsynovich
          Valery Yatsynovich

          ๐Ÿ“– - Vasily Anisimov
          Vasily Anisimov

          ๐Ÿ› + Vasily Anisimov
          Vasily Anisimov

          ๐Ÿ› Vedant Chokshi
          Vedant Chokshi

          ๐Ÿ› Vibhor Goyal
          Vibhor Goyal

          ๐Ÿ› Vickenty Fesunov
          Vickenty Fesunov

          ๐Ÿ› Victor Noรซl
          Victor Noรซl

          ๐Ÿ› Vincent Galloy
          Vincent Galloy

          ๐Ÿ’ป Vincent HUYNH
          Vincent HUYNH

          ๐Ÿ› - Vincent Maurin
          Vincent Maurin

          ๐Ÿ› + Vincent Maurin
          Vincent Maurin

          ๐Ÿ› Vincent Potucek
          Vincent Potucek

          ๐Ÿ’ป Vincent Privat
          Vincent Privat

          ๐Ÿ› Vincent Zorge
          Vincent Zorge

          ๐Ÿ› Vishhwas
          Vishhwas

          ๐Ÿ› Vishv_Android
          Vishv_Android

          ๐Ÿ› Vitalii Yevtushenko
          Vitalii Yevtushenko

          ๐Ÿ› - Vitaly
          Vitaly

          ๐Ÿ› + Vitaly
          Vitaly

          ๐Ÿ› Vitaly Polonetsky
          Vitaly Polonetsky

          ๐Ÿ› Vojtech Polivka
          Vojtech Polivka

          ๐Ÿ› Vsevolod Zholobov
          Vsevolod Zholobov

          ๐Ÿ› Vyom Yadav
          Vyom Yadav

          ๐Ÿ’ป Wang Shidong
          Wang Shidong

          ๐Ÿ› Waqas Ahmed
          Waqas Ahmed

          ๐Ÿ› - Wayne J. Earl
          Wayne J. Earl

          ๐Ÿ› + Wayne J. Earl
          Wayne J. Earl

          ๐Ÿ› Wchenghui
          Wchenghui

          ๐Ÿ› Wener
          Wener

          ๐Ÿ’ป Will Winder
          Will Winder

          ๐Ÿ› Willem A. Hajenius
          Willem A. Hajenius

          ๐Ÿ’ป William Brockhus
          William Brockhus

          ๐Ÿ’ป ๐Ÿ› Wilson Kurniawan
          Wilson Kurniawan

          ๐Ÿ› - Wim Deblauwe
          Wim Deblauwe

          ๐Ÿ› + Wim Deblauwe
          Wim Deblauwe

          ๐Ÿ› Wolf2323
          Wolf2323

          ๐Ÿ› Woongsik Choi
          Woongsik Choi

          ๐Ÿ› XenoAmess
          XenoAmess

          ๐Ÿ’ป ๐Ÿ› Yang
          Yang

          ๐Ÿ’ป YaroslavTER
          YaroslavTER

          ๐Ÿ› Yasar Shaikh
          Yasar Shaikh

          ๐Ÿ’ป - Young Chan
          Young Chan

          ๐Ÿ’ป ๐Ÿ› + Young Chan
          Young Chan

          ๐Ÿ’ป ๐Ÿ› YuJin Kim
          YuJin Kim

          ๐Ÿ› Yuri Dolzhenko
          Yuri Dolzhenko

          ๐Ÿ› Yurii Dubinka
          Yurii Dubinka

          ๐Ÿ› Zbynek Konecny
          Zbynek Konecny

          ๐Ÿ› ๐Ÿ’ป Zoltan Farkas
          Zoltan Farkas

          ๐Ÿ› Zustin
          Zustin

          ๐Ÿ› - aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป + aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป alexmodis
          alexmodis

          ๐Ÿ› andreoss
          andreoss

          ๐Ÿ› andrey81inmd
          andrey81inmd

          ๐Ÿ’ป ๐Ÿ› anicoara
          anicoara

          ๐Ÿ› arunprasathav
          arunprasathav

          ๐Ÿ› asiercamara
          asiercamara

          ๐Ÿ› - astillich-igniti
          astillich-igniti

          ๐Ÿ’ป + astillich-igniti
          astillich-igniti

          ๐Ÿ’ป avesolovksyy
          avesolovksyy

          ๐Ÿ› avishvat
          avishvat

          ๐Ÿ› avivmu
          avivmu

          ๐Ÿ› axelbarfod1
          axelbarfod1

          ๐Ÿ› b-3-n
          b-3-n

          ๐Ÿ› balbhadra9
          balbhadra9

          ๐Ÿ› - base23de
          base23de

          ๐Ÿ› + base23de
          base23de

          ๐Ÿ› bergander
          bergander

          ๐Ÿ› ๐Ÿ’ป berkam
          berkam

          ๐Ÿ’ป ๐Ÿ› bmeier-pros
          bmeier-pros

          ๐Ÿ› breizh31
          breizh31

          ๐Ÿ› caesarkim
          caesarkim

          ๐Ÿ› caiocarvalhotero
          caiocarvalhotero

          ๐Ÿ› - carolyujing
          carolyujing

          ๐Ÿ› + carolyujing
          carolyujing

          ๐Ÿ› cbfiddle
          cbfiddle

          ๐Ÿ› cesares-basilico
          cesares-basilico

          ๐Ÿ› chrite
          chrite

          ๐Ÿ› ciufudean
          ciufudean

          ๐Ÿ“– cobratbq
          cobratbq

          ๐Ÿ› coladict
          coladict

          ๐Ÿ› - cosmoJFH
          cosmoJFH

          ๐Ÿ› + cosmoJFH
          cosmoJFH

          ๐Ÿ› cristalp
          cristalp

          ๐Ÿ› crunsk
          crunsk

          ๐Ÿ› csrma
          csrma

          ๐Ÿ› cwholmes
          cwholmes

          ๐Ÿ› cyberjj999
          cyberjj999

          ๐Ÿ› cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“– - d1ss0nanz
          d1ss0nanz

          ๐Ÿ› + d1ss0nanz
          d1ss0nanz

          ๐Ÿ› dague1
          dague1

          ๐Ÿ“– dalizi007
          dalizi007

          ๐Ÿ’ป danbrycefairsailcom
          danbrycefairsailcom

          ๐Ÿ› dariansanity
          dariansanity

          ๐Ÿ› darrenmiliband
          darrenmiliband

          ๐Ÿ› davidburstrom
          davidburstrom

          ๐Ÿ› - dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ› + dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ› deepak-patra
          deepak-patra

          ๐Ÿ› dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ› dinesh150
          dinesh150

          ๐Ÿ› diziaq
          diziaq

          ๐Ÿ› dreaminpast123
          dreaminpast123

          ๐Ÿ› duanyanan
          duanyanan

          ๐Ÿ› - dutt-sanjay
          dutt-sanjay

          ๐Ÿ› + dutt-sanjay
          dutt-sanjay

          ๐Ÿ› duursma
          duursma

          ๐Ÿ’ป dylanleung
          dylanleung

          ๐Ÿ› dzeigler
          dzeigler

          ๐Ÿ› eant60
          eant60

          ๐Ÿ› ekkirala
          ekkirala

          ๐Ÿ› emersonmoura
          emersonmoura

          ๐Ÿ› - emouty
          emouty

          ๐Ÿ’ป ๐Ÿ› + emouty
          emouty

          ๐Ÿ’ป ๐Ÿ› eugenepugach
          eugenepugach

          ๐Ÿ› fairy
          fairy

          ๐Ÿ› filiprafalowicz
          filiprafalowicz

          ๐Ÿ’ป flxbl-io
          flxbl-io

          ๐Ÿ’ต foxmason
          foxmason

          ๐Ÿ› frankegabor
          frankegabor

          ๐Ÿ› - frankl
          frankl

          ๐Ÿ› + frankk3
          frankk3

          ๐Ÿ› + frankl
          frankl

          ๐Ÿ› freafrea
          freafrea

          ๐Ÿ› fsapatin
          fsapatin

          ๐Ÿ› gearsethenry
          gearsethenry

          ๐Ÿ› gracia19
          gracia19

          ๐Ÿ› gudzpoz
          gudzpoz

          ๐Ÿ› - guo fei
          guo fei

          ๐Ÿ› - gurmsc5
          gurmsc5

          ๐Ÿ› + guo fei
          guo fei

          ๐Ÿ› + gurmsc5
          gurmsc5

          ๐Ÿ› gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ› haigsn
          haigsn

          ๐Ÿ› hemanshu070
          hemanshu070

          ๐Ÿ› henrik242
          henrik242

          ๐Ÿ› hongpuwu
          hongpuwu

          ๐Ÿ› - hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ› - igniti GmbH
          igniti GmbH

          ๐Ÿ› + hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ› + igniti GmbH
          igniti GmbH

          ๐Ÿ› ilovezfs
          ilovezfs

          ๐Ÿ› imax-erik
          imax-erik

          ๐Ÿ› itaigilo
          itaigilo

          ๐Ÿ› jakivey32
          jakivey32

          ๐Ÿ› jbennett2091
          jbennett2091

          ๐Ÿ› - jcamerin
          jcamerin

          ๐Ÿ› - jkeener1
          jkeener1

          ๐Ÿ› + jcamerin
          jcamerin

          ๐Ÿ› + jkeener1
          jkeener1

          ๐Ÿ› jmetertea
          jmetertea

          ๐Ÿ› johnra2
          johnra2

          ๐Ÿ’ป johnzhao9
          johnzhao9

          ๐Ÿ› josemanuelrolon
          josemanuelrolon

          ๐Ÿ’ป ๐Ÿ› julees7
          julees7

          ๐Ÿ’ป ๐Ÿ› - kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ› - karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“– + kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ› + karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“– karwer
          karwer

          ๐Ÿ› kaulonline
          kaulonline

          ๐Ÿ› kdaemonv
          kdaemonv

          ๐Ÿ› kdandoy107255
          kdandoy107255

          ๐Ÿ› kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป - kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ› - kfranic
          kfranic

          ๐Ÿ› + kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ› + kfranic
          kfranic

          ๐Ÿ› khalidkh
          khalidkh

          ๐Ÿ› koalalam
          koalalam

          ๐Ÿ› krzyk
          krzyk

          ๐Ÿ› lasselindqvist
          lasselindqvist

          ๐Ÿ› lgemeinhardt
          lgemeinhardt

          ๐Ÿ› - lihuaib
          lihuaib

          ๐Ÿ› - liqingjun123
          liqingjun123

          ๐Ÿ› + lihuaib
          lihuaib

          ๐Ÿ› + liqingjun123
          liqingjun123

          ๐Ÿ› lonelyma1021
          lonelyma1021

          ๐Ÿ› lothas
          lothas

          ๐Ÿ› lpeddy
          lpeddy

          ๐Ÿ› lujiefsi
          lujiefsi

          ๐Ÿ’ป lukelukes
          lukelukes

          ๐Ÿ’ป - lyriccoder
          lyriccoder

          ๐Ÿ› - marcelmore
          marcelmore

          ๐Ÿ› + lyriccoder
          lyriccoder

          ๐Ÿ› + marcelmore
          marcelmore

          ๐Ÿ› matchbox
          matchbox

          ๐Ÿ› matthiaskraaz
          matthiaskraaz

          ๐Ÿ› meandonlyme
          meandonlyme

          ๐Ÿ› mikesive
          mikesive

          ๐Ÿ› milossesic
          milossesic

          ๐Ÿ› - mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ› - mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป + mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ› + mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป mrclmh
          mrclmh

          ๐Ÿ› ๐Ÿ’ป mriddell95
          mriddell95

          ๐Ÿ› mrlzh
          mrlzh

          ๐Ÿ› msloan
          msloan

          ๐Ÿ› mucharlaravalika
          mucharlaravalika

          ๐Ÿ› - mvenneman
          mvenneman

          ๐Ÿ› - nareshl119
          nareshl119

          ๐Ÿ› + mvenneman
          mvenneman

          ๐Ÿ› + nareshl119
          nareshl119

          ๐Ÿ› nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ› noerremark
          noerremark

          ๐Ÿ› novsirion
          novsirion

          ๐Ÿ› nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
          oggboy

          ๐Ÿ› - oinume
          oinume

          ๐Ÿ› - orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ› + oinume
          oinume

          ๐Ÿ› + orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ› pablogomez2197
          pablogomez2197

          ๐Ÿ› pacvz
          pacvz

          ๐Ÿ’ป pallavi agarwal
          pallavi agarwal

          ๐Ÿ› pankratz76
          pankratz76

          ๐Ÿ› parksungrin
          parksungrin

          ๐Ÿ› - patpatpat123
          patpatpat123

          ๐Ÿ› - patriksevallius
          patriksevallius

          ๐Ÿ› + patpatpat123
          patpatpat123

          ๐Ÿ› + patriksevallius
          patriksevallius

          ๐Ÿ› pbrajesh1
          pbrajesh1

          ๐Ÿ› phoenix384
          phoenix384

          ๐Ÿ› piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป plan3d
          plan3d

          ๐Ÿ› poojasix
          poojasix

          ๐Ÿ› - prabhushrikant
          prabhushrikant

          ๐Ÿ› - pujitha8783
          pujitha8783

          ๐Ÿ› + prabhushrikant
          prabhushrikant

          ๐Ÿ› + pujitha8783
          pujitha8783

          ๐Ÿ› r-r-a-j
          r-r-a-j

          ๐Ÿ› raghujayjunk
          raghujayjunk

          ๐Ÿ› rajeshveera
          rajeshveera

          ๐Ÿ› rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ› recdevs
          recdevs

          ๐Ÿ› - reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ› - rijkt
          rijkt

          ๐Ÿ› + reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ› + rijkt
          rijkt

          ๐Ÿ› rillig-tk
          rillig-tk

          ๐Ÿ› rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ› rnveach
          rnveach

          ๐Ÿ› rubenporras
          rubenporras

          ๐Ÿ› rxmicro
          rxmicro

          ๐Ÿ› - ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ› - sabi0
          sabi0

          ๐Ÿ› + ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ› + sabi0
          sabi0

          ๐Ÿ› samc-gearset
          samc-gearset

          ๐Ÿ“– scais
          scais

          ๐Ÿ› schosin
          schosin

          ๐Ÿ› screamingfrog
          screamingfrog

          ๐Ÿ’ต sebbASF
          sebbASF

          ๐Ÿ› - sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป - shilko2013
          shilko2013

          ๐Ÿ› + sergeygorbaty
          sergeygorbaty

          ๐Ÿ’ป + shilko2013
          shilko2013

          ๐Ÿ› shiomiyan
          shiomiyan

          ๐Ÿ“– simeonKondr
          simeonKondr

          ๐Ÿ› snajberk
          snajberk

          ๐Ÿ› sniperrifle2004
          sniperrifle2004

          ๐Ÿ› snuyanzin
          snuyanzin

          ๐Ÿ› ๐Ÿ’ป - soloturn
          soloturn

          ๐Ÿ› - soyodream
          soyodream

          ๐Ÿ› + soloturn
          soloturn

          ๐Ÿ› + soyodream
          soyodream

          ๐Ÿ› sratz
          sratz

          ๐Ÿ› stonio
          stonio

          ๐Ÿ› sturton
          sturton

          ๐Ÿ’ป ๐Ÿ› sudharmohan
          sudharmohan

          ๐Ÿ› suruchidawar
          suruchidawar

          ๐Ÿ› - svenfinitiv
          svenfinitiv

          ๐Ÿ› - szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป + svenfinitiv
          svenfinitiv

          ๐Ÿ› + szymanp23
          szymanp23

          ๐Ÿ› ๐Ÿ’ป tashiscool
          tashiscool

          ๐Ÿ› test-git-hook
          test-git-hook

          ๐Ÿ› testation21
          testation21

          ๐Ÿ’ป ๐Ÿ› thanosa
          thanosa

          ๐Ÿ› tiandiyixian
          tiandiyixian

          ๐Ÿ› - tobwoerk
          tobwoerk

          ๐Ÿ› - tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป + tobwoerk
          tobwoerk

          ๐Ÿ› + tprouvot
          tprouvot

          ๐Ÿ› ๐Ÿ’ป trentchilders
          trentchilders

          ๐Ÿ› triandicAnt
          triandicAnt

          ๐Ÿ› trishul14
          trishul14

          ๐Ÿ› tsui
          tsui

          ๐Ÿ› wangzitom12306
          wangzitom12306

          ๐Ÿ› - winhkey
          winhkey

          ๐Ÿ› - witherspore
          witherspore

          ๐Ÿ› + winhkey
          winhkey

          ๐Ÿ› + witherspore
          witherspore

          ๐Ÿ› wjljack
          wjljack

          ๐Ÿ› wuchiuwong
          wuchiuwong

          ๐Ÿ› xingsong
          xingsong

          ๐Ÿ› xioayuge
          xioayuge

          ๐Ÿ› xnYi9wRezm
          xnYi9wRezm

          ๐Ÿ’ป ๐Ÿ› - xuanuy
          xuanuy

          ๐Ÿ› - xyf0921
          xyf0921

          ๐Ÿ› + xuanuy
          xuanuy

          ๐Ÿ› + xyf0921
          xyf0921

          ๐Ÿ› yalechen-cyw3
          yalechen-cyw3

          ๐Ÿ› yarlpavaworkday
          yarlpavaworkday

          ๐Ÿ› yasuharu-sato
          yasuharu-sato

          ๐Ÿ› zenglian
          zenglian

          ๐Ÿ› zgrzyt93
          zgrzyt93

          ๐Ÿ’ป ๐Ÿ› - zh3ng
          zh3ng

          ๐Ÿ› - zt_soft
          zt_soft

          ๐Ÿ› + zh3ng
          zh3ng

          ๐Ÿ› + zt_soft
          zt_soft

          ๐Ÿ› ztt79
          ztt79

          ๐Ÿ› zzzzfeng
          zzzzfeng

          ๐Ÿ› รrpรกd Magosรกnyi
          รrpรกd Magosรกnyi

          ๐Ÿ› ไปป่ดตๆฐ
          ไปป่ดตๆฐ

          ๐Ÿ› ๅคฉ็ƒญๅƒ่ฅฟ็“œ
          ๅคฉ็ƒญๅƒ่ฅฟ็“œ

          ๐Ÿ› + + ่Œ…ๅปถๅฎ‰
          ่Œ…ๅปถๅฎ‰

          ๐Ÿ’ป From e0f52d2a092082eabc538e74cc5d17b195593852 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 28 Nov 2025 11:42:34 +0100 Subject: [PATCH 1709/1962] Prepare pmd release 7.19.0 --- docs/_config.yml | 2 +- docs/pages/release_notes.md | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 65464430b8e..9ed919a449d 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,7 +1,7 @@ repository: pmd/pmd pmd: - version: 7.19.0-SNAPSHOT + version: 7.19.0 previous_version: 7.18.0 date: 2025-11-28 # release types: major, minor, bugfix diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 7bf7a22d39e..cc5f491e350 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -146,8 +146,8 @@ and [PMD Designer Changelog (7.19.1)](https://github.com/pmd/pmd-designer/releas * [#6201](https://github.com/pmd/pmd/pull/6201): \[java] Fix #6199: AssignmentInOperandRule: Update description of allowIncrementDecrement property - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6202](https://github.com/pmd/pmd/pull/6202): \[java] Fix #6188: UnitTestsShouldIncludeAssert - FP when TestNG @Test.expectedException is present - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#6204](https://github.com/pmd/pmd/pull/6204): \[apex] Add rule to limit usage of @Future annotation - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) -* [#6217](https://github.com/pmd/pmd/pull/6217): \[doc] Add Blue Cave to known tools using PMD - [Jude Pereira](https://github.com/judepereira) (@judepereira) * [#6214](https://github.com/pmd/pmd/pull/6214): \[plsql] New rule NcssCount to replace old Ncss*Count rules - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6217](https://github.com/pmd/pmd/pull/6217): \[doc] Add Blue Cave to known tools using PMD - [Jude Pereira](https://github.com/judepereira) (@judepereira) * [#6227](https://github.com/pmd/pmd/pull/6227): \[java] UseArraysAsList: check increment - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6228](https://github.com/pmd/pmd/pull/6228): \[java] UseArraysAsList: skip when if-statements - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#6229](https://github.com/pmd/pmd/pull/6229): chore: remove public methods from SourceManager - [Andreas Dangel](https://github.com/adangel) (@adangel) @@ -165,9 +165,38 @@ and [PMD Designer Changelog (7.19.1)](https://github.com/pmd/pmd-designer/releas ### ๐Ÿ“ฆ๏ธ Dependency updates +* [#6197](https://github.com/pmd/pmd/pull/6197): Bump PMD from 7.17.0 to 7.18.0 +* [#6205](https://github.com/pmd/pmd/pull/6205): chore(deps): bump junit.version from 6.0.0 to 6.0.1 +* [#6206](https://github.com/pmd/pmd/pull/6206): chore(deps): bump org.checkerframework:checker-qual from 3.51.1 to 3.52.0 +* [#6207](https://github.com/pmd/pmd/pull/6207): chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.17.7 to 1.17.8 +* [#6208](https://github.com/pmd/pmd/pull/6208): chore(deps): bump com.google.protobuf:protobuf-java from 4.32.1 to 4.33.0 +* [#6209](https://github.com/pmd/pmd/pull/6209): chore(deps): bump com.puppycrawl.tools:checkstyle from 12.0.1 to 12.1.1 +* [#6210](https://github.com/pmd/pmd/pull/6210): chore(deps): bump org.jacoco:jacoco-maven-plugin from 0.8.13 to 0.8.14 +* [#6219](https://github.com/pmd/pmd/pull/6219): chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.17.8 to 1.18.0 +* [#6220](https://github.com/pmd/pmd/pull/6220): chore(deps): bump org.apache.maven.plugins:maven-release-plugin from 3.1.1 to 3.2.0 +* [#6221](https://github.com/pmd/pmd/pull/6221): chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.17.8 to 1.18.0 +* [#6222](https://github.com/pmd/pmd/pull/6222): chore(deps): bump com.puppycrawl.tools:checkstyle from 12.1.1 to 12.1.2 +* [#6223](https://github.com/pmd/pmd/pull/6223): chore(deps): bump org.sonarsource.scanner.maven:sonar-maven-plugin from 5.2.0.4988 to 5.3.0.6276 +* [#6240](https://github.com/pmd/pmd/pull/6240): chore(deps): bump ruby/setup-ruby from 1.267.0 to 1.268.0 +* [#6241](https://github.com/pmd/pmd/pull/6241): chore(deps): bump actions/checkout from 5.0.0 to 5.0.1 +* [#6242](https://github.com/pmd/pmd/pull/6242): chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.18.0 to 1.18.1 +* [#6243](https://github.com/pmd/pmd/pull/6243): chore(deps): bump org.scala-lang:scala-library from 2.13.17 to 2.13.18 +* [#6244](https://github.com/pmd/pmd/pull/6244): chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.18.0 to 1.18.1 +* [#6245](https://github.com/pmd/pmd/pull/6245): chore(deps): bump org.apache.maven.plugins:maven-jar-plugin from 3.4.2 to 3.5.0 +* [#6246](https://github.com/pmd/pmd/pull/6246): chore(deps): bump org.scala-lang:scala-reflect from 2.13.17 to 2.13.18 +* [#6247](https://github.com/pmd/pmd/pull/6247): chore(deps): bump com.google.protobuf:protobuf-java from 4.33.0 to 4.33.1 +* [#6263](https://github.com/pmd/pmd/pull/6263): chore(deps): bump actions/checkout from 5.0.1 to 6.0.0 +* [#6264](https://github.com/pmd/pmd/pull/6264): chore(deps): bump org.apache.commons:commons-lang3 from 3.19.0 to 3.20.0 +* [#6265](https://github.com/pmd/pmd/pull/6265): chore(deps): bump actions/create-github-app-token from 2.1.4 to 2.2.0 +* [#6266](https://github.com/pmd/pmd/pull/6266): chore(deps): bump scalameta.version from 4.14.1 to 4.14.2 +* [#6267](https://github.com/pmd/pmd/pull/6267): chore(deps): bump org.codehaus.mojo:versions-maven-plugin from 2.19.1 to 2.20.1 +* [#6281](https://github.com/pmd/pmd/pull/6281): Bump build-tools from 35 to 36 +* [#6283](https://github.com/pmd/pmd/pull/6283): Bump PMD Designer from 7.10.0 to 7.19.1 ### ๐Ÿ“ˆ๏ธ Stats +* 122 commits +* 44 closed tickets & PRs +* Days since last release: 28 {% endtocmaker %} - From 2373452e01460c91bc575220e1b22941bbb75a49 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 28 Nov 2025 12:03:50 +0100 Subject: [PATCH 1710/1962] [release] prepare release pmd_releases/7.19.0 --- pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-css/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-rust/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 6 +++--- 44 files changed, 46 insertions(+), 46 deletions(-) diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index 9874ebe744b..517e5ca8a7e 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.19.0-SNAPSHOT + 7.19.0 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index d9e7a1e252a..eca0516ad73 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index 7383c5a600a..e3223989c39 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index 1aebd0b7605..87830136b73 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index 4cbe6d81232..3260511ff44 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index bd7bc3bca99..d82b4db420d 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index d4c2b6b9b8c..b78fea301e7 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-css/pom.xml b/pmd-css/pom.xml index 7bac6e1a7c7..acf741d8b2b 100644 --- a/pmd-css/pom.xml +++ b/pmd-css/pom.xml @@ -9,7 +9,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index f818ec775f6..0321cf29dcd 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index 2399aa2069c..a2887a8d5be 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index 2562b34b318..e2d30e676da 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index cd5f574a543..5a8fdf0ffb5 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index 21943f10843..ee550b13415 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index 91ca5158ed5..1622ff32820 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index 9a215f640e0..3a741c94c6a 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index c3ba03d2f10..b2e97b9b6f3 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 55cb2f23d87..de0c3d68552 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index 49cfe4f4f0c..a7c351541c4 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index 2ff102a7125..937e70d96b0 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index 663de183645..e9641e7b7d0 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index c4e74dcf41b..7346a26f752 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index 969ab3273a5..07fb233789e 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index 2c97f6a03f2..04233c75d8d 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index edf7938a5a0..203745a279a 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index 2fb784570d1..6997a14d871 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index b678c1a7ea5..729d95e943b 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index 8d9d530d044..46de63cbc1c 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index 2843453df2f..c8b649c5d22 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index c4249ed7ab7..3f9fb3214f8 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index 4a0a0546fb3..8e4e34589e1 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index 429b1c08c54..f1a7c9eede3 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index 0813ca82de9..b3951900a9f 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index 6c4529a777b..08cdce31c2c 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index 50cd7ff768e..f7362dbfb1d 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index fb3f90ed718..6ddd25bd3f1 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.19.0-SNAPSHOT + 7.19.0 ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index fa2190f5111..5330be33dc8 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.19.0-SNAPSHOT + 7.19.0 ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index 2d7401c62a3..65e7deb6ca6 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index c72de44766c..8a0ba3a68e1 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index 4fc7e9bf064..ed824b68dd3 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index f1e6b2d1e36..bdc109ca505 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index 4d5ebb4b7e0..5670e3747b1 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index 45db26ff856..c0f8f313082 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index 377d0b55186..310961a0807 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 ../pom.xml diff --git a/pom.xml b/pom.xml index fafd6007ff9..ff2b6768591 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.19.0-SNAPSHOT + 7.19.0 pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - HEAD + pmd_releases/7.19.0 PMD @@ -73,7 +73,7 @@ - 2025-10-31T08:02:02Z + 2025-11-28T10:42:42Z 8 From 5136dbad093afa3247acdb850375f659dce177f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 28 Nov 2025 12:08:07 +0100 Subject: [PATCH 1711/1962] [java] Improve LambdaCanBeMethodReference Use similar approach as UseDiamondOperator, replay inference with a faked expr mirror to check that replacing lambda with method ref would be valid. Fix #5043 Fix a TODO in type resolution codebase that was causing ambiguity errors with method references. Potential compatibility of method refs was not checked properly. --- .../LambdaCanBeMethodReferenceRule.java | 196 +++++++++++++++++- .../java/types/internal/infer/ExprMirror.java | 13 ++ .../java/types/internal/infer/ExprOps.java | 65 ++++-- .../lang/java/types/internal/infer/Infer.java | 2 +- .../infer/ResolutionFailedException.java | 6 + .../internal/infer/TypeInferenceLogger.java | 2 +- .../internal/infer/OverloadSpecificityTest.kt | 39 +++- .../xml/LambdaCanBeMethodReference.xml | 60 +++++- 8 files changed, 352 insertions(+), 31 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LambdaCanBeMethodReferenceRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LambdaCanBeMethodReferenceRule.java index 51f8beb1ef9..021fe170d88 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LambdaCanBeMethodReferenceRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LambdaCanBeMethodReferenceRule.java @@ -4,6 +4,12 @@ package net.sourceforge.pmd.lang.java.rule.codestyle; +import java.util.Collections; +import java.util.List; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + import net.sourceforge.pmd.lang.java.ast.ASTArgumentList; import net.sourceforge.pmd.lang.java.ast.ASTClassLiteral; import net.sourceforge.pmd.lang.java.ast.ASTConstructorCall; @@ -21,6 +27,9 @@ import net.sourceforge.pmd.lang.java.ast.ASTThisExpression; import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTTypeExpression; +import net.sourceforge.pmd.lang.java.ast.InternalApiBridge; +import net.sourceforge.pmd.lang.java.ast.InvocationNode; +import net.sourceforge.pmd.lang.java.ast.JavaNode; import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; import net.sourceforge.pmd.lang.java.ast.internal.PrettyPrintingUtil; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; @@ -28,9 +37,17 @@ import net.sourceforge.pmd.lang.java.symbols.JTypeDeclSymbol; import net.sourceforge.pmd.lang.java.symbols.JVariableSymbol; import net.sourceforge.pmd.lang.java.types.JClassType; +import net.sourceforge.pmd.lang.java.types.JMethodSig; import net.sourceforge.pmd.lang.java.types.JTypeMirror; import net.sourceforge.pmd.lang.java.types.OverloadSelectionResult; import net.sourceforge.pmd.lang.java.types.TypeOps; +import net.sourceforge.pmd.lang.java.types.TypingContext; +import net.sourceforge.pmd.lang.java.types.ast.ExprContext; +import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror; +import net.sourceforge.pmd.lang.java.types.internal.infer.Infer; +import net.sourceforge.pmd.lang.java.types.internal.infer.MethodCallSite; +import net.sourceforge.pmd.lang.java.types.internal.infer.PolySite; +import net.sourceforge.pmd.lang.java.types.internal.infer.ast.JavaExprMirrors; import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.properties.PropertyFactory; import net.sourceforge.pmd.reporting.RuleContext; @@ -83,7 +100,9 @@ private void processLambdaWithBody(ASTLambdaExpression lambda, RuleContext data, } if (expression instanceof ASTMethodCall) { ASTMethodCall call = (ASTMethodCall) expression; - if (canBeTransformed(lambda, call) && argumentsListMatches(call, lambda.getParameters())) { + if (canBeTransformed(lambda, call) + && argumentsListMatches(call, lambda.getParameters()) + && inferenceSucceedsWithMethodRef(lambda, call)) { data.addViolation(lambda, buildMethodRefString(lambda, call)); } } @@ -186,4 +205,179 @@ private boolean canBeTransformed(ASTLambdaExpression lambda, ASTMethodCall call) } + + /** + * This creates a fake method ref mirror that simulates how the method + * reference would behave after applying the fix. We redo inference of + * the context of that method ref (ie, maybe inferring an enclosing method + * call) and check that inference gives the same result as the current lambda. + * This ensures that changing the lambda to a method reference does not + * error with an ambiguity error, and also does not change the result of + * overload resolution. Refer to e.g. {@link UseDiamondOperatorRule} for a + * similar approach to checking the validity of a code transformation. + */ + private static boolean inferenceSucceedsWithMethodRef(ASTLambdaExpression lambda, ASTMethodCall call) { + ExprContext context = lambda.getConversionContext(); + if (context.isMissing()) { + return false; + } + + Infer infer = InternalApiBridge.getInferenceEntryPoint(lambda); + // this may not mutate the AST + JavaExprMirrors factory = JavaExprMirrors.forObservation(infer); + + InvocationNode invocContext = InternalApiBridge.getTopLevelExprContext(lambda).getInvocNodeIfInvocContext(); + if (invocContext == null) { + ExprMirror.LambdaExprMirror lambdaMirror = (ExprMirror.LambdaExprMirror) factory.getTopLevelFunctionalMirror(lambda); + LambdaAsMethodRefMirror mirror; + mirror = new LambdaAsMethodRefMirror(lambdaMirror, call); + // topmostContext = lambda.getConversionContext(); + PolySite site = infer.newFunctionalSite(mirror, lambda.getConversionContext().getTargetType()); + infer.inferFunctionalExprInUnambiguousContext(site); + return mirror.succeeded(); + } else { + ExprMirror.InvocationMirror topMostMirror = factory.getInvocationMirror(invocContext, (e, parent, self) -> { + ExprMirror defaultImpl = factory.defaultMirrorMaker().createMirrorForSubexpression(e, parent, self); + if (e == lambda) { + return new LambdaAsMethodRefMirror((ExprMirror.LambdaExprMirror) defaultImpl, call); + } else { + return defaultImpl; + } + }); + + ExprContext topmostContext; + if (invocContext instanceof ASTExpression) { + topmostContext = ((ASTExpression) invocContext).getConversionContext(); + } else { + topmostContext = ExprContext.getMissingInstance(); + } + JTypeMirror targetType = topmostContext.getPolyTargetType(false); + MethodCallSite fakeCallSite = infer.newCallSite(topMostMirror, targetType); + infer.inferInvocationRecursively(fakeCallSite); + return topMostMirror.isEquivalentToUnderlyingAst() + && topmostContext.acceptsType(topMostMirror.getInferredType()); + } + } + + + static final class LambdaAsMethodRefMirror implements ExprMirror.MethodRefMirror { + + LambdaExprMirror lambda; + private final ASTMethodCall call; + private final JTypeMirror lhsType; + private final boolean isLhsType; + + LambdaAsMethodRefMirror(LambdaExprMirror lambda, ASTMethodCall call) { + this.lambda = lambda; + this.call = call; + this.isLhsType = call.getQualifier() == null && call.getMethodType().isStatic() + || call.getArguments().size() != lambda.getParamCount() + || call.getQualifier() instanceof ASTTypeExpression; + + this.lhsType = call.getQualifier() == null ? call.getMethodType().getDeclaringType() + : call.getQualifier().getTypeMirror(); + } + + @Override + public CharSequence getLocationText() { + return this + " (mref adapter on lambda)"; + } + + @Override + public String toString() { + if (isLhsType) { + return lhsType.toString() + "::" + getMethodName(); + } else { + return call.getQualifier() + "::" + getMethodName(); + } + } + + @Override + public boolean isConstructorRef() { + return false; + } + + @Override + public JTypeMirror getTypeToSearch() { + return lhsType; + } + + @Override + public @Nullable JTypeMirror getLhsIfType() { + return isLhsType ? lhsType : null; + } + + @Override + public String getMethodName() { + return call.getMethodName(); + } + + @Override + public @NonNull List getExplicitTypeArguments() { + return Collections.emptyList(); + } + + InvocationMirror.MethodCtDecl ctDecl; + + @Override + public void setCompileTimeDecl(InvocationMirror.MethodCtDecl methodType) { + this.ctDecl = methodType; + } + + private JMethodSig exactMethod; + + @Override + public @Nullable JMethodSig getCachedExactMethod() { + return exactMethod; + } + + @Override + public void setCachedExactMethod(@Nullable JMethodSig sig) { + exactMethod = sig; + } + + @Override + public JavaNode getLocation() { + return lambda.getLocation(); + } + + @Override + public void setInferredType(@Nullable JTypeMirror mirror) { + + } + + @Override + public @Nullable JTypeMirror getInferredType() { + return null; + } + + @Override + public TypingContext getTypingContext() { + return lambda.getTypingContext(); + } + + @Override + public boolean isEquivalentToUnderlyingAst() { + return succeeded() && ctDecl.getMethodType().equals(call.getMethodType()); + } + + @Override + public void setFunctionalMethod(@Nullable JMethodSig methodType) { + + } + + @Override + public void finishFailedInference(@Nullable JTypeMirror targetType) { + ctDecl = null; + } + + @Override + public @NonNull JClassType getEnclosingType() { + return lambda.getEnclosingType(); + } + + boolean succeeded() { + return ctDecl != null && !ctDecl.isFailed(); + } + } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java index 61af4b3e773..b654f0c16b1 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java @@ -40,6 +40,16 @@ public interface ExprMirror { */ JavaNode getLocation(); + /** + * Return the text of the location node. May be overridden if this + * mirror is fake (eg, using a lambda node but presenting a method ref, + * or using a method ref node but presenting an invocation). + * Use this only to log messages and for debugging. + */ + default CharSequence getLocationText() { + return getLocation().getText(); + } + /** * If this expression is of a standalone form, returns the type of @@ -324,6 +334,9 @@ interface MethodRefMirror extends FunctionalExprMirror, MethodUsageMirror { @Nullable JTypeMirror getLhsIfType(); + default boolean isLhsAType() { + return getLhsIfType() != null; + } /** * Returns the name of the invoked method, or {@link JConstructorSymbol#CTOR_NAME} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java index 47c154f3bba..141a34a8e13 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java @@ -100,9 +100,23 @@ boolean isPotentiallyCompatible(JMethodSig m, ExprMirror e, JTypeMirror t) { } else { // is method reference + MethodRefMirror mref = (MethodRefMirror) e; + boolean hasAppropriateCandidate; + if (mref.isLhsAType() && !mref.isConstructorRef()) { + // The method reference expression has the form + // ReferenceType :: [TypeArguments] Identifier and + // at least one potentially applicable method is + // either (i) static and supports arity n, or + // (ii) not static and supports arity n-1. + hasAppropriateCandidate = + hasCandidate(mref, fun, false, true) + || hasCandidate(mref, fun, true, false); + } else { + // The method reference expression has some other form and at least one potentially applicable method is not static. + hasAppropriateCandidate = hasCandidate(mref, fun, false, false); + } - // TODO need to look for potentially applicable methods - return true; + return hasAppropriateCandidate; } } @@ -112,6 +126,17 @@ boolean isPotentiallyCompatible(JMethodSig m, ExprMirror e, JTypeMirror t) { return true; } + private boolean hasCandidate(MethodRefMirror mref, JMethodSig fun, boolean firstParamIsReceiver, boolean expectStatic) { + InvocationMirror asMethodCall = methodRefAsInvocation(mref, fun, firstParamIsReceiver); + for (JMethodSig cand : asMethodCall.getAccessibleCandidates()) { + if (infer.isPotentiallyApplicable(cand, asMethodCall) + && cand.isStatic() == expectStatic) { + return true; + } + } + return false; + } + /** * Returns true if the the argument expression is pertinent * to applicability for the potentially applicable method m, @@ -143,26 +168,25 @@ static boolean isPertinentToApplicability(ExprMirror arg, JMethodSig m, JTypeMir return false; } } - - // If m is a generic method and the method invocation does - // not provide explicit type arguments, an explicitly typed - // lambda expression for which the corresponding target type - // (as derived from the signature of m) is a type parameter of m. - return !m.isGeneric() - || !invoc.getExplicitTypeArguments().isEmpty() - || !formalType.isTypeVariable(); } if (arg instanceof MethodRefMirror) { // An inexact method reference expression(ยง 15.13 .1). - return getExactMethod((MethodRefMirror) arg) != null - // If m is a generic method and the method invocation does - // not provide explicit type arguments, an exact method - // reference expression for which the corresponding target type - // (as derived from the signature of m) is a type parameter of m. - && (!m.isGeneric() - || !invoc.getExplicitTypeArguments().isEmpty() - || !formalType.isTypeVariable()); + if (getExactMethod((MethodRefMirror) arg) == null) { + return false; + } + } + + if (arg instanceof FunctionalExprMirror) { + // If m is a generic method and the method invocation does + // not provide explicit type arguments, an explicitly typed + // lambda expression or an exact method reference expression + // for which the corresponding target type (as derived from + // the signature of m) is a type parameter of m. + if (m.isGeneric() && !invoc.getExplicitTypeArguments().isEmpty() + && m.getTypeParameters().contains(formalType)) { + return false; + } } if (arg instanceof BranchingMirror) { @@ -370,6 +394,11 @@ public JavaNode getLocation() { return mref.getLocation(); } + @Override + public CharSequence getLocationText() { + return mref.getLocationText() + " (viewed as method call)"; + } + @Override public Iterable getAccessibleCandidates() { return ExprOps.getAccessibleCandidates(mref, asInstanceMethod, targetType); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java index 2c2d38e0ad0..87388124424 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java @@ -1019,7 +1019,7 @@ static Convertibility isConvertible(JTypeMirror exprType, JTypeMirror formalType * @param m Method to test * @param expr Invocation expression */ - private boolean isPotentiallyApplicable(JMethodSig m, InvocationMirror expr) { + boolean isPotentiallyApplicable(JMethodSig m, InvocationMirror expr) { if (m.isGeneric() && !expr.getExplicitTypeArguments().isEmpty() diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ResolutionFailedException.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ResolutionFailedException.java index b955129c56c..729c81b989c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ResolutionFailedException.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ResolutionFailedException.java @@ -165,6 +165,12 @@ static ResolutionFailedException cannotInvokeInstanceMethodOnPrimitive(TypeInfer + actual)); } + static ResolutionFailedException unboundMrefCannotTargetInstanceMethod(TypeInferenceLogger logger, MethodRefMirror mref, JMethodSig targetFun) { + return getShared(logger.isNoop() ? UNKNOWN + : new ResolutionFailure(mref.getLocation(), + "Instance method reference cannot target functional type " + targetFun)); + } + static ResolutionFailedException noCtDeclaration(TypeInferenceLogger logger, JMethodSig fun, MethodRefMirror mref) { return getShared(logger.isNoop() ? UNKNOWN : new ResolutionFailure(mref.getLocation(), diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java index 83ea662d57d..05c85855c13 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java @@ -329,7 +329,7 @@ public void ambiguityError(MethodCallSite site, @Nullable MethodCtDecl selected, } protected void printExpr(ExprMirror expr) { - String exprText = expr.getLocation().getText().toString(); + String exprText = expr.getLocationText().toString(); exprText = exprText.replaceAll("\\R\\s+", ""); exprText = StringUtil.escapeJava(StringUtils.truncate(exprText, 100)); println("At: " + fileLocation(expr)); diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadSpecificityTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadSpecificityTest.kt index 838987cff15..d718309f742 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadSpecificityTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadSpecificityTest.kt @@ -6,11 +6,11 @@ package net.sourceforge.pmd.lang.java.types.internal.infer import io.kotest.matchers.shouldBe -import net.sourceforge.pmd.lang.test.ast.shouldBe import net.sourceforge.pmd.lang.java.ast.* import net.sourceforge.pmd.lang.java.types.* import net.sourceforge.pmd.lang.java.types.TypeOps.areOverrideEquivalent import net.sourceforge.pmd.lang.java.types.testdata.Overloads +import net.sourceforge.pmd.lang.test.ast.shouldBe import net.sourceforge.pmd.util.OptionalBool import net.sourceforge.pmd.lang.java.types.internal.infer.OverloadSet.shouldAlwaysTakePrecedence as shouldTakePrecedence @@ -425,4 +425,41 @@ class Scratch { spy.shouldBeAmbiguous(stdM) spy.shouldBeAmbiguous(polyM) } + + parserTest("Non ambiguous test, no diff between lambda and mref") { + val (acu, spy) = parser.parseWithTypeInferenceSpy( + """ + public final class Foo { + + public static void iTakeLambda(Lambda1Arg l) {} + public static void iTakeLambda(Lambda2Args l) {} + static { + iTakeLambda(x -> x.isEmpty()); + iTakeLambda(String::isEmpty); + iTakeLambda((x,c) -> x.contains(c)); + iTakeLambda(String::contains); + } + public boolean correct(int a) { + return false; + } + } + + interface Lambda2Args { + boolean doSomething(String a, CharSequence c); + } + interface Lambda1Arg { + boolean doSomething(String a); + } + """.trimIndent() + ) + + val (takes1ArgLambda, takes2ArgsLambda) = acu.declaredMethodSignatures().toList() + val (a, b, c, d) = acu.descendants(ASTInitializer::class.java).firstOrThrow().body!!.children().children(ASTMethodCall::class.java).toList() + spy.shouldBeOk { + a.methodType shouldBeSomeInstantiationOf takes1ArgLambda + b.methodType shouldBeSomeInstantiationOf takes1ArgLambda + c.methodType shouldBeSomeInstantiationOf takes2ArgsLambda + d.methodType shouldBeSomeInstantiationOf takes2ArgsLambda + } + } }) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LambdaCanBeMethodReference.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LambdaCanBeMethodReference.xml index 9025e8a88cf..0a4a3f5d92e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LambdaCanBeMethodReference.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LambdaCanBeMethodReference.xml @@ -74,6 +74,7 @@ return correct(x); }); // do not flag iTakeLambda(x -> {}); + iTakeLambda(this::correct); } public int correct(int a) { return 0; @@ -147,7 +148,7 @@ true 4 - Lambda expression could be written as a method reference: `"abc"::indexOf` + Lambda expression could be written as a method reference: `"abc"::equals` Lambda expression could be written as a method reference: `this::correct` Lambda expression could be written as a method reference: `Integer::valueOf` Lambda expression could be written as a method reference: `String.class::isAssignableFrom` @@ -157,8 +158,8 @@ public static void iTakeLambda(ALambda l) {} public static void iTakeClass(Consumer> l) {} - static { - iTakeLambda(x -> "abc".indexOf(x)); + { + iTakeLambda(x -> "abc".equals(x)); iTakeLambda(x -> this.correct(x)); iTakeLambda(x -> Integer.valueOf(x)); iTakeClass(x -> String.class.isAssignableFrom(x)); @@ -169,9 +170,13 @@ } interface ALambda { - boolean doSomething(int a); + void doSomething(int a); } - ]]> + + interface Consumer { + void doSomething(T a); + } +]]>
          Test annotated lambda @@ -256,8 +261,7 @@ ]]> - - - + ]]> @@ -374,5 +377,44 @@ ]]> + + #5043 Method reference would be ambiguous + 0 + st.foo(); + Alambda l2 = st -> Something.foo(st); + l2 = Something::foo; // ambiguous + } + } + ]]> + + + + + #5043 Method reference would be ambiguous (Integer toString + 0 + x = v -> Integer.toString(v); + + System.out.println(x.apply(100)); + } + } + ]]> + + + From 7bf550dd2c59481f44681249b050d6f66d33f837 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 28 Nov 2025 12:47:38 +0100 Subject: [PATCH 1712/1962] [release] Prepare next development version --- docs/_config.yml | 6 +- docs/pages/release_notes.md | 163 +---------------- docs/pages/release_notes_old.md | 199 +++++++++++++++++++++ pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-css/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-rust/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 4 +- 47 files changed, 248 insertions(+), 210 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 9ed919a449d..34530d84567 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,9 +1,9 @@ repository: pmd/pmd pmd: - version: 7.19.0 - previous_version: 7.18.0 - date: 2025-11-28 + version: 7.20.0-SNAPSHOT + previous_version: 7.19.0 + date: 2025-12-28 # release types: major, minor, bugfix release_type: minor diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index cc5f491e350..48d7c2ca2f6 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -24,179 +24,18 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy -#### Updated PMD Designer - -This PMD release ships a new version of the pmd-designer. -For the changes, see [PMD Designer Changelog (7.19.0)](https://github.com/pmd/pmd-designer/releases/tag/7.19.0) -and [PMD Designer Changelog (7.19.1)](https://github.com/pmd/pmd-designer/releases/tag/7.19.1). - -### ๐ŸŒŸ๏ธ New and Changed Rules -#### New Rules -* The new Apex rule {%rule apex/bestpractices/AvoidFutureAnnotation %} finds usages of the `@Future` - annotation. It is a legacy way to execute asynchronous Apex code. New code should implement - the `Queueable` interface instead. -* The new Java rule {%rule java/bestpractices/EnumComparison %} finds usages of `equals()` on - enum constants or values. Enums should be compared directly with `==` instead of `equals()` which - has some advantages (e.g. static type checking at compile time). -* The new Apex rule {% rule apex/design/NcssCount %} replaces the four rules "ExcessiveClassLength", - "NcssConstructorCount", "NcssMethodCount", and "NcssTypeCount". The new rule uses the metrics framework - to achieve the same. It has two properties, to define the report level for method and class sizes separately. - Constructors and methods are considered the same. - The rule has been added to the quickstart ruleset. - Note: The new metric is implemented more correct than in the old rules. E.g. it considers now also - switch statements and correctly counts if-statements only once and ignores method calls that are - part of an expression and not a statement on their own. This leads to different numbers. Keep in mind, - that NCSS counts statements and not lines of code. Statements that are split on multiple lines are - still counted as one. -* The new PL/SQL rule {% rule plsql/design/NcssCount %} replaces the rules "ExcessiveMethodLength", - "ExcessiveObjectLength", "ExcessivePackageBodyLength", "ExcessivePackageSpecificationLength", - "ExcessiveTypeLength", "NcssMethodCount" and "NcssObjectCount". The new rule uses the metrics framework - to achieve the same. It has two properties, to define the report level for method and object sizes separately. - Note: the new metric is implemented more correct than in the old rules, so that the actual numbers of - the NCSS metric from the old rules might be different from the new rule "NcssCount". Statements that are - split on multiple lines are still counted as one. - -#### Deprecated Rules -* The Apex rule {% rule apex/design/ExcessiveClassLength %} has been deprecated. Use {%rule apex/design/NcssCount %} to - find big classes or create a custom XPath based rule using - `//ApexFile[UserClass][@EndLine - @BeginLine > 1000]`. -* The Apex rules {% rule apex/design/NcssConstructorCount %}, {%rule apex/design/NcssMethodCount %}, and - {% rule apex/design/NcssTypeCount %} have been deprecated in favor or the new rule {%rule apex/design/NcssCount %}. -* The PL/SQL rule {% rule plsql/design/ExcessiveMethodLength %} has been deprecated. Use {% rule plsql/design/NcssCount %} - instead or create a custom XPath based rule using - `//(MethodDeclaration|ProgramUnit|TriggerTimingPointSection|TriggerUnit|TypeMethod)[@EndLine - @BeginLine > 100]`. -* The PL/SQL rule {% rule plsql/design/ExcessiveObjectLength %} has been deprecated. Use {% rule plsql/design/NcssCount %} - instead or create a custom XPath based rule using - `//(PackageBody|PackageSpecification|ProgramUnit|TriggerUnit|TypeSpecification)[@EndLine - @BeginLine > 1000]`. -* The PL/SQL rule {% rule plsql/design/ExcessivePackageBodyLength %} has been deprecated. Use {% rule plsql/design/NcssCount %} - instead or create a custom XPath based rule using - `//PackageBody[@EndLine - @BeginLine > 1000]`. -* The PL/SQL rule {% rule plsql/design/ExcessivePackageSpecificationLength %} has been deprecated. Use {% rule plsql/design/NcssCount %} - instead or create a custom XPath based rule using - `//PackageSpecification[@EndLine - @BeginLine > 1000]`. -* The PL/SQL rule {% rule plsql/design/ExcessiveTypeLength %} has been deprecated. Use {% rule plsql/design/NcssCount %} - instead or create a custom XPath based rule using - `//TypeSpecification[@EndLine - @BeginLine > 1000]`. -* The PL/SQL rules {% rule plsql/design/NcssMethodCount %} and {% rule plsql/design/NcssObjectCount %} have been - deprecated in favor of the new rule {% rule plsql/design/NcssCount %}. - ### ๐Ÿ›๏ธ Fixed Issues -* core - * [#4767](https://github.com/pmd/pmd/issues/4767): \[core] Deprecate old symboltable API -* apex-bestpractices - * [#6203](https://github.com/pmd/pmd/issues/6203): \[apex] New Rule: Avoid Future Annotation -* apex-design - * [#2128](https://github.com/pmd/pmd/issues/2128): \[apex] Merge NCSS count rules for Apex -* java - * [#5689](https://github.com/pmd/pmd/issues/5689): \[java] Members of record should be in scope in record header - * [#6256](https://github.com/pmd/pmd/issues/6256): \[java] java.lang.IllegalArgumentException: Invalid target type of type annotation for method or ctor type annotation: 19 -* java-bestpractices - * [#5820](https://github.com/pmd/pmd/issues/5820): \[java] GuardLogStatement recognizes that a string is a compile-time constant expression only if at first position - * [#6188](https://github.com/pmd/pmd/issues/6188): \[java] UnitTestShouldIncludeAssert false positive when TestNG @Test.expectedException present - * [#6193](https://github.com/pmd/pmd/issues/6193): \[java] New Rule: Always compare enum values with == -* java-codestyle - * [#6053](https://github.com/pmd/pmd/issues/6053): \[java] ModifierOrder false-positives with type annotations and type parameters (typeAnnotations = anywhere) -* java-errorprone - * [#4742](https://github.com/pmd/pmd/issues/4742): \[java] EmptyFinalizer should not trigger if finalize method is final and class is not - * [#6072](https://github.com/pmd/pmd/issues/6072): \[java] OverrideBothEqualsAndHashCodeOnComparable should not be required for record classes - * [#6092](https://github.com/pmd/pmd/issues/6092): \[java] AssignmentInOperand false positive in 7.17.0 for case blocks in switch statements - * [#6096](https://github.com/pmd/pmd/issues/6096): \[java] OverrideBothEqualsAndHashCodeOnComparable on class with lombok.EqualsAndHashCode annotation - * [#6199](https://github.com/pmd/pmd/issues/6199): \[java] AssignmentInOperand: description of property allowIncrementDecrement is unclear - * [#6273](https://github.com/pmd/pmd/issues/6273): \[java] TestClassWithoutTestCases documentation does not mention test prefixes -* java-performance - * [#4577](https://github.com/pmd/pmd/issues/4577): \[java] UseArraysAsList with condition in loop - * [#5071](https://github.com/pmd/pmd/issues/5071): \[java] UseArraysAsList should not warn when elements are skipped in array -* plsql-design - * [#4326](https://github.com/pmd/pmd/issues/4326): \[plsql] Merge NCSS count rules for PL/SQL -* maintenance - * [#5701](https://github.com/pmd/pmd/issues/5701): \[core] net.sourceforge.pmd.cpd.SourceManager has public methods ### ๐Ÿšจ๏ธ API Changes -#### Deprecations -* core - * {%jdoc_package core::lang.symboltable %}: All classes in this package are deprecated. - The symbol table and type resolution implementation for Java has been rewritten from scratch - for PMD 7.0.0. This package is the remains of the old symbol table API, that is only used by - PL/SQL. For PMD 8.0.0 all these classes will be removed from pmd-core. -* apex - * {% jdoc apex::lang.apex.rule.design.ExcessiveClassLengthRule %} - * {% jdoc apex::lang.apex.rule.design.NcssConstructorCountRule %} - * {% jdoc apex::lang.apex.rule.design.NcssMethodCountRule %} - * {% jdoc apex::lang.apex.rule.design.NcssTypeCountRule %} - * {% jdoc apex::lang.apex.ast.ASTStatement %}: This AST node is not used and doesn't appear in the tree. - * {% jdoc !ac!apex::lang.apex.ast.ApexVisitor#visit(apex::lang.apex.ast.ASTStatement,P) %} -* plsql - * {% jdoc plsql::lang.plsql.rule.design.ExcessiveMethodLengthRule %} - * {% jdoc plsql::lang.plsql.rule.design.ExcessiveObjectLengthRule %} - * {% jdoc plsql::lang.plsql.rule.design.ExcessivePackageBodyLengthRule %} - * {% jdoc plsql::lang.plsql.rule.design.ExcessivePackageSpecificationLengthRule %} - * {% jdoc plsql::lang.plsql.rule.design.ExcessiveTypeLengthRule %} - * {% jdoc plsql::lang.plsql.rule.design.NcssMethodCountRule %} - * {% jdoc plsql::lang.plsql.rule.design.NcssObjectCountRule %} - ### โœจ๏ธ Merged pull requests -* [#6081](https://github.com/pmd/pmd/pull/6081): \[java] Fix #6072: OverrideBothEqualsAndHashCodeOnComparable should not be required for record classes - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) -* [#6192](https://github.com/pmd/pmd/pull/6192): \[java] Fix #6053: ModifierOrder - consider type params - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6194](https://github.com/pmd/pmd/pull/6194): chore: always place type annotations on the type - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6195](https://github.com/pmd/pmd/pull/6195): chore: always compare enums with == - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6196](https://github.com/pmd/pmd/pull/6196): \[java] New Rule: EnumComparison - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6198](https://github.com/pmd/pmd/pull/6198): \[apex] New rule NcssCount to replace old Ncss*Count rules - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6201](https://github.com/pmd/pmd/pull/6201): \[java] Fix #6199: AssignmentInOperandRule: Update description of allowIncrementDecrement property - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) -* [#6202](https://github.com/pmd/pmd/pull/6202): \[java] Fix #6188: UnitTestsShouldIncludeAssert - FP when TestNG @Test.expectedException is present - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) -* [#6204](https://github.com/pmd/pmd/pull/6204): \[apex] Add rule to limit usage of @Future annotation - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) -* [#6214](https://github.com/pmd/pmd/pull/6214): \[plsql] New rule NcssCount to replace old Ncss*Count rules - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6217](https://github.com/pmd/pmd/pull/6217): \[doc] Add Blue Cave to known tools using PMD - [Jude Pereira](https://github.com/judepereira) (@judepereira) -* [#6227](https://github.com/pmd/pmd/pull/6227): \[java] UseArraysAsList: check increment - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6228](https://github.com/pmd/pmd/pull/6228): \[java] UseArraysAsList: skip when if-statements - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6229](https://github.com/pmd/pmd/pull/6229): chore: remove public methods from SourceManager - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6238](https://github.com/pmd/pmd/pull/6238): \[java] Fix #6096: Detect Lombok generated equals/hashCode in Comparable - [Marcel](https://github.com/mrclmh) (@mrclmh) -* [#6249](https://github.com/pmd/pmd/pull/6249): \[core] Deprecate old symboltable API - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6250](https://github.com/pmd/pmd/pull/6250): chore: fail build for compiler warnings - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#6251](https://github.com/pmd/pmd/pull/6251): \[java] Fix #6092: AssignmentInOperand false positive in 7.17.0 for case statements - [Marcel](https://github.com/mrclmh) (@mrclmh) -* [#6255](https://github.com/pmd/pmd/pull/6255): \[java] Fix #4742: EmptyFinalizer should not trigger if finalize method is final and class is not - [Marcel](https://github.com/mrclmh) (@mrclmh) -* [#6258](https://github.com/pmd/pmd/pull/6258): \[java] Fix #5820: GuardLogStatement recognizes that a string is a compile-time constant expression only if at first position - [Marcel](https://github.com/mrclmh) (@mrclmh) -* [#6259](https://github.com/pmd/pmd/pull/6259): \[java] Fix #5689: Issue with scoping of record members - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#6277](https://github.com/pmd/pmd/pull/6277): \[doc] Add button to copy configuration snippet - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#6278](https://github.com/pmd/pmd/pull/6278): \[doc] TestClassWithoutTestCases: Mention test prefixes - [Marcel](https://github.com/mrclmh) (@mrclmh) -* [#6280](https://github.com/pmd/pmd/pull/6280): \[ci] Exclude build resources from spring-framework for regression tester - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#6282](https://github.com/pmd/pmd/pull/6282): \[java] Fix #6256: ignore invalid annotation type - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ๏ธ Dependency updates -* [#6197](https://github.com/pmd/pmd/pull/6197): Bump PMD from 7.17.0 to 7.18.0 -* [#6205](https://github.com/pmd/pmd/pull/6205): chore(deps): bump junit.version from 6.0.0 to 6.0.1 -* [#6206](https://github.com/pmd/pmd/pull/6206): chore(deps): bump org.checkerframework:checker-qual from 3.51.1 to 3.52.0 -* [#6207](https://github.com/pmd/pmd/pull/6207): chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.17.7 to 1.17.8 -* [#6208](https://github.com/pmd/pmd/pull/6208): chore(deps): bump com.google.protobuf:protobuf-java from 4.32.1 to 4.33.0 -* [#6209](https://github.com/pmd/pmd/pull/6209): chore(deps): bump com.puppycrawl.tools:checkstyle from 12.0.1 to 12.1.1 -* [#6210](https://github.com/pmd/pmd/pull/6210): chore(deps): bump org.jacoco:jacoco-maven-plugin from 0.8.13 to 0.8.14 -* [#6219](https://github.com/pmd/pmd/pull/6219): chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.17.8 to 1.18.0 -* [#6220](https://github.com/pmd/pmd/pull/6220): chore(deps): bump org.apache.maven.plugins:maven-release-plugin from 3.1.1 to 3.2.0 -* [#6221](https://github.com/pmd/pmd/pull/6221): chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.17.8 to 1.18.0 -* [#6222](https://github.com/pmd/pmd/pull/6222): chore(deps): bump com.puppycrawl.tools:checkstyle from 12.1.1 to 12.1.2 -* [#6223](https://github.com/pmd/pmd/pull/6223): chore(deps): bump org.sonarsource.scanner.maven:sonar-maven-plugin from 5.2.0.4988 to 5.3.0.6276 -* [#6240](https://github.com/pmd/pmd/pull/6240): chore(deps): bump ruby/setup-ruby from 1.267.0 to 1.268.0 -* [#6241](https://github.com/pmd/pmd/pull/6241): chore(deps): bump actions/checkout from 5.0.0 to 5.0.1 -* [#6242](https://github.com/pmd/pmd/pull/6242): chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.18.0 to 1.18.1 -* [#6243](https://github.com/pmd/pmd/pull/6243): chore(deps): bump org.scala-lang:scala-library from 2.13.17 to 2.13.18 -* [#6244](https://github.com/pmd/pmd/pull/6244): chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.18.0 to 1.18.1 -* [#6245](https://github.com/pmd/pmd/pull/6245): chore(deps): bump org.apache.maven.plugins:maven-jar-plugin from 3.4.2 to 3.5.0 -* [#6246](https://github.com/pmd/pmd/pull/6246): chore(deps): bump org.scala-lang:scala-reflect from 2.13.17 to 2.13.18 -* [#6247](https://github.com/pmd/pmd/pull/6247): chore(deps): bump com.google.protobuf:protobuf-java from 4.33.0 to 4.33.1 -* [#6263](https://github.com/pmd/pmd/pull/6263): chore(deps): bump actions/checkout from 5.0.1 to 6.0.0 -* [#6264](https://github.com/pmd/pmd/pull/6264): chore(deps): bump org.apache.commons:commons-lang3 from 3.19.0 to 3.20.0 -* [#6265](https://github.com/pmd/pmd/pull/6265): chore(deps): bump actions/create-github-app-token from 2.1.4 to 2.2.0 -* [#6266](https://github.com/pmd/pmd/pull/6266): chore(deps): bump scalameta.version from 4.14.1 to 4.14.2 -* [#6267](https://github.com/pmd/pmd/pull/6267): chore(deps): bump org.codehaus.mojo:versions-maven-plugin from 2.19.1 to 2.20.1 -* [#6281](https://github.com/pmd/pmd/pull/6281): Bump build-tools from 35 to 36 -* [#6283](https://github.com/pmd/pmd/pull/6283): Bump PMD Designer from 7.10.0 to 7.19.1 ### ๐Ÿ“ˆ๏ธ Stats -* 122 commits -* 44 closed tickets & PRs -* Days since last release: 28 {% endtocmaker %} + diff --git a/docs/pages/release_notes_old.md b/docs/pages/release_notes_old.md index de3d5c551c7..5381059cbe6 100644 --- a/docs/pages/release_notes_old.md +++ b/docs/pages/release_notes_old.md @@ -7,6 +7,205 @@ Previous versions of PMD can be downloaded here: [Releases - pmd/pmd (GitHub)](h +## 28-November-2025 - 7.19.0 + +The PMD team is pleased to announce PMD 7.19.0. + +This is a minor release. + +### Table Of Contents + +* [๐Ÿš€๏ธ New and noteworthy](#new-and-noteworthy) + * [Updated PMD Designer](#updated-pmd-designer) +* [๐ŸŒŸ๏ธ New and Changed Rules](#new-and-changed-rules) + * [New Rules](#new-rules) + * [Deprecated Rules](#deprecated-rules) +* [๐Ÿ›๏ธ Fixed Issues](#fixed-issues) +* [๐Ÿšจ๏ธ API Changes](#api-changes) + * [Deprecations](#deprecations) +* [โœจ๏ธ Merged pull requests](#merged-pull-requests) +* [๐Ÿ“ฆ๏ธ Dependency updates](#dependency-updates) +* [๐Ÿ“ˆ๏ธ Stats](#stats) + +### ๐Ÿš€๏ธ New and noteworthy + +#### Updated PMD Designer + +This PMD release ships a new version of the pmd-designer. +For the changes, see [PMD Designer Changelog (7.19.0)](https://github.com/pmd/pmd-designer/releases/tag/7.19.0) +and [PMD Designer Changelog (7.19.1)](https://github.com/pmd/pmd-designer/releases/tag/7.19.1). + +### ๐ŸŒŸ๏ธ New and Changed Rules +#### New Rules +* The new Apex rule [`AvoidFutureAnnotation`](https://docs.pmd-code.org/pmd-doc-7.19.0/pmd_rules_apex_bestpractices.html#avoidfutureannotation) finds usages of the `@Future` + annotation. It is a legacy way to execute asynchronous Apex code. New code should implement + the `Queueable` interface instead. +* The new Java rule [`EnumComparison`](https://docs.pmd-code.org/pmd-doc-7.19.0/pmd_rules_java_bestpractices.html#enumcomparison) finds usages of `equals()` on + enum constants or values. Enums should be compared directly with `==` instead of `equals()` which + has some advantages (e.g. static type checking at compile time). +* The new Apex rule [`NcssCount`](https://docs.pmd-code.org/pmd-doc-7.19.0/pmd_rules_apex_design.html#ncsscount) replaces the four rules "ExcessiveClassLength", + "NcssConstructorCount", "NcssMethodCount", and "NcssTypeCount". The new rule uses the metrics framework + to achieve the same. It has two properties, to define the report level for method and class sizes separately. + Constructors and methods are considered the same. + The rule has been added to the quickstart ruleset. + Note: The new metric is implemented more correct than in the old rules. E.g. it considers now also + switch statements and correctly counts if-statements only once and ignores method calls that are + part of an expression and not a statement on their own. This leads to different numbers. Keep in mind, + that NCSS counts statements and not lines of code. Statements that are split on multiple lines are + still counted as one. +* The new PL/SQL rule [`NcssCount`](https://docs.pmd-code.org/pmd-doc-7.19.0/pmd_rules_plsql_design.html#ncsscount) replaces the rules "ExcessiveMethodLength", + "ExcessiveObjectLength", "ExcessivePackageBodyLength", "ExcessivePackageSpecificationLength", + "ExcessiveTypeLength", "NcssMethodCount" and "NcssObjectCount". The new rule uses the metrics framework + to achieve the same. It has two properties, to define the report level for method and object sizes separately. + Note: the new metric is implemented more correct than in the old rules, so that the actual numbers of + the NCSS metric from the old rules might be different from the new rule "NcssCount". Statements that are + split on multiple lines are still counted as one. + +#### Deprecated Rules +* The Apex rule [`ExcessiveClassLength`](https://docs.pmd-code.org/pmd-doc-7.19.0/pmd_rules_apex_design.html#excessiveclasslength) has been deprecated. Use [`NcssCount`](https://docs.pmd-code.org/pmd-doc-7.19.0/pmd_rules_apex_design.html#ncsscount) to + find big classes or create a custom XPath based rule using + `//ApexFile[UserClass][@EndLine - @BeginLine > 1000]`. +* The Apex rules [`NcssConstructorCount`](https://docs.pmd-code.org/pmd-doc-7.19.0/pmd_rules_apex_design.html#ncssconstructorcount), [`NcssMethodCount`](https://docs.pmd-code.org/pmd-doc-7.19.0/pmd_rules_apex_design.html#ncssmethodcount), and + [`NcssTypeCount`](https://docs.pmd-code.org/pmd-doc-7.19.0/pmd_rules_apex_design.html#ncsstypecount) have been deprecated in favor or the new rule [`NcssCount`](https://docs.pmd-code.org/pmd-doc-7.19.0/pmd_rules_apex_design.html#ncsscount). +* The PL/SQL rule [`ExcessiveMethodLength`](https://docs.pmd-code.org/pmd-doc-7.19.0/pmd_rules_plsql_design.html#excessivemethodlength) has been deprecated. Use [`NcssCount`](https://docs.pmd-code.org/pmd-doc-7.19.0/pmd_rules_plsql_design.html#ncsscount) + instead or create a custom XPath based rule using + `//(MethodDeclaration|ProgramUnit|TriggerTimingPointSection|TriggerUnit|TypeMethod)[@EndLine - @BeginLine > 100]`. +* The PL/SQL rule [`ExcessiveObjectLength`](https://docs.pmd-code.org/pmd-doc-7.19.0/pmd_rules_plsql_design.html#excessiveobjectlength) has been deprecated. Use [`NcssCount`](https://docs.pmd-code.org/pmd-doc-7.19.0/pmd_rules_plsql_design.html#ncsscount) + instead or create a custom XPath based rule using + `//(PackageBody|PackageSpecification|ProgramUnit|TriggerUnit|TypeSpecification)[@EndLine - @BeginLine > 1000]`. +* The PL/SQL rule [`ExcessivePackageBodyLength`](https://docs.pmd-code.org/pmd-doc-7.19.0/pmd_rules_plsql_design.html#excessivepackagebodylength) has been deprecated. Use [`NcssCount`](https://docs.pmd-code.org/pmd-doc-7.19.0/pmd_rules_plsql_design.html#ncsscount) + instead or create a custom XPath based rule using + `//PackageBody[@EndLine - @BeginLine > 1000]`. +* The PL/SQL rule [`ExcessivePackageSpecificationLength`](https://docs.pmd-code.org/pmd-doc-7.19.0/pmd_rules_plsql_design.html#excessivepackagespecificationlength) has been deprecated. Use [`NcssCount`](https://docs.pmd-code.org/pmd-doc-7.19.0/pmd_rules_plsql_design.html#ncsscount) + instead or create a custom XPath based rule using + `//PackageSpecification[@EndLine - @BeginLine > 1000]`. +* The PL/SQL rule [`ExcessiveTypeLength`](https://docs.pmd-code.org/pmd-doc-7.19.0/pmd_rules_plsql_design.html#excessivetypelength) has been deprecated. Use [`NcssCount`](https://docs.pmd-code.org/pmd-doc-7.19.0/pmd_rules_plsql_design.html#ncsscount) + instead or create a custom XPath based rule using + `//TypeSpecification[@EndLine - @BeginLine > 1000]`. +* The PL/SQL rules [`NcssMethodCount`](https://docs.pmd-code.org/pmd-doc-7.19.0/pmd_rules_plsql_design.html#ncssmethodcount) and [`NcssObjectCount`](https://docs.pmd-code.org/pmd-doc-7.19.0/pmd_rules_plsql_design.html#ncssobjectcount) have been + deprecated in favor of the new rule [`NcssCount`](https://docs.pmd-code.org/pmd-doc-7.19.0/pmd_rules_plsql_design.html#ncsscount). + +### ๐Ÿ›๏ธ Fixed Issues +* core + * [#4767](https://github.com/pmd/pmd/issues/4767): \[core] Deprecate old symboltable API +* apex-bestpractices + * [#6203](https://github.com/pmd/pmd/issues/6203): \[apex] New Rule: Avoid Future Annotation +* apex-design + * [#2128](https://github.com/pmd/pmd/issues/2128): \[apex] Merge NCSS count rules for Apex +* java + * [#5689](https://github.com/pmd/pmd/issues/5689): \[java] Members of record should be in scope in record header + * [#6256](https://github.com/pmd/pmd/issues/6256): \[java] java.lang.IllegalArgumentException: Invalid target type of type annotation for method or ctor type annotation: 19 +* java-bestpractices + * [#5820](https://github.com/pmd/pmd/issues/5820): \[java] GuardLogStatement recognizes that a string is a compile-time constant expression only if at first position + * [#6188](https://github.com/pmd/pmd/issues/6188): \[java] UnitTestShouldIncludeAssert false positive when TestNG @Test.expectedException present + * [#6193](https://github.com/pmd/pmd/issues/6193): \[java] New Rule: Always compare enum values with == +* java-codestyle + * [#6053](https://github.com/pmd/pmd/issues/6053): \[java] ModifierOrder false-positives with type annotations and type parameters (typeAnnotations = anywhere) +* java-errorprone + * [#4742](https://github.com/pmd/pmd/issues/4742): \[java] EmptyFinalizer should not trigger if finalize method is final and class is not + * [#6072](https://github.com/pmd/pmd/issues/6072): \[java] OverrideBothEqualsAndHashCodeOnComparable should not be required for record classes + * [#6092](https://github.com/pmd/pmd/issues/6092): \[java] AssignmentInOperand false positive in 7.17.0 for case blocks in switch statements + * [#6096](https://github.com/pmd/pmd/issues/6096): \[java] OverrideBothEqualsAndHashCodeOnComparable on class with lombok.EqualsAndHashCode annotation + * [#6199](https://github.com/pmd/pmd/issues/6199): \[java] AssignmentInOperand: description of property allowIncrementDecrement is unclear + * [#6273](https://github.com/pmd/pmd/issues/6273): \[java] TestClassWithoutTestCases documentation does not mention test prefixes +* java-performance + * [#4577](https://github.com/pmd/pmd/issues/4577): \[java] UseArraysAsList with condition in loop + * [#5071](https://github.com/pmd/pmd/issues/5071): \[java] UseArraysAsList should not warn when elements are skipped in array +* plsql-design + * [#4326](https://github.com/pmd/pmd/issues/4326): \[plsql] Merge NCSS count rules for PL/SQL +* maintenance + * [#5701](https://github.com/pmd/pmd/issues/5701): \[core] net.sourceforge.pmd.cpd.SourceManager has public methods + +### ๐Ÿšจ๏ธ API Changes + +#### Deprecations +* core + * net.sourceforge.pmd.lang.symboltable: All classes in this package are deprecated. + The symbol table and type resolution implementation for Java has been rewritten from scratch + for PMD 7.0.0. This package is the remains of the old symbol table API, that is only used by + PL/SQL. For PMD 8.0.0 all these classes will be removed from pmd-core. +* apex + * ExcessiveClassLengthRule + * NcssConstructorCountRule + * NcssMethodCountRule + * NcssTypeCountRule + * ASTStatement: This AST node is not used and doesn't appear in the tree. + * ApexVisitor#visit(ASTStatement, P) +* plsql + * ExcessiveMethodLengthRule + * ExcessiveObjectLengthRule + * ExcessivePackageBodyLengthRule + * ExcessivePackageSpecificationLengthRule + * ExcessiveTypeLengthRule + * NcssMethodCountRule + * NcssObjectCountRule + +### โœจ๏ธ Merged pull requests + +* [#6081](https://github.com/pmd/pmd/pull/6081): \[java] Fix #6072: OverrideBothEqualsAndHashCodeOnComparable should not be required for record classes - [UncleOwen](https://github.com/UncleOwen) (@UncleOwen) +* [#6192](https://github.com/pmd/pmd/pull/6192): \[java] Fix #6053: ModifierOrder - consider type params - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6194](https://github.com/pmd/pmd/pull/6194): chore: always place type annotations on the type - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6195](https://github.com/pmd/pmd/pull/6195): chore: always compare enums with == - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6196](https://github.com/pmd/pmd/pull/6196): \[java] New Rule: EnumComparison - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6198](https://github.com/pmd/pmd/pull/6198): \[apex] New rule NcssCount to replace old Ncss*Count rules - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6201](https://github.com/pmd/pmd/pull/6201): \[java] Fix #6199: AssignmentInOperandRule: Update description of allowIncrementDecrement property - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#6202](https://github.com/pmd/pmd/pull/6202): \[java] Fix #6188: UnitTestsShouldIncludeAssert - FP when TestNG @Test.expectedException is present - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#6204](https://github.com/pmd/pmd/pull/6204): \[apex] Add rule to limit usage of @Future annotation - [Mitch Spano](https://github.com/mitchspano) (@mitchspano) +* [#6214](https://github.com/pmd/pmd/pull/6214): \[plsql] New rule NcssCount to replace old Ncss*Count rules - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6217](https://github.com/pmd/pmd/pull/6217): \[doc] Add Blue Cave to known tools using PMD - [Jude Pereira](https://github.com/judepereira) (@judepereira) +* [#6227](https://github.com/pmd/pmd/pull/6227): \[java] UseArraysAsList: check increment - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6228](https://github.com/pmd/pmd/pull/6228): \[java] UseArraysAsList: skip when if-statements - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6229](https://github.com/pmd/pmd/pull/6229): chore: remove public methods from SourceManager - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6238](https://github.com/pmd/pmd/pull/6238): \[java] Fix #6096: Detect Lombok generated equals/hashCode in Comparable - [Marcel](https://github.com/mrclmh) (@mrclmh) +* [#6249](https://github.com/pmd/pmd/pull/6249): \[core] Deprecate old symboltable API - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6250](https://github.com/pmd/pmd/pull/6250): chore: fail build for compiler warnings - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6251](https://github.com/pmd/pmd/pull/6251): \[java] Fix #6092: AssignmentInOperand false positive in 7.17.0 for case statements - [Marcel](https://github.com/mrclmh) (@mrclmh) +* [#6255](https://github.com/pmd/pmd/pull/6255): \[java] Fix #4742: EmptyFinalizer should not trigger if finalize method is final and class is not - [Marcel](https://github.com/mrclmh) (@mrclmh) +* [#6258](https://github.com/pmd/pmd/pull/6258): \[java] Fix #5820: GuardLogStatement recognizes that a string is a compile-time constant expression only if at first position - [Marcel](https://github.com/mrclmh) (@mrclmh) +* [#6259](https://github.com/pmd/pmd/pull/6259): \[java] Fix #5689: Issue with scoping of record members - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#6277](https://github.com/pmd/pmd/pull/6277): \[doc] Add button to copy configuration snippet - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6278](https://github.com/pmd/pmd/pull/6278): \[doc] TestClassWithoutTestCases: Mention test prefixes - [Marcel](https://github.com/mrclmh) (@mrclmh) +* [#6280](https://github.com/pmd/pmd/pull/6280): \[ci] Exclude build resources from spring-framework for regression tester - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#6282](https://github.com/pmd/pmd/pull/6282): \[java] Fix #6256: ignore invalid annotation type - [Andreas Dangel](https://github.com/adangel) (@adangel) + +### ๐Ÿ“ฆ๏ธ Dependency updates + +* [#6197](https://github.com/pmd/pmd/pull/6197): Bump PMD from 7.17.0 to 7.18.0 +* [#6205](https://github.com/pmd/pmd/pull/6205): chore(deps): bump junit.version from 6.0.0 to 6.0.1 +* [#6206](https://github.com/pmd/pmd/pull/6206): chore(deps): bump org.checkerframework:checker-qual from 3.51.1 to 3.52.0 +* [#6207](https://github.com/pmd/pmd/pull/6207): chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.17.7 to 1.17.8 +* [#6208](https://github.com/pmd/pmd/pull/6208): chore(deps): bump com.google.protobuf:protobuf-java from 4.32.1 to 4.33.0 +* [#6209](https://github.com/pmd/pmd/pull/6209): chore(deps): bump com.puppycrawl.tools:checkstyle from 12.0.1 to 12.1.1 +* [#6210](https://github.com/pmd/pmd/pull/6210): chore(deps): bump org.jacoco:jacoco-maven-plugin from 0.8.13 to 0.8.14 +* [#6219](https://github.com/pmd/pmd/pull/6219): chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.17.8 to 1.18.0 +* [#6220](https://github.com/pmd/pmd/pull/6220): chore(deps): bump org.apache.maven.plugins:maven-release-plugin from 3.1.1 to 3.2.0 +* [#6221](https://github.com/pmd/pmd/pull/6221): chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.17.8 to 1.18.0 +* [#6222](https://github.com/pmd/pmd/pull/6222): chore(deps): bump com.puppycrawl.tools:checkstyle from 12.1.1 to 12.1.2 +* [#6223](https://github.com/pmd/pmd/pull/6223): chore(deps): bump org.sonarsource.scanner.maven:sonar-maven-plugin from 5.2.0.4988 to 5.3.0.6276 +* [#6240](https://github.com/pmd/pmd/pull/6240): chore(deps): bump ruby/setup-ruby from 1.267.0 to 1.268.0 +* [#6241](https://github.com/pmd/pmd/pull/6241): chore(deps): bump actions/checkout from 5.0.0 to 5.0.1 +* [#6242](https://github.com/pmd/pmd/pull/6242): chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.18.0 to 1.18.1 +* [#6243](https://github.com/pmd/pmd/pull/6243): chore(deps): bump org.scala-lang:scala-library from 2.13.17 to 2.13.18 +* [#6244](https://github.com/pmd/pmd/pull/6244): chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.18.0 to 1.18.1 +* [#6245](https://github.com/pmd/pmd/pull/6245): chore(deps): bump org.apache.maven.plugins:maven-jar-plugin from 3.4.2 to 3.5.0 +* [#6246](https://github.com/pmd/pmd/pull/6246): chore(deps): bump org.scala-lang:scala-reflect from 2.13.17 to 2.13.18 +* [#6247](https://github.com/pmd/pmd/pull/6247): chore(deps): bump com.google.protobuf:protobuf-java from 4.33.0 to 4.33.1 +* [#6263](https://github.com/pmd/pmd/pull/6263): chore(deps): bump actions/checkout from 5.0.1 to 6.0.0 +* [#6264](https://github.com/pmd/pmd/pull/6264): chore(deps): bump org.apache.commons:commons-lang3 from 3.19.0 to 3.20.0 +* [#6265](https://github.com/pmd/pmd/pull/6265): chore(deps): bump actions/create-github-app-token from 2.1.4 to 2.2.0 +* [#6266](https://github.com/pmd/pmd/pull/6266): chore(deps): bump scalameta.version from 4.14.1 to 4.14.2 +* [#6267](https://github.com/pmd/pmd/pull/6267): chore(deps): bump org.codehaus.mojo:versions-maven-plugin from 2.19.1 to 2.20.1 +* [#6281](https://github.com/pmd/pmd/pull/6281): Bump build-tools from 35 to 36 +* [#6283](https://github.com/pmd/pmd/pull/6283): Bump PMD Designer from 7.10.0 to 7.19.1 + +### ๐Ÿ“ˆ๏ธ Stats + +* 122 commits +* 44 closed tickets & PRs +* Days since last release: 28 + + + ## 31-October-2025 - 7.18.0 The PMD team is pleased to announce PMD 7.18.0. diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index 517e5ca8a7e..490e72add84 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.19.0 + 7.20.0-SNAPSHOT 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index eca0516ad73..9ec89697c7e 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index e3223989c39..7e3933105e6 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index 87830136b73..11d0a185aa9 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index 3260511ff44..e0572bdbeeb 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index d82b4db420d..c790214f4b2 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index b78fea301e7..f0fffaac3af 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-css/pom.xml b/pmd-css/pom.xml index acf741d8b2b..7f47b303b8e 100644 --- a/pmd-css/pom.xml +++ b/pmd-css/pom.xml @@ -9,7 +9,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index 0321cf29dcd..adfec9779cf 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index a2887a8d5be..cd7ece0dbff 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index e2d30e676da..8dfafddfe7a 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index 5a8fdf0ffb5..ca39cac3f91 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index ee550b13415..965cfff3981 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index 1622ff32820..fcf8768ad5e 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index 3a741c94c6a..96db91eebcf 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index b2e97b9b6f3..860942102ae 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index de0c3d68552..2abd49c8888 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index a7c351541c4..c89d95f0e67 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index 937e70d96b0..3d0992bcf55 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index e9641e7b7d0..0feca275256 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index 7346a26f752..7a93f60a2ee 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index 07fb233789e..c4fff49b44c 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index 04233c75d8d..829c9c2cae8 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index 203745a279a..a0d8804f630 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index 6997a14d871..50522c82f3a 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index 729d95e943b..e742cdd74ee 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index 46de63cbc1c..91f82e6e852 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index c8b649c5d22..0df600f9029 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index 3f9fb3214f8..2e85696aa35 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index 8e4e34589e1..d65f5d25771 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index f1a7c9eede3..2de426045e7 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index b3951900a9f..2813f23a06d 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index 08cdce31c2c..180d8aab61b 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index f7362dbfb1d..f45c9aac80e 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index 6ddd25bd3f1..6bdb08da2fa 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.19.0 + 7.20.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index 5330be33dc8..b2c8f0c3f31 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.19.0 + 7.20.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index 65e7deb6ca6..26596df6302 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index 8a0ba3a68e1..c36ca99f62b 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index ed824b68dd3..f36aca31e33 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index bdc109ca505..ab917814a64 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index 5670e3747b1..02670dd0533 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index c0f8f313082..34202ece856 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index 310961a0807..6f6c7b14c36 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index ff2b6768591..13a6edf1720 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.19.0 + 7.20.0-SNAPSHOT pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - pmd_releases/7.19.0 + HEAD PMD From bb1c1f7e4a9f6ded33aa27a5b5069976d33eb6b6 Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Fri, 28 Nov 2025 15:33:28 +0100 Subject: [PATCH 1713/1962] Doc: Explain how to build or pull snapshot dependencies --- docs/pages/pmd/devdocs/building/building_general.md | 7 +++++++ .../pages/pmd/devdocs/contributing/newcomers_guide.md | 11 +++++++++++ 2 files changed, 18 insertions(+) diff --git a/docs/pages/pmd/devdocs/building/building_general.md b/docs/pages/pmd/devdocs/building/building_general.md index d78ac25acd8..7b4209a57a1 100644 --- a/docs/pages/pmd/devdocs/building/building_general.md +++ b/docs/pages/pmd/devdocs/building/building_general.md @@ -126,6 +126,13 @@ See also . ```shell ./mvnw verify -pl pmd-apex ``` +* If you are currently on a snapshot commit (as opposed to a release commit) you need snapshot modules as dependencies + for the module you want to build. You can either build them yourself (line 1) or you can activate the snapshot + repository (line 2) for your build: + ```shell + ./mvnw verify -pl pmd-apex -am + ./mvnw verify -pl pmd-apex -Pcentral-portal-snapshots + ``` **Caveats:** We have some integration tests, that run only after all modules have been built. You could break these without noticing. **Note:** In our CI (via GitHub Actions) we always build the complete project. diff --git a/docs/pages/pmd/devdocs/contributing/newcomers_guide.md b/docs/pages/pmd/devdocs/contributing/newcomers_guide.md index 280f108f389..f6882d31e55 100644 --- a/docs/pages/pmd/devdocs/contributing/newcomers_guide.md +++ b/docs/pages/pmd/devdocs/contributing/newcomers_guide.md @@ -84,6 +84,17 @@ pull requests later for your fix. $ ./mvnw clean verify -pl pmd-apex ``` +6. You might get an error about not being able to resolve a `snapshot` module: + ```shell + Could not resolve dependencies for project net.sourceforge.pmd:pmd-apex:jar:7.20.0-SNAPSHOT + ``` + Then you are on snapshot commit and need snapshot dependencies for your module. You can activate building the + required dependencies yourself (line 1) or you can activate the snapshot repository (line 2) for your build: + ```shell + $ ./mvnw clean verify -pl pmd-apex -am + $ ./mvnw clean verify -pl pmd-apex -Pcentral-portal-snapshots + ``` + We recommend to read the documentation [Building PMD General Info](pmd_devdocs_building_general.html) and especially the IDE specific guides, such as [Building PMD with IntelliJ IDEA](pmd_devdocs_building_intellij.html). These pages explain how to prepare your local development environment in order to work on PMD. From f940eaeaa54b6fab0063789d764563d554632300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 28 Nov 2025 15:44:16 +0100 Subject: [PATCH 1714/1962] Fix pmd warning --- .../java/rule/codestyle/LambdaCanBeMethodReferenceRule.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LambdaCanBeMethodReferenceRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LambdaCanBeMethodReferenceRule.java index 021fe170d88..fb35ba55d6d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LambdaCanBeMethodReferenceRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/LambdaCanBeMethodReferenceRule.java @@ -343,7 +343,7 @@ public JavaNode getLocation() { @Override public void setInferredType(@Nullable JTypeMirror mirror) { - + // Not needed } @Override @@ -363,11 +363,12 @@ public boolean isEquivalentToUnderlyingAst() { @Override public void setFunctionalMethod(@Nullable JMethodSig methodType) { - + // Not needed } @Override public void finishFailedInference(@Nullable JTypeMirror targetType) { + // Null this out to signify that we failed inference ctDecl = null; } From 5487f653f7250b6ac7df1b9433489072930c8148 Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Fri, 28 Nov 2025 16:13:03 +0100 Subject: [PATCH 1715/1962] Style: Indentation fix and avoid overshooting max line length --- pmd-java/src/main/resources/category/java/codestyle.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml index 8ffdf0e5b70..9207c62d278 100644 --- a/pmd-java/src/main/resources/category/java/codestyle.xml +++ b/pmd-java/src/main/resources/category/java/codestyle.xml @@ -484,12 +484,14 @@ usage by developers who should be implementing their own versions in the concret From b87b7ce824a81c46d6c6305ac1acb4d18da0a059 Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Fri, 28 Nov 2025 16:15:47 +0100 Subject: [PATCH 1716/1962] Fix: Add an exception for final finalize The construct final finalize is one security measure that can be used to prevent finalizer attacks. --- pmd-java/src/main/resources/category/java/codestyle.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml index 9207c62d278..35f6446d360 100644 --- a/pmd-java/src/main/resources/category/java/codestyle.xml +++ b/pmd-java/src/main/resources/category/java/codestyle.xml @@ -486,6 +486,7 @@ usage by developers who should be implementing their own versions in the concret //ClassDeclaration[@RegularClass = true() and pmd-java:modifiers() = "abstract"] /ClassBody /MethodDeclaration + [not(@Name = "finalize" and @Final = true())] [Block[ let $size := count(*[not(self::EmptyStatement)]) return $size = 0 From 44ffcf2ce511c8b2befb29e21578782263e84bdb Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Fri, 28 Nov 2025 16:16:28 +0100 Subject: [PATCH 1717/1962] Test: Allow final finalize to prevent finalizer attack --- ...yMethodInAbstractClassShouldBeAbstract.xml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/EmptyMethodInAbstractClassShouldBeAbstract.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/EmptyMethodInAbstractClassShouldBeAbstract.xml index aec3caa4d8c..0ba7a98e4f7 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/EmptyMethodInAbstractClassShouldBeAbstract.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/EmptyMethodInAbstractClassShouldBeAbstract.xml @@ -213,6 +213,25 @@ public interface Foo { default void isVisible() { } +} + ]]> + + + + #6279 allow final finalize to prevent finalizer attack + 0 + From 6d14ed6bc13323b50cee5065bbd91729aae815cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 28 Nov 2025 17:44:31 +0100 Subject: [PATCH 1718/1962] Improve recovery behavior (fix failing test) --- .../lang/java/types/internal/infer/ExprMirror.java | 2 +- .../pmd/lang/java/types/internal/infer/ExprOps.java | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java index b654f0c16b1..70630c93aa3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java @@ -319,7 +319,7 @@ interface MethodRefMirror extends FunctionalExprMirror, MethodUsageMirror { * while we don't). */ @Override - JTypeMirror getTypeToSearch(); + @NonNull JTypeMirror getTypeToSearch(); /** diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java index 141a34a8e13..f6fb719b45f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java @@ -101,22 +101,22 @@ boolean isPotentiallyCompatible(JMethodSig m, ExprMirror e, JTypeMirror t) { } else { // is method reference MethodRefMirror mref = (MethodRefMirror) e; - boolean hasAppropriateCandidate; + if (TypeOps.isUnresolved(mref.getTypeToSearch())) { + // don't fail if the LHS is not known or not fully known + return true; + } if (mref.isLhsAType() && !mref.isConstructorRef()) { // The method reference expression has the form // ReferenceType :: [TypeArguments] Identifier and // at least one potentially applicable method is // either (i) static and supports arity n, or // (ii) not static and supports arity n-1. - hasAppropriateCandidate = - hasCandidate(mref, fun, false, true) + return hasCandidate(mref, fun, false, true) || hasCandidate(mref, fun, true, false); } else { // The method reference expression has some other form and at least one potentially applicable method is not static. - hasAppropriateCandidate = hasCandidate(mref, fun, false, false); + return hasCandidate(mref, fun, false, false); } - - return hasAppropriateCandidate; } } From 62769dfe6622f25111923385a6fdd70bb52c59a5 Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Fri, 28 Nov 2025 22:39:45 +0100 Subject: [PATCH 1719/1962] Refactor: Allow all final empty methods in abstract --- pmd-java/src/main/resources/category/java/codestyle.xml | 2 +- .../xml/EmptyMethodInAbstractClassShouldBeAbstract.xml | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml index 35f6446d360..1f57d48d2a9 100644 --- a/pmd-java/src/main/resources/category/java/codestyle.xml +++ b/pmd-java/src/main/resources/category/java/codestyle.xml @@ -486,7 +486,7 @@ usage by developers who should be implementing their own versions in the concret //ClassDeclaration[@RegularClass = true() and pmd-java:modifiers() = "abstract"] /ClassBody /MethodDeclaration - [not(@Name = "finalize" and @Final = true())] + [@Final = false()] [Block[ let $size := count(*[not(self::EmptyStatement)]) return $size = 0 diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/EmptyMethodInAbstractClassShouldBeAbstract.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/EmptyMethodInAbstractClassShouldBeAbstract.xml index 0ba7a98e4f7..389b17dc7e3 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/EmptyMethodInAbstractClassShouldBeAbstract.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/EmptyMethodInAbstractClassShouldBeAbstract.xml @@ -218,7 +218,7 @@ public interface Foo { - #6279 allow final finalize to prevent finalizer attack + #6279 allow all final methods 0 From 1bef938381f794e88cbd2fd88834148218917084 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Gr=C3=A4f?= Date: Fri, 28 Nov 2025 23:28:04 +0100 Subject: [PATCH 1720/1962] [java] Fix NullAssignment should not report assigning null to a final field in a constructor --- .../rule/errorprone/NullAssignmentRule.java | 43 +++++++++++++++---- .../rule/errorprone/xml/NullAssignment.xml | 18 ++++++++ 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/NullAssignmentRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/NullAssignmentRule.java index bf6166a5702..4d4ed727bd4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/NullAssignmentRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/NullAssignmentRule.java @@ -11,8 +11,10 @@ import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr.ASTNamedReferenceExpr; import net.sourceforge.pmd.lang.java.ast.ASTAssignmentExpression; import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression; +import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTNullLiteral; import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator; +import net.sourceforge.pmd.lang.java.ast.JavaNode; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; import net.sourceforge.pmd.lang.java.symbols.JVariableSymbol; @@ -42,14 +44,8 @@ public Object visit(ASTNullLiteral node, Object data) { } private boolean isAssignmentToFinal(ASTAssignmentExpression n) { - @NonNull - ASTAssignableExpr leftOperand = n.getLeftOperand(); - if (leftOperand instanceof ASTNamedReferenceExpr) { - @Nullable - JVariableSymbol symbol = ((ASTNamedReferenceExpr) leftOperand).getReferencedSym(); - return symbol != null && symbol.isFinal(); - } - return false; + JVariableSymbol symbol = tryGetLeftOperandSymbol(n); + return symbol != null && symbol.isFinal(); } private boolean isBadTernary(ASTConditionalExpression ternary, ASTNullLiteral nullLiteral) { @@ -68,10 +64,39 @@ private boolean isBadTernary(ASTConditionalExpression ternary, ASTNullLiteral nu currentTernary = parentTernary; } - boolean isAssignment = currentTernary.getParent() instanceof ASTAssignmentExpression; + final JavaNode parent = currentTernary.getParent(); + boolean isAssignment = parent instanceof ASTAssignmentExpression; + if (isAssignment && isFinalFieldInitializer((ASTAssignmentExpression) parent)) { + isInitializer = true; + } return isThenOrElse && isAssignment && !isInitializer; } + + @Nullable + private JVariableSymbol tryGetLeftOperandSymbol(ASTAssignmentExpression expression) { + @NonNull + ASTAssignableExpr leftOperand = expression.getLeftOperand(); + if (leftOperand instanceof ASTNamedReferenceExpr) { + @Nullable + JVariableSymbol symbol = ((ASTNamedReferenceExpr) leftOperand).getReferencedSym(); + return symbol; + } + return null; + } + + private boolean isFinalFieldInitializer(ASTAssignmentExpression expression) { + if (!isInsideConstructor(expression)) { + return false; + } + + final JVariableSymbol symbol = tryGetLeftOperandSymbol(expression); + return symbol != null && symbol.isField() && symbol.isFinal(); + } + + private boolean isInsideConstructor(JavaNode node) { + return node.ancestors(ASTConstructorDeclaration.class).nonEmpty(); + } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/NullAssignment.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/NullAssignment.xml index ea4d9807854..5192f91240b 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/NullAssignment.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/NullAssignment.xml @@ -302,6 +302,24 @@ class Tester { x = (null); // should report a warning in this line } } +]]> + + + + #6276: NullAssignment should not report assigning null to a final field in a constructor + 0 + From f57f4691e291aed718e633872a8e036e4e2c35dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Gr=C3=A4f?= Date: Fri, 28 Nov 2025 23:54:26 +0100 Subject: [PATCH 1721/1962] Re-order nullable annotations to fix build --- .../pmd/lang/java/rule/errorprone/NullAssignmentRule.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/NullAssignmentRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/NullAssignmentRule.java index 4d4ed727bd4..99bfa7e97f9 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/NullAssignmentRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/NullAssignmentRule.java @@ -44,6 +44,7 @@ public Object visit(ASTNullLiteral node, Object data) { } private boolean isAssignmentToFinal(ASTAssignmentExpression n) { + @Nullable JVariableSymbol symbol = tryGetLeftOperandSymbol(n); return symbol != null && symbol.isFinal(); } @@ -75,8 +76,7 @@ private boolean isBadTernary(ASTConditionalExpression ternary, ASTNullLiteral nu && !isInitializer; } - @Nullable - private JVariableSymbol tryGetLeftOperandSymbol(ASTAssignmentExpression expression) { + private @Nullable JVariableSymbol tryGetLeftOperandSymbol(ASTAssignmentExpression expression) { @NonNull ASTAssignableExpr leftOperand = expression.getLeftOperand(); if (leftOperand instanceof ASTNamedReferenceExpr) { @@ -92,7 +92,8 @@ private boolean isFinalFieldInitializer(ASTAssignmentExpression expression) { return false; } - final JVariableSymbol symbol = tryGetLeftOperandSymbol(expression); + @Nullable + JVariableSymbol symbol = tryGetLeftOperandSymbol(expression); return symbol != null && symbol.isField() && symbol.isFinal(); } From 7070c2765e3f0e6baf1010f80c7cae42c3c7dcfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Gr=C3=A4f?= Date: Fri, 28 Nov 2025 23:56:08 +0100 Subject: [PATCH 1722/1962] Minor cleanup: Remove unused initializer --- .../pmd/lang/java/rule/errorprone/NullAssignmentRule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/NullAssignmentRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/NullAssignmentRule.java index 99bfa7e97f9..e2f41f789c0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/NullAssignmentRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/NullAssignmentRule.java @@ -50,7 +50,7 @@ private boolean isAssignmentToFinal(ASTAssignmentExpression n) { } private boolean isBadTernary(ASTConditionalExpression ternary, ASTNullLiteral nullLiteral) { - boolean isInitializer = false; + boolean isInitializer; ASTVariableDeclarator variableDeclarator = ternary.ancestors(ASTVariableDeclarator.class).first(); isInitializer = variableDeclarator != null && variableDeclarator.getInitializer() == ternary; From 82999bc7f574174158b6352258a4ac1f3319a585 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sat, 29 Nov 2025 17:04:56 +0100 Subject: [PATCH 1723/1962] [java] Fix #6291: EnumComparison FP when comparing with null --- .../pmd/lang/java/types/TypeTestUtil.java | 3 +++ .../pmd/lang/java/types/TypeTestUtilTest.java | 22 +++++++++++++++++++ .../rule/bestpractices/xml/EnumComparison.xml | 19 ++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeTestUtil.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeTestUtil.java index 285e6911ba4..bf468eed77b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeTestUtil.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeTestUtil.java @@ -159,6 +159,9 @@ public static boolean isA(@Nullable JTypeMirror t1, @NonNull JTypeMirror t2) { } } return false; + } else if (t2.isBottom()) { + // null type should only be considered subtype of top and itself. + return t1.isTop() || t1.isBottom(); } return t2.isSubtypeOf(t1); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/TypeTestUtilTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/TypeTestUtilTest.java index c9ef03c5e6f..2644384e342 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/TypeTestUtilTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/types/TypeTestUtilTest.java @@ -24,6 +24,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTClassDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTEnumDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTNullLiteral; import net.sourceforge.pmd.lang.java.ast.ASTType; import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration; import net.sourceforge.pmd.lang.java.ast.TypeNode; @@ -278,6 +279,27 @@ void testNullClass() { assertThrows(NullPointerException.class, () -> TypeTestUtil.isExactlyA((String) null, node)); } + + @Test + void testNullLiteralIsNotAnyType() { + final ASTNullLiteral node = java.parse("class Foo {{ Integer i = null; }}") + .descendants(ASTNullLiteral.class).firstOrThrow(); + assertNotNull(node); + + assertTrue(TypeTestUtil.isA(node.getTypeSystem().NULL_TYPE, node), "null literal matches the null type"); + // assertTrue(TypeTestUtil.isExactlyA(node.getTypeSystem().NULL_TYPE, node), "null literal matches the null type exactly"); + + assertTrue(TypeTestUtil.isA(Object.class, node), "null is considered subtype of Object"); + assertFalse(TypeTestUtil.isExactlyA(Object.class, node), "null is not considered an instance of Object"); + + assertFalse(TypeTestUtil.isA(Integer.class, node), "null is not considered a subtype of a more specific type"); + assertFalse(TypeTestUtil.isExactlyA(Integer.class, node), "null is not considered an instance of a more specific type"); + + // overloads with name + assertFalse(TypeTestUtil.isA(Integer.class.getName(), node), "null is not considered a subtype of a more specific type"); + assertFalse(TypeTestUtil.isExactlyA(Integer.class.getName(), node), "null is not considered an instance of a more specific type"); + } + private void assertIsA(TypeNode node, Class type) { assertIsA(node, type, false, true); } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/EnumComparison.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/EnumComparison.xml index 89b2cd19393..9cab2b94ae9 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/EnumComparison.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/EnumComparison.xml @@ -81,6 +81,25 @@ class Foo { if (x == y) {} } } +]]> + + + + Equals null + 1 + 8-8 + \ No newline at end of file From a966a69aa4a707dc57f0b43e91fc3929963cdb53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sat, 29 Nov 2025 19:04:54 +0100 Subject: [PATCH 1724/1962] Fix problem, improve logging of type inf --- .../types/internal/infer/ExprCheckHelper.java | 10 +++++++-- .../java/types/internal/infer/ExprOps.java | 22 +++++++++---------- .../internal/infer/TypeInferenceLogger.java | 20 ++++++++++++++++- .../infer/UnresolvedTypesRecoveryTest.kt | 20 +++++++++++++++++ 4 files changed, 58 insertions(+), 14 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java index 94d25ed1183..ca4aa101e24 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java @@ -391,9 +391,15 @@ private boolean isMethodRefCompatible(@NonNull JClassType functionalItf, MethodR // to resolve input vars before resolving the constraint: // https://docs.oracle.com/javase/specs/jls/se12/html/jls-18.html#jls-18.5.2.2 - // here we defer the check until the variables are ground + Set inputIvars = infCtx.freeVarsIn(fun.getFormalParameters()); + // The free vars of the return type depend on the free vars of the parameters. + // This explicit dependency is there to prevent solving the variables in the + // return type before solving those of the parameters. That is because the variables + // mentioned in the return type may be further constrained by adding the return constraints + // below (in the listener), which is only triggered when the input ivars have been instantiated. + infCtx.addInstantiationDependencies(infCtx.freeVarsIn(fun.getReturnType()), inputIvars); infCtx.addInstantiationListener( - infCtx.freeVarsIn(fun.getFormalParameters()), + inputIvars, solvedCtx -> solveInexactMethodRefCompatibility(mref, solvedCtx.ground(nonWildcard), solvedCtx.ground(fun)) ); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java index f6fb719b45f..7e0077535a8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java @@ -129,8 +129,8 @@ boolean isPotentiallyCompatible(JMethodSig m, ExprMirror e, JTypeMirror t) { private boolean hasCandidate(MethodRefMirror mref, JMethodSig fun, boolean firstParamIsReceiver, boolean expectStatic) { InvocationMirror asMethodCall = methodRefAsInvocation(mref, fun, firstParamIsReceiver); for (JMethodSig cand : asMethodCall.getAccessibleCandidates()) { - if (infer.isPotentiallyApplicable(cand, asMethodCall) - && cand.isStatic() == expectStatic) { + if (cand.isStatic() == expectStatic + && infer.isPotentiallyApplicable(cand, asMethodCall)) { return true; } } @@ -297,8 +297,8 @@ static boolean isPertinentToApplicability(ExprMirror arg, JMethodSig m, JTypeMir boolean acceptLowerArity = lhsIfType != null && lhsIfType.isClassOrInterface() && !mref.isConstructorRef(); MethodCallSite site1 = infer.newCallSite(methodRefAsInvocation(mref, targetType, false), null); - site1.setLogging(!acceptLowerArity); // if we do only one search, then failure matters - MethodCtDecl ctd1 = infer.determineInvocationTypeOrFail(site1); + site1.setLogging(!acceptLowerArity); + MethodCtDecl ctd1 = infer.LOG.inContext("Method ref ctdectl search 1 (static) ", () -> infer.determineInvocationTypeOrFail(site1)); JMethodSig m1 = ctd1.getMethodType(); if (acceptLowerArity) { @@ -306,8 +306,8 @@ static boolean isPertinentToApplicability(ExprMirror arg, JMethodSig m, JTypeMir // one with n-1, looking for instance methods MethodCallSite site2 = infer.newCallSite(methodRefAsInvocation(mref, targetType, true), null); - site2.setLogging(false); - MethodCtDecl ctd2 = infer.determineInvocationTypeOrFail(site2); + site1.setLogging(false); + MethodCtDecl ctd2 = infer.LOG.inContext("Method ref ctdectl search 2 (instance) ", () -> infer.determineInvocationTypeOrFail(site2)); JMethodSig m2 = ctd2.getMethodType(); // If the first search produces a most specific method that is static, @@ -545,11 +545,11 @@ private static boolean canUseInstanceMethods(JTypeMirror typeToSearch, JMethodSi // The type to search is Objects. But Objects inherits Object.toString(), // which could not be called on a string (String.toString() != Objects.toString()). - if (mref.getLhsIfType() != null && !sig.getFormalParameters().isEmpty()) { - // ReferenceType :: [TypeArguments] Identifier - JTypeMirror firstFormal = sig.getFormalParameters().get(0); - return firstFormal.isSubtypeOf(typeToSearch); - } + // if (mref.getLhsIfType() != null && !sig.getFormalParameters().isEmpty()) { + // // ReferenceType :: [TypeArguments] Identifier + // JTypeMirror firstFormal = sig.getFormalParameters().get(0); + // return firstFormal.isSubtypeOf(typeToSearch); + // } return true; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java index 05c85855c13..b8575517c2d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/TypeInferenceLogger.java @@ -13,6 +13,7 @@ import java.util.Iterator; import java.util.List; import java.util.Set; +import java.util.function.Supplier; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -107,6 +108,11 @@ default void ivarInstantiated(InferenceContext ctx, InferenceVar var, JTypeMirro default void ivarDependencyRegistered(InferenceContext ctx, InferenceVar var, Set deps) { } + // Context management + + default T inContext(String st, Supplier action) { + return action.get(); + } /** * Log that the instantiation of the method type m for the given @@ -205,7 +211,7 @@ protected void addIndentSegment(String segment) { protected void removeIndentSegment(String segment) { assert indent.endsWith(segment) : "mismatched end section!"; - indent = StringUtils.removeEnd(indent, segment); + indent = indent.substring(0, indent.length() - segment.length()); } protected void setIndent(String indent) { @@ -221,6 +227,18 @@ protected void println(String str) { out.println(str); } + @Override + public T inContext(String st, Supplier action) { + String indent = "โ”‚ "; + println("START " + st); + addIndentSegment(indent); + try { + return action.get(); + } finally { + removeIndentSegment(indent); + println("โ”” END " + st); + } + } protected void endSection(String footer) { removeIndentSegment(BASE_INDENT); diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt index d9024f8f34a..bab58499091 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/UnresolvedTypesRecoveryTest.kt @@ -982,4 +982,24 @@ class C { debugCall.qualifier!! shouldHaveType ts.ERROR } } + parserTest("Failure with method ref") { + val (acu, spy) = parser.logTypeInferenceVerbose().parseWithTypeInferenceSpy( + """ + import java.util.List; + import java.util.stream.Collectors; + public class Foo { + static { + List.of("a", "b").stream().collect(Collectors.toMap(String::toUpperCase, _ -> "NO_DATA")); + } + } + """.trimIndent() + ) + + + val (collect, _, _, toMap) = acu.methodCalls().crossFindBoundaries().toList() + + acu.withTypeDsl { + collect shouldHaveType java.util.Map::class[ts.STRING, ts.STRING] + } + } }) From ad9b0e06a96c0bf3aabe8e229c1f79948fb21826 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Sat, 29 Nov 2025 16:26:14 +0100 Subject: [PATCH 1725/1962] Handle guard statement separately --- .../table/internal/SymbolTableResolver.java | 10 ++++++--- .../bestpractices/xml/UnusedLocalVariable.xml | 22 ++++++++++++++++++- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java index 85b8f14f33a..e36cdb34676 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java @@ -40,6 +40,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTForStatement; import net.sourceforge.pmd.lang.java.ast.ASTForeachStatement; +import net.sourceforge.pmd.lang.java.ast.ASTGuard; import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTInfixExpression; @@ -385,14 +386,17 @@ private Void visitSwitch(ASTSwitchLike node, @NonNull ReferenceCtx ctx) { for (ASTSwitchBranch branch : node.getBranches()) { ASTSwitchLabel label = branch.getLabel(); - // collect all bindings. Maybe it's illegal to use composite label with bindings, idk - BindSet bindings = - label.descendants(ASTPattern.class) + // Collect all bindings. Composite label with bindings would be a compilation error. + BindSet bindings = label.children(ASTPattern.class) .reduce(BindSet.EMPTY, (bindSet, pat) -> bindSet.union(bindersOfPattern(pat))); // visit guarded patterns in label int pushBindings = pushOnStack(f.localVarSymTable(top(), enclosing(), bindings.getTrueBindings())); setTopSymbolTableAndVisit(label, ctx); + bindings = label.children(ASTGuard.class).reduce(BindSet.EMPTY, + (bindSet, pat) -> bindSet.union(bindersOfExpr(pat.getGuard()))); + + pushBindings += pushOnStack(f.localVarSymTable(top(), enclosing(), bindings.getTrueBindings())); if (branch instanceof ASTSwitchArrowBranch) { pushed = pushBindings; diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml index 93de7c331ff..75fae9aa729 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml @@ -715,10 +715,11 @@ class Foo { java 22 - pattern with guard + pattern with guard #6257 0 fooString.equals(barString); @@ -729,4 +730,23 @@ class Foo { ]]> java 21 + + pattern with negative guard #6257 + 1 + + Avoid unused local variables such as 'barString'. + + fooString.equals(barString); + default -> false; + }; + } + } + ]]> + java 21 + From 18da69c6b8110e3373b056ec4e354f53d5b8a563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 1 Dec 2025 11:27:13 +0100 Subject: [PATCH 1726/1962] Fix actual problem --- .../java/types/internal/infer/ExprOps.java | 39 +++++++------------ .../internal/infer/MethodRefInferenceTest.kt | 3 +- .../java/types/dumptests/UnnamedPatterns.txt | 6 +-- 3 files changed, 17 insertions(+), 31 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java index 7e0077535a8..b8ab14e3436 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java @@ -8,7 +8,6 @@ import static net.sourceforge.pmd.lang.java.types.internal.InternalMethodTypeItf.cast; import static net.sourceforge.pmd.util.CollectionUtil.listOf; -import java.lang.reflect.Modifier; import java.util.Collections; import java.util.List; import java.util.function.Predicate; @@ -298,17 +297,23 @@ static boolean isPertinentToApplicability(ExprMirror arg, JMethodSig m, JTypeMir MethodCallSite site1 = infer.newCallSite(methodRefAsInvocation(mref, targetType, false), null); site1.setLogging(!acceptLowerArity); - MethodCtDecl ctd1 = infer.LOG.inContext("Method ref ctdectl search 1 (static) ", () -> infer.determineInvocationTypeOrFail(site1)); + MethodCtDecl ctd1 = infer.LOG.inContext("Method ref ctdectl search 1 (static) ", () -> infer.determineInvocationTypeOrFail(site1)); JMethodSig m1 = ctd1.getMethodType(); - if (acceptLowerArity) { + if (lhsIfType != null && !mref.isConstructorRef()) { // then we need to perform two searches, one with arity n, looking for static methods, // one with n-1, looking for instance methods - MethodCallSite site2 = infer.newCallSite(methodRefAsInvocation(mref, targetType, true), null); - site1.setLogging(false); - MethodCtDecl ctd2 = infer.LOG.inContext("Method ref ctdectl search 2 (instance) ", () -> infer.determineInvocationTypeOrFail(site2)); - JMethodSig m2 = ctd2.getMethodType(); + MethodCtDecl ctd2 = null; + JMethodSig m2 = ts.UNRESOLVED_METHOD; + if (!targetType.getFormalParameters().isEmpty() + && targetType.getFormalParameters().get(0).isSubtypeOf(lhsIfType)) { + // todo prevent this to add constraints to variables in the target type? + MethodCallSite site2 = infer.newCallSite(methodRefAsInvocation(mref, targetType, true), null); + site1.setLogging(false); + ctd2 = infer.LOG.inContext("Method ref ctdectl search 2 (instance) ", () -> infer.determineInvocationTypeOrFail(site2)); + m2 = ctd2.getMethodType(); + } // If the first search produces a most specific method that is static, // and the set of applicable methods produced by the second search @@ -529,29 +534,11 @@ private static Iterable getAccessibleCandidates(MethodRefMirror mref // TypeName.super :: [TypeArguments] Identifier // ReferenceType :: [TypeArguments] Identifier - boolean acceptsInstanceMethods = canUseInstanceMethods(actualTypeToSearch, targetType, mref); - - Predicate prefilter = TypeOps.accessibleMethodFilter(mref.getMethodName(), mref.getEnclosingType().getSymbol()) - .and(m -> Modifier.isStatic(m.getModifiers()) - || acceptsInstanceMethods); + Predicate prefilter = TypeOps.accessibleMethodFilter(mref.getMethodName(), mref.getEnclosingType().getSymbol()); return actualTypeToSearch.streamMethods(prefilter).collect(Collectors.toList()); } } - private static boolean canUseInstanceMethods(JTypeMirror typeToSearch, JMethodSig sig, MethodRefMirror mref) { - // For example, if you write - // stringStream.map(Objects::toString), - - // The type to search is Objects. But Objects inherits Object.toString(), - // which could not be called on a string (String.toString() != Objects.toString()). - - // if (mref.getLhsIfType() != null && !sig.getFormalParameters().isEmpty()) { - // // ReferenceType :: [TypeArguments] Identifier - // JTypeMirror firstFormal = sig.getFormalParameters().get(0); - // return firstFormal.isSubtypeOf(typeToSearch); - // } - return true; - } /** diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/MethodRefInferenceTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/MethodRefInferenceTest.kt index ef10cf77df8..940c138c9b7 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/MethodRefInferenceTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/MethodRefInferenceTest.kt @@ -329,12 +329,11 @@ class MethodRefInferenceTest : ProcessorTestSpec({ """.trimIndent() ) - val t_Archive = acu.firstTypeSignature() val mref = acu.descendants(ASTMethodReference::class.java).firstOrThrow() val (getName) = acu.declaredMethodSignatures().toList() val call = acu.firstMethodCall() - spy.shouldHaveMissingCtDecl(call) + spy.shouldHaveNoApplicableMethods(call) acu.withTypeDsl { mref.referencedMethod shouldBe getName diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/UnnamedPatterns.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/UnnamedPatterns.txt index a836b86a283..6e8a55d7526 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/UnnamedPatterns.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/types/dumptests/UnnamedPatterns.txt @@ -583,7 +583,7 @@ | +- ArgumentList[] | +- StringLiteral[@TypeMirror = "java.lang.String"] +- ExpressionStatement[] - +- MethodCall[@Failed = false, @Function = "java.util.stream.Stream. collect(java.util.stream.Collector>) -> java.util.Map", @MethodName = "collect", @TypeMirror = "java.util.Map", @Unchecked = false, @VarargsCall = false] + +- MethodCall[@Failed = false, @Function = "java.util.stream.Stream. collect(java.util.stream.Collector>) -> java.util.Map", @MethodName = "collect", @TypeMirror = "java.util.Map", @Unchecked = false, @VarargsCall = false] +- MethodCall[@Failed = false, @Function = "java.util.Collection.stream() -> java.util.stream.Stream", @MethodName = "stream", @TypeMirror = "java.util.stream.Stream", @Unchecked = false, @VarargsCall = false] | +- MethodCall[@Failed = false, @Function = "java.util.List. of(java.lang.String, java.lang.String) -> java.util.List", @MethodName = "of", @TypeMirror = "java.util.List", @Unchecked = false, @VarargsCall = false] | | +- TypeExpression[@TypeMirror = "java.util.List"] @@ -593,11 +593,11 @@ | | +- StringLiteral[@TypeMirror = "java.lang.String"] | +- ArgumentList[] +- ArgumentList[] - +- MethodCall[@Failed = false, @Function = "java.util.stream.Collectors. toMap(java.util.function.Function, java.util.function.Function) -> java.util.stream.Collector>", @MethodName = "toMap", @TypeMirror = "java.util.stream.Collector>", @Unchecked = false, @VarargsCall = false] + +- MethodCall[@Failed = false, @Function = "java.util.stream.Collectors. toMap(java.util.function.Function, java.util.function.Function) -> java.util.stream.Collector>", @MethodName = "toMap", @TypeMirror = "java.util.stream.Collector>", @Unchecked = false, @VarargsCall = false] +- TypeExpression[@TypeMirror = "java.util.stream.Collectors"] | +- ClassType[@TypeMirror = "java.util.stream.Collectors"] +- ArgumentList[] - +- MethodReference[@TypeMirror = "java.util.function.Function"] + +- MethodReference[@TypeMirror = "java.util.function.Function"] | +- TypeExpression[@TypeMirror = "java.lang.String"] | +- ClassType[@TypeMirror = "java.lang.String"] +- LambdaExpression[@TypeMirror = "java.util.function.Function"] From 5fb64171ce9dba2c2dc877f26c52543fe2e807d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 1 Dec 2025 11:44:45 +0100 Subject: [PATCH 1727/1962] [java] Fix #6237 - error in UnnecessaryCast rule Improve ExprContext to determine properly when a lambda return expression has context-dependent type. --- .../rule/codestyle/UnnecessaryCastRule.java | 100 +---------- .../java/types/ast/internal/InvocCtx.java | 12 ++ .../types/ast/internal/PolyResolution.java | 163 ++++++++++++++---- .../rule/codestyle/xml/UnnecessaryCast.xml | 24 +++ 4 files changed, 173 insertions(+), 126 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java index a3733264b61..b5577bee37d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java @@ -15,10 +15,6 @@ import static net.sourceforge.pmd.lang.java.ast.BinaryOp.SHIFT_OPS; import static net.sourceforge.pmd.lang.java.ast.BinaryOp.SUB; import static net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils.isInfixExprWithOperator; -import static net.sourceforge.pmd.util.OptionalBool.NO; -import static net.sourceforge.pmd.util.OptionalBool.UNKNOWN; -import static net.sourceforge.pmd.util.OptionalBool.YES; -import static net.sourceforge.pmd.util.OptionalBool.definitely; import java.util.EnumSet; import java.util.Set; @@ -35,17 +31,13 @@ import net.sourceforge.pmd.lang.java.ast.ASTMethodReference; import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement; import net.sourceforge.pmd.lang.java.ast.BinaryOp; -import net.sourceforge.pmd.lang.java.ast.InvocationNode; import net.sourceforge.pmd.lang.java.ast.JavaNode; import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; import net.sourceforge.pmd.lang.java.ast.internal.PrettyPrintingUtil; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; -import net.sourceforge.pmd.lang.java.symbols.JExecutableSymbol; -import net.sourceforge.pmd.lang.java.types.JClassType; import net.sourceforge.pmd.lang.java.types.JMethodSig; import net.sourceforge.pmd.lang.java.types.JTypeMirror; import net.sourceforge.pmd.lang.java.types.JTypeVar; -import net.sourceforge.pmd.lang.java.types.OverloadSelectionResult; import net.sourceforge.pmd.lang.java.types.Substitution; import net.sourceforge.pmd.lang.java.types.TypeConversion; import net.sourceforge.pmd.lang.java.types.TypeOps; @@ -53,7 +45,6 @@ import net.sourceforge.pmd.lang.java.types.TypeTestUtil; import net.sourceforge.pmd.lang.java.types.ast.ExprContext; import net.sourceforge.pmd.lang.java.types.ast.ExprContext.ExprContextKind; -import net.sourceforge.pmd.util.OptionalBool; /** * Detects casts where the operand is already a subtype of the context @@ -140,20 +131,18 @@ private boolean isTypeExpression(JTypeMirror type) { } private boolean isCastUnnecessary(ASTCastExpression castExpr, @NonNull ExprContext context, JTypeMirror coercionType, JTypeMirror operandType) { - if (isCastDeterminingReturnOfLambda(castExpr) != NO) { - return false; - } - if (operandType.equals(coercionType)) { - // with the exception of the lambda thing above, casts to - // the same type are always unnecessary return true; } else if (context.isMissing()) { // then we have fewer violation conditions return !operandType.isBottom() // casts on a null literal are necessary - && operandType.isSubtypeOf(coercionType) - && !isCastToRawType(coercionType, operandType); + && operandType.isSubtypeOf(coercionType) + && !isCastToRawType(coercionType, operandType) + // If the context is missing when the parent is a lambda, + // that means the body of the lambda is determining the return + // type of the lambda + && getLambdaParent(castExpr) == null; } return !isCastDeterminingContext(castExpr, context, coercionType, operandType) @@ -245,83 +234,6 @@ private static boolean isCastDeterminingContext(ASTCastExpression castExpr, Expr return false; } - private static OptionalBool isCastDeterminingReturnOfLambda(ASTCastExpression castExpr) { - ASTLambdaExpression lambda = getLambdaParent(castExpr); - if (lambda == null) { - return NO; - } - - // The necessary conditions are: - // - The lambda return type mentions type vars that are missing from its arguments - // (lambda is context dependent) - // - The lambda type is inferred: - // 1. its context is missing, or - // 2. it is invocation and the parent method call - // a. is inferred (generic + no explicit arguments) - // b. mentions some of its type params in the argument type corresponding to the lambda - - JExecutableSymbol symbol = lambda.getFunctionalMethod().getSymbol(); - if (symbol.isUnresolved()) { - return UNKNOWN; - } - - // Note we don't test the functional method directly, because it has been instantiated - // We test its generic signature (the symbol). - boolean contextDependent = TypeOps.isContextDependent(symbol); - if (!contextDependent) { - return NO; - } - - ExprContext lambdaCtx = lambda.getConversionContext(); - if (lambdaCtx.isMissing()) { - return YES; - } else if (lambdaCtx.hasKind(ExprContextKind.CAST)) { - return NO; - } else if (lambdaCtx.hasKind(ExprContextKind.INVOCATION)) { - InvocationNode parentCall = (InvocationNode) lambda.getParent().getParent(); - if (parentCall.getExplicitTypeArguments() != null) { - return NO; - } - OverloadSelectionResult overload = parentCall.getOverloadSelectionInfo(); - if (overload.isFailed()) { - return UNKNOWN; - } - JMethodSig parentMethod = overload.getMethodType(); - if (!parentMethod.getSymbol().isGeneric()) { - return NO; - } - - int argIdx = lambda.getIndexInParent(); - JMethodSig genericSig = parentMethod.getSymbol().getGenericSignature(); - // this is the generic lambda ty as mentioned in the formal parameters - JTypeMirror genericLambdaTy = genericSig.ithFormalParam(argIdx, overload.isVarargsCall()); - if (!(genericLambdaTy instanceof JClassType)) { - return NO; - } - // Note that we don't capture this type, which may make the method type malformed (eg mentioning a wildcard - // as return type). We need these bare wildcards for "mentionsAny" to work properly. - // The "correct" approach here to remove wildcards would be to infer the ground non-wildcard parameterization - // of the lambda but this is pretty deep inside the inference code and not readily usable. - JClassType lambdaTyCapture = (JClassType) genericLambdaTy; - - // This is the method signature of the lambda, given the formal parameter type of the parent call. - // The formal type is not instantiated, it may contain type variables of the parent method... - JMethodSig expectedLambdaMethod = genericLambdaTy.getTypeSystem().sigOf( - lambda.getFunctionalMethod().getSymbol(), - lambdaTyCapture.getTypeParamSubst() - ); - // but if the return type does not contain such tvars, then the parent method type does - // not depend on the lambda type :) - return definitely( - TypeOps.mentionsAny( - expectedLambdaMethod.getReturnType(), - parentMethod.getTypeParameters() - ) - ); - } - return UNKNOWN; - } - private static @Nullable ASTLambdaExpression getLambdaParent(ASTCastExpression castExpr) { if (castExpr.getParent() instanceof ASTLambdaExpression) { return (ASTLambdaExpression) castExpr.getParent(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/InvocCtx.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/InvocCtx.java index b6dcc88eb4f..d3e6eb3d7f0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/InvocCtx.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/InvocCtx.java @@ -9,6 +9,8 @@ import org.checkerframework.checker.nullness.qual.Nullable; import net.sourceforge.pmd.lang.java.ast.InvocationNode; +import net.sourceforge.pmd.lang.java.symbols.JExecutableSymbol; +import net.sourceforge.pmd.lang.java.types.JMethodSig; import net.sourceforge.pmd.lang.java.types.JTypeMirror; import net.sourceforge.pmd.lang.java.types.OverloadSelectionResult; import net.sourceforge.pmd.lang.java.types.ast.ExprContext; @@ -34,6 +36,16 @@ public InvocCtx(int arg, InvocationNode node) { return overload.ithFormalParam(arg); } + @Nullable JTypeMirror getTargetTypeOfSymbol() { + OverloadSelectionResult overload = node.getOverloadSelectionInfo(); + if (overload.isFailed()) { + return null; + } + JExecutableSymbol symbol = overload.getMethodType().getSymbol(); + JMethodSig genericMethod = symbol.getGenericSignature(); + return genericMethod.ithFormalParam(arg, overload.isVarargsCall()); + } + @Override public boolean isMissing() { return false; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/PolyResolution.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/PolyResolution.java index 99cc53a44cf..dc7266d2e20 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/PolyResolution.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/PolyResolution.java @@ -14,6 +14,10 @@ import static net.sourceforge.pmd.util.AssertionUtil.shouldNotReachHere; import static net.sourceforge.pmd.util.CollectionUtil.all; import static net.sourceforge.pmd.util.CollectionUtil.map; +import static net.sourceforge.pmd.util.OptionalBool.NO; +import static net.sourceforge.pmd.util.OptionalBool.UNKNOWN; +import static net.sourceforge.pmd.util.OptionalBool.YES; +import static net.sourceforge.pmd.util.OptionalBool.definitely; import java.util.EnumMap; import java.util.List; @@ -55,6 +59,7 @@ import net.sourceforge.pmd.lang.java.ast.JavaNode; import net.sourceforge.pmd.lang.java.ast.TypeNode; import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; +import net.sourceforge.pmd.lang.java.symbols.JExecutableSymbol; import net.sourceforge.pmd.lang.java.types.JClassType; import net.sourceforge.pmd.lang.java.types.JMethodSig; import net.sourceforge.pmd.lang.java.types.JPrimitiveType; @@ -75,7 +80,7 @@ import net.sourceforge.pmd.lang.java.types.internal.infer.MethodCallSite; import net.sourceforge.pmd.lang.java.types.internal.infer.PolySite; import net.sourceforge.pmd.lang.java.types.internal.infer.ast.JavaExprMirrors; -import net.sourceforge.pmd.util.AssertionUtil; +import net.sourceforge.pmd.util.OptionalBool; /** * Routines to handle context around poly expressions. @@ -185,7 +190,7 @@ private JTypeMirror polyTypeOtherCtx(TypeNode e, ExprContext ctx) { List branches = ((ASTSwitchExpression) e).getYieldExpressions().toList(TypeNode::getTypeMirror); return computeStandaloneConditionalType(ts, branches); } else { - throw AssertionUtil.shouldNotReachHere("ConditionalMirrorImpl returns non-null for conditionals: " + e); + throw shouldNotReachHere("ConditionalMirrorImpl returns non-null for conditionals: " + e); } } return ts.ERROR; @@ -369,25 +374,6 @@ ExprContext getTopLevelConversionContext(TypeNode e) { return contextOf(e, false, true); } - private static @Nullable JTypeMirror returnTargetType(ASTReturnStatement context) { - JavaNode methodDecl = JavaAstUtils.getReturnTarget(context); - - if (methodDecl instanceof ASTLambdaExpression) { - // return within a lambda - // "assignment context", deferred to lambda inference - JMethodSig fun = ((ASTLambdaExpression) methodDecl).getFunctionalMethod(); - return fun == null ? null : fun.getReturnType(); - } else if (methodDecl instanceof ASTMethodDeclaration) { - @NonNull ASTType resultType = ((ASTMethodDeclaration) methodDecl).getResultTypeNode(); - return resultType instanceof ASTVoidType ? null // (this is an error) - : resultType.getTypeMirror(); - } - // Return within ctor or initializer or the like, - // return with value is disallowed. This is an error. - return null; - } - - /** * Returns the node on which the type of the given node depends. * This addresses the fact that poly expressions depend on their @@ -484,7 +470,7 @@ ExprContext getTopLevelConversionContext(TypeNode e) { } else if (papa instanceof ASTReturnStatement) { - return newAssignmentCtx(returnTargetType((ASTReturnStatement) papa)); + return newAssignmentCtx(returnTargetType((ASTReturnStatement) papa, internalUse)); } else if (papa instanceof ASTVariableDeclarator @@ -518,7 +504,7 @@ ExprContext getTopLevelConversionContext(TypeNode e) { return ExprContext.getMissingInstance(); } - // more detailed + // more detailed, only for external use private ExprContext conversionContextOf(JavaNode node, JavaNode papa) { if (papa instanceof ASTArrayAccess && node.getIndexInParent() == 1) { @@ -533,15 +519,8 @@ private ExprContext conversionContextOf(JavaNode node, JavaNode papa) { } else if (papa instanceof ASTLambdaExpression && node.getIndexInParent() == 1) { // lambda expression body - - JMethodSig fun = ((ASTLambdaExpression) papa).getFunctionalMethod(); - if (fun == null || TypeOps.isContextDependent(fun.getSymbol())) { - // Missing context, because the expression type itself - // is used to infer the context type. - return ExprContext.getMissingInstance(); - } - return newAssignmentCtx(fun.getReturnType()); - + JTypeMirror ty = getContextTypeOfLambdaReturnExpr((ASTLambdaExpression) papa, false); + return ty == null ? ExprContext.getMissingInstance() : newAssignmentCtx(ty); } else if (papa instanceof ASTIfStatement || papa instanceof ASTLoopStatement && !(papa instanceof ASTForeachStatement)) { @@ -640,6 +619,126 @@ private ExprContext conversionContextOf(JavaNode node, JavaNode papa) { } } + private @Nullable JTypeMirror returnTargetType(ASTReturnStatement context, boolean internalUse) { + JavaNode returnTarget = JavaAstUtils.getReturnTarget(context); + + if (returnTarget instanceof ASTLambdaExpression) { + // return within a lambda + // "assignment context", deferred to lambda inference + return getContextTypeOfLambdaReturnExpr((ASTLambdaExpression) returnTarget, internalUse); + } else if (returnTarget instanceof ASTMethodDeclaration) { + @NonNull ASTType resultType = ((ASTMethodDeclaration) returnTarget).getResultTypeNode(); + return resultType instanceof ASTVoidType ? null // (this is an error) + : resultType.getTypeMirror(); + } + // Return within ctor or initializer or the like, + // return with value is disallowed. This is an error. + return null; + } + + private @Nullable JTypeMirror getContextTypeOfLambdaReturnExpr(ASTLambdaExpression papa, boolean internalUse) { + JMethodSig fun = papa.getFunctionalMethod(); + // If we're in "internal use" mode, then we cannot call isLambdaReturnExprInDependentContext + // because that would trigger overload resolution of the parent invocation if any. + if (fun == null || !internalUse && isLambdaReturnExprInDependentContext(papa) != NO) { + return null; + } + + // This is the target type for the lambda, as given by + // the generic method declaration. For instance if the + // lambda appears in `foo(() -> X)`: + // - if `foo` has signature ` foo(Supplier)`, then this is `Supplier`. + // This means the lambda's return expression type is used in the type inference of + // `foo`, in which case we return a missing context. + // - if `foo` has signature `foo(Supplier)`, then this is Supplier. + // This means the lambda's return expression type is NOT used in the type inference of + // `foo`, as it is known to be Long. In this case we return an assignment context. + return fun.getReturnType(); + } + + + private OptionalBool isLambdaReturnExprInDependentContext(ASTLambdaExpression lambda) { + // The necessary conditions are: + // - The lambda return type mentions type vars that are missing from its arguments + // (lambda is context dependent) + // - The lambda type is inferred: + // 1. its context is missing, or + // 2. it is invocation and the parent method call + // a. is inferred (generic + no explicit arguments) + // b. mentions some of its type params in the argument type corresponding to the lambda + + JExecutableSymbol symbol = lambda.getFunctionalMethod().getSymbol(); + if (symbol.isUnresolved()) { + return UNKNOWN; + } + + // Note we don't test the functional method directly, because it has been instantiated + // We test its generic signature (the symbol). + boolean contextDependent = TypeOps.isContextDependent(symbol); + if (!contextDependent) { + return NO; + } + + ExprContext lambdaCtx = getConversionContextForExternalUse(lambda); + if (lambdaCtx.isMissing()) { + return YES; + } else if (lambdaCtx.hasKind(ExprContextKind.CAST)) { + return NO; + } else if (lambdaCtx.hasKind(ExprContextKind.INVOCATION)) { + // Note an invocation context does not mean the lambda's + // parent is an argument list. There may be branching (switch, + // ternary) exprs between the lambda and the invocation. + int argIdx = lambda.getIndexInParent(); + JavaNode parent = lambda.getParent(); + while (!(parent instanceof ASTArgumentList)) { + argIdx = parent.getIndexInParent(); + parent = parent.getParent(); + } + + InvocationNode parentCall = (InvocationNode) parent.getParent(); + if (parentCall.getExplicitTypeArguments() != null) { + return NO; + } + OverloadSelectionResult overload = parentCall.getOverloadSelectionInfo(); + if (overload.isFailed()) { + return UNKNOWN; + } + JMethodSig parentMethod = overload.getMethodType(); + if (!parentMethod.getSymbol().isGeneric()) { + return NO; + } + + JMethodSig genericSig = parentMethod.getSymbol().getGenericSignature(); + // this is the generic lambda ty as mentioned in the formal parameters + JTypeMirror genericLambdaTy = genericSig.ithFormalParam(argIdx, overload.isVarargsCall()); + if (!(genericLambdaTy instanceof JClassType)) { + return NO; + } + // Note that we don't capture this type, which may make the method type malformed (eg mentioning a wildcard + // as return type). We need these bare wildcards for "mentionsAny" to work properly. + // The "correct" approach here to remove wildcards would be to infer the ground non-wildcard parameterization + // of the lambda but this is pretty deep inside the inference code and not readily usable. + JClassType lambdaTyCapture = (JClassType) genericLambdaTy; + + // This is the method signature of the lambda, given the formal parameter type of the parent call. + // The formal type is not instantiated, it may contain type variables of the parent method... + JMethodSig expectedLambdaMethod = genericLambdaTy.getTypeSystem().sigOf( + lambda.getFunctionalMethod().getSymbol(), + lambdaTyCapture.getTypeParamSubst() + ); + // but if the return type does not contain such tvars, then the parent method type does + // not depend on the lambda type :) + return definitely( + TypeOps.mentionsAny( + expectedLambdaMethod.getReturnType(), + parentMethod.getTypeParameters() + ) + ); + } + return UNKNOWN; + } + + /** * Identifies a node that can forward an invocation/assignment context diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml index 9474939c7f7..1cf9ea2b154 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryCast.xml @@ -1175,5 +1175,29 @@ class Tester { } ]]> + + #6237 Error with lambdas in switch expr + 1 + 6 + () -> (long) 1; // this is necessary int -> long -> Long + case 1 -> () -> (long) 2L; // this is unnecessary long -> long -> Long + default -> throw new Error(); + } + ); + } + void foo(Supplier sup) { + // intentionally empty + } + } + interface Supplier { + T get(); + } + ]]> + From 80eb10b35af6b16412aa56a8a3cfc270ffe68709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 1 Dec 2025 15:42:33 +0100 Subject: [PATCH 1728/1962] Surface whether there are overloads in OverloadSelectionInfo --- .../java/types/OverloadSelectionResult.java | 9 +++++++++ .../types/ast/internal/PolyResolution.java | 8 ++++++++ .../types/internal/infer/ExprCheckHelper.java | 2 +- .../java/types/internal/infer/ExprMirror.java | 20 +++++++++++++++---- .../lang/java/types/internal/infer/Infer.java | 17 +++++++++------- .../types/internal/infer/OverloadSet.java | 14 +++++++++++++ 6 files changed, 58 insertions(+), 12 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java index b9094c898bf..927ee989e18 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java @@ -102,4 +102,13 @@ default JTypeMirror ithFormalParam(int i) { */ @Experimental @Nullable JTypeMirror getTypeToSearch(); + + + /** + * Return whether several overloads were applicable, and needed to + * be disambiguated through specificity checks. + */ + @Experimental + boolean hadSeveralApplicableOverloads(); + } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/PolyResolution.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/PolyResolution.java index dc7266d2e20..1654adee9c6 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/PolyResolution.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/internal/PolyResolution.java @@ -703,6 +703,14 @@ private OptionalBool isLambdaReturnExprInDependentContext(ASTLambdaExpression la if (overload.isFailed()) { return UNKNOWN; } + + // If the overload selection had to pick between several applicable overloads + // then we reply yes. This is an approximation that should avoid FPs in rules that + // use the context. + if (overload.hadSeveralApplicableOverloads()) { + return UNKNOWN; // maybe + } + JMethodSig parentMethod = overload.getMethodType(); if (!parentMethod.getSymbol().isGeneric()) { return NO; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java index 94d25ed1183..ccbd267bcbf 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java @@ -493,7 +493,7 @@ private void completeMethodRefInference(MethodRefMirror mref, JClassType groundT } MethodCtDecl mrefSigAsCtDecl(JMethodSig sig) { - return new MethodCtDecl(sig, MethodResolutionPhase.INVOC_LOOSE, false, OptionalBool.UNKNOWN, false, null); + return new MethodCtDecl(sig, MethodResolutionPhase.INVOC_LOOSE, false, OptionalBool.UNKNOWN, false, null, false); } MethodCtDecl inferMethodRefInvocation(MethodRefMirror mref, JMethodSig targetType, MethodCtDecl ctdecl) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java index 61af4b3e773..4fc9dd43db5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprMirror.java @@ -521,19 +521,22 @@ class MethodCtDecl implements OverloadSelectionResult { private final OptionalBool needsUncheckedConversion; private final boolean failed; private final @Nullable MethodUsageMirror expr; + private final boolean neededSpecificityCheck; MethodCtDecl(JMethodSig methodType, MethodResolutionPhase resolvePhase, boolean canSkipInvocation, OptionalBool needsUncheckedConversion, boolean failed, - @Nullable MethodUsageMirror expr) { + @Nullable MethodUsageMirror expr, + boolean neededSpecificityCheck) { this.methodType = methodType; this.resolvePhase = resolvePhase; this.canSkipInvocation = canSkipInvocation; this.needsUncheckedConversion = needsUncheckedConversion; this.failed = failed; this.expr = expr; + this.neededSpecificityCheck = neededSpecificityCheck; } // package-private: @@ -542,12 +545,16 @@ public MethodCtDecl withMethod(JMethodSig method) { return withMethod(method, failed); } + MethodCtDecl neededSpecificityCheck(boolean needed) { + return new MethodCtDecl(methodType, resolvePhase, canSkipInvocation, needsUncheckedConversion, failed, expr, needed); + } + MethodCtDecl withMethod(JMethodSig method, boolean failed) { - return new MethodCtDecl(method, resolvePhase, canSkipInvocation, needsUncheckedConversion, failed, expr); + return new MethodCtDecl(method, resolvePhase, canSkipInvocation, needsUncheckedConversion, failed, expr, neededSpecificityCheck); } public MethodCtDecl withExpr(MethodUsageMirror expr) { - return new MethodCtDecl(methodType, resolvePhase, canSkipInvocation, needsUncheckedConversion, failed, expr); + return new MethodCtDecl(methodType, resolvePhase, canSkipInvocation, needsUncheckedConversion, failed, expr, neededSpecificityCheck); } MethodCtDecl asFailed() { @@ -563,7 +570,7 @@ MethodResolutionPhase getResolvePhase() { } static MethodCtDecl unresolved(TypeSystem ts) { - return new MethodCtDecl(ts.UNRESOLVED_METHOD, STRICT, true, OptionalBool.UNKNOWN, true, null); + return new MethodCtDecl(ts.UNRESOLVED_METHOD, STRICT, true, OptionalBool.UNKNOWN, true, null, false); } // public: @@ -598,6 +605,11 @@ public String toString() { public @Nullable JTypeMirror getTypeToSearch() { return expr != null ? expr.getTypeToSearch() : null; } + + @Override + public boolean hadSeveralApplicableOverloads() { + return neededSpecificityCheck; + } } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java index 2c2d38e0ad0..0949ae5a8ad 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java @@ -325,7 +325,7 @@ private JMethodSig deleteTypeParams(JMethodSig m) { MethodCtDecl bestApplicable = applicable.getMostSpecificOrLogAmbiguity(LOG); JMethodSig adapted = ExprOps.adaptGetClass(bestApplicable.getMethodType(), site.getExpr()::getErasedReceiverType); - return bestApplicable.withMethod(adapted); + return bestApplicable.withMethod(adapted).neededSpecificityCheck(applicable.threwAwaySomeOverloads()); } } @@ -380,12 +380,15 @@ private boolean assertReturnIsGround(JMethodSig t) { if (candidate == null) { return FAILED_INVOCATION; } else { - return new MethodCtDecl(candidate, - phase, - site.canSkipInvocation(), - OptionalBool.definitely(site.needsUncheckedConversion()), - false, - site.getExpr()); + return new MethodCtDecl( + candidate, + phase, + site.canSkipInvocation(), + OptionalBool.definitely(site.needsUncheckedConversion()), + false, + site.getExpr(), + false + ); } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadSet.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadSet.java index 71f69452803..7619f6b2b89 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadSet.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadSet.java @@ -25,6 +25,7 @@ import net.sourceforge.pmd.lang.java.types.JClassType; import net.sourceforge.pmd.lang.java.types.JMethodSig; import net.sourceforge.pmd.lang.java.types.JTypeMirror; +import net.sourceforge.pmd.lang.java.types.OverloadSelectionResult; import net.sourceforge.pmd.lang.java.types.TypeOps; import net.sourceforge.pmd.util.OptionalBool; @@ -35,6 +36,13 @@ public abstract class OverloadSet { private final List overloads = new ArrayList<>(); + /** + * Whether several signatures were added, and some of them were + * thrown out because they were less specific than others. This + * is used to surface whether a call needed disambiguating between + * several applicable overloads in {@link OverloadSelectionResult#hadSeveralApplicableOverloads()}. + */ + private boolean threwAwaySomeOverloads; OverloadSet() { // package-private @@ -48,10 +56,12 @@ void add(T sig) { switch (shouldTakePrecedence(existing, sig)) { case YES: // new sig is less specific than an existing one, don't add it + threwAwaySomeOverloads = true; return; case NO: // new sig is more specific than an existing one iterator.remove(); + threwAwaySomeOverloads = true; break; case UNKNOWN: // neither sig is more specific @@ -71,6 +81,10 @@ boolean nonEmpty() { return !overloads.isEmpty(); } + boolean threwAwaySomeOverloads() { + return threwAwaySomeOverloads; + } + /** * Returns a collector that can apply to a stream of method signatures, * and that collects them into a set of method, where none override one another. From c8f7fe17c3f3ad4ca20df0a6cc4aa85f37b7c8be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 1 Dec 2025 17:01:39 +0100 Subject: [PATCH 1729/1962] Add test for #1103 --- .../codestyle/xml/LocalVariableCouldBeFinal.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LocalVariableCouldBeFinal.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LocalVariableCouldBeFinal.xml index 86884b921a1..95181347dd0 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LocalVariableCouldBeFinal.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/LocalVariableCouldBeFinal.xml @@ -424,4 +424,20 @@ public class Test { } ]]> + + + Ensure lambda param not reported #1103 + 0 + { + System.out.println(i); + return; + }; + } + } + ]]> + From 406043b72f393cba750bfe14c4c0528d08624090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 1 Dec 2025 16:42:23 +0100 Subject: [PATCH 1730/1962] Fix #6028 - specificity bug --- .../internal/infer/PhaseOverloadSet.java | 4 +-- .../internal/infer/OverloadSpecificityTest.kt | 32 ++++++++++++++++++- .../types/internal/infer/OverridingTest.kt | 14 ++++---- .../bestpractices/xml/UnusedPrivateMethod.xml | 17 ++++++++++ 4 files changed, 58 insertions(+), 9 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/PhaseOverloadSet.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/PhaseOverloadSet.java index 16e81f85332..06b04cf30be 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/PhaseOverloadSet.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/PhaseOverloadSet.java @@ -158,7 +158,7 @@ private boolean doInfer(JMethodSig m1, JMethodSig m2) { } if (si.isSubtypeOf(ti)) { - return true; + continue; } else if (ti.isSubtypeOf(si)) { return false; } @@ -176,7 +176,7 @@ private boolean doInfer(JMethodSig m1, JMethodSig m2) { // the boxing/unboxing conversion, without widening // afterwards. if (stdExprTy.box().equals(si.box())) { - return true; + continue; } else if (stdExprTy.box().equals(ti.box())) { return false; } diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadSpecificityTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadSpecificityTest.kt index 838987cff15..ce6bda9c716 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadSpecificityTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/OverloadSpecificityTest.kt @@ -6,11 +6,11 @@ package net.sourceforge.pmd.lang.java.types.internal.infer import io.kotest.matchers.shouldBe -import net.sourceforge.pmd.lang.test.ast.shouldBe import net.sourceforge.pmd.lang.java.ast.* import net.sourceforge.pmd.lang.java.types.* import net.sourceforge.pmd.lang.java.types.TypeOps.areOverrideEquivalent import net.sourceforge.pmd.lang.java.types.testdata.Overloads +import net.sourceforge.pmd.lang.test.ast.shouldBe import net.sourceforge.pmd.util.OptionalBool import net.sourceforge.pmd.lang.java.types.internal.infer.OverloadSet.shouldAlwaysTakePrecedence as shouldTakePrecedence @@ -425,4 +425,34 @@ class Scratch { spy.shouldBeAmbiguous(stdM) spy.shouldBeAmbiguous(polyM) } + + parserTest("Test specificity between args with explicit cast") { + val (acu, spy) = parser.parseWithTypeInferenceSpy( + """ + interface Collection {} + interface Multiset extends Collection { } + public final class Scratch { + static Multiset addAllImpl( + Multiset self, Collection elements) { + return addAllImpl(self, (Multiset) elements); + } + + private static Multiset addAllImpl( + Multiset self, Multiset elements) { + } + } + """.trimIndent() + ) + + + val (_, multiSetTy) = acu.declaredTypeSignatures() + val (addAllImpl) = acu.methodCalls().toList() + val (_, multisetMethod) = acu.declaredMethodSignatures() + + spy.shouldBeOk { + addAllImpl.methodType shouldBeSomeInstantiationOf multisetMethod + // since unchecked conversion is necessary the return type is erased + addAllImpl.typeMirror shouldBe multiSetTy.erasure + } + } }) diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/OverridingTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/OverridingTest.kt index c883e0d29e9..9510e058b65 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/OverridingTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/types/internal/infer/OverridingTest.kt @@ -7,7 +7,7 @@ package net.sourceforge.pmd.lang.java.types.internal.infer import io.kotest.matchers.shouldBe -import net.sourceforge.pmd.lang.java.ast.* +import net.sourceforge.pmd.lang.java.ast.ProcessorTestSpec import net.sourceforge.pmd.lang.java.types.* import net.sourceforge.pmd.util.OptionalBool import kotlin.test.assertFalse @@ -194,9 +194,12 @@ class Sub extends Sup { class F { { - // Well it is ambiguous, though a nice compiler - // wouldn't say it is, and rather consider the method hidden, - // and report an error on the declaration of Sub + // This is not ambiguous, as Sub.m is more specific than Sup.m. + // However, it is illegal to write the declaration of Sub.m above, + // because it has the same erasure as Sup.m but doesn't override + // it. If both `m` methods are placed in unrelated classes and then + // static imported, the method call is resolved to Sub.m through + // specificity rules. Sub.m(new F>()); } } @@ -205,7 +208,6 @@ class F { val (supE, subE) = acu.declaredMethodSignatures() - // their type parameters have a different bound // technically this is a compile-time error: // both methods have the same erasure but neither hides the other @@ -213,7 +215,7 @@ class F { TypeOps.overrides(subE, supE, subE.declaringType) } - spy.shouldBeAmbiguous(acu.firstMethodCall()) + spy.shouldHaveNoErrors() acu.firstMethodCall().methodType shouldBeSomeInstantiationOf subE } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml index 66008bee943..1a8e2587d65 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedPrivateMethod.xml @@ -2780,6 +2780,23 @@ class Foo { ]]> + + #6028 FP with raw type + 0 + {} + public final class addAllImpl { + private static abstract class Multiset extends Collection { } + static boolean addAllImpl( + Multiset self, Collection elements) { + return addAllImpl(self, (Multiset) elements); + } + private static boolean addAllImpl( + Multiset self, Multiset elements) { + } + } + ]]> + From ec5a99c21d6fd6433979a74e76bf3501478ef45a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 1 Dec 2025 17:56:40 +0100 Subject: [PATCH 1731/1962] Add test in symtable test file --- .../table/internal/PatternVarScopingTests.kt | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/PatternVarScopingTests.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/PatternVarScopingTests.kt index ee3bd999e41..937de97cf8f 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/PatternVarScopingTests.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/symbols/table/internal/PatternVarScopingTests.kt @@ -6,11 +6,12 @@ package net.sourceforge.pmd.lang.java.symbols.table.internal import io.kotest.assertions.withClue import io.kotest.matchers.collections.shouldBeSingleton -import io.kotest.matchers.collections.shouldMatchEach import net.sourceforge.pmd.lang.java.ast.* import net.sourceforge.pmd.lang.java.ast.JavaVersion.Companion.since import net.sourceforge.pmd.lang.java.ast.JavaVersion.J17 import net.sourceforge.pmd.lang.java.ast.JavaVersion.J22 +import net.sourceforge.pmd.lang.java.symbols.JFieldSymbol +import net.sourceforge.pmd.lang.java.symbols.JLocalVariableSymbol import net.sourceforge.pmd.lang.java.types.* import net.sourceforge.pmd.lang.test.ast.shouldBe import net.sourceforge.pmd.lang.test.ast.shouldBeA @@ -363,6 +364,41 @@ class PatternVarScopingTests : ProcessorTestSpec({ } } + doTest("Guarded branches in switch") { + val switch = parser.parse( + """ + class Foo { + int cs; + Object foo(Object foo) { + return switch (foo) { + case char[] array when array.length > 0 -> 44; + case String string when foo instanceof CharSequence cs -> cs; // cs in scope + case String string when !(foo instanceof CharSequence cs) -> cs; // cs refers to field + default -> throw new RuntimeException(); + }; + } + } + """ + ).descendants(ASTSwitchExpression::class.java).firstOrThrow() + + switch.withTypeDsl { + switch.varAccesses("array").shouldBeSingleton { + it shouldHaveType char.toArray() + } + val (cs1, cs2) = switch.varAccesses("cs").toList() + cs1.referencedSym.shouldBeA() + cs1 shouldHaveType java.lang.CharSequence::class.decl + + cs2.referencedSym.shouldBeA() + cs2 shouldHaveType int + + switch.varAccesses("foo").forEach { + it.referencedSym.shouldBeA() + it shouldHaveType ts.OBJECT + } + } + } + doTest("Record tests") { val acu = parser.parse( """ From 325825b80d331f6b4f641be2c0e225238ec10538 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 1 Dec 2025 18:07:27 +0100 Subject: [PATCH 1732/1962] Cleanup: there is at most one guard --- .../pmd/lang/java/ast/ASTSwitchLabel.java | 21 ++++++++++++++++--- .../table/internal/PatternBindingsUtil.java | 13 ++++++++---- .../table/internal/SymbolTableResolver.java | 6 ++---- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabel.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabel.java index 93491bf09bc..c1c54bd93ba 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabel.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabel.java @@ -6,6 +6,8 @@ import java.util.Iterator; +import org.checkerframework.checker.nullness.qual.Nullable; + import net.sourceforge.pmd.lang.ast.NodeStream; @@ -18,7 +20,7 @@ * * SwitchLabel ::= "case" {@linkplain ASTExpression Expression} ("," {@linkplain ASTExpression Expression} )* * | "case" "null [ "," "default" ] - * | "case" ( {@linkplain ASTTypePattern TypePattern} | {@linkplain ASTRecordPattern RecordPattern} ) + * | "case" {@linkplain ASTPattern Pattern} ("," {@linkplain ASTPattern Pattern} )* [ {@linkplain ASTGuard Guard} ] * | "default" * * @@ -42,8 +44,10 @@ void setDefault() { isDefault = true; } - /** Returns true if this is the {@code default} label. */ - // todo `case default` + /** + * Returns true if this is the {@code default} label. + * This also returns true if this is the variant {@code case null, default}. + */ public boolean isDefault() { return isDefault; } @@ -58,6 +62,17 @@ public NodeStream getExprList() { return children(ASTExpression.class); } + /** Return the guard expression for this branch if there is one. */ + public @Nullable ASTExpression getGuardExpression() { + ASTGuard guard = getGuard(); + return guard == null ? null : guard.getGuard(); + } + + public @Nullable ASTGuard getGuard() { + JavaNode last = getLastChild(); + return last instanceof ASTGuard ? (ASTGuard) last : null; + } + @Override protected R acceptVisitor(JavaVisitor visitor, P data) { return visitor.visit(this, data); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/PatternBindingsUtil.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/PatternBindingsUtil.java index 1a5ab9f5c1e..d970fdbd0d4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/PatternBindingsUtil.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/PatternBindingsUtil.java @@ -4,6 +4,7 @@ package net.sourceforge.pmd.lang.java.symbols.table.internal; +import org.checkerframework.checker.nullness.qual.Nullable; import org.pcollections.HashTreePSet; import org.pcollections.PSet; @@ -37,7 +38,7 @@ private PatternBindingsUtil() { * of expression does not contribute anything (meaning, all subexpressions * are not processed). */ - static BindSet bindersOfExpr(ASTExpression e) { + static BindSet bindersOfExpr(@Nullable ASTExpression e) { /* JLS 17ยง6.3.1 If an expression is not a conditional-and expression, conditional-or @@ -45,8 +46,9 @@ static BindSet bindersOfExpr(ASTExpression e) { instanceof expression, switch expression, or parenthesized expression, then no scope rules apply. */ - - if (e instanceof ASTUnaryExpression) { + if (e == null) { + return BindSet.EMPTY; + } else if (e instanceof ASTUnaryExpression) { ASTUnaryExpression unary = (ASTUnaryExpression) e; return unary.getOperator() == UnaryOp.NEGATION ? bindersOfExpr(unary.getOperand()).negate() @@ -88,7 +90,10 @@ static BindSet bindersOfExpr(ASTExpression e) { return BindSet.EMPTY; } - static BindSet bindersOfPattern(ASTPattern pattern) { + static BindSet bindersOfPattern(@Nullable ASTPattern pattern) { + if (pattern == null) { + return BindSet.EMPTY; + } if (pattern instanceof ASTTypePattern) { if (!((ASTTypePattern) pattern).getVarId().isUnnamed()) { return BindSet.whenTrue(HashTreePSet.singleton(((ASTTypePattern) pattern).getVarId())); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java index b084a384375..e78844bfa8d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java @@ -40,7 +40,6 @@ import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTForStatement; import net.sourceforge.pmd.lang.java.ast.ASTForeachStatement; -import net.sourceforge.pmd.lang.java.ast.ASTGuard; import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTInfixExpression; @@ -400,9 +399,8 @@ private Void visitSwitch(ASTSwitchLike node, @NonNull ReferenceCtx ctx) { // visit guarded patterns in label int pushBindings = pushOnStack(f.localVarSymTable(top(), enclosing(), bindings.getTrueBindings())); - setTopSymbolTableAndVisit(label, ctx); - bindings = label.children(ASTGuard.class).reduce(BindSet.EMPTY, - (bindSet, pat) -> bindSet.union(bindersOfExpr(pat.getGuard()))); + setTopSymbolTableAndVisit(label.getGuard(), ctx); + bindings = bindersOfExpr(label.getGuardExpression()); pushBindings += pushOnStack(f.localVarSymTable(top(), enclosing(), bindings.getTrueBindings())); From 208d531e94a5fd9068d8b7a23f2c2f3ac6b87d47 Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Mon, 1 Dec 2025 19:29:22 +0100 Subject: [PATCH 1733/1962] Refactor: Check an additional ancestor for guard methods --- .../bestpractices/GuardLogStatementRule.java | 45 +++++++++++-------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/GuardLogStatementRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/GuardLogStatementRule.java index 85311d48761..7bfb5257ddf 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/GuardLogStatementRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/GuardLogStatementRule.java @@ -133,28 +133,13 @@ private boolean needsGuard(ASTMethodCall node) { } private boolean hasGuard(ASTMethodCall node, String logLevel) { - ASTIfStatement ifStatement = node.ancestors(ASTIfStatement.class).first(); - if (ifStatement == null) { - return false; - } - - for (ASTMethodCall maybeAGuardCall : ifStatement.getCondition().descendantsOrSelf().filterIs(ASTMethodCall.class)) { - String guardMethodName = maybeAGuardCall.getMethodName(); - // the guard is adapted to the actual log statement - - if (!guardStmtByLogLevel.get(logLevel).contains(guardMethodName)) { - continue; + for (ASTIfStatement ifStatement: node.ancestors(ASTIfStatement.class).take(2)) { + if (ifStatement == null) { + return false; } - - if (JAVA_UTIL_LOG_GUARD_METHOD.equals(guardMethodName)) { - // java.util.logging: guard method with argument. Verify the log level - if (logLevel.equals(getJutilLogLevelInFirstArg(maybeAGuardCall))) { - return true; - } - } else { + if (containsGuardMethod(ifStatement, logLevel)) { return true; } - } return false; } @@ -264,4 +249,26 @@ private void buildGuardStatementMap(List logLevels, List guardMe } } } + + private boolean containsGuardMethod(ASTIfStatement ifStatement, String logLevel) { + for (ASTMethodCall maybeAGuardCall : ifStatement.getCondition().descendantsOrSelf().filterIs(ASTMethodCall.class)) { + String guardMethodName = maybeAGuardCall.getMethodName(); + // the guard is adapted to the actual log statement + + if (!guardStmtByLogLevel.get(logLevel).contains(guardMethodName)) { + continue; + } + + if (JAVA_UTIL_LOG_GUARD_METHOD.equals(guardMethodName)) { + // java.util.logging: guard method with argument. Verify the log level + if (logLevel.equals(getJutilLogLevelInFirstArg(maybeAGuardCall))) { + return true; + } + } else { + return true; + } + + } + return false; + } } From 5a48aef29cd4dc1ae4bf2fbf43439a83951df8c6 Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Mon, 1 Dec 2025 19:34:14 +0100 Subject: [PATCH 1734/1962] Test: Check an extra ancestor for guard methods --- .../bestpractices/xml/GuardLogStatement.xml | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/GuardLogStatement.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/GuardLogStatement.xml index 4c00360f382..a3c7cbfbc69 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/GuardLogStatement.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/GuardLogStatement.xml @@ -809,4 +809,28 @@ public class MyLogger { } ]]> + + + #4282 GuardLogStatement only detects guard methods immediately around it + 0 + + From 791096973fd207d27e73123fc5b4dd54a9aa2300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 2 Dec 2025 10:49:44 +0100 Subject: [PATCH 1735/1962] Update release notes, ref #6262 --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..aae6ad90a95 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -26,6 +26,9 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿ›๏ธ Fixed Issues +- java-bestpractices + - [#6257](https://github.com/pmd/pmd/issues/6257): \[java] UnusedLocalVariable: False positive with instanceof pattern guard + ### ๐Ÿšจ๏ธ API Changes ### โœจ๏ธ Merged pull requests From fb0dcb322f673a209a522304c1a370e90c3ca77c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 2 Dec 2025 13:51:06 +0100 Subject: [PATCH 1736/1962] [java] Fix grammar of switch label Add tests for switch labels, --- .../pmd/lang/java/ast/ASTSwitchLabel.java | 8 + .../pmd/lang/java/ast/ASTSwitchLike.java | 10 ++ pmd-java/src/main/javacc/Java.jjt | 34 ++-- ...Test.java => ASTSwitchExhaustiveTest.java} | 2 +- .../pmd/lang/java/ast/ASTSwitchLabelTest.kt | 168 ++++++++++++++++++ .../pmd/lang/java/ast/TestExtensions.kt | 35 +++- 6 files changed, 231 insertions(+), 26 deletions(-) rename pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/{ASTSwitchLabelTest.java => ASTSwitchExhaustiveTest.java} (98%) create mode 100644 pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabelTest.kt diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabel.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabel.java index c1c54bd93ba..386cc9d163f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabel.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabel.java @@ -52,6 +52,13 @@ public boolean isDefault() { return isDefault; } + /** + * Returns true if this is the label {@code case null} or {@code case null, default}. + */ + public boolean isCaseNull() { + return getFirstChild() instanceof ASTNullLiteral; + } + /** * Returns the expressions of this label, or an empty list if this * is the default label. This does neither contain {@linkplain ASTTypePattern TypePatterns} @@ -62,6 +69,7 @@ public NodeStream getExprList() { return children(ASTExpression.class); } + /** Return the guard expression for this branch if there is one. */ public @Nullable ASTExpression getGuardExpression() { ASTGuard guard = getGuard(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLike.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLike.java index b7cd1c98751..96299bee7be 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLike.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLike.java @@ -171,4 +171,14 @@ default boolean isFallthroughSwitch() { return getBranches().filterIs(ASTSwitchFallthroughBranch.class).nonEmpty(); } + /** + * Return true if this switch accepts null. This must be explicitly + * declared in a branch which matches {@link ASTSwitchLabel#isCaseNull()}. + * Any switch that does not have this branch throws NullPointerException + * at runtime if the scrutinee is null. + * This is a feature of Java 25. + */ + default boolean isNullTolerant() { + return getBranches().map(ASTSwitchBranch::getLabel).any(ASTSwitchLabel::isCaseNull); + } } diff --git a/pmd-java/src/main/javacc/Java.jjt b/pmd-java/src/main/javacc/Java.jjt index e87a27bb73d..444bf2062a7 100644 --- a/pmd-java/src/main/javacc/Java.jjt +++ b/pmd-java/src/main/javacc/Java.jjt @@ -1,4 +1,9 @@ /** + * Fix grammar of switch labels and switch guards. At most one guard is + * allowed, guards are only allowed on pattern branches, several patterns + * are allowed. + * Clรฉment Fournier 12/2025 + *==================================================================== * Removed support for String Templates, introduced in Java 21 / 22 Preview * Andreas Dangel 01/2025 *==================================================================== @@ -2555,40 +2560,23 @@ void SwitchFallthroughBranch(): (LOOKAHEAD({shouldStartStatementInSwitch()}) BlockStatement() )* } +// https://docs.oracle.com/javase/specs/jls/se25/html/jls-14.html#jls-SwitchLabel void SwitchLabel() : {} { { inSwitchLabel = true; } ( - "case" CaseLabelElement(jjtThis) ( "," CaseLabelElement(jjtThis) )* + "case" ( + "null" #NullLiteral [ "," "default" {jjtThis.setDefault();} ] + | LOOKAHEAD(Pattern()) Pattern() ("," Pattern())* [ LOOKAHEAD({isKeyword("when")}) Guard() ] + | ConditionalExpression() ("," ConditionalExpression())* + ) | "default" {jjtThis.setDefault();} ) { inSwitchLabel = false; } } -void CaseLabelElement(ASTSwitchLabel label) #void: -{} -{ - "null" #NullLiteral [ "," "default" {label.setDefault();} ] - | - LOOKAHEAD(Pattern()) CasePattern() [ LOOKAHEAD({isKeyword("when")}) Guard() ] - | - CaseConstant() -} - -void CaseConstant() #void: -{} -{ - ConditionalExpression() -} - -void CasePattern() #void: -{} -{ - Pattern() -} - void Guard() : {} { diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabelTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchExhaustiveTest.java similarity index 98% rename from pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabelTest.java rename to pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchExhaustiveTest.java index acc67d902f3..4b8ced914b4 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabelTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchExhaustiveTest.java @@ -15,7 +15,7 @@ import net.sourceforge.pmd.lang.java.BaseParserTest; import net.sourceforge.pmd.lang.java.JavaParsingHelper; -class ASTSwitchLabelTest extends BaseParserTest { +class ASTSwitchExhaustiveTest extends BaseParserTest { private final JavaParsingHelper java = JavaParsingHelper.DEFAULT; diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabelTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabelTest.kt new file mode 100644 index 00000000000..9e4521891f2 --- /dev/null +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabelTest.kt @@ -0,0 +1,168 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.ast + +import io.kotest.matchers.shouldBe +import net.sourceforge.pmd.lang.test.ast.shouldBe + +/** + * @author Clรฉment Fournier + */ +class ASTSwitchLabelTest : ProcessorTestSpec({ + + parserTestContainer("Different label forms") { + inContext(ExpressionParsingCtx) { + """ + switch (x) { + default: y = 2; + case null, default: y = 3; + case null: y = 4; + case 4: break; + case 4, 6, a?b:c : break; + } + """.trimIndent() should parseAs { + switchExpr { + it::hasDefaultCase shouldBe true + it::isExhaustiveEnumSwitch shouldBe false + + variableAccess("x") + switchFallthrough { + switchDefaultLabel() + exprStatement() + } + switchFallthrough { + switchNullLabel(isDefault = true) + exprStatement() + } + switchFallthrough { + switchNullLabel(isDefault = false) + exprStatement() + } + switchFallthrough { + switchLabel { + int(4) + } + breakStatement() + } + switchFallthrough { + switchLabel { + it::isPatternLabel shouldBe false + it::getGuard shouldBe null + int(4) + int(6) + ternaryExpr() + } + breakStatement() + } + } + } + } + } + + parserTestContainer("Guards and patterns") { + inContext(ExpressionParsingCtx) { + """ + switch (x) { + case Integer i, Label _: + case Label _: + case Record(int _): + case Integer i when i != 0: + } + """.trimIndent() should parseAs { + switchExpr { + it::hasDefaultCase shouldBe false + it::isExhaustiveEnumSwitch shouldBe false + + variableAccess("x") + switchFallthrough { + switchLabel { + it.exprList.toList() shouldBe emptyList() + it::isPatternLabel shouldBe true + typePattern { + modifiers() + classType("Integer") + variableId("i") + } + typePattern { + modifiers() + classType("Label") + variableId("_") + } + } + } + switchFallthrough { + switchLabel { + it.exprList.toList() shouldBe emptyList() + it::isPatternLabel shouldBe true + typePattern { + modifiers() + classType("Label") + variableId("_") + } + } + } + switchFallthrough { + switchLabel { + it.exprList.toList() shouldBe emptyList() + it::isPatternLabel shouldBe true + + recordPattern("Record") + } + } + switchFallthrough { + switchLabel { + it.exprList.toList() shouldBe emptyList() + it::isPatternLabel shouldBe true + typePattern { + modifiers() + classType("Integer") + variableId("i") + } + it::getGuard shouldBe child { + it::getGuard shouldBe infixExpr(BinaryOp.NE) + } + } + } + + } + } + } + } + class SwitchLabelParsingContext(arrow: Boolean) : NodeParsingCtx("switch label") { + private val sep = if (arrow) " ->" else " :" + + override fun getTemplate(construct: String, ctx: ParserTestCtx): String = + ExpressionParsingCtx.getTemplate( + """ + switch (x) { + $construct $sep + } + """.trimIndent(), + ctx + ) + + override fun retrieveNode(acu: ASTCompilationUnit): ASTSwitchLabel = + ExpressionParsingCtx.retrieveNode(acu) + .let { it as ASTSwitchExpression } + .branches[0]!!.label!! + } + + parserTestContainer("Invalid syntax") { + inContext(SwitchLabelParsingContext(arrow = false)) { + "case Integer i, 4" shouldNot parse() + "case 4, Integer i" shouldNot parse() + "case null, null" shouldNot parse() + "case null, default, null" shouldNot parse() + "case default, null" shouldNot parse() + "case 4 when 4 == 2" shouldNot parse() + "case Integer i when 4 == 2, Boolean b when b" shouldNot parse() + "case Integer i when 4 == 2, Boolean b" shouldNot parse() + + "case Integer i when 4 == 2" should parse() + "case Integer i, Boolean b when b" should parse() + } + } + +}) diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/TestExtensions.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/TestExtensions.kt index 9a65387a01f..8c04d5875f2 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/TestExtensions.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/TestExtensions.kt @@ -343,9 +343,18 @@ fun TreeNodeWrapper.localVarDecl(contents: NodeSpec.localClassDecl(simpleName: String, contents: NodeSpec = EmptyAssertions) = - child { - it::getDeclaration shouldBe classDecl(simpleName, contents) + localTypeDecl(simpleName, contents) + +inline fun TreeNodeWrapper.localTypeDecl( + simpleName: String, + noinline contents: NodeSpec = EmptyAssertions +) = + child { + it::getDeclaration shouldBe child(ignoreChildren = contents == EmptyAssertions) { + it::getSimpleName shouldBe simpleName + contents() } + } fun TreeNodeWrapper.exprStatement(contents: ValuedNodeSpec = { null }) = child { @@ -416,6 +425,15 @@ fun TreeNodeWrapper.typePattern(contents: NodeSpec) = child(ignoreChildren = contents == EmptyAssertions) { contents() } +fun TreeNodeWrapper.recordPattern(simpleName: String, contents: NodeSpec = EmptyAssertions) = + child { + it::getTypeNode shouldBe classType(simpleName) + if (contents == EmptyAssertions) { + unspecifiedChild() + } else { + contents() + } + } fun TreeNodeWrapper.arrayType(contents: NodeSpec = EmptyAssertions) = @@ -600,12 +618,25 @@ fun TreeNodeWrapper.switchFallthrough(assertions: NodeSpec.switchLabel(assertions: NodeSpec = EmptyAssertions) = child(ignoreChildren = assertions == EmptyAssertions) { it::isDefault shouldBe false + it::isCaseNull shouldBe false assertions() } +fun TreeNodeWrapper.switchNullLabel( + isDefault: Boolean = false, + assertions: NodeSpec = EmptyAssertions +) = + child { + it::isDefault shouldBe isDefault + it::isCaseNull shouldBe true + it.exprList.toList() shouldBe listOf(nullLit()) + assertions() + } + fun TreeNodeWrapper.switchDefaultLabel(assertions: NodeSpec = EmptyAssertions) = child(ignoreChildren = assertions == EmptyAssertions) { it::isDefault shouldBe true + it::isCaseNull shouldBe false it.exprList.toList() shouldBe emptyList() assertions() } From 84a5f4271d4c71c54432c395eb71b1d406f275a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 2 Dec 2025 17:07:22 +0100 Subject: [PATCH 1737/1962] Update reference tests --- .../pmd/lang/java/ast/ParserCornerCases17.txt | 38 ++++----- .../pmd/lang/java/ast/SwitchStatements.txt | 14 ++-- .../lang/java/ast/SwitchWithFallthrough.txt | 6 +- .../java14/MultipleCaseLabels.txt | 10 +-- .../java14/SimpleSwitchExpressions.txt | 12 +-- .../java14/SwitchExpressions.txt | 54 ++++++------- .../jdkversiontests/java14/SwitchRules.txt | 12 +-- .../java14/YieldStatements.txt | 12 +-- .../ast/jdkversiontests/java15/TextBlocks.txt | 4 +- .../java21/DealingWithNull.txt | 58 +++++++------- .../java21/EnhancedTypeCheckingSwitch.txt | 14 ++-- .../java21/ExhaustiveSwitch.txt | 36 ++++----- .../java21/GuardedPatterns.txt | 22 ++--- .../java21/Jep440_RecordPatterns.txt | 4 +- .../Jep441_PatternMatchingForSwitch.txt | 80 +++++++++---------- .../java21/PatternsInSwitchLabels.txt | 12 +-- .../java21/RecordPatternsExhaustiveSwitch.txt | 22 ++--- .../java21/RefiningPatternsInSwitch.txt | 26 +++--- .../ScopeOfPatternVariableDeclarations.txt | 20 ++--- .../Jep456_UnnamedPatternsAndVariables.txt | 22 ++--- ...tiveTypesInPatternsInstanceofAndSwitch.txt | 64 +++++++-------- .../Jep492_FlexibleConstructorBodies.txt | 8 +- .../Jep513_FlexibleConstructorBodies.txt | 8 +- ...tiveTypesInPatternsInstanceofAndSwitch.txt | 64 +++++++-------- 24 files changed, 311 insertions(+), 311 deletions(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.txt index 9ec8a167ecd..28ab9026db2 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases17.txt @@ -102,44 +102,44 @@ | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.AND, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "instruction", @Name = "instruction", @ParenthesisDepth = 0, @Parenthesized = false] | | +- NumericLiteral[@Base = 2, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0b00001111", @IntLiteral = true, @Integral = true, @LiteralText = "0b00001111", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 15.0, @ValueAsFloat = 15.0, @ValueAsInt = 15, @ValueAsLong = 15] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true, @NullTolerant = false] | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.AND, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "instruction", @Name = "instruction", @ParenthesisDepth = 0, @Parenthesized = false] | | +- NumericLiteral[@Base = 2, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0b11110000", @IntLiteral = true, @Integral = true, @LiteralText = "0b11110000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 240.0, @ValueAsFloat = 240.0, @ValueAsInt = 240, @ValueAsLong = 240] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 2, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0b00000000", @IntLiteral = true, @Integral = true, @LiteralText = "0b00000000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 2, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0b00010000", @IntLiteral = true, @Integral = true, @LiteralText = "0b00010000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 16.0, @ValueAsFloat = 16.0, @ValueAsInt = 16, @ValueAsLong = 16] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 2, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0b00100000", @IntLiteral = true, @Integral = true, @LiteralText = "0b00100000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 32.0, @ValueAsFloat = 32.0, @ValueAsInt = 32, @ValueAsLong = 32] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 2, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0b00110000", @IntLiteral = true, @Integral = true, @LiteralText = "0b00110000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 48.0, @ValueAsFloat = 48.0, @ValueAsInt = 48, @ValueAsLong = 48] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 2, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0b01000000", @IntLiteral = true, @Integral = true, @LiteralText = "0b01000000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 64.0, @ValueAsFloat = 64.0, @ValueAsInt = 64, @ValueAsLong = 64] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 2, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0b01010000", @IntLiteral = true, @Integral = true, @LiteralText = "0b01010000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 80.0, @ValueAsFloat = 80.0, @ValueAsInt = 80, @ValueAsLong = 80] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 2, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0b01100000", @IntLiteral = true, @Integral = true, @LiteralText = "0b01100000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 96.0, @ValueAsFloat = 96.0, @ValueAsInt = 96, @ValueAsLong = 96] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 2, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0b01110000", @IntLiteral = true, @Integral = true, @LiteralText = "0b01110000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 112.0, @ValueAsFloat = 112.0, @ValueAsInt = 112, @ValueAsLong = 112] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | +- ThrowStatement[] | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "IllegalArgumentException"] @@ -255,10 +255,10 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] | | +- VariableDeclarator[@Initializer = false, @Name = "typeOfDay"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "typeOfDay", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true, @NullTolerant = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "dayOfWeekArg", @Name = "dayOfWeekArg", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Monday", @Empty = false, @Image = "\"Monday\"", @Length = 6, @LiteralText = "\"Monday\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- ExpressionStatement[] | | | | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] @@ -266,13 +266,13 @@ | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Start of work week", @Empty = false, @Image = "\"Start of work week\"", @Length = 18, @LiteralText = "\"Start of work week\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- BreakStatement[@Label = null] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Tuesday", @Empty = false, @Image = "\"Tuesday\"", @Length = 7, @LiteralText = "\"Tuesday\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Wednesday", @Empty = false, @Image = "\"Wednesday\"", @Length = 9, @LiteralText = "\"Wednesday\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Thursday", @Empty = false, @Image = "\"Thursday\"", @Length = 8, @LiteralText = "\"Thursday\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- ExpressionStatement[] | | | | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] @@ -280,7 +280,7 @@ | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Midweek", @Empty = false, @Image = "\"Midweek\"", @Length = 7, @LiteralText = "\"Midweek\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- BreakStatement[@Label = null] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Friday", @Empty = false, @Image = "\"Friday\"", @Length = 6, @LiteralText = "\"Friday\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- ExpressionStatement[] | | | | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] @@ -288,10 +288,10 @@ | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "End of work week", @Empty = false, @Image = "\"End of work week\"", @Length = 16, @LiteralText = "\"End of work week\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- BreakStatement[@Label = null] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Saturday", @Empty = false, @Image = "\"Saturday\"", @Length = 8, @LiteralText = "\"Saturday\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Sunday", @Empty = false, @Image = "\"Sunday\"", @Length = 6, @LiteralText = "\"Sunday\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- ExpressionStatement[] | | | | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] @@ -299,7 +299,7 @@ | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Weekend", @Empty = false, @Image = "\"Weekend\"", @Length = 7, @LiteralText = "\"Weekend\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- BreakStatement[@Label = null] | | +- SwitchFallthroughBranch[@Default = true] - | | +- SwitchLabel[@Default = true, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | | +- ThrowStatement[] | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "IllegalArgumentException"] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchStatements.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchStatements.txt index e9dd434478d..0ba9c93e84b 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchStatements.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchStatements.txt @@ -13,19 +13,19 @@ | +- VariableDeclarator[@Initializer = true, @Name = "a"] | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "a", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] - +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true, @NullTolerant = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "a", @Name = "a", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | +- SwitchFallthroughBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] - +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] + +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "a", @Name = "a", @ParenthesisDepth = 0, @Parenthesized = false] - +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true, @NullTolerant = false] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "a", @Name = "a", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchFallthroughBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | +- ExpressionStatement[] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] @@ -36,4 +36,4 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "1", @Empty = false, @Image = "\"1\"", @Length = 1, @LiteralText = "\"1\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- BreakStatement[@Label = null] +- SwitchFallthroughBranch[@Default = true] - +- SwitchLabel[@Default = true, @PatternLabel = false] + +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchWithFallthrough.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchWithFallthrough.txt index d61e7005f1b..6af74226f6c 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchWithFallthrough.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/SwitchWithFallthrough.txt @@ -13,10 +13,10 @@ | +- VariableDeclarator[@Initializer = true, @Name = "a"] | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "a", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] - +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true, @NullTolerant = false] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "a", @Name = "a", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchFallthroughBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] +- SwitchFallthroughBranch[@Default = true] - +- SwitchLabel[@Default = true, @PatternLabel = false] + +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/MultipleCaseLabels.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/MultipleCaseLabels.txt index 16a741f8340..cb381c86d2b 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/MultipleCaseLabels.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/MultipleCaseLabels.txt @@ -62,10 +62,10 @@ | +- VariableDeclarator[@Initializer = true, @Name = "day"] | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "day", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "THURSDAY", @Name = "THURSDAY", @ParenthesisDepth = 0, @Parenthesized = false] - +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true, @NullTolerant = false] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "day", @Name = "day", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchFallthroughBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "MONDAY", @Name = "MONDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "FRIDAY", @Name = "FRIDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "SUNDAY", @Name = "SUNDAY", @ParenthesisDepth = 0, @Parenthesized = false] @@ -78,7 +78,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = " 6", @Empty = false, @Image = "\" 6\"", @Length = 3, @LiteralText = "\" 6\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- BreakStatement[@Label = null] +- SwitchFallthroughBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "TUESDAY", @Name = "TUESDAY", @ParenthesisDepth = 0, @Parenthesized = false] | +- ExpressionStatement[] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] @@ -89,7 +89,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = " 7", @Empty = false, @Image = "\" 7\"", @Length = 3, @LiteralText = "\" 7\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- BreakStatement[@Label = null] +- SwitchFallthroughBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "THURSDAY", @Name = "THURSDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "SATURDAY", @Name = "SATURDAY", @ParenthesisDepth = 0, @Parenthesized = false] | +- ExpressionStatement[] @@ -101,7 +101,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = " 8", @Empty = false, @Image = "\" 8\"", @Length = 3, @LiteralText = "\" 8\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- BreakStatement[@Label = null] +- SwitchFallthroughBranch[@Default = false] - +- SwitchLabel[@Default = false, @PatternLabel = false] + +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "WEDNESDAY", @Name = "WEDNESDAY", @ParenthesisDepth = 0, @Parenthesized = false] +- ExpressionStatement[] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SimpleSwitchExpressions.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SimpleSwitchExpressions.txt index 261e68797dd..bec0cf752fb 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SimpleSwitchExpressions.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SimpleSwitchExpressions.txt @@ -66,29 +66,29 @@ | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | +- VariableDeclarator[@Initializer = true, @Name = "numLetters"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "numLetters", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "day", @Name = "day", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "MONDAY", @Name = "MONDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "FRIDAY", @Name = "FRIDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "SUNDAY", @Name = "SUNDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "6", @IntLiteral = true, @Integral = true, @LiteralText = "6", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 6.0, @ValueAsFloat = 6.0, @ValueAsInt = 6, @ValueAsLong = 6] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "TUESDAY", @Name = "TUESDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "7", @IntLiteral = true, @Integral = true, @LiteralText = "7", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 7.0, @ValueAsFloat = 7.0, @ValueAsInt = 7, @ValueAsLong = 7] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "THURSDAY", @Name = "THURSDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "SATURDAY", @Name = "SATURDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "8", @IntLiteral = true, @Integral = true, @LiteralText = "8", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 8.0, @ValueAsFloat = 8.0, @ValueAsInt = 8, @ValueAsLong = 8] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "WEDNESDAY", @Name = "WEDNESDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "9", @IntLiteral = true, @Integral = true, @LiteralText = "9", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 9.0, @ValueAsFloat = 9.0, @ValueAsInt = 9, @ValueAsLong = 9] | | +- SwitchArrowBranch[@Default = true] - | | +- SwitchLabel[@Default = true, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | | +- Block[@Empty = false, @Size = 3, @containsComment = false] | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchExpressions.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchExpressions.txt index dcc9b803bdc..1a3f5e2e6a9 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchExpressions.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchExpressions.txt @@ -52,10 +52,10 @@ | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "THURSDAY", @Name = "THURSDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Day"] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = true, @Exhaustive = true, @ExhaustiveEnumSwitch = true, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = true, @Exhaustive = true, @ExhaustiveEnumSwitch = true, @FallthroughSwitch = false, @NullTolerant = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "day", @Name = "day", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "MONDAY", @Name = "MONDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "FRIDAY", @Name = "FRIDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "SUNDAY", @Name = "SUNDAY", @ParenthesisDepth = 0, @Parenthesized = false] @@ -66,7 +66,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "6", @IntLiteral = true, @Integral = true, @LiteralText = "6", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 6.0, @ValueAsFloat = 6.0, @ValueAsInt = 6, @ValueAsLong = 6] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "TUESDAY", @Name = "TUESDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -75,7 +75,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "7", @IntLiteral = true, @Integral = true, @LiteralText = "7", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 7.0, @ValueAsFloat = 7.0, @ValueAsInt = 7, @ValueAsLong = 7] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "THURSDAY", @Name = "THURSDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "SATURDAY", @Name = "SATURDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] @@ -85,7 +85,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "8", @IntLiteral = true, @Integral = true, @LiteralText = "8", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 8.0, @ValueAsFloat = 8.0, @ValueAsInt = 8, @ValueAsLong = 8] | | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "WEDNESDAY", @Name = "WEDNESDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -98,25 +98,25 @@ | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] | | +- VariableDeclarator[@Initializer = true, @Name = "numLetters"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "numLetters", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = true, @Exhaustive = true, @ExhaustiveEnumSwitch = true, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = true, @Exhaustive = true, @ExhaustiveEnumSwitch = true, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "day", @Name = "day", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "MONDAY", @Name = "MONDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "FRIDAY", @Name = "FRIDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "SUNDAY", @Name = "SUNDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "6", @IntLiteral = true, @Integral = true, @LiteralText = "6", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 6.0, @ValueAsFloat = 6.0, @ValueAsInt = 6, @ValueAsLong = 6] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "TUESDAY", @Name = "TUESDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "7", @IntLiteral = true, @Integral = true, @LiteralText = "7", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 7.0, @ValueAsFloat = 7.0, @ValueAsInt = 7, @ValueAsLong = 7] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "THURSDAY", @Name = "THURSDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "SATURDAY", @Name = "SATURDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "8", @IntLiteral = true, @Integral = true, @LiteralText = "8", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 8.0, @ValueAsFloat = 8.0, @ValueAsInt = 8, @ValueAsLong = 8] | | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "WEDNESDAY", @Name = "WEDNESDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "9", @IntLiteral = true, @Integral = true, @LiteralText = "9", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 9.0, @ValueAsFloat = 9.0, @ValueAsInt = 9, @ValueAsLong = 9] | +- ExpressionStatement[] @@ -156,18 +156,18 @@ | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] | | +- VariableDeclarator[@Initializer = true, @Name = "j"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "j", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = true, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = true, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "day", @Name = "day", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "MONDAY", @Name = "MONDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "TUESDAY", @Name = "TUESDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | | +- SwitchArrowBranch[@Default = true] - | | +- SwitchLabel[@Default = true, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | | +- Block[@Empty = false, @Size = 3, @containsComment = false] | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] @@ -208,27 +208,27 @@ | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] | | +- VariableDeclarator[@Initializer = true, @Name = "result"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "result", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Foo", @Empty = false, @Image = "\"Foo\"", @Length = 3, @LiteralText = "\"Foo\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- YieldStatement[] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Bar", @Empty = false, @Image = "\"Bar\"", @Length = 3, @LiteralText = "\"Bar\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- YieldStatement[] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2", @IntLiteral = true, @Integral = true, @LiteralText = "2", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Baz", @Empty = false, @Image = "\"Baz\"", @Length = 3, @LiteralText = "\"Baz\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- YieldStatement[] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "BAZ", @Name = "BAZ", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "SwitchExpressions"] | | +- SwitchFallthroughBranch[@Default = true] - | | +- SwitchLabel[@Default = true, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | | +- ExpressionStatement[] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -255,10 +255,10 @@ | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "k", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "k", @Name = "k", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -267,7 +267,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "one", @Empty = false, @Image = "\"one\"", @Length = 3, @LiteralText = "\"one\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2", @IntLiteral = true, @Integral = true, @LiteralText = "2", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -276,7 +276,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "two", @Empty = false, @Image = "\"two\"", @Length = 3, @LiteralText = "\"two\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] @@ -298,18 +298,18 @@ | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] | +- ArgumentList[@Empty = false, @Size = 1] - | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "k", @Name = "k", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "one", @Empty = false, @Image = "\"one\"", @Length = 3, @LiteralText = "\"one\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2", @IntLiteral = true, @Integral = true, @LiteralText = "2", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "two", @Empty = false, @Image = "\"two\"", @Length = 3, @LiteralText = "\"two\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "many", @Empty = false, @Image = "\"many\"", @Length = 4, @LiteralText = "\"many\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] +- MethodDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PRIVATE, @Final = false, @Name = "f", @Overridden = false, @Static = true, @Varargs = false, @Visibility = Visibility.V_PRIVATE, @Void = false] +- ModifierList[@EffectiveModifiers = (JModifier.PRIVATE, JModifier.STATIC), @ExplicitModifiers = (JModifier.PRIVATE, JModifier.STATIC)] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchRules.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchRules.txt index 1f064e65db5..96b1907a945 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchRules.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/SwitchRules.txt @@ -62,10 +62,10 @@ | +- VariableDeclarator[@Initializer = true, @Name = "day"] | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "day", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "WEDNESDAY", @Name = "WEDNESDAY", @ParenthesisDepth = 0, @Parenthesized = false] - +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "day", @Name = "day", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "MONDAY", @Name = "MONDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "FRIDAY", @Name = "FRIDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "SUNDAY", @Name = "SUNDAY", @ParenthesisDepth = 0, @Parenthesized = false] @@ -76,7 +76,7 @@ | +- ArgumentList[@Empty = false, @Size = 1] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = " 6", @Empty = false, @Image = "\" 6\"", @Length = 3, @LiteralText = "\" 6\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "TUESDAY", @Name = "TUESDAY", @ParenthesisDepth = 0, @Parenthesized = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -85,7 +85,7 @@ | +- ArgumentList[@Empty = false, @Size = 1] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = " 7", @Empty = false, @Image = "\" 7\"", @Length = 3, @LiteralText = "\" 7\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "THURSDAY", @Name = "THURSDAY", @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "SATURDAY", @Name = "SATURDAY", @ParenthesisDepth = 0, @Parenthesized = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] @@ -95,7 +95,7 @@ | +- ArgumentList[@Empty = false, @Size = 1] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = " 8", @Empty = false, @Image = "\" 8\"", @Length = 3, @LiteralText = "\" 8\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "WEDNESDAY", @Name = "WEDNESDAY", @ParenthesisDepth = 0, @Parenthesized = false] | +- Block[@Empty = false, @Size = 1, @containsComment = false] | +- ExpressionStatement[] @@ -106,7 +106,7 @@ | +- ArgumentList[@Empty = false, @Size = 1] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = " 9", @Empty = false, @Image = "\" 9\"", @Length = 3, @LiteralText = "\" 9\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] +- SwitchArrowBranch[@Default = true] - +- SwitchLabel[@Default = true, @PatternLabel = false] + +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] +- ThrowStatement[] +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "IllegalArgumentException"] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.txt index 49226fc4f71..55dc0f1e625 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java14/YieldStatements.txt @@ -26,10 +26,10 @@ +- ExpressionStatement[] +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] +- VariableAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "yield", @Name = "yield", @ParenthesisDepth = 0, @Parenthesized = false] - +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "e", @Name = "e", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchArrowBranch[@Default = false] - +- SwitchLabel[@Default = false, @PatternLabel = false] + +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] +- Block[@Empty = false, @Size = 39, @containsComment = false] +- ExpressionStatement[] @@ -64,10 +64,10 @@ +- ExpressionStatement[] | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "yield", @Name = "yield", @ParenthesisDepth = 0, @Parenthesized = false] - | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "foo", @Name = "foo", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "4", @IntLiteral = true, @Integral = true, @LiteralText = "4", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 4.0, @ValueAsFloat = 4.0, @ValueAsInt = 4, @ValueAsLong = 4] | +- Block[@Empty = false, @Size = 1, @containsComment = false] | +- YieldStatement[] @@ -147,10 +147,10 @@ | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | +- ArgumentList[@Empty = true, @Size = 0] +- YieldStatement[] - | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "foo", @Name = "foo", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "4", @IntLiteral = true, @Integral = true, @LiteralText = "4", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 4.0, @ValueAsFloat = 4.0, @ValueAsInt = 4, @ValueAsLong = 4] +- YieldStatement[] | +- ThisExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/TextBlocks.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/TextBlocks.txt index 1c5c1002b7e..4d2a3628b21 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/TextBlocks.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/TextBlocks.txt @@ -195,10 +195,10 @@ +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] +- VariableDeclarator[@Initializer = true, @Name = "x"] +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "foo", @Name = "foo", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchArrowBranch[@Default = false] - +- SwitchLabel[@Default = false, @PatternLabel = false] + +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "a label\n", @Empty = false, @Image = "\"\"\"\n a label\n \"\"\"", @Length = 8, @LiteralText = "\"\"\"\n a label\n \"\"\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = true] +- Block[@Empty = false, @Size = 1, @containsComment = false] +- YieldStatement[] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/DealingWithNull.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/DealingWithNull.txt index feeaec8b249..e5df8d82f69 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/DealingWithNull.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/DealingWithNull.txt @@ -11,10 +11,10 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = true, @Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -23,7 +23,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Oops", @Empty = false, @Image = "\"Oops\"", @Length = 4, @LiteralText = "\"Oops\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Foo", @Empty = false, @Image = "\"Foo\"", @Length = 3, @LiteralText = "\"Foo\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Bar", @Empty = false, @Image = "\"Bar\"", @Length = 3, @LiteralText = "\"Bar\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] @@ -33,7 +33,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Great", @Empty = false, @Image = "\"Great\"", @Length = 5, @LiteralText = "\"Great\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] @@ -49,10 +49,10 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "o", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -66,7 +66,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "String: ", @Empty = false, @Image = "\"String: \"", @Length = 8, @LiteralText = "\"String: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = true, @Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -75,7 +75,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "null", @Empty = false, @Image = "\"null\"", @Length = 4, @LiteralText = "\"null\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] @@ -91,10 +91,10 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "o", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -108,7 +108,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "String: ", @Empty = false, @Image = "\"String: \"", @Length = 8, @LiteralText = "\"String: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = true, @Default = true, @PatternLabel = false] | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -125,17 +125,17 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "o", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = true, @Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- ThrowStatement[] | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "NullPointerException"] | | +- ArgumentList[@Empty = true, @Size = 0] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -149,7 +149,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "String: ", @Empty = false, @Image = "\"String: \"", @Length = 8, @LiteralText = "\"String: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] @@ -161,7 +161,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Integer", @Empty = false, @Image = "\"Integer\"", @Length = 7, @LiteralText = "\"Integer\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] @@ -177,10 +177,10 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "o", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 4, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true, @NullTolerant = true] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = true, @Default = false, @PatternLabel = false] | | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ExpressionStatement[] | | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] @@ -191,7 +191,7 @@ | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "null", @Empty = false, @Image = "\"null\"", @Length = 4, @LiteralText = "\"null\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- BreakStatement[@Label = null] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -205,7 +205,7 @@ | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "String", @Empty = false, @Image = "\"String\"", @Length = 6, @LiteralText = "\"String\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- BreakStatement[@Label = null] | | +- SwitchFallthroughBranch[@Default = true] - | | +- SwitchLabel[@Default = true, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | | +- ExpressionStatement[] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -214,10 +214,10 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "default case", @Empty = false, @Image = "\"default case\"", @Length = 12, @LiteralText = "\"default case\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- BreakStatement[@Label = null] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = true] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = true, @Default = false, @PatternLabel = false] | | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -226,7 +226,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "null", @Empty = false, @Image = "\"null\"", @Length = 4, @LiteralText = "\"null\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -238,20 +238,20 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "String", @Empty = false, @Image = "\"String\"", @Length = 6, @LiteralText = "\"String\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchArrowBranch[@Default = true] - | | +- SwitchLabel[@Default = true, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "default case", @Empty = false, @Image = "\"default case\"", @Length = 12, @LiteralText = "\"default case\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true, @NullTolerant = true] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = true, @Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchFallthroughBranch[@Default = true] - | | +- SwitchLabel[@Default = true, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | | +- ExpressionStatement[] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -259,10 +259,10 @@ | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "The rest (including null)", @Empty = false, @Image = "\"The rest (including null)\"", @Length = 25, @LiteralText = "\"The rest (including null)\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = true, @Default = true, @PatternLabel = false] | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/EnhancedTypeCheckingSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/EnhancedTypeCheckingSwitch.txt index b820b67415e..81811d84271 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/EnhancedTypeCheckingSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/EnhancedTypeCheckingSwitch.txt @@ -35,10 +35,10 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "obj", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "obj", @Name = "obj", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = true, @Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -47,7 +47,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "null", @Empty = false, @Image = "\"null\"", @Length = 4, @LiteralText = "\"null\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -59,7 +59,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "String", @Empty = false, @Image = "\"String\"", @Length = 6, @LiteralText = "\"String\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Color"] @@ -75,7 +75,7 @@ | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "c", @Name = "c", @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArgumentList[@Empty = true, @Size = 0] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Point"] @@ -91,7 +91,7 @@ | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "p", @Name = "p", @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArgumentList[@Empty = true, @Size = 0] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ArrayType[@ArrayDepth = 1] @@ -109,7 +109,7 @@ | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "length", @Name = "length", @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "ia", @Name = "ia", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ExhaustiveSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ExhaustiveSwitch.txt index 02e353c5f0a..f5c0842bcd8 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ExhaustiveSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ExhaustiveSwitch.txt @@ -12,10 +12,10 @@ | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "obj", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] | +- ReturnStatement[] - | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "obj", @Name = "obj", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -24,14 +24,14 @@ | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArgumentList[@Empty = true, @Size = 0] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "i", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] +- MethodDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "coverageStatement", @Overridden = false, @Static = true, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC), @ExplicitModifiers = (JModifier.STATIC)] @@ -42,10 +42,10 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "o", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true, @NullTolerant = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -59,7 +59,7 @@ | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] @@ -73,7 +73,7 @@ | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Integer", @Empty = false, @Image = "\"Integer\"", @Length = 7, @LiteralText = "\"Integer\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | +- BreakStatement[@Label = null] +- ClassDeclaration[@Abstract = true, @Annotation = false, @Anonymous = false, @BinaryName = "ExhaustiveSwitch$S", @CanonicalName = "ExhaustiveSwitch.S", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = true, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = true, @SimpleName = "S", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] | +- ModifierList[@EffectiveModifiers = (JModifier.ABSTRACT, JModifier.STATIC, JModifier.SEALED), @ExplicitModifiers = (JModifier.SEALED)] @@ -112,24 +112,24 @@ | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] | +- ReturnStatement[] - | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "A"] | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "a", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "B"] | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "b", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2", @IntLiteral = true, @Integral = true, @LiteralText = "2", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = true] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "C"] @@ -144,10 +144,10 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "S"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 2, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true, @NullTolerant = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "A"] @@ -161,7 +161,7 @@ | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "A", @Empty = false, @Image = "\"A\"", @Length = 1, @LiteralText = "\"A\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- BreakStatement[@Label = null] | | +- SwitchFallthroughBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "C"] @@ -175,7 +175,7 @@ | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "C", @Empty = false, @Image = "\"C\"", @Length = 1, @LiteralText = "\"C\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- BreakStatement[@Label = null] | | +- SwitchFallthroughBranch[@Default = true] - | | +- SwitchLabel[@Default = true, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | | +- ExpressionStatement[] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -223,10 +223,10 @@ | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] | +- ReturnStatement[] - | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = true] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "F"] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/GuardedPatterns.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/GuardedPatterns.txt index bb6d75959ed..3094273758e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/GuardedPatterns.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/GuardedPatterns.txt @@ -11,10 +11,10 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "o", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -32,7 +32,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "single char string", @Empty = false, @Image = "\"single char string\"", @Length = 18, @LiteralText = "\"single char string\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -44,7 +44,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "string", @Empty = false, @Image = "\"string\"", @Length = 6, @LiteralText = "\"string\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] @@ -62,7 +62,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "integer 1", @Empty = false, @Image = "\"integer 1\"", @Length = 9, @LiteralText = "\"integer 1\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] @@ -115,10 +115,10 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "o", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -136,7 +136,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "single char string", @Empty = false, @Image = "\"single char string\"", @Length = 18, @LiteralText = "\"single char string\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -148,7 +148,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "string", @Empty = false, @Image = "\"string\"", @Length = 6, @LiteralText = "\"string\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] @@ -166,7 +166,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "integer 1", @Empty = false, @Image = "\"integer 1\"", @Length = 9, @LiteralText = "\"integer 1\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = true, @Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -175,7 +175,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "null!", @Empty = false, @Image = "\"null!\"", @Length = 5, @LiteralText = "\"null!\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep440_RecordPatterns.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep440_RecordPatterns.txt index 4bed5a255f4..5b3a9a6145f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep440_RecordPatterns.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep440_RecordPatterns.txt @@ -257,10 +257,10 @@ | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "pair", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "pair", @Name = "pair", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = true] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | +- RecordPattern[] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "MyPair"] | | +- PatternList[@Empty = false, @Size = 2] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt index f49cf72128e..3b75352cf36 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/Jep441_PatternMatchingForSwitch.txt @@ -12,10 +12,10 @@ | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "obj", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] | +- ReturnStatement[] - | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "obj", @Name = "obj", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] @@ -27,7 +27,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "int %d", @Empty = false, @Image = "\"int %d\"", @Length = 6, @LiteralText = "\"int %d\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Long"] @@ -39,7 +39,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "long %d", @Empty = false, @Image = "\"long %d\"", @Length = 7, @LiteralText = "\"long %d\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "l", @Name = "l", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Double"] @@ -51,7 +51,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "double %f", @Empty = false, @Image = "\"double %f\"", @Length = 9, @LiteralText = "\"double %f\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -63,7 +63,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "String %s", @Empty = false, @Image = "\"String %s\"", @Length = 9, @LiteralText = "\"String %s\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "toString", @MethodName = "toString", @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "obj", @Name = "obj", @ParenthesisDepth = 0, @Parenthesized = false] | +- ArgumentList[@Empty = true, @Size = 0] @@ -76,10 +76,10 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = true, @Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -88,7 +88,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Oops", @Empty = false, @Image = "\"Oops\"", @Length = 4, @LiteralText = "\"Oops\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Foo", @Empty = false, @Image = "\"Foo\"", @Length = 3, @LiteralText = "\"Foo\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Bar", @Empty = false, @Image = "\"Bar\"", @Length = 3, @LiteralText = "\"Bar\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] @@ -98,7 +98,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Great", @Empty = false, @Image = "\"Great\"", @Length = 5, @LiteralText = "\"Great\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] @@ -114,14 +114,14 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "response", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "response", @Name = "response", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = true, @Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- Block[@Empty = true, @Size = 0, @containsComment = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -140,7 +140,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "You got it", @Empty = false, @Image = "\"You got it\"", @Length = 10, @LiteralText = "\"You got it\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -159,7 +159,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Shame", @Empty = false, @Image = "\"Shame\"", @Length = 5, @LiteralText = "\"Shame\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = true] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -181,14 +181,14 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "response", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "response", @Name = "response", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = true, @Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- Block[@Empty = true, @Size = 0, @containsComment = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "y", @Empty = false, @Image = "\"y\"", @Length = 1, @LiteralText = "\"y\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Y", @Empty = false, @Image = "\"Y\"", @Length = 1, @LiteralText = "\"Y\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- Block[@Empty = false, @Size = 1, @containsComment = false] @@ -200,7 +200,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "You got it", @Empty = false, @Image = "\"You got it\"", @Length = 10, @LiteralText = "\"You got it\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "n", @Empty = false, @Image = "\"n\"", @Length = 1, @LiteralText = "\"n\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "N", @Empty = false, @Image = "\"N\"", @Length = 1, @LiteralText = "\"N\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- Block[@Empty = false, @Size = 1, @containsComment = false] @@ -212,7 +212,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Shame", @Empty = false, @Image = "\"Shame\"", @Length = 5, @LiteralText = "\"Shame\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -231,7 +231,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "You got it", @Empty = false, @Image = "\"You got it\"", @Length = 10, @LiteralText = "\"You got it\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -250,7 +250,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Shame", @Empty = false, @Image = "\"Shame\"", @Length = 5, @LiteralText = "\"Shame\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = true] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -300,10 +300,10 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "CardClassification"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "c", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "c", @Name = "c", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Suit"] @@ -323,7 +323,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "It\'s clubs", @Empty = false, @Image = "\"It\'s clubs\"", @Length = 10, @LiteralText = "\"It\'s clubs\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Suit"] @@ -343,7 +343,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "It\'s diamonds", @Empty = false, @Image = "\"It\'s diamonds\"", @Length = 13, @LiteralText = "\"It\'s diamonds\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Suit"] @@ -363,7 +363,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "It\'s hearts", @Empty = false, @Image = "\"It\'s hearts\"", @Length = 11, @LiteralText = "\"It\'s hearts\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Suit"] @@ -377,7 +377,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "It\'s spades", @Empty = false, @Image = "\"It\'s spades\"", @Length = 11, @LiteralText = "\"It\'s spades\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = true] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Tarot"] @@ -399,10 +399,10 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "CardClassification"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "c", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "c", @Name = "c", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "CLUBS", @Name = "CLUBS", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Suit"] @@ -415,7 +415,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "It\'s clubs", @Empty = false, @Image = "\"It\'s clubs\"", @Length = 10, @LiteralText = "\"It\'s clubs\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "DIAMONDS", @Name = "DIAMONDS", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Suit"] @@ -428,7 +428,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "It\'s diamonds", @Empty = false, @Image = "\"It\'s diamonds\"", @Length = 13, @LiteralText = "\"It\'s diamonds\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "HEARTS", @Name = "HEARTS", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Suit"] @@ -441,7 +441,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "It\'s hearts", @Empty = false, @Image = "\"It\'s hearts\"", @Length = 11, @LiteralText = "\"It\'s hearts\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "SPADES", @Name = "SPADES", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Suit"] @@ -454,7 +454,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "It\'s spades", @Empty = false, @Image = "\"It\'s spades\"", @Length = 11, @LiteralText = "\"It\'s spades\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = true] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Tarot"] @@ -492,10 +492,10 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Currency"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "c", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "c", @Name = "c", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "HEADS", @Name = "HEADS", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Coin"] @@ -508,7 +508,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Heads", @Empty = false, @Image = "\"Heads\"", @Length = 5, @LiteralText = "\"Heads\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "TAILS", @Name = "TAILS", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Coin"] @@ -529,10 +529,10 @@ | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Coin"] | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "c", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] +- Block[@Empty = false, @Size = 1, @containsComment = false] - +- SwitchStatement[@DefaultCase = false, @EnumSwitch = true, @Exhaustive = true, @ExhaustiveEnumSwitch = true, @FallthroughSwitch = false] + +- SwitchStatement[@DefaultCase = false, @EnumSwitch = true, @Exhaustive = true, @ExhaustiveEnumSwitch = true, @FallthroughSwitch = false, @NullTolerant = false] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "c", @Name = "c", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "HEADS", @Name = "HEADS", @ParenthesisDepth = 0, @Parenthesized = false] | +- Block[@Empty = false, @Size = 1, @containsComment = false] | +- ExpressionStatement[] @@ -543,7 +543,7 @@ | +- ArgumentList[@Empty = false, @Size = 1] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Heads", @Empty = false, @Image = "\"Heads\"", @Length = 5, @LiteralText = "\"Heads\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] +- SwitchArrowBranch[@Default = false] - +- SwitchLabel[@Default = false, @PatternLabel = false] + +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "TAILS", @Name = "TAILS", @ParenthesisDepth = 0, @Parenthesized = false] | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Coin"] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/PatternsInSwitchLabels.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/PatternsInSwitchLabels.txt index d84807282c5..37633d04ef0 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/PatternsInSwitchLabels.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/PatternsInSwitchLabels.txt @@ -25,10 +25,10 @@ | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] | +- VariableDeclarator[@Initializer = true, @Name = "formatted"] | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "formatted", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] @@ -40,7 +40,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "int %d", @Empty = false, @Image = "\"int %d\"", @Length = 6, @LiteralText = "\"int %d\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Long"] @@ -52,7 +52,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "long %d", @Empty = false, @Image = "\"long %d\"", @Length = 7, @LiteralText = "\"long %d\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "l", @Name = "l", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Double"] @@ -64,7 +64,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "double %f", @Empty = false, @Image = "\"double %f\"", @Length = 9, @LiteralText = "\"double %f\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] @@ -76,7 +76,7 @@ | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "String %s", @Empty = false, @Image = "\"String %s\"", @Length = 9, @LiteralText = "\"String %s\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "toString", @MethodName = "toString", @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- ArgumentList[@Empty = true, @Size = 0] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatternsExhaustiveSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatternsExhaustiveSwitch.txt index d61d70dccee..3ccf26f07e6 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatternsExhaustiveSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RecordPatternsExhaustiveSwitch.txt @@ -61,10 +61,10 @@ | +- VariableDeclarator[@Initializer = true, @Name = "p2"] | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "p2", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] - +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "p1", @Name = "p1", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- RecordPattern[] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Pair"] | | | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] @@ -85,7 +85,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "a", @Empty = false, @Image = "\"a\"", @Length = 1, @LiteralText = "\"a\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- RecordPattern[] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Pair"] | | | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] @@ -106,7 +106,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "a", @Empty = false, @Image = "\"a\"", @Length = 1, @LiteralText = "\"a\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = true] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | +- RecordPattern[] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Pair"] | | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] @@ -126,10 +126,10 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] | +- ArgumentList[@Empty = false, @Size = 1] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "exhaustive now", @Empty = false, @Image = "\"exhaustive now\"", @Length = 14, @LiteralText = "\"exhaustive now\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "p2", @Name = "p2", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- RecordPattern[] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Pair"] | | | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] @@ -150,7 +150,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "a", @Empty = false, @Image = "\"a\"", @Length = 1, @LiteralText = "\"a\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = true] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | +- RecordPattern[] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Pair"] | | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] @@ -170,10 +170,10 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] | +- ArgumentList[@Empty = false, @Size = 1] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "a", @Empty = false, @Image = "\"a\"", @Length = 1, @LiteralText = "\"a\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "p2", @Name = "p2", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = true] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | +- RecordPattern[] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Pair"] | | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] @@ -194,7 +194,7 @@ | +- ArgumentList[@Empty = false, @Size = 1] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "a", @Empty = false, @Image = "\"a\"", @Length = 1, @LiteralText = "\"a\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = true] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | +- RecordPattern[] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Pair"] | | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] @@ -215,7 +215,7 @@ | +- ArgumentList[@Empty = false, @Size = 1] | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "a", @Empty = false, @Image = "\"a\"", @Length = 1, @LiteralText = "\"a\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] +- SwitchArrowBranch[@Default = false] - +- SwitchLabel[@Default = false, @PatternLabel = true] + +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | +- RecordPattern[] | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Pair"] | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RefiningPatternsInSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RefiningPatternsInSwitch.txt index 917529b5995..01bbca5377f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RefiningPatternsInSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/RefiningPatternsInSwitch.txt @@ -49,14 +49,14 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Shape"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true, @NullTolerant = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = true, @Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Triangle"] @@ -77,7 +77,7 @@ | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Large triangle", @Empty = false, @Image = "\"Large triangle\"", @Length = 14, @LiteralText = "\"Large triangle\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | +- ExpressionStatement[] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -94,15 +94,15 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Shape"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = true, @Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- Block[@Empty = false, @Size = 1, @containsComment = false] | | +- BreakStatement[@Label = null] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Triangle"] @@ -120,7 +120,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Large triangle", @Empty = false, @Image = "\"Large triangle\"", @Length = 14, @LiteralText = "\"Large triangle\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] @@ -136,15 +136,15 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Shape"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = true] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = true, @Default = false, @PatternLabel = false] | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] | | +- Block[@Empty = false, @Size = 1, @containsComment = false] | | +- BreakStatement[@Label = null] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Triangle"] @@ -162,7 +162,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Large triangle", @Empty = false, @Image = "\"Large triangle\"", @Length = 14, @LiteralText = "\"Large triangle\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Triangle"] @@ -174,7 +174,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Small triangle", @Empty = false, @Image = "\"Small triangle\"", @Length = 14, @LiteralText = "\"Small triangle\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ScopeOfPatternVariableDeclarations.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ScopeOfPatternVariableDeclarations.txt index 955704a522a..dff2762d10f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ScopeOfPatternVariableDeclarations.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java21/ScopeOfPatternVariableDeclarations.txt @@ -11,10 +11,10 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "obj", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true, @NullTolerant = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "obj", @Name = "obj", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Character"] @@ -34,7 +34,7 @@ | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Ding!", @Empty = false, @Image = "\"Ding!\"", @Length = 5, @LiteralText = "\"Ding!\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- BreakStatement[@Label = null] | +- SwitchFallthroughBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | +- BreakStatement[@Label = null] +- MethodDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "testSwitchRule", @Overridden = false, @Static = true, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC), @ExplicitModifiers = (JModifier.STATIC)] @@ -45,10 +45,10 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "o", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Character"] @@ -76,7 +76,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Character", @Empty = false, @Image = "\"Character\"", @Length = 9, @LiteralText = "\"Character\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] @@ -91,7 +91,7 @@ | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArgumentList[@Empty = true, @Size = 0] | +- SwitchArrowBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | +- Block[@Empty = false, @Size = 1, @containsComment = false] | +- BreakStatement[@Label = null] +- MethodDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "test2", @Overridden = false, @Static = true, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] @@ -103,10 +103,10 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "o", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true] + | +- SwitchStatement[@DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = true, @NullTolerant = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchFallthroughBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Character"] @@ -147,7 +147,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "character", @Empty = false, @Image = "\"character\"", @Length = 9, @LiteralText = "\"character\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | +- SwitchFallthroughBranch[@Default = true] - | +- SwitchLabel[@Default = true, @PatternLabel = false] + | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | +- ExpressionStatement[] | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt index d83a5066bfa..1e944045228 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java22/Jep456_UnnamedPatternsAndVariables.txt @@ -178,10 +178,10 @@ | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "RedBall"] | | +- ArgumentList[@Empty = true, @Size = 0] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | | +- RecordPattern[] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] | | | | +- PatternList[@Empty = false, @Size = 1] @@ -193,7 +193,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | | +- RecordPattern[] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] | | | | +- PatternList[@Empty = false, @Size = 1] @@ -205,7 +205,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- RecordPattern[] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] | | | +- PatternList[@Empty = false, @Size = 1] @@ -215,10 +215,10 @@ | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "_", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = true, @Visibility = Visibility.V_LOCAL] | | +- MethodCall[@CompileTimeConstant = false, @Image = "stopProcessing", @MethodName = "stopProcessing", @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArgumentList[@Empty = true, @Size = 0] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | | +- RecordPattern[] | | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] | | | | | +- PatternList[@Empty = false, @Size = 1] @@ -237,7 +237,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | | +- RecordPattern[] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] | | | | +- PatternList[@Empty = false, @Size = 1] @@ -248,7 +248,7 @@ | | | +- MethodCall[@CompileTimeConstant = false, @Image = "stopProcessing", @MethodName = "stopProcessing", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ArgumentList[@Empty = true, @Size = 0] | | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- RecordPattern[] | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] | | | +- PatternList[@Empty = false, @Size = 1] @@ -261,10 +261,10 @@ | | +- VariableDeclarator[@Initializer = true, @Name = "x"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "42", @IntLiteral = true, @Integral = true, @LiteralText = "42", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 42.0, @ValueAsFloat = 42.0, @ValueAsInt = 42, @ValueAsLong = 42] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- RecordPattern[] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] | | | | +- PatternList[@Empty = false, @Size = 1] @@ -287,7 +287,7 @@ | | +- ArgumentList[@Empty = false, @Size = 1] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = true] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | +- RecordPattern[] | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"] | | +- PatternList[@Empty = false, @Size = 1] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt index 001fb04dd0f..3dc573dc379 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt @@ -54,24 +54,24 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] | | +- VariableDeclarator[@Initializer = true, @Name = "status"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "status", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "getStatus", @MethodName = "getStatus", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ArgumentList[@Empty = true, @Size = 0] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "okay", @Empty = false, @Image = "\"okay\"", @Length = 4, @LiteralText = "\"okay\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "warning", @Empty = false, @Image = "\"warning\"", @Length = 7, @LiteralText = "\"warning\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2", @IntLiteral = true, @Integral = true, @LiteralText = "2", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "error", @Empty = false, @Image = "\"error\"", @Length = 5, @LiteralText = "\"error\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] @@ -88,30 +88,30 @@ | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "status: ", @Empty = false, @Image = "\"status: \"", @Length = 8, @LiteralText = "\"status: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "status", @Name = "status", @ParenthesisDepth = 0, @Parenthesized = false] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "getYearlyFlights", @MethodName = "getYearlyFlights", @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArgumentList[@Empty = true, @Size = 0] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] | | +- MethodCall[@CompileTimeConstant = false, @Image = "noop", @MethodName = "noop", @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArgumentList[@Empty = true, @Size = 0] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | | +- MethodCall[@CompileTimeConstant = false, @Image = "noop", @MethodName = "noop", @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArgumentList[@Empty = true, @Size = 0] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2", @IntLiteral = true, @Integral = true, @LiteralText = "2", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] | | +- MethodCall[@CompileTimeConstant = false, @Image = "issueDiscount", @MethodName = "issueDiscount", @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArgumentList[@Empty = true, @Size = 0] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] @@ -124,7 +124,7 @@ | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArgumentList[@Empty = true, @Size = 0] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = true] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] @@ -377,18 +377,18 @@ | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] | | +- VariableDeclarator[@Initializer = true, @Name = "userId"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "userId", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "isLoggedIn", @MethodName = "isLoggedIn", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "user", @Name = "user", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ArgumentList[@Empty = true, @Size = 0] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "true", @ParenthesisDepth = 0, @Parenthesized = false, @True = true] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "id", @MethodName = "id", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "user", @Name = "user", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ArgumentList[@Empty = true, @Size = 0] | | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "false", @ParenthesisDepth = 0, @Parenthesized = false, @True = false] | | +- Block[@Empty = false, @Size = 2, @containsComment = false] | | +- ExpressionStatement[] @@ -407,10 +407,10 @@ | | +- VariableDeclarator[@Initializer = true, @Name = "v"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "v", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "12345L", @IntLiteral = false, @Integral = true, @LiteralText = "12345L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 12345.0, @ValueAsFloat = 12345.0, @ValueAsInt = 12345, @ValueAsLong = 12345] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "v", @Name = "v", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1L", @IntLiteral = false, @Integral = true, @LiteralText = "1L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -419,7 +419,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "1L", @Empty = false, @Image = "\"1L\"", @Length = 2, @LiteralText = "\"1L\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2L", @IntLiteral = false, @Integral = true, @LiteralText = "2L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -428,7 +428,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "2L", @Empty = false, @Image = "\"2L\"", @Length = 2, @LiteralText = "\"2L\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "10_000_000_000L", @IntLiteral = false, @Integral = true, @LiteralText = "10_000_000_000L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0E10, @ValueAsFloat = 1.0E10, @ValueAsInt = 1410065408, @ValueAsLong = 10000000000] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -437,7 +437,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "10x", @Empty = false, @Image = "\"10x\"", @Length = 3, @LiteralText = "\"10x\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "20_000_000_000L", @IntLiteral = false, @Integral = true, @LiteralText = "20_000_000_000L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0E10, @ValueAsFloat = 2.0E10, @ValueAsInt = -1474836480, @ValueAsLong = 20000000000] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -446,7 +446,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "20x", @Empty = false, @Image = "\"20x\"", @Length = 3, @LiteralText = "\"20x\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.LONG] @@ -470,14 +470,14 @@ | +- ExpressionStatement[] | | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "fv", @Name = "fv", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "fv", @Name = "fv", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "0f", @IntLiteral = false, @Integral = false, @LiteralText = "0f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "5f", @IntLiteral = false, @Integral = false, @LiteralText = "5f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 5.0, @ValueAsFloat = 5.0, @ValueAsInt = 5, @ValueAsLong = 5] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] @@ -490,7 +490,7 @@ | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "6f", @IntLiteral = false, @Integral = false, @LiteralText = "6f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 6.0, @ValueAsFloat = 6.0, @ValueAsInt = 6, @ValueAsLong = 6] | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] @@ -507,14 +507,14 @@ | +- ExpressionStatement[] | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "dd", @Name = "dd", @ParenthesisDepth = 0, @Parenthesized = false] - | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "dd", @Name = "dd", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = true, @FloatLiteral = false, @Image = "0d", @IntLiteral = false, @Integral = false, @LiteralText = "0d", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "5", @IntLiteral = true, @Integral = true, @LiteralText = "5", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 5.0, @ValueAsFloat = 5.0, @ValueAsInt = 5, @ValueAsLong = 5] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] @@ -527,7 +527,7 @@ | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "6", @IntLiteral = true, @Integral = true, @LiteralText = "6", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 6.0, @ValueAsFloat = 6.0, @ValueAsInt = 6, @ValueAsLong = 6] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = true] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] @@ -702,10 +702,10 @@ | +- VariableDeclarator[@Initializer = true, @Name = "i"] | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] - +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = true] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] @@ -724,10 +724,10 @@ | +- VariableDeclarator[@Initializer = true, @Name = "b"] | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "b", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] - +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchArrowBranch[@Default = false] - +- SwitchLabel[@Default = false, @PatternLabel = true] + +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep492_FlexibleConstructorBodies.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep492_FlexibleConstructorBodies.txt index 4000fafd72e..a674767c207 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep492_FlexibleConstructorBodies.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep492_FlexibleConstructorBodies.txt @@ -85,10 +85,10 @@ | | | +- ArrayTypeDim[@Varargs = false] | | +- VariableDeclarator[@Initializer = true, @Name = "certBytes"] | | +- VariableId[@ArrayType = true, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "certBytes", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "publicKey", @Name = "publicKey", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "RSAKey"] @@ -99,7 +99,7 @@ | | | | +- ArgumentList[@Empty = true, @Size = 0] | | | +- ArgumentList[@Empty = true, @Size = 0] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "DSAPublicKey"] @@ -110,7 +110,7 @@ | | | | +- ArgumentList[@Empty = true, @Size = 0] | | | +- ArgumentList[@Empty = true, @Size = 0] | | +- SwitchArrowBranch[@Default = true] - | | +- SwitchLabel[@Default = true, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | | +- ArrayAllocation[@ArrayDepth = 1, @CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArrayType[@ArrayDepth = 1] | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep513_FlexibleConstructorBodies.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep513_FlexibleConstructorBodies.txt index 945103e6e90..33a64025834 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep513_FlexibleConstructorBodies.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25/Jep513_FlexibleConstructorBodies.txt @@ -85,10 +85,10 @@ | | | +- ArrayTypeDim[@Varargs = false] | | +- VariableDeclarator[@Initializer = true, @Name = "certBytes"] | | +- VariableId[@ArrayType = true, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "certBytes", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "publicKey", @Name = "publicKey", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "RSAKey"] @@ -99,7 +99,7 @@ | | | | +- ArgumentList[@Empty = true, @Size = 0] | | | +- ArgumentList[@Empty = true, @Size = 0] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "DSAPublicKey"] @@ -110,7 +110,7 @@ | | | | +- ArgumentList[@Empty = true, @Size = 0] | | | +- ArgumentList[@Empty = true, @Size = 0] | | +- SwitchArrowBranch[@Default = true] - | | +- SwitchLabel[@Default = true, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] | | +- ArrayAllocation[@ArrayDepth = 1, @CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArrayType[@ArrayDepth = 1] | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25p/Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25p/Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.txt index 1da9ed524af..f7c92006a49 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25p/Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java25p/Jep507_PrimitiveTypesInPatternsInstanceofAndSwitch.txt @@ -54,24 +54,24 @@ | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] | | +- VariableDeclarator[@Initializer = true, @Name = "status"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "status", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "getStatus", @MethodName = "getStatus", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ArgumentList[@Empty = true, @Size = 0] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "okay", @Empty = false, @Image = "\"okay\"", @Length = 4, @LiteralText = "\"okay\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "warning", @Empty = false, @Image = "\"warning\"", @Length = 7, @LiteralText = "\"warning\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2", @IntLiteral = true, @Integral = true, @LiteralText = "2", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "error", @Empty = false, @Image = "\"error\"", @Length = 5, @LiteralText = "\"error\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] @@ -88,30 +88,30 @@ | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "status: ", @Empty = false, @Image = "\"status: \"", @Length = 8, @LiteralText = "\"status: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "status", @Name = "status", @ParenthesisDepth = 0, @Parenthesized = false] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] | +- MethodCall[@CompileTimeConstant = false, @Image = "getYearlyFlights", @MethodName = "getYearlyFlights", @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArgumentList[@Empty = true, @Size = 0] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] | | +- MethodCall[@CompileTimeConstant = false, @Image = "noop", @MethodName = "noop", @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArgumentList[@Empty = true, @Size = 0] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | | +- MethodCall[@CompileTimeConstant = false, @Image = "noop", @MethodName = "noop", @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArgumentList[@Empty = true, @Size = 0] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2", @IntLiteral = true, @Integral = true, @LiteralText = "2", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] | | +- MethodCall[@CompileTimeConstant = false, @Image = "issueDiscount", @MethodName = "issueDiscount", @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArgumentList[@Empty = true, @Size = 0] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] @@ -124,7 +124,7 @@ | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] | | +- ArgumentList[@Empty = true, @Size = 0] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = true] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] @@ -377,18 +377,18 @@ | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] | | +- VariableDeclarator[@Initializer = true, @Name = "userId"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "userId", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- MethodCall[@CompileTimeConstant = false, @Image = "isLoggedIn", @MethodName = "isLoggedIn", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "user", @Name = "user", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ArgumentList[@Empty = true, @Size = 0] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "true", @ParenthesisDepth = 0, @Parenthesized = false, @True = true] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "id", @MethodName = "id", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "user", @Name = "user", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ArgumentList[@Empty = true, @Size = 0] | | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "false", @ParenthesisDepth = 0, @Parenthesized = false, @True = false] | | +- Block[@Empty = false, @Size = 2, @containsComment = false] | | +- ExpressionStatement[] @@ -407,10 +407,10 @@ | | +- VariableDeclarator[@Initializer = true, @Name = "v"] | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "v", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "12345L", @IntLiteral = false, @Integral = true, @LiteralText = "12345L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 12345.0, @ValueAsFloat = 12345.0, @ValueAsInt = 12345, @ValueAsLong = 12345] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "v", @Name = "v", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1L", @IntLiteral = false, @Integral = true, @LiteralText = "1L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -419,7 +419,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "1L", @Empty = false, @Image = "\"1L\"", @Length = 2, @LiteralText = "\"1L\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2L", @IntLiteral = false, @Integral = true, @LiteralText = "2L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -428,7 +428,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "2L", @Empty = false, @Image = "\"2L\"", @Length = 2, @LiteralText = "\"2L\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "10_000_000_000L", @IntLiteral = false, @Integral = true, @LiteralText = "10_000_000_000L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0E10, @ValueAsFloat = 1.0E10, @ValueAsInt = 1410065408, @ValueAsLong = 10000000000] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -437,7 +437,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "10x", @Empty = false, @Image = "\"10x\"", @Length = 3, @LiteralText = "\"10x\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "20_000_000_000L", @IntLiteral = false, @Integral = true, @LiteralText = "20_000_000_000L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0E10, @ValueAsFloat = 2.0E10, @ValueAsInt = -1474836480, @ValueAsLong = 20000000000] | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] @@ -446,7 +446,7 @@ | | | +- ArgumentList[@Empty = false, @Size = 1] | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "20x", @Empty = false, @Image = "\"20x\"", @Length = 3, @LiteralText = "\"20x\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] | | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.LONG] @@ -470,14 +470,14 @@ | +- ExpressionStatement[] | | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "fv", @Name = "fv", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "fv", @Name = "fv", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "0f", @IntLiteral = false, @Integral = false, @LiteralText = "0f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "5f", @IntLiteral = false, @Integral = false, @LiteralText = "5f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 5.0, @ValueAsFloat = 5.0, @ValueAsInt = 5, @ValueAsLong = 5] | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] @@ -490,7 +490,7 @@ | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "6f", @IntLiteral = false, @Integral = false, @LiteralText = "6f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 6.0, @ValueAsFloat = 6.0, @ValueAsInt = 6, @ValueAsLong = 6] | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] | | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] @@ -507,14 +507,14 @@ | +- ExpressionStatement[] | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "dd", @Name = "dd", @ParenthesisDepth = 0, @Parenthesized = false] - | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "dd", @Name = "dd", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = true, @FloatLiteral = false, @Image = "0d", @IntLiteral = false, @Integral = false, @LiteralText = "0d", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "5", @IntLiteral = true, @Integral = true, @LiteralText = "5", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 5.0, @ValueAsFloat = 5.0, @ValueAsInt = 5, @ValueAsLong = 5] | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@Default = false, @PatternLabel = true] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] @@ -527,7 +527,7 @@ | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "6", @IntLiteral = true, @Integral = true, @LiteralText = "6", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 6.0, @ValueAsFloat = 6.0, @ValueAsInt = 6, @ValueAsLong = 6] | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = true] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] @@ -702,10 +702,10 @@ | +- VariableDeclarator[@Initializer = true, @Name = "i"] | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] - +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@Default = false, @PatternLabel = true] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] @@ -724,10 +724,10 @@ | +- VariableDeclarator[@Initializer = true, @Name = "b"] | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "b", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] - +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false] + +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] +- SwitchArrowBranch[@Default = false] - +- SwitchLabel[@Default = false, @PatternLabel = true] + +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] From e20c02fd1a98a6e17fc616199f76ff32310beac9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Dec 2025 08:55:07 +0100 Subject: [PATCH 1738/1962] chore(deps): bump actions/checkout from 6.0.0 to 6.0.1 (#6300) Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.0 to 6.0.1. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/1af3b93b6815bc44a9784bd300feb67ff0d1eeb3...8e8c483db84b4bee98b60c0593521ed34d9990e8) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 6.0.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 12 ++++++------ .github/workflows/git-repo-sync.yml | 2 +- .github/workflows/publish-release.yml | 6 +++--- .github/workflows/publish-snapshot.yml | 12 ++++++------ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5dd3d24ecbd..3718370a267 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,7 +23,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' @@ -81,7 +81,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' @@ -121,7 +121,7 @@ jobs: matrix: os: [ ubuntu-latest, windows-latest, macos-latest ] steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 # under linux we execute more extensive integration tests with various java versions if: ${{ runner.os == 'Linux' }} @@ -172,7 +172,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' @@ -258,7 +258,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 with: distribution: 'temurin' @@ -311,7 +311,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 with: fetch-depth: 2 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 diff --git a/.github/workflows/git-repo-sync.yml b/.github/workflows/git-repo-sync.yml index 23473a37d87..f1d5dc0c577 100644 --- a/.github/workflows/git-repo-sync.yml +++ b/.github/workflows/git-repo-sync.yml @@ -28,7 +28,7 @@ jobs: shell: bash continue-on-error: false steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 with: fetch-depth: 100 - name: Setup ssh key for sourceforge diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 94ce577e640..88fac66479b 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -31,7 +31,7 @@ jobs: outputs: PMD_VERSION: ${{ steps.version.outputs.PMD_VERSION }} steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 with: ref: ${{ github.event.workflow_run.head_branch }} - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 @@ -85,7 +85,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 with: ref: ${{ github.event.workflow_run.head_branch }} - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 @@ -622,7 +622,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 with: ref: ${{ github.event.workflow_run.head_branch }} - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 9a87ef2a98b..7bab9bff054 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -30,7 +30,7 @@ jobs: outputs: PMD_VERSION: ${{ steps.version.outputs.PMD_VERSION }} steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 with: ref: main - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 @@ -76,7 +76,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 with: ref: main - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 @@ -416,7 +416,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 with: ref: gh-pages - name: Clear old files @@ -639,7 +639,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 with: ref: main - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 @@ -726,7 +726,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 with: ref: main - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 @@ -763,7 +763,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 #v6.0.0 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 with: ref: main - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 From 7cd2c786577b77edd4bc4332d6fb3c8439c5d7e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Dec 2025 08:55:27 +0100 Subject: [PATCH 1739/1962] chore(deps): bump org.checkerframework:checker-qual from 3.52.0 to 3.52.1 (#6301) chore(deps): bump org.checkerframework:checker-qual Bumps [org.checkerframework:checker-qual](https://github.com/typetools/checker-framework) from 3.52.0 to 3.52.1. - [Release notes](https://github.com/typetools/checker-framework/releases) - [Changelog](https://github.com/typetools/checker-framework/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/typetools/checker-framework/compare/checker-framework-3.52.0...checker-framework-3.52.1) --- updated-dependencies: - dependency-name: org.checkerframework:checker-qual dependency-version: 3.52.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 13a6edf1720..a9bc2d3bb94 100644 --- a/pom.xml +++ b/pom.xml @@ -907,7 +907,7 @@ org.checkerframework checker-qual - 3.52.0 + 3.52.1 net.sf.saxon From 9efa2de25007ba674b677cad58cc47162687e069 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Dec 2025 08:55:49 +0100 Subject: [PATCH 1740/1962] chore(deps): bump org.apache.maven.plugins:maven-resources-plugin from 3.3.1 to 3.4.0 (#6302) chore(deps): bump org.apache.maven.plugins:maven-resources-plugin Bumps [org.apache.maven.plugins:maven-resources-plugin](https://github.com/apache/maven-resources-plugin) from 3.3.1 to 3.4.0. - [Release notes](https://github.com/apache/maven-resources-plugin/releases) - [Commits](https://github.com/apache/maven-resources-plugin/compare/maven-resources-plugin-3.3.1...v3.4.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-resources-plugin dependency-version: 3.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a9bc2d3bb94..7103f197d4c 100644 --- a/pom.xml +++ b/pom.xml @@ -328,7 +328,7 @@ org.apache.maven.plugins maven-resources-plugin - 3.3.1 + 3.4.0 ${project.build.sourceEncoding} From 0af8c6b5bf929aff0d40b4cc3808de088e154fee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Dec 2025 08:56:19 +0100 Subject: [PATCH 1741/1962] chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.18.1 to 1.18.2 (#6303) Bumps [net.bytebuddy:byte-buddy](https://github.com/raphw/byte-buddy) from 1.18.1 to 1.18.2. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.18.1...byte-buddy-1.18.2) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-version: 1.18.2 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7103f197d4c..d562860eaff 100644 --- a/pom.xml +++ b/pom.xml @@ -1042,7 +1042,7 @@ net.bytebuddy byte-buddy - 1.18.1 + 1.18.2 test From e5aa91782cc9113a28f925de5fb7dbb746377cc3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Dec 2025 08:56:56 +0100 Subject: [PATCH 1742/1962] chore(deps): bump com.puppycrawl.tools:checkstyle from 12.1.2 to 12.2.0 (#6304) Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 12.1.2 to 12.2.0. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-12.1.2...checkstyle-12.2.0) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-version: 12.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d562860eaff..360ab4dcffd 100644 --- a/pom.xml +++ b/pom.xml @@ -91,7 +91,7 @@ 5.0 3.5.4 - 12.1.2 + 12.2.0 3.6.0 3.28.0 1.10.15 From c73ea1c9776e41bcd2cf768dd242b43546c86580 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Dec 2025 08:57:28 +0100 Subject: [PATCH 1743/1962] chore(deps): bump org.sonarsource.scanner.maven:sonar-maven-plugin from 5.3.0.6276 to 5.4.0.6343 (#6305) chore(deps): bump org.sonarsource.scanner.maven:sonar-maven-plugin Bumps [org.sonarsource.scanner.maven:sonar-maven-plugin](https://github.com/SonarSource/sonar-scanner-maven) from 5.3.0.6276 to 5.4.0.6343. - [Release notes](https://github.com/SonarSource/sonar-scanner-maven/releases) - [Commits](https://github.com/SonarSource/sonar-scanner-maven/compare/5.3.0.6276...5.4.0.6343) --- updated-dependencies: - dependency-name: org.sonarsource.scanner.maven:sonar-maven-plugin dependency-version: 5.4.0.6343 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 360ab4dcffd..3abc9edfafe 100644 --- a/pom.xml +++ b/pom.xml @@ -1310,7 +1310,7 @@ org.sonarsource.scanner.maven sonar-maven-plugin - 5.3.0.6276 + 5.4.0.6343 From b237e77e34bdb26f6a53a400b96576feb082e4d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Dec 2025 08:58:19 +0100 Subject: [PATCH 1744/1962] chore(deps): bump webrick from 1.9.1 to 1.9.2 in /docs (#6306) Bumps [webrick](https://github.com/ruby/webrick) from 1.9.1 to 1.9.2. - [Release notes](https://github.com/ruby/webrick/releases) - [Commits](https://github.com/ruby/webrick/compare/v1.9.1...v1.9.2) --- updated-dependencies: - dependency-name: webrick dependency-version: 1.9.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index 07e739fe497..7f43197d967 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -269,7 +269,7 @@ GEM concurrent-ruby (~> 1.0) unicode-display_width (1.8.0) uri (1.0.3) - webrick (1.9.1) + webrick (1.9.2) PLATFORMS x86_64-linux From e9f8146a16ae8d3c3e1d76b235b0bffb9a10d9a6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 4 Dec 2025 08:58:57 +0100 Subject: [PATCH 1745/1962] Bump PMD from 7.18.0 to 7.19.0 (#6286) Dogfood update... --- pom.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 3abc9edfafe..8f29af45544 100644 --- a/pom.xml +++ b/pom.xml @@ -606,27 +606,27 @@ net.sourceforge.pmd pmd-core - 7.18.0 + 7.19.0 net.sourceforge.pmd pmd-java - 7.18.0 + 7.19.0 net.sourceforge.pmd pmd-jsp - 7.18.0 + 7.19.0 net.sourceforge.pmd pmd-javascript - 7.18.0 + 7.19.0 net.sourceforge.pmd pmd-xml - 7.18.0 + 7.19.0 From 94896cd0a985ca6d0bdabdf1658a7aa5f3b3d059 Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Thu, 4 Dec 2025 17:14:54 +0100 Subject: [PATCH 1746/1962] Feat: Introduce ignoredMethodNames for OnlyOneReturn Introduce the property ignoredMethodNames, which defaults to compareTo and equals as common methods with multiple returns. The property is a String List to align with other ignore properties: ignoredFieldNames and ignoredAnnotations. --- .../rule/codestyle/OnlyOneReturnRule.java | 17 ++++++++++- .../java/rule/codestyle/xml/OnlyOneReturn.xml | 30 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/OnlyOneReturnRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/OnlyOneReturnRule.java index 7414be76b4f..6097df88d03 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/OnlyOneReturnRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/OnlyOneReturnRule.java @@ -4,20 +4,31 @@ package net.sourceforge.pmd.lang.java.rule.codestyle; +import java.util.List; + import net.sourceforge.pmd.lang.ast.NodeStream; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; +import net.sourceforge.pmd.properties.PropertyDescriptor; +import net.sourceforge.pmd.properties.PropertyFactory; public class OnlyOneReturnRule extends AbstractJavaRulechainRule { + private static final PropertyDescriptor> IGNORED_METHOD_NAMES + = PropertyFactory.stringListProperty("ignoredMethodNames") + .defaultValues("compareTo", "equals") + .desc("Method names that are ignored from checking for only one return.") + .build(); + public OnlyOneReturnRule() { super(ASTMethodDeclaration.class); + definePropertyDescriptor(IGNORED_METHOD_NAMES); } @Override public Object visit(ASTMethodDeclaration node, Object data) { - if (node.getBody() == null) { + if (node.getBody() == null || isIgnoredMethod(node)) { return null; } @@ -29,4 +40,8 @@ public Object visit(ASTMethodDeclaration node, Object data) { } return null; } + + private boolean isIgnoredMethod(ASTMethodDeclaration node) { + return getProperty(IGNORED_METHOD_NAMES).contains(node.getName()); + } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/OnlyOneReturn.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/OnlyOneReturn.xml index 24e16885ee9..d4051e36c64 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/OnlyOneReturn.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/OnlyOneReturn.xml @@ -126,6 +126,36 @@ public class OnlyOneReturn { } }; } +} + ]]> + + + + #4257 allow ignoring methods, compareTo and equals as default + 0 + { + private String name = "Name"; + private int age = 27; + + @Override + public int compareTo(Person other) { + if (other == null) return 1; + if (this.age < other.age) return -1; + if (this.age > other.age) return 1; + return this.name.compareTo(other.name); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + Person other = (Person) obj; + if (this.age != other.age) return false; + return Objects.equals(this.name, other.name); + } } ]]> From f99ae4e248b9f8833a35a5af2336641e7d6ad0a0 Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Fri, 5 Dec 2025 19:33:13 +0100 Subject: [PATCH 1747/1962] Fix: Allow empty default constructor with Javadoc --- .../rule/codestyle/UnnecessaryConstructorRule.java | 8 ++++++-- .../rule/codestyle/xml/UnnecessaryConstructor.xml | 13 +++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java index cee6ab5c463..03935355b6a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java @@ -56,8 +56,12 @@ public Object visit(ASTEnumDeclaration node, Object data) { private void checkClassOrEnum(ASTTypeDeclaration node, Object data) { List ctors = node.getDeclarations(ASTConstructorDeclaration.class).take(2).toList(); - if (ctors.size() == 1 && isExplicitDefaultConstructor(node, ctors.get(0))) { - asCtx(data).addViolation(ctors.get(0)); + if (ctors.size() != 1) { + return; + } + ASTConstructorDeclaration ctor = ctors.get(0); + if (isExplicitDefaultConstructor(node, ctor) && ctor.getJavadocComment() == null) { + asCtx(data).addViolation(ctor); } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryConstructor.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryConstructor.xml index a656bfd98cb..127b03ee707 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryConstructor.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryConstructor.xml @@ -229,6 +229,19 @@ public class Bar extends Foo { public class Bar extends Foo { @Autowired public Bar() {} +} + ]]> + + + + #6284 false positive on JavaDoc-bearing constructor + 0 + From 2a5e0616b5ea9f81249316d7d1f305699d840fa4 Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Sun, 7 Dec 2025 19:33:57 +0100 Subject: [PATCH 1748/1962] Fix: Consecutive append in blockless if Consecutive appends in if-statements without blocks are siblings but should not be reported. --- .../ConsecutiveAppendsShouldReuseRule.java | 6 +++++- .../xml/ConsecutiveAppendsShouldReuse.xml | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveAppendsShouldReuseRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveAppendsShouldReuseRule.java index a0324def94c..49e735c5a00 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveAppendsShouldReuseRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/ConsecutiveAppendsShouldReuseRule.java @@ -12,6 +12,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTAssignmentExpression; import net.sourceforge.pmd.lang.java.ast.ASTExpression; import net.sourceforge.pmd.lang.java.ast.ASTExpressionStatement; +import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; import net.sourceforge.pmd.lang.java.ast.ASTLocalVariableDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; import net.sourceforge.pmd.lang.java.ast.ASTVariableId; @@ -36,7 +37,10 @@ public Object visit(ASTExpressionStatement node, Object data) { @Nullable JVariableSymbol variable = getVariableAppended(node); if (variable != null) { @Nullable JVariableSymbol nextVariable = getVariableAppended((ASTExpressionStatement) nextSibling); - if (nextVariable != null && nextVariable.equals(variable)) { + if (nextVariable != null + && nextVariable.equals(variable) + && !(node.getParent() instanceof ASTIfStatement) + ) { asCtx(data).addViolation(node); } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/ConsecutiveAppendsShouldReuse.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/ConsecutiveAppendsShouldReuse.xml index 863971af4b7..5ced7a5d867 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/ConsecutiveAppendsShouldReuse.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/ConsecutiveAppendsShouldReuse.xml @@ -299,4 +299,19 @@ public class Foo { } ]]> + + #4910 if-statement without blocks + 0 + + From 979f5819c3d848cad2342baa90cd58a4d46c9b2e Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Mon, 8 Dec 2025 17:25:16 +0100 Subject: [PATCH 1749/1962] Fix: Report boolean local variables as unconditional if This excludes compile time constants. --- .../main/resources/category/java/errorprone.xml | 6 ++++++ .../errorprone/xml/UnconditionalIfStatement.xml | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 2383ed7754d..167430d23a2 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -3234,6 +3234,12 @@ Do not use "if" statements whose conditionals are always true or always false. diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UnconditionalIfStatement.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UnconditionalIfStatement.xml index 8adff01f55d..552e8751201 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UnconditionalIfStatement.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UnconditionalIfStatement.xml @@ -51,6 +51,22 @@ public class Foo { void bar(Object x, boolean y) { if (y == true) {} } +} + ]]> + + + + #5882 false-negative if true/false is not literal + 1 + 4 + From c87cd30636b2b2913c75a1d61aa295a3a3e198fa Mon Sep 17 00:00:00 2001 From: mrclmh <2975481+mrclmh@users.noreply.github.com> Date: Mon, 8 Dec 2025 18:49:29 +0100 Subject: [PATCH 1750/1962] Fix: Detect array copy loop with switch break --- .../resources/category/java/performance.xml | 2 +- .../rule/performance/xml/AvoidArrayLoops.xml | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/resources/category/java/performance.xml b/pmd-java/src/main/resources/category/java/performance.xml index 012e66ad071..7dd9ce5d819 100644 --- a/pmd-java/src/main/resources/category/java/performance.xml +++ b/pmd-java/src/main/resources/category/java/performance.xml @@ -71,7 +71,7 @@ If you want to copy/move elements inside the _same_ array (e.g. shift the elemen //(ForStatement[ForUpdate//(UnaryExpression[@Operator=('++','--')] | AssignmentExpression[@Operator = ('+=', '-=')][NumericLiteral[@Image = '1']])] | WhileStatement | DoStatement) [not(.//ContinueStatement)] - [not(.//BreakStatement)] + [not(.//BreakStatement[not(parent::SwitchFallthroughBranch)])] [not(.//ThrowStatement)] [not(.//ReturnStatement)] [count(Block//AssignmentExpression[@Operator='='] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/AvoidArrayLoops.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/AvoidArrayLoops.xml index eec6f0a93b0..24316537cfa 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/AvoidArrayLoops.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/AvoidArrayLoops.xml @@ -448,6 +448,27 @@ class AvoidArrayLoopsSamples { } } } +]]> + + + + #5877 false-negative when break inside switch statement + 1 + 4 + From 9ed04db9dd17346fe9f56976f0ce90f02a2d6499 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Dec 2025 20:34:38 +0100 Subject: [PATCH 1751/1962] chore(deps): bump actions/create-github-app-token from 2.2.0 to 2.2.1 (#6318) Bumps [actions/create-github-app-token](https://github.com/actions/create-github-app-token) from 2.2.0 to 2.2.1. - [Release notes](https://github.com/actions/create-github-app-token/releases) - [Commits](https://github.com/actions/create-github-app-token/compare/7e473efe3cb98aa54f8d4bac15400b15fad77d94...29824e69f54612133e76f7eaac726eef6c875baf) --- updated-dependencies: - dependency-name: actions/create-github-app-token dependency-version: 2.2.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/publish-pull-requests.yml | 2 +- .github/workflows/publish-release.yml | 4 ++-- .github/workflows/publish-snapshot.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish-pull-requests.yml b/.github/workflows/publish-pull-requests.yml index 294b16ab6ad..67c1581503b 100644 --- a/.github/workflows/publish-pull-requests.yml +++ b/.github/workflows/publish-pull-requests.yml @@ -21,7 +21,7 @@ jobs: run: shell: bash steps: - - uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94 #v2.2.0 + - uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf #v2.2.1 id: pmd-actions-helper-app-token with: app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 88fac66479b..0520e88e54f 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -504,7 +504,7 @@ jobs: --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-src.zip" printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-doc.zip" - - uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94 #v2.2.0 + - uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf #v2.2.1 id: pmd-actions-helper-app-token with: app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} @@ -760,7 +760,7 @@ jobs: run: shell: bash steps: - - uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94 #v2.2.0 + - uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf #v2.2.1 id: pmd-actions-helper-app-token with: app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 7bab9bff054..627be2d332f 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -495,7 +495,7 @@ jobs: --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-src.zip" printenv MAVEN_GPG_PASSPHRASE | gpg --pinentry-mode loopback --passphrase-fd 0 --batch --no-tty \ --status-fd 1 --armor --detach-sign --sign "pmd-dist-${PMD_VERSION}-doc.zip" - - uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94 #v2.2.0 + - uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf #v2.2.1 id: pmd-actions-helper-app-token with: app-id: ${{ secrets.PMD_ACTIONS_HELPER_ID }} From 0896d2022c593d5fc539baa6db0a830b34be6ac2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Dec 2025 20:35:03 +0100 Subject: [PATCH 1752/1962] chore(deps): bump actions/setup-java from 5.0.0 to 5.1.0 (#6319) Bumps [actions/setup-java](https://github.com/actions/setup-java) from 5.0.0 to 5.1.0. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/dded0888837ed1f317902acf8a20df0ad188d165...f2beeb24e141e01a676f977032f5a29d81c9e27e) --- updated-dependencies: - dependency-name: actions/setup-java dependency-version: 5.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 14 +++++++------- .github/workflows/publish-release.yml | 6 +++--- .github/workflows/publish-snapshot.yml | 10 +++++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3718370a267..44d2cdfa70d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,7 +24,7 @@ jobs: shell: bash steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 - - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 + - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' java-version: '17' @@ -82,7 +82,7 @@ jobs: shell: bash steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 - - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 + - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' java-version: '17' @@ -122,7 +122,7 @@ jobs: os: [ ubuntu-latest, windows-latest, macos-latest ] steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 - - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 + - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 # under linux we execute more extensive integration tests with various java versions if: ${{ runner.os == 'Linux' }} with: @@ -132,7 +132,7 @@ jobs: 11 21 25 - - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 + - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 # default java version for all os is 17 with: distribution: 'temurin' @@ -173,7 +173,7 @@ jobs: shell: bash steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 - - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 + - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' java-version: '17' @@ -259,7 +259,7 @@ jobs: shell: bash steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 - - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 + - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' java-version: '17' @@ -314,7 +314,7 @@ jobs: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 with: fetch-depth: 2 - - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 + - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' java-version: | diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 0520e88e54f..98cc05e32ec 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -34,7 +34,7 @@ jobs: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 with: ref: ${{ github.event.workflow_run.head_branch }} - - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 + - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' java-version: '17' @@ -88,7 +88,7 @@ jobs: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 with: ref: ${{ github.event.workflow_run.head_branch }} - - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 + - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' java-version: '17' @@ -625,7 +625,7 @@ jobs: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 with: ref: ${{ github.event.workflow_run.head_branch }} - - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 + - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' java-version: | diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 627be2d332f..7fac00b6fc0 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -33,7 +33,7 @@ jobs: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 with: ref: main - - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 + - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' java-version: '17' @@ -79,7 +79,7 @@ jobs: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 with: ref: main - - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 + - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' java-version: '17' @@ -642,7 +642,7 @@ jobs: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 with: ref: main - - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 + - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' java-version: | @@ -729,7 +729,7 @@ jobs: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 with: ref: main - - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 + - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' java-version: '17' @@ -766,7 +766,7 @@ jobs: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 with: ref: main - - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 #v5.0.0 + - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' java-version: '17' From 88dc80c623d3c4b36f4fec8618baac02ed3d2132 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Dec 2025 20:35:32 +0100 Subject: [PATCH 1753/1962] chore(deps): bump ruby/setup-ruby from 1.268.0 to 1.269.0 (#6320) Bumps [ruby/setup-ruby](https://github.com/ruby/setup-ruby) from 1.268.0 to 1.269.0. - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/8aeb6ff8030dd539317f8e1769a044873b56ea71...d697be2f83c6234b20877c3b5eac7a7f342f0d0c) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-version: 1.269.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 4 ++-- .github/workflows/publish-release.yml | 2 +- .github/workflows/publish-snapshot.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 44d2cdfa70d..77971d2f193 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -280,7 +280,7 @@ jobs: -Pgenerate-rule-docs,fastSkip \ -DskipTests -Dassembly.skipAssembly=true - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 #v1.268.0 + uses: ruby/setup-ruby@d697be2f83c6234b20877c3b5eac7a7f342f0d0c #v1.269.0 with: ruby-version: 3.3 - name: Setup bundler @@ -321,7 +321,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 #v1.268.0 + uses: ruby/setup-ruby@d697be2f83c6234b20877c3b5eac7a7f342f0d0c #v1.269.0 with: ruby-version: 3.3 - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4.3.0 diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 98cc05e32ec..8f7c1b01181 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -632,7 +632,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 #v1.268.0 + uses: ruby/setup-ruby@d697be2f83c6234b20877c3b5eac7a7f342f0d0c #v1.269.0 with: ruby-version: 3.3 - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4.3.0 diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 7fac00b6fc0..96d1b2a1cb8 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -649,7 +649,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 #v1.268.0 + uses: ruby/setup-ruby@d697be2f83c6234b20877c3b5eac7a7f342f0d0c #v1.269.0 with: ruby-version: 3.3 - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 #v4.3.0 From 81ed7ffcf52f4a87db1d724d88b4f6b09820945f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Dec 2025 20:36:23 +0100 Subject: [PATCH 1754/1962] chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.18.1 to 1.18.2 (#6321) chore(deps-dev): bump net.bytebuddy:byte-buddy-agent Bumps [net.bytebuddy:byte-buddy-agent](https://github.com/raphw/byte-buddy) from 1.18.1 to 1.18.2. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.18.1...byte-buddy-1.18.2) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy-agent dependency-version: 1.18.2 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8f29af45544..2aa25079911 100644 --- a/pom.xml +++ b/pom.xml @@ -1048,7 +1048,7 @@ net.bytebuddy byte-buddy-agent - 1.18.1 + 1.18.2 test From 65a5dbf5b15665c8c5f395cebffbed74d6cdf97a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Dec 2025 20:36:51 +0100 Subject: [PATCH 1755/1962] chore(deps): bump com.google.protobuf:protobuf-java from 4.33.1 to 4.33.2 (#6323) chore(deps): bump com.google.protobuf:protobuf-java Bumps [com.google.protobuf:protobuf-java](https://github.com/protocolbuffers/protobuf) from 4.33.1 to 4.33.2. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Commits](https://github.com/protocolbuffers/protobuf/commits) --- updated-dependencies: - dependency-name: com.google.protobuf:protobuf-java dependency-version: 4.33.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2aa25079911..788ac271963 100644 --- a/pom.xml +++ b/pom.xml @@ -1138,7 +1138,7 @@ com.google.protobuf protobuf-java - 4.33.1 + 4.33.2 LiteralText (XPath) - java-bestpractices - [#6257](https://github.com/pmd/pmd/issues/6257): \[java] UnusedLocalVariable: False positive with instanceof pattern guard From 991ddb316c40a1206194fb53c9a4c648c8e5d6ea Mon Sep 17 00:00:00 2001 From: Mohamed Hamed Date: Fri, 19 Dec 2025 20:31:02 +0100 Subject: [PATCH 1782/1962] [java] Fix UnusedLocalVariable false positive in brace-less for-each (#6328) --- .../table/internal/SymbolTableResolver.java | 34 +++++++++---------- .../bestpractices/xml/UnusedLocalVariable.xml | 15 ++++++++ 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java index e78844bfa8d..3b4db13d69e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/table/internal/SymbolTableResolver.java @@ -470,24 +470,6 @@ private int processLocalVarDecl(ASTLocalVariableDeclaration st, @NonNull Referen return pushed; } - @Override - public Void visit(ASTForeachStatement node, @NonNull ReferenceCtx ctx) { - // the varId is only in scope in the body and not the iterable expr - setTopSymbolTableAndVisit(node.getIterableExpr(), ctx); - - ASTVariableId varId = node.getVarId(); - setTopSymbolTableAndVisit(varId.getTypeNode(), ctx); - - int pushed = pushOnStack(f.localVarSymTable(top(), enclosing(), varId)); - ASTStatement body = node.getBody(); - // unless it's a block the body statement may never set a - // symbol table that would have this table as parent, - // so the table would be dangling - setTopSymbolTableAndVisit(body, ctx); - popStack(pushed); - return null; - } - @Override public Void visit(ASTTryStatement node, @NonNull ReferenceCtx ctx) { @@ -704,6 +686,22 @@ public PSet visit(ASTForStatement node, @NonNull ReferenceCtx ctx } } + @Override + public PSet visit(ASTForeachStatement node, @NonNull ReferenceCtx ctx) { + MyVisitor.this.setTopSymbolTableAndVisit(node.getIterableExpr(), ctx); + + ASTVariableId varId = node.getVarId(); + MyVisitor.this.setTopSymbolTableAndVisit(varId.getTypeNode(), ctx); + + int pushed = pushOnStack(f.localVarSymTable(top(), enclosing(), varId)); + + setTopSymbolTableAndVisit(node.getBody(), ctx); + + popStack(pushed); + + return BindSet.noBindings(); + } + private boolean hasNoBreakContainingStmt(ASTLoopStatement node) { Set containingStatements = node.ancestorsOrSelf() .filter(JavaAstUtils::mayBeBreakTarget) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml index 75fae9aa729..96eeaa7c488 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/UnusedLocalVariable.xml @@ -749,4 +749,19 @@ class Foo { ]]> java 21 + + Pattern variable in for-each without brackets (Issue 6328) + 0 + + From 5cd9580e943c9f8759cddaf3b0740fc537d29beb Mon Sep 17 00:00:00 2001 From: Mohamed Hamed Date: Fri, 19 Dec 2025 20:31:18 +0100 Subject: [PATCH 1783/1962] [java] Update release notes for #6328 --- docs/pages/release_notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 3bbdf6ec381..5ad84634feb 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -31,6 +31,7 @@ This is a {{ site.pmd.release_type }} release. * [#6028](https://github.com/pmd/pmd/issues/6028): \[java] UnusedPrivateMethod: False positive with raw type for generic method * [#6257](https://github.com/pmd/pmd/issues/6257): \[java] UnusedLocalVariable: False positive with instanceof pattern guard * [#6291](https://github.com/pmd/pmd/issues/6291): \[java] EnumComparison: False positive for any object when object.equals(null) + * [#6328](https://github.com/pmd/pmd/issues/6328): \[java] UnusedLocalVariable: False positive for pattern variable in for-each without braces * java-codestyle * [#5043](https://github.com/pmd/pmd/issues/5043): \[java] LambdaCanBeMethodReference: False positive on overloaded methods * [#6279](https://github.com/pmd/pmd/issues/6279): \[java] EmptyMethodInAbstractClassShouldBeAbstract: False positive for final empty methods @@ -52,4 +53,3 @@ This is a {{ site.pmd.release_type }} release. {% endtocmaker %} - From 8990dc8de733fb7009f204917cf29bfed64841a8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 21 Dec 2025 18:41:54 +0100 Subject: [PATCH 1784/1962] [java] AssignmentInOperand - add test case for chained assignments This was mentioned in https://github.com/pmd/pmd/blob/e50ac051a8106a0cdd60762094c658d76c4daa98/docs/pages/pmd/devdocs/roadmap.md?plain=1#L65 --- .../rule/errorprone/xml/AssignmentInOperand.xml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml index 3926f4988b5..2ab2df95b59 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/AssignmentInOperand.xml @@ -405,4 +405,21 @@ public class Foo { } ]]> + + + Chained assignments + 1 + 4 + + Avoid assignment to b in operand + + + From e53d1c8a121555725e9cbae59f54b6c5aed06e23 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 21 Dec 2025 19:00:17 +0100 Subject: [PATCH 1785/1962] [doc] Update release notes (#6237, #6295) --- docs/pages/release_notes.md | 5 +++++ .../pmd/lang/java/types/OverloadSelectionResult.java | 1 + 2 files changed, 6 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..e7bad0d0beb 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,9 +25,14 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy ### ๐Ÿ›๏ธ Fixed Issues +* java-codestyle + * [#6237](https://github.com/pmd/pmd/issues/6237): \[java] UnnecessaryCast: ContextedRuntimeException when parsing switch expression with lambdas ### ๐Ÿšจ๏ธ API Changes +#### Experimental API +* pmd-java: {%jdoc !!java::lang.java.types.OverloadSelectionResult#hadSeveralApplicableOverloads()%} + ### โœจ๏ธ Merged pull requests diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java index 927ee989e18..adcd1854164 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java @@ -107,6 +107,7 @@ default JTypeMirror ithFormalParam(int i) { /** * Return whether several overloads were applicable, and needed to * be disambiguated through specificity checks. + * @experimental Since 7.20.0 */ @Experimental boolean hadSeveralApplicableOverloads(); From f968a49be97a1bbd4bc24eb8a8b848a476602c41 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 21 Dec 2025 19:18:36 +0100 Subject: [PATCH 1786/1962] [doc] Update release notes (#4282, #6296) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..70ecfe34a99 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,6 +25,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy ### ๐Ÿ›๏ธ Fixed Issues +* java-bestpractices + * [#4282](https://github.com/pmd/pmd/issues/4282): \[java] GuardLogStatement: False positive when guard is not a direct parent ### ๐Ÿšจ๏ธ API Changes From 2f9a13f8ac4c37eb218317887bca0732e2052ed0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 21 Dec 2025 19:28:32 +0100 Subject: [PATCH 1787/1962] [java] Update release notes (#6299) --- docs/pages/release_notes.md | 2 ++ .../java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabel.java | 1 + .../java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLike.java | 1 + 3 files changed, 4 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index aae6ad90a95..5a07cc9616c 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -26,6 +26,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿ›๏ธ Fixed Issues +* java + * [#6299](https://github.com/pmd/pmd/issues/6299): \[java] Fix grammar of switch label - java-bestpractices - [#6257](https://github.com/pmd/pmd/issues/6257): \[java] UnusedLocalVariable: False positive with instanceof pattern guard diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabel.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabel.java index 386cc9d163f..acf4372dd79 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabel.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLabel.java @@ -54,6 +54,7 @@ public boolean isDefault() { /** * Returns true if this is the label {@code case null} or {@code case null, default}. + * @since 7.20.0 */ public boolean isCaseNull() { return getFirstChild() instanceof ASTNullLiteral; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLike.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLike.java index 96299bee7be..209f33a8e49 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLike.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLike.java @@ -177,6 +177,7 @@ default boolean isFallthroughSwitch() { * Any switch that does not have this branch throws NullPointerException * at runtime if the scrutinee is null. * This is a feature of Java 25. + * @since 7.20.0 */ default boolean isNullTolerant() { return getBranches().map(ASTSwitchBranch::getLabel).any(ASTSwitchLabel::isCaseNull); From d4dc19f66e0193d705b4ad9ec4bd8dad63b1e113 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 22 Dec 2025 10:32:20 +0100 Subject: [PATCH 1788/1962] [java] OnlyOneReturn - add test case for new property --- .../java/rule/codestyle/xml/OnlyOneReturn.xml | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/OnlyOneReturn.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/OnlyOneReturn.xml index d4051e36c64..d2134b48164 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/OnlyOneReturn.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/OnlyOneReturn.xml @@ -156,6 +156,38 @@ public class Person implements Comparable { if (this.age != other.age) return false; return Objects.equals(this.name, other.name); } +} + ]]> + + + + #4257 check compareTo and equals when property ignoredMethodNames is empty + + 6 + 9,10,11,17,18,20 + { + private String name = "Name"; + private int age = 27; + + @Override + public int compareTo(Person other) { + if (other == null) return 1; // line 9 + if (this.age < other.age) return -1; // line 10 + if (this.age > other.age) return 1; // line 11 + return this.name.compareTo(other.name); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; // line 17 + if (obj == null || getClass() != obj.getClass()) return false; // line 18 + Person other = (Person) obj; + if (this.age != other.age) return false; // line 20 + return Objects.equals(this.name, other.name); + } } ]]> From a2355c355d758a97d23d5132df7a280389444487 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 22 Dec 2025 10:32:40 +0100 Subject: [PATCH 1789/1962] [doc] Update release notes (#4257, #6309) --- docs/pages/release_notes.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index aae6ad90a95..97b98ecc7ac 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -24,10 +24,17 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy +### ๐ŸŒŸ๏ธ Changed Rules +* The Java rule {%rule java/codestyle/OnlyOneReturn %} has a new property `ignoredMethodNames`. This property by + default is set to `compareTo` and `equals`, thus this rule now by default allows multiple return statements + for these methods. To restore the old behavior, simply set this property to an empty value. + ### ๐Ÿ›๏ธ Fixed Issues - java-bestpractices - [#6257](https://github.com/pmd/pmd/issues/6257): \[java] UnusedLocalVariable: False positive with instanceof pattern guard +* java-codestyle + * [#4257](https://github.com/pmd/pmd/issues/4257): \[java] OnlyOneReturn: False positive with equals method ### ๐Ÿšจ๏ธ API Changes From 7a3219538d113e5adf0d9eca9753770d013e6b5e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 22 Dec 2025 10:48:53 +0100 Subject: [PATCH 1790/1962] [core] Exclude UnnecessaryWarningSuppression for dogfood to succeed --- pmd-core/pmd-core-exclude-pmd.properties | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pmd-core/pmd-core-exclude-pmd.properties b/pmd-core/pmd-core-exclude-pmd.properties index 6e636acc2fe..5c33c361561 100644 --- a/pmd-core/pmd-core-exclude-pmd.properties +++ b/pmd-core/pmd-core-exclude-pmd.properties @@ -1,2 +1,4 @@ # ignore missing override for isEmpty() method, see #4291 #5299 net.sourceforge.pmd.lang.document.Chars=MissingOverride +# Will be fixed by #6311 +net.sourceforge.pmd.lang.rule.RuleSetLoader=UnnecessaryWarningSuppression From dd5850ad9a64a923573808c38653f923e3b4c02d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 22 Dec 2025 10:49:39 +0100 Subject: [PATCH 1791/1962] [doc] Update release notes (#6284, #6311) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 4d437df130e..90f07e1b997 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -44,6 +44,7 @@ This is a {{ site.pmd.release_type }} release. * [#5043](https://github.com/pmd/pmd/issues/5043): \[java] LambdaCanBeMethodReference: False positive on overloaded methods * [#6237](https://github.com/pmd/pmd/issues/6237): \[java] UnnecessaryCast: ContextedRuntimeException when parsing switch expression with lambdas * [#6279](https://github.com/pmd/pmd/issues/6279): \[java] EmptyMethodInAbstractClassShouldBeAbstract: False positive for final empty methods + * [#6284](https://github.com/pmd/pmd/issues/6284): \[java] UnnecessaryConstructor: False positive for JavaDoc-bearing constructor * java-errorprone * [#6276](https://github.com/pmd/pmd/issues/6276): \[java] NullAssignment: False positive when assigning null to a final field in a constructor * [#6343](https://github.com/pmd/pmd/issues/6343): \[java] MissingStaticMethodInNonInstantiatableClass: False negative when method in nested class returns null From 4489484dc4834a82dc7735fb247a9190d2a5fa8d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 22 Dec 2025 11:57:27 +0100 Subject: [PATCH 1792/1962] More exclusions for UnnecessaryWarningSuppression for dogfood to succeed --- pmd-core/pmd-core-exclude-pmd.properties | 2 +- .../main/java/net/sourceforge/pmd/lang/rule/RuleSetLoader.java | 2 +- pmd-java/pmd-java-exclude-pmd.properties | 2 ++ .../net/sourceforge/pmd/lang/java/types/TypePrettyPrint.java | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pmd-core/pmd-core-exclude-pmd.properties b/pmd-core/pmd-core-exclude-pmd.properties index 5c33c361561..ebad65194bd 100644 --- a/pmd-core/pmd-core-exclude-pmd.properties +++ b/pmd-core/pmd-core-exclude-pmd.properties @@ -1,4 +1,4 @@ # ignore missing override for isEmpty() method, see #4291 #5299 net.sourceforge.pmd.lang.document.Chars=MissingOverride -# Will be fixed by #6311 +# Will be fixed by #6311 / #6284 net.sourceforge.pmd.lang.rule.RuleSetLoader=UnnecessaryWarningSuppression diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetLoader.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetLoader.java index 9d0cc5aa4f4..dd41b6f76bf 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetLoader.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetLoader.java @@ -48,7 +48,7 @@ public final class RuleSetLoader { * Create a new RuleSetLoader with a default configuration. * The defaults are described on each configuration method of this class. */ - public RuleSetLoader() { // NOPMD UnnecessaryConstructor + public RuleSetLoader() { // NOPMD UnnecessaryConstructor #6311 / #6284 // default } diff --git a/pmd-java/pmd-java-exclude-pmd.properties b/pmd-java/pmd-java-exclude-pmd.properties index 714afb9328a..a0c2d93336e 100644 --- a/pmd-java/pmd-java-exclude-pmd.properties +++ b/pmd-java/pmd-java-exclude-pmd.properties @@ -3,3 +3,5 @@ # This revealed a false positive of the rule MissingStaticMethodInNonInstantiatableClass, we we need # to suppress for dogfood runs. After 7.20.0, this exclusion can be removed. net.sourceforge.pmd.lang.java.ast.InternalInterfaces=UnnecessaryWarningSuppression +# Will be fixed by #6311 / #6284 +net.sourceforge.pmd.lang.java.types.TypePrettyPrint.TypePrettyPrinter=UnnecessaryWarningSuppression \ No newline at end of file diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypePrettyPrint.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypePrettyPrint.java index fa531f8d6ad..14efa0b1026 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypePrettyPrint.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypePrettyPrint.java @@ -59,7 +59,7 @@ public static class TypePrettyPrinter { private boolean qualifyAnnotations = false; /** Create a new pretty printer with the default configuration. */ - public TypePrettyPrinter() { // NOPMD + public TypePrettyPrinter() { // NOPMD UnnecessaryConstructor #6311 / #6284 // default } From aa9fce842cb087a7db47173a2c6a2d7a1226d562 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Dec 2025 12:55:03 +0100 Subject: [PATCH 1793/1962] chore(deps-dev): bump org.apache.logging.log4j:log4j-core from 2.25.2 to 2.25.3 in /pmd-java (#6347) chore(deps-dev): bump org.apache.logging.log4j:log4j-core in /pmd-java Bumps org.apache.logging.log4j:log4j-core from 2.25.2 to 2.25.3. --- updated-dependencies: - dependency-name: org.apache.logging.log4j:log4j-core dependency-version: 2.25.3 dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-java/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 3a70fb0a74a..5a1fab7d0c9 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -12,7 +12,7 @@ - 2.25.2 + 2.25.3 From 85373490dd7514ec353734c2b974f682a235db8a Mon Sep 17 00:00:00 2001 From: gianmarco Date: Tue, 23 Dec 2025 12:02:37 +0100 Subject: [PATCH 1794/1962] Fix malformed Javadoc HTML in JspDocStyleTest --- .../net/sourceforge/pmd/lang/jsp/ast/JspDocStyleTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/JspDocStyleTest.java b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/JspDocStyleTest.java index c5f890ea229..2977d34acc3 100644 --- a/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/JspDocStyleTest.java +++ b/pmd-jsp/src/test/java/net/sourceforge/pmd/lang/jsp/ast/JspDocStyleTest.java @@ -888,19 +888,19 @@ void unclosedEndOfDoc() { private static final String TEST_MULTIPLE_NESTED_TAGS = " "; /** - * will close before , thus leaving to remain unclosed + * {@code } will close before {@code }, thus leaving {@code } to remain unclosed */ private static final String TEST_UNCLOSED_END_AFTER_PARENT_CLOSE = " aa bb "; /** - * is just a dangling closing tag not matching any parent. The parser + * {@code } is just a dangling closing tag not matching any parent. The parser * should disregard it */ private static final String TEST_UNCLOSED_UNMATCHED_CLOSING_TAG = " "; /** - * First tag does not close. The first closing of will match the - * second opening of a. Another rogue is there for testing compliance + * First {@code } tag does not close. The first closing of {@code } will match the + * second opening of a. Another rogue {@code } is there for testing compliance */ private static final String TEST_UNCLOSED_START_TAG_WITH_UNMATCHED_CLOSE = " "; From 933df731ae15915dcc701e8ac26392fe2159daa8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 24 Dec 2025 09:12:20 +0100 Subject: [PATCH 1795/1962] [doc] Update release notes (#4910, #6313) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index aae6ad90a95..bd693d98429 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -28,6 +28,8 @@ This is a {{ site.pmd.release_type }} release. - java-bestpractices - [#6257](https://github.com/pmd/pmd/issues/6257): \[java] UnusedLocalVariable: False positive with instanceof pattern guard +* java-performance + * [#4910](https://github.com/pmd/pmd/issues/4910): \[java] ConsecutiveAppendsShouldReuse: False positive within if-statement without curly braces ### ๐Ÿšจ๏ธ API Changes From 23dc68641db562606b7622748f05ae8726988dfa Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 24 Dec 2025 09:41:10 +0100 Subject: [PATCH 1796/1962] [doc] Update release notes (#5877, #6316) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index aae6ad90a95..3f8a18adf5b 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -28,6 +28,8 @@ This is a {{ site.pmd.release_type }} release. - java-bestpractices - [#6257](https://github.com/pmd/pmd/issues/6257): \[java] UnusedLocalVariable: False positive with instanceof pattern guard +* java-performance + * [#5877](https://github.com/pmd/pmd/issues/5877): \[java] AvoidArrayLoops: False negative when break inside switch statement ### ๐Ÿšจ๏ธ API Changes From fb78af2915725b762e495bf7ad93f2ba8599ec1f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Dec 2025 10:29:25 +0100 Subject: [PATCH 1797/1962] chore(deps): bump com.github.siom79.japicmp:japicmp-maven-plugin from 0.24.2 to 0.25.1 (#6350) chore(deps): bump com.github.siom79.japicmp:japicmp-maven-plugin Bumps [com.github.siom79.japicmp:japicmp-maven-plugin](https://github.com/siom79/japicmp) from 0.24.2 to 0.25.1. - [Release notes](https://github.com/siom79/japicmp/releases) - [Changelog](https://github.com/siom79/japicmp/blob/master/release.py) - [Commits](https://github.com/siom79/japicmp/compare/japicmp-base-0.24.2...japicmp-base-0.25.1) --- updated-dependencies: - dependency-name: com.github.siom79.japicmp:japicmp-maven-plugin dependency-version: 0.25.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 004f0d886ce..e9bacda03a7 100644 --- a/pom.xml +++ b/pom.xml @@ -694,7 +694,7 @@ com.github.siom79.japicmp japicmp-maven-plugin - 0.24.2 + 0.25.1 true From 09636126ea0787295c017d2dd0a253cfb0f6f413 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Dec 2025 10:29:39 +0100 Subject: [PATCH 1798/1962] chore(deps): bump ruby/setup-ruby from 1.270.0 to 1.275.0 (#6352) Bumps [ruby/setup-ruby](https://github.com/ruby/setup-ruby) from 1.270.0 to 1.275.0. - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/ac793fdd38cc468a4dd57246fa9d0e868aba9085...d354de180d0c9e813cfddfcbdc079945d4be589b) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-version: 1.275.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 4 ++-- .github/workflows/publish-release.yml | 2 +- .github/workflows/publish-snapshot.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e601dd77e82..7338bf909d3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -280,7 +280,7 @@ jobs: -Pgenerate-rule-docs,fastSkip \ -DskipTests -Dassembly.skipAssembly=true - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@ac793fdd38cc468a4dd57246fa9d0e868aba9085 #v1.270.0 + uses: ruby/setup-ruby@d354de180d0c9e813cfddfcbdc079945d4be589b #v1.275.0 with: ruby-version: 3.3 - name: Setup bundler @@ -321,7 +321,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@ac793fdd38cc468a4dd57246fa9d0e868aba9085 #v1.270.0 + uses: ruby/setup-ruby@d354de180d0c9e813cfddfcbdc079945d4be589b #v1.275.0 with: ruby-version: 3.3 - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb #v5.0.1 diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 8f156a1be3c..1b8e09fa569 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -632,7 +632,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@ac793fdd38cc468a4dd57246fa9d0e868aba9085 #v1.270.0 + uses: ruby/setup-ruby@d354de180d0c9e813cfddfcbdc079945d4be589b #v1.275.0 with: ruby-version: 3.3 - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb #v5.0.1 diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index ff8fb9bcb1c..e8fb5835cc6 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -649,7 +649,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@ac793fdd38cc468a4dd57246fa9d0e868aba9085 #v1.270.0 + uses: ruby/setup-ruby@d354de180d0c9e813cfddfcbdc079945d4be589b #v1.275.0 with: ruby-version: 3.3 - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb #v5.0.1 From 08be4aac116ea008ee1f542f644a757c58eb3a2a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Dec 2025 10:29:54 +0100 Subject: [PATCH 1799/1962] chore(deps): bump org.ow2.asm:asm from 9.9 to 9.9.1 (#6353) Bumps org.ow2.asm:asm from 9.9 to 9.9.1. --- updated-dependencies: - dependency-name: org.ow2.asm:asm dependency-version: 9.9.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e9bacda03a7..533028c66c0 100644 --- a/pom.xml +++ b/pom.xml @@ -882,7 +882,7 @@ org.ow2.asm asm - 9.9 + 9.9.1 org.pcollections From a7e4a8a83f766dd3a9f2fced47d9eb55c5acffba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Dec 2025 10:30:07 +0100 Subject: [PATCH 1800/1962] chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.18.2 to 1.18.3 (#6354) chore(deps-dev): bump net.bytebuddy:byte-buddy-agent Bumps [net.bytebuddy:byte-buddy-agent](https://github.com/raphw/byte-buddy) from 1.18.2 to 1.18.3. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.18.2...byte-buddy-1.18.3) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy-agent dependency-version: 1.18.3 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 533028c66c0..899756de546 100644 --- a/pom.xml +++ b/pom.xml @@ -1048,7 +1048,7 @@ net.bytebuddy byte-buddy-agent - 1.18.2 + 1.18.3 test From d858f5cfd4f066fcde955d850802184fbfd521ec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Dec 2025 10:30:22 +0100 Subject: [PATCH 1801/1962] chore(deps): bump org.sonarsource.scanner.maven:sonar-maven-plugin from 5.4.0.6343 to 5.5.0.6356 (#6356) chore(deps): bump org.sonarsource.scanner.maven:sonar-maven-plugin Bumps [org.sonarsource.scanner.maven:sonar-maven-plugin](https://github.com/SonarSource/sonar-scanner-maven) from 5.4.0.6343 to 5.5.0.6356. - [Release notes](https://github.com/SonarSource/sonar-scanner-maven/releases) - [Commits](https://github.com/SonarSource/sonar-scanner-maven/compare/5.4.0.6343...5.5.0.6356) --- updated-dependencies: - dependency-name: org.sonarsource.scanner.maven:sonar-maven-plugin dependency-version: 5.5.0.6356 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 899756de546..a8d70351b19 100644 --- a/pom.xml +++ b/pom.xml @@ -1310,7 +1310,7 @@ org.sonarsource.scanner.maven sonar-maven-plugin - 5.4.0.6343 + 5.5.0.6356 From 40277d1196d9a75a5d5599a2773149764c4e74a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Dec 2025 10:30:39 +0100 Subject: [PATCH 1802/1962] chore(deps): bump org.apache.commons:commons-text from 1.14.0 to 1.15.0 (#6357) Bumps [org.apache.commons:commons-text](https://github.com/apache/commons-text) from 1.14.0 to 1.15.0. - [Changelog](https://github.com/apache/commons-text/blob/master/RELEASE-NOTES.txt) - [Commits](https://github.com/apache/commons-text/compare/rel/commons-text-1.14.0...rel/commons-text-1.15.0) --- updated-dependencies: - dependency-name: org.apache.commons:commons-text dependency-version: 1.15.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a8d70351b19..2473311de23 100644 --- a/pom.xml +++ b/pom.xml @@ -922,7 +922,7 @@ org.apache.commons commons-text - 1.14.0 + 1.15.0 org.slf4j From 98ac32079ac7becb27eba994c580a36b58cd0e5c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Dec 2025 10:30:54 +0100 Subject: [PATCH 1803/1962] chore(deps): bump bigdecimal from 4.0.0 to 4.0.1 in /docs (#6358) Bumps [bigdecimal](https://github.com/ruby/bigdecimal) from 4.0.0 to 4.0.1. - [Release notes](https://github.com/ruby/bigdecimal/releases) - [Changelog](https://github.com/ruby/bigdecimal/blob/master/CHANGES.md) - [Commits](https://github.com/ruby/bigdecimal/compare/v4.0.0...v4.0.1) --- updated-dependencies: - dependency-name: bigdecimal dependency-version: 4.0.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index 6d422c67e89..68375cd7261 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -18,7 +18,7 @@ GEM public_suffix (>= 2.0.2, < 7.0) base64 (0.2.0) benchmark (0.4.1) - bigdecimal (4.0.0) + bigdecimal (4.0.1) coffee-script (2.4.1) coffee-script-source execjs From 87d246bca39071f4eed142c286197fff19b5bd13 Mon Sep 17 00:00:00 2001 From: Mohamed Hamed Date: Fri, 26 Dec 2025 13:30:13 +0100 Subject: [PATCH 1804/1962] [java] Fix #6234: Parser fails to parse switch expressions in super() constructor calls --- docs/pages/release_notes.md | 2 + pmd-java/src/main/javacc/Java.jjt | 40 ++++++++++++++++--- .../lang/java/ast/ASTSwitchExpressionTests.kt | 28 +++++++++++++ .../pmd/lang/java/ast/GitHubBug6234.java | 19 +++++++++ 4 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug6234.java diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 3bbdf6ec381..d120b5cea22 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -27,6 +27,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿ›๏ธ Fixed Issues * core * [#6330](https://github.com/pmd/pmd/issues/6330): \[core] "Unable to create ValueRepresentation" when using @LiteralText (XPath) +* java + * [#6234](https://github.com/pmd/pmd/issues/6234): \[java] Parser fails to parse switch expressions in super() constructor calls * java-bestpractices * [#6028](https://github.com/pmd/pmd/issues/6028): \[java] UnusedPrivateMethod: False positive with raw type for generic method * [#6257](https://github.com/pmd/pmd/issues/6257): \[java] UnusedLocalVariable: False positive with instanceof pattern guard diff --git a/pmd-java/src/main/javacc/Java.jjt b/pmd-java/src/main/javacc/Java.jjt index e87a27bb73d..fcc287e424f 100644 --- a/pmd-java/src/main/javacc/Java.jjt +++ b/pmd-java/src/main/javacc/Java.jjt @@ -1439,17 +1439,47 @@ private void ConstructorBlock() #Block: { "{" ( - LOOKAHEAD(ExplicitConstructorInvocation()) ExplicitConstructorInvocation() + LOOKAHEAD(ExplicitCtorInvocLookahead()) ExplicitConstructorInvocation() | ( LOOKAHEAD(2) BlockStatement() )* - [ LOOKAHEAD(ExplicitConstructorInvocation()) ExplicitConstructorInvocation() ] + [ LOOKAHEAD(ExplicitCtorInvocLookahead()) ExplicitConstructorInvocation() ] ) ( BlockStatement() )* "}" } +// Lookahead for explicit constructor invocation that avoids parsing full argument lists. +// This fixes issue #6234 where complex expressions in arguments (like switch expressions +// inside lambdas) caused the lookahead to fail. +// This mirrors the structure of ExplicitConstructorInvocation but stops at "(" instead +// of parsing ArgumentList. +private void ExplicitCtorInvocLookahead() #void: +{} +{ + // Pattern: [TypeArguments] ("this" | "super") "(" + // Use same LOOKAHEAD strategy as ExplicitConstructorInvocation + ( LOOKAHEAD("<") TypeArguments() ("this" | "super") "(" + | LOOKAHEAD("this") "this" "(" + | LOOKAHEAD("super") "super" "(" + // Qualified pattern: PrimaryExpression "." [TypeArguments] "super" "(" + // Since "this" and "super" can't start the qualifier PrimaryExpression (per JLS), + // if we get here, it must be an identifier-based expression. + | PrimaryExpressionNoSuperThis() "." [ TypeArguments() ] "super" "(" + ) +} + +// PrimaryExpression variant for explicit constructor invocation qualifier lookahead. +// This is used during lookahead only, so we avoid complex expressions that could +// cause lookahead issues. Handles: Outer, Outer.Inner, Outer.this, new Foo(), etc. +private void PrimaryExpressionNoSuperThis() #void: +{} +{ + ( AmbiguousName() | "new" [ TypeArguments() ] AnnotatedClassOrInterfaceType() ArgumentList() ) + ( "." ( "this" | | TypeArguments() | "new" [ TypeArguments() ] AnnotatedClassOrInterfaceType() ArgumentList() ) | ArgumentList() )* +} + void ExplicitConstructorInvocation() : -{boolean prev = inExplicitConstructorInvoc; inExplicitConstructorInvoc = true;} +{boolean prev = inExplicitConstructorInvoc;} { // We may only lookahead one token here, because: // * "this" or "super" can't appear in the primary expression in case of @@ -1461,10 +1491,8 @@ void ExplicitConstructorInvocation() : ( LOOKAHEAD("<") TypeArguments() ( "this" | "super" {jjtThis.setIsSuper();} ) | LOOKAHEAD("this") "this" | LOOKAHEAD("super") "super" {jjtThis.setIsSuper();} - | PrimaryExpression() "." [ TypeArguments() ] "super" {jjtThis.setIsSuper();} + | {inExplicitConstructorInvoc = true;} PrimaryExpression() {inExplicitConstructorInvoc = prev;} "." [ TypeArguments() ] "super" {jjtThis.setIsSuper();} ) - // reset this before parsing the arguments list - {inExplicitConstructorInvoc = prev;} ArgumentList() ";" } diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTSwitchExpressionTests.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTSwitchExpressionTests.kt index fd3b33813da..f893bef36d4 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTSwitchExpressionTests.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTSwitchExpressionTests.kt @@ -461,4 +461,32 @@ class ASTSwitchExpressionTests : ParserTestSpec({ } } } + + parserTest("Switch expression inside lambda passed to super() constructor call (#6234)", javaVersions = switchVersions) { + // https://github.com/pmd/pmd/issues/6234 + // Parser fails when switch expression is used inside a lambda passed to super() + val code = """ + import java.util.concurrent.Callable; + + class A { + A(Callable x) {} + } + + class B extends A { + private static final int X = 1; + B() { + super( + () -> { + return switch (1) { + case X -> true; + default -> false; + }; + } + ); + } + } + """.trimIndent() + + parser.parse(code) + } }) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug6234.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug6234.java new file mode 100644 index 00000000000..0525afd95fe --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug6234.java @@ -0,0 +1,19 @@ +import java.util.concurrent.Callable; + +class A { + A(Callable x) {} +} + +class B extends A { + private static final int X = 1; + B() { + super( + () -> { + return switch (1) { + case X -> true; + default -> false; + }; + } + ); + } +} From 9623cb23650c9de1891249a6cecd63de5bc60f74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Gr=C3=A4f?= Date: Fri, 26 Dec 2025 17:40:13 +0100 Subject: [PATCH 1805/1962] [java] Fix issue 4158: False negative in BigIntegerInstantiation --- .../performance/BigIntegerInstantiationRule.java | 2 +- .../performance/xml/BigIntegerInstantiation.xml | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/BigIntegerInstantiationRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/BigIntegerInstantiationRule.java index 97e3593aa42..677d24420cc 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/BigIntegerInstantiationRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/BigIntegerInstantiationRule.java @@ -43,7 +43,7 @@ public Object visit(ASTConstructorCall node, Object data) { } // might be a String, an Integer, a Long, a Double, or a BigInteger - Object constValue = arguments.get(0).getConstValue(); + Object constValue = arguments.get(0).getConstFoldingResult().getValue(); boolean java5 = languageVersion.compareToVersion("1.5") >= 0; boolean java9 = languageVersion.compareToVersion("9") >= 0; diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/BigIntegerInstantiation.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/BigIntegerInstantiation.xml index 2db3bc1f8da..9d13d1da154 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/BigIntegerInstantiation.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/BigIntegerInstantiation.xml @@ -204,4 +204,20 @@ class Foo { ]]> java 19 + + + #4158: False negative with constant value + 1 + 5 + + From f2ca2d6ddfd5c9c631b35194009814f7816515f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Gr=C3=A4f?= Date: Fri, 26 Dec 2025 17:43:07 +0100 Subject: [PATCH 1806/1962] [java] Issue 4158: minor optimization in case value is not constant --- .../java/rule/performance/BigIntegerInstantiationRule.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/BigIntegerInstantiationRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/BigIntegerInstantiationRule.java index 677d24420cc..496abed78eb 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/BigIntegerInstantiationRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/BigIntegerInstantiationRule.java @@ -44,6 +44,10 @@ public Object visit(ASTConstructorCall node, Object data) { // might be a String, an Integer, a Long, a Double, or a BigInteger Object constValue = arguments.get(0).getConstFoldingResult().getValue(); + if (constValue == null) { + // skip further checks if no constFoldingResult is present + return data; + } boolean java5 = languageVersion.compareToVersion("1.5") >= 0; boolean java9 = languageVersion.compareToVersion("9") >= 0; From 704a2fa1632d48970231591d12f067b5857f56f4 Mon Sep 17 00:00:00 2001 From: gianmarco Date: Fri, 26 Dec 2025 19:38:01 +0100 Subject: [PATCH 1807/1962] Fix invalid Javadoc syntax in VfDocStyleTest --- .../pmd/lang/visualforce/ast/VfDocStyleTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/VfDocStyleTest.java b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/VfDocStyleTest.java index 4848f62643f..27b49339657 100644 --- a/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/VfDocStyleTest.java +++ b/pmd-visualforce/src/test/java/net/sourceforge/pmd/lang/visualforce/ast/VfDocStyleTest.java @@ -741,19 +741,19 @@ void noQuoteAttrWithJspEL() { private static final String TEST_MULTIPLE_NESTED_TAGS = " "; /** - * will close before , thus leaving to remain unclosed + * </x> will close before </a>, thus leaving <a> to remain unclosed */ private static final String TEST_UNCLOSED_END_AFTER_PARENT_CLOSE = " aa bb "; /** - * is just a dangling closing tag not matching any parent. The parser + * </z> is just a dangling closing tag not matching any parent. The parser * should disregard it */ private static final String TEST_UNCLOSED_UNMATCHED_CLOSING_TAG = " "; /** - * First tag does not close. The first closing of will match the - * second opening of a. Another rogue is there for testing compliance + * First <a> tag does not close. The first closing of </a> will match the + * second opening of a. Another rogue </z> is there for testing compliance */ private static final String TEST_UNCLOSED_START_TAG_WITH_UNMATCHED_CLOSE = " "; From 127160ab172fc048c09f8f61e74d66a1249e5bb3 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Sat, 27 Dec 2025 14:14:18 +0100 Subject: [PATCH 1808/1962] chore: Fix typos --- docs/_data/definitions.yml | 9 --- docs/_data/glossary.yml | 11 --- .../pmd/devdocs/github_actions_workflows.md | 2 +- .../adding_a_new_antlr_based_language.md | 2 +- docs/pages/pmd/languages/lua.md | 2 +- docs/pages/pmd/projectdocs/credits.md | 2 +- .../userdocs/extending/writing_xpath_rules.md | 2 +- docs/pages/pmd/userdocs/migrating_to_pmd7.md | 2 +- docs/pages/pmd/userdocs/tools/ant.md | 2 +- docs/pages/pmd/userdocs/tools/maven.md | 2 +- docs/pages/release_notes_old.md | 6 +- docs/pages/release_notes_pmd7.md | 2 +- javacc-wrapper.xml | 2 +- .../pmd/lang/apex/ast/ASTSoqlExpression.java | 6 +- .../pmd/lang/apex/ast/ASTSoslExpression.java | 6 +- .../apex/multifile/ApexMultifileAnalysis.java | 2 +- .../rule/design/ExcessivePublicCountRule.java | 2 +- .../apex/rule/security/ApexBadCryptoRule.java | 4 +- .../rule/security/ApexSOQLInjectionRule.java | 4 +- .../resources/category/apex/bestpractices.xml | 4 +- .../main/resources/category/apex/security.xml | 2 +- .../apex/rule/design/UnusedMethodTest.java | 4 +- .../src/test/resources/SObjectDataLoader.cls | 36 +++++----- .../test/resources/fflib_SObjectDomain.cls | 26 +++---- .../resources/fflib_SObjectUnitOfWorkTest.cls | 8 +-- .../lang/apex/cpd/issue427/SFDCEncoder.cls | 2 +- .../cpd/issue427/SFDCEncoderConstants.cls | 2 +- .../rule/design/xml/CognitiveComplexity.xml | 10 +-- .../performance/xml/AvoidDebugStatements.xml | 4 +- .../AbstractAnalysisPmdSubcommand.java | 2 +- .../net/sourceforge/pmd/lang/coco/ast/Coco.g4 | 2 +- .../ast/impl/javacc/JjtreeParserAdapter.java | 4 +- .../pmd/lang/cpp/cpd/CppCpdLexer.java | 20 +++--- .../pmd/lang/cs/ast/CSharpLexer.g4 | 20 +++--- .../net/sourceforge/pmd/lang/dart/ast/Dart.g4 | 2 +- .../cpd/testdata/annotatedSource.feature | 2 +- .../gherkin/cpd/testdata/annotatedSource.txt | 22 +++--- .../net/sourceforge/pmd/lang/go/ast/Golang.g4 | 4 +- .../pmd/lang/go/cpd/testdata/btrfs.go | 2 +- .../java/internal/JavaViolationDecorator.java | 8 +-- .../AvoidReassigningLoopVariablesRule.java | 10 +-- .../internal/asm/TypeAnnotationHelper.java | 2 +- .../types/internal/infer/ExprCheckHelper.java | 4 +- .../java/types/internal/infer/ExprOps.java | 6 +- .../lang/java/types/internal/infer/Infer.java | 2 +- .../pmd/lang/java/ast/ASTSwitchLikeTest.java | 2 +- .../pmd/lang/java/ast/NodeParsingCtx.kt | 2 +- .../lang/java/ast/ParserCornerCases18.java | 4 +- .../pmd/lang/java/ast/ParserCornerCases18.txt | 4 +- .../rule/bestpractices/xml/EnumComparison.xml | 2 +- .../rule/codestyle/xml/UselessParentheses.xml | 6 +- .../xml/AvoidInstantiatingObjectsInLoops.xml | 2 +- .../performance/xml/UseStringBufferLength.xml | 4 +- .../lang/ecmascript/ast/ASTAssignment.java | 4 +- .../category/ecmascript/bestpractices.xml | 2 +- .../category/ecmascript/codestyle.xml | 2 +- .../ecmascript/ast/ASTTryStatementTest.java | 6 +- .../rule/codestyle/xml/UnnecessaryBlock.xml | 4 +- pmd-matlab/src/main/javacc/Matlab.jj | 6 +- .../lang/matlab/cpd/testdata/sample-matlab.m | 4 +- .../matlab/cpd/testdata/sample-matlab.txt | 16 ++--- .../resolver/ModelicaBuiltinType.java | 4 +- .../resolver/ModelicaClassDeclaration.java | 12 ++-- .../pmd/lang/modelica/resolver/RootScope.java | 6 +- .../resolver/internal/ResolutionContext.java | 6 +- pmd-modelica/src/main/javacc/Modelica.jjt | 2 +- .../pmd/lang/modelica/ModelicaParserTest.java | 2 +- .../resolver/ModelicaResolverTest.java | 6 +- pmd-plsql/src/main/javacc/PLSQL.jjt | 24 +++---- .../pmd/lang/plsql/ast/InnerJoinUsing.pls | 4 +- .../pmd/lang/plsql/ast/IsOfType.pls | 4 +- .../pmd/lang/plsql/ast/IsOfType.txt | 10 +-- .../pmd/lang/plsql/ast/XMLQuery.pls | 2 +- .../pmd/lang/plsql/ast/XMLQuery.txt | 8 +-- .../pmd/lang/plsql/ast/XMLType.pls | 8 +-- .../pmd/lang/plsql/ast/XMLType.txt | 32 ++++----- .../lang/plsql/cpd/testdata/sample-plsql.sql | 18 ++--- .../lang/plsql/cpd/testdata/sample-plsql.txt | 12 ++-- .../testdata/sample-plsql_ignore-literals.txt | 12 ++-- .../plsql/rule/design/xml/NcssMethodCount.xml | 2 +- .../scala/cpd/testdata/sample-LiftActor.scala | 2 +- .../pmd/lang/swift/ast/testdata/BTree.swift | 2 +- .../pmd/lang/swift/cpd/testdata/BTree.swift | 2 +- .../tsql/cpd/testdata/MailJobTimeLine.sql | 2 +- .../tsql/cpd/testdata/MailJobTimeLine.txt | 2 +- pmd-velocity/src/main/javacc/Vtl.jjt | 16 ++--- .../pmd/lang/visualforce/DataType.java | 2 +- pmd-visualforce/src/main/javacc/Vf.jjt | 28 ++++---- .../resources/category/xsl/performance.xml | 2 +- .../performance/xml/AvoidAxisNavigation.xml | 2 +- typos.toml | 70 +++++++++++++++++++ 91 files changed, 352 insertions(+), 302 deletions(-) delete mode 100644 docs/_data/definitions.yml delete mode 100644 docs/_data/glossary.yml create mode 100644 typos.toml diff --git a/docs/_data/definitions.yml b/docs/_data/definitions.yml deleted file mode 100644 index 0da85d3d87b..00000000000 --- a/docs/_data/definitions.yml +++ /dev/null @@ -1,9 +0,0 @@ -elephant: "This is a sample definition." - -baseball: "Baseball is considered America's pasttime sport, though that may be more of a historical term than a current one. There's a lot more excitement about football than baseball. A baseball game is somewhat of a snooze to watch, for the most part." - -basketball: "Basketball is a sport involving two teams of five players each competing to put a ball through a small circular rim 10 feet above the ground. Basketball requires players to be in top physical condition, since they spend most of the game running back and forth along a 94-foot-long floor." - -football: "No doubt the most fun sport to watch, football also manages to accrue the most injuries with the players. From concussions to blown knees, football players have short sport lives." - -soccer: "If there's one sport that dominates the world landscape, it's soccer. However, US soccer fans are few and far between. Apart from the popularity of soccer during the World Cup, most people don't even know the name of the professional soccer organization in their area." \ No newline at end of file diff --git a/docs/_data/glossary.yml b/docs/_data/glossary.yml deleted file mode 100644 index e953fe73bfd..00000000000 --- a/docs/_data/glossary.yml +++ /dev/null @@ -1,11 +0,0 @@ -jekyll_platform: "Jekyll is a static site generator that builds sites using most modern web technologies." - -fractious: "Like a little mischevious child, full of annoying and constant trouble." - -gratuitous: "Something that is unwarranted and uncouth, like the social equivalent of a flagrant foul." - -haughty: "Proud and flaunting it. Holding your head high up like a snooty, too-good-for-everything rich person." - -impertinent: "Someone acting rude and insensitive to others." - -intrepid: "Brave and courageous especially in a difficult, dangerous situation." \ No newline at end of file diff --git a/docs/pages/pmd/devdocs/github_actions_workflows.md b/docs/pages/pmd/devdocs/github_actions_workflows.md index dd1eeeacbf2..e41f47d0efc 100644 --- a/docs/pages/pmd/devdocs/github_actions_workflows.md +++ b/docs/pages/pmd/devdocs/github_actions_workflows.md @@ -12,7 +12,7 @@ last_updated: July 2025 (7.17.0) ## Build, Build Pull Request, Build Snapshot, Build Release -"Build" itself is a [reuseable workflow](https://docs.github.com/en/actions/sharing-automations/reusing-workflows), +"Build" itself is a [reusable workflow](https://docs.github.com/en/actions/sharing-automations/reusing-workflows), that is called by "Build Pull Request" and "Build Snapshot" and "Build Release". * Workflow files: diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md index 605d135c2e3..47f0d0e0943 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md @@ -138,7 +138,7 @@ definitely don't come for free. It is much effort and requires perseverance to i you can create your own implementation of [`AntlrTokenFilter`](https://github.com/pmd/pmd/blob/main/pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/AntlrTokenFilter.java). You'll need to override then the protected method `getTokenFilter(AntlrTokenManager)` - and return your custom filter. See the CpdLexer for C# as an exmaple: + and return your custom filter. See the CpdLexer for C# as an example: [`CsCpdLexer`](https://github.com/pmd/pmd/blob/main/pmd-cs/src/main/java/net/sourceforge/pmd/lang/cs/cpd/CsCpdLexer.java). If you don't need a custom token filter, you don't need to override the method. It returns the default diff --git a/docs/pages/pmd/languages/lua.md b/docs/pages/pmd/languages/lua.md index fbc95b66079..4dc49f57ac4 100644 --- a/docs/pages/pmd/languages/lua.md +++ b/docs/pages/pmd/languages/lua.md @@ -3,7 +3,7 @@ title: Lua support permalink: pmd_languages_lua.html last_updated: September 2023 (7.0.0) tags: [languages, CpdCapableLanguage] -summary: "Lua-specifc features and guidance" +summary: "Lua-specific features and guidance" --- > [Lua](https://www.lua.org/) is a powerful, efficient, lightweight, embeddable scripting language. diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 0bb5e71935a..665420fbf71 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -1338,7 +1338,7 @@ According to the book [PMD Applied](https://pmdapplied.thomasleecopeland.com/) t * Christopher Stach - bug report for VariableNamingConventions, bug report for CallSuperInConstructor, many bug reports for rules that didn't handle Java 1.5 constructs * Matthew Harrah - noticed missing element in UseCorrectExceptionLogging definition, script bug report -* Mike Kaufman - Reported abug in UnnecessaryCaseChange +* Mike Kaufman - Reported a bug in UnnecessaryCaseChange * [Elliotte Rusty Harold](http://www.cafeaulait.org/) - reported bug in UseAssertSameInsteadOfAssertTrue, suggested creating a new ruleset containing rules in each release, UncommentedEmptyConstructor suggestions, noted missed case for UnusedFormalParameter, documentation suggestions, diff --git a/docs/pages/pmd/userdocs/extending/writing_xpath_rules.md b/docs/pages/pmd/userdocs/extending/writing_xpath_rules.md index d2d0d1505b6..9295f599898 100644 --- a/docs/pages/pmd/userdocs/extending/writing_xpath_rules.md +++ b/docs/pages/pmd/userdocs/extending/writing_xpath_rules.md @@ -63,7 +63,7 @@ to XDM types. The same `conv` function is used to translate rule property values to XDM values. -Additionaly, PMD's own `net.sourceforge.pmd.lang.document.Chars` is also translated to a `xs:string` +Additionally, PMD's own `net.sourceforge.pmd.lang.document.Chars` is also translated to a `xs:string` ## Rule properties diff --git a/docs/pages/pmd/userdocs/migrating_to_pmd7.md b/docs/pages/pmd/userdocs/migrating_to_pmd7.md index 50049d0ef87..12b48a463ad 100644 --- a/docs/pages/pmd/userdocs/migrating_to_pmd7.md +++ b/docs/pages/pmd/userdocs/migrating_to_pmd7.md @@ -2997,7 +2997,7 @@ super.method(); โ””โ”€ ExpressionStatement โ””โ”€ AssignmentExpression "=" - โ”œโ”€ FieldAccess[ @AcessType = "WRITE" ] "field" + โ”œโ”€ FieldAccess[ @AccessType = "WRITE" ] "field" โ”‚ โ””โ”€ SuperExpression โ””โ”€ NumericLiteral "1" diff --git a/docs/pages/pmd/userdocs/tools/ant.md b/docs/pages/pmd/userdocs/tools/ant.md index 007f23500f6..1d9a2b8a55a 100644 --- a/docs/pages/pmd/userdocs/tools/ant.md +++ b/docs/pages/pmd/userdocs/tools/ant.md @@ -105,7 +105,7 @@ The examples below won't repeat this taskdef element, as this is always required cacheLocation The location of the analysis cache file to be used. - Setting this property enables Incremental Analysis, which can greatly improve analysis time without loosing analysis quality. + Setting this property enables Incremental Analysis, which can greatly improve analysis time without losing analysis quality. Its use is strongly recommended. No diff --git a/docs/pages/pmd/userdocs/tools/maven.md b/docs/pages/pmd/userdocs/tools/maven.md index 02fd2a07ddb..5eaebfa73d1 100644 --- a/docs/pages/pmd/userdocs/tools/maven.md +++ b/docs/pages/pmd/userdocs/tools/maven.md @@ -39,7 +39,7 @@ section: ``` -When defining the version in the pluginManagment section, then it doesn't need to be specified in the normal plugins +When defining the version in the pluginManagement section, then it doesn't need to be specified in the normal plugins section. However, it should additionally be specified in the reporting section. More information, see [Guide to Configuring Plugin-ins](https://maven.apache.org/guides/mini/guide-configuring-plugins.html). diff --git a/docs/pages/release_notes_old.md b/docs/pages/release_notes_old.md index 5381059cbe6..0fb372443ec 100644 --- a/docs/pages/release_notes_old.md +++ b/docs/pages/release_notes_old.md @@ -1085,7 +1085,7 @@ for a list of common, shared parameters that are valid for both commands. * [#5736](https://github.com/pmd/pmd/pull/5736): Fix #5061: \[java] UnusedLocalVariable FP when using compound assignment - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) * [#5741](https://github.com/pmd/pmd/pull/5741): \[cli] Make CLI default to multithreaded - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) * [#5742](https://github.com/pmd/pmd/pull/5742): \[ci] publish-snapshot/old build: migrate to central portal - [Andreas Dangel](https://github.com/adangel) (@adangel) -* [#5743](https://github.com/pmd/pmd/pull/5743): \[ci] Make build a reuseable workflow - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#5743](https://github.com/pmd/pmd/pull/5743): \[ci] Make build a reusable workflow - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5744](https://github.com/pmd/pmd/pull/5744): Fix #5705: \[cli] Always determine PMD_HOME based on script location - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5748](https://github.com/pmd/pmd/pull/5748): \[core] Reformat SarifLog to comply to coding standards - [Andreas Dangel](https://github.com/adangel) (@adangel) * [#5763](https://github.com/pmd/pmd/pull/5763): \[java] Support annotated constructor return type in symbol API - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) @@ -7698,7 +7698,7 @@ This minor release will be the last one in 2021. The next release is scheduled t #### Command Line Interface -The command line options for PMD and CPD now use GNU-syle long options format. E.g. instead of `-rulesets` the +The command line options for PMD and CPD now use GNU-style long options format. E.g. instead of `-rulesets` the preferred usage is now `--rulesets`. Alternatively one can still use the short option `-R`. Some options also have been renamed to a more consistent casing pattern at the same time (`--fail-on-violation` instead of `-failOnViolation`). @@ -14719,7 +14719,7 @@ public class Foo { Detects hardcoded credentials used in requests to an endpoint. You should refrain from hardcoding credentials: - * They are hard to mantain by being mixed in application code + * They are hard to maintain by being mixed in application code * Particularly hard to update them when used from different classes * Granting a developer access to the codebase means granting knowledge of credentials, keeping a two-level access is not possible. diff --git a/docs/pages/release_notes_pmd7.md b/docs/pages/release_notes_pmd7.md index b8024d9779c..9e702da98a9 100644 --- a/docs/pages/release_notes_pmd7.md +++ b/docs/pages/release_notes_pmd7.md @@ -2024,7 +2024,7 @@ No changes. **Command Line Interface** -The command line options for PMD and CPD now use GNU-syle long options format. E.g. instead of `-rulesets` the +The command line options for PMD and CPD now use GNU-style long options format. E.g. instead of `-rulesets` the preferred usage is now `--rulesets`. Alternatively one can still use the short option `-R`. Some options also have been renamed to a more consistent casing pattern at the same time (`--fail-on-violation` instead of `-failOnViolation`). diff --git a/javacc-wrapper.xml b/javacc-wrapper.xml index 0eb6e1a6de7..ef14868f279 100644 --- a/javacc-wrapper.xml +++ b/javacc-wrapper.xml @@ -445,7 +445,7 @@ public final class ${token-constants-name} \{${line.separator} TOKEN_NAMES = java.util.Collections.unmodifiableList(java.util.Arrays.asList(tokenImage)); ]]> diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTSoqlExpression.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTSoqlExpression.java index 3b08de7d9bb..602c3410e78 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTSoqlExpression.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTSoqlExpression.java @@ -10,11 +10,11 @@ import com.google.summit.ast.expression.SoqlExpression; public final class ASTSoqlExpression extends AbstractApexNode.Single { - private final String canoncialQuery; + private final String canonicalQuery; ASTSoqlExpression(SoqlExpression soqlExpression) { super(soqlExpression); - canoncialQuery = convertToCanonicalQuery(soqlExpression.getQuery()); + canonicalQuery = convertToCanonicalQuery(soqlExpression.getQuery()); } @@ -34,7 +34,7 @@ public String getQuery() { * Returns the query with the SOQL keywords normalized as uppercase. */ public String getCanonicalQuery() { - return canoncialQuery; + return canonicalQuery; } static String convertToCanonicalQuery(String rawQuery) { diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTSoslExpression.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTSoslExpression.java index 8e7a4e33dbe..02106d09e6a 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTSoslExpression.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ASTSoslExpression.java @@ -9,11 +9,11 @@ import com.google.summit.ast.expression.SoslExpression; public final class ASTSoslExpression extends AbstractApexNode.Single { - private final String canoncialQuery; + private final String canonicalQuery; ASTSoslExpression(SoslExpression soslExpression) { super(soslExpression); - canoncialQuery = convertToCanonicalQuery(soslExpression.getQuery()); + canonicalQuery = convertToCanonicalQuery(soslExpression.getQuery()); } @@ -33,6 +33,6 @@ public String getQuery() { * Returns the query with the SOSL keywords normalized as uppercase. */ public String getCanonicalQuery() { - return canoncialQuery; + return canonicalQuery; } } diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/ApexMultifileAnalysis.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/ApexMultifileAnalysis.java index 2f2ebd5590d..dce7bf2898f 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/ApexMultifileAnalysis.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/ApexMultifileAnalysis.java @@ -84,7 +84,7 @@ public final class ApexMultifileAnalysis { } } catch (Exception | ExceptionInInitializerError | NoClassDefFoundError e) { // Note: Org.newOrg() will try to find the base Apex Types through the current classloader - // in package "com.nawforce.runforce". This requires, that directory listings can be retrievied + // in package "com.nawforce.runforce". This requires, that directory listings can be retrieved // on the URL that the classloader returns from getResource("/com/nawforce/runforce"): // https://github.com/nawforce/apex-link/blob/7688adcb7a2d7f8aa28d0618ffb2a3aa81151858/apexlink/src/main/scala/com/nawforce/apexlink/types/platform/PlatformTypeDeclaration.scala#L260-L273 // However, when running as an Eclipse plugin, we have a special bundle classloader, that returns diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountRule.java index af61e66df31..d66f303ade2 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountRule.java @@ -19,7 +19,7 @@ * subclasses.

          * *

          A large proportion of public members and operations means the class - * has high potential to be affected by external classes. Futhermore, + * has high potential to be affected by external classes. Furthermore, * increased effort will be required to thoroughly test the class.

          * * @author ported from Java original of aglover diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexBadCryptoRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexBadCryptoRule.java index 6ead998e978..c1720f4a9d1 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexBadCryptoRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexBadCryptoRule.java @@ -65,7 +65,7 @@ public Object visit(ASTUserClass node, Object data) { || Helper.isMethodName(methodCall, CRYPTO, ENCRYPT_WITH_MANAGED_IV) || Helper.isMethodName(methodCall, CRYPTO, DECRYPT_WITH_MANAGED_IV)) { - validateStaticIVorKey(methodCall, data); + validateStaticIVOrKey(methodCall, data); } } @@ -84,7 +84,7 @@ private void findSafeVariables(ApexNode var) { } } - private void validateStaticIVorKey(ASTMethodCallExpression methodCall, Object data) { + private void validateStaticIVOrKey(ASTMethodCallExpression methodCall, Object data) { // .encrypt('AES128', key, exampleIv, data); int numberOfChildren = methodCall.getNumChildren(); switch (numberOfChildren) { diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSOQLInjectionRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSOQLInjectionRule.java index 13fd6b00d1f..201664b5648 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSOQLInjectionRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/ApexSOQLInjectionRule.java @@ -78,13 +78,13 @@ public Object visit(ASTUserClass node, Object data) { findSelectContainingVariables(a); } - // String foo = String.escapeSignleQuotes(...); + // String foo = String.escapeSingleQuotes(...); for (ASTVariableDeclaration a : node.descendants(ASTVariableDeclaration.class)) { findSanitizedVariables(a); findSelectContainingVariables(a); } - // baz = String.escapeSignleQuotes(...); + // baz = String.escapeSingleQuotes(...); for (ASTAssignmentExpression a : node.descendants(ASTAssignmentExpression.class)) { findSanitizedVariables(a); findSelectContainingVariables(a); diff --git a/pmd-apex/src/main/resources/category/apex/bestpractices.xml b/pmd-apex/src/main/resources/category/apex/bestpractices.xml index acdf4306d4c..de2ee305b4e 100644 --- a/pmd-apex/src/main/resources/category/apex/bestpractices.xml +++ b/pmd-apex/src/main/resources/category/apex/bestpractices.xml @@ -111,7 +111,7 @@ private class TestRunAs { Apex test methods should have `@isTest` annotation instead of the `testMethod` keyword, as `testMethod` is deprecated. -Salesforce advices to use [@isTest](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_isTest.htm) +Salesforce advises to use [@isTest](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_isTest.htm) annotation for test classes and methods. 3 @@ -257,7 +257,7 @@ Many interfaces (e.g. Batch) required global modifiers in the past but don't req pathLikeOption = Option.apply(new com.nawforce.runtime.platform.Path(tempDir)); - Option> cachDirOption = Option.apply(pathLikeOption); - Environment.setCacheDirOverride(cachDirOption); + Option> cacheDirOption = Option.apply(pathLikeOption); + Environment.setCacheDirOverride(cacheDirOption); Language apexLanguage = ApexLanguageModule.getInstance(); LanguageVersion languageVersion = apexLanguage.getDefaultVersion(); diff --git a/pmd-apex/src/test/resources/SObjectDataLoader.cls b/pmd-apex/src/test/resources/SObjectDataLoader.cls index da391120d94..92bb287bb7d 100644 --- a/pmd-apex/src/test/resources/SObjectDataLoader.cls +++ b/pmd-apex/src/test/resources/SObjectDataLoader.cls @@ -163,7 +163,7 @@ public with sharing class SObjectDataLoader **/ private void searchRelationships(Schema.SObjectType sObjectType, Integer lookupDepth, Integer childDepth, Boolean searchChildren, Set searched, Set searchedParentOnly) { - // Stop infinite recursion and checks that an object shuold not be searched twice, unless the scope of the search is different + // Stop infinite recursion and checks that an object should not be searched twice, unless the scope of the search is different if(searched.contains(sObjectType) || (searchChildren == false && searchedParentOnly.contains(sObjectType)) || lookupDepth > 2 || childDepth > 3) // TODO: Make max depth configurable return; @@ -217,12 +217,12 @@ public with sharing class SObjectDataLoader for(Schema.SObjectField sObjectField : sObjectFields.values()) if(sObjectField.getDescribe().getType() == Schema.DisplayType.Reference) { - Boolean omitRefernceToFields = false; - for(Schema.sObjectType refernceToType : sObjectField.getDescribe().getReferenceTo()){ - if(referenceToWhitelist.contains(refernceToType.getDescribe().getName())) - omitRefernceToFields = true; + Boolean omitReferenceToFields = false; + for(Schema.sObjectType referenceToType : sObjectField.getDescribe().getReferenceTo()){ + if(referenceToWhitelist.contains(referenceToType.getDescribe().getName())) + omitReferenceToFields = true; } - if(!followChildRelationships.contains(sObjectField) && !relationshipWhitelist.contains(sObjectField.getDescribe().getName()) && !omitRefernceToFields && !userWhiteListSet.contains(sObjectField.getDescribe().getName()) && !matchNameSpaceForObject(sObjectField.getDescribe().getName())) + if(!followChildRelationships.contains(sObjectField) && !relationshipWhitelist.contains(sObjectField.getDescribe().getName()) && !omitReferenceToFields && !userWhiteListSet.contains(sObjectField.getDescribe().getName()) && !matchNameSpaceForObject(sObjectField.getDescribe().getName())) { if(sObjectField.getDescribe().getReferenceTo()!=null && sObjectField.getDescribe().getReferenceTo().size()>0) follow(sObjectField). @@ -282,14 +282,14 @@ public with sharing class SObjectDataLoader 'RecordAssociatedGroups' }; - // Standard RefernceTo that are not included when using the auto config + // Standard ReferenceTo that are not included when using the auto config private Set referenceToWhitelist = new Set { 'User', 'Organization' }; - // Standard fiels to be omitted + // Standard fields to be omitted private Set fieldWhitelist = new Set { @@ -436,9 +436,9 @@ public with sharing class SObjectDataLoader Map sObjectFields; sObjectFields = sObjectType.getDescribe().fields.getMap(); List relationshipsFields = new List(); - //adding selfrefernce Fields in set + //adding self-reference Fields in set Set selfReferenceFields = new Set(); - // Unresolved refrences list for callback + // Unresolved references list for callback List callbackUnresolvedReferencesList= new List(); for(Schema.SObjectField sObjectField : sObjectFields.values()) { @@ -540,19 +540,19 @@ public with sharing class SObjectDataLoader /* * Method to Update foreign key references / lookups / master-detail relationships */ - private static void updateReferenceFieldsInRecords(List relationshipsFields,Set filteredUnresolvedFieldReferences,Map recordsByOriginalId,Sobject orignalRecord,Set allUnresolvedFieldReferences) + private static void updateReferenceFieldsInRecords(List relationshipsFields,Set filteredUnresolvedFieldReferences,Map recordsByOriginalId,Sobject originalRecord,Set allUnresolvedFieldReferences) { for(Schema.SObjectField sObjectField : relationshipsFields) { // Obtained original related record Id and search map over new records by old Ids - Id oldRelatedRecordId = (Id) orignalRecord.get(sObjectField); + Id oldRelatedRecordId = (Id) originalRecord.get(sObjectField); if(oldRelatedRecordId!=null ) { SObject newRelatedRecord = recordsByOriginalId.get(oldRelatedRecordId); Sobject newRecord ; if(newRelatedRecord!=null && newRelatedRecord.Id!=null) { - newRecord = recordsByOriginalId.get(orignalRecord.ID); + newRecord = recordsByOriginalId.get(originalRecord.ID); newRecord.put(sObjectField, newRelatedRecord.Id); } else @@ -615,8 +615,8 @@ public with sharing class SObjectDataLoader * @param Set The set of IDs of the main records that should be serialized * @param Schema.SObjectType The sObject type that is being serialised * @param SerializeConfig Configuration object that controls which relationships etc should be processed - * @param Integer The current lookup depth. This is incremented for each recurssion that looks at lookup links and is used to prevent infinate loops - * @param Integer The current child depth. This is incremented for each recurssion that looks at related child records links and is used to prevent infinate loops + * @param Integer The current lookup depth. This is incremented for each recursion that looks at lookup links and is used to prevent infinite loops + * @param Integer The current child depth. This is incremented for each recursion that looks at related child records links and is used to prevent infinite loops * @param RecordsBundle The bundle of records that is being added to * @param Set A set of record IDs that have already been serialised **/ @@ -659,7 +659,7 @@ public with sharing class SObjectDataLoader if(recordsToSerializeById.size()==0) return; - // Any lookup relationships to folow? + // Any lookup relationships to follow? Set sObjectFollowRelationships = config.followRelationships.clone(); sObjectFollowRelationships.retainAll(sObjectFields.values()); if(sObjectFollowRelationships.size()>0) @@ -790,7 +790,7 @@ public with sharing class SObjectDataLoader } /** - * Internal Apex represnetation of the serialized output for all recordsets + * Internal Apex representation of the serialized output for all recordsets **/ private class RecordsBundle { @@ -835,7 +835,7 @@ public with sharing class SObjectDataLoader } /** - * Internal Apex represnetation of the serialized output for a given recordset + * Internal Apex representation of the serialized output for a given recordset **/ private class RecordSetBundle { diff --git a/pmd-apex/src/test/resources/fflib_SObjectDomain.cls b/pmd-apex/src/test/resources/fflib_SObjectDomain.cls index cea18e7e13d..b70e3f02580 100644 --- a/pmd-apex/src/test/resources/fflib_SObjectDomain.cls +++ b/pmd-apex/src/test/resources/fflib_SObjectDomain.cls @@ -25,7 +25,7 @@ **/ /** - * Base class aiding in the implemetnation of a Domain Model around SObject collections + * Base class aiding in the implementation of a Domain Model around SObject collections * * Domain (software engineering). โ€œa set of common requirements, terminology, and functionality * for any software program constructed to solve a problem in that fieldโ€, @@ -62,7 +62,7 @@ public virtual with sharing class fflib_SObjectDomain public static ErrorFactory Errors {get; private set;} /** - * Useful during unit testing to access mock support for database inserts and udpates (testing without DML) + * Useful during unit testing to access mock support for database inserts and updates (testing without DML) **/ public static TestFactory Test {get; private set;} @@ -72,7 +72,7 @@ public virtual with sharing class fflib_SObjectDomain private static Map> TriggerStateByClass; /** - * Retains the trigger tracking configuraiton used for each domain + * Retains the trigger tracking configuration used for each domain **/ private static Map TriggerEventByClass; @@ -214,7 +214,7 @@ public virtual with sharing class fflib_SObjectDomain public virtual void handleAfterUpdate(Map existingRecords) { if(Configuration.EnforcingTriggerCRUDSecurity && !SObjectDescribe.isUpdateable()) - throw new DomainException('Permission to udpate an ' + SObjectDescribe.getName() + ' denied.'); + throw new DomainException('Permission to update an ' + SObjectDescribe.getName() + ' denied.'); if(Configuration.OldOnUpdateValidateBehaviour) onValidate(); @@ -344,7 +344,7 @@ public virtual with sharing class fflib_SObjectDomain Type constructableClass = domainClassName.endsWith('Constructor') ? Type.forName(domainClassName) : Type.forName(domainClassName+'.Constructor'); IConstructable domainConstructor = (IConstructable) constructableClass.newInstance(); - // Construct the domain class with the approprite record set + // Construct the domain class with the appropriate record set if(isInsert) domainObject = domainConstructor.construct(newRecords); else if(isUpdate) domainObject = domainConstructor.construct(newRecords); else if(isDelete) domainObject = domainConstructor.construct(oldRecordsMap.values()); @@ -428,7 +428,7 @@ public virtual with sharing class fflib_SObjectDomain this.enableAll(); } - // befores + // before public TriggerEvent enableBeforeInsert() {BeforeInsertEnabled = true; return this;} public TriggerEvent enableBeforeUpdate() {BeforeUpdateEnabled = true; return this;} public TriggerEvent enableBeforeDelete() {BeforeDeleteEnabled = true; return this;} @@ -437,7 +437,7 @@ public virtual with sharing class fflib_SObjectDomain public TriggerEvent disableBeforeUpdate() {BeforeUpdateEnabled = false; return this;} public TriggerEvent disableBeforeDelete() {BeforeDeleteEnabled = false; return this;} - // afters + // after public TriggerEvent enableAfterInsert() {AfterInsertEnabled = true; return this;} public TriggerEvent enableAfterUpdate() {AfterUpdateEnabled = true; return this;} public TriggerEvent enableAfterDelete() {AfterDeleteEnabled = true; return this;} @@ -504,7 +504,7 @@ public virtual with sharing class fflib_SObjectDomain public class Configuration { /** - * Backwards compatability mode for handleAfterUpdate routing to onValidate() + * Backwards compatibility mode for handleAfterUpdate routing to onValidate() **/ public Boolean OldOnUpdateValidateBehaviour {get; private set;} /** @@ -522,7 +522,7 @@ public virtual with sharing class fflib_SObjectDomain **/ public Configuration() { - EnforcingTriggerCRUDSecurity = true; // Default is true for backwards compatability + EnforcingTriggerCRUDSecurity = true; // Default is true for backwards compatibility TriggerStateEnabled = false; OldOnUpdateValidateBehaviour = false; // Breaking change, but felt to better practice } @@ -859,12 +859,12 @@ public virtual with sharing class fflib_SObjectDomain public override void onBeforeInsert() { // Assert this variable is null in the after insert (since this domain class is stateless) - someState = 'This should not survice the trigger after phase'; + someState = 'This should not survive the trigger after phase'; } public override void onAfterInsert() { - // This is a stateless domain class, so should not retain anything betweet before and after + // This is a stateless domain class, so should not retain anything between before and after System.assertEquals(null, someState); } } @@ -913,7 +913,7 @@ public virtual with sharing class fflib_SObjectDomain newOpps.add(new Opportunity ( Name = 'Test Recursive 2', Type = 'Existing Account' )); } - // If testing recursiving emulate an insert + // If testing recursion emulate an insert if(newOpps.size()>0) { // This will force recursion and thus validate via the above assert results in a new domain instance @@ -959,7 +959,7 @@ public virtual with sharing class fflib_SObjectDomain public override void onValidate() { - // Throw exception to give the test somethign to assert on + // Throw exception to give the test something to assert on throw new DomainException('onValidate called'); } } diff --git a/pmd-apex/src/test/resources/fflib_SObjectUnitOfWorkTest.cls b/pmd-apex/src/test/resources/fflib_SObjectUnitOfWorkTest.cls index 91a6ef13978..0c1f030a27c 100644 --- a/pmd-apex/src/test/resources/fflib_SObjectUnitOfWorkTest.cls +++ b/pmd-apex/src/test/resources/fflib_SObjectUnitOfWorkTest.cls @@ -38,7 +38,7 @@ private with sharing class fflib_SObjectUnitOfWorkTest @isTest private static void testUnitOfWorkNewDirtyDelete() { - // Insert Opporunities with UnitOfWork + // Insert Opportunities with UnitOfWork { fflib_SObjectUnitOfWork uow = new fflib_SObjectUnitOfWork(MY_SOBJECTS); for(Integer o=0; o<10; o++) @@ -176,7 +176,7 @@ private with sharing class fflib_SObjectUnitOfWorkTest @isTest private static void testDerivedUnitOfWork_CommitSuccess() { - // Insert Opporunities with UnitOfWork + // Insert Opportunities with UnitOfWork DerivedUnitOfWork uow = new DerivedUnitOfWork(MY_SOBJECTS); for(Integer o=0; o<10; o++) { @@ -231,7 +231,7 @@ private with sharing class fflib_SObjectUnitOfWorkTest @isTest private static void testDerivedUnitOfWork_CommitDMLFail() { - // Insert Opporunities with UnitOfWork forcing a failure on DML by not setting 'Name' field + // Insert Opportunities with UnitOfWork forcing a failure on DML by not setting 'Name' field DerivedUnitOfWork uow = new DerivedUnitOfWork(MY_SOBJECTS); Opportunity opp = new Opportunity(); uow.registerNew(new List{opp}); @@ -269,7 +269,7 @@ private with sharing class fflib_SObjectUnitOfWorkTest @isTest private static void testDerivedUnitOfWork_CommitDoWorkFail() { - // Insert Opporunities with UnitOfWork + // Insert Opportunities with UnitOfWork DerivedUnitOfWork uow = new DerivedUnitOfWork(MY_SOBJECTS); Opportunity opp = new Opportunity(); opp.Name = 'UoW Test Name 1'; diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/issue427/SFDCEncoder.cls b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/issue427/SFDCEncoder.cls index 016c565c032..034539dbb0d 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/issue427/SFDCEncoder.cls +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/issue427/SFDCEncoder.cls @@ -19,7 +19,7 @@ */ global with sharing class SFDCEncoder { - /* TODO Yoel - all these functions should be converted into a white list aproach - I am using blacklist to be consistent with the VISUALFORCE functions */ + /* TODO Yoel - all these functions should be converted into a white list approach - I am using blacklist to be consistent with the VISUALFORCE functions */ /* TODO Yoel - Do we need to encode ASCII/Unicode white-space/new-line characters? These used to cause some security issues in some browsers not sure if this is still the case */ /* Note - the order of these encoding strings is very important so we don't end up with double encoding. diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/issue427/SFDCEncoderConstants.cls b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/issue427/SFDCEncoderConstants.cls index 48718e39e6c..b047a0ca453 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/issue427/SFDCEncoderConstants.cls +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/issue427/SFDCEncoderConstants.cls @@ -16,7 +16,7 @@ /** * Common character classes used for input validation, output encoding, verifying password strength - * CSRF token generation, generating salts, etc. I removed all the constatnts that are not used so we + * CSRF token generation, generating salts, etc. I removed all the constants that are not used so we * don't burn governor limits. */ public with sharing class SFDCEncoderConstants { diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/CognitiveComplexity.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/CognitiveComplexity.xml index 034ca90956e..84b2e0cedfc 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/CognitiveComplexity.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/CognitiveComplexity.xml @@ -70,13 +70,13 @@ while (true) { // +1 try { //synchronized (this) { - if (frst != null) { // +2 (nesting = 1) - if (frst.getVersion() > entry.getVersion()) { // +3 (nesting = 2) + if (first != null) { // +2 (nesting = 1) + if (first.getVersion() > entry.getVersion()) { // +3 (nesting = 2) throw new RollbackException(); } if (txn.isActive()) { // +3 (nesting = 2) for // +4 (nesting = 3) - (Entry e = frst; e != null; e = e.getPrevious()) { + (Entry e = first; e != null; e = e.getPrevious()) { final long version = e.getVersion(); final long depends = ti.wwDependency(version, txn.getTransactionStatus(), 0); @@ -90,8 +90,8 @@ } } } - entry.setPrevious(frst); - frst = entry; + entry.setPrevious(first); + first = entry; break; //} } catch (final WWRetryException re) { // +2 (nesting = 1) diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/performance/xml/AvoidDebugStatements.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/performance/xml/AvoidDebugStatements.xml index 078abb2c1cb..1ce1d264903 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/performance/xml/AvoidDebugStatements.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/performance/xml/AvoidDebugStatements.xml @@ -25,7 +25,7 @@ public class Foo { - Unnecesary debug statements + Unnecessary debug statements 2 inputPaths) { this.inputPaths.addAll(inputPaths); } - @Option(names = "--non-recursive", description = "Don't scan subdirectiories when using the --d (-dir) option.") + @Option(names = "--non-recursive", description = "Don't scan subdirectories when using the --d (-dir) option.") private boolean nonRecursive; diff --git a/pmd-coco/src/main/antlr4/net/sourceforge/pmd/lang/coco/ast/Coco.g4 b/pmd-coco/src/main/antlr4/net/sourceforge/pmd/lang/coco/ast/Coco.g4 index 32a867b8b24..c645454345b 100644 --- a/pmd-coco/src/main/antlr4/net/sourceforge/pmd/lang/coco/ast/Coco.g4 +++ b/pmd-coco/src/main/antlr4/net/sourceforge/pmd/lang/coco/ast/Coco.g4 @@ -210,7 +210,7 @@ nondetClause : ( IF LP expression RP )? expression ; -matchClauses // COCOTEC: both comma and semicolon seem to be allowed (trailing one can be omited), only comma is documented +matchClauses // COCOTEC: both comma and semicolon seem to be allowed (trailing one can be omitted), only comma is documented : matchClause ((COMMA|SEMI) matchClause )* (COMMA|SEMI)? ; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeParserAdapter.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeParserAdapter.java index 7b274480f11..af3b0768318 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeParserAdapter.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JjtreeParserAdapter.java @@ -34,8 +34,8 @@ public final R parse(ParserTask task) throws ParseException { task = task.withTextDocument(charStream.getTokenDocument().getTextDocument()); // Finally, do the parsing return parseImpl(charStream, task); - } catch (FileAnalysisException tme) { - throw tme.setFileId(task.getTextDocument().getFileId()); + } catch (FileAnalysisException analysisException) { + throw analysisException.setFileId(task.getTextDocument().getFileId()); } } diff --git a/pmd-cpp/src/main/java/net/sourceforge/pmd/lang/cpp/cpd/CppCpdLexer.java b/pmd-cpp/src/main/java/net/sourceforge/pmd/lang/cpp/cpd/CppCpdLexer.java index 56edc15d85c..097520859be 100644 --- a/pmd-cpp/src/main/java/net/sourceforge/pmd/lang/cpp/cpd/CppCpdLexer.java +++ b/pmd-cpp/src/main/java/net/sourceforge/pmd/lang/cpp/cpd/CppCpdLexer.java @@ -32,14 +32,14 @@ public class CppCpdLexer extends JavaccCpdLexer { private boolean skipBlocks; private Pattern skipBlocksStart; private Pattern skipBlocksEnd; - private final boolean ignoreIdentifierAndLiteralSeqences; + private final boolean ignoreIdentifierAndLiteralSequences; private final boolean ignoreLiteralSequences; private final boolean ignoreLiterals; private final boolean ignoreIdentifiers; public CppCpdLexer(LanguagePropertyBundle cppProperties) { ignoreLiteralSequences = cppProperties.getProperty(CpdLanguageProperties.CPD_IGNORE_LITERAL_SEQUENCES); - ignoreIdentifierAndLiteralSeqences = cppProperties.getProperty(CpdLanguageProperties.CPD_IGNORE_LITERAL_AND_IDENTIFIER_SEQUENCES); + ignoreIdentifierAndLiteralSequences = cppProperties.getProperty(CpdLanguageProperties.CPD_IGNORE_LITERAL_AND_IDENTIFIER_SEQUENCES); ignoreLiterals = cppProperties.getProperty(CpdLanguageProperties.CPD_ANONYMIZE_LITERALS); ignoreIdentifiers = cppProperties.getProperty(CpdLanguageProperties.CPD_ANONYMIZE_IDENTIFIERS); String skipBlocksPattern = cppProperties.getProperty(CppLanguageModule.CPD_SKIP_BLOCKS); @@ -75,7 +75,7 @@ public TextDocument translate(TextDocument text) throws MalformedSourceException @Override protected TokenManager filterTokenStream(final TokenManager tokenManager) { - return new CppTokenFilter(tokenManager, ignoreLiteralSequences, ignoreIdentifierAndLiteralSeqences); + return new CppTokenFilter(tokenManager, ignoreLiteralSequences, ignoreIdentifierAndLiteralSequences); } @Override @@ -98,13 +98,13 @@ protected void processToken(TokenFactory tokenEntries, JavaccToken currentToken) private static class CppTokenFilter extends JavaCCTokenFilter { private final boolean ignoreLiteralSequences; - private final boolean ignoreIdentifierAndLiteralSeqences; + private final boolean ignoreIdentifierAndLiteralSequences; private JavaccToken discardingTokensUntil = null; private boolean discardCurrent = false; - CppTokenFilter(final TokenManager tokenManager, final boolean ignoreLiteralSequences, final boolean ignoreIdentifierAndLiteralSeqences) { + CppTokenFilter(final TokenManager tokenManager, final boolean ignoreLiteralSequences, final boolean ignoreIdentifierAndLiteralSequences) { super(tokenManager); - this.ignoreIdentifierAndLiteralSeqences = ignoreIdentifierAndLiteralSeqences; + this.ignoreIdentifierAndLiteralSequences = ignoreIdentifierAndLiteralSequences; this.ignoreLiteralSequences = ignoreLiteralSequences; } @@ -115,7 +115,7 @@ protected void analyzeTokens(final JavaccToken currentToken, final Iterable remainingTokens) { - if (ignoreLiteralSequences || ignoreIdentifierAndLiteralSeqences) { + if (ignoreLiteralSequences || ignoreIdentifierAndLiteralSequences) { final int kind = currentToken.getKind(); if (isDiscardingToken()) { if (currentToken == discardingTokensUntil) { @@ -123,12 +123,12 @@ private void skipSequences(final JavaccToken currentToken, final Iterable remainingTokens, boolean ignoreIdentifierAndLiteralSeqences) { + private static JavaccToken findEndOfSequenceToDiscard(final Iterable remainingTokens, boolean ignoreIdentifierAndLiteralSequences) { boolean seenAllowedToken = false; int braceCount = 0; for (final JavaccToken token : remainingTokens) { @@ -144,7 +144,7 @@ private static JavaccToken findEndOfSequenceToDiscard(final Iterable interpolatedVerbatiums = new Stack(); +private Stack interpolatedVerbatims = new Stack(); private Stack curlyLevels = new Stack(); -private boolean verbatium; +private boolean verbatim; } BYTE_ORDER_MARK: '\u00EF\u00BB\u00BF'; @@ -150,9 +150,9 @@ CHARACTER_LITERAL: '\'' (~['\\\r\n\u0085\u2028\u2029] | Common REGULAR_STRING: '"' (~["\\\r\n\u0085\u2028\u2029] | CommonCharacter)* '"'; VERBATIUM_STRING: '@"' (~'"' | '""')* '"'; INTERPOLATED_REGULAR_STRING_START: '$"' - { interpolatedStringLevel++; interpolatedVerbatiums.push(false); verbatium = false; } -> pushMode(INTERPOLATION_STRING); + { interpolatedStringLevel++; interpolatedVerbatims.push(false); verbatim = false; } -> pushMode(INTERPOLATION_STRING); INTERPOLATED_VERBATIUM_STRING_START: ('$@"' | '@$"') - { interpolatedStringLevel++; interpolatedVerbatiums.push(true); verbatium = true; } -> pushMode(INTERPOLATION_STRING); + { interpolatedStringLevel++; interpolatedVerbatims.push(true); verbatim = true; } -> pushMode(INTERPOLATION_STRING); //B.1.9 Operators And Punctuators OPEN_BRACE: '{' @@ -245,12 +245,12 @@ mode INTERPOLATION_STRING; DOUBLE_CURLY_INSIDE: '{{'; OPEN_BRACE_INSIDE: '{' { curlyLevels.push(1); } -> skip, pushMode(DEFAULT_MODE); -REGULAR_CHAR_INSIDE: { !verbatium }? SimpleEscapeSequence; -VERBATIUM_DOUBLE_QUOTE_INSIDE: { verbatium }? '""'; -DOUBLE_QUOTE_INSIDE: '"' { interpolatedStringLevel--; interpolatedVerbatiums.pop(); - verbatium = (interpolatedVerbatiums.size() > 0 ? interpolatedVerbatiums.peek() : false); } -> popMode; -REGULAR_STRING_INSIDE: { !verbatium }? ~('{' | '\\' | '"')+; -VERBATIUM_INSIDE_STRING: { verbatium }? ~('{' | '"')+; +REGULAR_CHAR_INSIDE: { !verbatim }? SimpleEscapeSequence; +VERBATIUM_DOUBLE_QUOTE_INSIDE: { verbatim }? '""'; +DOUBLE_QUOTE_INSIDE: '"' { interpolatedStringLevel--; interpolatedVerbatims.pop(); + verbatim = (interpolatedVerbatims.size() > 0 ? interpolatedVerbatims.peek() : false); } -> popMode; +REGULAR_STRING_INSIDE: { !verbatim }? ~('{' | '\\' | '"')+; +VERBATIUM_INSIDE_STRING: { verbatim }? ~('{' | '"')+; mode INTERPOLATION_FORMAT; diff --git a/pmd-dart/src/main/antlr4/net/sourceforge/pmd/lang/dart/ast/Dart.g4 b/pmd-dart/src/main/antlr4/net/sourceforge/pmd/lang/dart/ast/Dart.g4 index be3d39ee055..72ade112b19 100644 --- a/pmd-dart/src/main/antlr4/net/sourceforge/pmd/lang/dart/ast/Dart.g4 +++ b/pmd-dart/src/main/antlr4/net/sourceforge/pmd/lang/dart/ast/Dart.g4 @@ -543,7 +543,7 @@ relationalOperator | '<' ; -// 16.26 Bitwize Expression +// 16.26 Bitwise Expression bitwiseOrExpression : bitwiseXorExpression ('|' bitwiseXorExpression)* | 'super' ('|' bitwiseOrExpression)+ diff --git a/pmd-gherkin/src/test/resources/net/sourceforge/pmd/lang/gherkin/cpd/testdata/annotatedSource.feature b/pmd-gherkin/src/test/resources/net/sourceforge/pmd/lang/gherkin/cpd/testdata/annotatedSource.feature index 45008f6c710..f0a1664518f 100644 --- a/pmd-gherkin/src/test/resources/net/sourceforge/pmd/lang/gherkin/cpd/testdata/annotatedSource.feature +++ b/pmd-gherkin/src/test/resources/net/sourceforge/pmd/lang/gherkin/cpd/testdata/annotatedSource.feature @@ -6,7 +6,7 @@ Feature: Annotated Source 1 Annotation metrics can be selected with a dropdown menu. Only enabled metrics must be shown. 2 When the annotated source is opened while a specific metric is selected, only that metric should be selected. 3 A user can scroll through the violations using two buttons (illustrated by up and down arrows). The arrows wrap around the document. - 4 The table collumn "Type" is only shown when multiple metrics are selected + 4 The table column "Type" is only shown when multiple metrics are selected Scenario: Select a metric type Given the Annotated Source for file "HIE://11261-37/main/monop/execute.c" diff --git a/pmd-gherkin/src/test/resources/net/sourceforge/pmd/lang/gherkin/cpd/testdata/annotatedSource.txt b/pmd-gherkin/src/test/resources/net/sourceforge/pmd/lang/gherkin/cpd/testdata/annotatedSource.txt index cf05f81f6b2..60177ececd1 100644 --- a/pmd-gherkin/src/test/resources/net/sourceforge/pmd/lang/gherkin/cpd/testdata/annotatedSource.txt +++ b/pmd-gherkin/src/test/resources/net/sourceforge/pmd/lang/gherkin/cpd/testdata/annotatedSource.txt @@ -97,17 +97,17 @@ L9 [4] 3 4 [The] 5 8 [table] 9 14 - [collumn] 15 22 - ["Type"] 23 29 - [is] 30 32 - [only] 33 37 - [shown] 38 43 - [when] 44 48 - [multiple] 49 57 - [metrics] 58 65 - [are] 66 69 - [selected] 70 78 - [\n] 78 79 + [column] 15 21 + ["Type"] 22 28 + [is] 29 31 + [only] 32 36 + [shown] 37 42 + [when] 43 47 + [multiple] 48 56 + [metrics] 57 64 + [are] 65 68 + [selected] 69 77 + [\n] 77 78 L10 [\n] 1 2 L11 diff --git a/pmd-go/src/main/antlr4/net/sourceforge/pmd/lang/go/ast/Golang.g4 b/pmd-go/src/main/antlr4/net/sourceforge/pmd/lang/go/ast/Golang.g4 index c54605fc858..a0a3879feb9 100644 --- a/pmd-go/src/main/antlr4/net/sourceforge/pmd/lang/go/ast/Golang.g4 +++ b/pmd-go/src/main/antlr4/net/sourceforge/pmd/lang/go/ast/Golang.g4 @@ -98,11 +98,11 @@ grammar Golang; } /** - * Returns {@code true} if no line terminator exists after any encounterd + * Returns {@code true} if no line terminator exists after any encountered * parameters beyond the specified token offset and the next on the * {@code HIDDEN} channel. * - * @return {@code true} if no line terminator exists after any encounterd + * @return {@code true} if no line terminator exists after any encountered * parameters beyond the specified token offset and the next on the * {@code HIDDEN} channel. */ diff --git a/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/btrfs.go b/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/btrfs.go index b8c0434bdcb..5d3e045d73c 100644 --- a/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/btrfs.go +++ b/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/btrfs.go @@ -449,7 +449,7 @@ func subvolLimitQgroup(path string, size uint64) error { // subvolQgroupStatus performs a BTRFS_IOC_TREE_SEARCH on the root path // with search key of BTRFS_QGROUP_STATUS_KEY. -// In case qgroup is enabled, the retuned key type will match BTRFS_QGROUP_STATUS_KEY. +// In case qgroup is enabled, the returned key type will match BTRFS_QGROUP_STATUS_KEY. // For more details please see https://github.com/kdave/btrfs-progs/blob/v4.9/qgroup.c#L1035 func subvolQgroupStatus(path string) error { dir, err := openDir(path) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecorator.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecorator.java index c7b4f77525b..c9ba80407fb 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecorator.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaViolationDecorator.java @@ -58,7 +58,7 @@ public void decorate(Node violationNode, Map additionalInfo) { enclosing = javaNode.getRoot().getTypeDeclarations().first(); } if (enclosing != null) { - String className = determineCanoncialName(enclosing); + String className = determineCanonicalName(enclosing); String packageName = enclosing.getPackageName(); if (className != null && !packageName.isEmpty()) { assert className.startsWith(packageName); @@ -69,13 +69,13 @@ public void decorate(Node violationNode, Map additionalInfo) { return null; } - private String determineCanoncialName(ASTTypeDeclaration type) { + private String determineCanonicalName(ASTTypeDeclaration type) { final String canonicalName; ASTTypeDeclaration enclosingType = type.getEnclosingType(); if (type.isLocal()) { - canonicalName = determineCanoncialName(enclosingType) + "." + type.getSimpleName(); + canonicalName = determineCanonicalName(enclosingType) + "." + type.getSimpleName(); } else if (type.isAnonymous()) { - canonicalName = determineCanoncialName(enclosingType); + canonicalName = determineCanonicalName(enclosingType); } else { canonicalName = type.getCanonicalName(); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java index 1061e1e55e3..460842bb1eb 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java @@ -171,7 +171,7 @@ private boolean roamStatementsForExit(NodeStream stmts) { ASTStatement body = ((ASTLoopStatement) stmt).getBody(); for (JavaNode child : stmt.children()) { if (child != body) { - checkVorViolations(child); + checkForViolations(child); } } @@ -180,18 +180,18 @@ private boolean roamStatementsForExit(NodeStream stmts) { } else if (stmt instanceof ASTSwitchStatement) { ASTSwitchStatement switchStmt = (ASTSwitchStatement) stmt; - checkVorViolations(switchStmt.getTestedExpression()); + checkForViolations(switchStmt.getTestedExpression()); mayExit |= copy(true, true, false).roamStatementsForExit(switchStmt.getBranches()); } else if (stmt instanceof ASTIfStatement) { ASTIfStatement ifStmt = (ASTIfStatement) stmt; - checkVorViolations(ifStmt.getCondition()); + checkForViolations(ifStmt.getCondition()); mayExit |= withGuard(true).roamStatementsForExit(ifStmt.getThenBranch()); mayExit |= withGuard(this.guarded).roamStatementsForExit(ifStmt.getElseBranch()); } else if (stmt instanceof ASTExpression) { // these two catch-all clauses implement other statements & eg switch branches - checkVorViolations(stmt); + checkForViolations(stmt); } else if (!(stmt instanceof ASTLocalClassStatement)) { mayExit |= roamStatementsForExit(stmt.children()); } @@ -199,7 +199,7 @@ private boolean roamStatementsForExit(NodeStream stmts) { return mayExit; } - private void checkVorViolations(JavaNode node) { + private void checkForViolations(JavaNode node) { if (node == null) { return; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/TypeAnnotationHelper.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/TypeAnnotationHelper.java index b59d6d78044..ee8bd3b4ce6 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/TypeAnnotationHelper.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/TypeAnnotationHelper.java @@ -149,7 +149,7 @@ private static JTypeMirror resolvePathStepNoInner(JTypeMirror t, @Nullable TypeP JTypeMirror newBound = resolvePathStep(wild.getBound(), path, i + 1, annot); return wild.getTypeSystem().wildcard(wild.isUpperBound(), newBound).withAnnotations(wild.getTypeAnnotations()); } - throw new IllegalArgumentException("Expected wilcard type: " + t); + throw new IllegalArgumentException("Expected wildcard type: " + t); default: throw new IllegalArgumentException("Illegal path step for annotation TypePath" + i); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java index 0ca93e8a38e..c468711b603 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprCheckHelper.java @@ -317,8 +317,8 @@ private boolean isMethodRefCompatible(@NonNull JClassType functionalItf, MethodR JMethodSig exactMethod = ExprOps.getExactMethod(mref); if (exactMethod != null) { - // if the method reference is exact (ยง15.13.1), then let P1, ..., Pn be the parameter - // types of the function type of T, and let F1, ..., Fk be + // if the method reference is exact (ยง15.13.1), then let P_1, ..., P_n be the parameter + // types of the function type of T, and let F_1, ..., F_k be // the parameter types of the potentially applicable method List ps = fun.getFormalParameters(); List fs = exactMethod.getFormalParameters(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java index b8ab14e3436..ae24a6e2304 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.java @@ -508,13 +508,13 @@ private static Iterable getAccessibleCandidates(MethodRefMirror mref if (asInstanceMethod && typeToSearch.isRaw() && typeToSearch instanceof JClassType && targetType.getArity() > 0) { - // In the second search, if P1, ..., Pn is not empty + // In the second search, if P_1, ..., P_n is not empty // and P1 is a subtype of ReferenceType, then the // method reference expression is treated as if it were // a method invocation expression with argument expressions - // of types P2, ..., Pn. If ReferenceType is a raw type, + // of types P_2, ..., P_n. If ReferenceType is a raw type, // and there exists a parameterization of this type, G<...>, - // that is a supertype of P1, the type to search is the result + // that is a supertype of P_1, the type to search is the result // of capture conversion (ยง5.1.10) applied to G<...>; otherwise, // the type to search is the same as the type of the first search. diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java index 8becbc1f02d..1e4a257a2e9 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/Infer.java @@ -655,7 +655,7 @@ private JMethodSig tryToSolve(JMethodSig m, MethodCallSite site, InferenceContex // this means we're not in an invocation context, // if we are, we must ignore it in java 7 if (site.getOuterCtx().isEmpty()) { - // Then add the return contraints late + // Then add the return constraints late // Java 7 only uses the context type if the arguments are not enough // https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2.8 m = doReturnChecksAndChangeReturnType(m, site, infCtx); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLikeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLikeTest.java index e13580cc868..073c3e117ca 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLikeTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ASTSwitchLikeTest.java @@ -90,7 +90,7 @@ void exhaustiveSwitchSealedClassesAST() { () -> assertSwitch(switchStatements.get("exhaustiveSealed"), false, true, false), () -> assertSwitch(switchStatements.get("exhaustiveSealedWithDefault"), false, true, true), // Note: the method "notExhaustiveSealed" doesn't actually compile - it is not exhaustive and doesn't have a default - // the implementation of #isExhaustive uses a shortcut by assuming, the code it sees compiles and assumes it is exhausive... + // the implementation of #isExhaustive uses a shortcut by assuming, the code it sees compiles and assumes it is exhaustive... //() -> assertSwitch(switchStatements.get("notExhaustiveSealed"), false, false, false), () -> assertSwitch(switchStatements.get("notExhaustiveSealedWithDefault"), false, false, true), () -> assertSwitch(switchStatements.get("exhaustiveEnum"), true, true, false), diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/NodeParsingCtx.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/NodeParsingCtx.kt index cecc164d177..643232895d7 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/NodeParsingCtx.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/NodeParsingCtx.kt @@ -39,7 +39,7 @@ abstract class NodeParsingCtx(val constructName: String) { /** * Parse the string the context described by this object, and finds the first descendant of type [N]. * The descendant is searched for by [findFirstNodeOnStraightLine], to prevent accidental - * mis-selection of a node. In such a case, a [NoSuchElementException] is thrown, and you + * selection of a wrong node. In such a case, a [NoSuchElementException] is thrown, and you * should fix your test case. * * @param construct The construct to parse diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases18.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases18.java index 82d83097df4..48393d80675 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases18.java +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases18.java @@ -135,7 +135,7 @@ void monitorTemperature() throws @Critical TemperatureException {} // https://sourceforge.net/p/pmd/bugs/1205/ public static class X { - public void lambaWithIf() { + public void lambdaWithIf() { Stream.of(1, 2, 3) .sorted((a, b) -> { int x = a.hashCode() - b.hashCode(); @@ -145,7 +145,7 @@ public void lambaWithIf() { }) .count(); } - public void lambaWithIf2() { + public void lambdaWithIf2() { Stream.of(1, 2, 3) .sorted((Integer a, Integer b) -> { int x = a.hashCode() - b.hashCode(); diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases18.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases18.txt index 6fbbbaf0f4e..1ba36a52649 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases18.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/ParserCornerCases18.txt @@ -760,7 +760,7 @@ | +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "ParserCornerCases18$X", @CanonicalName = "ParserCornerCases18.X", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "X", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] | | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.STATIC), @ExplicitModifiers = (JModifier.PUBLIC, JModifier.STATIC)] | | +- ClassBody[@Empty = false, @Size = 3] - | | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @Name = "lambaWithIf", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @Void = true] + | | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @Name = "lambdaWithIf", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @Void = true] | | | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] | | | +- VoidType[] | | | +- FormalParameters[@Empty = true, @Size = 0] @@ -811,7 +811,7 @@ | | | | +- ReturnStatement[] | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] | | | +- ArgumentList[@Empty = true, @Size = 0] - | | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @Name = "lambaWithIf2", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @Void = true] + | | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @Name = "lambdaWithIf2", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @Void = true] | | | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] | | | +- VoidType[] | | | +- FormalParameters[@Empty = true, @Size = 0] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/EnumComparison.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/EnumComparison.xml index 8844df71128..1f9f2bfd403 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/EnumComparison.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/EnumComparison.xml @@ -75,7 +75,7 @@ class Foo { RetentionPolicy y = RetentionPolicy.CLASS; if (x.equals(y)) {} // violation, line 9 - if (y.equals(x)) {} // violation, ine 10 + if (y.equals(x)) {} // violation, line 10 // note: this is compilation error (incompatible types) if (x == y) {} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml index f719fda5d43..54fd0b64e56 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UselessParentheses.xml @@ -656,9 +656,9 @@ public class Test { public final class TestStringInterned { public static void main(String[] args) { - String hello = "Hello"; - String lo = "lo"; - System.out.println(hello == ("Hel" + lo).intern()); + String cargo = "Cargo"; + String go = "go"; + System.out.println(cargo == ("Car" + go).intern()); } } ]]> diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/AvoidInstantiatingObjectsInLoops.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/AvoidInstantiatingObjectsInLoops.xml index c750a3afd9a..c46feb570c7 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/AvoidInstantiatingObjectsInLoops.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/AvoidInstantiatingObjectsInLoops.xml @@ -420,7 +420,7 @@ public class AvoidInstantiatingArraysInLoops { import java.util.ArrayList; import java.util.List; -public class AvoidInsantiatingArraysInLoops { +public class AvoidInstantiatingArraysInLoops { public void test() { List data = new ArrayList<>(); diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseStringBufferLength.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseStringBufferLength.xml index 37b7c6cab08..dbc6a9ce3e7 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseStringBufferLength.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/UseStringBufferLength.xml @@ -172,7 +172,7 @@ public class Foo { #1177 Incorrect StringBuffer warning when that class is not used 0 diff --git a/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTAssignment.java b/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTAssignment.java index 04a3c928fdf..84365e72550 100644 --- a/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTAssignment.java +++ b/pmd-javascript/src/main/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTAssignment.java @@ -7,8 +7,8 @@ import org.mozilla.javascript.ast.Assignment; public final class ASTAssignment extends AbstractInfixEcmascriptNode { - ASTAssignment(Assignment asssignment) { - super(asssignment); + ASTAssignment(Assignment assignment) { + super(assignment); } @Override diff --git a/pmd-javascript/src/main/resources/category/ecmascript/bestpractices.xml b/pmd-javascript/src/main/resources/category/ecmascript/bestpractices.xml index c46cbe920d3..1e197106851 100644 --- a/pmd-javascript/src/main/resources/category/ecmascript/bestpractices.xml +++ b/pmd-javascript/src/main/resources/category/ecmascript/bestpractices.xml @@ -75,7 +75,7 @@ function bar() { class="net.sourceforge.pmd.lang.rule.xpath.XPathRule" externalInfoUrl="${pmd.website.baseurl}/pmd_rules_ecmascript_bestpractices.html#globalvariable"> -This rule helps to avoid using accidently global variables by simply missing the "var" declaration. +This rule helps to avoid using accidentally global variables by simply missing the "var" declaration. Global variables can lead to side-effects that are hard to debug. 1 diff --git a/pmd-javascript/src/main/resources/category/ecmascript/codestyle.xml b/pmd-javascript/src/main/resources/category/ecmascript/codestyle.xml index 055c512228c..cd2019152ce 100644 --- a/pmd-javascript/src/main/resources/category/ecmascript/codestyle.xml +++ b/pmd-javascript/src/main/resources/category/ecmascript/codestyle.xml @@ -216,7 +216,7 @@ return z; externalInfoUrl="${pmd.website.baseurl}/pmd_rules_ecmascript_codestyle.html#unnecessaryblock"> An unnecessary Block is present. Such Blocks are often used in other languages to -introduce a new variable scope. Blocks do not behave like this in ECMAScipt, and using them can +introduce a new variable scope. Blocks do not behave like this in ECMAScript, and using them can be misleading. Considering removing this unnecessary Block. 3 diff --git a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTTryStatementTest.java b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTTryStatementTest.java index 8c0059f9bc0..a0c09bfbff2 100644 --- a/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTTryStatementTest.java +++ b/pmd-javascript/src/test/java/net/sourceforge/pmd/lang/ecmascript/ast/ASTTryStatementTest.java @@ -23,9 +23,9 @@ class ASTTryStatementTest extends EcmascriptParserTestBase { private ASTTryStatement getTryStmt(String js) { EcmascriptNode node = this.js.parse(js); - List trys = node.descendants(ASTTryStatement.class).toList(); - assertEquals(1, trys.size()); - ASTTryStatement tryStmt = trys.get(0); + List tries = node.descendants(ASTTryStatement.class).toList(); + assertEquals(1, tries.size()); + ASTTryStatement tryStmt = tries.get(0); return tryStmt; } diff --git a/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/xml/UnnecessaryBlock.xml b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/xml/UnnecessaryBlock.xml index b30bcdf92fc..2b9d8ed2099 100644 --- a/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/xml/UnnecessaryBlock.xml +++ b/pmd-javascript/src/test/resources/net/sourceforge/pmd/lang/ecmascript/rule/codestyle/xml/UnnecessaryBlock.xml @@ -209,7 +209,7 @@ try { - Ok, destructure assigments (#2305) + Ok, destructuring assignments (#2305) 0 - Ok, destructure assigments (#2305) - without semicolons + Ok, destructuring assignments (#2305) - without semicolons 0 MORE: { < ~[] > } - TOKEN : /* SEPARATORS AND OTHER USEFULL LANGUAGE CONSTRUCTS*/ + TOKEN : /* SEPARATORS AND OTHER USEFUL LANGUAGE CONSTRUCTS*/ { < SEMI: ";" > : DEFAULT | < LPAREN: "(" > : DEFAULT diff --git a/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/sample-matlab.m b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/sample-matlab.m index 8d56a318c88..31911582595 100644 --- a/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/sample-matlab.m +++ b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/sample-matlab.m @@ -34,7 +34,7 @@ % CHEBFUN(A, 'equi') are similar, but here the data is assumed to come from a % 1st-kind Chebyshev or equispaced grid linspace(-1, 1, N), respectively. (In % the latter case, a smooth interpolant is constructed using an adaptive -% Floater-Hormann scheme [Numer. Math. 107, 315-331 (2007)].). CHEBFUN(F, N) or +% Floater-Hormann scheme [Numerische Mathematik 107, 315-331 (2007)].). CHEBFUN(F, N) or % CHEBFUN(F, N, 'chebkind', 2) is equivalent to CHEBFUN(feval(F, chebpts(N)). % % CHEBFUN(C, 'coeffs'), where C is an Nx1 matrix, constructs a CHEBFUN object @@ -468,7 +468,7 @@ varargin = fzero(varargout); % Get Delta functions within a CHEBFUN. - [deltaMag, deltLoc] = getDeltaFunctions(f); + [deltaMag, deltaLoc] = getDeltaFunctions(f); % Get roots of a CHEBFUN and polish for use as breakpoints. [rBreaks, rAll] = getRootsForBreaks(f, tol) diff --git a/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/sample-matlab.txt b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/sample-matlab.txt index a015ab0f439..77b0aa8c010 100644 --- a/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/sample-matlab.txt +++ b/pmd-matlab/src/test/resources/net/sourceforge/pmd/lang/matlab/cpd/testdata/sample-matlab.txt @@ -1157,14 +1157,14 @@ L471 [\[] 9 10 [deltaMag] 10 18 [,] 18 19 - [deltLoc] 20 27 - [\]] 27 28 - [=] 29 30 - [getDeltaFunctions] 31 48 - [(] 48 49 - [f] 49 50 - [)] 50 51 - [;] 51 52 + [deltaLoc] 20 28 + [\]] 28 29 + [=] 30 31 + [getDeltaFunctions] 32 49 + [(] 49 50 + [f] 50 51 + [)] 51 52 + [;] 52 53 L474 [\[] 9 10 [rBreaks] 10 17 diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaBuiltinType.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaBuiltinType.java index 81683f8e051..0f91b4c5912 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaBuiltinType.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaBuiltinType.java @@ -34,8 +34,8 @@ public String toString() { private final BaseType baseType; - ModelicaBuiltinType(BaseType tpe) { - baseType = tpe; + ModelicaBuiltinType(BaseType type) { + baseType = type; } public BaseType getBaseType() { diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaClassDeclaration.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaClassDeclaration.java index 8d88218fcc1..67d58c69c11 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaClassDeclaration.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaClassDeclaration.java @@ -186,15 +186,15 @@ private void lookupInInstanceScopeFurtherParts(ResolutionContext result, Modelic ModelicaComponentDeclaration component = (ModelicaComponentDeclaration) resolvedSimpleName; if (result.getState().needRecurseInto(component)) { ResolutionResult componentTypes = component.getTypeCandidates(); - for (ModelicaType tpe : componentTypes.getBestCandidates()) { - if (tpe instanceof ModelicaClassDeclaration) { - ((ModelicaClassDeclaration) tpe).lookupInInstanceScope(result, furtherParts); + for (ModelicaType type : componentTypes.getBestCandidates()) { + if (type instanceof ModelicaClassDeclaration) { + ((ModelicaClassDeclaration) type).lookupInInstanceScope(result, furtherParts); } } result.markHidingPoint(); - for (ModelicaType tpe : componentTypes.getHiddenCandidates()) { - if (tpe instanceof ModelicaClassDeclaration) { - ((ModelicaClassDeclaration) tpe).lookupInInstanceScope(result, furtherParts); + for (ModelicaType type : componentTypes.getHiddenCandidates()) { + if (type instanceof ModelicaClassDeclaration) { + ((ModelicaClassDeclaration) type).lookupInInstanceScope(result, furtherParts); } } } diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/RootScope.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/RootScope.java index 5ed9a68c3c8..48cdf990810 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/RootScope.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/RootScope.java @@ -26,9 +26,9 @@ void addSourceFile(ModelicaSourceFileScope sourceFile) { void resolveBuiltin(ResolutionContext result, CompositeName name) { if (!name.isEmpty() && name.getTail().isEmpty()) { String simpleName = name.getHead(); - for (ModelicaBuiltinType.BaseType tpe: ModelicaBuiltinType.BaseType.values()) { - if (tpe.getName().equals(simpleName)) { - result.addCandidate(new ModelicaBuiltinType(tpe)); + for (ModelicaBuiltinType.BaseType type: ModelicaBuiltinType.BaseType.values()) { + if (type.getName().equals(simpleName)) { + result.addCandidate(new ModelicaBuiltinType(type)); } } } diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/internal/ResolutionContext.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/internal/ResolutionContext.java index 50961f0a733..43638dfb012 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/internal/ResolutionContext.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/internal/ResolutionContext.java @@ -72,14 +72,14 @@ private static class Result implements ResolutionRes private final List hiddenCandidates = new ArrayList<>(); private final boolean timedOut; - Result(Class tpe, List best, List hidden, boolean timedOut) { + Result(Class type, List best, List hidden, boolean timedOut) { for (Object b: best) { - if (tpe.isInstance(b)) { + if (type.isInstance(b)) { bestCandidates.add((A) b); } } for (Object h: hidden) { - if (tpe.isInstance(h)) { + if (type.isInstance(h)) { hiddenCandidates.add((A) h); } } diff --git a/pmd-modelica/src/main/javacc/Modelica.jjt b/pmd-modelica/src/main/javacc/Modelica.jjt index 96ecbf0eadc..01dc3925584 100644 --- a/pmd-modelica/src/main/javacc/Modelica.jjt +++ b/pmd-modelica/src/main/javacc/Modelica.jjt @@ -168,7 +168,7 @@ SKIP: { } -// Copyed from cpp.jj +// Copied from cpp.jj MORE: { "/*" : IN_MULTI_LINE_COMMENT } diff --git a/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/ModelicaParserTest.java b/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/ModelicaParserTest.java index daf1caf10c4..bd5a99a8821 100644 --- a/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/ModelicaParserTest.java +++ b/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/ModelicaParserTest.java @@ -8,7 +8,7 @@ class ModelicaParserTest { @Test - void testParsingGrapgical() { + void testParsingGraphical() { ModelicaParsingHelper.DEFAULT.parseResource("ParserTestGraphical.mo"); } diff --git a/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaResolverTest.java b/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaResolverTest.java index 7718391101f..8fbc9a60f58 100644 --- a/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaResolverTest.java +++ b/pmd-modelica/src/test/java/net/sourceforge/pmd/lang/modelica/resolver/ModelicaResolverTest.java @@ -273,9 +273,9 @@ void builtinTest() { ModelicaComponentDeclaration x = (ModelicaComponentDeclaration) xs.get(0); ResolutionResult xTypes = x.getTypeCandidates(); ensureCounts(xTypes, 1, 0); - ResolvableEntity tpe = xTypes.getBestCandidates().get(0); - assertTrue(tpe instanceof ModelicaBuiltinType); - assertEquals(ModelicaBuiltinType.BaseType.REAL, ((ModelicaBuiltinType) tpe).getBaseType()); + ResolvableEntity type = xTypes.getBestCandidates().get(0); + assertTrue(type instanceof ModelicaBuiltinType); + assertEquals(ModelicaBuiltinType.BaseType.REAL, ((ModelicaBuiltinType) type).getBaseType()); } @Test diff --git a/pmd-plsql/src/main/javacc/PLSQL.jjt b/pmd-plsql/src/main/javacc/PLSQL.jjt index 46ba17242f0..b63774fe58f 100644 --- a/pmd-plsql/src/main/javacc/PLSQL.jjt +++ b/pmd-plsql/src/main/javacc/PLSQL.jjt @@ -450,12 +450,12 @@ ASTSqlPlusCommand SqlPlusCommand() : /** * All global definitions of triggers, functions and procedures are evaluated here. * Every occurrence goes under a new PACKAGE-Node in the XML document. - * This happens, cause a global "block" does not have a definied start and end token + * This happens, cause a global "block" does not have a defined start and end token * like a package specification or a package body. * Thats why every construct is handled like a new part of the global package. * To overcome this problem, I could use an infinity lookahead - which should solve the problem * and slow down the whole parsing. - * Another idea would be to lookahead the next tokens and decide wether they belong to a package definition or not. + * Another idea would be to lookahead the next tokens and decide whether they belong to a package definition or not. * Then I could decide to stay in this global parsing state. By now lookahead gives the parser a hint to * choose the correct way on a given base. So we can't negate it easily. * On the other hand I could also hold the global state in a global variable. @@ -635,7 +635,7 @@ ASTCompilationDeclarationFragment CompilationDeclarationFragment() : * 2006-05-22 - Matthias Hendler - Printing of custom tag "@deprecated" removed. * Printing of any custom tag added. Now user can define his own * custom tags which he can evaluate in the XSLT. - * This methode also documents global functions/procedures. + * This method also documents global functions/procedures. */ ASTProgramUnit ProgramUnit() : { @@ -3011,7 +3011,7 @@ ASTSubTypeDefinition SubTypeDefinition() : [ ] //SRT 20110604 ) | - ( name = QualifiedID() // SRT 20110605 to Parse SYS.standars ned to allow nprmally reserved words which are low-level types + ( name = QualifiedID() // SRT 20110605 to Parse SYS.standard need to allow nprmally reserved words which are low-level types (|) ( LOOKAHEAD(2) ( @@ -3024,7 +3024,7 @@ ASTSubTypeDefinition SubTypeDefinition() : ) | - //SRT 20110606 SYS.STANDRD + //SRT 20110606 SYS.STANDARD ( "(" FieldDeclaration() ("," FieldDeclaration())* ")" ) | ( "(" FieldDeclaration() ("," FieldDeclaration())* ")" ) @@ -3659,7 +3659,7 @@ ASTIsOfTypeCondition IsOfTypeCondition() #IsOfTypeCondition(>1) : /** * 2006-05-23 - Matthias Hendler - Added lookahead otherwise warning encountered. - * Warning arised while adding methode triggerUnit(). + * Warning arose while adding method triggerUnit(). * 2011-04-27 - SRT - Add optional NEW Keyword to cope with Object Type constructors */ ASTPrimaryExpression PrimaryExpression() #PrimaryExpression(>1) : @@ -3845,7 +3845,7 @@ ASTNumericLiteral NumericLiteral() : } { ( - //Essentially unchanged, as it previouly returned a Token + //Essentially unchanged, as it previously returned a Token t = ) { @@ -4367,7 +4367,7 @@ ASTTypeSpecification TypeSpecification() : // //incomplete OBJECT TYPE and COLLECTION TYPEs will not have this [ ("(" ) - //Try matching against keywords first to allow FINCTION and procedure as a fallback + //Try matching against keywords first to allow FUNCTION and procedure as a fallback (LOOKAHEAD(2) TypeMethod() | AttributeDeclaration() | PragmaClause() )* //SRT 20111125 This part may be completely empty if is a subtype which is effectively an alias for the supertype @@ -4419,7 +4419,7 @@ ASTAlterTypeSpec AlterTypeSpec() : ( ( | ) ( - // Move typeMethidMatching above attribure matvhing becausse FUNCTION is a valid attribute name + // Move TypeMethod matching above attribute matching because FUNCTION is a valid attribute name ( (TypeMethod() ) //( "," ( typeMethod(,typeVersion, tokenAlterTypeString) ) )* @@ -4855,7 +4855,7 @@ ASTNonDMLEvent NonDMLEvent(): {} /* When DBMS_METADATA.GET_DDL returns a trigger, it can come in 2 DDL statements. -The first is the CREATE OR REPLACE TRIGER statement; the second is an ALTER TRIGGER statement, +The first is the CREATE OR REPLACE TRIGGER statement; the second is an ALTER TRIGGER statement, enabling or disabling the trigger. Unlike the ALTER TYPE, it does not seem to alter the structure of the object. @@ -4928,7 +4928,7 @@ SPECIAL_TOKEN : SPECIAL_TOKEN : { - //Remove terminating EOL from Single Comment Token definition: it causes failurs if no other newline exists before next production + //Remove terminating EOL from Single Comment Token definition: it causes failures if no other newline exists before next production } @@ -6679,7 +6679,7 @@ private void KEYWORD_NOT_RESERVED () #void: {} | | | -| // APEX_0400000.WWW_CALCUATOR.SHOW +| // APEX_0400000.WWW_CALCULATOR.SHOW | //Not a keyword - just a type defined in standard | | diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/InnerJoinUsing.pls b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/InnerJoinUsing.pls index 74109d3464b..ee0d868dd5d 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/InnerJoinUsing.pls +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/InnerJoinUsing.pls @@ -14,8 +14,8 @@ INTO r_record -- SELECT COUNT(qsec_id) - FROM quots_sections qsec - INNER JOIN quots_sections_lang USING (qsec_id) + FROM quote_sections qsec + INNER JOIN quote_sections_lang USING (qsec_id) WHERE qsec.wsh_id = 11 AND qsec.revision = 1 AND lang_code = 'en'; diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/IsOfType.pls b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/IsOfType.pls index 616188a165d..74617e51881 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/IsOfType.pls +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/IsOfType.pls @@ -2,8 +2,8 @@ PROCEDURE IsOfType ( inChannelID IN number, inOperID IN number, inClientId IN number, -ioFPOobj IN FPO_OBJ, -inPackageIDout IN number, +ioFPOObj IN FPO_OBJ, +inPackageIDOut IN number, inStatusId IN number) is loFPOGE_OBJ FPOGE_OBJ; diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/IsOfType.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/IsOfType.txt index 4f1b0c51f2c..8834a97bd33 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/IsOfType.txt +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/IsOfType.txt @@ -4,7 +4,7 @@ +- MethodDeclarator[@CanonicalImage = "ISOFTYPE", @Image = "IsOfType", @ParameterCount = 1] | +- ObjectNameDeclaration[@CanonicalImage = "ISOFTYPE", @Image = "IsOfType"] | | +- ID[@CanonicalImage = "ISOFTYPE", @Image = "IsOfType"] - | +- FormalParameters[@CanonicalImage = "(INCHANNELID,INOPERID,INCLIENTID,IOFPOOBJ,INPACKAGEIDOUT,INSTATUSID)", @Image = "(inChannelID,inOperID,inClientId,ioFPOobj,inPackageIDout,inStatusId)"] + | +- FormalParameters[@CanonicalImage = "(INCHANNELID,INOPERID,INCLIENTID,IOFPOOBJ,INPACKAGEIDOUT,INSTATUSID)", @Image = "(inChannelID,inOperID,inClientId,ioFPOObj,inPackageIDOut,inStatusId)"] | +- FormalParameter[@CanonicalImage = "INCHANNELID", @Image = "inChannelID", @In = true, @NoCopy = false, @Out = false] | | +- ID[@CanonicalImage = "INCHANNELID", @Image = "inChannelID"] | | +- Datatype[@CanonicalImage = "NUMBER", @Image = "NUMBER", @TypeImage = "NUMBER"] @@ -17,13 +17,13 @@ | | +- ID[@CanonicalImage = "INCLIENTID", @Image = "inClientId"] | | +- Datatype[@CanonicalImage = "NUMBER", @Image = "NUMBER", @TypeImage = "NUMBER"] | | +- ScalarDataTypeName[@CanonicalImage = "NUMBER", @Image = "NUMBER"] - | +- FormalParameter[@CanonicalImage = "IOFPOOBJ", @Image = "ioFPOobj", @In = true, @NoCopy = false, @Out = false] - | | +- ID[@CanonicalImage = "IOFPOOBJ", @Image = "ioFPOobj"] + | +- FormalParameter[@CanonicalImage = "IOFPOOBJ", @Image = "ioFPOObj", @In = true, @NoCopy = false, @Out = false] + | | +- ID[@CanonicalImage = "IOFPOOBJ", @Image = "ioFPOObj"] | | +- Datatype[@CanonicalImage = "FPO_OBJ", @Image = "FPO_OBJ", @TypeImage = "FPO_OBJ"] | | +- QualifiedName[@CanonicalImage = "FPO_OBJ", @Image = "FPO_OBJ"] | | +- UnqualifiedID[@CanonicalImage = "FPO_OBJ", @Image = "FPO_OBJ"] - | +- FormalParameter[@CanonicalImage = "INPACKAGEIDOUT", @Image = "inPackageIDout", @In = true, @NoCopy = false, @Out = false] - | | +- ID[@CanonicalImage = "INPACKAGEIDOUT", @Image = "inPackageIDout"] + | +- FormalParameter[@CanonicalImage = "INPACKAGEIDOUT", @Image = "inPackageIDOut", @In = true, @NoCopy = false, @Out = false] + | | +- ID[@CanonicalImage = "INPACKAGEIDOUT", @Image = "inPackageIDOut"] | | +- Datatype[@CanonicalImage = "NUMBER", @Image = "NUMBER", @TypeImage = "NUMBER"] | | +- ScalarDataTypeName[@CanonicalImage = "NUMBER", @Image = "NUMBER"] | +- FormalParameter[@CanonicalImage = "INSTATUSID", @Image = "inStatusId", @In = true, @NoCopy = false, @Out = false] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/XMLQuery.pls b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/XMLQuery.pls index 5e7c10c0f2d..50a00555a28 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/XMLQuery.pls +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/XMLQuery.pls @@ -7,7 +7,7 @@ DECLARE l_xml XMLTYPE := XMLTYPE(' Steven Feuerstein - Oracle PLSQL Languaje Pocket Reference + Oracle PLSQL Language Pocket Reference Programming 18.25 2015-09-04 diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/XMLQuery.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/XMLQuery.txt index 7dfbce81350..65894ba1897 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/XMLQuery.txt +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/XMLQuery.txt @@ -19,10 +19,10 @@ | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] | | +- ArgumentList[@CanonicalImage = null] | | +- Argument[@CanonicalImage = null] - | | +- Expression[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAJE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'"] - | | +- PrimaryPrefix[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAJE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'", @SelfModifier = false] - | | +- Literal[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAJE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'"] - | | +- StringLiteral[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAJE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'", @String = "\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n"] + | | +- Expression[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAGE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'"] + | | +- PrimaryPrefix[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAGE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAGE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'"] + | | +- StringLiteral[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAGE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'", @String = "\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n"] | +- DeclarativeUnit[@CanonicalImage = null] | | +- VariableOrConstantDeclaration[@CanonicalImage = null] | | +- VariableOrConstantDeclarator[@CanonicalImage = "L_TAGNAME VARCHAR2(100) := \'$P//AUTHOR\'", @Image = "l_tagname VARCHAR2(100) := \'$p//Author\'"] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/XMLType.pls b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/XMLType.pls index 55810efadeb..47b882bde52 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/XMLType.pls +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/XMLType.pls @@ -6,7 +6,7 @@ DECLARE l_xml1 XMLTYPE := XMLTYPE(' Steven Feuerstein - Oracle PLSQL Languaje Pocket Reference + Oracle PLSQL Language Pocket Reference Programming 18.25 2015-09-04 @@ -17,7 +17,7 @@ DECLARE l_xml2 XMLTYPE := XMLTYPE(' Steven Feuerstein - Oracle PLSQL Languaje Pocket Reference + Oracle PLSQL Language Pocket Reference Programming 18.25 2015-09-04 @@ -28,7 +28,7 @@ DECLARE l_xml3 XMLTYPE := XMLTYPE(' Steven Feuerstein - Oracle PLSQL Languaje Pocket Reference + Oracle PLSQL Language Pocket Reference Programming 18.25 2015-09-04 @@ -41,7 +41,7 @@ DECLARE l_xml4 XMLTYPE := XMLTYPE(' Steven Feuerstein - Oracle PLSQL Languaje Pocket Reference + Oracle PLSQL Language Pocket Reference Programming 18.25 2015-09-04 diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/XMLType.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/XMLType.txt index 847eff210e8..d614300ecfc 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/XMLType.txt +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/XMLType.txt @@ -19,10 +19,10 @@ | | +- Arguments[@ArgumentCount = 1, @CanonicalImage = null] | | +- ArgumentList[@CanonicalImage = null] | | +- Argument[@CanonicalImage = null] - | | +- Expression[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAJE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'"] - | | +- PrimaryPrefix[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAJE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'", @SelfModifier = false] - | | +- Literal[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAJE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'"] - | | +- StringLiteral[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAJE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'", @String = "\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n"] + | | +- Expression[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAGE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'"] + | | +- PrimaryPrefix[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAGE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAGE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'"] + | | +- StringLiteral[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAGE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'", @String = "\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n"] | +- DeclarativeUnit[@CanonicalImage = null] | | +- VariableOrConstantDeclaration[@CanonicalImage = null] | | +- VariableOrConstantDeclarator[@CanonicalImage = "L_XML2 XMLTYPE := XMLTYPE", @Image = "l_xml2 XMLTYPE := XMLTYPE"] @@ -40,10 +40,10 @@ | | +- Arguments[@ArgumentCount = 2, @CanonicalImage = null] | | +- ArgumentList[@CanonicalImage = null] | | +- Argument[@CanonicalImage = null] - | | | +- Expression[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAJE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'"] - | | | +- PrimaryPrefix[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAJE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'", @SelfModifier = false] - | | | +- Literal[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAJE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'"] - | | | +- StringLiteral[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAJE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'", @String = "\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n"] + | | | +- Expression[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAGE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'"] + | | | +- PrimaryPrefix[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAGE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAGE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'"] + | | | +- StringLiteral[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAGE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'", @String = "\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n"] | | +- Argument[@CanonicalImage = null] | | +- Expression[@CanonicalImage = "\'SCHEMA\'", @Image = "\'schema\'"] | | +- PrimaryPrefix[@CanonicalImage = "\'SCHEMA\'", @Image = "\'schema\'", @SelfModifier = false] @@ -66,10 +66,10 @@ | | +- Arguments[@ArgumentCount = 3, @CanonicalImage = null] | | +- ArgumentList[@CanonicalImage = null] | | +- Argument[@CanonicalImage = null] - | | | +- Expression[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAJE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'"] - | | | +- PrimaryPrefix[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAJE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'", @SelfModifier = false] - | | | +- Literal[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAJE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'"] - | | | +- StringLiteral[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAJE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'", @String = "\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n"] + | | | +- Expression[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAGE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'"] + | | | +- PrimaryPrefix[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAGE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'", @SelfModifier = false] + | | | +- Literal[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAGE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'"] + | | | +- StringLiteral[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAGE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'", @String = "\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n"] | | +- Argument[@CanonicalImage = null] | | | +- Expression[@CanonicalImage = "\'SCHEMA\'", @Image = "\'schema\'"] | | | +- PrimaryPrefix[@CanonicalImage = "\'SCHEMA\'", @Image = "\'schema\'", @SelfModifier = false] @@ -97,10 +97,10 @@ | +- Arguments[@ArgumentCount = 4, @CanonicalImage = null] | +- ArgumentList[@CanonicalImage = null] | +- Argument[@CanonicalImage = null] - | | +- Expression[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAJE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'"] - | | +- PrimaryPrefix[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAJE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'", @SelfModifier = false] - | | +- Literal[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAJE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'"] - | | +- StringLiteral[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAJE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'", @String = "\n \n Steven Feuerstein\n Oracle PLSQL Languaje Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n"] + | | +- Expression[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAGE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'"] + | | +- PrimaryPrefix[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAGE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'", @SelfModifier = false] + | | +- Literal[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAGE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'"] + | | +- StringLiteral[@CanonicalImage = "\'\n \n STEVEN FEUERSTEIN\n ORACLE PLSQL LANGUAGE POCKET REFERENCE\n PROGRAMMING\n 18.25\n 2015-09-04\n A GUIDE TO ORACLE PLSQL LANGUAGE FUNDAMENTALS.\n \n\'", @Image = "\'\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n\'", @String = "\n \n Steven Feuerstein\n Oracle PLSQL Language Pocket Reference\n Programming\n 18.25\n 2015-09-04\n A guide to Oracle PLSQL Language Fundamentals.\n \n"] | +- Argument[@CanonicalImage = null] | | +- Expression[@CanonicalImage = "\'SCHEMA\'", @Image = "\'schema\'"] | | +- PrimaryPrefix[@CanonicalImage = "\'SCHEMA\'", @Image = "\'schema\'", @SelfModifier = false] diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/cpd/testdata/sample-plsql.sql b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/cpd/testdata/sample-plsql.sql index e6c44f2f28e..793849342c4 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/cpd/testdata/sample-plsql.sql +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/cpd/testdata/sample-plsql.sql @@ -246,7 +246,7 @@ IS /** * ========================================================================
          * Project: Test Project (PLDoc)
          -* Description: Advices
          +* Description: Advice
          * DB impact: YES
          * Commit inside: YES
          * Rollback inside: YES
          @@ -260,7 +260,7 @@ TYPE advice_type_table IS TABLE OF advice_type_record INDEX BY BINARY_INTEGER; SUBTYPE advice_medium_record IS advice_medium%ROWTYPE; TYPE advice_medium_table IS TABLE OF advice_medium_record INDEX BY BINARY_INTEGER; -SUBTYPE advice_record IS advices%ROWTYPE; +SUBTYPE advice_record IS advice%ROWTYPE; TYPE advice_table IS TABLE OF advice_record INDEX BY BINARY_INTEGER; SUBTYPE sw_advice_record IS sw_advice%ROWTYPE; @@ -328,14 +328,14 @@ PROCEDURE Get ( r_result IN OUT NUMBER, -- return code, 0=ok r_message IN OUT VARCHAR2); -- return message --- Get list of advices on contract -PROCEDURE List_Advices ( +-- Get list of advice on contract +PROCEDURE List_Advice ( p_contract_id VARCHAR2, -- contract ID p_step_seq NUMBER, -- step number p_in_out VARCHAR2, -- direction r_result IN OUT NUMBER, -- return code, 0=ok r_message IN OUT VARCHAR2, -- return message - r_list IN OUT advice_table); -- list of advices + r_list IN OUT advice_table); -- list of advice -- Register advice PROCEDURE Ins ( @@ -376,7 +376,7 @@ PROCEDURE Get_Files ( r_message IN OUT VARCHAR2); -- return message /** -* Clearance for release of outgoing advices. +* Clearance for release of outgoing advice. * @param p_contract_id contract ID * @param p_step step number * @param p_app_user application user @@ -391,7 +391,7 @@ PROCEDURE CFR_Advice_Out ( r_message IN OUT VARCHAR2); /** -* Clearance for release of incoming advices. +* Clearance for release of incoming advice. * @param p_contract_id contract ID * @param p_step step number * @param p_app_user application user @@ -406,7 +406,7 @@ PROCEDURE CFR_Advice_In ( r_message IN OUT VARCHAR2); /** -* Step release of outgoing advices. +* Step release of outgoing advice. * @param p_contract_id contract ID * @param p_step step number * @param p_app_user application user @@ -421,7 +421,7 @@ PROCEDURE Release_Advice_Out ( r_message IN OUT VARCHAR2); /** -* Step release of incoming advices. +* Step release of incoming advice. * @param p_contract_id contract ID * @param p_step step number * @param p_app_user application user diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/cpd/testdata/sample-plsql.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/cpd/testdata/sample-plsql.txt index c51a31077a5..20366e502f8 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/cpd/testdata/sample-plsql.txt +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/cpd/testdata/sample-plsql.txt @@ -659,10 +659,10 @@ L263 [SUBTYPE] 1 8 [ADVICE_RECORD] 9 22 [IS] 23 25 - [ADVICES] 26 33 - [%] 33 34 - [ROWTYPE] 34 41 - [;] 41 42 + [ADVICE] 26 32 + [%] 32 33 + [ROWTYPE] 33 40 + [;] 40 41 L264 [TYPE] 1 5 [ADVICE_TABLE] 6 18 @@ -856,8 +856,8 @@ L329 [;] 37 38 L332 [PROCEDURE] 1 10 - [LIST_ADVICES] 11 23 - [(] 24 25 + [LIST_ADVICE] 11 22 + [(] 23 24 L333 [P_CONTRACT_ID] 3 16 [VARCHAR2] 21 29 diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/cpd/testdata/sample-plsql_ignore-literals.txt b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/cpd/testdata/sample-plsql_ignore-literals.txt index 977057fddf9..f7426af1914 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/cpd/testdata/sample-plsql_ignore-literals.txt +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/cpd/testdata/sample-plsql_ignore-literals.txt @@ -659,10 +659,10 @@ L263 [SUBTYPE] 1 8 [ADVICE_RECORD] 9 22 [IS] 23 25 - [ADVICES] 26 33 - [%] 33 34 - [ROWTYPE] 34 41 - [;] 41 42 + [ADVICE] 26 32 + [%] 32 33 + [ROWTYPE] 33 40 + [;] 40 41 L264 [TYPE] 1 5 [ADVICE_TABLE] 6 18 @@ -856,8 +856,8 @@ L329 [;] 37 38 L332 [PROCEDURE] 1 10 - [LIST_ADVICES] 11 23 - [(] 24 25 + [LIST_ADVICE] 11 22 + [(] 23 24 L333 [P_CONTRACT_ID] 3 16 [VARCHAR2] 21 29 diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/rule/design/xml/NcssMethodCount.xml b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/rule/design/xml/NcssMethodCount.xml index e548a1436d5..da37a7589d4 100644 --- a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/rule/design/xml/NcssMethodCount.xml +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/rule/design/xml/NcssMethodCount.xml @@ -16,7 +16,7 @@ CREATE OR REPLACE PROCEDURE prc_test_unreserved_keyword /*

          This procedure is based on {@link pkg_test_unreserved_keyword} and the variable definitions should be kept - sychronised to that package specification. + synchronised to that package specification.

          diff --git a/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/cpd/testdata/sample-LiftActor.scala b/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/cpd/testdata/sample-LiftActor.scala index 142aa96f205..e3f0118cf9e 100644 --- a/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/cpd/testdata/sample-LiftActor.scala +++ b/pmd-scala-modules/pmd-scala-common/src/test/resources/net/sourceforge/pmd/lang/scala/cpd/testdata/sample-LiftActor.scala @@ -518,7 +518,7 @@ with ForwardableActor[Any, Any] { } /** - * A MockLiftActor for use in testing other compnents that talk to actors. + * A MockLiftActor for use in testing other components that talk to actors. * * Much like MockSpecializedLiftActor, this class is intended to be injected into other * components, such as snippets, during testing. Whereas these components would normally diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/BTree.swift b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/BTree.swift index ceefe4f25e1..9940a571454 100644 --- a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/BTree.swift +++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/ast/testdata/BTree.swift @@ -906,7 +906,7 @@ extension BTree { without "escaping" single quotes. The indentation of the closing quotes - below deside where the text line + below decide where the text line begins. You can even dynamically add values diff --git a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/BTree.swift b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/BTree.swift index 9b283a3ec8b..05f537340bf 100644 --- a/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/BTree.swift +++ b/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/cpd/testdata/BTree.swift @@ -906,7 +906,7 @@ extension BTree { without "escaping" single quotes. The indentation of the closing quotes - below deside where the text line + below decide where the text line begins. You can even dynamically add values diff --git a/pmd-tsql/src/test/resources/net/sourceforge/pmd/lang/tsql/cpd/testdata/MailJobTimeLine.sql b/pmd-tsql/src/test/resources/net/sourceforge/pmd/lang/tsql/cpd/testdata/MailJobTimeLine.sql index 17e7e1e26f9..b0779cd2388 100644 --- a/pmd-tsql/src/test/resources/net/sourceforge/pmd/lang/tsql/cpd/testdata/MailJobTimeLine.sql +++ b/pmd-tsql/src/test/resources/net/sourceforge/pmd/lang/tsql/cpd/testdata/MailJobTimeLine.sql @@ -624,7 +624,7 @@ SELECT ' DECLARE @emailBodyText NVARCHAR(MAX); SET @emailBodyText = 'Timeline of all jobs between ' + CONVERT(VARCHAR(20), @StartDate, 120) + ' to ' - + CONVERT(VARCHAR(20), @EndDate, 120) + ' open the attachement.' + + CONVERT(VARCHAR(20), @EndDate, 120) + ' open the attachment.' DECLARE @emailSubjectText NVARCHAR(MAX); SET @emailSubjectText = @@servername + ' Jons between ' diff --git a/pmd-tsql/src/test/resources/net/sourceforge/pmd/lang/tsql/cpd/testdata/MailJobTimeLine.txt b/pmd-tsql/src/test/resources/net/sourceforge/pmd/lang/tsql/cpd/testdata/MailJobTimeLine.txt index e8925013845..528a24e7a93 100644 --- a/pmd-tsql/src/test/resources/net/sourceforge/pmd/lang/tsql/cpd/testdata/MailJobTimeLine.txt +++ b/pmd-tsql/src/test/resources/net/sourceforge/pmd/lang/tsql/cpd/testdata/MailJobTimeLine.txt @@ -2107,7 +2107,7 @@ L627 [120] 37 40 [)] 40 41 [+] 42 43 - [' open the attachement.'] 44 68 + [' open the attachment.'] 44 67 L629 [DECLARE] 1 8 [@EMAILSUBJECTTEXT] 9 26 diff --git a/pmd-velocity/src/main/javacc/Vtl.jjt b/pmd-velocity/src/main/javacc/Vtl.jjt index 975196b0fb4..28f016fa86d 100644 --- a/pmd-velocity/src/main/javacc/Vtl.jjt +++ b/pmd-velocity/src/main/javacc/Vtl.jjt @@ -406,7 +406,7 @@ TOKEN: * to render properly in front of the block * * This is really simplistic. I actually would prefer to find them in - * grammatical context, but I am neither smart nor rested, a receipe + * grammatical context, but I am neither smart nor rested, a recipe * for disaster, another long night with Mr. Parser, or both. */ @@ -424,9 +424,9 @@ TOKEN: * address JIRA issue VELOCITY-631. With SET_DIRECTIVE only in the * DEFAULT lexical state the following VTL fails "$a#set($b = 1)" * because the Reference token uses LOOKAHEAD(2) combined with the - * fact that we explicity set the lex state to REFERENCE with the $ - * token, which means we would never evaulate this token during the - * look ahead. This general issue is disscussed here: + * fact that we explicitly set the lex state to REFERENCE with the $ + * token, which means we would never evaluate this token during the + * look ahead. This general issue is discussed here: * * http://www.engr.mun.ca/~theo/JavaCC-FAQ/javacc-faq-ie.htm#tth_sEc3.12 * @@ -716,7 +716,7 @@ TOKEN : { /* * - if we are in DIRECTIVE and haven't seen ( yet, then also drop out. - * don't forget to account for the beloved yet wierd #set + * don't forget to account for the beloved yet weird #set * - finally, if we are in REFMOD2 (remember : $foo.bar( ) then " is ok! */ @@ -1595,7 +1595,7 @@ void PrimaryExpression() #void : {} DIRECTIVE : This state is triggered by the a match of a DD or a PD. - REFERENCE : Triggered by '$'. Analagous to PRE_DIRECTIVE. + REFERENCE : Triggered by '$'. Analogous to PRE_DIRECTIVE. REFMODIFIER : Triggered by . when in REFERENCE. @@ -1612,9 +1612,9 @@ void PrimaryExpression() #void : {} A VTL element is either : - 1) It preceeds a reference that is in the context. + 1) It precedes a reference that is in the context. - 2) It preceeds a defined directive (#set, #if, #end, etc) or a valid + 2) It precedes a defined directive (#set, #if, #end, etc) or a valid pluggable directive, such as #foreach In all other cases the '\' is just another piece of text. The purpose of this diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/DataType.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/DataType.java index 45efabccf9d..d4eef820ab1 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/DataType.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/DataType.java @@ -50,7 +50,7 @@ public enum DataType { Time(false, "Time"), Url(false), /** - * Indicates that Metatada was found, but its type was not mappable. This could because it is a type which isn't + * Indicates that Metadata was found, but its type was not mappable. This could because it is a type which isn't * mapped, or it was an edge case where the type was ambiguously defined in the Metadata. */ Unknown(true); diff --git a/pmd-visualforce/src/main/javacc/Vf.jjt b/pmd-visualforce/src/main/javacc/Vf.jjt index 81c31b2df7f..c468ebd7c75 100644 --- a/pmd-visualforce/src/main/javacc/Vf.jjt +++ b/pmd-visualforce/src/main/javacc/Vf.jjt @@ -84,8 +84,8 @@ PARSER_END(VfParserImpl) | <#TEXT_IN_EL: (~["}", "'", "\""])+ > | <#CLOSEBRACE: ("}")> | <#DOT: "." > -| <#COMMNT_START: "/*" > -| <#COMMNT_END: "*/" > +| <#COMMENT_MULTI_START: "/*" > +| <#COMMENT_MULTI_END: "*/" > } @@ -165,13 +165,13 @@ PARSER_END(VfParserImpl) TOKEN : { - > : InlineCommentStateSQ + > : InlineCommentStateSQ | )? > : AttrValueBetweenSingleQuotesState } TOKEN : -{ - > : InlineCommentStateDQ +{ + > : InlineCommentStateDQ | )? > : AttrValueBetweenDoubleQuotesState } @@ -182,7 +182,7 @@ PARSER_END(VfParserImpl) TOKEN : { - > : InlineCommentStateScript + > : InlineCommentStateScript | )? > : HtmlScriptContentState } @@ -266,20 +266,20 @@ PARSER_END(VfParserImpl) TOKEN : { - < COMMENT_CLOSE_SCRIPT: () > : ElInScriptState + < COMMENT_CLOSE_SCRIPT: () > : ElInScriptState | < COMMENT_INNER_TEXT_SCRIPT: (~[]) > } TOKEN : { - < COMMENT_CLOSE_SQ: () > : ElAttribTagStateSQ + < COMMENT_CLOSE_SQ: () > : ElAttribTagStateSQ | < COMMENT_INNER_TEXT_SQ: (~[]) > } TOKEN : { - < COMMENT_CLOSE_DQ: () > : ElAttribTagStateDQ + < COMMENT_CLOSE_DQ: () > : ElAttribTagStateDQ | < COMMENT_INNER_TEXT_DQ: (~[]) > } @@ -504,32 +504,32 @@ void UnaryExpression() #void : void PrimaryExpression() #void : {} { - PrimaryPrefix() ( LOOKAHEAD(2) PrimarySuffix() )* + PrimaryPrefix() ( LOOKAHEAD(2) PrimarySuffix() )* } void ELSQCommentExpression() #void : {} { - ( )* + ( )* } void ELDQCommentExpression() #void : {} { - ( )* + ( )* } void CommentExpression() #void : {} { - ( )* + ( )* } void PrimaryPrefix() #void : {} { Literal() - | Identifier() + | Identifier() | Expression() | Expression() ( Expression())* | NegationExpression() diff --git a/pmd-xml/src/main/resources/category/xsl/performance.xml b/pmd-xml/src/main/resources/category/xsl/performance.xml index 223b7f8de5d..cbe87c905c1 100644 --- a/pmd-xml/src/main/resources/category/xsl/performance.xml +++ b/pmd-xml/src/main/resources/category/xsl/performance.xml @@ -46,7 +46,7 @@ cutting through 100% of the document. ]]> - + - using an axis descendant::self abreviation with checkSelfDescendantAbreviation @true + using an axis descendant::self abbreviation with checkSelfDescendantAbreviation @true true 1 Date: Sun, 28 Dec 2025 14:38:51 +0100 Subject: [PATCH 1809/1962] [java] Add testcase for #6234 --- .../pmd/lang/java/ast/ParserCornersTest.java | 5 +++ .../pmd/lang/java/ast/GitHubBug6234.txt | 45 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug6234.txt diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java index 04c50c0051c..de7b112d5da 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java @@ -372,4 +372,9 @@ void testGithubBug4947() { void testGithubBug6014() { java.parse("//"); } + + @Test + void testGitHubBug6234() { + doTest("GitHubBug6234", java); + } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug6234.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug6234.txt new file mode 100644 index 00000000000..29be02f091e --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/GitHubBug6234.txt @@ -0,0 +1,45 @@ ++- CompilationUnit[@Compact = false, @PackageName = ""] + +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.concurrent.Callable", @ImportedSimpleName = "Callable", @ModuleImport = false, @PackageName = "java.util.concurrent", @Static = false] + +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "A", @CanonicalName = "A", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "A", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- ClassBody[@Empty = false, @Size = 1] + | +- ConstructorDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Image = "A", @Name = "A", @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @containsComment = false] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- FormalParameters[@Empty = false, @Size = 1] + | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Callable"] + | | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Boolean"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- Block[@Empty = true, @Size = 0, @containsComment = false] + +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "B", @CanonicalName = "B", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "B", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + +- ExtendsList[@Empty = false, @Size = 1] + | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "A"] + +- ClassBody[@Empty = false, @Size = 2] + +- FieldDeclaration[@EffectiveVisibility = Visibility.V_PRIVATE, @Static = true, @Visibility = Visibility.V_PRIVATE] + | +- ModifierList[@EffectiveModifiers = (JModifier.PRIVATE, JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = (JModifier.PRIVATE, JModifier.STATIC, JModifier.FINAL)] + | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | +- VariableDeclarator[@Initializer = true, @Name = "X"] + | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PRIVATE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = true, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "X", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = true, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PRIVATE] + | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] + +- ConstructorDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Image = "B", @Name = "B", @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @containsComment = false] + +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + +- FormalParameters[@Empty = true, @Size = 0] + +- Block[@Empty = false, @Size = 1, @containsComment = false] + +- ExplicitConstructorInvocation[@ArgumentCount = 1, @MethodName = "new", @Qualified = false, @Super = true, @This = false] + +- ArgumentList[@Empty = false, @Size = 1] + +- LambdaExpression[@Arity = 0, @BlockBody = true, @CompileTimeConstant = false, @ExplicitlyTyped = true, @ExpressionBody = false, @ParenthesisDepth = 0, @Parenthesized = false] + +- LambdaParameterList[@Empty = true, @Size = 0] + +- Block[@Empty = false, @Size = 1, @containsComment = false] + +- ReturnStatement[] + +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] + +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] + +- SwitchArrowBranch[@Default = false] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "X", @Name = "X", @ParenthesisDepth = 0, @Parenthesized = false] + | +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "true", @ParenthesisDepth = 0, @Parenthesized = false, @True = true] + +- SwitchArrowBranch[@Default = true] + +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] + +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "false", @ParenthesisDepth = 0, @Parenthesized = false, @True = false] From eb35c7537f148888c53f5d4dc98298b5fb5ea81d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 28 Dec 2025 15:16:39 +0100 Subject: [PATCH 1810/1962] [doc] Update release notes (#4158) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index ef13000a1c0..8b8cd285198 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -50,6 +50,7 @@ This is a {{ site.pmd.release_type }} release. * [#6276](https://github.com/pmd/pmd/issues/6276): \[java] NullAssignment: False positive when assigning null to a final field in a constructor * [#6343](https://github.com/pmd/pmd/issues/6343): \[java] MissingStaticMethodInNonInstantiatableClass: False negative when method in nested class returns null * java-performance + * [#4158](https://github.com/pmd/pmd/issues/4158): \[java] BigIntegerInstantiation: False negative with compile-time constant * [#4910](https://github.com/pmd/pmd/issues/4910): \[java] ConsecutiveAppendsShouldReuse: False positive within if-statement without curly braces * [#5877](https://github.com/pmd/pmd/issues/5877): \[java] AvoidArrayLoops: False negative when break inside switch statement * maintenance From 668a73394149d48da63ea17a1b4e6ea12654a15b Mon Sep 17 00:00:00 2001 From: Beech Horn Date: Sun, 28 Dec 2025 20:54:07 +0000 Subject: [PATCH 1811/1962] Add sca-extra ruleset for Salesforce Apex testing --- docs/pages/pmd/userdocs/3rdpartyrulesets.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/pmd/userdocs/3rdpartyrulesets.md b/docs/pages/pmd/userdocs/3rdpartyrulesets.md index 949dd0d5ff9..1e6738f024e 100644 --- a/docs/pages/pmd/userdocs/3rdpartyrulesets.md +++ b/docs/pages/pmd/userdocs/3rdpartyrulesets.md @@ -27,4 +27,6 @@ last_updated: December 2024 (7.9.0) ## For Apex * **unhappy-soup**, a repository with problematic Salesforce code to showcase PMD, the SFDX Scanner CLI * + * **sca-extra**, additional PMD and Regex rules for testing Salesforce Apex code using Salesforce Code Analyzer + * From cbc6795a649cde1710d8aaf768df9ff6a09dbeb6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 30 Dec 2025 14:56:50 +0100 Subject: [PATCH 1812/1962] [doc] Update last_updated for 3rdpartyrulesets.md --- docs/pages/pmd/userdocs/3rdpartyrulesets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/pmd/userdocs/3rdpartyrulesets.md b/docs/pages/pmd/userdocs/3rdpartyrulesets.md index 1e6738f024e..0de1f7ca21a 100644 --- a/docs/pages/pmd/userdocs/3rdpartyrulesets.md +++ b/docs/pages/pmd/userdocs/3rdpartyrulesets.md @@ -5,7 +5,7 @@ language_name: 3rd party rulesets tags: [rule_references, userdocs] summary: Lists rulesets and rules from the community permalink: pmd_userdocs_3rdpartyrulesets.html -last_updated: December 2024 (7.9.0) +last_updated: December 2025 (7.20.0) --- ## For Java From 32ceb3f9abbca8ecc31435071e7662869cc1bb5e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 30 Dec 2025 14:59:39 +0100 Subject: [PATCH 1813/1962] Update all-contributors - Add @mdhamed238 as a contributor - Add @gianmarcoschifone as a contributor - Add @styurin as a contributor - Add @sarser2048 as a contributor - Update @lukasgraef as a contributor - Add @Frettman as a contributor - Add @FabioMarangonSMI as a contributor - Add @metalshark as a contributor --- .all-contributorsrc | 66 ++++- docs/pages/pmd/projectdocs/credits.md | 335 +++++++++++++------------- 2 files changed, 237 insertions(+), 164 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 579dcdde4d5..f54695f62a9 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7796,7 +7796,8 @@ "avatar_url": "https://avatars.githubusercontent.com/u/48957581?v=4", "profile": "https://github.com/lukasgraef", "contributions": [ - "code" + "code", + "bug" ] }, { @@ -8363,6 +8364,69 @@ "contributions": [ "bug" ] + }, + { + "login": "FabioMarangonSMI", + "name": "FabioMarangonSMI", + "avatar_url": "https://avatars.githubusercontent.com/u/74663033?v=4", + "profile": "https://github.com/FabioMarangonSMI", + "contributions": [ + "bug" + ] + }, + { + "login": "Frettman", + "name": "Patrick Schmidt", + "avatar_url": "https://avatars.githubusercontent.com/u/24453813?v=4", + "profile": "https://github.com/Frettman", + "contributions": [ + "bug" + ] + }, + { + "login": "sarser2048", + "name": "sarser.eth", + "avatar_url": "https://avatars.githubusercontent.com/u/120093137?v=4", + "profile": "https://github.com/sarser2048", + "contributions": [ + "bug" + ] + }, + { + "login": "styurin", + "name": "Sergey Tyurin", + "avatar_url": "https://avatars.githubusercontent.com/u/2167790?v=4", + "profile": "https://github.com/styurin", + "contributions": [ + "bug" + ] + }, + { + "login": "gianmarcoschifone", + "name": "Gianmarco", + "avatar_url": "https://avatars.githubusercontent.com/u/133696105?v=4", + "profile": "https://github.com/gianmarcoschifone", + "contributions": [ + "code" + ] + }, + { + "login": "mdhamed238", + "name": "Mohamed Hamed", + "avatar_url": "https://avatars.githubusercontent.com/u/79021260?v=4", + "profile": "https://www.mdhamed.dev/", + "contributions": [ + "code" + ] + }, + { + "login": "metalshark", + "name": "Beech Horn", + "avatar_url": "https://avatars.githubusercontent.com/u/146708?v=4", + "profile": "https://github.com/metalshark", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 0bb5e71935a..03033efeee7 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -134,988 +134,997 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Basavaraj K N
          Basavaraj K N

          ๐Ÿ› Basil Peace
          Basil Peace

          ๐Ÿ› + Beech Horn
          Beech Horn

          ๐Ÿ“– Belle
          Belle

          ๐Ÿ› Ben Lerner
          Ben Lerner

          ๐Ÿ› Ben Manes
          Ben Manes

          ๐Ÿ› Ben McCann
          Ben McCann

          ๐Ÿ› - Bendegรบz Nagy
          Bendegรบz Nagy

          ๐Ÿ› + Bendegรบz Nagy
          Bendegรบz Nagy

          ๐Ÿ› Bennet S Yee
          Bennet S Yee

          ๐Ÿ› Benoit Lacelle
          Benoit Lacelle

          ๐Ÿ› Bernardo Macรชdo
          Bernardo Macรชdo

          ๐Ÿ› Bernd Farka
          Bernd Farka

          ๐Ÿ› Betina Cynthia Mamani
          Betina Cynthia Mamani

          ๐Ÿ› Bhanu Prakash Pamidi
          Bhanu Prakash Pamidi

          ๐Ÿ’ป ๐Ÿ› - Bhargav Thanki
          Bhargav Thanki

          ๐Ÿ› + Bhargav Thanki
          Bhargav Thanki

          ๐Ÿ› Binu R J
          Binu R J

          ๐Ÿ› Bjรถrn Kautler
          Bjรถrn Kautler

          ๐Ÿ’ป ๐Ÿ› Blightbuster
          Blightbuster

          ๐Ÿ› Bo Zhang
          Bo Zhang

          ๐Ÿ› Bob "Wombat" Hogg
          Bob "Wombat" Hogg

          ๐Ÿ› Bobby Wertman
          Bobby Wertman

          ๐Ÿ› - Bolarinwa Saheed Olayemi
          Bolarinwa Saheed Olayemi

          ๐Ÿ’ป ๐Ÿ› + Bolarinwa Saheed Olayemi
          Bolarinwa Saheed Olayemi

          ๐Ÿ’ป ๐Ÿ› Boris Petrov
          Boris Petrov

          ๐Ÿ› Brad Kent
          Brad Kent

          ๐Ÿ› Brandon Mikeska
          Brandon Mikeska

          ๐Ÿ› Brian Batronis
          Brian Batronis

          ๐Ÿ› Brian Johnson
          Brian Johnson

          ๐Ÿ› Brice Dutheil
          Brice Dutheil

          ๐Ÿ’ป ๐Ÿ› - Bruno Ferreira
          Bruno Ferreira

          ๐Ÿ› + Bruno Ferreira
          Bruno Ferreira

          ๐Ÿ› Bruno Harbulot
          Bruno Harbulot

          ๐Ÿ› Bruno Ritz
          Bruno Ritz

          ๐Ÿ› BurovnikovEvgeniy
          BurovnikovEvgeniy

          ๐Ÿ› Cameron Donaldson
          Cameron Donaldson

          ๐Ÿ› Carlos Macasaet
          Carlos Macasaet

          ๐Ÿ› Carsten Otto
          Carsten Otto

          ๐Ÿ› - Charlie Housh
          Charlie Housh

          ๐Ÿ› + Charlie Housh
          Charlie Housh

          ๐Ÿ› Charlie Jonas
          Charlie Jonas

          ๐Ÿ› Chas Honton
          Chas Honton

          ๐Ÿ› ๐Ÿ’ป Chen Yang
          Chen Yang

          ๐Ÿ› Chotu
          Chotu

          ๐Ÿ› Chris Smith
          Chris Smith

          ๐Ÿ› Chris Toomey
          Chris Toomey

          ๐Ÿ› - Christian Hujer
          Christian Hujer

          ๐Ÿ› + Christian Hujer
          Christian Hujer

          ๐Ÿ› Christian Pontesegger
          Christian Pontesegger

          ๐Ÿ› ChristianWulf
          ChristianWulf

          ๐Ÿ› Christofer Dutz
          Christofer Dutz

          ๐Ÿ’ป Christoffer Anselm
          Christoffer Anselm

          ๐Ÿ› Christophe Vidal
          Christophe Vidal

          ๐Ÿ› Christopher Dancy
          Christopher Dancy

          ๐Ÿ› - Clemens Prill
          Clemens Prill

          ๐Ÿ› + Clemens Prill
          Clemens Prill

          ๐Ÿ› Clint Chester
          Clint Chester

          ๐Ÿ’ป ๐Ÿ› Clรฉment Fournier
          Clรฉment Fournier

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง Codacy Badger
          Codacy Badger

          ๐Ÿ› Code-Nil
          Code-Nil

          ๐Ÿ› ColColonCleaner
          ColColonCleaner

          ๐Ÿ› Colin Ingarfield
          Colin Ingarfield

          ๐Ÿ› - Craig Andrews
          Craig Andrews

          ๐Ÿ› + Craig Andrews
          Craig Andrews

          ๐Ÿ› Craig Muchinsky
          Craig Muchinsky

          ๐Ÿ› Cybozu
          Cybozu

          ๐Ÿ’ต Cyril
          Cyril

          ๐Ÿ’ป ๐Ÿ› Dale
          Dale

          ๐Ÿ’ป Damien Jiang
          Damien Jiang

          ๐Ÿ› Dan Berindei
          Dan Berindei

          ๐Ÿ› - Dan Rollo
          Dan Rollo

          ๐Ÿ› + Dan Rollo
          Dan Rollo

          ๐Ÿ› Dan Ziemba
          Dan Ziemba

          ๐Ÿ› Daniel Gredler
          Daniel Gredler

          ๐Ÿ’ป ๐Ÿ› Daniel Jipa
          Daniel Jipa

          ๐Ÿ› Daniel Paul Searles
          Daniel Paul Searles

          ๐Ÿ’ป Daniel Reigada
          Daniel Reigada

          ๐Ÿ› Daniel Ventura
          Daniel Ventura

          ๐Ÿ› - Danilo Pianini
          Danilo Pianini

          ๐Ÿ› + Danilo Pianini
          Danilo Pianini

          ๐Ÿ› Darko
          Darko

          ๐Ÿ› Dave Brosius
          Dave Brosius

          ๐Ÿ› David
          David

          ๐Ÿ› David Atkinson
          David Atkinson

          ๐Ÿ› David Burstrรถm
          David Burstrรถm

          ๐Ÿ’ป ๐Ÿ› David Goatรฉ
          David Goatรฉ

          ๐Ÿ› - David Golpira
          David Golpira

          ๐Ÿ› + David Golpira
          David Golpira

          ๐Ÿ› David Kovaล™รญk
          David Kovaล™รญk

          ๐Ÿ› David M. Karr (fullname at gmail.com)
          David M. Karr (fullname at gmail.com)

          ๐Ÿ› David Renz
          David Renz

          ๐Ÿ’ป ๐Ÿ› David Renz
          David Renz

          ๐Ÿ› David Schach
          David Schach

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– Dawid Ciok
          Dawid Ciok

          ๐Ÿ› ๐Ÿ’ป - Debamoy Datta
          Debamoy Datta

          ๐Ÿ’ป + Debamoy Datta
          Debamoy Datta

          ๐Ÿ’ป Delany
          Delany

          ๐Ÿ› Deleted user
          Deleted user

          ๐Ÿ› Dell Green
          Dell Green

          ๐Ÿ› Dem Pilafian
          Dem Pilafian

          ๐Ÿ› Den
          Den

          ๐Ÿ› Denis Borovikov
          Denis Borovikov

          ๐Ÿ’ป ๐Ÿ› - Dennie Reniers
          Dennie Reniers

          ๐Ÿ’ป ๐Ÿ› + Dennie Reniers
          Dennie Reniers

          ๐Ÿ’ป ๐Ÿ› Dennis Kieselhorst
          Dennis Kieselhorst

          ๐Ÿ› Derek P. Moore
          Derek P. Moore

          ๐Ÿ› Dichotomia
          Dichotomia

          ๐Ÿ› Dionisio Cortรฉs Fernรกndez
          Dionisio Cortรฉs Fernรกndez

          ๐Ÿ’ป ๐Ÿ› Dmitri Bourlatchkov
          Dmitri Bourlatchkov

          ๐Ÿ› Dmitriy Kuzmin
          Dmitriy Kuzmin

          ๐Ÿ› - Dmytro Dashenkov
          Dmytro Dashenkov

          ๐Ÿ› + Dmytro Dashenkov
          Dmytro Dashenkov

          ๐Ÿ› Douglas Griffith
          Douglas Griffith

          ๐Ÿ“– Dr. Christian Kohlschรผtter
          Dr. Christian Kohlschรผtter

          ๐Ÿ› Drew Hall
          Drew Hall

          ๐Ÿ› Dumitru Postoronca
          Dumitru Postoronca

          ๐Ÿ› Dylan Adams
          Dylan Adams

          ๐Ÿ› Eden Hao
          Eden Hao

          ๐Ÿ› - Edward Klimoshenko
          Edward Klimoshenko

          ๐Ÿ› ๐Ÿ’ป + Edward Klimoshenko
          Edward Klimoshenko

          ๐Ÿ› ๐Ÿ’ป Egor Bredikhin
          Egor Bredikhin

          ๐Ÿ› Elan P. Kugelmass
          Elan P. Kugelmass

          ๐Ÿ› Elder S.
          Elder S.

          ๐Ÿ› Eldrick Wega
          Eldrick Wega

          ๐Ÿ“– Elliotte Rusty Harold
          Elliotte Rusty Harold

          ๐Ÿ’ป ๐Ÿ› Emile
          Emile

          ๐Ÿ› - Eng Zer Jun
          Eng Zer Jun

          ๐Ÿ› + Eng Zer Jun
          Eng Zer Jun

          ๐Ÿ› Eric
          Eric

          ๐Ÿ› Eric Kintzer
          Eric Kintzer

          ๐Ÿ› Eric Perret
          Eric Perret

          ๐Ÿ› Eric Squires
          Eric Squires

          ๐Ÿ› Erich L Foster
          Erich L Foster

          ๐Ÿ› Erik Bleske
          Erik Bleske

          ๐Ÿ› - Erik C. Thauvin
          Erik C. Thauvin

          ๐Ÿ“– ๐Ÿ› + Erik C. Thauvin
          Erik C. Thauvin

          ๐Ÿ“– ๐Ÿ› Ernst Reissner
          Ernst Reissner

          ๐Ÿ› Ethan Sargent
          Ethan Sargent

          ๐Ÿ› Ewan Tempero
          Ewan Tempero

          ๐Ÿ› F.W. Dekker
          F.W. Dekker

          ๐Ÿ› FSchliephacke
          FSchliephacke

          ๐Ÿ› - Facundo
          Facundo

          ๐Ÿ› - Federico Giust
          Federico Giust

          ๐Ÿ› + FabioMarangonSMI
          FabioMarangonSMI

          ๐Ÿ› + Facundo
          Facundo

          ๐Ÿ› + Federico Giust
          Federico Giust

          ๐Ÿ› Fedor Sherstobitov
          Fedor Sherstobitov

          ๐Ÿ› Felix Lampe
          Felix Lampe

          ๐Ÿ› Filip Golonka
          Filip Golonka

          ๐Ÿ› Filipe Esperandio
          Filipe Esperandio

          ๐Ÿ’ป ๐Ÿ› Filippo Barbari
          Filippo Barbari

          ๐Ÿ› - Filippo Nova
          Filippo Nova

          ๐Ÿ› - Francesco la Torre
          Francesco la Torre

          ๐Ÿ› + Filippo Nova
          Filippo Nova

          ๐Ÿ› + Francesco la Torre
          Francesco la Torre

          ๐Ÿ› Francisco Duarte
          Francisco Duarte

          ๐Ÿ› Frederick Zhang
          Frederick Zhang

          ๐Ÿ› Frieder Bluemle
          Frieder Bluemle

          ๐Ÿ› Frits Jalvingh
          Frits Jalvingh

          ๐Ÿ’ป ๐Ÿ› G. Bazior
          G. Bazior

          ๐Ÿ› - Gabe Henkes
          Gabe Henkes

          ๐Ÿ› - Gary Gregory
          Gary Gregory

          ๐Ÿ› + Gabe Henkes
          Gabe Henkes

          ๐Ÿ› + Gary Gregory
          Gary Gregory

          ๐Ÿ› Genoud Magloire
          Genoud Magloire

          ๐Ÿ› Geoffrey555
          Geoffrey555

          ๐Ÿ› Georg Romstorfer
          Georg Romstorfer

          ๐Ÿ› + Gianmarco
          Gianmarco

          ๐Ÿ’ป Gili Tzabari
          Gili Tzabari

          ๐Ÿ› ๐Ÿ’ป + + Gio
          Gio

          ๐Ÿ› Gol
          Gol

          ๐Ÿ› Gold856
          Gold856

          ๐Ÿ› ๐Ÿ’ป - - Gonzalo Exequiel Ibars Ingman
          Gonzalo Exequiel Ibars Ingman

          ๐Ÿ’ป ๐Ÿ› GooDer
          GooDer

          ๐Ÿ› Gregor Riegler
          Gregor Riegler

          ๐Ÿ› Grzegorz Olszewski
          Grzegorz Olszewski

          ๐Ÿ› + + Gunther Schrijvers
          Gunther Schrijvers

          ๐Ÿ’ป ๐Ÿ› Gustavo Krieger
          Gustavo Krieger

          ๐Ÿ› Guy Elsmore-Paddock
          Guy Elsmore-Paddock

          ๐Ÿ› - - Gรถrkem Mรผlayim
          Gรถrkem Mรผlayim

          ๐Ÿ› Hanzel Godinez
          Hanzel Godinez

          ๐Ÿ› Haoliang Chen
          Haoliang Chen

          ๐Ÿ› Harsh Kukreja
          Harsh Kukreja

          ๐Ÿ› + + Hassan ALAMI
          Hassan ALAMI

          ๐Ÿ› Heber
          Heber

          ๐Ÿ› Hector Miuler Malpica Gallegos
          Hector Miuler Malpica Gallegos

          ๐Ÿ› - - Henning Schmiedehausen
          Henning Schmiedehausen

          ๐Ÿ’ป ๐Ÿ› Henning von Bargen
          Henning von Bargen

          ๐Ÿ’ป Hervรฉ Boutemy
          Hervรฉ Boutemy

          ๐Ÿ› Himanshu Pandey
          Himanshu Pandey

          ๐Ÿ› + + Hokwang Lee
          Hokwang Lee

          ๐Ÿ› Hooperbloob
          Hooperbloob

          ๐Ÿ’ป Hung PHAN
          Hung PHAN

          ๐Ÿ› - - IDoCodingStuffs
          IDoCodingStuffs

          ๐Ÿ’ป ๐Ÿ› Iccen Gan
          Iccen Gan

          ๐Ÿ› Ignacio Mariano Tirabasso
          Ignacio Mariano Tirabasso

          ๐Ÿ› Igor Melnichenko
          Igor Melnichenko

          ๐Ÿ› + + Igor Moreno
          Igor Moreno

          ๐Ÿ› Intelesis-MS
          Intelesis-MS

          ๐Ÿ› Iroha_
          Iroha_

          ๐Ÿ› - - Ishan Srivastava
          Ishan Srivastava

          ๐Ÿ› Iskren Stanislavov
          Iskren Stanislavov

          ๐Ÿ› Ivan Vakhrushev
          Ivan Vakhrushev

          ๐Ÿ› Ivano Guerini
          Ivano Guerini

          ๐Ÿ› + + Ivar Andreas Bonsaksen
          Ivar Andreas Bonsaksen

          ๐Ÿ› Ivo ล mรญd
          Ivo ล mรญd

          ๐Ÿ› JJengility
          JJengility

          ๐Ÿ› - - Jake Hemmerle
          Jake Hemmerle

          ๐Ÿ› Jakub Dupak
          Jakub Dupak

          ๐Ÿ’ป James Harrison
          James Harrison

          ๐Ÿ› ๐Ÿ’ป Jamie Bisotti
          Jamie Bisotti

          ๐Ÿ› + + Jan
          Jan

          ๐Ÿ› Jan Aertgeerts
          Jan Aertgeerts

          ๐Ÿ’ป ๐Ÿ› Jan Brรผmmer
          Jan Brรผmmer

          ๐Ÿ› - - Jan Tล™รญska
          Jan Tล™รญska

          ๐Ÿ› Jan-Lukas Else
          Jan-Lukas Else

          ๐Ÿ› Jason Qiu
          Jason Qiu

          ๐Ÿ’ป ๐Ÿ“– Jason Williams
          Jason Williams

          ๐Ÿ› + + Javier Spagnoletti
          Javier Spagnoletti

          ๐Ÿ› Jean-Paul Mayer
          Jean-Paul Mayer

          ๐Ÿ› Jean-Simon Larochelle
          Jean-Simon Larochelle

          ๐Ÿ› - - Jeff Bartolotta
          Jeff Bartolotta

          ๐Ÿ’ป ๐Ÿ› Jeff Hube
          Jeff Hube

          ๐Ÿ’ป ๐Ÿ› Jeff Jensen
          Jeff Jensen

          ๐Ÿ› Jeff May
          Jeff May

          ๐Ÿ› + + Jens Gerdes
          Jens Gerdes

          ๐Ÿ› Jeroen Borgers
          Jeroen Borgers

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข Jeroen Meijer
          Jeroen Meijer

          ๐Ÿ› - - Jeroen van Wilgenburg
          Jeroen van Wilgenburg

          ๐Ÿ“– Jerome Russ
          Jerome Russ

          ๐Ÿ› JerritEic
          JerritEic

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› Jiri Pejchal
          Jiri Pejchal

          ๐Ÿ› + + Jithin Sunny
          Jithin Sunny

          ๐Ÿ› Jiล™รญ ล korpil
          Jiล™รญ ล korpil

          ๐Ÿ› Joao Machado
          Joao Machado

          ๐Ÿ› - - Jochen Krauss
          Jochen Krauss

          ๐Ÿ› Johan Hammar
          Johan Hammar

          ๐Ÿ› John Jetmore
          John Jetmore

          ๐Ÿ“– John Karp
          John Karp

          ๐Ÿ› + + John Zhang
          John Zhang

          ๐Ÿ› John-Teng
          John-Teng

          ๐Ÿ’ป ๐Ÿ› Jon Moroney
          Jon Moroney

          ๐Ÿ’ป ๐Ÿ› - - Jonas Geiregat
          Jonas Geiregat

          ๐Ÿ› Jonas KeรŸler
          Jonas KeรŸler

          ๐Ÿ› Jonathan Gillespie
          Jonathan Gillespie

          ๐Ÿ’ต Jonathan Wiesel
          Jonathan Wiesel

          ๐Ÿ’ป ๐Ÿ› + + Jordan
          Jordan

          ๐Ÿ› Jordan Alligood
          Jordan Alligood

          ๐Ÿ› Jordi Llach
          Jordi Llach

          ๐Ÿ› - - Jorge Solรณrzano
          Jorge Solรณrzano

          ๐Ÿ› JorneVL
          JorneVL

          ๐Ÿ› Jose Palafox
          Jose Palafox

          ๐Ÿ› Jose Stovall
          Jose Stovall

          ๐Ÿ› + + Joseph
          Joseph

          ๐Ÿ’ป Joseph Heenan
          Joseph Heenan

          ๐Ÿ› Josh Feingold
          Josh Feingold

          ๐Ÿ’ป ๐Ÿ› - - Josh Holthaus
          Josh Holthaus

          ๐Ÿ› Joshua S Arquilevich
          Joshua S Arquilevich

          ๐Ÿ› Joรฃo Dinis Ferreira
          Joรฃo Dinis Ferreira

          ๐Ÿ“– Joรฃo Ferreira
          Joรฃo Ferreira

          ๐Ÿ’ป ๐Ÿ› + + Joรฃo Pedro Schmitt
          Joรฃo Pedro Schmitt

          ๐Ÿ› Juan Martรญn Sotuyo Dodero
          Juan Martรญn Sotuyo Dodero

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง Juan Pablo Civile
          Juan Pablo Civile

          ๐Ÿ› - - Jude Pereira
          Jude Pereira

          ๐Ÿ’ป Julian Voronetsky
          Julian Voronetsky

          ๐Ÿ› Julien
          Julien

          ๐Ÿ› Julius
          Julius

          ๐Ÿ› + + JustPRV
          JustPRV

          ๐Ÿ› Justin Stroud
          Justin Stroud

          ๐Ÿ’ป Jรถrn Huxhorn
          Jรถrn Huxhorn

          ๐Ÿ› - - KThompso
          KThompso

          ๐Ÿ› Kai Amundsen
          Kai Amundsen

          ๐Ÿ› Karel Vervaeke
          Karel Vervaeke

          ๐Ÿ› Karl-Andero Mere
          Karl-Andero Mere

          ๐Ÿ› + + Karl-Philipp Richter
          Karl-Philipp Richter

          ๐Ÿ› Karsten Silz
          Karsten Silz

          ๐Ÿ› Kazuma Watanabe
          Kazuma Watanabe

          ๐Ÿ› - - Kernevez
          Kernevez

          ๐Ÿ› Kev
          Kev

          ๐Ÿ› Keve Mรผller
          Keve Mรผller

          ๐Ÿ› Kevin Guerra
          Kevin Guerra

          ๐Ÿ’ป + + Kevin Jones
          Kevin Jones

          ๐Ÿ› ๐Ÿ’ป Kevin Poorman
          Kevin Poorman

          ๐Ÿ› Kevin Wayne
          Kevin Wayne

          ๐Ÿ› - - Kieran Black
          Kieran Black

          ๐Ÿ› Kirill Zubov
          Kirill Zubov

          ๐Ÿ› Kirk Clemens
          Kirk Clemens

          ๐Ÿ’ป ๐Ÿ› Klaus Hartl
          Klaus Hartl

          ๐Ÿ› + + Koen Van Looveren
          Koen Van Looveren

          ๐Ÿ› Kris Scheibe
          Kris Scheibe

          ๐Ÿ’ป ๐Ÿ› Krystian Dabrowski
          Krystian Dabrowski

          ๐Ÿ› ๐Ÿ’ป - - Krzysztof Dymek
          Krzysztof Dymek

          ๐Ÿ› Kunal Thanki
          Kunal Thanki

          ๐Ÿ› Kursat Aktas
          Kursat Aktas

          ๐Ÿ“– LaLucid
          LaLucid

          ๐Ÿ’ป + + Larry Diamond
          Larry Diamond

          ๐Ÿ’ป ๐Ÿ› Lars Knickrehm
          Lars Knickrehm

          ๐Ÿ› Laurent Bovet
          Laurent Bovet

          ๐Ÿ› ๐Ÿ’ป - - Leo Gutierrez
          Leo Gutierrez

          ๐Ÿ› LiGaOg
          LiGaOg

          ๐Ÿ’ป Liam Sharp
          Liam Sharp

          ๐Ÿ› Lintsi
          Lintsi

          ๐Ÿ› + + Linus Fernandes
          Linus Fernandes

          ๐Ÿ› Lixon Lookose
          Lixon Lookose

          ๐Ÿ› Logesh
          Logesh

          ๐Ÿ› - - Lorenzo Gabriele
          Lorenzo Gabriele

          ๐Ÿ› Loรฏc Ledoyen
          Loรฏc Ledoyen

          ๐Ÿ› Lucas
          Lucas

          ๐Ÿ› Lucas Silva
          Lucas Silva

          ๐Ÿ› - Lucas Soncini
          Lucas Soncini

          ๐Ÿ’ป ๐Ÿ› - Luis Alcantar
          Luis Alcantar

          ๐Ÿ’ป - Lukas Grรคf
          Lukas Grรคf

          ๐Ÿ’ป + Lucas Soncini
          Lucas Soncini

          ๐Ÿ’ป ๐Ÿ› + Luis Alcantar
          Luis Alcantar

          ๐Ÿ’ป + Lukas Grรคf
          Lukas Grรคf

          ๐Ÿ’ป ๐Ÿ› Lukasz Slonina
          Lukasz Slonina

          ๐Ÿ› Lukebray
          Lukebray

          ๐Ÿ› Lynn
          Lynn

          ๐Ÿ’ป ๐Ÿ› Lyor Goldstein
          Lyor Goldstein

          ๐Ÿ› + + MCMicS
          MCMicS

          ๐Ÿ› Macarse
          Macarse

          ๐Ÿ› Machine account for PMD
          Machine account for PMD

          ๐Ÿ’ป - - Maciek Siemczyk
          Maciek Siemczyk

          ๐Ÿ› Maikel Steneker
          Maikel Steneker

          ๐Ÿ’ป ๐Ÿ› Maksim Moiseikin
          Maksim Moiseikin

          ๐Ÿ› Malik
          Malik

          ๐Ÿ› + + Manfred Koch
          Manfred Koch

          ๐Ÿ› Manuel Moya Ferrer
          Manuel Moya Ferrer

          ๐Ÿ’ป ๐Ÿ› Manuel Romeiro
          Manuel Romeiro

          ๐Ÿ› - - Manuel Ryan
          Manuel Ryan

          ๐Ÿ› Marat Vyshegorodtsev
          Marat Vyshegorodtsev

          ๐Ÿ› Marcel Hรคrle
          Marcel Hรคrle

          ๐Ÿ› Marcello Fialho
          Marcello Fialho

          ๐Ÿ› + + Marcin Dฤ…browski
          Marcin Dฤ…browski

          ๐Ÿ’ป ๐Ÿ› Marcin Rataj
          Marcin Rataj

          ๐Ÿ› Marcono1234
          Marcono1234

          ๐Ÿ› - - Mark Adamcin
          Mark Adamcin

          ๐Ÿ› Mark Hall
          Mark Hall

          ๐Ÿ’ป ๐Ÿ› Mark Kolich
          Mark Kolich

          ๐Ÿ› Mark Pritchard
          Mark Pritchard

          ๐Ÿ› + + Markus Rathgeb
          Markus Rathgeb

          ๐Ÿ› Marquis Wang
          Marquis Wang

          ๐Ÿ› MartGit
          MartGit

          ๐Ÿ› - - Martin Feldsztejn
          Martin Feldsztejn

          ๐Ÿ› Martin Lehmann
          Martin Lehmann

          ๐Ÿ› Martin Spamer
          Martin Spamer

          ๐Ÿ› Martin Tarjรกnyi
          Martin Tarjรกnyi

          ๐Ÿ› + + MatFl
          MatFl

          ๐Ÿ› Mateusz Stefanski
          Mateusz Stefanski

          ๐Ÿ› Mathias Lagerwall
          Mathias Lagerwall

          ๐Ÿ› - - Mathieu Gouin
          Mathieu Gouin

          ๐Ÿ› MatiasComercio
          MatiasComercio

          ๐Ÿ’ป ๐Ÿ› Matt Benson
          Matt Benson

          ๐Ÿ› Matt De Poorter
          Matt De Poorter

          ๐Ÿ› + + Matt Hargett
          Matt Hargett

          ๐Ÿ’ป ๐Ÿ’ต Matt Harrah
          Matt Harrah

          ๐Ÿ› Matt Nelson
          Matt Nelson

          ๐Ÿ› - - Matthew Amos
          Matthew Amos

          ๐Ÿ› Matthew Duggan
          Matthew Duggan

          ๐Ÿ› Matthew Hall
          Matthew Hall

          ๐Ÿ› Matthew Rossner
          Matthew Rossner

          ๐Ÿ› + + Matรญas Fraga
          Matรญas Fraga

          ๐Ÿ’ป ๐Ÿ› Maxime Robert
          Maxime Robert

          ๐Ÿ’ป ๐Ÿ› MetaBF
          MetaBF

          ๐Ÿ› - - Metin Dagcilar
          Metin Dagcilar

          ๐Ÿ› Michael
          Michael

          ๐Ÿ› Michael Bell
          Michael Bell

          ๐Ÿ› Michael Bernstein
          Michael Bernstein

          ๐Ÿ› + + Michael Clay
          Michael Clay

          ๐Ÿ› Michael Dombrowski
          Michael Dombrowski

          ๐Ÿ› Michael Hausegger
          Michael Hausegger

          ๐Ÿ› - - Michael Hoefer
          Michael Hoefer

          ๐Ÿ› Michael Kolesnikov
          Michael Kolesnikov

          ๐Ÿ› Michael Mรถbius
          Michael Mรถbius

          ๐Ÿ› Michael N. Lipp
          Michael N. Lipp

          ๐Ÿ› + + Michael Pellegrini
          Michael Pellegrini

          ๐Ÿ› Michal Kordas
          Michal Kordas

          ๐Ÿ› Michaล‚ Borek
          Michaล‚ Borek

          ๐Ÿ› - - Michaล‚ Kuliล„ski
          Michaล‚ Kuliล„ski

          ๐Ÿ› Miguel Nรบรฑez Dรญaz-Montes
          Miguel Nรบรฑez Dรญaz-Montes

          ๐Ÿ› Mihai Ionut
          Mihai Ionut

          ๐Ÿ› Mikhail Kuchma
          Mikhail Kuchma

          ๐Ÿ› + + MiladSadinam
          MiladSadinam

          ๐Ÿ› Mirek Hankus
          Mirek Hankus

          ๐Ÿ› Mitch Spano
          Mitch Spano

          ๐Ÿ’ป ๐Ÿ› - - Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ› Mladjan Gadzic
          Mladjan Gadzic

          ๐Ÿ› + Mohamed Hamed
          Mohamed Hamed

          ๐Ÿ’ป MrAngry52
          MrAngry52

          ๐Ÿ› + + Muminur Choudhury
          Muminur Choudhury

          ๐Ÿ› Mykhailo Palahuta
          Mykhailo Palahuta

          ๐Ÿ’ป ๐Ÿ› Nagendra Kumar Singh
          Nagendra Kumar Singh

          ๐Ÿ› Nahuel Barrios
          Nahuel Barrios

          ๐Ÿ› - - Nakul Sharma
          Nakul Sharma

          ๐Ÿ› Nathan Braun
          Nathan Braun

          ๐Ÿ› Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ› + + Nathan Reynolds
          Nathan Reynolds

          ๐Ÿ› Nathanaรซl
          Nathanaรซl

          ๐Ÿ› Naveen
          Naveen

          ๐Ÿ’ป Nazdravi
          Nazdravi

          ๐Ÿ› - - Neha-Dhonde
          Neha-Dhonde

          ๐Ÿ› Nicholas Doyle
          Nicholas Doyle

          ๐Ÿ› Nick Butcher
          Nick Butcher

          ๐Ÿ› + + Nico Gallinal
          Nico Gallinal

          ๐Ÿ› Nicola Dal Maso
          Nicola Dal Maso

          ๐Ÿ› Nicolas Filotto
          Nicolas Filotto

          ๐Ÿ’ป Nicolas Vervelle
          Nicolas Vervelle

          ๐Ÿ› - - Nicolas Vuillamy
          Nicolas Vuillamy

          ๐Ÿ“– Nikita Chursin
          Nikita Chursin

          ๐Ÿ› Niklas Baudy
          Niklas Baudy

          ๐Ÿ› + + Nikolas Havrikov
          Nikolas Havrikov

          ๐Ÿ› Nilesh Virkar
          Nilesh Virkar

          ๐Ÿ› Nimit Patel
          Nimit Patel

          ๐Ÿ› Niranjan Harpale
          Niranjan Harpale

          ๐Ÿ› - - Nirvik Patel
          Nirvik Patel

          ๐Ÿ’ป Noah Sussman
          Noah Sussman

          ๐Ÿ› Noah0120
          Noah0120

          ๐Ÿ› + + Noam Tamim
          Noam Tamim

          ๐Ÿ› Noel Grandin
          Noel Grandin

          ๐Ÿ› Olaf Haalstra
          Olaf Haalstra

          ๐Ÿ› Oleg Andreych
          Oleg Andreych

          ๐Ÿ’ป ๐Ÿ› - - Oleg Estekhin
          Oleg Estekhin

          ๐Ÿ› Oleg Pavlenko
          Oleg Pavlenko

          ๐Ÿ› Oleksii Dykov
          Oleksii Dykov

          ๐Ÿ’ป ๐Ÿ› + + Oliver Eikemeier
          Oliver Eikemeier

          ๐Ÿ› Oliver Siegmar
          Oliver Siegmar

          ๐Ÿ’ต Olivier Parent
          Olivier Parent

          ๐Ÿ’ป ๐Ÿ› Ollie Abbey
          Ollie Abbey

          ๐Ÿ’ป ๐Ÿ› - - Olof-Joachim Frahm (ๆฌง้›…็ฆ)
          Olof-Joachim Frahm (ๆฌง้›…็ฆ)

          ๐Ÿ› Ondrej Kratochvil
          Ondrej Kratochvil

          ๐Ÿ› OverDrone
          OverDrone

          ๐Ÿ› + + Ozan Gulle
          Ozan Gulle

          ๐Ÿ’ป ๐Ÿ› PUNEET JAIN
          PUNEET JAIN

          ๐Ÿ› Pankraz76
          Pankraz76

          ๐Ÿ’ป ๐Ÿ› Parbati Bose
          Parbati Bose

          ๐Ÿ› - - + Patrick Schmidt
          Patrick Schmidt

          ๐Ÿ› Paul Berg
          Paul Berg

          ๐Ÿ› Paul Guyot
          Paul Guyot

          ๐Ÿ’ป + + Pavel Bludov
          Pavel Bludov

          ๐Ÿ› Pavel Miฤka
          Pavel Miฤka

          ๐Ÿ› Pedro Nuno Santos
          Pedro Nuno Santos

          ๐Ÿ› Pedro Rijo
          Pedro Rijo

          ๐Ÿ› Pelisse Romain
          Pelisse Romain

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› - - Per Abich
          Per Abich

          ๐Ÿ’ป Pete Davids
          Pete Davids

          ๐Ÿ› + + Peter Bruin
          Peter Bruin

          ๐Ÿ› Peter Chittum
          Peter Chittum

          ๐Ÿ’ป ๐Ÿ› Peter Cudmore
          Peter Cudmore

          ๐Ÿ› Peter Kasson
          Peter Kasson

          ๐Ÿ› Peter Kofler
          Peter Kofler

          ๐Ÿ› - - Peter Paul Bakker
          Peter Paul Bakker

          ๐Ÿ’ป ๐Ÿ› Peter Rader
          Peter Rader

          ๐Ÿ› + + Pham Hai Trung
          Pham Hai Trung

          ๐Ÿ› Philip Graf
          Philip Graf

          ๐Ÿ’ป ๐Ÿ› Philip Hachey
          Philip Hachey

          ๐Ÿ› Philippe Ozil
          Philippe Ozil

          ๐Ÿ› Phinehas Artemix
          Phinehas Artemix

          ๐Ÿ› - - Phokham Nonava
          Phokham Nonava

          ๐Ÿ› Pim van der Loos
          Pim van der Loos

          ๐Ÿ’ป โš ๏ธ + + Piotr Koลผuchowski
          Piotr Koลผuchowski

          ๐Ÿ› Piotr Szymaล„ski
          Piotr Szymaล„ski

          ๐Ÿ› Piotrek ลปygieล‚o
          Piotrek ลปygieล‚o

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– Pranay Jaiswal
          Pranay Jaiswal

          ๐Ÿ› Prasad Kamath
          Prasad Kamath

          ๐Ÿ› - - Prasanna
          Prasanna

          ๐Ÿ› Presh-AR
          Presh-AR

          ๐Ÿ› + + Puneet1726
          Puneet1726

          ๐Ÿ› RBRi
          RBRi

          ๐Ÿ› Rafael Cortรชs
          Rafael Cortรชs

          ๐Ÿ› RaheemShaik999
          RaheemShaik999

          ๐Ÿ› RajeshR
          RajeshR

          ๐Ÿ’ป ๐Ÿ› - - Ramachandra Mohan
          Ramachandra Mohan

          ๐Ÿ› Ramel0921
          Ramel0921

          ๐Ÿ› + + Raquel Pau
          Raquel Pau

          ๐Ÿ› Ravikiran Janardhana
          Ravikiran Janardhana

          ๐Ÿ› Reda Benhemmouche
          Reda Benhemmouche

          ๐Ÿ› Reinhard Schiedermeier
          Reinhard Schiedermeier

          ๐Ÿ› Renato Oliveira
          Renato Oliveira

          ๐Ÿ’ป ๐Ÿ› - - Rich DiCroce
          Rich DiCroce

          ๐Ÿ› Richard Corfield
          Richard Corfield

          ๐Ÿ’ป + + Richard Corfield
          Richard Corfield

          ๐Ÿ› ๐Ÿ’ป Riot R1cket
          Riot R1cket

          ๐Ÿ› Rishabh Jain
          Rishabh Jain

          ๐Ÿ› RishabhDeep Singh
          RishabhDeep Singh

          ๐Ÿ› Rob Baillie
          Rob Baillie

          ๐Ÿ› - - Robbie Martinus
          Robbie Martinus

          ๐Ÿ’ป ๐Ÿ› Robert Henry
          Robert Henry

          ๐Ÿ› + + Robert Mihaly
          Robert Mihaly

          ๐Ÿ› Robert Painsi
          Robert Painsi

          ๐Ÿ› Robert Russell
          Robert Russell

          ๐Ÿ› Robert Sรถsemann
          Robert Sรถsemann

          ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ› Robert Whitebit
          Robert Whitebit

          ๐Ÿ› - - Robin Richtsfeld
          Robin Richtsfeld

          ๐Ÿ› Robin Stocker
          Robin Stocker

          ๐Ÿ’ป ๐Ÿ› + + Robin Wils
          Robin Wils

          ๐Ÿ› RochusOest
          RochusOest

          ๐Ÿ› Rodolfo Noviski
          Rodolfo Noviski

          ๐Ÿ› Rodrigo Casara
          Rodrigo Casara

          ๐Ÿ› Rodrigo Fernandes
          Rodrigo Fernandes

          ๐Ÿ› - - Roman Salvador
          Roman Salvador

          ๐Ÿ’ป ๐Ÿ› Ronald Blaschke
          Ronald Blaschke

          ๐Ÿ› + + Rรณbert Papp
          Rรณbert Papp

          ๐Ÿ› Saikat Sengupta
          Saikat Sengupta

          ๐Ÿ› Saksham Handu
          Saksham Handu

          ๐Ÿ› Saladoc
          Saladoc

          ๐Ÿ› Salesforce Bob Lightning
          Salesforce Bob Lightning

          ๐Ÿ› - - Sam Carlberg
          Sam Carlberg

          ๐Ÿ› Sascha Riemer
          Sascha Riemer

          ๐Ÿ› + + Sashko
          Sashko

          ๐Ÿ’ป Satoshi Kubo
          Satoshi Kubo

          ๐Ÿ› Scott Kennedy
          Scott Kennedy

          ๐Ÿ› Scott Wells
          Scott Wells

          ๐Ÿ› ๐Ÿ’ป Scrates1
          Scrates1

          ๐Ÿ› ๐Ÿ’ป - - Scrsloota
          Scrsloota

          ๐Ÿ’ป Sebastian Bรถgl
          Sebastian Bรถgl

          ๐Ÿ› + + Sebastian Davids
          Sebastian Davids

          ๐Ÿ› Sebastian Lรถvdahl
          Sebastian Lรถvdahl

          ๐Ÿ› Sebastian Schuberth
          Sebastian Schuberth

          ๐Ÿ› Sebastian Schwarz
          Sebastian Schwarz

          ๐Ÿ› Seren
          Seren

          ๐Ÿ› ๐Ÿ’ป - - Sergey Gorbaty
          Sergey Gorbaty

          ๐Ÿ› Sergey Kozlov
          Sergey Kozlov

          ๐Ÿ› + + + Sergey Tyurin
          Sergey Tyurin

          ๐Ÿ› Sergey Yanzin
          Sergey Yanzin

          ๐Ÿ’ป ๐Ÿ› Seth Wilcox
          Seth Wilcox

          ๐Ÿ’ป Shai Bennathan
          Shai Bennathan

          ๐Ÿ› ๐Ÿ’ป Shubham
          Shubham

          ๐Ÿ’ป ๐Ÿ› Simon Abykov
          Simon Abykov

          ๐Ÿ’ป ๐Ÿ› + Simon Xiao
          Simon Xiao

          ๐Ÿ› - Simon Xiao
          Simon Xiao

          ๐Ÿ› Srinivasan Venkatachalam
          Srinivasan Venkatachalam

          ๐Ÿ› Stanislav Gromov
          Stanislav Gromov

          ๐Ÿ› Stanislav Myachenkov
          Stanislav Myachenkov

          ๐Ÿ’ป Stefan Birkner
          Stefan Birkner

          ๐Ÿ› Stefan Bohn
          Stefan Bohn

          ๐Ÿ› Stefan Endrullis
          Stefan Endrullis

          ๐Ÿ› + Stefan Klรถss-Schuster
          Stefan Klรถss-Schuster

          ๐Ÿ› - Stefan Klรถss-Schuster
          Stefan Klรถss-Schuster

          ๐Ÿ› Stefan Wolf
          Stefan Wolf

          ๐Ÿ› Stephan H. Wissel
          Stephan H. Wissel

          ๐Ÿ› Stephen
          Stephen

          ๐Ÿ› Stephen Carter
          Stephen Carter

          ๐Ÿ› Stephen Friedrich
          Stephen Friedrich

          ๐Ÿ› Steve Babula
          Steve Babula

          ๐Ÿ’ป + Steve White
          Steve White

          ๐Ÿ› - Steve White
          Steve White

          ๐Ÿ› Steven Schlansker
          Steven Schlansker

          ๐Ÿ› Steven Stearns
          Steven Stearns

          ๐Ÿ› ๐Ÿ’ป Stexxe
          Stexxe

          ๐Ÿ› Stian Lรฅgstad
          Stian Lรฅgstad

          ๐Ÿ› StuartClayton5
          StuartClayton5

          ๐Ÿ› Supun Arunoda
          Supun Arunoda

          ๐Ÿ› + Suren Abrahamyan
          Suren Abrahamyan

          ๐Ÿ› - Suren Abrahamyan
          Suren Abrahamyan

          ๐Ÿ› Suvashri
          Suvashri

          ๐Ÿ“– Sven Barden
          Sven Barden

          ๐Ÿ› SwatiBGupta1110
          SwatiBGupta1110

          ๐Ÿ› SyedThoufich
          SyedThoufich

          ๐Ÿ› Szymon Sasin
          Szymon Sasin

          ๐Ÿ› T-chuangxin
          T-chuangxin

          ๐Ÿ› + TERAI Atsuhiro
          TERAI Atsuhiro

          ๐Ÿ› - TERAI Atsuhiro
          TERAI Atsuhiro

          ๐Ÿ› TIOBE Software
          TIOBE Software

          ๐Ÿ’ป ๐Ÿ› Tarush Singh
          Tarush Singh

          ๐Ÿ’ป Taylor Smock
          Taylor Smock

          ๐Ÿ› Techeira Damiรกn
          Techeira Damiรกn

          ๐Ÿ’ป ๐Ÿ› Ted Husted
          Ted Husted

          ๐Ÿ› TehBakker
          TehBakker

          ๐Ÿ› + The Gitter Badger
          The Gitter Badger

          ๐Ÿ› - The Gitter Badger
          The Gitter Badger

          ๐Ÿ› Theodoor
          Theodoor

          ๐Ÿ› Thiago Henrique Hรผpner
          Thiago Henrique Hรผpner

          ๐Ÿ› Thibault Meyer
          Thibault Meyer

          ๐Ÿ› Thomas Gรผttler
          Thomas Gรผttler

          ๐Ÿ› Thomas Jones-Low
          Thomas Jones-Low

          ๐Ÿ› Thomas Smith
          Thomas Smith

          ๐Ÿ’ป ๐Ÿ› + ThrawnCA
          ThrawnCA

          ๐Ÿ› - ThrawnCA
          ThrawnCA

          ๐Ÿ› Thu Vo
          Thu Vo

          ๐Ÿ› Thunderforge
          Thunderforge

          ๐Ÿ’ป ๐Ÿ› Tim van der Lippe
          Tim van der Lippe

          ๐Ÿ› Tobias Weimer
          Tobias Weimer

          ๐Ÿ’ป ๐Ÿ› Tom Copeland
          Tom Copeland

          ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– Tom Daly
          Tom Daly

          ๐Ÿ› + Tomas
          Tomas

          ๐Ÿ› - Tomas
          Tomas

          ๐Ÿ› Tomer Figenblat
          Tomer Figenblat

          ๐Ÿ› Tomi De Lucca
          Tomi De Lucca

          ๐Ÿ’ป ๐Ÿ› Tony
          Tony

          ๐Ÿ“– Torsten Kleiber
          Torsten Kleiber

          ๐Ÿ› Torsten Krause
          Torsten Krause

          ๐Ÿ› TrackerSB
          TrackerSB

          ๐Ÿ› + Tyson Stewart
          Tyson Stewart

          ๐Ÿ› - Tyson Stewart
          Tyson Stewart

          ๐Ÿ› Ullrich Hafner
          Ullrich Hafner

          ๐Ÿ› UncleOwen
          UncleOwen

          ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– Utku Cuhadaroglu
          Utku Cuhadaroglu

          ๐Ÿ’ป ๐Ÿ› Valentin Brandl
          Valentin Brandl

          ๐Ÿ› Valeria
          Valeria

          ๐Ÿ› Valery Yatsynovich
          Valery Yatsynovich

          ๐Ÿ“– + Vasily Anisimov
          Vasily Anisimov

          ๐Ÿ› - Vasily Anisimov
          Vasily Anisimov

          ๐Ÿ› Vedant Chokshi
          Vedant Chokshi

          ๐Ÿ› Vibhor Goyal
          Vibhor Goyal

          ๐Ÿ› Vickenty Fesunov
          Vickenty Fesunov

          ๐Ÿ› Victor Noรซl
          Victor Noรซl

          ๐Ÿ› Vincent Galloy
          Vincent Galloy

          ๐Ÿ’ป Vincent HUYNH
          Vincent HUYNH

          ๐Ÿ› + Vincent Maurin
          Vincent Maurin

          ๐Ÿ› - Vincent Maurin
          Vincent Maurin

          ๐Ÿ› Vincent Potucek
          Vincent Potucek

          ๐Ÿ’ป Vincent Privat
          Vincent Privat

          ๐Ÿ› Vincent Zorge
          Vincent Zorge

          ๐Ÿ› Vishhwas
          Vishhwas

          ๐Ÿ› Vishv_Android
          Vishv_Android

          ๐Ÿ› Vitalii Yevtushenko
          Vitalii Yevtushenko

          ๐Ÿ› + Vitaly
          Vitaly

          ๐Ÿ› - Vitaly
          Vitaly

          ๐Ÿ› Vitaly Polonetsky
          Vitaly Polonetsky

          ๐Ÿ› Vojtech Polivka
          Vojtech Polivka

          ๐Ÿ› Vsevolod Zholobov
          Vsevolod Zholobov

          ๐Ÿ› Vyom Yadav
          Vyom Yadav

          ๐Ÿ’ป Wang Shidong
          Wang Shidong

          ๐Ÿ› Waqas Ahmed
          Waqas Ahmed

          ๐Ÿ› + Wayne J. Earl
          Wayne J. Earl

          ๐Ÿ› - Wayne J. Earl
          Wayne J. Earl

          ๐Ÿ› Wchenghui
          Wchenghui

          ๐Ÿ› Wener
          Wener

          ๐Ÿ’ป Will Winder
          Will Winder

          ๐Ÿ› Willem A. Hajenius
          Willem A. Hajenius

          ๐Ÿ’ป William Brockhus
          William Brockhus

          ๐Ÿ’ป ๐Ÿ› Wilson Kurniawan
          Wilson Kurniawan

          ๐Ÿ› + Wim Deblauwe
          Wim Deblauwe

          ๐Ÿ› - Wim Deblauwe
          Wim Deblauwe

          ๐Ÿ› Wolf2323
          Wolf2323

          ๐Ÿ› Woongsik Choi
          Woongsik Choi

          ๐Ÿ› XenoAmess
          XenoAmess

          ๐Ÿ’ป ๐Ÿ› Yang
          Yang

          ๐Ÿ’ป YaroslavTER
          YaroslavTER

          ๐Ÿ› Yasar Shaikh
          Yasar Shaikh

          ๐Ÿ’ป + Young Chan
          Young Chan

          ๐Ÿ’ป ๐Ÿ› - Young Chan
          Young Chan

          ๐Ÿ’ป ๐Ÿ› YuJin Kim
          YuJin Kim

          ๐Ÿ› Yuri Dolzhenko
          Yuri Dolzhenko

          ๐Ÿ› Yurii Dubinka
          Yurii Dubinka

          ๐Ÿ› Zbynek Konecny
          Zbynek Konecny

          ๐Ÿ› ๐Ÿ’ป Zoltan Farkas
          Zoltan Farkas

          ๐Ÿ› Zustin
          Zustin

          ๐Ÿ› + aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป - aaronhurst-google
          aaronhurst-google

          ๐Ÿ› ๐Ÿ’ป alexmodis
          alexmodis

          ๐Ÿ› andreoss
          andreoss

          ๐Ÿ› andrey81inmd
          andrey81inmd

          ๐Ÿ’ป ๐Ÿ› anicoara
          anicoara

          ๐Ÿ› arunprasathav
          arunprasathav

          ๐Ÿ› asiercamara
          asiercamara

          ๐Ÿ› + astillich-igniti
          astillich-igniti

          ๐Ÿ’ป - astillich-igniti
          astillich-igniti

          ๐Ÿ’ป avesolovksyy
          avesolovksyy

          ๐Ÿ› avishvat
          avishvat

          ๐Ÿ› avivmu
          avivmu

          ๐Ÿ› axelbarfod1
          axelbarfod1

          ๐Ÿ› b-3-n
          b-3-n

          ๐Ÿ› balbhadra9
          balbhadra9

          ๐Ÿ› + base23de
          base23de

          ๐Ÿ› - base23de
          base23de

          ๐Ÿ› bergander
          bergander

          ๐Ÿ› ๐Ÿ’ป berkam
          berkam

          ๐Ÿ’ป ๐Ÿ› bmeier-pros
          bmeier-pros

          ๐Ÿ› breizh31
          breizh31

          ๐Ÿ› caesarkim
          caesarkim

          ๐Ÿ› caiocarvalhotero
          caiocarvalhotero

          ๐Ÿ› + carolyujing
          carolyujing

          ๐Ÿ› - carolyujing
          carolyujing

          ๐Ÿ› cbfiddle
          cbfiddle

          ๐Ÿ› cesares-basilico
          cesares-basilico

          ๐Ÿ› chrite
          chrite

          ๐Ÿ› ciufudean
          ciufudean

          ๐Ÿ“– cobratbq
          cobratbq

          ๐Ÿ› coladict
          coladict

          ๐Ÿ› + cosmoJFH
          cosmoJFH

          ๐Ÿ› - cosmoJFH
          cosmoJFH

          ๐Ÿ› cristalp
          cristalp

          ๐Ÿ› crunsk
          crunsk

          ๐Ÿ› csrma
          csrma

          ๐Ÿ› cwholmes
          cwholmes

          ๐Ÿ› cyberjj999
          cyberjj999

          ๐Ÿ› cyw3
          cyw3

          ๐Ÿ› ๐Ÿ“– + d1ss0nanz
          d1ss0nanz

          ๐Ÿ› - d1ss0nanz
          d1ss0nanz

          ๐Ÿ› dague1
          dague1

          ๐Ÿ“– dalizi007
          dalizi007

          ๐Ÿ’ป danbrycefairsailcom
          danbrycefairsailcom

          ๐Ÿ› dariansanity
          dariansanity

          ๐Ÿ› darrenmiliband
          darrenmiliband

          ๐Ÿ› davidburstrom
          davidburstrom

          ๐Ÿ› + dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ› - dbirkman-paloalto
          dbirkman-paloalto

          ๐Ÿ› deepak-patra
          deepak-patra

          ๐Ÿ› dependabot[bot]
          dependabot[bot]

          ๐Ÿ’ป ๐Ÿ› dinesh150
          dinesh150

          ๐Ÿ› diziaq
          diziaq

          ๐Ÿ› dreaminpast123
          dreaminpast123

          ๐Ÿ› duanyanan
          duanyanan

          ๐Ÿ› + dutt-sanjay
          dutt-sanjay

          ๐Ÿ› - dutt-sanjay
          dutt-sanjay

          ๐Ÿ› duursma
          duursma

          ๐Ÿ’ป dylanleung
          dylanleung

          ๐Ÿ› dzeigler
          dzeigler

          ๐Ÿ› eant60
          eant60

          ๐Ÿ› ekkirala
          ekkirala

          ๐Ÿ› emersonmoura
          emersonmoura

          ๐Ÿ› + emouty
          emouty

          ๐Ÿ’ป ๐Ÿ› - emouty
          emouty

          ๐Ÿ’ป ๐Ÿ› eugenepugach
          eugenepugach

          ๐Ÿ› fairy
          fairy

          ๐Ÿ› filiprafalowicz
          filiprafalowicz

          ๐Ÿ’ป flxbl-io
          flxbl-io

          ๐Ÿ’ต foxmason
          foxmason

          ๐Ÿ› frankegabor
          frankegabor

          ๐Ÿ› + frankk3
          frankk3

          ๐Ÿ› - frankk3
          frankk3

          ๐Ÿ› frankl
          frankl

          ๐Ÿ› freafrea
          freafrea

          ๐Ÿ› fsapatin
          fsapatin

          ๐Ÿ› gearsethenry
          gearsethenry

          ๐Ÿ› gracia19
          gracia19

          ๐Ÿ› gudzpoz
          gudzpoz

          ๐Ÿ› + guo fei
          guo fei

          ๐Ÿ› - guo fei
          guo fei

          ๐Ÿ› gurmsc5
          gurmsc5

          ๐Ÿ› gwilymatgearset
          gwilymatgearset

          ๐Ÿ’ป ๐Ÿ› haigsn
          haigsn

          ๐Ÿ› hemanshu070
          hemanshu070

          ๐Ÿ› henrik242
          henrik242

          ๐Ÿ› hongpuwu
          hongpuwu

          ๐Ÿ› + hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ› - hvbtup
          hvbtup

          ๐Ÿ’ป ๐Ÿ› igniti GmbH
          igniti GmbH

          ๐Ÿ› ilovezfs
          ilovezfs

          ๐Ÿ› imax-erik
          imax-erik

          ๐Ÿ› itaigilo
          itaigilo

          ๐Ÿ› jakivey32
          jakivey32

          ๐Ÿ› jbennett2091
          jbennett2091

          ๐Ÿ› + jcamerin
          jcamerin

          ๐Ÿ› - jcamerin
          jcamerin

          ๐Ÿ› jkeener1
          jkeener1

          ๐Ÿ› jmetertea
          jmetertea

          ๐Ÿ› johnra2
          johnra2

          ๐Ÿ’ป johnzhao9
          johnzhao9

          ๐Ÿ› josemanuelrolon
          josemanuelrolon

          ๐Ÿ’ป ๐Ÿ› julees7
          julees7

          ๐Ÿ’ป ๐Ÿ› + kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ› - kabroxiko
          kabroxiko

          ๐Ÿ’ป ๐Ÿ› karthikaiyasamy
          karthikaiyasamy

          ๐Ÿ“– karwer
          karwer

          ๐Ÿ› kaulonline
          kaulonline

          ๐Ÿ› kdaemonv
          kdaemonv

          ๐Ÿ› kdandoy107255
          kdandoy107255

          ๐Ÿ› kdebski85
          kdebski85

          ๐Ÿ› ๐Ÿ’ป + kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ› - kenji21
          kenji21

          ๐Ÿ’ป ๐Ÿ› kfranic
          kfranic

          ๐Ÿ› khalidkh
          khalidkh

          ๐Ÿ› koalalam
          koalalam

          ๐Ÿ› krzyk
          krzyk

          ๐Ÿ› lasselindqvist
          lasselindqvist

          ๐Ÿ› lgemeinhardt
          lgemeinhardt

          ๐Ÿ› + lihuaib
          lihuaib

          ๐Ÿ› - lihuaib
          lihuaib

          ๐Ÿ› liqingjun123
          liqingjun123

          ๐Ÿ› lonelyma1021
          lonelyma1021

          ๐Ÿ› lothas
          lothas

          ๐Ÿ› lpeddy
          lpeddy

          ๐Ÿ› lujiefsi
          lujiefsi

          ๐Ÿ’ป lukelukes
          lukelukes

          ๐Ÿ’ป + lyriccoder
          lyriccoder

          ๐Ÿ› - lyriccoder
          lyriccoder

          ๐Ÿ› marcelmore
          marcelmore

          ๐Ÿ› matchbox
          matchbox

          ๐Ÿ› matthiaskraaz
          matthiaskraaz

          ๐Ÿ› meandonlyme
          meandonlyme

          ๐Ÿ› mikesive
          mikesive

          ๐Ÿ› milossesic
          milossesic

          ๐Ÿ› + mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ› - mluckam
          mluckam

          ๐Ÿ’ป ๐Ÿ› mohan-chinnappan-n
          mohan-chinnappan-n

          ๐Ÿ’ป mrclmh
          mrclmh

          ๐Ÿ› ๐Ÿ’ป mriddell95
          mriddell95

          ๐Ÿ› mrlzh
          mrlzh

          ๐Ÿ› msloan
          msloan

          ๐Ÿ› mucharlaravalika
          mucharlaravalika

          ๐Ÿ› + mvenneman
          mvenneman

          ๐Ÿ› - mvenneman
          mvenneman

          ๐Ÿ› nareshl119
          nareshl119

          ๐Ÿ› nicolas-harraudeau-sonarsource
          nicolas-harraudeau-sonarsource

          ๐Ÿ› noerremark
          noerremark

          ๐Ÿ› novsirion
          novsirion

          ๐Ÿ› nwcm
          nwcm

          ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
          oggboy

          ๐Ÿ› + oinume
          oinume

          ๐Ÿ› - oinume
          oinume

          ๐Ÿ› orimarko
          orimarko

          ๐Ÿ’ป ๐Ÿ› pablogomez2197
          pablogomez2197

          ๐Ÿ› pacvz
          pacvz

          ๐Ÿ’ป pallavi agarwal
          pallavi agarwal

          ๐Ÿ› pankratz76
          pankratz76

          ๐Ÿ› parksungrin
          parksungrin

          ๐Ÿ› + patpatpat123
          patpatpat123

          ๐Ÿ› - patpatpat123
          patpatpat123

          ๐Ÿ› patriksevallius
          patriksevallius

          ๐Ÿ› pbrajesh1
          pbrajesh1

          ๐Ÿ› phoenix384
          phoenix384

          ๐Ÿ› piotrszymanski-sc
          piotrszymanski-sc

          ๐Ÿ’ป plan3d
          plan3d

          ๐Ÿ› poojasix
          poojasix

          ๐Ÿ› + prabhushrikant
          prabhushrikant

          ๐Ÿ› - prabhushrikant
          prabhushrikant

          ๐Ÿ› pujitha8783
          pujitha8783

          ๐Ÿ› r-r-a-j
          r-r-a-j

          ๐Ÿ› raghujayjunk
          raghujayjunk

          ๐Ÿ› rajeshveera
          rajeshveera

          ๐Ÿ› rajeswarreddy88
          rajeswarreddy88

          ๐Ÿ› recdevs
          recdevs

          ๐Ÿ› + reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ› - reudismam
          reudismam

          ๐Ÿ’ป ๐Ÿ› rijkt
          rijkt

          ๐Ÿ› rillig-tk
          rillig-tk

          ๐Ÿ› rmohan20
          rmohan20

          ๐Ÿ’ป ๐Ÿ› rnveach
          rnveach

          ๐Ÿ› rubenporras
          rubenporras

          ๐Ÿ› rxmicro
          rxmicro

          ๐Ÿ› + ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ› - ryan-gustafson
          ryan-gustafson

          ๐Ÿ’ป ๐Ÿ› sabi0
          sabi0

          ๐Ÿ› samc-gearset
          samc-gearset

          ๐Ÿ“– + sarser.eth
          sarser.eth

          ๐Ÿ› scais
          scais

          ๐Ÿ› schosin
          schosin

          ๐Ÿ› screamingfrog
          screamingfrog

          ๐Ÿ’ต From 0be0d64865554d51d483bb0462d77f838bfe7af9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 30 Dec 2025 15:37:34 +0100 Subject: [PATCH 1814/1962] Prepare pmd release 7.20.0 --- docs/_config.yml | 4 +-- docs/pages/release_notes.md | 59 +++++++++++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 34530d84567..5414eaf7dac 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,9 +1,9 @@ repository: pmd/pmd pmd: - version: 7.20.0-SNAPSHOT + version: 7.20.0 previous_version: 7.19.0 - date: 2025-12-28 + date: 2025-12-30 # release types: major, minor, bugfix release_type: minor diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 895a4a91b69..69a61a01af9 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -22,8 +22,6 @@ This is a {{ site.pmd.release_type }} release. {% tocmaker is_release_notes_processor %} -### ๐Ÿš€๏ธ New and noteworthy - ### ๐ŸŒŸ๏ธ Changed Rules * The Java rule {%rule java/codestyle/OnlyOneReturn %} has a new property `ignoredMethodNames`. This property by default is set to `compareTo` and `equals`, thus this rule now by default allows multiple return statements @@ -64,11 +62,68 @@ This is a {{ site.pmd.release_type }} release. ### โœจ๏ธ Merged pull requests +* [#6262](https://github.com/pmd/pmd/pull/6262): \[java] UnusedLocalVariable: fix false positive with guard in switch - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6285](https://github.com/pmd/pmd/pull/6285): \[java] Fix #5043: FP in LambdaCanBeMethodReference when method ref would be ambiguous - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#6287](https://github.com/pmd/pmd/pull/6287): \[doc] Explain how to build or pull snapshot dependencies for single module builds - [Marcel](https://github.com/mrclmh) (@mrclmh) +* [#6288](https://github.com/pmd/pmd/pull/6288): \[java] Fix #6279: EmptyMethodInAbstractClassShouldBeAbstract should ignore final methods - [Marcel](https://github.com/mrclmh) (@mrclmh) +* [#6292](https://github.com/pmd/pmd/pull/6292): \[java] Fix #6291: EnumComparison FP when comparing with null - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#6293](https://github.com/pmd/pmd/pull/6293): \[java] Fix #6276: NullAssignment should not report assigning null to a final field in a constructor - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#6294](https://github.com/pmd/pmd/pull/6294): \[java] Fix #6028: UnusedPrivateMethod FP - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#6295](https://github.com/pmd/pmd/pull/6295): \[java] Fix #6237: UnnecessaryCast error with switch expr returning lambdas - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#6296](https://github.com/pmd/pmd/pull/6296): \[java] Fix #4282: GuardLogStatement only detects guard methods immediately around it - [Marcel](https://github.com/mrclmh) (@mrclmh) +* [#6299](https://github.com/pmd/pmd/pull/6299): \[java] Fix grammar of switch label - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#6309](https://github.com/pmd/pmd/pull/6309): \[java] Fix #4257: Allow ignoring methods in OnlyOneReturn - [Marcel](https://github.com/mrclmh) (@mrclmh) +* [#6311](https://github.com/pmd/pmd/pull/6311): \[java] Fix #6284: UnnecessaryConstructor reporting false-positive on JavaDoc-bearing constructor - [Marcel](https://github.com/mrclmh) (@mrclmh) +* [#6313](https://github.com/pmd/pmd/pull/6313): \[java] Fix #4910: if-statement triggers ConsecutiveAppendsShouldReuse - [Marcel](https://github.com/mrclmh) (@mrclmh) +* [#6316](https://github.com/pmd/pmd/pull/6316): \[java] Fix #5877: AvoidArrayLoops false-negative when break inside switch statement - [Marcel](https://github.com/mrclmh) (@mrclmh) +* [#6342](https://github.com/pmd/pmd/pull/6342): \[core] Fix #6330: Cannot access Chars attribute from XPath - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#6344](https://github.com/pmd/pmd/pull/6344): \[java] Fix #6328: UnusedLocalVariable should consider pattern variable in for-each without curly braces - [Mohamed Hamed](https://github.com/mdhamed238) (@mdhamed238) +* [#6348](https://github.com/pmd/pmd/pull/6348): \[jsp] Fix malformed Javadoc HTML in JspDocStyleTest - [Gianmarco](https://github.com/gianmarcoschifone) (@gianmarcoschifone) +* [#6359](https://github.com/pmd/pmd/pull/6359): \[java] Fix #6234: Parser fails to parse switch expressions in super() constructor calls - [Mohamed Hamed](https://github.com/mdhamed238) (@mdhamed238) +* [#6360](https://github.com/pmd/pmd/pull/6360): \[java] Fix #4158: BigIntegerInstantiation false-negative with compile-time constant - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#6361](https://github.com/pmd/pmd/pull/6361): \[vf] Fix invalid Javadoc syntax in VfDocStyleTest - [Gianmarco](https://github.com/gianmarcoschifone) (@gianmarcoschifone) +* [#6363](https://github.com/pmd/pmd/pull/6363): \[apex] Add sca-extra ruleset for Salesforce Apex testing - [Beech Horn](https://github.com/metalshark) (@metalshark) ### ๐Ÿ“ฆ๏ธ Dependency updates +* [#6286](https://github.com/pmd/pmd/pull/6286): Bump PMD from 7.18.0 to 7.19.0 +* [#6300](https://github.com/pmd/pmd/pull/6300): chore(deps): bump actions/checkout from 6.0.0 to 6.0.1 +* [#6301](https://github.com/pmd/pmd/pull/6301): chore(deps): bump org.checkerframework:checker-qual from 3.52.0 to 3.52.1 +* [#6302](https://github.com/pmd/pmd/pull/6302): chore(deps): bump org.apache.maven.plugins:maven-resources-plugin from 3.3.1 to 3.4.0 +* [#6303](https://github.com/pmd/pmd/pull/6303): chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.18.1 to 1.18.2 +* [#6304](https://github.com/pmd/pmd/pull/6304): chore(deps): bump com.puppycrawl.tools:checkstyle from 12.1.2 to 12.2.0 +* [#6305](https://github.com/pmd/pmd/pull/6305): chore(deps): bump org.sonarsource.scanner.maven:sonar-maven-plugin from 5.3.0.6276 to 5.4.0.6343 +* [#6306](https://github.com/pmd/pmd/pull/6306): chore(deps): bump webrick from 1.9.1 to 1.9.2 in /docs +* [#6318](https://github.com/pmd/pmd/pull/6318): chore(deps): bump actions/create-github-app-token from 2.2.0 to 2.2.1 +* [#6319](https://github.com/pmd/pmd/pull/6319): chore(deps): bump actions/setup-java from 5.0.0 to 5.1.0 +* [#6320](https://github.com/pmd/pmd/pull/6320): chore(deps): bump ruby/setup-ruby from 1.268.0 to 1.269.0 +* [#6321](https://github.com/pmd/pmd/pull/6321): chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.18.1 to 1.18.2 +* [#6323](https://github.com/pmd/pmd/pull/6323): chore(deps): bump com.google.protobuf:protobuf-java from 4.33.1 to 4.33.2 +* [#6324](https://github.com/pmd/pmd/pull/6324): chore(deps): bump io.github.apex-dev-tools:apex-ls_2.13 from 6.0.1 to 6.0.2 +* [#6325](https://github.com/pmd/pmd/pull/6325): chore(deps): bump org.apache.maven.plugins:maven-assembly-plugin from 3.7.1 to 3.8.0 +* [#6329](https://github.com/pmd/pmd/pull/6329): chore(deps): bump org.mozilla:rhino from 1.7.15 to 1.7.15.1 +* [#6331](https://github.com/pmd/pmd/pull/6331): chore(deps): bump actions/upload-artifact from 5.0.0 to 6.0.0 +* [#6332](https://github.com/pmd/pmd/pull/6332): chore(deps): bump org.mockito:mockito-core from 5.20.0 to 5.21.0 +* [#6333](https://github.com/pmd/pmd/pull/6333): chore(deps): bump actions/download-artifact from 6.0.0 to 7.0.0 +* [#6334](https://github.com/pmd/pmd/pull/6334): chore(deps): bump ruby/setup-ruby from 1.269.0 to 1.270.0 +* [#6335](https://github.com/pmd/pmd/pull/6335): chore(deps): bump com.puppycrawl.tools:checkstyle from 12.2.0 to 12.3.0 +* [#6336](https://github.com/pmd/pmd/pull/6336): chore(deps): bump actions/cache from 4.3.0 to 5.0.1 +* [#6337](https://github.com/pmd/pmd/pull/6337): chore(deps): bump bigdecimal from 3.3.1 to 4.0.0 in /docs +* [#6339](https://github.com/pmd/pmd/pull/6339): chore(deps): bump org.apache.maven.plugins:maven-release-plugin from 3.2.0 to 3.3.1 +* [#6341](https://github.com/pmd/pmd/pull/6341): chore(deps): bump org.apache.maven.plugins:maven-source-plugin from 3.3.1 to 3.4.0 +* [#6347](https://github.com/pmd/pmd/pull/6347): chore(deps-dev): bump org.apache.logging.log4j:log4j-core from 2.25.2 to 2.25.3 in /pmd-java +* [#6350](https://github.com/pmd/pmd/pull/6350): chore(deps): bump com.github.siom79.japicmp:japicmp-maven-plugin from 0.24.2 to 0.25.1 +* [#6352](https://github.com/pmd/pmd/pull/6352): chore(deps): bump ruby/setup-ruby from 1.270.0 to 1.275.0 +* [#6353](https://github.com/pmd/pmd/pull/6353): chore(deps): bump org.ow2.asm:asm from 9.9 to 9.9.1 +* [#6354](https://github.com/pmd/pmd/pull/6354): chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.18.2 to 1.18.3 +* [#6356](https://github.com/pmd/pmd/pull/6356): chore(deps): bump org.sonarsource.scanner.maven:sonar-maven-plugin from 5.4.0.6343 to 5.5.0.6356 +* [#6357](https://github.com/pmd/pmd/pull/6357): chore(deps): bump org.apache.commons:commons-text from 1.14.0 to 1.15.0 +* [#6358](https://github.com/pmd/pmd/pull/6358): chore(deps): bump bigdecimal from 4.0.0 to 4.0.1 in /docs ### ๐Ÿ“ˆ๏ธ Stats +* 102 commits +* 39 closed tickets & PRs +* Days since last release: 32 {% endtocmaker %} From fa478ec141c154d34aac5389f0d5add0f28ecfea Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 30 Dec 2025 16:08:59 +0100 Subject: [PATCH 1815/1962] [release] prepare release pmd_releases/7.20.0 --- pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-css/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-rust/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 6 +++--- 44 files changed, 46 insertions(+), 46 deletions(-) diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index 490e72add84..5f6ecabf1fd 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.20.0-SNAPSHOT + 7.20.0 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index ef48dc3495d..d9203b22102 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index 7e3933105e6..7a648efa8e0 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index 11d0a185aa9..1b65abeb038 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index e0572bdbeeb..32cb046d64f 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index c790214f4b2..d41733720a5 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index f0fffaac3af..d6a0e3d93c2 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-css/pom.xml b/pmd-css/pom.xml index 7f47b303b8e..74a467c99b3 100644 --- a/pmd-css/pom.xml +++ b/pmd-css/pom.xml @@ -9,7 +9,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index adfec9779cf..0d2c6d35bcb 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index cd7ece0dbff..1e099318361 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index 8dfafddfe7a..54c279f863f 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index ca39cac3f91..b85bed2d3bb 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index 965cfff3981..99fed7f2f2b 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index fcf8768ad5e..8b0ad9f01f3 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index 96db91eebcf..39e821e6b5c 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index 860942102ae..f6f8bf7aab9 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 5a1fab7d0c9..8b9de470407 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index 0b77f253bfe..3e2dea69105 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index 3d0992bcf55..bc2b22c9518 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index 0feca275256..2ba86404c51 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index 7a93f60a2ee..9ac847f470c 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index c4fff49b44c..86eae2594f0 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index 829c9c2cae8..78b1b5d5a68 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index a0d8804f630..2302892df6b 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index 50522c82f3a..50c429c1915 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index e742cdd74ee..0d9effc73f8 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index 91f82e6e852..43d3921db90 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index 0df600f9029..5ca20068d38 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index 2e85696aa35..4a0f0ff2412 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index d65f5d25771..b5fab5d81b6 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index 2de426045e7..3a35859ae60 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index 2813f23a06d..2e5079cc76f 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index 180d8aab61b..fe99c728daf 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index f45c9aac80e..4b17ca4379d 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index 6bdb08da2fa..af9a4d44b48 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.20.0-SNAPSHOT + 7.20.0 ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index b2c8f0c3f31..80a3e9c9778 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.20.0-SNAPSHOT + 7.20.0 ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index 26596df6302..8afb5880e78 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index c36ca99f62b..35d59737c2f 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index f36aca31e33..afa7b920c22 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index ab917814a64..f23d7b59508 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index 02670dd0533..d9fee7a905a 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index 34202ece856..dd85f8b1206 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index 6f6c7b14c36..f9f27ce25e1 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 ../pom.xml diff --git a/pom.xml b/pom.xml index 2473311de23..7a0193f201a 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.20.0-SNAPSHOT + 7.20.0 pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - HEAD + pmd_releases/7.20.0 PMD @@ -73,7 +73,7 @@ - 2025-11-28T10:42:42Z + 2025-12-30T14:37:52Z 8 From 571123d63404e47e6d258c193be316093082ac7e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 30 Dec 2025 16:50:16 +0100 Subject: [PATCH 1816/1962] [release] Prepare next development version --- docs/_config.yml | 6 +- docs/pages/release_notes.md | 92 +--------------- docs/pages/release_notes_old.md | 122 +++++++++++++++++++++ pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-css/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-rust/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 4 +- 47 files changed, 172 insertions(+), 138 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 5414eaf7dac..25c7c49d837 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,9 +1,9 @@ repository: pmd/pmd pmd: - version: 7.20.0 - previous_version: 7.19.0 - date: 2025-12-30 + version: 7.21.0-SNAPSHOT + previous_version: 7.20.0 + date: 2026-01-30 # release types: major, minor, bugfix release_type: minor diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 69a61a01af9..48d7c2ca2f6 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -22,108 +22,20 @@ This is a {{ site.pmd.release_type }} release. {% tocmaker is_release_notes_processor %} -### ๐ŸŒŸ๏ธ Changed Rules -* The Java rule {%rule java/codestyle/OnlyOneReturn %} has a new property `ignoredMethodNames`. This property by - default is set to `compareTo` and `equals`, thus this rule now by default allows multiple return statements - for these methods. To restore the old behavior, simply set this property to an empty value. +### ๐Ÿš€๏ธ New and noteworthy ### ๐Ÿ›๏ธ Fixed Issues -* core - * [#6330](https://github.com/pmd/pmd/issues/6330): \[core] "Unable to create ValueRepresentation" when using @LiteralText (XPath) -* java - * [#6234](https://github.com/pmd/pmd/issues/6234): \[java] Parser fails to parse switch expressions in super() constructor calls - * [#6299](https://github.com/pmd/pmd/issues/6299): \[java] Fix grammar of switch label -* java-bestpractices - * [#4282](https://github.com/pmd/pmd/issues/4282): \[java] GuardLogStatement: False positive when guard is not a direct parent - * [#6028](https://github.com/pmd/pmd/issues/6028): \[java] UnusedPrivateMethod: False positive with raw type for generic method - * [#6257](https://github.com/pmd/pmd/issues/6257): \[java] UnusedLocalVariable: False positive with instanceof pattern guard - * [#6291](https://github.com/pmd/pmd/issues/6291): \[java] EnumComparison: False positive for any object when object.equals(null) - * [#6328](https://github.com/pmd/pmd/issues/6328): \[java] UnusedLocalVariable: False positive for pattern variable in for-each without braces -* java-codestyle - * [#4257](https://github.com/pmd/pmd/issues/4257): \[java] OnlyOneReturn: False positive with equals method - * [#5043](https://github.com/pmd/pmd/issues/5043): \[java] LambdaCanBeMethodReference: False positive on overloaded methods - * [#6237](https://github.com/pmd/pmd/issues/6237): \[java] UnnecessaryCast: ContextedRuntimeException when parsing switch expression with lambdas - * [#6279](https://github.com/pmd/pmd/issues/6279): \[java] EmptyMethodInAbstractClassShouldBeAbstract: False positive for final empty methods - * [#6284](https://github.com/pmd/pmd/issues/6284): \[java] UnnecessaryConstructor: False positive for JavaDoc-bearing constructor -* java-errorprone - * [#6276](https://github.com/pmd/pmd/issues/6276): \[java] NullAssignment: False positive when assigning null to a final field in a constructor - * [#6343](https://github.com/pmd/pmd/issues/6343): \[java] MissingStaticMethodInNonInstantiatableClass: False negative when method in nested class returns null -* java-performance - * [#4158](https://github.com/pmd/pmd/issues/4158): \[java] BigIntegerInstantiation: False negative with compile-time constant - * [#4910](https://github.com/pmd/pmd/issues/4910): \[java] ConsecutiveAppendsShouldReuse: False positive within if-statement without curly braces - * [#5877](https://github.com/pmd/pmd/issues/5877): \[java] AvoidArrayLoops: False negative when break inside switch statement -* maintenance - * [#6230](https://github.com/pmd/pmd/issues/6230): \[core] Single module snapshot build fails ### ๐Ÿšจ๏ธ API Changes -#### Experimental API -* pmd-java: {%jdoc !!java::lang.java.types.OverloadSelectionResult#hadSeveralApplicableOverloads()%} - ### โœจ๏ธ Merged pull requests -* [#6262](https://github.com/pmd/pmd/pull/6262): \[java] UnusedLocalVariable: fix false positive with guard in switch - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) -* [#6285](https://github.com/pmd/pmd/pull/6285): \[java] Fix #5043: FP in LambdaCanBeMethodReference when method ref would be ambiguous - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#6287](https://github.com/pmd/pmd/pull/6287): \[doc] Explain how to build or pull snapshot dependencies for single module builds - [Marcel](https://github.com/mrclmh) (@mrclmh) -* [#6288](https://github.com/pmd/pmd/pull/6288): \[java] Fix #6279: EmptyMethodInAbstractClassShouldBeAbstract should ignore final methods - [Marcel](https://github.com/mrclmh) (@mrclmh) -* [#6292](https://github.com/pmd/pmd/pull/6292): \[java] Fix #6291: EnumComparison FP when comparing with null - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#6293](https://github.com/pmd/pmd/pull/6293): \[java] Fix #6276: NullAssignment should not report assigning null to a final field in a constructor - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) -* [#6294](https://github.com/pmd/pmd/pull/6294): \[java] Fix #6028: UnusedPrivateMethod FP - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#6295](https://github.com/pmd/pmd/pull/6295): \[java] Fix #6237: UnnecessaryCast error with switch expr returning lambdas - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#6296](https://github.com/pmd/pmd/pull/6296): \[java] Fix #4282: GuardLogStatement only detects guard methods immediately around it - [Marcel](https://github.com/mrclmh) (@mrclmh) -* [#6299](https://github.com/pmd/pmd/pull/6299): \[java] Fix grammar of switch label - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#6309](https://github.com/pmd/pmd/pull/6309): \[java] Fix #4257: Allow ignoring methods in OnlyOneReturn - [Marcel](https://github.com/mrclmh) (@mrclmh) -* [#6311](https://github.com/pmd/pmd/pull/6311): \[java] Fix #6284: UnnecessaryConstructor reporting false-positive on JavaDoc-bearing constructor - [Marcel](https://github.com/mrclmh) (@mrclmh) -* [#6313](https://github.com/pmd/pmd/pull/6313): \[java] Fix #4910: if-statement triggers ConsecutiveAppendsShouldReuse - [Marcel](https://github.com/mrclmh) (@mrclmh) -* [#6316](https://github.com/pmd/pmd/pull/6316): \[java] Fix #5877: AvoidArrayLoops false-negative when break inside switch statement - [Marcel](https://github.com/mrclmh) (@mrclmh) -* [#6342](https://github.com/pmd/pmd/pull/6342): \[core] Fix #6330: Cannot access Chars attribute from XPath - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) -* [#6344](https://github.com/pmd/pmd/pull/6344): \[java] Fix #6328: UnusedLocalVariable should consider pattern variable in for-each without curly braces - [Mohamed Hamed](https://github.com/mdhamed238) (@mdhamed238) -* [#6348](https://github.com/pmd/pmd/pull/6348): \[jsp] Fix malformed Javadoc HTML in JspDocStyleTest - [Gianmarco](https://github.com/gianmarcoschifone) (@gianmarcoschifone) -* [#6359](https://github.com/pmd/pmd/pull/6359): \[java] Fix #6234: Parser fails to parse switch expressions in super() constructor calls - [Mohamed Hamed](https://github.com/mdhamed238) (@mdhamed238) -* [#6360](https://github.com/pmd/pmd/pull/6360): \[java] Fix #4158: BigIntegerInstantiation false-negative with compile-time constant - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) -* [#6361](https://github.com/pmd/pmd/pull/6361): \[vf] Fix invalid Javadoc syntax in VfDocStyleTest - [Gianmarco](https://github.com/gianmarcoschifone) (@gianmarcoschifone) -* [#6363](https://github.com/pmd/pmd/pull/6363): \[apex] Add sca-extra ruleset for Salesforce Apex testing - [Beech Horn](https://github.com/metalshark) (@metalshark) ### ๐Ÿ“ฆ๏ธ Dependency updates -* [#6286](https://github.com/pmd/pmd/pull/6286): Bump PMD from 7.18.0 to 7.19.0 -* [#6300](https://github.com/pmd/pmd/pull/6300): chore(deps): bump actions/checkout from 6.0.0 to 6.0.1 -* [#6301](https://github.com/pmd/pmd/pull/6301): chore(deps): bump org.checkerframework:checker-qual from 3.52.0 to 3.52.1 -* [#6302](https://github.com/pmd/pmd/pull/6302): chore(deps): bump org.apache.maven.plugins:maven-resources-plugin from 3.3.1 to 3.4.0 -* [#6303](https://github.com/pmd/pmd/pull/6303): chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.18.1 to 1.18.2 -* [#6304](https://github.com/pmd/pmd/pull/6304): chore(deps): bump com.puppycrawl.tools:checkstyle from 12.1.2 to 12.2.0 -* [#6305](https://github.com/pmd/pmd/pull/6305): chore(deps): bump org.sonarsource.scanner.maven:sonar-maven-plugin from 5.3.0.6276 to 5.4.0.6343 -* [#6306](https://github.com/pmd/pmd/pull/6306): chore(deps): bump webrick from 1.9.1 to 1.9.2 in /docs -* [#6318](https://github.com/pmd/pmd/pull/6318): chore(deps): bump actions/create-github-app-token from 2.2.0 to 2.2.1 -* [#6319](https://github.com/pmd/pmd/pull/6319): chore(deps): bump actions/setup-java from 5.0.0 to 5.1.0 -* [#6320](https://github.com/pmd/pmd/pull/6320): chore(deps): bump ruby/setup-ruby from 1.268.0 to 1.269.0 -* [#6321](https://github.com/pmd/pmd/pull/6321): chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.18.1 to 1.18.2 -* [#6323](https://github.com/pmd/pmd/pull/6323): chore(deps): bump com.google.protobuf:protobuf-java from 4.33.1 to 4.33.2 -* [#6324](https://github.com/pmd/pmd/pull/6324): chore(deps): bump io.github.apex-dev-tools:apex-ls_2.13 from 6.0.1 to 6.0.2 -* [#6325](https://github.com/pmd/pmd/pull/6325): chore(deps): bump org.apache.maven.plugins:maven-assembly-plugin from 3.7.1 to 3.8.0 -* [#6329](https://github.com/pmd/pmd/pull/6329): chore(deps): bump org.mozilla:rhino from 1.7.15 to 1.7.15.1 -* [#6331](https://github.com/pmd/pmd/pull/6331): chore(deps): bump actions/upload-artifact from 5.0.0 to 6.0.0 -* [#6332](https://github.com/pmd/pmd/pull/6332): chore(deps): bump org.mockito:mockito-core from 5.20.0 to 5.21.0 -* [#6333](https://github.com/pmd/pmd/pull/6333): chore(deps): bump actions/download-artifact from 6.0.0 to 7.0.0 -* [#6334](https://github.com/pmd/pmd/pull/6334): chore(deps): bump ruby/setup-ruby from 1.269.0 to 1.270.0 -* [#6335](https://github.com/pmd/pmd/pull/6335): chore(deps): bump com.puppycrawl.tools:checkstyle from 12.2.0 to 12.3.0 -* [#6336](https://github.com/pmd/pmd/pull/6336): chore(deps): bump actions/cache from 4.3.0 to 5.0.1 -* [#6337](https://github.com/pmd/pmd/pull/6337): chore(deps): bump bigdecimal from 3.3.1 to 4.0.0 in /docs -* [#6339](https://github.com/pmd/pmd/pull/6339): chore(deps): bump org.apache.maven.plugins:maven-release-plugin from 3.2.0 to 3.3.1 -* [#6341](https://github.com/pmd/pmd/pull/6341): chore(deps): bump org.apache.maven.plugins:maven-source-plugin from 3.3.1 to 3.4.0 -* [#6347](https://github.com/pmd/pmd/pull/6347): chore(deps-dev): bump org.apache.logging.log4j:log4j-core from 2.25.2 to 2.25.3 in /pmd-java -* [#6350](https://github.com/pmd/pmd/pull/6350): chore(deps): bump com.github.siom79.japicmp:japicmp-maven-plugin from 0.24.2 to 0.25.1 -* [#6352](https://github.com/pmd/pmd/pull/6352): chore(deps): bump ruby/setup-ruby from 1.270.0 to 1.275.0 -* [#6353](https://github.com/pmd/pmd/pull/6353): chore(deps): bump org.ow2.asm:asm from 9.9 to 9.9.1 -* [#6354](https://github.com/pmd/pmd/pull/6354): chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.18.2 to 1.18.3 -* [#6356](https://github.com/pmd/pmd/pull/6356): chore(deps): bump org.sonarsource.scanner.maven:sonar-maven-plugin from 5.4.0.6343 to 5.5.0.6356 -* [#6357](https://github.com/pmd/pmd/pull/6357): chore(deps): bump org.apache.commons:commons-text from 1.14.0 to 1.15.0 -* [#6358](https://github.com/pmd/pmd/pull/6358): chore(deps): bump bigdecimal from 4.0.0 to 4.0.1 in /docs ### ๐Ÿ“ˆ๏ธ Stats -* 102 commits -* 39 closed tickets & PRs -* Days since last release: 32 {% endtocmaker %} + diff --git a/docs/pages/release_notes_old.md b/docs/pages/release_notes_old.md index 5381059cbe6..307840db19e 100644 --- a/docs/pages/release_notes_old.md +++ b/docs/pages/release_notes_old.md @@ -7,6 +7,128 @@ Previous versions of PMD can be downloaded here: [Releases - pmd/pmd (GitHub)](h +## 30-December-2025 - 7.20.0 + +The PMD team is pleased to announce PMD 7.20.0. + +This is a minor release. + +### Table Of Contents + +* [๐ŸŒŸ๏ธ Changed Rules](#changed-rules) +* [๐Ÿ›๏ธ Fixed Issues](#fixed-issues) +* [๐Ÿšจ๏ธ API Changes](#api-changes) + * [Experimental API](#experimental-api) +* [โœจ๏ธ Merged pull requests](#merged-pull-requests) +* [๐Ÿ“ฆ๏ธ Dependency updates](#dependency-updates) +* [๐Ÿ“ˆ๏ธ Stats](#stats) + +### ๐ŸŒŸ๏ธ Changed Rules +* The Java rule [`OnlyOneReturn`](https://docs.pmd-code.org/pmd-doc-7.20.0/pmd_rules_java_codestyle.html#onlyonereturn) has a new property `ignoredMethodNames`. This property by + default is set to `compareTo` and `equals`, thus this rule now by default allows multiple return statements + for these methods. To restore the old behavior, simply set this property to an empty value. + +### ๐Ÿ›๏ธ Fixed Issues +* core + * [#6330](https://github.com/pmd/pmd/issues/6330): \[core] "Unable to create ValueRepresentation" when using @LiteralText (XPath) +* java + * [#6234](https://github.com/pmd/pmd/issues/6234): \[java] Parser fails to parse switch expressions in super() constructor calls + * [#6299](https://github.com/pmd/pmd/issues/6299): \[java] Fix grammar of switch label +* java-bestpractices + * [#4282](https://github.com/pmd/pmd/issues/4282): \[java] GuardLogStatement: False positive when guard is not a direct parent + * [#6028](https://github.com/pmd/pmd/issues/6028): \[java] UnusedPrivateMethod: False positive with raw type for generic method + * [#6257](https://github.com/pmd/pmd/issues/6257): \[java] UnusedLocalVariable: False positive with instanceof pattern guard + * [#6291](https://github.com/pmd/pmd/issues/6291): \[java] EnumComparison: False positive for any object when object.equals(null) + * [#6328](https://github.com/pmd/pmd/issues/6328): \[java] UnusedLocalVariable: False positive for pattern variable in for-each without braces +* java-codestyle + * [#4257](https://github.com/pmd/pmd/issues/4257): \[java] OnlyOneReturn: False positive with equals method + * [#5043](https://github.com/pmd/pmd/issues/5043): \[java] LambdaCanBeMethodReference: False positive on overloaded methods + * [#6237](https://github.com/pmd/pmd/issues/6237): \[java] UnnecessaryCast: ContextedRuntimeException when parsing switch expression with lambdas + * [#6279](https://github.com/pmd/pmd/issues/6279): \[java] EmptyMethodInAbstractClassShouldBeAbstract: False positive for final empty methods + * [#6284](https://github.com/pmd/pmd/issues/6284): \[java] UnnecessaryConstructor: False positive for JavaDoc-bearing constructor +* java-errorprone + * [#6276](https://github.com/pmd/pmd/issues/6276): \[java] NullAssignment: False positive when assigning null to a final field in a constructor + * [#6343](https://github.com/pmd/pmd/issues/6343): \[java] MissingStaticMethodInNonInstantiatableClass: False negative when method in nested class returns null +* java-performance + * [#4158](https://github.com/pmd/pmd/issues/4158): \[java] BigIntegerInstantiation: False negative with compile-time constant + * [#4910](https://github.com/pmd/pmd/issues/4910): \[java] ConsecutiveAppendsShouldReuse: False positive within if-statement without curly braces + * [#5877](https://github.com/pmd/pmd/issues/5877): \[java] AvoidArrayLoops: False negative when break inside switch statement +* maintenance + * [#6230](https://github.com/pmd/pmd/issues/6230): \[core] Single module snapshot build fails + +### ๐Ÿšจ๏ธ API Changes + +#### Experimental API +* pmd-java: OverloadSelectionResult#hadSeveralApplicableOverloads + +### โœจ๏ธ Merged pull requests + +* [#6262](https://github.com/pmd/pmd/pull/6262): \[java] UnusedLocalVariable: fix false positive with guard in switch - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6285](https://github.com/pmd/pmd/pull/6285): \[java] Fix #5043: FP in LambdaCanBeMethodReference when method ref would be ambiguous - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#6287](https://github.com/pmd/pmd/pull/6287): \[doc] Explain how to build or pull snapshot dependencies for single module builds - [Marcel](https://github.com/mrclmh) (@mrclmh) +* [#6288](https://github.com/pmd/pmd/pull/6288): \[java] Fix #6279: EmptyMethodInAbstractClassShouldBeAbstract should ignore final methods - [Marcel](https://github.com/mrclmh) (@mrclmh) +* [#6292](https://github.com/pmd/pmd/pull/6292): \[java] Fix #6291: EnumComparison FP when comparing with null - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#6293](https://github.com/pmd/pmd/pull/6293): \[java] Fix #6276: NullAssignment should not report assigning null to a final field in a constructor - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#6294](https://github.com/pmd/pmd/pull/6294): \[java] Fix #6028: UnusedPrivateMethod FP - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#6295](https://github.com/pmd/pmd/pull/6295): \[java] Fix #6237: UnnecessaryCast error with switch expr returning lambdas - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#6296](https://github.com/pmd/pmd/pull/6296): \[java] Fix #4282: GuardLogStatement only detects guard methods immediately around it - [Marcel](https://github.com/mrclmh) (@mrclmh) +* [#6299](https://github.com/pmd/pmd/pull/6299): \[java] Fix grammar of switch label - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#6309](https://github.com/pmd/pmd/pull/6309): \[java] Fix #4257: Allow ignoring methods in OnlyOneReturn - [Marcel](https://github.com/mrclmh) (@mrclmh) +* [#6311](https://github.com/pmd/pmd/pull/6311): \[java] Fix #6284: UnnecessaryConstructor reporting false-positive on JavaDoc-bearing constructor - [Marcel](https://github.com/mrclmh) (@mrclmh) +* [#6313](https://github.com/pmd/pmd/pull/6313): \[java] Fix #4910: if-statement triggers ConsecutiveAppendsShouldReuse - [Marcel](https://github.com/mrclmh) (@mrclmh) +* [#6316](https://github.com/pmd/pmd/pull/6316): \[java] Fix #5877: AvoidArrayLoops false-negative when break inside switch statement - [Marcel](https://github.com/mrclmh) (@mrclmh) +* [#6342](https://github.com/pmd/pmd/pull/6342): \[core] Fix #6330: Cannot access Chars attribute from XPath - [Clรฉment Fournier](https://github.com/oowekyala) (@oowekyala) +* [#6344](https://github.com/pmd/pmd/pull/6344): \[java] Fix #6328: UnusedLocalVariable should consider pattern variable in for-each without curly braces - [Mohamed Hamed](https://github.com/mdhamed238) (@mdhamed238) +* [#6348](https://github.com/pmd/pmd/pull/6348): \[jsp] Fix malformed Javadoc HTML in JspDocStyleTest - [Gianmarco](https://github.com/gianmarcoschifone) (@gianmarcoschifone) +* [#6359](https://github.com/pmd/pmd/pull/6359): \[java] Fix #6234: Parser fails to parse switch expressions in super() constructor calls - [Mohamed Hamed](https://github.com/mdhamed238) (@mdhamed238) +* [#6360](https://github.com/pmd/pmd/pull/6360): \[java] Fix #4158: BigIntegerInstantiation false-negative with compile-time constant - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#6361](https://github.com/pmd/pmd/pull/6361): \[vf] Fix invalid Javadoc syntax in VfDocStyleTest - [Gianmarco](https://github.com/gianmarcoschifone) (@gianmarcoschifone) +* [#6363](https://github.com/pmd/pmd/pull/6363): \[apex] Add sca-extra ruleset for Salesforce Apex testing - [Beech Horn](https://github.com/metalshark) (@metalshark) + +### ๐Ÿ“ฆ๏ธ Dependency updates + +* [#6286](https://github.com/pmd/pmd/pull/6286): Bump PMD from 7.18.0 to 7.19.0 +* [#6300](https://github.com/pmd/pmd/pull/6300): chore(deps): bump actions/checkout from 6.0.0 to 6.0.1 +* [#6301](https://github.com/pmd/pmd/pull/6301): chore(deps): bump org.checkerframework:checker-qual from 3.52.0 to 3.52.1 +* [#6302](https://github.com/pmd/pmd/pull/6302): chore(deps): bump org.apache.maven.plugins:maven-resources-plugin from 3.3.1 to 3.4.0 +* [#6303](https://github.com/pmd/pmd/pull/6303): chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.18.1 to 1.18.2 +* [#6304](https://github.com/pmd/pmd/pull/6304): chore(deps): bump com.puppycrawl.tools:checkstyle from 12.1.2 to 12.2.0 +* [#6305](https://github.com/pmd/pmd/pull/6305): chore(deps): bump org.sonarsource.scanner.maven:sonar-maven-plugin from 5.3.0.6276 to 5.4.0.6343 +* [#6306](https://github.com/pmd/pmd/pull/6306): chore(deps): bump webrick from 1.9.1 to 1.9.2 in /docs +* [#6318](https://github.com/pmd/pmd/pull/6318): chore(deps): bump actions/create-github-app-token from 2.2.0 to 2.2.1 +* [#6319](https://github.com/pmd/pmd/pull/6319): chore(deps): bump actions/setup-java from 5.0.0 to 5.1.0 +* [#6320](https://github.com/pmd/pmd/pull/6320): chore(deps): bump ruby/setup-ruby from 1.268.0 to 1.269.0 +* [#6321](https://github.com/pmd/pmd/pull/6321): chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.18.1 to 1.18.2 +* [#6323](https://github.com/pmd/pmd/pull/6323): chore(deps): bump com.google.protobuf:protobuf-java from 4.33.1 to 4.33.2 +* [#6324](https://github.com/pmd/pmd/pull/6324): chore(deps): bump io.github.apex-dev-tools:apex-ls_2.13 from 6.0.1 to 6.0.2 +* [#6325](https://github.com/pmd/pmd/pull/6325): chore(deps): bump org.apache.maven.plugins:maven-assembly-plugin from 3.7.1 to 3.8.0 +* [#6329](https://github.com/pmd/pmd/pull/6329): chore(deps): bump org.mozilla:rhino from 1.7.15 to 1.7.15.1 +* [#6331](https://github.com/pmd/pmd/pull/6331): chore(deps): bump actions/upload-artifact from 5.0.0 to 6.0.0 +* [#6332](https://github.com/pmd/pmd/pull/6332): chore(deps): bump org.mockito:mockito-core from 5.20.0 to 5.21.0 +* [#6333](https://github.com/pmd/pmd/pull/6333): chore(deps): bump actions/download-artifact from 6.0.0 to 7.0.0 +* [#6334](https://github.com/pmd/pmd/pull/6334): chore(deps): bump ruby/setup-ruby from 1.269.0 to 1.270.0 +* [#6335](https://github.com/pmd/pmd/pull/6335): chore(deps): bump com.puppycrawl.tools:checkstyle from 12.2.0 to 12.3.0 +* [#6336](https://github.com/pmd/pmd/pull/6336): chore(deps): bump actions/cache from 4.3.0 to 5.0.1 +* [#6337](https://github.com/pmd/pmd/pull/6337): chore(deps): bump bigdecimal from 3.3.1 to 4.0.0 in /docs +* [#6339](https://github.com/pmd/pmd/pull/6339): chore(deps): bump org.apache.maven.plugins:maven-release-plugin from 3.2.0 to 3.3.1 +* [#6341](https://github.com/pmd/pmd/pull/6341): chore(deps): bump org.apache.maven.plugins:maven-source-plugin from 3.3.1 to 3.4.0 +* [#6347](https://github.com/pmd/pmd/pull/6347): chore(deps-dev): bump org.apache.logging.log4j:log4j-core from 2.25.2 to 2.25.3 in /pmd-java +* [#6350](https://github.com/pmd/pmd/pull/6350): chore(deps): bump com.github.siom79.japicmp:japicmp-maven-plugin from 0.24.2 to 0.25.1 +* [#6352](https://github.com/pmd/pmd/pull/6352): chore(deps): bump ruby/setup-ruby from 1.270.0 to 1.275.0 +* [#6353](https://github.com/pmd/pmd/pull/6353): chore(deps): bump org.ow2.asm:asm from 9.9 to 9.9.1 +* [#6354](https://github.com/pmd/pmd/pull/6354): chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.18.2 to 1.18.3 +* [#6356](https://github.com/pmd/pmd/pull/6356): chore(deps): bump org.sonarsource.scanner.maven:sonar-maven-plugin from 5.4.0.6343 to 5.5.0.6356 +* [#6357](https://github.com/pmd/pmd/pull/6357): chore(deps): bump org.apache.commons:commons-text from 1.14.0 to 1.15.0 +* [#6358](https://github.com/pmd/pmd/pull/6358): chore(deps): bump bigdecimal from 4.0.0 to 4.0.1 in /docs + +### ๐Ÿ“ˆ๏ธ Stats + +* 102 commits +* 39 closed tickets & PRs +* Days since last release: 32 + + + ## 28-November-2025 - 7.19.0 The PMD team is pleased to announce PMD 7.19.0. diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index 5f6ecabf1fd..7cef1f73bb8 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.20.0 + 7.21.0-SNAPSHOT 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index d9203b22102..6374aaf02b7 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index 7a648efa8e0..e3eb6b6ab54 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index 1b65abeb038..871d02725b3 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index 32cb046d64f..a406eef6283 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index d41733720a5..4a63513cfef 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index d6a0e3d93c2..da6a532f867 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-css/pom.xml b/pmd-css/pom.xml index 74a467c99b3..c6e752aa57e 100644 --- a/pmd-css/pom.xml +++ b/pmd-css/pom.xml @@ -9,7 +9,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index 0d2c6d35bcb..4b9b767b8c7 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index 1e099318361..2accf069004 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index 54c279f863f..55b39c22803 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index b85bed2d3bb..7479ccad085 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index 99fed7f2f2b..a5289fcca04 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index 8b0ad9f01f3..3d0f3fe3640 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index 39e821e6b5c..8a017aa951c 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index f6f8bf7aab9..e9bd7ff6848 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 8b9de470407..1477b53790d 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index 3e2dea69105..d849450686b 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index bc2b22c9518..2a3a9eaaca0 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index 2ba86404c51..0032a1ab343 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index 9ac847f470c..ab8b0ed00a3 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index 86eae2594f0..6bbeaf34d46 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index 78b1b5d5a68..0107bb78b37 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index 2302892df6b..3269c833aca 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index 50c429c1915..a27a1868753 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index 0d9effc73f8..7da4710fb79 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index 43d3921db90..0c58ebf7942 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index 5ca20068d38..f3eee8862d5 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index 4a0f0ff2412..265564d0eaa 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index b5fab5d81b6..58b59b54ab9 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index 3a35859ae60..89a8dd0c55c 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index 2e5079cc76f..7ac23063cec 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index fe99c728daf..181120786db 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index 4b17ca4379d..340f7a84cea 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index af9a4d44b48..7d70fd83587 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.20.0 + 7.21.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index 80a3e9c9778..ea5db6d7c3e 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.20.0 + 7.21.0-SNAPSHOT ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index 8afb5880e78..db54002f799 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index 35d59737c2f..1b5988497fc 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index afa7b920c22..942ed93cde2 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index f23d7b59508..185d6e4f89a 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index d9fee7a905a..69750f5b947 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index dd85f8b1206..c9d78ac0f91 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index f9f27ce25e1..9a5713ed1a5 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index 7a0193f201a..3c2de4df6a6 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.20.0 + 7.21.0-SNAPSHOT pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - pmd_releases/7.20.0 + HEAD PMD From 4b1061538281cbde516b5aa73832732cc2284367 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Jan 2026 09:19:19 +0100 Subject: [PATCH 1817/1962] chore(deps): bump ruby/setup-ruby from 1.275.0 to 1.277.0 (#6369) Bumps [ruby/setup-ruby](https://github.com/ruby/setup-ruby) from 1.275.0 to 1.277.0. - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/d354de180d0c9e813cfddfcbdc079945d4be589b...8a836efbcebe5de0fe86b48a775b7a31b5c70c93) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-version: 1.277.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 4 ++-- .github/workflows/publish-release.yml | 2 +- .github/workflows/publish-snapshot.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7338bf909d3..2aa0a3ba01a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -280,7 +280,7 @@ jobs: -Pgenerate-rule-docs,fastSkip \ -DskipTests -Dassembly.skipAssembly=true - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@d354de180d0c9e813cfddfcbdc079945d4be589b #v1.275.0 + uses: ruby/setup-ruby@8a836efbcebe5de0fe86b48a775b7a31b5c70c93 #v1.277.0 with: ruby-version: 3.3 - name: Setup bundler @@ -321,7 +321,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@d354de180d0c9e813cfddfcbdc079945d4be589b #v1.275.0 + uses: ruby/setup-ruby@8a836efbcebe5de0fe86b48a775b7a31b5c70c93 #v1.277.0 with: ruby-version: 3.3 - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb #v5.0.1 diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 1b8e09fa569..8b1c27badfc 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -632,7 +632,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@d354de180d0c9e813cfddfcbdc079945d4be589b #v1.275.0 + uses: ruby/setup-ruby@8a836efbcebe5de0fe86b48a775b7a31b5c70c93 #v1.277.0 with: ruby-version: 3.3 - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb #v5.0.1 diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index e8fb5835cc6..c2173de62f2 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -649,7 +649,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@d354de180d0c9e813cfddfcbdc079945d4be589b #v1.275.0 + uses: ruby/setup-ruby@8a836efbcebe5de0fe86b48a775b7a31b5c70c93 #v1.277.0 with: ruby-version: 3.3 - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb #v5.0.1 From 2599bcc7488652fab991d3deffbba12ecd881eed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Jan 2026 09:21:11 +0100 Subject: [PATCH 1818/1962] chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.18.2 to 1.18.3 (#6371) Bumps [net.bytebuddy:byte-buddy](https://github.com/raphw/byte-buddy) from 1.18.2 to 1.18.3. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.18.2...byte-buddy-1.18.3) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-version: 1.18.3 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3c2de4df6a6..c0479240af3 100644 --- a/pom.xml +++ b/pom.xml @@ -1042,7 +1042,7 @@ net.bytebuddy byte-buddy - 1.18.2 + 1.18.3 test From 29b894594981731e7d0ca17bd4e76de673242ed0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Jan 2026 09:26:36 +0100 Subject: [PATCH 1819/1962] chore(deps): bump org.apache.groovy:groovy from 5.0.2 to 5.0.3 (#6370) Bumps [org.apache.groovy:groovy](https://github.com/apache/groovy) from 5.0.2 to 5.0.3. - [Commits](https://github.com/apache/groovy/commits) --- updated-dependencies: - dependency-name: org.apache.groovy:groovy dependency-version: 5.0.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c0479240af3..6523990eb25 100644 --- a/pom.xml +++ b/pom.xml @@ -942,7 +942,7 @@ org.apache.groovy groovy - 5.0.2 + 5.0.3 com.google.code.gson From 4b7f76c160772be5bbbdb71be82ff3174472ff74 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Jan 2026 09:29:22 +0100 Subject: [PATCH 1820/1962] chore(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.6.2 to 3.6.3 (#6372) chore(deps): bump org.codehaus.mojo:exec-maven-plugin Bumps [org.codehaus.mojo:exec-maven-plugin](https://github.com/mojohaus/exec-maven-plugin) from 3.6.2 to 3.6.3. - [Release notes](https://github.com/mojohaus/exec-maven-plugin/releases) - [Commits](https://github.com/mojohaus/exec-maven-plugin/compare/3.6.2...3.6.3) --- updated-dependencies: - dependency-name: org.codehaus.mojo:exec-maven-plugin dependency-version: 3.6.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6523990eb25..8b6f1955bc1 100644 --- a/pom.xml +++ b/pom.xml @@ -387,7 +387,7 @@ org.codehaus.mojo exec-maven-plugin - 3.6.2 + 3.6.3 org.apache.maven.plugins From 6920a1006af4615a5dd079319cab7ba37fde05a4 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 5 Jan 2026 08:56:06 +0100 Subject: [PATCH 1821/1962] [java] Add new java language versions 26 and 26-preview --- docs/pages/pmd/languages/java.md | 6 +++-- docs/pages/pmd/userdocs/tools/ant.md | 4 ++-- .../pmd/dist/BinaryDistributionIT.java | 1 + .../pmd/lang/java/JavaLanguageModule.java | 7 ++++-- .../pmd/lang/java/JavaLanguageModuleTest.java | 4 ++-- .../pmd/lang/java/LanguageVersionTest.java | 4 +++- .../lang/java/ast/AllJavaAstTreeDumpTest.java | 4 +++- .../java/ast/Java26PreviewTreeDumpTest.java | 22 +++++++++++++++++++ .../pmd/lang/java/ast/Java26TreeDumpTest.java | 22 +++++++++++++++++++ .../pmd/lang/java/ast/KotlinTestingDsl.kt | 4 +++- 10 files changed, 67 insertions(+), 11 deletions(-) create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java26PreviewTreeDumpTest.java create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java26TreeDumpTest.java diff --git a/docs/pages/pmd/languages/java.md b/docs/pages/pmd/languages/java.md index f28c6ab184e..227a55ca537 100644 --- a/docs/pages/pmd/languages/java.md +++ b/docs/pages/pmd/languages/java.md @@ -2,7 +2,7 @@ title: Java support permalink: pmd_languages_java.html author: Clรฉment Fournier -last_updated: July 2025 (7.16.0) +last_updated: January 2026 (7.21.0) tags: [languages, PmdCapableLanguage, CpdCapableLanguage] summary: "Java-specific features and guidance" --- @@ -15,8 +15,10 @@ Usually the latest non-preview Java Version is the default version. | Java Version | Alias | Supported by PMD since | |--------------|-------|------------------------| +| 26-preview | | 7.21.0 | +| 26 (default) | | 7.21.0 | | 25-preview | | 7.16.0 | -| 25 (default) | | 7.16.0 | +| 25 | | 7.16.0 | | 24-preview | | 7.10.0 | | 24 | | 7.10.0 | | 23 | | 7.5.0 | diff --git a/docs/pages/pmd/userdocs/tools/ant.md b/docs/pages/pmd/userdocs/tools/ant.md index 007f23500f6..90d755966f0 100644 --- a/docs/pages/pmd/userdocs/tools/ant.md +++ b/docs/pages/pmd/userdocs/tools/ant.md @@ -6,7 +6,7 @@ author: > David Dixon-Peugh , Tom Copeland , Xavier Le Vourch -last_updated: July 2025 (7.16.0) +last_updated: January 2026 (7.21.0) --- ## PMD @@ -213,7 +213,7 @@ accordingly and this rule won't be executed. The specific version of a language to be used is selected via the `sourceLanguage` nested element. Example: - + The available versions depend on the language. You can get a list of the currently supported language versions via the CLI option `--help`. diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java b/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java index 6a3e7d7b3be..7826c03a837 100644 --- a/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java +++ b/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java @@ -56,6 +56,7 @@ class BinaryDistributionIT extends AbstractBinaryDistributionTest { "java-23", "java-24", "java-24-preview", "java-25", "java-25-preview", + "java-26", "java-26-preview", "java-5", "java-6", "java-7", "java-8", "java-9", "jsp-2", "jsp-3", "kotlin-1.6", "kotlin-1.7", "kotlin-1.8", "modelica-3.4", "modelica-3.5", diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java index 669f4dea7a8..8da50a12bd8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java @@ -47,8 +47,11 @@ public JavaLanguageModule() { .addVersion("23") .addVersion("24") .addVersion("24-preview") - .addDefaultVersion("25") // 25 is the default - .addVersion("25-preview")); + .addVersion("25") + .addVersion("25-preview") + .addDefaultVersion("26") // 26 is the default + .addVersion("26-preview") + ); } public static JavaLanguageModule getInstance() { diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaLanguageModuleTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaLanguageModuleTest.java index 3afe74e3962..d70dc034932 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaLanguageModuleTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/JavaLanguageModuleTest.java @@ -24,8 +24,8 @@ void java9IsSmallerThanJava10() { @Test void previewVersionShouldBeGreaterThanNonPreview() { - LanguageVersion java = JavaLanguageModule.getInstance().getVersion("25"); - LanguageVersion javaPreview = JavaLanguageModule.getInstance().getVersion("25-preview"); + LanguageVersion java = JavaLanguageModule.getInstance().getVersion("26"); + LanguageVersion javaPreview = JavaLanguageModule.getInstance().getVersion("26-preview"); assertTrue(javaPreview.compareTo(java) > 0, "java-preview should be greater than java"); } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionTest.java index 6eba98abf18..0dcdd212406 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionTest.java @@ -44,8 +44,10 @@ static Collection data() { new TestDescriptor(java, "24-preview"), new TestDescriptor(java, "25"), new TestDescriptor(java, "25-preview"), + new TestDescriptor(java, "26"), + new TestDescriptor(java, "26-preview"), - defaultVersionIs(java, "25"), + defaultVersionIs(java, "26"), // this one won't be found: case-sensitive! versionDoesNotExist("JAVA", "JAVA", "1.7"), diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AllJavaAstTreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AllJavaAstTreeDumpTest.java index 493f2524745..12355a8c781 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AllJavaAstTreeDumpTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AllJavaAstTreeDumpTest.java @@ -22,7 +22,9 @@ Java24TreeDumpTest.class, Java24PreviewTreeDumpTest.class, Java25TreeDumpTest.class, - Java25PreviewTreeDumpTest.class + Java25PreviewTreeDumpTest.class, + Java26TreeDumpTest.class, + Java26PreviewTreeDumpTest.class }) class AllJavaAstTreeDumpTest { diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java26PreviewTreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java26PreviewTreeDumpTest.java new file mode 100644 index 00000000000..3822606e5fd --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java26PreviewTreeDumpTest.java @@ -0,0 +1,22 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.ast; + +import net.sourceforge.pmd.lang.java.BaseJavaTreeDumpTest; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; +import net.sourceforge.pmd.lang.test.ast.BaseParsingHelper; + +class Java26PreviewTreeDumpTest extends BaseJavaTreeDumpTest { + private final JavaParsingHelper java26p = + JavaParsingHelper.DEFAULT.withDefaultVersion("26-preview") + .withResourceContext(Java26PreviewTreeDumpTest.class, "jdkversiontests/java26p/"); + private final JavaParsingHelper java26 = java26p.withDefaultVersion("26"); + + @Override + public BaseParsingHelper getParser() { + return java26p; + } + +} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java26TreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java26TreeDumpTest.java new file mode 100644 index 00000000000..d0045541d97 --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java26TreeDumpTest.java @@ -0,0 +1,22 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.ast; + +import net.sourceforge.pmd.lang.java.BaseJavaTreeDumpTest; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; +import net.sourceforge.pmd.lang.test.ast.BaseParsingHelper; + +class Java26TreeDumpTest extends BaseJavaTreeDumpTest { + private final JavaParsingHelper java26 = + JavaParsingHelper.DEFAULT.withDefaultVersion("26") + .withResourceContext(Java26TreeDumpTest.class, "jdkversiontests/java26/"); + + @Override + public BaseParsingHelper getParser() { + return java26; + } + + // Java 26 didn't finalize any new features, thus there are no tests +} diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt index 3a0de20f1d9..cd352ce00d7 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt @@ -42,7 +42,9 @@ enum class JavaVersion : Comparable { J22, J23, J24, J24__PREVIEW, - J25, J25__PREVIEW; + J25, J25__PREVIEW, + J26, J26__PREVIEW, + ; /** Name suitable for use with e.g. [JavaParsingHelper.parse] */ val pmdName: String = name.removePrefix("J").replaceFirst("__", "-").replace('_', '.').lowercase() From 9b4a3382f2822b8db544a3f32a7cc6e9e4bb9c90 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 5 Jan 2026 09:17:44 +0100 Subject: [PATCH 1822/1962] [java] Remove java language version 24-preview --- docs/pages/pmd/languages/java.md | 1 - .../pmd/dist/BinaryDistributionIT.java | 2 +- .../pmd/lang/java/JavaLanguageModule.java | 1 - .../pmd/lang/java/LanguageVersionTest.java | 1 - .../lang/java/ast/AllJavaAstTreeDumpTest.java | 1 - .../java/ast/Java24PreviewTreeDumpTest.java | 107 --- .../java/ast/ASTInstanceOfExpressionTest.kt | 4 +- .../pmd/lang/java/ast/KotlinTestingDsl.kt | 2 +- ...iveTypesInPatternsInstanceofAndSwitch.java | 173 ---- ...tiveTypesInPatternsInstanceofAndSwitch.txt | 742 ------------------ .../Jep492_FlexibleConstructorBodies.java | 98 --- .../Jep492_FlexibleConstructorBodies.txt | 318 -------- .../Jep494_ModuleImportDeclarations.java | 20 - .../Jep494_ModuleImportDeclarations.txt | 53 -- ...mpleSourceFilesAndInstanceMainMethods.java | 36 - ...impleSourceFilesAndInstanceMainMethods.txt | 109 --- 16 files changed, 4 insertions(+), 1664 deletions(-) delete mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java24PreviewTreeDumpTest.java delete mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.java delete mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt delete mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep492_FlexibleConstructorBodies.java delete mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep492_FlexibleConstructorBodies.txt delete mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep494_ModuleImportDeclarations.java delete mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep494_ModuleImportDeclarations.txt delete mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep495_SimpleSourceFilesAndInstanceMainMethods.java delete mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep495_SimpleSourceFilesAndInstanceMainMethods.txt diff --git a/docs/pages/pmd/languages/java.md b/docs/pages/pmd/languages/java.md index 227a55ca537..566e8d970fc 100644 --- a/docs/pages/pmd/languages/java.md +++ b/docs/pages/pmd/languages/java.md @@ -19,7 +19,6 @@ Usually the latest non-preview Java Version is the default version. | 26 (default) | | 7.21.0 | | 25-preview | | 7.16.0 | | 25 | | 7.16.0 | -| 24-preview | | 7.10.0 | | 24 | | 7.10.0 | | 23 | | 7.5.0 | | 22 | | 7.0.0 | diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java b/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java index 7826c03a837..ca98b1241df 100644 --- a/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java +++ b/pmd-dist/src/test/java/net/sourceforge/pmd/dist/BinaryDistributionIT.java @@ -54,7 +54,7 @@ class BinaryDistributionIT extends AbstractBinaryDistributionTest { "java-21", "java-22", "java-23", - "java-24", "java-24-preview", + "java-24", "java-25", "java-25-preview", "java-26", "java-26-preview", "java-5", "java-6", "java-7", diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java index 8da50a12bd8..d9417e0167b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java @@ -46,7 +46,6 @@ public JavaLanguageModule() { .addVersion("22") .addVersion("23") .addVersion("24") - .addVersion("24-preview") .addVersion("25") .addVersion("25-preview") .addDefaultVersion("26") // 26 is the default diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionTest.java index 0dcdd212406..a204b18bc10 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/LanguageVersionTest.java @@ -41,7 +41,6 @@ static Collection data() { new TestDescriptor(java, "22"), new TestDescriptor(java, "23"), new TestDescriptor(java, "24"), - new TestDescriptor(java, "24-preview"), new TestDescriptor(java, "25"), new TestDescriptor(java, "25-preview"), new TestDescriptor(java, "26"), diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AllJavaAstTreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AllJavaAstTreeDumpTest.java index 12355a8c781..d21bfb30879 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AllJavaAstTreeDumpTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/AllJavaAstTreeDumpTest.java @@ -20,7 +20,6 @@ Java22TreeDumpTest.class, Java23TreeDumpTest.class, Java24TreeDumpTest.class, - Java24PreviewTreeDumpTest.class, Java25TreeDumpTest.class, Java25PreviewTreeDumpTest.class, Java26TreeDumpTest.class, diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java24PreviewTreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java24PreviewTreeDumpTest.java deleted file mode 100644 index 87d1a78675f..00000000000 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java24PreviewTreeDumpTest.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.java.ast; - -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assumptions.assumeTrue; - -import java.util.List; - -import org.junit.jupiter.api.Test; - -import net.sourceforge.pmd.lang.ast.ParseException; -import net.sourceforge.pmd.lang.java.BaseJavaTreeDumpTest; -import net.sourceforge.pmd.lang.java.JavaParsingHelper; -import net.sourceforge.pmd.lang.java.types.OverloadSelectionResult; -import net.sourceforge.pmd.lang.java.types.TypeTestUtil; -import net.sourceforge.pmd.lang.test.ast.BaseParsingHelper; - -class Java24PreviewTreeDumpTest extends BaseJavaTreeDumpTest { - private final JavaParsingHelper java24p = - JavaParsingHelper.DEFAULT.withDefaultVersion("24-preview") - .withResourceContext(Java24PreviewTreeDumpTest.class, "jdkversiontests/java24p/"); - private final JavaParsingHelper java24 = java24p.withDefaultVersion("24"); - - @Override - public BaseParsingHelper getParser() { - return java24p; - } - - @Test - void jep488PrimitiveTypesInPatternsInstanceofAndSwitch() { - doTest("Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch"); - } - - @Test - void jep488PrimitiveTypesInPatternsInstanceofAndSwitchBeforeJava24Preview() { - ParseException thrown = assertThrows(ParseException.class, () -> java24.parseResource("Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.java")); - assertThat(thrown.getMessage(), containsString("Primitive types in patterns instanceof and switch is a preview feature of JDK 24, you should select your language version accordingly")); - } - - @Test - void jep492FlexibleConstructorBodies() { - doTest("Jep492_FlexibleConstructorBodies"); - } - - @Test - void jep492FlexibleConstructorBodiesBeforeJava24Preview() { - ParseException thrown = assertThrows(ParseException.class, () -> java24.parseResource("Jep492_FlexibleConstructorBodies.java")); - assertThat(thrown.getMessage(), containsString("Flexible constructor bodies was only standardized in Java 25, you should select your language version accordingly")); - } - - @Test - void jep494ModuleImportDeclarations() { - doTest("Jep494_ModuleImportDeclarations"); - } - - @Test - void jep494ModuleImportDeclarationsBeforeJava24Preview() { - ParseException thrown = assertThrows(ParseException.class, () -> java24.parseResource("Jep494_ModuleImportDeclarations.java")); - assertThat(thrown.getMessage(), containsString("Module import declarations was only standardized in Java 25, you should select your language version accordingly")); - } - - @Test - void jep495SimpleSourceFilesAndInstanceMainMethods() { - doTest("Jep495_SimpleSourceFilesAndInstanceMainMethods"); - } - - @Test - void jep495SimpleSourceFilesAndInstanceMainMethodsVerifyTypes() { - int javaVersion = Integer.parseInt(System.getProperty("java.version").split("\\.")[0].replaceAll("-ea", "")); - assumeTrue(javaVersion >= 23 && javaVersion < 25, "Java " + javaVersion + " doesn't support java.io.IO. Java 23 or Java 24 is needed for this test."); - - ASTCompilationUnit compilationUnit = java24p.parseResource("Jep495_SimpleSourceFilesAndInstanceMainMethods.java"); - assertTrue(compilationUnit.isCompact()); - - List methodCalls = compilationUnit.descendants(ASTMethodCall.class).toList(); - OverloadSelectionResult systemOutPrintln = methodCalls.get(4).getOverloadSelectionInfo(); // System.out.println - assertFalse(systemOutPrintln.isFailed()); - TypeTestUtil.isA("java.io.PrintStream", systemOutPrintln.getMethodType().getDeclaringType()); - - ASTVariableDeclarator authorsVar = compilationUnit.descendants(ASTVariableDeclarator.class).filter(decl -> "authors".equals(decl.getName())).first(); - assertInstanceOf(ASTMethodCall.class, authorsVar.getInitializer()); - ASTMethodCall initializer = (ASTMethodCall) authorsVar.getInitializer(); - assertEquals("of", initializer.getMethodName()); - assertInstanceOf(ASTTypeExpression.class, initializer.getQualifier()); - ASTTypeExpression qualifier = (ASTTypeExpression) initializer.getQualifier(); - TypeTestUtil.isA("java.util.List", qualifier.getTypeNode().getTypeMirror()); - - OverloadSelectionResult javaIoPrintln = methodCalls.get(5).getOverloadSelectionInfo(); // println from java.io.IO - assertFalse(javaIoPrintln.isFailed()); - TypeTestUtil.isA("java.io.IO", javaIoPrintln.getMethodType().getDeclaringType()); - } - - @Test - void jep495SimpleSourceFilesAndInstanceMainMethodsBeforeJava24Preview() { - ParseException thrown = assertThrows(ParseException.class, () -> java24.parseResource("Jep495_SimpleSourceFilesAndInstanceMainMethods.java")); - assertThat(thrown.getMessage(), containsString("Compact source files and instance main methods was only standardized in Java 25, you should select your language version accordingly")); - } -} diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTInstanceOfExpressionTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTInstanceOfExpressionTest.kt index 8cb1f86868e..6aaa76aae15 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTInstanceOfExpressionTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTInstanceOfExpressionTest.kt @@ -48,7 +48,7 @@ class ASTInstanceOfExpressionTest : ParserTestSpec({ } } - parserTestContainer("InstanceofExpression cannot test primitive types", JavaVersion.except(JavaVersion.J24__PREVIEW, JavaVersion.J25__PREVIEW)) { + parserTestContainer("InstanceofExpression cannot test primitive types", JavaVersion.except(JavaVersion.J25__PREVIEW, JavaVersion.J25__PREVIEW)) { inContext(ExpressionParsingCtx) { PrimitiveTypeKind.values().map { it.simpleName }.forEach { "f instanceof $it" shouldNot parse() @@ -60,7 +60,7 @@ class ASTInstanceOfExpressionTest : ParserTestSpec({ // since Java 23 Preview, primitive types in instanceof are possible (JEP 455) // Java 24 Preview: JEP 488 // Java 25 Preview: JEP 507 - parserTestContainer("InstanceofExpression can test primitive types", listOf(JavaVersion.J24__PREVIEW, JavaVersion.J25__PREVIEW)) { + parserTestContainer("InstanceofExpression can test primitive types", listOf(JavaVersion.J25__PREVIEW, JavaVersion.J25__PREVIEW)) { inContext(ExpressionParsingCtx) { PrimitiveTypeKind.values().forEach { typeKind -> "f instanceof ${typeKind.simpleName}" should parseAs { diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt index cd352ce00d7..fc790e5ddbd 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt @@ -41,7 +41,7 @@ enum class JavaVersion : Comparable { J21, J22, J23, - J24, J24__PREVIEW, + J24, J25, J25__PREVIEW, J26, J26__PREVIEW, ; diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.java deleted file mode 100644 index c85850e3057..00000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -import java.util.Map; - -/** - * @see JEP 488: Primitive Types in Patterns, instanceof, and switch (Second Preview) (Java 24) - */ -public class Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch { - - void switchWithPrimitiveTypePatterns() { - class X { - int getStatus() { return 0; } - int getYearlyFlights() { return 1; } - void noop() {} - void issueDiscount() {} - void issueGoldCard() {} - } - X x = new X(); - - String status = switch (x.getStatus()) { - case 0 -> "okay"; - case 1 -> "warning"; - case 2 -> "error"; - case int i -> "unknown status: " + i; - }; - System.out.println("status: " + status); - - switch (x.getYearlyFlights()) { - case 0 -> x.noop(); - case 1 -> x.noop(); - case 2 -> x.issueDiscount(); - case int i when i >= 100 -> x.issueGoldCard(); - case int i -> x.issueDiscount(); // ... appropriate action when i > 2 && i < 100 ... - } - } - - sealed interface JsonValue {} - record JsonString(String s) implements JsonValue { } - record JsonNumber(double d) implements JsonValue { } - record JsonObject(Map map) implements JsonValue { } - void recordPatternsWithPrimitiveTypes() { - var json = new JsonObject(Map.of("name", new JsonString("John"), - "age", new JsonNumber(30))); - - if (json instanceof JsonObject(var map) - && map.get("name") instanceof JsonString(String n) - && map.get("age") instanceof JsonNumber(int a)) { - int age = a; - System.out.printf("Name: %s Age: %d%n", n, age); - } - } - - void patternMatchingForInstanceofWithPrimitiveTypes() { - class X { - int getPopulation() { return 0; } - } - - X x = new X(); - if (x.getPopulation() instanceof float pop) { - System.out.println("pop: " + pop); - } - int i = x.getPopulation(); - if (i instanceof byte b) { - System.out.println("byte: " + b); - } - if (i instanceof byte) { // value of i fits in a byte - byte b = (byte)i; // traditional cast required - System.out.println("byte: ... " + b); - } - } - - void expandedPrimitiveSupportInSwitch() { - class User { - boolean isLoggedIn() { return false; } - int id() { return 42; } - } - User user = new User(); - int userId = switch(user.isLoggedIn()) { - case true -> user.id(); - case false -> { System.out.println("Unrecognized user"); yield - 1; } - }; - - long v = 12345L; - switch(v) { - case 1L -> System.out.println("1L"); - case 2L -> System.out.println("2L"); - case 10_000_000_000L -> System.out.println("10x"); - case 20_000_000_000L -> System.out.println("20x"); - case long x -> System.out.println("... " + x + " ..."); - } - - float fv = 1.2f; - fv = switch (fv) { - case 0f -> 5f; - case float x when x == 1f -> 6f + x; - case float x -> 7f + x; - }; - - double dd = 1.2; - dd = switch (dd) { - case 0d -> 5; - case double d when d == 2 -> 6 + d; - case double d -> 8 + d; - }; - } - - void instanceofPrecondition() { - { - byte b = 42; - assert b instanceof int; // true (unconditionally exact) - } - - { - int i = 42; - assert i instanceof byte; // true (exact) - } - - { - int i = 1000; - assert !(i instanceof byte); // false (not exact) - } - - { - int i = 16_777_217; // 2^24 + 1 - assert !(i instanceof float); // false (not exact) - assert i instanceof double; // true (unconditionally exact) - assert i instanceof Integer; // true (unconditionally exact) - assert i instanceof Number; // true (unconditionally exact) - } - - { - float f = 1000.0f; - assert !(f instanceof byte); // false - assert f instanceof int; // true (exact) - assert f instanceof double; // true (unconditionally exact) - } - - { - double d = 1000.0d; - assert !(d instanceof byte); // false - assert d instanceof int; // true (exact) - assert d instanceof float; // true (exact) - } - - { - Integer ii = 1000; - assert ii instanceof int; // true (exact) - assert ii instanceof float; // true (exact) - assert ii instanceof double; // true (exact) - } - - { - Integer ii = 16_777_217; - assert !(ii instanceof float); // false (not exact) - assert ii instanceof double; // true (exact) - } - } - - void primitivePatternInSwitch() { - // Applicability - int i = 1; - switch (i) { - case double d -> System.out.println("double: " + d); - } - - Byte b = 1; - switch (b) { // exhaustive switch - case int p -> System.out.println("p: " + p); - } - } -} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt deleted file mode 100644 index 3dc573dc379..00000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.txt +++ /dev/null @@ -1,742 +0,0 @@ -+- CompilationUnit[@Compact = false, @PackageName = ""] - +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.Map", @ImportedSimpleName = "Map", @ModuleImport = false, @PackageName = "java.util", @Static = false] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch", @CanonicalName = "Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] - +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - +- ClassBody[@Empty = false, @Size = 10] - +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "switchWithPrimitiveTypePatterns", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- VoidType[] - | +- FormalParameters[@Empty = true, @Size = 0] - | +- Block[@Empty = false, @Size = 5, @containsComment = false] - | +- LocalClassStatement[] - | | +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch$1X", @CanonicalName = null, @EffectiveVisibility = Visibility.V_LOCAL, @Enum = false, @Final = false, @Interface = false, @Local = true, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "X", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- ClassBody[@Empty = false, @Size = 5] - | | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Name = "getStatus", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = false] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | | +- FormalParameters[@Empty = true, @Size = 0] - | | | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | | | +- ReturnStatement[] - | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] - | | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Name = "getYearlyFlights", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = false] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | | +- FormalParameters[@Empty = true, @Size = 0] - | | | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | | | +- ReturnStatement[] - | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] - | | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Name = "noop", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- VoidType[] - | | | +- FormalParameters[@Empty = true, @Size = 0] - | | | +- Block[@Empty = true, @Size = 0, @containsComment = false] - | | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Name = "issueDiscount", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- VoidType[] - | | | +- FormalParameters[@Empty = true, @Size = 0] - | | | +- Block[@Empty = true, @Size = 0, @containsComment = false] - | | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Name = "issueGoldCard", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- VoidType[] - | | +- FormalParameters[@Empty = true, @Size = 0] - | | +- Block[@Empty = true, @Size = 0, @containsComment = false] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "X"] - | | +- VariableDeclarator[@Initializer = true, @Name = "x"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "X"] - | | +- ArgumentList[@Empty = true, @Size = 0] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] - | | +- VariableDeclarator[@Initializer = true, @Name = "status"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "status", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "getStatus", @MethodName = "getStatus", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ArgumentList[@Empty = true, @Size = 0] - | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] - | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] - | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "okay", @Empty = false, @Image = "\"okay\"", @Length = 4, @LiteralText = "\"okay\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] - | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] - | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "warning", @Empty = false, @Image = "\"warning\"", @Length = 7, @LiteralText = "\"warning\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] - | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2", @IntLiteral = true, @Integral = true, @LiteralText = "2", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] - | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "error", @Empty = false, @Image = "\"error\"", @Length = 5, @LiteralText = "\"error\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] - | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "i", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "unknown status: ", @Empty = false, @Image = "\"unknown status: \"", @Length = 16, @LiteralText = "\"unknown status: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "status: ", @Empty = false, @Image = "\"status: \"", @Length = 8, @LiteralText = "\"status: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "status", @Name = "status", @ParenthesisDepth = 0, @Parenthesized = false] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] - | +- MethodCall[@CompileTimeConstant = false, @Image = "getYearlyFlights", @MethodName = "getYearlyFlights", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ArgumentList[@Empty = true, @Size = 0] - | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] - | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "noop", @MethodName = "noop", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ArgumentList[@Empty = true, @Size = 0] - | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] - | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "noop", @MethodName = "noop", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ArgumentList[@Empty = true, @Size = 0] - | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] - | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2", @IntLiteral = true, @Integral = true, @LiteralText = "2", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "issueDiscount", @MethodName = "issueDiscount", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ArgumentList[@Empty = true, @Size = 0] - | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] - | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "i", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | | +- Guard[] - | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.GE, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "100", @IntLiteral = true, @Integral = true, @LiteralText = "100", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 100.0, @ValueAsFloat = 100.0, @ValueAsInt = 100, @ValueAsLong = 100] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "issueGoldCard", @MethodName = "issueGoldCard", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ArgumentList[@Empty = true, @Size = 0] - | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] - | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "i", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- MethodCall[@CompileTimeConstant = false, @Image = "issueDiscount", @MethodName = "issueDiscount", @ParenthesisDepth = 0, @Parenthesized = false] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ArgumentList[@Empty = true, @Size = 0] - +- ClassDeclaration[@Abstract = true, @Annotation = false, @Anonymous = false, @BinaryName = "Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch$JsonValue", @CanonicalName = "Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.JsonValue", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = true, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = true, @SimpleName = "JsonValue", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (JModifier.ABSTRACT, JModifier.STATIC, JModifier.SEALED), @ExplicitModifiers = (JModifier.SEALED)] - | +- ClassBody[@Empty = true, @Size = 0] - +- RecordDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch$JsonString", @CanonicalName = "Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.JsonString", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = true, @RegularClass = false, @RegularInterface = false, @SimpleName = "JsonString", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = ()] - | +- RecordComponentList[@Empty = false, @Size = 1, @Varargs = false] - | | +- RecordComponent[@EffectiveVisibility = Visibility.V_PRIVATE, @Varargs = false, @Visibility = Visibility.V_PRIVATE] - | | +- ModifierList[@EffectiveModifiers = (JModifier.PRIVATE, JModifier.FINAL), @ExplicitModifiers = ()] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PRIVATE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = false, @RecordComponent = true, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PRIVATE] - | +- ImplementsList[@Empty = false, @Size = 1] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonValue"] - | +- RecordBody[@Empty = true, @Size = 0] - +- RecordDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch$JsonNumber", @CanonicalName = "Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.JsonNumber", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = true, @RegularClass = false, @RegularInterface = false, @SimpleName = "JsonNumber", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = ()] - | +- RecordComponentList[@Empty = false, @Size = 1, @Varargs = false] - | | +- RecordComponent[@EffectiveVisibility = Visibility.V_PRIVATE, @Varargs = false, @Visibility = Visibility.V_PRIVATE] - | | +- ModifierList[@EffectiveModifiers = (JModifier.PRIVATE, JModifier.FINAL), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PRIVATE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "d", @PatternBinding = false, @RecordComponent = true, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PRIVATE] - | +- ImplementsList[@Empty = false, @Size = 1] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonValue"] - | +- RecordBody[@Empty = true, @Size = 0] - +- RecordDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch$JsonObject", @CanonicalName = "Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch.JsonObject", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = true, @RegularClass = false, @RegularInterface = false, @SimpleName = "JsonObject", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = ()] - | +- RecordComponentList[@Empty = false, @Size = 1, @Varargs = false] - | | +- RecordComponent[@EffectiveVisibility = Visibility.V_PRIVATE, @Varargs = false, @Visibility = Visibility.V_PRIVATE] - | | +- ModifierList[@EffectiveModifiers = (JModifier.PRIVATE, JModifier.FINAL), @ExplicitModifiers = ()] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Map"] - | | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 2] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonValue"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PRIVATE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "map", @PatternBinding = false, @RecordComponent = true, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PRIVATE] - | +- ImplementsList[@Empty = false, @Size = 1] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonValue"] - | +- RecordBody[@Empty = true, @Size = 0] - +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "recordPatternsWithPrimitiveTypes", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- VoidType[] - | +- FormalParameters[@Empty = true, @Size = 0] - | +- Block[@Empty = false, @Size = 2, @containsComment = false] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = true, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- VariableDeclarator[@Initializer = true, @Name = "json"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "json", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonObject"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "of", @MethodName = "of", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Map"] - | | +- ArgumentList[@Empty = false, @Size = 4] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "name", @Empty = false, @Image = "\"name\"", @Length = 4, @LiteralText = "\"name\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonString"] - | | | +- ArgumentList[@Empty = false, @Size = 1] - | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "John", @Empty = false, @Image = "\"John\"", @Length = 4, @LiteralText = "\"John\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "age", @Empty = false, @Image = "\"age\"", @Length = 3, @LiteralText = "\"age\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonNumber"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "30", @IntLiteral = true, @Integral = true, @LiteralText = "30", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 30.0, @ValueAsFloat = 30.0, @ValueAsInt = 30, @ValueAsLong = 30] - | +- IfStatement[@Else = false] - | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.CONDITIONAL_AND, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.CONDITIONAL_AND, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "json", @Name = "json", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- RecordPattern[] - | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonObject"] - | | | | +- PatternList[@Empty = false, @Size = 1] - | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "map", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- MethodCall[@CompileTimeConstant = false, @Image = "get", @MethodName = "get", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "map", @Name = "map", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- ArgumentList[@Empty = false, @Size = 1] - | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "name", @Empty = false, @Image = "\"name\"", @Length = 4, @LiteralText = "\"name\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | | +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- RecordPattern[] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonString"] - | | | +- PatternList[@Empty = false, @Size = 1] - | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] - | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "n", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "get", @MethodName = "get", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "map", @Name = "map", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ArgumentList[@Empty = false, @Size = 1] - | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "age", @Empty = false, @Image = "\"age\"", @Length = 3, @LiteralText = "\"age\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- RecordPattern[] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonNumber"] - | | +- PatternList[@Empty = false, @Size = 1] - | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "a", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- Block[@Empty = false, @Size = 2, @containsComment = false] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- VariableDeclarator[@Initializer = true, @Name = "age"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "age", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "a", @Name = "a", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ExpressionStatement[] - | +- MethodCall[@CompileTimeConstant = false, @Image = "printf", @MethodName = "printf", @ParenthesisDepth = 0, @Parenthesized = false] - | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | +- ArgumentList[@Empty = false, @Size = 3] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Name: %s Age: %d%n", @Empty = false, @Image = "\"Name: %s Age: %d%n\"", @Length = 18, @LiteralText = "\"Name: %s Age: %d%n\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "n", @Name = "n", @ParenthesisDepth = 0, @Parenthesized = false] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "age", @Name = "age", @ParenthesisDepth = 0, @Parenthesized = false] - +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "patternMatchingForInstanceofWithPrimitiveTypes", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- VoidType[] - | +- FormalParameters[@Empty = true, @Size = 0] - | +- Block[@Empty = false, @Size = 6, @containsComment = false] - | +- LocalClassStatement[] - | | +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch$2X", @CanonicalName = null, @EffectiveVisibility = Visibility.V_LOCAL, @Enum = false, @Final = false, @Interface = false, @Local = true, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "X", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- ClassBody[@Empty = false, @Size = 1] - | | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Name = "getPopulation", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = false] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- FormalParameters[@Empty = true, @Size = 0] - | | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | | +- ReturnStatement[] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "X"] - | | +- VariableDeclarator[@Initializer = true, @Name = "x"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "X"] - | | +- ArgumentList[@Empty = true, @Size = 0] - | +- IfStatement[@Else = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- MethodCall[@CompileTimeConstant = false, @Image = "getPopulation", @MethodName = "getPopulation", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- ArgumentList[@Empty = true, @Size = 0] - | | | +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] - | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "pop", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "pop: ", @Empty = false, @Image = "\"pop: \"", @Length = 5, @LiteralText = "\"pop: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "pop", @Name = "pop", @ParenthesisDepth = 0, @Parenthesized = false] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- VariableDeclarator[@Initializer = true, @Name = "i"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "getPopulation", @MethodName = "getPopulation", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ArgumentList[@Empty = true, @Size = 0] - | +- IfStatement[@Else = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] - | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "b", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "byte: ", @Empty = false, @Image = "\"byte: \"", @Length = 6, @LiteralText = "\"byte: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] - | +- IfStatement[@Else = false] - | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] - | +- Block[@Empty = false, @Size = 2, @containsComment = false] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] - | | +- VariableDeclarator[@Initializer = true, @Name = "b"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "b", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- CastExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ExpressionStatement[] - | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "byte: ... ", @Empty = false, @Image = "\"byte: ... \"", @Length = 10, @LiteralText = "\"byte: ... \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] - +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "expandedPrimitiveSupportInSwitch", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- VoidType[] - | +- FormalParameters[@Empty = true, @Size = 0] - | +- Block[@Empty = false, @Size = 9, @containsComment = false] - | +- LocalClassStatement[] - | | +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep488_PrimitiveTypesInPatternsInstanceofAndSwitch$1User", @CanonicalName = null, @EffectiveVisibility = Visibility.V_LOCAL, @Enum = false, @Final = false, @Interface = false, @Local = true, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "User", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- ClassBody[@Empty = false, @Size = 2] - | | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Name = "isLoggedIn", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = false] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BOOLEAN] - | | | +- FormalParameters[@Empty = true, @Size = 0] - | | | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | | | +- ReturnStatement[] - | | | +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "false", @ParenthesisDepth = 0, @Parenthesized = false, @True = false] - | | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Name = "id", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = false] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- FormalParameters[@Empty = true, @Size = 0] - | | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | | +- ReturnStatement[] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "42", @IntLiteral = true, @Integral = true, @LiteralText = "42", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 42.0, @ValueAsFloat = 42.0, @ValueAsInt = 42, @ValueAsLong = 42] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "User"] - | | +- VariableDeclarator[@Initializer = true, @Name = "user"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "user", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "User"] - | | +- ArgumentList[@Empty = true, @Size = 0] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- VariableDeclarator[@Initializer = true, @Name = "userId"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "userId", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "isLoggedIn", @MethodName = "isLoggedIn", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "user", @Name = "user", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ArgumentList[@Empty = true, @Size = 0] - | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] - | | | | +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "true", @ParenthesisDepth = 0, @Parenthesized = false, @True = true] - | | | +- MethodCall[@CompileTimeConstant = false, @Image = "id", @MethodName = "id", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "user", @Name = "user", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ArgumentList[@Empty = true, @Size = 0] - | | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] - | | | +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "false", @ParenthesisDepth = 0, @Parenthesized = false, @True = false] - | | +- Block[@Empty = false, @Size = 2, @containsComment = false] - | | +- ExpressionStatement[] - | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | | +- ArgumentList[@Empty = false, @Size = 1] - | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Unrecognized user", @Empty = false, @Image = "\"Unrecognized user\"", @Length = 17, @LiteralText = "\"Unrecognized user\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- YieldStatement[] - | | +- UnaryExpression[@CompileTimeConstant = true, @Operator = UnaryOp.UNARY_MINUS, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.LONG] - | | +- VariableDeclarator[@Initializer = true, @Name = "v"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "v", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "12345L", @IntLiteral = false, @Integral = true, @LiteralText = "12345L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 12345.0, @ValueAsFloat = 12345.0, @ValueAsInt = 12345, @ValueAsLong = 12345] - | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "v", @Name = "v", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] - | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1L", @IntLiteral = false, @Integral = true, @LiteralText = "1L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] - | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | | +- ArgumentList[@Empty = false, @Size = 1] - | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "1L", @Empty = false, @Image = "\"1L\"", @Length = 2, @LiteralText = "\"1L\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] - | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2L", @IntLiteral = false, @Integral = true, @LiteralText = "2L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] - | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | | +- ArgumentList[@Empty = false, @Size = 1] - | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "2L", @Empty = false, @Image = "\"2L\"", @Length = 2, @LiteralText = "\"2L\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] - | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "10_000_000_000L", @IntLiteral = false, @Integral = true, @LiteralText = "10_000_000_000L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0E10, @ValueAsFloat = 1.0E10, @ValueAsInt = 1410065408, @ValueAsLong = 10000000000] - | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | | +- ArgumentList[@Empty = false, @Size = 1] - | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "10x", @Empty = false, @Image = "\"10x\"", @Length = 3, @LiteralText = "\"10x\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] - | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "20_000_000_000L", @IntLiteral = false, @Integral = true, @LiteralText = "20_000_000_000L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0E10, @ValueAsFloat = 2.0E10, @ValueAsInt = -1474836480, @ValueAsLong = 20000000000] - | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | | +- ArgumentList[@Empty = false, @Size = 1] - | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "20x", @Empty = false, @Image = "\"20x\"", @Length = 3, @LiteralText = "\"20x\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] - | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.LONG] - | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "... ", @Empty = false, @Image = "\"... \"", @Length = 4, @LiteralText = "\"... \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = " ...", @Empty = false, @Image = "\" ...\"", @Length = 4, @LiteralText = "\" ...\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] - | | +- VariableDeclarator[@Initializer = true, @Name = "fv"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "fv", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "1.2f", @IntLiteral = false, @Integral = false, @LiteralText = "1.2f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.2, @ValueAsFloat = 1.2, @ValueAsInt = 1, @ValueAsLong = 1] - | +- ExpressionStatement[] - | | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "fv", @Name = "fv", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "fv", @Name = "fv", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] - | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "0f", @IntLiteral = false, @Integral = false, @LiteralText = "0f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] - | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "5f", @IntLiteral = false, @Integral = false, @LiteralText = "5f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 5.0, @ValueAsFloat = 5.0, @ValueAsInt = 5, @ValueAsLong = 5] - | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] - | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] - | | | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | | | +- Guard[] - | | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.EQ, @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "1f", @IntLiteral = false, @Integral = false, @LiteralText = "1f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] - | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "6f", @IntLiteral = false, @Integral = false, @LiteralText = "6f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 6.0, @ValueAsFloat = 6.0, @ValueAsInt = 6, @ValueAsLong = 6] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] - | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] - | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "7f", @IntLiteral = false, @Integral = false, @LiteralText = "7f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 7.0, @ValueAsFloat = 7.0, @ValueAsInt = 7, @ValueAsLong = 7] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] - | | +- VariableDeclarator[@Initializer = true, @Name = "dd"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "dd", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = true, @FloatLiteral = false, @Image = "1.2", @IntLiteral = false, @Integral = false, @LiteralText = "1.2", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.2, @ValueAsFloat = 1.2, @ValueAsInt = 1, @ValueAsLong = 1] - | +- ExpressionStatement[] - | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] - | +- VariableAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "dd", @Name = "dd", @ParenthesisDepth = 0, @Parenthesized = false] - | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "dd", @Name = "dd", @ParenthesisDepth = 0, @Parenthesized = false] - | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] - | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = true, @FloatLiteral = false, @Image = "0d", @IntLiteral = false, @Integral = false, @LiteralText = "0d", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "5", @IntLiteral = true, @Integral = true, @LiteralText = "5", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 5.0, @ValueAsFloat = 5.0, @ValueAsInt = 5, @ValueAsLong = 5] - | +- SwitchArrowBranch[@Default = false] - | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] - | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] - | | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "d", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | | +- Guard[] - | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.EQ, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2", @IntLiteral = true, @Integral = true, @LiteralText = "2", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "6", @IntLiteral = true, @Integral = true, @LiteralText = "6", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 6.0, @ValueAsFloat = 6.0, @ValueAsInt = 6, @ValueAsLong = 6] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] - | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] - | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "d", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "8", @IntLiteral = true, @Integral = true, @LiteralText = "8", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 8.0, @ValueAsFloat = 8.0, @ValueAsInt = 8, @ValueAsLong = 8] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] - +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "instanceofPrecondition", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- VoidType[] - | +- FormalParameters[@Empty = true, @Size = 0] - | +- Block[@Empty = false, @Size = 8, @containsComment = false] - | +- Block[@Empty = false, @Size = 2, @containsComment = true] - | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] - | | | +- VariableDeclarator[@Initializer = true, @Name = "b"] - | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "b", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "42", @IntLiteral = true, @Integral = true, @LiteralText = "42", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 42.0, @ValueAsFloat = 42.0, @ValueAsInt = 42, @ValueAsLong = 42] - | | +- AssertStatement[@DetailMessage = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | +- Block[@Empty = false, @Size = 2, @containsComment = true] - | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | | +- VariableDeclarator[@Initializer = true, @Name = "i"] - | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "42", @IntLiteral = true, @Integral = true, @LiteralText = "42", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 42.0, @ValueAsFloat = 42.0, @ValueAsInt = 42, @ValueAsLong = 42] - | | +- AssertStatement[@DetailMessage = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] - | +- Block[@Empty = false, @Size = 2, @containsComment = true] - | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | | +- VariableDeclarator[@Initializer = true, @Name = "i"] - | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1000", @IntLiteral = true, @Integral = true, @LiteralText = "1000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1000.0, @ValueAsFloat = 1000.0, @ValueAsInt = 1000, @ValueAsLong = 1000] - | | +- AssertStatement[@DetailMessage = false] - | | +- UnaryExpression[@CompileTimeConstant = false, @Operator = UnaryOp.NEGATION, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] - | +- Block[@Empty = false, @Size = 5, @containsComment = true] - | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | | +- VariableDeclarator[@Initializer = true, @Name = "i"] - | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "16_777_217", @IntLiteral = true, @Integral = true, @LiteralText = "16_777_217", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.6777217E7, @ValueAsFloat = 1.6777216E7, @ValueAsInt = 16777217, @ValueAsLong = 16777217] - | | +- AssertStatement[@DetailMessage = false] - | | | +- UnaryExpression[@CompileTimeConstant = false, @Operator = UnaryOp.NEGATION, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] - | | +- AssertStatement[@DetailMessage = false] - | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] - | | +- AssertStatement[@DetailMessage = false] - | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] - | | +- AssertStatement[@DetailMessage = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Number"] - | +- Block[@Empty = false, @Size = 4, @containsComment = true] - | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] - | | | +- VariableDeclarator[@Initializer = true, @Name = "f"] - | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "f", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "1000.0f", @IntLiteral = false, @Integral = false, @LiteralText = "1000.0f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1000.0, @ValueAsFloat = 1000.0, @ValueAsInt = 1000, @ValueAsLong = 1000] - | | +- AssertStatement[@DetailMessage = false] - | | | +- UnaryExpression[@CompileTimeConstant = false, @Operator = UnaryOp.NEGATION, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "f", @Name = "f", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] - | | +- AssertStatement[@DetailMessage = false] - | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "f", @Name = "f", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- AssertStatement[@DetailMessage = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "f", @Name = "f", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] - | +- Block[@Empty = false, @Size = 4, @containsComment = true] - | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] - | | | +- VariableDeclarator[@Initializer = true, @Name = "d"] - | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "d", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = true, @FloatLiteral = false, @Image = "1000.0d", @IntLiteral = false, @Integral = false, @LiteralText = "1000.0d", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1000.0, @ValueAsFloat = 1000.0, @ValueAsInt = 1000, @ValueAsLong = 1000] - | | +- AssertStatement[@DetailMessage = false] - | | | +- UnaryExpression[@CompileTimeConstant = false, @Operator = UnaryOp.NEGATION, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] - | | +- AssertStatement[@DetailMessage = false] - | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- AssertStatement[@DetailMessage = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] - | +- Block[@Empty = false, @Size = 4, @containsComment = true] - | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] - | | | +- VariableDeclarator[@Initializer = true, @Name = "ii"] - | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "ii", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1000", @IntLiteral = true, @Integral = true, @LiteralText = "1000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1000.0, @ValueAsFloat = 1000.0, @ValueAsInt = 1000, @ValueAsLong = 1000] - | | +- AssertStatement[@DetailMessage = false] - | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "ii", @Name = "ii", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- AssertStatement[@DetailMessage = false] - | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "ii", @Name = "ii", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] - | | +- AssertStatement[@DetailMessage = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "ii", @Name = "ii", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] - | +- Block[@Empty = false, @Size = 3, @containsComment = true] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] - | | +- VariableDeclarator[@Initializer = true, @Name = "ii"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "ii", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "16_777_217", @IntLiteral = true, @Integral = true, @LiteralText = "16_777_217", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.6777217E7, @ValueAsFloat = 1.6777216E7, @ValueAsInt = 16777217, @ValueAsLong = 16777217] - | +- AssertStatement[@DetailMessage = false] - | | +- UnaryExpression[@CompileTimeConstant = false, @Operator = UnaryOp.NEGATION, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "ii", @Name = "ii", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] - | +- AssertStatement[@DetailMessage = false] - | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "ii", @Name = "ii", @ParenthesisDepth = 0, @Parenthesized = false] - | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] - +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "primitivePatternInSwitch", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] - +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - +- VoidType[] - +- FormalParameters[@Empty = true, @Size = 0] - +- Block[@Empty = false, @Size = 4, @containsComment = false] - +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | +- VariableDeclarator[@Initializer = true, @Name = "i"] - | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] - +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] - | +- SwitchArrowBranch[@Default = false] - | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] - | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "d", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "double: ", @Empty = false, @Image = "\"double: \"", @Length = 8, @LiteralText = "\"double: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] - +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Byte"] - | +- VariableDeclarator[@Initializer = true, @Name = "b"] - | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "b", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] - +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] - +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] - +- SwitchArrowBranch[@Default = false] - +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] - | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "p", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - +- ArgumentList[@Empty = false, @Size = 1] - +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "p: ", @Empty = false, @Image = "\"p: \"", @Length = 3, @LiteralText = "\"p: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "p", @Name = "p", @ParenthesisDepth = 0, @Parenthesized = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep492_FlexibleConstructorBodies.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep492_FlexibleConstructorBodies.java deleted file mode 100644 index f6e7727161f..00000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep492_FlexibleConstructorBodies.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -import java.math.BigInteger; -import java.security.cert.Certificate; -import java.security.interfaces.DSAPublicKey; -import java.security.interfaces.RSAKey; - -/** - * @see JEP 492: Flexible Constructor Bodies (Third Preview) (Java 24) - */ -public class Jep492_FlexibleConstructorBodies { - - // Example: Validating superclass constructor arguments - public class PositiveBigInteger extends BigInteger { - public PositiveBigInteger(long value) { - if (value <= 0) throw new IllegalArgumentException("value must be positive"); - super(String.valueOf(value)); - } - } - - // Example: Preparing superclass constructor arguments - public class Super { - public Super(byte[] bytes) {} - } - public class Sub extends Super { - public Sub(Certificate certificate) { - var publicKey = certificate.getPublicKey(); - if (publicKey == null) throw new NullPointerException(); - byte[] certBytes = switch (publicKey) { - case RSAKey rsaKey -> rsaKey.getModulus().toByteArray(); - case DSAPublicKey dsaKey -> dsaKey.getY().toByteArray(); - default -> new byte[0]; - }; - super(certBytes); - } - } - - // Example: Sharing superclass constructor arguments - public class C { - private final int i; - public C(int i) { - this.i = i; - } - } - public class Super2 { - private final C x; - private final C y; - public Super2(C x, C y) { - this.x = x; - this.y = y; - } - } - public class Sub2 extends Super2 { - public Sub2(int i) { - var x = new C(i); - super(x, x); - } - } - - // Using enclosing instances in early construction contexts - class Outer { - int i; - void hello() { System.out.println("Hello"); } - - class Inner { - int j; - - Inner() { - var x = i; // OK - implicitly refers to field of enclosing instance - var y = Outer.this.i; // OK - explicitly refers to field of enclosing instance - hello(); // OK - implicitly refers to method of enclosing instance - Outer.this.hello(); // OK - explicitly refers to method of enclosing instance - super(); - } - } - } - - // Early assignment to fields - class Super3 { - Super3() { overriddenMethod(); } - void overriddenMethod() { System.out.println("hello"); } - } - class Sub3 extends Super3 { - final int x; - - Sub3(int x) { - this.x = x; // Initialize the field - super(); // Then invoke the Super constructor explicitly - } - - @Override - void overriddenMethod() { System.out.println(x); } - } - - -} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep492_FlexibleConstructorBodies.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep492_FlexibleConstructorBodies.txt deleted file mode 100644 index a674767c207..00000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep492_FlexibleConstructorBodies.txt +++ /dev/null @@ -1,318 +0,0 @@ -+- CompilationUnit[@Compact = false, @PackageName = ""] - +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.math.BigInteger", @ImportedSimpleName = "BigInteger", @ModuleImport = false, @PackageName = "java.math", @Static = false] - +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.security.cert.Certificate", @ImportedSimpleName = "Certificate", @ModuleImport = false, @PackageName = "java.security.cert", @Static = false] - +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.security.interfaces.DSAPublicKey", @ImportedSimpleName = "DSAPublicKey", @ModuleImport = false, @PackageName = "java.security.interfaces", @Static = false] - +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.security.interfaces.RSAKey", @ImportedSimpleName = "RSAKey", @ModuleImport = false, @PackageName = "java.security.interfaces", @Static = false] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep492_FlexibleConstructorBodies", @CanonicalName = "Jep492_FlexibleConstructorBodies", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Jep492_FlexibleConstructorBodies", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] - +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - +- ClassBody[@Empty = false, @Size = 9] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep492_FlexibleConstructorBodies$PositiveBigInteger", @CanonicalName = "Jep492_FlexibleConstructorBodies.PositiveBigInteger", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "PositiveBigInteger", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - | +- ExtendsList[@Empty = false, @Size = 1] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "BigInteger"] - | +- ClassBody[@Empty = false, @Size = 1] - | +- ConstructorDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @Image = "PositiveBigInteger", @Name = "PositiveBigInteger", @Static = false, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @containsComment = false] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - | +- FormalParameters[@Empty = false, @Size = 1] - | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.LONG] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "value", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- Block[@Empty = false, @Size = 2, @containsComment = false] - | +- IfStatement[@Else = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.LE, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "value", @Name = "value", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] - | | +- ThrowStatement[] - | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "IllegalArgumentException"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "value must be positive", @Empty = false, @Image = "\"value must be positive\"", @Length = 22, @LiteralText = "\"value must be positive\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- ExplicitConstructorInvocation[@ArgumentCount = 1, @MethodName = "new", @Qualified = false, @Super = true, @This = false] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- MethodCall[@CompileTimeConstant = false, @Image = "valueOf", @MethodName = "valueOf", @ParenthesisDepth = 0, @Parenthesized = false] - | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "value", @Name = "value", @ParenthesisDepth = 0, @Parenthesized = false] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep492_FlexibleConstructorBodies$Super", @CanonicalName = "Jep492_FlexibleConstructorBodies.Super", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Super", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - | +- ClassBody[@Empty = false, @Size = 1] - | +- ConstructorDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @Image = "Super", @Name = "Super", @Static = false, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @containsComment = false] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - | +- FormalParameters[@Empty = false, @Size = 1] - | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- ArrayType[@ArrayDepth = 1] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] - | | | +- ArrayDimensions[@Empty = false, @Size = 1] - | | | +- ArrayTypeDim[@Varargs = false] - | | +- VariableId[@ArrayType = true, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "bytes", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- Block[@Empty = true, @Size = 0, @containsComment = false] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep492_FlexibleConstructorBodies$Sub", @CanonicalName = "Jep492_FlexibleConstructorBodies.Sub", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Sub", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - | +- ExtendsList[@Empty = false, @Size = 1] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Super"] - | +- ClassBody[@Empty = false, @Size = 1] - | +- ConstructorDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @Image = "Sub", @Name = "Sub", @Static = false, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @containsComment = false] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - | +- FormalParameters[@Empty = false, @Size = 1] - | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Certificate"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "certificate", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- Block[@Empty = false, @Size = 4, @containsComment = false] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = true, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- VariableDeclarator[@Initializer = true, @Name = "publicKey"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "publicKey", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "getPublicKey", @MethodName = "getPublicKey", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "certificate", @Name = "certificate", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ArgumentList[@Empty = true, @Size = 0] - | +- IfStatement[@Else = false] - | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.EQ, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "publicKey", @Name = "publicKey", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- NullLiteral[@CompileTimeConstant = false, @LiteralText = "null", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ThrowStatement[] - | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "NullPointerException"] - | | +- ArgumentList[@Empty = true, @Size = 0] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- ArrayType[@ArrayDepth = 1] - | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] - | | | +- ArrayDimensions[@Empty = false, @Size = 1] - | | | +- ArrayTypeDim[@Varargs = false] - | | +- VariableDeclarator[@Initializer = true, @Name = "certBytes"] - | | +- VariableId[@ArrayType = true, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "certBytes", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = true, @EnumSwitch = false, @Exhaustive = false, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "publicKey", @Name = "publicKey", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] - | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "RSAKey"] - | | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "rsaKey", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | | +- MethodCall[@CompileTimeConstant = false, @Image = "toByteArray", @MethodName = "toByteArray", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- MethodCall[@CompileTimeConstant = false, @Image = "getModulus", @MethodName = "getModulus", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "rsaKey", @Name = "rsaKey", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- ArgumentList[@Empty = true, @Size = 0] - | | | +- ArgumentList[@Empty = true, @Size = 0] - | | +- SwitchArrowBranch[@Default = false] - | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] - | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] - | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "DSAPublicKey"] - | | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "dsaKey", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | | +- MethodCall[@CompileTimeConstant = false, @Image = "toByteArray", @MethodName = "toByteArray", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- MethodCall[@CompileTimeConstant = false, @Image = "getY", @MethodName = "getY", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "dsaKey", @Name = "dsaKey", @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- ArgumentList[@Empty = true, @Size = 0] - | | | +- ArgumentList[@Empty = true, @Size = 0] - | | +- SwitchArrowBranch[@Default = true] - | | +- SwitchLabel[@CaseNull = false, @Default = true, @PatternLabel = false] - | | +- ArrayAllocation[@ArrayDepth = 1, @CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ArrayType[@ArrayDepth = 1] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] - | | +- ArrayDimensions[@Empty = false, @Size = 1] - | | +- ArrayDimExpr[@Varargs = false] - | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] - | +- ExplicitConstructorInvocation[@ArgumentCount = 1, @MethodName = "new", @Qualified = false, @Super = true, @This = false] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "certBytes", @Name = "certBytes", @ParenthesisDepth = 0, @Parenthesized = false] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep492_FlexibleConstructorBodies$C", @CanonicalName = "Jep492_FlexibleConstructorBodies.C", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "C", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - | +- ClassBody[@Empty = false, @Size = 2] - | +- FieldDeclaration[@EffectiveVisibility = Visibility.V_PRIVATE, @Static = false, @Visibility = Visibility.V_PRIVATE] - | | +- ModifierList[@EffectiveModifiers = (JModifier.PRIVATE, JModifier.FINAL), @ExplicitModifiers = (JModifier.PRIVATE, JModifier.FINAL)] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- VariableDeclarator[@Initializer = false, @Name = "i"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PRIVATE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = true, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PRIVATE] - | +- ConstructorDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @Image = "C", @Name = "C", @Static = false, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @containsComment = false] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - | +- FormalParameters[@Empty = false, @Size = 1] - | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- ExpressionStatement[] - | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] - | +- FieldAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ThisExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep492_FlexibleConstructorBodies$Super2", @CanonicalName = "Jep492_FlexibleConstructorBodies.Super2", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Super2", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - | +- ClassBody[@Empty = false, @Size = 3] - | +- FieldDeclaration[@EffectiveVisibility = Visibility.V_PRIVATE, @Static = false, @Visibility = Visibility.V_PRIVATE] - | | +- ModifierList[@EffectiveModifiers = (JModifier.PRIVATE, JModifier.FINAL), @ExplicitModifiers = (JModifier.PRIVATE, JModifier.FINAL)] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "C"] - | | +- VariableDeclarator[@Initializer = false, @Name = "x"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PRIVATE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = true, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PRIVATE] - | +- FieldDeclaration[@EffectiveVisibility = Visibility.V_PRIVATE, @Static = false, @Visibility = Visibility.V_PRIVATE] - | | +- ModifierList[@EffectiveModifiers = (JModifier.PRIVATE, JModifier.FINAL), @ExplicitModifiers = (JModifier.PRIVATE, JModifier.FINAL)] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "C"] - | | +- VariableDeclarator[@Initializer = false, @Name = "y"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PRIVATE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = true, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "y", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PRIVATE] - | +- ConstructorDeclaration[@Abstract = false, @Arity = 2, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @Image = "Super2", @Name = "Super2", @Static = false, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @containsComment = false] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - | +- FormalParameters[@Empty = false, @Size = 2] - | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] - | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "C"] - | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "C"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "y", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- Block[@Empty = false, @Size = 2, @containsComment = false] - | +- ExpressionStatement[] - | | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ThisExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ExpressionStatement[] - | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] - | +- FieldAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "y", @Name = "y", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ThisExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "y", @Name = "y", @ParenthesisDepth = 0, @Parenthesized = false] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep492_FlexibleConstructorBodies$Sub2", @CanonicalName = "Jep492_FlexibleConstructorBodies.Sub2", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Sub2", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - | +- ExtendsList[@Empty = false, @Size = 1] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Super2"] - | +- ClassBody[@Empty = false, @Size = 1] - | +- ConstructorDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @Image = "Sub2", @Name = "Sub2", @Static = false, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @containsComment = false] - | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - | +- FormalParameters[@Empty = false, @Size = 1] - | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- Block[@Empty = false, @Size = 2, @containsComment = false] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = true, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- VariableDeclarator[@Initializer = true, @Name = "x"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "C"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ExplicitConstructorInvocation[@ArgumentCount = 2, @MethodName = "new", @Qualified = false, @Super = true, @This = false] - | +- ArgumentList[@Empty = false, @Size = 2] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep492_FlexibleConstructorBodies$Outer", @CanonicalName = "Jep492_FlexibleConstructorBodies.Outer", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Outer", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- ClassBody[@Empty = false, @Size = 3] - | +- FieldDeclaration[@EffectiveVisibility = Visibility.V_PACKAGE, @Static = false, @Visibility = Visibility.V_PACKAGE] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- VariableDeclarator[@Initializer = false, @Name = "i"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PACKAGE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = true, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PACKAGE] - | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "hello", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- VoidType[] - | | +- FormalParameters[@Empty = true, @Size = 0] - | | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | | +- ArgumentList[@Empty = false, @Size = 1] - | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Hello", @Empty = false, @Image = "\"Hello\"", @Length = 5, @LiteralText = "\"Hello\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep492_FlexibleConstructorBodies$Outer$Inner", @CanonicalName = "Jep492_FlexibleConstructorBodies.Outer.Inner", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Inner", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- ClassBody[@Empty = false, @Size = 2] - | +- FieldDeclaration[@EffectiveVisibility = Visibility.V_PACKAGE, @Static = false, @Visibility = Visibility.V_PACKAGE] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- VariableDeclarator[@Initializer = false, @Name = "j"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PACKAGE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = true, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "j", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PACKAGE] - | +- ConstructorDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Image = "Inner", @Name = "Inner", @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @containsComment = false] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- FormalParameters[@Empty = true, @Size = 0] - | +- Block[@Empty = false, @Size = 5, @containsComment = false] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = true, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- VariableDeclarator[@Initializer = true, @Name = "x"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] - | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = true, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- VariableDeclarator[@Initializer = true, @Name = "y"] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "y", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ThisExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Outer"] - | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "hello", @MethodName = "hello", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ArgumentList[@Empty = true, @Size = 0] - | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "hello", @MethodName = "hello", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ThisExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Outer"] - | | +- ArgumentList[@Empty = true, @Size = 0] - | +- ExplicitConstructorInvocation[@ArgumentCount = 0, @MethodName = "new", @Qualified = false, @Super = true, @This = false] - | +- ArgumentList[@Empty = true, @Size = 0] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep492_FlexibleConstructorBodies$Super3", @CanonicalName = "Jep492_FlexibleConstructorBodies.Super3", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Super3", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- ClassBody[@Empty = false, @Size = 2] - | +- ConstructorDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Image = "Super3", @Name = "Super3", @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @containsComment = false] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- FormalParameters[@Empty = true, @Size = 0] - | | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | | +- ExpressionStatement[] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "overriddenMethod", @MethodName = "overriddenMethod", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ArgumentList[@Empty = true, @Size = 0] - | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "overriddenMethod", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- VoidType[] - | +- FormalParameters[@Empty = true, @Size = 0] - | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- ExpressionStatement[] - | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "hello", @Empty = false, @Image = "\"hello\"", @Length = 5, @LiteralText = "\"hello\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep492_FlexibleConstructorBodies$Sub3", @CanonicalName = "Jep492_FlexibleConstructorBodies.Sub3", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Sub3", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] - +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - +- ExtendsList[@Empty = false, @Size = 1] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Super3"] - +- ClassBody[@Empty = false, @Size = 3] - +- FieldDeclaration[@EffectiveVisibility = Visibility.V_PACKAGE, @Static = false, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (JModifier.FINAL), @ExplicitModifiers = (JModifier.FINAL)] - | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | +- VariableDeclarator[@Initializer = false, @Name = "x"] - | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PACKAGE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = true, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PACKAGE] - +- ConstructorDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Image = "Sub3", @Name = "Sub3", @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @containsComment = true] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- FormalParameters[@Empty = false, @Size = 1] - | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] - | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] - | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- Block[@Empty = false, @Size = 2, @containsComment = true] - | +- ExpressionStatement[] - | | +- AssignmentExpression[@CompileTimeConstant = false, @Compound = false, @Operator = AssignmentOp.ASSIGN, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- FieldAccess[@AccessType = AccessType.WRITE, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- ThisExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ExplicitConstructorInvocation[@ArgumentCount = 0, @MethodName = "new", @Qualified = false, @Super = true, @This = false] - | +- ArgumentList[@Empty = true, @Size = 0] - +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "overriddenMethod", @Overridden = true, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] - +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- Annotation[@SimpleName = "Override"] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Override"] - +- VoidType[] - +- FormalParameters[@Empty = true, @Size = 0] - +- Block[@Empty = false, @Size = 1, @containsComment = false] - +- ExpressionStatement[] - +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - +- ArgumentList[@Empty = false, @Size = 1] - +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep494_ModuleImportDeclarations.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep494_ModuleImportDeclarations.java deleted file mode 100644 index 974e907bd82..00000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep494_ModuleImportDeclarations.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -import module java.base; -import module java.desktop; - -import java.util.List; - -/** - * @see JEP 494: Module Import Declarations (Second Preview) (Java 24) - */ -public class Jep494_ModuleImportDeclarations { - public static void main(String[] args) { - File f = new File("."); - List myList = new ArrayList<>(); - myList.add(f); - System.out.println("myList = " + myList); - } -} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep494_ModuleImportDeclarations.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep494_ModuleImportDeclarations.txt deleted file mode 100644 index 795eafa6cd3..00000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep494_ModuleImportDeclarations.txt +++ /dev/null @@ -1,53 +0,0 @@ -+- CompilationUnit[@Compact = false, @PackageName = ""] - +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.base", @ImportedSimpleName = null, @ModuleImport = true, @PackageName = null, @Static = false] - +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.desktop", @ImportedSimpleName = null, @ModuleImport = true, @PackageName = null, @Static = false] - +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.List", @ImportedSimpleName = "List", @ModuleImport = false, @PackageName = "java.util", @Static = false] - +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep494_ModuleImportDeclarations", @CanonicalName = "Jep494_ModuleImportDeclarations", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Jep494_ModuleImportDeclarations", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] - +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] - +- ClassBody[@Empty = false, @Size = 1] - +- MethodDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PUBLIC, @Final = false, @MainMethod = true, @Name = "main", @Overridden = false, @Static = true, @Varargs = false, @Visibility = Visibility.V_PUBLIC, @Void = true] - +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.STATIC), @ExplicitModifiers = (JModifier.PUBLIC, JModifier.STATIC)] - +- VoidType[] - +- FormalParameters[@Empty = false, @Size = 1] - | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- ArrayType[@ArrayDepth = 1] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] - | | +- ArrayDimensions[@Empty = false, @Size = 1] - | | +- ArrayTypeDim[@Varargs = false] - | +- VariableId[@ArrayType = true, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "args", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - +- Block[@Empty = false, @Size = 4, @containsComment = false] - +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "File"] - | +- VariableDeclarator[@Initializer = true, @Name = "f"] - | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "f", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "File"] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = ".", @Empty = false, @Image = "\".\"", @Length = 1, @LiteralText = "\".\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "List"] - | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "File"] - | +- VariableDeclarator[@Initializer = true, @Name = "myList"] - | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "myList", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = true, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "ArrayList"] - | | +- TypeArguments[@Diamond = true, @Empty = true, @Size = 0] - | +- ArgumentList[@Empty = true, @Size = 0] - +- ExpressionStatement[] - | +- MethodCall[@CompileTimeConstant = false, @Image = "add", @MethodName = "add", @ParenthesisDepth = 0, @Parenthesized = false] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "myList", @Name = "myList", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "f", @Name = "f", @ParenthesisDepth = 0, @Parenthesized = false] - +- ExpressionStatement[] - +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - +- ArgumentList[@Empty = false, @Size = 1] - +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "myList = ", @Empty = false, @Image = "\"myList = \"", @Length = 9, @LiteralText = "\"myList = \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "myList", @Name = "myList", @ParenthesisDepth = 0, @Parenthesized = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep495_SimpleSourceFilesAndInstanceMainMethods.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep495_SimpleSourceFilesAndInstanceMainMethods.java deleted file mode 100644 index e3e8fb05538..00000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep495_SimpleSourceFilesAndInstanceMainMethods.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -// explicit imports are possible as well (although not really needed in this example) -import java.util.Arrays; -import java.util.stream.Collectors; -import static java.io.IO.*; // support for the implicit import in PMD and Java 25 has been removed with JEP 512 - -/** - * @see JEP 495: Simple Source Files and Instance Main Methods (Fourth Preview) (Java 24) - */ - -// Top-level members are interpreted as members of the implicit class (methods and fields) -String greetingField = "Hello, World! (Field)"; -String greeting() { - return "Hello, World! (Method)"; -} -String greetingText2 = Arrays.asList("Hello", "World!", "(with imports)").stream().collect(Collectors.joining(", ")); - -void main() { - System.out.println(greetingField); - println(greeting()); //java.io.IO.println - println(greetingText2); - - // java.io.IO.readln - String name = readln("Please enter your name: "); - print("Pleased to meet you, "); - println(name); - - // java.util.List is automatically available via implicit "import module java.base" - var authors = List.of("James", "Bill", "Guy", "Alex", "Dan", "Gavin"); - for (var authorName : authors) { - println(authorName + ": " + authorName.length()); - } -} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep495_SimpleSourceFilesAndInstanceMainMethods.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep495_SimpleSourceFilesAndInstanceMainMethods.txt deleted file mode 100644 index 6c1d79e6793..00000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java24p/Jep495_SimpleSourceFilesAndInstanceMainMethods.txt +++ /dev/null @@ -1,109 +0,0 @@ -+- CompilationUnit[@Compact = true, @PackageName = ""] - +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.Arrays", @ImportedSimpleName = "Arrays", @ModuleImport = false, @PackageName = "java.util", @Static = false] - +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.stream.Collectors", @ImportedSimpleName = "Collectors", @ModuleImport = false, @PackageName = "java.util.stream", @Static = false] - +- ImportDeclaration[@ImportOnDemand = true, @ImportedName = "java.io.IO", @ImportedSimpleName = null, @ModuleImport = false, @PackageName = "java.io.IO", @Static = true] - +- ImplicitClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "", @CanonicalName = null, @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = false, @SimpleName = "", @Static = false, @TopLevel = true, @UnnamedToplevelClass = true, @Visibility = Visibility.V_PACKAGE] - +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - +- ClassBody[@Empty = false, @Size = 4] - +- FieldDeclaration[@EffectiveVisibility = Visibility.V_PACKAGE, @Static = false, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] - | +- VariableDeclarator[@Initializer = true, @Name = "greetingField"] - | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PACKAGE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = true, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "greetingField", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PACKAGE] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Hello, World! (Field)", @Empty = false, @Image = "\"Hello, World! (Field)\"", @Length = 21, @LiteralText = "\"Hello, World! (Field)\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "greeting", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = false] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] - | +- FormalParameters[@Empty = true, @Size = 0] - | +- Block[@Empty = false, @Size = 1, @containsComment = false] - | +- ReturnStatement[] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Hello, World! (Method)", @Empty = false, @Image = "\"Hello, World! (Method)\"", @Length = 22, @LiteralText = "\"Hello, World! (Method)\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- FieldDeclaration[@EffectiveVisibility = Visibility.V_PACKAGE, @Static = false, @Visibility = Visibility.V_PACKAGE] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] - | +- VariableDeclarator[@Initializer = true, @Name = "greetingText2"] - | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PACKAGE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = true, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "greetingText2", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PACKAGE] - | +- MethodCall[@CompileTimeConstant = false, @Image = "collect", @MethodName = "collect", @ParenthesisDepth = 0, @Parenthesized = false] - | +- MethodCall[@CompileTimeConstant = false, @Image = "stream", @MethodName = "stream", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- MethodCall[@CompileTimeConstant = false, @Image = "asList", @MethodName = "asList", @ParenthesisDepth = 0, @Parenthesized = false] - | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Arrays"] - | | | +- ArgumentList[@Empty = false, @Size = 3] - | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Hello", @Empty = false, @Image = "\"Hello\"", @Length = 5, @LiteralText = "\"Hello\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "World!", @Empty = false, @Image = "\"World!\"", @Length = 6, @LiteralText = "\"World!\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "(with imports)", @Empty = false, @Image = "\"(with imports)\"", @Length = 14, @LiteralText = "\"(with imports)\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | | +- ArgumentList[@Empty = true, @Size = 0] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- MethodCall[@CompileTimeConstant = false, @Image = "joining", @MethodName = "joining", @ParenthesisDepth = 0, @Parenthesized = false] - | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Collectors"] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = ", ", @Empty = false, @Image = "\", \"", @Length = 2, @LiteralText = "\", \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @MainMethod = true, @Name = "main", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] - +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - +- VoidType[] - +- FormalParameters[@Empty = true, @Size = 0] - +- Block[@Empty = false, @Size = 8, @containsComment = false] - +- ExpressionStatement[] - | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] - | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "greetingField", @Name = "greetingField", @ParenthesisDepth = 0, @Parenthesized = false] - +- ExpressionStatement[] - | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- MethodCall[@CompileTimeConstant = false, @Image = "greeting", @MethodName = "greeting", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ArgumentList[@Empty = true, @Size = 0] - +- ExpressionStatement[] - | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "greetingText2", @Name = "greetingText2", @ParenthesisDepth = 0, @Parenthesized = false] - +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] - | +- VariableDeclarator[@Initializer = true, @Name = "name"] - | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "name", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- MethodCall[@CompileTimeConstant = false, @Image = "readln", @MethodName = "readln", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Please enter your name: ", @Empty = false, @Image = "\"Please enter your name: \"", @Length = 24, @LiteralText = "\"Please enter your name: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- ExpressionStatement[] - | +- MethodCall[@CompileTimeConstant = false, @Image = "print", @MethodName = "print", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Pleased to meet you, ", @Empty = false, @Image = "\"Pleased to meet you, \"", @Length = 21, @LiteralText = "\"Pleased to meet you, \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- ExpressionStatement[] - | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - | +- ArgumentList[@Empty = false, @Size = 1] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "name", @Name = "name", @ParenthesisDepth = 0, @Parenthesized = false] - +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = true, @Visibility = Visibility.V_LOCAL] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- VariableDeclarator[@Initializer = true, @Name = "authors"] - | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "authors", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - | +- MethodCall[@CompileTimeConstant = false, @Image = "of", @MethodName = "of", @ParenthesisDepth = 0, @Parenthesized = false] - | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] - | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "List"] - | +- ArgumentList[@Empty = false, @Size = 6] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "James", @Empty = false, @Image = "\"James\"", @Length = 5, @LiteralText = "\"James\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Bill", @Empty = false, @Image = "\"Bill\"", @Length = 4, @LiteralText = "\"Bill\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Guy", @Empty = false, @Image = "\"Guy\"", @Length = 3, @LiteralText = "\"Guy\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Alex", @Empty = false, @Image = "\"Alex\"", @Length = 4, @LiteralText = "\"Alex\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Dan", @Empty = false, @Image = "\"Dan\"", @Length = 3, @LiteralText = "\"Dan\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Gavin", @Empty = false, @Image = "\"Gavin\"", @Length = 5, @LiteralText = "\"Gavin\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- ForeachStatement[] - +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = true, @Visibility = Visibility.V_LOCAL] - | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] - | +- VariableDeclarator[@Initializer = false, @Name = "authorName"] - | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = true, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "authorName", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] - +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "authors", @Name = "authors", @ParenthesisDepth = 0, @Parenthesized = false] - +- Block[@Empty = false, @Size = 1, @containsComment = false] - +- ExpressionStatement[] - +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] - +- ArgumentList[@Empty = false, @Size = 1] - +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] - | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "authorName", @Name = "authorName", @ParenthesisDepth = 0, @Parenthesized = false] - | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = ": ", @Empty = false, @Image = "\": \"", @Length = 2, @LiteralText = "\": \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] - +- MethodCall[@CompileTimeConstant = false, @Image = "length", @MethodName = "length", @ParenthesisDepth = 0, @Parenthesized = false] - +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "authorName", @Name = "authorName", @ParenthesisDepth = 0, @Parenthesized = false] - +- ArgumentList[@Empty = true, @Size = 0] From f15a139268ecea7a8cb5166c52674c52ee63631d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 5 Jan 2026 10:54:39 +0100 Subject: [PATCH 1823/1962] [java] Update implementation for JEP 530: Primitive Types in Patterns... --- .../ast/internal/LanguageLevelChecker.java | 3 +- .../java/ast/Java26PreviewTreeDumpTest.java | 17 + .../java/ast/ASTInstanceOfExpressionTest.kt | 5 +- ...iveTypesInPatternsInstanceofAndSwitch.java | 210 +++++ ...tiveTypesInPatternsInstanceofAndSwitch.txt | 728 ++++++++++++++++++ 5 files changed, 960 insertions(+), 3 deletions(-) create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java26p/Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java26p/Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch.txt diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java index afeb7a00dd1..3bafdbb27f5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java @@ -161,8 +161,9 @@ private enum PreviewFeature implements LanguageFeature { * @see JEP 455: Primitive Types in Patterns, instanceof, and switch (Preview) (Java 23) * @see JEP 488: Primitive Types in Patterns, instanceof, and switch (Second Preview) (Java 24) * @see JEP 507: Primitive Types in Patterns, instanceof, and switch (Third Preview) (Java 25) + * @see JEP 530: Primitive Types in Patterns, instanceof, and switch (Fourth Preview) (Java 26) */ - PRIMITIVE_TYPES_IN_PATTERNS_INSTANCEOF_AND_SWITCH(23, 25, false), + PRIMITIVE_TYPES_IN_PATTERNS_INSTANCEOF_AND_SWITCH(23, 26, false), ; // SUPPRESS CHECKSTYLE enum trailing semi is awesome diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java26PreviewTreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java26PreviewTreeDumpTest.java index 3822606e5fd..13dc4490fef 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java26PreviewTreeDumpTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java26PreviewTreeDumpTest.java @@ -4,6 +4,13 @@ package net.sourceforge.pmd.lang.java.ast; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +import net.sourceforge.pmd.lang.ast.ParseException; import net.sourceforge.pmd.lang.java.BaseJavaTreeDumpTest; import net.sourceforge.pmd.lang.java.JavaParsingHelper; import net.sourceforge.pmd.lang.test.ast.BaseParsingHelper; @@ -19,4 +26,14 @@ class Java26PreviewTreeDumpTest extends BaseJavaTreeDumpTest { return java26p; } + @Test + void jep530PrimitiveTypesInPatternsInstanceofAndSwitch() { + doTest("Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch"); + } + + @Test + void jep530PrimitiveTypesInPatternsInstanceofAndSwitchBeforeJava26Preview() { + ParseException thrown = assertThrows(ParseException.class, () -> java26.parseResource("Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch.java")); + assertThat(thrown.getMessage(), containsString("Primitive types in patterns instanceof and switch is a preview feature of JDK 26, you should select your language version accordingly")); + } } diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTInstanceOfExpressionTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTInstanceOfExpressionTest.kt index 6aaa76aae15..eada326ec8a 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTInstanceOfExpressionTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTInstanceOfExpressionTest.kt @@ -48,7 +48,7 @@ class ASTInstanceOfExpressionTest : ParserTestSpec({ } } - parserTestContainer("InstanceofExpression cannot test primitive types", JavaVersion.except(JavaVersion.J25__PREVIEW, JavaVersion.J25__PREVIEW)) { + parserTestContainer("InstanceofExpression cannot test primitive types", JavaVersion.except(JavaVersion.J25__PREVIEW, JavaVersion.J26__PREVIEW)) { inContext(ExpressionParsingCtx) { PrimitiveTypeKind.values().map { it.simpleName }.forEach { "f instanceof $it" shouldNot parse() @@ -60,7 +60,8 @@ class ASTInstanceOfExpressionTest : ParserTestSpec({ // since Java 23 Preview, primitive types in instanceof are possible (JEP 455) // Java 24 Preview: JEP 488 // Java 25 Preview: JEP 507 - parserTestContainer("InstanceofExpression can test primitive types", listOf(JavaVersion.J25__PREVIEW, JavaVersion.J25__PREVIEW)) { + // Java 26 Preview: JEP 530 + parserTestContainer("InstanceofExpression can test primitive types", listOf(JavaVersion.J25__PREVIEW, JavaVersion.J26__PREVIEW)) { inContext(ExpressionParsingCtx) { PrimitiveTypeKind.values().forEach { typeKind -> "f instanceof ${typeKind.simpleName}" should parseAs { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java26p/Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java26p/Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch.java new file mode 100644 index 00000000000..184eadcbdfb --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java26p/Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch.java @@ -0,0 +1,210 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +import java.util.Map; + +/** + * @see JEP 530: Primitive Types in Patterns, instanceof, and switch (Fourth Preview) (Java 26) + */ +public class Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch { + + /** + * 1. Extend pattern matching so that primitive type patterns are applicable to a wider range of match candidate + * types. This will allow expressions such as v instanceof JsonNumber(int age). + */ + void primitiveTypePatterns() { + var json = new JsonObject(Map.of("name", new JsonString("John"), + "age", new JsonNumber(30))); + + if (json instanceof JsonObject(var map) + && map.get("name") instanceof JsonString(String n) + && map.get("age") instanceof JsonNumber(int age)) { + System.out.printf("Name: %s Age: %d%n", n, age); + } + } + sealed interface JsonValue {} + record JsonString(String s) implements JsonValue { } + record JsonNumber(double d) implements JsonValue { } + record JsonObject(Map map) implements JsonValue { } + + /** + * 2. Enhance the instanceof and switch constructs to support primitive type patterns as top level patterns. + */ + void topLevelPrimitiveTypePatterns() { + X x = new X(); + + String status = switch (x.getStatus()) { + case 0 -> "okay"; + case 1 -> "warning"; + case 2 -> "error"; + case int i -> "unknown status: " + i; + }; + System.out.println("status: " + status); + + switch (x.getYearlyFlights()) { + case 0 -> x.noop(); + case 1 -> x.noop(); + case 2 -> x.issueDiscount(); + case int i when i >= 100 -> x.issueGoldCard(); + case int i -> x.issueDiscount(); // ... appropriate action when i > 2 && i < 100 ... + } + + if (x.getPopulation() instanceof float p) { + // ... p ... + } + int i = 42; + if (i instanceof byte b) { + // ... b ... + } + } + class X { + int getStatus() { return 0; } + int getYearlyFlights() { return 1; } + void noop() {} + void issueDiscount() {} + void issueGoldCard() {} + int getPopulation() { return 1; } + } + + /** + * 3. Further enhance the instanceof construct so that, when used for type testing rather than pattern matching, + * it can test against all types, not just reference types. This will extend instanceof's current role, as the + * precondition for safe casting on reference types, to apply to all types. + * + *

          More broadly, this means that instanceof can safeguard all conversions, whether the match candidate is + * having its type tested (e.g., x instanceof int, or y instanceof String) or having its value matched + * (e.g., x instanceof int i, or y instanceof String s). + */ + void instanceofWithPrimitives() { + int i = 42; + if (i instanceof byte) { + byte b = (byte) i; + // ... b ... + } + } + + /** + * 4. Further enhance the switch construct so that it works with all primitive types, not just a subset + * of the integral primitive types. + */ + void switchOnAllPrimitives() { + User user = new User(); + User.startProcessing(User.OrderStatus.NEW, switch (user.isLoggedIn()) { + case true -> user.id(); + case false -> { User.log("Unrecognized user"); yield -1; } + }); + + { + long v = (long) Math.random() * Long.MAX_VALUE; + switch (v) { + case 1L -> System.out.println("v is 1L"); + case 2L -> System.out.println("v is 2L"); + case 10_000_000_000L -> System.out.println("v is 10b"); + case 20_000_000_000L -> System.out.println("v is 20b"); + case long x -> System.out.println("v is " + x); + } + } + + { + Byte b = 2; + switch (b) { // exhaustive switch + case int p -> {} + } + } + + { + int x = 42; + switch (x) { + case int _ -> {} // unconditional pattern + //case float _ -> {} // error: dominated + } + } + + { + float v = 1.1f; + float result = switch (v) { + case 0f -> 5f; + case float x when x == 1f -> 6f + x; + case float x -> 7f + x; + }; + } + + { + boolean v = true; + switch (v) { + case true -> { + } + case false -> { + } + } + } + + { + // Applicability + int i = 1; + switch (i) { + case double d -> System.out.println("double: " + d); + } + } + } + class User { + boolean isLoggedIn() { return false; } + int id() { return 42; } + static void startProcessing(OrderStatus status, int userId) {} + static void log(String s) {} + enum OrderStatus { NEW }; + } + + void instanceofAsThePreconditionForSafeCasting() { + { + byte b = 42; + assert b instanceof int; // true (unconditionally exact) + } + + { + int i = 42; + assert i instanceof byte; // true (exact) + } + + { + int i = 1000; + assert !(i instanceof byte); // false (not exact) + } + + { + int i = 16_777_217; // 2^24 + 1 + assert !(i instanceof float); // false (not exact) + assert i instanceof double; // true (unconditionally exact) + assert i instanceof Integer; // true (unconditionally exact) + assert i instanceof Number; // true (unconditionally exact) + } + + { + float f = 1000.0f; + assert !(f instanceof byte); // false + assert f instanceof int; // true (exact) + assert f instanceof double; // true (unconditionally exact) + } + + { + double d = 1000.0d; + assert !(d instanceof byte); // false + assert d instanceof int; // true (exact) + assert d instanceof float; // true (exact) + } + + { + Integer ii = 1000; + assert ii instanceof int; // true (exact) + assert ii instanceof float; // true (exact) + assert ii instanceof double; // true (exact) + } + + { + Integer ii = 16_777_217; + assert !(ii instanceof float); // false (not exact) + assert ii instanceof double; // true (exact) + } + } +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java26p/Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java26p/Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch.txt new file mode 100644 index 00000000000..ffd2a4aa8bf --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java26p/Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch.txt @@ -0,0 +1,728 @@ ++- CompilationUnit[@Compact = false, @PackageName = ""] + +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.Map", @ImportedSimpleName = "Map", @ModuleImport = false, @PackageName = "java.util", @Static = false] + +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch", @CanonicalName = "Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC] + +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)] + +- ClassBody[@Empty = false, @Size = 11] + +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "primitiveTypePatterns", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- VoidType[] + | +- FormalParameters[@Empty = true, @Size = 0] + | +- Block[@Empty = false, @Size = 2, @containsComment = false] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = true, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- VariableDeclarator[@Initializer = true, @Name = "json"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "json", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonObject"] + | | +- ArgumentList[@Empty = false, @Size = 1] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "of", @MethodName = "of", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Map"] + | | +- ArgumentList[@Empty = false, @Size = 4] + | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "name", @Empty = false, @Image = "\"name\"", @Length = 4, @LiteralText = "\"name\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonString"] + | | | +- ArgumentList[@Empty = false, @Size = 1] + | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "John", @Empty = false, @Image = "\"John\"", @Length = 4, @LiteralText = "\"John\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "age", @Empty = false, @Image = "\"age\"", @Length = 3, @LiteralText = "\"age\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonNumber"] + | | +- ArgumentList[@Empty = false, @Size = 1] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "30", @IntLiteral = true, @Integral = true, @LiteralText = "30", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 30.0, @ValueAsFloat = 30.0, @ValueAsInt = 30, @ValueAsLong = 30] + | +- IfStatement[@Else = false] + | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.CONDITIONAL_AND, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.CONDITIONAL_AND, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "json", @Name = "json", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- RecordPattern[] + | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonObject"] + | | | | +- PatternList[@Empty = false, @Size = 1] + | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "map", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "get", @MethodName = "get", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "map", @Name = "map", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- ArgumentList[@Empty = false, @Size = 1] + | | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "name", @Empty = false, @Image = "\"name\"", @Length = 4, @LiteralText = "\"name\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | | +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- RecordPattern[] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonString"] + | | | +- PatternList[@Empty = false, @Size = 1] + | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "n", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "get", @MethodName = "get", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "map", @Name = "map", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ArgumentList[@Empty = false, @Size = 1] + | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "age", @Empty = false, @Image = "\"age\"", @Length = 3, @LiteralText = "\"age\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- RecordPattern[] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonNumber"] + | | +- PatternList[@Empty = false, @Size = 1] + | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "age", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- Block[@Empty = false, @Size = 1, @containsComment = false] + | +- ExpressionStatement[] + | +- MethodCall[@CompileTimeConstant = false, @Image = "printf", @MethodName = "printf", @ParenthesisDepth = 0, @Parenthesized = false] + | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | +- ArgumentList[@Empty = false, @Size = 3] + | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Name: %s Age: %d%n", @Empty = false, @Image = "\"Name: %s Age: %d%n\"", @Length = 18, @LiteralText = "\"Name: %s Age: %d%n\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "n", @Name = "n", @ParenthesisDepth = 0, @Parenthesized = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "age", @Name = "age", @ParenthesisDepth = 0, @Parenthesized = false] + +- ClassDeclaration[@Abstract = true, @Annotation = false, @Anonymous = false, @BinaryName = "Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch$JsonValue", @CanonicalName = "Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch.JsonValue", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = true, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = true, @SimpleName = "JsonValue", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + | +- ModifierList[@EffectiveModifiers = (JModifier.ABSTRACT, JModifier.STATIC, JModifier.SEALED), @ExplicitModifiers = (JModifier.SEALED)] + | +- ClassBody[@Empty = true, @Size = 0] + +- RecordDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch$JsonString", @CanonicalName = "Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch.JsonString", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = true, @RegularClass = false, @RegularInterface = false, @SimpleName = "JsonString", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = ()] + | +- RecordComponentList[@Empty = false, @Size = 1, @Varargs = false] + | | +- RecordComponent[@EffectiveVisibility = Visibility.V_PRIVATE, @Varargs = false, @Visibility = Visibility.V_PRIVATE] + | | +- ModifierList[@EffectiveModifiers = (JModifier.PRIVATE, JModifier.FINAL), @ExplicitModifiers = ()] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PRIVATE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = false, @RecordComponent = true, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PRIVATE] + | +- ImplementsList[@Empty = false, @Size = 1] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonValue"] + | +- RecordBody[@Empty = true, @Size = 0] + +- RecordDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch$JsonNumber", @CanonicalName = "Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch.JsonNumber", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = true, @RegularClass = false, @RegularInterface = false, @SimpleName = "JsonNumber", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = ()] + | +- RecordComponentList[@Empty = false, @Size = 1, @Varargs = false] + | | +- RecordComponent[@EffectiveVisibility = Visibility.V_PRIVATE, @Varargs = false, @Visibility = Visibility.V_PRIVATE] + | | +- ModifierList[@EffectiveModifiers = (JModifier.PRIVATE, JModifier.FINAL), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PRIVATE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "d", @PatternBinding = false, @RecordComponent = true, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PRIVATE] + | +- ImplementsList[@Empty = false, @Size = 1] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonValue"] + | +- RecordBody[@Empty = true, @Size = 0] + +- RecordDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch$JsonObject", @CanonicalName = "Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch.JsonObject", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = true, @RegularClass = false, @RegularInterface = false, @SimpleName = "JsonObject", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = ()] + | +- RecordComponentList[@Empty = false, @Size = 1, @Varargs = false] + | | +- RecordComponent[@EffectiveVisibility = Visibility.V_PRIVATE, @Varargs = false, @Visibility = Visibility.V_PRIVATE] + | | +- ModifierList[@EffectiveModifiers = (JModifier.PRIVATE, JModifier.FINAL), @ExplicitModifiers = ()] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Map"] + | | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 2] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonValue"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PRIVATE, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "map", @PatternBinding = false, @RecordComponent = true, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_PRIVATE] + | +- ImplementsList[@Empty = false, @Size = 1] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "JsonValue"] + | +- RecordBody[@Empty = true, @Size = 0] + +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "topLevelPrimitiveTypePatterns", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- VoidType[] + | +- FormalParameters[@Empty = true, @Size = 0] + | +- Block[@Empty = false, @Size = 7, @containsComment = false] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "X"] + | | +- VariableDeclarator[@Initializer = true, @Name = "x"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "X"] + | | +- ArgumentList[@Empty = true, @Size = 0] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] + | | +- VariableDeclarator[@Initializer = true, @Name = "status"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "status", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "getStatus", @MethodName = "getStatus", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ArgumentList[@Empty = true, @Size = 0] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] + | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] + | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "okay", @Empty = false, @Image = "\"okay\"", @Length = 4, @LiteralText = "\"okay\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] + | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] + | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "warning", @Empty = false, @Image = "\"warning\"", @Length = 7, @LiteralText = "\"warning\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] + | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2", @IntLiteral = true, @Integral = true, @LiteralText = "2", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] + | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "error", @Empty = false, @Image = "\"error\"", @Length = 5, @LiteralText = "\"error\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- SwitchArrowBranch[@Default = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] + | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "i", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "unknown status: ", @Empty = false, @Image = "\"unknown status: \"", @Length = 16, @LiteralText = "\"unknown status: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | +- ExpressionStatement[] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | | +- ArgumentList[@Empty = false, @Size = 1] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "status: ", @Empty = false, @Image = "\"status: \"", @Length = 8, @LiteralText = "\"status: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "status", @Name = "status", @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "getYearlyFlights", @MethodName = "getYearlyFlights", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ArgumentList[@Empty = true, @Size = 0] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] + | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "noop", @MethodName = "noop", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ArgumentList[@Empty = true, @Size = 0] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] + | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "noop", @MethodName = "noop", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ArgumentList[@Empty = true, @Size = 0] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] + | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2", @IntLiteral = true, @Integral = true, @LiteralText = "2", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "issueDiscount", @MethodName = "issueDiscount", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ArgumentList[@Empty = true, @Size = 0] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] + | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "i", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | | | +- Guard[] + | | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.GE, @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "100", @IntLiteral = true, @Integral = true, @LiteralText = "100", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 100.0, @ValueAsFloat = 100.0, @ValueAsInt = 100, @ValueAsLong = 100] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "issueGoldCard", @MethodName = "issueGoldCard", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ArgumentList[@Empty = true, @Size = 0] + | | +- SwitchArrowBranch[@Default = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] + | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "i", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "issueDiscount", @MethodName = "issueDiscount", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ArgumentList[@Empty = true, @Size = 0] + | +- IfStatement[@Else = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "getPopulation", @MethodName = "getPopulation", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- ArgumentList[@Empty = true, @Size = 0] + | | | +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "p", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- Block[@Empty = true, @Size = 0, @containsComment = true] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- VariableDeclarator[@Initializer = true, @Name = "i"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "42", @IntLiteral = true, @Integral = true, @LiteralText = "42", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 42.0, @ValueAsFloat = 42.0, @ValueAsInt = 42, @ValueAsLong = 42] + | +- IfStatement[@Else = false] + | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "b", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- Block[@Empty = true, @Size = 0, @containsComment = true] + +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch$X", @CanonicalName = "Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch.X", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "X", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- ClassBody[@Empty = false, @Size = 6] + | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "getStatus", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = false] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- FormalParameters[@Empty = true, @Size = 0] + | | +- Block[@Empty = false, @Size = 1, @containsComment = false] + | | +- ReturnStatement[] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "0", @IntLiteral = true, @Integral = true, @LiteralText = "0", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] + | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "getYearlyFlights", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = false] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- FormalParameters[@Empty = true, @Size = 0] + | | +- Block[@Empty = false, @Size = 1, @containsComment = false] + | | +- ReturnStatement[] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] + | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "noop", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- VoidType[] + | | +- FormalParameters[@Empty = true, @Size = 0] + | | +- Block[@Empty = true, @Size = 0, @containsComment = false] + | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "issueDiscount", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- VoidType[] + | | +- FormalParameters[@Empty = true, @Size = 0] + | | +- Block[@Empty = true, @Size = 0, @containsComment = false] + | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "issueGoldCard", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- VoidType[] + | | +- FormalParameters[@Empty = true, @Size = 0] + | | +- Block[@Empty = true, @Size = 0, @containsComment = false] + | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "getPopulation", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = false] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | +- FormalParameters[@Empty = true, @Size = 0] + | +- Block[@Empty = false, @Size = 1, @containsComment = false] + | +- ReturnStatement[] + | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] + +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "instanceofWithPrimitives", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- VoidType[] + | +- FormalParameters[@Empty = true, @Size = 0] + | +- Block[@Empty = false, @Size = 2, @containsComment = false] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- VariableDeclarator[@Initializer = true, @Name = "i"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "42", @IntLiteral = true, @Integral = true, @LiteralText = "42", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 42.0, @ValueAsFloat = 42.0, @ValueAsInt = 42, @ValueAsLong = 42] + | +- IfStatement[@Else = false] + | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] + | +- Block[@Empty = false, @Size = 1, @containsComment = true] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] + | +- VariableDeclarator[@Initializer = true, @Name = "b"] + | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "b", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- CastExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "switchOnAllPrimitives", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- VoidType[] + | +- FormalParameters[@Empty = true, @Size = 0] + | +- Block[@Empty = false, @Size = 8, @containsComment = false] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "User"] + | | +- VariableDeclarator[@Initializer = true, @Name = "user"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "user", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- ConstructorCall[@AnonymousClass = false, @CompileTimeConstant = false, @DiamondTypeArgs = false, @MethodName = "new", @ParenthesisDepth = 0, @Parenthesized = false, @QualifiedInstanceCreation = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "User"] + | | +- ArgumentList[@Empty = true, @Size = 0] + | +- ExpressionStatement[] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "startProcessing", @MethodName = "startProcessing", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "User"] + | | +- ArgumentList[@Empty = false, @Size = 2] + | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "NEW", @Name = "NEW", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "OrderStatus"] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "User"] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "isLoggedIn", @MethodName = "isLoggedIn", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "user", @Name = "user", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ArgumentList[@Empty = true, @Size = 0] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] + | | | | +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "true", @ParenthesisDepth = 0, @Parenthesized = false, @True = true] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "id", @MethodName = "id", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "user", @Name = "user", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ArgumentList[@Empty = true, @Size = 0] + | | +- SwitchArrowBranch[@Default = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] + | | | +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "false", @ParenthesisDepth = 0, @Parenthesized = false, @True = false] + | | +- Block[@Empty = false, @Size = 2, @containsComment = false] + | | +- ExpressionStatement[] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "log", @MethodName = "log", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "User"] + | | | +- ArgumentList[@Empty = false, @Size = 1] + | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Unrecognized user", @Empty = false, @Image = "\"Unrecognized user\"", @Length = 17, @LiteralText = "\"Unrecognized user\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- YieldStatement[] + | | +- UnaryExpression[@CompileTimeConstant = true, @Operator = UnaryOp.UNARY_MINUS, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] + | +- Block[@Empty = false, @Size = 2, @containsComment = false] + | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.LONG] + | | | +- VariableDeclarator[@Initializer = true, @Name = "v"] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "v", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.MUL, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- CastExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.LONG] + | | | | +- MethodCall[@CompileTimeConstant = false, @Image = "random", @MethodName = "random", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Math"] + | | | | +- ArgumentList[@Empty = true, @Size = 0] + | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = true, @Image = "MAX_VALUE", @Name = "MAX_VALUE", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Long"] + | | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "v", @Name = "v", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] + | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1L", @IntLiteral = false, @Integral = true, @LiteralText = "1L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | | | +- ArgumentList[@Empty = false, @Size = 1] + | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "v is 1L", @Empty = false, @Image = "\"v is 1L\"", @Length = 7, @LiteralText = "\"v is 1L\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] + | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2L", @IntLiteral = false, @Integral = true, @LiteralText = "2L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | | | +- ArgumentList[@Empty = false, @Size = 1] + | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "v is 2L", @Empty = false, @Image = "\"v is 2L\"", @Length = 7, @LiteralText = "\"v is 2L\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] + | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "10_000_000_000L", @IntLiteral = false, @Integral = true, @LiteralText = "10_000_000_000L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0E10, @ValueAsFloat = 1.0E10, @ValueAsInt = 1410065408, @ValueAsLong = 10000000000] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | | | +- ArgumentList[@Empty = false, @Size = 1] + | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "v is 10b", @Empty = false, @Image = "\"v is 10b\"", @Length = 8, @LiteralText = "\"v is 10b\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] + | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "20_000_000_000L", @IntLiteral = false, @Integral = true, @LiteralText = "20_000_000_000L", @LongLiteral = true, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0E10, @ValueAsFloat = 2.0E10, @ValueAsInt = -1474836480, @ValueAsLong = 20000000000] + | | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | | | +- ArgumentList[@Empty = false, @Size = 1] + | | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "v is 20b", @Empty = false, @Image = "\"v is 20b\"", @Length = 8, @LiteralText = "\"v is 20b\"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- SwitchArrowBranch[@Default = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] + | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.LONG] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | | +- ArgumentList[@Empty = false, @Size = 1] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "v is ", @Empty = false, @Image = "\"v is \"", @Length = 5, @LiteralText = "\"v is \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | +- Block[@Empty = false, @Size = 2, @containsComment = false] + | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Byte"] + | | | +- VariableDeclarator[@Initializer = true, @Name = "b"] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "b", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "2", @IntLiteral = true, @Integral = true, @LiteralText = "2", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 2.0, @ValueAsFloat = 2.0, @ValueAsInt = 2, @ValueAsLong = 2] + | | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchArrowBranch[@Default = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] + | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "p", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- Block[@Empty = true, @Size = 0, @containsComment = false] + | +- Block[@Empty = false, @Size = 2, @containsComment = false] + | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | | +- VariableDeclarator[@Initializer = true, @Name = "x"] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "x", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "42", @IntLiteral = true, @Integral = true, @LiteralText = "42", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 42.0, @ValueAsFloat = 42.0, @ValueAsInt = 42, @ValueAsLong = 42] + | | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchArrowBranch[@Default = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] + | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "_", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = true, @Visibility = Visibility.V_LOCAL] + | | +- Block[@Empty = true, @Size = 0, @containsComment = false] + | +- Block[@Empty = false, @Size = 2, @containsComment = false] + | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] + | | | +- VariableDeclarator[@Initializer = true, @Name = "v"] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "v", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "1.1f", @IntLiteral = false, @Integral = false, @LiteralText = "1.1f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.1, @ValueAsFloat = 1.1, @ValueAsInt = 1, @ValueAsLong = 1] + | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] + | | +- VariableDeclarator[@Initializer = true, @Name = "result"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "result", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- SwitchExpression[@CompileTimeConstant = false, @DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "v", @Name = "v", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] + | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "0f", @IntLiteral = false, @Integral = false, @LiteralText = "0f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 0.0, @ValueAsFloat = 0.0, @ValueAsInt = 0, @ValueAsLong = 0] + | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "5f", @IntLiteral = false, @Integral = false, @LiteralText = "5f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 5.0, @ValueAsFloat = 5.0, @ValueAsInt = 5, @ValueAsLong = 5] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] + | | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] + | | | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | | | +- Guard[] + | | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.EQ, @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "1f", @IntLiteral = false, @Integral = false, @LiteralText = "1f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] + | | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] + | | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "6f", @IntLiteral = false, @Integral = false, @LiteralText = "6f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 6.0, @ValueAsFloat = 6.0, @ValueAsInt = 6, @ValueAsLong = 6] + | | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchArrowBranch[@Default = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] + | | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "7f", @IntLiteral = false, @Integral = false, @LiteralText = "7f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 7.0, @ValueAsFloat = 7.0, @ValueAsInt = 7, @ValueAsLong = 7] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "x", @Name = "x", @ParenthesisDepth = 0, @Parenthesized = false] + | +- Block[@Empty = false, @Size = 2, @containsComment = false] + | | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BOOLEAN] + | | | +- VariableDeclarator[@Initializer = true, @Name = "v"] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "v", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | | +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "true", @ParenthesisDepth = 0, @Parenthesized = false, @True = true] + | | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "v", @Name = "v", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- SwitchArrowBranch[@Default = false] + | | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] + | | | | +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "true", @ParenthesisDepth = 0, @Parenthesized = false, @True = true] + | | | +- Block[@Empty = true, @Size = 0, @containsComment = false] + | | +- SwitchArrowBranch[@Default = false] + | | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = false] + | | | +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "false", @ParenthesisDepth = 0, @Parenthesized = false, @True = false] + | | +- Block[@Empty = true, @Size = 0, @containsComment = false] + | +- Block[@Empty = false, @Size = 2, @containsComment = false] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- VariableDeclarator[@Initializer = true, @Name = "i"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1", @IntLiteral = true, @Integral = true, @LiteralText = "1", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.0, @ValueAsFloat = 1.0, @ValueAsInt = 1, @ValueAsLong = 1] + | +- SwitchStatement[@DefaultCase = false, @EnumSwitch = false, @Exhaustive = true, @ExhaustiveEnumSwitch = false, @FallthroughSwitch = false, @NullTolerant = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | +- SwitchArrowBranch[@Default = false] + | +- SwitchLabel[@CaseNull = false, @Default = false, @PatternLabel = true] + | | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "d", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false] + | +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"] + | +- ArgumentList[@Empty = false, @Size = 1] + | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false] + | +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "double: ", @Empty = false, @Image = "\"double: \"", @Length = 8, @LiteralText = "\"double: \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] + +- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch$User", @CanonicalName = "Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch.User", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "User", @Static = false, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- ClassBody[@Empty = false, @Size = 6] + | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "isLoggedIn", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = false] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BOOLEAN] + | | +- FormalParameters[@Empty = true, @Size = 0] + | | +- Block[@Empty = false, @Size = 1, @containsComment = false] + | | +- ReturnStatement[] + | | +- BooleanLiteral[@CompileTimeConstant = true, @LiteralText = "false", @ParenthesisDepth = 0, @Parenthesized = false, @True = false] + | +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "id", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = false] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- FormalParameters[@Empty = true, @Size = 0] + | | +- Block[@Empty = false, @Size = 1, @containsComment = false] + | | +- ReturnStatement[] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "42", @IntLiteral = true, @Integral = true, @LiteralText = "42", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 42.0, @ValueAsFloat = 42.0, @ValueAsInt = 42, @ValueAsLong = 42] + | +- MethodDeclaration[@Abstract = false, @Arity = 2, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "startProcessing", @Overridden = false, @Static = true, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + | | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC), @ExplicitModifiers = (JModifier.STATIC)] + | | +- VoidType[] + | | +- FormalParameters[@Empty = false, @Size = 2] + | | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] + | | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "OrderStatus"] + | | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "status", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "userId", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- Block[@Empty = true, @Size = 0, @containsComment = false] + | +- MethodDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "log", @Overridden = false, @Static = true, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + | | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC), @ExplicitModifiers = (JModifier.STATIC)] + | | +- VoidType[] + | | +- FormalParameters[@Empty = false, @Size = 1] + | | | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL] + | | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"] + | | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- Block[@Empty = true, @Size = 0, @containsComment = false] + | +- EnumDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch$User$OrderStatus", @CanonicalName = "Jep530_PrimitiveTypesInPatternsInstanceofAndSwitch.User.OrderStatus", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = true, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = false, @RegularClass = false, @RegularInterface = false, @SimpleName = "OrderStatus", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE] + | | +- ModifierList[@EffectiveModifiers = (JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = ()] + | | +- EnumBody[@Empty = false, @SeparatorSemi = false, @Size = 1, @TrailingComma = false] + | | +- EnumConstant[@AnonymousClass = false, @EffectiveVisibility = Visibility.V_PACKAGE, @Image = "NEW", @MethodName = "new", @Name = "NEW", @Visibility = Visibility.V_PUBLIC] + | | +- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC, JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = ()] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_PACKAGE, @EnumConstant = true, @ExceptionBlockParameter = false, @Field = false, @Final = true, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "NEW", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = true, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_PUBLIC] + | +- EmptyDeclaration[] + +- MethodDeclaration[@Abstract = false, @Arity = 0, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "instanceofAsThePreconditionForSafeCasting", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true] + +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + +- VoidType[] + +- FormalParameters[@Empty = true, @Size = 0] + +- Block[@Empty = false, @Size = 8, @containsComment = false] + +- Block[@Empty = false, @Size = 2, @containsComment = true] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] + | | +- VariableDeclarator[@Initializer = true, @Name = "b"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "b", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "42", @IntLiteral = true, @Integral = true, @LiteralText = "42", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 42.0, @ValueAsFloat = 42.0, @ValueAsInt = 42, @ValueAsLong = 42] + | +- AssertStatement[@DetailMessage = false] + | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "b", @Name = "b", @ParenthesisDepth = 0, @Parenthesized = false] + | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + +- Block[@Empty = false, @Size = 2, @containsComment = true] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- VariableDeclarator[@Initializer = true, @Name = "i"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "42", @IntLiteral = true, @Integral = true, @LiteralText = "42", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 42.0, @ValueAsFloat = 42.0, @ValueAsInt = 42, @ValueAsLong = 42] + | +- AssertStatement[@DetailMessage = false] + | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] + +- Block[@Empty = false, @Size = 2, @containsComment = true] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- VariableDeclarator[@Initializer = true, @Name = "i"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1000", @IntLiteral = true, @Integral = true, @LiteralText = "1000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1000.0, @ValueAsFloat = 1000.0, @ValueAsInt = 1000, @ValueAsLong = 1000] + | +- AssertStatement[@DetailMessage = false] + | +- UnaryExpression[@CompileTimeConstant = false, @Operator = UnaryOp.NEGATION, @ParenthesisDepth = 0, @Parenthesized = false] + | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] + +- Block[@Empty = false, @Size = 5, @containsComment = true] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | | +- VariableDeclarator[@Initializer = true, @Name = "i"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "i", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "16_777_217", @IntLiteral = true, @Integral = true, @LiteralText = "16_777_217", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.6777217E7, @ValueAsFloat = 1.6777216E7, @ValueAsInt = 16777217, @ValueAsLong = 16777217] + | +- AssertStatement[@DetailMessage = false] + | | +- UnaryExpression[@CompileTimeConstant = false, @Operator = UnaryOp.NEGATION, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] + | +- AssertStatement[@DetailMessage = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] + | +- AssertStatement[@DetailMessage = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] + | +- AssertStatement[@DetailMessage = false] + | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "i", @Name = "i", @ParenthesisDepth = 0, @Parenthesized = false] + | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Number"] + +- Block[@Empty = false, @Size = 4, @containsComment = true] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] + | | +- VariableDeclarator[@Initializer = true, @Name = "f"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "f", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = true, @Image = "1000.0f", @IntLiteral = false, @Integral = false, @LiteralText = "1000.0f", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1000.0, @ValueAsFloat = 1000.0, @ValueAsInt = 1000, @ValueAsLong = 1000] + | +- AssertStatement[@DetailMessage = false] + | | +- UnaryExpression[@CompileTimeConstant = false, @Operator = UnaryOp.NEGATION, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "f", @Name = "f", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] + | +- AssertStatement[@DetailMessage = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "f", @Name = "f", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | +- AssertStatement[@DetailMessage = false] + | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "f", @Name = "f", @ParenthesisDepth = 0, @Parenthesized = false] + | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] + +- Block[@Empty = false, @Size = 4, @containsComment = true] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] + | | +- VariableDeclarator[@Initializer = true, @Name = "d"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "d", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = true, @FloatLiteral = false, @Image = "1000.0d", @IntLiteral = false, @Integral = false, @LiteralText = "1000.0d", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1000.0, @ValueAsFloat = 1000.0, @ValueAsInt = 1000, @ValueAsLong = 1000] + | +- AssertStatement[@DetailMessage = false] + | | +- UnaryExpression[@CompileTimeConstant = false, @Operator = UnaryOp.NEGATION, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.BYTE] + | +- AssertStatement[@DetailMessage = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | +- AssertStatement[@DetailMessage = false] + | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "d", @Name = "d", @ParenthesisDepth = 0, @Parenthesized = false] + | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] + +- Block[@Empty = false, @Size = 4, @containsComment = true] + | +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] + | | +- VariableDeclarator[@Initializer = true, @Name = "ii"] + | | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "ii", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "1000", @IntLiteral = true, @Integral = true, @LiteralText = "1000", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1000.0, @ValueAsFloat = 1000.0, @ValueAsInt = 1000, @ValueAsLong = 1000] + | +- AssertStatement[@DetailMessage = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "ii", @Name = "ii", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.INT] + | +- AssertStatement[@DetailMessage = false] + | | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "ii", @Name = "ii", @ParenthesisDepth = 0, @Parenthesized = false] + | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] + | +- AssertStatement[@DetailMessage = false] + | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "ii", @Name = "ii", @ParenthesisDepth = 0, @Parenthesized = false] + | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] + +- Block[@Empty = false, @Size = 3, @containsComment = true] + +- LocalVariableDeclaration[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @TypeInferred = false, @Visibility = Visibility.V_LOCAL] + | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()] + | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Integer"] + | +- VariableDeclarator[@Initializer = true, @Name = "ii"] + | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = true, @Name = "ii", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL] + | +- NumericLiteral[@Base = 10, @CompileTimeConstant = true, @DoubleLiteral = false, @FloatLiteral = false, @Image = "16_777_217", @IntLiteral = true, @Integral = true, @LiteralText = "16_777_217", @LongLiteral = false, @ParenthesisDepth = 0, @Parenthesized = false, @ValueAsDouble = 1.6777217E7, @ValueAsFloat = 1.6777216E7, @ValueAsInt = 16777217, @ValueAsLong = 16777217] + +- AssertStatement[@DetailMessage = false] + | +- UnaryExpression[@CompileTimeConstant = false, @Operator = UnaryOp.NEGATION, @ParenthesisDepth = 0, @Parenthesized = false] + | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 1, @Parenthesized = true] + | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "ii", @Name = "ii", @ParenthesisDepth = 0, @Parenthesized = false] + | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + | +- PrimitiveType[@Kind = PrimitiveTypeKind.FLOAT] + +- AssertStatement[@DetailMessage = false] + +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false] + +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "ii", @Name = "ii", @ParenthesisDepth = 0, @Parenthesized = false] + +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false] + +- PrimitiveType[@Kind = PrimitiveTypeKind.DOUBLE] From d0323efdb60ba381ff6bd90b880428bdb9b1ab4e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 5 Jan 2026 11:00:37 +0100 Subject: [PATCH 1824/1962] [java] Move standardized Preview Language Features to Regular Features --- .../ast/internal/LanguageLevelChecker.java | 60 +++++++++---------- .../pmd/lang/java/ast/Java25TreeDumpTest.java | 6 +- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java index 3bafdbb27f5..afe7751c55d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/LanguageLevelChecker.java @@ -129,33 +129,6 @@ private static String versionDisplayName(int jdk) { * They might be also be standardized. */ private enum PreviewFeature implements LanguageFeature { - /** - * Compact Source Files and Instance Main Methods - * @see JEP 445: Unnamed Classes and Instance Main Methods (Preview) (Java 21) - * @see JEP 463: Implicitly Declared Classes and Instance Main Methods (Second Preview) (Java 22) - * @see JEP 477: Implicitly Declared Classes and Instance Main Methods (Third Preview) (Java 23) - * @see JEP 495: Simple Source Files and Instance Main Methods (Fourth Preview) (Java 24) - * @see JEP 512: Compact Source Files and Instance Main Methods (Java 25) - */ - COMPACT_SOURCE_FILES_AND_INSTANCE_MAIN_METHODS(22, 24, true), - - /** - * Flexible Constructor Bodies - * @see JEP 447: Statements before super(...) (Preview) (Java 22) - * @see JEP 482: Flexible Constructor Bodies (Second Preview) (Java 23) - * @see JEP 492: Flexible Constructor Bodies (Third Preview) (Java 24) - * @see JEP 513: Flexible Constructor Bodies (Java 25) - */ - FLEXIBLE_CONSTRUCTOR_BODIES(22, 24, true), - - /** - * Module import declarations - * @see JEP 476: Module Import Declarations (Preview) (Java 23) - * @see JEP 494: Module Import Declarations (Second Preview) (Java 24) - * @see JEP 511: Module Import Declarations (Java 25) - */ - MODULE_IMPORT_DECLARATIONS(23, 24, true), - /** * Primitive types in patterns, instanceof, and switch * @see JEP 455: Primitive Types in Patterns, instanceof, and switch (Preview) (Java 23) @@ -404,6 +377,33 @@ private enum RegularLanguageFeature implements LanguageFeature { */ UNNAMED_VARIABLES_AND_PATTERNS(22), + /** + * Compact Source Files and Instance Main Methods + * @see JEP 445: Unnamed Classes and Instance Main Methods (Preview) (Java 21) + * @see JEP 463: Implicitly Declared Classes and Instance Main Methods (Second Preview) (Java 22) + * @see JEP 477: Implicitly Declared Classes and Instance Main Methods (Third Preview) (Java 23) + * @see JEP 495: Simple Source Files and Instance Main Methods (Fourth Preview) (Java 24) + * @see JEP 512: Compact Source Files and Instance Main Methods (Java 25) + */ + COMPACT_SOURCE_FILES_AND_INSTANCE_MAIN_METHODS(25), + + /** + * Flexible Constructor Bodies + * @see JEP 447: Statements before super(...) (Preview) (Java 22) + * @see JEP 482: Flexible Constructor Bodies (Second Preview) (Java 23) + * @see JEP 492: Flexible Constructor Bodies (Third Preview) (Java 24) + * @see JEP 513: Flexible Constructor Bodies (Java 25) + */ + FLEXIBLE_CONSTRUCTOR_BODIES(25), + + /** + * Module import declarations + * @see JEP 476: Module Import Declarations (Preview) (Java 23) + * @see JEP 494: Module Import Declarations (Second Preview) (Java 24) + * @see JEP 511: Module Import Declarations (Java 25) + */ + MODULE_IMPORT_DECLARATIONS(25), + ; // SUPPRESS CHECKSTYLE enum trailing semi is awesome private final int minJdkLevel; @@ -445,7 +445,7 @@ public Void visitNode(Node node, T param) { @Override public Void visit(ASTImplicitClassDeclaration node, T data) { - check(node, PreviewFeature.COMPACT_SOURCE_FILES_AND_INSTANCE_MAIN_METHODS, data); + check(node, RegularLanguageFeature.COMPACT_SOURCE_FILES_AND_INSTANCE_MAIN_METHODS, data); return null; } @@ -466,7 +466,7 @@ public Void visit(ASTImportDeclaration node, T data) { check(node, RegularLanguageFeature.STATIC_IMPORT, data); } if (node.isModuleImport()) { - check(node, PreviewFeature.MODULE_IMPORT_DECLARATIONS, data); + check(node, RegularLanguageFeature.MODULE_IMPORT_DECLARATIONS, data); } return null; } @@ -727,7 +727,7 @@ public Void visit(ASTConstructorDeclaration node, T data) { super.visit(node, data); if (node.getBody().descendants(ASTExplicitConstructorInvocation.class).nonEmpty()) { if (!(node.getBody().getFirstChild() instanceof ASTExplicitConstructorInvocation)) { - check(node, PreviewFeature.FLEXIBLE_CONSTRUCTOR_BODIES, data); + check(node, RegularLanguageFeature.FLEXIBLE_CONSTRUCTOR_BODIES, data); } } return null; diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java index 348751441f8..f7137bbd43c 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java25TreeDumpTest.java @@ -43,7 +43,7 @@ void jep513FlexibleConstructorBodies() { @Test void jep513FlexibleConstructorBodiesBeforeJava25() { ParseException thrown = assertThrows(ParseException.class, () -> java24.parseResource("Jep513_FlexibleConstructorBodies.java")); - assertThat(thrown.getMessage(), containsString("Flexible constructor bodies was only standardized in Java 25, you should select your language version accordingly")); + assertThat(thrown.getMessage(), containsString("Flexible constructor bodies are a feature of Java 25, you should select your language version accordingly")); } @Test @@ -54,7 +54,7 @@ void jep511ModuleImportDeclarations() { @Test void jep511ModuleImportDeclarationsBeforeJava25() { ParseException thrown = assertThrows(ParseException.class, () -> java24.parseResource("Jep511_ModuleImportDeclarations.java")); - assertThat(thrown.getMessage(), containsString("Module import declarations was only standardized in Java 25, you should select your language version accordingly")); + assertThat(thrown.getMessage(), containsString("Module import declarations are a feature of Java 25, you should select your language version accordingly")); } @Test @@ -99,7 +99,7 @@ void jep512CompactSourceFilesAndInstanceMainMethodsVerifyTypes() { @Test void jep512CompactSourceFilesAndInstanceMainMethodsBeforeJava24Preview() { ParseException thrown = assertThrows(ParseException.class, () -> java24.parseResource("Jep512_CompactSourceFilesAndInstanceMainMethodsAfterJava23.java")); - assertThat(thrown.getMessage(), containsString("Compact source files and instance main methods was only standardized in Java 25, you should select your language version accordingly")); + assertThat(thrown.getMessage(), containsString("Compact source files and instance main methods are a feature of Java 25, you should select your language version accordingly")); } } From f24a53cb20e08435a0ff5aad5a7fb9a63de97373 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 5 Jan 2026 11:19:08 +0100 Subject: [PATCH 1825/1962] [doc] Update release notes (#5871) --- docs/pages/release_notes.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..aa96faea822 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -24,7 +24,25 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy +#### ๐Ÿš€๏ธ New: Java 26 Support +This release of PMD brings support for Java 26. + +There are no new standard language features. + +There is one preview language feature: +* [JEP 530: Primitive Types in Patterns, instanceof, and switch (Fourth Preview)](https://openjdk.org/jeps/530) + +In order to analyze a project with PMD that uses these preview language features, +you'll need to select the new language version `26-preview`: + + pmd check --use-version java-26-preview ... + +Note: Support for Java 24 preview language features have been removed. The version "24-preview" +is no longer available. + ### ๐Ÿ›๏ธ Fixed Issues +* java + * [#5871](https://github.com/pmd/pmd/issues/5871): \[java] Support Java 26 ### ๐Ÿšจ๏ธ API Changes From 4af864b34ffa282806a63ec545e0b16c273bf979 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 5 Jan 2026 14:47:15 +0100 Subject: [PATCH 1826/1962] [java] Remove unneeded PMD_JAVA_OPTS for preview features Since we use asm for reading classfiles and not reflection, `--enable-preview` is not needed anymore. --- docs/pages/pmd/languages/java.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/pages/pmd/languages/java.md b/docs/pages/pmd/languages/java.md index 566e8d970fc..eda22f572f6 100644 --- a/docs/pages/pmd/languages/java.md +++ b/docs/pages/pmd/languages/java.md @@ -44,11 +44,10 @@ Usually the latest non-preview Java Version is the default version. ## Using Java preview features -In order to analyze a project with PMD that uses preview language features, you'll need to enable -it via the environment variable `PMD_JAVA_OPTS` and select the new language version, e.g. `24-preview`: +In order to analyze a project with PMD that uses preview language features, you'll need to +select the new language version, e.g. `26-preview`: - export PMD_JAVA_OPTS=--enable-preview - pmd check --use-version java-24-preview ... + pmd check --use-version java-26-preview ... Note: we only support preview language features for the latest two java versions. From d8ec07149a7dfab9276e22692ffdf86dedf3cfa1 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Tue, 6 Jan 2026 06:35:58 +0100 Subject: [PATCH 1827/1962] Clarify typos config, fix TestNG capitalization --- docs/pages/release_notes_pmd7.md | 2 +- .../rule/internal/TestFrameworksUtil.java | 4 ++-- typos.toml | 21 +++++++++---------- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/docs/pages/release_notes_pmd7.md b/docs/pages/release_notes_pmd7.md index 9e702da98a9..b81c7bd274c 100644 --- a/docs/pages/release_notes_pmd7.md +++ b/docs/pages/release_notes_pmd7.md @@ -3512,7 +3512,7 @@ Language specific fixes: * [#4488](https://github.com/pmd/pmd/pull/4488): \[java] Fix #4477: A false-positive about SignatureDeclareThrowsException - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe) * [#4494](https://github.com/pmd/pmd/pull/4494): \[java] Fix #4487: A false-positive about UnnecessaryConstructor and @Inject and @Autowired - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe) * [#4495](https://github.com/pmd/pmd/pull/4495): \[java] Fix #4493: false-positive about MissingStaticMethodInNonInstantiatableClass and @Inject - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe) -* [#4507](https://github.com/pmd/pmd/pull/4507): \[java] Fix #4503: A false negative about JUnitTestsShouldIncludeAssert and testng - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe) +* [#4507](https://github.com/pmd/pmd/pull/4507): \[java] Fix #4503: A false negative about JUnitTestsShouldIncludeAssert and TestNG - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe) * [#4520](https://github.com/pmd/pmd/pull/4520): \[doc] Fix typo: missing closing quotation mark after CPD-END - [Joรฃo Dinis Ferreira](https://github.com/joaodinissf) (@joaodinissf) * [#4528](https://github.com/pmd/pmd/pull/4528): \[apex] Update to apexlink - [Kevin Jones](https://github.com/nawforce) (@nawforce) * [#4533](https://github.com/pmd/pmd/pull/4533): \[java] Fix #4063: False-negative about try/catch block in Loop - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java index 0e00cec5c01..4542c955af6 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java @@ -27,7 +27,7 @@ public final class TestFrameworksUtil { private static final String JUNIT3_CLASS_NAME = "junit.framework.TestCase"; private static final String JUNIT4_TEST_ANNOT = "org.junit.Test"; - private static final String TESTNG_TEST_ANNOT = "org.testng.annotations.Test"; + private static final String TEST_NG_TEST_ANNOT = "org.testng.annotations.Test"; private static final Set JUNIT5_ALL_TEST_ANNOTS = setOf("org.junit.jupiter.api.Test", @@ -99,7 +99,7 @@ public static boolean isTestConfigurationMethod(ASTMethodDeclaration method) { } private static boolean isTestNgMethod(ASTMethodDeclaration method) { - return method.isAnnotationPresent(TESTNG_TEST_ANNOT); + return method.isAnnotationPresent(TEST_NG_TEST_ANNOT); } public static boolean isJUnit4Method(ASTMethodDeclaration method) { diff --git a/typos.toml b/typos.toml index cb929c62dd6..ec7eef993cc 100644 --- a/typos.toml +++ b/typos.toml @@ -12,30 +12,29 @@ extend-exclude = [ "Swift4.2.txt", "Issue628.txt", "sample-matlab.txt", - "sample_python.txt" + "sample_python.txt", + "btrfs.txt" ] - [default.extend-words] # public API verbatium="verbatium" # Apex terminology Createable = "Createable" -# Generally acceptable -incrementers = "incrementers" # lowercase for TestNG -testng = "testng" +# # TSQL token name iif="iif" +# Unicode range +nd = "nd" +# part of PROCEDURE_SCHEM +schem="schem" # Short strings used as identifiers typ = "typ" ba = "ba" -fo="fo" -thr="thr" -strat = "strat" +fo = "fo" parm = "parm" -nd = "nd" -schem="schem" +strat = "strat" ois = "ois" parms = "parms" opps = "opps" @@ -67,4 +66,4 @@ Hendler="Hendler" Ure="Ure" [default] -extend-ignore-re = [".*pn\\\\3\\\\2" ] +extend-ignore-re = ["pn\\\\3\\\\2", "thr\\(ough", "org.testng" ] From 86ace98f0f7fe0608f96f28d3a584ce4b3150854 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 6 Jan 2026 18:12:56 +0100 Subject: [PATCH 1828/1962] [doc] Add update-last-updated.sh helper script --- docs/update-last-updated.sh | 54 +++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100755 docs/update-last-updated.sh diff --git a/docs/update-last-updated.sh b/docs/update-last-updated.sh new file mode 100755 index 00000000000..903187e03af --- /dev/null +++ b/docs/update-last-updated.sh @@ -0,0 +1,54 @@ +#!/bin/bash +# +# BSD-style license; for more info see http://pmd.sourceforge.net/license.html +# + +# Helper script, that updates the "last_updated" field in the front matter based on the git info. +# It searches in the current directory. +# +# Usage: +# ./update-last-updated.sh +# +# This will update all markdown files. Then review the changed files +# and commit or revert. +# +# ./update-last-updated.sh pages/pmd/about/help.md +# +# Updates a single file only. +# + +function process_file() { + FILE="$1" + echo -n "$FILE: " + read -ra COMMIT_INFO < <(git log -1 --pretty="%cI %H" "$FILE") + #echo "Date: ${COMMIT_INFO[0]}" + #echo "Commit: ${COMMIT_INFO[1]}" + + DATE=$(date --date="${COMMIT_INFO[0]}" "+%B %Y") + + TAG="$(git describe --contains "${COMMIT_INFO[1]}")" + TAG="${TAG%%~*}" + TAG="${TAG#pmd_releases/}" + #echo "Version: $TAG" + + LAST_UPDATED="last_updated: $DATE ($TAG)" + echo "$LAST_UPDATED" + sed -i -e "s/^last_updated:.*\$/$LAST_UPDATED/" "$FILE" +} + +# English locale - needed when creating the date +export LANG="en_US.UTF-8" + +if [ -n "$1" ]; then + # single file given + process_file "$1" +else + # no file given, search for all markdown files in current directory + # ignore files in directory "vendor" + for i in `find . -type d -name vendor -prune -o -type f -name "*.md" -print`; do + # only consider files, that are under version control + if git ls-files --error-unmatch "$i" >/dev/null 2>&1; then + process_file "$i" + fi + done +fi From 1ac42cf5993b722d9d885dcf82963e0f59b1f2e1 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 6 Jan 2026 18:53:02 +0100 Subject: [PATCH 1829/1962] [doc] Improve update-last-updated.sh to ignore front matter --- docs/update-last-updated.sh | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/update-last-updated.sh b/docs/update-last-updated.sh index 903187e03af..10aa005d2e8 100755 --- a/docs/update-last-updated.sh +++ b/docs/update-last-updated.sh @@ -20,15 +20,21 @@ function process_file() { FILE="$1" echo -n "$FILE: " - read -ra COMMIT_INFO < <(git log -1 --pretty="%cI %H" "$FILE") + + LINE_NUMBER_FRONT_MATTER_END=$(grep -n -e "---" "$FILE"|head -2|tail -1|cut -d ":" -f 1) + LINE_NUMBER_FRONT_MATTER_END=$((LINE_NUMBER_FRONT_MATTER_END + 1)) + read -ra COMMIT_INFO < <(git annotate -L $LINE_NUMBER_FRONT_MATTER_END -t "$FILE"| cut -f 1,3|sed -e 's/\(.\+\)\t\(.\+\) .\+/\2 \1/'|sort|tail -1) #echo "Date: ${COMMIT_INFO[0]}" #echo "Commit: ${COMMIT_INFO[1]}" - DATE=$(date --date="${COMMIT_INFO[0]}" "+%B %Y") + DATE=$(date --date="@${COMMIT_INFO[0]}" "+%B %Y") TAG="$(git describe --contains "${COMMIT_INFO[1]}")" TAG="${TAG%%~*}" TAG="${TAG#pmd_releases/}" + if [[ $TAG = 7.0.0-* ]]; then + TAG="7.0.0" + fi #echo "Version: $TAG" LAST_UPDATED="last_updated: $DATE ($TAG)" @@ -45,10 +51,11 @@ if [ -n "$1" ]; then else # no file given, search for all markdown files in current directory # ignore files in directory "vendor" - for i in `find . -type d -name vendor -prune -o -type f -name "*.md" -print`; do + while IFS= read -r -d '' i + do # only consider files, that are under version control if git ls-files --error-unmatch "$i" >/dev/null 2>&1; then process_file "$i" fi - done + done < <(find . -type d -name vendor -prune -o -type f -name "*.md" -print0) fi From 0da9ed8d07eac07c8aa6a5f828ef48da4d8a2346 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 6 Jan 2026 18:24:29 +0100 Subject: [PATCH 1830/1962] [doc] Update last_updated info --- docs/index.md | 2 +- docs/pages/pmd/about/help.md | 2 +- docs/pages/pmd/about/release_policies.md | 2 +- docs/pages/pmd/about/security.md | 2 +- docs/pages/pmd/about/support_lifecycle.md | 2 +- docs/pages/pmd/devdocs/building/building_general.md | 2 +- docs/pages/pmd/devdocs/contributing/newcomers_guide.md | 2 +- docs/pages/pmd/devdocs/contributing/writing_documentation.md | 4 ++-- docs/pages/pmd/devdocs/how_pmd_works.md | 2 +- .../major_contributions/adding_a_new_antlr_based_language.md | 2 +- .../devdocs/major_contributions/adding_new_cpd_language.md | 2 +- docs/pages/pmd/devdocs/major_contributions/rule_guidelines.md | 2 +- docs/pages/pmd/devdocs/rule_deprecation.md | 2 +- docs/pages/pmd/languages/apex.md | 2 +- docs/pages/pmd/languages/groovy.md | 2 +- docs/pages/pmd/languages/html.md | 2 +- docs/pages/pmd/languages/kotlin.md | 2 +- docs/pages/pmd/languages/modelica.md | 2 +- docs/pages/pmd/languages/swift.md | 2 +- docs/pages/pmd/languages/velocity.md | 2 +- docs/pages/pmd/languages/xml.md | 2 +- docs/pages/pmd/projectdocs/committers/main_landing_page.md | 2 +- .../pages/pmd/projectdocs/committers/merging_pull_requests.md | 2 +- docs/pages/pmd/projectdocs/decisions.md | 2 +- docs/pages/pmd/projectdocs/decisions/adr-1.md | 2 +- docs/pages/pmd/projectdocs/decisions/adr-2.md | 2 +- docs/pages/pmd/projectdocs/decisions/adr-3.md | 2 +- docs/pages/pmd/projectdocs/decisions/adr-NNN.md | 2 +- docs/pages/pmd/userdocs/3rdpartyrulesets.md | 4 ++-- docs/pages/pmd/userdocs/best_practices.md | 2 +- docs/pages/pmd/userdocs/configuring_rules.md | 2 +- docs/pages/pmd/userdocs/cpd/cpd_report_formats.md | 2 +- docs/pages/pmd/userdocs/extending/ast_dump.md | 2 +- docs/pages/pmd/userdocs/extending/defining_properties.md | 2 +- docs/pages/pmd/userdocs/extending/designer_reference.md | 2 +- docs/pages/pmd/userdocs/extending/testing.md | 2 +- docs/pages/pmd/userdocs/extending/writing_java_rules.md | 2 +- docs/pages/pmd/userdocs/extending/writing_rules_intro.md | 2 +- docs/pages/pmd/userdocs/extending/writing_xpath_rules.md | 2 +- docs/pages/pmd/userdocs/extending/your_first_rule.md | 2 +- docs/pages/pmd/userdocs/making_rulesets.md | 2 +- docs/pages/pmd/userdocs/suppressing_warnings.md | 2 +- docs/pages/pmd/userdocs/tools/bld.md | 2 +- docs/pages/pmd/userdocs/tools/java-api.md | 2 +- docs/pages/pmd/userdocs/tools/maven.md | 2 +- 45 files changed, 47 insertions(+), 47 deletions(-) diff --git a/docs/index.md b/docs/index.md index d1141fb98ad..663ef01e5bd 100644 --- a/docs/index.md +++ b/docs/index.md @@ -7,7 +7,7 @@ summary: > Welcome to the documentation site for PMD and CPD!

          -last_updated: October 2022 +last_updated: October 2025 (7.18.0) author: Jeff Jensen , Andreas Dangel , Clรฉment Fournier diff --git a/docs/pages/pmd/about/help.md b/docs/pages/pmd/about/help.md index 5d276779e8f..3bc301e6a6c 100644 --- a/docs/pages/pmd/about/help.md +++ b/docs/pages/pmd/about/help.md @@ -2,7 +2,7 @@ title: Getting Help permalink: pmd_about_help.html author: Andreas Dangel -last_updated: November 2024 +last_updated: November 2024 (7.8.0) --- There are numerous ways of getting help: diff --git a/docs/pages/pmd/about/release_policies.md b/docs/pages/pmd/about/release_policies.md index 21e4d2c2e36..5b1311e5bad 100644 --- a/docs/pages/pmd/about/release_policies.md +++ b/docs/pages/pmd/about/release_policies.md @@ -2,7 +2,7 @@ title: Release schedule and version policies permalink: pmd_about_release_policies.html author: Andreas Dangel -last_updated: June 2024 (PMD 7.3.0) +last_updated: September 2024 (7.6.0) --- ## Release schedule diff --git a/docs/pages/pmd/about/security.md b/docs/pages/pmd/about/security.md index 7743f2f7917..519003779f0 100644 --- a/docs/pages/pmd/about/security.md +++ b/docs/pages/pmd/about/security.md @@ -2,7 +2,7 @@ title: PMD Security permalink: pmd_about_security.html author: Andreas Dangel -last_updated: January 2025 (PMD 7.11.0) +last_updated: January 2025 (7.11.0) --- For reporting security issues, see [SECURITY.md](https://github.com/pmd/pmd/blob/main/SECURITY.md). diff --git a/docs/pages/pmd/about/support_lifecycle.md b/docs/pages/pmd/about/support_lifecycle.md index 437715949cf..7039536e259 100644 --- a/docs/pages/pmd/about/support_lifecycle.md +++ b/docs/pages/pmd/about/support_lifecycle.md @@ -2,7 +2,7 @@ title: Support lifecycle permalink: pmd_about_support_lifecycle.html author: Andreas Dangel -last_updated: June 2024 (PMD 7.3.0) +last_updated: June 2024 (7.3.0) --- {% capture latest_release %}{{site.pmd.version}} ({{site.pmd.date | date: "%Y-%m-%d" }}){% endcapture %} diff --git a/docs/pages/pmd/devdocs/building/building_general.md b/docs/pages/pmd/devdocs/building/building_general.md index 7b4209a57a1..2cfc8852fae 100644 --- a/docs/pages/pmd/devdocs/building/building_general.md +++ b/docs/pages/pmd/devdocs/building/building_general.md @@ -3,7 +3,7 @@ title: Building PMD General Info tags: [devdocs] permalink: pmd_devdocs_building_general.html author: Andreas Dangel -last_updated: September 2025 (7.18.0) +last_updated: November 2025 (7.20.0) --- ## Before Development diff --git a/docs/pages/pmd/devdocs/contributing/newcomers_guide.md b/docs/pages/pmd/devdocs/contributing/newcomers_guide.md index f6882d31e55..8ee7c9338fa 100644 --- a/docs/pages/pmd/devdocs/contributing/newcomers_guide.md +++ b/docs/pages/pmd/devdocs/contributing/newcomers_guide.md @@ -3,7 +3,7 @@ title: Newcomers' Guide tags: [devdocs] permalink: pmd_devdocs_contributing_newcomers_guide.html author: Andreas Dangel -last_updated: January 2025 (7.10.0) +last_updated: November 2025 (7.20.0) --- This is a small guide for GSoC Students and new contributors. diff --git a/docs/pages/pmd/devdocs/contributing/writing_documentation.md b/docs/pages/pmd/devdocs/contributing/writing_documentation.md index 39a55cc9a7e..50708be6b63 100644 --- a/docs/pages/pmd/devdocs/contributing/writing_documentation.md +++ b/docs/pages/pmd/devdocs/contributing/writing_documentation.md @@ -1,7 +1,7 @@ --- title: Writing documentation tags: [devdocs] -last_updated: January 2025 (7.10.0) +last_updated: January 2026 (7.21.0) permalink: pmd_devdocs_writing_documentation.html keywords: documentation, jekyll, markdown author: Andreas Dangel @@ -150,7 +150,7 @@ You can prevent this with "toc: false". You can add **keywords**, that will be used for the on-site search: "keywords: documentation, jekyll, markdown" -It's useful to maintain a **last_update** field. This will be added at the bottom of the +It's useful to maintain a **last_updated** field. This will be added at the bottom of the page. A **summary** can also be provided. It will be added in a box before the content. diff --git a/docs/pages/pmd/devdocs/how_pmd_works.md b/docs/pages/pmd/devdocs/how_pmd_works.md index f91b76757d4..cae0aa5ed35 100644 --- a/docs/pages/pmd/devdocs/how_pmd_works.md +++ b/docs/pages/pmd/devdocs/how_pmd_works.md @@ -2,7 +2,7 @@ title: How PMD Works tags: [devdocs] summary: Processing overview of the different steps taken by PMD. -last_updated: September 2017 +last_updated: April 2023 (7.0.0) permalink: pmd_devdocs_how_pmd_works.html author: Tom Copeland, Andreas Dangel --- diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md index 605d135c2e3..7e8f58dd0d2 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md @@ -3,7 +3,7 @@ title: Adding PMD support for a new ANTLR grammar based language short_title: Adding a new language with ANTLR tags: [devdocs, extending] summary: "How to add a new language to PMD using ANTLR grammar." -last_updated: December 2023 (7.0.0) +last_updated: April 2025 (7.13.0) sidebar: pmd_sidebar permalink: pmd_devdocs_major_adding_new_language_antlr.html folder: pmd/devdocs diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md index a6a5c63c8a9..ab562b7f3e8 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md @@ -3,7 +3,7 @@ title: How to add a new CPD language short_title: Adding a new CPD language tags: [devdocs, extending] summary: How to add a new language module with CPD support. -last_updated: June 2024 (7.3.0) +last_updated: May 2025 (7.16.0) permalink: pmd_devdocs_major_adding_new_cpd_language.html author: Matรญas Fraga, Clรฉment Fournier --- diff --git a/docs/pages/pmd/devdocs/major_contributions/rule_guidelines.md b/docs/pages/pmd/devdocs/major_contributions/rule_guidelines.md index 2b252ba996c..8a2a977900b 100644 --- a/docs/pages/pmd/devdocs/major_contributions/rule_guidelines.md +++ b/docs/pages/pmd/devdocs/major_contributions/rule_guidelines.md @@ -3,7 +3,7 @@ title: Guidelines for standard rules short_title: Rule guidelines tags: [devdocs, extending] summary: "Guidelines for rules that are included in the standard distribution" -last_updated: August, 2021 +last_updated: August 2021 (6.38.0) sidebar: pmd_sidebar permalink: pmd_devdocs_major_rule_guidelines.html --- diff --git a/docs/pages/pmd/devdocs/rule_deprecation.md b/docs/pages/pmd/devdocs/rule_deprecation.md index a0ce7c08742..a9397a5cbe6 100644 --- a/docs/pages/pmd/devdocs/rule_deprecation.md +++ b/docs/pages/pmd/devdocs/rule_deprecation.md @@ -2,7 +2,7 @@ title: Rule deprecation policy tags: [devdocs] summary: Describes when and how rules are deprecated -last_updated: November 15, 2019 +last_updated: November 2019 (6.20.0) permalink: pmd_devdocs_rule_deprecation_policy.html author: Andreas Dangel --- diff --git a/docs/pages/pmd/languages/apex.md b/docs/pages/pmd/languages/apex.md index 1c5b19e64fc..e5ec4d32e2f 100644 --- a/docs/pages/pmd/languages/apex.md +++ b/docs/pages/pmd/languages/apex.md @@ -1,7 +1,7 @@ --- title: Apex support permalink: pmd_languages_apex.html -last_updated: September 2023 (7.0.0) +last_updated: March 2024 (7.0.0) author: Clรฉment Fournier tags: [languages, PmdCapableLanguage, CpdCapableLanguage] summary: "Apex-specific features and guidance" diff --git a/docs/pages/pmd/languages/groovy.md b/docs/pages/pmd/languages/groovy.md index 6b9e4c62fee..da02149b9e3 100644 --- a/docs/pages/pmd/languages/groovy.md +++ b/docs/pages/pmd/languages/groovy.md @@ -1,7 +1,7 @@ --- title: Groovy support permalink: pmd_languages_groovy.html -last_updated: September 2023 (7.0.0) +last_updated: December 2023 (7.0.0) tags: [languages, CpdCapableLanguage] summary: "Groovy-specific features and guidance" --- diff --git a/docs/pages/pmd/languages/html.md b/docs/pages/pmd/languages/html.md index dba9fc0e4ee..180554eba49 100644 --- a/docs/pages/pmd/languages/html.md +++ b/docs/pages/pmd/languages/html.md @@ -1,7 +1,7 @@ --- title: HTML support permalink: pmd_languages_html.html -last_updated: February 2024 (7.0.0) +last_updated: September 2023 (7.0.0) tags: [languages, PmdCapableLanguage, CpdCapableLanguage] summary: "HTML-specific features and guidance" --- diff --git a/docs/pages/pmd/languages/kotlin.md b/docs/pages/pmd/languages/kotlin.md index 29c04368e0b..36695d79073 100644 --- a/docs/pages/pmd/languages/kotlin.md +++ b/docs/pages/pmd/languages/kotlin.md @@ -1,7 +1,7 @@ --- title: Kotlin Support permalink: pmd_languages_kotlin.html -last_updated: February 2024 (7.0.0) +last_updated: March 2024 (7.0.0) tags: [languages, PmdCapableLanguage, CpdCapableLanguage] summary: "Kotlin-specific features and guidance" --- diff --git a/docs/pages/pmd/languages/modelica.md b/docs/pages/pmd/languages/modelica.md index 1ee363a7d82..fc95095f1cb 100644 --- a/docs/pages/pmd/languages/modelica.md +++ b/docs/pages/pmd/languages/modelica.md @@ -1,7 +1,7 @@ --- title: Modelica support permalink: pmd_languages_modelica.html -last_updated: September 2023 (7.0.0) +last_updated: March 2024 (7.0.0) tags: [languages, PmdCapableLanguage, CpdCapableLanguage] summary: "Modelica-specific features and guidance" --- diff --git a/docs/pages/pmd/languages/swift.md b/docs/pages/pmd/languages/swift.md index 1f93eed49ac..4881f636031 100644 --- a/docs/pages/pmd/languages/swift.md +++ b/docs/pages/pmd/languages/swift.md @@ -1,7 +1,7 @@ --- title: Swift support permalink: pmd_languages_swift.html -last_updated: September 2023 (7.0.0) +last_updated: December 2023 (7.0.0) tags: [languages, PmdCapableLanguage, CpdCapableLanguage] summary: "Swift-specific features and guidance" --- diff --git a/docs/pages/pmd/languages/velocity.md b/docs/pages/pmd/languages/velocity.md index d2fa81480b9..6f38a71d7c9 100644 --- a/docs/pages/pmd/languages/velocity.md +++ b/docs/pages/pmd/languages/velocity.md @@ -1,7 +1,7 @@ --- title: Velocity Template Language (VTL) support permalink: pmd_languages_velocity.html -last_updated: February 2024 (7.0.0) +last_updated: March 2024 (7.0.0) tags: [languages, PmdCapableLanguage, CpdCapableLanguage] summary: "VTL-specific features and guidance" --- diff --git a/docs/pages/pmd/languages/xml.md b/docs/pages/pmd/languages/xml.md index 957e7588185..fd18fd8dbeb 100644 --- a/docs/pages/pmd/languages/xml.md +++ b/docs/pages/pmd/languages/xml.md @@ -1,7 +1,7 @@ --- title: XML support permalink: pmd_languages_xml.html -last_updated: September 2023 (7.0.0) +last_updated: March 2024 (7.0.0) tags: [languages, PmdCapableLanguage, CpdCapableLanguage] summary: "XML-specific features and guidance" --- diff --git a/docs/pages/pmd/projectdocs/committers/main_landing_page.md b/docs/pages/pmd/projectdocs/committers/main_landing_page.md index 4c9e4ec0bed..3bf0fe5ef04 100644 --- a/docs/pages/pmd/projectdocs/committers/main_landing_page.md +++ b/docs/pages/pmd/projectdocs/committers/main_landing_page.md @@ -1,7 +1,7 @@ --- title: Main Landing Page permalink: pmd_projectdocs_committers_main_landing_page.html -last_updated: March 2020 +last_updated: September 2024 (7.6.0) author: Andreas Dangel --- diff --git a/docs/pages/pmd/projectdocs/committers/merging_pull_requests.md b/docs/pages/pmd/projectdocs/committers/merging_pull_requests.md index af1391c586d..2cfb617362e 100644 --- a/docs/pages/pmd/projectdocs/committers/merging_pull_requests.md +++ b/docs/pages/pmd/projectdocs/committers/merging_pull_requests.md @@ -1,7 +1,7 @@ --- title: Merging pull requests permalink: pmd_projectdocs_committers_merging_pull_requests.html -last_updated: October 2021 +last_updated: September 2024 (7.8.0) author: Andreas Dangel --- diff --git a/docs/pages/pmd/projectdocs/decisions.md b/docs/pages/pmd/projectdocs/decisions.md index b8f813bad76..d2acf909fa2 100644 --- a/docs/pages/pmd/projectdocs/decisions.md +++ b/docs/pages/pmd/projectdocs/decisions.md @@ -2,7 +2,7 @@ title: Architecture Decisions sidebar: pmd_sidebar permalink: pmd_projectdocs_decisions.html -last_updated: July 2022 +last_updated: October 2022 (6.51.0) ---

            diff --git a/docs/pages/pmd/projectdocs/decisions/adr-1.md b/docs/pages/pmd/projectdocs/decisions/adr-1.md index 9daf3643de7..0f842a1b6b0 100644 --- a/docs/pages/pmd/projectdocs/decisions/adr-1.md +++ b/docs/pages/pmd/projectdocs/decisions/adr-1.md @@ -6,7 +6,7 @@ sidebaractiveurl: /pmd_projectdocs_decisions.html adr: true # Proposed / Accepted / Deprecated / Superseded adr_status: "Accepted" -last_updated: September 2022 +last_updated: February 2024 (7.0.0) --- ## Context diff --git a/docs/pages/pmd/projectdocs/decisions/adr-2.md b/docs/pages/pmd/projectdocs/decisions/adr-2.md index 1e5edf66895..fa5beea8761 100644 --- a/docs/pages/pmd/projectdocs/decisions/adr-2.md +++ b/docs/pages/pmd/projectdocs/decisions/adr-2.md @@ -6,7 +6,7 @@ sidebaractiveurl: /pmd_projectdocs_decisions.html adr: true # Proposed / Accepted / Deprecated / Superseded adr_status: "Accepted" -last_updated: September 2022 +last_updated: February 2024 (7.0.0) --- ## Context diff --git a/docs/pages/pmd/projectdocs/decisions/adr-3.md b/docs/pages/pmd/projectdocs/decisions/adr-3.md index 70d08d56512..35357d08d3c 100644 --- a/docs/pages/pmd/projectdocs/decisions/adr-3.md +++ b/docs/pages/pmd/projectdocs/decisions/adr-3.md @@ -6,7 +6,7 @@ sidebaractiveurl: /pmd_projectdocs_decisions.html adr: true # Proposed / Accepted / Deprecated / Superseded adr_status: "Accepted" -last_updated: February 2024 +last_updated: February 2024 (7.0.0) --- diff --git a/docs/pages/pmd/projectdocs/decisions/adr-NNN.md b/docs/pages/pmd/projectdocs/decisions/adr-NNN.md index af7934ac125..7e262220bc7 100644 --- a/docs/pages/pmd/projectdocs/decisions/adr-NNN.md +++ b/docs/pages/pmd/projectdocs/decisions/adr-NNN.md @@ -6,7 +6,7 @@ sidebaractiveurl: /pmd_projectdocs_decisions.html adr: true # Proposed / Accepted / Deprecated / Superseded adr_status: "" -last_updated: July 2022 +last_updated: December 2023 (7.0.0) --- diff --git a/docs/pages/pmd/userdocs/3rdpartyrulesets.md b/docs/pages/pmd/userdocs/3rdpartyrulesets.md index 0de1f7ca21a..919f135f949 100644 --- a/docs/pages/pmd/userdocs/3rdpartyrulesets.md +++ b/docs/pages/pmd/userdocs/3rdpartyrulesets.md @@ -5,7 +5,7 @@ language_name: 3rd party rulesets tags: [rule_references, userdocs] summary: Lists rulesets and rules from the community permalink: pmd_userdocs_3rdpartyrulesets.html -last_updated: December 2025 (7.20.0) +last_updated: January 2026 (7.21.0) --- ## For Java @@ -27,6 +27,6 @@ last_updated: December 2025 (7.20.0) ## For Apex * **unhappy-soup**, a repository with problematic Salesforce code to showcase PMD, the SFDX Scanner CLI * - * **sca-extra**, additional PMD and Regex rules for testing Salesforce Apex code using Salesforce Code Analyzer +* **sca-extra**, additional PMD and Regex rules for testing Salesforce Apex code using Salesforce Code Analyzer * diff --git a/docs/pages/pmd/userdocs/best_practices.md b/docs/pages/pmd/userdocs/best_practices.md index 49ce854a073..6168670592e 100644 --- a/docs/pages/pmd/userdocs/best_practices.md +++ b/docs/pages/pmd/userdocs/best_practices.md @@ -3,7 +3,7 @@ title: Best Practices tags: [userdocs] permalink: pmd_userdocs_best_practices.html author: Tom Copeland -last_updated: November 2017 +last_updated: December 2018 (6.11.0) --- ## Choose the rules that are right for you diff --git a/docs/pages/pmd/userdocs/configuring_rules.md b/docs/pages/pmd/userdocs/configuring_rules.md index 8c28a80ad34..610d5a64ad7 100644 --- a/docs/pages/pmd/userdocs/configuring_rules.md +++ b/docs/pages/pmd/userdocs/configuring_rules.md @@ -4,7 +4,7 @@ short_title: Configuring rules keywords: [property, properties, message, priority] tags: [userdocs, getting_started] summary: "Learn how to configure your rules directly from the ruleset XML." -last_updated: February 2024 (7.0.0) +last_updated: September 2025 (7.18.0) permalink: pmd_userdocs_configuring_rules.html author: Hooper Bloob , Romain Pelisse , Clรฉment Fournier --- diff --git a/docs/pages/pmd/userdocs/cpd/cpd_report_formats.md b/docs/pages/pmd/userdocs/cpd/cpd_report_formats.md index d18cf985157..e27f83c369a 100644 --- a/docs/pages/pmd/userdocs/cpd/cpd_report_formats.md +++ b/docs/pages/pmd/userdocs/cpd/cpd_report_formats.md @@ -5,7 +5,7 @@ keywords: [formats, renderers] summary: "Overview of the built-in report formats for CPD" permalink: pmd_userdocs_cpd_report_formats.html author: Andreas Dangel -last_updated: August 2025 (7.17.0) +last_updated: September 2025 (7.17.0) --- ## Overview diff --git a/docs/pages/pmd/userdocs/extending/ast_dump.md b/docs/pages/pmd/userdocs/extending/ast_dump.md index f8801d0bb83..ecbd029c503 100644 --- a/docs/pages/pmd/userdocs/extending/ast_dump.md +++ b/docs/pages/pmd/userdocs/extending/ast_dump.md @@ -2,7 +2,7 @@ title: Creating XML dump of the AST tags: [userdocs] summary: Creating a XML representation of the AST allows to analyze the AST with other tools. -last_updated: January 2024 (7.0.0) +last_updated: February 2024 (7.0.0) permalink: pmd_userdocs_extending_ast_dump.html --- diff --git a/docs/pages/pmd/userdocs/extending/defining_properties.md b/docs/pages/pmd/userdocs/extending/defining_properties.md index 19c728aa191..ca519fa0b31 100644 --- a/docs/pages/pmd/userdocs/extending/defining_properties.md +++ b/docs/pages/pmd/userdocs/extending/defining_properties.md @@ -3,7 +3,7 @@ title: Defining rule properties short_title: Defining rule properties tags: [extending, userdocs] summary: "Learn how to define your own properties both for Java and XPath rules." -last_updated: December 2023 (7.0.0) +last_updated: September 2024 (7.6.0) permalink: pmd_userdocs_extending_defining_properties.html author: Hooper Bloob , Romain Pelisse , Clรฉment Fournier --- diff --git a/docs/pages/pmd/userdocs/extending/designer_reference.md b/docs/pages/pmd/userdocs/extending/designer_reference.md index 7cf0a07662c..65892c167a9 100644 --- a/docs/pages/pmd/userdocs/extending/designer_reference.md +++ b/docs/pages/pmd/userdocs/extending/designer_reference.md @@ -3,7 +3,7 @@ title: The rule designer short_title: Rule designer tags: [extending, userdocs] summary: "Learn about the usage and features of the rule designer." -last_updated: March 2024 (7.0.0) +last_updated: April 2025 (7.13.0) permalink: pmd_userdocs_extending_designer_reference.html author: Clรฉment Fournier --- diff --git a/docs/pages/pmd/userdocs/extending/testing.md b/docs/pages/pmd/userdocs/extending/testing.md index 0518244dc4b..8b9df55d121 100644 --- a/docs/pages/pmd/userdocs/extending/testing.md +++ b/docs/pages/pmd/userdocs/extending/testing.md @@ -3,7 +3,7 @@ title: Testing your rules tags: [extending, userdocs] summary: "Learn how to use PMD's simple test framework for unit testing rules." permalink: pmd_userdocs_extending_testing.html -last_updated: July 2025 (7.17.0) +last_updated: August 2025 (7.17.0) author: Andreas Dangel --- diff --git a/docs/pages/pmd/userdocs/extending/writing_java_rules.md b/docs/pages/pmd/userdocs/extending/writing_java_rules.md index ee711091617..ba7924a713b 100644 --- a/docs/pages/pmd/userdocs/extending/writing_java_rules.md +++ b/docs/pages/pmd/userdocs/extending/writing_java_rules.md @@ -2,7 +2,7 @@ title: Writing a custom rule tags: [extending, userdocs] summary: "Learn how to write a custom rule for PMD" -last_updated: December 2023 (7.0.0) +last_updated: February 2024 (7.0.0) permalink: pmd_userdocs_extending_writing_java_rules.html author: Tom Copeland --- diff --git a/docs/pages/pmd/userdocs/extending/writing_rules_intro.md b/docs/pages/pmd/userdocs/extending/writing_rules_intro.md index 43fece776ca..6013a1a911c 100644 --- a/docs/pages/pmd/userdocs/extending/writing_rules_intro.md +++ b/docs/pages/pmd/userdocs/extending/writing_rules_intro.md @@ -2,7 +2,7 @@ title: Introduction to writing PMD rules tags: [extending, userdocs, getting_started] summary: "Writing your own PMD rules" -last_updated: December 2023 (7.0.0) +last_updated: January 2024 (7.0.0) permalink: pmd_userdocs_extending_writing_rules_intro.html author: Clรฉment Fournier --- diff --git a/docs/pages/pmd/userdocs/extending/writing_xpath_rules.md b/docs/pages/pmd/userdocs/extending/writing_xpath_rules.md index d2d0d1505b6..e94f9594b1f 100644 --- a/docs/pages/pmd/userdocs/extending/writing_xpath_rules.md +++ b/docs/pages/pmd/userdocs/extending/writing_xpath_rules.md @@ -2,7 +2,7 @@ title: Writing XPath rules tags: [extending, userdocs] summary: "This page describes XPath rule support in more details" -last_updated: December 2023 (7.0.0) +last_updated: April 2024 (7.2.0) permalink: pmd_userdocs_extending_writing_xpath_rules.html author: Miguel Griffa , Clรฉment Fournier --- diff --git a/docs/pages/pmd/userdocs/extending/your_first_rule.md b/docs/pages/pmd/userdocs/extending/your_first_rule.md index 30c2f98e13e..067ad5c0078 100644 --- a/docs/pages/pmd/userdocs/extending/your_first_rule.md +++ b/docs/pages/pmd/userdocs/extending/your_first_rule.md @@ -2,7 +2,7 @@ title: Your first rule tags: [extending, userdocs] summary: "Introduction to rule writing through an example for a XPath rule." -last_updated: December 2023 (7.0.0) +last_updated: January 2024 (7.0.0) permalink: pmd_userdocs_extending_your_first_rule.html author: Miguel Griffa , Clรฉment Fournier --- diff --git a/docs/pages/pmd/userdocs/making_rulesets.md b/docs/pages/pmd/userdocs/making_rulesets.md index fad6ac37e10..aa95f7beb42 100644 --- a/docs/pages/pmd/userdocs/making_rulesets.md +++ b/docs/pages/pmd/userdocs/making_rulesets.md @@ -8,7 +8,7 @@ summary: "A ruleset is an XML configuration file, which describes a collection o users are encouraged to make their own rulesets from the start, because they allow for so much configurability. This page walk you through the creation of a ruleset and the multiple configuration features offered by rulesets." -last_updated: October 2022 (6.51.0) +last_updated: November 2022 (6.52.0) permalink: pmd_userdocs_making_rulesets.html author: Tom Copeland , Clรฉment Fournier --- diff --git a/docs/pages/pmd/userdocs/suppressing_warnings.md b/docs/pages/pmd/userdocs/suppressing_warnings.md index 60d2565dc05..946dd761a26 100644 --- a/docs/pages/pmd/userdocs/suppressing_warnings.md +++ b/docs/pages/pmd/userdocs/suppressing_warnings.md @@ -5,7 +5,7 @@ tags: [userdocs] summary: "Learn how to suppress some rule violations, from the source code using annotations or comments, or globally from the ruleset" permalink: pmd_userdocs_suppressing_warnings.html author: Tom Copeland -last_updated: July 2025 (7.17.0) +last_updated: August 2025 (7.17.0) --- PMD provides several methods by which Rule violations can be suppressed. diff --git a/docs/pages/pmd/userdocs/tools/bld.md b/docs/pages/pmd/userdocs/tools/bld.md index 785184f20c0..b9671fa863b 100644 --- a/docs/pages/pmd/userdocs/tools/bld.md +++ b/docs/pages/pmd/userdocs/tools/bld.md @@ -2,7 +2,7 @@ title: bld PMD Extension tags: [userdocs, tools] permalink: pmd_userdocs_tools_bld.html -last_updated: September 2023 +last_updated: September 2023 (7.0.0) --- > [bld](https://rife2.com/bld) is a new build system that allows you to write your build logic in pure Java. diff --git a/docs/pages/pmd/userdocs/tools/java-api.md b/docs/pages/pmd/userdocs/tools/java-api.md index e04fdf97977..4f0c2e6be14 100644 --- a/docs/pages/pmd/userdocs/tools/java-api.md +++ b/docs/pages/pmd/userdocs/tools/java-api.md @@ -2,7 +2,7 @@ title: PMD Java API tags: [userdocs, tools] permalink: pmd_userdocs_tools_java_api.html -last_updated: August 2023 (7.0.0) +last_updated: January 2024 (7.0.0) --- The easiest way to run PMD is to just use a build plugin in your favorite build tool diff --git a/docs/pages/pmd/userdocs/tools/maven.md b/docs/pages/pmd/userdocs/tools/maven.md index 02fd2a07ddb..eff81d6468b 100644 --- a/docs/pages/pmd/userdocs/tools/maven.md +++ b/docs/pages/pmd/userdocs/tools/maven.md @@ -2,7 +2,7 @@ title: Maven PMD Plugin tags: [userdocs, tools] permalink: pmd_userdocs_tools_maven.html -last_updated: June 2024 (7.3.0) +last_updated: July 2024 (7.4.0) mpmd_version: 3.23.0 author: > Miguel Griffa , From e96320d63046f0ec802c6f434e4ba5577ac8c255 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 7 Jan 2026 08:27:53 +0100 Subject: [PATCH 1831/1962] [doc] Improve update-last-updated.sh to use default version --- docs/update-last-updated.sh | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/docs/update-last-updated.sh b/docs/update-last-updated.sh index 10aa005d2e8..2f08bf8a598 100755 --- a/docs/update-last-updated.sh +++ b/docs/update-last-updated.sh @@ -4,21 +4,24 @@ # # Helper script, that updates the "last_updated" field in the front matter based on the git info. -# It searches in the current directory. +# It searches in the current directory. The given version (first argument) is used, when the +# version cannot be determined (because the file has been changed after the last release). +# It should be the next release number. # # Usage: -# ./update-last-updated.sh +# ./update-last-updated.sh 7.21.0 # # This will update all markdown files. Then review the changed files # and commit or revert. # -# ./update-last-updated.sh pages/pmd/about/help.md +# ./update-last-updated.sh 7.21.0 pages/pmd/about/help.md # # Updates a single file only. # function process_file() { - FILE="$1" + DEFAULT_VERSION="$1" + FILE="$2" echo -n "$FILE: " LINE_NUMBER_FRONT_MATTER_END=$(grep -n -e "---" "$FILE"|head -2|tail -1|cut -d ":" -f 1) @@ -35,19 +38,29 @@ function process_file() { if [[ $TAG = 7.0.0-* ]]; then TAG="7.0.0" fi + if [ -z "$TAG" ]; then + TAG="$DEFAULT_VERSION" + fi #echo "Version: $TAG" LAST_UPDATED="last_updated: $DATE ($TAG)" echo "$LAST_UPDATED" - sed -i -e "s/^last_updated:.*\$/$LAST_UPDATED/" "$FILE" + sed -i -e "s/^last_updated: \([a-zA-Z]\+ [0-9]\{4,4\}\) ([0-9.]\+)\$/$LAST_UPDATED/" "$FILE" } # English locale - needed when creating the date export LANG="en_US.UTF-8" -if [ -n "$1" ]; then +if [ -z "$1" ]; then + echo "Please provide a default version (aka the next release)" + echo + echo "./update-last-updated.sh " + exit 1 +fi + +if [ -n "$2" ]; then # single file given - process_file "$1" + process_file "$1" "$2" else # no file given, search for all markdown files in current directory # ignore files in directory "vendor" @@ -55,7 +68,7 @@ else do # only consider files, that are under version control if git ls-files --error-unmatch "$i" >/dev/null 2>&1; then - process_file "$i" + process_file "$1" "$i" fi done < <(find . -type d -name vendor -prune -o -type f -name "*.md" -print0) fi From 1ffe5d4bf528ba389519a346ed4bb4435840d880 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 7 Jan 2026 08:55:09 +0100 Subject: [PATCH 1832/1962] chore: helper script check-all-contributors.sh This script checks that all contributors of issues and pull requests of the given milestone are mentioned in /.all-contributorsrc. This is useful to run before a release to make sure the contributors list is up to date. --- .all-contributorsrc | 2 +- .ci/tools/check-all-contributors.sh | 148 ++++++++++++++++++ do-release.sh | 3 + .../pmd/devdocs/contributing/contributing.md | 3 +- .../committers/merging_pull_requests.md | 12 +- .../pmd/projectdocs/committers/releasing.md | 18 ++- 6 files changed, 176 insertions(+), 10 deletions(-) create mode 100755 .ci/tools/check-all-contributors.sh diff --git a/.all-contributorsrc b/.all-contributorsrc index f54695f62a9..95d6a5034b8 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7,7 +7,7 @@ "docs/pages/pmd/projectdocs/credits.md" ], "imageSize": 100, - "commit": true, + "commit": false, "commitConvention": "none", "contributors": [ { diff --git a/.ci/tools/check-all-contributors.sh b/.ci/tools/check-all-contributors.sh new file mode 100755 index 00000000000..8a9029467a7 --- /dev/null +++ b/.ci/tools/check-all-contributors.sh @@ -0,0 +1,148 @@ +#!/bin/bash +set -e + +if [ -z "$1" ]; then + echo "$0 " + exit 1 +fi + +BASEDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +NEW_VERSION="$1" + +CURL_API_HEADER=(--header "X-GitHub-Api-Version: 2022-11-28") +CURL_AUTH_HEADER=() +if [ -z "$GITHUB_TOKEN" ]; then + echo -n "GITHUB_TOKEN=" + IFS= read -r GITHUB_TOKEN + if [ -n "$GITHUB_TOKEN" ]; then + export GITHUB_TOKEN + echo "Using provided GITHUB_TOKEN..." + else + echo "Not using GITHUB_TOKEN" + fi +fi + +if [ -n "$GITHUB_TOKEN" ]; then + echo "Will use env var GITHUB_TOKEN for github REST API" + CURL_AUTH_HEADER=(--header "Authorization: Bearer $GITHUB_TOKEN") +fi + +# determine current milestone +MILESTONE_JSON=$(curl "${CURL_API_HEADER[@]}" "${CURL_AUTH_HEADER[@]}" -s "https://api.github.com/repos/pmd/pmd/milestones?state=all&direction=desc&per_page=10&page=1"|jq ".[] | select(.title == \"$NEW_VERSION\")") +#DEBUG ONLY +#MILESTONE_JSON='{"number":80,"closed_issues":40}' +#DEBUG ONLY +MILESTONE=$(echo "$MILESTONE_JSON" | jq .number) + +PAGE="1" +HAS_NEXT="true" +ISSUES_JSON="" +while [ "$HAS_NEXT" = "true" ]; do + echo "Fetching issues for milestone ${MILESTONE} page ${PAGE}..." + URL="https://api.github.com/repos/pmd/pmd/issues?state=closed&sort=created&direction=asc&per_page=30&page=${PAGE}&milestone=${MILESTONE}" + RESPONSE="$(curl "${CURL_API_HEADER[@]}" "${CURL_AUTH_HEADER[@]}" -s -w "\nLink: %header{link}" "$URL")" + + #DEBUG ONLY + #echo "$RESPONSE" > issues-response-${PAGE}.txt + #RESPONSE="$(cat issues-response-${PAGE}.txt)" + #DEBUG ONLY + + LINK_HEADER="$(echo "$RESPONSE" | tail -1)" + BODY="$(echo "$RESPONSE" | head -n -1)" + + #DEBUG ONLY + #echo "$BODY" > "issues-response-page-${PAGE}.txt" + #BODY="$(cat "issues-response-page-${PAGE}.txt")" + #DEBUG ONLY + + COMMA="," + if [ "$PAGE" -eq 1 ]; then + COMMA="" + fi + ISSUES_JSON="${ISSUES_JSON}${COMMA}${BODY}" + + if [[ $LINK_HEADER == *"; rel=\"next\""* ]]; then + HAS_NEXT="true" + else + HAS_NEXT="false" + fi + PAGE=$((PAGE + 1)) + + #DEBUG ONLY + #HAS_NEXT="true" + #if [ "$PAGE" -gt 2 ]; then break; fi + #DEBUG ONLY + + # stop after 10 pages + if [ "$PAGE" -gt 10 ]; then + echo + echo + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + echo "!!!!!!!!!!!!!! reached page 10, stopping now !!!!!!!!!!!!!" + echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + echo + echo + break; + fi +done + + +ISSUES_JSON="$(echo "[ $ISSUES_JSON ]" | jq 'flatten(1)')" +echo "Found $(echo "$ISSUES_JSON" | jq length) issues/pull requests" +#DEBUG ONLY +# echo "$ISSUES_JSON" > issues-all.txt +#DEBUG ONLY + +# Users which reported a bug, that has been fixed now (assigned to the milestone) +BUG_USERS="$(echo "$ISSUES_JSON" | jq 'map(select(has("pull_request") | not)) | [ .[].user.login ] | unique')" + +COL_GREEN="\e[32m" +COL_RED="\e[31m" +COL_WHITE="\e[37m" +COL_RESET="\e[0m" + +echo +echo "Checking for bug contributions..." +# for each user, check if "bug" is already present +for login in $(echo "$BUG_USERS" | jq --raw-output .[]); do + USER_JSON="$(jq '.contributors[] | select(.login == "'"$login"'")' < "$BASEDIR"/.all-contributorsrc)" + BUGS="$(echo "$ISSUES_JSON" | jq 'map(select(has("pull_request") | not)) | map(select(.user.login == "'"$login"'")) | .[] | { number: .number, title: .title, login: .user.login }')" + echo -en "${COL_WHITE}$login:${COL_RESET} " + if [ -z "$USER_JSON" ]; then + echo -e "${COL_RED}Missing user entirely${COL_RESET}" + echo "$BUGS" + else + HAS_BUG="$(echo "$USER_JSON" | jq --raw-output 'if .contributions | contains(["bug"]) | not then "false" else "true" end')" + if [ "$HAS_BUG" = "true" ]; then + echo -e "${COL_GREEN}ok${COL_RESET}" + else + echo -e "${COL_RED}bug is missing${COL_RESET}" + echo "$BUGS" + fi + fi +done + +echo +echo "Checking for code contributions..." +# Users which submitted a pull request that has been merged (assigned to the milestone) +CODE_USERS="$(echo "$ISSUES_JSON" | jq 'map(select(has("pull_request"))) | [ .[].user.login ] | unique')" + +# for each user, check if "code" is already present +for login in $(echo "$CODE_USERS" | jq --raw-output .[]); do + USER_JSON="$(jq '.contributors[] | select(.login == "'"$login"'")' < "$BASEDIR"/.all-contributorsrc)" + PRS="$(echo "$ISSUES_JSON" | jq 'map(select(has("pull_request"))) | map(select(.user.login == "'"$login"'")) | .[] | { number: .number, title: .title, login: .user.login }')" + echo -en "${COL_WHITE}$login:${COL_RESET} " + if [ -z "$USER_JSON" ]; then + echo -e "${COL_RED}Missing user entirely${COL_RESET}" + echo "$PRS" + else + HAS_CODE="$(echo "$USER_JSON" | jq --raw-output 'if .contributions | contains(["code"]) | not then "false" else "true" end')" + if [ "$HAS_CODE" = "true" ]; then + echo -e "${COL_GREEN}ok${COL_RESET}" + else + echo -e "${COL_RED}code is missing${COL_RESET}" + echo "$PRS" + fi + fi +done + diff --git a/do-release.sh b/do-release.sh index d0c36c101d0..6248163f8db 100755 --- a/do-release.sh +++ b/do-release.sh @@ -122,6 +122,9 @@ if [ "${BUILD_TOOLS_VERSION}" != "${BUILD_TOOLS_VERSION_RELEASE}" ]; then exit 1 fi +echo "* Run '.ci/tools/check-all-contributors $RELEASE_VERSION' and update contributors" +echo " by calling 'npx all-contributors add bug,code' accordingly" +echo echo "* Update version info in **docs/_config.yml**." echo " remove the SNAPSHOT from site.pmd.version" echo diff --git a/docs/pages/pmd/devdocs/contributing/contributing.md b/docs/pages/pmd/devdocs/contributing/contributing.md index 881b5fd40f0..aadd38e954e 100644 --- a/docs/pages/pmd/devdocs/contributing/contributing.md +++ b/docs/pages/pmd/devdocs/contributing/contributing.md @@ -4,7 +4,7 @@ summary: How to contribute to PMD tags: [devdocs] permalink: pmd_devdocs_contributing.html author: Andreas Dangel -last_updated: January 2025 (7.10.0) +last_updated: January 2026 (7.21.0) --- First off, thanks for taking the time to contribute! @@ -100,6 +100,7 @@ Or use the CLI: 1. Install the CLI: `npm i` (in PMD's top level directory) 2. Add yourself: `npx all-contributors add ` +3. Commit the changes: `git commit -am "Add @ as contributor` Where `username` is your GitHub username and `contribution` is a `,`-separated list of contributions. See [Emoji Key](https://allcontributors.org/docs/en/emoji-key) for a list diff --git a/docs/pages/pmd/projectdocs/committers/merging_pull_requests.md b/docs/pages/pmd/projectdocs/committers/merging_pull_requests.md index af1391c586d..bcbe53dbfa9 100644 --- a/docs/pages/pmd/projectdocs/committers/merging_pull_requests.md +++ b/docs/pages/pmd/projectdocs/committers/merging_pull_requests.md @@ -1,7 +1,7 @@ --- title: Merging pull requests permalink: pmd_projectdocs_committers_merging_pull_requests.html -last_updated: October 2021 +last_updated: January 2026 (7.21.0) author: Andreas Dangel --- @@ -56,19 +56,17 @@ author: Andreas Dangel 4. Add the contributor to `.all-contributorsrc`: ``` - npx all-contributors add + npx all-contributors add code ``` - And follow the instructions. This will create a new commit into to the current branch (pr-123) updating both - the file `.all-contributorsrc` and `docs/pages/pmd/projectdocs/credits.md`. + This will modify the files `.all-contributorsrc` and `docs/pages/pmd/projectdocs/credits.md`. + Commit them with `git commit -am "Add @ as a contributor` into the current branch (pr-123). 5. Now merge the pull request into the main branch: ``` git checkout main - git merge --no-ff pr-123 -m "Full-title-of-the-pr (#123) - - Merge pull request #123 from xyz:branch" --log + git merge --no-ff pr-123 -m "Full-title-of-the-pr (#123)" ``` {%include note.html content="If there are merge conflicts, you'll need to deal with them here." %} diff --git a/docs/pages/pmd/projectdocs/committers/releasing.md b/docs/pages/pmd/projectdocs/committers/releasing.md index 21b190a86eb..a91eea997ca 100644 --- a/docs/pages/pmd/projectdocs/committers/releasing.md +++ b/docs/pages/pmd/projectdocs/committers/releasing.md @@ -2,7 +2,7 @@ title: Release process permalink: pmd_projectdocs_committers_releasing.html author: Romain Pelisse , Andreas Dangel -last_updated: June 2025 (7.15.0) +last_updated: January 2026 (7.21.0) --- This page describes the current status of the release process. @@ -54,6 +54,22 @@ The script `do-release.sh` is called in the directory `/home/joe/source/pmd` and Also make sure, that the repo "pmd.github.io" is locally up-to-date and has no local changes. +### All Contributors + +Before a release, it makes sense to ensure the .all-contributorsrc file is up to date. +There is a simple script in `.ci/tools/check-all-contributors.sh`, that compares the issues and +pull request from the given milestone with the users and suggests, whether the all contributors +list should be updated. + + $ .ci/tool/check-all-contributors.sh + +This will ask for a GitHub Token to access the GitHub API to read the milestones. Without the token, +you might run into API rate limiting. + +The script doesn't change the all contributors list directly, it only outputs when some contributor +is missing. You'll need to call `npx all-contributors add bug,code` (or only bug, or only code) +additionally. + ### The Release Notes and docs Before the release, you need to verify the release notes: Does it contain all the relevant changes for the From 5e7b77152e02165f94a37ade9e166497ef37d9b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 09:14:08 +0100 Subject: [PATCH 1833/1962] chore(deps): bump ruby/setup-ruby from 1.277.0 to 1.279.0 (#6378) Bumps [ruby/setup-ruby](https://github.com/ruby/setup-ruby) from 1.277.0 to 1.279.0. - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/8a836efbcebe5de0fe86b48a775b7a31b5c70c93...b90be12699fdfcbee4440c2bba85f6f460446bb0) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-version: 1.279.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 4 ++-- .github/workflows/publish-release.yml | 2 +- .github/workflows/publish-snapshot.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2aa0a3ba01a..f620705da1f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -280,7 +280,7 @@ jobs: -Pgenerate-rule-docs,fastSkip \ -DskipTests -Dassembly.skipAssembly=true - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@8a836efbcebe5de0fe86b48a775b7a31b5c70c93 #v1.277.0 + uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 #v1.279.0 with: ruby-version: 3.3 - name: Setup bundler @@ -321,7 +321,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@8a836efbcebe5de0fe86b48a775b7a31b5c70c93 #v1.277.0 + uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 #v1.279.0 with: ruby-version: 3.3 - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb #v5.0.1 diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 8b1c27badfc..fb69e22b3e0 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -632,7 +632,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@8a836efbcebe5de0fe86b48a775b7a31b5c70c93 #v1.277.0 + uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 #v1.279.0 with: ruby-version: 3.3 - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb #v5.0.1 diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index c2173de62f2..e17e6fe4d1b 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -649,7 +649,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@8a836efbcebe5de0fe86b48a775b7a31b5c70c93 #v1.277.0 + uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 #v1.279.0 with: ruby-version: 3.3 - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb #v5.0.1 From 6c1c41ca2d4839024203ead1d6ab11c45fcea9a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 09:24:36 +0100 Subject: [PATCH 1834/1962] chore(deps): bump junit.version from 6.0.1 to 6.0.2 (#6380) Bumps `junit.version` from 6.0.1 to 6.0.2. Updates `org.junit.platform:junit-platform-launcher` from 6.0.1 to 6.0.2 - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r6.0.1...r6.0.2) Updates `org.junit:junit-bom` from 6.0.1 to 6.0.2 - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r6.0.1...r6.0.2) Updates `org.junit.platform:junit-platform-commons` from 6.0.1 to 6.0.2 - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r6.0.1...r6.0.2) --- updated-dependencies: - dependency-name: org.junit.platform:junit-platform-launcher dependency-version: 6.0.2 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.junit:junit-bom dependency-version: 6.0.2 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.junit.platform:junit-platform-commons dependency-version: 6.0.2 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8b6f1955bc1..56ec9e2f221 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ ${maven.compiler.test.target} 2.2.10 5.9.1 - 6.0.1 + 6.0.2 2.0.0 5.0 From 26be0db7c5cc5e5e25942916a0f80de5ca995c67 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 09:25:02 +0100 Subject: [PATCH 1835/1962] chore(deps): bump org.checkerframework:checker-qual from 3.52.1 to 3.53.0 (#6382) chore(deps): bump org.checkerframework:checker-qual Bumps [org.checkerframework:checker-qual](https://github.com/typetools/checker-framework) from 3.52.1 to 3.53.0. - [Release notes](https://github.com/typetools/checker-framework/releases) - [Changelog](https://github.com/typetools/checker-framework/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/typetools/checker-framework/compare/checker-framework-3.52.1...checker-framework-3.53.0) --- updated-dependencies: - dependency-name: org.checkerframework:checker-qual dependency-version: 3.53.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 56ec9e2f221..d6dd9f93cf7 100644 --- a/pom.xml +++ b/pom.xml @@ -907,7 +907,7 @@ org.checkerframework checker-qual - 3.52.1 + 3.53.0 net.sf.saxon From 9f9ddee6dd0f14904b82012cac0271973f12c9ec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 09:25:47 +0100 Subject: [PATCH 1836/1962] chore(deps): bump org.jsoup:jsoup from 1.21.2 to 1.22.1 (#6381) Bumps [org.jsoup:jsoup](https://github.com/jhy/jsoup) from 1.21.2 to 1.22.1. - [Release notes](https://github.com/jhy/jsoup/releases) - [Changelog](https://github.com/jhy/jsoup/blob/master/CHANGES.md) - [Commits](https://github.com/jhy/jsoup/compare/jsoup-1.21.2...jsoup-1.22.1) --- updated-dependencies: - dependency-name: org.jsoup:jsoup dependency-version: 1.22.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-html/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index e9bd7ff6848..e9c1f54af9f 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -31,7 +31,7 @@ org.jsoup jsoup - 1.21.2 + 1.22.1 From eac0335cd1b4bfd5c47d2992162cf945384d5854 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 14 Nov 2025 09:48:21 +0100 Subject: [PATCH 1837/1962] [core] Properties: Expose info about collection and enumerations --- .../pmd/properties/ConstraintDecorator.java | 11 ++++++ .../pmd/properties/PropertySerializer.java | 14 ++++++++ .../internal/PropertyParsingUtil.java | 15 +++++--- .../pmd/properties/internal/ValueSyntax.java | 34 +++++++++++++++---- 4 files changed, 64 insertions(+), 10 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/ConstraintDecorator.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/ConstraintDecorator.java index 802c20ef612..104433ea9ab 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/ConstraintDecorator.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/ConstraintDecorator.java @@ -5,6 +5,7 @@ package net.sourceforge.pmd.properties; import java.util.List; +import java.util.Set; import org.checkerframework.checker.nullness.qual.NonNull; @@ -45,6 +46,16 @@ public T fromString(@NonNull String attributeData) { return t; } + @Override + public boolean isCollection() { + return propertySerializer.isCollection(); + } + + @Override + public Set enumeratedValues() { + return propertySerializer.enumeratedValues(); + } + @Override public @NonNull String toString(T value) { return propertySerializer.toString(value); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertySerializer.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertySerializer.java index 6eb7dca88ea..37192ec302d 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertySerializer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertySerializer.java @@ -6,6 +6,7 @@ import java.util.Collections; import java.util.List; +import java.util.Set; import org.checkerframework.checker.nullness.qual.NonNull; @@ -53,5 +54,18 @@ public PropertySerializer withConstraint(PropertyConstraint t) { */ public abstract @NonNull String toString(T value); + /** + * Whether this property allows multiple values. + * @since 7.19.0 + */ + public abstract boolean isCollection(); + /** + * If this property only allows specific enumerated values, this set contains + * all possible values. This is useful for documentation. + * If this property doesn't represent an enumerated property, then the returned + * set will be empty. + * @since 7.19.0 + */ + public abstract Set enumeratedValues(); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java index 69f56aaa3e5..833d750f6f2 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; @@ -35,7 +36,8 @@ public final class PropertyParsingUtil { PropertyConstraint.fromPredicate( s -> s.length() == 1, "Should be exactly one character in length" - )); + ), + Collections.emptySet()); public static final ValueSyntax REGEX = ValueSyntax.withDefaultToString(Pattern::compile); public static final ValueSyntax INTEGER = ValueSyntax.withDefaultToString(preTrim(Integer::valueOf)); @@ -76,7 +78,9 @@ public static PropertySerializer> toOptional(PropertySerializer< return Optional.empty(); } return Optional.of(itemSyntax.fromString(str)); - } + }, + itemSyntax.isCollection(), + itemSyntax.enumeratedValues() ); } @@ -128,7 +132,9 @@ public static > PropertySerializer delimitedString(P String delim = "" + PropertyFactory.DEFAULT_DELIMITER; return ValueSyntax.create( coll -> IteratorUtil.toStream(coll.iterator()).map(itemSyntax::toString).collect(Collectors.joining(delim)), - string -> parseListWithEscapes(string, PropertyFactory.DEFAULT_DELIMITER, itemSyntax::fromString).stream().collect(collector) + string -> parseListWithEscapes(string, PropertyFactory.DEFAULT_DELIMITER, itemSyntax::fromString).stream().collect(collector), + true, + itemSyntax.enumeratedValues() ); } @@ -205,7 +211,8 @@ public static ValueSyntax enumerationParser(final Map mappings PropertyConstraint.fromPredicate( mappings::containsKey, "Should be " + XmlUtil.formatPossibleNames(XmlUtil.toConstants(mappings.keySet())) - ) + ), + new HashSet<>(mappings.values()) ); } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/ValueSyntax.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/ValueSyntax.java index 61f37251dd7..68c840796a7 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/ValueSyntax.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/ValueSyntax.java @@ -9,6 +9,7 @@ import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.Set; import java.util.function.Function; import org.checkerframework.checker.nullness.qual.NonNull; @@ -33,16 +34,22 @@ class ValueSyntax extends InternalApiBridge.InternalPropertySerializer { private final Function toString; private final Function<@NonNull String, ? extends T> fromString; + private final boolean collection; + private final Set enumeratedValues; // these are not applied, just used to document the possible values private final List> docConstraints; ValueSyntax(Function toString, Function<@NonNull String, ? extends T> fromString, - List> docConstraints) { + List> docConstraints, + boolean collection, + Set enumeratedValues) { this.toString = toString; this.fromString = fromString; this.docConstraints = docConstraints; + this.collection = collection; + this.enumeratedValues = enumeratedValues; } @Override @@ -60,6 +67,16 @@ public T fromString(@NonNull String attributeData) { return toString.apply(data); } + @Override + public boolean isCollection() { + return collection; + } + + @Override + public Set enumeratedValues() { + return enumeratedValues; + } + /** * Creates a value syntax that cannot parse just any string, but * which only applies the fromString parser if a precondition holds. @@ -68,7 +85,8 @@ public T fromString(@NonNull String attributeData) { */ static ValueSyntax partialFunction(Function toString, Function<@NonNull String, ? extends T> fromString, - PropertyConstraint checker) { + PropertyConstraint checker, + Set enumeratedValues) { PropertyConstraint docConstraint = PropertyConstraint.fromPredicate( PredicateUtil.always(), checker.getConstraintDescription() @@ -80,16 +98,20 @@ static ValueSyntax partialFunction(Function t checker.validate(s); return fromString.apply(s); }, - listOf(docConstraint) + listOf(docConstraint), + false, + enumeratedValues ); } static ValueSyntax withDefaultToString(Function fromString) { - return new ValueSyntax<>(Objects::toString, fromString, Collections.emptyList()); + return new ValueSyntax<>(Objects::toString, fromString, Collections.emptyList(), false, Collections.emptySet()); } static ValueSyntax create(Function toString, - Function fromString) { - return new ValueSyntax<>(toString, fromString, Collections.emptyList()); + Function fromString, + boolean isCollection, + Set enumeratedValues) { + return new ValueSyntax<>(toString, fromString, Collections.emptyList(), isCollection, enumeratedValues); } } From 81200b42230e0e1be65e33bd4db548997607db5d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 13 Nov 2025 19:09:14 +0100 Subject: [PATCH 1838/1962] [doc] RuleDoc: Display possible enumerated values --- .../pmd/doc/internal/RuleDocGenerator.java | 45 ++++++++++++------- .../SampleRuleWithEnumPropertiesRule.java | 39 ++++++++++++++++ pmd-doc/src/test/resources/expected/java.md | 1 + pmd-doc/src/test/resources/expected/sample.md | 38 +++++++++++++++- .../resources/rulesets/ruledoctest/sample.xml | 8 ++++ 5 files changed, 112 insertions(+), 19 deletions(-) create mode 100644 pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/SampleRuleWithEnumPropertiesRule.java diff --git a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java index 5842133ea62..8ad203a999c 100644 --- a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java +++ b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java @@ -22,6 +22,7 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; import java.util.regex.Matcher; @@ -490,14 +491,35 @@ private void generateRuleSetIndex(Map> rulesets) throws description = description.substring(DEPRECATED_RULE_PROPERTY_MARKER.length()); } - String defaultValue = determineDefaultValueAsString(propertyDescriptor, rule, true); + String enumValuesDescription = ""; + Set enumValues = propertyDescriptor.serializer().enumeratedValues(); + if (!enumValues.isEmpty()) { + if (propertyDescriptor.serializer().isCollection()) { + enumValuesDescription = "
            One or more of: "; + enumValues = enumValues.stream().map(Collections::singleton).collect(Collectors.toSet()); + } else { + enumValuesDescription = "
            One of: "; + } + enumValuesDescription += enumValues.stream() + .map(v -> EscapeUtils.escapeMarkdown(determinePropertyValueAsString(propertyDescriptor, v))) + .map(v -> "`" + v + "`") + .sorted() + .collect(Collectors.joining(", ")); + } + + String defaultValue = determinePropertyValueAsString(propertyDescriptor, propertyDescriptor.defaultValue()); + if (propertyDescriptor.serializer().isCollection()) { + // surround the delimiter of multi property with spaces, so that the browser can wrap the value nicely + defaultValue = defaultValue.replaceAll(",", " , "); + } lines.add("|" + EscapeUtils.escapeMarkdown(StringEscapeUtils.escapeHtml4(propertyDescriptor.name())) + "|" - + EscapeUtils.escapeMarkdown(defaultValue) + + EscapeUtils.escapeMarkdown(StringEscapeUtils.escapeHtml4(defaultValue)) + "|" + EscapeUtils.escapeMarkdown((isDeprecated ? DEPRECATION_LABEL_SMALL : "") + StringEscapeUtils.escapeHtml4(description)) + + enumValuesDescription + "|" ); } @@ -521,7 +543,8 @@ private void generateRuleSetIndex(Map> rulesets) throws lines.add(" "); for (PropertyDescriptor propertyDescriptor : properties) { if (!isDeprecated(propertyDescriptor)) { - String defaultValue = determineDefaultValueAsString(propertyDescriptor, rule, false); + String defaultValue = determinePropertyValueAsString(propertyDescriptor, propertyDescriptor.defaultValue()); + defaultValue = StringEscapeUtils.escapeXml10(defaultValue); lines.add(" "); } @@ -594,20 +617,8 @@ private static boolean isDeprecated(PropertyDescriptor propertyDescriptor) { && propertyDescriptor.description().toLowerCase(Locale.ROOT).startsWith(DEPRECATED_RULE_PROPERTY_MARKER); } - private String determineDefaultValueAsString(PropertyDescriptor propertyDescriptor, Rule rule, boolean pad) { - String defaultValue = ""; - T realDefaultValue = rule.getProperty(propertyDescriptor); - - if (realDefaultValue != null) { - defaultValue = propertyDescriptor.serializer().toString(realDefaultValue); - if (pad && realDefaultValue instanceof Collection) { - // surround the delimiter with spaces, so that the browser can wrap - // the value nicely - defaultValue = defaultValue.replaceAll(",", " , "); - } - } - defaultValue = StringEscapeUtils.escapeHtml4(defaultValue); - return defaultValue; + private String determinePropertyValueAsString(PropertyDescriptor propertyDescriptor, Object value) { + return propertyDescriptor.serializer().toString((T) value); } private static String stripIndentation(String description) { diff --git a/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/SampleRuleWithEnumPropertiesRule.java b/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/SampleRuleWithEnumPropertiesRule.java new file mode 100644 index 00000000000..238c8359987 --- /dev/null +++ b/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/SampleRuleWithEnumPropertiesRule.java @@ -0,0 +1,39 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.doc.internal; + +import java.util.List; + +import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.rule.AbstractRule; +import net.sourceforge.pmd.properties.PropertyDescriptor; +import net.sourceforge.pmd.properties.PropertyFactory; +import net.sourceforge.pmd.reporting.RuleContext; + +public class SampleRuleWithEnumPropertiesRule extends AbstractRule { + private enum MyEnum { + OPTION_ONE, + OPTION_TWO + } + + private static final PropertyDescriptor ENUM_PROPERTY = PropertyFactory.enumProperty("enumProperty", MyEnum.class) + .desc("Description") + .defaultValue(MyEnum.OPTION_ONE) + .build(); + private static final PropertyDescriptor> ENUMLIST_PROPERTY = PropertyFactory.enumListProperty("enumListProperty", MyEnum.class, Object::toString) + .desc("Description") + .emptyDefaultValue() + .build(); + + public SampleRuleWithEnumPropertiesRule() { + definePropertyDescriptor(ENUM_PROPERTY); + definePropertyDescriptor(ENUMLIST_PROPERTY); + } + + @Override + public void apply(Node target, RuleContext ctx) { + + } +} diff --git a/pmd-doc/src/test/resources/expected/java.md b/pmd-doc/src/test/resources/expected/java.md index 7cbb6ac78e4..a49c95e3d96 100644 --- a/pmd-doc/src/test/resources/expected/java.md +++ b/pmd-doc/src/test/resources/expected/java.md @@ -20,6 +20,7 @@ editmepath: false * [RenamedRule2](pmd_rules_java_sample.html#renamedrule2): Deprecated The rule has been renamed. Use instead [JumbledIncrementer](pmd_rules_java_sample.html#jumbledincrementer). * [RenamedRule3](pmd_rules_java_sample.html#renamedrule3): Deprecated The rule has been renamed. Use instead [JumbledIncrementer](pmd_rules_java_sample.html#jumbledincrementer). * [RenamedRule4](pmd_rules_java_sample.html#renamedrule4): Deprecated The rule has been renamed. Use instead [JumbledIncrementer](pmd_rules_java_sample.html#jumbledincrementer). +* [SampleRuleWithEnumProperties](pmd_rules_java_sample.html#samplerulewithenumproperties): This rule is for testing enum properties * [XSSInDocumentation](pmd_rules_java_sample.html#xssindocumentation): <script>alert('XSS at the beginning');</script> HTML tags might appear at various places. ... ## Additional rulesets diff --git a/pmd-doc/src/test/resources/expected/sample.md b/pmd-doc/src/test/resources/expected/sample.md index 1785c771522..cbd50cf95ef 100644 --- a/pmd-doc/src/test/resources/expected/sample.md +++ b/pmd-doc/src/test/resources/expected/sample.md @@ -5,7 +5,7 @@ permalink: pmd_rules_java_sample.html folder: pmd/rules/java sidebaractiveurl: /pmd_rules_java.html editmepath: ../rulesets/ruledoctest/sample.xml -keywords: Sample, DeprecatedSample, JumbledIncrementer, MovedRule, OverrideBothEqualsAndHashcode, RenamedRule1, RenamedRule2, RenamedRule3, RenamedRule4, XSSInDocumentation +keywords: Sample, DeprecatedSample, JumbledIncrementer, MovedRule, OverrideBothEqualsAndHashcode, RenamedRule1, RenamedRule2, RenamedRule3, RenamedRule4, SampleRuleWithEnumProperties, XSSInDocumentation rules: DeprecatedSample: | Just some description of a deprecated rule. @@ -54,6 +54,8 @@ rules: This rule has been renamed. Use instead: [JumbledIncrementer](#jumbledincrementer) + SampleRuleWithEnumProperties: | + This rule is for testing enum properties XSSInDocumentation: | <script>alert('XSS at the beginning');</script> HTML tags might appear at various places. Sometimes they should be escaped, sometimes not: @@ -586,6 +588,38 @@ Avoid jumbled loop incrementers - it's usually a mistake, and is confusing even ``` +## SampleRuleWithEnumProperties + +**Since:** PMD 7.19.0 + +**Priority:** Medium (3) + +This rule is for testing enum properties + +**This rule is defined by the following Java class:** [net.sourceforge.pmd.doc.internal.SampleRuleWithEnumPropertiesRule](https://github.com/pmd/pmd/blob/main/net/sourceforge/pmd/doc/internal/SampleRuleWithEnumPropertiesRule.java) + +**This rule has the following properties:** + +|Name|Default Value|Description| +|----|-------------|-----------| +|enumProperty|OPTION\_ONE|Description
            One of: `OPTION\_ONE`, `OPTION\_TWO`| +|enumListProperty||Description
            One or more of: `OPTION\_ONE`, `OPTION\_TWO`| + +**Use this rule with the default properties by just referencing it:** +``` xml + +``` + +**Use this rule and customize it:** +``` xml + + + + + + +``` + ## XSSInDocumentation **Since:** PMD 0.1 @@ -664,7 +698,7 @@ if (0 > 1 && 0 < 1) { - + diff --git a/pmd-doc/src/test/resources/rulesets/ruledoctest/sample.xml b/pmd-doc/src/test/resources/rulesets/ruledoctest/sample.xml index 412047cef6d..df23604ea08 100644 --- a/pmd-doc/src/test/resources/rulesets/ruledoctest/sample.xml +++ b/pmd-doc/src/test/resources/rulesets/ruledoctest/sample.xml @@ -228,4 +228,12 @@ RuleTag with full category and without quotes: Use {% rule java/sample/RenamedRu + + This rule is for testing enum properties + 3 + From fb906d4eebb673943df0cf97a19bd2eeb08d0eba Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 14 Nov 2025 11:06:23 +0100 Subject: [PATCH 1839/1962] [core] Properties: update unit tests --- .../properties/PropertyDescriptorTest.java | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java index 1847876af9c..8c8bd488428 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java @@ -10,13 +10,17 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.function.Function; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; @@ -108,7 +112,11 @@ void testIntProperty() { assertEquals(Integer.valueOf(1), descriptor.defaultValue()); assertEquals(Integer.valueOf(5), descriptor.serializer().fromString("5")); assertEquals(Integer.valueOf(5), descriptor.serializer().fromString(" 5 ")); + assertFalse(descriptor.serializer().isCollection()); + } + @Test + void testIntListProperty() { PropertyDescriptor> listDescriptor = PropertyFactory.intListProperty("intListProp") .desc("hello") .defaultValues(1, 2) @@ -118,6 +126,7 @@ void testIntProperty() { assertEquals(Arrays.asList(1, 2), listDescriptor.defaultValue()); assertEquals(Arrays.asList(5, 7), listDescriptor.serializer().fromString("5,7")); assertEquals(Arrays.asList(5, 7), listDescriptor.serializer().fromString(" 5 , 7 ")); + assertTrue(listDescriptor.serializer().isCollection()); } @Test @@ -143,7 +152,11 @@ void testDoubleProperty() { assertEquals(Double.valueOf(1.0), descriptor.defaultValue()); assertEquals(Double.valueOf(2.0), descriptor.serializer().fromString("2.0")); assertEquals(Double.valueOf(2.0), descriptor.serializer().fromString(" 2.0 ")); + assertFalse(descriptor.serializer().isCollection()); + } + @Test + void testDoubleListProperty() { PropertyDescriptor> listDescriptor = PropertyFactory.doubleListProperty("doubleListProp") .desc("hello") .defaultValues(1.0, 2.0) @@ -153,6 +166,7 @@ void testDoubleProperty() { assertEquals(Arrays.asList(1.0, 2.0), listDescriptor.defaultValue()); assertEquals(Arrays.asList(2.0, 3.0), listDescriptor.serializer().fromString("2.0,3.0")); assertEquals(Arrays.asList(2.0, 3.0), listDescriptor.serializer().fromString(" 2.0 , 3.0 ")); + assertTrue(listDescriptor.serializer().isCollection()); } @Test @@ -177,7 +191,7 @@ void testStringProperty() { assertEquals("default value", descriptor.defaultValue()); assertEquals("foo", descriptor.serializer().fromString("foo")); assertEquals("foo", descriptor.serializer().fromString(" foo ")); - + assertFalse(descriptor.serializer().isCollection()); } @Test @@ -192,6 +206,7 @@ void testStringListProperty() { assertEquals(Arrays.asList("foo", "bar"), listDescriptor.serializer().fromString("foo,bar")); assertEquals(Arrays.asList("foo", "bar"), listDescriptor.serializer().fromString(" foo , bar ")); assertEquals(Arrays.asList("foo", "bar"), listDescriptor.serializer().fromString(" foo , bar , ")); // Github issue 4714 + assertTrue(listDescriptor.serializer().isCollection()); } private enum SampleEnum { A, B, C } @@ -214,7 +229,14 @@ void testEnumProperty() { assertEquals("hello", descriptor.description()); assertEquals(SampleEnum.B, descriptor.defaultValue()); assertEquals(SampleEnum.C, descriptor.serializer().fromString("TEST_C")); + assertFalse(descriptor.serializer().isCollection()); + assertFalse(descriptor.serializer().enumeratedValues().isEmpty()); + Set expectedEnumValues = new HashSet<>(Arrays.asList(SampleEnum.values())); + assertEquals(expectedEnumValues, descriptor.serializer().enumeratedValues()); + } + @Test + void testEnumListProperty() { PropertyDescriptor> listDescriptor = PropertyFactory.enumListProperty("enumListProp", NAME_MAP) .desc("hello") .defaultValues(SampleEnum.A, SampleEnum.B) @@ -223,6 +245,9 @@ void testEnumProperty() { assertEquals("hello", listDescriptor.description()); assertEquals(Arrays.asList(SampleEnum.A, SampleEnum.B), listDescriptor.defaultValue()); assertEquals(Arrays.asList(SampleEnum.B, SampleEnum.C), listDescriptor.serializer().fromString("TEST_B,TEST_C")); + assertTrue(listDescriptor.serializer().isCollection()); + Set expectedEnumValues = new HashSet<>(Arrays.asList(SampleEnum.values())); + assertEquals(expectedEnumValues, listDescriptor.serializer().enumeratedValues()); } @@ -270,6 +295,7 @@ void testRegexProperty() { assertEquals("hello", descriptor.description()); assertEquals("^[A-Z].*$", descriptor.defaultValue().toString()); assertEquals("[0-9]+", descriptor.serializer().fromString("[0-9]+").toString()); + assertFalse(descriptor.serializer().isCollection()); } @Test From 5088b71596a478e7439d5439a1ffa67ed53677ed Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 14 Nov 2025 12:18:06 +0100 Subject: [PATCH 1840/1962] [core] Enum properties: supported deprecated values --- .../pmd/properties/ConstraintDecorator.java | 5 ++ .../pmd/properties/PropertyFactory.java | 32 +++++++++++- .../pmd/properties/PropertySerializer.java | 2 + .../internal/PropertyParsingUtil.java | 11 ++-- .../pmd/properties/internal/ValueSyntax.java | 15 +++++- .../properties/PropertyDescriptorTest.java | 52 +++++++++++++++++++ 6 files changed, 111 insertions(+), 6 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/ConstraintDecorator.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/ConstraintDecorator.java index 104433ea9ab..513a680ca08 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/ConstraintDecorator.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/ConstraintDecorator.java @@ -46,6 +46,11 @@ public T fromString(@NonNull String attributeData) { return t; } + @Override + public boolean isFromStringDeprecated(@NonNull String attributeData) { + return propertySerializer.isFromStringDeprecated(attributeData); + } + @Override public boolean isCollection() { return propertySerializer.isCollection(); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java index 24dcc82fdba..ea2d7fdd7ce 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java @@ -8,12 +8,14 @@ import static net.sourceforge.pmd.properties.internal.PropertyParsingUtil.enumerationParser; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.Function; import java.util.stream.Collectors; +import org.apache.commons.lang3.EnumUtils; import org.checkerframework.checker.nullness.qual.NonNull; import net.sourceforge.pmd.properties.PropertyBuilder.GenericCollectionPropertyBuilder; @@ -21,6 +23,7 @@ import net.sourceforge.pmd.properties.PropertyBuilder.RegexPropertyBuilder; import net.sourceforge.pmd.properties.internal.PropertyParsingUtil; import net.sourceforge.pmd.util.CollectionUtil; +import net.sourceforge.pmd.util.StringUtil; //@formatter:off /** @@ -310,6 +313,7 @@ public static GenericPropertyBuilder booleanProperty(String name) { public static GenericPropertyBuilder enumProperty(String name, Map nameToValue) { PropertySerializer parser = enumerationParser( nameToValue, + Collections.emptyMap(), t -> Objects.requireNonNull(CollectionUtil.getKeyOfValue(nameToValue, t)) ); return new GenericPropertyBuilder<>(name, parser); @@ -353,7 +357,33 @@ public static > GenericPropertyBuilder enumProperty(String Map labelsToValues = Arrays.stream(enumClass.getEnumConstants()) .collect(Collectors.toMap(labelMaker, t -> t)); - return new GenericPropertyBuilder<>(name, enumerationParser(labelsToValues, labelMaker)); + return new GenericPropertyBuilder<>(name, enumerationParser(labelsToValues, Collections.emptyMap(), labelMaker)); + } + + /** + * Returns a builder for an enumerated property for the given enum class. + * It uses the given mapping to support deprecated (old) values in addition to the + * default mapping. + * + *

            This build should only be used for maintaining backwards compatibility. + * + * @param name Property name + * @param enumClass Enum class + * @param deprecatedMapping Map with still allowed, but deprecated values + * @param Type of the enum class + * + * @return a new builder + * @deprecated Since 7.19.0. Only use it for maintaining compatibility. + */ + @Deprecated + public static > GenericPropertyBuilder enumProperty(String name, + Class enumClass, + Map deprecatedMapping) { + // default mapping using the default naming convention of enum properties: camel case + Function toString = v -> StringUtil.CaseConvention.SCREAMING_SNAKE_CASE.convertTo(StringUtil.CaseConvention.CAMEL_CASE, v.name()); + Map labelsToValues = EnumUtils.getEnumMap(enumClass, toString); + + return new GenericPropertyBuilder<>(name, enumerationParser(labelsToValues, deprecatedMapping, toString)); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertySerializer.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertySerializer.java index 37192ec302d..47284120117 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertySerializer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertySerializer.java @@ -47,6 +47,8 @@ public PropertySerializer withConstraint(PropertyConstraint t) { */ public abstract T fromString(@NonNull String attributeData); + public abstract boolean isFromStringDeprecated(@NonNull String attributeData); + /** * Format the value to a string. * diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java index 833d750f6f2..139922a5b4d 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java @@ -33,6 +33,7 @@ public final class PropertyParsingUtil { ValueSyntax.partialFunction( c -> Character.toString(c), s -> s.charAt(0), + s -> false, PropertyConstraint.fromPredicate( s -> s.length() == 1, "Should be exactly one character in length" @@ -79,6 +80,7 @@ public static PropertySerializer> toOptional(PropertySerializer< } return Optional.of(itemSyntax.fromString(str)); }, + itemSyntax::isFromStringDeprecated, itemSyntax.isCollection(), itemSyntax.enumeratedValues() ); @@ -133,6 +135,8 @@ public static > PropertySerializer delimitedString(P return ValueSyntax.create( coll -> IteratorUtil.toStream(coll.iterator()).map(itemSyntax::toString).collect(Collectors.joining(delim)), string -> parseListWithEscapes(string, PropertyFactory.DEFAULT_DELIMITER, itemSyntax::fromString).stream().collect(collector), + string -> parseListWithEscapes(string, PropertyFactory.DEFAULT_DELIMITER, s -> s).stream() + .anyMatch(itemSyntax::isFromStringDeprecated), true, itemSyntax.enumeratedValues() ); @@ -199,7 +203,7 @@ public static List parseListWithEscapes(String str, char delimiter, Funct } - public static ValueSyntax enumerationParser(final Map mappings, Function reverseFun) { + public static ValueSyntax enumerationParser(final Map mappings, final Map deprecatedMappings, Function reverseFun) { if (mappings.containsValue(null)) { throw new IllegalArgumentException("Map may not contain entries with null values"); @@ -207,9 +211,10 @@ public static ValueSyntax enumerationParser(final Map mappings return ValueSyntax.partialFunction( reverseFun, - mappings::get, + s -> mappings.getOrDefault(s, deprecatedMappings.get(s)), + deprecatedMappings::containsKey, PropertyConstraint.fromPredicate( - mappings::containsKey, + s -> mappings.containsKey(s) || deprecatedMappings.containsKey(s), "Should be " + XmlUtil.formatPossibleNames(XmlUtil.toConstants(mappings.keySet())) ), new HashSet<>(mappings.values()) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/ValueSyntax.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/ValueSyntax.java index 68c840796a7..ba66afbf2db 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/ValueSyntax.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/ValueSyntax.java @@ -34,6 +34,7 @@ class ValueSyntax extends InternalApiBridge.InternalPropertySerializer { private final Function toString; private final Function<@NonNull String, ? extends T> fromString; + private final Function<@NonNull String, Boolean> deprecated; private final boolean collection; private final Set enumeratedValues; @@ -42,11 +43,13 @@ class ValueSyntax extends InternalApiBridge.InternalPropertySerializer { ValueSyntax(Function toString, Function<@NonNull String, ? extends T> fromString, + Function<@NonNull String, Boolean> deprecated, List> docConstraints, boolean collection, Set enumeratedValues) { this.toString = toString; this.fromString = fromString; + this.deprecated = deprecated; this.docConstraints = docConstraints; this.collection = collection; this.enumeratedValues = enumeratedValues; @@ -62,6 +65,11 @@ public T fromString(@NonNull String attributeData) { return fromString.apply(attributeData); } + @Override + public boolean isFromStringDeprecated(@NonNull String attributeData) { + return deprecated.apply(attributeData); + } + @Override public @NonNull String toString(T data) { return toString.apply(data); @@ -85,6 +93,7 @@ public Set enumeratedValues() { */ static ValueSyntax partialFunction(Function toString, Function<@NonNull String, ? extends T> fromString, + Function<@NonNull String, Boolean> deprecated, PropertyConstraint checker, Set enumeratedValues) { PropertyConstraint docConstraint = PropertyConstraint.fromPredicate( @@ -98,6 +107,7 @@ static ValueSyntax partialFunction(Function t checker.validate(s); return fromString.apply(s); }, + deprecated, listOf(docConstraint), false, enumeratedValues @@ -105,13 +115,14 @@ static ValueSyntax partialFunction(Function t } static ValueSyntax withDefaultToString(Function fromString) { - return new ValueSyntax<>(Objects::toString, fromString, Collections.emptyList(), false, Collections.emptySet()); + return new ValueSyntax<>(Objects::toString, fromString, s -> false, Collections.emptyList(), false, Collections.emptySet()); } static ValueSyntax create(Function toString, Function fromString, + Function<@NonNull String, Boolean> deprecated, boolean isCollection, Set enumeratedValues) { - return new ValueSyntax<>(toString, fromString, Collections.emptyList(), isCollection, enumeratedValues); + return new ValueSyntax<>(toString, fromString, deprecated, Collections.emptyList(), isCollection, enumeratedValues); } } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java index 8c8bd488428..c89da33debd 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.BiFunction; import java.util.function.Function; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; @@ -235,6 +236,38 @@ void testEnumProperty() { assertEquals(expectedEnumValues, descriptor.serializer().enumeratedValues()); } + @Test + void testEnumPropertyWithDeprecatedValueMappings() { + Map deprecatedMappings = new HashMap<>(NAME_MAP); + deprecatedMappings.put("A", SampleEnum.A); + PropertyDescriptor descriptor = PropertyFactory.enumProperty("enumProp", SampleEnum.class, deprecatedMappings) + .desc("hello") + .defaultValue(SampleEnum.B) + .build(); + assertEquals(SampleEnum.B, descriptor.defaultValue()); + + BiFunction assertValue = (v, s) -> { + assertEquals(v, descriptor.serializer().fromString(s)); + assertEquals(s, descriptor.serializer().toString(v)); + assertFalse(descriptor.serializer().isFromStringDeprecated(s)); + return null; + }; + BiFunction assertDeprecatedValue = (v, s) -> { + assertEquals(v, descriptor.serializer().fromString(s)); + assertTrue(descriptor.serializer().isFromStringDeprecated(s)); + return null; + }; + + assertValue.apply(SampleEnum.A, "a"); + assertValue.apply(SampleEnum.B, "b"); + assertValue.apply(SampleEnum.C, "c"); + + assertDeprecatedValue.apply(SampleEnum.A, "A"); + assertDeprecatedValue.apply(SampleEnum.A, "TEST_A"); + assertDeprecatedValue.apply(SampleEnum.B, "TEST_B"); + assertDeprecatedValue.apply(SampleEnum.C, "TEST_C"); + } + @Test void testEnumListProperty() { PropertyDescriptor> listDescriptor = PropertyFactory.enumListProperty("enumListProp", NAME_MAP) @@ -250,6 +283,25 @@ void testEnumListProperty() { assertEquals(expectedEnumValues, listDescriptor.serializer().enumeratedValues()); } + @Test + void testEnumListPropertyWithDeprecatedValueMappings() { + Map deprecatedMappings = new HashMap<>(NAME_MAP); + deprecatedMappings.put("A", SampleEnum.A); + PropertyDescriptor> listDescriptor = PropertyFactory.enumProperty("enumProp", SampleEnum.class, deprecatedMappings) + .toList() + .desc("hello") + .defaultValues(SampleEnum.A, SampleEnum.B) + .build(); + + assertEquals(Arrays.asList(SampleEnum.A, SampleEnum.B), listDescriptor.defaultValue()); + assertEquals("a,c", listDescriptor.serializer().toString(Arrays.asList(SampleEnum.A, SampleEnum.C))); + assertFalse(listDescriptor.serializer().isFromStringDeprecated("a")); + assertFalse(listDescriptor.serializer().isFromStringDeprecated("c")); + assertFalse(listDescriptor.serializer().isFromStringDeprecated("a,b")); + assertEquals(Arrays.asList(SampleEnum.B, SampleEnum.C), listDescriptor.serializer().fromString("TEST_B,TEST_C")); + assertTrue(listDescriptor.serializer().isFromStringDeprecated("TEST_A")); + assertTrue(listDescriptor.serializer().isFromStringDeprecated("TEST_A,TEST_C")); + } @Test void testEnumPropertyNullValueFailsBuild() { From cb5b5185e98b570e5ff7884a371e4e0afa991ce9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 14 Nov 2025 12:56:58 +0100 Subject: [PATCH 1841/1962] [core] RuleFactory: display warnings for deprecated properties --- .../pmd/lang/rule/RuleFactory.java | 20 +++++++-- .../internal/PropertyParsingUtil.java | 7 +++ .../util/internal/xml/XmlErrorMessages.java | 3 ++ .../MockRuleWithDeprecatedProperties.java | 38 ++++++++++++++++ .../lang/rule/RuleSetFactoryMessagesTest.java | 43 +++++++++++++++++++ .../pmd/doc/internal/RuleDocGenerator.java | 3 +- 6 files changed, 109 insertions(+), 5 deletions(-) create mode 100644 pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/MockRuleWithDeprecatedProperties.java diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleFactory.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleFactory.java index 0c4cd635344..bd81ce13f8b 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleFactory.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleFactory.java @@ -4,6 +4,7 @@ package net.sourceforge.pmd.lang.rule; +import static net.sourceforge.pmd.properties.internal.PropertyParsingUtil.DEPRECATED_RULE_PROPERTY_MARKER; import static net.sourceforge.pmd.util.internal.xml.SchemaConstants.CLASS; import static net.sourceforge.pmd.util.internal.xml.SchemaConstants.DELIMITER; import static net.sourceforge.pmd.util.internal.xml.SchemaConstants.DEPRECATED; @@ -29,6 +30,8 @@ import static net.sourceforge.pmd.util.internal.xml.XmlErrorMessages.ERR__PROPERTY_DOES_NOT_EXIST; import static net.sourceforge.pmd.util.internal.xml.XmlErrorMessages.IGNORED__DUPLICATE_PROPERTY_SETTER; import static net.sourceforge.pmd.util.internal.xml.XmlErrorMessages.IGNORED__PROPERTY_CHILD_HAS_PRECEDENCE; +import static net.sourceforge.pmd.util.internal.xml.XmlErrorMessages.WARN__DEPRECATED_ENUM_VALUE; +import static net.sourceforge.pmd.util.internal.xml.XmlErrorMessages.WARN__DEPRECATED_PROPERTY; import java.util.HashSet; import java.util.Optional; @@ -316,6 +319,10 @@ private void setPropertyValues(Rule rule, Element propertiesElt, PmdXmlReporter // todo just warn and ignore throw err.at(element).error(ERR__PROPERTY_DOES_NOT_EXIST, name, rule.getName()); } + if (desc.description().startsWith(DEPRECATED_RULE_PROPERTY_MARKER)) { + err.at(element).warn(WARN__DEPRECATED_PROPERTY, name, rule.getName()); + } + try { setRulePropertyCapture(rule, desc, element, err); } catch (XmlException e) { @@ -332,7 +339,7 @@ private void setPropertyValues(Rule rule, Element propertiesElt, PmdXmlReporter } private void setRulePropertyCapture(Rule rule, PropertyDescriptor descriptor, Element propertyElt, PmdXmlReporter err) { - T value = parsePropertyValue(propertyElt, err, descriptor.serializer()); + T value = parsePropertyValue(propertyElt, err, descriptor.name(), descriptor.serializer()); rule.setProperty(descriptor, value); } @@ -384,7 +391,7 @@ private static PropertyDescriptor propertyDefCapture(Element propertyElem } parseConstraints(propertyElement, factory, builder, err); - builder.defaultValue(parsePropertyValue(propertyElement, err, factory.getXmlMapper())); + builder.defaultValue(parsePropertyValue(propertyElement, err, name, factory.getXmlMapper())); return builder.build(); } catch (IllegalArgumentException e) { @@ -438,7 +445,7 @@ private static Comparable asComparableOrThrow(T object, PmdReporter err) throw err.error("Object is not comparable"); } - private static T parsePropertyValue(Element propertyElt, PmdXmlReporter err, PropertySerializer syntax) { + private static T parsePropertyValue(Element propertyElt, PmdXmlReporter err, String propertyName, PropertySerializer syntax) { String valueAttr = PROPERTY_VALUE.getAttributeOrNull(propertyElt); Element valueChild = PROPERTY_VALUE.getOptChildIn(propertyElt, err); Attr attrNode = PROPERTY_VALUE.getAttributeNode(propertyElt); @@ -458,7 +465,12 @@ private static T parsePropertyValue(Element propertyElt, PmdXmlReporter err, } try { - return syntax.fromString(valueStr); + T result = syntax.fromString(valueStr); + + if (syntax.isFromStringDeprecated(valueStr)) { + err.at(node).warn(WARN__DEPRECATED_ENUM_VALUE, valueStr, propertyName, syntax.toString(result)); + } + return result; } catch (ConstraintViolatedException e) { throw err.at(node).error(e, StringUtil.quoteMessageFormat(e.getMessageWithoutValue())); } catch (IllegalArgumentException e) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java index 139922a5b4d..4e7ca8977d8 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java @@ -28,6 +28,13 @@ */ public final class PropertyParsingUtil { + /** + * Marker used for rule properties, that are deprecated. If the description of a property + * starts exactly with that string, then are warning is issued when the ruleset is loaded + * and the property is used and the rule documentation displays a deprecated label. + */ + public static final String DEPRECATED_RULE_PROPERTY_MARKER = "deprecated!"; + public static final ValueSyntax STRING = ValueSyntax.withDefaultToString(String::trim); public static final ValueSyntax CHARACTER = ValueSyntax.partialFunction( diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/internal/xml/XmlErrorMessages.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/internal/xml/XmlErrorMessages.java index 60973f9f3cf..d9061d1d65a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/internal/xml/XmlErrorMessages.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/internal/xml/XmlErrorMessages.java @@ -42,6 +42,9 @@ public final class XmlErrorMessages { public static final String ERR__UNSUPPORTED_PROPERTY_TYPE = "Unsupported property type ''{0}''"; public static final String WARN__DELIMITER_DEPRECATED = "Delimiter attribute is not supported anymore, values are always comma-separated."; + public static final String WARN__DEPRECATED_PROPERTY = "The property ''{0}'' on rule {1} is deprecated."; + public static final String WARN__DEPRECATED_ENUM_VALUE = "The value ''{0}'' for property ''{1}'' is deprecated. Use ''{2}'' instead."; + private XmlErrorMessages() { // utility class } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/MockRuleWithDeprecatedProperties.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/MockRuleWithDeprecatedProperties.java new file mode 100644 index 00000000000..2bbf8610d28 --- /dev/null +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/MockRuleWithDeprecatedProperties.java @@ -0,0 +1,38 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.rule; + +import java.util.HashMap; +import java.util.Map; + +import net.sourceforge.pmd.properties.PropertyDescriptor; +import net.sourceforge.pmd.properties.PropertyFactory; + +public class MockRuleWithDeprecatedProperties extends MockRuleWithNoProperties { + static final PropertyDescriptor STRING_PROPERTY = PropertyFactory.stringProperty("stringProp") + .desc("deprecated! This should not be used anymore") + .defaultValue("a") + .build(); + + enum SampleEnum { VALUE_A, VALUE_B } + + static final PropertyDescriptor ENUM_PROPERTY = PropertyFactory.enumProperty("enumProp", + SampleEnum.class, getDeprecatedMapping()) + .desc("This prop replaces the old stringProp") + .defaultValue(SampleEnum.VALUE_A) + .build(); + + private static Map getDeprecatedMapping() { + Map map = new HashMap<>(); + map.put("a", SampleEnum.VALUE_A); + map.put("b", SampleEnum.VALUE_B); + return map; + } + + public MockRuleWithDeprecatedProperties() { + definePropertyDescriptor(STRING_PROPERTY); + definePropertyDescriptor(ENUM_PROPERTY); + } +} diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleSetFactoryMessagesTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleSetFactoryMessagesTest.java index b876dbcb549..248c359c78d 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleSetFactoryMessagesTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/RuleSetFactoryMessagesTest.java @@ -142,4 +142,47 @@ void validationMessagesFromReferencedRulesets(@TempDir Path tempDir) throws Exce + " ^^^^^^^^^ Not a valid priority: 'not a priority', expected a number in [1,5]" )); } + + @Test + void deprecatedPropertyUsed() throws Exception { + String log = SystemLambda.tapSystemErr(() -> assertEquals("a", loadFirstRule( + rulesetXml( + dummyRule( + attrs -> attrs.put(SchemaConstants.CLASS, MockRuleWithDeprecatedProperties.class.getName()), + properties( + "\n" + + " a\n" + + "\n" + ) + ) + ) + ).getProperty(MockRuleWithDeprecatedProperties.STRING_PROPERTY))); + + assertThat(log, containsString( + " 10| \n" + + " ^^^^^^^^^ The property 'stringProp' on rule MockRuleName is deprecated." + )); + } + + @Test + void enumPropertyWithDeprecatedValueUsed() throws Exception { + String log = SystemLambda.tapSystemErr(() -> assertEquals(MockRuleWithDeprecatedProperties.SampleEnum.VALUE_A, loadFirstRule( + rulesetXml( + dummyRule( + attrs -> attrs.put(SchemaConstants.CLASS, MockRuleWithDeprecatedProperties.class.getName()), + properties( + "\n" + + " a\n" + + "\n" + ) + ) + ) + ).getProperty(MockRuleWithDeprecatedProperties.ENUM_PROPERTY))); + + assertThat(log, containsString( + " 10| \n" + + " 11| a\n" + + " ^^^^^^ The value 'a' for property 'enumProp' is deprecated. Use 'valueA' instead." + )); + } } diff --git a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java index 8ad203a999c..1344d9fafe9 100644 --- a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java +++ b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java @@ -4,6 +4,8 @@ package net.sourceforge.pmd.doc.internal; +import static net.sourceforge.pmd.properties.internal.PropertyParsingUtil.DEPRECATED_RULE_PROPERTY_MARKER; + import java.io.File; import java.io.IOException; import java.nio.file.FileVisitResult; @@ -57,7 +59,6 @@ public class RuleDocGenerator { private static final String DEPRECATION_LABEL_SMALL = "Deprecated "; private static final String DEPRECATION_LABEL = "Deprecated"; - private static final String DEPRECATED_RULE_PROPERTY_MARKER = "deprecated!"; private static final String GITHUB_SOURCE_LINK = "https://github.com/pmd/pmd/blob/main/"; From 8761d04a21fbfc455638af847a1910c1c06ccdce Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 18 Nov 2025 19:14:49 +0100 Subject: [PATCH 1842/1962] [core] Define new enumProperty method, deprecated old --- .../pmd/properties/PropertyFactory.java | 81 +++++++++++++++++-- .../MockRuleWithDeprecatedProperties.java | 2 +- .../properties/PropertyDescriptorTest.java | 4 +- .../net/sourceforge/pmd/test/RuleTst.java | 3 + 4 files changed, 80 insertions(+), 10 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java index ea2d7fdd7ce..f73fd9de8c6 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java @@ -309,7 +309,10 @@ public static GenericPropertyBuilder booleanProperty(String name) { * @throws IllegalArgumentException If the map contains a null value or key * * @return A new builder + * + * @deprecated Since 7.19.0. Use {@link #enumPropertyNew(String, Class)} instead. */ + @Deprecated public static GenericPropertyBuilder enumProperty(String name, Map nameToValue) { PropertySerializer parser = enumerationParser( nameToValue, @@ -329,7 +332,9 @@ public static GenericPropertyBuilder enumProperty(String name, Map Type of the enum class * * @return A new builder + * @deprecated Since 7.19.0. Use {@link #enumPropertyNew(String, Class)} instead. */ + @Deprecated public static > GenericPropertyBuilder enumProperty(String name, Class enumClass) { return enumProperty(name, enumClass, Object::toString); } @@ -348,7 +353,10 @@ public static > GenericPropertyBuilder enumProperty(String * @throws NullPointerException If any of the arguments is null * @throws IllegalArgumentException If the label maker returns null on some constant * @throws IllegalStateException If the label maker maps two constants to the same label + * + * @deprecated Since 7.19.0. Use {@link #enumPropertyNew(String, Class)} instead. */ + @Deprecated public static > GenericPropertyBuilder enumProperty(String name, Class enumClass, Function labelMaker) { @@ -361,11 +369,31 @@ public static > GenericPropertyBuilder enumProperty(String } /** - * Returns a builder for an enumerated property for the given enum class. - * It uses the given mapping to support deprecated (old) values in addition to the - * default mapping. + * Returns a builder for an enumerated property for the given enum + * class. It is using the conventional mapping of its enum constants + * to labels. Enum constants are expected to be in "SCREAMING_SNAKE_CASE", + * the labels are in "camelCase". + * + * @param name Property name + * @param enumClass Enum class + * @param Type of the enum class + * + * @return A new builder + */ + public static > GenericPropertyBuilder enumPropertyNew(String name, Class enumClass) { + return enumPropertyTransitional(name, enumClass, Collections.emptyMap()); + } + + /** + * Returns a builder for an enumerated property for the given enum + * class. It is using the conventional mapping of its enum constants + * to labels. Enum constants are expected to be in "SCREAMING_SNAKE_CASE", + * the labels are in "camelCase". + * + *

            It uses additionally the given mapping to support deprecated (old) values in addition to the + * default mapping.

            * - *

            This build should only be used for maintaining backwards compatibility. + *

            This build should only be used for maintaining backwards compatibility.

            * * @param name Property name * @param enumClass Enum class @@ -373,10 +401,8 @@ public static > GenericPropertyBuilder enumProperty(String * @param Type of the enum class * * @return a new builder - * @deprecated Since 7.19.0. Only use it for maintaining compatibility. */ - @Deprecated - public static > GenericPropertyBuilder enumProperty(String name, + public static > GenericPropertyBuilder enumPropertyTransitional(String name, Class enumClass, Map deprecatedMapping) { // default mapping using the default naming convention of enum properties: camel case @@ -386,6 +412,41 @@ public static > GenericPropertyBuilder enumProperty(String return new GenericPropertyBuilder<>(name, enumerationParser(labelsToValues, deprecatedMapping, toString)); } + /** + * Returns a builder for a property having as value a list of the given enum class {@code }. The + * format of the individual items is the same as for {@linkplain #enumProperty(String, Map)}. + * + * @param name Name of the property to build + * @param enumClass Enum class + * @param Value type of the property + * + * @return A new builder + */ + public static > GenericCollectionPropertyBuilder> enumListPropertyNew(String name, Class enumClass) { + return enumPropertyNew(name, enumClass).toList(); + } + + /** + * Returns a builder for a property having as value a list of the given enum class {@code }. The + * format of the individual items is the same as for {@linkplain #enumProperty(String, Map)}. + * + *

            It uses additionally the given mapping to support deprecated (old) values in addition to the + * default mapping.

            + * + *

            This build should only be used for maintaining backwards compatibility.

            + * + * @param name Name of the property to build + * @param enumClass Enum class + * @param deprecatedMapping Map with still allowed, but deprecated values + * @param Value type of the property + * + * @return A new builder + */ + public static > GenericCollectionPropertyBuilder> enumListPropertyTransitional(String name, + Class enumClass, Map deprecatedMapping) { + return enumPropertyTransitional(name, enumClass, deprecatedMapping).toList(); + } + /** * Returns a builder for a property having as value a list of {@code }. The @@ -396,7 +457,10 @@ public static > GenericPropertyBuilder enumProperty(String * @param Value type of the property * * @return A new builder + * + * @deprecated Since 7.19.0. Use {@link #enumListPropertyNew(String, Class)} instead. */ + @Deprecated public static GenericCollectionPropertyBuilder> enumListProperty(String name, Map nameToValue) { return enumProperty(name, nameToValue).toList(); } @@ -412,7 +476,10 @@ public static GenericCollectionPropertyBuilder> enumListProperty( * @param Value type of the property * * @return A new builder + * + * @deprecated Since 7.19.0. Use {@link #enumListPropertyNew(String, Class)} instead. */ + @Deprecated public static > GenericCollectionPropertyBuilder> enumListProperty(String name, Class enumClass, Function labelMaker) { Map enumMap = CollectionUtil.associateBy(asList(enumClass.getEnumConstants()), labelMaker); return enumListProperty(name, enumMap); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/MockRuleWithDeprecatedProperties.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/MockRuleWithDeprecatedProperties.java index 2bbf8610d28..3bdec5789b8 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/MockRuleWithDeprecatedProperties.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/MockRuleWithDeprecatedProperties.java @@ -18,7 +18,7 @@ public class MockRuleWithDeprecatedProperties extends MockRuleWithNoProperties { enum SampleEnum { VALUE_A, VALUE_B } - static final PropertyDescriptor ENUM_PROPERTY = PropertyFactory.enumProperty("enumProp", + static final PropertyDescriptor ENUM_PROPERTY = PropertyFactory.enumPropertyTransitional("enumProp", SampleEnum.class, getDeprecatedMapping()) .desc("This prop replaces the old stringProp") .defaultValue(SampleEnum.VALUE_A) diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java index c89da33debd..448bddc1ef1 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java @@ -240,7 +240,7 @@ void testEnumProperty() { void testEnumPropertyWithDeprecatedValueMappings() { Map deprecatedMappings = new HashMap<>(NAME_MAP); deprecatedMappings.put("A", SampleEnum.A); - PropertyDescriptor descriptor = PropertyFactory.enumProperty("enumProp", SampleEnum.class, deprecatedMappings) + PropertyDescriptor descriptor = PropertyFactory.enumPropertyTransitional("enumProp", SampleEnum.class, deprecatedMappings) .desc("hello") .defaultValue(SampleEnum.B) .build(); @@ -287,7 +287,7 @@ void testEnumListProperty() { void testEnumListPropertyWithDeprecatedValueMappings() { Map deprecatedMappings = new HashMap<>(NAME_MAP); deprecatedMappings.put("A", SampleEnum.A); - PropertyDescriptor> listDescriptor = PropertyFactory.enumProperty("enumProp", SampleEnum.class, deprecatedMappings) + PropertyDescriptor> listDescriptor = PropertyFactory.enumPropertyTransitional("enumProp", SampleEnum.class, deprecatedMappings) .toList() .desc("hello") .defaultValues(SampleEnum.A, SampleEnum.B) diff --git a/pmd-test/src/main/java/net/sourceforge/pmd/test/RuleTst.java b/pmd-test/src/main/java/net/sourceforge/pmd/test/RuleTst.java index 6b1e58fecc7..c968376863a 100644 --- a/pmd-test/src/main/java/net/sourceforge/pmd/test/RuleTst.java +++ b/pmd-test/src/main/java/net/sourceforge/pmd/test/RuleTst.java @@ -115,6 +115,9 @@ void runTest(RuleTestDescriptor test) { } Object value = propertyDescriptor.serializer().fromString((String) entry.getValue()); + if (propertyDescriptor.serializer().isFromStringDeprecated((String) entry.getValue())) { + System.err.println(rule.getName() + ":" + test.getDescription() + ": Deprecated property value used! " + entry); + } rule.setProperty(propertyDescriptor, value); } } From aceaefba6be034f46ea294c024775c85f595a6e9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 18 Nov 2025 19:58:50 +0100 Subject: [PATCH 1843/1962] [java] Refactor rule to use new enum property --- .../sourceforge/pmd/util/CollectionUtil.java | 11 ++++ .../AvoidReassigningLoopVariablesRule.java | 22 ++------ .../rule/codestyle/ConfusingTernaryRule.java | 22 +++++--- .../rule/codestyle/ModifierOrderRule.java | 22 +++----- .../documentation/CommentRequiredRule.java | 52 +++++++++---------- .../resources/category/java/codestyle.xml | 4 +- .../documentation/CommentRequiredTest.java | 6 +-- .../rule/codestyle/xml/ConfusingTernary.xml | 33 +++++++++--- .../java/rule/codestyle/xml/ModifierOrder.xml | 39 ++++++++++++-- .../documentation/xml/CommentRequired.xml | 47 ++++++++++------- 10 files changed, 157 insertions(+), 101 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java index a8e2758a29c..f7465c6a017 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java @@ -233,6 +233,17 @@ public static Map mapOf(K k1, V v1, K k2, V v2) { return Collections.unmodifiableMap(map); } + /** + * @since 7.19.0. + */ + public static Map mapOf(K k1, V v1, K k2, V v2, K k3, V v3) { + Map map = new LinkedHashMap<>(); + map.put(k1, v1); + map.put(k2, v2); + map.put(k3, v3); + return Collections.unmodifiableMap(map); + } + public static Map buildMap(Consumer> effect) { Map map = new LinkedHashMap<>(); effect.accept(map); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java index 1061e1e55e3..f1889002886 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java @@ -4,7 +4,7 @@ package net.sourceforge.pmd.lang.java.rule.bestpractices; -import static net.sourceforge.pmd.properties.PropertyFactory.enumProperty; +import static net.sourceforge.pmd.properties.PropertyFactory.enumPropertyNew; import java.util.Set; import java.util.stream.Collectors; @@ -41,13 +41,13 @@ public class AvoidReassigningLoopVariablesRule extends AbstractJavaRulechainRule { private static final PropertyDescriptor FOREACH_REASSIGN - = enumProperty("foreachReassign", ForeachReassignOption.class, ForeachReassignOption::getDisplayName) + = enumPropertyNew("foreachReassign", ForeachReassignOption.class) .defaultValue(ForeachReassignOption.DENY) .desc("how/if foreach control variables may be reassigned") .build(); private static final PropertyDescriptor FOR_REASSIGN - = enumProperty("forReassign", ForReassignOption.class, ForReassignOption::getDisplayName) + = enumPropertyNew("forReassign", ForReassignOption.class) .defaultValue(ForReassignOption.DENY) .desc("how/if for control variables may be reassigned") .build(); @@ -297,21 +297,7 @@ private enum ForeachReassignOption { /** * Allow reassigning the 'foreach' control variable. */ - ALLOW; - - /** - * The RuleDocGenerator uses toString() to determine the default value. - * - * @return the mapped property value instead of the enum name - */ - @Override - public String toString() { - return getDisplayName(); - } - - public String getDisplayName() { - return CaseConvention.SCREAMING_SNAKE_CASE.convertTo(CaseConvention.CAMEL_CASE, name()); - } + ALLOW } private enum ForReassignOption { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryRule.java index 9b589d25d2c..39cf3f16f65 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ConfusingTernaryRule.java @@ -5,7 +5,9 @@ package net.sourceforge.pmd.lang.java.rule.codestyle; import static net.sourceforge.pmd.properties.PropertyFactory.booleanProperty; -import static net.sourceforge.pmd.properties.PropertyFactory.enumProperty; +import static net.sourceforge.pmd.properties.PropertyFactory.enumPropertyTransitional; + +import java.util.Map; import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression; import net.sourceforge.pmd.lang.java.ast.ASTExpression; @@ -17,6 +19,7 @@ import net.sourceforge.pmd.lang.java.ast.UnaryOp; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; import net.sourceforge.pmd.properties.PropertyDescriptor; +import net.sourceforge.pmd.util.CollectionUtil; /** @@ -57,13 +60,16 @@ public class ConfusingTernaryRule extends AbstractJavaRulechainRule { private static final PropertyDescriptor IGNORE_ELSE_IF = booleanProperty("ignoreElseIf") .desc("Ignore conditions with an else-if case").defaultValue(false).build(); - private static final PropertyDescriptor NULL_CHECK_BRANCH = enumProperty("nullCheckBranch", NullCheckBranch.class) - .desc("One of `Any`, `Then`, `Else`. For `Any` null checks may have any form," - + " for `Then` only `foo == null` is allowed, for `Else` only `foo != null` is allowed") - .defaultValue(NullCheckBranch.Any).build(); + private static final Map DEPRECATED_MAPPING = + CollectionUtil.mapOf("Any", NullCheckBranch.ANY, "Then", NullCheckBranch.THEN, "Else", NullCheckBranch.ELSE); + + private static final PropertyDescriptor NULL_CHECK_BRANCH = enumPropertyTransitional("nullCheckBranch", NullCheckBranch.class, DEPRECATED_MAPPING) + .desc("For `any` null checks may have any form," + + " for `then` only `foo == null` is allowed, for `else` only `foo != null` is allowed") + .defaultValue(NullCheckBranch.ANY).build(); private enum NullCheckBranch { - Any, Then, Else + ANY, THEN, ELSE } public ConfusingTernaryRule() { @@ -114,12 +120,12 @@ private boolean isNotEquals(ASTExpression node) { // look for "x != y" if (infix.getOperator() == BinaryOp.NE) { return !isNullComparison(infix) - || getProperty(NULL_CHECK_BRANCH) == NullCheckBranch.Then; + || getProperty(NULL_CHECK_BRANCH) == NullCheckBranch.THEN; } return infix.getOperator() == BinaryOp.EQ && isNullComparison(infix) - && getProperty(NULL_CHECK_BRANCH) == NullCheckBranch.Else; + && getProperty(NULL_CHECK_BRANCH) == NullCheckBranch.ELSE; } private boolean isNullComparison(ASTInfixExpression infix) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ModifierOrderRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ModifierOrderRule.java index 05b7145dcbd..c5ba1103b39 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ModifierOrderRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/ModifierOrderRule.java @@ -5,6 +5,7 @@ package net.sourceforge.pmd.lang.java.rule.codestyle; import java.util.List; +import java.util.Map; import org.checkerframework.checker.nullness.qual.Nullable; @@ -27,7 +28,7 @@ import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.properties.PropertyFactory; import net.sourceforge.pmd.reporting.RuleContext; -import net.sourceforge.pmd.util.AssertionUtil; +import net.sourceforge.pmd.util.CollectionUtil; import net.sourceforge.pmd.util.OptionalBool; /** @@ -47,8 +48,11 @@ public class ModifierOrderRule extends AbstractJavaRulechainRule { private static final String MSG_TYPE_ANNOT_SHOULD_BE_BEFORE_TYPE = "Missorted modifiers `{0} {1}`. Type annotations should be placed before the type they qualify."; + private static final Map TYPE_ANNOT_POLICY_DEPRECATED_MAPPING = + CollectionUtil.mapOf("ontype", TypeAnnotationPosition.ON_TYPE, "ondecl", TypeAnnotationPosition.ON_DECL); + private static final PropertyDescriptor TYPE_ANNOT_POLICY - = PropertyFactory.enumProperty("typeAnnotations", TypeAnnotationPosition.class, TypeAnnotationPosition::label) + = PropertyFactory.enumPropertyTransitional("typeAnnotations", TypeAnnotationPosition.class, TYPE_ANNOT_POLICY_DEPRECATED_MAPPING) .desc("Whether type annotations should be placed next to the type they qualify and not before modifiers.") .defaultValue(TypeAnnotationPosition.ANYWHERE) .build(); @@ -56,19 +60,7 @@ public class ModifierOrderRule extends AbstractJavaRulechainRule { public enum TypeAnnotationPosition { ON_TYPE, ON_DECL, - ANYWHERE; - - String label() { - switch (this) { - case ON_TYPE: - return "ontype"; - case ON_DECL: - return "ondecl"; - case ANYWHERE: - return "anywhere"; - } - throw AssertionUtil.shouldNotReachHere("exhaustive switch"); - } + ANYWHERE } private TypeAnnotationPosition typeAnnotPosition; diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredRule.java index 5a97a21c3c6..30308d164bc 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredRule.java @@ -34,13 +34,16 @@ public class CommentRequiredRule extends AbstractJavaRulechainRule { // Used to pretty print a message private static final Map DESCRIPTOR_NAME_TO_COMMENT_TYPE = new HashMap<>(); + private static final Map COMMENT_REQUIREMENT_DEPRECATED_MAPPING = + CollectionUtil.mapOf("Required", CommentRequirement.REQUIRED, "Ignored", CommentRequirement.IGNORED, + "Unwanted", CommentRequirement.UNWANTED); private static final PropertyDescriptor ACCESSOR_CMT_DESCRIPTOR = requirementPropertyBuilder("accessorCommentRequirement", "Comments on getters and setters\"") - .defaultValue(CommentRequirement.Ignored).build(); + .defaultValue(CommentRequirement.IGNORED).build(); private static final PropertyDescriptor OVERRIDE_CMT_DESCRIPTOR = requirementPropertyBuilder("methodWithOverrideCommentRequirement", "Comments on @Override methods") - .defaultValue(CommentRequirement.Ignored).build(); + .defaultValue(CommentRequirement.IGNORED).build(); private static final PropertyDescriptor CLASS_CMT_REQUIREMENT_DESCRIPTOR = requirementPropertyBuilder("classCommentRequirement", "Class comments").build(); private static final PropertyDescriptor FIELD_CMT_REQUIREMENT_DESCRIPTOR @@ -53,10 +56,10 @@ public class CommentRequiredRule extends AbstractJavaRulechainRule { = requirementPropertyBuilder("enumCommentRequirement", "Enum comments").build(); private static final PropertyDescriptor SERIAL_VERSION_UID_CMT_REQUIREMENT_DESCRIPTOR = requirementPropertyBuilder("serialVersionUIDCommentRequired", "Serial version UID comments") - .defaultValue(CommentRequirement.Ignored).build(); + .defaultValue(CommentRequirement.IGNORED).build(); private static final PropertyDescriptor SERIAL_PERSISTENT_FIELDS_CMT_REQUIREMENT_DESCRIPTOR = requirementPropertyBuilder("serialPersistentFieldsCommentRequired", "Serial persistent fields comments") - .defaultValue(CommentRequirement.Ignored).build(); + .defaultValue(CommentRequirement.IGNORED).build(); /** stores the resolved property values. This is necessary in order to transparently use deprecated properties. */ private final Map, CommentRequirement> propertyValues = new HashMap<>(); @@ -92,14 +95,14 @@ public void start(RuleContext ctx) { private void checkCommentMeetsRequirement(Object data, JavadocCommentOwner node, PropertyDescriptor descriptor) { switch (propertyValues.get(descriptor)) { - case Ignored: + case IGNORED: break; - case Required: + case REQUIRED: if (node.getJavadocComment() == null) { commentRequiredViolation(data, node, descriptor); } break; - case Unwanted: + case UNWANTED: if (node.getJavadocComment() != null) { commentRequiredViolation(data, node, descriptor); } @@ -116,7 +119,7 @@ private void commentRequiredViolation(Object data, JavaNode node, asCtx(data).addViolationWithMessage(node, DESCRIPTOR_NAME_TO_COMMENT_TYPE.get(descriptor.name()) + " are " - + getProperty(descriptor).label.toLowerCase(Locale.ROOT)); + + getProperty(descriptor).name().toLowerCase(Locale.ROOT)); } @@ -178,15 +181,15 @@ public Object visit(ASTEnumDeclaration decl, Object data) { private boolean allCommentsAreIgnored() { - return getProperty(OVERRIDE_CMT_DESCRIPTOR) == CommentRequirement.Ignored - && getProperty(ACCESSOR_CMT_DESCRIPTOR) == CommentRequirement.Ignored - && getProperty(CLASS_CMT_REQUIREMENT_DESCRIPTOR) == CommentRequirement.Ignored - && getProperty(FIELD_CMT_REQUIREMENT_DESCRIPTOR) == CommentRequirement.Ignored - && getProperty(PUB_METHOD_CMT_REQUIREMENT_DESCRIPTOR) == CommentRequirement.Ignored - && getProperty(PROT_METHOD_CMT_REQUIREMENT_DESCRIPTOR) == CommentRequirement.Ignored - && getProperty(ENUM_CMT_REQUIREMENT_DESCRIPTOR) == CommentRequirement.Ignored - && getProperty(SERIAL_VERSION_UID_CMT_REQUIREMENT_DESCRIPTOR) == CommentRequirement.Ignored - && getProperty(SERIAL_PERSISTENT_FIELDS_CMT_REQUIREMENT_DESCRIPTOR) == CommentRequirement.Ignored; + return getProperty(OVERRIDE_CMT_DESCRIPTOR) == CommentRequirement.IGNORED + && getProperty(ACCESSOR_CMT_DESCRIPTOR) == CommentRequirement.IGNORED + && getProperty(CLASS_CMT_REQUIREMENT_DESCRIPTOR) == CommentRequirement.IGNORED + && getProperty(FIELD_CMT_REQUIREMENT_DESCRIPTOR) == CommentRequirement.IGNORED + && getProperty(PUB_METHOD_CMT_REQUIREMENT_DESCRIPTOR) == CommentRequirement.IGNORED + && getProperty(PROT_METHOD_CMT_REQUIREMENT_DESCRIPTOR) == CommentRequirement.IGNORED + && getProperty(ENUM_CMT_REQUIREMENT_DESCRIPTOR) == CommentRequirement.IGNORED + && getProperty(SERIAL_VERSION_UID_CMT_REQUIREMENT_DESCRIPTOR) == CommentRequirement.IGNORED + && getProperty(SERIAL_PERSISTENT_FIELDS_CMT_REQUIREMENT_DESCRIPTOR) == CommentRequirement.IGNORED; } @Override @@ -195,21 +198,14 @@ public String dysfunctionReason() { } private enum CommentRequirement { - Required("Required"), Ignored("Ignored"), Unwanted("Unwanted"); - - private final String label; - - CommentRequirement(String theLabel) { - label = theLabel; - } + REQUIRED, IGNORED, UNWANTED } - // pre-filled builder private static GenericPropertyBuilder requirementPropertyBuilder(String name, String commentType) { DESCRIPTOR_NAME_TO_COMMENT_TYPE.put(name, commentType); - return PropertyFactory.enumProperty(name, CommentRequirement.class, cr -> cr.label) - .desc(commentType + ". Possible values: " + CollectionUtil.map(CommentRequirement.values(), cr -> cr.label)) - .defaultValue(CommentRequirement.Required); + return PropertyFactory.enumPropertyTransitional(name, CommentRequirement.class, COMMENT_REQUIREMENT_DEPRECATED_MAPPING) + .desc(commentType) + .defaultValue(CommentRequirement.REQUIRED); } } diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml index 1f57d48d2a9..4df63429e19 100644 --- a/pmd-java/src/main/resources/category/java/codestyle.xml +++ b/pmd-java/src/main/resources/category/java/codestyle.xml @@ -1150,8 +1150,8 @@ public class Foo { By setting the property `typeAnnotations`, you can also enforce that type annotations appear right of the modifier keywords, next to the type they apply to. This property can have three values: - - `ontype`: Type annotations must be placed next to the type they apply to - - `ondecl`: Type annotations must be placed with other annotations, before modifiers. + - `onType`: Type annotations must be placed next to the type they apply to + - `onDecl`: Type annotations must be placed with other annotations, before modifiers. This is not enforced if the type annotations syntactically appears within the type, e.g. in `public Map.@Nullable Entry<K,V> method()` or `public <T> @NonNull T method()`. - `anywhere` (default): Either position fits. They still cannot be interspersed within keyword diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredTest.java index 8f0bb0e2043..733ac74c3de 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/documentation/CommentRequiredTest.java @@ -24,17 +24,17 @@ void allCommentTypesIgnored() { List> propertyDescriptors = getProperties(rule); for (PropertyDescriptor property : propertyDescriptors) { - setPropertyValue(rule, property, "Ignored"); + setPropertyValue(rule, property, "ignored"); } assertNotNull(rule.dysfunctionReason(), "All properties are ignored, rule should be dysfunctional"); // now, try out combinations: only one of the properties is required. for (PropertyDescriptor property : propertyDescriptors) { - setPropertyValue(rule, property, "Required"); + setPropertyValue(rule, property, "required"); assertNull(rule.dysfunctionReason(), "The property " + property.name() + " is set to required, the rule should be functional."); - setPropertyValue(rule, property, "Ignored"); + setPropertyValue(rule, property, "ignored"); } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ConfusingTernary.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ConfusingTernary.xml index 35072121944..847d3b7bf43 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ConfusingTernary.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ConfusingTernary.xml @@ -58,43 +58,64 @@ public class Foo { - null check, ok (if) - any branch + null check, ok (if) - any branch (deprecated property test) Any 0 - null check, ok (if) - else branch + null check, ok (if) - any branch + any + 0 + + + + + null check, ok (if) - else branch (deprecated property test) Else 0 - null check, not ok (if) - then branch + null check, ok (if) - else branch + else + 0 + + + + + null check, not ok (if) - then branch (deprecated property test) Then 1 + + null check, not ok (if) - then branch + then + 1 + + + null check, ok (if) - any branch - Any + any 0 null check, not ok (if) - else branch - Else + else 1 null check, ok (if) - then branch - Then + then 0 diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ModifierOrder.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ModifierOrder.xml index 04af2665ff5..3e58684086b 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ModifierOrder.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ModifierOrder.xml @@ -78,7 +78,7 @@ abstract public class Foo { // warn l1 - Annotation order (property=ontype) + Annotation order (property=ontype) (deprecated property value test) ontype 7 7,10,14,16,19,22,24 @@ -93,12 +93,45 @@ abstract public class Foo { // warn l1 - + - Annotation order (property=ondecl) + Annotation order (property=ontype) + onType + 7 + 7,10,14,16,19,22,24 + + Missorted modifiers `@TypeA public`. Type annotations should be placed before the type they qualify. + Missorted modifiers `@TypeA public`. Type annotations should be placed before the type they qualify. + Missorted modifiers `@TypeA static`. Type annotations should be placed before the type they qualify. + Missorted modifiers `@TypeA public`. Type annotations should be placed before the type they qualify. + Missorted modifiers `@TypeA public`. Type annotations should be placed before the type they qualify. + Missorted modifiers `static @Decl`. Annotations should be placed before modifiers. + Missorted modifiers `@TypeA static`. Type annotations should be placed before the type they qualify. + + + + + + Annotation order (property=ondecl) (deprecated property value test) ondecl 6 5,8,14,17,22,24 + + Missorted modifiers `public @TypeA`. Annotations should be placed before modifiers. + Missorted modifiers `public @Decl`. Annotations should be placed before modifiers. + Missorted modifiers `public @TypeA`. Annotations should be placed before modifiers. + Missorted modifiers `public @Decl`. Annotations should be placed before modifiers. + Missorted modifiers `static @Decl`. Annotations should be placed before modifiers. + Missorted modifiers `public @TypeA`. Annotations should be placed before modifiers. + + + + + + Annotation order (property=ondecl) + onDecl + 6 + 5,8,14,17,22,24 Missorted modifiers `public @TypeA`. Type annotations should be placed before modifiers. Missorted modifiers `public @Decl`. Non-type annotations should be placed before modifiers. diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentRequired.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentRequired.xml index 6fe42408a28..16f6ac5e0ad 100755 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentRequired.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/documentation/xml/CommentRequired.xml @@ -51,7 +51,7 @@ public class Foo { - Missing comments - only class level required. + Missing comments - only class level required. (deprecate property values test) Required Ignored Ignored @@ -61,13 +61,24 @@ public class Foo { + + Missing comments - only class level required. + required + ignored + ignored + ignored + ignored + 1 + + + Too many comments - all comments are unwanted. - Unwanted - Unwanted - Unwanted - Unwanted - Unwanted + unwanted + unwanted + unwanted + unwanted + unwanted 6 @@ -151,7 +162,7 @@ public class CommentRequired implements java.io.Serializable { serialVersionUID comment required - Required + required 1 3 #1684 serialPersistentFields comment required - Required + required 1 7 Test @override methods reporting - Required + required 2 Test @override methods reporting #2 - Required + required 0 Test @override methods unwanted - Unwanted + unwanted 2 9,16 @@ -415,7 +426,7 @@ public class CommentRequired { Test getter or setter comments are ignored by default - Ignored + ignored 0 Test accessors are reported when required - Ignored - Required + ignored + required 3 Test accessors are reported when unwanted - Ignored - Unwanted + ignored + unwanted 2 #1683 [java] CommentRequired property names are inconsistent - Unwanted + unwanted 1 Method overridden without @Override (#3123) - Required + required 1 4 Date: Thu, 20 Nov 2025 12:34:29 +0100 Subject: [PATCH 1844/1962] [java] Refactor rules to use new enum list property --- .../AvoidUsingHardCodedIPRule.java | 21 ++-- .../rule/design/CyclomaticComplexityRule.java | 12 +- .../lang/java/rule/design/NcssCountRule.java | 13 +-- ...oidBranchingStatementAsLastInLoopRule.java | 108 ++++++++++++++---- .../xml/AvoidUsingHardCodedIP.xml | 17 ++- 5 files changed, 110 insertions(+), 61 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidUsingHardCodedIPRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidUsingHardCodedIPRule.java index 84ea62da0c4..711d3238764 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidUsingHardCodedIPRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidUsingHardCodedIPRule.java @@ -8,6 +8,7 @@ import java.util.EnumSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -19,25 +20,25 @@ import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.properties.PropertyFactory; import net.sourceforge.pmd.reporting.RuleContext; +import net.sourceforge.pmd.util.CollectionUtil; public class AvoidUsingHardCodedIPRule extends AbstractJavaRulechainRule { private enum AddressKinds { - IPV4("IPv4"), - IPV6("IPv6"), - IPV4_MAPPED_IPV6("IPv4 mapped IPv6"); - - private final String label; - - AddressKinds(String label) { - this.label = label; - } + IPV4, + IPV6, + IPV4_MAPPED_IPV6 } + private static final Map DEPRECATED_ADDRESS_KINDS = CollectionUtil.mapOf( + "IPv4", AddressKinds.IPV4, + "IPv6", AddressKinds.IPV6, + "IPv4 mapped IPv6", AddressKinds.IPV4_MAPPED_IPV6 + ); private static final PropertyDescriptor> CHECK_ADDRESS_TYPES_DESCRIPTOR = - PropertyFactory.enumListProperty("checkAddressTypes", AddressKinds.class, k -> k.label) + PropertyFactory.enumListPropertyTransitional("checkAddressTypes", AddressKinds.class, DEPRECATED_ADDRESS_KINDS) .desc("Check for IP address types.") .defaultValue(asList(AddressKinds.values())) .build(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CyclomaticComplexityRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CyclomaticComplexityRule.java index fe221d3239f..d7729c31331 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CyclomaticComplexityRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CyclomaticComplexityRule.java @@ -6,9 +6,7 @@ import static net.sourceforge.pmd.properties.NumericConstraints.positive; -import java.util.HashMap; import java.util.List; -import java.util.Map; import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTExecutableDeclaration; @@ -43,16 +41,8 @@ public class CyclomaticComplexityRule extends AbstractJavaRulechainRule { .desc("Cyclomatic complexity reporting threshold") .require(positive()).defaultValue(10).build(); - private static final Map OPTION_MAP; - - static { - OPTION_MAP = new HashMap<>(); - OPTION_MAP.put(CycloOption.IGNORE_BOOLEAN_PATHS.valueName(), CycloOption.IGNORE_BOOLEAN_PATHS); - OPTION_MAP.put(CycloOption.CONSIDER_ASSERT.valueName(), CycloOption.CONSIDER_ASSERT); - } - private static final PropertyDescriptor> CYCLO_OPTIONS_DESCRIPTOR - = PropertyFactory.enumListProperty("cycloOptions", OPTION_MAP) + = PropertyFactory.enumListPropertyNew("cycloOptions", CycloOption.class) .desc("Choose options for the computation of Cyclo") .emptyDefaultValue() .build(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/NcssCountRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/NcssCountRule.java index 7244df718e4..8a6bbe0530c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/NcssCountRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/NcssCountRule.java @@ -6,9 +6,7 @@ import static net.sourceforge.pmd.properties.NumericConstraints.positive; -import java.util.HashMap; import java.util.List; -import java.util.Map; import net.sourceforge.pmd.lang.java.ast.ASTExecutableDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; @@ -48,19 +46,12 @@ public final class NcssCountRule extends AbstractJavaRulechainRule { .defaultValue(1500) .build(); - private static final PropertyDescriptor> NCSS_OPTIONS_DESCRIPTOR; - - static { - Map options = new HashMap<>(); - options.put(NcssOption.COUNT_IMPORTS.valueName(), NcssOption.COUNT_IMPORTS); - - NCSS_OPTIONS_DESCRIPTOR = PropertyFactory.enumListProperty("ncssOptions", options) + private static final PropertyDescriptor> NCSS_OPTIONS_DESCRIPTOR = + PropertyFactory.enumListPropertyNew("ncssOptions", NcssOption.class) .desc("Choose options for the computation of Ncss") .emptyDefaultValue() .build(); - } - public NcssCountRule() { super(ASTExecutableDeclaration.class, ASTTypeDeclaration.class); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java index 85ddc490dc6..0b6e19fd770 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java @@ -5,10 +5,8 @@ package net.sourceforge.pmd.lang.java.rule.errorprone; import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Map; +import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; @@ -26,39 +24,67 @@ import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.properties.PropertyFactory; +import net.sourceforge.pmd.util.StringUtil; public class AvoidBranchingStatementAsLastInLoopRule extends AbstractJavaRulechainRule { + /** + * @since 7.19.0. Should have never been public. + */ + @Deprecated + public static final String CHECK_FOR = "for"; + /** + * @since 7.19.0. Should have never been public. + */ + @Deprecated + public static final String CHECK_DO = "do"; + /** + * @since 7.19.0. Should have never been public. + */ + @Deprecated public static final String CHECK_WHILE = "while"; - private static final Map LOOP_TYPES_MAPPINGS; - private static final List DEFAULTS = Arrays.asList(CHECK_FOR, CHECK_DO, CHECK_WHILE); + private static final List DEFAULTS = Arrays.asList(LoopTypes.FOR, LoopTypes.DO, LoopTypes.WHILE); - static { - Map mappings = new HashMap<>(); - mappings.put(CHECK_FOR, CHECK_FOR); - mappings.put(CHECK_DO, CHECK_DO); - mappings.put(CHECK_WHILE, CHECK_WHILE); - LOOP_TYPES_MAPPINGS = Collections.unmodifiableMap(mappings); + private enum LoopTypes { + FOR, DO, WHILE; } // TODO I don't think we need this configurability. // I think we should tone that down to just be able to ignore some type of statement, // but I can't see a use case to e.g. report only breaks in 'for' loops but not in 'while'. + /** + * @deprecated Since 7.19.0. Should have been private. + */ + @Deprecated public static final PropertyDescriptor> CHECK_BREAK_LOOP_TYPES = propertyFor("break"); + + /** + * @deprecated Since 7.19.0. Should have been private. + */ + @Deprecated public static final PropertyDescriptor> CHECK_CONTINUE_LOOP_TYPES = propertyFor("continue"); + + /** + * @deprecated Since 7.19.0. Should have been private. + */ + @Deprecated public static final PropertyDescriptor> CHECK_RETURN_LOOP_TYPES = propertyFor("return"); + private static final PropertyDescriptor> CHECK_BREAK_LOOP_TYPES_NEW = propertyForNew("break"); + private static final PropertyDescriptor> CHECK_CONTINUE_LOOP_TYPES_NEW = propertyForNew("continue"); + private static final PropertyDescriptor> CHECK_RETURN_LOOP_TYPES_NEW = propertyForNew("return"); + public AvoidBranchingStatementAsLastInLoopRule() { super(ASTBreakStatement.class, ASTContinueStatement.class, ASTReturnStatement.class); - definePropertyDescriptor(CHECK_BREAK_LOOP_TYPES); - definePropertyDescriptor(CHECK_CONTINUE_LOOP_TYPES); - definePropertyDescriptor(CHECK_RETURN_LOOP_TYPES); + definePropertyDescriptor(CHECK_BREAK_LOOP_TYPES_NEW); + definePropertyDescriptor(CHECK_CONTINUE_LOOP_TYPES_NEW); + definePropertyDescriptor(CHECK_RETURN_LOOP_TYPES_NEW); } @@ -68,11 +94,19 @@ public Object visit(ASTBreakStatement node, Object data) { if (node.ancestors().get(1) instanceof ASTSwitchStatement) { return data; } - return check(CHECK_BREAK_LOOP_TYPES, node, data); + return check(CHECK_BREAK_LOOP_TYPES_NEW, node, data); } - protected Object check(PropertyDescriptor> property, Node node, Object data) { + /** + * @deprecated Since 7.19.0. Should have been private. + */ + @Deprecated + protected Object check(PropertyDescriptor> property, Node node, Object data) { + return checkInternal(property, node, data); + } + + private Object checkInternal(PropertyDescriptor> property, Node node, Object data) { Node parent = node.getParent(); if (parent instanceof ASTBlock) { parent = parent.getParent(); @@ -83,15 +117,15 @@ protected Object check(PropertyDescriptor> property, Node node, Obj } } if (parent instanceof ASTForStatement || parent instanceof ASTForeachStatement) { - if (hasPropertyValue(property, CHECK_FOR)) { + if (hasPropertyValue(property, LoopTypes.FOR)) { asCtx(data).addViolation(node); } } else if (parent instanceof ASTWhileStatement) { - if (hasPropertyValue(property, CHECK_WHILE)) { + if (hasPropertyValue(property, LoopTypes.WHILE)) { asCtx(data).addViolation(node); } } else if (parent instanceof ASTDoStatement) { - if (hasPropertyValue(property, CHECK_DO)) { + if (hasPropertyValue(property, LoopTypes.DO)) { asCtx(data).addViolation(node); } } @@ -99,20 +133,28 @@ protected Object check(PropertyDescriptor> property, Node node, Obj } + /** + * @deprecated Since 7.19.0. Should have been private. + */ + @Deprecated protected boolean hasPropertyValue(PropertyDescriptor> property, String value) { return getProperty(property).contains(value); } + private boolean hasPropertyValue(PropertyDescriptor> property, LoopTypes value) { + return getProperty(property).contains(value); + } + @Override public Object visit(ASTContinueStatement node, Object data) { - return check(CHECK_CONTINUE_LOOP_TYPES, node, data); + return check(CHECK_CONTINUE_LOOP_TYPES_NEW, node, data); } @Override public Object visit(ASTReturnStatement node, Object data) { - return check(CHECK_RETURN_LOOP_TYPES, node, data); + return check(CHECK_RETURN_LOOP_TYPES_NEW, node, data); } @@ -121,16 +163,34 @@ public String dysfunctionReason() { return checksNothing() ? "All loop types are ignored" : null; } + @Deprecated private static PropertyDescriptor> propertyFor(String stmtName) { - return PropertyFactory.enumListProperty("check" + StringUtils.capitalize(stmtName) + "LoopTypes", LOOP_TYPES_MAPPINGS) + return PropertyFactory.stringListProperty("check" + StringUtils.capitalize(stmtName) + "LoopTypes") + .desc("List of loop types in which " + stmtName + " statements will be checked") + .defaultValue(DEFAULTS.stream() + .map(v -> StringUtil.CaseConvention.SCREAMING_SNAKE_CASE.convertTo(StringUtil.CaseConvention.CAMEL_CASE, v.name())) + .collect(Collectors.toList())) + .build(); + } + + private static PropertyDescriptor> propertyForNew(String stmtName) { + return PropertyFactory.enumListPropertyNew("check" + StringUtils.capitalize(stmtName) + "LoopTypes", LoopTypes.class) .desc("List of loop types in which " + stmtName + " statements will be checked") .defaultValue(DEFAULTS) .build(); } + /** + * @deprecated Since 7.19.0. Should have been private. + */ + @Deprecated public boolean checksNothing() { + return checksNothingInternal(); + } - return getProperty(CHECK_BREAK_LOOP_TYPES).isEmpty() && getProperty(CHECK_CONTINUE_LOOP_TYPES).isEmpty() - && getProperty(CHECK_RETURN_LOOP_TYPES).isEmpty(); + private boolean checksNothingInternal() { + return getProperty(CHECK_BREAK_LOOP_TYPES_NEW).isEmpty() + && getProperty(CHECK_CONTINUE_LOOP_TYPES_NEW).isEmpty() + && getProperty(CHECK_RETURN_LOOP_TYPES_NEW).isEmpty(); } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml index 470f89b2631..b16c322ff02 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/AvoidUsingHardCodedIP.xml @@ -57,12 +57,19 @@ public class Foo { ]]> - Comprehensive, check for IPv4 mapped IPv6 xxx + Comprehensive, check for IPv4 mapped IPv6 xxx (deprecated property value test) IPv4 mapped IPv6 4 + + Comprehensive, check for IPv4 mapped IPv6 xxx + ipv4MappedIpv6 + 4 + + + Common basic case 1 @@ -135,28 +142,28 @@ class Foo { Comprehensive, check for IPv4 - IPv4 + ipv4 6 Comprehensive, check for IPv6 - IPv6 + ipv6 11 Comprehensive, check for IPv4 mapped IPv6 - IPv4 mapped IPv6 + ipv4MappedIpv6 4 Comprehensive, check for IPv6 and IPv4 mapped IPv6 - IPv6,IPv4 mapped IPv6 + ipv6,ipv4MappedIpv6 15 From 38a0e8bba6625cf699e2de8095104ce75ac5f4ab Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Nov 2025 13:00:06 +0100 Subject: [PATCH 1845/1962] [java] Refactor metric test rules to use new enum property --- .../pmd/lang/metrics/MetricOption.java | 11 +++- .../metrics/ParameterizedMetricKeyTest.java | 8 +-- .../properties/PropertyDescriptorTest.java | 39 ++++++++++++-- .../pmd/lang/java/metrics/JavaMetrics.java | 12 +++++ .../lang/java/metrics/impl/CfoTestRule.java | 14 +---- .../lang/java/metrics/impl/CycloTestRule.java | 14 +---- .../JavaIntMetricWithOptionsTestRule.java | 34 ++++++++++++ .../lang/java/metrics/impl/NPathTestRule.java | 2 +- .../lang/java/metrics/impl/NcssTestRule.java | 14 +---- .../pmd/lang/test/AbstractMetricTestRule.java | 53 ++++++++++++++----- 10 files changed, 139 insertions(+), 62 deletions(-) create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/JavaIntMetricWithOptionsTestRule.java diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOption.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOption.java index 84e155ec611..4c0cc7362b0 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOption.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOption.java @@ -4,6 +4,8 @@ package net.sourceforge.pmd.lang.metrics; +import net.sourceforge.pmd.util.StringUtil; + /** * Option to pass to a metric. Options modify the behaviour of a metric. * You must bundle them into a {@link MetricOptions} to pass them all to a metric. @@ -27,7 +29,12 @@ public interface MetricOption { * Returns the name of the option as it should be used in properties. * * @return The name of the option. + * @deprecated Since 7.19.0. When metrics are used for (rule) properties, then the default + * enum mapping (from SCREAMING_SNAKE_CASE to camelCase) will be used for the enum values. + * See {@link net.sourceforge.pmd.properties.PropertyFactory#enumListPropertyNew(String, Class)}. */ - String valueName(); - + @Deprecated + default String valueName() { + return StringUtil.CaseConvention.SCREAMING_SNAKE_CASE.convertTo(StringUtil.CaseConvention.CAMEL_CASE, name()); + } } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/metrics/ParameterizedMetricKeyTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/metrics/ParameterizedMetricKeyTest.java index ebe27c5ce81..327770eb519 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/metrics/ParameterizedMetricKeyTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/metrics/ParameterizedMetricKeyTest.java @@ -67,13 +67,7 @@ void testAdHocMetricKey() { private enum Options implements MetricOption { DUMMY1, - DUMMY2; - - - @Override - public String valueName() { - return null; - } + DUMMY2 } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java index 448bddc1ef1..86da2b25a30 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java @@ -221,15 +221,15 @@ private enum SampleEnum { A, B, C } } @Test - void testEnumProperty() { - PropertyDescriptor descriptor = PropertyFactory.enumProperty("enumProp", NAME_MAP) + void testEnumPropertyNew() { + PropertyDescriptor descriptor = PropertyFactory.enumPropertyNew("enumProp", SampleEnum.class) .desc("hello") .defaultValue(SampleEnum.B) .build(); assertEquals("enumProp", descriptor.name()); assertEquals("hello", descriptor.description()); assertEquals(SampleEnum.B, descriptor.defaultValue()); - assertEquals(SampleEnum.C, descriptor.serializer().fromString("TEST_C")); + assertEquals(SampleEnum.C, descriptor.serializer().fromString("c")); assertFalse(descriptor.serializer().isCollection()); assertFalse(descriptor.serializer().enumeratedValues().isEmpty()); Set expectedEnumValues = new HashSet<>(Arrays.asList(SampleEnum.values())); @@ -269,6 +269,22 @@ void testEnumPropertyWithDeprecatedValueMappings() { } @Test + void testEnumListPropertyNew() { + PropertyDescriptor> listDescriptor = PropertyFactory.enumListPropertyNew("enumListProp", SampleEnum.class) + .desc("hello") + .defaultValues(SampleEnum.A, SampleEnum.B) + .build(); + assertEquals("enumListProp", listDescriptor.name()); + assertEquals("hello", listDescriptor.description()); + assertEquals(Arrays.asList(SampleEnum.A, SampleEnum.B), listDescriptor.defaultValue()); + assertEquals(Arrays.asList(SampleEnum.B, SampleEnum.C), listDescriptor.serializer().fromString("b,c")); + assertTrue(listDescriptor.serializer().isCollection()); + Set expectedEnumValues = new HashSet<>(Arrays.asList(SampleEnum.values())); + assertEquals(expectedEnumValues, listDescriptor.serializer().enumeratedValues()); + } + + @Test + @Deprecated // Tests the deprecated API void testEnumListProperty() { PropertyDescriptor> listDescriptor = PropertyFactory.enumListProperty("enumListProp", NAME_MAP) .desc("hello") @@ -283,6 +299,23 @@ void testEnumListProperty() { assertEquals(expectedEnumValues, listDescriptor.serializer().enumeratedValues()); } + @Test + @Deprecated // Tests the deprecated API + void testEnumProperty() { + PropertyDescriptor descriptor = PropertyFactory.enumProperty("enumProp", NAME_MAP) + .desc("hello") + .defaultValue(SampleEnum.B) + .build(); + assertEquals("enumProp", descriptor.name()); + assertEquals("hello", descriptor.description()); + assertEquals(SampleEnum.B, descriptor.defaultValue()); + assertEquals(SampleEnum.C, descriptor.serializer().fromString("TEST_C")); + assertFalse(descriptor.serializer().isCollection()); + assertFalse(descriptor.serializer().enumeratedValues().isEmpty()); + Set expectedEnumValues = new HashSet<>(Arrays.asList(SampleEnum.values())); + assertEquals(expectedEnumValues, descriptor.serializer().enumeratedValues()); + } + @Test void testEnumListPropertyWithDeprecatedValueMappings() { Map deprecatedMappings = new HashMap<>(NAME_MAP); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java index 31fa04c75ba..0453c6ed35c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java @@ -615,7 +615,11 @@ public enum NcssOption implements MetricOption { } + /** + * @deprecated Since 7.19.0. + */ @Override + @Deprecated public String valueName() { return vName; } @@ -639,7 +643,11 @@ public enum CycloOption implements MetricOption { } + /** + * @deprecated Since 7.19.0. + */ @Override + @Deprecated public String valueName() { return vName; } @@ -687,7 +695,11 @@ public enum ClassFanOutOption implements MetricOption { this.vName = valueName; } + /** + * @deprecated Since 7.19.0. + */ @Override + @Deprecated public String valueName() { return vName; } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/CfoTestRule.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/CfoTestRule.java index 8e5a7253f9a..4cfe33b104f 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/CfoTestRule.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/CfoTestRule.java @@ -4,25 +4,15 @@ package net.sourceforge.pmd.lang.java.metrics.impl; -import java.util.Map; - import net.sourceforge.pmd.lang.java.metrics.JavaMetrics; import net.sourceforge.pmd.lang.java.metrics.JavaMetrics.ClassFanOutOption; -import net.sourceforge.pmd.lang.metrics.MetricOption; /** * @author Andreas Pabst */ -public class CfoTestRule extends JavaIntMetricTestRule { +public class CfoTestRule extends JavaIntMetricWithOptionsTestRule { public CfoTestRule() { - super(JavaMetrics.FAN_OUT); - } - - @Override - protected Map optionMappings() { - Map mappings = super.optionMappings(); - mappings.put(ClassFanOutOption.INCLUDE_JAVA_LANG.valueName(), ClassFanOutOption.INCLUDE_JAVA_LANG); - return mappings; + super(JavaMetrics.FAN_OUT, ClassFanOutOption.class); } } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/CycloTestRule.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/CycloTestRule.java index 852560aac1b..2fe375e569b 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/CycloTestRule.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/CycloTestRule.java @@ -4,28 +4,18 @@ package net.sourceforge.pmd.lang.java.metrics.impl; -import java.util.Map; - import net.sourceforge.pmd.lang.java.metrics.JavaMetrics; import net.sourceforge.pmd.lang.java.metrics.JavaMetrics.CycloOption; -import net.sourceforge.pmd.lang.metrics.MetricOption; /** * Tests cyclo. * * @author Clรฉment Fournier */ -public class CycloTestRule extends JavaIntMetricTestRule { +public class CycloTestRule extends JavaIntMetricWithOptionsTestRule { public CycloTestRule() { - super(JavaMetrics.CYCLO); + super(JavaMetrics.CYCLO, CycloOption.class); } - @Override - protected Map optionMappings() { - Map mappings = super.optionMappings(); - mappings.put(CycloOption.IGNORE_BOOLEAN_PATHS.valueName(), CycloOption.IGNORE_BOOLEAN_PATHS); - mappings.put(CycloOption.CONSIDER_ASSERT.valueName(), CycloOption.CONSIDER_ASSERT); - return mappings; - } } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/JavaIntMetricWithOptionsTestRule.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/JavaIntMetricWithOptionsTestRule.java new file mode 100644 index 00000000000..425fde8c777 --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/JavaIntMetricWithOptionsTestRule.java @@ -0,0 +1,34 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.metrics.impl; + +import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.java.ast.ASTExecutableDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration; +import net.sourceforge.pmd.lang.metrics.Metric; +import net.sourceforge.pmd.lang.metrics.MetricOption; +import net.sourceforge.pmd.lang.test.AbstractMetricTestRule; + +/** + * @since 7.19.0. + */ +public abstract class JavaIntMetricWithOptionsTestRule & MetricOption> extends AbstractMetricTestRule.OfIntWithOptions { + + protected JavaIntMetricWithOptionsTestRule(Metric metric, Class metricOptionsEnum) { + super(metric, metricOptionsEnum); + } + + @Override + protected boolean reportOn(Node node) { + return super.reportOn(node) + && (node instanceof ASTExecutableDeclaration + || node instanceof ASTTypeDeclaration); + } + + @Override + protected String violationMessage(Node node, Integer result) { + return AllMetricsTest.formatJavaMessage(node, result); + } +} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NPathTestRule.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NPathTestRule.java index 7b6ea966d4c..64e32135b4e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NPathTestRule.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NPathTestRule.java @@ -11,7 +11,7 @@ /** * @author Clรฉment Fournier */ -public class NPathTestRule extends AbstractMetricTestRule { +public class NPathTestRule extends AbstractMetricTestRule { public NPathTestRule() { super(JavaMetrics.NPATH_COMP); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NcssTestRule.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NcssTestRule.java index 27f5e7cd09f..c73c6e885c7 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NcssTestRule.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/NcssTestRule.java @@ -4,21 +4,18 @@ package net.sourceforge.pmd.lang.java.metrics.impl; -import java.util.Map; - import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.java.ast.ASTExecutableDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration; import net.sourceforge.pmd.lang.java.metrics.JavaMetrics; import net.sourceforge.pmd.lang.java.metrics.JavaMetrics.NcssOption; -import net.sourceforge.pmd.lang.metrics.MetricOption; import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.properties.PropertyFactory; /** * @author Clรฉment Fournier */ -public class NcssTestRule extends JavaIntMetricTestRule { +public class NcssTestRule extends JavaIntMetricWithOptionsTestRule { static final PropertyDescriptor REPORT_CLASSES = PropertyFactory.booleanProperty("reportClasses") @@ -26,7 +23,7 @@ public class NcssTestRule extends JavaIntMetricTestRule { .defaultValue(false).build(); public NcssTestRule() { - super(JavaMetrics.NCSS); + super(JavaMetrics.NCSS, NcssOption.class); definePropertyDescriptor(REPORT_CLASSES); } @@ -36,11 +33,4 @@ protected boolean reportOn(Node node) { && (node instanceof ASTExecutableDeclaration || getProperty(REPORT_CLASSES) && node instanceof ASTTypeDeclaration); } - - @Override - protected Map optionMappings() { - Map mappings = super.optionMappings(); - mappings.put(NcssOption.COUNT_IMPORTS.valueName(), NcssOption.COUNT_IMPORTS); - return mappings; - } } diff --git a/pmd-lang-test/src/main/java/net/sourceforge/pmd/lang/test/AbstractMetricTestRule.java b/pmd-lang-test/src/main/java/net/sourceforge/pmd/lang/test/AbstractMetricTestRule.java index 61ae56b966a..0635c4ed775 100644 --- a/pmd-lang-test/src/main/java/net/sourceforge/pmd/lang/test/AbstractMetricTestRule.java +++ b/pmd-lang-test/src/main/java/net/sourceforge/pmd/lang/test/AbstractMetricTestRule.java @@ -27,16 +27,19 @@ * * @param Result type of the metric. The nested subclasses provide * defaults for common result types + * @param The enum type of the {@link MetricOption}. If the metric doesn't + * support options, then {@link NoOptions} can be used as + * a placeholder. * * @author Clรฉment Fournier */ -public abstract class AbstractMetricTestRule> extends AbstractRule { +public abstract class AbstractMetricTestRule, O extends Enum & MetricOption> extends AbstractRule { - private final PropertyDescriptor> optionsDescriptor = - PropertyFactory.enumListProperty("metricOptions", optionMappings()) - .desc("Choose a variant of the metric or the standard") - .emptyDefaultValue() - .build(); + public enum NoOptions implements MetricOption { + VOID + } + + private final PropertyDescriptor> optionsDescriptor; private final PropertyDescriptor reportLevelDescriptor = PropertyFactory.stringProperty("reportLevel") @@ -47,10 +50,23 @@ public abstract class AbstractMetricTestRule> e private final Metric metric; public AbstractMetricTestRule(Metric metric) { + this(metric, null); + } + + public AbstractMetricTestRule(Metric metric, Class metricOptionsEnum) { this.metric = metric; + if (metricOptionsEnum != null) { + this.optionsDescriptor = + PropertyFactory.enumListPropertyNew("metricOptions", metricOptionsEnum) + .desc("Choose a variant of the metric or the standard") + .emptyDefaultValue() + .build(); + definePropertyDescriptor(optionsDescriptor); + } else { + this.optionsDescriptor = null; + } definePropertyDescriptor(reportLevelDescriptor); - definePropertyDescriptor(optionsDescriptor); } protected abstract N parseReportLevel(String value); @@ -63,12 +79,15 @@ protected boolean reportOn(Node node) { * Mappings of labels to options for use in the options property. * * @return A map of labels to options + * @deprecated Since 7.19.0. No extra mapping is required anymore. The {@link MetricOption} enum + * values are used. See {@link #AbstractMetricTestRule(Metric, Class)} to provide the + * enum at construction time. */ + @Deprecated protected Map optionMappings() { return new HashMap<>(); } - /** * Default report level, which is 0. * @@ -83,7 +102,10 @@ protected String violationMessage(Node node, N result) { @Override public void apply(Node target, RuleContext ctx) { if (reportOn(target)) { - MetricOptions options = MetricOptions.ofOptions(getProperty(optionsDescriptor)); + MetricOptions options = MetricOptions.emptyOptions(); + if (optionsDescriptor != null) { + options = MetricOptions.ofOptions(getProperty(optionsDescriptor)); + } N reportLevel = parseReportLevel(getProperty(reportLevelDescriptor)); N result = Metric.compute(metric, target, options); @@ -99,10 +121,15 @@ public void apply(Node target, RuleContext ctx) { } - public abstract static class OfInt extends AbstractMetricTestRule { - + public abstract static class OfInt extends OfIntWithOptions { protected OfInt(Metric metric) { - super(metric); + super(metric, null); + } + } + + public abstract static class OfIntWithOptions & MetricOption> extends AbstractMetricTestRule { + protected OfIntWithOptions(Metric metric, Class metricOptionsEnum) { + super(metric, metricOptionsEnum); } @Override @@ -116,7 +143,7 @@ protected Integer defaultReportLevel() { } } - public abstract static class OfDouble extends AbstractMetricTestRule { + public abstract static class OfDouble extends AbstractMetricTestRule { protected OfDouble(Metric metric) { super(metric); From 9a0cb3fe4d06a2c080d3aec3fc7a0cac33ce31f2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Nov 2025 14:43:09 +0100 Subject: [PATCH 1846/1962] [doc] Rule doc: test new enum properties --- .../SampleRuleWithEnumPropertiesRule.java | 15 +++++++++++++++ pmd-doc/src/test/resources/expected/sample.md | 4 ++++ 2 files changed, 19 insertions(+) diff --git a/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/SampleRuleWithEnumPropertiesRule.java b/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/SampleRuleWithEnumPropertiesRule.java index 238c8359987..f055860607f 100644 --- a/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/SampleRuleWithEnumPropertiesRule.java +++ b/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/SampleRuleWithEnumPropertiesRule.java @@ -18,16 +18,31 @@ private enum MyEnum { OPTION_TWO } + private static final PropertyDescriptor ENUM_PROPERTY_NEW = PropertyFactory.enumPropertyNew("enumPropertyNew", MyEnum.class) + .desc("Description") + .defaultValue(MyEnum.OPTION_ONE) + .build(); + + @Deprecated // required only for tests private static final PropertyDescriptor ENUM_PROPERTY = PropertyFactory.enumProperty("enumProperty", MyEnum.class) .desc("Description") .defaultValue(MyEnum.OPTION_ONE) .build(); + + private static final PropertyDescriptor> ENUMLIST_PROPERTY_NEW = PropertyFactory.enumListPropertyNew("enumListPropertyNew", MyEnum.class) + .desc("Description") + .emptyDefaultValue() + .build(); + + @Deprecated // required only for tests private static final PropertyDescriptor> ENUMLIST_PROPERTY = PropertyFactory.enumListProperty("enumListProperty", MyEnum.class, Object::toString) .desc("Description") .emptyDefaultValue() .build(); public SampleRuleWithEnumPropertiesRule() { + definePropertyDescriptor(ENUM_PROPERTY_NEW); + definePropertyDescriptor(ENUMLIST_PROPERTY_NEW); definePropertyDescriptor(ENUM_PROPERTY); definePropertyDescriptor(ENUMLIST_PROPERTY); } diff --git a/pmd-doc/src/test/resources/expected/sample.md b/pmd-doc/src/test/resources/expected/sample.md index cbd50cf95ef..12b33ab2a85 100644 --- a/pmd-doc/src/test/resources/expected/sample.md +++ b/pmd-doc/src/test/resources/expected/sample.md @@ -602,6 +602,8 @@ This rule is for testing enum properties |Name|Default Value|Description| |----|-------------|-----------| +|enumPropertyNew|optionOne|Description
            One of: `optionOne`, `optionTwo`| +|enumListPropertyNew||Description
            One or more of: `optionOne`, `optionTwo`| |enumProperty|OPTION\_ONE|Description
            One of: `OPTION\_ONE`, `OPTION\_TWO`| |enumListProperty||Description
            One or more of: `OPTION\_ONE`, `OPTION\_TWO`| @@ -614,6 +616,8 @@ This rule is for testing enum properties ``` xml + + From a92fb35276d28e1d244da442380d5d46cb060d07 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Nov 2025 15:00:38 +0100 Subject: [PATCH 1847/1962] [core] Remove last usages of deprecated enum property --- .../pmd/lang/LanguagePropertyBundle.java | 32 ++++++++++--------- .../properties/PropertyDescriptorTest.java | 20 ++++++++++-- .../java/internal/JavaLanguageProperties.java | 5 +-- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguagePropertyBundle.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguagePropertyBundle.java index bb39b83646a..0cfd48bb544 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguagePropertyBundle.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguagePropertyBundle.java @@ -4,13 +4,14 @@ package net.sourceforge.pmd.lang; +import java.util.stream.Collectors; + import org.checkerframework.checker.nullness.qual.NonNull; import net.sourceforge.pmd.PMDConfiguration; import net.sourceforge.pmd.properties.AbstractPropertySource; import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.properties.PropertyFactory; -import net.sourceforge.pmd.util.CollectionUtil; /** * A bundle of properties used by languages (see {@link Language#newPropertyBundle()}). @@ -32,7 +33,7 @@ public class LanguagePropertyBundle extends AbstractPropertySource { .build(); public static final String LANGUAGE_VERSION = "version"; - private final PropertyDescriptor languageVersion; + private final PropertyDescriptor languageVersion; private final Language language; /** @@ -40,24 +41,25 @@ public class LanguagePropertyBundle extends AbstractPropertySource { */ public LanguagePropertyBundle(@NonNull Language language) { this.language = language; + languageVersion = PropertyFactory.stringProperty(LANGUAGE_VERSION) + .desc("Language version to use for this language. See the --use-version CLI switch as well.") + .defaultValue(language.getDefaultVersion().getVersion()) + .build(); definePropertyDescriptor(SUPPRESS_MARKER); - - languageVersion = - PropertyFactory.enumProperty( - LANGUAGE_VERSION, - CollectionUtil.associateBy(language.getVersions(), LanguageVersion::getVersion) - ) - .desc("Language version to use for this language. See the --use-version CLI switch as well.") - - .defaultValue(language.getDefaultVersion()) - .build(); - definePropertyDescriptor(languageVersion); } public void setLanguageVersion(String string) { - setProperty(languageVersion, languageVersion.serializer().fromString(string)); + LanguageVersion version = language.getVersion(string); + if (version == null) { + throw new IllegalArgumentException("'" + string + "' should be one of " + + language.getVersions().stream() + .map(LanguageVersion::getVersion) + .map(s -> "'" + s + "'") + .collect(Collectors.joining(", "))); + } + setProperty(languageVersion, version.getVersion()); } @Override @@ -75,7 +77,7 @@ public Language getLanguage() { } public LanguageVersion getLanguageVersion() { - return getProperty(languageVersion); + return language.getVersion(getProperty(languageVersion)); } public String getSuppressMarker() { diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java index 86da2b25a30..0c3d93099e9 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java @@ -26,7 +26,7 @@ import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; -import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Strings; import org.hamcrest.Matcher; import org.hamcrest.Matchers; import org.hamcrest.core.SubstringMatcher; @@ -337,6 +337,7 @@ void testEnumListPropertyWithDeprecatedValueMappings() { } @Test + @Deprecated // Tests the deprecated API void testEnumPropertyNullValueFailsBuild() { Map map = new HashMap<>(NAME_MAP); map.put("TEST_NULL", null); @@ -346,8 +347,8 @@ void testEnumPropertyNullValueFailsBuild() { assertThat(thrown.getMessage(), containsIgnoreCase("null value")); } - @Test + @Deprecated // Tests the deprecated API void testEnumListPropertyNullValueFailsBuild() { Map map = new HashMap<>(NAME_MAP); map.put("TEST_NULL", null); @@ -359,6 +360,7 @@ void testEnumListPropertyNullValueFailsBuild() { @Test + @Deprecated // Tests the deprecated API void testEnumPropertyInvalidValue() { PropertyDescriptor descriptor = PropertyFactory.enumProperty("enumProp", NAME_MAP) .desc("hello") @@ -370,6 +372,18 @@ void testEnumPropertyInvalidValue() { assertThat(thrown.getMessage(), containsString("'InvalidEnumValue' should be one of 'TEST_A', 'TEST_B', 'TEST_C'")); } + @Test + void testEnumPropertyNewInvalidValue() { + PropertyDescriptor descriptor = PropertyFactory.enumPropertyNew("enumProp", SampleEnum.class) + .desc("hello") + .defaultValue(SampleEnum.B) + .build(); + + IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> + descriptor.serializer().fromString("InvalidEnumValue")); + assertThat(thrown.getMessage(), containsString("'InvalidEnumValue' should be one of 'a', 'b', 'c'")); + } + @Test void testRegexProperty() { PropertyDescriptor descriptor = PropertyFactory.regexProperty("regexProp") @@ -451,7 +465,7 @@ private static Matcher containsIgnoreCase(final String substring) { @Override protected boolean evalSubstringOf(String string) { - return StringUtils.indexOfIgnoreCase(string, substring) != -1; + return Strings.CI.indexOf(string, substring) != -1; } }; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProperties.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProperties.java index 3b652eb6b59..0b6c05df93d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProperties.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProperties.java @@ -4,8 +4,6 @@ package net.sourceforge.pmd.lang.java.internal; -import org.apache.commons.lang3.EnumUtils; - import net.sourceforge.pmd.cpd.CpdLanguageProperties; import net.sourceforge.pmd.lang.JvmLanguagePropertyBundle; import net.sourceforge.pmd.lang.LanguageVersion; @@ -22,8 +20,7 @@ public class JavaLanguageProperties extends JvmLanguagePropertyBundle { * @since 7.0.0 */ static final PropertyDescriptor INTERNAL_INFERENCE_LOGGING_VERBOSITY = - PropertyFactory.enumProperty("xTypeInferenceLogging", - EnumUtils.getEnumMap(InferenceLoggingVerbosity.class)) + PropertyFactory.enumPropertyNew("xTypeInferenceLogging", InferenceLoggingVerbosity.class) .desc("Verbosity of the type inference logging") .defaultValue(InferenceLoggingVerbosity.DISABLED) .build(); From c12b067cbd95f3eda3be3b2ef6d183eb354879d1 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 12 Dec 2025 15:16:17 +0100 Subject: [PATCH 1848/1962] [core] PropertyFactory: Rename enumPropNew -> conventionalEnumProperty --- .../pmd/lang/metrics/MetricOption.java | 2 +- .../pmd/properties/PropertyFactory.java | 20 +++++++++---------- .../properties/PropertyDescriptorTest.java | 6 +++--- .../SampleRuleWithEnumPropertiesRule.java | 4 ++-- .../java/internal/JavaLanguageProperties.java | 2 +- .../AvoidReassigningLoopVariablesRule.java | 6 +++--- .../rule/design/CyclomaticComplexityRule.java | 2 +- .../lang/java/rule/design/NcssCountRule.java | 2 +- ...oidBranchingStatementAsLastInLoopRule.java | 2 +- .../pmd/lang/test/AbstractMetricTestRule.java | 2 +- 10 files changed, 24 insertions(+), 24 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOption.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOption.java index 4c0cc7362b0..c0e1675a001 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOption.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOption.java @@ -31,7 +31,7 @@ public interface MetricOption { * @return The name of the option. * @deprecated Since 7.19.0. When metrics are used for (rule) properties, then the default * enum mapping (from SCREAMING_SNAKE_CASE to camelCase) will be used for the enum values. - * See {@link net.sourceforge.pmd.properties.PropertyFactory#enumListPropertyNew(String, Class)}. + * See {@link net.sourceforge.pmd.properties.PropertyFactory#conventionalEnumListProperty(String, Class)}. */ @Deprecated default String valueName() { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java index f73fd9de8c6..c50580053ea 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java @@ -310,7 +310,7 @@ public static GenericPropertyBuilder booleanProperty(String name) { * * @return A new builder * - * @deprecated Since 7.19.0. Use {@link #enumPropertyNew(String, Class)} instead. + * @deprecated Since 7.19.0. Use {@link #conventionalEnumProperty(String, Class)} instead. */ @Deprecated public static GenericPropertyBuilder enumProperty(String name, Map nameToValue) { @@ -332,7 +332,7 @@ public static GenericPropertyBuilder enumProperty(String name, Map Type of the enum class * * @return A new builder - * @deprecated Since 7.19.0. Use {@link #enumPropertyNew(String, Class)} instead. + * @deprecated Since 7.19.0. Use {@link #conventionalEnumProperty(String, Class)} instead. */ @Deprecated public static > GenericPropertyBuilder enumProperty(String name, Class enumClass) { @@ -354,7 +354,7 @@ public static > GenericPropertyBuilder enumProperty(String * @throws IllegalArgumentException If the label maker returns null on some constant * @throws IllegalStateException If the label maker maps two constants to the same label * - * @deprecated Since 7.19.0. Use {@link #enumPropertyNew(String, Class)} instead. + * @deprecated Since 7.19.0. Use {@link #conventionalEnumProperty(String, Class)} instead. */ @Deprecated public static > GenericPropertyBuilder enumProperty(String name, @@ -380,7 +380,7 @@ public static > GenericPropertyBuilder enumProperty(String * * @return A new builder */ - public static > GenericPropertyBuilder enumPropertyNew(String name, Class enumClass) { + public static > GenericPropertyBuilder conventionalEnumProperty(String name, Class enumClass) { return enumPropertyTransitional(name, enumClass, Collections.emptyMap()); } @@ -414,7 +414,7 @@ public static > GenericPropertyBuilder enumPropertyTransiti /** * Returns a builder for a property having as value a list of the given enum class {@code }. The - * format of the individual items is the same as for {@linkplain #enumProperty(String, Map)}. + * format of the individual items is the same as for {@linkplain #conventionalEnumProperty(String, Class)}. * * @param name Name of the property to build * @param enumClass Enum class @@ -422,13 +422,13 @@ public static > GenericPropertyBuilder enumPropertyTransiti * * @return A new builder */ - public static > GenericCollectionPropertyBuilder> enumListPropertyNew(String name, Class enumClass) { - return enumPropertyNew(name, enumClass).toList(); + public static > GenericCollectionPropertyBuilder> conventionalEnumListProperty(String name, Class enumClass) { + return conventionalEnumProperty(name, enumClass).toList(); } /** * Returns a builder for a property having as value a list of the given enum class {@code }. The - * format of the individual items is the same as for {@linkplain #enumProperty(String, Map)}. + * format of the individual items is the same as for {@linkplain #conventionalEnumProperty(String, Class)}. * *

            It uses additionally the given mapping to support deprecated (old) values in addition to the * default mapping.

            @@ -458,7 +458,7 @@ public static > GenericCollectionPropertyBuilder> e * * @return A new builder * - * @deprecated Since 7.19.0. Use {@link #enumListPropertyNew(String, Class)} instead. + * @deprecated Since 7.19.0. Use {@link #conventionalEnumListProperty(String, Class)} instead. */ @Deprecated public static GenericCollectionPropertyBuilder> enumListProperty(String name, Map nameToValue) { @@ -477,7 +477,7 @@ public static GenericCollectionPropertyBuilder> enumListProperty( * * @return A new builder * - * @deprecated Since 7.19.0. Use {@link #enumListPropertyNew(String, Class)} instead. + * @deprecated Since 7.19.0. Use {@link #conventionalEnumListProperty(String, Class)} instead. */ @Deprecated public static > GenericCollectionPropertyBuilder> enumListProperty(String name, Class enumClass, Function labelMaker) { diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java index 0c3d93099e9..d3d56843e2b 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/properties/PropertyDescriptorTest.java @@ -222,7 +222,7 @@ private enum SampleEnum { A, B, C } @Test void testEnumPropertyNew() { - PropertyDescriptor descriptor = PropertyFactory.enumPropertyNew("enumProp", SampleEnum.class) + PropertyDescriptor descriptor = PropertyFactory.conventionalEnumProperty("enumProp", SampleEnum.class) .desc("hello") .defaultValue(SampleEnum.B) .build(); @@ -270,7 +270,7 @@ void testEnumPropertyWithDeprecatedValueMappings() { @Test void testEnumListPropertyNew() { - PropertyDescriptor> listDescriptor = PropertyFactory.enumListPropertyNew("enumListProp", SampleEnum.class) + PropertyDescriptor> listDescriptor = PropertyFactory.conventionalEnumListProperty("enumListProp", SampleEnum.class) .desc("hello") .defaultValues(SampleEnum.A, SampleEnum.B) .build(); @@ -374,7 +374,7 @@ void testEnumPropertyInvalidValue() { @Test void testEnumPropertyNewInvalidValue() { - PropertyDescriptor descriptor = PropertyFactory.enumPropertyNew("enumProp", SampleEnum.class) + PropertyDescriptor descriptor = PropertyFactory.conventionalEnumProperty("enumProp", SampleEnum.class) .desc("hello") .defaultValue(SampleEnum.B) .build(); diff --git a/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/SampleRuleWithEnumPropertiesRule.java b/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/SampleRuleWithEnumPropertiesRule.java index f055860607f..16eec4d5105 100644 --- a/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/SampleRuleWithEnumPropertiesRule.java +++ b/pmd-doc/src/test/java/net/sourceforge/pmd/doc/internal/SampleRuleWithEnumPropertiesRule.java @@ -18,7 +18,7 @@ private enum MyEnum { OPTION_TWO } - private static final PropertyDescriptor ENUM_PROPERTY_NEW = PropertyFactory.enumPropertyNew("enumPropertyNew", MyEnum.class) + private static final PropertyDescriptor ENUM_PROPERTY_NEW = PropertyFactory.conventionalEnumProperty("enumPropertyNew", MyEnum.class) .desc("Description") .defaultValue(MyEnum.OPTION_ONE) .build(); @@ -29,7 +29,7 @@ private enum MyEnum { .defaultValue(MyEnum.OPTION_ONE) .build(); - private static final PropertyDescriptor> ENUMLIST_PROPERTY_NEW = PropertyFactory.enumListPropertyNew("enumListPropertyNew", MyEnum.class) + private static final PropertyDescriptor> ENUMLIST_PROPERTY_NEW = PropertyFactory.conventionalEnumListProperty("enumListPropertyNew", MyEnum.class) .desc("Description") .emptyDefaultValue() .build(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProperties.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProperties.java index 0b6c05df93d..9e5ddceb430 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProperties.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/internal/JavaLanguageProperties.java @@ -20,7 +20,7 @@ public class JavaLanguageProperties extends JvmLanguagePropertyBundle { * @since 7.0.0 */ static final PropertyDescriptor INTERNAL_INFERENCE_LOGGING_VERBOSITY = - PropertyFactory.enumPropertyNew("xTypeInferenceLogging", InferenceLoggingVerbosity.class) + PropertyFactory.conventionalEnumProperty("xTypeInferenceLogging", InferenceLoggingVerbosity.class) .desc("Verbosity of the type inference logging") .defaultValue(InferenceLoggingVerbosity.DISABLED) .build(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java index f1889002886..946286c0dad 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/AvoidReassigningLoopVariablesRule.java @@ -4,7 +4,7 @@ package net.sourceforge.pmd.lang.java.rule.bestpractices; -import static net.sourceforge.pmd.properties.PropertyFactory.enumPropertyNew; +import static net.sourceforge.pmd.properties.PropertyFactory.conventionalEnumProperty; import java.util.Set; import java.util.stream.Collectors; @@ -41,13 +41,13 @@ public class AvoidReassigningLoopVariablesRule extends AbstractJavaRulechainRule { private static final PropertyDescriptor FOREACH_REASSIGN - = enumPropertyNew("foreachReassign", ForeachReassignOption.class) + = conventionalEnumProperty("foreachReassign", ForeachReassignOption.class) .defaultValue(ForeachReassignOption.DENY) .desc("how/if foreach control variables may be reassigned") .build(); private static final PropertyDescriptor FOR_REASSIGN - = enumPropertyNew("forReassign", ForReassignOption.class) + = conventionalEnumProperty("forReassign", ForReassignOption.class) .defaultValue(ForReassignOption.DENY) .desc("how/if for control variables may be reassigned") .build(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CyclomaticComplexityRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CyclomaticComplexityRule.java index d7729c31331..563015b6a44 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CyclomaticComplexityRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CyclomaticComplexityRule.java @@ -42,7 +42,7 @@ public class CyclomaticComplexityRule extends AbstractJavaRulechainRule { .require(positive()).defaultValue(10).build(); private static final PropertyDescriptor> CYCLO_OPTIONS_DESCRIPTOR - = PropertyFactory.enumListPropertyNew("cycloOptions", CycloOption.class) + = PropertyFactory.conventionalEnumListProperty("cycloOptions", CycloOption.class) .desc("Choose options for the computation of Cyclo") .emptyDefaultValue() .build(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/NcssCountRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/NcssCountRule.java index 8a6bbe0530c..a926b76767c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/NcssCountRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/NcssCountRule.java @@ -47,7 +47,7 @@ public final class NcssCountRule extends AbstractJavaRulechainRule { .build(); private static final PropertyDescriptor> NCSS_OPTIONS_DESCRIPTOR = - PropertyFactory.enumListPropertyNew("ncssOptions", NcssOption.class) + PropertyFactory.conventionalEnumListProperty("ncssOptions", NcssOption.class) .desc("Choose options for the computation of Ncss") .emptyDefaultValue() .build(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java index 0b6e19fd770..ca44e4079f7 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java @@ -174,7 +174,7 @@ private static PropertyDescriptor> propertyFor(String stmtName) { } private static PropertyDescriptor> propertyForNew(String stmtName) { - return PropertyFactory.enumListPropertyNew("check" + StringUtils.capitalize(stmtName) + "LoopTypes", LoopTypes.class) + return PropertyFactory.conventionalEnumListProperty("check" + StringUtils.capitalize(stmtName) + "LoopTypes", LoopTypes.class) .desc("List of loop types in which " + stmtName + " statements will be checked") .defaultValue(DEFAULTS) .build(); diff --git a/pmd-lang-test/src/main/java/net/sourceforge/pmd/lang/test/AbstractMetricTestRule.java b/pmd-lang-test/src/main/java/net/sourceforge/pmd/lang/test/AbstractMetricTestRule.java index 0635c4ed775..a33e2f9b51a 100644 --- a/pmd-lang-test/src/main/java/net/sourceforge/pmd/lang/test/AbstractMetricTestRule.java +++ b/pmd-lang-test/src/main/java/net/sourceforge/pmd/lang/test/AbstractMetricTestRule.java @@ -57,7 +57,7 @@ public AbstractMetricTestRule(Metric metric, Class metricOptionsEnum) { this.metric = metric; if (metricOptionsEnum != null) { this.optionsDescriptor = - PropertyFactory.enumListPropertyNew("metricOptions", metricOptionsEnum) + PropertyFactory.conventionalEnumListProperty("metricOptions", metricOptionsEnum) .desc("Choose a variant of the metric or the standard") .emptyDefaultValue() .build(); From 0493a5a535570a79913f4cc63d3cbe50e92002be Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 12 Dec 2025 16:11:38 +0100 Subject: [PATCH 1849/1962] [java] ModifierOrder: Fix rule tests after merge --- .../lang/java/rule/codestyle/xml/ModifierOrder.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ModifierOrder.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ModifierOrder.xml index 3e58684086b..5446baf2d4e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ModifierOrder.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/ModifierOrder.xml @@ -105,7 +105,7 @@ abstract public class Foo { // warn l1 Missorted modifiers `@TypeA static`. Type annotations should be placed before the type they qualify. Missorted modifiers `@TypeA public`. Type annotations should be placed before the type they qualify. Missorted modifiers `@TypeA public`. Type annotations should be placed before the type they qualify. - Missorted modifiers `static @Decl`. Annotations should be placed before modifiers. + Missorted modifiers `static @Decl`. Non-type annotations should be placed before modifiers. Missorted modifiers `@TypeA static`. Type annotations should be placed before the type they qualify. @@ -117,12 +117,12 @@ abstract public class Foo { // warn l1 6 5,8,14,17,22,24 - Missorted modifiers `public @TypeA`. Annotations should be placed before modifiers. - Missorted modifiers `public @Decl`. Annotations should be placed before modifiers. - Missorted modifiers `public @TypeA`. Annotations should be placed before modifiers. - Missorted modifiers `public @Decl`. Annotations should be placed before modifiers. - Missorted modifiers `static @Decl`. Annotations should be placed before modifiers. - Missorted modifiers `public @TypeA`. Annotations should be placed before modifiers. + Missorted modifiers `public @TypeA`. Type annotations should be placed before modifiers. + Missorted modifiers `public @Decl`. Non-type annotations should be placed before modifiers. + Missorted modifiers `public @TypeA`. Type annotations should be placed before modifiers. + Missorted modifiers `public @Decl`. Non-type annotations should be placed before modifiers. + Missorted modifiers `static @Decl`. Non-type annotations should be placed before modifiers. + Missorted modifiers `public @TypeA`. Type annotations should be placed before modifiers. From 2fe8b7652951afa91b1d953d245954aca7e49893 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 12 Dec 2025 16:13:12 +0100 Subject: [PATCH 1850/1962] Update versions (7.19.0 -> 7.20.0) --- .../pmd/lang/metrics/MetricOption.java | 2 +- .../pmd/properties/PropertyFactory.java | 12 ++-- .../pmd/properties/PropertySerializer.java | 10 ++- .../internal/PropertyParsingUtil.java | 1 + .../sourceforge/pmd/util/CollectionUtil.java | 2 +- pmd-doc/src/test/resources/expected/sample.md | 2 +- .../resources/rulesets/ruledoctest/sample.xml | 2 +- .../pmd/lang/java/metrics/JavaMetrics.java | 54 ++++++---------- ...oidBranchingStatementAsLastInLoopRule.java | 62 ++++++++++--------- .../JavaIntMetricWithOptionsTestRule.java | 2 +- .../pmd/lang/test/AbstractMetricTestRule.java | 2 +- 11 files changed, 74 insertions(+), 77 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOption.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOption.java index c0e1675a001..9c9c7639e68 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOption.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOption.java @@ -29,7 +29,7 @@ public interface MetricOption { * Returns the name of the option as it should be used in properties. * * @return The name of the option. - * @deprecated Since 7.19.0. When metrics are used for (rule) properties, then the default + * @deprecated Since 7.20.0. When metrics are used for (rule) properties, then the conventional * enum mapping (from SCREAMING_SNAKE_CASE to camelCase) will be used for the enum values. * See {@link net.sourceforge.pmd.properties.PropertyFactory#conventionalEnumListProperty(String, Class)}. */ diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java index c50580053ea..ab5a1068281 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java @@ -310,7 +310,7 @@ public static GenericPropertyBuilder booleanProperty(String name) { * * @return A new builder * - * @deprecated Since 7.19.0. Use {@link #conventionalEnumProperty(String, Class)} instead. + * @deprecated Since 7.20.0. Use {@link #conventionalEnumProperty(String, Class)} instead. */ @Deprecated public static GenericPropertyBuilder enumProperty(String name, Map nameToValue) { @@ -332,7 +332,7 @@ public static GenericPropertyBuilder enumProperty(String name, Map Type of the enum class * * @return A new builder - * @deprecated Since 7.19.0. Use {@link #conventionalEnumProperty(String, Class)} instead. + * @deprecated Since 7.20.0. Use {@link #conventionalEnumProperty(String, Class)} instead. */ @Deprecated public static > GenericPropertyBuilder enumProperty(String name, Class enumClass) { @@ -354,7 +354,7 @@ public static > GenericPropertyBuilder enumProperty(String * @throws IllegalArgumentException If the label maker returns null on some constant * @throws IllegalStateException If the label maker maps two constants to the same label * - * @deprecated Since 7.19.0. Use {@link #conventionalEnumProperty(String, Class)} instead. + * @deprecated Since 7.20.0. Use {@link #conventionalEnumProperty(String, Class)} instead. */ @Deprecated public static > GenericPropertyBuilder enumProperty(String name, @@ -393,7 +393,7 @@ public static > GenericPropertyBuilder conventionalEnumProp *

            It uses additionally the given mapping to support deprecated (old) values in addition to the * default mapping.

            * - *

            This build should only be used for maintaining backwards compatibility.

            + *

            This builder should only be used for maintaining backwards compatibility.

            * * @param name Property name * @param enumClass Enum class @@ -458,7 +458,7 @@ public static > GenericCollectionPropertyBuilder> e * * @return A new builder * - * @deprecated Since 7.19.0. Use {@link #conventionalEnumListProperty(String, Class)} instead. + * @deprecated Since 7.20.0. Use {@link #conventionalEnumListProperty(String, Class)} instead. */ @Deprecated public static GenericCollectionPropertyBuilder> enumListProperty(String name, Map nameToValue) { @@ -477,7 +477,7 @@ public static GenericCollectionPropertyBuilder> enumListProperty( * * @return A new builder * - * @deprecated Since 7.19.0. Use {@link #conventionalEnumListProperty(String, Class)} instead. + * @deprecated Since 7.20.0. Use {@link #conventionalEnumListProperty(String, Class)} instead. */ @Deprecated public static > GenericCollectionPropertyBuilder> enumListProperty(String name, Class enumClass, Function labelMaker) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertySerializer.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertySerializer.java index 47284120117..038b8adfdd7 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertySerializer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertySerializer.java @@ -47,6 +47,12 @@ public PropertySerializer withConstraint(PropertyConstraint t) { */ public abstract T fromString(@NonNull String attributeData); + /** + * For properties that are based off enumerated values (see {@link #enumeratedValues()}, deprecated values + * might be provided. This method checks whether the given attribute data is actually a deprecated value + * so that we can issue a warning. + * @since 7.20.0 + */ public abstract boolean isFromStringDeprecated(@NonNull String attributeData); /** @@ -58,7 +64,7 @@ public PropertySerializer withConstraint(PropertyConstraint t) { /** * Whether this property allows multiple values. - * @since 7.19.0 + * @since 7.20.0 */ public abstract boolean isCollection(); @@ -67,7 +73,7 @@ public PropertySerializer withConstraint(PropertyConstraint t) { * all possible values. This is useful for documentation. * If this property doesn't represent an enumerated property, then the returned * set will be empty. - * @since 7.19.0 + * @since 7.20.0 */ public abstract Set enumeratedValues(); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java index 4e7ca8977d8..804b000ad1b 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java @@ -32,6 +32,7 @@ public final class PropertyParsingUtil { * Marker used for rule properties, that are deprecated. If the description of a property * starts exactly with that string, then are warning is issued when the ruleset is loaded * and the property is used and the rule documentation displays a deprecated label. + * @since 7.20.0 */ public static final String DEPRECATED_RULE_PROPERTY_MARKER = "deprecated!"; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java index f7465c6a017..b4cd92a61a7 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java @@ -234,7 +234,7 @@ public static Map mapOf(K k1, V v1, K k2, V v2) { } /** - * @since 7.19.0. + * @since 7.20.0. */ public static Map mapOf(K k1, V v1, K k2, V v2, K k3, V v3) { Map map = new LinkedHashMap<>(); diff --git a/pmd-doc/src/test/resources/expected/sample.md b/pmd-doc/src/test/resources/expected/sample.md index 12b33ab2a85..9f4f6e30361 100644 --- a/pmd-doc/src/test/resources/expected/sample.md +++ b/pmd-doc/src/test/resources/expected/sample.md @@ -590,7 +590,7 @@ Avoid jumbled loop incrementers - it's usually a mistake, and is confusing even ## SampleRuleWithEnumProperties -**Since:** PMD 7.19.0 +**Since:** PMD 7.20.0 **Priority:** Medium (3) diff --git a/pmd-doc/src/test/resources/rulesets/ruledoctest/sample.xml b/pmd-doc/src/test/resources/rulesets/ruledoctest/sample.xml index df23604ea08..efb69bf4cdf 100644 --- a/pmd-doc/src/test/resources/rulesets/ruledoctest/sample.xml +++ b/pmd-doc/src/test/resources/rulesets/ruledoctest/sample.xml @@ -230,7 +230,7 @@ RuleTag with full category and without quotes: Use {% rule java/sample/RenamedRu This rule is for testing enum properties diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java index 0453c6ed35c..95e077042ce 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java @@ -605,23 +605,17 @@ private static int maxMethodPairs(int methods) { */ public enum NcssOption implements MetricOption { /** Counts import and package statement. This makes the metric JavaNCSS compliant. */ - COUNT_IMPORTS("countImports"); - - private final String vName; - - - NcssOption(String valueName) { - this.vName = valueName; - } - + COUNT_IMPORTS; /** - * @deprecated Since 7.19.0. + * @deprecated Since 7.20.0. When metrics are used for (rule) properties, then the conventional + * enum mapping (from SCREAMING_SNAKE_CASE to camelCase) will be used for the enum values. + * See {@link net.sourceforge.pmd.properties.PropertyFactory#conventionalEnumListProperty(String, Class)}. */ - @Override @Deprecated + @Override public String valueName() { - return vName; + return MetricOption.super.valueName(); } } @@ -631,25 +625,19 @@ public String valueName() { */ public enum CycloOption implements MetricOption { /** Do not count the paths in boolean expressions as decision points. */ - IGNORE_BOOLEAN_PATHS("ignoreBooleanPaths"), + IGNORE_BOOLEAN_PATHS, /** Consider assert statements as if they were {@code if (..) throw new AssertionError(..)}. */ - CONSIDER_ASSERT("considerAssert"); - - private final String vName; - - - CycloOption(String valueName) { - this.vName = valueName; - } - + CONSIDER_ASSERT; /** - * @deprecated Since 7.19.0. + * @deprecated Since 7.20.0. When metrics are used for (rule) properties, then the conventional + * enum mapping (from SCREAMING_SNAKE_CASE to camelCase) will be used for the enum values. + * See {@link net.sourceforge.pmd.properties.PropertyFactory#conventionalEnumListProperty(String, Class)}. */ - @Override @Deprecated + @Override public String valueName() { - return vName; + return MetricOption.super.valueName(); } } @@ -687,21 +675,17 @@ private static int computeFanOut(JavaNode node, MetricOptions options) { */ public enum ClassFanOutOption implements MetricOption { /** Whether to include classes in the {@code java.lang} package. */ - INCLUDE_JAVA_LANG("includeJavaLang"); - - private final String vName; - - ClassFanOutOption(String valueName) { - this.vName = valueName; - } + INCLUDE_JAVA_LANG; /** - * @deprecated Since 7.19.0. + * @deprecated Since 7.20.0. When metrics are used for (rule) properties, then the conventional + * enum mapping (from SCREAMING_SNAKE_CASE to camelCase) will be used for the enum values. + * See {@link net.sourceforge.pmd.properties.PropertyFactory#conventionalEnumListProperty(String, Class)}. */ - @Override @Deprecated + @Override public String valueName() { - return vName; + return MetricOption.super.valueName(); } } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java index ca44e4079f7..c4d7d7eb3a7 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java @@ -29,19 +29,19 @@ public class AvoidBranchingStatementAsLastInLoopRule extends AbstractJavaRulechainRule { /** - * @since 7.19.0. Should have never been public. + * @since 7.20.0. Should have never been public. */ @Deprecated - public static final String CHECK_FOR = "for"; + /** - * @since 7.19.0. Should have never been public. + * @since 7.20.0. Should have never been public. */ @Deprecated - public static final String CHECK_DO = "do"; + /** - * @since 7.19.0. Should have never been public. + * @since 7.20.0. Should have never been public. */ @Deprecated public static final String CHECK_WHILE = "while"; @@ -57,34 +57,37 @@ private enum LoopTypes { // but I can't see a use case to e.g. report only breaks in 'for' loops but not in 'while'. /** - * @deprecated Since 7.19.0. Should have been private. + * @deprecated Since 7.20.0. Should have been private. This property descriptor is not used anymore. + * Use {@link #getPropertyDescriptor(String)} instead. */ @Deprecated - public static final PropertyDescriptor> CHECK_BREAK_LOOP_TYPES = propertyFor("break"); + public static final PropertyDescriptor> CHECK_BREAK_LOOP_TYPES = propertyForDeprecated("break"); /** - * @deprecated Since 7.19.0. Should have been private. + * @deprecated Since 7.20.0. Should have been private. This property descriptor is not used anymore. + * Use {@link #getPropertyDescriptor(String)} instead. */ @Deprecated - public static final PropertyDescriptor> CHECK_CONTINUE_LOOP_TYPES = propertyFor("continue"); + public static final PropertyDescriptor> CHECK_CONTINUE_LOOP_TYPES = propertyForDeprecated("continue"); /** - * @deprecated Since 7.19.0. Should have been private. + * @deprecated Since 7.20.0. Should have been private. This property descriptor is not used anymore. + * Use {@link #getPropertyDescriptor(String)} instead. */ @Deprecated - public static final PropertyDescriptor> CHECK_RETURN_LOOP_TYPES = propertyFor("return"); + public static final PropertyDescriptor> CHECK_RETURN_LOOP_TYPES = propertyForDeprecated("return"); - private static final PropertyDescriptor> CHECK_BREAK_LOOP_TYPES_NEW = propertyForNew("break"); - private static final PropertyDescriptor> CHECK_CONTINUE_LOOP_TYPES_NEW = propertyForNew("continue"); - private static final PropertyDescriptor> CHECK_RETURN_LOOP_TYPES_NEW = propertyForNew("return"); + private static final PropertyDescriptor> CHECK_BREAK_LOOP_TYPES_PROPERTY = propertyFor("break"); + private static final PropertyDescriptor> CHECK_CONTINUE_LOOP_TYPES_PROPERTY = propertyFor("continue"); + private static final PropertyDescriptor> CHECK_RETURN_LOOP_TYPES_PROPERTY = propertyFor("return"); public AvoidBranchingStatementAsLastInLoopRule() { super(ASTBreakStatement.class, ASTContinueStatement.class, ASTReturnStatement.class); - definePropertyDescriptor(CHECK_BREAK_LOOP_TYPES_NEW); - definePropertyDescriptor(CHECK_CONTINUE_LOOP_TYPES_NEW); - definePropertyDescriptor(CHECK_RETURN_LOOP_TYPES_NEW); + definePropertyDescriptor(CHECK_BREAK_LOOP_TYPES_PROPERTY); + definePropertyDescriptor(CHECK_CONTINUE_LOOP_TYPES_PROPERTY); + definePropertyDescriptor(CHECK_RETURN_LOOP_TYPES_PROPERTY); } @@ -94,12 +97,12 @@ public Object visit(ASTBreakStatement node, Object data) { if (node.ancestors().get(1) instanceof ASTSwitchStatement) { return data; } - return check(CHECK_BREAK_LOOP_TYPES_NEW, node, data); + return check(CHECK_BREAK_LOOP_TYPES_PROPERTY, node, data); } /** - * @deprecated Since 7.19.0. Should have been private. + * @deprecated Since 7.20.0. Should have been private. */ @Deprecated protected Object check(PropertyDescriptor> property, Node node, Object data) { @@ -134,7 +137,7 @@ private Object checkInternal(PropertyDescriptor> property, Node /** - * @deprecated Since 7.19.0. Should have been private. + * @deprecated Since 7.20.0. Should have been private. */ @Deprecated protected boolean hasPropertyValue(PropertyDescriptor> property, String value) { @@ -148,13 +151,13 @@ private boolean hasPropertyValue(PropertyDescriptor> property, L @Override public Object visit(ASTContinueStatement node, Object data) { - return check(CHECK_CONTINUE_LOOP_TYPES_NEW, node, data); + return check(CHECK_CONTINUE_LOOP_TYPES_PROPERTY, node, data); } @Override public Object visit(ASTReturnStatement node, Object data) { - return check(CHECK_RETURN_LOOP_TYPES_NEW, node, data); + return check(CHECK_RETURN_LOOP_TYPES_PROPERTY, node, data); } @@ -163,8 +166,11 @@ public String dysfunctionReason() { return checksNothing() ? "All loop types are ignored" : null; } + /** + * @deprecated Since 7.20.0 + */ @Deprecated - private static PropertyDescriptor> propertyFor(String stmtName) { + private static PropertyDescriptor> propertyForDeprecated(String stmtName) { return PropertyFactory.stringListProperty("check" + StringUtils.capitalize(stmtName) + "LoopTypes") .desc("List of loop types in which " + stmtName + " statements will be checked") .defaultValue(DEFAULTS.stream() @@ -173,7 +179,7 @@ private static PropertyDescriptor> propertyFor(String stmtName) { .build(); } - private static PropertyDescriptor> propertyForNew(String stmtName) { + private static PropertyDescriptor> propertyFor(String stmtName) { return PropertyFactory.conventionalEnumListProperty("check" + StringUtils.capitalize(stmtName) + "LoopTypes", LoopTypes.class) .desc("List of loop types in which " + stmtName + " statements will be checked") .defaultValue(DEFAULTS) @@ -181,7 +187,7 @@ private static PropertyDescriptor> propertyForNew(String stmtNam } /** - * @deprecated Since 7.19.0. Should have been private. + * @deprecated Since 7.20.0. Should have been private. */ @Deprecated public boolean checksNothing() { @@ -189,8 +195,8 @@ public boolean checksNothing() { } private boolean checksNothingInternal() { - return getProperty(CHECK_BREAK_LOOP_TYPES_NEW).isEmpty() - && getProperty(CHECK_CONTINUE_LOOP_TYPES_NEW).isEmpty() - && getProperty(CHECK_RETURN_LOOP_TYPES_NEW).isEmpty(); + return getProperty(CHECK_BREAK_LOOP_TYPES_PROPERTY).isEmpty() + && getProperty(CHECK_CONTINUE_LOOP_TYPES_PROPERTY).isEmpty() + && getProperty(CHECK_RETURN_LOOP_TYPES_PROPERTY).isEmpty(); } } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/JavaIntMetricWithOptionsTestRule.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/JavaIntMetricWithOptionsTestRule.java index 425fde8c777..378d0def8b2 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/JavaIntMetricWithOptionsTestRule.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/JavaIntMetricWithOptionsTestRule.java @@ -12,7 +12,7 @@ import net.sourceforge.pmd.lang.test.AbstractMetricTestRule; /** - * @since 7.19.0. + * @since 7.20.0. */ public abstract class JavaIntMetricWithOptionsTestRule & MetricOption> extends AbstractMetricTestRule.OfIntWithOptions { diff --git a/pmd-lang-test/src/main/java/net/sourceforge/pmd/lang/test/AbstractMetricTestRule.java b/pmd-lang-test/src/main/java/net/sourceforge/pmd/lang/test/AbstractMetricTestRule.java index a33e2f9b51a..f19b3dad7a9 100644 --- a/pmd-lang-test/src/main/java/net/sourceforge/pmd/lang/test/AbstractMetricTestRule.java +++ b/pmd-lang-test/src/main/java/net/sourceforge/pmd/lang/test/AbstractMetricTestRule.java @@ -79,7 +79,7 @@ protected boolean reportOn(Node node) { * Mappings of labels to options for use in the options property. * * @return A map of labels to options - * @deprecated Since 7.19.0. No extra mapping is required anymore. The {@link MetricOption} enum + * @deprecated Since 7.20.0. No extra mapping is required anymore. The {@link MetricOption} enum * values are used. See {@link #AbstractMetricTestRule(Metric, Class)} to provide the * enum at construction time. */ From cdf76f8b8cb2e4c0f9eee522d1a38e1bffc974b5 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 12 Dec 2025 16:54:29 +0100 Subject: [PATCH 1851/1962] Update release notes (#6184) --- docs/pages/release_notes.md | 69 +++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..b8e60edcdb4 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -24,10 +24,79 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy +#### Changed Rules +The following rules have been changed to use a consistent implementation of enum based +rule properties: +* The property `checkAddressTypes` of rule {%rule java/bestpractices/AvoidUsingHardCodedIP %} has changed: + * Instead of `IPv4` use `ipv4` + * Instead of `IPv6` use `ipv6` + * Instead of `IPv4 mapped IPv6` use `ipv4MappedIpv6` + * The old values still work, but you'll see a deprecation warning. +* The property `nullCheckBranch` of rule {%rule java/codestyle/ConfusingTernary %} has changed: + * Instead of `Any` use `any` + * Instead of `Then` use `then` + * Instead of `Else` use `else` + * The old values still work, but you'll see a deprecation warning. +* The property `typeAnnotations` of rule {%rule java/codestyle/ModifierOrder %} has changed: + * Instead of `ontype` use `onType` + * Instead of `ondecl` use `onDecl` + * The old values still work, but you'll see a deprecation warning. +* The values of the properties of rule {%rule java/documentation/CommentRequired %} have changed: + * Instead of `Required` use `required` + * Instead of `Ignored` use `ignored` + * Instead of `Unwanted` use `unwanted` + * The old values still work, but you'll see a deprecation warning. + ### ๐Ÿ›๏ธ Fixed Issues +* core + * [#6184](https://github.com/pmd/pmd/issues/6184): \[core] Consistent implementation of enum properties ### ๐Ÿšจ๏ธ API Changes +#### Deprecations +* core + * {%jdoc !!core::lang.metrics.MetricOption#valueName %}: When metrics are used for (rule) properties, + then the conventional enum mapping (from SCREAMING_SNAKE_CASE to camelCase) will be used for the enum values. + See {%jdoc core::properties.PropertyFactory#conventionalEnumListProperty(java.lang.String, java.lang.Class) %}. + * In {%jdoc core::properties.PropertyFactory %}: + * {%jdoc !a!core::properties.PropertyFactory#enumProperty(java.lang.String, java.util.Map) %}. Use + {%jdoc core::properties.PropertyFactory#conventionalEnumProperty(java.lang.String, java.lang.Class) %} instead. + * {%jdoc !a!core::properties.PropertyFactory#enumProperty(java.lang.String, java.lang.Class) %}. Use + {%jdoc core::properties.PropertyFactory#conventionalEnumProperty(java.lang.String, java.lang.Class) %} instead. + * {%jdoc !a!core::properties.PropertyFactory#enumProperty(java.lang.String, java.lang.Class, java.util.function.Function) %}. Use + {%jdoc core::properties.PropertyFactory#conventionalEnumProperty(java.lang.String, java.lang.Class) %} instead. + * {%jdoc !a!core::properties.PropertyFactory#enumListProperty(java.lang.String, java.util.Map) %}. Use + {%jdoc core::properties.PropertyFactory#conventionalEnumListProperty(java.lang.String, java.lang.Class) %} instead. + * {%jdoc !a!core::properties.PropertyFactory#enumListProperty(java.lang.String, java.lang.Class, java.util.function.Function) %}. Use + {%jdoc core::properties.PropertyFactory#conventionalEnumListProperty(java.lang.String, java.lang.Class) %} instead. +* java + * {%jdoc !c!java::lang.java.rule.errorprone.AvoidBranchingStatementAsLastInLoopRule#CHECK_FOR %}. This constant should + have never been public. + * {%jdoc !c!java::lang.java.rule.errorprone.AvoidBranchingStatementAsLastInLoopRule#CHECK_DO %}. This constant should + have never been public. + * {%jdoc !c!java::lang.java.rule.errorprone.AvoidBranchingStatementAsLastInLoopRule#CHECK_WHILE %}. This constant should + have never been public. + * {%jdoc !c!java::lang.java.rule.errorprone.AvoidBranchingStatementAsLastInLoopRule#CHECK_BREAK_LOOP_TYPES %}. This property + descriptor should have been private. It won't be used anymore. Use {%jdoc core::properties.AbstractPropertySource#getPropertyDescriptor(java.lang.String) %} + on the rule to retrieve the property descriptor. + * {%jdoc !c!java::lang.java.rule.errorprone.AvoidBranchingStatementAsLastInLoopRule#CHECK_CONTINUE_LOOP_TYPES %}. This property + descriptor should have been private. It won't be used anymore. Use {%jdoc core::properties.AbstractPropertySource#getPropertyDescriptor(java.lang.String) %} + on the rule to retrieve the property descriptor. + * {%jdoc !c!java::lang.java.rule.errorprone.AvoidBranchingStatementAsLastInLoopRule#CHECK_RETURN_LOOP_TYPES %}. This property + descriptor should have been private. It won't be used anymore. Use {%jdoc core::properties.AbstractPropertySource#getPropertyDescriptor(java.lang.String) %} + on the rule to retrieve the property descriptor. + * {%jdoc !c!java::lang.java.rule.errorprone.AvoidBranchingStatementAsLastInLoopRule#check(core::properties.PropertyDescriptor, core::lang.ast.Node, java.lang.Object) %}. + This method should have been private and will be internalized. + * {%jdoc !c!java::lang.java.rule.errorprone.AvoidBranchingStatementAsLastInLoopRule#hasPropertyValue(core::properties.PropertyDescriptor, java.lang.String) %}. + This method should have been private and will be internalized. + * {%jdoc !c!java::lang.java.rule.errorprone.AvoidBranchingStatementAsLastInLoopRule#checksNothing() %}. + This method should have been private and will be internalized. +* lang-test + * {%jdoc !c!lang-test::lang.test.AbstractMetricTestRule#optionMappings() %}. No extra mapping is required anymore. + The {%jdoc core::lang.metrics.MetricOption %} enum values are used. See + {%jdoc !a!lang-test::lang.test.AbstractMetricTestRule#AbstractMetricTestRule(core::lang.metrics.Metric, java.lang.Class) %} + to provide the enum at construction time. + ### โœจ๏ธ Merged pull requests From c43d3838805d54cb6fa0368d433f91b9f0dff9c9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 7 Jan 2026 09:03:09 +0100 Subject: [PATCH 1852/1962] Update versions (7.20.0 -> 7.21.0) --- .../pmd/lang/metrics/MetricOption.java | 2 +- .../pmd/properties/PropertyFactory.java | 10 +++++----- .../pmd/properties/PropertySerializer.java | 6 +++--- .../internal/PropertyParsingUtil.java | 2 +- .../sourceforge/pmd/util/CollectionUtil.java | 2 +- pmd-doc/src/test/resources/expected/sample.md | 2 +- .../resources/rulesets/ruledoctest/sample.xml | 2 +- .../pmd/lang/java/metrics/JavaMetrics.java | 6 +++--- ...oidBranchingStatementAsLastInLoopRule.java | 20 +++++++++---------- .../JavaIntMetricWithOptionsTestRule.java | 2 +- .../pmd/lang/test/AbstractMetricTestRule.java | 2 +- 11 files changed, 28 insertions(+), 28 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOption.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOption.java index 9c9c7639e68..58999f68c23 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOption.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/MetricOption.java @@ -29,7 +29,7 @@ public interface MetricOption { * Returns the name of the option as it should be used in properties. * * @return The name of the option. - * @deprecated Since 7.20.0. When metrics are used for (rule) properties, then the conventional + * @deprecated Since 7.21.0. When metrics are used for (rule) properties, then the conventional * enum mapping (from SCREAMING_SNAKE_CASE to camelCase) will be used for the enum values. * See {@link net.sourceforge.pmd.properties.PropertyFactory#conventionalEnumListProperty(String, Class)}. */ diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java index ab5a1068281..e2d30715dc5 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java @@ -310,7 +310,7 @@ public static GenericPropertyBuilder booleanProperty(String name) { * * @return A new builder * - * @deprecated Since 7.20.0. Use {@link #conventionalEnumProperty(String, Class)} instead. + * @deprecated Since 7.21.0. Use {@link #conventionalEnumProperty(String, Class)} instead. */ @Deprecated public static GenericPropertyBuilder enumProperty(String name, Map nameToValue) { @@ -332,7 +332,7 @@ public static GenericPropertyBuilder enumProperty(String name, Map Type of the enum class * * @return A new builder - * @deprecated Since 7.20.0. Use {@link #conventionalEnumProperty(String, Class)} instead. + * @deprecated Since 7.21.0. Use {@link #conventionalEnumProperty(String, Class)} instead. */ @Deprecated public static > GenericPropertyBuilder enumProperty(String name, Class enumClass) { @@ -354,7 +354,7 @@ public static > GenericPropertyBuilder enumProperty(String * @throws IllegalArgumentException If the label maker returns null on some constant * @throws IllegalStateException If the label maker maps two constants to the same label * - * @deprecated Since 7.20.0. Use {@link #conventionalEnumProperty(String, Class)} instead. + * @deprecated Since 7.21.0. Use {@link #conventionalEnumProperty(String, Class)} instead. */ @Deprecated public static > GenericPropertyBuilder enumProperty(String name, @@ -458,7 +458,7 @@ public static > GenericCollectionPropertyBuilder> e * * @return A new builder * - * @deprecated Since 7.20.0. Use {@link #conventionalEnumListProperty(String, Class)} instead. + * @deprecated Since 7.21.0. Use {@link #conventionalEnumListProperty(String, Class)} instead. */ @Deprecated public static GenericCollectionPropertyBuilder> enumListProperty(String name, Map nameToValue) { @@ -477,7 +477,7 @@ public static GenericCollectionPropertyBuilder> enumListProperty( * * @return A new builder * - * @deprecated Since 7.20.0. Use {@link #conventionalEnumListProperty(String, Class)} instead. + * @deprecated Since 7.21.0. Use {@link #conventionalEnumListProperty(String, Class)} instead. */ @Deprecated public static > GenericCollectionPropertyBuilder> enumListProperty(String name, Class enumClass, Function labelMaker) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertySerializer.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertySerializer.java index 038b8adfdd7..7a714f32723 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertySerializer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertySerializer.java @@ -51,7 +51,7 @@ public PropertySerializer withConstraint(PropertyConstraint t) { * For properties that are based off enumerated values (see {@link #enumeratedValues()}, deprecated values * might be provided. This method checks whether the given attribute data is actually a deprecated value * so that we can issue a warning. - * @since 7.20.0 + * @since 7.21.0 */ public abstract boolean isFromStringDeprecated(@NonNull String attributeData); @@ -64,7 +64,7 @@ public PropertySerializer withConstraint(PropertyConstraint t) { /** * Whether this property allows multiple values. - * @since 7.20.0 + * @since 7.21.0 */ public abstract boolean isCollection(); @@ -73,7 +73,7 @@ public PropertySerializer withConstraint(PropertyConstraint t) { * all possible values. This is useful for documentation. * If this property doesn't represent an enumerated property, then the returned * set will be empty. - * @since 7.20.0 + * @since 7.21.0 */ public abstract Set enumeratedValues(); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java index 804b000ad1b..df178a910b3 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyParsingUtil.java @@ -32,7 +32,7 @@ public final class PropertyParsingUtil { * Marker used for rule properties, that are deprecated. If the description of a property * starts exactly with that string, then are warning is issued when the ruleset is loaded * and the property is used and the rule documentation displays a deprecated label. - * @since 7.20.0 + * @since 7.21.0 */ public static final String DEPRECATED_RULE_PROPERTY_MARKER = "deprecated!"; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java index b4cd92a61a7..1ec96ef31be 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/CollectionUtil.java @@ -234,7 +234,7 @@ public static Map mapOf(K k1, V v1, K k2, V v2) { } /** - * @since 7.20.0. + * @since 7.21.0. */ public static Map mapOf(K k1, V v1, K k2, V v2, K k3, V v3) { Map map = new LinkedHashMap<>(); diff --git a/pmd-doc/src/test/resources/expected/sample.md b/pmd-doc/src/test/resources/expected/sample.md index 9f4f6e30361..78b4f55657d 100644 --- a/pmd-doc/src/test/resources/expected/sample.md +++ b/pmd-doc/src/test/resources/expected/sample.md @@ -590,7 +590,7 @@ Avoid jumbled loop incrementers - it's usually a mistake, and is confusing even ## SampleRuleWithEnumProperties -**Since:** PMD 7.20.0 +**Since:** PMD 7.21.0 **Priority:** Medium (3) diff --git a/pmd-doc/src/test/resources/rulesets/ruledoctest/sample.xml b/pmd-doc/src/test/resources/rulesets/ruledoctest/sample.xml index efb69bf4cdf..e877a9f089d 100644 --- a/pmd-doc/src/test/resources/rulesets/ruledoctest/sample.xml +++ b/pmd-doc/src/test/resources/rulesets/ruledoctest/sample.xml @@ -230,7 +230,7 @@ RuleTag with full category and without quotes: Use {% rule java/sample/RenamedRu This rule is for testing enum properties diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java index 95e077042ce..801cb0502f7 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java @@ -608,7 +608,7 @@ public enum NcssOption implements MetricOption { COUNT_IMPORTS; /** - * @deprecated Since 7.20.0. When metrics are used for (rule) properties, then the conventional + * @deprecated Since 7.21.0. When metrics are used for (rule) properties, then the conventional * enum mapping (from SCREAMING_SNAKE_CASE to camelCase) will be used for the enum values. * See {@link net.sourceforge.pmd.properties.PropertyFactory#conventionalEnumListProperty(String, Class)}. */ @@ -630,7 +630,7 @@ public enum CycloOption implements MetricOption { CONSIDER_ASSERT; /** - * @deprecated Since 7.20.0. When metrics are used for (rule) properties, then the conventional + * @deprecated Since 7.21.0. When metrics are used for (rule) properties, then the conventional * enum mapping (from SCREAMING_SNAKE_CASE to camelCase) will be used for the enum values. * See {@link net.sourceforge.pmd.properties.PropertyFactory#conventionalEnumListProperty(String, Class)}. */ @@ -678,7 +678,7 @@ public enum ClassFanOutOption implements MetricOption { INCLUDE_JAVA_LANG; /** - * @deprecated Since 7.20.0. When metrics are used for (rule) properties, then the conventional + * @deprecated Since 7.21.0. When metrics are used for (rule) properties, then the conventional * enum mapping (from SCREAMING_SNAKE_CASE to camelCase) will be used for the enum values. * See {@link net.sourceforge.pmd.properties.PropertyFactory#conventionalEnumListProperty(String, Class)}. */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java index c4d7d7eb3a7..cd4cb97e010 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java @@ -29,19 +29,19 @@ public class AvoidBranchingStatementAsLastInLoopRule extends AbstractJavaRulechainRule { /** - * @since 7.20.0. Should have never been public. + * @since 7.21.0. Should have never been public. */ @Deprecated public static final String CHECK_FOR = "for"; /** - * @since 7.20.0. Should have never been public. + * @since 7.21.0. Should have never been public. */ @Deprecated public static final String CHECK_DO = "do"; /** - * @since 7.20.0. Should have never been public. + * @since 7.21.0. Should have never been public. */ @Deprecated public static final String CHECK_WHILE = "while"; @@ -57,21 +57,21 @@ private enum LoopTypes { // but I can't see a use case to e.g. report only breaks in 'for' loops but not in 'while'. /** - * @deprecated Since 7.20.0. Should have been private. This property descriptor is not used anymore. + * @deprecated Since 7.21.0. Should have been private. This property descriptor is not used anymore. * Use {@link #getPropertyDescriptor(String)} instead. */ @Deprecated public static final PropertyDescriptor> CHECK_BREAK_LOOP_TYPES = propertyForDeprecated("break"); /** - * @deprecated Since 7.20.0. Should have been private. This property descriptor is not used anymore. + * @deprecated Since 7.21.0. Should have been private. This property descriptor is not used anymore. * Use {@link #getPropertyDescriptor(String)} instead. */ @Deprecated public static final PropertyDescriptor> CHECK_CONTINUE_LOOP_TYPES = propertyForDeprecated("continue"); /** - * @deprecated Since 7.20.0. Should have been private. This property descriptor is not used anymore. + * @deprecated Since 7.21.0. Should have been private. This property descriptor is not used anymore. * Use {@link #getPropertyDescriptor(String)} instead. */ @Deprecated @@ -102,7 +102,7 @@ public Object visit(ASTBreakStatement node, Object data) { /** - * @deprecated Since 7.20.0. Should have been private. + * @deprecated Since 7.21.0. Should have been private. */ @Deprecated protected Object check(PropertyDescriptor> property, Node node, Object data) { @@ -137,7 +137,7 @@ private Object checkInternal(PropertyDescriptor> property, Node /** - * @deprecated Since 7.20.0. Should have been private. + * @deprecated Since 7.21.0. Should have been private. */ @Deprecated protected boolean hasPropertyValue(PropertyDescriptor> property, String value) { @@ -167,7 +167,7 @@ public String dysfunctionReason() { } /** - * @deprecated Since 7.20.0 + * @deprecated Since 7.21.0 */ @Deprecated private static PropertyDescriptor> propertyForDeprecated(String stmtName) { @@ -187,7 +187,7 @@ private static PropertyDescriptor> propertyFor(String stmtName) } /** - * @deprecated Since 7.20.0. Should have been private. + * @deprecated Since 7.21.0. Should have been private. */ @Deprecated public boolean checksNothing() { diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/JavaIntMetricWithOptionsTestRule.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/JavaIntMetricWithOptionsTestRule.java index 378d0def8b2..3e6118b1757 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/JavaIntMetricWithOptionsTestRule.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/JavaIntMetricWithOptionsTestRule.java @@ -12,7 +12,7 @@ import net.sourceforge.pmd.lang.test.AbstractMetricTestRule; /** - * @since 7.20.0. + * @since 7.21.0. */ public abstract class JavaIntMetricWithOptionsTestRule & MetricOption> extends AbstractMetricTestRule.OfIntWithOptions { diff --git a/pmd-lang-test/src/main/java/net/sourceforge/pmd/lang/test/AbstractMetricTestRule.java b/pmd-lang-test/src/main/java/net/sourceforge/pmd/lang/test/AbstractMetricTestRule.java index f19b3dad7a9..bf7fdf388bb 100644 --- a/pmd-lang-test/src/main/java/net/sourceforge/pmd/lang/test/AbstractMetricTestRule.java +++ b/pmd-lang-test/src/main/java/net/sourceforge/pmd/lang/test/AbstractMetricTestRule.java @@ -79,7 +79,7 @@ protected boolean reportOn(Node node) { * Mappings of labels to options for use in the options property. * * @return A map of labels to options - * @deprecated Since 7.20.0. No extra mapping is required anymore. The {@link MetricOption} enum + * @deprecated Since 7.21.0. No extra mapping is required anymore. The {@link MetricOption} enum * values are used. See {@link #AbstractMetricTestRule(Metric, Class)} to provide the * enum at construction time. */ From 465827c0f64bac62ffaec29f15bd19e23b0a0fd2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 10:04:13 +0100 Subject: [PATCH 1853/1962] chore(deps): bump uri from 1.0.3 to 1.0.4 in /docs (#6385) Bumps [uri](https://github.com/ruby/uri) from 1.0.3 to 1.0.4. - [Release notes](https://github.com/ruby/uri/releases) - [Commits](https://github.com/ruby/uri/compare/v1.0.3...v1.0.4) --- updated-dependencies: - dependency-name: uri dependency-version: 1.0.4 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index 68375cd7261..170786af6db 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -268,7 +268,7 @@ GEM tzinfo (2.0.6) concurrent-ruby (~> 1.0) unicode-display_width (1.8.0) - uri (1.0.3) + uri (1.0.4) webrick (1.9.2) PLATFORMS From de5008a1d58601e7deabfb0d574d86ea1d1793f7 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 7 Jan 2026 13:43:04 +0100 Subject: [PATCH 1854/1962] [ci] publish-pull-requests: download latest build result --- .ci/files/pmdtester.rb | 2 +- .github/workflows/publish-pull-requests.yml | 26 +++++++++++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/.ci/files/pmdtester.rb b/.ci/files/pmdtester.rb index 41ccbbb2a13..efcda90ea94 100644 --- a/.ci/files/pmdtester.rb +++ b/.ci/files/pmdtester.rb @@ -38,7 +38,7 @@ def run_pmdtester end rescue StandardError => e - message = "โš  Running pmdtester failed, this message is mainly used to remind the maintainers of PMD." + message = "โš ๏ธ Running pmdtester failed, this message is mainly used to remind the maintainers of PMD." conclusion = "failure" @logger.error "Running pmdtester failed: #{e.inspect}" end diff --git a/.github/workflows/publish-pull-requests.yml b/.github/workflows/publish-pull-requests.yml index 67c1581503b..00d7a01ffd0 100644 --- a/.github/workflows/publish-pull-requests.yml +++ b/.github/workflows/publish-pull-requests.yml @@ -70,7 +70,18 @@ jobs: run: | mkdir docs-artifact cd docs-artifact - gh run download "${RUN_ID}" --repo pmd/pmd --name docs-artifact + # gh run download "${RUN_ID}" --repo pmd/pmd --name docs-artifact + # apply workaround for https://github.com/cli/cli/issues/12437 + download_url=$(gh api \ + "/repos/pmd/pmd/actions/runs/$RUN_ID/artifacts?name=docs-artifact" \ + --jq '.artifacts|sort_by(.created_at)|.[-1]|.archive_download_url' \ + ) + curl -L \ + -H "Authorization: Bearer $GH_TOKEN" \ + --output artifact.zip \ + $download_url + unzip -q artifact.zip + rm artifact.zip - name: Upload docs-artifact to s3://pmd-pull-requests env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_S3_PMD_PULL_REQUESTS_ACCESS_KEY_ID }} @@ -114,7 +125,18 @@ jobs: run: | mkdir pmd-regression-tester cd pmd-regression-tester - gh run download "${RUN_ID}" --repo pmd/pmd --name pmd-regression-tester + # gh run download "${RUN_ID}" --repo pmd/pmd --name pmd-regression-tester + # apply workaround for https://github.com/cli/cli/issues/12437 + download_url=$(gh api \ + "/repos/pmd/pmd/actions/runs/$RUN_ID/artifacts?name=pmd-regression-tester" \ + --jq '.artifacts|sort_by(.created_at)|.[-1]|.archive_download_url' \ + ) + curl -L \ + -H "Authorization: Bearer $GH_TOKEN" \ + --output artifact.zip \ + $download_url + unzip -q artifact.zip + rm artifact.zip - name: Upload regression report to s3://pmd-pull-requests env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_S3_PMD_PULL_REQUESTS_ACCESS_KEY_ID }} From 3b995c39b64051769b301ca190b1f7e610aa673e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 13:49:04 +0100 Subject: [PATCH 1855/1962] chore(deps): bump scalameta.version from 4.14.2 to 4.14.4 (#6379) * chore(deps): bump scalameta.version from 4.14.2 to 4.14.4 Bumps `scalameta.version` from 4.14.2 to 4.14.4. Updates `org.scalameta:parsers_2.13` from 4.14.2 to 4.14.4 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.14.2...v4.14.4) Updates `org.scalameta:trees_2.13` from 4.14.2 to 4.14.4 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.14.2...v4.14.4) Updates `org.scalameta:parsers_2.12` from 4.14.2 to 4.14.4 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.14.2...v4.14.4) Updates `org.scalameta:trees_2.12` from 4.14.2 to 4.14.4 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.14.2...v4.14.4) --- updated-dependencies: - dependency-name: org.scalameta:parsers_2.13 dependency-version: 4.14.4 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:trees_2.13 dependency-version: 4.14.4 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:parsers_2.12 dependency-version: 4.14.4 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:trees_2.12 dependency-version: 4.14.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * [scala] Avoid using internal API --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andreas Dangel --- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- .../java/net/sourceforge/pmd/lang/scala/ast/ScalaParser.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index 340f7a84cea..a3ca74a2a3a 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -13,7 +13,7 @@ - 4.14.2 + 4.14.4 diff --git a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ScalaParser.java b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ScalaParser.java index d309b34dae9..b696dd29b20 100644 --- a/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ScalaParser.java +++ b/pmd-scala-modules/pmd-scala-common/src/main/java/net/sourceforge/pmd/lang/scala/ast/ScalaParser.java @@ -11,7 +11,7 @@ import scala.meta.Dialect; import scala.meta.Source; import scala.meta.inputs.Input; -import scala.meta.internal.parsers.ScalametaParser; +import scala.meta.parsers.Parse; /** * Scala's Parser implementation. Defers parsing to the scala compiler via @@ -24,7 +24,7 @@ public final class ScalaParser implements Parser { public ASTSource parse(ParserTask task) throws ParseException { Input.VirtualFile virtualFile = new Input.VirtualFile(task.getFileId().getAbsolutePath(), task.getSourceText()); Dialect dialect = ScalaDialect.dialectOf(task.getLanguageVersion()); - Source src = new ScalametaParser(virtualFile, dialect).parseSource(); + Source src = Parse.parseSource().apply(virtualFile, dialect).get(); ASTSource root = (ASTSource) new ScalaTreeBuilder().build(src); root.addTaskInfo(task); return root; From 42174491e5e8786612eccf538212838d82b1bc56 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 28 Nov 2025 18:34:15 +0100 Subject: [PATCH 1856/1962] [cli] Improve start script for designer --- pmd-dist/src/main/resources/scripts/pmd | 82 ++++++--- .../java-with-fx/jre/lib/javafx.properties | 4 + .../src/test/resources/scripts/runtest.sh | 159 +++++++++++------- 3 files changed, 154 insertions(+), 91 deletions(-) create mode 100644 pmd-dist/src/test/resources/scripts/java-with-fx/jre/lib/javafx.properties diff --git a/pmd-dist/src/main/resources/scripts/pmd b/pmd-dist/src/main/resources/scripts/pmd index fe1e7e6fa74..923b96dd4e6 100755 --- a/pmd-dist/src/main/resources/scripts/pmd +++ b/pmd-dist/src/main/resources/scripts/pmd @@ -108,20 +108,31 @@ check_java() { } determine_java_version() { - full_ver=$(java -version 2>&1) - # java_ver is eg "80" for java 1.8, "90" for java 9.0, "100" for java 10.0.x - java_ver=$(echo "$full_ver" | sed -n '{ - # replace early access versions, e.g. 11-ea with 11.0.0 - s/-ea/.0.0/ - # replace versions such as 10 with 10.0.0 - s/version "\([0-9]\{1,\}\)"/version "\1.0.0"/ - # replace old java versions 1.x.* (java 1.7, java 1.8) with x.* - s/version "1\.\(.*\)"/version "\1"/ - # extract the major and minor parts of the version - s/^.* version "\([0-9]\{1,\}\)\.\([0-9]\{1,\}\).*".*$/\1\2/p + all_props=$(java -XshowSettings:properties 2>&1) + java_ver_normalized=$(echo "$all_props" | grep "java.version" | sed -n -e '{ + s/^.*java\.version *= *// + # replace java versions java 1.7 and java 1.8 with 7 and 8 + s/^1\.\([78]\)/\1/ + # print what is left + p }') - # java_vendor is either java (oracle) or openjdk - java_vendor=$(echo "$full_ver" | sed -n -e 's/^\(.*\) version .*$/\1/p') + # 1. component: java_version_feature is e.g. "8" for java 1.8, "9" for java 9, "10" for java 10, ... + java_version_feature=$(echo "$java_ver_normalized" | sed -n -e 's/^\([0-9]\{1,\}\).*$/\1/p') + # 3. component: update release counter + java_version_update=$(echo "$java_ver_normalized" | sed -n -e 's/^\([0-9]\{1,\}\)\.\([0-9]\{1,\}\).\([0-9]\{1,\}\).*$/\3/p') + # if there was no 3rd component, use "0" + java_version_update=${java_version_update:="0"} + + java_home_property=$(echo "$all_props" | grep "java.home" | sed -n -e 's/^.*java\.home *= *\(.*\)$/\1/; p') + java_has_javafx=0 + java_javafx_properties= + if [ -e "$java_home_property/lib/javafx.properties" ]; then + java_javafx_properties="$java_home_property/lib/javafx.properties" + java_has_javafx=1 + elif [ -e "$java_home_property/jre/lib/javafx.properties" ]; then + java_javafx_properties="$java_home_property/jre/lib/javafx.properties" + java_has_javafx=1 + fi } jre_specific_vm_options() { @@ -129,13 +140,12 @@ jre_specific_vm_options() { then options="" - if [ "$java_ver" -ge 80 ] && [ "$java_ver" -lt 90 ] - then - # no options needed for java8. - options="" - elif [ "$java_ver" -ge 90 ] && [ "$java_ver" -lt 110 ] && [ "$java_vendor" = "java" ] + if [ "$java_version_feature" -ge 9 ] && [ $java_has_javafx = 1 ] then # java9 and java10 from oracle contain javafx as a module + # Azul provides builds which include javafx as well + # Since Java 9, it is included as a module. But we run on the classpath (aka unnamed module) and + # want to access the classes. # open internal module of javafx to reflection (for our TreeViewWrapper) options="--add-opens javafx.controls/javafx.scene.control.skin=ALL-UNNAMED" # The rest here is for RichtextFX @@ -143,13 +153,12 @@ jre_specific_vm_options() { options="$options --add-opens javafx.graphics/com.sun.javafx.scene.text=ALL-UNNAMED" options="$options --add-opens javafx.graphics/com.sun.javafx.text=ALL-UNNAMED" options="$options --add-opens javafx.graphics/com.sun.javafx.geom=ALL-UNNAMED" + # for ?? + options="$options --add-opens javafx.fxml/com.sun.javafx.fxml.builder=ALL-UNNAMED" + # for controlsfx + options="$options --add-opens javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED" # Warn of remaining illegal accesses options="$options --illegal-access=warn" - elif [ "$java_vendor" = "openjdk" ] || { [ "$java_vendor" = "java" ] && [ "$java_ver" -ge 110 ] ; } - then - # openjdk and java11 from oracle onwards do not contain javafx directly - # there are no extra options either - javafx will be added to the classpath without modules - options="" fi echo "$options" @@ -168,13 +177,32 @@ add_pmd_classpath() { add_openjfx_classpath() { if [ "$APPNAME" = "designer" ] + echo "add_openfx_classpath: java_version_feature='$java_version_feature' java_version_update='$java_version_update' java_has_javafx=$java_has_javafx" then - if [ "$java_vendor" = "openjdk" ] && [ "$java_ver" -lt 100 ] + if [ $java_has_javafx = 1 ] then - script_exit "For openjfx at least java 10 is required" - elif [ "$java_vendor" = "openjdk" ] || { [ "$java_vendor" = "java" ] && [ "$java_ver" -ge 110 ] ; } + # almost nothing to do, javafx is bundled (either an old Oracle Java < 8u451 or an OpenJDK 8 Build from Azul) + # still hadd the path where javafx.properties is located to the classpath, so that Designer's + # net.sourceforge.pmd.util.fxdesigner.util.JavaFxUtil#getJavaFxVersion can find it. + if [ -n "$classpath" ]; then + classpath="$classpath:$(dirname "$java_javafx_properties")" + else + classpath="$(dirname "$java_javafx_properties")" + fi + elif [ "$java_version_feature" = "8" ] && [ "$java_version_update" -ge 451 ] + then + script_exit " + JavaFX has been removed from Oracle Java 8 since Java 8u451. See https://www.oracle.com/javase/javafx. + Use Java 11 or later with OpenJFX separately from https://openjfx.io/. + Alternatively use an OpenJDK build from Azul with JavaFX bundled (JDK FX). + " + elif [ "$java_version_feature" -lt 10 ] then - # openjfx is required for openjdk builds and oracle java 11 or later + script_exit " + For OpenJFX at least Java 10 is required. + " + else + # openjfx is required for any openjdk builds which don't include JavaFX if [ -z "$JAVAFX_HOME" ] then script_exit "The environment variable JAVAFX_HOME is missing." diff --git a/pmd-dist/src/test/resources/scripts/java-with-fx/jre/lib/javafx.properties b/pmd-dist/src/test/resources/scripts/java-with-fx/jre/lib/javafx.properties new file mode 100644 index 00000000000..d45361907d7 --- /dev/null +++ b/pmd-dist/src/test/resources/scripts/java-with-fx/jre/lib/javafx.properties @@ -0,0 +1,4 @@ +# sample file to that the start script determine +# whether javafx is bundled with the jdk/jre or not +# + diff --git a/pmd-dist/src/test/resources/scripts/runtest.sh b/pmd-dist/src/test/resources/scripts/runtest.sh index 34185ddb1c9..23cbcf636aa 100755 --- a/pmd-dist/src/test/resources/scripts/runtest.sh +++ b/pmd-dist/src/test/resources/scripts/runtest.sh @@ -1,88 +1,119 @@ -#!/bin/bash +#!/bin/sh # BSD-style license; for more info see http://pmd.sourceforge.net/license.html # # Simple manual test script # - code is copied from run.sh to be tested here (so please check, it might be out of sync) -# - mostly the function "determine_java_version" is tested here +# - only the function "determine_java_version" is tested here # - just run it with "./runtest.sh" and look at the output # - test cases are at the end of this script # export LANG=en_US.UTF-8 -FULL_JAVA_VERSION="" - -get_full_java_version() { - #java -version 2>&1 - #echo "openjdk version \"11.0.6\" 2022-08-12" - echo "$FULL_JAVA_VERSION" +mock_show_settings_properties() { + # instead of: java -XshowSettings:properties 2>&1 + echo "Property settings: + some.other.property1 = value + java.version = $MOCKED_JAVA_VERSION + some.other.property2 = value + java.home = $MOCKED_JAVA_HOME + some.other.property3 = value +" } +# See also +# https://openjdk.org/jeps/223 JEP 223: New Version-String Scheme (Since Java 9) +# https://openjdk.org/jeps/322 JEP 322: Time-Based Release Versioning (Since Java 10) determine_java_version() { - local full_ver=$(get_full_java_version) - # java_ver is eg "80" for java 1.8, "90" for java 9.0, "100" for java 10.0.x - java_ver=$(echo "$full_ver" | sed -n '{ - # replace early access versions, e.g. 11-ea with 11.0.0 - s/-ea/.0.0/ - # replace versions such as 10 with 10.0.0 - s/version "\([0-9]\{1,\}\)"/version "\1.0.0"/ - # replace old java versions 1.x.* (java 1.7, java 1.8) with x.* - s/version "1\.\(.*\)"/version "\1"/ - # extract the major and minor parts of the version - s/^.* version "\([0-9]\{1,\}\)\.\([0-9]\{1,\}\).*".*$/\1\2/p + #local all_props=$(java -XshowSettings:properties 2>&1) + all_props="$(mock_show_settings_properties)" + java_ver_normalized=$(echo "$all_props" | grep "java.version" | sed -n -e '{ + s/^.*java\.version *= *// + # replace java versions java 1.7 and java 1.8 with 7 and 8 + s/^1\.\([78]\)/\1/ + # print what is left + p }') - # java_vendor is either java (oracle) or openjdk - java_vendor=$(echo "$full_ver" | sed -n -e 's/^\(.*\) version .*$/\1/p') -} + # 1. component: java_version_feature is e.g. "8" for java 1.8, "9" for java 9, "10" for java 10, ... + java_version_feature=$(echo "$java_ver_normalized" | sed -n -e 's/^\([0-9]\{1,\}\).*$/\1/p') + # 3. component: update release counter + java_version_update=$(echo "$java_ver_normalized" | sed -n -e 's/^\([0-9]\{1,\}\)\.\([0-9]\{1,\}\).\([0-9]\{1,\}\).*$/\3/p') + # if there was no 3rd component, use "0" + java_version_update=${java_version_update:="0"} -jre_specific_vm_options() { - options="" - if [ "$java_ver" -ge 70 ] && [ "$java_ver" -lt 80 ] - then - options="detected java 7" - elif [ "$java_ver" -ge 80 ] && [ "$java_ver" -lt 90 ] - then - options="detected java 8" - elif [ "$java_ver" -ge 90 ] && [ "$java_ver" -lt 110 ] && [ "$java_vendor" = "java" ] - then - options="detected java 9 or 10 from oracle" - elif [ "$java_vendor" = "openjdk" ] || ( [ "$java_vendor" = "java" ] && [ "$java_ver" -ge 110 ] ) - then - options="detected java 11 from oracle or any openjdk" + java_home_property=$(echo "$all_props" | grep "java.home" | sed -n -e 's/^.*java\.home *= *\(.*\)$/\1/; p') + java_has_javafx=0 + java_javafx_properties= + if [ -e "$java_home_property/lib/javafx.properties" ]; then + java_javafx_properties="$java_home_property/lib/javafx.properties" + java_has_javafx=1 + elif [ -e "$java_home_property/jre/lib/javafx.properties" ]; then + java_javafx_properties="$java_home_property/jre/lib/javafx.properties" + java_has_javafx=1 fi - echo $options +} + +pass() { + printf "\e[32mOK\e[0m%s\n" "$1" +} + +fail() { + printf "\e[31mFAILED\e[0m\n" + exit 1 } run_test() { - FULL_JAVA_VERSION="$1" - EXPECTED_VENDOR="$2" - EXPECTED_VER="$3" - EXPECTED="$4" - echo "Testing: '${FULL_JAVA_VERSION}'" + MOCKED_JAVA_VERSION="$1" + MOCKED_JAVA_HOME="$2" + EXPECTED_FEATURE="$3" + EXPECTED_UPDATE="$4" + EXPECTED_HAS_JAVAFX="$5" + echo "Testing: '${MOCKED_JAVA_VERSION}' in '${MOCKED_JAVA_HOME}" + # use mocked path relative to the test script + MOCKED_JAVA_HOME="$(dirname "$0")/$MOCKED_JAVA_HOME" determine_java_version - java_opts="$(jre_specific_vm_options)" - echo -n "java_ver: $java_ver " - if [ "$EXPECTED_VER" = "$java_ver" ]; then echo -e "\e[32mOK\e[0m"; else echo -e "\e[31mFAILED\e[0m"; fi - echo -n "java_vendor: $java_vendor " - if [ "$EXPECTED_VENDOR" = "$java_vendor" ]; then echo -e "\e[32mOK\e[0m"; else echo -e "\e[31mFAILED\e[0m"; fi - echo -n "java_opts: $java_opts " - if [ "$EXPECTED" = "$java_opts" ]; then echo -e "\e[32mOK\e[0m"; else echo -e "\e[31mFAILED\e[0m - expected: ${EXPECTED}"; fi + printf "java_version_feature: %s " "$java_version_feature" + if [ "$EXPECTED_FEATURE" = "$java_version_feature" ]; then pass; else fail; fi + printf "java_version_update: %s " "$java_version_update" + if [ "$EXPECTED_UPDATE" = "$java_version_update" ]; then pass; else fail; fi + printf "java_has_javafx: %s " "$java_has_javafx" + if [ "$EXPECTED_HAS_JAVAFX" = "yes" ] && [ "$java_has_javafx" = 1 ] && [ -n "$java_javafx_properties" ]; then pass; + elif [ "$EXPECTED_HAS_JAVAFX" = "no" ] && [ "$java_has_javafx" = 0 ] && [ -z "$java_javafx_properties" ]; then pass; + else fail; fi echo } -run_test "java version \"1.7.0_80\"" "java" "70" "detected java 7" -run_test "openjdk version \"1.7.0_352\"" "openjdk" "70" "detected java 7" -run_test "java version \"1.8.0_271\"" "java" "80" "detected java 8" -run_test "openjdk version \"1.8.0_345\"" "openjdk" "80" "detected java 8" -run_test "java version \"9.0.4\"" "java" "90" "detected java 9 or 10 from oracle" -run_test "openjdk version \"9.0.4\"" "openjdk" "90" "detected java 11 from oracle or any openjdk" -run_test "java version \"10.0.2\" 2018-07-17" "java" "100" "detected java 9 or 10 from oracle" -run_test "openjdk version \"11.0.6\" 2022-08-12" "openjdk" "110" "detected java 11 from oracle or any openjdk" -run_test "openjdk version \"11.0.6.1\" 2022-08-12" "openjdk" "110" "detected java 11 from oracle or any openjdk" -run_test "java version \"11.0.13\" 2021-10-19 LTS" "java" "110" "detected java 11 from oracle or any openjdk" -run_test "openjdk version \"17.0.4\" 2022-08-12" "openjdk" "170" "detected java 11 from oracle or any openjdk" -run_test "openjdk version \"17.1.4\" 2022-08-12" "openjdk" "171" "detected java 11 from oracle or any openjdk" -run_test "openjdk version \"17.0.4.1\" 2022-08-12" "openjdk" "170" "detected java 11 from oracle or any openjdk" -run_test "openjdk version \"18.0.2.1\" 2022-08-18" "openjdk" "180" "detected java 11 from oracle or any openjdk" -run_test "openjdk version \"19-ea\" 2022-09-20" "openjdk" "190" "detected java 11 from oracle or any openjdk" + +# Some predefined variants. We only check for the existence of a javafx.properties file +# at lib/ or jre/lib. java.home sometimes points already to jre (oracle), but openjdk +# builds don't have a jre folder anymore. Anyway, both should work. +JH_WITH_FX=java-with-fx +JH_WITH_FX2=java-with-fx/jre +JH_WITHOUT_FX=java-without-fx + +#exit + +run_test "1.7.0_80" "$JH_WITH_FX" "7" "80" "yes" +run_test "1.7.0_352" "$JH_WITH_FX" "7" "352" "yes" +run_test "1.8.0_271" "$JH_WITH_FX" "8" "271" "yes" +run_test "1.8.0_345" "$JH_WITH_FX" "8" "345" "yes" +run_test "1.8.0_441" "$JH_WITH_FX" "8" "441" "yes" +run_test "1.8.0_441" "$JH_WITH_FX2" "8" "441" "yes" +run_test "1.8.0_471" "$JH_WITHOUT_FX" "8" "471" "no" # e.g. oracle +run_test "1.8.0_471" "$JH_WITH_FX2" "8" "471" "yes" # e.g. azul +run_test "9.0.4" "$JH_WITHOUT_FX" "9" "4" "no" +run_test "10.0.2" "$JH_WITHOUT_FX" "10" "2" "no" +run_test "11.0.6" "$JH_WITHOUT_FX" "11" "6" "no" +run_test "11.0.6.1" "$JH_WITHOUT_FX" "11" "6" "no" +run_test "11.0.13" "$JH_WITHOUT_FX" "11" "13" "no" +run_test '11.0.19' "$JH_WITHOUT_FX" "11" "19" "no" +run_test "17.0.4" "$JH_WITHOUT_FX" "17" "4" "no" +run_test "17.0.4.1" "$JH_WITHOUT_FX" "17" "4" "no" +run_test "17.0.17" "$JH_WITH_FX" "17" "17" "yes" +run_test "18.0.2.1" "$JH_WITHOUT_FX" "18" "2" "no" +run_test "19-ea" "$JH_WITHOUT_FX" "19" "0" "no" +run_test "25" "$JH_WITHOUT_FX" "25" "0" "no" +run_test '25.0.1' "$JH_WITHOUT_FX" "25" "1" "no" + +pass " All tests passed. โœ”๏ธ" From b02d9aa9e7c07ae63b503bb7591245469dc1f8fb Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 28 Nov 2025 20:23:03 +0100 Subject: [PATCH 1857/1962] [cli] Add more opens for reflection This allows to use Azul JDK with JavaFX up to 21. --- pmd-dist/src/main/resources/scripts/pmd | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/pmd-dist/src/main/resources/scripts/pmd b/pmd-dist/src/main/resources/scripts/pmd index 923b96dd4e6..66f8ee9e8ef 100755 --- a/pmd-dist/src/main/resources/scripts/pmd +++ b/pmd-dist/src/main/resources/scripts/pmd @@ -146,19 +146,31 @@ jre_specific_vm_options() { # Azul provides builds which include javafx as well # Since Java 9, it is included as a module. But we run on the classpath (aka unnamed module) and # want to access the classes. - # open internal module of javafx to reflection (for our TreeViewWrapper) + # + # for PMD Designer + # in net.sourceforge.pmd.util.fxdesigner.util.controls.TreeViewWrapper.getVirtualFlow options="--add-opens javafx.controls/javafx.scene.control.skin=ALL-UNNAMED" - # The rest here is for RichtextFX + # in net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil.customBuilderFactory + options="$options --add-opens javafx.fxml/com.sun.javafx.fxml.builder=ALL-UNNAMED" + # + # for RichtextFX options="$options --add-opens javafx.graphics/javafx.scene.text=ALL-UNNAMED" options="$options --add-opens javafx.graphics/com.sun.javafx.scene.text=ALL-UNNAMED" options="$options --add-opens javafx.graphics/com.sun.javafx.text=ALL-UNNAMED" options="$options --add-opens javafx.graphics/com.sun.javafx.geom=ALL-UNNAMED" - # for ?? - options="$options --add-opens javafx.fxml/com.sun.javafx.fxml.builder=ALL-UNNAMED" + # # for controlsfx options="$options --add-opens javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED" - # Warn of remaining illegal accesses - options="$options --illegal-access=warn" + options="$options --add-opens javafx.base/com.sun.javafx.runtime=ALL-UNNAMED" + options="$options --add-opens javafx.base/com.sun.javafx.event=ALL-UNNAMED" + options="$options --add-opens javafx.graphics/com.sun.javafx.scene.traversal=ALL-UNNAMED" + + if [ "$java_version_feature" -lt 17 ] + then + # Warn of remaining illegal accesses - only possible until java 16. + # With Java 17+ this option has no effect anymore (https://openjdk.org/jeps/403). + options="$options --illegal-access=warn" + fi fi echo "$options" @@ -177,7 +189,6 @@ add_pmd_classpath() { add_openjfx_classpath() { if [ "$APPNAME" = "designer" ] - echo "add_openfx_classpath: java_version_feature='$java_version_feature' java_version_update='$java_version_update' java_has_javafx=$java_has_javafx" then if [ $java_has_javafx = 1 ] then From cb2eed4a15c1b5456e1a5d45ec9612cf805ade53 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 4 Dec 2025 18:05:17 +0100 Subject: [PATCH 1858/1962] [cli] Improve start script for designer (windows) --- pmd-dist/src/main/resources/scripts/pmd | 6 +- pmd-dist/src/main/resources/scripts/pmd.bat | 132 +++++++---- .../src/test/resources/scripts/pmdtest.bat | 207 ++++++++++++------ 3 files changed, 231 insertions(+), 114 deletions(-) diff --git a/pmd-dist/src/main/resources/scripts/pmd b/pmd-dist/src/main/resources/scripts/pmd index 66f8ee9e8ef..9985cde100f 100755 --- a/pmd-dist/src/main/resources/scripts/pmd +++ b/pmd-dist/src/main/resources/scripts/pmd @@ -118,9 +118,9 @@ determine_java_version() { }') # 1. component: java_version_feature is e.g. "8" for java 1.8, "9" for java 9, "10" for java 10, ... java_version_feature=$(echo "$java_ver_normalized" | sed -n -e 's/^\([0-9]\{1,\}\).*$/\1/p') - # 3. component: update release counter + # 3. component: update release counter is e.g. "17" for java 11.0.17 java_version_update=$(echo "$java_ver_normalized" | sed -n -e 's/^\([0-9]\{1,\}\)\.\([0-9]\{1,\}\).\([0-9]\{1,\}\).*$/\3/p') - # if there was no 3rd component, use "0" + # if there was no 3rd component (eg. -ea or ga version), use "0" java_version_update=${java_version_update:="0"} java_home_property=$(echo "$all_props" | grep "java.home" | sed -n -e 's/^.*java\.home *= *\(.*\)$/\1/; p') @@ -193,7 +193,7 @@ add_openjfx_classpath() { if [ $java_has_javafx = 1 ] then # almost nothing to do, javafx is bundled (either an old Oracle Java < 8u451 or an OpenJDK 8 Build from Azul) - # still hadd the path where javafx.properties is located to the classpath, so that Designer's + # still add the path where javafx.properties is located to the classpath, so that Designer's # net.sourceforge.pmd.util.fxdesigner.util.JavaFxUtil#getJavaFxVersion can find it. if [ -n "$classpath" ]; then classpath="$classpath:$(dirname "$java_javafx_properties")" diff --git a/pmd-dist/src/main/resources/scripts/pmd.bat b/pmd-dist/src/main/resources/scripts/pmd.bat index d32ce4fd9d1..81cb9049633 100644 --- a/pmd-dist/src/main/resources/scripts/pmd.bat +++ b/pmd-dist/src/main/resources/scripts/pmd.bat @@ -1,5 +1,6 @@ @echo off +SETLOCAL EnableDelayedExpansion rem use unicode codepage to properly support UTF-8 chcp 65001>nul @@ -16,63 +17,110 @@ java -version > nul 2>&1 || ( exit /b 1 ) -rem sets the jver variable to the java version, eg 90 for 9.0.1+x or 80 for 1.8.0_171-b11 or 110 for 11.0.6.1 -rem sets the jvendor variable to either java (oracle) or openjdk -for /f tokens^=1^,3^,4^,5^ delims^=.-_+^"^ %%j in ('java -version 2^>^&1 ^| findstr /c:"version"') do ( - set jvendor=%%j - if %%l EQU ea ( - set /A "jver=%%k0" - ) else ( - if %%k EQU 1 ( - rem for java version 1.7.x, 1.8.x, ignore the first 1. - set /A "jver=%%l%%m" - ) else ( - set /A "jver=%%k%%l" - ) +rem sets the java_version_feature variable. This is e.g. "8" for java 1.8, "9" for java 9, "10" for java 10, ... +rem sets the java_version_update variable. This is the update release counter: e.g. "17" for java 11.0.17 + +set java_version_prop= +set java_home_property= +FOR /F tokens^=1^,3^ %%j IN ('java -XshowSettings:properties 2^>^&1') DO ( + IF "%%j" == "java.version" set java_version_prop=%%k + IF "%%j" == "java.home" set java_home_property=%%k +) + +set java_version_feature= +set java_version_update= +FOR /f tokens^=1^,2^,3^,4^ delims^=.-_+^"^ %%j IN ("%java_version_prop%") DO ( + IF %%j EQU 1 ( + set java_version_feature=%%k + set java_version_update=%%m + ) ELSE ( + set java_version_feature=%%j + set java_version_update=%%l ) ) +rem if there was no 3rd component (eg. -ea or ga version), use "0" +IF "%java_version_update%" == "" set java_version_update=0 + +set java_has_javafx=0 +set java_javafx_properties= +set java_javafx_properties_path= +IF EXIST "%java_home_property%/lib/javafx.properties" ( + set "java_javafx_properties=%java_home_property%/lib/javafx.properties" + set java_has_javafx=1 +) +IF EXIST "%java_home_property%/jre/lib/javafx.properties" ( + set "java_javafx_properties=%java_home_property%/jre/lib/javafx.properties" + set java_has_javafx=1 +) +rem resolve dirname +IF %java_has_javafx% EQU 1 FOR %%F IN (%java_javafx_properties%) DO set "java_javafx_properties_path=%%~dpF" +rem remove trailing backslash +IF %java_has_javafx% EQU 1 set "java_javafx_properties_path=%java_javafx_properties_path:~0,-1%" Set "jreopts=" -rem oracle java 9 and 10 has javafx included as a module -if /I %jvendor% == java ( - if %jver% GEQ 90 ( - if %jver% LSS 110 ( - rem enable reflection - SETLOCAL EnableDelayedExpansion +IF [%COMMAND%] == [designer] ( + IF %java_version_feature% GEQ 9 ( + IF %java_has_javafx% EQU 1 ( rem java9 and java10 from oracle contain javafx as a module - rem open internal module of javafx to reflection (for our TreeViewWrapper) + rem Azul provides builds which include javafx as well + rem Since Java 9, it is included as a module. But we run on the classpath (aka unnamed module) and + rem want to access the classes. + rem + rem for PMD Designer + rem in net.sourceforge.pmd.util.fxdesigner.util.controls.TreeViewWrapper.getVirtualFlow set "jreopts=--add-opens javafx.controls/javafx.scene.control.skin=ALL-UNNAMED" - rem The rest here is for RichtextFX + rem in net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil.customBuilderFactory + set "jreopts=!jreopts! --add-opens javafx.fxml/com.sun.javafx.fxml.builder=ALL-UNNAMED" + rem + rem for RichtextFX set "jreopts=!jreopts! --add-opens javafx.graphics/javafx.scene.text=ALL-UNNAMED" set "jreopts=!jreopts! --add-opens javafx.graphics/com.sun.javafx.scene.text=ALL-UNNAMED" set "jreopts=!jreopts! --add-opens javafx.graphics/com.sun.javafx.text=ALL-UNNAMED" set "jreopts=!jreopts! --add-opens javafx.graphics/com.sun.javafx.geom=ALL-UNNAMED" - rem Warn of remaining illegal accesses - set "jreopts=!jreopts! --illegal-access=warn" + rem + rem for controlsfx + set "jreopts=!jreopts! --add-opens javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED" + set "jreopts=!jreopts! --add-opens javafx.base/com.sun.javafx.runtime=ALL-UNNAMED" + set "jreopts=!jreopts! --add-opens javafx.base/com.sun.javafx.event=ALL-UNNAMED" + set "jreopts=!jreopts! --add-opens javafx.graphics/com.sun.javafx.scene.traversal=ALL-UNNAMED" + + IF %java_version_feature% LSS 17 ( + rem Warn of remaining illegal accesses - only possible until java 16. + rem With Java 17+ this option has no effect anymore (https://openjdk.org/jeps/403). + set "jreopts=!jreopts! --illegal-access=warn" + ) ) ) ) -set "_needjfxlib=0" -if [%COMMAND%] == [designer] ( - if /I %jvendor% == openjdk set _needjfxlib=1 - if /I %jvendor% == java ( - if %jver% GEQ 110 set _needjfxlib=1 - ) -) -if %_needjfxlib% EQU 1 ( - if %jver% LSS 100 ( - echo For openjfx at least java 10 is required. - exit /b 1 - ) - if not defined JAVAFX_HOME ( - echo The environment variable JAVAFX_HOME is missing. - exit /b 1 +IF [%COMMAND%] == [designer] ( + IF %java_has_javafx% EQU 1 ( + rem almost nothing to do, javafx is bundled (either an old Oracle Java < 8u451 or an OpenJDK 8 Build from Azul) + rem still add the path where javafx.properties is located to the classpath, so that Designer's + rem net.sourceforge.pmd.util.fxdesigner.util.JavaFxUtil#getJavaFxVersion can find it. + set "pmd_classpath=%TOPDIR%\conf;%TOPDIR%\lib\*;%java_javafx_properties_path%" + ) ELSE ( + IF %java_version_feature% EQU 8 ( + IF %java_version_update% GEQ 451 ( + echo JavaFX has been removed from Oracle Java 8 since Java 8u451. See https://www.oracle.com/javase/javafx. + echo Use Java 11 or later with OpenJFX separately from https://openjfx.io/. + echo Alternatively use an OpenJDK build from Azul with JavaFX bundled ^(JDK FX^). + EXIT /B 1 + ) + ) + IF %java_version_feature% LSS 10 ( + echo For OpenJFX at least Java 10 is required. + EXIT /B 1 + ) + IF not defined JAVAFX_HOME ( + echo The environment variable JAVAFX_HOME is missing. + EXIT /B 1 + ) + rem The wildcard will include only jar files, but we need to access also + rem property files such as javafx.properties that lay bare in the dir + rem note: no trailing backslash, as this would escape a following quote when %pmd_classpath% is used later + set "pmd_classpath=%TOPDIR%\conf;%TOPDIR%\lib\*;%JAVAFX_HOME%\lib\*;%JAVAFX_HOME%\lib" ) - rem The wildcard will include only jar files, but we need to access also - rem property files such as javafx.properties that lay bare in the dir - rem note: no trailing backslash, as this would escape a following quote when %pmd_classpath% is used later - set "pmd_classpath=%TOPDIR%\conf;%TOPDIR%\lib\*;%JAVAFX_HOME%\lib\*;%JAVAFX_HOME%\lib" ) else ( rem note: no trailing backslash, as this would escape a following quote when %pmd_classpath% is used later set "pmd_classpath=%TOPDIR%\conf;%TOPDIR%\lib\*" diff --git a/pmd-dist/src/test/resources/scripts/pmdtest.bat b/pmd-dist/src/test/resources/scripts/pmdtest.bat index 40f189ce7a6..5dcd4dff4af 100644 --- a/pmd-dist/src/test/resources/scripts/pmdtest.bat +++ b/pmd-dist/src/test/resources/scripts/pmdtest.bat @@ -6,63 +6,75 @@ rem rem Simple manual test script rem - code is copied from pmd.bat to be tested here (so please check, it might be out of sync) rem - mostly the function "determine_java_version" is tested here -rem - just run it with "pmd.bat" and look at the output +rem - just run it with "pmdtest.bat" and look at the output rem - test cases are at the end of this script rem +setlocal EnableDelayedExpansion +rem use unicode codepage to properly support UTF-8 +chcp 65001>nul +rem make all variables local to not add new global environment variables to the current cmd session +setlocal + GOTO :main +:mock_show_settings_properties +rem instead of: java -XshowSettings:properties 2>&1 + +set nl=^ + + +rem two empty lines required +set "MOCKED_JAVA_PROPERTIES=Property settings:!nl!" +set "MOCKED_JAVA_PROPERTIES=!MOCKED_JAVA_PROPERTIES! some.other.property1 = value!nl!" +set "MOCKED_JAVA_PROPERTIES=!MOCKED_JAVA_PROPERTIES! java.version = !MOCKED_JAVA_VERSION!!nl!" +set "MOCKED_JAVA_PROPERTIES=!MOCKED_JAVA_PROPERTIES! some.other.property2 = value!nl!" +set "MOCKED_JAVA_PROPERTIES=!MOCKED_JAVA_PROPERTIES! java.home = !MOCKED_JAVA_HOME!!nl!" +set "MOCKED_JAVA_PROPERTIES=!MOCKED_JAVA_PROPERTIES! some.other.property3 = value!nl!" +EXIT /B + :determine_java_version -rem sets the jver variable to the java version, eg 90 for 9.0.1+x or 80 for 1.8.0_171-b11 or 110 for 11.0.6.1 -rem sets the jvendor variable to either java (oracle) or openjdk -for /f tokens^=1^,3^,4^,5^ delims^=.-_+^"^ %%j in (%full_version%) do ( - set jvendor=%%j - if %%l EQU ea ( - set /A "jver=%%k0" - ) else ( - if %%k EQU 1 ( - rem for java version 1.7.x, 1.8.x, ignore the first 1. - set /A "jver=%%l%%m" - ) else ( - set /A "jver=%%k%%l" - ) - ) -) +CALL :mock_show_settings_properties -set detection= -if %jver% GEQ 70 ( - if %jver% LSS 80 ( - set detection="detected java 7" - ) -) -if [%detection%] == [] ( - if %jver% GEQ 80 ( - if %jver% LSS 90 ( - set detection="detected java 8" - ) - ) +rem sets the java_version_feature variable. This is e.g. "8" for java 1.8, "9" for java 9, "10" for java 10, ... +rem sets the java_version_update variable. This is the update release counter: e.g. "17" for java 11.0.17 + +set java_version_prop= +set java_home_property= +FOR /F tokens^=1^,3^ %%j IN ("!MOCKED_JAVA_PROPERTIES!") DO ( + IF "%%j" == "java.version" set java_version_prop=%%k + IF "%%j" == "java.home" set java_home_property=%%k ) -if [%detection%] == [] ( - if %jver% GEQ 90 ( - if %jver% LSS 110 ( - if %jvendor% == java ( - set detection="detected java 9 or 10 from oracle" - ) - ) - ) + +set java_version_feature= +set java_version_update= +FOR /f tokens^=1^,2^,3^,4^ delims^=.-_+^"^ %%j IN ("%java_version_prop%") DO ( + IF %%j EQU 1 ( + set java_version_feature=%%k + set java_version_update=%%m + ) ELSE ( + set java_version_feature=%%j + set java_version_update=%%l + ) ) -if [%detection%] == [] ( - if %jvendor% == openjdk ( - set detection="detected java 11 from oracle or any openjdk" - ) +rem if there was no 3rd component (eg. -ea or ga version), use "0" +IF "%java_version_update%" == "" set java_version_update=0 + +set java_has_javafx=0 +set java_javafx_properties= +set java_javafx_properties_path= +IF EXIST "%java_home_property%/lib/javafx.properties" ( + set "java_javafx_properties=%java_home_property%/lib/javafx.properties" + set java_has_javafx=1 ) -if [%detection%] == [] ( - if %jvendor% == java ( - if %jver% GEQ 110 ( - set detection="detected java 11 from oracle or any openjdk" - ) - ) +IF EXIST "%java_home_property%/jre/lib/javafx.properties" ( + set "java_javafx_properties=%java_home_property%/jre/lib/javafx.properties" + set java_has_javafx=1 ) +rem resolve dirname +IF %java_has_javafx% EQU 1 FOR %%F IN (%java_javafx_properties%) DO set "java_javafx_properties_path=%%~dpF" +rem remove trailing backslash +IF %java_has_javafx% EQU 1 set "java_javafx_properties_path=%java_javafx_properties_path:~0,-1%" EXIT /B @@ -86,18 +98,54 @@ if defined cp ( endlocal EXIT /B +:pass +echo OK %~1 +EXIT /B + +:fail +echo FAILED +set failed=1 +EXIT /B + :run_test -set full_version=%1 -set expected_vendor=%2 -set expected_version=%3 -set expected_detection=%4 +IF %failed% EQU 1 EXIT /B +set MOCKED_JAVA_VERSION=%~1 +set MOCKED_JAVA_HOME=%~2 +set EXPECTED_FEATURE=%3 +set EXPECTED_UPDATE=%4 +set EXPECTED_HAS_JAVAFX=%5 + +echo Testing: '%MOCKED_JAVA_VERSION%' in '%MOCKED_JAVA_HOME%' +rem use mocked path relative to the test script +set MOCKED_JAVA_HOME=%~dp0%MOCKED_JAVA_HOME% CALL :determine_java_version -echo full_version: %full_version% -if %jver% == %expected_version% ( echo jver: %jver% OK ) ELSE ( echo jver: %jver% EXPECTED: %expected_version%  ) -if %jvendor% == %expected_vendor% ( echo jvendor: %jvendor% OK ) ELSE ( echo jvendor: %jvendor% EXPECTED: %expected_vendor%  ) -if [%detection%] == [%expected_detection%] ( echo detection: %detection% OK ) ELSE ( echo detection: %detection% EXPECTED: %expected_detection%  ) +echo.|set /p =java_version_feature: %java_version_feature% +IF %EXPECTED_FEATURE% == %java_version_feature% ( CALL :pass ) ELSE ( CALL :fail ) +echo.|set /p =java_version_update: %java_version_update% +IF %EXPECTED_UPDATE% == %java_version_update% ( CALL :pass ) ELSE ( CALL :fail ) +echo.|set /p =java_has_javafx: %java_has_javafx% +set "_temp_javafx_passed=0" +IF "%EXPECTED_HAS_JAVAFX%" == "yes" ( + IF %java_has_javafx% EQU 1 ( + IF NOT "%java_javafx_properties%" == "" ( + set "_temp_javafx_passed=1" + CALL :pass + ) + ) +) +IF "%EXPECTED_HAS_JAVAFX%" == "no" ( + IF %java_has_javafx% EQU 0 ( + IF "%java_javafx_properties%" == "" ( + set "_temp_javafx_passed=1" + CALL :pass + ) + ) +) +IF %_temp_javafx_passed% EQU 0 ( CALL :fail ) +rem echo javafx_properties: %java_javafx_properties% +rem echo javafx_properties_path: %java_javafx_properties_path% echo. EXIT /B @@ -114,18 +162,39 @@ CALL :check_classpath_extension "a\b.jar" CALL :check_classpath_extension "a"\b.jar CALL :check_classpath_extension "a"\b.jar;"c"\d.jar -CALL :run_test "java version ""1.7.0_80""" java 70 "detected java 7" -CALL :run_test "openjdk version ""1.7.0_352""" openjdk 70 "detected java 7" -CALL :run_test "java version ""1.8.0_271""" java 80 "detected java 8" -CALL :run_test "openjdk version ""1.8.0_345""" openjdk 80 "detected java 8" -CALL :run_test "java version ""9.0.4""" java 90 "detected java 9 or 10 from oracle" -CALL :run_test "openjdk version ""9.0.4""" openjdk 90 "detected java 11 from oracle or any openjdk" -CALL :run_test "java version ""10.0.2"" 2018-07-17" java 100 "detected java 9 or 10 from oracle" -CALL :run_test "openjdk version ""11.0.6"" 2022-08-12" openjdk 110 "detected java 11 from oracle or any openjdk" -CALL :run_test "openjdk version ""11.0.6.1"" 2022-08-12" openjdk 110 "detected java 11 from oracle or any openjdk" -CALL :run_test "java version ""11.0.13"" 2021-10-19 LTS" java 110 "detected java 11 from oracle or any openjdk" -CALL :run_test "openjdk version ""17.0.4"" 2022-08-12" openjdk 170 "detected java 11 from oracle or any openjdk" -CALL :run_test "openjdk version ""17.1.4"" 2022-08-12" openjdk 171 "detected java 11 from oracle or any openjdk" -CALL :run_test "openjdk version ""17.0.4.1"" 2022-08-12" openjdk 170 "detected java 11 from oracle or any openjdk" -CALL :run_test "openjdk version ""18.0.2.1"" 2022-08-18" openjdk 180 "detected java 11 from oracle or any openjdk" -CALL :run_test "openjdk version ""19-ea"" 2022-09-20" openjdk 190 "detected java 11 from oracle or any openjdk" +rem Some predefined variants. We only check for the existence of a javafx.properties file +rem at lib/ or jre/lib. java.home sometimes points already to jre (oracle), but openjdk +rem builds don't have a jre folder anymore. Anyway, both should work. +set JH_WITH_FX=java-with-fx +set JH_WITH_FX2=java-with-fx/jre +set JH_WITHOUT_FX=java-without-fx + +set failed=0 +CALL :run_test "1.7.0_80" "%JH_WITH_FX%" 7 80 yes +CALL :run_test "1.7.0_352" "%JH_WITH_FX%" 7 352 yes +CALL :run_test "1.8.0_271" "%JH_WITH_FX%" 8 271 yes +CALL :run_test "1.8.0_345" "%JH_WITH_FX%" 8 345 yes +CALL :run_test "1.8.0_441" "%JH_WITH_FX%" 8 441 yes +CALL :run_test "1.8.0_441" "%JH_WITH_FX2%" 8 441 yes +rem e.g. oracle +CALL :run_test "1.8.0_471" "%JH_WITHOUT_FX%" 8 471 no +rem # e.g. azul +CALL :run_test "1.8.0_471" "%JH_WITH_FX2%" 8 471 yes +CALL :run_test "9.0.4" "%JH_WITHOUT_FX%" 9 4 no +CALL :run_test "10.0.2" "%JH_WITHOUT_FX%" 10 2 no +CALL :run_test "11.0.6" "%JH_WITHOUT_FX%" 11 6 no +CALL :run_test "11.0.6.1" "%JH_WITHOUT_FX%" 11 6 no +CALL :run_test "11.0.13" "%JH_WITHOUT_FX%" 11 13 no +CALL :run_test "11.0.19" "%JH_WITHOUT_FX%" 11 19 no +CALL :run_test "17.0.4" "%JH_WITHOUT_FX%" 17 4 no +CALL :run_test "17.0.4.1" "%JH_WITHOUT_FX%" 17 4 no +CALL :run_test "17.0.17" "%JH_WITH_FX%" 17 17 yes +CALL :run_test "18.0.2.1" "%JH_WITHOUT_FX%" 18 2 no +CALL :run_test "19-ea" "%JH_WITHOUT_FX%" 19 0 no +CALL :run_test "25" "%JH_WITHOUT_FX%" 25 0 no +CALL :run_test "25.0.1" "%JH_WITHOUT_FX%" 25 1 no + + +IF %failed% EQU 0 CALL :pass "All tests passed. โœ”๏ธ" + +EXIT /B From 4d697b81f9c64222bbefeec7d61b1bb8d46943e2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 4 Dec 2025 18:06:56 +0100 Subject: [PATCH 1859/1962] Fix missing license header --- .../scripts/java-with-fx/jre/lib/javafx.properties | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pmd-dist/src/test/resources/scripts/java-with-fx/jre/lib/javafx.properties b/pmd-dist/src/test/resources/scripts/java-with-fx/jre/lib/javafx.properties index d45361907d7..75397335b5b 100644 --- a/pmd-dist/src/test/resources/scripts/java-with-fx/jre/lib/javafx.properties +++ b/pmd-dist/src/test/resources/scripts/java-with-fx/jre/lib/javafx.properties @@ -1,4 +1,8 @@ -# sample file to that the start script determine +# +# BSD-style license; for more info see http://pmd.sourceforge.net/license.html +# + +# sample file so that the start script can determine # whether javafx is bundled with the jdk/jre or not # From 6be532228c6d16ea8d2977eea94fc136153582c6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 4 Dec 2025 18:15:43 +0100 Subject: [PATCH 1860/1962] [doc] Update release notes (#6290) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..5510c310448 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,6 +25,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy ### ๐Ÿ›๏ธ Fixed Issues +* cli + * [#6290](https://github.com/pmd/pmd/issues/6290): \[cli] Improve Designer start script ### ๐Ÿšจ๏ธ API Changes From 2cc2c7fb9a9d9d6042a60071e2e83055a84d1147 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 5 Dec 2025 09:49:19 +0100 Subject: [PATCH 1861/1962] Refactoring of pmd start script - determine java_javafx_properties_path once - unnest if statements - always warn about illegal-access (not only for Designer) - improve error messages --- pmd-dist/src/main/resources/scripts/pmd | 146 ++++++++++-------- .../src/test/resources/scripts/runtest.sh | 10 ++ 2 files changed, 91 insertions(+), 65 deletions(-) diff --git a/pmd-dist/src/main/resources/scripts/pmd b/pmd-dist/src/main/resources/scripts/pmd index 9985cde100f..7626e5fe997 100755 --- a/pmd-dist/src/main/resources/scripts/pmd +++ b/pmd-dist/src/main/resources/scripts/pmd @@ -126,6 +126,7 @@ determine_java_version() { java_home_property=$(echo "$all_props" | grep "java.home" | sed -n -e 's/^.*java\.home *= *\(.*\)$/\1/; p') java_has_javafx=0 java_javafx_properties= + java_javafx_properties_path= if [ -e "$java_home_property/lib/javafx.properties" ]; then java_javafx_properties="$java_home_property/lib/javafx.properties" java_has_javafx=1 @@ -133,60 +134,69 @@ determine_java_version() { java_javafx_properties="$java_home_property/jre/lib/javafx.properties" java_has_javafx=1 fi + if [ $java_has_javafx = 1 ] + then + java_javafx_properties_path="$(dirname "$java_javafx_properties")" + fi } jre_specific_vm_options() { - if [ "$APPNAME" = "designer" ] + options="" + if [ "$APPNAME" = "designer" ] && [ "$java_version_feature" -ge 9 ] && [ $java_has_javafx = 1 ] then - options="" - - if [ "$java_version_feature" -ge 9 ] && [ $java_has_javafx = 1 ] - then - # java9 and java10 from oracle contain javafx as a module - # Azul provides builds which include javafx as well - # Since Java 9, it is included as a module. But we run on the classpath (aka unnamed module) and - # want to access the classes. - # - # for PMD Designer - # in net.sourceforge.pmd.util.fxdesigner.util.controls.TreeViewWrapper.getVirtualFlow - options="--add-opens javafx.controls/javafx.scene.control.skin=ALL-UNNAMED" - # in net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil.customBuilderFactory - options="$options --add-opens javafx.fxml/com.sun.javafx.fxml.builder=ALL-UNNAMED" - # - # for RichtextFX - options="$options --add-opens javafx.graphics/javafx.scene.text=ALL-UNNAMED" - options="$options --add-opens javafx.graphics/com.sun.javafx.scene.text=ALL-UNNAMED" - options="$options --add-opens javafx.graphics/com.sun.javafx.text=ALL-UNNAMED" - options="$options --add-opens javafx.graphics/com.sun.javafx.geom=ALL-UNNAMED" - # - # for controlsfx - options="$options --add-opens javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED" - options="$options --add-opens javafx.base/com.sun.javafx.runtime=ALL-UNNAMED" - options="$options --add-opens javafx.base/com.sun.javafx.event=ALL-UNNAMED" - options="$options --add-opens javafx.graphics/com.sun.javafx.scene.traversal=ALL-UNNAMED" - - if [ "$java_version_feature" -lt 17 ] - then - # Warn of remaining illegal accesses - only possible until java 16. - # With Java 17+ this option has no effect anymore (https://openjdk.org/jeps/403). - options="$options --illegal-access=warn" - fi - fi + # Since Java 9, Java uses the module system. If JavaFX is bundled, this is also + # included as modules. PMD however is run on the classpath and will run as the + # "unnamed module". To allow reflection to some JavaFX classes, we need to allow + # this access explicitly by opening specific javafx packages. + # + # This applies to Java 9/10 builds from Oracle and to Java 9+ builds from + # Azul (Zulu) or Bellsoft (Liberica). + # + # It does not apply, if we run Java 8+ without bundled JavaFX and we + # put JavaFX on the classpath. Then we don't use the module system at all + # and all classes on the classpath are allowed to access all other classes + # on the classpath by reflection without explicitly opening packages. + # + # Reflective access used by PMD Designer + # in net.sourceforge.pmd.util.fxdesigner.util.controls.TreeViewWrapper.getVirtualFlow + options="$options --add-opens javafx.controls/javafx.scene.control.skin=ALL-UNNAMED" + # in net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil.customBuilderFactory + options="$options --add-opens javafx.fxml/com.sun.javafx.fxml.builder=ALL-UNNAMED" + # + # Reflective access used by RichtextFX + options="$options --add-opens javafx.graphics/javafx.scene.text=ALL-UNNAMED" + options="$options --add-opens javafx.graphics/com.sun.javafx.scene.text=ALL-UNNAMED" + options="$options --add-opens javafx.graphics/com.sun.javafx.text=ALL-UNNAMED" + options="$options --add-opens javafx.graphics/com.sun.javafx.geom=ALL-UNNAMED" + # + # Reflective access used by controlsfx + options="$options --add-opens javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED" + options="$options --add-opens javafx.base/com.sun.javafx.runtime=ALL-UNNAMED" + options="$options --add-opens javafx.base/com.sun.javafx.event=ALL-UNNAMED" + options="$options --add-opens javafx.graphics/com.sun.javafx.scene.traversal=ALL-UNNAMED" + fi - echo "$options" - else - echo "" + if [ "$java_version_feature" -ge 9 ] && [ "$java_version_feature" -le 16 ] + then + # Warn of illegal accesses in general - only possible for Java 9 until Java 16 (inclusive). + # With Java 17+ this option has no effect anymore (https://openjdk.org/jeps/403) and is deprecated. + options="$options --illegal-access=warn" fi + echo "$options" } -add_pmd_classpath() { +append_classpath() { if [ -n "$classpath" ]; then - classpath="$classpath:$CONF_DIR:$LIB_DIR/*" + classpath="$classpath:$1" else - classpath="$CONF_DIR:$LIB_DIR/*" + classpath="$1" fi } +add_pmd_classpath() { + append_classpath "$CONF_DIR:$LIB_DIR/*" +} + add_openjfx_classpath() { if [ "$APPNAME" = "designer" ] then @@ -195,36 +205,40 @@ add_openjfx_classpath() { # almost nothing to do, javafx is bundled (either an old Oracle Java < 8u451 or an OpenJDK 8 Build from Azul) # still add the path where javafx.properties is located to the classpath, so that Designer's # net.sourceforge.pmd.util.fxdesigner.util.JavaFxUtil#getJavaFxVersion can find it. - if [ -n "$classpath" ]; then - classpath="$classpath:$(dirname "$java_javafx_properties")" - else - classpath="$(dirname "$java_javafx_properties")" - fi - elif [ "$java_version_feature" = "8" ] && [ "$java_version_update" -ge 451 ] - then - script_exit " - JavaFX has been removed from Oracle Java 8 since Java 8u451. See https://www.oracle.com/javase/javafx. - Use Java 11 or later with OpenJFX separately from https://openjfx.io/. - Alternatively use an OpenJDK build from Azul with JavaFX bundled (JDK FX). - " - elif [ "$java_version_feature" -lt 10 ] - then - script_exit " - For OpenJFX at least Java 10 is required. - " + append_classpath "$java_javafx_properties_path" else + + if [ "$java_version_feature" = "8" ] && [ "$java_version_update" -ge 451 ] + then + script_exit " + JavaFX has been removed from Oracle Java 8 since Java 8u451. + See https://www.oracle.com/javase/javafx. + Use Java 11 or later with OpenJFX separately from https://openjfx.io/. + Alternatively use an OpenJDK build from Azul with JavaFX bundled (JDK FX) + or from Bellsoft with JavaFX bundled (Full JDK). + " + fi + + if [ "$java_version_feature" -lt 10 ] + then + script_exit " + For OpenJFX at least Java 10 is required. Newer OpenJFX version + might require newer Java versions. + " + fi + # openjfx is required for any openjdk builds which don't include JavaFX if [ -z "$JAVAFX_HOME" ] then - script_exit "The environment variable JAVAFX_HOME is missing." + script_exit " + The environment variable JAVAFX_HOME is missing. + See https://docs.pmd-code.org/latest/pmd_userdocs_extending_designer_reference.html#installing-running-updating + for instructions. + " else # The wildcard will include only jar files, but we need to access also # property files such as javafx.properties that lay bare in the dir - if [ -n "$classpath" ]; then - classpath="$classpath:$JAVAFX_HOME/lib/*:$JAVAFX_HOME/lib/" - else - classpath="$JAVAFX_HOME/lib/*:$JAVAFX_HOME/lib/" - fi + append_classpath "$JAVAFX_HOME/lib/*:$JAVAFX_HOME/lib/" fi fi fi @@ -254,7 +268,9 @@ cygwin_paths java_heapsize_settings -# Note: we want word-splitting happening on PMD_JAVA_OPTS and jre_specific_vm_options +# Note: we want word-splitting happening on PMD_JAVA_OPTS and jre_specific_vm_options, +# so we explicitly don't use quotes. +# shellcheck disable=SC2046,SC2086 exec java \ ${HEAPSIZE:+"$HEAPSIZE"} \ $PMD_JAVA_OPTS $(jre_specific_vm_options) \ diff --git a/pmd-dist/src/test/resources/scripts/runtest.sh b/pmd-dist/src/test/resources/scripts/runtest.sh index 23cbcf636aa..927b702aa4f 100755 --- a/pmd-dist/src/test/resources/scripts/runtest.sh +++ b/pmd-dist/src/test/resources/scripts/runtest.sh @@ -45,6 +45,7 @@ determine_java_version() { java_home_property=$(echo "$all_props" | grep "java.home" | sed -n -e 's/^.*java\.home *= *\(.*\)$/\1/; p') java_has_javafx=0 java_javafx_properties= + java_javafx_properties_path= if [ -e "$java_home_property/lib/javafx.properties" ]; then java_javafx_properties="$java_home_property/lib/javafx.properties" java_has_javafx=1 @@ -52,6 +53,10 @@ determine_java_version() { java_javafx_properties="$java_home_property/jre/lib/javafx.properties" java_has_javafx=1 fi + if [ $java_has_javafx = 1 ] + then + java_javafx_properties_path="$(dirname "$java_javafx_properties")" + fi } pass() { @@ -81,6 +86,11 @@ run_test() { if [ "$EXPECTED_HAS_JAVAFX" = "yes" ] && [ "$java_has_javafx" = 1 ] && [ -n "$java_javafx_properties" ]; then pass; elif [ "$EXPECTED_HAS_JAVAFX" = "no" ] && [ "$java_has_javafx" = 0 ] && [ -z "$java_javafx_properties" ]; then pass; else fail; fi + if [ "$java_has_javafx" = 1 ] + then + printf "java_javafx_properties_path: " + if [ -n "$java_javafx_properties_path" ]; then pass; else fail; fi + fi echo } From d5c05a0cb0b203a0fce3b4fb7d6561425fc829a7 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 5 Dec 2025 09:49:37 +0100 Subject: [PATCH 1862/1962] Update documentation for designer --- .../userdocs/extending/designer_reference.md | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/docs/pages/pmd/userdocs/extending/designer_reference.md b/docs/pages/pmd/userdocs/extending/designer_reference.md index 7cf0a07662c..0a89e84f04e 100644 --- a/docs/pages/pmd/userdocs/extending/designer_reference.md +++ b/docs/pages/pmd/userdocs/extending/designer_reference.md @@ -3,7 +3,7 @@ title: The rule designer short_title: Rule designer tags: [extending, userdocs] summary: "Learn about the usage and features of the rule designer." -last_updated: March 2024 (7.0.0) +last_updated: December 2025 (7.20.0) permalink: pmd_userdocs_extending_designer_reference.html author: Clรฉment Fournier --- @@ -13,32 +13,36 @@ author: Clรฉment Fournier The designer is part of PMD's binary distributions. To **install a distribution**, see the [documentation page about installing PMD](pmd_userdocs_installation.html). -The designer still works with Java 8 from Oracle, which includes JavaFX. If you use this Java version, then -all is set. However, it is recommended to use OpenJDK along with OpenJFX. The recommended Java Runtime is +The designer still works with Java 8 from Oracle, which includes JavaFX up until Java 8u441. It also works +with Java 8+ from Azul (Zulu JDK FX) or Bellsoft (Liberica Full JDK) which also include JavaFX. +Note: The latest Java 8 from Oracle does _not_ include JavaFX anymore, see . + +If you use a Java version, which includes JavaFX, then all is set. + +However, it is recommended to use OpenJDK along with OpenJFX. The recommended Java Runtime is Java 11 (or later) with OpenJFX 17 (or later). You can get OpenJDK from [Adoptium](https://adoptium.net), [Azul](https://www.azul.com/downloads/#zulu), +[Bellsoft](https://bell-sw.com/pages/downloads/), [Microsoft](https://learn.microsoft.com/en-us/java/openjdk/download), [SAP](https://sap.github.io/SapMachine/), [Amazon](https://downloads.corretto.aws/#/overview) and other OpenJDK vendors. -Note: Azul provides a JDK which includes JavaFX - this variant is currently not supported. You always need -to install OpenJFX separately. [OpenJFX](https://openjfx.io/) is available from [JavaFX download page](https://gluonhq.com/products/javafx/). You need the SDK. Extract the zip file, and set the `JAVAFX_HOME` environment variable to the extracted -directory. It should be the directory, that contain the sub-folder "lib" in it. +directory. It should be the directory, that contains the sub-folder "lib" in it. Example (for linux x64 only, with Java 21 and OpenJFX 21): ```shell $ mkdir $HOME/openjdk $ cd $HOME/openjdk -$ wget https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.2%2B13/OpenJDK21U-jdk_x64_linux_hotspot_21.0.2_13.tar.gz -$ tar xfz OpenJDK21U-jdk_x64_linux_hotspot_21.0.2_13.tar.gz -$ export JAVA_HOME=$HOME/openjdk/jdk-21.0.2+13 +$ wget https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.9%2B10/OpenJDK21U-jdk_x64_linux_hotspot_21.0.9_10.tar.gz +$ tar xfz OpenJDK21U-jdk_x64_linux_hotspot_21.0.9_10.tar.gz +$ export JAVA_HOME=$HOME/openjdk/jdk-21.0.9+10 $ export PATH=$JAVA_HOME/bin:$PATH -$ wget https://download2.gluonhq.com/openjfx/21.0.2/openjfx-21.0.2_linux-x64_bin-sdk.zip -$ unzip -q openjfx-21.0.2_linux-x64_bin-sdk.zip -$ export JAVAFX_HOME=$HOME/openjdk/javafx-sdk-21.0.2 +$ wget https://download2.gluonhq.com/openjfx/21.0.9/openjfx-21.0.9_linux-x64_bin-sdk.zip +$ unzip -q openjfx-21.0.9_linux-x64_bin-sdk.zip +$ export JAVAFX_HOME=$HOME/openjdk/javafx-sdk-21.0.9 ``` If the bin directory of your PMD distribution is on your shell's path, then you can then **launch the app** with From 493b73884e9fd41ff8c7f29caff42ea32ab0b5af Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 5 Dec 2025 10:07:38 +0100 Subject: [PATCH 1863/1962] Put openjfx on the module path instead of classpath. This avoids warnings like: WARNING: Unsupported JavaFX configuration: classes were loaded from 'unnamed module @222fb444' Note: OpenJFX's lib directory is still on the classpath --- pmd-dist/src/main/resources/scripts/pmd | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/pmd-dist/src/main/resources/scripts/pmd b/pmd-dist/src/main/resources/scripts/pmd index 7626e5fe997..c3fedcc0211 100755 --- a/pmd-dist/src/main/resources/scripts/pmd +++ b/pmd-dist/src/main/resources/scripts/pmd @@ -142,7 +142,7 @@ determine_java_version() { jre_specific_vm_options() { options="" - if [ "$APPNAME" = "designer" ] && [ "$java_version_feature" -ge 9 ] && [ $java_has_javafx = 1 ] + if [ "$APPNAME" = "designer" ] && [ "$java_version_feature" -ge 9 ] then # Since Java 9, Java uses the module system. If JavaFX is bundled, this is also # included as modules. PMD however is run on the classpath and will run as the @@ -198,6 +198,7 @@ add_pmd_classpath() { } add_openjfx_classpath() { + openjfx_module_path="" if [ "$APPNAME" = "designer" ] then if [ $java_has_javafx = 1 ] @@ -236,9 +237,10 @@ add_openjfx_classpath() { for instructions. " else - # The wildcard will include only jar files, but we need to access also - # property files such as javafx.properties that lay bare in the dir - append_classpath "$JAVAFX_HOME/lib/*:$JAVAFX_HOME/lib/" + openjfx_module_path="--module-path $JAVAFX_HOME/lib --add-modules javafx.controls,javafx.fxml" + # still add the path where javafx.properties is located to the classpath, so that Designer's + # net.sourceforge.pmd.util.fxdesigner.util.JavaFxUtil#getJavaFxVersion can find it. + append_classpath "$JAVAFX_HOME/lib" fi fi fi @@ -268,11 +270,12 @@ cygwin_paths java_heapsize_settings -# Note: we want word-splitting happening on PMD_JAVA_OPTS and jre_specific_vm_options, -# so we explicitly don't use quotes. +# Note: we want word-splitting happening on PMD_JAVA_OPTS, jre_specific_vm_options +# and openjfx_module_path. That's why we explicitly don't use quotes. # shellcheck disable=SC2046,SC2086 exec java \ ${HEAPSIZE:+"$HEAPSIZE"} \ $PMD_JAVA_OPTS $(jre_specific_vm_options) \ + $openjfx_module_path \ -cp "$classpath" \ net.sourceforge.pmd.cli.PmdCli "$@" From 29656457a1e2cf88c7b2c4f3e1dc48cc691910cb Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 5 Dec 2025 11:10:16 +0100 Subject: [PATCH 1864/1962] Remove HEAPSIZE option Was already deprecated with 6.13.0 and supposed to be removed with PMD 7. --- pmd-dist/src/main/resources/scripts/pmd | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/pmd-dist/src/main/resources/scripts/pmd b/pmd-dist/src/main/resources/scripts/pmd index c3fedcc0211..6ce2648a1a5 100755 --- a/pmd-dist/src/main/resources/scripts/pmd +++ b/pmd-dist/src/main/resources/scripts/pmd @@ -33,19 +33,6 @@ convert_cygwin_vars() { fi } -java_heapsize_settings() { - case "$HEAPSIZE" in - [1-9]*[mgMG]) - HEAPSIZE="-Xmx$HEAPSIZE" - ;; - '') - ;; - *) - echo "HEAPSIZE '$HEAPSIZE' unknown (try: 1024m)" - exit 1 - esac -} - set_pmd_home_dir() { script_real_loc="$0" @@ -274,7 +261,6 @@ java_heapsize_settings # and openjfx_module_path. That's why we explicitly don't use quotes. # shellcheck disable=SC2046,SC2086 exec java \ - ${HEAPSIZE:+"$HEAPSIZE"} \ $PMD_JAVA_OPTS $(jre_specific_vm_options) \ $openjfx_module_path \ -cp "$classpath" \ From 346739ce8e8bea6bd490d220f7b991f894acac91 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 5 Dec 2025 11:11:29 +0100 Subject: [PATCH 1865/1962] Refactor jre_specific_vm_options, add PMD_ADDITIONAL_JAVA_OPTS --- pmd-dist/src/main/resources/scripts/pmd | 44 +++++++++---------- .../src/test/resources/scripts/runtest.sh | 4 +- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/pmd-dist/src/main/resources/scripts/pmd b/pmd-dist/src/main/resources/scripts/pmd index 6ce2648a1a5..ba03dead4bd 100755 --- a/pmd-dist/src/main/resources/scripts/pmd +++ b/pmd-dist/src/main/resources/scripts/pmd @@ -127,8 +127,8 @@ determine_java_version() { fi } -jre_specific_vm_options() { - options="" +determine_additional_java_opts() { + PMD_ADDITIONAL_JAVA_OPTS="" if [ "$APPNAME" = "designer" ] && [ "$java_version_feature" -ge 9 ] then # Since Java 9, Java uses the module system. If JavaFX is bundled, this is also @@ -146,30 +146,29 @@ jre_specific_vm_options() { # # Reflective access used by PMD Designer # in net.sourceforge.pmd.util.fxdesigner.util.controls.TreeViewWrapper.getVirtualFlow - options="$options --add-opens javafx.controls/javafx.scene.control.skin=ALL-UNNAMED" + PMD_ADDITIONAL_JAVA_OPTS="$PMD_ADDITIONAL_JAVA_OPTS --add-opens javafx.controls/javafx.scene.control.skin=ALL-UNNAMED" # in net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil.customBuilderFactory - options="$options --add-opens javafx.fxml/com.sun.javafx.fxml.builder=ALL-UNNAMED" + PMD_ADDITIONAL_JAVA_OPTS="$PMD_ADDITIONAL_JAVA_OPTS --add-opens javafx.fxml/com.sun.javafx.fxml.builder=ALL-UNNAMED" # # Reflective access used by RichtextFX - options="$options --add-opens javafx.graphics/javafx.scene.text=ALL-UNNAMED" - options="$options --add-opens javafx.graphics/com.sun.javafx.scene.text=ALL-UNNAMED" - options="$options --add-opens javafx.graphics/com.sun.javafx.text=ALL-UNNAMED" - options="$options --add-opens javafx.graphics/com.sun.javafx.geom=ALL-UNNAMED" + PMD_ADDITIONAL_JAVA_OPTS="$PMD_ADDITIONAL_JAVA_OPTS --add-opens javafx.graphics/javafx.scene.text=ALL-UNNAMED" + PMD_ADDITIONAL_JAVA_OPTS="$PMD_ADDITIONAL_JAVA_OPTS --add-opens javafx.graphics/com.sun.javafx.scene.text=ALL-UNNAMED" + PMD_ADDITIONAL_JAVA_OPTS="$PMD_ADDITIONAL_JAVA_OPTS --add-opens javafx.graphics/com.sun.javafx.text=ALL-UNNAMED" + PMD_ADDITIONAL_JAVA_OPTS="$PMD_ADDITIONAL_JAVA_OPTS --add-opens javafx.graphics/com.sun.javafx.geom=ALL-UNNAMED" # # Reflective access used by controlsfx - options="$options --add-opens javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED" - options="$options --add-opens javafx.base/com.sun.javafx.runtime=ALL-UNNAMED" - options="$options --add-opens javafx.base/com.sun.javafx.event=ALL-UNNAMED" - options="$options --add-opens javafx.graphics/com.sun.javafx.scene.traversal=ALL-UNNAMED" + PMD_ADDITIONAL_JAVA_OPTS="$PMD_ADDITIONAL_JAVA_OPTS --add-opens javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED" + PMD_ADDITIONAL_JAVA_OPTS="$PMD_ADDITIONAL_JAVA_OPTS --add-opens javafx.base/com.sun.javafx.runtime=ALL-UNNAMED" + PMD_ADDITIONAL_JAVA_OPTS="$PMD_ADDITIONAL_JAVA_OPTS --add-opens javafx.base/com.sun.javafx.event=ALL-UNNAMED" + PMD_ADDITIONAL_JAVA_OPTS="$PMD_ADDITIONAL_JAVA_OPTS --add-opens javafx.graphics/com.sun.javafx.scene.traversal=ALL-UNNAMED" fi if [ "$java_version_feature" -ge 9 ] && [ "$java_version_feature" -le 16 ] then # Warn of illegal accesses in general - only possible for Java 9 until Java 16 (inclusive). # With Java 17+ this option has no effect anymore (https://openjdk.org/jeps/403) and is deprecated. - options="$options --illegal-access=warn" + PMD_ADDITIONAL_JAVA_OPTS="$PMD_ADDITIONAL_JAVA_OPTS --illegal-access=warn" fi - echo "$options" } append_classpath() { @@ -223,12 +222,12 @@ add_openjfx_classpath() { See https://docs.pmd-code.org/latest/pmd_userdocs_extending_designer_reference.html#installing-running-updating for instructions. " - else - openjfx_module_path="--module-path $JAVAFX_HOME/lib --add-modules javafx.controls,javafx.fxml" - # still add the path where javafx.properties is located to the classpath, so that Designer's - # net.sourceforge.pmd.util.fxdesigner.util.JavaFxUtil#getJavaFxVersion can find it. - append_classpath "$JAVAFX_HOME/lib" fi + + openjfx_module_path="--module-path $JAVAFX_HOME/lib --add-modules javafx.controls,javafx.fxml" + # still add the path where javafx.properties is located to the classpath, so that Designer's + # net.sourceforge.pmd.util.fxdesigner.util.JavaFxUtil#getJavaFxVersion can find it. + append_classpath "$JAVAFX_HOME/lib" fi fi } @@ -252,16 +251,15 @@ classpath=$CLASSPATH add_pmd_classpath determine_java_version add_openjfx_classpath +determine_additional_java_opts cygwin_paths -java_heapsize_settings - -# Note: we want word-splitting happening on PMD_JAVA_OPTS, jre_specific_vm_options +# Note: we want word-splitting happening on PMD_JAVA_OPTS, PMD_ADDITIONAL_JAVA_OPTS # and openjfx_module_path. That's why we explicitly don't use quotes. # shellcheck disable=SC2046,SC2086 exec java \ - $PMD_JAVA_OPTS $(jre_specific_vm_options) \ + $PMD_JAVA_OPTS $PMD_ADDITIONAL_JAVA_OPTS \ $openjfx_module_path \ -cp "$classpath" \ net.sourceforge.pmd.cli.PmdCli "$@" diff --git a/pmd-dist/src/test/resources/scripts/runtest.sh b/pmd-dist/src/test/resources/scripts/runtest.sh index 927b702aa4f..0cfeaa26dff 100755 --- a/pmd-dist/src/test/resources/scripts/runtest.sh +++ b/pmd-dist/src/test/resources/scripts/runtest.sh @@ -37,9 +37,9 @@ determine_java_version() { }') # 1. component: java_version_feature is e.g. "8" for java 1.8, "9" for java 9, "10" for java 10, ... java_version_feature=$(echo "$java_ver_normalized" | sed -n -e 's/^\([0-9]\{1,\}\).*$/\1/p') - # 3. component: update release counter + # 3. component: update release counter is e.g. "17" for java 11.0.17 java_version_update=$(echo "$java_ver_normalized" | sed -n -e 's/^\([0-9]\{1,\}\)\.\([0-9]\{1,\}\).\([0-9]\{1,\}\).*$/\3/p') - # if there was no 3rd component, use "0" + # if there was no 3rd component (eg. -ea or ga version), use "0" java_version_update=${java_version_update:="0"} java_home_property=$(echo "$all_props" | grep "java.home" | sed -n -e 's/^.*java\.home *= *\(.*\)$/\1/; p') From e985b31d9259198f08415cca2071bbe7a13f89c3 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 5 Dec 2025 11:13:37 +0100 Subject: [PATCH 1866/1962] Rename openjfx_module_path to PMD_OPENJFX_MODULE_PATH --- pmd-dist/src/main/resources/scripts/pmd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pmd-dist/src/main/resources/scripts/pmd b/pmd-dist/src/main/resources/scripts/pmd index ba03dead4bd..f8ad5ae915b 100755 --- a/pmd-dist/src/main/resources/scripts/pmd +++ b/pmd-dist/src/main/resources/scripts/pmd @@ -184,7 +184,7 @@ add_pmd_classpath() { } add_openjfx_classpath() { - openjfx_module_path="" + PMD_OPENJFX_MODULE_PATH="" if [ "$APPNAME" = "designer" ] then if [ $java_has_javafx = 1 ] @@ -224,7 +224,7 @@ add_openjfx_classpath() { " fi - openjfx_module_path="--module-path $JAVAFX_HOME/lib --add-modules javafx.controls,javafx.fxml" + PMD_OPENJFX_MODULE_PATH="--module-path $JAVAFX_HOME/lib --add-modules javafx.controls,javafx.fxml" # still add the path where javafx.properties is located to the classpath, so that Designer's # net.sourceforge.pmd.util.fxdesigner.util.JavaFxUtil#getJavaFxVersion can find it. append_classpath "$JAVAFX_HOME/lib" @@ -256,10 +256,10 @@ determine_additional_java_opts cygwin_paths # Note: we want word-splitting happening on PMD_JAVA_OPTS, PMD_ADDITIONAL_JAVA_OPTS -# and openjfx_module_path. That's why we explicitly don't use quotes. +# and PMD_OPENJFX_MODULE_PATH. That's why we explicitly don't use quotes. # shellcheck disable=SC2046,SC2086 exec java \ $PMD_JAVA_OPTS $PMD_ADDITIONAL_JAVA_OPTS \ - $openjfx_module_path \ + $PMD_OPENJFX_MODULE_PATH \ -cp "$classpath" \ net.sourceforge.pmd.cli.PmdCli "$@" From 83db6c690266576c22bc013a00dc8d735d49505e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 5 Dec 2025 11:21:22 +0100 Subject: [PATCH 1867/1962] Rename classpath to CLASSPATH --- pmd-dist/src/main/resources/scripts/pmd | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/pmd-dist/src/main/resources/scripts/pmd b/pmd-dist/src/main/resources/scripts/pmd index f8ad5ae915b..2dd69a50e4b 100755 --- a/pmd-dist/src/main/resources/scripts/pmd +++ b/pmd-dist/src/main/resources/scripts/pmd @@ -19,8 +19,7 @@ cygwin_paths() { if [ "$cygwin" = true ] ; then [ -n "$JAVA_HOME" ] && JAVA_HOME=$(cygpath --windows "$JAVA_HOME") [ -n "$JAVAFX_HOME" ] && JAVAFX_HOME=$(cygpath --windows "$JAVAFX_HOME") - [ -n "$DIRECTORY" ] && DIRECTORY=$(cygpath --windows "$DIRECTORY") - classpath=$(cygpath --path --windows "$classpath") + [ -n "$CLASSPATH" ] && CLASSPATH=$(cypath --windows "$CLASSPATH") fi } @@ -172,10 +171,10 @@ determine_additional_java_opts() { } append_classpath() { - if [ -n "$classpath" ]; then - classpath="$classpath:$1" + if [ -n "$CLASSPATH" ]; then + CLASSPATH="$CLASSPATH:$1" else - classpath="$1" + CLASSPATH="$1" fi } @@ -246,8 +245,6 @@ check_conf_dir convert_cygwin_vars -classpath=$CLASSPATH - add_pmd_classpath determine_java_version add_openjfx_classpath @@ -261,5 +258,5 @@ cygwin_paths exec java \ $PMD_JAVA_OPTS $PMD_ADDITIONAL_JAVA_OPTS \ $PMD_OPENJFX_MODULE_PATH \ - -cp "$classpath" \ + -cp "$CLASSPATH" \ net.sourceforge.pmd.cli.PmdCli "$@" From 8894373079594904568508b8f92342cbc709264f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 5 Dec 2025 11:54:24 +0100 Subject: [PATCH 1868/1962] Use exit code 2 for invalid script invocations --- pmd-dist/src/main/resources/scripts/pmd | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pmd-dist/src/main/resources/scripts/pmd b/pmd-dist/src/main/resources/scripts/pmd index 2dd69a50e4b..3648c771d10 100755 --- a/pmd-dist/src/main/resources/scripts/pmd +++ b/pmd-dist/src/main/resources/scripts/pmd @@ -66,7 +66,7 @@ set_lib_dir() { check_lib_dir() { if [ ! -e "$LIB_DIR" ]; then - echo "The jar directory [$LIB_DIR] does not exist" + script_exit "The jar directory [$LIB_DIR] does not exist" fi } @@ -78,13 +78,13 @@ set_conf_dir() { check_conf_dir() { if [ ! -e "$CONF_DIR" ]; then - echo "The configuration directory [$CONF_DIR] does not exist" + script_exit "The configuration directory [$CONF_DIR] does not exist" fi } script_exit() { echo "$1" >&2 - exit 1 + exit 2 } check_java() { From 418c6d80ba007c5f52c235ebe5a8c140462dfa4e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 5 Dec 2025 12:07:22 +0100 Subject: [PATCH 1869/1962] Refactor windows pmd start script Use subroutines, similar names like in the unix script. --- pmd-dist/src/main/resources/scripts/pmd.bat | 235 ++++++++++++------ .../src/test/resources/scripts/pmdtest.bat | 6 +- 2 files changed, 164 insertions(+), 77 deletions(-) diff --git a/pmd-dist/src/main/resources/scripts/pmd.bat b/pmd-dist/src/main/resources/scripts/pmd.bat index 81cb9049633..f52c8eb6c4a 100644 --- a/pmd-dist/src/main/resources/scripts/pmd.bat +++ b/pmd-dist/src/main/resources/scripts/pmd.bat @@ -1,22 +1,89 @@ @echo off +rem main script +rem make all variables local to not add new global environment variables to the current cmd session +SETLOCAL +rem Use delayed expansion, required e.g. within IF blocks SETLOCAL EnableDelayedExpansion rem use unicode codepage to properly support UTF-8 chcp 65001>nul -rem make all variables local to not add new global environment variables to the current cmd session -setlocal -set "TOPDIR=%~dp0.." -set "OPTS=" -set "COMMAND=%1" -set "MAIN_CLASS=net.sourceforge.pmd.cli.PmdCli" +SET "APPNAME=%1" +CALL :check_java +IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + +CALL :set_pmd_home_dir +CALL :set_lib_dir +CALL :check_lib_dir +IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% +CALL :set_conf_dir +CALL :check_conf_dir +IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + +CALL :add_pmd_classpath +CALL :determine_java_version +CALL :add_openjfx_classpath +IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% +CALL :determine_additional_java_opts + +java ^ + %PMD_JAVA_OPTS% %PMD_ADDITIONAL_JAVA_OPTS% ^ + %PMD_OPENJFX_MODULE_PATH% ^ + -cp "%CLASSPATH%" ^ + net.sourceforge.pmd.cli.PmdCli %* +ENDLOCAL +EXIT /B %ERRORLEVEL% + + + +:check_java rem check whether java is available at all java -version > nul 2>&1 || ( - echo No java executable found in PATH - exit /b 1 + echo No java executable found in PATH + EXIT /B 2 +) +EXIT /B + +:set_pmd_home_dir +SET "PMD_HOME=%~dp0.." +EXIT /B + +:set_lib_dir +SET "LIB_DIR=%PMD_HOME%/lib" +EXIT /B + +:check_lib_dir +IF NOT EXIST "%LIB_DIR%" ( + echo The jar directory [%LIB_DIR%] does not exist + EXIT /B 2 +) +EXIT /B + +:set_conf_dir +SET "CONF_DIR=%PMD_HOME%/conf" +EXIT /B + +:check_conf_dir +IF NOT EXIST "%CONF_DIR%" ( + echo The configuration directory [%CONF_DIR%] does not exist + EXIT /B 2 +) +EXIT /B + +:append_classpath +IF DEFINED CLASSPATH ( + SET "CLASSPATH=%CLASSPATH%;%~1" +) ELSE ( + SET "CLASSPATH=%~1" ) +EXIT /B + +:add_pmd_classpath +CALL :append_classpath "%CONF_DIR%;%LIB_DIR%/*" +EXIT /B +:determine_java_version rem sets the java_version_feature variable. This is e.g. "8" for java 1.8, "9" for java 9, "10" for java 10, ... rem sets the java_version_update variable. This is the update release counter: e.g. "17" for java 11.0.17 @@ -56,78 +123,96 @@ rem resolve dirname IF %java_has_javafx% EQU 1 FOR %%F IN (%java_javafx_properties%) DO set "java_javafx_properties_path=%%~dpF" rem remove trailing backslash IF %java_has_javafx% EQU 1 set "java_javafx_properties_path=%java_javafx_properties_path:~0,-1%" +EXIT /B -Set "jreopts=" -IF [%COMMAND%] == [designer] ( - IF %java_version_feature% GEQ 9 ( - IF %java_has_javafx% EQU 1 ( - rem java9 and java10 from oracle contain javafx as a module - rem Azul provides builds which include javafx as well - rem Since Java 9, it is included as a module. But we run on the classpath (aka unnamed module) and - rem want to access the classes. - rem - rem for PMD Designer - rem in net.sourceforge.pmd.util.fxdesigner.util.controls.TreeViewWrapper.getVirtualFlow - set "jreopts=--add-opens javafx.controls/javafx.scene.control.skin=ALL-UNNAMED" - rem in net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil.customBuilderFactory - set "jreopts=!jreopts! --add-opens javafx.fxml/com.sun.javafx.fxml.builder=ALL-UNNAMED" - rem - rem for RichtextFX - set "jreopts=!jreopts! --add-opens javafx.graphics/javafx.scene.text=ALL-UNNAMED" - set "jreopts=!jreopts! --add-opens javafx.graphics/com.sun.javafx.scene.text=ALL-UNNAMED" - set "jreopts=!jreopts! --add-opens javafx.graphics/com.sun.javafx.text=ALL-UNNAMED" - set "jreopts=!jreopts! --add-opens javafx.graphics/com.sun.javafx.geom=ALL-UNNAMED" - rem - rem for controlsfx - set "jreopts=!jreopts! --add-opens javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED" - set "jreopts=!jreopts! --add-opens javafx.base/com.sun.javafx.runtime=ALL-UNNAMED" - set "jreopts=!jreopts! --add-opens javafx.base/com.sun.javafx.event=ALL-UNNAMED" - set "jreopts=!jreopts! --add-opens javafx.graphics/com.sun.javafx.scene.traversal=ALL-UNNAMED" - - IF %java_version_feature% LSS 17 ( - rem Warn of remaining illegal accesses - only possible until java 16. - rem With Java 17+ this option has no effect anymore (https://openjdk.org/jeps/403). - set "jreopts=!jreopts! --illegal-access=warn" - ) - ) +:add_openjfx_classpath +SET "PMD_OPENJFX_MODULE_PATH=" +IF [%APPNAME%] == [designer] ( + IF %java_has_javafx% EQU 1 ( + rem almost nothing to do, javafx is bundled (either an old Oracle Java < 8u451 or an OpenJDK 8 Build from Azul) + rem still add the path where javafx.properties is located to the classpath, so that Designer's + rem net.sourceforge.pmd.util.fxdesigner.util.JavaFxUtil#getJavaFxVersion can find it. + CALL :append_classpath "%java_javafx_properties_path%" + ) ELSE ( + + IF %java_version_feature% EQU 8 ( + IF %java_version_update% GEQ 451 ( + echo. + echo JavaFX has been removed from Oracle Java 8 since Java 8u451. + echo See https://www.oracle.com/javase/javafx. + echo Use Java 11 or later with OpenJFX separately from https://openjfx.io/. + echo Alternatively use an OpenJDK build from Azul with JavaFX bundled ^(JDK FX^) + echo or from Bellsoft with JavaFX bundled ^(Full JDK^). + EXIT /B 2 + ) ) -) -IF [%COMMAND%] == [designer] ( - IF %java_has_javafx% EQU 1 ( - rem almost nothing to do, javafx is bundled (either an old Oracle Java < 8u451 or an OpenJDK 8 Build from Azul) - rem still add the path where javafx.properties is located to the classpath, so that Designer's - rem net.sourceforge.pmd.util.fxdesigner.util.JavaFxUtil#getJavaFxVersion can find it. - set "pmd_classpath=%TOPDIR%\conf;%TOPDIR%\lib\*;%java_javafx_properties_path%" - ) ELSE ( - IF %java_version_feature% EQU 8 ( - IF %java_version_update% GEQ 451 ( - echo JavaFX has been removed from Oracle Java 8 since Java 8u451. See https://www.oracle.com/javase/javafx. - echo Use Java 11 or later with OpenJFX separately from https://openjfx.io/. - echo Alternatively use an OpenJDK build from Azul with JavaFX bundled ^(JDK FX^). - EXIT /B 1 - ) - ) - IF %java_version_feature% LSS 10 ( - echo For OpenJFX at least Java 10 is required. - EXIT /B 1 - ) - IF not defined JAVAFX_HOME ( - echo The environment variable JAVAFX_HOME is missing. - EXIT /B 1 - ) - rem The wildcard will include only jar files, but we need to access also - rem property files such as javafx.properties that lay bare in the dir - rem note: no trailing backslash, as this would escape a following quote when %pmd_classpath% is used later - set "pmd_classpath=%TOPDIR%\conf;%TOPDIR%\lib\*;%JAVAFX_HOME%\lib\*;%JAVAFX_HOME%\lib" + IF %java_version_feature% LSS 10 ( + echo. + echo For OpenJFX at least Java 10 is required. Newer OpenJFX version + echo might require newer Java versions. + EXIT /B 2 ) -) else ( - rem note: no trailing backslash, as this would escape a following quote when %pmd_classpath% is used later - set "pmd_classpath=%TOPDIR%\conf;%TOPDIR%\lib\*" + + rem openjfx is required for any openjdk builds which don't include JavaFX + IF NOT DEFINED JAVAFX_HOME ( + echo The environment variable JAVAFX_HOME is missing. + echo See https://docs.pmd-code.org/latest/pmd_userdocs_extending_designer_reference.html#installing-running-updating + echo for instructions. + EXIT /B 2 + ) + + SET "PMD_OPENJFX_MODULE_PATH=--module-path %JAVAFX_HOME%/lib --add-modules javafx.controls,javafx.fxml" + rem still add the path where javafx.properties is located to the classpath, so that Designer's + rem net.sourceforge.pmd.util.fxdesigner.util.JavaFxUtil#getJavaFxVersion can find it. + rem note: no trailing backslash, as this would escape a following quote when %CLASSPATH% is used later + CALL :append_classpath "%JAVAFX_HOME%/lib" + ) ) +EXIT /B -if defined CLASSPATH ( - set "pmd_classpath=%CLASSPATH%;%pmd_classpath%" +:determine_additional_java_opts +SET "PMD_ADDITIONAL_JAVA_OPTS=" +IF [%APPNAME%] == [designer] ( + IF %java_version_feature% GEQ 9 ( + rem Since Java 9, Java uses the module system. If JavaFX is bundled, this is also + rem included as modules. PMD however is run on the classpath and will run as the + rem "unnamed module". To allow reflection to some JavaFX classes, we need to allow + rem this access explicitly by opening specific javafx packages. + rem + rem This applies to Java 9/10 builds from Oracle and to Java 9+ builds from + rem Azul (Zulu) or Bellsoft (Liberica). + rem + rem It does not apply, if we run Java 8+ without bundled JavaFX and we + rem put JavaFX on the classpath. Then we don't use the module system at all + rem and all classes on the classpath are allowed to access all other classes + rem on the classpath by reflection without explicitly opening packages. + rem + rem Reflective access used by PMD Designer + rem in net.sourceforge.pmd.util.fxdesigner.util.controls.TreeViewWrapper.getVirtualFlow + SET "PMD_ADDITIONAL_JAVA_OPTS=!PMD_ADDITIONAL_JAVA_OPTS! --add-opens javafx.controls/javafx.scene.control.skin=ALL-UNNAMED" + rem in net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil.customBuilderFactory + SET "PMD_ADDITIONAL_JAVA_OPTS=!PMD_ADDITIONAL_JAVA_OPTS! --add-opens javafx.fxml/com.sun.javafx.fxml.builder=ALL-UNNAMED" + rem + rem Reflective access used by RichtextFX + SET "PMD_ADDITIONAL_JAVA_OPTS=!PMD_ADDITIONAL_JAVA_OPTS! --add-opens javafx.graphics/javafx.scene.text=ALL-UNNAMED" + SET "PMD_ADDITIONAL_JAVA_OPTS=!PMD_ADDITIONAL_JAVA_OPTS! --add-opens javafx.graphics/com.sun.javafx.scene.text=ALL-UNNAMED" + SET "PMD_ADDITIONAL_JAVA_OPTS=!PMD_ADDITIONAL_JAVA_OPTS! --add-opens javafx.graphics/com.sun.javafx.text=ALL-UNNAMED" + SET "PMD_ADDITIONAL_JAVA_OPTS=!PMD_ADDITIONAL_JAVA_OPTS! --add-opens javafx.graphics/com.sun.javafx.geom=ALL-UNNAMED" + rem + rem Reflective access used by controlsfx + SET "PMD_ADDITIONAL_JAVA_OPTS=!PMD_ADDITIONAL_JAVA_OPTS! --add-opens javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED" + SET "PMD_ADDITIONAL_JAVA_OPTS=!PMD_ADDITIONAL_JAVA_OPTS! --add-opens javafx.base/com.sun.javafx.runtime=ALL-UNNAMED" + SET "PMD_ADDITIONAL_JAVA_OPTS=!PMD_ADDITIONAL_JAVA_OPTS! --add-opens javafx.base/com.sun.javafx.event=ALL-UNNAMED" + SET "PMD_ADDITIONAL_JAVA_OPTS=!PMD_ADDITIONAL_JAVA_OPTS! --add-opens javafx.graphics/com.sun.javafx.scene.traversal=ALL-UNNAMED" + ) ) -java %PMD_JAVA_OPTS% %jreopts% -classpath "%pmd_classpath%" %OPTS% %MAIN_CLASS% %* +IF %java_version_feature% GEQ 9 ( + IF %java_version_feature% LEQ 16 ( + rem Warn of illegal accesses in general - only possible for Java 9 until Java 16 (inclusive). + rem With Java 17+ this option has no effect anymore (https://openjdk.org/jeps/403) and is deprecated. + SET "PMD_ADDITIONAL_JAVA_OPTS=!PMD_ADDITIONAL_JAVA_OPTS! --illegal-access=warn" + ) +) +EXIT /B diff --git a/pmd-dist/src/test/resources/scripts/pmdtest.bat b/pmd-dist/src/test/resources/scripts/pmdtest.bat index 5dcd4dff4af..bcf8df1ab5a 100644 --- a/pmd-dist/src/test/resources/scripts/pmdtest.bat +++ b/pmd-dist/src/test/resources/scripts/pmdtest.bat @@ -144,8 +144,10 @@ IF "%EXPECTED_HAS_JAVAFX%" == "no" ( ) ) IF %_temp_javafx_passed% EQU 0 ( CALL :fail ) -rem echo javafx_properties: %java_javafx_properties% -rem echo javafx_properties_path: %java_javafx_properties_path% +IF %java_has_javafx% EQU 1 ( + echo.|set /p =java_javafx_properties_path: + IF NOT "%java_javafx_properties_path%" == "" ( CALL :pass ) ELSE ( CALL :fail ) +) echo. EXIT /B From a8a82da8eac907049dabc77d0004aa5761095702 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 5 Dec 2025 12:07:37 +0100 Subject: [PATCH 1870/1962] Fix cygpath --- pmd-dist/src/main/resources/scripts/pmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-dist/src/main/resources/scripts/pmd b/pmd-dist/src/main/resources/scripts/pmd index 3648c771d10..3d12dddeccc 100755 --- a/pmd-dist/src/main/resources/scripts/pmd +++ b/pmd-dist/src/main/resources/scripts/pmd @@ -19,7 +19,7 @@ cygwin_paths() { if [ "$cygwin" = true ] ; then [ -n "$JAVA_HOME" ] && JAVA_HOME=$(cygpath --windows "$JAVA_HOME") [ -n "$JAVAFX_HOME" ] && JAVAFX_HOME=$(cygpath --windows "$JAVAFX_HOME") - [ -n "$CLASSPATH" ] && CLASSPATH=$(cypath --windows "$CLASSPATH") + [ -n "$CLASSPATH" ] && CLASSPATH=$(cygpath --path --windows "$CLASSPATH") fi } From 7d04f8b1df9d69fe9d2188bd24d47c3ef3857aad Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 5 Dec 2025 12:25:39 +0100 Subject: [PATCH 1871/1962] Remove JAVA_HOME --- pmd-dist/src/main/resources/scripts/pmd | 2 -- 1 file changed, 2 deletions(-) diff --git a/pmd-dist/src/main/resources/scripts/pmd b/pmd-dist/src/main/resources/scripts/pmd index 3d12dddeccc..b175651a383 100755 --- a/pmd-dist/src/main/resources/scripts/pmd +++ b/pmd-dist/src/main/resources/scripts/pmd @@ -17,7 +17,6 @@ is_cygwin() { cygwin_paths() { # For Cygwin, switch paths to Windows format before running java if [ "$cygwin" = true ] ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=$(cygpath --windows "$JAVA_HOME") [ -n "$JAVAFX_HOME" ] && JAVAFX_HOME=$(cygpath --windows "$JAVAFX_HOME") [ -n "$CLASSPATH" ] && CLASSPATH=$(cygpath --path --windows "$CLASSPATH") fi @@ -26,7 +25,6 @@ cygwin_paths() { convert_cygwin_vars() { # If cygwin, convert to Unix form before manipulating if [ "$cygwin" = true ] ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=$(cygpath --unix "$JAVA_HOME") [ -n "$JAVAFX_HOME" ] && JAVAFX_HOME=$(cygpath --unix "$JAVAFX_HOME") [ -n "$CLASSPATH" ] && CLASSPATH=$(cygpath --path --unix "$CLASSPATH") fi From f76ffbf6fa4f94ad48c6631603ce43fe243b5be0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 5 Dec 2025 12:33:12 +0100 Subject: [PATCH 1872/1962] Fix script for cygwin --- pmd-dist/src/main/resources/scripts/pmd | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pmd-dist/src/main/resources/scripts/pmd b/pmd-dist/src/main/resources/scripts/pmd index b175651a383..6159ead0205 100755 --- a/pmd-dist/src/main/resources/scripts/pmd +++ b/pmd-dist/src/main/resources/scripts/pmd @@ -19,6 +19,7 @@ cygwin_paths() { if [ "$cygwin" = true ] ; then [ -n "$JAVAFX_HOME" ] && JAVAFX_HOME=$(cygpath --windows "$JAVAFX_HOME") [ -n "$CLASSPATH" ] && CLASSPATH=$(cygpath --path --windows "$CLASSPATH") + [ -n "$PMD_OPENJFX_MODULE_PATH" ] && PMD_OPENJFX_MODULE_PATH=$(cygpath --path --windows "$PMD_OPENJFX_MODULE_PATH") fi } @@ -177,7 +178,7 @@ append_classpath() { } add_pmd_classpath() { - append_classpath "$CONF_DIR:$LIB_DIR/*" + append_classpath "$CONF_DIR:$LIB_DIR/*" } add_openjfx_classpath() { @@ -221,7 +222,7 @@ add_openjfx_classpath() { " fi - PMD_OPENJFX_MODULE_PATH="--module-path $JAVAFX_HOME/lib --add-modules javafx.controls,javafx.fxml" + PMD_OPENJFX_MODULE_PATH="$JAVAFX_HOME/lib" # still add the path where javafx.properties is located to the classpath, so that Designer's # net.sourceforge.pmd.util.fxdesigner.util.JavaFxUtil#getJavaFxVersion can find it. append_classpath "$JAVAFX_HOME/lib" @@ -255,6 +256,6 @@ cygwin_paths # shellcheck disable=SC2046,SC2086 exec java \ $PMD_JAVA_OPTS $PMD_ADDITIONAL_JAVA_OPTS \ - $PMD_OPENJFX_MODULE_PATH \ + ${PMD_OPENJFX_MODULE_PATH:+--module-path "$PMD_OPENJFX_MODULE_PATH" --add-modules javafx.controls,javafx.fxml} \ -cp "$CLASSPATH" \ net.sourceforge.pmd.cli.PmdCli "$@" From 395930aebed40b9a50ee93c0eb0df38d5f377ebb Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 5 Dec 2025 12:49:26 +0100 Subject: [PATCH 1873/1962] Avoid warnings for native access from javafx.graphics --- pmd-dist/src/main/resources/scripts/pmd | 5 +++++ pmd-dist/src/main/resources/scripts/pmd.bat | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/pmd-dist/src/main/resources/scripts/pmd b/pmd-dist/src/main/resources/scripts/pmd index 6159ead0205..48d8a0635ea 100755 --- a/pmd-dist/src/main/resources/scripts/pmd +++ b/pmd-dist/src/main/resources/scripts/pmd @@ -167,6 +167,11 @@ determine_additional_java_opts() { # With Java 17+ this option has no effect anymore (https://openjdk.org/jeps/403) and is deprecated. PMD_ADDITIONAL_JAVA_OPTS="$PMD_ADDITIONAL_JAVA_OPTS --illegal-access=warn" fi + if [ "$java_version_feature" -ge 24 ] + then + # Allow native access to javafx.graphics + PMD_ADDITIONAL_JAVA_OPTS="$PMD_ADDITIONAL_JAVA_OPTS --enable-native-access=javafx.graphics" + fi } append_classpath() { diff --git a/pmd-dist/src/main/resources/scripts/pmd.bat b/pmd-dist/src/main/resources/scripts/pmd.bat index f52c8eb6c4a..f1d9102d101 100644 --- a/pmd-dist/src/main/resources/scripts/pmd.bat +++ b/pmd-dist/src/main/resources/scripts/pmd.bat @@ -215,4 +215,9 @@ IF %java_version_feature% GEQ 9 ( SET "PMD_ADDITIONAL_JAVA_OPTS=!PMD_ADDITIONAL_JAVA_OPTS! --illegal-access=warn" ) ) +IF %java_version_feature% GEQ 24 ( + rem Allow native access to javafx.graphics + SET "PMD_ADDITIONAL_JAVA_OPTS=!PMD_ADDITIONAL_JAVA_OPTS! --enable-native-access=javafx.graphics" +) + EXIT /B From dc9634e4799f9525c13718efeef018ceacd69a0d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 11 Dec 2025 10:26:43 +0100 Subject: [PATCH 1874/1962] Avoid warnings for sun.misc.Unsafe from javafx.graphics --- pmd-dist/src/main/resources/scripts/pmd | 2 ++ pmd-dist/src/main/resources/scripts/pmd.bat | 2 ++ 2 files changed, 4 insertions(+) diff --git a/pmd-dist/src/main/resources/scripts/pmd b/pmd-dist/src/main/resources/scripts/pmd index 48d8a0635ea..58713d5133d 100755 --- a/pmd-dist/src/main/resources/scripts/pmd +++ b/pmd-dist/src/main/resources/scripts/pmd @@ -171,6 +171,8 @@ determine_additional_java_opts() { then # Allow native access to javafx.graphics PMD_ADDITIONAL_JAVA_OPTS="$PMD_ADDITIONAL_JAVA_OPTS --enable-native-access=javafx.graphics" + # Don't warn about sun misc unsafe (used by javafx.graphics). Needed until JavaFX 25. See https://bugs.openjdk.org/browse/JDK-8359264. + PMD_ADDITIONAL_JAVA_OPTS="$PMD_ADDITIONAL_JAVA_OPTS --sun-misc-unsafe-memory-access=allow" fi } diff --git a/pmd-dist/src/main/resources/scripts/pmd.bat b/pmd-dist/src/main/resources/scripts/pmd.bat index f1d9102d101..a5614b07515 100644 --- a/pmd-dist/src/main/resources/scripts/pmd.bat +++ b/pmd-dist/src/main/resources/scripts/pmd.bat @@ -218,6 +218,8 @@ IF %java_version_feature% GEQ 9 ( IF %java_version_feature% GEQ 24 ( rem Allow native access to javafx.graphics SET "PMD_ADDITIONAL_JAVA_OPTS=!PMD_ADDITIONAL_JAVA_OPTS! --enable-native-access=javafx.graphics" + rem Don't warn about sun misc unsafe (used by javafx.graphics). Needed until JavaFX 25. See https://bugs.openjdk.org/browse/JDK-8359264. + SET "PMD_ADDITIONAL_JAVA_OPTS=!PMD_ADDITIONAL_JAVA_OPTS! --sun-misc-unsafe-memory-access=allow" ) EXIT /B From 4ea3e26887a9738f60bf6bb6c4de876ba5fa95b2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 11 Dec 2025 10:38:14 +0100 Subject: [PATCH 1875/1962] Remove JavaFX from classpath for modules --- pmd-dist/src/main/resources/scripts/pmd | 11 ++++------- pmd-dist/src/main/resources/scripts/pmd.bat | 12 ++++-------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/pmd-dist/src/main/resources/scripts/pmd b/pmd-dist/src/main/resources/scripts/pmd index 58713d5133d..78cf037cf8a 100755 --- a/pmd-dist/src/main/resources/scripts/pmd +++ b/pmd-dist/src/main/resources/scripts/pmd @@ -194,10 +194,10 @@ add_openjfx_classpath() { then if [ $java_has_javafx = 1 ] then - # almost nothing to do, javafx is bundled (either an old Oracle Java < 8u451 or an OpenJDK 8 Build from Azul) - # still add the path where javafx.properties is located to the classpath, so that Designer's - # net.sourceforge.pmd.util.fxdesigner.util.JavaFxUtil#getJavaFxVersion can find it. - append_classpath "$java_javafx_properties_path" + # No additional options needed as JavaFX is bundled. + # We are running either an old Oracle Java < 8u451 or an OpenJDK 8 Build from Azul/Bellsoft which + # have JavaFX bundled as modules. + PMD_OPENJFX_MODULE_PATH="" else if [ "$java_version_feature" = "8" ] && [ "$java_version_update" -ge 451 ] @@ -230,9 +230,6 @@ add_openjfx_classpath() { fi PMD_OPENJFX_MODULE_PATH="$JAVAFX_HOME/lib" - # still add the path where javafx.properties is located to the classpath, so that Designer's - # net.sourceforge.pmd.util.fxdesigner.util.JavaFxUtil#getJavaFxVersion can find it. - append_classpath "$JAVAFX_HOME/lib" fi fi } diff --git a/pmd-dist/src/main/resources/scripts/pmd.bat b/pmd-dist/src/main/resources/scripts/pmd.bat index a5614b07515..821fe2517b5 100644 --- a/pmd-dist/src/main/resources/scripts/pmd.bat +++ b/pmd-dist/src/main/resources/scripts/pmd.bat @@ -129,10 +129,10 @@ EXIT /B SET "PMD_OPENJFX_MODULE_PATH=" IF [%APPNAME%] == [designer] ( IF %java_has_javafx% EQU 1 ( - rem almost nothing to do, javafx is bundled (either an old Oracle Java < 8u451 or an OpenJDK 8 Build from Azul) - rem still add the path where javafx.properties is located to the classpath, so that Designer's - rem net.sourceforge.pmd.util.fxdesigner.util.JavaFxUtil#getJavaFxVersion can find it. - CALL :append_classpath "%java_javafx_properties_path%" + rem No additional options needed as JavaFX is bundled. + rem We are running either an old Oracle Java < 8u451 or an OpenJDK 8 Build from Azul/Bellsoft which + rem have JavaFX bundled as modules. + SET "PMD_OPENJFX_MODULE_PATH=" ) ELSE ( IF %java_version_feature% EQU 8 ( @@ -163,10 +163,6 @@ IF [%APPNAME%] == [designer] ( ) SET "PMD_OPENJFX_MODULE_PATH=--module-path %JAVAFX_HOME%/lib --add-modules javafx.controls,javafx.fxml" - rem still add the path where javafx.properties is located to the classpath, so that Designer's - rem net.sourceforge.pmd.util.fxdesigner.util.JavaFxUtil#getJavaFxVersion can find it. - rem note: no trailing backslash, as this would escape a following quote when %CLASSPATH% is used later - CALL :append_classpath "%JAVAFX_HOME%/lib" ) ) EXIT /B From 9d296c29240eccddf3765c0f6426d0642722e4c3 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 11 Dec 2025 18:01:42 +0100 Subject: [PATCH 1876/1962] Remove JavaFX from classpath for modules --- pmd-dist/src/main/resources/scripts/pmd | 8 ------- pmd-dist/src/main/resources/scripts/pmd.bat | 8 ------- .../src/test/resources/scripts/pmdtest.bat | 24 ++++--------------- .../src/test/resources/scripts/runtest.sh | 17 ++----------- 4 files changed, 6 insertions(+), 51 deletions(-) diff --git a/pmd-dist/src/main/resources/scripts/pmd b/pmd-dist/src/main/resources/scripts/pmd index 78cf037cf8a..62140b98695 100755 --- a/pmd-dist/src/main/resources/scripts/pmd +++ b/pmd-dist/src/main/resources/scripts/pmd @@ -110,19 +110,11 @@ determine_java_version() { java_home_property=$(echo "$all_props" | grep "java.home" | sed -n -e 's/^.*java\.home *= *\(.*\)$/\1/; p') java_has_javafx=0 - java_javafx_properties= - java_javafx_properties_path= if [ -e "$java_home_property/lib/javafx.properties" ]; then - java_javafx_properties="$java_home_property/lib/javafx.properties" java_has_javafx=1 elif [ -e "$java_home_property/jre/lib/javafx.properties" ]; then - java_javafx_properties="$java_home_property/jre/lib/javafx.properties" java_has_javafx=1 fi - if [ $java_has_javafx = 1 ] - then - java_javafx_properties_path="$(dirname "$java_javafx_properties")" - fi } determine_additional_java_opts() { diff --git a/pmd-dist/src/main/resources/scripts/pmd.bat b/pmd-dist/src/main/resources/scripts/pmd.bat index 821fe2517b5..18c7f882361 100644 --- a/pmd-dist/src/main/resources/scripts/pmd.bat +++ b/pmd-dist/src/main/resources/scripts/pmd.bat @@ -109,20 +109,12 @@ rem if there was no 3rd component (eg. -ea or ga version), use "0" IF "%java_version_update%" == "" set java_version_update=0 set java_has_javafx=0 -set java_javafx_properties= -set java_javafx_properties_path= IF EXIST "%java_home_property%/lib/javafx.properties" ( - set "java_javafx_properties=%java_home_property%/lib/javafx.properties" set java_has_javafx=1 ) IF EXIST "%java_home_property%/jre/lib/javafx.properties" ( - set "java_javafx_properties=%java_home_property%/jre/lib/javafx.properties" set java_has_javafx=1 ) -rem resolve dirname -IF %java_has_javafx% EQU 1 FOR %%F IN (%java_javafx_properties%) DO set "java_javafx_properties_path=%%~dpF" -rem remove trailing backslash -IF %java_has_javafx% EQU 1 set "java_javafx_properties_path=%java_javafx_properties_path:~0,-1%" EXIT /B :add_openjfx_classpath diff --git a/pmd-dist/src/test/resources/scripts/pmdtest.bat b/pmd-dist/src/test/resources/scripts/pmdtest.bat index bcf8df1ab5a..39a4ddd8697 100644 --- a/pmd-dist/src/test/resources/scripts/pmdtest.bat +++ b/pmd-dist/src/test/resources/scripts/pmdtest.bat @@ -61,20 +61,12 @@ rem if there was no 3rd component (eg. -ea or ga version), use "0" IF "%java_version_update%" == "" set java_version_update=0 set java_has_javafx=0 -set java_javafx_properties= -set java_javafx_properties_path= IF EXIST "%java_home_property%/lib/javafx.properties" ( - set "java_javafx_properties=%java_home_property%/lib/javafx.properties" set java_has_javafx=1 ) IF EXIST "%java_home_property%/jre/lib/javafx.properties" ( - set "java_javafx_properties=%java_home_property%/jre/lib/javafx.properties" set java_has_javafx=1 ) -rem resolve dirname -IF %java_has_javafx% EQU 1 FOR %%F IN (%java_javafx_properties%) DO set "java_javafx_properties_path=%%~dpF" -rem remove trailing backslash -IF %java_has_javafx% EQU 1 set "java_javafx_properties_path=%java_javafx_properties_path:~0,-1%" EXIT /B @@ -129,25 +121,17 @@ echo.|set /p =java_has_javafx: %java_has_javafx% set "_temp_javafx_passed=0" IF "%EXPECTED_HAS_JAVAFX%" == "yes" ( IF %java_has_javafx% EQU 1 ( - IF NOT "%java_javafx_properties%" == "" ( - set "_temp_javafx_passed=1" - CALL :pass - ) + set "_temp_javafx_passed=1" + CALL :pass ) ) IF "%EXPECTED_HAS_JAVAFX%" == "no" ( IF %java_has_javafx% EQU 0 ( - IF "%java_javafx_properties%" == "" ( - set "_temp_javafx_passed=1" - CALL :pass - ) + set "_temp_javafx_passed=1" + CALL :pass ) ) IF %_temp_javafx_passed% EQU 0 ( CALL :fail ) -IF %java_has_javafx% EQU 1 ( - echo.|set /p =java_javafx_properties_path: - IF NOT "%java_javafx_properties_path%" == "" ( CALL :pass ) ELSE ( CALL :fail ) -) echo. EXIT /B diff --git a/pmd-dist/src/test/resources/scripts/runtest.sh b/pmd-dist/src/test/resources/scripts/runtest.sh index 0cfeaa26dff..72c0293e4b8 100755 --- a/pmd-dist/src/test/resources/scripts/runtest.sh +++ b/pmd-dist/src/test/resources/scripts/runtest.sh @@ -44,19 +44,11 @@ determine_java_version() { java_home_property=$(echo "$all_props" | grep "java.home" | sed -n -e 's/^.*java\.home *= *\(.*\)$/\1/; p') java_has_javafx=0 - java_javafx_properties= - java_javafx_properties_path= if [ -e "$java_home_property/lib/javafx.properties" ]; then - java_javafx_properties="$java_home_property/lib/javafx.properties" java_has_javafx=1 elif [ -e "$java_home_property/jre/lib/javafx.properties" ]; then - java_javafx_properties="$java_home_property/jre/lib/javafx.properties" java_has_javafx=1 fi - if [ $java_has_javafx = 1 ] - then - java_javafx_properties_path="$(dirname "$java_javafx_properties")" - fi } pass() { @@ -83,14 +75,9 @@ run_test() { printf "java_version_update: %s " "$java_version_update" if [ "$EXPECTED_UPDATE" = "$java_version_update" ]; then pass; else fail; fi printf "java_has_javafx: %s " "$java_has_javafx" - if [ "$EXPECTED_HAS_JAVAFX" = "yes" ] && [ "$java_has_javafx" = 1 ] && [ -n "$java_javafx_properties" ]; then pass; - elif [ "$EXPECTED_HAS_JAVAFX" = "no" ] && [ "$java_has_javafx" = 0 ] && [ -z "$java_javafx_properties" ]; then pass; + if [ "$EXPECTED_HAS_JAVAFX" = "yes" ] && [ "$java_has_javafx" = 1 ]; then pass; + elif [ "$EXPECTED_HAS_JAVAFX" = "no" ] && [ "$java_has_javafx" = 0 ]; then pass; else fail; fi - if [ "$java_has_javafx" = 1 ] - then - printf "java_javafx_properties_path: " - if [ -n "$java_javafx_properties_path" ]; then pass; else fail; fi - fi echo } From 8d51cec5803a775b8ef7a0a4d36f8a3213f6e50b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 11 Dec 2025 18:02:17 +0100 Subject: [PATCH 1877/1962] Only add --enable-native-access when running Designer --- pmd-dist/src/main/resources/scripts/pmd | 2 +- pmd-dist/src/main/resources/scripts/pmd.bat | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/pmd-dist/src/main/resources/scripts/pmd b/pmd-dist/src/main/resources/scripts/pmd index 62140b98695..13677e6d8bf 100755 --- a/pmd-dist/src/main/resources/scripts/pmd +++ b/pmd-dist/src/main/resources/scripts/pmd @@ -159,7 +159,7 @@ determine_additional_java_opts() { # With Java 17+ this option has no effect anymore (https://openjdk.org/jeps/403) and is deprecated. PMD_ADDITIONAL_JAVA_OPTS="$PMD_ADDITIONAL_JAVA_OPTS --illegal-access=warn" fi - if [ "$java_version_feature" -ge 24 ] + if [ "$APPNAME" = "designer" ] && [ "$java_version_feature" -ge 24 ] then # Allow native access to javafx.graphics PMD_ADDITIONAL_JAVA_OPTS="$PMD_ADDITIONAL_JAVA_OPTS --enable-native-access=javafx.graphics" diff --git a/pmd-dist/src/main/resources/scripts/pmd.bat b/pmd-dist/src/main/resources/scripts/pmd.bat index 18c7f882361..0c47495709b 100644 --- a/pmd-dist/src/main/resources/scripts/pmd.bat +++ b/pmd-dist/src/main/resources/scripts/pmd.bat @@ -203,11 +203,13 @@ IF %java_version_feature% GEQ 9 ( SET "PMD_ADDITIONAL_JAVA_OPTS=!PMD_ADDITIONAL_JAVA_OPTS! --illegal-access=warn" ) ) -IF %java_version_feature% GEQ 24 ( - rem Allow native access to javafx.graphics - SET "PMD_ADDITIONAL_JAVA_OPTS=!PMD_ADDITIONAL_JAVA_OPTS! --enable-native-access=javafx.graphics" - rem Don't warn about sun misc unsafe (used by javafx.graphics). Needed until JavaFX 25. See https://bugs.openjdk.org/browse/JDK-8359264. - SET "PMD_ADDITIONAL_JAVA_OPTS=!PMD_ADDITIONAL_JAVA_OPTS! --sun-misc-unsafe-memory-access=allow" +IF [%APPNAME%] == [designer] ( + IF %java_version_feature% GEQ 24 ( + rem Allow native access to javafx.graphics + SET "PMD_ADDITIONAL_JAVA_OPTS=!PMD_ADDITIONAL_JAVA_OPTS! --enable-native-access=javafx.graphics" + rem Don't warn about sun misc unsafe (used by javafx.graphics). Needed until JavaFX 25. See https://bugs.openjdk.org/browse/JDK-8359264. + SET "PMD_ADDITIONAL_JAVA_OPTS=!PMD_ADDITIONAL_JAVA_OPTS! --sun-misc-unsafe-memory-access=allow" + ) ) EXIT /B From c83a6f6f87a9f3d2c628ccd51faf228dca88a6c8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 12 Dec 2025 12:12:03 +0100 Subject: [PATCH 1878/1962] Bump pmd-designer from 7.19.1 to 7.19.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d6dd9f93cf7..0b149c788fd 100644 --- a/pom.xml +++ b/pom.xml @@ -109,7 +109,7 @@ 36 - 7.19.1 + 7.19.2 ${project.build.directory}/generated-sources/javacc ${project.basedir}/../javacc-wrapper.xml From 3e7d559f6a46f919d9f6e8dad9d6c749bdaa20a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Thu, 8 Jan 2026 13:38:50 +0100 Subject: [PATCH 1879/1962] [java] Fix #6364 - parse error with yield lambda --- pmd-java/src/main/javacc/Java.jjt | 5 +++-- .../pmd/lang/java/ast/ParserCornersTest.java | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/javacc/Java.jjt b/pmd-java/src/main/javacc/Java.jjt index 09f65dc19f5..2c96d95fde4 100644 --- a/pmd-java/src/main/javacc/Java.jjt +++ b/pmd-java/src/main/javacc/Java.jjt @@ -501,18 +501,19 @@ class JavaParserImpl { int lookahead = offset + 1; int balance = 1; JavaccToken t; + boolean hasComma = false; while ((t = getToken(lookahead)) != null && balance > 0) { switch (t.kind) { case LPAREN: balance++; break; case RPAREN: balance--; break; - case COMMA: if (balance == 1) return false; // a method call, eg yield(1, 2); + case COMMA: if (balance == 1) { hasComma = true; } break; } lookahead++; } // lambda: yield () -> {}; // method call: yield (); return t != null - && (lookahead != offset + 2 // ie () + && (!hasComma && lookahead != offset + 2 // ie () || t.kind == LAMBDA); default: return false; diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java index de7b112d5da..6add1e1d4d8 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java @@ -195,6 +195,27 @@ void testGenericsProblem() { java7.parse(code); } + @Test + void testYieldStmtWithLambda() { + java15.parse( + "public class Lambda {\n" + + " interface Func {\n" + + " String apply(Lambda a, Lambda b);\n" + + " }\n" + + "\n" + + " public static void main( String[] args ) {\n" + + " foo(switch ( args[0] ) {\n" + + " default:\n" + + " yield (Lambda a, Lambda b) -> \"hello\";\n" + + " });\n" + + " }\n" + + "\n" + + " private static void foo(Func f) {} \n" + + "}" + ); + } + + @Test void testUnicodeIndent() { // https://github.com/pmd/pmd/issues/3423 From 44c177a45a373eeea9834cc56d94488c1775e133 Mon Sep 17 00:00:00 2001 From: Mohamed Hamed Date: Fri, 9 Jan 2026 15:21:29 +0100 Subject: [PATCH 1880/1962] fix(apex): Treat properties as field-like in FieldDeclarationsShouldBeAtStart (#6349) --- .../FieldDeclarationsShouldBeAtStartRule.java | 6 +- .../xml/FieldDeclarationsShouldBeAtStart.xml | 104 +++++++++++++++++- 2 files changed, 104 insertions(+), 6 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldDeclarationsShouldBeAtStartRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldDeclarationsShouldBeAtStartRule.java index 4f9863f62b0..2444138e6fd 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldDeclarationsShouldBeAtStartRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldDeclarationsShouldBeAtStartRule.java @@ -45,7 +45,6 @@ public Object visit(ASTUserClass node, Object data) { nonFieldDeclarations.addAll(getMethodNodes(node)); nonFieldDeclarations.addAll(node.children(ASTUserClass.class).toList()); - nonFieldDeclarations.addAll(node.children(ASTProperty.class).toList()); nonFieldDeclarations.addAll(node.children(ASTBlockStatement.class).toList()); Optional> firstNonFieldDeclaration = nonFieldDeclarations.stream() @@ -67,6 +66,9 @@ public Object visit(ASTUserClass node, Object data) { } private List> getMethodNodes(ASTUserClass node) { - return node.descendants(ASTMethod.class).map(m -> (ApexNode) m).toList(); + return node.descendants(ASTMethod.class) + .filter(m -> m.ancestors(ASTProperty.class).isEmpty()) + .map(m -> (ApexNode) m) + .toList(); } } diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/codestyle/xml/FieldDeclarationsShouldBeAtStart.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/codestyle/xml/FieldDeclarationsShouldBeAtStart.xml index 2ee671ed1ca..1f13aae6231 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/codestyle/xml/FieldDeclarationsShouldBeAtStart.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/codestyle/xml/FieldDeclarationsShouldBeAtStart.xml @@ -139,14 +139,13 @@ class Foo { - Fields should go before properties too - 1 - 4 + Fields can come after properties (properties are field-like) + 0 @@ -194,4 +193,101 @@ class Foo { } ]]> + + + Issue #6349: Properties with accessors are field-like declarations + 0 + + + + + Properties and fields can be intermixed + 0 + + + + + Fields should still come before methods even with properties present + 1 + 5 + + Field declaration for 'thisIsNotOkay' should be before method declarations in its class + + + + + + Complex mix of properties and fields before methods is valid + 0 + + + + + Properties can come before regular fields + 0 + + + + + Fields before methods is valid + 0 + + + + + Methods before fields triggers violation + 1 + 5 + + Field declaration for 'field1' should be before method declarations in its class + + + From 759b2da94f30507722ca7b8d2c5c1c54e82bc888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Gr=C3=A4f?= Date: Sun, 28 Dec 2025 21:30:09 +0100 Subject: [PATCH 1881/1962] [java] Reproduce Issue 3857 --- .../InsufficientStringBufferDeclaration.xml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml index bd5d364eb1d..79697f3626d 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml @@ -1436,6 +1436,27 @@ public class StringBufferInstantiationWithCharTest { StringBuilder sb4 = new StringBuilder("c"); } } +]]> + + + + #3857: InsufficientStringBufferDeclaration should consider constant String + 1 + list = new ArrayList<>(); + + public static final String PRE = "The size of list is: "; // 21 characters, exceed default 16 + + public void func() { + StringBuilder builder = new StringBuilder(); + builder.append(PRE); + } +} + ]]> From 48af8fda4560141a5b87b1eab50798cef0deb64b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Gr=C3=A4f?= Date: Sun, 28 Dec 2025 21:37:55 +0100 Subject: [PATCH 1882/1962] [java] Fix Issue 3857: InsufficientStringBufferDeclaration should consider constant String --- ...nsufficientStringBufferDeclarationRule.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java index bd994279717..48fc6139548 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java @@ -7,7 +7,9 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Objects; import java.util.Set; +import java.util.stream.Collectors; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr.ASTNamedReferenceExpr; @@ -23,6 +25,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTStringLiteral; import net.sourceforge.pmd.lang.java.ast.ASTSwitchBranch; import net.sourceforge.pmd.lang.java.ast.ASTSwitchStatement; +import net.sourceforge.pmd.lang.java.ast.ASTVariableAccess; import net.sourceforge.pmd.lang.java.ast.ASTVariableId; import net.sourceforge.pmd.lang.java.ast.JavaNode; import net.sourceforge.pmd.lang.java.ast.TypeNode; @@ -157,8 +160,7 @@ public Object visit(ASTVariableId node, Object data) { private void processMethodCall(State state, ASTMethodCall methodCall) { if ("append".equals(methodCall.getMethodName())) { int counter = 0; - Set literals = new HashSet<>(); - literals.addAll(methodCall.getArguments() + Set literals = new HashSet<>(methodCall.getArguments() .descendants(ASTLiteral.class) // exclude literals, that belong to different method calls .filter(n -> n.ancestors(ASTMethodCall.class).first() == methodCall).toList()); @@ -176,7 +178,17 @@ private void processMethodCall(State state, ASTMethodCall methodCall) { counter += 1; } } - + + Set constValues = methodCall.getArguments().descendants(ASTVariableAccess.class).toStream() + .map(ASTVariableAccess::getConstFoldingResult) + .map(ASTExpression.ConstResult::getValue) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + for (Object constValue : constValues) { + counter += constValue.toString().length(); + } + ASTIfStatement ifStatement = methodCall.ancestors(ASTIfStatement.class).first(); ASTSwitchStatement switchStatement = methodCall.ancestors(ASTSwitchStatement.class).first(); if (ifStatement != null) { From a76dd60f9265c933003c9b4e4a65b5829081c028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Gr=C3=A4f?= Date: Mon, 29 Dec 2025 00:23:36 +0100 Subject: [PATCH 1883/1962] [java] simplify expected length calculation --- .../InsufficientStringBufferDeclarationRule.java | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java index 48fc6139548..9c7cd554dd5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java @@ -15,14 +15,11 @@ import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr.ASTNamedReferenceExpr; import net.sourceforge.pmd.lang.java.ast.ASTAssignmentExpression; import net.sourceforge.pmd.lang.java.ast.ASTCastExpression; -import net.sourceforge.pmd.lang.java.ast.ASTCharLiteral; import net.sourceforge.pmd.lang.java.ast.ASTConstructorCall; import net.sourceforge.pmd.lang.java.ast.ASTExpression; import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; import net.sourceforge.pmd.lang.java.ast.ASTLiteral; import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; -import net.sourceforge.pmd.lang.java.ast.ASTNumericLiteral; -import net.sourceforge.pmd.lang.java.ast.ASTStringLiteral; import net.sourceforge.pmd.lang.java.ast.ASTSwitchBranch; import net.sourceforge.pmd.lang.java.ast.ASTSwitchStatement; import net.sourceforge.pmd.lang.java.ast.ASTVariableAccess; @@ -165,17 +162,11 @@ private void processMethodCall(State state, ASTMethodCall methodCall) { // exclude literals, that belong to different method calls .filter(n -> n.ancestors(ASTMethodCall.class).first() == methodCall).toList()); for (ASTLiteral literal : literals) { - if (literal instanceof ASTStringLiteral) { - counter += ((ASTStringLiteral) literal).length(); - } else if (literal instanceof ASTNumericLiteral) { - if (literal.getParent() instanceof ASTCastExpression + if (literal.getParent() instanceof ASTCastExpression && TypeTestUtil.isA(char.class, (ASTCastExpression) literal.getParent())) { - counter += 1; - } else { - counter += String.valueOf(((ASTNumericLiteral) literal).getConstValue()).length(); - } - } else if (literal instanceof ASTCharLiteral) { counter += 1; + } else { + counter += String.valueOf(literal.getConstValue()).length(); } } From dc57c9a0a3105bcf123ea341a55400118dcaaa79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Gr=C3=A4f?= Date: Mon, 29 Dec 2025 19:17:14 +0100 Subject: [PATCH 1884/1962] [java] extend testcase to also check non-static final Strings --- .../xml/InsufficientStringBufferDeclaration.xml | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml index 79697f3626d..ef8b2b42da7 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml @@ -1440,8 +1440,13 @@ public class StringBufferInstantiationWithCharTest { - #3857: InsufficientStringBufferDeclaration should consider constant String - 1 + #3857: InsufficientStringBufferDeclaration should consider constant Strings + 2 + 10,15 + + StringBuilder has been initialized with size 16, but has at least 21 characters appended. + StringBuilder has been initialized with size 3, but has at least 6 characters appended. + From b3782795dd92c5be03cc426c10c1e152813657bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Gr=C3=A4f?= Date: Mon, 29 Dec 2025 19:43:04 +0100 Subject: [PATCH 1885/1962] [java] Fix handling of constants wrapped in another method --- ...sufficientStringBufferDeclarationRule.java | 8 +++++- .../InsufficientStringBufferDeclaration.xml | 26 ++++++++++++++----- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java index 9c7cd554dd5..972a9add433 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java @@ -9,6 +9,7 @@ import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.function.Predicate; import java.util.stream.Collectors; import net.sourceforge.pmd.lang.ast.Node; @@ -157,10 +158,14 @@ public Object visit(ASTVariableId node, Object data) { private void processMethodCall(State state, ASTMethodCall methodCall) { if ("append".equals(methodCall.getMethodName())) { int counter = 0; + Predicate methodPredicate = n -> n.ancestors(ASTMethodCall.class).first() == methodCall; + Set literals = new HashSet<>(methodCall.getArguments() .descendants(ASTLiteral.class) // exclude literals, that belong to different method calls - .filter(n -> n.ancestors(ASTMethodCall.class).first() == methodCall).toList()); + .filter(methodPredicate) + .toList()); + for (ASTLiteral literal : literals) { if (literal.getParent() instanceof ASTCastExpression && TypeTestUtil.isA(char.class, (ASTCastExpression) literal.getParent())) { @@ -171,6 +176,7 @@ private void processMethodCall(State state, ASTMethodCall methodCall) { } Set constValues = methodCall.getArguments().descendants(ASTVariableAccess.class).toStream() + .filter(methodPredicate) .map(ASTVariableAccess::getConstFoldingResult) .map(ASTExpression.ConstResult::getValue) .filter(Objects::nonNull) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml index ef8b2b42da7..b6dd35bb271 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml @@ -1442,18 +1442,13 @@ public class StringBufferInstantiationWithCharTest { #3857: InsufficientStringBufferDeclaration should consider constant Strings 2 - 10,15 + 5,10 StringBuilder has been initialized with size 16, but has at least 21 characters appended. StringBuilder has been initialized with size 3, but has at least 6 characters appended. list = new ArrayList<>(); - public static final String PRE = "The size of list is: "; // 21 characters, exceed default 16 public void compileTimeConstant() { @@ -1468,6 +1463,25 @@ public class Example { } } +]]> + + + Constant wrapped in method should be allowed + 0 + From 4dd950eca8f875d757833ad388db266fda1e8d8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Gr=C3=A4f?= Date: Tue, 30 Dec 2025 01:58:50 +0100 Subject: [PATCH 1886/1962] [java] Support appending from char cast with constants --- ...sufficientStringBufferDeclarationRule.java | 53 ++++++++++--------- .../InsufficientStringBufferDeclaration.xml | 5 ++ 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java index 972a9add433..3ea598f7586 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java @@ -5,11 +5,9 @@ package net.sourceforge.pmd.lang.java.rule.performance; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; -import java.util.Objects; import java.util.Set; -import java.util.function.Predicate; +import java.util.function.ToIntFunction; import java.util.stream.Collectors; import net.sourceforge.pmd.lang.ast.Node; @@ -158,32 +156,22 @@ public Object visit(ASTVariableId node, Object data) { private void processMethodCall(State state, ASTMethodCall methodCall) { if ("append".equals(methodCall.getMethodName())) { int counter = 0; - Predicate methodPredicate = n -> n.ancestors(ASTMethodCall.class).first() == methodCall; - - Set literals = new HashSet<>(methodCall.getArguments() - .descendants(ASTLiteral.class) - // exclude literals, that belong to different method calls - .filter(methodPredicate) - .toList()); + Set literals = collectArgumentsOfType(methodCall, ASTLiteral.class); for (ASTLiteral literal : literals) { - if (literal.getParent() instanceof ASTCastExpression - && TypeTestUtil.isA(char.class, (ASTCastExpression) literal.getParent())) { - counter += 1; - } else { - counter += String.valueOf(literal.getConstValue()).length(); - } + counter += calculateExpectedLength(literal, value -> String.valueOf(value.getConstValue()).length()); } - Set constValues = methodCall.getArguments().descendants(ASTVariableAccess.class).toStream() - .filter(methodPredicate) - .map(ASTVariableAccess::getConstFoldingResult) - .map(ASTExpression.ConstResult::getValue) - .filter(Objects::nonNull) - .collect(Collectors.toSet()); + Set variables = collectArgumentsOfType(methodCall, ASTVariableAccess.class); + for (ASTVariableAccess variable : variables) { + counter += calculateExpectedLength(variable, value -> { + Object constValue = value.getConstFoldingResult().getValue(); + if (constValue == null) { + return 0; + } - for (Object constValue : constValues) { - counter += constValue.toString().length(); + return String.valueOf(constValue).length(); + }); } ASTIfStatement ifStatement = methodCall.ancestors(ASTIfStatement.class).first(); @@ -217,6 +205,23 @@ private void processMethodCall(State state, ASTMethodCall methodCall) { } } + private static int calculateExpectedLength(T expression, ToIntFunction countingStrategy) { + if (expression.getParent() instanceof ASTCastExpression + && TypeTestUtil.isA(char.class, (ASTCastExpression) expression.getParent())) { + return 1; + } + + return countingStrategy.applyAsInt(expression); + } + + private static Set collectArgumentsOfType(ASTMethodCall methodCall, Class type) { + return methodCall.getArguments() + .descendants(type) + // exclude literals, that belong to different method calls + .filter(n -> n.ancestors(ASTMethodCall.class).first() == methodCall) + .collect(Collectors.toSet()); + } + private State getConstructorCapacity(ASTVariableId variable, ASTExpression node) { State state = new State(variable, null, State.UNKNOWN_CAPACITY, 0); diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml index b6dd35bb271..0e902ffd783 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml @@ -753,6 +753,11 @@ public class Foo { StringBuilder sb = new StringBuilder(1); sb.append((char) 0x0041); } + public void bar3() { + StringBuilder sb = new StringBuilder(1); + final int x = 0x0041; + sb.append((char) x); + } } ]]> From 846bae46bbaafa92f3f2cd96bde6ad5879a57cc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Gr=C3=A4f?= Date: Tue, 30 Dec 2025 02:21:31 +0100 Subject: [PATCH 1887/1962] [java] Cleanup counting implementation --- ...sufficientStringBufferDeclarationRule.java | 26 +++++++------------ 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java index 3ea598f7586..09469115f5b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java @@ -6,6 +6,7 @@ import java.util.HashMap; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.function.ToIntFunction; import java.util.stream.Collectors; @@ -155,25 +156,17 @@ public Object visit(ASTVariableId node, Object data) { private void processMethodCall(State state, ASTMethodCall methodCall) { if ("append".equals(methodCall.getMethodName())) { - int counter = 0; Set literals = collectArgumentsOfType(methodCall, ASTLiteral.class); - - for (ASTLiteral literal : literals) { - counter += calculateExpectedLength(literal, value -> String.valueOf(value.getConstValue()).length()); - } + ToIntFunction literalCounter = value -> String.valueOf(value.getConstValue()).length(); + int literalsCount = literals.stream().mapToInt(value -> calculateExpectedLength(value, literalCounter)).sum(); Set variables = collectArgumentsOfType(methodCall, ASTVariableAccess.class); - for (ASTVariableAccess variable : variables) { - counter += calculateExpectedLength(variable, value -> { - Object constValue = value.getConstFoldingResult().getValue(); - if (constValue == null) { - return 0; - } - - return String.valueOf(constValue).length(); - }); - } + ToIntFunction variablesCounter = value -> Optional.ofNullable(value.getConstFoldingResult().getValue()) + .map(constValue -> String.valueOf(constValue).length()) + .orElse(0); + int variablesCount = variables.stream().mapToInt(value -> calculateExpectedLength(value, variablesCounter)).sum(); + int counter = literalsCount + variablesCount; ASTIfStatement ifStatement = methodCall.ancestors(ASTIfStatement.class).first(); ASTSwitchStatement switchStatement = methodCall.ancestors(ASTSwitchStatement.class).first(); if (ifStatement != null) { @@ -205,12 +198,11 @@ private void processMethodCall(State state, ASTMethodCall methodCall) { } } - private static int calculateExpectedLength(T expression, ToIntFunction countingStrategy) { + private static int calculateExpectedLength(T expression, ToIntFunction countingStrategy) { if (expression.getParent() instanceof ASTCastExpression && TypeTestUtil.isA(char.class, (ASTCastExpression) expression.getParent())) { return 1; } - return countingStrategy.applyAsInt(expression); } From 800a3833784f947d3bf683b24031653cc9f1b019 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Gr=C3=A4f?= Date: Tue, 30 Dec 2025 02:27:11 +0100 Subject: [PATCH 1888/1962] [java] Add testcase for mixed usage of constants and literals --- .../InsufficientStringBufferDeclaration.xml | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml index 0e902ffd783..ce56cd07451 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml @@ -1467,9 +1467,9 @@ public class Example { builder.append(s); } } - ]]> + Constant wrapped in method should be allowed 0 @@ -1486,7 +1486,28 @@ public class Foo { return s.length(); } } +]]> + + + + Mixing constant variables and literals + 1 + 6 + + StringBuilder has been initialized with size 7, but has at least 8 characters appended. + + From 9cda9b68f0fcec9f7722d139a84ab8470a56acb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Gr=C3=A4f?= Date: Tue, 30 Dec 2025 16:07:37 +0100 Subject: [PATCH 1889/1962] [java] Fix FPs involving arrays --- .../InsufficientStringBufferDeclarationRule.java | 5 ++++- .../xml/InsufficientStringBufferDeclaration.xml | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java index 09469115f5b..4da00023806 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java @@ -12,6 +12,7 @@ import java.util.stream.Collectors; import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.java.ast.ASTArrayAccess; import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr.ASTNamedReferenceExpr; import net.sourceforge.pmd.lang.java.ast.ASTAssignmentExpression; import net.sourceforge.pmd.lang.java.ast.ASTCastExpression; @@ -209,8 +210,10 @@ private static int calculateExpectedLength(T expressio private static Set collectArgumentsOfType(ASTMethodCall methodCall, Class type) { return methodCall.getArguments() .descendants(type) - // exclude literals, that belong to different method calls + // exclude arguments, that belong to different method calls .filter(n -> n.ancestors(ASTMethodCall.class).first() == methodCall) + // also exclude args that are used to access arrays + .filter(n -> !(n.getParent() instanceof ASTArrayAccess)) .collect(Collectors.toSet()); } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml index ce56cd07451..768d8791c8f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml @@ -1508,6 +1508,21 @@ public class Foo { builder.append(BAZ); } } +]]> + + + + Access constant from array + 0 + From 09570667733b68f713f753d9a4ebb795487257bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Gr=C3=A4f?= Date: Sat, 3 Jan 2026 20:41:02 +0100 Subject: [PATCH 1890/1962] [java] Fix appending conditional expressions --- .../InsufficientStringBufferDeclarationRule.java | 8 ++++++++ .../xml/InsufficientStringBufferDeclaration.xml | 13 +++++++++++++ 2 files changed, 21 insertions(+) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java index 4da00023806..72ea9c5f272 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java @@ -16,6 +16,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr.ASTNamedReferenceExpr; import net.sourceforge.pmd.lang.java.ast.ASTAssignmentExpression; import net.sourceforge.pmd.lang.java.ast.ASTCastExpression; +import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression; import net.sourceforge.pmd.lang.java.ast.ASTConstructorCall; import net.sourceforge.pmd.lang.java.ast.ASTExpression; import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; @@ -208,12 +209,19 @@ private static int calculateExpectedLength(T expressio } private static Set collectArgumentsOfType(ASTMethodCall methodCall, Class type) { + Set conditionalNodes = methodCall.descendants(ASTConditionalExpression.class) + .map(ASTConditionalExpression::getCondition) + .descendants() + .collect(Collectors.toSet()); + return methodCall.getArguments() .descendants(type) // exclude arguments, that belong to different method calls .filter(n -> n.ancestors(ASTMethodCall.class).first() == methodCall) // also exclude args that are used to access arrays .filter(n -> !(n.getParent() instanceof ASTArrayAccess)) + // also exclude args that are only used in the conditional part of a conditional expression + .filter(o -> !conditionalNodes.contains(o)) .collect(Collectors.toSet()); } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml index 768d8791c8f..250ea694092 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml @@ -1523,6 +1523,19 @@ public class Foo { builder.append(TEST[0]); } } +]]> + + + + Ignore values used in conditional part of conditional expression + 0 + From bf225faabaa0beabca9301dbc9a0aa4800ad8b11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Gr=C3=A4f?= Date: Sat, 10 Jan 2026 17:57:30 +0100 Subject: [PATCH 1891/1962] [java] Add testcase for expected size of null literals --- .../xml/InsufficientStringBufferDeclaration.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml index 250ea694092..f5dd7003457 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml @@ -1536,6 +1536,22 @@ public class Foo { builder.append(s != null ? "1" : ""); } } +]]> + + + String representation of null is counted as four characters + 1 + 3 + + StringBuilder has been initialized with size 1, but has at least 4 characters appended. + + From 24cd9f60197fb01ce5f8edbfffcf4d8afd8b9115 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Jan 2026 11:10:06 +0100 Subject: [PATCH 1892/1962] chore(deps): bump com.github.siom79.japicmp:japicmp-maven-plugin from 0.25.1 to 0.25.4 (#6400) chore(deps): bump com.github.siom79.japicmp:japicmp-maven-plugin Bumps [com.github.siom79.japicmp:japicmp-maven-plugin](https://github.com/siom79/japicmp) from 0.25.1 to 0.25.4. - [Release notes](https://github.com/siom79/japicmp/releases) - [Changelog](https://github.com/siom79/japicmp/blob/master/release.py) - [Commits](https://github.com/siom79/japicmp/compare/japicmp-base-0.25.1...japicmp-base-0.25.4) --- updated-dependencies: - dependency-name: com.github.siom79.japicmp:japicmp-maven-plugin dependency-version: 0.25.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d6dd9f93cf7..4b0745749b2 100644 --- a/pom.xml +++ b/pom.xml @@ -694,7 +694,7 @@ com.github.siom79.japicmp japicmp-maven-plugin - 0.25.1 + 0.25.4 true From 6dc0020ca4b79c7cbd485dd2e937d4147ad7c4be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Jan 2026 11:10:48 +0100 Subject: [PATCH 1893/1962] chore(deps): bump ruby/setup-ruby from 1.279.0 to 1.282.0 (#6399) Bumps [ruby/setup-ruby](https://github.com/ruby/setup-ruby) from 1.279.0 to 1.282.0. - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/b90be12699fdfcbee4440c2bba85f6f460446bb0...4fc31e1c823882afd7ef55985266a526c589de90) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-version: 1.282.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 4 ++-- .github/workflows/publish-release.yml | 2 +- .github/workflows/publish-snapshot.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f620705da1f..1a81ba43715 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -280,7 +280,7 @@ jobs: -Pgenerate-rule-docs,fastSkip \ -DskipTests -Dassembly.skipAssembly=true - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 #v1.279.0 + uses: ruby/setup-ruby@4fc31e1c823882afd7ef55985266a526c589de90 #v1.282.0 with: ruby-version: 3.3 - name: Setup bundler @@ -321,7 +321,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 #v1.279.0 + uses: ruby/setup-ruby@4fc31e1c823882afd7ef55985266a526c589de90 #v1.282.0 with: ruby-version: 3.3 - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb #v5.0.1 diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index fb69e22b3e0..ec841804443 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -632,7 +632,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 #v1.279.0 + uses: ruby/setup-ruby@4fc31e1c823882afd7ef55985266a526c589de90 #v1.282.0 with: ruby-version: 3.3 - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb #v5.0.1 diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index e17e6fe4d1b..5c08e151683 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -649,7 +649,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 #v1.279.0 + uses: ruby/setup-ruby@4fc31e1c823882afd7ef55985266a526c589de90 #v1.282.0 with: ruby-version: 3.3 - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb #v5.0.1 From 58044b71526c9a2a29304815c82261a3d881b2a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Jan 2026 11:17:04 +0100 Subject: [PATCH 1894/1962] chore(deps): bump org.sonatype.central:central-publishing-maven-plugin from 0.9.0 to 0.10.0 (#6401) chore(deps): bump org.sonatype.central:central-publishing-maven-plugin Bumps [org.sonatype.central:central-publishing-maven-plugin](https://github.com/sonatype/central-publishing-maven-plugin) from 0.9.0 to 0.10.0. - [Commits](https://github.com/sonatype/central-publishing-maven-plugin/commits) --- updated-dependencies: - dependency-name: org.sonatype.central:central-publishing-maven-plugin dependency-version: 0.10.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4b0745749b2..8ab2effaf3d 100644 --- a/pom.xml +++ b/pom.xml @@ -649,7 +649,7 @@ org.sonatype.central central-publishing-maven-plugin - 0.9.0 + 0.10.0 org.jacoco From 25df3cccb46b9f76f73d295b4a9898ff42b38f83 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Jan 2026 11:17:52 +0100 Subject: [PATCH 1895/1962] chore(deps): bump com.google.protobuf:protobuf-java from 4.33.2 to 4.33.4 (#6403) chore(deps): bump com.google.protobuf:protobuf-java Bumps [com.google.protobuf:protobuf-java](https://github.com/protocolbuffers/protobuf) from 4.33.2 to 4.33.4. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Commits](https://github.com/protocolbuffers/protobuf/commits) --- updated-dependencies: - dependency-name: com.google.protobuf:protobuf-java dependency-version: 4.33.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8ab2effaf3d..6c35dee386c 100644 --- a/pom.xml +++ b/pom.xml @@ -1138,7 +1138,7 @@ com.google.protobuf protobuf-java - 4.33.2 + 4.33.4 + 7.20.0 net.sourceforge.pmd pmd-java - 7.19.0 + 7.20.0 net.sourceforge.pmd pmd-jsp - 7.19.0 + 7.20.0 net.sourceforge.pmd pmd-javascript - 7.19.0 + 7.20.0 net.sourceforge.pmd pmd-xml - 7.19.0 + 7.20.0 From 95cb4f9df37bfbf85f7f333c5488c7d30777839c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 13 Nov 2025 17:33:19 +0100 Subject: [PATCH 1898/1962] [java] New Rule PublicMemberInNonPublicType --- docs/pages/release_notes.md | 6 ++ .../main/resources/category/java/design.xml | 44 ++++++++++++++ .../resources/rulesets/java/quickstart.xml | 1 + .../PublicMemberInNonPublicTypeTest.java | 11 ++++ .../xml/PublicMemberInNonPublicType.xml | 57 +++++++++++++++++++ 5 files changed, 119 insertions(+) create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/PublicMemberInNonPublicTypeTest.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/PublicMemberInNonPublicType.xml diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..3974d260af5 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -24,6 +24,12 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy +### ๐ŸŒŸ๏ธ New and Changed Rules +#### New Rules +* The new Java rule {% rule java/design/PublicMemberInNonPublicType %} finds public members + (like methods or fields) in types, that are not public as well but package-private. Their effective + visibility will be package-private anyway, so declaring them "public" is just confusing. + ### ๐Ÿ›๏ธ Fixed Issues ### ๐Ÿšจ๏ธ API Changes diff --git a/pmd-java/src/main/resources/category/java/design.xml b/pmd-java/src/main/resources/category/java/design.xml index 20aade890cf..dbfc374c118 100644 --- a/pmd-java/src/main/resources/category/java/design.xml +++ b/pmd-java/src/main/resources/category/java/design.xml @@ -1058,6 +1058,50 @@ public class Foo { + + +A package-private type should not contain members that are public. Their effective visibility will +be package-private anyway, so declaring them "public" is just confusing. If the type is later +made public, then suddenly all members are public as well, which might not be intended. + +These members should be made package-private as well or even private. + + 3 + + + + + + + + --> + diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/PublicMemberInNonPublicTypeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/PublicMemberInNonPublicTypeTest.java new file mode 100644 index 00000000000..fe158350c1a --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/PublicMemberInNonPublicTypeTest.java @@ -0,0 +1,11 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.design; + +import net.sourceforge.pmd.test.PmdRuleTst; + +class PublicMemberInNonPublicTypeTest extends PmdRuleTst { + // no additional unit tests +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/PublicMemberInNonPublicType.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/PublicMemberInNonPublicType.xml new file mode 100644 index 00000000000..2345cbd27e8 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/PublicMemberInNonPublicType.xml @@ -0,0 +1,57 @@ + + + + + Rule example + 2 + 2,3 + + + + + More declarations + 8 + 2,3,8,10,11,14,15,19 + + + From a144f39101d3edc6555544da91207ab60096afca Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 15 Jan 2026 15:39:04 +0100 Subject: [PATCH 1899/1962] [java] PublicMemberInNonPublicType: Fixes from review --- docs/pages/release_notes.md | 2 +- pmd-java/src/main/resources/category/java/design.xml | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 3974d260af5..f834106afda 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -27,7 +27,7 @@ This is a {{ site.pmd.release_type }} release. ### ๐ŸŒŸ๏ธ New and Changed Rules #### New Rules * The new Java rule {% rule java/design/PublicMemberInNonPublicType %} finds public members - (like methods or fields) in types, that are not public as well but package-private. Their effective + (like methods or fields) in types, that are not public. Their effective visibility will be package-private anyway, so declaring them "public" is just confusing. ### ๐Ÿ›๏ธ Fixed Issues diff --git a/pmd-java/src/main/resources/category/java/design.xml b/pmd-java/src/main/resources/category/java/design.xml index dbfc374c118..cec2a93a712 100644 --- a/pmd-java/src/main/resources/category/java/design.xml +++ b/pmd-java/src/main/resources/category/java/design.xml @@ -1060,8 +1060,7 @@ public class Foo { @@ -1069,7 +1068,7 @@ A package-private type should not contain members that are public. Their effecti be package-private anyway, so declaring them "public" is just confusing. If the type is later made public, then suddenly all members are public as well, which might not be intended. -These members should be made package-private as well or even private. +These members should be made package-private or even private. 3 From 9af1bdecbd466be7022756a19ba8a1e7c78f1b49 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 15 Jan 2026 15:40:54 +0100 Subject: [PATCH 1900/1962] [java] PublicMemberInNonPublicType: Ignore interfaces Members of interfaces are implicitly public. --- .../main/resources/category/java/design.xml | 1 + .../xml/PublicMemberInNonPublicType.xml | 63 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/pmd-java/src/main/resources/category/java/design.xml b/pmd-java/src/main/resources/category/java/design.xml index cec2a93a712..2bcb3028d61 100644 --- a/pmd-java/src/main/resources/category/java/design.xml +++ b/pmd-java/src/main/resources/category/java/design.xml @@ -1080,6 +1080,7 @@ These members should be made package-private or even private. [@EffectiveVisibility != 'public'] [@Visibility = 'public'] [@Overridden = false() or not(@Overridden)] + [not(ancestor::ClassDeclaration[@Interface = true()] or ancestor::AnnotationTypeDeclaration)] ]]> diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/PublicMemberInNonPublicType.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/PublicMemberInNonPublicType.xml index 2345cbd27e8..342df3f3d2e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/PublicMemberInNonPublicType.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/PublicMemberInNonPublicType.xml @@ -54,4 +54,67 @@ record MyRecord(String a) { } ]]> + + + Members of top-level interface are implicitly public + 0 + +/*package*/ interface Intf { + String CONST = "constant"; + public static final String CONST2 = "constant"; + + void method1(); + public abstract void method2(); + + default void method3() {}; + public default void method4() {}; + + class MemberClass {} + public static class MemberClass2 {} + + enum MemberEnum { A } + public enum MemberEnum2 { A } +} + + + + + Members of top-level annotation interface are implicitly public + 0 + +/*package*/ @interface Annot { + String value(); + public String value2(); +} + + + + + Members of nested interface are implicitly public + 1 + 2-2 + +/*package*/ class TopLevel { + public interface PublicIntf {} // violation here + /*package*/ interface Intf { + // fields are implicit public + String CONST = "constant"; + public static final String CONST2 = "constant"; + + void method1(); + public abstract void method2(); + + default void method3() {}; + public default void method4() {}; + + class MemberClass {} + public static class MemberClass2 {} + } + + /*package*/ @interface Annot { + String value(); + } +} + + From dfced8469e2418480efde0ff68f44e79d27dc1fb Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 15 Jan 2026 16:40:12 +0100 Subject: [PATCH 1901/1962] [java] PublicMemberInNonPublicType: Improve rule description and tests --- docs/pages/release_notes.md | 4 +- .../main/resources/category/java/design.xml | 18 ++++++--- .../xml/PublicMemberInNonPublicType.xml | 40 ++++++++++++++++++- 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index f834106afda..a78b9d806a9 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -27,8 +27,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐ŸŒŸ๏ธ New and Changed Rules #### New Rules * The new Java rule {% rule java/design/PublicMemberInNonPublicType %} finds public members - (like methods or fields) in types, that are not public. Their effective - visibility will be package-private anyway, so declaring them "public" is just confusing. + (like methods or fields) in types, that are not public. A non-public type should not have public members, + as their visibility is effectively limited and using the public modifier creates confusion. ### ๐Ÿ›๏ธ Fixed Issues diff --git a/pmd-java/src/main/resources/category/java/design.xml b/pmd-java/src/main/resources/category/java/design.xml index 2bcb3028d61..a1aeea6a5e2 100644 --- a/pmd-java/src/main/resources/category/java/design.xml +++ b/pmd-java/src/main/resources/category/java/design.xml @@ -1061,14 +1061,20 @@ public class Foo { -A package-private type should not contain members that are public. Their effective visibility will -be package-private anyway, so declaring them "public" is just confusing. If the type is later -made public, then suddenly all members are public as well, which might not be intended. - -These members should be made package-private or even private. +A non-public type should not contain members with public visibility. In such cases, their actual accessibility +is constrained to private, package-private, or protected, making the use of the public modifier misleading. +Declaring members as public within a non-public type creates confusion and can lead to unintended consequences +if the type is later made public, as this would expose all its public members. + +To avoid such issues, these members should be declared as protected, package-private, or even private, +as appropriate. Note that altering the visibility of such members might unintentionally affect the API +of a public subtype. Specifically, a public subtype of a package-private supertype inherits all public +methods of the supertype. Converting these methods to private removes them from the subtype as well, which +can inadvertently change the subtype's public API. 3 @@ -1081,6 +1087,8 @@ These members should be made package-private or even private. [@Visibility = 'public'] [@Overridden = false() or not(@Overridden)] [not(ancestor::ClassDeclaration[@Interface = true()] or ancestor::AnnotationTypeDeclaration)] +(: Make sure, we return nodes that implement getName() for {0} in the rule message :) +!(if (self::FieldDeclaration) then VariableDeclarator else .) ]]> diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/PublicMemberInNonPublicType.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/PublicMemberInNonPublicType.xml index 342df3f3d2e..3658f596280 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/PublicMemberInNonPublicType.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/PublicMemberInNonPublicType.xml @@ -7,7 +7,11 @@ Rule example 2 - 2,3 + 2-2,3-3 + + Public member 'method' declared in a non-public type + Public member 'field' declared in a non-public type + More declarations 8 2,3,8,10,11,14,15,19 + + Public member 'PackagePrivateClass' declared in a non-public type + Public member 'publicMethod' declared in a non-public type + Public member 'field' declared in a non-public type + Public member 'Nested' declared in a non-public type + Public member 'Foo' declared in a non-public type + Public member 'Intf' declared in a non-public type + Public member 'Annotation' declared in a non-public type + Public member 'MyRecord' declared in a non-public type + + + Verify location of violation + 4 + 4-4,10-10,14-14,15-15 + + + Members of top-level interface are implicitly public 0 From 775cdd1a5ce806298619f26298937cfbcc27adc3 Mon Sep 17 00:00:00 2001 From: Thomas Leplus Date: Thu, 13 Nov 2025 21:05:39 +0100 Subject: [PATCH 1902/1962] [java] New rule DoNotUseUnsafe --- .../main/resources/category/java/security.xml | 32 +++++ .../resources/rulesets/java/quickstart.xml | 1 + .../rule/security/DoNotUseUnsafeTest.java | 11 ++ .../java/rule/security/xml/DoNotUseUnsafe.xml | 120 ++++++++++++++++++ 4 files changed, 164 insertions(+) create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/security/DoNotUseUnsafeTest.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/security/xml/DoNotUseUnsafe.xml diff --git a/pmd-java/src/main/resources/category/java/security.xml b/pmd-java/src/main/resources/category/java/security.xml index 0bc45a49e9a..6faea64315e 100644 --- a/pmd-java/src/main/resources/category/java/security.xml +++ b/pmd-java/src/main/resources/category/java/security.xml @@ -8,6 +8,38 @@ Rules that flag potential security flaws. + + +Do not use either `sun.misc.Unsafe` or `jdk.internal.misc.Unsafe`. As there class name indicates, these methods are not safe to use. They have been superseded by official APIs like the VarHandle API (JDK 9) and the Foreign Function & Memory API (JDK 22). See [JEP 471](https://openjdk.org/jeps/471) for details on the safer alternatives including before and after code samples. + + 3 + + + //MethodCall[pmd-java:matchesSig('sun.misc.Unsafe#_(_*)') or pmd-java:matchesSig('jdk.internal.misc.Unsafe#_(_*)')] + + + + + + + --> + diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/security/DoNotUseUnsafeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/security/DoNotUseUnsafeTest.java new file mode 100644 index 00000000000..5d62efc9c73 --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/security/DoNotUseUnsafeTest.java @@ -0,0 +1,11 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.rule.security; + +import net.sourceforge.pmd.test.PmdRuleTst; + +class DoNotUseUnsafeTest extends PmdRuleTst { + // no additional unit tests +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/security/xml/DoNotUseUnsafe.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/security/xml/DoNotUseUnsafe.xml new file mode 100644 index 00000000000..f080e963ef3 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/security/xml/DoNotUseUnsafe.xml @@ -0,0 +1,120 @@ + + + + + Use sun.misc.Unsafe, bad + 1 + + + + + Use sun.misc.Unsafe qualified, bad + 1 + + + + + Use jdk.internal.misc.Unsafe, bad + 1 + + + + + Use jdk.internal.misc.Unsafe qualified, bad + 1 + + + + + Use foo.bar.Unsafe, good + 0 + + + + + Do not sun.misc.Unsafe, good + 0 + + + From bcf296af2a92d85616a17b0fc288bfdd5fd8d83d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 15 Jan 2026 17:47:08 +0100 Subject: [PATCH 1903/1962] [java] Move DoNotUseUnsafe to errorprone --- .../resources/category/java/errorprone.xml | 35 +++++++++++++++++++ .../main/resources/category/java/security.xml | 32 ----------------- .../resources/rulesets/java/quickstart.xml | 2 +- .../DoNotUseUnsafeTest.java | 2 +- .../xml/DoNotUseUnsafe.xml | 0 5 files changed, 37 insertions(+), 34 deletions(-) rename pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/{security => errorprone}/DoNotUseUnsafeTest.java (79%) rename pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/{security => errorprone}/xml/DoNotUseUnsafe.xml (100%) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 2383ed7754d..143ee267e40 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -1553,6 +1553,41 @@ public class Foo { + + +Do not use either `sun.misc.Unsafe` or `jdk.internal.misc.Unsafe`. As there class name indicates, +these methods are not safe to use. They have been superseded by official APIs like the VarHandle API (JDK 9) +and the Foreign Function & Memory API (JDK 22). See [JEP 471](https://openjdk.org/jeps/471) for details +on the safer alternatives including before and after code samples. + + 3 + + + //MethodCall[pmd-java:matchesSig('sun.misc.Unsafe#_(_*)') or pmd-java:matchesSig('jdk.internal.misc.Unsafe#_(_*)')] + + + + + + + - - -Do not use either `sun.misc.Unsafe` or `jdk.internal.misc.Unsafe`. As there class name indicates, these methods are not safe to use. They have been superseded by official APIs like the VarHandle API (JDK 9) and the Foreign Function & Memory API (JDK 22). See [JEP 471](https://openjdk.org/jeps/471) for details on the safer alternatives including before and after code samples. - - 3 - - - //MethodCall[pmd-java:matchesSig('sun.misc.Unsafe#_(_*)') or pmd-java:matchesSig('jdk.internal.misc.Unsafe#_(_*)')] - - - - - - - + @@ -339,5 +340,4 @@ - diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/security/DoNotUseUnsafeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DoNotUseUnsafeTest.java similarity index 79% rename from pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/security/DoNotUseUnsafeTest.java rename to pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DoNotUseUnsafeTest.java index 5d62efc9c73..0c6e14c1257 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/security/DoNotUseUnsafeTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DoNotUseUnsafeTest.java @@ -2,7 +2,7 @@ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ -package net.sourceforge.pmd.lang.java.rule.security; +package net.sourceforge.pmd.lang.java.rule.errorprone; import net.sourceforge.pmd.test.PmdRuleTst; diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/security/xml/DoNotUseUnsafe.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/DoNotUseUnsafe.xml similarity index 100% rename from pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/security/xml/DoNotUseUnsafe.xml rename to pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/DoNotUseUnsafe.xml From 87ddf8cd9cd03751c97a2b0a6c874b88b79f95c6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 15 Jan 2026 18:11:39 +0100 Subject: [PATCH 1904/1962] [java] Rename DoNotUseUnsafe to UnsupportedJdkApiUsage And integrate rule DontImportSun. --- .../resources/category/java/errorprone.xml | 80 +++++++++++-------- .../resources/rulesets/java/quickstart.xml | 2 +- ...t.java => UnsupportedJdkApiUsageTest.java} | 2 +- ...eUnsafe.xml => UnsupportedJdkApiUsage.xml} | 33 ++++++-- 4 files changed, 74 insertions(+), 43 deletions(-) rename pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/{DoNotUseUnsafeTest.java => UnsupportedJdkApiUsageTest.java} (80%) rename pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/{DoNotUseUnsafe.xml => UnsupportedJdkApiUsage.xml} (76%) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 143ee267e40..14e71f3a1ce 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -1553,41 +1553,6 @@ public class Foo { - - -Do not use either `sun.misc.Unsafe` or `jdk.internal.misc.Unsafe`. As there class name indicates, -these methods are not safe to use. They have been superseded by official APIs like the VarHandle API (JDK 9) -and the Foreign Function & Memory API (JDK 22). See [JEP 471](https://openjdk.org/jeps/471) for details -on the safer alternatives including before and after code samples. - - 3 - - - //MethodCall[pmd-java:matchesSig('sun.misc.Unsafe#_(_*)') or pmd-java:matchesSig('jdk.internal.misc.Unsafe#_(_*)')] - - - - - - - + + + Avoid importing classes or using APIs from the `sun.*` packages, including `sun.misc.Unsafe` or + `jdk.internal.misc.Unsafe`. These packages are neither portable nor stable and may change or be removed in future + versions of the JDK. As the name implies, the `Unsafe` class methods are particularly dangerous and have been + superseded by safer alternatives, such as the VarHandle API (introduced in JDK 9) and the + Foreign Function & Memory API (introduced in JDK 22). Refer to [JEP 471](https://openjdk.org/jeps/471) + for safer alternatives with examples. + + If you must depend on Sun APIs, confine their usage to a minimal, isolated scope, such as within a stable + wrapper class. You may suppress this rule in the implementation of such a wrapper, but itโ€™s strongly + recommended to migrate to official APIs wherever possible. + + The use of such unsupported APIs will also be flagged by the Java compiler, as they are intended + strictly for internal purposes. This PMD rule has been added to facilitate independent code reviews + and to catch instances where compiler warnings may have been overlooked. + + 3 + + + + //ImportDeclaration[starts-with(@ImportedName, 'sun.')] + | + //MethodCall[pmd-java:matchesSig('sun.misc.Unsafe#_(_*)') or pmd-java:matchesSig('jdk.internal.misc.Unsafe#_(_*)')] + + + + + + + + - @@ -286,6 +285,7 @@ + diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DoNotUseUnsafeTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnsupportedJdkApiUsageTest.java similarity index 80% rename from pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DoNotUseUnsafeTest.java rename to pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnsupportedJdkApiUsageTest.java index 0c6e14c1257..ccead2e3141 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DoNotUseUnsafeTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/UnsupportedJdkApiUsageTest.java @@ -6,6 +6,6 @@ import net.sourceforge.pmd.test.PmdRuleTst; -class DoNotUseUnsafeTest extends PmdRuleTst { +class UnsupportedJdkApiUsageTest extends PmdRuleTst { // no additional unit tests } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/DoNotUseUnsafe.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UnsupportedJdkApiUsage.xml similarity index 76% rename from pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/DoNotUseUnsafe.xml rename to pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UnsupportedJdkApiUsage.xml index f080e963ef3..4bae044b3d9 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/DoNotUseUnsafe.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UnsupportedJdkApiUsage.xml @@ -6,10 +6,11 @@ Use sun.misc.Unsafe, bad - 1 + 2 + 2-2,10-10 - Do not sun.misc.Unsafe, good - 0 + Only import sun.misc.Unsafe, no usage + 1 + 1-1 + + + bad, import from sun. (from rule DontImportSun) + 1 + + + + + signal is not ok (from rule DontImportSun) + 1 + + + From a05a6afa4019f0dba9fa7f954fca882eaa61d3f6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 15 Jan 2026 18:25:26 +0100 Subject: [PATCH 1905/1962] [java] Deprecate rule DontImportSun --- pmd-java/src/main/resources/category/java/errorprone.xml | 4 ++++ .../pmd/lang/java/rule/errorprone/DontImportSunTest.java | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 14e71f3a1ce..ed963fedff8 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -1556,6 +1556,7 @@ public class Foo { @@ -1566,6 +1567,9 @@ and are likely to change. If you find yourself having to depend on Sun APIs, confine this dependency to as small a scope as possible, for instance by writing a stable wrapper class around the unstable API. You can then suppress this rule in the implementation of the wrapper. + +**Deprecated:** This rule is deprecated since PMD 7.21.0 and will be removed with PMD 8.0.0. +This rule has been replaced by {% rule UnsupportedJdkApiUsage %}. 4 diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DontImportSunTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DontImportSunTest.java index 358bb02e850..93387d80421 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DontImportSunTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/errorprone/DontImportSunTest.java @@ -6,6 +6,10 @@ import net.sourceforge.pmd.test.PmdRuleTst; +/** + * @deprecated Since 7.21.0. Replaced by {@link UnsupportedJdkApiUsageTest}. + */ +@Deprecated class DontImportSunTest extends PmdRuleTst { // no additional unit tests } From 43883f659cf93e1e0878fdd9770c239a2d4f3408 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 15 Jan 2026 18:36:58 +0100 Subject: [PATCH 1906/1962] [java] UnsupportedJdkApiUsage: recognize jdk.internal --- .../resources/category/java/errorprone.xml | 4 ++-- .../errorprone/xml/UnsupportedJdkApiUsage.xml | 21 ++++++++++++++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index ed963fedff8..25fd6593951 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -3371,7 +3371,7 @@ public String convert(int x) { class="net.sourceforge.pmd.lang.rule.xpath.XPathRule" externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#unsupportedjdkapiusage"> - Avoid importing classes or using APIs from the `sun.*` packages, including `sun.misc.Unsafe` or + Avoid importing classes or using APIs from the `sun.*` or `jdk.internal.*` packages, including `sun.misc.Unsafe` or `jdk.internal.misc.Unsafe`. These packages are neither portable nor stable and may change or be removed in future versions of the JDK. As the name implies, the `Unsafe` class methods are particularly dangerous and have been superseded by safer alternatives, such as the VarHandle API (introduced in JDK 9) and the @@ -3390,7 +3390,7 @@ public String convert(int x) { - //ImportDeclaration[starts-with(@ImportedName, 'sun.')] + //ImportDeclaration[starts-with(@ImportedName, 'sun.') or starts-with(@ImportedName, 'jdk.internal.')] | //MethodCall[pmd-java:matchesSig('sun.misc.Unsafe#_(_*)') or pmd-java:matchesSig('jdk.internal.misc.Unsafe#_(_*)')] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UnsupportedJdkApiUsage.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UnsupportedJdkApiUsage.xml index 4bae044b3d9..6b3a7f1f220 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UnsupportedJdkApiUsage.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UnsupportedJdkApiUsage.xml @@ -46,7 +46,9 @@ class BadUnsafeSunQualified { Use jdk.internal.misc.Unsafe, bad - 1 + + 2 + 2-2,10-10 + + package com.sun is ok + 0 + + + + + package jdk.internal is internal + 1 + + From d47aa8462a0533a56a948b19de90435af575a57a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 15 Jan 2026 18:40:40 +0100 Subject: [PATCH 1907/1962] [java] UnsupportedJdkApiUsage: verify location of violation --- .../errorprone/xml/UnsupportedJdkApiUsage.xml | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UnsupportedJdkApiUsage.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UnsupportedJdkApiUsage.xml index 6b3a7f1f220..ca18669c3bc 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UnsupportedJdkApiUsage.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UnsupportedJdkApiUsage.xml @@ -4,11 +4,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests http://pmd.sourceforge.net/rule-tests_1_0_0.xsd"> - - Use sun.misc.Unsafe, bad - 2 - 2-2,10-10 - + ]]> + + + Use sun.misc.Unsafe, bad + 2 + 2,10 + + + + + Verify location of violation + 2 + 2-2,10-10 + @@ -46,7 +55,6 @@ class BadUnsafeSunQualified { Use jdk.internal.misc.Unsafe, bad - 2 2-2,10-10 Date: Thu, 15 Jan 2026 18:46:15 +0100 Subject: [PATCH 1908/1962] [java] UnsupportedJdkApiUsage: release notes --- docs/pages/release_notes.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..fb3b6bc2f5b 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -24,7 +24,20 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy +### ๐ŸŒŸ๏ธ New and Changed Rules +#### New Rules +* The new Java rule {% rule java/errorprone/UnsupportedJdkApiUsage %} flags the use of unsupported and non-portable + JDK APIs, including `sun.*` packages, `sun.misc.Unsafe`, and `jdk.internal.misc.Unsafe`. These APIs are unstable, + intended for internal use, and may change or be removed. The rule complements Java compiler warnings by + highlighting such usage during code reviews and encouraging migration to official APIs like VarHandle and + the Foreign Function & Memory API. +#### Deprecated Rules +* The Java rule {% rule java/errorprone/DontImportSun %} has been deprecated. It is replaced by + {% rule java/error/UnsupportedJdkApiUsage %}. + ### ๐Ÿ›๏ธ Fixed Issues +* java + * [#5923](https://github.com/pmd/pmd/issues/5923): \[java] New rule: Catch usages of sun.misc.Unsafe or jdk.internal.misc.Unsafe ### ๐Ÿšจ๏ธ API Changes From 1d79133f9bf50f8a377d09e0e1f51d4bd504a3c8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 15 Jan 2026 19:12:27 +0100 Subject: [PATCH 1909/1962] [java] UnsupportedJdkApiUsage - fix release notes --- docs/pages/release_notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index fb3b6bc2f5b..9355a4bdfd0 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -33,7 +33,7 @@ This is a {{ site.pmd.release_type }} release. the Foreign Function & Memory API. #### Deprecated Rules * The Java rule {% rule java/errorprone/DontImportSun %} has been deprecated. It is replaced by - {% rule java/error/UnsupportedJdkApiUsage %}. + {% rule java/errorprone/UnsupportedJdkApiUsage %}. ### ๐Ÿ›๏ธ Fixed Issues * java From e6cf3807f7ff1cf4acae7ae5603d118ded2befa3 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 16 Jan 2026 09:44:25 +0100 Subject: [PATCH 1910/1962] Fixes from review --- docs/pages/release_notes.md | 5 ++++- .../sourceforge/pmd/properties/PropertyFactory.java | 3 +++ .../lang/rule/MockRuleWithDeprecatedProperties.java | 10 +++++----- .../sourceforge/pmd/doc/internal/RuleDocGenerator.java | 2 +- pmd-doc/src/test/resources/expected/sample.md | 4 ++-- .../AvoidBranchingStatementAsLastInLoopRule.java | 8 ++++---- .../metrics/impl/JavaIntMetricWithOptionsTestRule.java | 2 +- 7 files changed, 20 insertions(+), 14 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index b8e60edcdb4..ebba55c653a 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -55,7 +55,7 @@ rule properties: #### Deprecations * core - * {%jdoc !!core::lang.metrics.MetricOption#valueName %}: When metrics are used for (rule) properties, + * {%jdoc !!core::lang.metrics.MetricOption#valueName() %}: When metrics are used for (rule) properties, then the conventional enum mapping (from SCREAMING_SNAKE_CASE to camelCase) will be used for the enum values. See {%jdoc core::properties.PropertyFactory#conventionalEnumListProperty(java.lang.String, java.lang.Class) %}. * In {%jdoc core::properties.PropertyFactory %}: @@ -91,6 +91,9 @@ rule properties: This method should have been private and will be internalized. * {%jdoc !c!java::lang.java.rule.errorprone.AvoidBranchingStatementAsLastInLoopRule#checksNothing() %}. This method should have been private and will be internalized. + * {%jdoc !!java::lang.java.metrics.JavaMetrics.ClassFanOutOption#valueName() %}, + {%jdoc !!java::lang.java.metrics.JavaMetrics.CycloOption#valueName() %}, + {%jdoc !!java::lang.java.metrics.JavaMetrics.NcssOption#valueName() %} * lang-test * {%jdoc !c!lang-test::lang.test.AbstractMetricTestRule#optionMappings() %}. No extra mapping is required anymore. The {%jdoc core::lang.metrics.MetricOption %} enum values are used. See diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java index e2d30715dc5..6e370f99689 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyFactory.java @@ -379,6 +379,7 @@ public static > GenericPropertyBuilder enumProperty(String * @param Type of the enum class * * @return A new builder + * @since 7.21.0 */ public static > GenericPropertyBuilder conventionalEnumProperty(String name, Class enumClass) { return enumPropertyTransitional(name, enumClass, Collections.emptyMap()); @@ -401,6 +402,7 @@ public static > GenericPropertyBuilder conventionalEnumProp * @param Type of the enum class * * @return a new builder + * @since 7.21.0 */ public static > GenericPropertyBuilder enumPropertyTransitional(String name, Class enumClass, @@ -421,6 +423,7 @@ public static > GenericPropertyBuilder enumPropertyTransiti * @param Value type of the property * * @return A new builder + * @since 7.21.0 */ public static > GenericCollectionPropertyBuilder> conventionalEnumListProperty(String name, Class enumClass) { return conventionalEnumProperty(name, enumClass).toList(); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/MockRuleWithDeprecatedProperties.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/MockRuleWithDeprecatedProperties.java index 3bdec5789b8..cf573616d43 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/MockRuleWithDeprecatedProperties.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/MockRuleWithDeprecatedProperties.java @@ -4,11 +4,11 @@ package net.sourceforge.pmd.lang.rule; -import java.util.HashMap; import java.util.Map; import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.properties.PropertyFactory; +import net.sourceforge.pmd.util.CollectionUtil; public class MockRuleWithDeprecatedProperties extends MockRuleWithNoProperties { static final PropertyDescriptor STRING_PROPERTY = PropertyFactory.stringProperty("stringProp") @@ -25,10 +25,10 @@ SampleEnum.class, getDeprecatedMapping()) .build(); private static Map getDeprecatedMapping() { - Map map = new HashMap<>(); - map.put("a", SampleEnum.VALUE_A); - map.put("b", SampleEnum.VALUE_B); - return map; + return CollectionUtil.mapOf( + "a", SampleEnum.VALUE_A, + "b", SampleEnum.VALUE_B + ); } public MockRuleWithDeprecatedProperties() { diff --git a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java index 1344d9fafe9..400df354e89 100644 --- a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java +++ b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/internal/RuleDocGenerator.java @@ -496,7 +496,7 @@ private void generateRuleSetIndex(Map> rulesets) throws Set enumValues = propertyDescriptor.serializer().enumeratedValues(); if (!enumValues.isEmpty()) { if (propertyDescriptor.serializer().isCollection()) { - enumValuesDescription = "
            One or more of: "; + enumValuesDescription = "
            Zero or more of: "; enumValues = enumValues.stream().map(Collections::singleton).collect(Collectors.toSet()); } else { enumValuesDescription = "
            One of: "; diff --git a/pmd-doc/src/test/resources/expected/sample.md b/pmd-doc/src/test/resources/expected/sample.md index 78b4f55657d..15c2c344355 100644 --- a/pmd-doc/src/test/resources/expected/sample.md +++ b/pmd-doc/src/test/resources/expected/sample.md @@ -603,9 +603,9 @@ This rule is for testing enum properties |Name|Default Value|Description| |----|-------------|-----------| |enumPropertyNew|optionOne|Description
            One of: `optionOne`, `optionTwo`| -|enumListPropertyNew||Description
            One or more of: `optionOne`, `optionTwo`| +|enumListPropertyNew||Description
            Zero or more of: `optionOne`, `optionTwo`| |enumProperty|OPTION\_ONE|Description
            One of: `OPTION\_ONE`, `OPTION\_TWO`| -|enumListProperty||Description
            One or more of: `OPTION\_ONE`, `OPTION\_TWO`| +|enumListProperty||Description
            Zero or more of: `OPTION\_ONE`, `OPTION\_TWO`| **Use this rule with the default properties by just referencing it:** ``` xml diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java index cd4cb97e010..bb643c18e13 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/AvoidBranchingStatementAsLastInLoopRule.java @@ -29,19 +29,19 @@ public class AvoidBranchingStatementAsLastInLoopRule extends AbstractJavaRulechainRule { /** - * @since 7.21.0. Should have never been public. + * @deprecated Since 7.21.0. Should have never been public. */ @Deprecated public static final String CHECK_FOR = "for"; /** - * @since 7.21.0. Should have never been public. + * @deprecated Since 7.21.0. Should have never been public. */ @Deprecated public static final String CHECK_DO = "do"; /** - * @since 7.21.0. Should have never been public. + * @deprecated Since 7.21.0. Should have never been public. */ @Deprecated public static final String CHECK_WHILE = "while"; @@ -167,7 +167,7 @@ public String dysfunctionReason() { } /** - * @deprecated Since 7.21.0 + * @deprecated Since 7.21.0. Only used for backwards compatible property values. */ @Deprecated private static PropertyDescriptor> propertyForDeprecated(String stmtName) { diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/JavaIntMetricWithOptionsTestRule.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/JavaIntMetricWithOptionsTestRule.java index 3e6118b1757..2689b8c2acb 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/JavaIntMetricWithOptionsTestRule.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/metrics/impl/JavaIntMetricWithOptionsTestRule.java @@ -12,7 +12,7 @@ import net.sourceforge.pmd.lang.test.AbstractMetricTestRule; /** - * @since 7.21.0. + * @since 7.21.0 */ public abstract class JavaIntMetricWithOptionsTestRule & MetricOption> extends AbstractMetricTestRule.OfIntWithOptions { From 49aca582699f52bb32f0e55c0fbca2590a3e1318 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Jan 2026 10:33:56 +0100 Subject: [PATCH 1911/1962] chore(deps): bump actions/cache from 5.0.1 to 5.0.2 (#6411) Bumps [actions/cache](https://github.com/actions/cache) from 5.0.1 to 5.0.2. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/9255dc7a253b0ccc959486e2bca901246202afeb...8b402f58fbc84540c8b491a91e594a4576fec3d7) --- updated-dependencies: - dependency-name: actions/cache dependency-version: 5.0.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 12 ++++++------ .github/workflows/publish-release.yml | 2 +- .github/workflows/publish-snapshot.yml | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1a81ba43715..fc106acd78c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,7 +28,7 @@ jobs: with: distribution: 'temurin' java-version: '17' - - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb #v5.0.1 + - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 #v5.0.2 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- @@ -86,7 +86,7 @@ jobs: with: distribution: 'temurin' java-version: '17' - - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb #v5.0.1 + - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 #v5.0.2 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- @@ -141,7 +141,7 @@ jobs: # Note: this works under Windows only if pom.xml files use LF, so that hashFiles('**/pom.xml') # gives the same result (line endings...). # see .gitattributes for pom.xml - it should always be using lf. - - uses: actions/cache/restore@9255dc7a253b0ccc959486e2bca901246202afeb #v5.0.1 + - uses: actions/cache/restore@8b402f58fbc84540c8b491a91e594a4576fec3d7 #v5.0.2 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- @@ -177,7 +177,7 @@ jobs: with: distribution: 'temurin' java-version: '17' - - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb #v5.0.1 + - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 #v5.0.2 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- @@ -263,7 +263,7 @@ jobs: with: distribution: 'temurin' java-version: '17' - - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb #v5.0.1 + - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 #v5.0.2 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- @@ -324,7 +324,7 @@ jobs: uses: ruby/setup-ruby@4fc31e1c823882afd7ef55985266a526c589de90 #v1.282.0 with: ruby-version: 3.3 - - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb #v5.0.1 + - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 #v5.0.2 with: path: | ~/.m2/repository diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index ec841804443..2fd06808a7b 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -635,7 +635,7 @@ jobs: uses: ruby/setup-ruby@4fc31e1c823882afd7ef55985266a526c589de90 #v1.282.0 with: ruby-version: 3.3 - - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb #v5.0.1 + - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 #v5.0.2 with: path: | ~/.m2/repository diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 5c08e151683..9a38acec31f 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -88,7 +88,7 @@ jobs: server-password: MAVEN_PASSWORD gpg-passphrase: MAVEN_GPG_PASSPHRASE gpg-private-key: ${{ secrets.PMD_CI_GPG_PRIVATE_KEY }} - - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb #v5.0.1 + - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 #v5.0.2 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- @@ -652,7 +652,7 @@ jobs: uses: ruby/setup-ruby@4fc31e1c823882afd7ef55985266a526c589de90 #v1.282.0 with: ruby-version: 3.3 - - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb #v5.0.1 + - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 #v5.0.2 with: path: | ~/.m2/repository @@ -733,7 +733,7 @@ jobs: with: distribution: 'temurin' java-version: '17' - - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb #v5.0.1 + - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 #v5.0.2 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- @@ -770,7 +770,7 @@ jobs: with: distribution: 'temurin' java-version: '17' - - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb #v5.0.1 + - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 #v5.0.2 with: key: maven-${{ hashFiles('**/pom.xml') }} restore-keys: maven- From d4c4e9bacba5bce74e14e41f72b9fcec6996a11b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Jan 2026 10:35:13 +0100 Subject: [PATCH 1912/1962] chore(deps): bump scalameta.version from 4.14.4 to 4.14.5 (#6412) Bumps `scalameta.version` from 4.14.4 to 4.14.5. Updates `org.scalameta:parsers_2.13` from 4.14.4 to 4.14.5 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.14.4...v4.14.5) Updates `org.scalameta:trees_2.13` from 4.14.4 to 4.14.5 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.14.4...v4.14.5) Updates `org.scalameta:parsers_2.12` from 4.14.4 to 4.14.5 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.14.4...v4.14.5) Updates `org.scalameta:trees_2.12` from 4.14.4 to 4.14.5 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.14.4...v4.14.5) --- updated-dependencies: - dependency-name: org.scalameta:parsers_2.13 dependency-version: 4.14.5 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:trees_2.13 dependency-version: 4.14.5 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:parsers_2.12 dependency-version: 4.14.5 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:trees_2.12 dependency-version: 4.14.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index a3ca74a2a3a..ee9a3afa65a 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -13,7 +13,7 @@ - 4.14.4 + 4.14.5 From f2bddd57e7cdee981c96dee50100af07ad7326f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Jan 2026 10:35:28 +0100 Subject: [PATCH 1913/1962] chore(deps): bump ruby/setup-ruby from 1.282.0 to 1.285.0 (#6410) Bumps [ruby/setup-ruby](https://github.com/ruby/setup-ruby) from 1.282.0 to 1.285.0. - [Release notes](https://github.com/ruby/setup-ruby/releases) - [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb) - [Commits](https://github.com/ruby/setup-ruby/compare/4fc31e1c823882afd7ef55985266a526c589de90...e69dcf3ded5967f30d7ef595704928d91cdae930) --- updated-dependencies: - dependency-name: ruby/setup-ruby dependency-version: 1.285.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 4 ++-- .github/workflows/publish-release.yml | 2 +- .github/workflows/publish-snapshot.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fc106acd78c..4f29ff3476b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -280,7 +280,7 @@ jobs: -Pgenerate-rule-docs,fastSkip \ -DskipTests -Dassembly.skipAssembly=true - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@4fc31e1c823882afd7ef55985266a526c589de90 #v1.282.0 + uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 #v1.286.0 with: ruby-version: 3.3 - name: Setup bundler @@ -321,7 +321,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@4fc31e1c823882afd7ef55985266a526c589de90 #v1.282.0 + uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 #v1.286.0 with: ruby-version: 3.3 - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 #v5.0.2 diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 2fd06808a7b..2a4b03fac41 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -632,7 +632,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@4fc31e1c823882afd7ef55985266a526c589de90 #v1.282.0 + uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 #v1.286.0 with: ruby-version: 3.3 - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 #v5.0.2 diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 9a38acec31f..615f722f8c7 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -649,7 +649,7 @@ jobs: 11 17 - name: Set up Ruby 3.3 - uses: ruby/setup-ruby@4fc31e1c823882afd7ef55985266a526c589de90 #v1.282.0 + uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 #v1.286.0 with: ruby-version: 3.3 - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 #v5.0.2 From aa2c54dfd4658614d243cd09c5424452887c2a5d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Jan 2026 10:36:12 +0100 Subject: [PATCH 1914/1962] chore(deps-dev): bump org.codehaus.mojo:versions-maven-plugin from 2.20.1 to 2.21.0 (#6414) chore(deps-dev): bump org.codehaus.mojo:versions-maven-plugin Bumps [org.codehaus.mojo:versions-maven-plugin](https://github.com/mojohaus/versions) from 2.20.1 to 2.21.0. - [Release notes](https://github.com/mojohaus/versions/releases) - [Changelog](https://github.com/mojohaus/versions/blob/master/ReleaseNotes.md) - [Commits](https://github.com/mojohaus/versions/compare/2.20.1...2.21.0) --- updated-dependencies: - dependency-name: org.codehaus.mojo:versions-maven-plugin dependency-version: 2.21.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 247caf76855..4fca166d6f4 100644 --- a/pom.xml +++ b/pom.xml @@ -644,7 +644,7 @@ org.codehaus.mojo versions-maven-plugin - 2.20.1 + 2.21.0 org.sonatype.central From 31a0969a7d6f9cd08b6c9c66ddffe97b1e95c8d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Jan 2026 10:36:50 +0100 Subject: [PATCH 1915/1962] chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.18.3 to 1.18.4 (#6415) chore(deps-dev): bump net.bytebuddy:byte-buddy-agent Bumps [net.bytebuddy:byte-buddy-agent](https://github.com/raphw/byte-buddy) from 1.18.3 to 1.18.4. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.18.3...byte-buddy-1.18.4) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy-agent dependency-version: 1.18.4 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4fca166d6f4..417bbf9defb 100644 --- a/pom.xml +++ b/pom.xml @@ -1048,7 +1048,7 @@ net.bytebuddy byte-buddy-agent - 1.18.3 + 1.18.4 test From cdf317fb9d8fd873df992ee614a440b9cd25e288 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Jan 2026 10:37:17 +0100 Subject: [PATCH 1916/1962] chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.18.3 to 1.18.4 (#6413) Bumps [net.bytebuddy:byte-buddy](https://github.com/raphw/byte-buddy) from 1.18.3 to 1.18.4. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.18.3...byte-buddy-1.18.4) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-version: 1.18.4 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 417bbf9defb..b6d40a57ec3 100644 --- a/pom.xml +++ b/pom.xml @@ -1042,7 +1042,7 @@ net.bytebuddy byte-buddy - 1.18.3 + 1.18.4 test From e7f56788ea859ec269cb79f19d5b8eb583eb9dfc Mon Sep 17 00:00:00 2001 From: Jade Petraglia Date: Thu, 22 Jan 2026 13:24:46 -0700 Subject: [PATCH 1917/1962] [apex] Changed ApexCpdLexer to extend AntlrCpdLexer so that "CPD-OFF" & "CPD-ON" work --- .../pmd/lang/apex/cpd/ApexCpdLexer.java | 43 ++++++++----------- .../pmd/lang/apex/cpd/ApexCpdLexerTest.java | 5 +++ .../apex/cpd/testdata/specialComments.cls | 12 ++++++ .../apex/cpd/testdata/specialComments.txt | 4 ++ 4 files changed, 40 insertions(+), 24 deletions(-) create mode 100644 pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/testdata/specialComments.cls create mode 100644 pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/testdata/specialComments.txt diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/cpd/ApexCpdLexer.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/cpd/ApexCpdLexer.java index 2c22ce75fb4..1d80ad8a7ab 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/cpd/ApexCpdLexer.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/cpd/ApexCpdLexer.java @@ -4,40 +4,35 @@ package net.sourceforge.pmd.lang.apex.cpd; -import java.io.IOException; import java.util.Locale; import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.Lexer; -import net.sourceforge.pmd.cpd.CpdLexer; -import net.sourceforge.pmd.cpd.TokenFactory; +import net.sourceforge.pmd.cpd.impl.AntlrCpdLexer; +import net.sourceforge.pmd.cpd.impl.BaseTokenFilter; +import net.sourceforge.pmd.lang.TokenManager; import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrToken; -import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrTokenManager; -import net.sourceforge.pmd.lang.document.TextDocument; import io.github.apexdevtools.apexparser.ApexLexer; import io.github.apexdevtools.apexparser.CaseInsensitiveInputStream; -public class ApexCpdLexer implements CpdLexer { - @Override - public void tokenize(TextDocument document, TokenFactory tokenEntries) throws IOException { +public class ApexCpdLexer extends AntlrCpdLexer { - CharStream charStream = CharStreams.fromReader(document.newReader()); + @Override + protected Lexer getLexerForSource(CharStream charStream) { CaseInsensitiveInputStream caseInsensitiveInputStream = new CaseInsensitiveInputStream(charStream); - ApexLexer lexer = new ApexLexer(caseInsensitiveInputStream); - AntlrTokenManager tokenManager = new AntlrTokenManager(lexer, document); - - AntlrToken token = tokenManager.getNextToken(); - - while (!token.isEof()) { - if (token.isDefault()) { // excludes WHITESPACE_CHANNEL and COMMENT_CHANNEL - String tokenText = token.getImage(); - // be case-insensitive - tokenText = tokenText.toLowerCase(Locale.ROOT); - tokenEntries.recordToken(tokenText, token.getReportLocation()); - } - token = tokenManager.getNextToken(); - } + return new ApexLexer(caseInsensitiveInputStream); + } + + @Override + protected TokenManager filterTokenStream(TokenManager tokenManager) { + return new BaseTokenFilter<>(tokenManager); + } + + @Override + protected String getImage(AntlrToken token) { + // be case-insensitive + return token.getImage().toLowerCase(Locale.ROOT); } } diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/cpd/ApexCpdLexerTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/cpd/ApexCpdLexerTest.java index 7210cbfed76..104f811b0ff 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/cpd/ApexCpdLexerTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/cpd/ApexCpdLexerTest.java @@ -42,4 +42,9 @@ void lexExceptionExpected() { void caseInsensitiveStringLiterals() { doTest("StringLiterals5053"); } + + @Test + void testIgnoreBetweenSpecialComments() { + doTest("specialComments"); + } } diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/testdata/specialComments.cls b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/testdata/specialComments.cls new file mode 100644 index 00000000000..c9375e0e360 --- /dev/null +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/testdata/specialComments.cls @@ -0,0 +1,12 @@ +// CPD-OFF +public class Foo { + public void bar() { + Integer a = 1 + 2; + a += 1; + a++; + Decimal d = 3.14; + d *= 2; + Boolean b = !(d == 2.0 || d >= 1.0 && d <= 2.0); + } +// CPD-ON +} diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/testdata/specialComments.txt b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/testdata/specialComments.txt new file mode 100644 index 00000000000..3fa3ed44b7c --- /dev/null +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/cpd/testdata/specialComments.txt @@ -0,0 +1,4 @@ + [Image] or [Truncated image[ Bcol Ecol +L12 + [}] 1 2 +EOF From 2f4b296508009ac3427b8dc991cba4ac9344e10d Mon Sep 17 00:00:00 2001 From: Jade Petraglia Date: Thu, 22 Jan 2026 14:01:09 -0700 Subject: [PATCH 1918/1962] [apex] Added temporary exclusion to pom.xml due to method still being available via inheritance AFAIK this can and should be removed after the next release --- pmd-apex/pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 6374aaf02b7..5d511c2997c 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -65,6 +65,10 @@ net.sourceforge.pmd.lang.apex.internal net.sourceforge.pmd.lang.apex.metrics.internal net.sourceforge.pmd.lang.apex.rule.internal + + + + net.sourceforge.pmd.lang.apex.cpd.ApexCpdLexer#tokenize(net.sourceforge.pmd.lang.document.TextDocument,net.sourceforge.pmd.cpd.TokenFactory)
            From 936dc94dc976613b0d80bec5c376f0da817c90af Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 23 Jan 2026 09:13:33 +0100 Subject: [PATCH 1919/1962] [java] UnconditionalIfStatement: only effectively final local vars --- .../resources/category/java/errorprone.xml | 4 +- .../xml/UnconditionalIfStatement.xml | 37 ++++++++++++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 167430d23a2..8005066008a 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -3238,8 +3238,10 @@ union //IfStatement/VariableAccess[@CompileTimeConstant = false()] [@Name = parent::IfStatement /preceding-sibling::LocalVariableDeclaration[PrimitiveType[@Kind = "boolean"]] - /VariableDeclarator + /VariableDeclarator[@Initializer = true()][BooleanLiteral] /@Name] +(: var is only initialized with a literal and used only with the if statement, there is no other var access :) +[let $name := @Name return count(ancestor::Block//VariableAccess[@Name = $name]) = 1] ]]> diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UnconditionalIfStatement.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UnconditionalIfStatement.xml index 552e8751201..2f58c7ba90e 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UnconditionalIfStatement.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/UnconditionalIfStatement.xml @@ -56,7 +56,7 @@ public class Foo { - #5882 false-negative if true/false is not literal + #5882 false-negative if true/false is not literal but local variable 1 4 + + + + #5882 false-positive if true/false is not literal but local variable modified + 0 + + + + + #5882 false-positive if true/false is not literal but local variable not a literal + 0 + From 1b4ce185e25d99ceb2050983f70bd0309be7b66c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 23 Jan 2026 09:14:01 +0100 Subject: [PATCH 1920/1962] [doc] Update release notes (#5882, #6315) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index ebba55c653a..be6570e6a26 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -50,6 +50,8 @@ rule properties: ### ๐Ÿ›๏ธ Fixed Issues * core * [#6184](https://github.com/pmd/pmd/issues/6184): \[core] Consistent implementation of enum properties +* java-errorprone + * [#5882](https://github.com/pmd/pmd/issues/5882): \[java] UnconditionalIfStatement: False negative when true/false is not literal but local variable ### ๐Ÿšจ๏ธ API Changes From 0089f141f6ce266819882e47b267a39c16cd9f72 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 23 Jan 2026 09:55:08 +0100 Subject: [PATCH 1921/1962] [java] UnconditionalIfStatement: consider negation --- .../resources/category/java/errorprone.xml | 4 +- .../xml/UnconditionalIfStatement.xml | 38 +++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index 8005066008a..945f09ae53a 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -3235,8 +3235,8 @@ Do not use "if" statements whose conditionals are always true or always false. + + #5882 false-negative if true/false is not literal but local variable negated + 1 + 4 + + + + + #5882 false-negative if true/false is not literal but local variable nested + 3 + 6,7,8 + + + #5882 false-positive if true/false is not literal but local variable modified 0 From 9ed5b1ab2d8aed5a8ff23502cffc2c66ad8d02d6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 23 Jan 2026 11:10:03 +0100 Subject: [PATCH 1922/1962] [java] InsufficientStringBufferDeclaration: ignore array access --- ...sufficientStringBufferDeclarationRule.java | 30 +++++++++---------- .../InsufficientStringBufferDeclaration.xml | 18 ++++++++++- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java index 72ea9c5f272..9898ce98246 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java @@ -12,20 +12,21 @@ import java.util.stream.Collectors; import net.sourceforge.pmd.lang.ast.Node; -import net.sourceforge.pmd.lang.java.ast.ASTArrayAccess; +import net.sourceforge.pmd.lang.ast.NodeStream; import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr.ASTNamedReferenceExpr; import net.sourceforge.pmd.lang.java.ast.ASTAssignmentExpression; import net.sourceforge.pmd.lang.java.ast.ASTCastExpression; -import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression; import net.sourceforge.pmd.lang.java.ast.ASTConstructorCall; import net.sourceforge.pmd.lang.java.ast.ASTExpression; import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; +import net.sourceforge.pmd.lang.java.ast.ASTInfixExpression; import net.sourceforge.pmd.lang.java.ast.ASTLiteral; import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; import net.sourceforge.pmd.lang.java.ast.ASTSwitchBranch; import net.sourceforge.pmd.lang.java.ast.ASTSwitchStatement; import net.sourceforge.pmd.lang.java.ast.ASTVariableAccess; import net.sourceforge.pmd.lang.java.ast.ASTVariableId; +import net.sourceforge.pmd.lang.java.ast.BinaryOp; import net.sourceforge.pmd.lang.java.ast.JavaNode; import net.sourceforge.pmd.lang.java.ast.TypeNode; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; @@ -209,20 +210,17 @@ private static int calculateExpectedLength(T expressio } private static Set collectArgumentsOfType(ASTMethodCall methodCall, Class type) { - Set conditionalNodes = methodCall.descendants(ASTConditionalExpression.class) - .map(ASTConditionalExpression::getCondition) - .descendants() - .collect(Collectors.toSet()); - - return methodCall.getArguments() - .descendants(type) - // exclude arguments, that belong to different method calls - .filter(n -> n.ancestors(ASTMethodCall.class).first() == methodCall) - // also exclude args that are used to access arrays - .filter(n -> !(n.getParent() instanceof ASTArrayAccess)) - // also exclude args that are only used in the conditional part of a conditional expression - .filter(o -> !conditionalNodes.contains(o)) - .collect(Collectors.toSet()); + return NodeStream.union( + // direct children + methodCall.getArguments().children(type), + // string concatenation + methodCall.getArguments().children(ASTInfixExpression.class) + .filter(e -> e.getOperator() == BinaryOp.ADD && TypeTestUtil.isA(String.class, e.getTypeMirror())) + .descendants(type), + // cast expressions + methodCall.getArguments().children(ASTCastExpression.class) + .children(type) + ).collect(Collectors.toSet()); } private State getConstructorCapacity(ASTVariableId variable, ASTExpression node) { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml index f5dd7003457..89f038b691d 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml @@ -1519,13 +1519,29 @@ public class Foo { public static final String[] TEST = { "xyz" }; public void bar() { - StringBuilder builder = new StringBuilder(); + StringBuilder builder = new StringBuilder(0); builder.append(TEST[0]); } } ]]> + + Access expression from array + 0 + + + Ignore values used in conditional part of conditional expression 0 From ca47a654f356e78879f40e7d68ffdc7c667be5a1 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 23 Jan 2026 11:28:35 +0100 Subject: [PATCH 1923/1962] [java] InsufficientStringBufferDeclaration: correctly consider conditional --- ...sufficientStringBufferDeclarationRule.java | 55 ++++++++++++++----- .../InsufficientStringBufferDeclaration.xml | 14 ++++- 2 files changed, 53 insertions(+), 16 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java index 9898ce98246..8cb708a3478 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java @@ -8,7 +8,6 @@ import java.util.Map; import java.util.Optional; import java.util.Set; -import java.util.function.ToIntFunction; import java.util.stream.Collectors; import net.sourceforge.pmd.lang.ast.Node; @@ -16,12 +15,14 @@ import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr.ASTNamedReferenceExpr; import net.sourceforge.pmd.lang.java.ast.ASTAssignmentExpression; import net.sourceforge.pmd.lang.java.ast.ASTCastExpression; +import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression; import net.sourceforge.pmd.lang.java.ast.ASTConstructorCall; import net.sourceforge.pmd.lang.java.ast.ASTExpression; import net.sourceforge.pmd.lang.java.ast.ASTIfStatement; import net.sourceforge.pmd.lang.java.ast.ASTInfixExpression; import net.sourceforge.pmd.lang.java.ast.ASTLiteral; import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; +import net.sourceforge.pmd.lang.java.ast.ASTNullLiteral; import net.sourceforge.pmd.lang.java.ast.ASTSwitchBranch; import net.sourceforge.pmd.lang.java.ast.ASTSwitchStatement; import net.sourceforge.pmd.lang.java.ast.ASTVariableAccess; @@ -160,26 +161,22 @@ public Object visit(ASTVariableId node, Object data) { private void processMethodCall(State state, ASTMethodCall methodCall) { if ("append".equals(methodCall.getMethodName())) { Set literals = collectArgumentsOfType(methodCall, ASTLiteral.class); - ToIntFunction literalCounter = value -> String.valueOf(value.getConstValue()).length(); - int literalsCount = literals.stream().mapToInt(value -> calculateExpectedLength(value, literalCounter)).sum(); + int literalsCount = literals.stream().mapToInt(value -> calculateExpectedLength(value)).sum(); Set variables = collectArgumentsOfType(methodCall, ASTVariableAccess.class); - ToIntFunction variablesCounter = value -> Optional.ofNullable(value.getConstFoldingResult().getValue()) - .map(constValue -> String.valueOf(constValue).length()) - .orElse(0); - int variablesCount = variables.stream().mapToInt(value -> calculateExpectedLength(value, variablesCounter)).sum(); + int variablesCount = variables.stream().mapToInt(value -> calculateExpectedLength(value)).sum(); int counter = literalsCount + variablesCount; ASTIfStatement ifStatement = methodCall.ancestors(ASTIfStatement.class).first(); - ASTSwitchStatement switchStatement = methodCall.ancestors(ASTSwitchStatement.class).first(); + ASTSwitchBranch switchBranch = methodCall.ancestors(ASTSwitchBranch.class).first(); if (ifStatement != null) { if (ifStatement.getThenBranch().descendants().any(n -> n == methodCall)) { state.addBranch(ifStatement.getThenBranch(), counter); } else if (ifStatement.getElseBranch() != null) { state.addBranch(ifStatement.getElseBranch(), counter); } - } else if (switchStatement != null) { - state.addBranch(methodCall.ancestors(ASTSwitchBranch.class).first(), counter); + } else if (switchBranch != null) { + state.addBranch(switchBranch, counter); } else { state.addAnticipatedLength(counter); } @@ -201,12 +198,39 @@ private void processMethodCall(State state, ASTMethodCall methodCall) { } } - private static int calculateExpectedLength(T expression, ToIntFunction countingStrategy) { + private static int countExpression(ASTExpression expr) { + return Optional.of(expr.getConstFoldingResult()) + .map(ASTExpression.ConstResult::getValue) + .map(String::valueOf) + .map(String::length) + .orElse(0); + } + + private static int calculateExpectedLength(ASTExpression expression) { + if (expression instanceof ASTNullLiteral) { + return "null".length(); + } if (expression.getParent() instanceof ASTCastExpression && TypeTestUtil.isA(char.class, (ASTCastExpression) expression.getParent())) { return 1; } - return countingStrategy.applyAsInt(expression); + if (expression.getParent() instanceof ASTConditionalExpression) { + ASTConditionalExpression conditionalExpression = (ASTConditionalExpression) expression.getParent(); + final ASTExpression other; + if (expression == conditionalExpression.getThenBranch()) { + other = conditionalExpression.getElseBranch(); + } else { + other = conditionalExpression.getThenBranch(); + } + int thisExpression = countExpression(expression); + int otherExpression = countExpression(other); + if (thisExpression > otherExpression) { + return thisExpression; + } else { + return 0; + } + } + return countExpression(expression); } private static Set collectArgumentsOfType(ASTMethodCall methodCall, Class type) { @@ -219,7 +243,12 @@ private static Set collectArgumentsOfType(ASTMethod .descendants(type), // cast expressions methodCall.getArguments().children(ASTCastExpression.class) - .children(type) + .children(type), + // conditional expression + methodCall.getArguments().children(ASTConditionalExpression.class) + .children() + .drop(1) // drop condition + .filterIs(type) ).collect(Collectors.toSet()); } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml index 89f038b691d..93b84127686 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml @@ -1544,12 +1544,20 @@ public class Foo { Ignore values used in conditional part of conditional expression - 0 + 1 + 4 + + StringBuilder has been initialized with size 0, but has at least 14 characters appended. + From cbea34bac9380aa9940910bdcdf9ecdba79b05af Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 23 Jan 2026 12:09:14 +0100 Subject: [PATCH 1924/1962] [doc] Update release notes (#3857, #6366) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index be6570e6a26..d2a1b4deb4c 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -52,6 +52,8 @@ rule properties: * [#6184](https://github.com/pmd/pmd/issues/6184): \[core] Consistent implementation of enum properties * java-errorprone * [#5882](https://github.com/pmd/pmd/issues/5882): \[java] UnconditionalIfStatement: False negative when true/false is not literal but local variable +* java-performance + * [#3857](https://github.com/pmd/pmd/issues/3857): \[java] InsufficientStringBufferDeclaration: False negatives with String constants ### ๐Ÿšจ๏ธ API Changes From 2761ec6719ffac337fe7f275ac0c6398ca7ded0a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 23 Jan 2026 13:16:23 +0100 Subject: [PATCH 1925/1962] [java] InsufficientStringBufferDeclaration: correctly handle string concat --- ...sufficientStringBufferDeclarationRule.java | 3 +- .../InsufficientStringBufferDeclaration.xml | 29 +++++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java index 8cb708a3478..8d5c6617b53 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/performance/InsufficientStringBufferDeclarationRule.java @@ -240,7 +240,8 @@ private static Set collectArgumentsOfType(ASTMethod // string concatenation methodCall.getArguments().children(ASTInfixExpression.class) .filter(e -> e.getOperator() == BinaryOp.ADD && TypeTestUtil.isA(String.class, e.getTypeMirror())) - .descendants(type), + .descendants(type) + .filter(n -> n.getParent() instanceof ASTInfixExpression), // cast expressions methodCall.getArguments().children(ASTCastExpression.class) .children(type), diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml index 93b84127686..771d60469d3 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/performance/xml/InsufficientStringBufferDeclaration.xml @@ -1471,15 +1471,38 @@ public class Example { - Constant wrapped in method should be allowed + Constant/literal wrapped in method should be allowed 0 + + + + Constant/literal wrapped in method in string concat should be allowed + 0 + Date: Fri, 23 Jan 2026 13:58:04 +0100 Subject: [PATCH 1926/1962] [apex] FieldDeclarationsShouldBeAtStartRule - clarify properties change --- .../codestyle/FieldDeclarationsShouldBeAtStartRule.java | 2 +- pmd-apex/src/main/resources/category/apex/codestyle.xml | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldDeclarationsShouldBeAtStartRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldDeclarationsShouldBeAtStartRule.java index 2444138e6fd..b9769c80091 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldDeclarationsShouldBeAtStartRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/codestyle/FieldDeclarationsShouldBeAtStartRule.java @@ -67,7 +67,7 @@ public Object visit(ASTUserClass node, Object data) { private List> getMethodNodes(ASTUserClass node) { return node.descendants(ASTMethod.class) - .filter(m -> m.ancestors(ASTProperty.class).isEmpty()) + .filterNot(m -> m.getParent() instanceof ASTProperty) .map(m -> (ApexNode) m) .toList(); } diff --git a/pmd-apex/src/main/resources/category/apex/codestyle.xml b/pmd-apex/src/main/resources/category/apex/codestyle.xml index 6cfaaac10d9..a1c04ad7694 100644 --- a/pmd-apex/src/main/resources/category/apex/codestyle.xml +++ b/pmd-apex/src/main/resources/category/apex/codestyle.xml @@ -77,12 +77,16 @@ public class fooClass { } // This will be reported unless you change the regex class="net.sourceforge.pmd.lang.apex.rule.codestyle.FieldDeclarationsShouldBeAtStartRule" externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_codestyle.html#fielddeclarationsshouldbeatstart"> - Field declarations should appear before method declarations within a class. +Field declarations should appear before method declarations within a class. + +Note: Since PMD 7.21.0 properties are treated like fields. That means both fields and properties (in no specific +order) need to be before any method declaration. 3 Date: Fri, 23 Jan 2026 13:59:01 +0100 Subject: [PATCH 1927/1962] [doc] Update release notes (#6349, #6394) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index d2a1b4deb4c..947a20aabf1 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -50,6 +50,8 @@ rule properties: ### ๐Ÿ›๏ธ Fixed Issues * core * [#6184](https://github.com/pmd/pmd/issues/6184): \[core] Consistent implementation of enum properties +* apex-codestyle + * [#6349](https://github.com/pmd/pmd/issues/6349): \[apex] FieldDeclarationsShouldBeAtStart: False positive with properties * java-errorprone * [#5882](https://github.com/pmd/pmd/issues/5882): \[java] UnconditionalIfStatement: False negative when true/false is not literal but local variable * java-performance From 350c087747f9ea76e034d44522b7bb1db7cea26e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 23 Jan 2026 14:09:48 +0100 Subject: [PATCH 1928/1962] [apex] FieldDeclarationsShouldBeAtStartRule - clarify properties change --- .../src/main/resources/category/apex/codestyle.xml | 5 +++-- .../xml/FieldDeclarationsShouldBeAtStart.xml | 12 ++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/pmd-apex/src/main/resources/category/apex/codestyle.xml b/pmd-apex/src/main/resources/category/apex/codestyle.xml index a1c04ad7694..2a09929ef99 100644 --- a/pmd-apex/src/main/resources/category/apex/codestyle.xml +++ b/pmd-apex/src/main/resources/category/apex/codestyle.xml @@ -79,8 +79,9 @@ public class fooClass { } // This will be reported unless you change the regex Field declarations should appear before method declarations within a class. -Note: Since PMD 7.21.0 properties are treated like fields. That means both fields and properties (in no specific -order) need to be before any method declaration. +Note: Since PMD 7.21.0, properties are ignored. This means that fields can appear before +or after properties (or fields and properties can be mixed) as long as all fields are placed +before the first method declaration. 3 diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/codestyle/xml/FieldDeclarationsShouldBeAtStart.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/codestyle/xml/FieldDeclarationsShouldBeAtStart.xml index 1f13aae6231..7a767d062c3 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/codestyle/xml/FieldDeclarationsShouldBeAtStart.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/codestyle/xml/FieldDeclarationsShouldBeAtStart.xml @@ -290,4 +290,16 @@ class Foo { } ]]> + + + Property declaration after method is ok + 0 + + From 8cc745c2a2e7f827bd50565370c8a96c50ea55dc Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 7 Jan 2026 10:01:35 +0100 Subject: [PATCH 1929/1962] [core] chore: Bump minimum Java version required for building to 21 --- .github/workflows/build.yml | 18 +++++++++--------- .github/workflows/publish-release.yml | 6 +++--- .github/workflows/publish-snapshot.yml | 10 +++++----- .../pmd/devdocs/building/building_general.md | 6 +++--- docs/pages/release_notes.md | 5 +++++ .../sourceforge/pmd/lang/document/Chars.java | 2 +- pmd-dist/pom.xml | 10 +++++----- pom.xml | 2 +- 8 files changed, 32 insertions(+), 27 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4f29ff3476b..db4770cb292 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,7 +27,7 @@ jobs: - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' - java-version: '17' + java-version: '21' - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 #v5.0.2 with: key: maven-${{ hashFiles('**/pom.xml') }} @@ -85,7 +85,7 @@ jobs: - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' - java-version: '17' + java-version: '21' - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 #v5.0.2 with: key: maven-${{ hashFiles('**/pom.xml') }} @@ -130,13 +130,13 @@ jobs: java-version: | 8 11 - 21 + 17 25 - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 - # default java version for all os is 17 + # default java version for all os is 21 with: distribution: 'temurin' - java-version: '17' + java-version: '21' # only restore the cache, don't create a new cache # Note: this works under Windows only if pom.xml files use LF, so that hashFiles('**/pom.xml') # gives the same result (line endings...). @@ -161,7 +161,7 @@ jobs: -PfastSkip -Dcyclonedx.skip=false \ -Djava8.home="${JAVA_HOME_8_X64}" \ -Djava11.home="${JAVA_HOME_11_X64}" \ - -Djava21.home="${JAVA_HOME_21_X64}" \ + -Djava17.home="${JAVA_HOME_17_X64}" \ -Djava25.home="${JAVA_HOME_25_X64}" dogfood: @@ -176,7 +176,7 @@ jobs: - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' - java-version: '17' + java-version: '21' - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 #v5.0.2 with: key: maven-${{ hashFiles('**/pom.xml') }} @@ -262,7 +262,7 @@ jobs: - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' - java-version: '17' + java-version: '21' - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 #v5.0.2 with: key: maven-${{ hashFiles('**/pom.xml') }} @@ -319,7 +319,7 @@ jobs: distribution: 'temurin' java-version: | 11 - 17 + 21 - name: Set up Ruby 3.3 uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 #v1.286.0 with: diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 2a4b03fac41..a462b1f901f 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -37,7 +37,7 @@ jobs: - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' - java-version: '17' + java-version: '21' cache: 'maven' - name: Determine Version id: version @@ -91,7 +91,7 @@ jobs: - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' - java-version: '17' + java-version: '21' server-id: central server-username: MAVEN_USERNAME server-password: MAVEN_PASSWORD @@ -630,7 +630,7 @@ jobs: distribution: 'temurin' java-version: | 11 - 17 + 21 - name: Set up Ruby 3.3 uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 #v1.286.0 with: diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 615f722f8c7..52fc24d7aa8 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -36,7 +36,7 @@ jobs: - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' - java-version: '17' + java-version: '21' - name: Determine Version id: version run: | @@ -82,7 +82,7 @@ jobs: - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' - java-version: '17' + java-version: '21' server-id: central server-username: MAVEN_USERNAME server-password: MAVEN_PASSWORD @@ -647,7 +647,7 @@ jobs: distribution: 'temurin' java-version: | 11 - 17 + 21 - name: Set up Ruby 3.3 uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 #v1.286.0 with: @@ -732,7 +732,7 @@ jobs: - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' - java-version: '17' + java-version: '21' - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 #v5.0.2 with: key: maven-${{ hashFiles('**/pom.xml') }} @@ -769,7 +769,7 @@ jobs: - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' - java-version: '17' + java-version: '21' - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 #v5.0.2 with: key: maven-${{ hashFiles('**/pom.xml') }} diff --git a/docs/pages/pmd/devdocs/building/building_general.md b/docs/pages/pmd/devdocs/building/building_general.md index 7b4209a57a1..d09343ebff7 100644 --- a/docs/pages/pmd/devdocs/building/building_general.md +++ b/docs/pages/pmd/devdocs/building/building_general.md @@ -3,14 +3,14 @@ title: Building PMD General Info tags: [devdocs] permalink: pmd_devdocs_building_general.html author: Andreas Dangel -last_updated: September 2025 (7.18.0) +last_updated: January 2026 (7.21.0) --- ## Before Development -1. Ensure that [Git](https://git-scm.com/) and Java JDK >= 17 are installed. +1. Ensure that [Git](https://git-scm.com/) and Java JDK >= 21 are installed. You can get a OpenJDK distribution from e.g. [Adoptium](https://adoptium.net/). - **Note:** While Java 17 is required for building, running PMD only requires Java 8. + **Note:** While Java 21 is required for building, running PMD only requires Java 8. 2. Fork the [PMD repository](https://github.com/pmd/pmd) on GitHub as explained in [Fork a repository](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo). 3. Clone your forked repository to your computer: ```shell diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 947a20aabf1..c3633d354f0 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -47,6 +47,11 @@ rule properties: * Instead of `Unwanted` use `unwanted` * The old values still work, but you'll see a deprecation warning. +#### Build Requirement is Java 21 +From now on, Java 21 or newer is required to build PMD. PMD itself still remains compatible with Java 8, +so that it still can be used in a pure Java 8 environment. This allows us to use the latest +checkstyle version during the build. + ### ๐Ÿ›๏ธ Fixed Issues * core * [#6184](https://github.com/pmd/pmd/issues/6184): \[core] Consistent implementation of enum properties diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/Chars.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/Chars.java index 618c115f536..7a116347ab0 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/Chars.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/Chars.java @@ -76,7 +76,7 @@ private int idx(int off) { /** Whether this slice is the empty string. */ // @SuppressWarnings("PMD.MissingOverride") // with Java 15, isEmpty() has been added to java.lang.CharSequence (#4291) - // We compile against Java 8 and execute maven on GitHub Actions with Java 17. So there is no missing override. + // We compile against Java 8 and execute maven on GitHub Actions with Java 21. So there is no missing override. // However, when executing Maven with Java 15+, then we get MissingOverride (#5299). // This is suppressed via maven-pmd-plugin's excludeFromFailureFile public boolean isEmpty() { diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index 2accf069004..02c438275d7 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -247,10 +247,10 @@ - jdk21-compat-it + jdk17-compat-it - java21.home + java17.home @@ -260,15 +260,15 @@ maven-failsafe-plugin - jdk21-compat-it + jdk17-compat-it integration-test verify - ${java21.home} - ${java21.home}/bin:${env.PATH} + ${java17.home} + ${java17.home}/bin:${env.PATH} diff --git a/pom.xml b/pom.xml index b6d40a57ec3..1be4c52da97 100644 --- a/pom.xml +++ b/pom.xml @@ -743,7 +743,7 @@ - [17,) + [21,) From 772285255b156d72893be86f0739dffa4aafd964 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Jan 2026 15:22:06 +0100 Subject: [PATCH 1930/1962] chore(deps): bump com.puppycrawl.tools:checkstyle from 12.3.0 to 13.0.0 (#6383) Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 12.3.0 to 13.0.0. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-12.3.0...checkstyle-13.0.0) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-version: 13.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1be4c52da97..ca4efc34fb9 100644 --- a/pom.xml +++ b/pom.xml @@ -91,7 +91,7 @@ 5.0 3.5.4 - 12.3.0 + 13.0.0 3.6.0 3.28.0 1.10.15 From ed88eaf1bed99d4f315a980958b6cda5dfb7eae7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Jan 2026 15:22:25 +0100 Subject: [PATCH 1931/1962] chore(deps-dev): bump lodash from 4.17.21 to 4.17.23 (#6419) Bumps [lodash](https://github.com/lodash/lodash) from 4.17.21 to 4.17.23. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23) --- updated-dependencies: - dependency-name: lodash dependency-version: 4.17.23 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index b9515c683b4..18bf228a07f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -333,9 +333,9 @@ } }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", "dev": true }, "node_modules/mimic-fn": { @@ -938,9 +938,9 @@ } }, "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", "dev": true }, "mimic-fn": { From b119ee852e9e1c54091cee0a1562002f5f5f8576 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 23 Jan 2026 16:29:54 +0100 Subject: [PATCH 1932/1962] [ci] publish-snapshot: fix run-coveralls job For some reason, we now need test-compile... --- .github/workflows/publish-snapshot.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 52fc24d7aa8..2500708962f 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -793,9 +793,9 @@ jobs: COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} run: | # note: generate-sources is needed, so that antlr4 generated directories are on the compileSourceRoots - # compile is needed to that dependency resolution within this multi-module build works + # test-compile is needed to that dependency resolution within this multi-module build works ./mvnw \ --show-version --errors --batch-mode \ -Dmaven.repo.local=.m2/repository \ - generate-sources compile \ + generate-sources test-compile \ coveralls:report -DrepoToken="${COVERALLS_REPO_TOKEN}" -Pcoveralls,fastSkip From 9df9504013e7904b7a4f170c84a2b086a63ec00e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 23 Jan 2026 16:49:53 +0100 Subject: [PATCH 1933/1962] update typos.toml with short howto --- typos.toml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/typos.toml b/typos.toml index ec7eef993cc..4a883f0beb6 100644 --- a/typos.toml +++ b/typos.toml @@ -1,3 +1,14 @@ +# +# Configuration for [typos](https://github.com/crate-ci/typos) - source spell checker +# +# To run the tool locally: +# +# TYPOS_VERSION="v1.42.1" +# wget https://github.com/crate-ci/typos/releases/download/${TYPOS_VERSION}/typos-${TYPOS_VERSION}-x86_64-unknown-linux-musl.tar.gz +# tar -x -v -f typos-${TYPOS_VERSION}-x86_64-unknown-linux-musl.tar.gz ./typos +# ./typos -c typos.toml --format brief . +# + [files] extend-exclude = [ "*.min.js", @@ -46,10 +57,11 @@ checkSelfDescendantAbreviation="checkSelfDescendantAbreviation" ColonSubsript="ColonSubsript" XMLTableColum="XMLTableColum" ASTXMLTableColum="ASTXMLTableColum" -# renamed +# renamed but mentioned in release_notes_old.md / category/ecmascript/errorprone.xml InnaccurateNumericLiteral="InnaccurateNumericLiteral" -# removed but mentioned in changelog +# removed but mentioned in credits.md AvoidConcateningNonLiteralsInStringBuffer="AvoidConcateningNonLiteralsInStringBuffer" +# removed method, mentioned in release_notes_old.md isSupressed="isSupressed" # fingerprint 9CAF="9CAF" From 301610e81bd24ca64f2c4bd34cb6c7fec6fa8895 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 23 Jan 2026 17:07:43 +0100 Subject: [PATCH 1934/1962] Move typos.toml to .ci/files/ --- typos.toml => .ci/files/typos.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename typos.toml => .ci/files/typos.toml (97%) diff --git a/typos.toml b/.ci/files/typos.toml similarity index 97% rename from typos.toml rename to .ci/files/typos.toml index 4a883f0beb6..651f8e45fbd 100644 --- a/typos.toml +++ b/.ci/files/typos.toml @@ -6,7 +6,7 @@ # TYPOS_VERSION="v1.42.1" # wget https://github.com/crate-ci/typos/releases/download/${TYPOS_VERSION}/typos-${TYPOS_VERSION}-x86_64-unknown-linux-musl.tar.gz # tar -x -v -f typos-${TYPOS_VERSION}-x86_64-unknown-linux-musl.tar.gz ./typos -# ./typos -c typos.toml --format brief . +# ./typos -c .ci/files/typos.toml --format brief . # [files] From 83d1d389872015814a52d7a4573006c1c93074db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Gr=C3=A4f?= Date: Sat, 3 Jan 2026 16:26:24 +0100 Subject: [PATCH 1935/1962] [java] Fix InvalidLogMessageFormat FP when final parameter is Supplier --- .../InvalidLogMessageFormatRule.java | 33 ++++++++++++++- .../xml/InvalidLogMessageFormat.xml | 41 +++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidLogMessageFormatRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidLogMessageFormatRule.java index 0bbb4d3d768..2a110d39d46 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidLogMessageFormatRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidLogMessageFormatRule.java @@ -6,8 +6,10 @@ import static net.sourceforge.pmd.util.CollectionUtil.immutableSetOf; +import java.util.List; import java.util.OptionalInt; import java.util.Set; +import java.util.function.Supplier; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -18,13 +20,17 @@ import net.sourceforge.pmd.lang.java.ast.ASTArrayAllocation; import net.sourceforge.pmd.lang.java.ast.ASTAssignableExpr.ASTNamedReferenceExpr; import net.sourceforge.pmd.lang.java.ast.ASTExpression; +import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression; import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; +import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement; import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; import net.sourceforge.pmd.lang.java.rule.internal.DataflowPass; import net.sourceforge.pmd.lang.java.rule.internal.DataflowPass.AssignmentEntry; import net.sourceforge.pmd.lang.java.rule.internal.DataflowPass.DataflowResult; import net.sourceforge.pmd.lang.java.rule.internal.DataflowPass.ReachingDefinitionSet; +import net.sourceforge.pmd.lang.java.types.JClassType; +import net.sourceforge.pmd.lang.java.types.JTypeMirror; import net.sourceforge.pmd.lang.java.types.TypeTestUtil; import net.sourceforge.pmd.util.CollectionUtil; @@ -74,7 +80,7 @@ public Object visit(ASTMethodCall call, Object data) { if (providedArguments == 1 && JavaAstUtils.isArrayInitializer(args.getLastChild())) { providedArguments = ((ASTArrayAllocation) args.getLastChild()).getArrayInitializer().length(); - } else if (TypeTestUtil.isA(Throwable.class, args.getLastChild()) + } else if (isThrowable(args) && providedArguments > expectedArguments) { // Remove throwable param, since it is shown separately. // But only, if it is not used as a placeholder argument @@ -102,6 +108,31 @@ public Object visit(ASTMethodCall call, Object data) { return null; } + private static boolean isThrowable(ASTArgumentList args) { + ASTExpression lastArg = args.getLastChild(); + if (TypeTestUtil.isA(Throwable.class, lastArg)) { + return true; + } + + if (TypeTestUtil.isA(Supplier.class, lastArg)) { + if (lastArg instanceof ASTLambdaExpression) { + ASTExpression expressionBody = ((ASTLambdaExpression) lastArg).getExpressionBody(); + if (expressionBody != null) { + return TypeTestUtil.isA(Throwable.class, expressionBody); + } + return lastArg.descendants(ASTReturnStatement.class).all(ret -> TypeTestUtil.isA(Throwable.class, ret.getExpr())); + } else if (lastArg instanceof ASTMethodCall) { + JTypeMirror typeMirror = lastArg.getTypeMirror(); + if (typeMirror instanceof JClassType) { + List typeArgs = ((JClassType) typeMirror).getTypeArgs(); + return typeArgs.size() == 1 && TypeTestUtil.isA(Throwable.class, typeArgs.get(0)); + } + } + } + + return false; + } + private boolean isLoggerCall(ASTMethodCall call, String loggerType, Set methodNames) { return TypeTestUtil.isA(loggerType, call.getQualifier()) && methodNames.contains(call.getMethodName()); } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml index 3f4358a50ce..b2af5aa435a 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml @@ -1348,4 +1348,45 @@ public class InvalidLogMessageFormat{ } ]]> + + #3601 [java] False positive when final parameter is Supplier of Throwable + 0 + String.valueOf(id), () -> exception); + } + } + + public void lambdaStatement(Object id) { + try { + throw new Exception("aaa"); + } catch (final Exception exception) { + logger.warn("Object with ID {} had a problem.", () -> String.valueOf(id), () -> { return exception; }); + } + } + + private static Supplier exceptionHandler(Exception ex) { + return () -> { ex.printStackTrace(); return ex; }; + } + + public void supplierMethod(Object id) { + try { + throw new Exception("aaa"); + } catch (final Exception exception) { + logger.warn("Object with ID {} had a problem.", () -> String.valueOf(id), exceptionHandler(exception)); + } + } + } + ]]> + From 9882ee801a2a41a1f8413801956ba328411fbad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Gr=C3=A4f?= Date: Sat, 17 Jan 2026 17:36:18 +0100 Subject: [PATCH 1936/1962] [java] Fix detection of Supplier for method calls and method references inside lambda --- .../InvalidLogMessageFormatRule.java | 29 ++++++++++++------- .../xml/InvalidLogMessageFormat.xml | 14 ++++++++- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidLogMessageFormatRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidLogMessageFormatRule.java index 2a110d39d46..ae058f9607a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidLogMessageFormatRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/errorprone/InvalidLogMessageFormatRule.java @@ -22,6 +22,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTExpression; import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression; import net.sourceforge.pmd.lang.java.ast.ASTMethodCall; +import net.sourceforge.pmd.lang.java.ast.ASTMethodReference; import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement; import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; @@ -80,7 +81,7 @@ public Object visit(ASTMethodCall call, Object data) { if (providedArguments == 1 && JavaAstUtils.isArrayInitializer(args.getLastChild())) { providedArguments = ((ASTArrayAllocation) args.getLastChild()).getArrayInitializer().length(); - } else if (isThrowable(args) + } else if (isThrowable(args.getLastChild()) && providedArguments > expectedArguments) { // Remove throwable param, since it is shown separately. // But only, if it is not used as a placeholder argument @@ -108,8 +109,7 @@ public Object visit(ASTMethodCall call, Object data) { return null; } - private static boolean isThrowable(ASTArgumentList args) { - ASTExpression lastArg = args.getLastChild(); + private static boolean isThrowable(ASTExpression lastArg) { if (TypeTestUtil.isA(Throwable.class, lastArg)) { return true; } @@ -118,21 +118,30 @@ private static boolean isThrowable(ASTArgumentList args) { if (lastArg instanceof ASTLambdaExpression) { ASTExpression expressionBody = ((ASTLambdaExpression) lastArg).getExpressionBody(); if (expressionBody != null) { - return TypeTestUtil.isA(Throwable.class, expressionBody); + if (expressionBody instanceof ASTMethodCall) { + return hasThrowableTypeArgument(expressionBody.getTypeMirror()); + } else { + return TypeTestUtil.isA(Throwable.class, expressionBody); + } } return lastArg.descendants(ASTReturnStatement.class).all(ret -> TypeTestUtil.isA(Throwable.class, ret.getExpr())); - } else if (lastArg instanceof ASTMethodCall) { - JTypeMirror typeMirror = lastArg.getTypeMirror(); - if (typeMirror instanceof JClassType) { - List typeArgs = ((JClassType) typeMirror).getTypeArgs(); - return typeArgs.size() == 1 && TypeTestUtil.isA(Throwable.class, typeArgs.get(0)); - } + } else if (lastArg instanceof ASTMethodReference) { + JTypeMirror returnType = ((ASTMethodReference) lastArg).getReferencedMethod().getReturnType(); + return hasThrowableTypeArgument(returnType); } } return false; } + private static boolean hasThrowableTypeArgument(JTypeMirror type) { + if (type instanceof JClassType) { + List typeArgs = ((JClassType) type).getTypeArgs(); + return typeArgs.size() == 1 && TypeTestUtil.isA(Throwable.class, typeArgs.get(0)); + } + return false; + } + private boolean isLoggerCall(ASTMethodCall call, String loggerType, Set methodNames) { return TypeTestUtil.isA(loggerType, call.getQualifier()) && methodNames.contains(call.getMethodName()); } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml index b2af5aa435a..051ff25e60f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/InvalidLogMessageFormat.xml @@ -1379,11 +1379,23 @@ public class InvalidLogMessageFormat{ return () -> { ex.printStackTrace(); return ex; }; } + private Supplier exceptionSupplier() { + return () -> { throw new RuntimeException(); }; + } + public void supplierMethod(Object id) { try { throw new Exception("aaa"); } catch (final Exception exception) { - logger.warn("Object with ID {} had a problem.", () -> String.valueOf(id), exceptionHandler(exception)); + logger.warn("Object with ID {} had a problem.", () -> String.valueOf(id), () -> exceptionHandler(exception)); + } + } + + public void supplierMethodReference(Object id) { + try { + throw new Exception("aaa"); + } catch (final Exception exception) { + logger.warn("Object with ID {} had a problem.", () -> String.valueOf(id), this::exceptionSupplier); } } } From 7abd97080d4880978c3811dcf380b8d5832a1d3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Gr=C3=A4f?= Date: Sat, 17 Jan 2026 20:05:09 +0100 Subject: [PATCH 1937/1962] [doc] Update release notes (#3601) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index d29a959795d..8742cbc3a11 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -79,6 +79,7 @@ checkstyle version during the build. * [#5871](https://github.com/pmd/pmd/issues/5871): \[java] Support Java 26 * java-errorprone * [#5882](https://github.com/pmd/pmd/issues/5882): \[java] UnconditionalIfStatement: False negative when true/false is not literal but local variable + * [#3601](https://github.com/pmd/pmd/issues/3601): \[java] InvalidLogMessageFormat: False positive when final parameter is Supplier * java-performance * [#3857](https://github.com/pmd/pmd/issues/3857): \[java] InsufficientStringBufferDeclaration: False negatives with String constants From 90d97f14c8a30d7355c7831a0cfb2019ec2016aa Mon Sep 17 00:00:00 2001 From: Jade Petraglia Date: Wed, 28 Jan 2026 16:07:02 -0700 Subject: [PATCH 1938/1962] [apex] Replaced temporary exclusion to pom.xml with a delegate passthru to account for code using reflection And added to documentation stating that CPD-ON & CPD-OFF are now supported for Apex --- docs/pages/pmd/userdocs/cpd/cpd.md | 2 +- pmd-apex/pom.xml | 4 ---- .../java/net/sourceforge/pmd/lang/apex/cpd/ApexCpdLexer.java | 5 +++++ 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/pages/pmd/userdocs/cpd/cpd.md b/docs/pages/pmd/userdocs/cpd/cpd.md index 71b82709236..ecfeccf6283 100644 --- a/docs/pages/pmd/userdocs/cpd/cpd.md +++ b/docs/pages/pmd/userdocs/cpd/cpd.md @@ -421,7 +421,7 @@ Here's a screenshot of CPD after running on the JDK 8 java.lang package: ## Suppression Arbitrary blocks of code can be ignored through comments on **Java**, **C/C++**, **Dart**, **Go**, **Groovy**, **Javascript**, -**Kotlin**, **Lua**, **Matlab**, **Objective-C**, **PL/SQL**, **Python**, **Scala**, **Swift** and **C#** by including the keywords `CPD-OFF` and `CPD-ON`. +**Kotlin**, **Lua**, **Matlab**, **Objective-C**, **PL/SQL**, **Python**, **Scala**, **Swift**, **C#** and **Apex** by including the keywords `CPD-OFF` and `CPD-ON`. ```java public Object someParameterizedFactoryMethod(int x) throws Exception { diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 5d511c2997c..6374aaf02b7 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -65,10 +65,6 @@ net.sourceforge.pmd.lang.apex.internal net.sourceforge.pmd.lang.apex.metrics.internal net.sourceforge.pmd.lang.apex.rule.internal - - - - net.sourceforge.pmd.lang.apex.cpd.ApexCpdLexer#tokenize(net.sourceforge.pmd.lang.document.TextDocument,net.sourceforge.pmd.cpd.TokenFactory) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/cpd/ApexCpdLexer.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/cpd/ApexCpdLexer.java index 1d80ad8a7ab..4dd7d815298 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/cpd/ApexCpdLexer.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/cpd/ApexCpdLexer.java @@ -29,6 +29,11 @@ protected Lexer getLexerForSource(CharStream charStream) { protected TokenManager filterTokenStream(TokenManager tokenManager) { return new BaseTokenFilter<>(tokenManager); } + + @Override + public void tokenize(TextDocument document, TokenFactory tokenFactory) { + super.tokenize(document, tokenFactory); + } @Override protected String getImage(AntlrToken token) { From 8628b258de3bdb44b521b749d5ecc82c917ed814 Mon Sep 17 00:00:00 2001 From: Jade Petraglia Date: Wed, 28 Jan 2026 16:11:20 -0700 Subject: [PATCH 1939/1962] [apex] Restored some imports to ApexCpdLexer.java that are still needed --- .../java/net/sourceforge/pmd/lang/apex/cpd/ApexCpdLexer.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/cpd/ApexCpdLexer.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/cpd/ApexCpdLexer.java index 4dd7d815298..83f445326e0 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/cpd/ApexCpdLexer.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/cpd/ApexCpdLexer.java @@ -11,8 +11,10 @@ import net.sourceforge.pmd.cpd.impl.AntlrCpdLexer; import net.sourceforge.pmd.cpd.impl.BaseTokenFilter; +import net.sourceforge.pmd.cpd.TokenFactory; import net.sourceforge.pmd.lang.TokenManager; import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrToken; +import net.sourceforge.pmd.lang.document.TextDocument; import io.github.apexdevtools.apexparser.ApexLexer; import io.github.apexdevtools.apexparser.CaseInsensitiveInputStream; From 3298f2ad54ff3b5bf42ba91d93bc8027a0e7fc3b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Jan 2026 10:22:15 +0100 Subject: [PATCH 1940/1962] chore(deps-dev): bump org.assertj:assertj-core from 3.27.6 to 3.27.7 (#6424) Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.27.6 to 3.27.7. - [Release notes](https://github.com/assertj/assertj/releases) - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.27.6...assertj-build-3.27.7) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-version: 3.27.7 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-java/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 1477b53790d..88d56dee006 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -293,7 +293,7 @@ org.assertj assertj-core - 3.27.6 + 3.27.7 test From 5ae7ec815f965c3cfb20b7dc695b52884dcdbebd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Jan 2026 10:22:27 +0100 Subject: [PATCH 1941/1962] chore(deps): bump actions/checkout from 6.0.1 to 6.0.2 (#6422) Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.1 to 6.0.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/8e8c483db84b4bee98b60c0593521ed34d9990e8...de0fac2e4500dabe0009e67214ff5f5447ce83dd) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 6.0.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 12 ++++++------ .github/workflows/git-repo-sync.yml | 2 +- .github/workflows/publish-release.yml | 6 +++--- .github/workflows/publish-snapshot.yml | 12 ++++++------ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index db4770cb292..e76a70926df 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,7 +23,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' @@ -81,7 +81,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' @@ -121,7 +121,7 @@ jobs: matrix: os: [ ubuntu-latest, windows-latest, macos-latest ] steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 # under linux we execute more extensive integration tests with various java versions if: ${{ runner.os == 'Linux' }} @@ -172,7 +172,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' @@ -258,7 +258,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 with: distribution: 'temurin' @@ -311,7 +311,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: fetch-depth: 2 - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 diff --git a/.github/workflows/git-repo-sync.yml b/.github/workflows/git-repo-sync.yml index f1d5dc0c577..f25e187f860 100644 --- a/.github/workflows/git-repo-sync.yml +++ b/.github/workflows/git-repo-sync.yml @@ -28,7 +28,7 @@ jobs: shell: bash continue-on-error: false steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: fetch-depth: 100 - name: Setup ssh key for sourceforge diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index a462b1f901f..97e96c11cc5 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -31,7 +31,7 @@ jobs: outputs: PMD_VERSION: ${{ steps.version.outputs.PMD_VERSION }} steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: ref: ${{ github.event.workflow_run.head_branch }} - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 @@ -85,7 +85,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: ref: ${{ github.event.workflow_run.head_branch }} - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 @@ -622,7 +622,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: ref: ${{ github.event.workflow_run.head_branch }} - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index 2500708962f..d6b099517ec 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -30,7 +30,7 @@ jobs: outputs: PMD_VERSION: ${{ steps.version.outputs.PMD_VERSION }} steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: ref: main - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 @@ -76,7 +76,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: ref: main - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 @@ -416,7 +416,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: ref: gh-pages - name: Clear old files @@ -639,7 +639,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: ref: main - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 @@ -726,7 +726,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: ref: main - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 @@ -763,7 +763,7 @@ jobs: run: shell: bash steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: ref: main - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 From 8b2ce51fd690d22693a4d05f261faa7e39f05dac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Jan 2026 10:45:48 +0100 Subject: [PATCH 1942/1962] chore(deps): bump actions/setup-java from 5.1.0 to 5.2.0 (#6421) Bumps [actions/setup-java](https://github.com/actions/setup-java) from 5.1.0 to 5.2.0. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/f2beeb24e141e01a676f977032f5a29d81c9e27e...be666c2fcd27ec809703dec50e508c2fdc7f6654) --- updated-dependencies: - dependency-name: actions/setup-java dependency-version: 5.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 14 +++++++------- .github/workflows/publish-release.yml | 6 +++--- .github/workflows/publish-snapshot.yml | 10 +++++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e76a70926df..dc338412615 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,7 +24,7 @@ jobs: shell: bash steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 - - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 + - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 #v5.2.0 with: distribution: 'temurin' java-version: '21' @@ -82,7 +82,7 @@ jobs: shell: bash steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 - - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 + - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 #v5.2.0 with: distribution: 'temurin' java-version: '21' @@ -122,7 +122,7 @@ jobs: os: [ ubuntu-latest, windows-latest, macos-latest ] steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 - - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 + - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 #v5.2.0 # under linux we execute more extensive integration tests with various java versions if: ${{ runner.os == 'Linux' }} with: @@ -132,7 +132,7 @@ jobs: 11 17 25 - - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 + - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 #v5.2.0 # default java version for all os is 21 with: distribution: 'temurin' @@ -173,7 +173,7 @@ jobs: shell: bash steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 - - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 + - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 #v5.2.0 with: distribution: 'temurin' java-version: '21' @@ -259,7 +259,7 @@ jobs: shell: bash steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 - - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 + - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 #v5.2.0 with: distribution: 'temurin' java-version: '21' @@ -314,7 +314,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: fetch-depth: 2 - - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 + - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 #v5.2.0 with: distribution: 'temurin' java-version: | diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 97e96c11cc5..06b9284ede7 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -34,7 +34,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: ref: ${{ github.event.workflow_run.head_branch }} - - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 + - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 #v5.2.0 with: distribution: 'temurin' java-version: '21' @@ -88,7 +88,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: ref: ${{ github.event.workflow_run.head_branch }} - - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 + - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 #v5.2.0 with: distribution: 'temurin' java-version: '21' @@ -625,7 +625,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: ref: ${{ github.event.workflow_run.head_branch }} - - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 + - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 #v5.2.0 with: distribution: 'temurin' java-version: | diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index d6b099517ec..1224cd1d8d0 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -33,7 +33,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: ref: main - - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 + - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 #v5.2.0 with: distribution: 'temurin' java-version: '21' @@ -79,7 +79,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: ref: main - - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 + - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 #v5.2.0 with: distribution: 'temurin' java-version: '21' @@ -642,7 +642,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: ref: main - - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 + - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 #v5.2.0 with: distribution: 'temurin' java-version: | @@ -729,7 +729,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: ref: main - - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 + - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 #v5.2.0 with: distribution: 'temurin' java-version: '21' @@ -766,7 +766,7 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: ref: main - - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e #v5.1.0 + - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 #v5.2.0 with: distribution: 'temurin' java-version: '21' From 247a4adb8a391dfa8ea876309099a92cdc78abe7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Jan 2026 10:45:59 +0100 Subject: [PATCH 1943/1962] chore(deps): bump scalameta.version from 4.14.5 to 4.14.6 (#6423) Bumps `scalameta.version` from 4.14.5 to 4.14.6. Updates `org.scalameta:parsers_2.13` from 4.14.5 to 4.14.6 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.14.5...v4.14.6) Updates `org.scalameta:trees_2.13` from 4.14.5 to 4.14.6 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.14.5...v4.14.6) Updates `org.scalameta:parsers_2.12` from 4.14.5 to 4.14.6 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.14.5...v4.14.6) Updates `org.scalameta:trees_2.12` from 4.14.5 to 4.14.6 - [Release notes](https://github.com/scalameta/scalameta/releases) - [Commits](https://github.com/scalameta/scalameta/compare/v4.14.5...v4.14.6) --- updated-dependencies: - dependency-name: org.scalameta:parsers_2.13 dependency-version: 4.14.6 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:trees_2.13 dependency-version: 4.14.6 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:parsers_2.12 dependency-version: 4.14.6 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.scalameta:trees_2.12 dependency-version: 4.14.6 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index ee9a3afa65a..601654c8828 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -13,7 +13,7 @@ - 4.14.5 + 4.14.6 From ca1a3d60ea5f10763543feb0dfeaac2e99dfbaa5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Jan 2026 10:46:10 +0100 Subject: [PATCH 1944/1962] chore(deps): bump org.apache.groovy:groovy from 5.0.3 to 5.0.4 (#6425) Bumps [org.apache.groovy:groovy](https://github.com/apache/groovy) from 5.0.3 to 5.0.4. - [Commits](https://github.com/apache/groovy/commits) --- updated-dependencies: - dependency-name: org.apache.groovy:groovy dependency-version: 5.0.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b5720c07466..85ee5223cd1 100644 --- a/pom.xml +++ b/pom.xml @@ -942,7 +942,7 @@ org.apache.groovy groovy - 5.0.3 + 5.0.4 com.google.code.gson From 66024cf8a5dae94a0e5eb93c7bdb4e1ee0f223c8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 29 Jan 2026 10:47:16 +0100 Subject: [PATCH 1945/1962] [ci] chore: run extensive integration tests under linux only (#6428) [ci] chore: run extensive integrations under linux only These tests were supposed to be run only on the linux runners, but other runners have all the java version installed as well and ran these tests as well. This was not intended and lengthens the build time. --- .github/workflows/build.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dc338412615..07470c188e0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -153,7 +153,9 @@ jobs: if: ${{ runner.os == 'Linux' }} with: name: compile-artifact - - name: Build with Maven and run unit tests + - name: Build with Maven and run unit and integration tests (linux) + # under linux we execute more extensive integration tests with various java versions + if: ${{ runner.os == 'Linux' }} run: | ./mvnw --show-version --errors --batch-mode \ -Dmaven.repo.local=.m2/repository \ @@ -163,6 +165,13 @@ jobs: -Djava11.home="${JAVA_HOME_11_X64}" \ -Djava17.home="${JAVA_HOME_17_X64}" \ -Djava25.home="${JAVA_HOME_25_X64}" + - name: Build with Maven and run unit tests + if: ${{ runner.os != 'Linux' }} + run: | + ./mvnw --show-version --errors --batch-mode \ + -Dmaven.repo.local=.m2/repository \ + verify \ + -PfastSkip -Dcyclonedx.skip=false dogfood: needs: compile From 3063efe275dfbef9be378017459540d80e293c7b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 29 Jan 2026 11:28:02 +0100 Subject: [PATCH 1946/1962] Update release notes --- docs/pages/release_notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 8742cbc3a11..aab69be4a91 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -78,8 +78,8 @@ checkstyle version during the build. * java * [#5871](https://github.com/pmd/pmd/issues/5871): \[java] Support Java 26 * java-errorprone + * [#3601](https://github.com/pmd/pmd/issues/3601): \[java] InvalidLogMessageFormat: False positive when final parameter is Supplier<Throwable> * [#5882](https://github.com/pmd/pmd/issues/5882): \[java] UnconditionalIfStatement: False negative when true/false is not literal but local variable - * [#3601](https://github.com/pmd/pmd/issues/3601): \[java] InvalidLogMessageFormat: False positive when final parameter is Supplier * java-performance * [#3857](https://github.com/pmd/pmd/issues/3857): \[java] InsufficientStringBufferDeclaration: False negatives with String constants From 6e954696edf03c11242208ce2cdd8b1cdabf6192 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 29 Jan 2026 12:15:44 +0100 Subject: [PATCH 1947/1962] [apex] Restore binary compat for ApexCpdLexer The #tokenize() method has been moved to the super class. This is not a problem. But the super class defines the method as final, which means it can't be overridden. For now, we simply delegate to the new version of the apex lexer. With PMD 8, we can merge the two implementations again. --- .../pmd/lang/apex/cpd/AntlrApexCpdLexer.java | 41 +++++++++++++++++++ .../pmd/lang/apex/cpd/ApexCpdLexer.java | 37 +++-------------- 2 files changed, 47 insertions(+), 31 deletions(-) create mode 100644 pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/cpd/AntlrApexCpdLexer.java diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/cpd/AntlrApexCpdLexer.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/cpd/AntlrApexCpdLexer.java new file mode 100644 index 00000000000..fa10b73b72e --- /dev/null +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/cpd/AntlrApexCpdLexer.java @@ -0,0 +1,41 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.apex.cpd; + +import java.util.Locale; + +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Lexer; + +import net.sourceforge.pmd.cpd.impl.AntlrCpdLexer; +import net.sourceforge.pmd.cpd.impl.BaseTokenFilter; +import net.sourceforge.pmd.lang.TokenManager; +import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrToken; + +import io.github.apexdevtools.apexparser.ApexLexer; +import io.github.apexdevtools.apexparser.CaseInsensitiveInputStream; + +/** + * @since 7.21.0 + */ +class AntlrApexCpdLexer extends AntlrCpdLexer { + + @Override + protected Lexer getLexerForSource(CharStream charStream) { + CaseInsensitiveInputStream caseInsensitiveInputStream = new CaseInsensitiveInputStream(charStream); + return new ApexLexer(caseInsensitiveInputStream); + } + + @Override + protected TokenManager filterTokenStream(TokenManager tokenManager) { + return new BaseTokenFilter<>(tokenManager); + } + + @Override + protected String getImage(AntlrToken token) { + // be case-insensitive + return token.getImage().toLowerCase(Locale.ROOT); + } +} diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/cpd/ApexCpdLexer.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/cpd/ApexCpdLexer.java index 83f445326e0..9810f4de18f 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/cpd/ApexCpdLexer.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/cpd/ApexCpdLexer.java @@ -4,42 +4,17 @@ package net.sourceforge.pmd.lang.apex.cpd; -import java.util.Locale; +import java.io.IOException; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.Lexer; - -import net.sourceforge.pmd.cpd.impl.AntlrCpdLexer; -import net.sourceforge.pmd.cpd.impl.BaseTokenFilter; +import net.sourceforge.pmd.cpd.CpdLexer; import net.sourceforge.pmd.cpd.TokenFactory; -import net.sourceforge.pmd.lang.TokenManager; -import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrToken; import net.sourceforge.pmd.lang.document.TextDocument; -import io.github.apexdevtools.apexparser.ApexLexer; -import io.github.apexdevtools.apexparser.CaseInsensitiveInputStream; - -public class ApexCpdLexer extends AntlrCpdLexer { - - @Override - protected Lexer getLexerForSource(CharStream charStream) { - CaseInsensitiveInputStream caseInsensitiveInputStream = new CaseInsensitiveInputStream(charStream); - return new ApexLexer(caseInsensitiveInputStream); - } - - @Override - protected TokenManager filterTokenStream(TokenManager tokenManager) { - return new BaseTokenFilter<>(tokenManager); - } - - @Override - public void tokenize(TextDocument document, TokenFactory tokenFactory) { - super.tokenize(document, tokenFactory); - } +public class ApexCpdLexer implements CpdLexer { + private final AntlrApexCpdLexer lexer = new AntlrApexCpdLexer(); @Override - protected String getImage(AntlrToken token) { - // be case-insensitive - return token.getImage().toLowerCase(Locale.ROOT); + public void tokenize(TextDocument document, TokenFactory tokenEntries) throws IOException { + lexer.tokenize(document, tokenEntries); } } From b0141e08dc5abad55d18681f713302f6f245ec93 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 29 Jan 2026 12:43:05 +0100 Subject: [PATCH 1948/1962] [doc] Update release notes (#6417) --- docs/pages/release_notes.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index ebba55c653a..903a0b0ab3e 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -47,9 +47,14 @@ rule properties: * Instead of `Unwanted` use `unwanted` * The old values still work, but you'll see a deprecation warning. +#### CPD +* The Apex module now supports [suppression](https://docs.pmd-code.org/latest/pmd_userdocs_cpd.html#suppression) through `CPD-ON`/`CPD-OFF` comment pairs. See [#6417](https://github.com/pmd/pmd/pull/6417) + ### ๐Ÿ›๏ธ Fixed Issues * core * [#6184](https://github.com/pmd/pmd/issues/6184): \[core] Consistent implementation of enum properties +* apex + * [#6417](https://github.com/pmd/pmd/issues/6417): \[apex] Support CPD suppression with "CPD-OFF" & "CPD-ON" ### ๐Ÿšจ๏ธ API Changes From ab25066fac4760a68797dad82006c7666850a57e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 29 Jan 2026 12:56:13 +0100 Subject: [PATCH 1949/1962] [doc] Update release notes (#6364, #6430) --- docs/pages/release_notes.md | 2 ++ .../net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java | 3 +++ 2 files changed, 5 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 48d7c2ca2f6..9ebcfb40f4e 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -25,6 +25,8 @@ This is a {{ site.pmd.release_type }} release. ### ๐Ÿš€๏ธ New and noteworthy ### ๐Ÿ›๏ธ Fixed Issues +* java + * [#6364](https://github.com/pmd/pmd/issues/6364): \[java] Parse error with yield lambda inside switch ### ๐Ÿšจ๏ธ API Changes diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java index 6add1e1d4d8..c73c19f22fb 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java @@ -195,6 +195,9 @@ void testGenericsProblem() { java7.parse(code); } + /** + * @see [java] Parse error with yield lambda inside switch #6364 + */ @Test void testYieldStmtWithLambda() { java15.parse( From 2e36c2910243b71d6e51509c0734003e3d9a69ef Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 29 Jan 2026 15:34:24 +0100 Subject: [PATCH 1950/1962] [java] PublicMembersInNonPublicType: Update rule description --- docs/pages/release_notes.md | 6 +++--- pmd-java/src/main/resources/category/java/design.xml | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index a78b9d806a9..28347c181d5 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -26,9 +26,9 @@ This is a {{ site.pmd.release_type }} release. ### ๐ŸŒŸ๏ธ New and Changed Rules #### New Rules -* The new Java rule {% rule java/design/PublicMemberInNonPublicType %} finds public members - (like methods or fields) in types, that are not public. A non-public type should not have public members, - as their visibility is effectively limited and using the public modifier creates confusion. +* The new Java rule {% rule java/design/PublicMemberInNonPublicType %} detects public members (such as methods + or fields) within non-public types. Non-public types should not declare public members, as their effective + visibility is limited, and using the `public` modifier can create confusion. ### ๐Ÿ›๏ธ Fixed Issues diff --git a/pmd-java/src/main/resources/category/java/design.xml b/pmd-java/src/main/resources/category/java/design.xml index a1aeea6a5e2..55b28d584ea 100644 --- a/pmd-java/src/main/resources/category/java/design.xml +++ b/pmd-java/src/main/resources/category/java/design.xml @@ -1065,10 +1065,12 @@ public class Foo { class="net.sourceforge.pmd.lang.rule.xpath.XPathRule" externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#publicmemberinnonpublictype"> -A non-public type should not contain members with public visibility. In such cases, their actual accessibility -is constrained to private, package-private, or protected, making the use of the public modifier misleading. +A non-public type should not declare its own members as public, as their visibility is effectively limited +to private, package-private, or protected, making the use of the public modifier misleading. Declaring members as public within a non-public type creates confusion and can lead to unintended consequences if the type is later made public, as this would expose all its public members. +However, it is acceptable for a non-public type to inherit public members from a superclass, as this is part of +the superclass's design. To avoid such issues, these members should be declared as protected, package-private, or even private, as appropriate. Note that altering the visibility of such members might unintentionally affect the API From 21d6ee5a9929b409b416960ccdfe0c4673ff70ae Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 29 Jan 2026 15:36:18 +0100 Subject: [PATCH 1951/1962] [doc] Update release notes (#6231) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 28347c181d5..c26a6a24830 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -31,6 +31,8 @@ This is a {{ site.pmd.release_type }} release. visibility is limited, and using the `public` modifier can create confusion. ### ๐Ÿ›๏ธ Fixed Issues +* java-design + * [#6231](https://github.com/pmd/pmd/issues/6231): \[java] New Rule: PublicMemberInNonPublicType ### ๐Ÿšจ๏ธ API Changes From 0408eb6b7ab4ce9314649a4670361a11290dddad Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 8 Jan 2026 12:32:07 +0100 Subject: [PATCH 1952/1962] chore: update javadoc internal API tags Add an apiNote --- .../net/sourceforge/pmd/lang/apex/ast/ApexCommentBuilder.java | 2 -- .../java/net/sourceforge/pmd/lang/ast/SemanticException.java | 3 +++ .../kotlin/net/sourceforge/pmd/lang/test/ast/IntelliMarker.kt | 3 +++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexCommentBuilder.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexCommentBuilder.java index 38e4cac5ac1..eb14b158552 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexCommentBuilder.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ast/ApexCommentBuilder.java @@ -19,7 +19,6 @@ import org.antlr.v4.runtime.Recognizer; import org.antlr.v4.runtime.Token; -import net.sourceforge.pmd.annotation.InternalApi; import net.sourceforge.pmd.lang.ast.LexException; import net.sourceforge.pmd.lang.ast.impl.SuppressionCommentImpl; import net.sourceforge.pmd.lang.document.FileLocation; @@ -30,7 +29,6 @@ import io.github.apexdevtools.apexparser.ApexLexer; import io.github.apexdevtools.apexparser.CaseInsensitiveInputStream; -@InternalApi final class ApexCommentBuilder { private final TextDocument sourceCode; private final CommentInformation commentInfo; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/SemanticException.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/SemanticException.java index 99586a12ef8..b4302699596 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/SemanticException.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/SemanticException.java @@ -29,6 +29,9 @@ public SemanticException(String message, Throwable cause) { super(message, cause); } + /** + * @apiNote Internal API + */ @InternalApi public void setReported() { reported = true; diff --git a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/test/ast/IntelliMarker.kt b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/test/ast/IntelliMarker.kt index 16c713aa2b3..15fa146e862 100644 --- a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/test/ast/IntelliMarker.kt +++ b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/test/ast/IntelliMarker.kt @@ -18,6 +18,9 @@ interface IntelliMarker { fun primer() { } + /** + * @apiNote Internal API + */ @Test @InternalApi fun dummyTestForIntelliJIntegration() { From a0751c0cb24556df805ba050b6e05dae799645ef Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 8 Jan 2026 13:07:07 +0100 Subject: [PATCH 1953/1962] chore: update internal API notes --- .../main/java/net/sourceforge/pmd/ant/InternalApiBridge.java | 2 +- .../sourceforge/pmd/lang/apex/multifile/InternalApiBridge.java | 2 +- .../main/java/net/sourceforge/pmd/lang/InternalApiBridge.java | 2 +- .../java/net/sourceforge/pmd/lang/ast/InternalApiBridge.java | 2 +- .../java/net/sourceforge/pmd/lang/ast/SemanticException.java | 2 +- .../net/sourceforge/pmd/lang/document/InternalApiBridge.java | 2 +- .../java/net/sourceforge/pmd/lang/rule/InternalApiBridge.java | 2 +- .../java/net/sourceforge/pmd/lang/rule/xpath/Attribute.java | 2 +- .../net/sourceforge/pmd/lang/rule/xpath/InternalApiBridge.java | 2 +- .../java/net/sourceforge/pmd/properties/InternalApiBridge.java | 2 +- .../java/net/sourceforge/pmd/reporting/InternalApiBridge.java | 2 +- .../java/net/sourceforge/pmd/InternalApiBridgeForTestsOnly.java | 2 +- .../main/java/net/sourceforge/pmd/doc/InternalApiBridge.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/InternalApiBridge.java | 2 +- .../net/sourceforge/pmd/lang/java/types/InternalApiBridge.java | 2 +- .../sourceforge/pmd/lang/java/types/ast/InternalApiBridge.java | 2 +- .../net/sourceforge/pmd/lang/jsp/ast/InternalApiBridge.java | 2 +- .../sourceforge/pmd/lang/modelica/ast/InternalApiBridge.java | 2 +- .../pmd/lang/modelica/resolver/InternalApiBridge.java | 2 +- .../net/sourceforge/pmd/lang/plsql/ast/InternalApiBridge.java | 2 +- .../sourceforge/pmd/lang/visualforce/ast/InternalApiBridge.java | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) diff --git a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/InternalApiBridge.java b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/InternalApiBridge.java index 604e9c39971..b229c92b325 100644 --- a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/InternalApiBridge.java +++ b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/InternalApiBridge.java @@ -20,7 +20,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API + * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/InternalApiBridge.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/InternalApiBridge.java index beba36c4f7a..722d189262b 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/InternalApiBridge.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/InternalApiBridge.java @@ -16,7 +16,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API + * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/InternalApiBridge.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/InternalApiBridge.java index 08d11470c57..2880de65cf2 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/InternalApiBridge.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/InternalApiBridge.java @@ -22,7 +22,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API + * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/InternalApiBridge.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/InternalApiBridge.java index 460ae0dd37b..be928de60c4 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/InternalApiBridge.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/InternalApiBridge.java @@ -15,7 +15,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API + * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/SemanticException.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/SemanticException.java index b4302699596..771514ede79 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/SemanticException.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/SemanticException.java @@ -30,7 +30,7 @@ public SemanticException(String message, Throwable cause) { } /** - * @apiNote Internal API + * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public void setReported() { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/InternalApiBridge.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/InternalApiBridge.java index 7c602331797..d6523ef6ee2 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/InternalApiBridge.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/InternalApiBridge.java @@ -17,7 +17,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API + * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/InternalApiBridge.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/InternalApiBridge.java index 802d07ccad9..092e387787b 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/InternalApiBridge.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/InternalApiBridge.java @@ -22,7 +22,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API + * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/Attribute.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/Attribute.java index 2799d75db6d..d0fc65a0f39 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/Attribute.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/Attribute.java @@ -78,7 +78,7 @@ public Attribute(@NonNull Node parent, @NonNull String name, @Nullable String va * Note that the type must be supported by {@link net.sourceforge.pmd.lang.rule.xpath.internal.DomainConversion} * if you want this attribute to be used from XPath. * - * @apiNote Internal API + * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. * @since 7.20.0 */ @InternalApi // used for tests diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/InternalApiBridge.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/InternalApiBridge.java index 60519103428..7d3bf7fc4b3 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/InternalApiBridge.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/InternalApiBridge.java @@ -15,7 +15,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API + * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/InternalApiBridge.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/InternalApiBridge.java index b9647e6554f..c0bb2f313ae 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/InternalApiBridge.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/InternalApiBridge.java @@ -18,7 +18,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API + * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/InternalApiBridge.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/InternalApiBridge.java index be65d395216..d996ed6330f 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/InternalApiBridge.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/InternalApiBridge.java @@ -20,7 +20,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API + * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/InternalApiBridgeForTestsOnly.java b/pmd-core/src/test/java/net/sourceforge/pmd/InternalApiBridgeForTestsOnly.java index f12d571d01a..d8922af0fe7 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/InternalApiBridgeForTestsOnly.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/InternalApiBridgeForTestsOnly.java @@ -16,7 +16,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API + * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridgeForTestsOnly { diff --git a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/InternalApiBridge.java b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/InternalApiBridge.java index 58746a417da..fd10889471f 100644 --- a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/InternalApiBridge.java +++ b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/InternalApiBridge.java @@ -15,7 +15,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API + * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalApiBridge.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalApiBridge.java index bdaf9e89724..3600ef978a5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalApiBridge.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalApiBridge.java @@ -47,7 +47,7 @@ * * @author Clรฉment Fournier * @since 7.0.0 - * @apiNote Internal API + * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/InternalApiBridge.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/InternalApiBridge.java index c5c19bcf507..779c477c938 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/InternalApiBridge.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/InternalApiBridge.java @@ -15,7 +15,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API + * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/InternalApiBridge.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/InternalApiBridge.java index 5b28467a0e0..a7339d8e484 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/InternalApiBridge.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/InternalApiBridge.java @@ -22,7 +22,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API + * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/InternalApiBridge.java b/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/InternalApiBridge.java index ec6966ef080..ef9c6bcdf4d 100644 --- a/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/InternalApiBridge.java +++ b/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/InternalApiBridge.java @@ -16,7 +16,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API + * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/InternalApiBridge.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/InternalApiBridge.java index 320be32319f..fa3d05f9b04 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/InternalApiBridge.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/InternalApiBridge.java @@ -19,7 +19,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API + * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/InternalApiBridge.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/InternalApiBridge.java index 7ef7190fc55..9ee4f86c53d 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/InternalApiBridge.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/InternalApiBridge.java @@ -20,7 +20,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API + * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/InternalApiBridge.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/InternalApiBridge.java index c9c2a348b4b..20937b02224 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/InternalApiBridge.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/InternalApiBridge.java @@ -22,7 +22,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API + * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/InternalApiBridge.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/InternalApiBridge.java index 2124753744b..254985e4194 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/InternalApiBridge.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/InternalApiBridge.java @@ -16,7 +16,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API + * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { From 6751d434a537660e55cd056de9f525c8fec0fc52 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 29 Jan 2026 16:32:29 +0100 Subject: [PATCH 1954/1962] chore: @apiNote -> @internalApi --- .../main/java/net/sourceforge/pmd/ant/InternalApiBridge.java | 2 +- .../main/java/net/sourceforge/pmd/ant/ReportException.java | 2 +- .../pmd/lang/apex/multifile/InternalApiBridge.java | 2 +- .../src/main/java/net/sourceforge/pmd/PMDConfiguration.java | 4 ++-- pmd-core/src/main/java/net/sourceforge/pmd/cpd/Tokens.java | 2 +- .../java/net/sourceforge/pmd/lang/InternalApiBridge.java | 2 +- .../java/net/sourceforge/pmd/lang/LanguageProcessor.java | 4 ++-- .../java/net/sourceforge/pmd/lang/ast/InternalApiBridge.java | 2 +- .../main/java/net/sourceforge/pmd/lang/ast/LexException.java | 2 +- .../java/net/sourceforge/pmd/lang/ast/SemanticException.java | 2 +- .../net/sourceforge/pmd/lang/document/FileCollector.java | 4 ++-- .../net/sourceforge/pmd/lang/document/InternalApiBridge.java | 2 +- .../net/sourceforge/pmd/lang/rule/InternalApiBridge.java | 2 +- .../src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java | 4 ++-- .../net/sourceforge/pmd/lang/rule/RuleSetLoadException.java | 4 ++-- .../java/net/sourceforge/pmd/lang/rule/RuleSetLoader.java | 2 +- .../java/net/sourceforge/pmd/lang/rule/xpath/Attribute.java | 4 ++-- .../sourceforge/pmd/lang/rule/xpath/InternalApiBridge.java | 2 +- .../net/sourceforge/pmd/properties/InternalApiBridge.java | 2 +- .../net/sourceforge/pmd/properties/PropertyDescriptor.java | 2 +- .../sourceforge/pmd/properties/internal/PropertyTypeId.java | 2 +- .../net/sourceforge/pmd/reporting/InternalApiBridge.java | 2 +- .../sourceforge/pmd/reporting/ParametricRuleViolation.java | 2 +- .../main/java/net/sourceforge/pmd/reporting/RuleContext.java | 4 ++-- .../net/sourceforge/pmd/util/internal/ResourceLoader.java | 2 +- .../net/sourceforge/pmd/InternalApiBridgeForTestsOnly.java | 2 +- .../main/java/net/sourceforge/pmd/doc/InternalApiBridge.java | 2 +- .../net/sourceforge/pmd/lang/java/ast/InternalApiBridge.java | 2 +- .../java/rule/internal/AbstractIgnoredAnnotationRule.java | 2 +- .../sourceforge/pmd/lang/java/types/InternalApiBridge.java | 2 +- .../java/net/sourceforge/pmd/lang/java/types/TypeOps.java | 2 +- .../pmd/lang/java/types/ast/InternalApiBridge.java | 2 +- .../net/sourceforge/pmd/lang/jsp/ast/InternalApiBridge.java | 2 +- .../sourceforge/pmd/lang/modelica/ast/InternalApiBridge.java | 2 +- .../pmd/lang/modelica/resolver/InternalApiBridge.java | 2 +- .../sourceforge/pmd/lang/plsql/ast/InternalApiBridge.java | 2 +- .../pmd/lang/plsql/rule/design/AbstractNcssCountRule.java | 2 +- .../pmd/lang/visualforce/ast/InternalApiBridge.java | 2 +- pom.xml | 5 +++++ 39 files changed, 50 insertions(+), 45 deletions(-) diff --git a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/InternalApiBridge.java b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/InternalApiBridge.java index b229c92b325..f9d4f776344 100644 --- a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/InternalApiBridge.java +++ b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/InternalApiBridge.java @@ -20,7 +20,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/ReportException.java b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/ReportException.java index d4737e99286..304aec78b36 100644 --- a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/ReportException.java +++ b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/ReportException.java @@ -6,7 +6,7 @@ /** * @author Philippe T'Seyen - * @apiNote Internal API + * @internalApi Internal API */ class ReportException extends RuntimeException { private static final long serialVersionUID = 6043174086675858209L; diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/InternalApiBridge.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/InternalApiBridge.java index 722d189262b..31b79ecf902 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/InternalApiBridge.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/multifile/InternalApiBridge.java @@ -16,7 +16,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java index bbd888aba82..7906dd33241 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java @@ -365,7 +365,7 @@ public void setReportProperties(Properties reportProperties) { * * @return The currently used analysis cache. Never null. * - * @apiNote This is internal API. + * @internalApi This is internal API. */ AnalysisCache getAnalysisCache() { // Make sure we are not null @@ -385,7 +385,7 @@ AnalysisCache getAnalysisCache() { * * @param cache The analysis cache to be used. * - * @apiNote This is internal API. Use {@link #setAnalysisCacheLocation(String)} to configure a cache. + * @internalApi This is internal API. Use {@link #setAnalysisCacheLocation(String)} to configure a cache. */ void setAnalysisCache(final AnalysisCache cache) { // the doc says it's a noop if incremental analysis was disabled, diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Tokens.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Tokens.java index b2a4c384ce5..1f1f4accb98 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Tokens.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Tokens.java @@ -32,7 +32,7 @@ public class Tokens { /** * Create a new instance. * - * @apiNote Internal API + * @internalApi Internal API */ Tokens() { // constructor is package private diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/InternalApiBridge.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/InternalApiBridge.java index 2880de65cf2..446e90c1594 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/InternalApiBridge.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/InternalApiBridge.java @@ -22,7 +22,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageProcessor.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageProcessor.java index 48bcdbcce83..96ec80c1f5d 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageProcessor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageProcessor.java @@ -72,7 +72,7 @@ class AnalysisTask { * Create a new task. This constructor is internal and will be * called by PMD. * - * @apiNote Internal API + * @internalApi Internal API */ AnalysisTask(RuleSets rulesets, List files, @@ -121,7 +121,7 @@ public LanguageProcessorRegistry getLpRegistry() { /** * Produce a new analysis task with just different files. * - * @apiNote Internal API + * @internalApi Internal API */ AnalysisTask withFiles(List newFiles) { return new AnalysisTask( diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/InternalApiBridge.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/InternalApiBridge.java index be928de60c4..7f83891a72f 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/InternalApiBridge.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/InternalApiBridge.java @@ -15,7 +15,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/LexException.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/LexException.java index 6331d798c9c..260a5c1ad04 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/LexException.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/LexException.java @@ -44,7 +44,7 @@ public LexException(int line, int column, @Nullable FileId filename, String mess /** * Constructor called by JavaCC. * - * @apiNote Internal API. + * @internalApi Internal API. */ LexException(boolean eofSeen, String lexStateName, int errorLine, int errorColumn, String errorAfter, char curChar) { super(makeReason(eofSeen, lexStateName, errorAfter, curChar)); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/SemanticException.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/SemanticException.java index 771514ede79..1f7c406469d 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/SemanticException.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/SemanticException.java @@ -30,7 +30,7 @@ public SemanticException(String message, Throwable cause) { } /** - * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public void setReported() { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java index 86865c7ffc6..197120250c4 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java @@ -73,7 +73,7 @@ private FileCollector(LanguageVersionDiscoverer discoverer, PmdReporter reporter } /** - * @apiNote Internal API - please use {@link PmdAnalysis#files()} instead of + * @internalApi Please use {@link PmdAnalysis#files()} instead of * creating a collector yourself. */ static FileCollector newCollector(LanguageVersionDiscoverer discoverer, PmdReporter reporter) { @@ -83,7 +83,7 @@ static FileCollector newCollector(LanguageVersionDiscoverer discoverer, PmdRepor /** * Returns a new collector using the same configuration except for the logger. * - * @apiNote Internal API - please use {@link PmdAnalysis#files()} instead of + * @internalApi Please use {@link PmdAnalysis#files()} instead of * creating a collector yourself. */ FileCollector newCollector(PmdReporter logger) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/InternalApiBridge.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/InternalApiBridge.java index d6523ef6ee2..5226c8efbd4 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/InternalApiBridge.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/InternalApiBridge.java @@ -17,7 +17,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/InternalApiBridge.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/InternalApiBridge.java index 092e387787b..02e40e881ce 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/InternalApiBridge.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/InternalApiBridge.java @@ -22,7 +22,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java index e131a0f037f..9f8acf7ce77 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java @@ -627,7 +627,7 @@ public Rule getRuleByName(String ruleName) { * @return true if the file should be checked, * false otherwise * - * @apiNote Internal API. + * @internalApi Internal API. */ boolean applies(FileId qualFileName) { return filter.test(qualFileName.getAbsolutePath()); @@ -646,7 +646,7 @@ boolean applies(FileId qualFileName) { * @return true if the given rule matches the given language, * which means, that the rule would be executed. * - * @apiNote This is internal API. + * @internalApi This is internal API. */ static boolean applies(Rule rule, LanguageVersion languageVersion) { assert rule.getLanguage() != null : "Rule has no language " + rule; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetLoadException.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetLoadException.java index ca533803844..226de16c8f3 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetLoadException.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetLoadException.java @@ -17,14 +17,14 @@ public class RuleSetLoadException extends RuntimeException { /** - * @apiNote Internal API. + * @internalApi Internal API. */ RuleSetLoadException(RuleSetReferenceId rsetId, @NonNull Throwable cause) { super("Cannot load ruleset " + rsetId + ": " + cause.getMessage(), cause); } /** - * @apiNote Internal API. + * @internalApi Internal API. */ RuleSetLoadException(RuleSetReferenceId rsetId, String message) { super("Cannot load ruleset " + rsetId + ": " + message); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetLoader.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetLoader.java index f53763e1069..53c66a964c1 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetLoader.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetLoader.java @@ -190,7 +190,7 @@ public List loadFromResources(Collection paths) { * Loads a list of rulesets, if any has an error, report it on the contextual * error reporter instead of aborting, and continue loading the rest. * - * @apiNote Internal API: might be published later, or maybe this + * @internalApi Internal API: might be published later, or maybe this * will be the default behaviour of every method of this class. */ List loadRuleSetsWithoutException(List rulesetPaths) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/Attribute.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/Attribute.java index d0fc65a0f39..4e1de7fb89f 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/Attribute.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/Attribute.java @@ -78,7 +78,7 @@ public Attribute(@NonNull Node parent, @NonNull String name, @Nullable String va * Note that the type must be supported by {@link net.sourceforge.pmd.lang.rule.xpath.internal.DomainConversion} * if you want this attribute to be used from XPath. * - * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. * @since 7.20.0 */ @InternalApi // used for tests @@ -120,7 +120,7 @@ public Type getType() { * Returns null for "not deprecated", empty string for "deprecated without replacement", * otherwise name of replacement attribute. * - * @apiNote Internal API + * @internalApi Internal API */ String replacementIfDeprecated() { if (method == null) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/InternalApiBridge.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/InternalApiBridge.java index 7d3bf7fc4b3..9543c34302f 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/InternalApiBridge.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/InternalApiBridge.java @@ -15,7 +15,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/InternalApiBridge.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/InternalApiBridge.java index c0bb2f313ae..4a55a99cb2f 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/InternalApiBridge.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/InternalApiBridge.java @@ -18,7 +18,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyDescriptor.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyDescriptor.java index a5abed824a6..9c9f81a2916 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyDescriptor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyDescriptor.java @@ -106,7 +106,7 @@ public PropertySerializer serializer() { * null if this property was defined in Java code and not in XML. This * is used to write the property back to XML, when using a {@link RuleSetWriter}. * - * @apiNote Internal API + * @internalApi Internal API */ @Nullable PropertyTypeId getTypeId() { return typeId; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyTypeId.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyTypeId.java index 08928569eb9..2a686bd8d1a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyTypeId.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyTypeId.java @@ -28,7 +28,7 @@ * * @author Clรฉment Fournier * @since 6.0.0 - * @apiNote Internal API + * @internalApi Internal API */ public enum PropertyTypeId { // These are exclusively used for XPath rules. It would make more sense to model the supported diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/InternalApiBridge.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/InternalApiBridge.java index d996ed6330f..b5316f18b3f 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/InternalApiBridge.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/InternalApiBridge.java @@ -20,7 +20,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ParametricRuleViolation.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ParametricRuleViolation.java index c6a4328f6b3..6b600c6a061 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ParametricRuleViolation.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ParametricRuleViolation.java @@ -12,7 +12,7 @@ import net.sourceforge.pmd.util.AssertionUtil; /** - * @apiNote This is internal API. Clients should exclusively use {@link RuleViolation}. + * @internalApi This is internal API. Clients should exclusively use {@link RuleViolation}. */ class ParametricRuleViolation implements RuleViolation { protected final Rule rule; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java index 38c5a75230e..a52e9c7ebe7 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java @@ -53,7 +53,7 @@ public final class RuleContext { private final Rule rule; /** - * @apiNote Internal API + * @internalApi Internal API */ RuleContext(FileAnalysisListener listener, Rule rule) { Objects.requireNonNull(listener, "Listener was null"); @@ -63,7 +63,7 @@ public final class RuleContext { } /** - * @apiNote Internal API. Used in {@link AbstractRule} in {@code asCtx(Object)}, + * @internalApi Internal API. Used in {@link AbstractRule} in {@code asCtx(Object)}, * through {@link InternalApiBridge}. */ Rule getRule() { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/internal/ResourceLoader.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/internal/ResourceLoader.java index 015b536b063..599d0c1ebc5 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/internal/ResourceLoader.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/internal/ResourceLoader.java @@ -22,7 +22,7 @@ import net.sourceforge.pmd.lang.rule.xpath.XPathRule; /** - * @apiNote Internal API + * @internalApi Internal API */ public class ResourceLoader { diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/InternalApiBridgeForTestsOnly.java b/pmd-core/src/test/java/net/sourceforge/pmd/InternalApiBridgeForTestsOnly.java index d8922af0fe7..8595b77894b 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/InternalApiBridgeForTestsOnly.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/InternalApiBridgeForTestsOnly.java @@ -16,7 +16,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridgeForTestsOnly { diff --git a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/InternalApiBridge.java b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/InternalApiBridge.java index fd10889471f..b8627fcf59f 100644 --- a/pmd-doc/src/main/java/net/sourceforge/pmd/doc/InternalApiBridge.java +++ b/pmd-doc/src/main/java/net/sourceforge/pmd/doc/InternalApiBridge.java @@ -15,7 +15,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalApiBridge.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalApiBridge.java index 3600ef978a5..596dc331dcb 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalApiBridge.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/InternalApiBridge.java @@ -47,7 +47,7 @@ * * @author Clรฉment Fournier * @since 7.0.0 - * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractIgnoredAnnotationRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractIgnoredAnnotationRule.java index a753ca45d87..10df6b2dfc7 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractIgnoredAnnotationRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractIgnoredAnnotationRule.java @@ -15,7 +15,7 @@ import net.sourceforge.pmd.properties.PropertyDescriptor; /** - * @apiNote Internal API + * @internalApi Internal API */ public abstract class AbstractIgnoredAnnotationRule extends AbstractJavaRule { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/InternalApiBridge.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/InternalApiBridge.java index 779c477c938..fd8f7678bff 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/InternalApiBridge.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/InternalApiBridge.java @@ -15,7 +15,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java index d69d484ed3e..e4489318b9f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java @@ -95,7 +95,7 @@ public static boolean isSameTypeWithSameAnnotations(JTypeMirror t, JTypeMirror s * Return true if t and s are the same type. This may perform side effects * on inference variables. Annotations are ignored. * - * @apiNote Internal API + * @internalApi Internal API */ static boolean isSameTypeInInference(JTypeMirror t, JTypeMirror s) { return isSameType(t, s, false, false); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/InternalApiBridge.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/InternalApiBridge.java index a7339d8e484..96b9997ef89 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/InternalApiBridge.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/ast/InternalApiBridge.java @@ -22,7 +22,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/InternalApiBridge.java b/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/InternalApiBridge.java index ef9c6bcdf4d..af2e4fe7af0 100644 --- a/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/InternalApiBridge.java +++ b/pmd-jsp/src/main/java/net/sourceforge/pmd/lang/jsp/ast/InternalApiBridge.java @@ -16,7 +16,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/InternalApiBridge.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/InternalApiBridge.java index fa3d05f9b04..5b6c869f7ad 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/InternalApiBridge.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/ast/InternalApiBridge.java @@ -19,7 +19,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/InternalApiBridge.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/InternalApiBridge.java index 9ee4f86c53d..82d9e871a88 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/InternalApiBridge.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/lang/modelica/resolver/InternalApiBridge.java @@ -20,7 +20,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/InternalApiBridge.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/InternalApiBridge.java index 20937b02224..f2a573b434f 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/InternalApiBridge.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/InternalApiBridge.java @@ -22,7 +22,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/AbstractNcssCountRule.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/AbstractNcssCountRule.java index 8af1ac8b3a2..d4920cb9251 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/AbstractNcssCountRule.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/AbstractNcssCountRule.java @@ -30,7 +30,7 @@ * Abstract superclass for NCSS counting methods. Analogous to and cribbed from * the Java version of the rule. * - * @apiNote Internal API + * @internalApi Internal API * @deprecated Since 7.19.0. */ @Deprecated diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/InternalApiBridge.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/InternalApiBridge.java index 254985e4194..e08182a6376 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/InternalApiBridge.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/lang/visualforce/ast/InternalApiBridge.java @@ -16,7 +16,7 @@ *

            None of this is published API, and compatibility can be broken anytime! * Use this only at your own risk. * - * @apiNote Internal API. None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @InternalApi public final class InternalApiBridge { diff --git a/pom.xml b/pom.xml index 85ee5223cd1..292e431342c 100644 --- a/pom.xml +++ b/pom.xml @@ -435,6 +435,11 @@ a Implementation Note: + + internalApi + a + Internal API: + experimental a From c90cd52f8030630b5fcd215775fe6e9c6f3e9678 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 8 Jan 2026 13:01:00 +0100 Subject: [PATCH 1955/1962] [doc] ADR 3: Clarify javadoc tags Add details on how to use javadoc tags for deprecated, experimental and internal APIs. --- docs/pages/pmd/projectdocs/decisions/adr-3.md | 8 +++++++- .../sourceforge/pmd/annotation/Experimental.java | 13 +++++++++++++ .../net/sourceforge/pmd/annotation/InternalApi.java | 12 ++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/docs/pages/pmd/projectdocs/decisions/adr-3.md b/docs/pages/pmd/projectdocs/decisions/adr-3.md index 35357d08d3c..68d9fe6ac19 100644 --- a/docs/pages/pmd/projectdocs/decisions/adr-3.md +++ b/docs/pages/pmd/projectdocs/decisions/adr-3.md @@ -6,7 +6,7 @@ sidebaractiveurl: /pmd_projectdocs_decisions.html adr: true # Proposed / Accepted / Deprecated / Superseded adr_status: "Accepted" -last_updated: February 2024 (7.0.0) +last_updated: January 2026 (7.21.0) --- @@ -102,6 +102,8 @@ All packages are considered to be public API by default, with **two exceptions** The `@InternalApi` annotation will be used for types that have to live outside of these packages, e.g. methods of a public type that shouldn't be used outside PMD (again, these can be removed anytime). + The javadoc tag `@internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk.` + will be added additionally. * Any package that contains an `impl` segment is considered internal. E.g. `net.sourceforge.pmd.lang.impl`. These packages contain base classes that are needed for extending PMD (like adding a new language). @@ -117,6 +119,7 @@ All packages are considered to be public API by default, with **two exceptions** * APIs can be deprecated at any time (even in PATCH versions). Deprecated APIs are marked with the `@Deprecated` annotation. + The javadoc tag `@deprecated Since x.y.z. Description` will be added additionally. * Deprecations should be listed in the release notes. * Deprecated APIs can only be removed with a MAJOR version change. @@ -124,6 +127,7 @@ All packages are considered to be public API by default, with **two exceptions** * New features often introduce new APIs. These new APIs can be marked with the annotation `@Experimental` at the class or method level. + These new APIs should use the javadoc tags `@since x.y.z` and `@experimental Description`. * APIs marked with the `@Experimental` annotation are subject to change and are considered **not stable**. They can be modified in any way, or even removed, at any time. You should not use or rely on them in any production code. They are purely to allow broad testing and feedback. @@ -184,6 +188,8 @@ Non-concrete AST classes (like base classes or common interfaces) should follow ## Change History +2026-01-29: Added details on how to use javadoc tags for deprecated, experimental and internal APIs. ([#6392](https://github.com/pmd/pmd/pull/6392)) + 2024-02-01: Changed status to "Accepted". ([#4756](https://github.com/pmd/pmd/pull/4756)) 2023-12-01: Proposed initial version. diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/annotation/Experimental.java b/pmd-core/src/main/java/net/sourceforge/pmd/annotation/Experimental.java index 97cb2b64604..532e5a158cf 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/annotation/Experimental.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/annotation/Experimental.java @@ -13,6 +13,19 @@ * The API members can be modified in any way, or even removed, at any time, without warning. * You should not use or rely on them in any production code. They are purely to allow broad testing and feedback. * + *

            Example usage: + *

            + * public class Example
            + *     /**
            + *      * @since 7.21.0
            + *      * @experimental New way to do x.
            + *      */
            + *     {@literal @}Experimental
            + *     public void calculateLength() {
            + *         ...
            + *     }
            + * 
            + * @since 6.7.0 */ @Documented diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/annotation/InternalApi.java b/pmd-core/src/main/java/net/sourceforge/pmd/annotation/InternalApi.java index cd56e76fafd..610e14807ae 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/annotation/InternalApi.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/annotation/InternalApi.java @@ -14,6 +14,18 @@ *

            Such members may be removed, renamed, moved, or otherwise broken at any time and should not be * relied upon outside the main PMD codebase. * + *

            Example usage: + *

            + * public class Example
            + *     /**
            + *      * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk.
            + *      */
            + *     {@literal @}InternalApi
            + *     public void internalHelperMethod() {
            + *         ...
            + *     }
            + * 
            + * * @since 6.7.0 */ @Documented From 7dcfeeafdb11c1f190a95f088c919331d9b397d6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 29 Jan 2026 16:48:28 +0100 Subject: [PATCH 1956/1962] chore: add full description to internalApi javadoc --- .../java/net/sourceforge/pmd/ant/ReportException.java | 2 +- .../main/java/net/sourceforge/pmd/PMDConfiguration.java | 5 +++-- .../src/main/java/net/sourceforge/pmd/cpd/Tokens.java | 2 +- .../java/net/sourceforge/pmd/lang/LanguageProcessor.java | 4 ++-- .../java/net/sourceforge/pmd/lang/ast/LexException.java | 2 +- .../net/sourceforge/pmd/lang/document/FileCollector.java | 8 ++++---- .../main/java/net/sourceforge/pmd/lang/rule/RuleSet.java | 4 ++-- .../sourceforge/pmd/lang/rule/RuleSetLoadException.java | 2 +- .../java/net/sourceforge/pmd/lang/rule/RuleSetLoader.java | 4 ++-- .../net/sourceforge/pmd/lang/rule/xpath/Attribute.java | 2 +- .../sourceforge/pmd/properties/PropertyDescriptor.java | 2 +- .../pmd/properties/internal/PropertyTypeId.java | 2 +- .../pmd/reporting/ParametricRuleViolation.java | 3 ++- .../java/net/sourceforge/pmd/reporting/RuleContext.java | 6 +++--- .../net/sourceforge/pmd/util/internal/ResourceLoader.java | 2 +- .../java/rule/internal/AbstractIgnoredAnnotationRule.java | 2 +- .../java/net/sourceforge/pmd/lang/java/types/TypeOps.java | 2 +- .../pmd/lang/plsql/rule/design/AbstractNcssCountRule.java | 2 +- 18 files changed, 29 insertions(+), 27 deletions(-) diff --git a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/ReportException.java b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/ReportException.java index 304aec78b36..02ad69bc73f 100644 --- a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/ReportException.java +++ b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/ReportException.java @@ -6,7 +6,7 @@ /** * @author Philippe T'Seyen - * @internalApi Internal API + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ class ReportException extends RuntimeException { private static final long serialVersionUID = 6043174086675858209L; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java index 7906dd33241..4de5e1f65bc 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java @@ -365,7 +365,7 @@ public void setReportProperties(Properties reportProperties) { * * @return The currently used analysis cache. Never null. * - * @internalApi This is internal API. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ AnalysisCache getAnalysisCache() { // Make sure we are not null @@ -385,7 +385,8 @@ AnalysisCache getAnalysisCache() { * * @param cache The analysis cache to be used. * - * @internalApi This is internal API. Use {@link #setAnalysisCacheLocation(String)} to configure a cache. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * Use {@link #setAnalysisCacheLocation(String)} to configure a cache. */ void setAnalysisCache(final AnalysisCache cache) { // the doc says it's a noop if incremental analysis was disabled, diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Tokens.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Tokens.java index 1f1f4accb98..532d29ca72e 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Tokens.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Tokens.java @@ -32,7 +32,7 @@ public class Tokens { /** * Create a new instance. * - * @internalApi Internal API + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ Tokens() { // constructor is package private diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageProcessor.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageProcessor.java index 96ec80c1f5d..7ab7a7e4954 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageProcessor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageProcessor.java @@ -72,7 +72,7 @@ class AnalysisTask { * Create a new task. This constructor is internal and will be * called by PMD. * - * @internalApi Internal API + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ AnalysisTask(RuleSets rulesets, List files, @@ -121,7 +121,7 @@ public LanguageProcessorRegistry getLpRegistry() { /** * Produce a new analysis task with just different files. * - * @internalApi Internal API + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ AnalysisTask withFiles(List newFiles) { return new AnalysisTask( diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/LexException.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/LexException.java index 260a5c1ad04..b89c1825619 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/LexException.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/LexException.java @@ -44,7 +44,7 @@ public LexException(int line, int column, @Nullable FileId filename, String mess /** * Constructor called by JavaCC. * - * @internalApi Internal API. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ LexException(boolean eofSeen, String lexStateName, int errorLine, int errorColumn, String errorAfter, char curChar) { super(makeReason(eofSeen, lexStateName, errorAfter, curChar)); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java index 197120250c4..bf055975b83 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java @@ -73,8 +73,8 @@ private FileCollector(LanguageVersionDiscoverer discoverer, PmdReporter reporter } /** - * @internalApi Please use {@link PmdAnalysis#files()} instead of - * creating a collector yourself. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * Please use {@link PmdAnalysis#files()} instead of creating a collector yourself. */ static FileCollector newCollector(LanguageVersionDiscoverer discoverer, PmdReporter reporter) { return new FileCollector(discoverer, reporter, null); @@ -83,8 +83,8 @@ static FileCollector newCollector(LanguageVersionDiscoverer discoverer, PmdRepor /** * Returns a new collector using the same configuration except for the logger. * - * @internalApi Please use {@link PmdAnalysis#files()} instead of - * creating a collector yourself. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * Please use {@link PmdAnalysis#files()} instead of creating a collector yourself. */ FileCollector newCollector(PmdReporter logger) { FileCollector fileCollector = new FileCollector(discoverer, logger, null); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java index 9f8acf7ce77..eb1b5ccfa2e 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSet.java @@ -627,7 +627,7 @@ public Rule getRuleByName(String ruleName) { * @return true if the file should be checked, * false otherwise * - * @internalApi Internal API. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ boolean applies(FileId qualFileName) { return filter.test(qualFileName.getAbsolutePath()); @@ -646,7 +646,7 @@ boolean applies(FileId qualFileName) { * @return true if the given rule matches the given language, * which means, that the rule would be executed. * - * @internalApi This is internal API. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ static boolean applies(Rule rule, LanguageVersion languageVersion) { assert rule.getLanguage() != null : "Rule has no language " + rule; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetLoadException.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetLoadException.java index 226de16c8f3..4623061a731 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetLoadException.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetLoadException.java @@ -17,7 +17,7 @@ public class RuleSetLoadException extends RuntimeException { /** - * @internalApi Internal API. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ RuleSetLoadException(RuleSetReferenceId rsetId, @NonNull Throwable cause) { super("Cannot load ruleset " + rsetId + ": " + cause.getMessage(), cause); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetLoader.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetLoader.java index 53c66a964c1..2b3405a29da 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetLoader.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/RuleSetLoader.java @@ -190,8 +190,8 @@ public List loadFromResources(Collection paths) { * Loads a list of rulesets, if any has an error, report it on the contextual * error reporter instead of aborting, and continue loading the rest. * - * @internalApi Internal API: might be published later, or maybe this - * will be the default behaviour of every method of this class. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * It might be published later, or maybe this will be the default behaviour of every method of this class. */ List loadRuleSetsWithoutException(List rulesetPaths) { List ruleSets = new ArrayList<>(rulesetPaths.size()); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/Attribute.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/Attribute.java index 4e1de7fb89f..91b179fed90 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/Attribute.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/Attribute.java @@ -120,7 +120,7 @@ public Type getType() { * Returns null for "not deprecated", empty string for "deprecated without replacement", * otherwise name of replacement attribute. * - * @internalApi Internal API + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ String replacementIfDeprecated() { if (method == null) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyDescriptor.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyDescriptor.java index 9c9f81a2916..877cfae00f1 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyDescriptor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/PropertyDescriptor.java @@ -106,7 +106,7 @@ public PropertySerializer serializer() { * null if this property was defined in Java code and not in XML. This * is used to write the property back to XML, when using a {@link RuleSetWriter}. * - * @internalApi Internal API + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ @Nullable PropertyTypeId getTypeId() { return typeId; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyTypeId.java b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyTypeId.java index 2a686bd8d1a..3dfcf85175f 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyTypeId.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/properties/internal/PropertyTypeId.java @@ -28,7 +28,7 @@ * * @author Clรฉment Fournier * @since 6.0.0 - * @internalApi Internal API + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ public enum PropertyTypeId { // These are exclusively used for XPath rules. It would make more sense to model the supported diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ParametricRuleViolation.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ParametricRuleViolation.java index 6b600c6a061..4575a506971 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ParametricRuleViolation.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ParametricRuleViolation.java @@ -12,7 +12,8 @@ import net.sourceforge.pmd.util.AssertionUtil; /** - * @internalApi This is internal API. Clients should exclusively use {@link RuleViolation}. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * Clients should exclusively use {@link RuleViolation}. */ class ParametricRuleViolation implements RuleViolation { protected final Rule rule; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java index a52e9c7ebe7..a69447e16ae 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java @@ -53,7 +53,7 @@ public final class RuleContext { private final Rule rule; /** - * @internalApi Internal API + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ RuleContext(FileAnalysisListener listener, Rule rule) { Objects.requireNonNull(listener, "Listener was null"); @@ -63,8 +63,8 @@ public final class RuleContext { } /** - * @internalApi Internal API. Used in {@link AbstractRule} in {@code asCtx(Object)}, - * through {@link InternalApiBridge}. + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. + * Used in {@link AbstractRule} in {@code asCtx(Object)}, through {@link InternalApiBridge}. */ Rule getRule() { return rule; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/internal/ResourceLoader.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/internal/ResourceLoader.java index 599d0c1ebc5..a61770dbacf 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/internal/ResourceLoader.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/internal/ResourceLoader.java @@ -22,7 +22,7 @@ import net.sourceforge.pmd.lang.rule.xpath.XPathRule; /** - * @internalApi Internal API + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ public class ResourceLoader { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractIgnoredAnnotationRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractIgnoredAnnotationRule.java index 10df6b2dfc7..27f8a7afb26 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractIgnoredAnnotationRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/AbstractIgnoredAnnotationRule.java @@ -15,7 +15,7 @@ import net.sourceforge.pmd.properties.PropertyDescriptor; /** - * @internalApi Internal API + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ public abstract class AbstractIgnoredAnnotationRule extends AbstractJavaRule { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java index e4489318b9f..94100c920c1 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java @@ -95,7 +95,7 @@ public static boolean isSameTypeWithSameAnnotations(JTypeMirror t, JTypeMirror s * Return true if t and s are the same type. This may perform side effects * on inference variables. Annotations are ignored. * - * @internalApi Internal API + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. */ static boolean isSameTypeInInference(JTypeMirror t, JTypeMirror s) { return isSameType(t, s, false, false); diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/AbstractNcssCountRule.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/AbstractNcssCountRule.java index d4920cb9251..2a611bda884 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/AbstractNcssCountRule.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/design/AbstractNcssCountRule.java @@ -30,7 +30,7 @@ * Abstract superclass for NCSS counting methods. Analogous to and cribbed from * the Java version of the rule. * - * @internalApi Internal API + * @internalApi None of this is published API, and compatibility can be broken anytime! Use this only at your own risk. * @deprecated Since 7.19.0. */ @Deprecated From 8fb286a6ade4d60e789203a3bb6a5626084a13bf Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 8 Jan 2026 12:12:56 +0100 Subject: [PATCH 1957/1962] chore: update javadoc experimental tags Add the since version separately. --- .../src/main/java/net/sourceforge/pmd/lang/Language.java | 6 ++++-- .../net/sourceforge/pmd/lang/LanguageModuleBase.java | 9 ++++++--- .../pmd/lang/ast/impl/SuppressionCommentImpl.java | 3 ++- .../lang/impl/BasePmdDialectLanguageVersionHandler.java | 2 +- .../pmd/lang/impl/SimpleDialectLanguageModuleBase.java | 2 +- .../lang/rule/impl/UnnecessaryPmdSuppressionRule.java | 3 ++- .../java/net/sourceforge/pmd/reporting/RuleContext.java | 9 ++++++--- .../sourceforge/pmd/reporting/ViolationSuppressor.java | 3 ++- .../pmd/lang/java/types/OverloadSelectionResult.java | 3 +++ 9 files changed, 27 insertions(+), 13 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java index e66a985e476..b80e11fa01a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/Language.java @@ -69,7 +69,8 @@ public interface Language extends Comparable { * Dialects are for example different flavors of XML. Dialects must share * the same AST as their base language. This makes it so that rules written * for the base language can be applied files of all dialects uniformly. - * @experimental Since 7.13.0. See [core] Support language dialects #5438. + * @since 7.13.0 + * @experimental See [core] Support language dialects #5438. */ @Experimental default @Nullable String getBaseLanguageId() { @@ -80,7 +81,8 @@ public interface Language extends Comparable { * Return true if this language is a dialect of the given language. * * @param language A language (not null) - * @experimental Since 7.13.0. See [core] Support language dialects #5438. + * @since 7.13.0 + * @experimental See [core] Support language dialects #5438. */ @Experimental @SuppressWarnings("PMD.SimplifyBooleanReturns") diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageModuleBase.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageModuleBase.java index b3d095c123f..5ff3f6e05ae 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageModuleBase.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/LanguageModuleBase.java @@ -55,7 +55,8 @@ protected LanguageModuleBase(LanguageMetadata metadata) { } /** - * @experimental Since 7.13.0. See [core] Support language dialects #5438. + * @since 7.13.0 + * @experimental See [core] Support language dialects #5438. */ @Experimental protected LanguageModuleBase(DialectLanguageMetadata metadata) { @@ -375,7 +376,8 @@ public LanguageMetadata addAllVersionsOf(Language language) { * * @param baseLanguageId The id of the base language this is a dialect of. * @return A new dialect language metadata model. - * @experimental Since 7.13.0. See [core] Support language dialects #5438. + * @since 7.13.0 + * @experimental See [core] Support language dialects #5438. */ @Experimental public DialectLanguageMetadata asDialectOf(String baseLanguageId) { @@ -442,7 +444,8 @@ private static void checkVersionName(String name) { /** * Expresses the language as a dialect of another language. - * @experimental Since 7.13.0. See [core] Support language dialects #5438. + * @since 7.13.0 + * @experimental See [core] Support language dialects #5438. */ @Experimental public static final class DialectLanguageMetadata { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/SuppressionCommentImpl.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/SuppressionCommentImpl.java index 580c13cc8c2..ea1318de68c 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/SuppressionCommentImpl.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/SuppressionCommentImpl.java @@ -15,7 +15,8 @@ * * @param Type of Reportable (node, token, lambda) * - * @experimental Since 7.14.0. See [core] Add rule to report unnecessary suppression comments/annotations #5609 + * @since 7.14.0 + * @experimental See [core] Add rule to report unnecessary suppression comments/annotations #5609 */ @Experimental public class SuppressionCommentImpl implements SuppressionCommentWrapper { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/BasePmdDialectLanguageVersionHandler.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/BasePmdDialectLanguageVersionHandler.java index 6cea5f62078..dc0ab97144c 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/BasePmdDialectLanguageVersionHandler.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/BasePmdDialectLanguageVersionHandler.java @@ -14,7 +14,7 @@ * * @author Juan Martรญn Sotuyo Dodero * @since 7.13.0 - * @experimental Since 7.13.0. See [core] Support language dialects #5438. + * @experimental See [core] Support language dialects #5438. */ @Experimental public class BasePmdDialectLanguageVersionHandler extends AbstractPmdLanguageVersionHandler { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java index 4b703e4db38..c0c4adf6a43 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/impl/SimpleDialectLanguageModuleBase.java @@ -40,7 +40,7 @@ * * @author Juan Martรญn Sotuyo Dodero * @since 7.13.0 - * @experimental Since 7.13.0. See [core] Support language dialects #5438. + * @experimental See [core] Support language dialects #5438. */ @Experimental public class SimpleDialectLanguageModuleBase extends LanguageModuleBase implements PmdCapableLanguage, CpdCapableLanguage { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/impl/UnnecessaryPmdSuppressionRule.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/impl/UnnecessaryPmdSuppressionRule.java index f48ac5ac6b8..4dbf1f20454 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/impl/UnnecessaryPmdSuppressionRule.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/impl/UnnecessaryPmdSuppressionRule.java @@ -27,7 +27,8 @@ * by {@link RuleSets} to execute after all other rules, so that whether * those produce warnings or not is known to this rule. * - * @experimental Since 7.14.0. See [core] Add rule to report unnecessary suppression comments/annotations #5609 + * @since 7.14.0 + * @experimental See [core] Add rule to report unnecessary suppression comments/annotations #5609 */ @Experimental public class UnnecessaryPmdSuppressionRule extends AbstractRule { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java index 38c5a75230e..da48964b0de 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/RuleContext.java @@ -157,7 +157,8 @@ public void addViolationWithPosition(Node node, int beginLine, int endLine, Stri * @param token Report location of the violation * @param message Violation message * @param formatArgs Format arguments for the message - * @experimental Since 7.17.0. This will probably never be stabilized, will instead be + * @since 7.17.0 + * @experimental This will probably never be stabilized, will instead be * replaced by a fluent API or something to report violations. Do not use * this outside of the PMD codebase. See [core] Add fluent API to report violations #5039. */ @@ -178,7 +179,8 @@ public void addViolationWithPosition(Node node, JavaccToken token, String messag * @param location Report location of the violation * @param message Violation message * @param formatArgs Format arguments for the message - * @experimental Since 7.9.0. This will probably never be stabilized, will instead be + * @since 7.9.0 + * @experimental This will probably never be stabilized, will instead be * replaced by a fluent API or something to report violations. Do not use * this outside of the PMD codebase. See [core] Add fluent API to report violations #5039. */ @@ -201,7 +203,8 @@ public void addViolationWithPosition(Reportable reportable, AstInfo astInfo, } /** - * @experimental Since 7.14.0. See [core] Add rule to report unnecessary suppression comments/annotations #5609 + * @since 7.14.0 + * @experimental See [core] Add rule to report unnecessary suppression comments/annotations #5609 */ @Experimental public void addViolationNoSuppress(Reportable reportable, AstInfo astInfo, diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ViolationSuppressor.java b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ViolationSuppressor.java index 6f7f0a926f6..96f37077a63 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ViolationSuppressor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/reporting/ViolationSuppressor.java @@ -221,7 +221,8 @@ interface UnusedSuppressorNode { /** * Wrapper around a suppression comment. * - * @experimental Since 7.14.0. See [core] Add rule to report unnecessary suppression comments/annotations #5609 + * @since 7.14.0 + * @experimental See [core] Add rule to report unnecessary suppression comments/annotations #5609 */ @Experimental interface SuppressionCommentWrapper { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java index adcd1854164..ab4ef1fb18d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/OverloadSelectionResult.java @@ -98,6 +98,7 @@ default JTypeMirror ithFormalParam(int i) { * constructor call expressions. * * @see ExprMirror.MethodUsageMirror#getTypeToSearch() + * @since 7.14.0 * @experimental Since 7.14.0 */ @Experimental @@ -107,6 +108,8 @@ default JTypeMirror ithFormalParam(int i) { /** * Return whether several overloads were applicable, and needed to * be disambiguated through specificity checks. + * + * @since 7.20.0 * @experimental Since 7.20.0 */ @Experimental From e7d97290ca933fd9c8bdb7708514ba0472b14e21 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 8 Jan 2026 11:50:07 +0100 Subject: [PATCH 1958/1962] chore: update javadoc deprecated tags All deprecated infos should contain the version, since the element has been deprecated. --- .../src/main/java/net/sourceforge/pmd/ant/CPDTask.java | 8 +++++++- .../commands/internal/AbstractAnalysisPmdSubcommand.java | 3 +++ .../sourceforge/pmd/cli/commands/internal/CpdCommand.java | 2 +- .../java/net/sourceforge/pmd/cpd/CPDConfiguration.java | 7 +++++-- .../main/java/net/sourceforge/pmd/cpd/XMLOldRenderer.java | 2 +- .../sourceforge/pmd/lang/ast/impl/antlr4/AntlrToken.java | 2 +- .../pmd/lang/ast/impl/javacc/AbstractTokenManager.java | 2 +- .../sourceforge/pmd/lang/symboltable/package-info.java | 7 ++++++- .../java/net/sourceforge/pmd/renderers/CSVWriter.java | 5 ++++- .../pmd/lang/java/ast/ASTClassDeclaration.java | 2 +- .../pmd/lang/java/ast/ASTFieldDeclaration.java | 2 +- .../pmd/lang/java/ast/ASTLambdaExpression.java | 4 ++-- .../sourceforge/pmd/lang/java/ast/ASTRecordPattern.java | 2 +- .../pmd/lang/java/ast/SyntacticJavaTokenizerFactory.java | 5 ++++- .../JUnitAssertionsShouldIncludeMessageRule.java | 2 +- .../JUnitTestContainsTooManyAssertsRule.java | 2 +- .../bestpractices/JUnitTestsShouldIncludeAssertRule.java | 2 +- .../pmd/lang/java/rule/design/ExcessiveImportsRule.java | 2 +- .../lang/java/rule/design/ExcessiveParameterListRule.java | 2 +- .../lang/java/rule/design/ExcessivePublicCountRule.java | 2 +- .../pmd/lang/java/rule/design/SingularFieldRule.java | 4 ++-- .../java/net/sourceforge/pmd/lang/java/types/TypeOps.java | 3 +++ .../sourceforge/pmd/lang/test/ast/BaseParsingHelper.kt | 6 ++++++ .../net/sourceforge/pmd/lang/test/ast/IntelliMarker.kt | 3 +++ 24 files changed, 58 insertions(+), 23 deletions(-) diff --git a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/CPDTask.java b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/CPDTask.java index 86558b60480..51141502518 100644 --- a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/CPDTask.java +++ b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/CPDTask.java @@ -67,6 +67,9 @@ public class CPDTask extends Task { private static final String TEXT_FORMAT = "text"; private static final String XML_FORMAT = "xml"; + /** + * @deprecated Since 7.3.0. + */ @Deprecated private static final String XMLOLD_FORMAT = "xmlold"; private static final String CSV_FORMAT = "csv"; @@ -78,6 +81,9 @@ public class CPDTask extends Task { private boolean ignoreIdentifiers; private boolean ignoreAnnotations; private boolean ignoreUsings; + /** + * @deprecated Since 7.3.0. + */ @Deprecated private boolean skipLexicalErrors; private boolean skipDuplicateFiles; @@ -241,7 +247,7 @@ public void setIgnoreUsings(boolean value) { } /** - * @deprecated Use {@link #setFailOnError(boolean)} instead. + * @deprecated Since 7.3.0. Use {@link #setFailOnError(boolean)} instead. */ @Deprecated public void setSkipLexicalErrors(boolean skipLexicalErrors) { diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java index ae321dac862..ba2c3b9112f 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java @@ -55,6 +55,9 @@ protected static class FileCollectionOptions { boolean usesDeprecatedIgnoreListOption = false; + /** + * @deprecated Since 7.14.0. Use {@code --exclude-file-list} instead. + */ @Option(names = "--ignore-list", description = "(DEPRECATED: use --exclude-file-list) Path to a file containing a list of files to exclude from the analysis, one path per line. " + "This option can be combined with --dir, --file-list and --uri.") diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java index b12b70eed5e..fb36fe90d8c 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java @@ -74,7 +74,7 @@ public class CpdCommand extends AbstractAnalysisPmdSubcommand private boolean ignoreIdentifierAndLiteralSequences; /** - * @deprecated Since 7.3.0. Use --[no-]fail-on-error instead. + * @deprecated Since 7.3.0. Use {@code --[no-]fail-on-error} instead. */ @Option(names = "--skip-lexical-errors", description = "Skip files which can't be tokenized due to invalid characters, instead of aborting with an error. Deprecated - use --[no-]fail-on-error instead.") diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java index fc2a110ab38..723d81f04d6 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java @@ -67,6 +67,9 @@ public class CPDConfiguration extends AbstractConfiguration { private boolean ignoreIdentifierAndLiteralSequences = false; + /** + * @deprecated Since 7.3.0. + */ @Deprecated // Note: The default value was false until up to 7.3.0 and is true since 7.4.0 private boolean skipLexicalErrors = true; @@ -231,7 +234,7 @@ public void setIgnoreIdentifierAndLiteralSequences(boolean ignoreIdentifierAndLi } /** - * @deprecated This option will be removed. With {@link #isFailOnError()}, you can + * @deprecated Since 7.3.0. This option will be removed. With {@link #isFailOnError()}, you can * control whether lexical errors should fail the build or not. */ @Deprecated @@ -240,7 +243,7 @@ public boolean isSkipLexicalErrors() { } /** - * @deprecated This option will be removed. With {@link #setFailOnError(boolean)}, you can + * @deprecated Since 7.3.0. This option will be removed. With {@link #setFailOnError(boolean)}, you can * control whether lexical errors should fail the build or not. */ @Deprecated diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLOldRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLOldRenderer.java index 3df44d6e961..10f6df1e816 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLOldRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLOldRenderer.java @@ -13,7 +13,7 @@ * *

            This renderer is available as "xmlold". * - * @deprecated Update your tools to use the standard XML renderer "xml" again. + * @deprecated Since 7.3.0. Update your tools to use the standard XML renderer "xml" again. */ @Deprecated public class XMLOldRenderer implements CPDReportRenderer { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrToken.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrToken.java index 5195beaa456..6bf189e050a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrToken.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrToken.java @@ -34,7 +34,7 @@ public class AntlrToken implements GenericToken { * @param previousComment The previous comment * @param textDoc The text document * - * @deprecated Don't create antlr tokens directly, use an {@link AntlrTokenManager} + * @deprecated Since 7.3.0. Don't create antlr tokens directly, use an {@link AntlrTokenManager} */ @Deprecated public AntlrToken(final Token token, final AntlrToken previousComment, TextDocument textDoc) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/AbstractTokenManager.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/AbstractTokenManager.java index 7d22db054c3..1d8899d7a1e 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/AbstractTokenManager.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/AbstractTokenManager.java @@ -33,7 +33,7 @@ public void setSuppressMarker(String marker) { } /** - * @deprecated since 7.14.0. Use {@link #getSuppressionComments()} instead. + * @deprecated Since 7.14.0. Use {@link #getSuppressionComments()} instead. */ @Deprecated public Map getSuppressMap() { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/package-info.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/package-info.java index 79d79b996c1..aaab7440e1b 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/package-info.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/symboltable/package-info.java @@ -3,10 +3,15 @@ */ /** - * @deprecated Since 7.19.0. All classes in this package are deprecated. The symbol table and type + * Deprecated: Since 7.19.0.
            + * + * All classes in this package are deprecated. The symbol table and type * resolution implementation for Java has been rewritten from scratch for PMD 7.0.0. This package * is the remains of the old symbol table API, that is only used by PL/SQL. For PMD 8.0.0 all these * classes will be removed from pmd-core. + * + * + * @deprecated Since 7.19.0. */ @Deprecated package net.sourceforge.pmd.lang.symboltable; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVWriter.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVWriter.java index 9048fbb079d..4eb91684b0f 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVWriter.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CSVWriter.java @@ -9,14 +9,17 @@ import java.util.Iterator; import java.util.List; +import net.sourceforge.pmd.annotation.InternalApi; + /** * A generic writer that formats input items into rows and columns per the * provided column descriptors. * * @author Brian Remedios * @param - * @deprecated This is internal API and an implementation detail for {@link CSVRenderer}. + * @apiNote This is internal API and an implementation detail for {@link CSVRenderer}. */ +@InternalApi class CSVWriter { private final String separator; // e.g., the comma diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassDeclaration.java index 429c4a5c7a9..ed0ed1fba0d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassDeclaration.java @@ -60,7 +60,7 @@ void setInterface() { /** - * @deprecated Use {@link #getPermitsClause()} or {@link JClassSymbol#getPermittedSubtypes()} + * @deprecated Since 7.8.0. Use {@link #getPermitsClause()} or {@link JClassSymbol#getPermittedSubtypes()} */ @Deprecated public List getPermittedSubclasses() { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclaration.java index f6267635cc5..4ec65b3be7a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTFieldDeclaration.java @@ -51,7 +51,7 @@ protected R acceptVisitor(JavaVisitor visitor, P * * @return a String representing the name of the variable * - * @deprecated FieldDeclaration may declare several variables, so this is not exhaustive + * @deprecated Since 6.10.0. FieldDeclaration may declare several variables, so this is not exhaustive * Iterate on the {@linkplain ASTVariableId VariableIds} instead */ @Deprecated diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLambdaExpression.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLambdaExpression.java index 7688c8bd96e..f0a5e7d3043 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLambdaExpression.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLambdaExpression.java @@ -86,7 +86,7 @@ public boolean isExpressionBody() { /** * Returns the body of this expression, if it is a block. * - * @deprecated Use {@link #getBlockBody()} + * @deprecated Since 7.1.0. Use {@link #getBlockBody()} */ @Deprecated public @Nullable ASTBlock getBlock() { @@ -96,7 +96,7 @@ public boolean isExpressionBody() { /** * Returns the body of this expression, if it is an expression. * - * @deprecated Use {@link #getExpressionBody()} + * @deprecated Since 7.1.0. Use {@link #getExpressionBody()} */ @Deprecated public @Nullable ASTExpression getExpression() { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordPattern.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordPattern.java index 874570e3835..23668935e62 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordPattern.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordPattern.java @@ -49,7 +49,7 @@ public ASTPatternList getComponentPatterns() { /** * Returns the declared variable. * - * @deprecated This method was added here by mistake. Record patterns don't declare a pattern variable + * @deprecated Since 7.3.0. This method was added here by mistake. Record patterns don't declare a pattern variable * for the whole pattern, but rather for individual record components, which can be accessed via * {@link #getComponentPatterns()}. */ diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/SyntacticJavaTokenizerFactory.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/SyntacticJavaTokenizerFactory.java index 25997a128c6..9287de7407d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/SyntacticJavaTokenizerFactory.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/SyntacticJavaTokenizerFactory.java @@ -19,7 +19,7 @@ * Creates a tokenizer, that uses the syntactic grammar to provide context * for the tokenizer when reducing the input characters to tokens. * - * @deprecated This implementation has been superseded. It is not necessary to parse Java code in order to tokenize it. + * @deprecated Since 7.2.0. This implementation has been superseded. It is not necessary to parse Java code in order to tokenize it. */ @Deprecated public final class SyntacticJavaTokenizerFactory { @@ -27,6 +27,9 @@ private SyntacticJavaTokenizerFactory() { // factory class } + /** + * @deprecated Since 7.2.0. This implementation has been superseded. It is not necessary to parse Java code in order to tokenize it. + */ @Deprecated public static TokenManager createTokenizer(CharStream cs) { final List tokenList = new ArrayList<>(); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitAssertionsShouldIncludeMessageRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitAssertionsShouldIncludeMessageRule.java index 3917356c4e0..d66f5de69d9 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitAssertionsShouldIncludeMessageRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitAssertionsShouldIncludeMessageRule.java @@ -5,7 +5,7 @@ package net.sourceforge.pmd.lang.java.rule.bestpractices; /** - * @deprecated The rule was renamed {@link UnitTestAssertionsShouldIncludeMessageRule} + * @deprecated Since 7.7.0. The rule was renamed {@link UnitTestAssertionsShouldIncludeMessageRule} */ @Deprecated public class JUnitAssertionsShouldIncludeMessageRule extends UnitTestAssertionsShouldIncludeMessageRule { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestContainsTooManyAssertsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestContainsTooManyAssertsRule.java index 164db22c17e..fa654e77116 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestContainsTooManyAssertsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestContainsTooManyAssertsRule.java @@ -5,7 +5,7 @@ package net.sourceforge.pmd.lang.java.rule.bestpractices; /** - * @deprecated The rule was renamed {@link UnitTestContainsTooManyAssertsRule} + * @deprecated Since 7.7.0. The rule was renamed {@link UnitTestContainsTooManyAssertsRule} */ @Deprecated public class JUnitTestContainsTooManyAssertsRule extends UnitTestContainsTooManyAssertsRule { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java index 6f4ff918627..38d8aa0419c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/JUnitTestsShouldIncludeAssertRule.java @@ -5,7 +5,7 @@ package net.sourceforge.pmd.lang.java.rule.bestpractices; /** - * @deprecated The rule was renamed {@link UnitTestShouldIncludeAssertRule} + * @deprecated Since 7.7.0. The rule was renamed {@link UnitTestShouldIncludeAssertRule} */ @Deprecated public class JUnitTestsShouldIncludeAssertRule extends UnitTestShouldIncludeAssertRule { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsRule.java index 7f357fd17ba..904321fac9c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveImportsRule.java @@ -29,7 +29,7 @@ protected int defaultReportLevel() { } /** - * @deprecated since 7.18.0. This method is not used anymore and shouldn't be implemented. + * @deprecated Since 7.18.0. This method is not used anymore and shouldn't be implemented. */ @Deprecated protected boolean isViolation(ASTCompilationUnit node, int reportLevel) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java index a586488334a..baa68a247f0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessiveParameterListRule.java @@ -38,7 +38,7 @@ private boolean areParametersOfPrivateConstructor(ASTFormalParameters params) { } /** - * @deprecated since 7.18.0. This method is not used anymore and shouldn't be implemented. + * @deprecated Since 7.18.0. This method is not used anymore and shouldn't be implemented. */ @Deprecated protected boolean isViolation(ASTFormalParameters node, int reportLevel) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java index bfed3d98b81..848ebb55d99 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ExcessivePublicCountRule.java @@ -40,7 +40,7 @@ protected int defaultReportLevel() { } /** - * @deprecated since 7.18.0. This method is not used anymore and shouldn't be implemented. + * @deprecated Since 7.18.0. This method is not used anymore and shouldn't be implemented. */ @Deprecated protected boolean isViolation(ASTTypeDeclaration node, int reportLevel) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SingularFieldRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SingularFieldRule.java index a9ef81f2096..8dce3a59b7e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SingularFieldRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SingularFieldRule.java @@ -98,9 +98,9 @@ public Object visitJavaNode(JavaNode node, Object data) { /** * This method is only relevant for this rule. It will be removed in the future. * - * @deprecated This method will be removed. Don't use it. + * @deprecated Since 7.1.0. This method will be removed. Don't use it. */ - @Deprecated //(since = "7.1.0", forRemoval = true) + @Deprecated public static boolean mayBeSingular(ModifierOwner varId) { return isPrivateNotFinal(varId); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java index d69d484ed3e..a286f09a2a2 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/TypeOps.java @@ -407,6 +407,9 @@ public static Convertibility isConvertible(@NonNull JTypeMirror t, @NonNull JTyp return SubtypeVisitor.INFERENCE.isConvertible(t, s, true); } + /** + * @deprecated Since 7.2.0. Use {@link #isConvertible(JTypeMirror, JTypeMirror)} or {@link #isConvertibleNoCapture(JTypeMirror, JTypeMirror)} instead. + */ @Deprecated // unused public static Convertibility isConvertible(@NonNull JTypeMirror t, @NonNull JTypeMirror s, boolean capture) { return SubtypeVisitor.PURE.isConvertible(t, s, capture); diff --git a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/test/ast/BaseParsingHelper.kt b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/test/ast/BaseParsingHelper.kt index dbff88b81f4..675a8aea7e7 100644 --- a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/test/ast/BaseParsingHelper.kt +++ b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/test/ast/BaseParsingHelper.kt @@ -47,6 +47,9 @@ abstract class BaseParsingHelper, T : RootNode val configLanguageProperties: LanguagePropertyBundle.() -> Unit = {} ) { + /** + * @deprecated Since 7.12.0. Overload added for binary compatibility. + */ @Deprecated("Overload added for binary compatibility") constructor( doProcess: Boolean, @@ -64,6 +67,9 @@ abstract class BaseParsingHelper, T : RootNode suppressMarker, configLanguageProperties = {}) + /** + * @deprecated Since 7.12.0. Overload added for binary compatibility. + */ @Deprecated("Overload added for binary compatibility") fun copy( doProcess: Boolean, diff --git a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/test/ast/IntelliMarker.kt b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/test/ast/IntelliMarker.kt index 16c713aa2b3..97841c0daf2 100644 --- a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/test/ast/IntelliMarker.kt +++ b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/test/ast/IntelliMarker.kt @@ -14,6 +14,9 @@ import org.junit.jupiter.api.Test * Kotest, but was removed in 4.2.0 without explanation. */ interface IntelliMarker { + /** + * @deprecated Since 7.16.0. This is not an API. + */ @Deprecated("This is not an API") fun primer() { } From e91caec80c59bd5c58a8b68d0cb7f955c10f901d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 Jan 2026 09:45:11 +0100 Subject: [PATCH 1959/1962] [doc] chore: add keywords for auxclasspath in Java documentation (#6429) Refs #5064 --- docs/pages/pmd/languages/java.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/pmd/languages/java.md b/docs/pages/pmd/languages/java.md index eda22f572f6..23ae38fcd82 100644 --- a/docs/pages/pmd/languages/java.md +++ b/docs/pages/pmd/languages/java.md @@ -4,6 +4,7 @@ permalink: pmd_languages_java.html author: Clรฉment Fournier last_updated: January 2026 (7.21.0) tags: [languages, PmdCapableLanguage, CpdCapableLanguage] +keywords: [auxclasspath, auxiliary, classpath, type resolution] summary: "Java-specific features and guidance" --- From 8fcf9732368c15149461b6521c313eeed658f505 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 Jan 2026 09:58:17 +0100 Subject: [PATCH 1960/1962] Prepare pmd release 7.21.0 --- .all-contributorsrc | 37 +++ docs/_config.yml | 2 +- docs/pages/pmd/projectdocs/credits.md | 314 +++++++++++++------------- docs/pages/release_notes.md | 55 ++++- 4 files changed, 251 insertions(+), 157 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 95d6a5034b8..61e7b7ad2b1 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -8427,6 +8427,43 @@ "contributions": [ "doc" ] + }, + { + "login": "kelunik", + "name": "Niklas Keller", + "avatar_url": "https://avatars.githubusercontent.com/u/2743004?v=4", + "profile": "https://blog.kelunik.com/", + "contributions": [ + "bug" + ] + }, + { + "login": "parsam97", + "name": "parsam97", + "avatar_url": "https://avatars.githubusercontent.com/u/32430185?v=4", + "profile": "https://github.com/parsam97", + "contributions": [ + "bug" + ] + }, + { + "login": "thomasleplus", + "name": "Thomas Leplus", + "avatar_url": "https://avatars.githubusercontent.com/u/1929743?v=4", + "profile": "https://www.leplus.org/", + "contributions": [ + "bug", + "code" + ] + }, + { + "login": "goto-dev-null", + "name": "Jade", + "avatar_url": "https://avatars.githubusercontent.com/u/2322497?v=4", + "profile": "https://codeberg.org/cat-dev-null", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/docs/_config.yml b/docs/_config.yml index 25c7c49d837..20df81e5541 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,7 +1,7 @@ repository: pmd/pmd pmd: - version: 7.21.0-SNAPSHOT + version: 7.21.0 previous_version: 7.20.0 date: 2026-01-30 # release types: major, minor, bugfix diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index eef0386f549..8e6f01941e5 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -369,831 +369,835 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Ivar Andreas Bonsaksen
            Ivar Andreas Bonsaksen

            ๐Ÿ› Ivo ล mรญd
            Ivo ล mรญd

            ๐Ÿ› JJengility
            JJengility

            ๐Ÿ› + Jade
            Jade

            ๐Ÿ’ป Jake Hemmerle
            Jake Hemmerle

            ๐Ÿ› Jakub Dupak
            Jakub Dupak

            ๐Ÿ’ป James Harrison
            James Harrison

            ๐Ÿ› ๐Ÿ’ป - Jamie Bisotti
            Jamie Bisotti

            ๐Ÿ› + Jamie Bisotti
            Jamie Bisotti

            ๐Ÿ› Jan
            Jan

            ๐Ÿ› Jan Aertgeerts
            Jan Aertgeerts

            ๐Ÿ’ป ๐Ÿ› Jan Brรผmmer
            Jan Brรผmmer

            ๐Ÿ› Jan Tล™รญska
            Jan Tล™รญska

            ๐Ÿ› Jan-Lukas Else
            Jan-Lukas Else

            ๐Ÿ› Jason Qiu
            Jason Qiu

            ๐Ÿ’ป ๐Ÿ“– - Jason Williams
            Jason Williams

            ๐Ÿ› + Jason Williams
            Jason Williams

            ๐Ÿ› Javier Spagnoletti
            Javier Spagnoletti

            ๐Ÿ› Jean-Paul Mayer
            Jean-Paul Mayer

            ๐Ÿ› Jean-Simon Larochelle
            Jean-Simon Larochelle

            ๐Ÿ› Jeff Bartolotta
            Jeff Bartolotta

            ๐Ÿ’ป ๐Ÿ› Jeff Hube
            Jeff Hube

            ๐Ÿ’ป ๐Ÿ› Jeff Jensen
            Jeff Jensen

            ๐Ÿ› - Jeff May
            Jeff May

            ๐Ÿ› + Jeff May
            Jeff May

            ๐Ÿ› Jens Gerdes
            Jens Gerdes

            ๐Ÿ› Jeroen Borgers
            Jeroen Borgers

            ๐Ÿ› ๐Ÿ’ป ๐Ÿ“ข Jeroen Meijer
            Jeroen Meijer

            ๐Ÿ› Jeroen van Wilgenburg
            Jeroen van Wilgenburg

            ๐Ÿ“– Jerome Russ
            Jerome Russ

            ๐Ÿ› JerritEic
            JerritEic

            ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› - Jiri Pejchal
            Jiri Pejchal

            ๐Ÿ› + Jiri Pejchal
            Jiri Pejchal

            ๐Ÿ› Jithin Sunny
            Jithin Sunny

            ๐Ÿ› Jiล™รญ ล korpil
            Jiล™รญ ล korpil

            ๐Ÿ› Joao Machado
            Joao Machado

            ๐Ÿ› Jochen Krauss
            Jochen Krauss

            ๐Ÿ› Johan Hammar
            Johan Hammar

            ๐Ÿ› John Jetmore
            John Jetmore

            ๐Ÿ“– - John Karp
            John Karp

            ๐Ÿ› + John Karp
            John Karp

            ๐Ÿ› John Zhang
            John Zhang

            ๐Ÿ› John-Teng
            John-Teng

            ๐Ÿ’ป ๐Ÿ› Jon Moroney
            Jon Moroney

            ๐Ÿ’ป ๐Ÿ› Jonas Geiregat
            Jonas Geiregat

            ๐Ÿ› Jonas KeรŸler
            Jonas KeรŸler

            ๐Ÿ› Jonathan Gillespie
            Jonathan Gillespie

            ๐Ÿ’ต - Jonathan Wiesel
            Jonathan Wiesel

            ๐Ÿ’ป ๐Ÿ› + Jonathan Wiesel
            Jonathan Wiesel

            ๐Ÿ’ป ๐Ÿ› Jordan
            Jordan

            ๐Ÿ› Jordan Alligood
            Jordan Alligood

            ๐Ÿ› Jordi Llach
            Jordi Llach

            ๐Ÿ› Jorge Solรณrzano
            Jorge Solรณrzano

            ๐Ÿ› JorneVL
            JorneVL

            ๐Ÿ› Jose Palafox
            Jose Palafox

            ๐Ÿ› - Jose Stovall
            Jose Stovall

            ๐Ÿ› + Jose Stovall
            Jose Stovall

            ๐Ÿ› Joseph
            Joseph

            ๐Ÿ’ป Joseph Heenan
            Joseph Heenan

            ๐Ÿ› Josh Feingold
            Josh Feingold

            ๐Ÿ’ป ๐Ÿ› Josh Holthaus
            Josh Holthaus

            ๐Ÿ› Joshua S Arquilevich
            Joshua S Arquilevich

            ๐Ÿ› Joรฃo Dinis Ferreira
            Joรฃo Dinis Ferreira

            ๐Ÿ“– - Joรฃo Ferreira
            Joรฃo Ferreira

            ๐Ÿ’ป ๐Ÿ› + Joรฃo Ferreira
            Joรฃo Ferreira

            ๐Ÿ’ป ๐Ÿ› Joรฃo Pedro Schmitt
            Joรฃo Pedro Schmitt

            ๐Ÿ› Juan Martรญn Sotuyo Dodero
            Juan Martรญn Sotuyo Dodero

            ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› ๐Ÿšง Juan Pablo Civile
            Juan Pablo Civile

            ๐Ÿ› Jude Pereira
            Jude Pereira

            ๐Ÿ’ป Julian Voronetsky
            Julian Voronetsky

            ๐Ÿ› Julien
            Julien

            ๐Ÿ› - Julius
            Julius

            ๐Ÿ› + Julius
            Julius

            ๐Ÿ› JustPRV
            JustPRV

            ๐Ÿ› Justin Stroud
            Justin Stroud

            ๐Ÿ’ป Jรถrn Huxhorn
            Jรถrn Huxhorn

            ๐Ÿ› KThompso
            KThompso

            ๐Ÿ› Kai Amundsen
            Kai Amundsen

            ๐Ÿ› Karel Vervaeke
            Karel Vervaeke

            ๐Ÿ› - Karl-Andero Mere
            Karl-Andero Mere

            ๐Ÿ› + Karl-Andero Mere
            Karl-Andero Mere

            ๐Ÿ› Karl-Philipp Richter
            Karl-Philipp Richter

            ๐Ÿ› Karsten Silz
            Karsten Silz

            ๐Ÿ› Kazuma Watanabe
            Kazuma Watanabe

            ๐Ÿ› Kernevez
            Kernevez

            ๐Ÿ› Kev
            Kev

            ๐Ÿ› Keve Mรผller
            Keve Mรผller

            ๐Ÿ› - Kevin Guerra
            Kevin Guerra

            ๐Ÿ’ป + Kevin Guerra
            Kevin Guerra

            ๐Ÿ’ป Kevin Jones
            Kevin Jones

            ๐Ÿ› ๐Ÿ’ป Kevin Poorman
            Kevin Poorman

            ๐Ÿ› Kevin Wayne
            Kevin Wayne

            ๐Ÿ› Kieran Black
            Kieran Black

            ๐Ÿ› Kirill Zubov
            Kirill Zubov

            ๐Ÿ› Kirk Clemens
            Kirk Clemens

            ๐Ÿ’ป ๐Ÿ› - Klaus Hartl
            Klaus Hartl

            ๐Ÿ› + Klaus Hartl
            Klaus Hartl

            ๐Ÿ› Koen Van Looveren
            Koen Van Looveren

            ๐Ÿ› Kris Scheibe
            Kris Scheibe

            ๐Ÿ’ป ๐Ÿ› Krystian Dabrowski
            Krystian Dabrowski

            ๐Ÿ› ๐Ÿ’ป Krzysztof Dymek
            Krzysztof Dymek

            ๐Ÿ› Kunal Thanki
            Kunal Thanki

            ๐Ÿ› Kursat Aktas
            Kursat Aktas

            ๐Ÿ“– - LaLucid
            LaLucid

            ๐Ÿ’ป + LaLucid
            LaLucid

            ๐Ÿ’ป Larry Diamond
            Larry Diamond

            ๐Ÿ’ป ๐Ÿ› Lars Knickrehm
            Lars Knickrehm

            ๐Ÿ› Laurent Bovet
            Laurent Bovet

            ๐Ÿ› ๐Ÿ’ป Leo Gutierrez
            Leo Gutierrez

            ๐Ÿ› LiGaOg
            LiGaOg

            ๐Ÿ’ป Liam Sharp
            Liam Sharp

            ๐Ÿ› - Lintsi
            Lintsi

            ๐Ÿ› + Lintsi
            Lintsi

            ๐Ÿ› Linus Fernandes
            Linus Fernandes

            ๐Ÿ› Lixon Lookose
            Lixon Lookose

            ๐Ÿ› Logesh
            Logesh

            ๐Ÿ› Lorenzo Gabriele
            Lorenzo Gabriele

            ๐Ÿ› Loรฏc Ledoyen
            Loรฏc Ledoyen

            ๐Ÿ› Lucas
            Lucas

            ๐Ÿ› - Lucas Silva
            Lucas Silva

            ๐Ÿ› + Lucas Silva
            Lucas Silva

            ๐Ÿ› Lucas Soncini
            Lucas Soncini

            ๐Ÿ’ป ๐Ÿ› Luis Alcantar
            Luis Alcantar

            ๐Ÿ’ป Lukas Grรคf
            Lukas Grรคf

            ๐Ÿ’ป ๐Ÿ› Lukasz Slonina
            Lukasz Slonina

            ๐Ÿ› Lukebray
            Lukebray

            ๐Ÿ› Lynn
            Lynn

            ๐Ÿ’ป ๐Ÿ› - Lyor Goldstein
            Lyor Goldstein

            ๐Ÿ› + Lyor Goldstein
            Lyor Goldstein

            ๐Ÿ› MCMicS
            MCMicS

            ๐Ÿ› Macarse
            Macarse

            ๐Ÿ› Machine account for PMD
            Machine account for PMD

            ๐Ÿ’ป Maciek Siemczyk
            Maciek Siemczyk

            ๐Ÿ› Maikel Steneker
            Maikel Steneker

            ๐Ÿ’ป ๐Ÿ› Maksim Moiseikin
            Maksim Moiseikin

            ๐Ÿ› - Malik
            Malik

            ๐Ÿ› + Malik
            Malik

            ๐Ÿ› Manfred Koch
            Manfred Koch

            ๐Ÿ› Manuel Moya Ferrer
            Manuel Moya Ferrer

            ๐Ÿ’ป ๐Ÿ› Manuel Romeiro
            Manuel Romeiro

            ๐Ÿ› Manuel Ryan
            Manuel Ryan

            ๐Ÿ› Marat Vyshegorodtsev
            Marat Vyshegorodtsev

            ๐Ÿ› Marcel Hรคrle
            Marcel Hรคrle

            ๐Ÿ› - Marcello Fialho
            Marcello Fialho

            ๐Ÿ› + Marcello Fialho
            Marcello Fialho

            ๐Ÿ› Marcin Dฤ…browski
            Marcin Dฤ…browski

            ๐Ÿ’ป ๐Ÿ› Marcin Rataj
            Marcin Rataj

            ๐Ÿ› Marcono1234
            Marcono1234

            ๐Ÿ› Mark Adamcin
            Mark Adamcin

            ๐Ÿ› Mark Hall
            Mark Hall

            ๐Ÿ’ป ๐Ÿ› Mark Kolich
            Mark Kolich

            ๐Ÿ› - Mark Pritchard
            Mark Pritchard

            ๐Ÿ› + Mark Pritchard
            Mark Pritchard

            ๐Ÿ› Markus Rathgeb
            Markus Rathgeb

            ๐Ÿ› Marquis Wang
            Marquis Wang

            ๐Ÿ› MartGit
            MartGit

            ๐Ÿ› Martin Feldsztejn
            Martin Feldsztejn

            ๐Ÿ› Martin Lehmann
            Martin Lehmann

            ๐Ÿ› Martin Spamer
            Martin Spamer

            ๐Ÿ› - Martin Tarjรกnyi
            Martin Tarjรกnyi

            ๐Ÿ› + Martin Tarjรกnyi
            Martin Tarjรกnyi

            ๐Ÿ› MatFl
            MatFl

            ๐Ÿ› Mateusz Stefanski
            Mateusz Stefanski

            ๐Ÿ› Mathias Lagerwall
            Mathias Lagerwall

            ๐Ÿ› Mathieu Gouin
            Mathieu Gouin

            ๐Ÿ› MatiasComercio
            MatiasComercio

            ๐Ÿ’ป ๐Ÿ› Matt Benson
            Matt Benson

            ๐Ÿ› - Matt De Poorter
            Matt De Poorter

            ๐Ÿ› + Matt De Poorter
            Matt De Poorter

            ๐Ÿ› Matt Hargett
            Matt Hargett

            ๐Ÿ’ป ๐Ÿ’ต Matt Harrah
            Matt Harrah

            ๐Ÿ› Matt Nelson
            Matt Nelson

            ๐Ÿ› Matthew Amos
            Matthew Amos

            ๐Ÿ› Matthew Duggan
            Matthew Duggan

            ๐Ÿ› Matthew Hall
            Matthew Hall

            ๐Ÿ› - Matthew Rossner
            Matthew Rossner

            ๐Ÿ› + Matthew Rossner
            Matthew Rossner

            ๐Ÿ› Matรญas Fraga
            Matรญas Fraga

            ๐Ÿ’ป ๐Ÿ› Maxime Robert
            Maxime Robert

            ๐Ÿ’ป ๐Ÿ› MetaBF
            MetaBF

            ๐Ÿ› Metin Dagcilar
            Metin Dagcilar

            ๐Ÿ› Michael
            Michael

            ๐Ÿ› Michael Bell
            Michael Bell

            ๐Ÿ› - Michael Bernstein
            Michael Bernstein

            ๐Ÿ› + Michael Bernstein
            Michael Bernstein

            ๐Ÿ› Michael Clay
            Michael Clay

            ๐Ÿ› Michael Dombrowski
            Michael Dombrowski

            ๐Ÿ› Michael Hausegger
            Michael Hausegger

            ๐Ÿ› Michael Hoefer
            Michael Hoefer

            ๐Ÿ› Michael Kolesnikov
            Michael Kolesnikov

            ๐Ÿ› Michael Mรถbius
            Michael Mรถbius

            ๐Ÿ› - Michael N. Lipp
            Michael N. Lipp

            ๐Ÿ› + Michael N. Lipp
            Michael N. Lipp

            ๐Ÿ› Michael Pellegrini
            Michael Pellegrini

            ๐Ÿ› Michal Kordas
            Michal Kordas

            ๐Ÿ› Michaล‚ Borek
            Michaล‚ Borek

            ๐Ÿ› Michaล‚ Kuliล„ski
            Michaล‚ Kuliล„ski

            ๐Ÿ› Miguel Nรบรฑez Dรญaz-Montes
            Miguel Nรบรฑez Dรญaz-Montes

            ๐Ÿ› Mihai Ionut
            Mihai Ionut

            ๐Ÿ› - Mikhail Kuchma
            Mikhail Kuchma

            ๐Ÿ› + Mikhail Kuchma
            Mikhail Kuchma

            ๐Ÿ› MiladSadinam
            MiladSadinam

            ๐Ÿ› Mirek Hankus
            Mirek Hankus

            ๐Ÿ› Mitch Spano
            Mitch Spano

            ๐Ÿ’ป ๐Ÿ› Mladjan Gadzic
            Mladjan Gadzic

            ๐Ÿ› Mladjan Gadzic
            Mladjan Gadzic

            ๐Ÿ› Mohamed Hamed
            Mohamed Hamed

            ๐Ÿ’ป - MrAngry52
            MrAngry52

            ๐Ÿ› + MrAngry52
            MrAngry52

            ๐Ÿ› Muminur Choudhury
            Muminur Choudhury

            ๐Ÿ› Mykhailo Palahuta
            Mykhailo Palahuta

            ๐Ÿ’ป ๐Ÿ› Nagendra Kumar Singh
            Nagendra Kumar Singh

            ๐Ÿ› Nahuel Barrios
            Nahuel Barrios

            ๐Ÿ› Nakul Sharma
            Nakul Sharma

            ๐Ÿ› Nathan Braun
            Nathan Braun

            ๐Ÿ› - Nathan Reynolds
            Nathan Reynolds

            ๐Ÿ› + Nathan Reynolds
            Nathan Reynolds

            ๐Ÿ› Nathan Reynolds
            Nathan Reynolds

            ๐Ÿ› Nathanaรซl
            Nathanaรซl

            ๐Ÿ› Naveen
            Naveen

            ๐Ÿ’ป Nazdravi
            Nazdravi

            ๐Ÿ› Neha-Dhonde
            Neha-Dhonde

            ๐Ÿ› Nicholas Doyle
            Nicholas Doyle

            ๐Ÿ› - Nick Butcher
            Nick Butcher

            ๐Ÿ› + Nick Butcher
            Nick Butcher

            ๐Ÿ› Nico Gallinal
            Nico Gallinal

            ๐Ÿ› Nicola Dal Maso
            Nicola Dal Maso

            ๐Ÿ› Nicolas Filotto
            Nicolas Filotto

            ๐Ÿ’ป Nicolas Vervelle
            Nicolas Vervelle

            ๐Ÿ› Nicolas Vuillamy
            Nicolas Vuillamy

            ๐Ÿ“– Nikita Chursin
            Nikita Chursin

            ๐Ÿ› - Niklas Baudy
            Niklas Baudy

            ๐Ÿ› + Niklas Baudy
            Niklas Baudy

            ๐Ÿ› + Niklas Keller
            Niklas Keller

            ๐Ÿ› Nikolas Havrikov
            Nikolas Havrikov

            ๐Ÿ› Nilesh Virkar
            Nilesh Virkar

            ๐Ÿ› Nimit Patel
            Nimit Patel

            ๐Ÿ› Niranjan Harpale
            Niranjan Harpale

            ๐Ÿ› Nirvik Patel
            Nirvik Patel

            ๐Ÿ’ป - Noah Sussman
            Noah Sussman

            ๐Ÿ› - Noah0120
            Noah0120

            ๐Ÿ› + Noah Sussman
            Noah Sussman

            ๐Ÿ› + Noah0120
            Noah0120

            ๐Ÿ› Noam Tamim
            Noam Tamim

            ๐Ÿ› Noel Grandin
            Noel Grandin

            ๐Ÿ› Olaf Haalstra
            Olaf Haalstra

            ๐Ÿ› Oleg Andreych
            Oleg Andreych

            ๐Ÿ’ป ๐Ÿ› Oleg Estekhin
            Oleg Estekhin

            ๐Ÿ› - Oleg Pavlenko
            Oleg Pavlenko

            ๐Ÿ› - Oleksii Dykov
            Oleksii Dykov

            ๐Ÿ’ป ๐Ÿ› + Oleg Pavlenko
            Oleg Pavlenko

            ๐Ÿ› + Oleksii Dykov
            Oleksii Dykov

            ๐Ÿ’ป ๐Ÿ› Oliver Eikemeier
            Oliver Eikemeier

            ๐Ÿ› Oliver Siegmar
            Oliver Siegmar

            ๐Ÿ’ต Olivier Parent
            Olivier Parent

            ๐Ÿ’ป ๐Ÿ› Ollie Abbey
            Ollie Abbey

            ๐Ÿ’ป ๐Ÿ› Olof-Joachim Frahm (ๆฌง้›…็ฆ)
            Olof-Joachim Frahm (ๆฌง้›…็ฆ)

            ๐Ÿ› - Ondrej Kratochvil
            Ondrej Kratochvil

            ๐Ÿ› - OverDrone
            OverDrone

            ๐Ÿ› + Ondrej Kratochvil
            Ondrej Kratochvil

            ๐Ÿ› + OverDrone
            OverDrone

            ๐Ÿ› Ozan Gulle
            Ozan Gulle

            ๐Ÿ’ป ๐Ÿ› PUNEET JAIN
            PUNEET JAIN

            ๐Ÿ› Pankraz76
            Pankraz76

            ๐Ÿ’ป ๐Ÿ› Parbati Bose
            Parbati Bose

            ๐Ÿ› Patrick Schmidt
            Patrick Schmidt

            ๐Ÿ› - Paul Berg
            Paul Berg

            ๐Ÿ› - Paul Guyot
            Paul Guyot

            ๐Ÿ’ป + Paul Berg
            Paul Berg

            ๐Ÿ› + Paul Guyot
            Paul Guyot

            ๐Ÿ’ป Pavel Bludov
            Pavel Bludov

            ๐Ÿ› Pavel Miฤka
            Pavel Miฤka

            ๐Ÿ› Pedro Nuno Santos
            Pedro Nuno Santos

            ๐Ÿ› Pedro Rijo
            Pedro Rijo

            ๐Ÿ› Pelisse Romain
            Pelisse Romain

            ๐Ÿ’ป ๐Ÿ“– ๐Ÿ› - Per Abich
            Per Abich

            ๐Ÿ’ป - Pete Davids
            Pete Davids

            ๐Ÿ› + Per Abich
            Per Abich

            ๐Ÿ’ป + Pete Davids
            Pete Davids

            ๐Ÿ› Peter Bruin
            Peter Bruin

            ๐Ÿ› Peter Chittum
            Peter Chittum

            ๐Ÿ’ป ๐Ÿ› Peter Cudmore
            Peter Cudmore

            ๐Ÿ› Peter Kasson
            Peter Kasson

            ๐Ÿ› Peter Kofler
            Peter Kofler

            ๐Ÿ› - Peter Paul Bakker
            Peter Paul Bakker

            ๐Ÿ’ป ๐Ÿ› - Peter Rader
            Peter Rader

            ๐Ÿ› + Peter Paul Bakker
            Peter Paul Bakker

            ๐Ÿ’ป ๐Ÿ› + Peter Rader
            Peter Rader

            ๐Ÿ› Pham Hai Trung
            Pham Hai Trung

            ๐Ÿ› Philip Graf
            Philip Graf

            ๐Ÿ’ป ๐Ÿ› Philip Hachey
            Philip Hachey

            ๐Ÿ› Philippe Ozil
            Philippe Ozil

            ๐Ÿ› Phinehas Artemix
            Phinehas Artemix

            ๐Ÿ› - Phokham Nonava
            Phokham Nonava

            ๐Ÿ› - Pim van der Loos
            Pim van der Loos

            ๐Ÿ’ป โš ๏ธ + Phokham Nonava
            Phokham Nonava

            ๐Ÿ› + Pim van der Loos
            Pim van der Loos

            ๐Ÿ’ป โš ๏ธ Piotr Koลผuchowski
            Piotr Koลผuchowski

            ๐Ÿ› Piotr Szymaล„ski
            Piotr Szymaล„ski

            ๐Ÿ› Piotrek ลปygieล‚o
            Piotrek ลปygieล‚o

            ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– Pranay Jaiswal
            Pranay Jaiswal

            ๐Ÿ› Prasad Kamath
            Prasad Kamath

            ๐Ÿ› - Prasanna
            Prasanna

            ๐Ÿ› - Presh-AR
            Presh-AR

            ๐Ÿ› + Prasanna
            Prasanna

            ๐Ÿ› + Presh-AR
            Presh-AR

            ๐Ÿ› Puneet1726
            Puneet1726

            ๐Ÿ› RBRi
            RBRi

            ๐Ÿ› Rafael Cortรชs
            Rafael Cortรชs

            ๐Ÿ› RaheemShaik999
            RaheemShaik999

            ๐Ÿ› RajeshR
            RajeshR

            ๐Ÿ’ป ๐Ÿ› - Ramachandra Mohan
            Ramachandra Mohan

            ๐Ÿ› - Ramel0921
            Ramel0921

            ๐Ÿ› + Ramachandra Mohan
            Ramachandra Mohan

            ๐Ÿ› + Ramel0921
            Ramel0921

            ๐Ÿ› Raquel Pau
            Raquel Pau

            ๐Ÿ› Ravikiran Janardhana
            Ravikiran Janardhana

            ๐Ÿ› Reda Benhemmouche
            Reda Benhemmouche

            ๐Ÿ› Reinhard Schiedermeier
            Reinhard Schiedermeier

            ๐Ÿ› Renato Oliveira
            Renato Oliveira

            ๐Ÿ’ป ๐Ÿ› - Rich DiCroce
            Rich DiCroce

            ๐Ÿ› - Richard Corfield
            Richard Corfield

            ๐Ÿ’ป + Rich DiCroce
            Rich DiCroce

            ๐Ÿ› + Richard Corfield
            Richard Corfield

            ๐Ÿ’ป Richard Corfield
            Richard Corfield

            ๐Ÿ› ๐Ÿ’ป Riot R1cket
            Riot R1cket

            ๐Ÿ› Rishabh Jain
            Rishabh Jain

            ๐Ÿ› RishabhDeep Singh
            RishabhDeep Singh

            ๐Ÿ› Rob Baillie
            Rob Baillie

            ๐Ÿ› - Robbie Martinus
            Robbie Martinus

            ๐Ÿ’ป ๐Ÿ› - Robert Henry
            Robert Henry

            ๐Ÿ› + Robbie Martinus
            Robbie Martinus

            ๐Ÿ’ป ๐Ÿ› + Robert Henry
            Robert Henry

            ๐Ÿ› Robert Mihaly
            Robert Mihaly

            ๐Ÿ› Robert Painsi
            Robert Painsi

            ๐Ÿ› Robert Russell
            Robert Russell

            ๐Ÿ› Robert Sรถsemann
            Robert Sรถsemann

            ๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ข ๐Ÿ› Robert Whitebit
            Robert Whitebit

            ๐Ÿ› - Robin Richtsfeld
            Robin Richtsfeld

            ๐Ÿ› - Robin Stocker
            Robin Stocker

            ๐Ÿ’ป ๐Ÿ› + Robin Richtsfeld
            Robin Richtsfeld

            ๐Ÿ› + Robin Stocker
            Robin Stocker

            ๐Ÿ’ป ๐Ÿ› Robin Wils
            Robin Wils

            ๐Ÿ› RochusOest
            RochusOest

            ๐Ÿ› Rodolfo Noviski
            Rodolfo Noviski

            ๐Ÿ› Rodrigo Casara
            Rodrigo Casara

            ๐Ÿ› Rodrigo Fernandes
            Rodrigo Fernandes

            ๐Ÿ› - Roman Salvador
            Roman Salvador

            ๐Ÿ’ป ๐Ÿ› - Ronald Blaschke
            Ronald Blaschke

            ๐Ÿ› + Roman Salvador
            Roman Salvador

            ๐Ÿ’ป ๐Ÿ› + Ronald Blaschke
            Ronald Blaschke

            ๐Ÿ› Rรณbert Papp
            Rรณbert Papp

            ๐Ÿ› Saikat Sengupta
            Saikat Sengupta

            ๐Ÿ› Saksham Handu
            Saksham Handu

            ๐Ÿ› Saladoc
            Saladoc

            ๐Ÿ› Salesforce Bob Lightning
            Salesforce Bob Lightning

            ๐Ÿ› - Sam Carlberg
            Sam Carlberg

            ๐Ÿ› - Sascha Riemer
            Sascha Riemer

            ๐Ÿ› + Sam Carlberg
            Sam Carlberg

            ๐Ÿ› + Sascha Riemer
            Sascha Riemer

            ๐Ÿ› Sashko
            Sashko

            ๐Ÿ’ป Satoshi Kubo
            Satoshi Kubo

            ๐Ÿ› Scott Kennedy
            Scott Kennedy

            ๐Ÿ› Scott Wells
            Scott Wells

            ๐Ÿ› ๐Ÿ’ป Scrates1
            Scrates1

            ๐Ÿ› ๐Ÿ’ป - Scrsloota
            Scrsloota

            ๐Ÿ’ป - Sebastian Bรถgl
            Sebastian Bรถgl

            ๐Ÿ› + Scrsloota
            Scrsloota

            ๐Ÿ’ป + Sebastian Bรถgl
            Sebastian Bรถgl

            ๐Ÿ› Sebastian Davids
            Sebastian Davids

            ๐Ÿ› Sebastian Lรถvdahl
            Sebastian Lรถvdahl

            ๐Ÿ› Sebastian Schuberth
            Sebastian Schuberth

            ๐Ÿ› Sebastian Schwarz
            Sebastian Schwarz

            ๐Ÿ› Seren
            Seren

            ๐Ÿ› ๐Ÿ’ป - Sergey Gorbaty
            Sergey Gorbaty

            ๐Ÿ› - Sergey Kozlov
            Sergey Kozlov

            ๐Ÿ› + Sergey Gorbaty
            Sergey Gorbaty

            ๐Ÿ› + Sergey Kozlov
            Sergey Kozlov

            ๐Ÿ› Sergey Tyurin
            Sergey Tyurin

            ๐Ÿ› Sergey Yanzin
            Sergey Yanzin

            ๐Ÿ’ป ๐Ÿ› Seth Wilcox
            Seth Wilcox

            ๐Ÿ’ป Shai Bennathan
            Shai Bennathan

            ๐Ÿ› ๐Ÿ’ป Shubham
            Shubham

            ๐Ÿ’ป ๐Ÿ› - Simon Abykov
            Simon Abykov

            ๐Ÿ’ป ๐Ÿ› - Simon Xiao
            Simon Xiao

            ๐Ÿ› + Simon Abykov
            Simon Abykov

            ๐Ÿ’ป ๐Ÿ› + Simon Xiao
            Simon Xiao

            ๐Ÿ› Srinivasan Venkatachalam
            Srinivasan Venkatachalam

            ๐Ÿ› Stanislav Gromov
            Stanislav Gromov

            ๐Ÿ› Stanislav Myachenkov
            Stanislav Myachenkov

            ๐Ÿ’ป Stefan Birkner
            Stefan Birkner

            ๐Ÿ› Stefan Bohn
            Stefan Bohn

            ๐Ÿ› - Stefan Endrullis
            Stefan Endrullis

            ๐Ÿ› - Stefan Klรถss-Schuster
            Stefan Klรถss-Schuster

            ๐Ÿ› + Stefan Endrullis
            Stefan Endrullis

            ๐Ÿ› + Stefan Klรถss-Schuster
            Stefan Klรถss-Schuster

            ๐Ÿ› Stefan Wolf
            Stefan Wolf

            ๐Ÿ› Stephan H. Wissel
            Stephan H. Wissel

            ๐Ÿ› Stephen
            Stephen

            ๐Ÿ› Stephen Carter
            Stephen Carter

            ๐Ÿ› Stephen Friedrich
            Stephen Friedrich

            ๐Ÿ› - Steve Babula
            Steve Babula

            ๐Ÿ’ป - Steve White
            Steve White

            ๐Ÿ› + Steve Babula
            Steve Babula

            ๐Ÿ’ป + Steve White
            Steve White

            ๐Ÿ› Steven Schlansker
            Steven Schlansker

            ๐Ÿ› Steven Stearns
            Steven Stearns

            ๐Ÿ› ๐Ÿ’ป Stexxe
            Stexxe

            ๐Ÿ› Stian Lรฅgstad
            Stian Lรฅgstad

            ๐Ÿ› StuartClayton5
            StuartClayton5

            ๐Ÿ› - Supun Arunoda
            Supun Arunoda

            ๐Ÿ› - Suren Abrahamyan
            Suren Abrahamyan

            ๐Ÿ› + Supun Arunoda
            Supun Arunoda

            ๐Ÿ› + Suren Abrahamyan
            Suren Abrahamyan

            ๐Ÿ› Suvashri
            Suvashri

            ๐Ÿ“– Sven Barden
            Sven Barden

            ๐Ÿ› SwatiBGupta1110
            SwatiBGupta1110

            ๐Ÿ› SyedThoufich
            SyedThoufich

            ๐Ÿ› Szymon Sasin
            Szymon Sasin

            ๐Ÿ› - T-chuangxin
            T-chuangxin

            ๐Ÿ› - TERAI Atsuhiro
            TERAI Atsuhiro

            ๐Ÿ› + T-chuangxin
            T-chuangxin

            ๐Ÿ› + TERAI Atsuhiro
            TERAI Atsuhiro

            ๐Ÿ› TIOBE Software
            TIOBE Software

            ๐Ÿ’ป ๐Ÿ› Tarush Singh
            Tarush Singh

            ๐Ÿ’ป Taylor Smock
            Taylor Smock

            ๐Ÿ› Techeira Damiรกn
            Techeira Damiรกn

            ๐Ÿ’ป ๐Ÿ› Ted Husted
            Ted Husted

            ๐Ÿ› - TehBakker
            TehBakker

            ๐Ÿ› - The Gitter Badger
            The Gitter Badger

            ๐Ÿ› + TehBakker
            TehBakker

            ๐Ÿ› + The Gitter Badger
            The Gitter Badger

            ๐Ÿ› Theodoor
            Theodoor

            ๐Ÿ› Thiago Henrique Hรผpner
            Thiago Henrique Hรผpner

            ๐Ÿ› Thibault Meyer
            Thibault Meyer

            ๐Ÿ› Thomas Gรผttler
            Thomas Gรผttler

            ๐Ÿ› Thomas Jones-Low
            Thomas Jones-Low

            ๐Ÿ› - Thomas Smith
            Thomas Smith

            ๐Ÿ’ป ๐Ÿ› - ThrawnCA
            ThrawnCA

            ๐Ÿ› + Thomas Leplus
            Thomas Leplus

            ๐Ÿ› ๐Ÿ’ป + Thomas Smith
            Thomas Smith

            ๐Ÿ’ป ๐Ÿ› + ThrawnCA
            ThrawnCA

            ๐Ÿ› Thu Vo
            Thu Vo

            ๐Ÿ› Thunderforge
            Thunderforge

            ๐Ÿ’ป ๐Ÿ› Tim van der Lippe
            Tim van der Lippe

            ๐Ÿ› Tobias Weimer
            Tobias Weimer

            ๐Ÿ’ป ๐Ÿ› + + Tom Copeland
            Tom Copeland

            ๐Ÿ› ๐Ÿ’ป ๐Ÿ“– Tom Daly
            Tom Daly

            ๐Ÿ› Tomas
            Tomas

            ๐Ÿ› - - Tomer Figenblat
            Tomer Figenblat

            ๐Ÿ› Tomi De Lucca
            Tomi De Lucca

            ๐Ÿ’ป ๐Ÿ› Tony
            Tony

            ๐Ÿ“– Torsten Kleiber
            Torsten Kleiber

            ๐Ÿ› + + Torsten Krause
            Torsten Krause

            ๐Ÿ› TrackerSB
            TrackerSB

            ๐Ÿ› Tyson Stewart
            Tyson Stewart

            ๐Ÿ› - - Ullrich Hafner
            Ullrich Hafner

            ๐Ÿ› UncleOwen
            UncleOwen

            ๐Ÿ’ป ๐Ÿ› ๐Ÿ“– Utku Cuhadaroglu
            Utku Cuhadaroglu

            ๐Ÿ’ป ๐Ÿ› Valentin Brandl
            Valentin Brandl

            ๐Ÿ› + + Valeria
            Valeria

            ๐Ÿ› Valery Yatsynovich
            Valery Yatsynovich

            ๐Ÿ“– Vasily Anisimov
            Vasily Anisimov

            ๐Ÿ› - - Vedant Chokshi
            Vedant Chokshi

            ๐Ÿ› Vibhor Goyal
            Vibhor Goyal

            ๐Ÿ› Vickenty Fesunov
            Vickenty Fesunov

            ๐Ÿ› Victor Noรซl
            Victor Noรซl

            ๐Ÿ› + + Vincent Galloy
            Vincent Galloy

            ๐Ÿ’ป Vincent HUYNH
            Vincent HUYNH

            ๐Ÿ› Vincent Maurin
            Vincent Maurin

            ๐Ÿ› - - Vincent Potucek
            Vincent Potucek

            ๐Ÿ’ป Vincent Privat
            Vincent Privat

            ๐Ÿ› Vincent Zorge
            Vincent Zorge

            ๐Ÿ› Vishhwas
            Vishhwas

            ๐Ÿ› + + Vishv_Android
            Vishv_Android

            ๐Ÿ› Vitalii Yevtushenko
            Vitalii Yevtushenko

            ๐Ÿ› Vitaly
            Vitaly

            ๐Ÿ› - - Vitaly Polonetsky
            Vitaly Polonetsky

            ๐Ÿ› Vojtech Polivka
            Vojtech Polivka

            ๐Ÿ› Vsevolod Zholobov
            Vsevolod Zholobov

            ๐Ÿ› Vyom Yadav
            Vyom Yadav

            ๐Ÿ’ป + + Wang Shidong
            Wang Shidong

            ๐Ÿ› Waqas Ahmed
            Waqas Ahmed

            ๐Ÿ› Wayne J. Earl
            Wayne J. Earl

            ๐Ÿ› - - Wchenghui
            Wchenghui

            ๐Ÿ› Wener
            Wener

            ๐Ÿ’ป Will Winder
            Will Winder

            ๐Ÿ› Willem A. Hajenius
            Willem A. Hajenius

            ๐Ÿ’ป + + William Brockhus
            William Brockhus

            ๐Ÿ’ป ๐Ÿ› Wilson Kurniawan
            Wilson Kurniawan

            ๐Ÿ› Wim Deblauwe
            Wim Deblauwe

            ๐Ÿ› - - Wolf2323
            Wolf2323

            ๐Ÿ› Woongsik Choi
            Woongsik Choi

            ๐Ÿ› XenoAmess
            XenoAmess

            ๐Ÿ’ป ๐Ÿ› Yang
            Yang

            ๐Ÿ’ป + + YaroslavTER
            YaroslavTER

            ๐Ÿ› Yasar Shaikh
            Yasar Shaikh

            ๐Ÿ’ป Young Chan
            Young Chan

            ๐Ÿ’ป ๐Ÿ› - - YuJin Kim
            YuJin Kim

            ๐Ÿ› Yuri Dolzhenko
            Yuri Dolzhenko

            ๐Ÿ› Yurii Dubinka
            Yurii Dubinka

            ๐Ÿ› Zbynek Konecny
            Zbynek Konecny

            ๐Ÿ› ๐Ÿ’ป + + Zoltan Farkas
            Zoltan Farkas

            ๐Ÿ› Zustin
            Zustin

            ๐Ÿ› aaronhurst-google
            aaronhurst-google

            ๐Ÿ› ๐Ÿ’ป - - alexmodis
            alexmodis

            ๐Ÿ› andreoss
            andreoss

            ๐Ÿ› andrey81inmd
            andrey81inmd

            ๐Ÿ’ป ๐Ÿ› anicoara
            anicoara

            ๐Ÿ› + + arunprasathav
            arunprasathav

            ๐Ÿ› asiercamara
            asiercamara

            ๐Ÿ› astillich-igniti
            astillich-igniti

            ๐Ÿ’ป - - avesolovksyy
            avesolovksyy

            ๐Ÿ› avishvat
            avishvat

            ๐Ÿ› avivmu
            avivmu

            ๐Ÿ› axelbarfod1
            axelbarfod1

            ๐Ÿ› + + b-3-n
            b-3-n

            ๐Ÿ› balbhadra9
            balbhadra9

            ๐Ÿ› base23de
            base23de

            ๐Ÿ› - - bergander
            bergander

            ๐Ÿ› ๐Ÿ’ป berkam
            berkam

            ๐Ÿ’ป ๐Ÿ› bmeier-pros
            bmeier-pros

            ๐Ÿ› breizh31
            breizh31

            ๐Ÿ› + + caesarkim
            caesarkim

            ๐Ÿ› caiocarvalhotero
            caiocarvalhotero

            ๐Ÿ› carolyujing
            carolyujing

            ๐Ÿ› - - cbfiddle
            cbfiddle

            ๐Ÿ› cesares-basilico
            cesares-basilico

            ๐Ÿ› chrite
            chrite

            ๐Ÿ› ciufudean
            ciufudean

            ๐Ÿ“– + + cobratbq
            cobratbq

            ๐Ÿ› coladict
            coladict

            ๐Ÿ› cosmoJFH
            cosmoJFH

            ๐Ÿ› - - cristalp
            cristalp

            ๐Ÿ› crunsk
            crunsk

            ๐Ÿ› csrma
            csrma

            ๐Ÿ› cwholmes
            cwholmes

            ๐Ÿ› + + cyberjj999
            cyberjj999

            ๐Ÿ› cyw3
            cyw3

            ๐Ÿ› ๐Ÿ“– d1ss0nanz
            d1ss0nanz

            ๐Ÿ› - - dague1
            dague1

            ๐Ÿ“– dalizi007
            dalizi007

            ๐Ÿ’ป danbrycefairsailcom
            danbrycefairsailcom

            ๐Ÿ› dariansanity
            dariansanity

            ๐Ÿ› + + darrenmiliband
            darrenmiliband

            ๐Ÿ› davidburstrom
            davidburstrom

            ๐Ÿ› dbirkman-paloalto
            dbirkman-paloalto

            ๐Ÿ› - - deepak-patra
            deepak-patra

            ๐Ÿ› dependabot[bot]
            dependabot[bot]

            ๐Ÿ’ป ๐Ÿ› dinesh150
            dinesh150

            ๐Ÿ› diziaq
            diziaq

            ๐Ÿ› + + dreaminpast123
            dreaminpast123

            ๐Ÿ› duanyanan
            duanyanan

            ๐Ÿ› dutt-sanjay
            dutt-sanjay

            ๐Ÿ› - - duursma
            duursma

            ๐Ÿ’ป dylanleung
            dylanleung

            ๐Ÿ› dzeigler
            dzeigler

            ๐Ÿ› eant60
            eant60

            ๐Ÿ› + + ekkirala
            ekkirala

            ๐Ÿ› emersonmoura
            emersonmoura

            ๐Ÿ› emouty
            emouty

            ๐Ÿ’ป ๐Ÿ› - - eugenepugach
            eugenepugach

            ๐Ÿ› fairy
            fairy

            ๐Ÿ› filiprafalowicz
            filiprafalowicz

            ๐Ÿ’ป flxbl-io
            flxbl-io

            ๐Ÿ’ต + + foxmason
            foxmason

            ๐Ÿ› frankegabor
            frankegabor

            ๐Ÿ› frankk3
            frankk3

            ๐Ÿ› - - frankl
            frankl

            ๐Ÿ› freafrea
            freafrea

            ๐Ÿ› fsapatin
            fsapatin

            ๐Ÿ› gearsethenry
            gearsethenry

            ๐Ÿ› + + gracia19
            gracia19

            ๐Ÿ› gudzpoz
            gudzpoz

            ๐Ÿ› guo fei
            guo fei

            ๐Ÿ› - - gurmsc5
            gurmsc5

            ๐Ÿ› gwilymatgearset
            gwilymatgearset

            ๐Ÿ’ป ๐Ÿ› haigsn
            haigsn

            ๐Ÿ› hemanshu070
            hemanshu070

            ๐Ÿ› + + henrik242
            henrik242

            ๐Ÿ› hongpuwu
            hongpuwu

            ๐Ÿ› hvbtup
            hvbtup

            ๐Ÿ’ป ๐Ÿ› - - igniti GmbH
            igniti GmbH

            ๐Ÿ› ilovezfs
            ilovezfs

            ๐Ÿ› imax-erik
            imax-erik

            ๐Ÿ› itaigilo
            itaigilo

            ๐Ÿ› + + jakivey32
            jakivey32

            ๐Ÿ› jbennett2091
            jbennett2091

            ๐Ÿ› jcamerin
            jcamerin

            ๐Ÿ› - - jkeener1
            jkeener1

            ๐Ÿ› jmetertea
            jmetertea

            ๐Ÿ› johnra2
            johnra2

            ๐Ÿ’ป johnzhao9
            johnzhao9

            ๐Ÿ› + + josemanuelrolon
            josemanuelrolon

            ๐Ÿ’ป ๐Ÿ› julees7
            julees7

            ๐Ÿ’ป ๐Ÿ› kabroxiko
            kabroxiko

            ๐Ÿ’ป ๐Ÿ› - - karthikaiyasamy
            karthikaiyasamy

            ๐Ÿ“– karwer
            karwer

            ๐Ÿ› kaulonline
            kaulonline

            ๐Ÿ› kdaemonv
            kdaemonv

            ๐Ÿ› + + kdandoy107255
            kdandoy107255

            ๐Ÿ› kdebski85
            kdebski85

            ๐Ÿ› ๐Ÿ’ป kenji21
            kenji21

            ๐Ÿ’ป ๐Ÿ› - - kfranic
            kfranic

            ๐Ÿ› khalidkh
            khalidkh

            ๐Ÿ› koalalam
            koalalam

            ๐Ÿ› krzyk
            krzyk

            ๐Ÿ› + + lasselindqvist
            lasselindqvist

            ๐Ÿ› lgemeinhardt
            lgemeinhardt

            ๐Ÿ› lihuaib
            lihuaib

            ๐Ÿ› - - liqingjun123
            liqingjun123

            ๐Ÿ› lonelyma1021
            lonelyma1021

            ๐Ÿ› lothas
            lothas

            ๐Ÿ› lpeddy
            lpeddy

            ๐Ÿ› + + lujiefsi
            lujiefsi

            ๐Ÿ’ป lukelukes
            lukelukes

            ๐Ÿ’ป lyriccoder
            lyriccoder

            ๐Ÿ› - - marcelmore
            marcelmore

            ๐Ÿ› matchbox
            matchbox

            ๐Ÿ› matthiaskraaz
            matthiaskraaz

            ๐Ÿ› meandonlyme
            meandonlyme

            ๐Ÿ› + + mikesive
            mikesive

            ๐Ÿ› milossesic
            milossesic

            ๐Ÿ› mluckam
            mluckam

            ๐Ÿ’ป ๐Ÿ› - - mohan-chinnappan-n
            mohan-chinnappan-n

            ๐Ÿ’ป mrclmh
            mrclmh

            ๐Ÿ› ๐Ÿ’ป mriddell95
            mriddell95

            ๐Ÿ› mrlzh
            mrlzh

            ๐Ÿ› + + msloan
            msloan

            ๐Ÿ› mucharlaravalika
            mucharlaravalika

            ๐Ÿ› mvenneman
            mvenneman

            ๐Ÿ› - - nareshl119
            nareshl119

            ๐Ÿ› nicolas-harraudeau-sonarsource
            nicolas-harraudeau-sonarsource

            ๐Ÿ› noerremark
            noerremark

            ๐Ÿ› novsirion
            novsirion

            ๐Ÿ› + + nwcm
            nwcm

            ๐Ÿ“– ๐Ÿ› ๐Ÿ’ป oggboy
            oggboy

            ๐Ÿ› oinume
            oinume

            ๐Ÿ› - - orimarko
            orimarko

            ๐Ÿ’ป ๐Ÿ› pablogomez2197
            pablogomez2197

            ๐Ÿ› pacvz
            pacvz

            ๐Ÿ’ป pallavi agarwal
            pallavi agarwal

            ๐Ÿ› + + pankratz76
            pankratz76

            ๐Ÿ› parksungrin
            parksungrin

            ๐Ÿ› + parsam97
            parsam97

            ๐Ÿ› patpatpat123
            patpatpat123

            ๐Ÿ› - - patriksevallius
            patriksevallius

            ๐Ÿ› pbrajesh1
            pbrajesh1

            ๐Ÿ› phoenix384
            phoenix384

            ๐Ÿ› + + piotrszymanski-sc
            piotrszymanski-sc

            ๐Ÿ’ป plan3d
            plan3d

            ๐Ÿ› poojasix
            poojasix

            ๐Ÿ› prabhushrikant
            prabhushrikant

            ๐Ÿ› - - pujitha8783
            pujitha8783

            ๐Ÿ› r-r-a-j
            r-r-a-j

            ๐Ÿ› raghujayjunk
            raghujayjunk

            ๐Ÿ› + + rajeshveera
            rajeshveera

            ๐Ÿ› rajeswarreddy88
            rajeswarreddy88

            ๐Ÿ› recdevs
            recdevs

            ๐Ÿ› reudismam
            reudismam

            ๐Ÿ’ป ๐Ÿ› - - rijkt
            rijkt

            ๐Ÿ› rillig-tk
            rillig-tk

            ๐Ÿ› rmohan20
            rmohan20

            ๐Ÿ’ป ๐Ÿ› + + rnveach
            rnveach

            ๐Ÿ› rubenporras
            rubenporras

            ๐Ÿ› rxmicro
            rxmicro

            ๐Ÿ› ryan-gustafson
            ryan-gustafson

            ๐Ÿ’ป ๐Ÿ› - - sabi0
            sabi0

            ๐Ÿ› samc-gearset
            samc-gearset

            ๐Ÿ“– sarser.eth
            sarser.eth

            ๐Ÿ› + + scais
            scais

            ๐Ÿ› schosin
            schosin

            ๐Ÿ› screamingfrog
            screamingfrog

            ๐Ÿ’ต sebbASF
            sebbASF

            ๐Ÿ› - - sergeygorbaty
            sergeygorbaty

            ๐Ÿ’ป shilko2013
            shilko2013

            ๐Ÿ› shiomiyan
            shiomiyan

            ๐Ÿ“– + + simeonKondr
            simeonKondr

            ๐Ÿ› snajberk
            snajberk

            ๐Ÿ› sniperrifle2004
            sniperrifle2004

            ๐Ÿ› snuyanzin
            snuyanzin

            ๐Ÿ› ๐Ÿ’ป - - soloturn
            soloturn

            ๐Ÿ› soyodream
            soyodream

            ๐Ÿ› sratz
            sratz

            ๐Ÿ› + + stonio
            stonio

            ๐Ÿ› sturton
            sturton

            ๐Ÿ’ป ๐Ÿ› sudharmohan
            sudharmohan

            ๐Ÿ› suruchidawar
            suruchidawar

            ๐Ÿ› - - svenfinitiv
            svenfinitiv

            ๐Ÿ› szymanp23
            szymanp23

            ๐Ÿ› ๐Ÿ’ป tashiscool
            tashiscool

            ๐Ÿ› + + test-git-hook
            test-git-hook

            ๐Ÿ› testation21
            testation21

            ๐Ÿ’ป ๐Ÿ› thanosa
            thanosa

            ๐Ÿ› tiandiyixian
            tiandiyixian

            ๐Ÿ› - - tobwoerk
            tobwoerk

            ๐Ÿ› tprouvot
            tprouvot

            ๐Ÿ› ๐Ÿ’ป trentchilders
            trentchilders

            ๐Ÿ› + + triandicAnt
            triandicAnt

            ๐Ÿ› trishul14
            trishul14

            ๐Ÿ› tsui
            tsui

            ๐Ÿ› wangzitom12306
            wangzitom12306

            ๐Ÿ› - - winhkey
            winhkey

            ๐Ÿ› witherspore
            witherspore

            ๐Ÿ› wjljack
            wjljack

            ๐Ÿ› + + wuchiuwong
            wuchiuwong

            ๐Ÿ› xingsong
            xingsong

            ๐Ÿ› xioayuge
            xioayuge

            ๐Ÿ› xnYi9wRezm
            xnYi9wRezm

            ๐Ÿ’ป ๐Ÿ› - - xuanuy
            xuanuy

            ๐Ÿ› xyf0921
            xyf0921

            ๐Ÿ› yalechen-cyw3
            yalechen-cyw3

            ๐Ÿ› + + yarlpavaworkday
            yarlpavaworkday

            ๐Ÿ› yasuharu-sato
            yasuharu-sato

            ๐Ÿ› zenglian
            zenglian

            ๐Ÿ› zgrzyt93
            zgrzyt93

            ๐Ÿ’ป ๐Ÿ› - - zh3ng
            zh3ng

            ๐Ÿ› zt_soft
            zt_soft

            ๐Ÿ› ztt79
            ztt79

            ๐Ÿ› + + zzzzfeng
            zzzzfeng

            ๐Ÿ› รrpรกd Magosรกnyi
            รrpรกd Magosรกnyi

            ๐Ÿ› ไปป่ดตๆฐ
            ไปป่ดตๆฐ

            ๐Ÿ› ๅคฉ็ƒญๅƒ่ฅฟ็“œ
            ๅคฉ็ƒญๅƒ่ฅฟ็“œ

            ๐Ÿ› - - ่Œ…ๅปถๅฎ‰
            ่Œ…ๅปถๅฎ‰

            ๐Ÿ’ป diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 1fc59f5a61f..62068634ba9 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -158,12 +158,65 @@ rule properties: ### โœจ๏ธ Merged pull requests +* [#6231](https://github.com/pmd/pmd/pull/6231): \[java] New Rule: PublicMemberInNonPublicType - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6232](https://github.com/pmd/pmd/pull/6232): \[java] New Rule: UnsupportedJdkApiUsage - [Thomas Leplus](https://github.com/thomasleplus) (@thomasleplus) +* [#6233](https://github.com/pmd/pmd/pull/6233): \[core] Fix #6184: More consistent enum properties - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6290](https://github.com/pmd/pmd/pull/6290): \[cli] Improve Designer start script - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6315](https://github.com/pmd/pmd/pull/6315): \[java] Fix #5882: UnconditionalIfStatement false-negative if true/false is not literal - [Marcel](https://github.com/mrclmh) (@mrclmh) +* [#6362](https://github.com/pmd/pmd/pull/6362): chore: Fix typos - [Zbynek Konecny](https://github.com/zbynek) (@zbynek) +* [#6366](https://github.com/pmd/pmd/pull/6366): \[java] Fix #3857: InsufficientStringBufferDeclaration should consider constant Strings - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#6373](https://github.com/pmd/pmd/pull/6373): \[java] Support Java 26 - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6377](https://github.com/pmd/pmd/pull/6377): \[doc] chore: update last_updated - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6384](https://github.com/pmd/pmd/pull/6384): chore: helper script check-all-contributors.sh - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6386](https://github.com/pmd/pmd/pull/6386): \[core] chore: Bump minimum Java version required for building to 21 - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6387](https://github.com/pmd/pmd/pull/6387): \[ci] publish-pull-requests: download latest build result - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6389](https://github.com/pmd/pmd/pull/6389): chore: update javadoc deprecated tags - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6390](https://github.com/pmd/pmd/pull/6390): chore: update javadoc experimental tags - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6391](https://github.com/pmd/pmd/pull/6391): chore: update javadoc internal API tags - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6392](https://github.com/pmd/pmd/pull/6392): \[doc] ADR 3: Clarify javadoc tags - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6394](https://github.com/pmd/pmd/pull/6394): \[apex] Fix #6349: FieldDeclarationsShouldBeAtStart false positive with properties - [Mohamed Hamed](https://github.com/mdhamed238) (@mdhamed238) +* [#6407](https://github.com/pmd/pmd/pull/6407): \[java] Fix #3601: InvalidLogMessageFormat: False positive when final parameter is Supplier - [Lukas Grรคf](https://github.com/lukasgraef) (@lukasgraef) +* [#6417](https://github.com/pmd/pmd/pull/6417): \[apex] Support CPD suppression with "CPD-OFF" & "CPD-ON" - [Jade](https://github.com/goto-dev-null) (@goto-dev-null) +* [#6428](https://github.com/pmd/pmd/pull/6428): \[ci] chore: run extensive integration tests under linux only - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6429](https://github.com/pmd/pmd/pull/6429): \[doc] chore: add keywords for auxclasspath in Java documentation - [Andreas Dangel](https://github.com/adangel) (@adangel) +* [#6430](https://github.com/pmd/pmd/pull/6430): \[java] Fix #6364: Parse error with yield lambda - [Andreas Dangel](https://github.com/adangel) (@adangel) ### ๐Ÿ“ฆ๏ธ Dependency updates +* [#6367](https://github.com/pmd/pmd/pull/6367): Bump PMD from 7.19.0 to 7.20.0 +* [#6369](https://github.com/pmd/pmd/pull/6369): chore(deps): bump ruby/setup-ruby from 1.275.0 to 1.277.0 +* [#6370](https://github.com/pmd/pmd/pull/6370): chore(deps): bump org.apache.groovy:groovy from 5.0.2 to 5.0.3 +* [#6371](https://github.com/pmd/pmd/pull/6371): chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.18.2 to 1.18.3 +* [#6372](https://github.com/pmd/pmd/pull/6372): chore(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.6.2 to 3.6.3 +* [#6375](https://github.com/pmd/pmd/pull/6375): chore: Bump maven from 3.9.11 to 3.9.12 +* [#6378](https://github.com/pmd/pmd/pull/6378): chore(deps): bump ruby/setup-ruby from 1.277.0 to 1.279.0 +* [#6379](https://github.com/pmd/pmd/pull/6379): chore(deps): bump scalameta.version from 4.14.2 to 4.14.4 +* [#6380](https://github.com/pmd/pmd/pull/6380): chore(deps): bump junit.version from 6.0.1 to 6.0.2 +* [#6381](https://github.com/pmd/pmd/pull/6381): chore(deps): bump org.jsoup:jsoup from 1.21.2 to 1.22.1 +* [#6382](https://github.com/pmd/pmd/pull/6382): chore(deps): bump org.checkerframework:checker-qual from 3.52.1 to 3.53.0 +* [#6383](https://github.com/pmd/pmd/pull/6383): chore(deps): bump com.puppycrawl.tools:checkstyle from 12.3.0 to 13.0.0 +* [#6385](https://github.com/pmd/pmd/pull/6385): chore(deps): bump uri from 1.0.3 to 1.0.4 in /docs +* [#6399](https://github.com/pmd/pmd/pull/6399): chore(deps): bump ruby/setup-ruby from 1.279.0 to 1.282.0 +* [#6400](https://github.com/pmd/pmd/pull/6400): chore(deps): bump com.github.siom79.japicmp:japicmp-maven-plugin from 0.25.1 to 0.25.4 +* [#6401](https://github.com/pmd/pmd/pull/6401): chore(deps): bump org.sonatype.central:central-publishing-maven-plugin from 0.9.0 to 0.10.0 +* [#6403](https://github.com/pmd/pmd/pull/6403): chore(deps): bump com.google.protobuf:protobuf-java from 4.33.2 to 4.33.4 +* [#6410](https://github.com/pmd/pmd/pull/6410): chore(deps): bump ruby/setup-ruby from 1.282.0 to 1.285.0 +* [#6411](https://github.com/pmd/pmd/pull/6411): chore(deps): bump actions/cache from 5.0.1 to 5.0.2 +* [#6412](https://github.com/pmd/pmd/pull/6412): chore(deps): bump scalameta.version from 4.14.4 to 4.14.5 +* [#6413](https://github.com/pmd/pmd/pull/6413): chore(deps-dev): bump net.bytebuddy:byte-buddy from 1.18.3 to 1.18.4 +* [#6414](https://github.com/pmd/pmd/pull/6414): chore(deps-dev): bump org.codehaus.mojo:versions-maven-plugin from 2.20.1 to 2.21.0 +* [#6415](https://github.com/pmd/pmd/pull/6415): chore(deps-dev): bump net.bytebuddy:byte-buddy-agent from 1.18.3 to 1.18.4 +* [#6419](https://github.com/pmd/pmd/pull/6419): chore(deps-dev): bump lodash from 4.17.21 to 4.17.23 +* [#6421](https://github.com/pmd/pmd/pull/6421): chore(deps): bump actions/setup-java from 5.1.0 to 5.2.0 +* [#6422](https://github.com/pmd/pmd/pull/6422): chore(deps): bump actions/checkout from 6.0.1 to 6.0.2 +* [#6423](https://github.com/pmd/pmd/pull/6423): chore(deps): bump scalameta.version from 4.14.5 to 4.14.6 +* [#6424](https://github.com/pmd/pmd/pull/6424): chore(deps-dev): bump org.assertj:assertj-core from 3.27.6 to 3.27.7 +* [#6425](https://github.com/pmd/pmd/pull/6425): chore(deps): bump org.apache.groovy:groovy from 5.0.3 to 5.0.4 ### ๐Ÿ“ˆ๏ธ Stats +* 146 commits +* 30 closed tickets & PRs +* Days since last release: 30 {% endtocmaker %} - From 4558030d6f9859d7142580a8595d08e36a21e737 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 30 Jan 2026 10:19:39 +0100 Subject: [PATCH 1961/1962] [release] prepare release pmd_releases/7.21.0 --- pmd-ant/pom.xml | 2 +- pmd-apex/pom.xml | 2 +- pmd-cli/pom.xml | 2 +- pmd-coco/pom.xml | 2 +- pmd-core/pom.xml | 2 +- pmd-cpp/pom.xml | 2 +- pmd-cs/pom.xml | 2 +- pmd-css/pom.xml | 2 +- pmd-dart/pom.xml | 2 +- pmd-dist/pom.xml | 2 +- pmd-doc/pom.xml | 2 +- pmd-fortran/pom.xml | 2 +- pmd-gherkin/pom.xml | 2 +- pmd-go/pom.xml | 2 +- pmd-groovy/pom.xml | 2 +- pmd-html/pom.xml | 2 +- pmd-java/pom.xml | 2 +- pmd-javascript/pom.xml | 2 +- pmd-jsp/pom.xml | 2 +- pmd-julia/pom.xml | 2 +- pmd-kotlin/pom.xml | 2 +- pmd-lang-test/pom.xml | 2 +- pmd-languages-deps/pom.xml | 2 +- pmd-lua/pom.xml | 2 +- pmd-matlab/pom.xml | 2 +- pmd-modelica/pom.xml | 2 +- pmd-objectivec/pom.xml | 2 +- pmd-perl/pom.xml | 2 +- pmd-php/pom.xml | 2 +- pmd-plsql/pom.xml | 2 +- pmd-python/pom.xml | 2 +- pmd-ruby/pom.xml | 2 +- pmd-rust/pom.xml | 2 +- pmd-scala-modules/pmd-scala-common/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.12/pom.xml | 2 +- pmd-scala-modules/pmd-scala_2.13/pom.xml | 2 +- pmd-swift/pom.xml | 2 +- pmd-test-schema/pom.xml | 2 +- pmd-test/pom.xml | 2 +- pmd-tsql/pom.xml | 2 +- pmd-velocity/pom.xml | 2 +- pmd-visualforce/pom.xml | 2 +- pmd-xml/pom.xml | 2 +- pom.xml | 6 +++--- 44 files changed, 46 insertions(+), 46 deletions(-) diff --git a/pmd-ant/pom.xml b/pmd-ant/pom.xml index 7cef1f73bb8..7a3309e5a9f 100644 --- a/pmd-ant/pom.xml +++ b/pmd-ant/pom.xml @@ -7,7 +7,7 @@ pmd net.sourceforge.pmd - 7.21.0-SNAPSHOT + 7.21.0 4.0.0 diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 6374aaf02b7..4121056cdd5 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index e3eb6b6ab54..9a370c966ef 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-coco/pom.xml b/pmd-coco/pom.xml index 871d02725b3..5a6c6434572 100644 --- a/pmd-coco/pom.xml +++ b/pmd-coco/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml index a406eef6283..a02c1c80668 100644 --- a/pmd-core/pom.xml +++ b/pmd-core/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-cpp/pom.xml b/pmd-cpp/pom.xml index 4a63513cfef..0e0523baa95 100644 --- a/pmd-cpp/pom.xml +++ b/pmd-cpp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-cs/pom.xml b/pmd-cs/pom.xml index da6a532f867..25b1378472e 100644 --- a/pmd-cs/pom.xml +++ b/pmd-cs/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-css/pom.xml b/pmd-css/pom.xml index c6e752aa57e..e11a60f5b05 100644 --- a/pmd-css/pom.xml +++ b/pmd-css/pom.xml @@ -9,7 +9,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-dart/pom.xml b/pmd-dart/pom.xml index 4b9b767b8c7..c861be86029 100644 --- a/pmd-dart/pom.xml +++ b/pmd-dart/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index 02c438275d7..1a0e433ca88 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml index 55b39c22803..a323bbb0f51 100644 --- a/pmd-doc/pom.xml +++ b/pmd-doc/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-fortran/pom.xml b/pmd-fortran/pom.xml index 7479ccad085..946ec0ad4e4 100644 --- a/pmd-fortran/pom.xml +++ b/pmd-fortran/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-gherkin/pom.xml b/pmd-gherkin/pom.xml index a5289fcca04..b21c5853838 100644 --- a/pmd-gherkin/pom.xml +++ b/pmd-gherkin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-go/pom.xml b/pmd-go/pom.xml index 3d0f3fe3640..38a91b62513 100644 --- a/pmd-go/pom.xml +++ b/pmd-go/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-groovy/pom.xml b/pmd-groovy/pom.xml index 8a017aa951c..0f733d9b9ec 100644 --- a/pmd-groovy/pom.xml +++ b/pmd-groovy/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml index e9c1f54af9f..18cb26f6922 100644 --- a/pmd-html/pom.xml +++ b/pmd-html/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-java/pom.xml b/pmd-java/pom.xml index 88d56dee006..faad87b8028 100644 --- a/pmd-java/pom.xml +++ b/pmd-java/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-javascript/pom.xml b/pmd-javascript/pom.xml index d849450686b..e34354d0cf4 100644 --- a/pmd-javascript/pom.xml +++ b/pmd-javascript/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-jsp/pom.xml b/pmd-jsp/pom.xml index 2a3a9eaaca0..f7ad1c01767 100644 --- a/pmd-jsp/pom.xml +++ b/pmd-jsp/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-julia/pom.xml b/pmd-julia/pom.xml index 0032a1ab343..ec09b1e48ba 100644 --- a/pmd-julia/pom.xml +++ b/pmd-julia/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-kotlin/pom.xml b/pmd-kotlin/pom.xml index ab8b0ed00a3..493e7554ba3 100644 --- a/pmd-kotlin/pom.xml +++ b/pmd-kotlin/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-lang-test/pom.xml b/pmd-lang-test/pom.xml index 6bbeaf34d46..b1a5ec060e0 100644 --- a/pmd-lang-test/pom.xml +++ b/pmd-lang-test/pom.xml @@ -12,7 +12,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml index 0107bb78b37..5271b4d560a 100644 --- a/pmd-languages-deps/pom.xml +++ b/pmd-languages-deps/pom.xml @@ -4,7 +4,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 pmd-languages-deps diff --git a/pmd-lua/pom.xml b/pmd-lua/pom.xml index 3269c833aca..61d33f6b9d8 100644 --- a/pmd-lua/pom.xml +++ b/pmd-lua/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-matlab/pom.xml b/pmd-matlab/pom.xml index a27a1868753..bb5476b5fa8 100644 --- a/pmd-matlab/pom.xml +++ b/pmd-matlab/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-modelica/pom.xml b/pmd-modelica/pom.xml index 7da4710fb79..2b78d614c33 100644 --- a/pmd-modelica/pom.xml +++ b/pmd-modelica/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-objectivec/pom.xml b/pmd-objectivec/pom.xml index 0c58ebf7942..c47dc34618b 100644 --- a/pmd-objectivec/pom.xml +++ b/pmd-objectivec/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-perl/pom.xml b/pmd-perl/pom.xml index f3eee8862d5..98012626f19 100644 --- a/pmd-perl/pom.xml +++ b/pmd-perl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-php/pom.xml b/pmd-php/pom.xml index 265564d0eaa..b6ab4c0b82e 100644 --- a/pmd-php/pom.xml +++ b/pmd-php/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-plsql/pom.xml b/pmd-plsql/pom.xml index 58b59b54ab9..e54772f5e81 100644 --- a/pmd-plsql/pom.xml +++ b/pmd-plsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-python/pom.xml b/pmd-python/pom.xml index 89a8dd0c55c..a2355befcc1 100644 --- a/pmd-python/pom.xml +++ b/pmd-python/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-ruby/pom.xml b/pmd-ruby/pom.xml index 7ac23063cec..7dd59ae02c4 100644 --- a/pmd-ruby/pom.xml +++ b/pmd-ruby/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-rust/pom.xml b/pmd-rust/pom.xml index 181120786db..79e8f8403ce 100644 --- a/pmd-rust/pom.xml +++ b/pmd-rust/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-scala-modules/pmd-scala-common/pom.xml b/pmd-scala-modules/pmd-scala-common/pom.xml index 601654c8828..90296e41fd8 100644 --- a/pmd-scala-modules/pmd-scala-common/pom.xml +++ b/pmd-scala-modules/pmd-scala-common/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../../pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.12/pom.xml b/pmd-scala-modules/pmd-scala_2.12/pom.xml index 7d70fd83587..07de6a22101 100644 --- a/pmd-scala-modules/pmd-scala_2.12/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.12/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.21.0-SNAPSHOT + 7.21.0 ../pmd-scala-common/pom.xml diff --git a/pmd-scala-modules/pmd-scala_2.13/pom.xml b/pmd-scala-modules/pmd-scala_2.13/pom.xml index ea5db6d7c3e..e58e65ce03a 100644 --- a/pmd-scala-modules/pmd-scala_2.13/pom.xml +++ b/pmd-scala-modules/pmd-scala_2.13/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd-scala-common - 7.21.0-SNAPSHOT + 7.21.0 ../pmd-scala-common/pom.xml diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index db54002f799..a45b4628508 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-test-schema/pom.xml b/pmd-test-schema/pom.xml index 1b5988497fc..f2daa1f4939 100644 --- a/pmd-test-schema/pom.xml +++ b/pmd-test-schema/pom.xml @@ -11,7 +11,7 @@ pmd net.sourceforge.pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-test/pom.xml b/pmd-test/pom.xml index 942ed93cde2..bb732687a2b 100644 --- a/pmd-test/pom.xml +++ b/pmd-test/pom.xml @@ -8,7 +8,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-tsql/pom.xml b/pmd-tsql/pom.xml index 185d6e4f89a..e60445e8e77 100644 --- a/pmd-tsql/pom.xml +++ b/pmd-tsql/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-velocity/pom.xml b/pmd-velocity/pom.xml index 69750f5b947..86f88044b87 100644 --- a/pmd-velocity/pom.xml +++ b/pmd-velocity/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-visualforce/pom.xml b/pmd-visualforce/pom.xml index c9d78ac0f91..408dbfcc8d3 100644 --- a/pmd-visualforce/pom.xml +++ b/pmd-visualforce/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pmd-xml/pom.xml b/pmd-xml/pom.xml index 9a5713ed1a5..e613662a5ed 100644 --- a/pmd-xml/pom.xml +++ b/pmd-xml/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 ../pom.xml diff --git a/pom.xml b/pom.xml index 292e431342c..8f1c6f189ed 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 net.sourceforge.pmd pmd - 7.21.0-SNAPSHOT + 7.21.0 pom PMD @@ -62,7 +62,7 @@ scm:git:git://github.com/pmd/pmd.git scm:git:ssh://git@github.com/pmd/pmd.git https://github.com/pmd/pmd - HEAD + pmd_releases/7.21.0 PMD @@ -73,7 +73,7 @@ - 2025-12-30T14:37:52Z + 2026-01-30T08:58:29Z 8 From 9b0dc2ba7810b4108ac4732e1bd97a2f70447b83 Mon Sep 17 00:00:00 2001 From: Marvin Wener Date: Wed, 4 Feb 2026 15:02:38 +0100 Subject: [PATCH 1962/1962] 37163: Upgraded CPD to 7.21.0. --- pmd-awl/pom.xml | 2 +- .../net/sourceforge/pmd/cli/commands/internal/CpdCommand.java | 3 --- .../typesupport/internal/CpdIgnoreSequenceTypeSupport.java | 2 +- .../java/net/sourceforge/pmd/lang/cpp/cpd/CppCpdLexer.java | 3 +-- pmd-powershell/pom.xml | 2 +- .../pmd/lang/powershell/PowershellLanguageModule.java | 2 +- .../pmd/lang/powershell/cpd/PowershellCpdLexer.java | 2 +- .../pmd/lang/powershell/cpd/PowershellTokenizerTest.java | 2 +- 8 files changed, 7 insertions(+), 11 deletions(-) diff --git a/pmd-awl/pom.xml b/pmd-awl/pom.xml index d1f2434da05..f1b637f8f08 100644 --- a/pmd-awl/pom.xml +++ b/pmd-awl/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.21.0 ../pom.xml diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java index fc936ee9e49..f99cbd89cfc 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java @@ -5,11 +5,8 @@ package net.sourceforge.pmd.cli.commands.internal; import java.io.IOException; -import java.nio.file.Path; -import java.util.ArrayList; import java.util.EnumSet; import java.util.Iterator; -import java.util.List; import java.util.Set; import org.apache.commons.lang3.mutable.MutableBoolean; diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/CpdIgnoreSequenceTypeSupport.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/CpdIgnoreSequenceTypeSupport.java index 03c932f8777..77b3d5215d8 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/CpdIgnoreSequenceTypeSupport.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/typesupport/internal/CpdIgnoreSequenceTypeSupport.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-cpp/src/main/java/net/sourceforge/pmd/lang/cpp/cpd/CppCpdLexer.java b/pmd-cpp/src/main/java/net/sourceforge/pmd/lang/cpp/cpd/CppCpdLexer.java index 5faa5138878..84d690b3fbd 100644 --- a/pmd-cpp/src/main/java/net/sourceforge/pmd/lang/cpp/cpd/CppCpdLexer.java +++ b/pmd-cpp/src/main/java/net/sourceforge/pmd/lang/cpp/cpd/CppCpdLexer.java @@ -42,7 +42,6 @@ public CppCpdLexer(LanguagePropertyBundle cppProperties) { ignoreLiteralSequences = cppProperties.getProperty(CpdLanguageProperties.CPD_IGNORE_LITERAL_SEQUENCES); ignoreIdentifierAndLiteralSequences = cppProperties.getProperty(CpdLanguageProperties.CPD_IGNORE_LITERAL_AND_IDENTIFIER_SEQUENCES); ignoreArrayInitializations = cppProperties.getProperty(CpdLanguageProperties.CPD_IGNORE_SEQUENCE_INITIALIZATION); - ignoreIdentifierAndLiteralSequences = cppProperties.getProperty(CpdLanguageProperties.CPD_IGNORE_LITERAL_AND_IDENTIFIER_SEQUENCES); ignoreLiterals = cppProperties.getProperty(CpdLanguageProperties.CPD_ANONYMIZE_LITERALS); ignoreIdentifiers = cppProperties.getProperty(CpdLanguageProperties.CPD_ANONYMIZE_IDENTIFIERS); String skipBlocksPattern = cppProperties.getProperty(CppLanguageModule.CPD_SKIP_BLOCKS); @@ -78,7 +77,7 @@ public TextDocument translate(TextDocument text) throws MalformedSourceException @Override protected TokenManager filterTokenStream(final TokenManager tokenManager) { - return new CppTokenFilter(tokenManager, ignoreLiteralSequences, ignoreIdentifierAndLiteralSequuences, ignoreArrayInitializations); + return new CppTokenFilter(tokenManager, ignoreLiteralSequences, ignoreIdentifierAndLiteralSequences, ignoreArrayInitializations); } @Override diff --git a/pmd-powershell/pom.xml b/pmd-powershell/pom.xml index 0db88a30c6d..d32e4d6e994 100644 --- a/pmd-powershell/pom.xml +++ b/pmd-powershell/pom.xml @@ -7,7 +7,7 @@ net.sourceforge.pmd pmd - 7.6.0 + 7.21.0 ../pom.xml diff --git a/pmd-powershell/src/main/java/net/sourceforge/pmd/lang/powershell/PowershellLanguageModule.java b/pmd-powershell/src/main/java/net/sourceforge/pmd/lang/powershell/PowershellLanguageModule.java index 3a9a00dabf8..11b923a6357 100644 --- a/pmd-powershell/src/main/java/net/sourceforge/pmd/lang/powershell/PowershellLanguageModule.java +++ b/pmd-powershell/src/main/java/net/sourceforge/pmd/lang/powershell/PowershellLanguageModule.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-powershell/src/main/java/net/sourceforge/pmd/lang/powershell/cpd/PowershellCpdLexer.java b/pmd-powershell/src/main/java/net/sourceforge/pmd/lang/powershell/cpd/PowershellCpdLexer.java index 821003e7e94..f841d695cbd 100644 --- a/pmd-powershell/src/main/java/net/sourceforge/pmd/lang/powershell/cpd/PowershellCpdLexer.java +++ b/pmd-powershell/src/main/java/net/sourceforge/pmd/lang/powershell/cpd/PowershellCpdLexer.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ diff --git a/pmd-powershell/src/test/java/net/sourceforge/pmd/lang/powershell/cpd/PowershellTokenizerTest.java b/pmd-powershell/src/test/java/net/sourceforge/pmd/lang/powershell/cpd/PowershellTokenizerTest.java index de1fb66db29..b18159cc7b3 100644 --- a/pmd-powershell/src/test/java/net/sourceforge/pmd/lang/powershell/cpd/PowershellTokenizerTest.java +++ b/pmd-powershell/src/test/java/net/sourceforge/pmd/lang/powershell/cpd/PowershellTokenizerTest.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */